From d0265935e36619bb6efc2dbfb785c8076cc2ccf2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= <olafurpg@gmail.com>
Date: Thu, 22 Jul 2021 16:37:27 +0200
Subject: [PATCH] Add Scala support.

Previously, lsif-java wasn't able to index Scala projects. This commit
add support to

- render Scala method/class signatures using Scala syntax
- compile Scala sources in package repositories (Maven Central libraries)
---
 build.sbt                                     |   16 +-
 .../lsif_java/SemanticdbPrinters.scala        |    2 +-
 .../lsif_java/buildtools/LsifBuildTool.scala  |  219 +-
 .../buildtools/ScalaCompilerClassLoader.scala |   24 +
 .../lsif_java/buildtools/ScalaVersion.scala   |   53 +
 .../lsif_semanticdb/SignatureFormatter.java   |  304 ++-
 .../sourcegraph/lsif_semanticdb/Symtab.java   |   10 +
 .../src/main/protobuf/semanticdb.proto        |   84 +-
 .../main/scala/benchmarks/CompileBench.scala  |    8 +-
 .../benchmarks/LsifSemanticdbBench.scala      |    7 +-
 .../test/scala/tests/LsifBuildToolSuite.scala |   39 +-
 .../minimized/MinimizedScalaSignatures.scala  |   48 +
 .../src/main/generated/BaseByteRenderer.scala |  468 ++++
 .../src/main/generated/BaseCharRenderer.scala |  468 ++++
 .../src/main/generated/ByteParser.scala       | 1930 +++++++++++++++++
 .../src/main/generated/CharParser.scala       | 1930 +++++++++++++++++
 .../airbnb/epoxy/AsyncEpoxyController.java    |    2 +-
 .../com/airbnb/epoxy/AsyncEpoxyDiffer.java    |    2 +-
 .../com/airbnb/epoxy/BaseEpoxyAdapter.java    |    2 +-
 .../com/airbnb/epoxy/BoundViewHolders.java    |    4 +-
 .../generated/com/airbnb/epoxy/Carousel.java  |    2 +-
 .../com/airbnb/epoxy/ControllerModelList.java |    2 +-
 .../com/airbnb/epoxy/DebugTimer.java          |    2 +-
 .../com/airbnb/epoxy/EpoxyAdapter.java        |    2 +-
 .../com/airbnb/epoxy/EpoxyController.java     |    2 +-
 .../airbnb/epoxy/EpoxyControllerAdapter.java  |    2 +-
 .../com/airbnb/epoxy/EpoxyDiffLogger.java     |    2 +-
 .../com/airbnb/epoxy/EpoxyDragCallback.java   |    2 +-
 .../epoxy/EpoxyItemSpacingDecorator.java      |    2 +-
 .../com/airbnb/epoxy/EpoxyModelGroup.java     |    2 +-
 .../airbnb/epoxy/EpoxyModelTouchCallback.java |    2 +-
 .../airbnb/epoxy/EpoxyModelWithHolder.java    |    2 +-
 .../com/airbnb/epoxy/EpoxyModelWithView.java  |    2 +-
 .../com/airbnb/epoxy/EpoxySwipeCallback.java  |    2 +-
 .../com/airbnb/epoxy/EpoxyTouchHelper.java    |    4 +-
 .../epoxy/EpoxyTouchHelperCallback.java       |    2 +-
 .../com/airbnb/epoxy/EpoxyViewHolder.java     |    2 +-
 .../com/airbnb/epoxy/HandlerExecutor.java     |    2 +-
 .../com/airbnb/epoxy/HiddenEpoxyModel.java    |    2 +-
 .../com/airbnb/epoxy/IllegalEpoxyUsage.java   |    2 +-
 .../airbnb/epoxy/ImmutableModelException.java |    2 +-
 .../com/airbnb/epoxy/MainThreadExecutor.java  |    2 +-
 .../generated/com/airbnb/epoxy/ModelList.java |   10 +-
 .../airbnb/epoxy/NoOpControllerHelper.java    |    2 +-
 .../generated/com/airbnb/epoxy/NoOpTimer.java |    2 +-
 .../com/airbnb/epoxy/NotifyBlocker.java       |    2 +-
 .../com/airbnb/epoxy/SimpleEpoxyAdapter.java  |    2 +-
 .../airbnb/epoxy/SimpleEpoxyController.java   |    2 +-
 .../com/airbnb/epoxy/SimpleEpoxyModel.java    |    2 +-
 .../airbnb/epoxy/Typed2EpoxyController.java   |    2 +-
 .../airbnb/epoxy/Typed3EpoxyController.java   |    2 +-
 .../airbnb/epoxy/Typed4EpoxyController.java   |    2 +-
 .../airbnb/epoxy/TypedEpoxyController.java    |    2 +-
 .../com/airbnb/epoxy/ViewHolderState.java     |    4 +-
 ...rappedEpoxyModelCheckedChangeListener.java |    2 +-
 .../generated/minimized/InnerClasses.java     |    2 +-
 .../minimized/MinimizedScalaMain.scala        |    6 +-
 .../minimized/MinimizedScalaSignatures.scala  |  175 ++
 .../main/generated/minimized/SubClasses.java  |    2 +-
 .../generated/minimized/TypeVariables.java    |    2 +-
 .../main/generated/ujson/AstTransformer.scala |  211 ++
 .../generated/ujson/ByteArrayParser.scala     |   99 +
 .../generated/ujson/ByteBufferParser.scala    |  113 +
 .../generated/ujson/CharSequenceParser.scala  |   73 +
 .../src/main/generated/ujson/Exceptions.scala |   34 +
 .../main/generated/ujson/IndexedValue.scala   |  454 ++++
 .../generated/ujson/InputStreamParser.scala   |   88 +
 .../src/main/generated/ujson/JsVisitor.scala  |  264 +++
 .../src/main/generated/ujson/Readable.scala   |  175 ++
 .../src/main/generated/ujson/Renderer.scala   |   75 +
 .../main/generated/ujson/StringParser.scala   |   82 +
 .../main/generated/ujson/Transformer.scala    |   29 +
 .../src/main/generated/ujson/Value.scala      |  976 +++++++++
 .../src/main/generated/ujson/package.scala    |  302 +++
 .../tests/LibrarySnapshotGenerator.scala      |   26 +-
 .../tests/LsifGraphSnapshotGenerator.scala    |    3 +-
 .../src/main/scala/tests/CompileResult.scala  |   22 +
 .../src/main/scala/tests/TestCompiler.scala   |   68 +-
 .../tests/JavacClassesDirectorySuite.scala    |    3 +-
 .../test/scala/tests/ScalaVersionSuite.scala  |   38 +
 80 files changed, 8874 insertions(+), 150 deletions(-)
 create mode 100644 lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaCompilerClassLoader.scala
 create mode 100644 lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaVersion.scala
 create mode 100644 tests/minimized-scala/src/main/scala/minimized/MinimizedScalaSignatures.scala
 create mode 100644 tests/snapshots/src/main/generated/BaseByteRenderer.scala
 create mode 100644 tests/snapshots/src/main/generated/BaseCharRenderer.scala
 create mode 100644 tests/snapshots/src/main/generated/ByteParser.scala
 create mode 100644 tests/snapshots/src/main/generated/CharParser.scala
 create mode 100644 tests/snapshots/src/main/generated/minimized/MinimizedScalaSignatures.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/AstTransformer.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/ByteArrayParser.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/ByteBufferParser.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/CharSequenceParser.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/Exceptions.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/IndexedValue.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/InputStreamParser.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/JsVisitor.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/Readable.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/Renderer.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/StringParser.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/Transformer.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/Value.scala
 create mode 100644 tests/snapshots/src/main/generated/ujson/package.scala
 create mode 100644 tests/unit/src/test/scala/tests/ScalaVersionSuite.scala

diff --git a/build.sbt b/build.sbt
index a92e6c336..9091e8d18 100644
--- a/build.sbt
+++ b/build.sbt
@@ -12,9 +12,12 @@ lazy val V =
     val bloop = "1.4.7"
     val bsp = "2.0.0-M13"
     val moped = "0.1.10"
-    def scala213 = "2.13.4"
-    def scala212 = "2.12.12"
-    def scalameta = "4.4.8"
+    def scala213 = "2.13.6"
+    def scala212 = "2.12.14"
+    def scala211 = "2.11.12"
+    def scala3 = "3.0.1"
+    def metals = "0.10.5"
+    def scalameta = "4.4.25"
     def testcontainers = "0.39.3"
     def requests = "0.6.5"
   }
@@ -143,6 +146,11 @@ lazy val cli = project
       Seq[BuildInfoKey](
         version,
         scalaVersion,
+        "mtags" -> V.metals,
+        "scala211" -> V.scala211,
+        "scala212" -> V.scala212,
+        "scala213" -> V.scala213,
+        "scala3" -> V.scala3,
         "bloopVersion" -> V.bloop,
         "bspVersion" -> V.bsp
       ),
@@ -150,6 +158,7 @@ lazy val cli = project
     libraryDependencies ++=
       List(
         "io.get-coursier" %% "coursier" % V.coursier,
+        "org.scalameta" % "mtags-interfaces" % V.metals,
         "org.scala-lang.modules" %% "scala-xml" % "1.3.0",
         "com.lihaoyi" %% "requests" % V.requests,
         "org.scalameta" %% "moped" % V.moped,
@@ -385,6 +394,7 @@ lazy val testSettings = List(
   libraryDependencies ++=
     List(
       "org.scalameta" %% "munit" % "0.7.27",
+      "org.scalameta" %% "mtags" % V.metals cross CrossVersion.full,
       "com.dimafeng" %% "testcontainers-scala-munit" % V.testcontainers,
       "com.dimafeng" %% "testcontainers-scala-postgresql" % V.testcontainers,
       "org.scalameta" %% "moped-testkit" % V.moped,
diff --git a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/SemanticdbPrinters.scala b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/SemanticdbPrinters.scala
index 892ab0fb8..e3998efc0 100644
--- a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/SemanticdbPrinters.scala
+++ b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/SemanticdbPrinters.scala
@@ -97,7 +97,7 @@ object SemanticdbPrinters {
             if (sig.isEmpty)
               " " + info.getDisplayName
             else
-              " " + sig.replace('\n', ' ')
+              " " + sig.trim.replace('\n', ' ')
           case _ =>
             ""
         }
diff --git a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/LsifBuildTool.scala b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/LsifBuildTool.scala
index 5a539ab79..b1456c231 100644
--- a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/LsifBuildTool.scala
+++ b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/LsifBuildTool.scala
@@ -2,6 +2,7 @@ package com.sourcegraph.lsif_java.buildtools
 
 import java.io.File
 import java.io.IOException
+import java.net.URLClassLoader
 import java.nio.file.FileSystems
 import java.nio.file.FileVisitResult
 import java.nio.file.Files
@@ -9,16 +10,26 @@ import java.nio.file.NoSuchFileException
 import java.nio.file.Path
 import java.nio.file.Paths
 import java.nio.file.SimpleFileVisitor
+import java.nio.file.StandardOpenOption
 import java.nio.file.attribute.BasicFileAttributes
+import java.util.ServiceLoader
 
 import scala.collection.mutable.ListBuffer
 import scala.jdk.CollectionConverters._
+import scala.util.Failure
+import scala.util.Success
+import scala.util.Try
 import scala.util.control.NonFatal
 
+import scala.meta.pc.PresentationCompiler
+
 import com.sourcegraph.io.DeleteVisitor
+import com.sourcegraph.lsif_java.BuildInfo
 import com.sourcegraph.lsif_java.Dependencies
 import com.sourcegraph.lsif_java.Embedded
 import com.sourcegraph.lsif_java.commands.IndexCommand
+import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocument
+import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocuments
 import moped.json.DecodingContext
 import moped.json.ErrorResult
 import moped.json.JsonCodec
@@ -32,6 +43,7 @@ import moped.reporters.Diagnostic
 import moped.reporters.Input
 import os.CommandResult
 import os.ProcessOutput.Readlines
+import os.SubprocessException
 
 /**
  * A custom build tool that is specifically made for lsif-java.
@@ -49,6 +61,16 @@ import os.ProcessOutput.Readlines
  */
 class LsifBuildTool(index: IndexCommand) extends BuildTool("LSIF", index) {
 
+  private val javaPattern = FileSystems
+    .getDefault
+    .getPathMatcher("glob:**.java")
+  private val scalaPattern = FileSystems
+    .getDefault
+    .getPathMatcher("glob:**.scala")
+  private val allPatterns = FileSystems
+    .getDefault
+    .getPathMatcher("glob:**.{java,scala}")
+  private val moduleInfo = Paths.get("module-info.java")
   protected def defaultTargetroot: Path = Paths.get("target")
   private def configFile =
     index.workingDirectory.resolve(LsifBuildTool.ConfigFileName)
@@ -96,40 +118,168 @@ class LsifBuildTool(index: IndexCommand) extends BuildTool("LSIF", index) {
     Files.createDirectories(tmp)
     Files.createDirectories(targetroot)
     val deps = Dependencies.resolveDependencies(config.dependencies.map(_.repr))
-    val semanticdbJar = Embedded.semanticdbJar(tmp)
-    val coursier = Embedded.coursier(tmp)
-    val actualClasspath = deps.classpath :+ semanticdbJar
-    val argsfile = targetroot.resolve("javacopts.txt")
     val sourceroot = index.workingDirectory
     if (!Files.isDirectory(sourceroot)) {
       throw new NoSuchFileException(sourceroot.toString())
     }
-    val allJavaFiles = collectAllJavaFiles(sourceroot)
-    val javaFiles = allJavaFiles
-      .filterNot(_.endsWith(moduleInfo))
-      .map(_.toString())
-    val moduleInfos = allJavaFiles.filter(_.endsWith(moduleInfo))
-    if (javaFiles.isEmpty) {
+    val allSourceFiles = collectAllSourceFiles(sourceroot)
+    val javaFiles = allSourceFiles.filter(path => javaPattern.matches(path))
+    val scalaFiles = allSourceFiles.filter(path => scalaPattern.matches(path))
+    if (javaFiles.isEmpty && scalaFiles.isEmpty) {
       index
         .app
         .warning(
-          s"doing nothing, no files matching pattern '$sourceroot/**.java'"
+          s"doing nothing, no files matching pattern '$sourceroot/**.{java,scala}'"
         )
       return CommandResult(0, Nil)
     }
-    def generatedDir(name: String): String = {
-      Files.createDirectory(tmp.resolve(name)).toString()
+    val errors = ListBuffer.empty[Try[Unit]]
+    errors += compileJavaFiles(tmp, deps, config, javaFiles)
+    errors += compileScalaFiles(deps, scalaFiles)
+    if (index.cleanup) {
+      Files.walkFileTree(tmp, new DeleteVisitor)
+    }
+    val isSemanticdbGenerated = Files
+      .isDirectory(targetroot.resolve("META-INF"))
+    if (errors.nonEmpty && !isSemanticdbGenerated) {
+      CommandResult(1, Nil)
+    } else {
+      if (isSemanticdbGenerated) {
+        index
+          .app
+          .reporter
+          .info(
+            "Some SemanticDB files got generated even if there were compile errors. " +
+              "In most cases, this means that lsif-java managed to index everything " +
+              "except the locations that had compile errors and you can ignore the compile errors."
+          )
+      }
+      CommandResult(0, Nil)
+    }
+  }
+
+  private def compileScalaFiles(
+      deps: Dependencies,
+      allScalaFiles: List[Path]
+  ): Try[Unit] =
+    Try {
+      withScalaPresentationCompiler(deps) { compiler =>
+        allScalaFiles.foreach { path =>
+          try compileScalaFile(compiler, path)
+          catch {
+            case NonFatal(e) =>
+              // We want to try and index as much as possible so we don't fail the entire
+              // compilation even if a single file fails to compile.
+              index.app.reporter.log(Diagnostic.exception(e))
+          }
+        }
+      }
+    }
+
+  private def compileScalaFile(
+      compiler: PresentationCompiler,
+      path: Path
+  ): Unit = {
+    val input = Input.path(path)
+    val textDocument = TextDocument
+      .parseFrom(compiler.semanticdbTextDocument(path.toUri, input.text).get())
+      .toBuilder
+      .setUri(sourceroot.relativize(path).iterator().asScala.mkString("/"))
+    val textDocuments = TextDocuments
+      .newBuilder()
+      .addDocuments(textDocument)
+      .build()
+    val relpath = sourceroot
+      .relativize(path)
+      .resolveSibling(path.getFileName.toString + ".semanticdb")
+    val out = targetroot
+      .resolve("META-INF")
+      .resolve("semanticdb")
+      .resolve(relpath)
+    Files.createDirectories(out.getParent)
+    Files.write(
+      out,
+      textDocuments.toByteArray,
+      StandardOpenOption.TRUNCATE_EXISTING,
+      StandardOpenOption.CREATE
+    )
+  }
+
+  private def withScalaPresentationCompiler[T](
+      deps: Dependencies
+  )(fn: PresentationCompiler => T): T = {
+    val scalaVersion = deps
+      .classpath
+      .headOption
+      .flatMap(jar => ScalaVersion.inferFromJar(jar))
+      .getOrElse {
+        throw new IllegalArgumentException(
+          s"failed to infer the Scala version from the dependencies: " +
+            pprint.PPrinter.BlackWhite.tokenize(deps.classpath).mkString
+        )
+      }
+    val mtags = Dependencies.resolveDependencies(
+      List(s"org.scalameta:mtags_${scalaVersion}:${BuildInfo.mtags}")
+    )
+    val scalaLibrary = mtags
+      .classpath
+      .filter(_.getFileName.toString.contains("scala-library"))
+    val parent = new ScalaCompilerClassLoader(this.getClass.getClassLoader)
+
+    val jars = mtags.classpath.map(_.toUri.toURL).toArray
+    val classloader = new URLClassLoader(jars, parent)
+    val compilers = ServiceLoader
+      .load(classOf[PresentationCompiler], classloader)
+      .iterator()
+    if (compilers.hasNext) {
+      val classpath = deps.classpath ++ scalaLibrary
+      val argsfile = targetroot.resolve("javacopts.txt")
+      Files.createDirectories(argsfile.getParent)
+      Files.write(
+        argsfile,
+        List("-classpath", classpath.mkString(File.pathSeparator)).asJava,
+        StandardOpenOption.CREATE,
+        StandardOpenOption.TRUNCATE_EXISTING
+      )
+      val compiler = compilers
+        .next()
+        .newInstance("lsif-java", classpath.asJava, List[String]().asJava)
+      try {
+        fn(compiler)
+      } finally {
+        compiler.shutdown()
+      }
+    } else {
+      throw new IllegalArgumentException(
+        s"failed to load mtags presentation compiler for Scala version $scalaVersion"
+      )
     }
+  }
+
+  private def compileJavaFiles(
+      tmp: Path,
+      deps: Dependencies,
+      config: Config,
+      allJavaFiles: List[Path]
+  ): Try[Unit] = {
+    val (moduleInfos, javaFiles) = allJavaFiles
+      .partition(_.endsWith(moduleInfo))
+    if (javaFiles.isEmpty)
+      return Success(())
+    val semanticdbJar = Embedded.semanticdbJar(tmp)
+    val coursier = Embedded.coursier(tmp)
+    val actualClasspath = deps.classpath :+ semanticdbJar
+    val argsfile = targetroot.resolve("javacopts.txt")
     val arguments = ListBuffer.empty[String]
     arguments += "-encoding"
     arguments += "utf8"
     arguments += "-nowarn"
     arguments += "-d"
-    arguments += generatedDir("d")
+    arguments += generatedDir(tmp, "d")
     arguments += "-s"
-    arguments += generatedDir("s")
+    arguments += generatedDir(tmp, "s")
     arguments += "-h"
-    arguments += generatedDir("h")
+    arguments += generatedDir(tmp, "h")
     arguments += "-classpath"
     arguments += actualClasspath.mkString(File.pathSeparator)
     arguments +=
@@ -142,7 +292,7 @@ class LsifBuildTool(index: IndexCommand) extends BuildTool("LSIF", index) {
       arguments += "--module-source-path"
       arguments += sourceroot.toString
     } else {
-      arguments ++= javaFiles
+      arguments ++= javaFiles.map(_.toString)
     }
     val quotedArguments = arguments.map(a => "\"" + a + "\"")
     Files.write(argsfile, quotedArguments.asJava)
@@ -169,37 +319,18 @@ class LsifBuildTool(index: IndexCommand) extends BuildTool("LSIF", index) {
         cwd = os.Path(sourceroot),
         check = false
       )
-    if (index.cleanup) {
-      Files.walkFileTree(tmp, new DeleteVisitor)
-    }
-    val isSemanticdbGenerated = Files
-      .isDirectory(targetroot.resolve("META-INF"))
-    if (result.exitCode != 0 && !isSemanticdbGenerated) {
-      result
-    } else {
-      if (isSemanticdbGenerated) {
-        index
-          .app
-          .reporter
-          .info(
-            "Some SemanticDB files got generated even if there were compile errors. " +
-              "In most cases, this means that lsif-java managed to index everything " +
-              "except the locations that had compile errors and you can ignore the compile errors."
-          )
-      }
-      CommandResult(0, Nil)
-    }
+    if (result.exitCode == 0)
+      Success(())
+    else
+      Failure(SubprocessException(result))
   }
 
   private def clean(): Unit = {
     Files.walkFileTree(targetroot, new DeleteVisitor)
   }
 
-  private val moduleInfo = Paths.get("module-info.java")
-
   /** Recursively collects all Java files in the working directory */
-  private def collectAllJavaFiles(dir: Path): List[Path] = {
-    val javaPattern = FileSystems.getDefault.getPathMatcher("glob:**.java")
+  private def collectAllSourceFiles(dir: Path): List[Path] = {
     val buf = ListBuffer.empty[Path]
     Files.walkFileTree(
       dir,
@@ -217,7 +348,7 @@ class LsifBuildTool(index: IndexCommand) extends BuildTool("LSIF", index) {
             file: Path,
             attrs: BasicFileAttributes
         ): FileVisitResult = {
-          if (javaPattern.matches(file)) {
+          if (allPatterns.matches(file)) {
             buf += file
           }
           FileVisitResult.CONTINUE
@@ -231,6 +362,10 @@ class LsifBuildTool(index: IndexCommand) extends BuildTool("LSIF", index) {
     buf.toList
   }
 
+  private def generatedDir(tmp: Path, name: String): String = {
+    Files.createDirectory(tmp.resolve(name)).toString()
+  }
+
   /**
    * Gets parsed from "junit:junit:4.13.1" strings inside lsif-java.json files.
    */
diff --git a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaCompilerClassLoader.scala b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaCompilerClassLoader.scala
new file mode 100644
index 000000000..3c269373e
--- /dev/null
+++ b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaCompilerClassLoader.scala
@@ -0,0 +1,24 @@
+package com.sourcegraph.lsif_java.buildtools
+// Copied from: https://github.com/scalameta/metals/blob/3c83447ec658f87fdccbfb3f0a39fca1cec4ef6e/metals/src/main/scala/scala/meta/internal/metals/PresentationCompilerClassLoader.scala
+
+/**
+ * ClassLoader that is used to reflectively invoke the Scala compiler.
+ *
+ * The Scala compiler is compiled against the exact Scala versions of the
+ * compiler while lsif-java is only compiled with Scala 2.13. In order to
+ * communicate between lsif-java and multiple versions of the compiler, this
+ * classloader shares a subset of Java classes that appear in method signatures
+ * of the `scala.meta.pc.PresentationCompiler` class.
+ */
+class ScalaCompilerClassLoader(parent: ClassLoader) extends ClassLoader(null) {
+  override def findClass(name: String): Class[_] = {
+    val isShared =
+      name.startsWith("org.eclipse.lsp4j") || name.startsWith("javax.") ||
+        name.startsWith("com.google.gson") || name.startsWith("scala.meta.pc")
+    if (isShared) {
+      parent.loadClass(name)
+    } else {
+      throw new ClassNotFoundException(name)
+    }
+  }
+}
diff --git a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaVersion.scala b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaVersion.scala
new file mode 100644
index 000000000..578da46a2
--- /dev/null
+++ b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/ScalaVersion.scala
@@ -0,0 +1,53 @@
+package com.sourcegraph.lsif_java.buildtools
+
+import java.nio.file.Path
+
+import com.sourcegraph.lsif_java.BuildInfo
+
+object ScalaVersion {
+
+  /**
+   * Returns a best-effort guess for which Scala version to compile with the
+   * given jar filename.
+   *
+   * The implementation of this method may seem hacky but it's the best approach
+   * I can think of that solves this problem with the given constraints:
+   *
+   *   - We can't assume scala-library.jar is on the classpath because Scala
+   *     libraries like `com.lihaoyi:geny` don't include an explicit dependency
+   *     on scala-library. See https://github.com/com-lihaoyi/geny/issues/32
+   *   - We want to support Scala 3, which uses the same scala-library as Scala
+   *     2.13.
+   *   - We should only infer Scala versions that are supported by the
+   *     `org.scalameta:mtags` module, which we use to compile SemanticDB files.
+   *     Currently, mtags supports the latest patch releases of Scala 2.11,
+   *     2.12, 2.13 and Scala 3.
+   */
+  def inferFromJar(jar: Path): Option[String] = {
+    val Scala3 = ".*_3\\b.*".r
+    val Scala211 = ".*_2.11\\b.*".r
+    val Scala212 = ".*_2.12\\b.*".r
+    val Scala213 = ".*_2.13\\b.*".r
+    // The official Scala 2 distribution doesn't use the standard _2.N suffix
+    // So we add a special case for scala-{compiler,reflect,library} and scalap.
+    val ScalaOfficial =
+      ".*scala(p|-compiler|-reflect|-library)?-2.([^\\.]+).*.jar".r
+    Option(jar.getFileName.toString).collect {
+      case Scala3() =>
+        BuildInfo.scala3
+      case Scala211() =>
+        BuildInfo.scala211
+      case Scala212() =>
+        BuildInfo.scala212
+      case Scala213() =>
+        BuildInfo.scala213
+      case ScalaOfficial(_, "11") =>
+        BuildInfo.scala211
+      case ScalaOfficial(_, "12") =>
+        BuildInfo.scala212
+      case ScalaOfficial(_, "13") =>
+        BuildInfo.scala213
+    }
+  }
+
+}
diff --git a/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/SignatureFormatter.java b/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/SignatureFormatter.java
index 80906b2a2..45448cfa0 100644
--- a/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/SignatureFormatter.java
+++ b/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/SignatureFormatter.java
@@ -4,9 +4,8 @@
 import com.sourcegraph.semanticdb_javac.Semanticdb.*;
 
 import com.sourcegraph.semanticdb_javac.SemanticdbSymbols;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
+
+import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
@@ -14,20 +13,42 @@
 
 public class SignatureFormatter {
   private static final Type OBJECT_TYPE_REF = typeRef("java/lang/Object#");
+  private static final Type PRODUCT_TYPE_REF = typeRef("scala/Product#");
+  private static final Type SCALA_SERIALIZABLE_TYPE_REF = typeRef("scala/package.Serializable#");
+  private static final Type JAVA_SERIALIZABLE_TYPE_REF = typeRef("java/util/Serializable#");
+  private static final Type SCALA_ANY_TYPE_REF = typeRef("scala/Any#");
+  private static final Type SCALA_ANYREF_TYPE_REF = typeRef("scala/AnyRef#");
 
   private static final Type WILDCARD_TYPE_REF = typeRef("local_wildcard");
 
+  private static final Type NOTHING_SYMBOL = typeRef("scala/Nothing#");
+  private static final String FUNCTION_SYMBOL_PREFIX = "scala/Function";
+  private static final String TUPLE_SYMBOL_PREFIX = "scala/Tuple";
   private static final String ARRAY_SYMBOL = "scala/Array#";
   private static final String ENUM_SYMBOL = "java/lang/Enum#";
   private static final String ANNOTATION_SYMBOL = "java/lang/annotation/Annotation#";
+  private static final Set<Type> REDUNDANT_CLASS_PARENTS = new HashSet<>();
+  private static final Set<Type> CASE_CLASS_PARENTS = new HashSet<>();
+
+  {
+    REDUNDANT_CLASS_PARENTS.add(OBJECT_TYPE_REF);
+    REDUNDANT_CLASS_PARENTS.add(SCALA_ANY_TYPE_REF);
+    REDUNDANT_CLASS_PARENTS.add(SCALA_ANYREF_TYPE_REF);
+
+    CASE_CLASS_PARENTS.add(PRODUCT_TYPE_REF);
+    CASE_CLASS_PARENTS.add(SCALA_SERIALIZABLE_TYPE_REF);
+    CASE_CLASS_PARENTS.add(JAVA_SERIALIZABLE_TYPE_REF);
+  }
 
   private final StringBuilder s = new StringBuilder();
   private final SymbolInformation symbolInformation;
   private final Symtab symtab;
+  private final boolean isScala;
 
   public SignatureFormatter(SymbolInformation symbolInformation, Symtab symtab) {
     this.symbolInformation = symbolInformation;
     this.symtab = symtab;
+    this.isScala = symbolInformation.getLanguage() == Language.SCALA;
   }
 
   public String formatSymbol() {
@@ -41,7 +62,6 @@ public String formatSymbol() {
     } else if (signature.hasTypeSignature()) {
       formatTypeParameterSignature(signature.getTypeSignature());
     }
-
     return s.toString();
   }
 
@@ -73,28 +93,60 @@ private void formatClassSignature(ClassSignature classSignature) {
         }
         printKeyword("interface");
         break;
+      case OBJECT:
+        printKeyword("object");
+        break;
+      case TRAIT:
+        printKeyword("trait");
+        break;
+      case PACKAGE_OBJECT:
+        printKeyword("package object");
+        break;
+      default:
+        break;
     }
     s.append(symbolInformation.getDisplayName());
+    if (symbolInformation.getKind() == SymbolInformation.Kind.CLASS && has(Property.CASE)) {
+      primaryConstructor(classSignature)
+          .ifPresent(
+              constructorSignature ->
+                  formatScalaParameterList(constructorSignature.getParameterListsList()));
+    }
 
     List<SymbolInformation> typeParameters = getSymlinks(classSignature.getTypeParameters());
     if (!typeParameters.isEmpty()) {
       s.append(
           typeParameters.stream()
               .map(this::formatTypeParameter)
-              .collect(Collectors.joining(", ", "<", ">")));
+              .collect(Collectors.joining(", ", isScala ? "[" : "<", isScala ? "]" : ">")));
     }
 
-    boolean hasSuperClass = !classSignature.getParentsList().contains(OBJECT_TYPE_REF);
+    boolean hasNonRedundantParent =
+        classSignature.getParentsList().size() > 0
+            && !REDUNDANT_CLASS_PARENTS.contains(classSignature.getParentsList().get(0));
+
+    boolean isCaseClass =
+        isScala
+            && symbolInformation.getKind() == SymbolInformation.Kind.CLASS
+            && has(Property.CASE);
 
     List<Type> nonSyntheticParents =
         classSignature.getParentsList().stream()
-            .filter(parent -> !parent.equals(OBJECT_TYPE_REF))
+            .filter(parent -> !REDUNDANT_CLASS_PARENTS.contains(parent))
             .filter(parent -> !parent.getTypeRef().getSymbol().equals(ENUM_SYMBOL))
+            .filter(parent -> isCaseClass && !CASE_CLASS_PARENTS.contains(parent))
             .filter(parent -> !parent.getTypeRef().getSymbol().equals(ANNOTATION_SYMBOL))
             .collect(Collectors.toList());
 
     if (nonSyntheticParents.isEmpty()) return;
 
+    if (isScala) {
+      printKeyword(" extends");
+      s.append(
+          nonSyntheticParents.stream().map(this::formatType).collect(Collectors.joining(" with ")));
+      return;
+    }
+
     // Determine which parents from ClassSignature.parents are classes or interfaces so we know to
     // use
     // 'extends' or 'implements'.
@@ -114,7 +166,7 @@ private void formatClassSignature(ClassSignature classSignature) {
     switch (symbolInformation.getKind()) {
       case CLASS:
         // if no superclass or is an enum, every non synthetic parent is an interface
-        if (isEnum || !hasSuperClass) {
+        if (isEnum || !hasNonRedundantParent) {
           printKeyword(" implements");
 
           String superInterfaces =
@@ -147,9 +199,13 @@ private void formatClassSignature(ClassSignature classSignature) {
   }
 
   private void formatMethodSignature(MethodSignature methodSignature) {
+    if (isScala) {
+      formatScalaMethodSignature(methodSignature);
+      return;
+    }
+
     printKeywordln(formatAnnotations());
     printKeyword(formatAccess());
-
     printKeyword(formatModifiers());
 
     List<SymbolInformation> typeParameters = getSymlinks(methodSignature.getTypeParameters());
@@ -160,25 +216,21 @@ private void formatMethodSignature(MethodSignature methodSignature) {
               .collect(Collectors.joining(", ", "<", ">")));
     }
 
-    if (symbolInformation.getKind() != SymbolInformation.Kind.CONSTRUCTOR) {
-      printKeyword(formatType(methodSignature.getReturnType()));
-      s.append(symbolInformation.getDisplayName());
-    } else {
+    if (symbolInformation.getKind() == SymbolInformation.Kind.CONSTRUCTOR) {
       String owner = SymbolDescriptor.parseFromSymbol(symbolInformation.getSymbol()).owner;
       // Fix for https://github.com/sourcegraph/lsif-java/issues/150
       if (!owner.equals(SemanticdbSymbols.NONE)) {
         s.append(SymbolDescriptor.parseFromSymbol(owner).descriptor.name);
       }
+    } else {
+      printKeyword(formatType(methodSignature.getReturnType()));
+      s.append(symbolInformation.getDisplayName());
     }
 
     s.append(
         methodSignature.getParameterListsList().stream()
             .flatMap((params) -> getSymlinks(params).stream())
-            .map(
-                symInfo ->
-                    formatType(symInfo.getSignature().getValueSignature().getTpe())
-                        + " "
-                        + symInfo.getDisplayName())
+            .map(this::formatTermParameter)
             .collect(Collectors.joining(", ", "(", ")")));
 
     if (!methodSignature.getThrowsList().isEmpty()) {
@@ -190,6 +242,65 @@ private void formatMethodSignature(MethodSignature methodSignature) {
     }
   }
 
+  private String formatTermParameter(SymbolInformation info) {
+    if (isScala) {
+      return info.getDisplayName()
+          + ": "
+          + formatType(info.getSignature().getValueSignature().getTpe());
+    }
+    return formatType(info.getSignature().getValueSignature().getTpe())
+        + " "
+        + info.getDisplayName();
+  }
+
+  private void formatScalaMethodSignature(MethodSignature methodSignature) {
+    printKeywordln(formatAnnotations());
+    printKeyword(formatAccess());
+    printKeyword(formatModifiers());
+    if (has(Property.VAL)) {
+      printKeyword("val");
+    } else if (has(Property.VAR)) {
+      printKeyword("var");
+    } else {
+      printKeyword("def");
+    }
+    s.append(
+        symbolInformation.getKind() == SymbolInformation.Kind.CONSTRUCTOR
+            ? "this"
+            : symbolInformation.getDisplayName());
+    formatScalaParameterList(methodSignature.getParameterListsList());
+    printKeyword(":");
+    s.append(this.formatType(methodSignature.getReturnType()));
+  }
+
+  private Optional<MethodSignature> primaryConstructor(ClassSignature classSignature) {
+    Symtab scopeSymtab = symtab.withHardlinks(classSignature.getDeclarations());
+    int n = classSignature.getDeclarations().getSymlinksCount();
+    for (int i = 0; i < n; i++) {
+      String symlink = classSignature.getDeclarations().getSymlinks(i);
+      SymbolInformation info = scopeSymtab.symbols.get(symlink);
+      if (info != null
+          && info.getKind() == SymbolInformation.Kind.CONSTRUCTOR
+          && has(Property.PRIMARY, info)
+          && info.hasSignature()
+          && info.getSignature().hasMethodSignature()) {
+        return Optional.of(info.getSignature().getMethodSignature());
+      }
+    }
+    return Optional.empty();
+  }
+
+  private void formatScalaParameterList(List<Scope> parameterList) {
+    for (Scope scope : parameterList) {
+      List<SymbolInformation> infos =
+          scope.getHardlinksCount() > 0 ? scope.getHardlinksList() : getSymlinks(scope);
+      s.append(
+          infos.stream()
+              .map(this::formatTermParameter)
+              .collect(Collectors.joining(", ", "(", ")")));
+    }
+  }
+
   private void formatValueSignature(ValueSignature valueSignature) {
     printKeywordln(formatAnnotations());
     if (isEnumConstant()) {
@@ -207,19 +318,30 @@ private void formatValueSignature(ValueSignature valueSignature) {
     } else {
       printKeyword(formatAccess());
       printKeyword(formatModifiers());
-      printKeyword(formatType(valueSignature.getTpe()));
-      s.append(symbolInformation.getDisplayName());
+      if (isScala) {
+        s.append(symbolInformation.getDisplayName());
+        printKeyword(":");
+        printKeyword(formatType(valueSignature.getTpe()));
+      } else {
+        printKeyword(formatType(valueSignature.getTpe()));
+        s.append(symbolInformation.getDisplayName());
+      }
     }
   }
 
   private void formatTypeParameterSignature(TypeSignature typeSignature) {
+    if (isScala && symbolInformation.getKind() == SymbolInformation.Kind.TYPE) {
+      printKeyword("type");
+    }
     s.append(symbolInformation.getDisplayName());
-    if (typeSignature.hasLowerBound()) {
-      printKeyword(" super");
+    if (typeSignature.hasLowerBound()
+        && (!isScala || !typeSignature.getLowerBound().equals(NOTHING_SYMBOL))) {
+      printKeyword(isScala ? " >:" : " super");
       s.append(formatType(typeSignature.getLowerBound()));
-    } else if (typeSignature.hasUpperBound()
-        && !typeSignature.getUpperBound().equals(OBJECT_TYPE_REF)) {
-      printKeyword(" extends");
+    }
+    if (typeSignature.hasUpperBound()
+        && !typeSignature.getUpperBound().equals(isScala ? SCALA_ANY_TYPE_REF : OBJECT_TYPE_REF)) {
+      printKeyword(isScala ? " <:" : " extends");
       s.append(formatType(typeSignature.getUpperBound()));
     }
   }
@@ -246,7 +368,9 @@ private String formatTypeParameter(SymbolInformation typeInfo) {
   private String formatTypeArguments(List<Type> typeArguments) {
     if (typeArguments.isEmpty()) return "";
 
-    return typeArguments.stream().map(this::formatType).collect(Collectors.joining(", ", "<", ">"));
+    return typeArguments.stream()
+        .map(this::formatType)
+        .collect(Collectors.joining(", ", isScala ? "[" : "<", isScala ? "]" : ">"));
   }
 
   private String formatAnnotations() {
@@ -341,7 +465,7 @@ private String formatConstant(Constant constant) {
     } else if (constant.hasShortConstant()) {
       return Integer.toString(constant.getShortConstant().getValue());
     } else if (constant.hasCharConstant()) {
-      return String.valueOf((char) constant.getCharConstant().getValue());
+      return String.format("'%s'", (char) constant.getCharConstant().getValue());
     } else if (constant.hasIntConstant()) {
       return Integer.toString(constant.getIntConstant().getValue());
     } else if (constant.hasLongConstant()) {
@@ -407,17 +531,83 @@ private String formatType(Type type) {
     if (type.hasTypeRef()) {
       TypeRef typeRef = type.getTypeRef();
       if (typeRef.getSymbol().equals(ARRAY_SYMBOL)) {
-        b.append(formatType(typeRef.getTypeArguments(0)));
-        b.append("[]");
+        if (isScala) {
+          b.append("Array[");
+          b.append(formatType(typeRef.getTypeArguments(0)));
+          b.append("]");
+        } else {
+          b.append(formatType(typeRef.getTypeArguments(0)));
+          b.append("[]");
+        }
+      } else if (isScala && typeRef.getSymbol().startsWith(FUNCTION_SYMBOL_PREFIX)) {
+        int n = typeRef.getTypeArgumentsCount() - 1;
+        if (n == 0) {
+          // Special-case for Function1[A, B]: don't wrap `A`  in parenthesis like this `(A) => B`
+          s.append(formatType(typeRef.getTypeArguments(0)));
+        } else {
+          b.append(
+              typeRef.getTypeArgumentsList().stream()
+                  .limit(n)
+                  .map(this::formatType)
+                  .collect(Collectors.joining(", ", "(", ")")));
+        }
+        b.append(" => ");
+        b.append(formatType(typeRef.getTypeArguments(n)));
+      } else if (isScala && typeRef.getSymbol().startsWith(TUPLE_SYMBOL_PREFIX)) {
+        b.append(
+            typeRef.getTypeArgumentsList().stream()
+                .map(this::formatType)
+                .collect(Collectors.joining(", ", "(", ")")));
       } else {
         b.append(symbolDisplayName(typeRef.getSymbol()));
         b.append(formatTypeArguments(typeRef.getTypeArgumentsList()));
       }
+    } else if (type.hasSingleType()) {
+      SingleType tpe = type.getSingleType();
+      if (tpe.hasPrefix()) {
+        b.append(formatType(tpe.getPrefix()));
+      }
+      SymbolInformation info = symtab.symbols.get(tpe.getSymbol());
+      if (info != null) {
+        b.append(info.getDisplayName()).append(".type");
+      }
+    } else if (type.hasThisType()) {
+      b.append("this.type");
+    } else if (type.hasSuperType()) {
+      SuperType tpe = type.getSuperType();
+      if (tpe.hasPrefix()) {
+        b.append(formatType(tpe.getPrefix())).append(".");
+      }
+      b.append("super");
+    } else if (type.hasConstantType()) {
+      b.append(this.formatConstant(type.getConstantType().getConstant()));
     } else if (type.hasIntersectionType()) {
       b.append(
           type.getIntersectionType().getTypesList().stream()
               .map(this::formatType)
-              .collect(Collectors.joining(" & ")));
+              .collect(Collectors.joining(isScala ? " with " : " & ")));
+    } else if (type.hasUnionType()) {
+      b.append(
+          type.getIntersectionType().getTypesList().stream()
+              .map(this::formatType)
+              .collect(Collectors.joining(" | ")));
+    } else if (type.hasStructuralType()) {
+      StructuralType tpe = type.getStructuralType();
+      int n = tpe.getDeclarations().getHardlinksCount();
+      if (n == 0) {
+        b.append(" {}");
+      } else {
+        b.append(formatType(tpe.getTpe())).append(" {");
+        Symtab hardlinkSymtab = symtab.withHardlinks(tpe.getDeclarations());
+        for (int i = 0; i < n; i++) {
+          SymbolInformation info = tpe.getDeclarations().getHardlinks(i);
+          if (i > 0) {
+            b.append(";");
+          }
+          b.append(" ").append(new SignatureFormatter(info, hardlinkSymtab).formatSymbol());
+        }
+        b.append(" }");
+      }
     } else if (type.hasExistentialType()) {
       AtomicInteger hardlinkStep = new AtomicInteger();
       TypeRef typeRef = type.getExistentialType().getTpe().getTypeRef();
@@ -439,19 +629,32 @@ private String formatType(Type type) {
                     // else for symlink we can use the usual path
                     return formatType(typeArg);
                   })
-              .collect(Collectors.joining(", ", "<", ">")));
+              .collect(Collectors.joining(", ", isScala ? "[" : "<", isScala ? "[" : ">")));
+    } else if (type.hasByNameType()) {
+      b.append("=> ").append(formatType(type.getByNameType().getTpe()));
+    } else if (type.hasRepeatedType()) {
+      b.append(formatType(type.getRepeatedType().getTpe())).append("*");
     }
 
-    return b.toString();
+    return b.toString().trim();
   }
 
   private String formatAccess() {
-    if (symbolInformation.getAccess().hasPrivateAccess()) {
+    Access access = symbolInformation.getAccess();
+    if (access.hasPrivateAccess()) {
       return "private";
-    } else if (symbolInformation.getAccess().hasPublicAccess()) {
+    } else if (!isScala && access.hasPublicAccess()) {
       return "public";
-    } else if (symbolInformation.getAccess().hasProtectedAccess()) {
+    } else if (access.hasProtectedAccess()) {
       return "protected";
+    } else if (isScala && access.hasPrivateThisAccess()) {
+      return "private[this]";
+    } else if (isScala && access.hasPrivateWithinAccess()) {
+      String name =
+          SymbolDescriptor.parseFromSymbol(access.getPrivateWithinAccess().getSymbol())
+              .descriptor
+              .name;
+      return String.format("protected[%s]", name);
     }
     return "";
   }
@@ -459,10 +662,23 @@ private String formatAccess() {
   // https://checkstyle.sourceforge.io/config_modifier.html#ModifierOrder
   private String formatModifiers() {
     ArrayList<String> modifiers = new ArrayList<>();
-    if (has(Property.ABSTRACT)) modifiers.add("abstract");
+    if (has(Property.ABSTRACT)) {
+      if (isScala && symbolInformation.getKind() != SymbolInformation.Kind.CLASS) {
+      } else {
+        modifiers.add("abstract");
+      }
+    }
     if (has(Property.DEFAULT)) modifiers.add("default");
     if (has(Property.STATIC)) modifiers.add("static");
-    if (has(Property.FINAL)) modifiers.add("final");
+    if (has(Property.FINAL)) {
+      if (symbolInformation.getKind() != SymbolInformation.Kind.OBJECT
+          && symbolInformation.getKind() != SymbolInformation.Kind.PACKAGE_OBJECT) {
+        modifiers.add("final");
+      }
+    }
+    if (has(Property.IMPLICIT)) modifiers.add("implicit");
+    if (has(Property.SEALED)) modifiers.add("sealed");
+    if (has(Property.CASE)) modifiers.add("case");
     return String.join(" ", modifiers);
   }
 
@@ -507,6 +723,20 @@ private boolean has(Property property) {
    * we check for those first before attempting to decode a SemanticDB symbol.
    */
   public String symbolDisplayName(String symbol) {
+    if (isScala) {
+      return symbolScalaDisplayName(symbol);
+    }
+    return symbolJavaDisplayName(symbol);
+  }
+
+  private String symbolScalaDisplayName(String symbol) {
+    if ("local_wildcard".equals(symbol)) {
+      return "*";
+    }
+    return SymbolDescriptor.parseFromSymbol(symbol).descriptor.name;
+  }
+
+  private String symbolJavaDisplayName(String symbol) {
     switch (symbol) {
       case "local_wildcard":
         return "?";
diff --git a/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/Symtab.java b/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/Symtab.java
index 6d3253e04..f066d2dde 100644
--- a/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/Symtab.java
+++ b/lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/Symtab.java
@@ -12,4 +12,14 @@ public Symtab(Semanticdb.TextDocument document) {
       symbols.put(symbolInformation.getSymbol(), symbolInformation);
     }
   }
+
+  public Symtab withHardlinks(Semanticdb.Scope scope) {
+    Symtab hardlinkSymtab = new Symtab(Semanticdb.TextDocument.getDefaultInstance());
+    hardlinkSymtab.symbols.putAll(this.symbols);
+    for (int i = 0; i < scope.getHardlinksCount(); i++) {
+      Semanticdb.SymbolInformation info = scope.getHardlinks(i);
+      hardlinkSymtab.symbols.put(info.getSymbol(), info);
+    }
+    return hardlinkSymtab;
+  }
 }
diff --git a/semanticdb-java/src/main/protobuf/semanticdb.proto b/semanticdb-java/src/main/protobuf/semanticdb.proto
index c1f60663e..80b71ad9b 100644
--- a/semanticdb-java/src/main/protobuf/semanticdb.proto
+++ b/semanticdb-java/src/main/protobuf/semanticdb.proto
@@ -81,11 +81,16 @@ message SymbolInformation {
     FIELD = 20;
     METHOD = 3;
     CONSTRUCTOR = 21;
+    MACRO = 6;
     TYPE = 7;
     PARAMETER = 8;
+    SELF_PARAMETER = 17;
     TYPE_PARAMETER = 9;
+    OBJECT = 10;
     PACKAGE = 11;
+    PACKAGE_OBJECT = 12;
     CLASS = 13;
+    TRAIT = 14;
     INTERFACE = 18;
   }
   enum Property {
@@ -95,7 +100,15 @@ message SymbolInformation {
     ABSTRACT = 0x4;
     FINAL = 0x8;
     SEALED = 0x10;
+    IMPLICIT = 0x20;
+    LAZY = 0x40;
+    CASE = 0x80;
+    COVARIANT = 0x100;
+    CONTRAVARIANT = 0x200;
+    VAL = 0x400;
+    VAR = 0x800;
     STATIC = 0x1000;
+    PRIMARY = 0x2000;
     ENUM = 0x4000;
     DEFAULT = 0x8000;
   }
@@ -117,6 +130,7 @@ message SymbolInformation {
 message Access {
   oneof sealed_value {
     PrivateAccess private_access = 1;
+    PrivateThisAccess private_this_access = 2;
     PrivateWithinAccess private_within_access = 3;
     ProtectedAccess protected_access = 4;
     PublicAccess public_access = 7;
@@ -129,6 +143,9 @@ message PrivateWithinAccess {
   string symbol = 1;
 }
 
+message PrivateThisAccess {
+}
+
 message ProtectedAccess {}
 
 message PublicAccess {}
@@ -165,26 +182,91 @@ message Type {
   reserved 1, 3, 4, 5, 6, 11, 12, 15, 16;
   oneof sealed_value {
     TypeRef type_ref = 2;
-    ExistentialType existential_type = 9;
+    SingleType single_type = 20;
+    ThisType this_type = 21;
+    SuperType super_type = 22;
+    ConstantType constant_type = 23;
     IntersectionType intersection_type = 17;
+    UnionType union_type = 18;
+    WithType with_type = 19;
+    StructuralType structural_type = 7;
+    AnnotatedType annotated_type = 8;
+    ExistentialType existential_type = 9;
+    UniversalType universal_type = 10;
+    ByNameType by_name_type = 13;
+    RepeatedType repeated_type = 14;
   }
 }
 
+
 message TypeRef {
+  Type prefix = 1;
   string symbol = 2;
   repeated Type type_arguments = 3;
 }
 
+message SingleType {
+  Type prefix = 1;
+  string symbol = 2;
+}
+
+message ThisType {
+  string symbol = 1;
+}
+
+message SuperType {
+  Type prefix = 1;
+  string symbol = 2;
+}
+
+message ConstantType {
+  Constant constant = 1;
+}
+
 message IntersectionType {
   repeated Type types = 1;
 }
 
+message UnionType {
+  repeated Type types = 1;
+}
+
+message WithType {
+  repeated Type types = 1;
+}
+
+message StructuralType {
+  reserved 1, 2, 3;
+  Type tpe = 4;
+  Scope declarations = 5;
+}
+
+message AnnotatedType {
+  reserved 2;
+  repeated AnnotationTree annotations = 3;
+  Type tpe = 1;
+}
+
 message ExistentialType {
   reserved 2;
   Type tpe = 1;
   Scope declarations = 3;
 }
 
+message UniversalType {
+  reserved 1;
+  Scope type_parameters = 3;
+  Type tpe = 2;
+}
+
+message ByNameType {
+  Type tpe = 1;
+}
+
+message RepeatedType {
+  Type tpe = 1;
+}
+
 message Tree {
   oneof sealed_value {
     ApplyTree apply_tree = 1;
diff --git a/tests/benchmarks/src/main/scala/benchmarks/CompileBench.scala b/tests/benchmarks/src/main/scala/benchmarks/CompileBench.scala
index 89bd0fa32..49c887456 100644
--- a/tests/benchmarks/src/main/scala/benchmarks/CompileBench.scala
+++ b/tests/benchmarks/src/main/scala/benchmarks/CompileBench.scala
@@ -34,7 +34,13 @@ class CompileBench {
   def setup(): Unit = {
     tmp = Files.createTempDirectory("benchmarks")
     deps = Dependencies.resolveDependencies(List(libs(lib)))
-    compiler = new TestCompiler(deps.classpathSyntax, List.empty[String], tmp)
+    compiler =
+      new TestCompiler(
+        deps.classpathSyntax,
+        javacOptions = Nil,
+        scalacOptions = Nil,
+        targetroot = tmp
+      )
   }
 
   @TearDown()
diff --git a/tests/benchmarks/src/main/scala/benchmarks/LsifSemanticdbBench.scala b/tests/benchmarks/src/main/scala/benchmarks/LsifSemanticdbBench.scala
index d9cfca84a..4f5469afe 100644
--- a/tests/benchmarks/src/main/scala/benchmarks/LsifSemanticdbBench.scala
+++ b/tests/benchmarks/src/main/scala/benchmarks/LsifSemanticdbBench.scala
@@ -22,7 +22,12 @@ class LsifSemanticdbBench {
     deps = Dependencies
       .resolveDependencies(List("com.google.guava:guava:30.1-jre"))
     val compiler =
-      new TestCompiler(deps.classpathSyntax, List.empty[String], targetroot)
+      new TestCompiler(
+        deps.classpathSyntax,
+        javacOptions = Nil,
+        scalacOptions = Nil,
+        targetroot
+      )
     CompileBench.foreachSource(deps) { inputs =>
       compiler.compileSemanticdb(inputs).byteCode.length
     }
diff --git a/tests/buildTools/src/test/scala/tests/LsifBuildToolSuite.scala b/tests/buildTools/src/test/scala/tests/LsifBuildToolSuite.scala
index 504a35daa..90cf2d14a 100644
--- a/tests/buildTools/src/test/scala/tests/LsifBuildToolSuite.scala
+++ b/tests/buildTools/src/test/scala/tests/LsifBuildToolSuite.scala
@@ -1,5 +1,7 @@
 package tests
 
+import com.sourcegraph.lsif_java.{BuildInfo => V}
+
 class LsifBuildToolSuite extends BaseBuildToolSuite {
   checkBuild(
     "basic",
@@ -13,10 +15,45 @@ class LsifBuildToolSuite extends BaseBuildToolSuite {
        |package foo;
        |public class Example2 {}
        |""".stripMargin,
-    2,
+    expectedSemanticdbFiles = 2,
     expectedPackages =
       """|maven:junit:junit:4.13.1
          |maven:org.hamcrest:hamcrest-core:1.3
          |""".stripMargin
   )
+
+  case class ScalaCombination(
+      binaryVersion: String,
+      fullVersion: String,
+      standardLibraryVersion: String
+  )
+
+  List(
+    ScalaCombination("2.11", V.scala211, V.scala211),
+    ScalaCombination("2.12", V.scala212, V.scala212),
+    ScalaCombination("2.13", V.scala213, V.scala213),
+    ScalaCombination("3", V.scala3, V.scala213)
+  ).foreach { scala =>
+    checkBuild(
+      s"scala-${scala.fullVersion}",
+      s"""|/lsif-java.json
+          |{"dependencies": ["com.lihaoyi:geny_${scala.binaryVersion}:0.6.10"]}
+          |/foo/Example.scala
+          |package foo
+          |object Example {
+          |  val gen = geny.Generator(1, 2, 3)
+          |}
+          |/foo/JavaExample.java
+          |package foo;
+          |public class JavaExample {
+          |  public static final geny.Generator gen = geny.Generator(1, 2, 3);
+          |}
+          |""".stripMargin,
+      expectedSemanticdbFiles = 2,
+      expectedPackages =
+        s"""|maven:com.lihaoyi:geny_${scala.binaryVersion}:0.6.10
+            |maven:org.scala-lang:scala-library:${scala.standardLibraryVersion}
+            |""".stripMargin
+    )
+  }
 }
diff --git a/tests/minimized-scala/src/main/scala/minimized/MinimizedScalaSignatures.scala b/tests/minimized-scala/src/main/scala/minimized/MinimizedScalaSignatures.scala
new file mode 100644
index 000000000..7535692da
--- /dev/null
+++ b/tests/minimized-scala/src/main/scala/minimized/MinimizedScalaSignatures.scala
@@ -0,0 +1,48 @@
+package minimized
+
+// format: off
+
+
+case class MinimizedCaseClass(value: String) {
+  def this() = this("value")
+}
+
+trait MinimizedTrait[T] extends AutoCloseable {
+  def add(e: T): T
+  final def +(e: T): T = add(e)
+}
+
+class MinimizedScalaSignatures extends AutoCloseable with java.io.Serializable {
+  def close(): Unit = ()
+}
+
+object MinimizedScalaSignatures extends MinimizedScalaSignatures with Comparable[Int] {
+  @inline def annotation(x: Int): Int = x + 1
+  @deprecated("2020-07-27") def annotationMessage(x: Int): Int = x + 1
+  def compareTo(x: Int): Int = ???
+  def identity[T](e: T): T = e
+  def tuple(): (Int, String) = null
+  def function0(): () => String = null
+  def function1(): Int => String = null
+  def function2(): (Int, String) => Unit = null
+  def typeParameter(): Map[Int, String] = null
+  def termParameter(a: Int, b: String): String = null
+  def singletonType(e: String): e.type = e
+  def thisType(): this.type = this
+  def constantInt(): 1 = 1
+  def constantString(): "string" = "string"
+  def constantBoolean(): true = true
+  def constantFloat(): 1.2f = 1.2f
+  def constantChar(): 'a' = 'a'
+  def structuralType(): { val x: Int; def foo(a: Int): String } = null
+  def byNameType(a: => Int): Unit = ()
+  def repeatedType(a: Int*): Unit = ()
+
+  type TypeAlias = Int
+  type ParameterizedTypeAlias[A] = () => A
+  type ParameterizedTypeAlias2[A, B] = A => B
+  type TypeBound
+  type TypeUpperBound <: String
+  type TypeLowerBound >: CharSequence
+  type TypeLowerUpperBound >: String <: CharSequence 
+}
diff --git a/tests/snapshots/src/main/generated/BaseByteRenderer.scala b/tests/snapshots/src/main/generated/BaseByteRenderer.scala
new file mode 100644
index 000000000..4f6b15556
--- /dev/null
+++ b/tests/snapshots/src/main/generated/BaseByteRenderer.scala
@@ -0,0 +1,468 @@
+package ujson
+//      ^^^^^ definition ujson/
+import scala.annotation.switch
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                      ^^^^^^ reference scala/annotation/switch#
+import upickle.core.{ArrVisitor, ObjVisitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                               ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+
+/**
+  * A specialized JSON renderer that can render Bytes (Chars or Bytes) directly
+  * to a [[java.io.Writer]] or [[java.io.OutputStream]]
+  *
+  * Note that we use an internal `ByteBuilder` to buffer the output internally
+  * before sending it to [[out]] in batches. This lets us benefit from the high
+  * performance and minimal overhead of `ByteBuilder` in the fast path of
+  * pushing characters, and avoid the synchronization/polymorphism overhead of
+  * [[out]] on the fast path. Most [[out]]s would also have performance
+  * benefits from receiving data in batches, rather than elem by elem.
+  */
+class BaseByteRenderer[T <: upickle.core.ByteOps.Output]
+//    ^^^^^^^^^^^^^^^^ definition ujson/BaseByteRenderer#
+//                     ^ definition ujson/BaseByteRenderer#[T]
+//                          ^^^^^^^ reference upickle/
+//                                  ^^^^ reference upickle/core/
+//                                       ^^^^^^^ reference upickle/core/ByteOps.
+//                                               ^^^^^^ reference upickle/core/ByteOps.Output#
+                      (out: T,
+//                     ^^^ definition ujson/BaseByteRenderer#out.
+//                          ^ reference ujson/BaseByteRenderer#[T]
+                       indent: Int = -1,
+//                     ^^^^^^ definition ujson/BaseByteRenderer#indent.
+//                             ^^^ reference scala/Int#
+                       escapeUnicode: Boolean = false) extends JsVisitor[T, T]{
+//                     ^^^^^^^^^^^^^ definition ujson/BaseByteRenderer#escapeUnicode.
+//                                    ^^^^^^^ reference scala/Boolean#
+//                                                             ^^^^^^^^^ reference ujson/JsVisitor#
+//                                                                       ^ reference ujson/BaseByteRenderer#[T]
+//                                                                          ^ reference ujson/BaseByteRenderer#[T]
+//                                                                             reference java/lang/Object#`<init>`().
+  private[this] val elemBuilder = new upickle.core.ByteBuilder
+//                  ^^^^^^^^^^^ definition ujson/BaseByteRenderer#elemBuilder.
+//                                    ^^^^^^^ reference upickle/
+//                                            ^^^^ reference upickle/core/
+//                                                 ^^^^^^^^^^^ reference upickle/core/ByteBuilder#
+//                                                             reference upickle/core/ByteBuilder#`<init>`().
+  private[this] val unicodeCharBuilder = new upickle.core.CharBuilder()
+//                  ^^^^^^^^^^^^^^^^^^ definition ujson/BaseByteRenderer#unicodeCharBuilder.
+//                                           ^^^^^^^ reference upickle/
+//                                                   ^^^^ reference upickle/core/
+//                                                        ^^^^^^^^^^^ reference upickle/core/CharBuilder#
+//                                                                    reference upickle/core/CharBuilder#`<init>`().
+  def flushByteBuilder() = {
+//    ^^^^^^^^^^^^^^^^ definition ujson/BaseByteRenderer#flushByteBuilder().
+    elemBuilder.writeOutToIfLongerThan(out, if (depth == 0) 0 else 1000)
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/ByteBuilder#writeOutToIfLongerThan().
+//                                     ^^^ reference ujson/BaseByteRenderer#out.
+//                                              ^^^^^ reference ujson/BaseByteRenderer#depth().
+//                                                    ^^ reference scala/Int#`==`(+3).
+  }
+
+  private[this] var depth: Int = 0
+//                  ^^^^^ definition ujson/BaseByteRenderer#depth().
+//                         ^^^ reference scala/Int#
+
+
+  private[this] var commaBuffered = false
+//                  ^^^^^^^^^^^^^ definition ujson/BaseByteRenderer#commaBuffered().
+
+  def flushBuffer() = {
+//    ^^^^^^^^^^^ definition ujson/BaseByteRenderer#flushBuffer().
+    if (commaBuffered) {
+//      ^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#commaBuffered().
+      commaBuffered = false
+//    ^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#commaBuffered().
+      elemBuilder.append(',')
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/ByteBuilder#append().
+      renderIndent()
+//    ^^^^^^^^^^^^ reference ujson/BaseByteRenderer#renderIndent().
+    }
+  }
+  def visitArray(length: Int, index: Int) = new ArrVisitor[T, T] {
+//    ^^^^^^^^^^ definition ujson/BaseByteRenderer#visitArray().
+//               ^^^^^^ definition ujson/BaseByteRenderer#visitArray().(length)
+//                       ^^^ reference scala/Int#
+//                            ^^^^^ definition ujson/BaseByteRenderer#visitArray().(index)
+//                                   ^^^ reference scala/Int#
+//                                              ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                                                         ^ reference ujson/BaseByteRenderer#[T]
+//                                                            ^ reference ujson/BaseByteRenderer#[T]
+//                                                                reference java/lang/Object#`<init>`().
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    elemBuilder.append('[')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^ reference upickle/core/ByteBuilder#append().
+
+    depth += 1
+//  ^^^^^ reference ujson/BaseByteRenderer#depth().
+//        ^^ reference scala/Int#`+`(+4).
+    renderIndent()
+//  ^^^^^^^^^^^^ reference ujson/BaseByteRenderer#renderIndent().
+    def subVisitor = BaseByteRenderer.this
+//      ^^^^^^^^^^ definition local0
+//                   ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#
+    def visitValue(v: T, index: Int): Unit = {
+//      ^^^^^^^^^^ definition local1
+//                 ^ definition local2
+//                    ^ reference ujson/BaseByteRenderer#[T]
+//                       ^^^^^ definition local3
+//                              ^^^ reference scala/Int#
+//                                    ^^^^ reference scala/Unit#
+      flushBuffer()
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+      commaBuffered = true
+//    ^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#commaBuffered().
+    }
+    def visitEnd(index: Int) = {
+//      ^^^^^^^^ definition local4
+//               ^^^^^ definition local5
+//                      ^^^ reference scala/Int#
+      commaBuffered = false
+//    ^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#commaBuffered().
+      depth -= 1
+//    ^^^^^ reference ujson/BaseByteRenderer#depth().
+//          ^^ reference scala/Int#`-`(+3).
+      renderIndent()
+//    ^^^^^^^^^^^^ reference ujson/BaseByteRenderer#renderIndent().
+      elemBuilder.append(']')
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/ByteBuilder#append().
+      flushByteBuilder()
+//    ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+      out
+//    ^^^ reference ujson/BaseByteRenderer#out.
+    }
+  }
+
+  def visitObject(length: Int, index: Int) = new ObjVisitor[T, T] {
+//    ^^^^^^^^^^^ definition ujson/BaseByteRenderer#visitObject().
+//                ^^^^^^ definition ujson/BaseByteRenderer#visitObject().(length)
+//                        ^^^ reference scala/Int#
+//                             ^^^^^ definition ujson/BaseByteRenderer#visitObject().(index)
+//                                    ^^^ reference scala/Int#
+//                                               ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                                          ^ reference ujson/BaseByteRenderer#[T]
+//                                                             ^ reference ujson/BaseByteRenderer#[T]
+//                                                                 reference java/lang/Object#`<init>`().
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    elemBuilder.append('{')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^ reference upickle/core/ByteBuilder#append().
+    depth += 1
+//  ^^^^^ reference ujson/BaseByteRenderer#depth().
+//        ^^ reference scala/Int#`+`(+4).
+    renderIndent()
+//  ^^^^^^^^^^^^ reference ujson/BaseByteRenderer#renderIndent().
+    def subVisitor = BaseByteRenderer.this
+//      ^^^^^^^^^^ definition local6
+//                   ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#
+    def visitKey(index: Int) = BaseByteRenderer.this
+//      ^^^^^^^^ definition local7
+//               ^^^^^ definition local8
+//                      ^^^ reference scala/Int#
+//                             ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#
+    def visitKeyValue(s: Any): Unit = {
+//      ^^^^^^^^^^^^^ definition local9
+//                    ^ definition local10
+//                       ^^^ reference scala/Any#
+//                             ^^^^ reference scala/Unit#
+      elemBuilder.append(':')
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/ByteBuilder#append().
+      if (indent != -1) elemBuilder.append(' ')
+//        ^^^^^^ reference ujson/BaseByteRenderer#indent.
+//               ^^ reference scala/Int#`!=`(+3).
+//                      ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                                  ^^^^^^ reference upickle/core/ByteBuilder#append().
+    }
+    def visitValue(v: T, index: Int): Unit = {
+//      ^^^^^^^^^^ definition local11
+//                 ^ definition local12
+//                    ^ reference ujson/BaseByteRenderer#[T]
+//                       ^^^^^ definition local13
+//                              ^^^ reference scala/Int#
+//                                    ^^^^ reference scala/Unit#
+      commaBuffered = true
+//    ^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#commaBuffered().
+    }
+    def visitEnd(index: Int) = {
+//      ^^^^^^^^ definition local14
+//               ^^^^^ definition local15
+//                      ^^^ reference scala/Int#
+      commaBuffered = false
+//    ^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#commaBuffered().
+      depth -= 1
+//    ^^^^^ reference ujson/BaseByteRenderer#depth().
+//          ^^ reference scala/Int#`-`(+3).
+      renderIndent()
+//    ^^^^^^^^^^^^ reference ujson/BaseByteRenderer#renderIndent().
+      elemBuilder.append('}')
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/ByteBuilder#append().
+      flushByteBuilder()
+//    ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+      out
+//    ^^^ reference ujson/BaseByteRenderer#out.
+    }
+  }
+
+  def visitNull(index: Int) = {
+//    ^^^^^^^^^ definition ujson/BaseByteRenderer#visitNull().
+//              ^^^^^ definition ujson/BaseByteRenderer#visitNull().(index)
+//                     ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    elemBuilder.ensureLength(4)
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#ensureLength().
+    elemBuilder.appendUnsafe('n')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('u')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('l')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('l')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    flushByteBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+    out
+//  ^^^ reference ujson/BaseByteRenderer#out.
+  }
+
+  def visitFalse(index: Int) = {
+//    ^^^^^^^^^^ definition ujson/BaseByteRenderer#visitFalse().
+//               ^^^^^ definition ujson/BaseByteRenderer#visitFalse().(index)
+//                      ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    elemBuilder.ensureLength(5)
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#ensureLength().
+    elemBuilder.appendUnsafe('f')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('a')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('l')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('s')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('e')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    flushByteBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+    out
+//  ^^^ reference ujson/BaseByteRenderer#out.
+  }
+
+  def visitTrue(index: Int) = {
+//    ^^^^^^^^^ definition ujson/BaseByteRenderer#visitTrue().
+//              ^^^^^ definition ujson/BaseByteRenderer#visitTrue().(index)
+//                     ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    elemBuilder.ensureLength(4)
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#ensureLength().
+    elemBuilder.appendUnsafe('t')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('r')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('u')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('e')
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+    flushByteBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+    out
+//  ^^^ reference ujson/BaseByteRenderer#out.
+  }
+
+  def visitFloat64StringParts(s: CharSequence, decIndex: Int, expIndex: Int, index: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/BaseByteRenderer#visitFloat64StringParts().
+//                            ^ definition ujson/BaseByteRenderer#visitFloat64StringParts().(s)
+//                               ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                             ^^^^^^^^ definition ujson/BaseByteRenderer#visitFloat64StringParts().(decIndex)
+//                                                       ^^^ reference scala/Int#
+//                                                            ^^^^^^^^ definition ujson/BaseByteRenderer#visitFloat64StringParts().(expIndex)
+//                                                                      ^^^ reference scala/Int#
+//                                                                           ^^^^^ definition ujson/BaseByteRenderer#visitFloat64StringParts().(index)
+//                                                                                  ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    elemBuilder.ensureLength(s.length())
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#ensureLength().
+//                           ^ reference ujson/BaseByteRenderer#visitFloat64StringParts().(s)
+//                             ^^^^^^ reference java/lang/CharSequence#length().
+    var i = 0
+//      ^ definition local16
+    val sLength = s.length
+//      ^^^^^^^ definition local17
+//                ^ reference ujson/BaseByteRenderer#visitFloat64StringParts().(s)
+//                  ^^^^^^ reference java/lang/CharSequence#length().
+    while(i < sLength){
+//        ^ reference local16
+//          ^ reference scala/Int#`<`(+3).
+//            ^^^^^^^ reference local17
+      elemBuilder.appendUnsafeC(s.charAt(i))
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                ^^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafeC().
+//                              ^ reference ujson/BaseByteRenderer#visitFloat64StringParts().(s)
+//                                ^^^^^^ reference java/lang/CharSequence#charAt().
+//                                       ^ reference local16
+      i += 1
+//    ^ reference local16
+//      ^^ reference scala/Int#`+`(+4).
+    }
+    flushByteBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+    out
+//  ^^^ reference ujson/BaseByteRenderer#out.
+  }
+
+  override def visitFloat64(d: Double, index: Int) = {
+//             ^^^^^^^^^^^^ definition ujson/BaseByteRenderer#visitFloat64().
+//                          ^ definition ujson/BaseByteRenderer#visitFloat64().(d)
+//                             ^^^^^^ reference scala/Double#
+//                                     ^^^^^ definition ujson/BaseByteRenderer#visitFloat64().(index)
+//                                            ^^^ reference scala/Int#
+    d match{
+//  ^ reference ujson/BaseByteRenderer#visitFloat64().(d)
+      case Double.PositiveInfinity => visitNonNullString("Infinity", -1)
+//         ^^^^^^ reference scala/Double.
+//                ^^^^^^^^^^^^^^^^ reference scala/Double.PositiveInfinity.
+//                                    ^^^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#visitNonNullString().
+      case Double.NegativeInfinity => visitNonNullString("-Infinity", -1)
+//         ^^^^^^ reference scala/Double.
+//                ^^^^^^^^^^^^^^^^ reference scala/Double.NegativeInfinity.
+//                                    ^^^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#visitNonNullString().
+      case d if java.lang.Double.isNaN(d) => visitNonNullString("NaN", -1)
+//         ^ definition local18
+//              ^^^^ reference java/
+//                   ^^^^ reference java/lang/
+//                        ^^^^^^ reference java/lang/Double#
+//                               ^^^^^ reference java/lang/Double#isNaN(+1).
+//                                     ^ reference local18
+//                                           ^^^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#visitNonNullString().
+      case d =>
+//         ^ definition local19
+        val i = d.toInt
+//          ^ definition local20
+//              ^ reference local19
+//                ^^^^^ reference scala/Double#toInt().
+        if (d == i) visitFloat64StringParts(i.toString, -1, -1, index)
+//          ^ reference local19
+//            ^^ reference scala/Double#`==`(+3).
+//               ^ reference local20
+//                  ^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#visitFloat64StringParts().
+//                                          ^ reference local20
+//                                            ^^^^^^^^ reference scala/Any#toString().
+//                                                              ^^^^^ reference ujson/BaseByteRenderer#visitFloat64().(index)
+        else super.visitFloat64(d, index)
+//                 ^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64().
+//                              ^ reference local19
+//                                 ^^^^^ reference ujson/BaseByteRenderer#visitFloat64().(index)
+        flushBuffer()
+//      ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    }
+    flushByteBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+    out
+//  ^^^ reference ujson/BaseByteRenderer#out.
+  }
+
+
+  def visitString(s: CharSequence, index: Int) = {
+//    ^^^^^^^^^^^ definition ujson/BaseByteRenderer#visitString().
+//                ^ definition ujson/BaseByteRenderer#visitString().(s)
+//                   ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                 ^^^^^ definition ujson/BaseByteRenderer#visitString().(index)
+//                                        ^^^ reference scala/Int#
+
+    if (s eq null) visitNull(index)
+//      ^ reference ujson/BaseByteRenderer#visitString().(s)
+//        ^^ reference java/lang/Object#eq().
+//                 ^^^^^^^^^ reference ujson/BaseByteRenderer#visitNull().
+//                           ^^^^^ reference ujson/BaseByteRenderer#visitString().(index)
+    else visitNonNullString(s, index)
+//       ^^^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#visitNonNullString().
+//                          ^ reference ujson/BaseByteRenderer#visitString().(s)
+//                             ^^^^^ reference ujson/BaseByteRenderer#visitString().(index)
+  }
+
+  def visitNonNullString(s: CharSequence, index: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/BaseByteRenderer#visitNonNullString().
+//                       ^ definition ujson/BaseByteRenderer#visitNonNullString().(s)
+//                          ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                        ^^^^^ definition ujson/BaseByteRenderer#visitNonNullString().(index)
+//                                               ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushBuffer().
+    upickle.core.RenderUtils.escapeByte(unicodeCharBuilder, elemBuilder, s, escapeUnicode)
+//  ^^^^^^^ reference upickle/
+//          ^^^^ reference upickle/core/
+//               ^^^^^^^^^^^ reference upickle/core/RenderUtils.
+//                           ^^^^^^^^^^ reference upickle/core/RenderUtils.escapeByte().
+//                                      ^^^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#unicodeCharBuilder.
+//                                                          ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                                                                       ^ reference ujson/BaseByteRenderer#visitNonNullString().(s)
+//                                                                          ^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#escapeUnicode.
+    flushByteBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#flushByteBuilder().
+    out
+//  ^^^ reference ujson/BaseByteRenderer#out.
+  }
+
+  final def renderIndent() = {
+//          ^^^^^^^^^^^^ definition ujson/BaseByteRenderer#renderIndent().
+    if (indent == -1) ()
+//      ^^^^^^ reference ujson/BaseByteRenderer#indent.
+//             ^^ reference scala/Int#`==`(+3).
+    else {
+      var i = indent * depth
+//        ^ definition local21
+//            ^^^^^^ reference ujson/BaseByteRenderer#indent.
+//                   ^ reference scala/Int#`*`(+3).
+//                     ^^^^^ reference ujson/BaseByteRenderer#depth().
+      elemBuilder.ensureLength(i + 1)
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#ensureLength().
+//                             ^ reference local21
+//                               ^ reference scala/Int#`+`(+4).
+      elemBuilder.appendUnsafe('\n')
+//    ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+      while(i > 0) {
+//          ^ reference local21
+//            ^ reference scala/Int#`>`(+3).
+        elemBuilder.appendUnsafe(' ')
+//      ^^^^^^^^^^^ reference ujson/BaseByteRenderer#elemBuilder.
+//                  ^^^^^^^^^^^^ reference upickle/core/ByteBuilder#appendUnsafe().
+        i -= 1
+//      ^ reference local21
+//        ^^ reference scala/Int#`-`(+3).
+      }
+    }
+  }
+}
diff --git a/tests/snapshots/src/main/generated/BaseCharRenderer.scala b/tests/snapshots/src/main/generated/BaseCharRenderer.scala
new file mode 100644
index 000000000..bf99637fe
--- /dev/null
+++ b/tests/snapshots/src/main/generated/BaseCharRenderer.scala
@@ -0,0 +1,468 @@
+package ujson
+//      ^^^^^ definition ujson/
+import scala.annotation.switch
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                      ^^^^^^ reference scala/annotation/switch#
+import upickle.core.{ArrVisitor, ObjVisitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                               ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+
+/**
+  * A specialized JSON renderer that can render Chars (Chars or Bytes) directly
+  * to a [[java.io.Writer]] or [[java.io.OutputStream]]
+  *
+  * Note that we use an internal `CharBuilder` to buffer the output internally
+  * before sending it to [[out]] in batches. This lets us benefit from the high
+  * performance and minimal overhead of `CharBuilder` in the fast path of
+  * pushing characters, and avoid the synchronization/polymorphism overhead of
+  * [[out]] on the fast path. Most [[out]]s would also have performance
+  * benefits from receiving data in batches, rather than elem by elem.
+  */
+class BaseCharRenderer[T <: upickle.core.CharOps.Output]
+//    ^^^^^^^^^^^^^^^^ definition ujson/BaseCharRenderer#
+//                     ^ definition ujson/BaseCharRenderer#[T]
+//                          ^^^^^^^ reference upickle/
+//                                  ^^^^ reference upickle/core/
+//                                       ^^^^^^^ reference upickle/core/CharOps.
+//                                               ^^^^^^ reference upickle/core/CharOps.Output#
+                      (out: T,
+//                     ^^^ definition ujson/BaseCharRenderer#out.
+//                          ^ reference ujson/BaseCharRenderer#[T]
+                       indent: Int = -1,
+//                     ^^^^^^ definition ujson/BaseCharRenderer#indent.
+//                             ^^^ reference scala/Int#
+                       escapeUnicode: Boolean = false) extends JsVisitor[T, T]{
+//                     ^^^^^^^^^^^^^ definition ujson/BaseCharRenderer#escapeUnicode.
+//                                    ^^^^^^^ reference scala/Boolean#
+//                                                             ^^^^^^^^^ reference ujson/JsVisitor#
+//                                                                       ^ reference ujson/BaseCharRenderer#[T]
+//                                                                          ^ reference ujson/BaseCharRenderer#[T]
+//                                                                             reference java/lang/Object#`<init>`().
+  private[this] val elemBuilder = new upickle.core.CharBuilder
+//                  ^^^^^^^^^^^ definition ujson/BaseCharRenderer#elemBuilder.
+//                                    ^^^^^^^ reference upickle/
+//                                            ^^^^ reference upickle/core/
+//                                                 ^^^^^^^^^^^ reference upickle/core/CharBuilder#
+//                                                             reference upickle/core/CharBuilder#`<init>`().
+  private[this] val unicodeCharBuilder = new upickle.core.CharBuilder()
+//                  ^^^^^^^^^^^^^^^^^^ definition ujson/BaseCharRenderer#unicodeCharBuilder.
+//                                           ^^^^^^^ reference upickle/
+//                                                   ^^^^ reference upickle/core/
+//                                                        ^^^^^^^^^^^ reference upickle/core/CharBuilder#
+//                                                                    reference upickle/core/CharBuilder#`<init>`().
+  def flushCharBuilder() = {
+//    ^^^^^^^^^^^^^^^^ definition ujson/BaseCharRenderer#flushCharBuilder().
+    elemBuilder.writeOutToIfLongerThan(out, if (depth == 0) 0 else 1000)
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/CharBuilder#writeOutToIfLongerThan().
+//                                     ^^^ reference ujson/BaseCharRenderer#out.
+//                                              ^^^^^ reference ujson/BaseCharRenderer#depth().
+//                                                    ^^ reference scala/Int#`==`(+3).
+  }
+
+  private[this] var depth: Int = 0
+//                  ^^^^^ definition ujson/BaseCharRenderer#depth().
+//                         ^^^ reference scala/Int#
+
+
+  private[this] var commaBuffered = false
+//                  ^^^^^^^^^^^^^ definition ujson/BaseCharRenderer#commaBuffered().
+
+  def flushBuffer() = {
+//    ^^^^^^^^^^^ definition ujson/BaseCharRenderer#flushBuffer().
+    if (commaBuffered) {
+//      ^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#commaBuffered().
+      commaBuffered = false
+//    ^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#commaBuffered().
+      elemBuilder.append(',')
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+      renderIndent()
+//    ^^^^^^^^^^^^ reference ujson/BaseCharRenderer#renderIndent().
+    }
+  }
+  def visitArray(length: Int, index: Int) = new ArrVisitor[T, T] {
+//    ^^^^^^^^^^ definition ujson/BaseCharRenderer#visitArray().
+//               ^^^^^^ definition ujson/BaseCharRenderer#visitArray().(length)
+//                       ^^^ reference scala/Int#
+//                            ^^^^^ definition ujson/BaseCharRenderer#visitArray().(index)
+//                                   ^^^ reference scala/Int#
+//                                              ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                                                         ^ reference ujson/BaseCharRenderer#[T]
+//                                                            ^ reference ujson/BaseCharRenderer#[T]
+//                                                                reference java/lang/Object#`<init>`().
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    elemBuilder.append('[')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+
+    depth += 1
+//  ^^^^^ reference ujson/BaseCharRenderer#depth().
+//        ^^ reference scala/Int#`+`(+4).
+    renderIndent()
+//  ^^^^^^^^^^^^ reference ujson/BaseCharRenderer#renderIndent().
+    def subVisitor = BaseCharRenderer.this
+//      ^^^^^^^^^^ definition local0
+//                   ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#
+    def visitValue(v: T, index: Int): Unit = {
+//      ^^^^^^^^^^ definition local1
+//                 ^ definition local2
+//                    ^ reference ujson/BaseCharRenderer#[T]
+//                       ^^^^^ definition local3
+//                              ^^^ reference scala/Int#
+//                                    ^^^^ reference scala/Unit#
+      flushBuffer()
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+      commaBuffered = true
+//    ^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#commaBuffered().
+    }
+    def visitEnd(index: Int) = {
+//      ^^^^^^^^ definition local4
+//               ^^^^^ definition local5
+//                      ^^^ reference scala/Int#
+      commaBuffered = false
+//    ^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#commaBuffered().
+      depth -= 1
+//    ^^^^^ reference ujson/BaseCharRenderer#depth().
+//          ^^ reference scala/Int#`-`(+3).
+      renderIndent()
+//    ^^^^^^^^^^^^ reference ujson/BaseCharRenderer#renderIndent().
+      elemBuilder.append(']')
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+      flushCharBuilder()
+//    ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+      out
+//    ^^^ reference ujson/BaseCharRenderer#out.
+    }
+  }
+
+  def visitObject(length: Int, index: Int) = new ObjVisitor[T, T] {
+//    ^^^^^^^^^^^ definition ujson/BaseCharRenderer#visitObject().
+//                ^^^^^^ definition ujson/BaseCharRenderer#visitObject().(length)
+//                        ^^^ reference scala/Int#
+//                             ^^^^^ definition ujson/BaseCharRenderer#visitObject().(index)
+//                                    ^^^ reference scala/Int#
+//                                               ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                                          ^ reference ujson/BaseCharRenderer#[T]
+//                                                             ^ reference ujson/BaseCharRenderer#[T]
+//                                                                 reference java/lang/Object#`<init>`().
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    elemBuilder.append('{')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+    depth += 1
+//  ^^^^^ reference ujson/BaseCharRenderer#depth().
+//        ^^ reference scala/Int#`+`(+4).
+    renderIndent()
+//  ^^^^^^^^^^^^ reference ujson/BaseCharRenderer#renderIndent().
+    def subVisitor = BaseCharRenderer.this
+//      ^^^^^^^^^^ definition local6
+//                   ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#
+    def visitKey(index: Int) = BaseCharRenderer.this
+//      ^^^^^^^^ definition local7
+//               ^^^^^ definition local8
+//                      ^^^ reference scala/Int#
+//                             ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#
+    def visitKeyValue(s: Any): Unit = {
+//      ^^^^^^^^^^^^^ definition local9
+//                    ^ definition local10
+//                       ^^^ reference scala/Any#
+//                             ^^^^ reference scala/Unit#
+      elemBuilder.append(':')
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+      if (indent != -1) elemBuilder.append(' ')
+//        ^^^^^^ reference ujson/BaseCharRenderer#indent.
+//               ^^ reference scala/Int#`!=`(+3).
+//                      ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                                  ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+    }
+    def visitValue(v: T, index: Int): Unit = {
+//      ^^^^^^^^^^ definition local11
+//                 ^ definition local12
+//                    ^ reference ujson/BaseCharRenderer#[T]
+//                       ^^^^^ definition local13
+//                              ^^^ reference scala/Int#
+//                                    ^^^^ reference scala/Unit#
+      commaBuffered = true
+//    ^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#commaBuffered().
+    }
+    def visitEnd(index: Int) = {
+//      ^^^^^^^^ definition local14
+//               ^^^^^ definition local15
+//                      ^^^ reference scala/Int#
+      commaBuffered = false
+//    ^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#commaBuffered().
+      depth -= 1
+//    ^^^^^ reference ujson/BaseCharRenderer#depth().
+//          ^^ reference scala/Int#`-`(+3).
+      renderIndent()
+//    ^^^^^^^^^^^^ reference ujson/BaseCharRenderer#renderIndent().
+      elemBuilder.append('}')
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+      flushCharBuilder()
+//    ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+      out
+//    ^^^ reference ujson/BaseCharRenderer#out.
+    }
+  }
+
+  def visitNull(index: Int) = {
+//    ^^^^^^^^^ definition ujson/BaseCharRenderer#visitNull().
+//              ^^^^^ definition ujson/BaseCharRenderer#visitNull().(index)
+//                     ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    elemBuilder.ensureLength(4)
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#ensureLength().
+    elemBuilder.appendUnsafe('n')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('u')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('l')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('l')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    flushCharBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+    out
+//  ^^^ reference ujson/BaseCharRenderer#out.
+  }
+
+  def visitFalse(index: Int) = {
+//    ^^^^^^^^^^ definition ujson/BaseCharRenderer#visitFalse().
+//               ^^^^^ definition ujson/BaseCharRenderer#visitFalse().(index)
+//                      ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    elemBuilder.ensureLength(5)
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#ensureLength().
+    elemBuilder.appendUnsafe('f')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('a')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('l')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('s')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('e')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    flushCharBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+    out
+//  ^^^ reference ujson/BaseCharRenderer#out.
+  }
+
+  def visitTrue(index: Int) = {
+//    ^^^^^^^^^ definition ujson/BaseCharRenderer#visitTrue().
+//              ^^^^^ definition ujson/BaseCharRenderer#visitTrue().(index)
+//                     ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    elemBuilder.ensureLength(4)
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#ensureLength().
+    elemBuilder.appendUnsafe('t')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('r')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('u')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    elemBuilder.appendUnsafe('e')
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+    flushCharBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+    out
+//  ^^^ reference ujson/BaseCharRenderer#out.
+  }
+
+  def visitFloat64StringParts(s: CharSequence, decIndex: Int, expIndex: Int, index: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/BaseCharRenderer#visitFloat64StringParts().
+//                            ^ definition ujson/BaseCharRenderer#visitFloat64StringParts().(s)
+//                               ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                             ^^^^^^^^ definition ujson/BaseCharRenderer#visitFloat64StringParts().(decIndex)
+//                                                       ^^^ reference scala/Int#
+//                                                            ^^^^^^^^ definition ujson/BaseCharRenderer#visitFloat64StringParts().(expIndex)
+//                                                                      ^^^ reference scala/Int#
+//                                                                           ^^^^^ definition ujson/BaseCharRenderer#visitFloat64StringParts().(index)
+//                                                                                  ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    elemBuilder.ensureLength(s.length())
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//              ^^^^^^^^^^^^ reference upickle/core/CharBuilder#ensureLength().
+//                           ^ reference ujson/BaseCharRenderer#visitFloat64StringParts().(s)
+//                             ^^^^^^ reference java/lang/CharSequence#length().
+    var i = 0
+//      ^ definition local16
+    val sLength = s.length
+//      ^^^^^^^ definition local17
+//                ^ reference ujson/BaseCharRenderer#visitFloat64StringParts().(s)
+//                  ^^^^^^ reference java/lang/CharSequence#length().
+    while(i < sLength){
+//        ^ reference local16
+//          ^ reference scala/Int#`<`(+3).
+//            ^^^^^^^ reference local17
+      elemBuilder.appendUnsafeC(s.charAt(i))
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                ^^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafeC().
+//                              ^ reference ujson/BaseCharRenderer#visitFloat64StringParts().(s)
+//                                ^^^^^^ reference java/lang/CharSequence#charAt().
+//                                       ^ reference local16
+      i += 1
+//    ^ reference local16
+//      ^^ reference scala/Int#`+`(+4).
+    }
+    flushCharBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+    out
+//  ^^^ reference ujson/BaseCharRenderer#out.
+  }
+
+  override def visitFloat64(d: Double, index: Int) = {
+//             ^^^^^^^^^^^^ definition ujson/BaseCharRenderer#visitFloat64().
+//                          ^ definition ujson/BaseCharRenderer#visitFloat64().(d)
+//                             ^^^^^^ reference scala/Double#
+//                                     ^^^^^ definition ujson/BaseCharRenderer#visitFloat64().(index)
+//                                            ^^^ reference scala/Int#
+    d match{
+//  ^ reference ujson/BaseCharRenderer#visitFloat64().(d)
+      case Double.PositiveInfinity => visitNonNullString("Infinity", -1)
+//         ^^^^^^ reference scala/Double.
+//                ^^^^^^^^^^^^^^^^ reference scala/Double.PositiveInfinity.
+//                                    ^^^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#visitNonNullString().
+      case Double.NegativeInfinity => visitNonNullString("-Infinity", -1)
+//         ^^^^^^ reference scala/Double.
+//                ^^^^^^^^^^^^^^^^ reference scala/Double.NegativeInfinity.
+//                                    ^^^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#visitNonNullString().
+      case d if java.lang.Double.isNaN(d) => visitNonNullString("NaN", -1)
+//         ^ definition local18
+//              ^^^^ reference java/
+//                   ^^^^ reference java/lang/
+//                        ^^^^^^ reference java/lang/Double#
+//                               ^^^^^ reference java/lang/Double#isNaN(+1).
+//                                     ^ reference local18
+//                                           ^^^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#visitNonNullString().
+      case d =>
+//         ^ definition local19
+        val i = d.toInt
+//          ^ definition local20
+//              ^ reference local19
+//                ^^^^^ reference scala/Double#toInt().
+        if (d == i) visitFloat64StringParts(i.toString, -1, -1, index)
+//          ^ reference local19
+//            ^^ reference scala/Double#`==`(+3).
+//               ^ reference local20
+//                  ^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#visitFloat64StringParts().
+//                                          ^ reference local20
+//                                            ^^^^^^^^ reference scala/Any#toString().
+//                                                              ^^^^^ reference ujson/BaseCharRenderer#visitFloat64().(index)
+        else super.visitFloat64(d, index)
+//                 ^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64().
+//                              ^ reference local19
+//                                 ^^^^^ reference ujson/BaseCharRenderer#visitFloat64().(index)
+        flushBuffer()
+//      ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    }
+    flushCharBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+    out
+//  ^^^ reference ujson/BaseCharRenderer#out.
+  }
+
+
+  def visitString(s: CharSequence, index: Int) = {
+//    ^^^^^^^^^^^ definition ujson/BaseCharRenderer#visitString().
+//                ^ definition ujson/BaseCharRenderer#visitString().(s)
+//                   ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                 ^^^^^ definition ujson/BaseCharRenderer#visitString().(index)
+//                                        ^^^ reference scala/Int#
+
+    if (s eq null) visitNull(index)
+//      ^ reference ujson/BaseCharRenderer#visitString().(s)
+//        ^^ reference java/lang/Object#eq().
+//                 ^^^^^^^^^ reference ujson/BaseCharRenderer#visitNull().
+//                           ^^^^^ reference ujson/BaseCharRenderer#visitString().(index)
+    else visitNonNullString(s, index)
+//       ^^^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#visitNonNullString().
+//                          ^ reference ujson/BaseCharRenderer#visitString().(s)
+//                             ^^^^^ reference ujson/BaseCharRenderer#visitString().(index)
+  }
+
+  def visitNonNullString(s: CharSequence, index: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/BaseCharRenderer#visitNonNullString().
+//                       ^ definition ujson/BaseCharRenderer#visitNonNullString().(s)
+//                          ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                        ^^^^^ definition ujson/BaseCharRenderer#visitNonNullString().(index)
+//                                               ^^^ reference scala/Int#
+    flushBuffer()
+//  ^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushBuffer().
+    upickle.core.RenderUtils.escapeChar(unicodeCharBuilder, elemBuilder, s, escapeUnicode)
+//  ^^^^^^^ reference upickle/
+//          ^^^^ reference upickle/core/
+//               ^^^^^^^^^^^ reference upickle/core/RenderUtils.
+//                           ^^^^^^^^^^ reference upickle/core/RenderUtils.escapeChar().
+//                                      ^^^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#unicodeCharBuilder.
+//                                                          ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                                                                       ^ reference ujson/BaseCharRenderer#visitNonNullString().(s)
+//                                                                          ^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#escapeUnicode.
+    flushCharBuilder()
+//  ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#flushCharBuilder().
+    out
+//  ^^^ reference ujson/BaseCharRenderer#out.
+  }
+
+  final def renderIndent() = {
+//          ^^^^^^^^^^^^ definition ujson/BaseCharRenderer#renderIndent().
+    if (indent == -1) ()
+//      ^^^^^^ reference ujson/BaseCharRenderer#indent.
+//             ^^ reference scala/Int#`==`(+3).
+    else {
+      var i = indent * depth
+//        ^ definition local21
+//            ^^^^^^ reference ujson/BaseCharRenderer#indent.
+//                   ^ reference scala/Int#`*`(+3).
+//                     ^^^^^ reference ujson/BaseCharRenderer#depth().
+      elemBuilder.ensureLength(i + 1)
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                ^^^^^^^^^^^^ reference upickle/core/CharBuilder#ensureLength().
+//                             ^ reference local21
+//                               ^ reference scala/Int#`+`(+4).
+      elemBuilder.appendUnsafe('\n')
+//    ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+      while(i > 0) {
+//          ^ reference local21
+//            ^ reference scala/Int#`>`(+3).
+        elemBuilder.appendUnsafe(' ')
+//      ^^^^^^^^^^^ reference ujson/BaseCharRenderer#elemBuilder.
+//                  ^^^^^^^^^^^^ reference upickle/core/CharBuilder#appendUnsafe().
+        i -= 1
+//      ^ reference local21
+//        ^^ reference scala/Int#`-`(+3).
+      }
+    }
+  }
+}
diff --git a/tests/snapshots/src/main/generated/ByteParser.scala b/tests/snapshots/src/main/generated/ByteParser.scala
new file mode 100644
index 000000000..25fad61d0
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ByteParser.scala
@@ -0,0 +1,1930 @@
+package ujson
+//      ^^^^^ definition ujson/
+import java.io.StringWriter
+//     ^^^^ reference java/
+//          ^^ reference java/io/
+//             ^^^^^^^^^^^^ reference java/io/StringWriter#
+
+import upickle.core.{Abort, AbortException, ObjArrVisitor, ObjVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^ reference upickle/core/Abort.
+//                   ^^^^^ reference upickle/core/Abort#
+//                          ^^^^^^^^^^^^^^ reference upickle/core/AbortException.
+//                          ^^^^^^^^^^^^^^ reference upickle/core/AbortException#
+//                                          ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                         ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                                                     ^^^^^^^ reference upickle/core/Visitor.
+//                                                                     ^^^^^^^ reference upickle/core/Visitor#
+import java.nio.charset.Charset
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^ reference java/nio/charset/
+//                      ^^^^^^^ reference java/nio/charset/Charset#
+
+
+import scala.annotation.{switch, tailrec}
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                       ^^^^^^ reference scala/annotation/switch#
+//                               ^^^^^^^ reference scala/annotation/tailrec#
+
+/**
+  * A specialized JSON parse that can parse Bytes (Chars or Bytes), sending
+  * method calls to the given [[upickle.core.Visitor]].
+  *
+  * Generally has a lot of tricks for performance: e.g. having duplicate
+  * implementations for nested v.s. top-level parsing, using an `ByteBuilder`
+  * to construct the `CharSequences` that `visitString` requires, etc.
+  */
+abstract class ByteParser[J] extends upickle.core.BufferingByteParser{
+//             ^^^^^^^^^^ definition ujson/ByteParser#
+//                        ^ definition ujson/ByteParser#[J]
+//                            definition ujson/ByteParser#`<init>`().
+//                                   ^^^^^^^ reference upickle/
+//                                           ^^^^ reference upickle/core/
+//                                                ^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#
+  private[this] val elemOps = upickle.core.ByteOps
+//                  ^^^^^^^ definition ujson/ByteParser#elemOps.
+//                            ^^^^^^^ reference upickle/
+//                                    ^^^^ reference upickle/core/
+//                                         ^^^^^^^ reference upickle/core/ByteOps.
+  private[this] val outputBuilder = new upickle.core.ByteBuilder()
+//                  ^^^^^^^^^^^^^ definition ujson/ByteParser#outputBuilder.
+//                                      ^^^^^^^ reference upickle/
+//                                              ^^^^ reference upickle/core/
+//                                                   ^^^^^^^^^^^ reference upickle/core/ByteBuilder#
+//                                                               reference upickle/core/ByteBuilder#`<init>`().
+
+  def requestUntilOrThrow(i: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#requestUntilOrThrow().
+//                        ^ definition ujson/ByteParser#requestUntilOrThrow().(i)
+//                           ^^^ reference scala/Int#
+    if (requestUntil(i)) throw new IncompleteParseException("exhausted input")
+//      ^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#requestUntil().
+//                   ^ reference ujson/ByteParser#requestUntilOrThrow().(i)
+//                                 ^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/IncompleteParseException#
+//                                                          reference ujson/IncompleteParseException#`<init>`().
+  }
+  override def getByteSafe(i: Int): Byte = {
+//             ^^^^^^^^^^^ definition ujson/ByteParser#getByteSafe().
+//                         ^ definition ujson/ByteParser#getByteSafe().(i)
+//                            ^^^ reference scala/Int#
+//                                  ^^^^ reference scala/Byte#
+    requestUntilOrThrow(i)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#requestUntilOrThrow().
+//                      ^ reference ujson/ByteParser#getByteSafe().(i)
+    getByteUnsafe(i)
+//  ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                ^ reference ujson/ByteParser#getByteSafe().(i)
+  }
+
+  /**
+   * Return true iff 'i' is at or beyond the end of the input (EOF).
+   */
+  protected[this] def atEof(i: Int) = requestUntil(i)
+//                    ^^^^^ definition ujson/ByteParser#atEof().
+//                          ^ definition ujson/ByteParser#atEof().(i)
+//                             ^^^ reference scala/Int#
+//                                    ^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#requestUntil().
+//                                                 ^ reference ujson/ByteParser#atEof().(i)
+
+  /**
+   * Should be called when parsing is finished.
+   */
+  protected[this] def close(): Unit
+//                    ^^^^^ definition ujson/ByteParser#close().
+//                             ^^^^ reference scala/Unit#
+
+  /**
+   * Valid parser states.
+   */
+  @inline private[this] final val ARRBEG = 6
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/ByteParser#ARRBEG.
+  @inline private[this] final val OBJBEG = 7
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/ByteParser#OBJBEG.
+  @inline private[this] final val DATA = 1
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^ definition ujson/ByteParser#DATA.
+  @inline private[this] final val KEY = 2
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^ definition ujson/ByteParser#KEY.
+  @inline private[this] final val COLON = 3
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^ definition ujson/ByteParser#COLON.
+  @inline private[this] final val ARREND = 4
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/ByteParser#ARREND.
+  @inline private[this] final val OBJEND = 5
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/ByteParser#OBJEND.
+
+  /**
+    * Parse the JSON document into a single JSON value.
+    *
+    * The parser considers documents like '333', 'true', and '"foo"' to be
+    * valid, as well as more traditional documents like [1,2,3,4,5]. However,
+    * multiple top-level objects are not allowed.
+    */
+  final def parse(facade: Visitor[_, J]): J = {
+//          ^^^^^ definition ujson/ByteParser#parse().
+//                ^^^^^^ definition ujson/ByteParser#parse().(facade)
+//                        ^^^^^^^ reference upickle/core/Visitor#
+//                                   ^ reference ujson/ByteParser#[J]
+//                                        ^ reference ujson/ByteParser#[J]
+    val (value, i) = parseTopLevel(0, facade)
+//       ^^^^^ definition local0
+//              ^ definition local1
+//                   ^^^^^^^^^^^^^ reference ujson/ByteParser#parseTopLevel().
+//                                    ^^^^^^ reference ujson/ByteParser#parse().(facade)
+    var j = i
+//      ^ definition local3
+//          ^ reference local1
+    while (!atEof(j)) {
+//         ^ reference scala/Boolean#`unary_!`().
+//          ^^^^^ reference ujson/ByteParser#atEof().
+//                ^ reference local3
+      (getByteSafe(j): @switch) match {
+//     ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                 ^ reference local3
+        case '\n' | ' ' | '\t' | '\r' => j += 1
+//                                       ^ reference local3
+//                                         ^^ reference scala/Int#`+`(+4).
+        case _ => die(j, "expected whitespace or eof")
+//                ^^^ reference ujson/ByteParser#die().
+//                    ^ reference local3
+      }
+    }
+    if (!atEof(j)) die(j, "expected eof")
+//      ^ reference scala/Boolean#`unary_!`().
+//       ^^^^^ reference ujson/ByteParser#atEof().
+//             ^ reference local3
+//                 ^^^ reference ujson/ByteParser#die().
+//                     ^ reference local3
+    close()
+//  ^^^^^ reference ujson/ByteParser#close().
+    value
+//  ^^^^^ reference local0
+  }
+
+  /**
+   * Used to generate error messages with character info and offsets.
+   */
+  protected[this] def die(i: Int, msg: String): Nothing = {
+//                    ^^^ definition ujson/ByteParser#die().
+//                        ^ definition ujson/ByteParser#die().(i)
+//                           ^^^ reference scala/Int#
+//                                ^^^ definition ujson/ByteParser#die().(msg)
+//                                     ^^^^^^ reference scala/Predef.String#
+//                                              ^^^^^^^ reference scala/Nothing#
+    val out = new upickle.core.ByteBuilder()
+//      ^^^ definition local4
+//                ^^^^^^^ reference upickle/
+//                        ^^^^ reference upickle/core/
+//                             ^^^^^^^^^^^ reference upickle/core/ByteBuilder#
+//                                         reference upickle/core/ByteBuilder#`<init>`().
+    upickle.core.RenderUtils.escapeByte(
+//  ^^^^^^^ reference upickle/
+//          ^^^^ reference upickle/core/
+//               ^^^^^^^^^^^ reference upickle/core/RenderUtils.
+//                           ^^^^^^^^^^ reference upickle/core/RenderUtils.escapeByte().
+      new upickle.core.CharBuilder(),
+//        ^^^^^^^ reference upickle/
+//                ^^^^ reference upickle/core/
+//                     ^^^^^^^^^^^ reference upickle/core/CharBuilder#
+//                                 reference upickle/core/CharBuilder#`<init>`().
+      out,
+//    ^^^ reference local4
+      new ArrayCharSequence(Array(elemOps.toInt(getByteSafe(i)).toChar)),
+//        ^^^^^^^^^^^^^^^^^ reference scala/Predef.ArrayCharSequence#
+//                          reference scala/Predef.ArrayCharSequence#`<init>`().
+//                          ^^^^^ reference scala/Array.
+//                                ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                                        ^^^^^ reference upickle/core/ByteOps.toInt().
+//                                              ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                                          ^ reference ujson/ByteParser#die().(i)
+//                                                              ^^^^^^ reference scala/Int#toChar().
+      unicode = false
+//    ^^^^^^^ reference upickle/core/RenderUtils.escapeByte().(unicode)
+    )
+    val s = "%s got %s" format (msg, out.makeString())
+//      ^ definition local5
+//                      ^^^^^^ reference scala/collection/StringOps#format().
+//                              ^^^ reference ujson/ByteParser#die().(msg)
+//                                   ^^^ reference local4
+//                                       ^^^^^^^^^^ reference upickle/core/ByteBuilder#makeString().
+    throw ParseException(s, i)
+//        ^^^^^^^^^^^^^^ reference ujson/ParseException.
+//                       ^ reference local5
+//                          ^ reference ujson/ByteParser#die().(i)
+  }
+
+
+  /**
+   * Parse the given number, and add it to the given context.
+   *
+   * We don't actually instantiate a number here, but rather pass the
+   * string of for future use. Facades can choose to be lazy and just
+   * store the string. This ends up being way faster and has the nice
+   * side-effect that we know exactly how the user represented the
+   * number.
+   */
+  protected[this] final def parseNum(i: Int, ctxt: ObjArrVisitor[Any, J], facade: Visitor[_, J]): Int = {
+//                          ^^^^^^^^ definition ujson/ByteParser#parseNum().
+//                                   ^ definition ujson/ByteParser#parseNum().(i)
+//                                      ^^^ reference scala/Int#
+//                                           ^^^^ definition ujson/ByteParser#parseNum().(ctxt)
+//                                                 ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                               ^^^ reference scala/Any#
+//                                                                    ^ reference ujson/ByteParser#[J]
+//                                                                        ^^^^^^ definition ujson/ByteParser#parseNum().(facade)
+//                                                                                ^^^^^^^ reference upickle/core/Visitor#
+//                                                                                           ^ reference ujson/ByteParser#[J]
+//                                                                                                ^^^ reference scala/Int#
+    var j = i
+//      ^ definition local6
+//          ^ reference ujson/ByteParser#parseNum().(i)
+    var c = getByteSafe(j)
+//      ^ definition local7
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local6
+    var decIndex = -1
+//      ^^^^^^^^ definition local8
+    var expIndex = -1
+//      ^^^^^^^^ definition local9
+
+    if (c == '-') {
+//      ^ reference local7
+//        ^^ reference scala/Byte#`==`(+2).
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getByteSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local6
+    }
+    if (c == '0') {
+//      ^ reference local7
+//        ^^ reference scala/Byte#`==`(+2).
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getByteSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local6
+    } else {
+      val j0 = j
+//        ^^ definition local10
+//             ^ reference local6
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                   ^^^^^^ reference upickle/core/ByteOps.within().
+//                               ^ reference local7
+        j += 1;
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getByteSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local6
+      }
+      if (j == j0) die(i, "expected digit")
+//        ^ reference local6
+//          ^^ reference scala/Int#`==`(+3).
+//             ^^ reference local10
+//                 ^^^ reference ujson/ByteParser#die().
+//                     ^ reference ujson/ByteParser#parseNum().(i)
+    }
+
+    if (c == '.') {
+//      ^ reference local7
+//        ^^ reference scala/Byte#`==`(+2).
+      decIndex = j - i
+//    ^^^^^^^^ reference local8
+//               ^ reference local6
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/ByteParser#parseNum().(i)
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getByteSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local6
+      val j0 = j
+//        ^^ definition local11
+//             ^ reference local6
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                   ^^^^^^ reference upickle/core/ByteOps.within().
+//                               ^ reference local7
+        j += 1
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getByteSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local6
+      }
+      if (j0 == j) die(i, "expected digit")
+//        ^^ reference local11
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local6
+//                 ^^^ reference ujson/ByteParser#die().
+//                     ^ reference ujson/ByteParser#parseNum().(i)
+    }
+
+    if (c == 'e' || c == 'E') {
+//      ^ reference local7
+//        ^^ reference scala/Byte#`==`(+2).
+//               ^^ reference scala/Boolean#`||`().
+//                  ^ reference local7
+//                    ^^ reference scala/Byte#`==`(+2).
+      expIndex = j - i
+//    ^^^^^^^^ reference local9
+//               ^ reference local6
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/ByteParser#parseNum().(i)
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getByteSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local6
+      if (c == '+' || c == '-') {
+//        ^ reference local7
+//          ^^ reference scala/Byte#`==`(+2).
+//                 ^^ reference scala/Boolean#`||`().
+//                    ^ reference local7
+//                      ^^ reference scala/Byte#`==`(+2).
+        j += 1
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getByteSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local6
+      }
+      val j0 = j
+//        ^^ definition local12
+//             ^ reference local6
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                   ^^^^^^ reference upickle/core/ByteOps.within().
+//                               ^ reference local7
+        j += 1
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getByteSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local6
+      }
+      if (j0 == j)  die(i, "expected digit")
+//        ^^ reference local12
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local6
+//                  ^^^ reference ujson/ByteParser#die().
+//                      ^ reference ujson/ByteParser#parseNum().(i)
+    }
+
+    ctxt.visitValue(visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), i)
+//  ^^^^ reference ujson/ByteParser#parseNum().(ctxt)
+//       ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().
+//                                                     ^^^^^^ reference ujson/ByteParser#parseNum().(facade)
+//                                                             ^^^^^^^^ reference local8
+//                                                                       ^^^^^^^^ reference local9
+//                                                                                 ^ reference ujson/ByteParser#parseNum().(i)
+//                                                                                    ^ reference local6
+//                                                                                        ^ reference ujson/ByteParser#parseNum().(i)
+    j
+//  ^ reference local6
+  }
+
+  def visitFloat64StringPartsWithWrapper(facade: Visitor[_, J],
+//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#visitFloat64StringPartsWithWrapper().
+//                                       ^^^^^^ definition ujson/ByteParser#visitFloat64StringPartsWithWrapper().(facade)
+//                                               ^^^^^^^ reference upickle/core/Visitor#
+//                                                          ^ reference ujson/ByteParser#[J]
+                                         decIndex: Int,
+//                                       ^^^^^^^^ definition ujson/ByteParser#visitFloat64StringPartsWithWrapper().(decIndex)
+//                                                 ^^^ reference scala/Int#
+                                         expIndex: Int,
+//                                       ^^^^^^^^ definition ujson/ByteParser#visitFloat64StringPartsWithWrapper().(expIndex)
+//                                                 ^^^ reference scala/Int#
+                                         i: Int,
+//                                       ^ definition ujson/ByteParser#visitFloat64StringPartsWithWrapper().(i)
+//                                          ^^^ reference scala/Int#
+                                         j: Int) = {
+//                                       ^ definition ujson/ByteParser#visitFloat64StringPartsWithWrapper().(j)
+//                                          ^^^ reference scala/Int#
+    facade.visitFloat64StringParts(
+//  ^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().(facade)
+//         ^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64StringParts().
+      unsafeCharSeqForRange(i, j - i),
+//    ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#unsafeCharSeqForRange().
+//                          ^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().(i)
+//                             ^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().(j)
+//                               ^ reference scala/Int#`-`(+3).
+//                                 ^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().(i)
+      decIndex,
+//    ^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().(decIndex)
+      expIndex,
+//    ^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().(expIndex)
+      i
+//    ^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().(i)
+    )
+  }
+
+  /**
+   * Parse the given number, and add it to the given context.
+   *
+   * This method is a bit slower than parseNum() because it has to be
+   * sure it doesn't run off the end of the input.
+   *
+   * Normally (when operating in rparse in the context of an outer
+   * array or object) we don't need to worry about this and can just
+   * grab characters, because if we run out of characters that would
+   * indicate bad input. This is for cases where the number could
+   * possibly be followed by a valid EOF.
+   *
+   * This method has all the same caveats as the previous method.
+   */
+  protected[this] final def parseNumTopLevel(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^^^^ definition ujson/ByteParser#parseNumTopLevel().
+//                                           ^ definition ujson/ByteParser#parseNumTopLevel().(i)
+//                                              ^^^ reference scala/Int#
+//                                                   ^^^^^^ definition ujson/ByteParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^ reference upickle/core/Visitor#
+//                                                                      ^ reference ujson/ByteParser#[J]
+//                                                                            ^ reference ujson/ByteParser#[J]
+//                                                                               ^^^ reference scala/Int#
+    var j = i
+//      ^ definition local13
+//          ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+    var c = getByteSafe(j)
+//      ^ definition local14
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local13
+    var decIndex = -1
+//      ^^^^^^^^ definition local15
+    var expIndex = -1
+//      ^^^^^^^^ definition local16
+
+    if (c == '-') {
+//      ^ reference local14
+//        ^^ reference scala/Byte#`==`(+2).
+      // any valid input will require at least one digit after -
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      c = getByteSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local13
+    }
+    if (c == '0') {
+//      ^ reference local14
+//        ^^ reference scala/Byte#`==`(+2).
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      if (atEof(j)) {
+//        ^^^^^ reference ujson/ByteParser#atEof().
+//              ^ reference local13
+        return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().
+//                                                 ^^^^^^ reference ujson/ByteParser#parseNumTopLevel().(facade)
+//                                                         ^^^^^^^^ reference local15
+//                                                                   ^^^^^^^^ reference local16
+//                                                                             ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+//                                                                                ^ reference local13
+//                                                                                    ^ reference local13
+      }
+      c = getByteSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local13
+    } else {
+      val j0 = j
+//        ^^ definition local17
+//             ^ reference local13
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                   ^^^^^^ reference upickle/core/ByteOps.within().
+//                               ^ reference local14
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        if (atEof(j)) {
+//          ^^^^^ reference ujson/ByteParser#atEof().
+//                ^ reference local13
+          return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().
+//                                                   ^^^^^^ reference ujson/ByteParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^^ reference local15
+//                                                                     ^^^^^^^^ reference local16
+//                                                                               ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+//                                                                                  ^ reference local13
+//                                                                                      ^ reference local13
+        }
+        c = getByteSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local13
+      }
+      if (j0 == j) die(i, "expected digit")
+//        ^^ reference local17
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local13
+//                 ^^^ reference ujson/ByteParser#die().
+//                     ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+    }
+
+    if (c == '.') {
+//      ^ reference local14
+//        ^^ reference scala/Byte#`==`(+2).
+      // any valid input will require at least one digit after .
+      decIndex = j - i
+//    ^^^^^^^^ reference local15
+//               ^ reference local13
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      c = getByteSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local13
+      val j0 = j
+//        ^^ definition local18
+//             ^ reference local13
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                   ^^^^^^ reference upickle/core/ByteOps.within().
+//                               ^ reference local14
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        if (atEof(j)) {
+//          ^^^^^ reference ujson/ByteParser#atEof().
+//                ^ reference local13
+          return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().
+//                                                   ^^^^^^ reference ujson/ByteParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^^ reference local15
+//                                                                     ^^^^^^^^ reference local16
+//                                                                               ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+//                                                                                  ^ reference local13
+//                                                                                      ^ reference local13
+        }
+        c = getByteSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local13
+      }
+      if(j0 == j) die(i, "expected digit")
+//       ^^ reference local18
+//          ^^ reference scala/Int#`==`(+3).
+//             ^ reference local13
+//                ^^^ reference ujson/ByteParser#die().
+//                    ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+    }
+
+    if (c == 'e' || c == 'E') {
+//      ^ reference local14
+//        ^^ reference scala/Byte#`==`(+2).
+//               ^^ reference scala/Boolean#`||`().
+//                  ^ reference local14
+//                    ^^ reference scala/Byte#`==`(+2).
+      // any valid input will require at least one digit after e, e+, etc
+      expIndex = j - i
+//    ^^^^^^^^ reference local16
+//               ^ reference local13
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      c = getByteSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                    ^ reference local13
+      if (c == '+' || c == '-') {
+//        ^ reference local14
+//          ^^ reference scala/Byte#`==`(+2).
+//                 ^^ reference scala/Boolean#`||`().
+//                    ^ reference local14
+//                      ^^ reference scala/Byte#`==`(+2).
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        c = getByteSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local13
+      }
+      val j0 = j
+//        ^^ definition local19
+//             ^ reference local13
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                   ^^^^^^ reference upickle/core/ByteOps.within().
+//                               ^ reference local14
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        if (atEof(j)) {
+//          ^^^^^ reference ujson/ByteParser#atEof().
+//                ^ reference local13
+          return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().
+//                                                   ^^^^^^ reference ujson/ByteParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^^ reference local15
+//                                                                     ^^^^^^^^ reference local16
+//                                                                               ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+//                                                                                  ^ reference local13
+//                                                                                      ^ reference local13
+        }
+        c = getByteSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                      ^ reference local13
+      }
+      if (j0 == j) die(i, "expected digit")
+//        ^^ reference local19
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local13
+//                 ^^^ reference ujson/ByteParser#die().
+//                     ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+    }
+
+    (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#visitFloat64StringPartsWithWrapper().
+//                                      ^^^^^^ reference ujson/ByteParser#parseNumTopLevel().(facade)
+//                                              ^^^^^^^^ reference local15
+//                                                        ^^^^^^^^ reference local16
+//                                                                  ^ reference ujson/ByteParser#parseNumTopLevel().(i)
+//                                                                     ^ reference local13
+//                                                                         ^ reference local13
+  }
+
+  /**
+   * Generate a Char from the hex digits of "\u1234" (i.e. "1234").
+   *
+   * NOTE: This is only capable of generating characters from the basic plane.
+   * This is why it can only return Char instead of Int.
+   */
+  protected[this] final def descape(i: Int): Char = {
+//                          ^^^^^^^ definition ujson/ByteParser#descape().
+//                                  ^ definition ujson/ByteParser#descape().(i)
+//                                     ^^^ reference scala/Int#
+//                                           ^^^^ reference scala/Char#
+    import upickle.core.RenderUtils.hex
+//         ^^^^^^^ reference upickle/
+//                 ^^^^ reference upickle/core/
+//                      ^^^^^^^^^^^ reference upickle/core/RenderUtils.
+//                                  ^^^ reference upickle/core/RenderUtils.hex().
+    var x = 0
+//      ^ definition local20
+    x = (x << 4) | hex(getByteSafe(i+2).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                 ^ reference ujson/ByteParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Byte#toInt().
+    x = (x << 4) | hex(getByteSafe(i+3).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                 ^ reference ujson/ByteParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Byte#toInt().
+    x = (x << 4) | hex(getByteSafe(i+4).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                 ^ reference ujson/ByteParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Byte#toInt().
+    x = (x << 4) | hex(getByteSafe(i+5).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                 ^ reference ujson/ByteParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Byte#toInt().
+    x.toChar
+//  ^ reference local20
+//    ^^^^^^ reference scala/Int#toChar().
+  }
+
+
+  /**
+   * Parse the JSON constant "true".
+   *
+   * Note that this method assumes that the first character has already been checked.
+   */
+  protected[this] final def parseTrue(i: Int, facade: Visitor[_, J]): J = {
+//                          ^^^^^^^^^ definition ujson/ByteParser#parseTrue().
+//                                    ^ definition ujson/ByteParser#parseTrue().(i)
+//                                       ^^^ reference scala/Int#
+//                                            ^^^^^^ definition ujson/ByteParser#parseTrue().(facade)
+//                                                    ^^^^^^^ reference upickle/core/Visitor#
+//                                                               ^ reference ujson/ByteParser#[J]
+//                                                                    ^ reference ujson/ByteParser#[J]
+    requestUntilOrThrow(i + 3)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#requestUntilOrThrow().
+//                      ^ reference ujson/ByteParser#parseTrue().(i)
+//                        ^ reference scala/Int#`+`(+4).
+    if (getByteUnsafe(i + 1) == 'r' && getByteUnsafe(i + 2) == 'u' && getByteUnsafe(i + 3) == 'e') {
+//      ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                    ^ reference ujson/ByteParser#parseTrue().(i)
+//                      ^ reference scala/Int#`+`(+4).
+//                           ^^ reference scala/Byte#`==`(+2).
+//                                  ^^ reference scala/Boolean#`&&`().
+//                                     ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                                                   ^ reference ujson/ByteParser#parseTrue().(i)
+//                                                     ^ reference scala/Int#`+`(+4).
+//                                                          ^^ reference scala/Byte#`==`(+2).
+//                                                                 ^^ reference scala/Boolean#`&&`().
+//                                                                    ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                                                                                  ^ reference ujson/ByteParser#parseTrue().(i)
+//                                                                                    ^ reference scala/Int#`+`(+4).
+//                                                                                         ^^ reference scala/Byte#`==`(+2).
+      facade.visitTrue(i)
+//    ^^^^^^ reference ujson/ByteParser#parseTrue().(facade)
+//           ^^^^^^^^^ reference upickle/core/Visitor#visitTrue().
+//                     ^ reference ujson/ByteParser#parseTrue().(i)
+    } else {
+      die(i, "expected true")
+//    ^^^ reference ujson/ByteParser#die().
+//        ^ reference ujson/ByteParser#parseTrue().(i)
+    }
+  }
+
+  /**
+   * Parse the JSON constant "false".
+   *
+   * Note that this method assumes that the first character has already been checked.
+   */
+  protected[this] final def parseFalse(i: Int, facade: Visitor[_, J]): J = {
+//                          ^^^^^^^^^^ definition ujson/ByteParser#parseFalse().
+//                                     ^ definition ujson/ByteParser#parseFalse().(i)
+//                                        ^^^ reference scala/Int#
+//                                             ^^^^^^ definition ujson/ByteParser#parseFalse().(facade)
+//                                                     ^^^^^^^ reference upickle/core/Visitor#
+//                                                                ^ reference ujson/ByteParser#[J]
+//                                                                     ^ reference ujson/ByteParser#[J]
+    requestUntilOrThrow(i + 4)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#requestUntilOrThrow().
+//                      ^ reference ujson/ByteParser#parseFalse().(i)
+//                        ^ reference scala/Int#`+`(+4).
+
+    if (getByteUnsafe(i + 1) == 'a' && getByteUnsafe(i + 2) == 'l' && getByteUnsafe(i + 3) == 's' && getByteUnsafe(i + 4) == 'e') {
+//      ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                    ^ reference ujson/ByteParser#parseFalse().(i)
+//                      ^ reference scala/Int#`+`(+4).
+//                           ^^ reference scala/Byte#`==`(+2).
+//                                  ^^ reference scala/Boolean#`&&`().
+//                                     ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                                                   ^ reference ujson/ByteParser#parseFalse().(i)
+//                                                     ^ reference scala/Int#`+`(+4).
+//                                                          ^^ reference scala/Byte#`==`(+2).
+//                                                                 ^^ reference scala/Boolean#`&&`().
+//                                                                    ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                                                                                  ^ reference ujson/ByteParser#parseFalse().(i)
+//                                                                                    ^ reference scala/Int#`+`(+4).
+//                                                                                         ^^ reference scala/Byte#`==`(+2).
+//                                                                                                ^^ reference scala/Boolean#`&&`().
+//                                                                                                   ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                                                                                                                 ^ reference ujson/ByteParser#parseFalse().(i)
+//                                                                                                                   ^ reference scala/Int#`+`(+4).
+//                                                                                                                        ^^ reference scala/Byte#`==`(+2).
+      facade.visitFalse(i)
+//    ^^^^^^ reference ujson/ByteParser#parseFalse().(facade)
+//           ^^^^^^^^^^ reference upickle/core/Visitor#visitFalse().
+//                      ^ reference ujson/ByteParser#parseFalse().(i)
+    } else {
+      die(i, "expected false")
+//    ^^^ reference ujson/ByteParser#die().
+//        ^ reference ujson/ByteParser#parseFalse().(i)
+    }
+  }
+
+  /**
+   * Parse the JSON constant "null".
+   *
+   * Note that this method assumes that the first character has already been checked.
+   */
+  protected[this] final def parseNull(i: Int, facade: Visitor[_, J]): J = {
+//                          ^^^^^^^^^ definition ujson/ByteParser#parseNull().
+//                                    ^ definition ujson/ByteParser#parseNull().(i)
+//                                       ^^^ reference scala/Int#
+//                                            ^^^^^^ definition ujson/ByteParser#parseNull().(facade)
+//                                                    ^^^^^^^ reference upickle/core/Visitor#
+//                                                               ^ reference ujson/ByteParser#[J]
+//                                                                    ^ reference ujson/ByteParser#[J]
+    requestUntilOrThrow(i + 3)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#requestUntilOrThrow().
+//                      ^ reference ujson/ByteParser#parseNull().(i)
+//                        ^ reference scala/Int#`+`(+4).
+    if (getByteUnsafe(i + 1) == 'u' && getByteUnsafe(i + 2) == 'l' && getByteUnsafe(i + 3) == 'l') {
+//      ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                    ^ reference ujson/ByteParser#parseNull().(i)
+//                      ^ reference scala/Int#`+`(+4).
+//                           ^^ reference scala/Byte#`==`(+2).
+//                                  ^^ reference scala/Boolean#`&&`().
+//                                     ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                                                   ^ reference ujson/ByteParser#parseNull().(i)
+//                                                     ^ reference scala/Int#`+`(+4).
+//                                                          ^^ reference scala/Byte#`==`(+2).
+//                                                                 ^^ reference scala/Boolean#`&&`().
+//                                                                    ^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#getByteUnsafe().
+//                                                                                  ^ reference ujson/ByteParser#parseNull().(i)
+//                                                                                    ^ reference scala/Int#`+`(+4).
+//                                                                                         ^^ reference scala/Byte#`==`(+2).
+      facade.visitNull(i)
+//    ^^^^^^ reference ujson/ByteParser#parseNull().(facade)
+//           ^^^^^^^^^ reference upickle/core/Visitor#visitNull().
+//                     ^ reference ujson/ByteParser#parseNull().(i)
+    } else {
+      die(i, "expected null")
+//    ^^^ reference ujson/ByteParser#die().
+//        ^ reference ujson/ByteParser#parseNull().(i)
+    }
+  }
+
+  protected[this] final def parseTopLevel(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^ definition ujson/ByteParser#parseTopLevel().
+//                                        ^ definition ujson/ByteParser#parseTopLevel().(i)
+//                                           ^^^ reference scala/Int#
+//                                                ^^^^^^ definition ujson/ByteParser#parseTopLevel().(facade)
+//                                                        ^^^^^^^ reference upickle/core/Visitor#
+//                                                                   ^ reference ujson/ByteParser#[J]
+//                                                                         ^ reference ujson/ByteParser#[J]
+//                                                                            ^^^ reference scala/Int#
+    try parseTopLevel0(i, facade)
+//      ^^^^^^^^^^^^^^ reference ujson/ByteParser#parseTopLevel0().
+//                     ^ reference ujson/ByteParser#parseTopLevel().(i)
+//                        ^^^^^^ reference ujson/ByteParser#parseTopLevel().(facade)
+    catch reject(i)
+//        ^^^^^^ reference ujson/ByteParser#reject().
+//               ^ reference ujson/ByteParser#parseTopLevel().(i)
+  }
+  /**
+   * Parse and return the next JSON value and the position beyond it.
+   */
+  @tailrec
+// ^^^^^^^ reference scala/annotation/tailrec#
+//         reference scala/annotation/tailrec#`<init>`().
+  protected[this] final def parseTopLevel0(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^^ definition ujson/ByteParser#parseTopLevel0().
+//                                         ^ definition ujson/ByteParser#parseTopLevel0().(i)
+//                                            ^^^ reference scala/Int#
+//                                                 ^^^^^^ definition ujson/ByteParser#parseTopLevel0().(facade)
+//                                                         ^^^^^^^ reference upickle/core/Visitor#
+//                                                                    ^ reference ujson/ByteParser#[J]
+//                                                                          ^ reference ujson/ByteParser#[J]
+//                                                                             ^^^ reference scala/Int#
+    (getByteSafe(i): @switch) match {
+//   ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//               ^ reference ujson/ByteParser#parseTopLevel0().(i)
+      // ignore whitespace
+      case ' ' | '\t' | 'r' => parseTopLevel0(i + 1, facade)
+//                             ^^^^^^^^^^^^^^ reference ujson/ByteParser#parseTopLevel0().
+//                                            ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                              ^ reference scala/Int#`+`(+4).
+//                                                   ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+      case '\n' => parseTopLevel0(i + 1, facade)
+//                 ^^^^^^^^^^^^^^ reference ujson/ByteParser#parseTopLevel0().
+//                                ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                       ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+
+      // if we have a recursive top-level structure, we'll delegate the parsing
+      // duties to our good friend rparse().
+      case '[' => parseNested(ARRBEG, i + 1, facade.visitArray(-1, i), Nil)
+//                ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                            ^^^^^^ reference ujson/ByteParser#ARRBEG.
+//                                    ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                      ^ reference scala/Int#`+`(+4).
+//                                           ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+//                                                  ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                                                                 ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                                                     ^^^ reference scala/package.Nil.
+      case '{' => parseNested(OBJBEG, i + 1, facade.visitObject(-1, i), Nil)
+//                ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                            ^^^^^^ reference ujson/ByteParser#OBJBEG.
+//                                    ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                      ^ reference scala/Int#`+`(+4).
+//                                           ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+//                                                  ^^^^^^^^^^^ reference upickle/core/Visitor#visitObject().
+//                                                                  ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                                                      ^^^ reference scala/package.Nil.
+
+      // we have a single top-level number
+      case '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => parseNumTopLevel(i, facade)
+//                                                                            ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseNumTopLevel().
+//                                                                                             ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                                                                                ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+
+      // we have a single top-level string
+      case '"' => parseStringTopLevel(i, facade)
+//                ^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringTopLevel().
+//                                    ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                       ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+
+      // we have a single top-level constant
+      case 't' => (parseTrue(i, facade), i + 4)
+//                 ^^^^^^^^^ reference ujson/ByteParser#parseTrue().
+//                           ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                              ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+//                                       ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                         ^ reference scala/Int#`+`(+4).
+      case 'f' => (parseFalse(i, facade), i + 5)
+//                 ^^^^^^^^^^ reference ujson/ByteParser#parseFalse().
+//                            ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                               ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+//                                        ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                          ^ reference scala/Int#`+`(+4).
+      case 'n' => (parseNull(i, facade), i + 4)
+//                 ^^^^^^^^^ reference ujson/ByteParser#parseNull().
+//                           ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                              ^^^^^^ reference ujson/ByteParser#parseTopLevel0().(facade)
+//                                       ^ reference ujson/ByteParser#parseTopLevel0().(i)
+//                                         ^ reference scala/Int#`+`(+4).
+
+      // invalid
+      case _ => die(i, "expected json value")
+//              ^^^ reference ujson/ByteParser#die().
+//                  ^ reference ujson/ByteParser#parseTopLevel0().(i)
+    }
+  }
+
+  def reject(j: Int): PartialFunction[Throwable, Nothing] = {
+//    ^^^^^^ definition ujson/ByteParser#reject().
+//           ^ definition ujson/ByteParser#reject().(j)
+//              ^^^ reference scala/Int#
+//                    ^^^^^^^^^^^^^^^ reference scala/PartialFunction#
+//                                    ^^^^^^^^^ reference scala/package.Throwable#
+//                                               ^^^^^^^ reference scala/Nothing#
+    case e: Abort =>
+//       ^ definition local21
+//          ^^^^^ reference upickle/core/Abort#
+      throw new AbortException(e.msg, j, -1, -1, e)
+//              ^^^^^^^^^^^^^^ reference upickle/core/AbortException#
+//                             reference upickle/core/AbortException#`<init>`().
+//                             ^ reference local21
+//                               ^^^ reference upickle/core/Abort#msg.
+//                                    ^ reference ujson/ByteParser#reject().(j)
+//                                               ^ reference local21
+  }
+  /**
+   * Tail-recursive parsing method to do the bulk of JSON parsing.
+   *
+   * This single method manages parser states, data, etc. Except for
+   * parsing non-recursive values (like strings, numbers, and
+   * constants) all important work happens in this loop (or in methods
+   * it calls, like reset()).
+   *
+   * Currently the code is optimized to make use of switch
+   * statements. Future work should consider whether this is better or
+   * worse than manually constructed if/else statements or something
+   * else. Also, it may be possible to reorder some cases for speed
+   * improvements.
+   *
+   * @param j index/position in the source json
+   * @param path the json path in the tree
+   */
+  @tailrec
+// ^^^^^^^ reference scala/annotation/tailrec#
+//         reference scala/annotation/tailrec#`<init>`().
+  protected[this] final def parseNested(state: Int,
+//                          ^^^^^^^^^^^ definition ujson/ByteParser#parseNested().
+//                                      ^^^^^ definition ujson/ByteParser#parseNested().(state)
+//                                             ^^^ reference scala/Int#
+                                        i: Int,
+//                                      ^ definition ujson/ByteParser#parseNested().(i)
+//                                         ^^^ reference scala/Int#
+                                        stackHead: ObjArrVisitor[_, J],
+//                                      ^^^^^^^^^ definition ujson/ByteParser#parseNested().(stackHead)
+//                                                 ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                  ^ reference ujson/ByteParser#[J]
+                                        stackTail: List[ObjArrVisitor[_, J]]) : (J, Int) = {
+//                                      ^^^^^^^^^ definition ujson/ByteParser#parseNested().(stackTail)
+//                                                 ^^^^ reference scala/package.List#
+//                                                      ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                       ^ reference ujson/ByteParser#[J]
+//                                                                               ^ reference ujson/ByteParser#[J]
+//                                                                                  ^^^ reference scala/Int#
+    (getByteSafe(i): @switch) match{
+//   ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//               ^ reference ujson/ByteParser#parseNested().(i)
+      case ' ' | '\t' | '\r' | '\n' =>
+        parseNested(state, i + 1, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                  ^^^^^ reference ujson/ByteParser#parseNested().(state)
+//                         ^ reference ujson/ByteParser#parseNested().(i)
+//                           ^ reference scala/Int#`+`(+4).
+//                                ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                           ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+      case '"' =>
+        state match{
+//      ^^^^^ reference ujson/ByteParser#parseNested().(state)
+          case KEY | OBJBEG =>
+//             ^^^ reference ujson/ByteParser#KEY.
+//                   ^^^^^^ reference ujson/ByteParser#OBJBEG.
+            val nextJ = try parseStringKey(i, stackHead) catch reject(i)
+//              ^^^^^ definition local22
+//                          ^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringKey().
+//                                         ^ reference ujson/ByteParser#parseNested().(i)
+//                                            ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                             ^^^^^^ reference ujson/ByteParser#reject().
+//                                                                    ^ reference ujson/ByteParser#parseNested().(i)
+            parseNested(COLON, nextJ, stackHead, stackTail)
+//          ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                      ^^^^^ reference ujson/ByteParser#COLON.
+//                             ^^^^^ reference local22
+//                                    ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                               ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+          case DATA | ARRBEG =>
+//             ^^^^ reference ujson/ByteParser#DATA.
+//                    ^^^^^^ reference ujson/ByteParser#ARRBEG.
+            val nextJ = try parseStringValue(i, stackHead) catch reject(i)
+//              ^^^^^ definition local23
+//                          ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringValue().
+//                                           ^ reference ujson/ByteParser#parseNested().(i)
+//                                              ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                               ^^^^^^ reference ujson/ByteParser#reject().
+//                                                                      ^ reference ujson/ByteParser#parseNested().(i)
+            parseNested(collectionEndFor(stackHead), nextJ, stackHead, stackTail)
+//          ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                      ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().
+//                                       ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                   ^^^^^ reference local23
+//                                                          ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                                     ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#dieWithFailureMessage().
+//                                        ^ reference ujson/ByteParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/ByteParser#parseNested().(state)
+        }
+
+      case ':' =>
+        // we are in an object just after a key, expecting to see a colon.
+        state match{
+//      ^^^^^ reference ujson/ByteParser#parseNested().(state)
+          case COLON => parseNested(DATA, i + 1, stackHead, stackTail)
+//             ^^^^^ reference ujson/ByteParser#COLON.
+//                      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                                  ^^^^ reference ujson/ByteParser#DATA.
+//                                        ^ reference ujson/ByteParser#parseNested().(i)
+//                                          ^ reference scala/Int#`+`(+4).
+//                                               ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                          ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#dieWithFailureMessage().
+//                                        ^ reference ujson/ByteParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/ByteParser#parseNested().(state)
+        }
+
+      case '[' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/ByteParser#failIfNotData().
+//                    ^^^^^ reference ujson/ByteParser#parseNested().(state)
+//                           ^ reference ujson/ByteParser#parseNested().(i)
+        val ctx =
+//          ^^^ definition local24
+          try stackHead.subVisitor.asInstanceOf[Visitor[_, J]].visitArray(-1, i)
+//            ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                      ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                 ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                              ^^^^^^^ reference upickle/core/Visitor#
+//                                                         ^ reference ujson/ByteParser#[J]
+//                                                             ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                                                                            ^ reference ujson/ByteParser#parseNested().(i)
+          catch reject(i)
+//              ^^^^^^ reference ujson/ByteParser#reject().
+//                     ^ reference ujson/ByteParser#parseNested().(i)
+        parseNested(ARRBEG, i + 1, ctx, stackHead :: stackTail)
+//      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                  ^^^^^^ reference ujson/ByteParser#ARRBEG.
+//                          ^ reference ujson/ByteParser#parseNested().(i)
+//                            ^ reference scala/Int#`+`(+4).
+//                                 ^^^ reference local24
+//                                      ^^^^^^^^^ reference local25
+//                                                ^^ reference scala/collection/immutable/List#`::`().
+//                                                   ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+      case '{' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/ByteParser#failIfNotData().
+//                    ^^^^^ reference ujson/ByteParser#parseNested().(state)
+//                           ^ reference ujson/ByteParser#parseNested().(i)
+        val ctx =
+//          ^^^ definition local27
+          try stackHead.subVisitor.asInstanceOf[Visitor[_, J]].visitObject(-1, i)
+//            ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                      ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                 ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                              ^^^^^^^ reference upickle/core/Visitor#
+//                                                         ^ reference ujson/ByteParser#[J]
+//                                                             ^^^^^^^^^^^ reference upickle/core/Visitor#visitObject().
+//                                                                             ^ reference ujson/ByteParser#parseNested().(i)
+          catch reject(i)
+//              ^^^^^^ reference ujson/ByteParser#reject().
+//                     ^ reference ujson/ByteParser#parseNested().(i)
+        parseNested(OBJBEG, i + 1, ctx, stackHead :: stackTail)
+//      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                  ^^^^^^ reference ujson/ByteParser#OBJBEG.
+//                          ^ reference ujson/ByteParser#parseNested().(i)
+//                            ^ reference scala/Int#`+`(+4).
+//                                 ^^^ reference local27
+//                                      ^^^^^^^^^ reference local28
+//                                                ^^ reference scala/collection/immutable/List#`::`().
+//                                                   ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+      case '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/ByteParser#failIfNotData().
+//                    ^^^^^ reference ujson/ByteParser#parseNested().(state)
+//                           ^ reference ujson/ByteParser#parseNested().(i)
+        val ctx =
+//          ^^^ definition local29
+          try parseNum(i, stackHead.narrow, stackHead.subVisitor.asInstanceOf[Visitor[_, J]])
+//            ^^^^^^^^ reference ujson/ByteParser#parseNum().
+//                     ^ reference ujson/ByteParser#parseNested().(i)
+//                        ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                  ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                                          ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                    ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                                               ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                                            ^^^^^^^ reference upickle/core/Visitor#
+//                                                                                       ^ reference ujson/ByteParser#[J]
+          catch reject(i)
+//              ^^^^^^ reference ujson/ByteParser#reject().
+//                     ^ reference ujson/ByteParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), ctx, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                               ^^^ reference local29
+//                                                    ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                               ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+      case 't' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/ByteParser#failIfNotData().
+//                    ^^^^^ reference ujson/ByteParser#parseNested().(state)
+//                           ^ reference ujson/ByteParser#parseNested().(i)
+        try stackHead.narrow.visitValue(
+//          ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                    ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                           ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+          parseTrue(i, stackHead.subVisitor.asInstanceOf[Visitor[_, J]]),
+//        ^^^^^^^^^ reference ujson/ByteParser#parseTrue().
+//                  ^ reference ujson/ByteParser#parseNested().(i)
+//                     ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                               ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                          ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                       ^^^^^^^ reference upickle/core/Visitor#
+//                                                                  ^ reference ujson/ByteParser#[J]
+          i
+//        ^ reference ujson/ByteParser#parseNested().(i)
+        )
+        catch reject(i)
+//            ^^^^^^ reference ujson/ByteParser#reject().
+//                   ^ reference ujson/ByteParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), i + 4, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                               ^ reference ujson/ByteParser#parseNested().(i)
+//                                                 ^ reference scala/Int#`+`(+4).
+//                                                      ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                                 ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+      case 'f' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/ByteParser#failIfNotData().
+//                    ^^^^^ reference ujson/ByteParser#parseNested().(state)
+//                           ^ reference ujson/ByteParser#parseNested().(i)
+        try stackHead.narrow.visitValue(
+//          ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                    ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                           ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+          parseFalse(i, stackHead.subVisitor.asInstanceOf[Visitor[_, J]]),
+//        ^^^^^^^^^^ reference ujson/ByteParser#parseFalse().
+//                   ^ reference ujson/ByteParser#parseNested().(i)
+//                      ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                           ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                        ^^^^^^^ reference upickle/core/Visitor#
+//                                                                   ^ reference ujson/ByteParser#[J]
+          i
+//        ^ reference ujson/ByteParser#parseNested().(i)
+        )
+        catch reject(i)
+//            ^^^^^^ reference ujson/ByteParser#reject().
+//                   ^ reference ujson/ByteParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), i + 5, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                               ^ reference ujson/ByteParser#parseNested().(i)
+//                                                 ^ reference scala/Int#`+`(+4).
+//                                                      ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                                 ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+      case 'n' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/ByteParser#failIfNotData().
+//                    ^^^^^ reference ujson/ByteParser#parseNested().(state)
+//                           ^ reference ujson/ByteParser#parseNested().(i)
+        try stackHead.narrow.visitValue(
+//          ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                    ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                           ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+          parseNull(i, stackHead.subVisitor.asInstanceOf[Visitor[_, J]]),
+//        ^^^^^^^^^ reference ujson/ByteParser#parseNull().
+//                  ^ reference ujson/ByteParser#parseNested().(i)
+//                     ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                               ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                          ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                       ^^^^^^^ reference upickle/core/Visitor#
+//                                                                  ^ reference ujson/ByteParser#[J]
+          i
+//        ^ reference ujson/ByteParser#parseNested().(i)
+        )
+        catch reject(i)
+//            ^^^^^^ reference ujson/ByteParser#reject().
+//                   ^ reference ujson/ByteParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), i + 4, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                               ^ reference ujson/ByteParser#parseNested().(i)
+//                                                 ^ reference scala/Int#`+`(+4).
+//                                                      ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                                 ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+
+      case ',' =>
+        dropBufferUntil(i)
+//      ^^^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#dropBufferUntil().
+//                      ^ reference ujson/ByteParser#parseNested().(i)
+        (state: @switch) match{
+//       ^^^^^ reference ujson/ByteParser#parseNested().(state)
+          case ARREND => parseNested(DATA, i + 1, stackHead, stackTail)
+//             ^^^^^^ reference ujson/ByteParser#ARREND.
+//                       ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                                   ^^^^ reference ujson/ByteParser#DATA.
+//                                         ^ reference ujson/ByteParser#parseNested().(i)
+//                                           ^ reference scala/Int#`+`(+4).
+//                                                ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                           ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+          case OBJEND => parseNested(KEY, i + 1, stackHead, stackTail)
+//             ^^^^^^ reference ujson/ByteParser#OBJEND.
+//                       ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                                   ^^^ reference ujson/ByteParser#KEY.
+//                                        ^ reference ujson/ByteParser#parseNested().(i)
+//                                          ^ reference scala/Int#`+`(+4).
+//                                               ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                                          ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#dieWithFailureMessage().
+//                                        ^ reference ujson/ByteParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/ByteParser#parseNested().(state)
+        }
+
+      case ']' =>
+        (state: @switch) match{
+//       ^^^^^ reference ujson/ByteParser#parseNested().(state)
+          case ARREND | ARRBEG =>
+//             ^^^^^^ reference ujson/ByteParser#ARREND.
+//                      ^^^^^^ reference ujson/ByteParser#ARRBEG.
+            tryCloseCollection(stackHead, stackTail, i) match{
+//          ^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#tryCloseCollection().
+//                             ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                        ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+//                                                   ^ reference ujson/ByteParser#parseNested().(i)
+              case Some(t) => t
+//                 ^^^^ reference scala/Some.
+//                      ^ definition local30
+//                            ^ reference local30
+              case None =>
+//                 ^^^^ reference scala/None.
+                val stackTailHead = stackTail.head
+//                  ^^^^^^^^^^^^^ definition local31
+//                                  ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+//                                            ^^^^ reference scala/collection/IterableOps#head().
+                parseNested(collectionEndFor(stackTailHead), i + 1, stackTailHead, stackTail.tail)
+//              ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                          ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().
+//                                           ^^^^^^^^^^^^^ reference local31
+//                                                           ^ reference ujson/ByteParser#parseNested().(i)
+//                                                             ^ reference scala/Int#`+`(+4).
+//                                                                  ^^^^^^^^^^^^^ reference local31
+//                                                                                 ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+//                                                                                           ^^^^ reference scala/collection/IterableOps#tail().
+            }
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#dieWithFailureMessage().
+//                                        ^ reference ujson/ByteParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/ByteParser#parseNested().(state)
+        }
+
+      case '}' =>
+        (state: @switch) match{
+//       ^^^^^ reference ujson/ByteParser#parseNested().(state)
+          case OBJEND | OBJBEG =>
+//             ^^^^^^ reference ujson/ByteParser#OBJEND.
+//                      ^^^^^^ reference ujson/ByteParser#OBJBEG.
+            tryCloseCollection(stackHead, stackTail, i) match{
+//          ^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#tryCloseCollection().
+//                             ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackHead)
+//                                        ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+//                                                   ^ reference ujson/ByteParser#parseNested().(i)
+              case Some(t) => t
+//                 ^^^^ reference scala/Some.
+//                      ^ definition local32
+//                            ^ reference local32
+              case None =>
+//                 ^^^^ reference scala/None.
+                val stackTailHead = stackTail.head
+//                  ^^^^^^^^^^^^^ definition local33
+//                                  ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+//                                            ^^^^ reference scala/collection/IterableOps#head().
+                parseNested(collectionEndFor(stackTailHead), i + 1, stackTailHead, stackTail.tail)
+//              ^^^^^^^^^^^ reference ujson/ByteParser#parseNested().
+//                          ^^^^^^^^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().
+//                                           ^^^^^^^^^^^^^ reference local33
+//                                                           ^ reference ujson/ByteParser#parseNested().(i)
+//                                                             ^ reference scala/Int#`+`(+4).
+//                                                                  ^^^^^^^^^^^^^ reference local33
+//                                                                                 ^^^^^^^^^ reference ujson/ByteParser#parseNested().(stackTail)
+//                                                                                           ^^^^ reference scala/collection/IterableOps#tail().
+            }
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#dieWithFailureMessage().
+//                                        ^ reference ujson/ByteParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/ByteParser#parseNested().(state)
+        }
+      case _ => dieWithFailureMessage(i, state)
+//              ^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#dieWithFailureMessage().
+//                                    ^ reference ujson/ByteParser#parseNested().(i)
+//                                       ^^^^^ reference ujson/ByteParser#parseNested().(state)
+
+    }
+  }
+
+
+  def dieWithFailureMessage(i: Int, state: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#dieWithFailureMessage().
+//                          ^ definition ujson/ByteParser#dieWithFailureMessage().(i)
+//                             ^^^ reference scala/Int#
+//                                  ^^^^^ definition ujson/ByteParser#dieWithFailureMessage().(state)
+//                                         ^^^ reference scala/Int#
+    val expected = state match{
+//      ^^^^^^^^ definition local34
+//                 ^^^^^ reference ujson/ByteParser#dieWithFailureMessage().(state)
+      case ARRBEG => "json value or ]"
+//         ^^^^^^ reference ujson/ByteParser#ARRBEG.
+      case OBJBEG => "json value or }"
+//         ^^^^^^ reference ujson/ByteParser#OBJBEG.
+      case DATA => "json value"
+//         ^^^^ reference ujson/ByteParser#DATA.
+      case KEY => "json string key"
+//         ^^^ reference ujson/ByteParser#KEY.
+      case COLON => ":"
+//         ^^^^^ reference ujson/ByteParser#COLON.
+      case ARREND => ", or ]"
+//         ^^^^^^ reference ujson/ByteParser#ARREND.
+      case OBJEND => ", or }"
+//         ^^^^^^ reference ujson/ByteParser#OBJEND.
+    }
+    die(i, s"expected $expected")
+//  ^^^ reference ujson/ByteParser#die().
+//      ^ reference ujson/ByteParser#dieWithFailureMessage().(i)
+//         ^ reference scala/StringContext#s().
+//                     ^^^^^^^^ reference local34
+  }
+
+  def failIfNotData(state: Int, i: Int) = (state: @switch) match{
+//    ^^^^^^^^^^^^^ definition ujson/ByteParser#failIfNotData().
+//                  ^^^^^ definition ujson/ByteParser#failIfNotData().(state)
+//                         ^^^ reference scala/Int#
+//                              ^ definition ujson/ByteParser#failIfNotData().(i)
+//                                 ^^^ reference scala/Int#
+//                                         ^^^^^ reference ujson/ByteParser#failIfNotData().(state)
+    case DATA | ARRBEG => // do nothing
+//       ^^^^ reference ujson/ByteParser#DATA.
+//              ^^^^^^ reference ujson/ByteParser#ARRBEG.
+    case _ => dieWithFailureMessage(i, state)
+//            ^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#dieWithFailureMessage().
+//                                  ^ reference ujson/ByteParser#failIfNotData().(i)
+//                                     ^^^^^ reference ujson/ByteParser#failIfNotData().(state)
+  }
+
+  def tryCloseCollection(stackHead: ObjArrVisitor[_, J], stackTail: List[ObjArrVisitor[_, J]], i: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#tryCloseCollection().
+//                       ^^^^^^^^^ definition ujson/ByteParser#tryCloseCollection().(stackHead)
+//                                  ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                   ^ reference ujson/ByteParser#[J]
+//                                                       ^^^^^^^^^ definition ujson/ByteParser#tryCloseCollection().(stackTail)
+//                                                                  ^^^^ reference scala/package.List#
+//                                                                       ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                                        ^ reference ujson/ByteParser#[J]
+//                                                                                             ^ definition ujson/ByteParser#tryCloseCollection().(i)
+//                                                                                                ^^^ reference scala/Int#
+    if (stackTail.isEmpty) {
+//      ^^^^^^^^^ reference ujson/ByteParser#tryCloseCollection().(stackTail)
+//                ^^^^^^^ reference scala/collection/immutable/List#isEmpty().
+      Some(try stackHead.visitEnd(i) catch reject(i), i + 1)
+//    ^^^^ reference scala/Some.
+//             ^^^^^^^^^ reference ujson/ByteParser#tryCloseCollection().(stackHead)
+//                       ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+//                                ^ reference ujson/ByteParser#tryCloseCollection().(i)
+//                                         ^^^^^^ reference ujson/ByteParser#reject().
+//                                                ^ reference ujson/ByteParser#tryCloseCollection().(i)
+//                                                    ^ reference ujson/ByteParser#tryCloseCollection().(i)
+//                                                      ^ reference scala/Int#`+`(+4).
+    } else {
+      val ctxt2 = stackTail.head.narrow
+//        ^^^^^ definition local35
+//                ^^^^^^^^^ reference ujson/ByteParser#tryCloseCollection().(stackTail)
+//                          ^^^^ reference scala/collection/IterableOps#head().
+//                               ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+      try ctxt2.visitValue(stackHead.visitEnd(i), i) catch reject(i)
+//        ^^^^^ reference local35
+//              ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                         ^^^^^^^^^ reference ujson/ByteParser#tryCloseCollection().(stackHead)
+//                                   ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+//                                            ^ reference ujson/ByteParser#tryCloseCollection().(i)
+//                                                ^ reference ujson/ByteParser#tryCloseCollection().(i)
+//                                                         ^^^^^^ reference ujson/ByteParser#reject().
+//                                                                ^ reference ujson/ByteParser#tryCloseCollection().(i)
+      None
+//    ^^^^ reference scala/None.
+
+    }
+  }
+  def collectionEndFor(stackHead: ObjArrVisitor[_, _]) = {
+//    ^^^^^^^^^^^^^^^^ definition ujson/ByteParser#collectionEndFor().
+//                     ^^^^^^^^^ definition ujson/ByteParser#collectionEndFor().(stackHead)
+//                                ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+    if (stackHead.isObj) OBJEND
+//      ^^^^^^^^^ reference ujson/ByteParser#collectionEndFor().(stackHead)
+//                ^^^^^ reference upickle/core/ObjArrVisitor#isObj().
+//                       ^^^^^^ reference ujson/ByteParser#OBJEND.
+    else ARREND
+//       ^^^^^^ reference ujson/ByteParser#ARREND.
+  }
+
+  /**
+    * See if the string has any escape sequences. If not, return the
+    * end of the string. If so, bail out and return -1.
+    *
+    * This method expects the data to be in UTF-16 and accesses it as
+    * chars.
+    */
+  protected[this] final def parseStringSimple(i: Int): Int = {
+//                          ^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#parseStringSimple().
+//                                            ^ definition ujson/ByteParser#parseStringSimple().(i)
+//                                               ^^^ reference scala/Int#
+//                                                     ^^^ reference scala/Int#
+    var j = i
+//      ^ definition local36
+//          ^ reference ujson/ByteParser#parseStringSimple().(i)
+    var c = elemOps.toUnsignedInt(getByteSafe(j))
+//      ^ definition local37
+//          ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                  ^^^^^^^^^^^^^ reference upickle/core/ByteOps.toUnsignedInt().
+//                                ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                            ^ reference local36
+    while (c != '"') {
+//         ^ reference local37
+//           ^^ reference scala/Int#`!=`(+2).
+      if (c < ' ') die(j, s"control char (${c}) in string")
+//        ^ reference local37
+//          ^ reference scala/Int#`<`(+2).
+//                 ^^^ reference ujson/ByteParser#die().
+//                     ^ reference local36
+//                        ^ reference scala/StringContext#s().
+//                                          ^ reference local37
+      if (c == '\\' || c > 127) return -1 - j
+//        ^ reference local37
+//          ^^ reference scala/Int#`==`(+2).
+//                  ^^ reference scala/Boolean#`||`().
+//                     ^ reference local37
+//                       ^ reference scala/Int#`>`(+3).
+//                                        ^ reference scala/Int#`-`(+3).
+//                                          ^ reference local36
+      j += 1
+//    ^ reference local36
+//      ^^ reference scala/Int#`+`(+4).
+      c = elemOps.toUnsignedInt(getByteSafe(j))
+//    ^ reference local37
+//        ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                ^^^^^^^^^^^^^ reference upickle/core/ByteOps.toUnsignedInt().
+//                              ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                          ^ reference local36
+    }
+    j + 1
+//  ^ reference local36
+//    ^ reference scala/Int#`+`(+4).
+  }
+
+  /**
+    * Parse a string that is known to have escape sequences.
+    */
+  protected[this] final def parseStringComplex(i0: Int): Int = {
+//                          ^^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#parseStringComplex().
+//                                             ^^ definition ujson/ByteParser#parseStringComplex().(i0)
+//                                                 ^^^ reference scala/Int#
+//                                                       ^^^ reference scala/Int#
+    var i = i0
+//      ^ definition local38
+//          ^^ reference ujson/ByteParser#parseStringComplex().(i0)
+    var c = elemOps.toUnsignedInt(getByteSafe(i))
+//      ^ definition local39
+//          ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                  ^^^^^^^^^^^^^ reference upickle/core/ByteOps.toUnsignedInt().
+//                                ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                            ^ reference local38
+    while (c != '"') {
+//         ^ reference local39
+//           ^^ reference scala/Int#`!=`(+2).
+
+      if (c < ' ') die(i, s"control char (${c}) in string")
+//        ^ reference local39
+//          ^ reference scala/Int#`<`(+2).
+//                 ^^^ reference ujson/ByteParser#die().
+//                     ^ reference local38
+//                        ^ reference scala/StringContext#s().
+//                                          ^ reference local39
+      else if (c == '\\') {
+//             ^ reference local39
+//               ^^ reference scala/Int#`==`(+2).
+        (getByteSafe(i + 1): @switch) match {
+//       ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                   ^ reference local38
+//                     ^ reference scala/Int#`+`(+4).
+          case 'b' => { outputBuilder.append('\b'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 'f' => { outputBuilder.append('\f'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 'n' => { outputBuilder.append('\n'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 'r' => { outputBuilder.append('\r'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 't' => { outputBuilder.append('\t'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+
+          case '"' => { outputBuilder.append('"'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                 ^ reference local38
+//                                                   ^^ reference scala/Int#`+`(+4).
+          case '/' => { outputBuilder.append('/'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                 ^ reference local38
+//                                                   ^^ reference scala/Int#`+`(+4).
+          case '\\' => { outputBuilder.append('\\'); i += 2 }
+//                       ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                     ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                                                   ^ reference local38
+//                                                     ^^ reference scala/Int#`+`(+4).
+
+          // if there's a problem then descape will explode
+          case 'u' =>
+            val d = descape(i)
+//              ^ definition local40
+//                  ^^^^^^^ reference ujson/ByteParser#descape().
+//                          ^ reference local38
+            outputBuilder.appendC(d)
+//          ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                        ^^^^^^^ reference upickle/core/ByteAppendC#appendC().
+//                                ^ reference local40
+
+            i += 6
+//          ^ reference local38
+//            ^^ reference scala/Int#`+`(+4).
+
+          case c => die(i + 1, s"illegal escape sequence after \\")
+//             ^ definition local41
+//                  ^^^ reference ujson/ByteParser#die().
+//                      ^ reference local38
+//                        ^ reference scala/Int#`+`(+4).
+//                             ^ reference scala/StringContext#s().
+        }
+      } else {
+        // this case is for "normal" code points that are just one Char.
+        //
+        // we don't have to worry about surrogate pairs, since those
+        // will all be in the ranges D800–DBFF (high surrogates) or
+        // DC00–DFFF (low surrogates).
+        outputBuilder.append(c)
+//      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                    ^^^^^^ reference upickle/core/ByteBuilder#append().
+//                           ^ reference local39
+        i += 1
+//      ^ reference local38
+//        ^^ reference scala/Int#`+`(+4).
+      }
+      c = elemOps.toUnsignedInt(getByteSafe(i))
+//    ^ reference local39
+//        ^^^^^^^ reference ujson/ByteParser#elemOps.
+//                ^^^^^^^^^^^^^ reference upickle/core/ByteOps.toUnsignedInt().
+//                              ^^^^^^^^^^^ reference ujson/ByteParser#getByteSafe().
+//                                          ^ reference local38
+    }
+
+    i + 1
+//  ^ reference local38
+//    ^ reference scala/Int#`+`(+4).
+  }
+
+  /**
+    * Parse the string according to JSON rules, and add to the given
+    * context.
+    *
+    * This method expects the data to be in UTF-16, and access it as
+    * Char. It performs the correct checks to make sure that we don't
+    * interpret a multi-char code point incorrectly.
+    */
+  protected[this] final def parseStringValue(i: Int, stackHead: ObjArrVisitor[_, J]): Int = {
+//                          ^^^^^^^^^^^^^^^^ definition ujson/ByteParser#parseStringValue().
+//                                           ^ definition ujson/ByteParser#parseStringValue().(i)
+//                                              ^^^ reference scala/Int#
+//                                                   ^^^^^^^^^ definition ujson/ByteParser#parseStringValue().(stackHead)
+//                                                              ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                               ^ reference ujson/ByteParser#[J]
+//                                                                                    ^^^ reference scala/Int#
+
+    val k = parseStringSimple(i + 1)
+//      ^ definition local42
+//          ^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringSimple().
+//                            ^ reference ujson/ByteParser#parseStringValue().(i)
+//                              ^ reference scala/Int#`+`(+4).
+    if (k >= 0) {
+//      ^ reference local42
+//        ^^ reference scala/Int#`>=`(+3).
+      visitString(i, unsafeCharSeqForRange(i + 1, k - i - 2), stackHead)
+//    ^^^^^^^^^^^ reference ujson/ByteParser#visitString().
+//                ^ reference ujson/ByteParser#parseStringValue().(i)
+//                   ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#unsafeCharSeqForRange().
+//                                         ^ reference ujson/ByteParser#parseStringValue().(i)
+//                                           ^ reference scala/Int#`+`(+4).
+//                                                ^ reference local42
+//                                                  ^ reference scala/Int#`-`(+3).
+//                                                    ^ reference ujson/ByteParser#parseStringValue().(i)
+//                                                      ^ reference scala/Int#`-`(+3).
+//                                                            ^^^^^^^^^ reference ujson/ByteParser#parseStringValue().(stackHead)
+      k
+//    ^ reference local42
+    } else {
+      val k2 = parseStringToOutputBuilder(i, k)
+//        ^^ definition local43
+//             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringToOutputBuilder().
+//                                        ^ reference ujson/ByteParser#parseStringValue().(i)
+//                                           ^ reference local42
+      visitString(i, outputBuilder.makeString(), stackHead)
+//    ^^^^^^^^^^^ reference ujson/ByteParser#visitString().
+//                ^ reference ujson/ByteParser#parseStringValue().(i)
+//                   ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                 ^^^^^^^^^^ reference upickle/core/ByteBuilder#makeString().
+//                                               ^^^^^^^^^ reference ujson/ByteParser#parseStringValue().(stackHead)
+      k2
+//    ^^ reference local43
+    }
+  }
+
+  protected[this] final def parseStringKey(i: Int, stackHead: ObjArrVisitor[_, J]): Int = {
+//                          ^^^^^^^^^^^^^^ definition ujson/ByteParser#parseStringKey().
+//                                         ^ definition ujson/ByteParser#parseStringKey().(i)
+//                                            ^^^ reference scala/Int#
+//                                                 ^^^^^^^^^ definition ujson/ByteParser#parseStringKey().(stackHead)
+//                                                            ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                             ^ reference ujson/ByteParser#[J]
+//                                                                                  ^^^ reference scala/Int#
+
+    val k = parseStringSimple(i + 1)
+//      ^ definition local44
+//          ^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringSimple().
+//                            ^ reference ujson/ByteParser#parseStringKey().(i)
+//                              ^ reference scala/Int#`+`(+4).
+    if (k >= 0) {
+//      ^ reference local44
+//        ^^ reference scala/Int#`>=`(+3).
+      visitStringKey(i, unsafeCharSeqForRange(i + 1, k - i - 2), stackHead)
+//    ^^^^^^^^^^^^^^ reference ujson/ByteParser#visitStringKey().
+//                   ^ reference ujson/ByteParser#parseStringKey().(i)
+//                      ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#unsafeCharSeqForRange().
+//                                            ^ reference ujson/ByteParser#parseStringKey().(i)
+//                                              ^ reference scala/Int#`+`(+4).
+//                                                   ^ reference local44
+//                                                     ^ reference scala/Int#`-`(+3).
+//                                                       ^ reference ujson/ByteParser#parseStringKey().(i)
+//                                                         ^ reference scala/Int#`-`(+3).
+//                                                               ^^^^^^^^^ reference ujson/ByteParser#parseStringKey().(stackHead)
+      k
+//    ^ reference local44
+    } else {
+      val k2 = parseStringToOutputBuilder(i, k)
+//        ^^ definition local45
+//             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringToOutputBuilder().
+//                                        ^ reference ujson/ByteParser#parseStringKey().(i)
+//                                           ^ reference local44
+      visitStringKey(i, outputBuilder.makeString(), stackHead)
+//    ^^^^^^^^^^^^^^ reference ujson/ByteParser#visitStringKey().
+//                   ^ reference ujson/ByteParser#parseStringKey().(i)
+//                      ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                    ^^^^^^^^^^ reference upickle/core/ByteBuilder#makeString().
+//                                                  ^^^^^^^^^ reference ujson/ByteParser#parseStringKey().(stackHead)
+      k2
+//    ^^ reference local45
+    }
+  }
+
+
+  def parseStringToOutputBuilder(i: Int, k: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#parseStringToOutputBuilder().
+//                               ^ definition ujson/ByteParser#parseStringToOutputBuilder().(i)
+//                                  ^^^ reference scala/Int#
+//                                       ^ definition ujson/ByteParser#parseStringToOutputBuilder().(k)
+//                                          ^^^ reference scala/Int#
+    outputBuilder.reset()
+//  ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                ^^^^^ reference upickle/core/ByteBuilder#reset().
+    appendBytesToBuilder(outputBuilder, i + 1, -k - 2 - i)
+//  ^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#appendBytesToBuilder().
+//                       ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                      ^ reference ujson/ByteParser#parseStringToOutputBuilder().(i)
+//                                        ^ reference scala/Int#`+`(+4).
+//                                             ^ reference scala/Int#`unary_-`().
+//                                              ^ reference ujson/ByteParser#parseStringToOutputBuilder().(k)
+//                                                ^ reference scala/Int#`-`(+3).
+//                                                    ^ reference scala/Int#`-`(+3).
+//                                                      ^ reference ujson/ByteParser#parseStringToOutputBuilder().(i)
+    val k2 = parseStringComplex(-k - 1)
+//      ^^ definition local46
+//           ^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringComplex().
+//                              ^ reference scala/Int#`unary_-`().
+//                               ^ reference ujson/ByteParser#parseStringToOutputBuilder().(k)
+//                                 ^ reference scala/Int#`-`(+3).
+    k2
+//  ^^ reference local46
+  }
+
+  def visitString(i: Int, s: CharSequence, stackHead: ObjArrVisitor[_, J]) = {
+//    ^^^^^^^^^^^ definition ujson/ByteParser#visitString().
+//                ^ definition ujson/ByteParser#visitString().(i)
+//                   ^^^ reference scala/Int#
+//                        ^ definition ujson/ByteParser#visitString().(s)
+//                           ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                         ^^^^^^^^^ definition ujson/ByteParser#visitString().(stackHead)
+//                                                    ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                     ^ reference ujson/ByteParser#[J]
+    val v = stackHead.subVisitor.visitString(s, i)
+//      ^ definition local47
+//          ^^^^^^^^^ reference ujson/ByteParser#visitString().(stackHead)
+//                    ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                               ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                           ^ reference ujson/ByteParser#visitString().(s)
+//                                              ^ reference ujson/ByteParser#visitString().(i)
+    stackHead.narrow.visitValue(v, i)
+//  ^^^^^^^^^ reference ujson/ByteParser#visitString().(stackHead)
+//            ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                   ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                              ^ reference local47
+//                                 ^ reference ujson/ByteParser#visitString().(i)
+  }
+  def visitStringKey(i: Int, s: CharSequence, stackHead: ObjArrVisitor[_, J]) = {
+//    ^^^^^^^^^^^^^^ definition ujson/ByteParser#visitStringKey().
+//                   ^ definition ujson/ByteParser#visitStringKey().(i)
+//                      ^^^ reference scala/Int#
+//                           ^ definition ujson/ByteParser#visitStringKey().(s)
+//                              ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                            ^^^^^^^^^ definition ujson/ByteParser#visitStringKey().(stackHead)
+//                                                       ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                        ^ reference ujson/ByteParser#[J]
+    val obj = stackHead.asInstanceOf[ObjVisitor[Any, _]]
+//      ^^^ definition local48
+//            ^^^^^^^^^ reference ujson/ByteParser#visitStringKey().(stackHead)
+//                      ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                   ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                              ^^^ reference scala/Any#
+    val keyVisitor = obj.visitKey(i)
+//      ^^^^^^^^^^ definition local49
+//                   ^^^ reference local48
+//                       ^^^^^^^^ reference upickle/core/ObjVisitor#visitKey().
+//                                ^ reference ujson/ByteParser#visitStringKey().(i)
+    obj.visitKeyValue(keyVisitor.visitString(s, i))
+//  ^^^ reference local48
+//      ^^^^^^^^^^^^^ reference upickle/core/ObjVisitor#visitKeyValue().
+//                    ^^^^^^^^^^ reference local49
+//                               ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                           ^ reference ujson/ByteParser#visitStringKey().(s)
+//                                              ^ reference ujson/ByteParser#visitStringKey().(i)
+  }
+
+
+  protected[this] final def parseStringTopLevel(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^^^^^^^ definition ujson/ByteParser#parseStringTopLevel().
+//                                              ^ definition ujson/ByteParser#parseStringTopLevel().(i)
+//                                                 ^^^ reference scala/Int#
+//                                                      ^^^^^^ definition ujson/ByteParser#parseStringTopLevel().(facade)
+//                                                              ^^^^^^^ reference upickle/core/Visitor#
+//                                                                         ^ reference ujson/ByteParser#[J]
+//                                                                               ^ reference ujson/ByteParser#[J]
+//                                                                                  ^^^ reference scala/Int#
+
+    val k = parseStringSimple(i + 1)
+//      ^ definition local50
+//          ^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringSimple().
+//                            ^ reference ujson/ByteParser#parseStringTopLevel().(i)
+//                              ^ reference scala/Int#`+`(+4).
+    if (k >= 0) {
+//      ^ reference local50
+//        ^^ reference scala/Int#`>=`(+3).
+      val res = facade.visitString(unsafeCharSeqForRange(i + 1, k - i - 2), i)
+//        ^^^ definition local51
+//              ^^^^^^ reference ujson/ByteParser#parseStringTopLevel().(facade)
+//                     ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                 ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingByteParser#unsafeCharSeqForRange().
+//                                                       ^ reference ujson/ByteParser#parseStringTopLevel().(i)
+//                                                         ^ reference scala/Int#`+`(+4).
+//                                                              ^ reference local50
+//                                                                ^ reference scala/Int#`-`(+3).
+//                                                                  ^ reference ujson/ByteParser#parseStringTopLevel().(i)
+//                                                                    ^ reference scala/Int#`-`(+3).
+//                                                                          ^ reference ujson/ByteParser#parseStringTopLevel().(i)
+      (res, k)
+//     ^^^ reference local51
+//          ^ reference local50
+    } else {
+      val k2 = parseStringToOutputBuilder(i, k)
+//        ^^ definition local52
+//             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ByteParser#parseStringToOutputBuilder().
+//                                        ^ reference ujson/ByteParser#parseStringTopLevel().(i)
+//                                           ^ reference local50
+      val res = facade.visitString(outputBuilder.makeString(), i)
+//        ^^^ definition local53
+//              ^^^^^^ reference ujson/ByteParser#parseStringTopLevel().(facade)
+//                     ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                 ^^^^^^^^^^^^^ reference ujson/ByteParser#outputBuilder.
+//                                               ^^^^^^^^^^ reference upickle/core/ByteBuilder#makeString().
+//                                                             ^ reference ujson/ByteParser#parseStringTopLevel().(i)
+      (res, k2)
+//     ^^^ reference local53
+//          ^^ reference local52
+    }
+  }
+}
diff --git a/tests/snapshots/src/main/generated/CharParser.scala b/tests/snapshots/src/main/generated/CharParser.scala
new file mode 100644
index 000000000..079f80c82
--- /dev/null
+++ b/tests/snapshots/src/main/generated/CharParser.scala
@@ -0,0 +1,1930 @@
+package ujson
+//      ^^^^^ definition ujson/
+import java.io.StringWriter
+//     ^^^^ reference java/
+//          ^^ reference java/io/
+//             ^^^^^^^^^^^^ reference java/io/StringWriter#
+
+import upickle.core.{Abort, AbortException, ObjArrVisitor, ObjVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^ reference upickle/core/Abort.
+//                   ^^^^^ reference upickle/core/Abort#
+//                          ^^^^^^^^^^^^^^ reference upickle/core/AbortException.
+//                          ^^^^^^^^^^^^^^ reference upickle/core/AbortException#
+//                                          ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                         ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                                                     ^^^^^^^ reference upickle/core/Visitor.
+//                                                                     ^^^^^^^ reference upickle/core/Visitor#
+import java.nio.charset.Charset
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^ reference java/nio/charset/
+//                      ^^^^^^^ reference java/nio/charset/Charset#
+
+
+import scala.annotation.{switch, tailrec}
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                       ^^^^^^ reference scala/annotation/switch#
+//                               ^^^^^^^ reference scala/annotation/tailrec#
+
+/**
+  * A specialized JSON parse that can parse Chars (Chars or Bytes), sending
+  * method calls to the given [[upickle.core.Visitor]].
+  *
+  * Generally has a lot of tricks for performance: e.g. having duplicate
+  * implementations for nested v.s. top-level parsing, using an `CharBuilder`
+  * to construct the `CharSequences` that `visitString` requires, etc.
+  */
+abstract class CharParser[J] extends upickle.core.BufferingCharParser{
+//             ^^^^^^^^^^ definition ujson/CharParser#
+//                        ^ definition ujson/CharParser#[J]
+//                            definition ujson/CharParser#`<init>`().
+//                                   ^^^^^^^ reference upickle/
+//                                           ^^^^ reference upickle/core/
+//                                                ^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#
+  private[this] val elemOps = upickle.core.CharOps
+//                  ^^^^^^^ definition ujson/CharParser#elemOps.
+//                            ^^^^^^^ reference upickle/
+//                                    ^^^^ reference upickle/core/
+//                                         ^^^^^^^ reference upickle/core/CharOps.
+  private[this] val outputBuilder = new upickle.core.CharBuilder()
+//                  ^^^^^^^^^^^^^ definition ujson/CharParser#outputBuilder.
+//                                      ^^^^^^^ reference upickle/
+//                                              ^^^^ reference upickle/core/
+//                                                   ^^^^^^^^^^^ reference upickle/core/CharBuilder#
+//                                                               reference upickle/core/CharBuilder#`<init>`().
+
+  def requestUntilOrThrow(i: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^ definition ujson/CharParser#requestUntilOrThrow().
+//                        ^ definition ujson/CharParser#requestUntilOrThrow().(i)
+//                           ^^^ reference scala/Int#
+    if (requestUntil(i)) throw new IncompleteParseException("exhausted input")
+//      ^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#requestUntil().
+//                   ^ reference ujson/CharParser#requestUntilOrThrow().(i)
+//                                 ^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/IncompleteParseException#
+//                                                          reference ujson/IncompleteParseException#`<init>`().
+  }
+  override def getCharSafe(i: Int): Char = {
+//             ^^^^^^^^^^^ definition ujson/CharParser#getCharSafe().
+//                         ^ definition ujson/CharParser#getCharSafe().(i)
+//                            ^^^ reference scala/Int#
+//                                  ^^^^ reference scala/Char#
+    requestUntilOrThrow(i)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#requestUntilOrThrow().
+//                      ^ reference ujson/CharParser#getCharSafe().(i)
+    getCharUnsafe(i)
+//  ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                ^ reference ujson/CharParser#getCharSafe().(i)
+  }
+
+  /**
+   * Return true iff 'i' is at or beyond the end of the input (EOF).
+   */
+  protected[this] def atEof(i: Int) = requestUntil(i)
+//                    ^^^^^ definition ujson/CharParser#atEof().
+//                          ^ definition ujson/CharParser#atEof().(i)
+//                             ^^^ reference scala/Int#
+//                                    ^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#requestUntil().
+//                                                 ^ reference ujson/CharParser#atEof().(i)
+
+  /**
+   * Should be called when parsing is finished.
+   */
+  protected[this] def close(): Unit
+//                    ^^^^^ definition ujson/CharParser#close().
+//                             ^^^^ reference scala/Unit#
+
+  /**
+   * Valid parser states.
+   */
+  @inline private[this] final val ARRBEG = 6
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/CharParser#ARRBEG.
+  @inline private[this] final val OBJBEG = 7
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/CharParser#OBJBEG.
+  @inline private[this] final val DATA = 1
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^ definition ujson/CharParser#DATA.
+  @inline private[this] final val KEY = 2
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^ definition ujson/CharParser#KEY.
+  @inline private[this] final val COLON = 3
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^ definition ujson/CharParser#COLON.
+  @inline private[this] final val ARREND = 4
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/CharParser#ARREND.
+  @inline private[this] final val OBJEND = 5
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//                                ^^^^^^ definition ujson/CharParser#OBJEND.
+
+  /**
+    * Parse the JSON document into a single JSON value.
+    *
+    * The parser considers documents like '333', 'true', and '"foo"' to be
+    * valid, as well as more traditional documents like [1,2,3,4,5]. However,
+    * multiple top-level objects are not allowed.
+    */
+  final def parse(facade: Visitor[_, J]): J = {
+//          ^^^^^ definition ujson/CharParser#parse().
+//                ^^^^^^ definition ujson/CharParser#parse().(facade)
+//                        ^^^^^^^ reference upickle/core/Visitor#
+//                                   ^ reference ujson/CharParser#[J]
+//                                        ^ reference ujson/CharParser#[J]
+    val (value, i) = parseTopLevel(0, facade)
+//       ^^^^^ definition local0
+//              ^ definition local1
+//                   ^^^^^^^^^^^^^ reference ujson/CharParser#parseTopLevel().
+//                                    ^^^^^^ reference ujson/CharParser#parse().(facade)
+    var j = i
+//      ^ definition local3
+//          ^ reference local1
+    while (!atEof(j)) {
+//         ^ reference scala/Boolean#`unary_!`().
+//          ^^^^^ reference ujson/CharParser#atEof().
+//                ^ reference local3
+      (getCharSafe(j): @switch) match {
+//     ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                 ^ reference local3
+        case '\n' | ' ' | '\t' | '\r' => j += 1
+//                                       ^ reference local3
+//                                         ^^ reference scala/Int#`+`(+4).
+        case _ => die(j, "expected whitespace or eof")
+//                ^^^ reference ujson/CharParser#die().
+//                    ^ reference local3
+      }
+    }
+    if (!atEof(j)) die(j, "expected eof")
+//      ^ reference scala/Boolean#`unary_!`().
+//       ^^^^^ reference ujson/CharParser#atEof().
+//             ^ reference local3
+//                 ^^^ reference ujson/CharParser#die().
+//                     ^ reference local3
+    close()
+//  ^^^^^ reference ujson/CharParser#close().
+    value
+//  ^^^^^ reference local0
+  }
+
+  /**
+   * Used to generate error messages with character info and offsets.
+   */
+  protected[this] def die(i: Int, msg: String): Nothing = {
+//                    ^^^ definition ujson/CharParser#die().
+//                        ^ definition ujson/CharParser#die().(i)
+//                           ^^^ reference scala/Int#
+//                                ^^^ definition ujson/CharParser#die().(msg)
+//                                     ^^^^^^ reference scala/Predef.String#
+//                                              ^^^^^^^ reference scala/Nothing#
+    val out = new upickle.core.CharBuilder()
+//      ^^^ definition local4
+//                ^^^^^^^ reference upickle/
+//                        ^^^^ reference upickle/core/
+//                             ^^^^^^^^^^^ reference upickle/core/CharBuilder#
+//                                         reference upickle/core/CharBuilder#`<init>`().
+    upickle.core.RenderUtils.escapeChar(
+//  ^^^^^^^ reference upickle/
+//          ^^^^ reference upickle/core/
+//               ^^^^^^^^^^^ reference upickle/core/RenderUtils.
+//                           ^^^^^^^^^^ reference upickle/core/RenderUtils.escapeChar().
+      new upickle.core.CharBuilder(),
+//        ^^^^^^^ reference upickle/
+//                ^^^^ reference upickle/core/
+//                     ^^^^^^^^^^^ reference upickle/core/CharBuilder#
+//                                 reference upickle/core/CharBuilder#`<init>`().
+      out,
+//    ^^^ reference local4
+      new ArrayCharSequence(Array(elemOps.toInt(getCharSafe(i)).toChar)),
+//        ^^^^^^^^^^^^^^^^^ reference scala/Predef.ArrayCharSequence#
+//                          reference scala/Predef.ArrayCharSequence#`<init>`().
+//                          ^^^^^ reference scala/Array.
+//                                ^^^^^^^ reference ujson/CharParser#elemOps.
+//                                        ^^^^^ reference upickle/core/CharOps.toInt().
+//                                              ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                                          ^ reference ujson/CharParser#die().(i)
+//                                                              ^^^^^^ reference scala/Int#toChar().
+      unicode = false
+//    ^^^^^^^ reference upickle/core/RenderUtils.escapeChar().(unicode)
+    )
+    val s = "%s got %s" format (msg, out.makeString())
+//      ^ definition local5
+//                      ^^^^^^ reference scala/collection/StringOps#format().
+//                              ^^^ reference ujson/CharParser#die().(msg)
+//                                   ^^^ reference local4
+//                                       ^^^^^^^^^^ reference upickle/core/CharBuilder#makeString().
+    throw ParseException(s, i)
+//        ^^^^^^^^^^^^^^ reference ujson/ParseException.
+//                       ^ reference local5
+//                          ^ reference ujson/CharParser#die().(i)
+  }
+
+
+  /**
+   * Parse the given number, and add it to the given context.
+   *
+   * We don't actually instantiate a number here, but rather pass the
+   * string of for future use. Facades can choose to be lazy and just
+   * store the string. This ends up being way faster and has the nice
+   * side-effect that we know exactly how the user represented the
+   * number.
+   */
+  protected[this] final def parseNum(i: Int, ctxt: ObjArrVisitor[Any, J], facade: Visitor[_, J]): Int = {
+//                          ^^^^^^^^ definition ujson/CharParser#parseNum().
+//                                   ^ definition ujson/CharParser#parseNum().(i)
+//                                      ^^^ reference scala/Int#
+//                                           ^^^^ definition ujson/CharParser#parseNum().(ctxt)
+//                                                 ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                               ^^^ reference scala/Any#
+//                                                                    ^ reference ujson/CharParser#[J]
+//                                                                        ^^^^^^ definition ujson/CharParser#parseNum().(facade)
+//                                                                                ^^^^^^^ reference upickle/core/Visitor#
+//                                                                                           ^ reference ujson/CharParser#[J]
+//                                                                                                ^^^ reference scala/Int#
+    var j = i
+//      ^ definition local6
+//          ^ reference ujson/CharParser#parseNum().(i)
+    var c = getCharSafe(j)
+//      ^ definition local7
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local6
+    var decIndex = -1
+//      ^^^^^^^^ definition local8
+    var expIndex = -1
+//      ^^^^^^^^ definition local9
+
+    if (c == '-') {
+//      ^ reference local7
+//        ^^ reference scala/Char#`==`(+2).
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getCharSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local6
+    }
+    if (c == '0') {
+//      ^ reference local7
+//        ^^ reference scala/Char#`==`(+2).
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getCharSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local6
+    } else {
+      val j0 = j
+//        ^^ definition local10
+//             ^ reference local6
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/CharParser#elemOps.
+//                   ^^^^^^ reference upickle/core/CharOps.within().
+//                               ^ reference local7
+        j += 1;
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getCharSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local6
+      }
+      if (j == j0) die(i, "expected digit")
+//        ^ reference local6
+//          ^^ reference scala/Int#`==`(+3).
+//             ^^ reference local10
+//                 ^^^ reference ujson/CharParser#die().
+//                     ^ reference ujson/CharParser#parseNum().(i)
+    }
+
+    if (c == '.') {
+//      ^ reference local7
+//        ^^ reference scala/Char#`==`(+2).
+      decIndex = j - i
+//    ^^^^^^^^ reference local8
+//               ^ reference local6
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/CharParser#parseNum().(i)
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getCharSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local6
+      val j0 = j
+//        ^^ definition local11
+//             ^ reference local6
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/CharParser#elemOps.
+//                   ^^^^^^ reference upickle/core/CharOps.within().
+//                               ^ reference local7
+        j += 1
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getCharSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local6
+      }
+      if (j0 == j) die(i, "expected digit")
+//        ^^ reference local11
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local6
+//                 ^^^ reference ujson/CharParser#die().
+//                     ^ reference ujson/CharParser#parseNum().(i)
+    }
+
+    if (c == 'e' || c == 'E') {
+//      ^ reference local7
+//        ^^ reference scala/Char#`==`(+2).
+//               ^^ reference scala/Boolean#`||`().
+//                  ^ reference local7
+//                    ^^ reference scala/Char#`==`(+2).
+      expIndex = j - i
+//    ^^^^^^^^ reference local9
+//               ^ reference local6
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/CharParser#parseNum().(i)
+      j += 1
+//    ^ reference local6
+//      ^^ reference scala/Int#`+`(+4).
+      c = getCharSafe(j)
+//    ^ reference local7
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local6
+      if (c == '+' || c == '-') {
+//        ^ reference local7
+//          ^^ reference scala/Char#`==`(+2).
+//                 ^^ reference scala/Boolean#`||`().
+//                    ^ reference local7
+//                      ^^ reference scala/Char#`==`(+2).
+        j += 1
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getCharSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local6
+      }
+      val j0 = j
+//        ^^ definition local12
+//             ^ reference local6
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/CharParser#elemOps.
+//                   ^^^^^^ reference upickle/core/CharOps.within().
+//                               ^ reference local7
+        j += 1
+//      ^ reference local6
+//        ^^ reference scala/Int#`+`(+4).
+        c = getCharSafe(j)
+//      ^ reference local7
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local6
+      }
+      if (j0 == j)  die(i, "expected digit")
+//        ^^ reference local12
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local6
+//                  ^^^ reference ujson/CharParser#die().
+//                      ^ reference ujson/CharParser#parseNum().(i)
+    }
+
+    ctxt.visitValue(visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), i)
+//  ^^^^ reference ujson/CharParser#parseNum().(ctxt)
+//       ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().
+//                                                     ^^^^^^ reference ujson/CharParser#parseNum().(facade)
+//                                                             ^^^^^^^^ reference local8
+//                                                                       ^^^^^^^^ reference local9
+//                                                                                 ^ reference ujson/CharParser#parseNum().(i)
+//                                                                                    ^ reference local6
+//                                                                                        ^ reference ujson/CharParser#parseNum().(i)
+    j
+//  ^ reference local6
+  }
+
+  def visitFloat64StringPartsWithWrapper(facade: Visitor[_, J],
+//    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/CharParser#visitFloat64StringPartsWithWrapper().
+//                                       ^^^^^^ definition ujson/CharParser#visitFloat64StringPartsWithWrapper().(facade)
+//                                               ^^^^^^^ reference upickle/core/Visitor#
+//                                                          ^ reference ujson/CharParser#[J]
+                                         decIndex: Int,
+//                                       ^^^^^^^^ definition ujson/CharParser#visitFloat64StringPartsWithWrapper().(decIndex)
+//                                                 ^^^ reference scala/Int#
+                                         expIndex: Int,
+//                                       ^^^^^^^^ definition ujson/CharParser#visitFloat64StringPartsWithWrapper().(expIndex)
+//                                                 ^^^ reference scala/Int#
+                                         i: Int,
+//                                       ^ definition ujson/CharParser#visitFloat64StringPartsWithWrapper().(i)
+//                                          ^^^ reference scala/Int#
+                                         j: Int) = {
+//                                       ^ definition ujson/CharParser#visitFloat64StringPartsWithWrapper().(j)
+//                                          ^^^ reference scala/Int#
+    facade.visitFloat64StringParts(
+//  ^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().(facade)
+//         ^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64StringParts().
+      unsafeCharSeqForRange(i, j - i),
+//    ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#unsafeCharSeqForRange().
+//                          ^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().(i)
+//                             ^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().(j)
+//                               ^ reference scala/Int#`-`(+3).
+//                                 ^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().(i)
+      decIndex,
+//    ^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().(decIndex)
+      expIndex,
+//    ^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().(expIndex)
+      i
+//    ^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().(i)
+    )
+  }
+
+  /**
+   * Parse the given number, and add it to the given context.
+   *
+   * This method is a bit slower than parseNum() because it has to be
+   * sure it doesn't run off the end of the input.
+   *
+   * Normally (when operating in rparse in the context of an outer
+   * array or object) we don't need to worry about this and can just
+   * grab characters, because if we run out of characters that would
+   * indicate bad input. This is for cases where the number could
+   * possibly be followed by a valid EOF.
+   *
+   * This method has all the same caveats as the previous method.
+   */
+  protected[this] final def parseNumTopLevel(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^^^^ definition ujson/CharParser#parseNumTopLevel().
+//                                           ^ definition ujson/CharParser#parseNumTopLevel().(i)
+//                                              ^^^ reference scala/Int#
+//                                                   ^^^^^^ definition ujson/CharParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^ reference upickle/core/Visitor#
+//                                                                      ^ reference ujson/CharParser#[J]
+//                                                                            ^ reference ujson/CharParser#[J]
+//                                                                               ^^^ reference scala/Int#
+    var j = i
+//      ^ definition local13
+//          ^ reference ujson/CharParser#parseNumTopLevel().(i)
+    var c = getCharSafe(j)
+//      ^ definition local14
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local13
+    var decIndex = -1
+//      ^^^^^^^^ definition local15
+    var expIndex = -1
+//      ^^^^^^^^ definition local16
+
+    if (c == '-') {
+//      ^ reference local14
+//        ^^ reference scala/Char#`==`(+2).
+      // any valid input will require at least one digit after -
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      c = getCharSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local13
+    }
+    if (c == '0') {
+//      ^ reference local14
+//        ^^ reference scala/Char#`==`(+2).
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      if (atEof(j)) {
+//        ^^^^^ reference ujson/CharParser#atEof().
+//              ^ reference local13
+        return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().
+//                                                 ^^^^^^ reference ujson/CharParser#parseNumTopLevel().(facade)
+//                                                         ^^^^^^^^ reference local15
+//                                                                   ^^^^^^^^ reference local16
+//                                                                             ^ reference ujson/CharParser#parseNumTopLevel().(i)
+//                                                                                ^ reference local13
+//                                                                                    ^ reference local13
+      }
+      c = getCharSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local13
+    } else {
+      val j0 = j
+//        ^^ definition local17
+//             ^ reference local13
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/CharParser#elemOps.
+//                   ^^^^^^ reference upickle/core/CharOps.within().
+//                               ^ reference local14
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        if (atEof(j)) {
+//          ^^^^^ reference ujson/CharParser#atEof().
+//                ^ reference local13
+          return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().
+//                                                   ^^^^^^ reference ujson/CharParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^^ reference local15
+//                                                                     ^^^^^^^^ reference local16
+//                                                                               ^ reference ujson/CharParser#parseNumTopLevel().(i)
+//                                                                                  ^ reference local13
+//                                                                                      ^ reference local13
+        }
+        c = getCharSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local13
+      }
+      if (j0 == j) die(i, "expected digit")
+//        ^^ reference local17
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local13
+//                 ^^^ reference ujson/CharParser#die().
+//                     ^ reference ujson/CharParser#parseNumTopLevel().(i)
+    }
+
+    if (c == '.') {
+//      ^ reference local14
+//        ^^ reference scala/Char#`==`(+2).
+      // any valid input will require at least one digit after .
+      decIndex = j - i
+//    ^^^^^^^^ reference local15
+//               ^ reference local13
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/CharParser#parseNumTopLevel().(i)
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      c = getCharSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local13
+      val j0 = j
+//        ^^ definition local18
+//             ^ reference local13
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/CharParser#elemOps.
+//                   ^^^^^^ reference upickle/core/CharOps.within().
+//                               ^ reference local14
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        if (atEof(j)) {
+//          ^^^^^ reference ujson/CharParser#atEof().
+//                ^ reference local13
+          return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().
+//                                                   ^^^^^^ reference ujson/CharParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^^ reference local15
+//                                                                     ^^^^^^^^ reference local16
+//                                                                               ^ reference ujson/CharParser#parseNumTopLevel().(i)
+//                                                                                  ^ reference local13
+//                                                                                      ^ reference local13
+        }
+        c = getCharSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local13
+      }
+      if(j0 == j) die(i, "expected digit")
+//       ^^ reference local18
+//          ^^ reference scala/Int#`==`(+3).
+//             ^ reference local13
+//                ^^^ reference ujson/CharParser#die().
+//                    ^ reference ujson/CharParser#parseNumTopLevel().(i)
+    }
+
+    if (c == 'e' || c == 'E') {
+//      ^ reference local14
+//        ^^ reference scala/Char#`==`(+2).
+//               ^^ reference scala/Boolean#`||`().
+//                  ^ reference local14
+//                    ^^ reference scala/Char#`==`(+2).
+      // any valid input will require at least one digit after e, e+, etc
+      expIndex = j - i
+//    ^^^^^^^^ reference local16
+//               ^ reference local13
+//                 ^ reference scala/Int#`-`(+3).
+//                   ^ reference ujson/CharParser#parseNumTopLevel().(i)
+      j += 1
+//    ^ reference local13
+//      ^^ reference scala/Int#`+`(+4).
+      c = getCharSafe(j)
+//    ^ reference local14
+//        ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                    ^ reference local13
+      if (c == '+' || c == '-') {
+//        ^ reference local14
+//          ^^ reference scala/Char#`==`(+2).
+//                 ^^ reference scala/Boolean#`||`().
+//                    ^ reference local14
+//                      ^^ reference scala/Char#`==`(+2).
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        c = getCharSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local13
+      }
+      val j0 = j
+//        ^^ definition local19
+//             ^ reference local13
+      while (elemOps.within('0', c, '9')) {
+//           ^^^^^^^ reference ujson/CharParser#elemOps.
+//                   ^^^^^^ reference upickle/core/CharOps.within().
+//                               ^ reference local14
+        j += 1
+//      ^ reference local13
+//        ^^ reference scala/Int#`+`(+4).
+        if (atEof(j)) {
+//          ^^^^^ reference ujson/CharParser#atEof().
+//                ^ reference local13
+          return (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().
+//                                                   ^^^^^^ reference ujson/CharParser#parseNumTopLevel().(facade)
+//                                                           ^^^^^^^^ reference local15
+//                                                                     ^^^^^^^^ reference local16
+//                                                                               ^ reference ujson/CharParser#parseNumTopLevel().(i)
+//                                                                                  ^ reference local13
+//                                                                                      ^ reference local13
+        }
+        c = getCharSafe(j)
+//      ^ reference local14
+//          ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                      ^ reference local13
+      }
+      if (j0 == j) die(i, "expected digit")
+//        ^^ reference local19
+//           ^^ reference scala/Int#`==`(+3).
+//              ^ reference local13
+//                 ^^^ reference ujson/CharParser#die().
+//                     ^ reference ujson/CharParser#parseNumTopLevel().(i)
+    }
+
+    (visitFloat64StringPartsWithWrapper(facade, decIndex, expIndex, i, j), j)
+//   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#visitFloat64StringPartsWithWrapper().
+//                                      ^^^^^^ reference ujson/CharParser#parseNumTopLevel().(facade)
+//                                              ^^^^^^^^ reference local15
+//                                                        ^^^^^^^^ reference local16
+//                                                                  ^ reference ujson/CharParser#parseNumTopLevel().(i)
+//                                                                     ^ reference local13
+//                                                                         ^ reference local13
+  }
+
+  /**
+   * Generate a Char from the hex digits of "\u1234" (i.e. "1234").
+   *
+   * NOTE: This is only capable of generating characters from the basic plane.
+   * This is why it can only return Char instead of Int.
+   */
+  protected[this] final def descape(i: Int): Char = {
+//                          ^^^^^^^ definition ujson/CharParser#descape().
+//                                  ^ definition ujson/CharParser#descape().(i)
+//                                     ^^^ reference scala/Int#
+//                                           ^^^^ reference scala/Char#
+    import upickle.core.RenderUtils.hex
+//         ^^^^^^^ reference upickle/
+//                 ^^^^ reference upickle/core/
+//                      ^^^^^^^^^^^ reference upickle/core/RenderUtils.
+//                                  ^^^ reference upickle/core/RenderUtils.hex().
+    var x = 0
+//      ^ definition local20
+    x = (x << 4) | hex(getCharSafe(i+2).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                 ^ reference ujson/CharParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Char#toInt().
+    x = (x << 4) | hex(getCharSafe(i+3).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                 ^ reference ujson/CharParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Char#toInt().
+    x = (x << 4) | hex(getCharSafe(i+4).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                 ^ reference ujson/CharParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Char#toInt().
+    x = (x << 4) | hex(getCharSafe(i+5).toInt)
+//  ^ reference local20
+//       ^ reference local20
+//         ^^ reference scala/Int#`<<`().
+//               ^ reference scala/Int#`|`(+3).
+//                 ^^^ reference upickle/core/RenderUtils.hex().
+//                     ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                 ^ reference ujson/CharParser#descape().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                      ^^^^^ reference scala/Char#toInt().
+    x.toChar
+//  ^ reference local20
+//    ^^^^^^ reference scala/Int#toChar().
+  }
+
+
+  /**
+   * Parse the JSON constant "true".
+   *
+   * Note that this method assumes that the first character has already been checked.
+   */
+  protected[this] final def parseTrue(i: Int, facade: Visitor[_, J]): J = {
+//                          ^^^^^^^^^ definition ujson/CharParser#parseTrue().
+//                                    ^ definition ujson/CharParser#parseTrue().(i)
+//                                       ^^^ reference scala/Int#
+//                                            ^^^^^^ definition ujson/CharParser#parseTrue().(facade)
+//                                                    ^^^^^^^ reference upickle/core/Visitor#
+//                                                               ^ reference ujson/CharParser#[J]
+//                                                                    ^ reference ujson/CharParser#[J]
+    requestUntilOrThrow(i + 3)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#requestUntilOrThrow().
+//                      ^ reference ujson/CharParser#parseTrue().(i)
+//                        ^ reference scala/Int#`+`(+4).
+    if (getCharUnsafe(i + 1) == 'r' && getCharUnsafe(i + 2) == 'u' && getCharUnsafe(i + 3) == 'e') {
+//      ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                    ^ reference ujson/CharParser#parseTrue().(i)
+//                      ^ reference scala/Int#`+`(+4).
+//                           ^^ reference scala/Char#`==`(+2).
+//                                  ^^ reference scala/Boolean#`&&`().
+//                                     ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                                                   ^ reference ujson/CharParser#parseTrue().(i)
+//                                                     ^ reference scala/Int#`+`(+4).
+//                                                          ^^ reference scala/Char#`==`(+2).
+//                                                                 ^^ reference scala/Boolean#`&&`().
+//                                                                    ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                                                                                  ^ reference ujson/CharParser#parseTrue().(i)
+//                                                                                    ^ reference scala/Int#`+`(+4).
+//                                                                                         ^^ reference scala/Char#`==`(+2).
+      facade.visitTrue(i)
+//    ^^^^^^ reference ujson/CharParser#parseTrue().(facade)
+//           ^^^^^^^^^ reference upickle/core/Visitor#visitTrue().
+//                     ^ reference ujson/CharParser#parseTrue().(i)
+    } else {
+      die(i, "expected true")
+//    ^^^ reference ujson/CharParser#die().
+//        ^ reference ujson/CharParser#parseTrue().(i)
+    }
+  }
+
+  /**
+   * Parse the JSON constant "false".
+   *
+   * Note that this method assumes that the first character has already been checked.
+   */
+  protected[this] final def parseFalse(i: Int, facade: Visitor[_, J]): J = {
+//                          ^^^^^^^^^^ definition ujson/CharParser#parseFalse().
+//                                     ^ definition ujson/CharParser#parseFalse().(i)
+//                                        ^^^ reference scala/Int#
+//                                             ^^^^^^ definition ujson/CharParser#parseFalse().(facade)
+//                                                     ^^^^^^^ reference upickle/core/Visitor#
+//                                                                ^ reference ujson/CharParser#[J]
+//                                                                     ^ reference ujson/CharParser#[J]
+    requestUntilOrThrow(i + 4)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#requestUntilOrThrow().
+//                      ^ reference ujson/CharParser#parseFalse().(i)
+//                        ^ reference scala/Int#`+`(+4).
+
+    if (getCharUnsafe(i + 1) == 'a' && getCharUnsafe(i + 2) == 'l' && getCharUnsafe(i + 3) == 's' && getCharUnsafe(i + 4) == 'e') {
+//      ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                    ^ reference ujson/CharParser#parseFalse().(i)
+//                      ^ reference scala/Int#`+`(+4).
+//                           ^^ reference scala/Char#`==`(+2).
+//                                  ^^ reference scala/Boolean#`&&`().
+//                                     ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                                                   ^ reference ujson/CharParser#parseFalse().(i)
+//                                                     ^ reference scala/Int#`+`(+4).
+//                                                          ^^ reference scala/Char#`==`(+2).
+//                                                                 ^^ reference scala/Boolean#`&&`().
+//                                                                    ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                                                                                  ^ reference ujson/CharParser#parseFalse().(i)
+//                                                                                    ^ reference scala/Int#`+`(+4).
+//                                                                                         ^^ reference scala/Char#`==`(+2).
+//                                                                                                ^^ reference scala/Boolean#`&&`().
+//                                                                                                   ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                                                                                                                 ^ reference ujson/CharParser#parseFalse().(i)
+//                                                                                                                   ^ reference scala/Int#`+`(+4).
+//                                                                                                                        ^^ reference scala/Char#`==`(+2).
+      facade.visitFalse(i)
+//    ^^^^^^ reference ujson/CharParser#parseFalse().(facade)
+//           ^^^^^^^^^^ reference upickle/core/Visitor#visitFalse().
+//                      ^ reference ujson/CharParser#parseFalse().(i)
+    } else {
+      die(i, "expected false")
+//    ^^^ reference ujson/CharParser#die().
+//        ^ reference ujson/CharParser#parseFalse().(i)
+    }
+  }
+
+  /**
+   * Parse the JSON constant "null".
+   *
+   * Note that this method assumes that the first character has already been checked.
+   */
+  protected[this] final def parseNull(i: Int, facade: Visitor[_, J]): J = {
+//                          ^^^^^^^^^ definition ujson/CharParser#parseNull().
+//                                    ^ definition ujson/CharParser#parseNull().(i)
+//                                       ^^^ reference scala/Int#
+//                                            ^^^^^^ definition ujson/CharParser#parseNull().(facade)
+//                                                    ^^^^^^^ reference upickle/core/Visitor#
+//                                                               ^ reference ujson/CharParser#[J]
+//                                                                    ^ reference ujson/CharParser#[J]
+    requestUntilOrThrow(i + 3)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#requestUntilOrThrow().
+//                      ^ reference ujson/CharParser#parseNull().(i)
+//                        ^ reference scala/Int#`+`(+4).
+    if (getCharUnsafe(i + 1) == 'u' && getCharUnsafe(i + 2) == 'l' && getCharUnsafe(i + 3) == 'l') {
+//      ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                    ^ reference ujson/CharParser#parseNull().(i)
+//                      ^ reference scala/Int#`+`(+4).
+//                           ^^ reference scala/Char#`==`(+2).
+//                                  ^^ reference scala/Boolean#`&&`().
+//                                     ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                                                   ^ reference ujson/CharParser#parseNull().(i)
+//                                                     ^ reference scala/Int#`+`(+4).
+//                                                          ^^ reference scala/Char#`==`(+2).
+//                                                                 ^^ reference scala/Boolean#`&&`().
+//                                                                    ^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#getCharUnsafe().
+//                                                                                  ^ reference ujson/CharParser#parseNull().(i)
+//                                                                                    ^ reference scala/Int#`+`(+4).
+//                                                                                         ^^ reference scala/Char#`==`(+2).
+      facade.visitNull(i)
+//    ^^^^^^ reference ujson/CharParser#parseNull().(facade)
+//           ^^^^^^^^^ reference upickle/core/Visitor#visitNull().
+//                     ^ reference ujson/CharParser#parseNull().(i)
+    } else {
+      die(i, "expected null")
+//    ^^^ reference ujson/CharParser#die().
+//        ^ reference ujson/CharParser#parseNull().(i)
+    }
+  }
+
+  protected[this] final def parseTopLevel(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^ definition ujson/CharParser#parseTopLevel().
+//                                        ^ definition ujson/CharParser#parseTopLevel().(i)
+//                                           ^^^ reference scala/Int#
+//                                                ^^^^^^ definition ujson/CharParser#parseTopLevel().(facade)
+//                                                        ^^^^^^^ reference upickle/core/Visitor#
+//                                                                   ^ reference ujson/CharParser#[J]
+//                                                                         ^ reference ujson/CharParser#[J]
+//                                                                            ^^^ reference scala/Int#
+    try parseTopLevel0(i, facade)
+//      ^^^^^^^^^^^^^^ reference ujson/CharParser#parseTopLevel0().
+//                     ^ reference ujson/CharParser#parseTopLevel().(i)
+//                        ^^^^^^ reference ujson/CharParser#parseTopLevel().(facade)
+    catch reject(i)
+//        ^^^^^^ reference ujson/CharParser#reject().
+//               ^ reference ujson/CharParser#parseTopLevel().(i)
+  }
+  /**
+   * Parse and return the next JSON value and the position beyond it.
+   */
+  @tailrec
+// ^^^^^^^ reference scala/annotation/tailrec#
+//         reference scala/annotation/tailrec#`<init>`().
+  protected[this] final def parseTopLevel0(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^^ definition ujson/CharParser#parseTopLevel0().
+//                                         ^ definition ujson/CharParser#parseTopLevel0().(i)
+//                                            ^^^ reference scala/Int#
+//                                                 ^^^^^^ definition ujson/CharParser#parseTopLevel0().(facade)
+//                                                         ^^^^^^^ reference upickle/core/Visitor#
+//                                                                    ^ reference ujson/CharParser#[J]
+//                                                                          ^ reference ujson/CharParser#[J]
+//                                                                             ^^^ reference scala/Int#
+    (getCharSafe(i): @switch) match {
+//   ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//               ^ reference ujson/CharParser#parseTopLevel0().(i)
+      // ignore whitespace
+      case ' ' | '\t' | 'r' => parseTopLevel0(i + 1, facade)
+//                             ^^^^^^^^^^^^^^ reference ujson/CharParser#parseTopLevel0().
+//                                            ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                              ^ reference scala/Int#`+`(+4).
+//                                                   ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+      case '\n' => parseTopLevel0(i + 1, facade)
+//                 ^^^^^^^^^^^^^^ reference ujson/CharParser#parseTopLevel0().
+//                                ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                  ^ reference scala/Int#`+`(+4).
+//                                       ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+
+      // if we have a recursive top-level structure, we'll delegate the parsing
+      // duties to our good friend rparse().
+      case '[' => parseNested(ARRBEG, i + 1, facade.visitArray(-1, i), Nil)
+//                ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                            ^^^^^^ reference ujson/CharParser#ARRBEG.
+//                                    ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                      ^ reference scala/Int#`+`(+4).
+//                                           ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+//                                                  ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                                                                 ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                                                     ^^^ reference scala/package.Nil.
+      case '{' => parseNested(OBJBEG, i + 1, facade.visitObject(-1, i), Nil)
+//                ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                            ^^^^^^ reference ujson/CharParser#OBJBEG.
+//                                    ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                      ^ reference scala/Int#`+`(+4).
+//                                           ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+//                                                  ^^^^^^^^^^^ reference upickle/core/Visitor#visitObject().
+//                                                                  ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                                                      ^^^ reference scala/package.Nil.
+
+      // we have a single top-level number
+      case '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => parseNumTopLevel(i, facade)
+//                                                                            ^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseNumTopLevel().
+//                                                                                             ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                                                                                ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+
+      // we have a single top-level string
+      case '"' => parseStringTopLevel(i, facade)
+//                ^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringTopLevel().
+//                                    ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                       ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+
+      // we have a single top-level constant
+      case 't' => (parseTrue(i, facade), i + 4)
+//                 ^^^^^^^^^ reference ujson/CharParser#parseTrue().
+//                           ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                              ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+//                                       ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                         ^ reference scala/Int#`+`(+4).
+      case 'f' => (parseFalse(i, facade), i + 5)
+//                 ^^^^^^^^^^ reference ujson/CharParser#parseFalse().
+//                            ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                               ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+//                                        ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                          ^ reference scala/Int#`+`(+4).
+      case 'n' => (parseNull(i, facade), i + 4)
+//                 ^^^^^^^^^ reference ujson/CharParser#parseNull().
+//                           ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                              ^^^^^^ reference ujson/CharParser#parseTopLevel0().(facade)
+//                                       ^ reference ujson/CharParser#parseTopLevel0().(i)
+//                                         ^ reference scala/Int#`+`(+4).
+
+      // invalid
+      case _ => die(i, "expected json value")
+//              ^^^ reference ujson/CharParser#die().
+//                  ^ reference ujson/CharParser#parseTopLevel0().(i)
+    }
+  }
+
+  def reject(j: Int): PartialFunction[Throwable, Nothing] = {
+//    ^^^^^^ definition ujson/CharParser#reject().
+//           ^ definition ujson/CharParser#reject().(j)
+//              ^^^ reference scala/Int#
+//                    ^^^^^^^^^^^^^^^ reference scala/PartialFunction#
+//                                    ^^^^^^^^^ reference scala/package.Throwable#
+//                                               ^^^^^^^ reference scala/Nothing#
+    case e: Abort =>
+//       ^ definition local21
+//          ^^^^^ reference upickle/core/Abort#
+      throw new AbortException(e.msg, j, -1, -1, e)
+//              ^^^^^^^^^^^^^^ reference upickle/core/AbortException#
+//                             reference upickle/core/AbortException#`<init>`().
+//                             ^ reference local21
+//                               ^^^ reference upickle/core/Abort#msg.
+//                                    ^ reference ujson/CharParser#reject().(j)
+//                                               ^ reference local21
+  }
+  /**
+   * Tail-recursive parsing method to do the bulk of JSON parsing.
+   *
+   * This single method manages parser states, data, etc. Except for
+   * parsing non-recursive values (like strings, numbers, and
+   * constants) all important work happens in this loop (or in methods
+   * it calls, like reset()).
+   *
+   * Currently the code is optimized to make use of switch
+   * statements. Future work should consider whether this is better or
+   * worse than manually constructed if/else statements or something
+   * else. Also, it may be possible to reorder some cases for speed
+   * improvements.
+   *
+   * @param j index/position in the source json
+   * @param path the json path in the tree
+   */
+  @tailrec
+// ^^^^^^^ reference scala/annotation/tailrec#
+//         reference scala/annotation/tailrec#`<init>`().
+  protected[this] final def parseNested(state: Int,
+//                          ^^^^^^^^^^^ definition ujson/CharParser#parseNested().
+//                                      ^^^^^ definition ujson/CharParser#parseNested().(state)
+//                                             ^^^ reference scala/Int#
+                                        i: Int,
+//                                      ^ definition ujson/CharParser#parseNested().(i)
+//                                         ^^^ reference scala/Int#
+                                        stackHead: ObjArrVisitor[_, J],
+//                                      ^^^^^^^^^ definition ujson/CharParser#parseNested().(stackHead)
+//                                                 ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                  ^ reference ujson/CharParser#[J]
+                                        stackTail: List[ObjArrVisitor[_, J]]) : (J, Int) = {
+//                                      ^^^^^^^^^ definition ujson/CharParser#parseNested().(stackTail)
+//                                                 ^^^^ reference scala/package.List#
+//                                                      ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                       ^ reference ujson/CharParser#[J]
+//                                                                               ^ reference ujson/CharParser#[J]
+//                                                                                  ^^^ reference scala/Int#
+    (getCharSafe(i): @switch) match{
+//   ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//               ^ reference ujson/CharParser#parseNested().(i)
+      case ' ' | '\t' | '\r' | '\n' =>
+        parseNested(state, i + 1, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                  ^^^^^ reference ujson/CharParser#parseNested().(state)
+//                         ^ reference ujson/CharParser#parseNested().(i)
+//                           ^ reference scala/Int#`+`(+4).
+//                                ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                           ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+      case '"' =>
+        state match{
+//      ^^^^^ reference ujson/CharParser#parseNested().(state)
+          case KEY | OBJBEG =>
+//             ^^^ reference ujson/CharParser#KEY.
+//                   ^^^^^^ reference ujson/CharParser#OBJBEG.
+            val nextJ = try parseStringKey(i, stackHead) catch reject(i)
+//              ^^^^^ definition local22
+//                          ^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringKey().
+//                                         ^ reference ujson/CharParser#parseNested().(i)
+//                                            ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                             ^^^^^^ reference ujson/CharParser#reject().
+//                                                                    ^ reference ujson/CharParser#parseNested().(i)
+            parseNested(COLON, nextJ, stackHead, stackTail)
+//          ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                      ^^^^^ reference ujson/CharParser#COLON.
+//                             ^^^^^ reference local22
+//                                    ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                               ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+          case DATA | ARRBEG =>
+//             ^^^^ reference ujson/CharParser#DATA.
+//                    ^^^^^^ reference ujson/CharParser#ARRBEG.
+            val nextJ = try parseStringValue(i, stackHead) catch reject(i)
+//              ^^^^^ definition local23
+//                          ^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringValue().
+//                                           ^ reference ujson/CharParser#parseNested().(i)
+//                                              ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                               ^^^^^^ reference ujson/CharParser#reject().
+//                                                                      ^ reference ujson/CharParser#parseNested().(i)
+            parseNested(collectionEndFor(stackHead), nextJ, stackHead, stackTail)
+//          ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                      ^^^^^^^^^^^^^^^^ reference ujson/CharParser#collectionEndFor().
+//                                       ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                   ^^^^^ reference local23
+//                                                          ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                                     ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#dieWithFailureMessage().
+//                                        ^ reference ujson/CharParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/CharParser#parseNested().(state)
+        }
+
+      case ':' =>
+        // we are in an object just after a key, expecting to see a colon.
+        state match{
+//      ^^^^^ reference ujson/CharParser#parseNested().(state)
+          case COLON => parseNested(DATA, i + 1, stackHead, stackTail)
+//             ^^^^^ reference ujson/CharParser#COLON.
+//                      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                                  ^^^^ reference ujson/CharParser#DATA.
+//                                        ^ reference ujson/CharParser#parseNested().(i)
+//                                          ^ reference scala/Int#`+`(+4).
+//                                               ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                          ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#dieWithFailureMessage().
+//                                        ^ reference ujson/CharParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/CharParser#parseNested().(state)
+        }
+
+      case '[' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/CharParser#failIfNotData().
+//                    ^^^^^ reference ujson/CharParser#parseNested().(state)
+//                           ^ reference ujson/CharParser#parseNested().(i)
+        val ctx =
+//          ^^^ definition local24
+          try stackHead.subVisitor.asInstanceOf[Visitor[_, J]].visitArray(-1, i)
+//            ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                      ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                 ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                              ^^^^^^^ reference upickle/core/Visitor#
+//                                                         ^ reference ujson/CharParser#[J]
+//                                                             ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                                                                            ^ reference ujson/CharParser#parseNested().(i)
+          catch reject(i)
+//              ^^^^^^ reference ujson/CharParser#reject().
+//                     ^ reference ujson/CharParser#parseNested().(i)
+        parseNested(ARRBEG, i + 1, ctx, stackHead :: stackTail)
+//      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                  ^^^^^^ reference ujson/CharParser#ARRBEG.
+//                          ^ reference ujson/CharParser#parseNested().(i)
+//                            ^ reference scala/Int#`+`(+4).
+//                                 ^^^ reference local24
+//                                      ^^^^^^^^^ reference local25
+//                                                ^^ reference scala/collection/immutable/List#`::`().
+//                                                   ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+      case '{' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/CharParser#failIfNotData().
+//                    ^^^^^ reference ujson/CharParser#parseNested().(state)
+//                           ^ reference ujson/CharParser#parseNested().(i)
+        val ctx =
+//          ^^^ definition local27
+          try stackHead.subVisitor.asInstanceOf[Visitor[_, J]].visitObject(-1, i)
+//            ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                      ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                 ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                              ^^^^^^^ reference upickle/core/Visitor#
+//                                                         ^ reference ujson/CharParser#[J]
+//                                                             ^^^^^^^^^^^ reference upickle/core/Visitor#visitObject().
+//                                                                             ^ reference ujson/CharParser#parseNested().(i)
+          catch reject(i)
+//              ^^^^^^ reference ujson/CharParser#reject().
+//                     ^ reference ujson/CharParser#parseNested().(i)
+        parseNested(OBJBEG, i + 1, ctx, stackHead :: stackTail)
+//      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                  ^^^^^^ reference ujson/CharParser#OBJBEG.
+//                          ^ reference ujson/CharParser#parseNested().(i)
+//                            ^ reference scala/Int#`+`(+4).
+//                                 ^^^ reference local27
+//                                      ^^^^^^^^^ reference local28
+//                                                ^^ reference scala/collection/immutable/List#`::`().
+//                                                   ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+      case '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/CharParser#failIfNotData().
+//                    ^^^^^ reference ujson/CharParser#parseNested().(state)
+//                           ^ reference ujson/CharParser#parseNested().(i)
+        val ctx =
+//          ^^^ definition local29
+          try parseNum(i, stackHead.narrow, stackHead.subVisitor.asInstanceOf[Visitor[_, J]])
+//            ^^^^^^^^ reference ujson/CharParser#parseNum().
+//                     ^ reference ujson/CharParser#parseNested().(i)
+//                        ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                  ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                                          ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                    ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                                               ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                                            ^^^^^^^ reference upickle/core/Visitor#
+//                                                                                       ^ reference ujson/CharParser#[J]
+          catch reject(i)
+//              ^^^^^^ reference ujson/CharParser#reject().
+//                     ^ reference ujson/CharParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), ctx, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/CharParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                               ^^^ reference local29
+//                                                    ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                               ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+      case 't' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/CharParser#failIfNotData().
+//                    ^^^^^ reference ujson/CharParser#parseNested().(state)
+//                           ^ reference ujson/CharParser#parseNested().(i)
+        try stackHead.narrow.visitValue(
+//          ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                    ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                           ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+          parseTrue(i, stackHead.subVisitor.asInstanceOf[Visitor[_, J]]),
+//        ^^^^^^^^^ reference ujson/CharParser#parseTrue().
+//                  ^ reference ujson/CharParser#parseNested().(i)
+//                     ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                               ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                          ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                       ^^^^^^^ reference upickle/core/Visitor#
+//                                                                  ^ reference ujson/CharParser#[J]
+          i
+//        ^ reference ujson/CharParser#parseNested().(i)
+        )
+        catch reject(i)
+//            ^^^^^^ reference ujson/CharParser#reject().
+//                   ^ reference ujson/CharParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), i + 4, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/CharParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                               ^ reference ujson/CharParser#parseNested().(i)
+//                                                 ^ reference scala/Int#`+`(+4).
+//                                                      ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                                 ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+      case 'f' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/CharParser#failIfNotData().
+//                    ^^^^^ reference ujson/CharParser#parseNested().(state)
+//                           ^ reference ujson/CharParser#parseNested().(i)
+        try stackHead.narrow.visitValue(
+//          ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                    ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                           ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+          parseFalse(i, stackHead.subVisitor.asInstanceOf[Visitor[_, J]]),
+//        ^^^^^^^^^^ reference ujson/CharParser#parseFalse().
+//                   ^ reference ujson/CharParser#parseNested().(i)
+//                      ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                           ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                        ^^^^^^^ reference upickle/core/Visitor#
+//                                                                   ^ reference ujson/CharParser#[J]
+          i
+//        ^ reference ujson/CharParser#parseNested().(i)
+        )
+        catch reject(i)
+//            ^^^^^^ reference ujson/CharParser#reject().
+//                   ^ reference ujson/CharParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), i + 5, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/CharParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                               ^ reference ujson/CharParser#parseNested().(i)
+//                                                 ^ reference scala/Int#`+`(+4).
+//                                                      ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                                 ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+      case 'n' =>
+        failIfNotData(state, i)
+//      ^^^^^^^^^^^^^ reference ujson/CharParser#failIfNotData().
+//                    ^^^^^ reference ujson/CharParser#parseNested().(state)
+//                           ^ reference ujson/CharParser#parseNested().(i)
+        try stackHead.narrow.visitValue(
+//          ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                    ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                           ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+          parseNull(i, stackHead.subVisitor.asInstanceOf[Visitor[_, J]]),
+//        ^^^^^^^^^ reference ujson/CharParser#parseNull().
+//                  ^ reference ujson/CharParser#parseNested().(i)
+//                     ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                               ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                          ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                       ^^^^^^^ reference upickle/core/Visitor#
+//                                                                  ^ reference ujson/CharParser#[J]
+          i
+//        ^ reference ujson/CharParser#parseNested().(i)
+        )
+        catch reject(i)
+//            ^^^^^^ reference ujson/CharParser#reject().
+//                   ^ reference ujson/CharParser#parseNested().(i)
+        parseNested(collectionEndFor(stackHead), i + 4, stackHead, stackTail)
+//      ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                  ^^^^^^^^^^^^^^^^ reference ujson/CharParser#collectionEndFor().
+//                                   ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                               ^ reference ujson/CharParser#parseNested().(i)
+//                                                 ^ reference scala/Int#`+`(+4).
+//                                                      ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                                 ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+
+      case ',' =>
+        dropBufferUntil(i)
+//      ^^^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#dropBufferUntil().
+//                      ^ reference ujson/CharParser#parseNested().(i)
+        (state: @switch) match{
+//       ^^^^^ reference ujson/CharParser#parseNested().(state)
+          case ARREND => parseNested(DATA, i + 1, stackHead, stackTail)
+//             ^^^^^^ reference ujson/CharParser#ARREND.
+//                       ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                                   ^^^^ reference ujson/CharParser#DATA.
+//                                         ^ reference ujson/CharParser#parseNested().(i)
+//                                           ^ reference scala/Int#`+`(+4).
+//                                                ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                           ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+          case OBJEND => parseNested(KEY, i + 1, stackHead, stackTail)
+//             ^^^^^^ reference ujson/CharParser#OBJEND.
+//                       ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                                   ^^^ reference ujson/CharParser#KEY.
+//                                        ^ reference ujson/CharParser#parseNested().(i)
+//                                          ^ reference scala/Int#`+`(+4).
+//                                               ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                                          ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#dieWithFailureMessage().
+//                                        ^ reference ujson/CharParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/CharParser#parseNested().(state)
+        }
+
+      case ']' =>
+        (state: @switch) match{
+//       ^^^^^ reference ujson/CharParser#parseNested().(state)
+          case ARREND | ARRBEG =>
+//             ^^^^^^ reference ujson/CharParser#ARREND.
+//                      ^^^^^^ reference ujson/CharParser#ARRBEG.
+            tryCloseCollection(stackHead, stackTail, i) match{
+//          ^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#tryCloseCollection().
+//                             ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                        ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+//                                                   ^ reference ujson/CharParser#parseNested().(i)
+              case Some(t) => t
+//                 ^^^^ reference scala/Some.
+//                      ^ definition local30
+//                            ^ reference local30
+              case None =>
+//                 ^^^^ reference scala/None.
+                val stackTailHead = stackTail.head
+//                  ^^^^^^^^^^^^^ definition local31
+//                                  ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+//                                            ^^^^ reference scala/collection/IterableOps#head().
+                parseNested(collectionEndFor(stackTailHead), i + 1, stackTailHead, stackTail.tail)
+//              ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                          ^^^^^^^^^^^^^^^^ reference ujson/CharParser#collectionEndFor().
+//                                           ^^^^^^^^^^^^^ reference local31
+//                                                           ^ reference ujson/CharParser#parseNested().(i)
+//                                                             ^ reference scala/Int#`+`(+4).
+//                                                                  ^^^^^^^^^^^^^ reference local31
+//                                                                                 ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+//                                                                                           ^^^^ reference scala/collection/IterableOps#tail().
+            }
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#dieWithFailureMessage().
+//                                        ^ reference ujson/CharParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/CharParser#parseNested().(state)
+        }
+
+      case '}' =>
+        (state: @switch) match{
+//       ^^^^^ reference ujson/CharParser#parseNested().(state)
+          case OBJEND | OBJBEG =>
+//             ^^^^^^ reference ujson/CharParser#OBJEND.
+//                      ^^^^^^ reference ujson/CharParser#OBJBEG.
+            tryCloseCollection(stackHead, stackTail, i) match{
+//          ^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#tryCloseCollection().
+//                             ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackHead)
+//                                        ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+//                                                   ^ reference ujson/CharParser#parseNested().(i)
+              case Some(t) => t
+//                 ^^^^ reference scala/Some.
+//                      ^ definition local32
+//                            ^ reference local32
+              case None =>
+//                 ^^^^ reference scala/None.
+                val stackTailHead = stackTail.head
+//                  ^^^^^^^^^^^^^ definition local33
+//                                  ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+//                                            ^^^^ reference scala/collection/IterableOps#head().
+                parseNested(collectionEndFor(stackTailHead), i + 1, stackTailHead, stackTail.tail)
+//              ^^^^^^^^^^^ reference ujson/CharParser#parseNested().
+//                          ^^^^^^^^^^^^^^^^ reference ujson/CharParser#collectionEndFor().
+//                                           ^^^^^^^^^^^^^ reference local33
+//                                                           ^ reference ujson/CharParser#parseNested().(i)
+//                                                             ^ reference scala/Int#`+`(+4).
+//                                                                  ^^^^^^^^^^^^^ reference local33
+//                                                                                 ^^^^^^^^^ reference ujson/CharParser#parseNested().(stackTail)
+//                                                                                           ^^^^ reference scala/collection/IterableOps#tail().
+            }
+          case _ => dieWithFailureMessage(i, state)
+//                  ^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#dieWithFailureMessage().
+//                                        ^ reference ujson/CharParser#parseNested().(i)
+//                                           ^^^^^ reference ujson/CharParser#parseNested().(state)
+        }
+      case _ => dieWithFailureMessage(i, state)
+//              ^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#dieWithFailureMessage().
+//                                    ^ reference ujson/CharParser#parseNested().(i)
+//                                       ^^^^^ reference ujson/CharParser#parseNested().(state)
+
+    }
+  }
+
+
+  def dieWithFailureMessage(i: Int, state: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^^^ definition ujson/CharParser#dieWithFailureMessage().
+//                          ^ definition ujson/CharParser#dieWithFailureMessage().(i)
+//                             ^^^ reference scala/Int#
+//                                  ^^^^^ definition ujson/CharParser#dieWithFailureMessage().(state)
+//                                         ^^^ reference scala/Int#
+    val expected = state match{
+//      ^^^^^^^^ definition local34
+//                 ^^^^^ reference ujson/CharParser#dieWithFailureMessage().(state)
+      case ARRBEG => "json value or ]"
+//         ^^^^^^ reference ujson/CharParser#ARRBEG.
+      case OBJBEG => "json value or }"
+//         ^^^^^^ reference ujson/CharParser#OBJBEG.
+      case DATA => "json value"
+//         ^^^^ reference ujson/CharParser#DATA.
+      case KEY => "json string key"
+//         ^^^ reference ujson/CharParser#KEY.
+      case COLON => ":"
+//         ^^^^^ reference ujson/CharParser#COLON.
+      case ARREND => ", or ]"
+//         ^^^^^^ reference ujson/CharParser#ARREND.
+      case OBJEND => ", or }"
+//         ^^^^^^ reference ujson/CharParser#OBJEND.
+    }
+    die(i, s"expected $expected")
+//  ^^^ reference ujson/CharParser#die().
+//      ^ reference ujson/CharParser#dieWithFailureMessage().(i)
+//         ^ reference scala/StringContext#s().
+//                     ^^^^^^^^ reference local34
+  }
+
+  def failIfNotData(state: Int, i: Int) = (state: @switch) match{
+//    ^^^^^^^^^^^^^ definition ujson/CharParser#failIfNotData().
+//                  ^^^^^ definition ujson/CharParser#failIfNotData().(state)
+//                         ^^^ reference scala/Int#
+//                              ^ definition ujson/CharParser#failIfNotData().(i)
+//                                 ^^^ reference scala/Int#
+//                                         ^^^^^ reference ujson/CharParser#failIfNotData().(state)
+    case DATA | ARRBEG => // do nothing
+//       ^^^^ reference ujson/CharParser#DATA.
+//              ^^^^^^ reference ujson/CharParser#ARRBEG.
+    case _ => dieWithFailureMessage(i, state)
+//            ^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#dieWithFailureMessage().
+//                                  ^ reference ujson/CharParser#failIfNotData().(i)
+//                                     ^^^^^ reference ujson/CharParser#failIfNotData().(state)
+  }
+
+  def tryCloseCollection(stackHead: ObjArrVisitor[_, J], stackTail: List[ObjArrVisitor[_, J]], i: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/CharParser#tryCloseCollection().
+//                       ^^^^^^^^^ definition ujson/CharParser#tryCloseCollection().(stackHead)
+//                                  ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                   ^ reference ujson/CharParser#[J]
+//                                                       ^^^^^^^^^ definition ujson/CharParser#tryCloseCollection().(stackTail)
+//                                                                  ^^^^ reference scala/package.List#
+//                                                                       ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                                        ^ reference ujson/CharParser#[J]
+//                                                                                             ^ definition ujson/CharParser#tryCloseCollection().(i)
+//                                                                                                ^^^ reference scala/Int#
+    if (stackTail.isEmpty) {
+//      ^^^^^^^^^ reference ujson/CharParser#tryCloseCollection().(stackTail)
+//                ^^^^^^^ reference scala/collection/immutable/List#isEmpty().
+      Some(try stackHead.visitEnd(i) catch reject(i), i + 1)
+//    ^^^^ reference scala/Some.
+//             ^^^^^^^^^ reference ujson/CharParser#tryCloseCollection().(stackHead)
+//                       ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+//                                ^ reference ujson/CharParser#tryCloseCollection().(i)
+//                                         ^^^^^^ reference ujson/CharParser#reject().
+//                                                ^ reference ujson/CharParser#tryCloseCollection().(i)
+//                                                    ^ reference ujson/CharParser#tryCloseCollection().(i)
+//                                                      ^ reference scala/Int#`+`(+4).
+    } else {
+      val ctxt2 = stackTail.head.narrow
+//        ^^^^^ definition local35
+//                ^^^^^^^^^ reference ujson/CharParser#tryCloseCollection().(stackTail)
+//                          ^^^^ reference scala/collection/IterableOps#head().
+//                               ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+      try ctxt2.visitValue(stackHead.visitEnd(i), i) catch reject(i)
+//        ^^^^^ reference local35
+//              ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                         ^^^^^^^^^ reference ujson/CharParser#tryCloseCollection().(stackHead)
+//                                   ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+//                                            ^ reference ujson/CharParser#tryCloseCollection().(i)
+//                                                ^ reference ujson/CharParser#tryCloseCollection().(i)
+//                                                         ^^^^^^ reference ujson/CharParser#reject().
+//                                                                ^ reference ujson/CharParser#tryCloseCollection().(i)
+      None
+//    ^^^^ reference scala/None.
+
+    }
+  }
+  def collectionEndFor(stackHead: ObjArrVisitor[_, _]) = {
+//    ^^^^^^^^^^^^^^^^ definition ujson/CharParser#collectionEndFor().
+//                     ^^^^^^^^^ definition ujson/CharParser#collectionEndFor().(stackHead)
+//                                ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+    if (stackHead.isObj) OBJEND
+//      ^^^^^^^^^ reference ujson/CharParser#collectionEndFor().(stackHead)
+//                ^^^^^ reference upickle/core/ObjArrVisitor#isObj().
+//                       ^^^^^^ reference ujson/CharParser#OBJEND.
+    else ARREND
+//       ^^^^^^ reference ujson/CharParser#ARREND.
+  }
+
+  /**
+    * See if the string has any escape sequences. If not, return the
+    * end of the string. If so, bail out and return -1.
+    *
+    * This method expects the data to be in UTF-16 and accesses it as
+    * chars.
+    */
+  protected[this] final def parseStringSimple(i: Int): Int = {
+//                          ^^^^^^^^^^^^^^^^^ definition ujson/CharParser#parseStringSimple().
+//                                            ^ definition ujson/CharParser#parseStringSimple().(i)
+//                                               ^^^ reference scala/Int#
+//                                                     ^^^ reference scala/Int#
+    var j = i
+//      ^ definition local36
+//          ^ reference ujson/CharParser#parseStringSimple().(i)
+    var c = elemOps.toUnsignedInt(getCharSafe(j))
+//      ^ definition local37
+//          ^^^^^^^ reference ujson/CharParser#elemOps.
+//                  ^^^^^^^^^^^^^ reference upickle/core/CharOps.toUnsignedInt().
+//                                ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                            ^ reference local36
+    while (c != '"') {
+//         ^ reference local37
+//           ^^ reference scala/Int#`!=`(+2).
+      if (c < ' ') die(j, s"control char (${c}) in string")
+//        ^ reference local37
+//          ^ reference scala/Int#`<`(+2).
+//                 ^^^ reference ujson/CharParser#die().
+//                     ^ reference local36
+//                        ^ reference scala/StringContext#s().
+//                                          ^ reference local37
+      if (c == '\\' || c > 127) return -1 - j
+//        ^ reference local37
+//          ^^ reference scala/Int#`==`(+2).
+//                  ^^ reference scala/Boolean#`||`().
+//                     ^ reference local37
+//                       ^ reference scala/Int#`>`(+3).
+//                                        ^ reference scala/Int#`-`(+3).
+//                                          ^ reference local36
+      j += 1
+//    ^ reference local36
+//      ^^ reference scala/Int#`+`(+4).
+      c = elemOps.toUnsignedInt(getCharSafe(j))
+//    ^ reference local37
+//        ^^^^^^^ reference ujson/CharParser#elemOps.
+//                ^^^^^^^^^^^^^ reference upickle/core/CharOps.toUnsignedInt().
+//                              ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                          ^ reference local36
+    }
+    j + 1
+//  ^ reference local36
+//    ^ reference scala/Int#`+`(+4).
+  }
+
+  /**
+    * Parse a string that is known to have escape sequences.
+    */
+  protected[this] final def parseStringComplex(i0: Int): Int = {
+//                          ^^^^^^^^^^^^^^^^^^ definition ujson/CharParser#parseStringComplex().
+//                                             ^^ definition ujson/CharParser#parseStringComplex().(i0)
+//                                                 ^^^ reference scala/Int#
+//                                                       ^^^ reference scala/Int#
+    var i = i0
+//      ^ definition local38
+//          ^^ reference ujson/CharParser#parseStringComplex().(i0)
+    var c = elemOps.toUnsignedInt(getCharSafe(i))
+//      ^ definition local39
+//          ^^^^^^^ reference ujson/CharParser#elemOps.
+//                  ^^^^^^^^^^^^^ reference upickle/core/CharOps.toUnsignedInt().
+//                                ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                            ^ reference local38
+    while (c != '"') {
+//         ^ reference local39
+//           ^^ reference scala/Int#`!=`(+2).
+
+      if (c < ' ') die(i, s"control char (${c}) in string")
+//        ^ reference local39
+//          ^ reference scala/Int#`<`(+2).
+//                 ^^^ reference ujson/CharParser#die().
+//                     ^ reference local38
+//                        ^ reference scala/StringContext#s().
+//                                          ^ reference local39
+      else if (c == '\\') {
+//             ^ reference local39
+//               ^^ reference scala/Int#`==`(+2).
+        (getCharSafe(i + 1): @switch) match {
+//       ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                   ^ reference local38
+//                     ^ reference scala/Int#`+`(+4).
+          case 'b' => { outputBuilder.append('\b'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 'f' => { outputBuilder.append('\f'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 'n' => { outputBuilder.append('\n'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 'r' => { outputBuilder.append('\r'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+          case 't' => { outputBuilder.append('\t'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                  ^ reference local38
+//                                                    ^^ reference scala/Int#`+`(+4).
+
+          case '"' => { outputBuilder.append('"'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                 ^ reference local38
+//                                                   ^^ reference scala/Int#`+`(+4).
+          case '/' => { outputBuilder.append('/'); i += 2 }
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                 ^ reference local38
+//                                                   ^^ reference scala/Int#`+`(+4).
+          case '\\' => { outputBuilder.append('\\'); i += 2 }
+//                       ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                     ^^^^^^ reference upickle/core/CharBuilder#append(+1).
+//                                                   ^ reference local38
+//                                                     ^^ reference scala/Int#`+`(+4).
+
+          // if there's a problem then descape will explode
+          case 'u' =>
+            val d = descape(i)
+//              ^ definition local40
+//                  ^^^^^^^ reference ujson/CharParser#descape().
+//                          ^ reference local38
+            outputBuilder.appendC(d)
+//          ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                        ^^^^^^^ reference upickle/core/CharAppendC#appendC().
+//                                ^ reference local40
+
+            i += 6
+//          ^ reference local38
+//            ^^ reference scala/Int#`+`(+4).
+
+          case c => die(i + 1, s"illegal escape sequence after \\")
+//             ^ definition local41
+//                  ^^^ reference ujson/CharParser#die().
+//                      ^ reference local38
+//                        ^ reference scala/Int#`+`(+4).
+//                             ^ reference scala/StringContext#s().
+        }
+      } else {
+        // this case is for "normal" code points that are just one Char.
+        //
+        // we don't have to worry about surrogate pairs, since those
+        // will all be in the ranges D800–DBFF (high surrogates) or
+        // DC00–DFFF (low surrogates).
+        outputBuilder.append(c)
+//      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                    ^^^^^^ reference upickle/core/CharBuilder#append().
+//                           ^ reference local39
+        i += 1
+//      ^ reference local38
+//        ^^ reference scala/Int#`+`(+4).
+      }
+      c = elemOps.toUnsignedInt(getCharSafe(i))
+//    ^ reference local39
+//        ^^^^^^^ reference ujson/CharParser#elemOps.
+//                ^^^^^^^^^^^^^ reference upickle/core/CharOps.toUnsignedInt().
+//                              ^^^^^^^^^^^ reference ujson/CharParser#getCharSafe().
+//                                          ^ reference local38
+    }
+
+    i + 1
+//  ^ reference local38
+//    ^ reference scala/Int#`+`(+4).
+  }
+
+  /**
+    * Parse the string according to JSON rules, and add to the given
+    * context.
+    *
+    * This method expects the data to be in UTF-16, and access it as
+    * Char. It performs the correct checks to make sure that we don't
+    * interpret a multi-char code point incorrectly.
+    */
+  protected[this] final def parseStringValue(i: Int, stackHead: ObjArrVisitor[_, J]): Int = {
+//                          ^^^^^^^^^^^^^^^^ definition ujson/CharParser#parseStringValue().
+//                                           ^ definition ujson/CharParser#parseStringValue().(i)
+//                                              ^^^ reference scala/Int#
+//                                                   ^^^^^^^^^ definition ujson/CharParser#parseStringValue().(stackHead)
+//                                                              ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                               ^ reference ujson/CharParser#[J]
+//                                                                                    ^^^ reference scala/Int#
+
+    val k = parseStringSimple(i + 1)
+//      ^ definition local42
+//          ^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringSimple().
+//                            ^ reference ujson/CharParser#parseStringValue().(i)
+//                              ^ reference scala/Int#`+`(+4).
+    if (k >= 0) {
+//      ^ reference local42
+//        ^^ reference scala/Int#`>=`(+3).
+      visitString(i, unsafeCharSeqForRange(i + 1, k - i - 2), stackHead)
+//    ^^^^^^^^^^^ reference ujson/CharParser#visitString().
+//                ^ reference ujson/CharParser#parseStringValue().(i)
+//                   ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#unsafeCharSeqForRange().
+//                                         ^ reference ujson/CharParser#parseStringValue().(i)
+//                                           ^ reference scala/Int#`+`(+4).
+//                                                ^ reference local42
+//                                                  ^ reference scala/Int#`-`(+3).
+//                                                    ^ reference ujson/CharParser#parseStringValue().(i)
+//                                                      ^ reference scala/Int#`-`(+3).
+//                                                            ^^^^^^^^^ reference ujson/CharParser#parseStringValue().(stackHead)
+      k
+//    ^ reference local42
+    } else {
+      val k2 = parseStringToOutputBuilder(i, k)
+//        ^^ definition local43
+//             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringToOutputBuilder().
+//                                        ^ reference ujson/CharParser#parseStringValue().(i)
+//                                           ^ reference local42
+      visitString(i, outputBuilder.makeString(), stackHead)
+//    ^^^^^^^^^^^ reference ujson/CharParser#visitString().
+//                ^ reference ujson/CharParser#parseStringValue().(i)
+//                   ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                 ^^^^^^^^^^ reference upickle/core/CharBuilder#makeString().
+//                                               ^^^^^^^^^ reference ujson/CharParser#parseStringValue().(stackHead)
+      k2
+//    ^^ reference local43
+    }
+  }
+
+  protected[this] final def parseStringKey(i: Int, stackHead: ObjArrVisitor[_, J]): Int = {
+//                          ^^^^^^^^^^^^^^ definition ujson/CharParser#parseStringKey().
+//                                         ^ definition ujson/CharParser#parseStringKey().(i)
+//                                            ^^^ reference scala/Int#
+//                                                 ^^^^^^^^^ definition ujson/CharParser#parseStringKey().(stackHead)
+//                                                            ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                             ^ reference ujson/CharParser#[J]
+//                                                                                  ^^^ reference scala/Int#
+
+    val k = parseStringSimple(i + 1)
+//      ^ definition local44
+//          ^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringSimple().
+//                            ^ reference ujson/CharParser#parseStringKey().(i)
+//                              ^ reference scala/Int#`+`(+4).
+    if (k >= 0) {
+//      ^ reference local44
+//        ^^ reference scala/Int#`>=`(+3).
+      visitStringKey(i, unsafeCharSeqForRange(i + 1, k - i - 2), stackHead)
+//    ^^^^^^^^^^^^^^ reference ujson/CharParser#visitStringKey().
+//                   ^ reference ujson/CharParser#parseStringKey().(i)
+//                      ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#unsafeCharSeqForRange().
+//                                            ^ reference ujson/CharParser#parseStringKey().(i)
+//                                              ^ reference scala/Int#`+`(+4).
+//                                                   ^ reference local44
+//                                                     ^ reference scala/Int#`-`(+3).
+//                                                       ^ reference ujson/CharParser#parseStringKey().(i)
+//                                                         ^ reference scala/Int#`-`(+3).
+//                                                               ^^^^^^^^^ reference ujson/CharParser#parseStringKey().(stackHead)
+      k
+//    ^ reference local44
+    } else {
+      val k2 = parseStringToOutputBuilder(i, k)
+//        ^^ definition local45
+//             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringToOutputBuilder().
+//                                        ^ reference ujson/CharParser#parseStringKey().(i)
+//                                           ^ reference local44
+      visitStringKey(i, outputBuilder.makeString(), stackHead)
+//    ^^^^^^^^^^^^^^ reference ujson/CharParser#visitStringKey().
+//                   ^ reference ujson/CharParser#parseStringKey().(i)
+//                      ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                    ^^^^^^^^^^ reference upickle/core/CharBuilder#makeString().
+//                                                  ^^^^^^^^^ reference ujson/CharParser#parseStringKey().(stackHead)
+      k2
+//    ^^ reference local45
+    }
+  }
+
+
+  def parseStringToOutputBuilder(i: Int, k: Int) = {
+//    ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/CharParser#parseStringToOutputBuilder().
+//                               ^ definition ujson/CharParser#parseStringToOutputBuilder().(i)
+//                                  ^^^ reference scala/Int#
+//                                       ^ definition ujson/CharParser#parseStringToOutputBuilder().(k)
+//                                          ^^^ reference scala/Int#
+    outputBuilder.reset()
+//  ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                ^^^^^ reference upickle/core/CharBuilder#reset().
+    appendCharsToBuilder(outputBuilder, i + 1, -k - 2 - i)
+//  ^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#appendCharsToBuilder().
+//                       ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                      ^ reference ujson/CharParser#parseStringToOutputBuilder().(i)
+//                                        ^ reference scala/Int#`+`(+4).
+//                                             ^ reference scala/Int#`unary_-`().
+//                                              ^ reference ujson/CharParser#parseStringToOutputBuilder().(k)
+//                                                ^ reference scala/Int#`-`(+3).
+//                                                    ^ reference scala/Int#`-`(+3).
+//                                                      ^ reference ujson/CharParser#parseStringToOutputBuilder().(i)
+    val k2 = parseStringComplex(-k - 1)
+//      ^^ definition local46
+//           ^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringComplex().
+//                              ^ reference scala/Int#`unary_-`().
+//                               ^ reference ujson/CharParser#parseStringToOutputBuilder().(k)
+//                                 ^ reference scala/Int#`-`(+3).
+    k2
+//  ^^ reference local46
+  }
+
+  def visitString(i: Int, s: CharSequence, stackHead: ObjArrVisitor[_, J]) = {
+//    ^^^^^^^^^^^ definition ujson/CharParser#visitString().
+//                ^ definition ujson/CharParser#visitString().(i)
+//                   ^^^ reference scala/Int#
+//                        ^ definition ujson/CharParser#visitString().(s)
+//                           ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                         ^^^^^^^^^ definition ujson/CharParser#visitString().(stackHead)
+//                                                    ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                     ^ reference ujson/CharParser#[J]
+    val v = stackHead.subVisitor.visitString(s, i)
+//      ^ definition local47
+//          ^^^^^^^^^ reference ujson/CharParser#visitString().(stackHead)
+//                    ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                               ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                           ^ reference ujson/CharParser#visitString().(s)
+//                                              ^ reference ujson/CharParser#visitString().(i)
+    stackHead.narrow.visitValue(v, i)
+//  ^^^^^^^^^ reference ujson/CharParser#visitString().(stackHead)
+//            ^^^^^^ reference upickle/core/ObjArrVisitor#narrow().
+//                   ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                              ^ reference local47
+//                                 ^ reference ujson/CharParser#visitString().(i)
+  }
+  def visitStringKey(i: Int, s: CharSequence, stackHead: ObjArrVisitor[_, J]) = {
+//    ^^^^^^^^^^^^^^ definition ujson/CharParser#visitStringKey().
+//                   ^ definition ujson/CharParser#visitStringKey().(i)
+//                      ^^^ reference scala/Int#
+//                           ^ definition ujson/CharParser#visitStringKey().(s)
+//                              ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                            ^^^^^^^^^ definition ujson/CharParser#visitStringKey().(stackHead)
+//                                                       ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                                        ^ reference ujson/CharParser#[J]
+    val obj = stackHead.asInstanceOf[ObjVisitor[Any, _]]
+//      ^^^ definition local48
+//            ^^^^^^^^^ reference ujson/CharParser#visitStringKey().(stackHead)
+//                      ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                   ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                              ^^^ reference scala/Any#
+    val keyVisitor = obj.visitKey(i)
+//      ^^^^^^^^^^ definition local49
+//                   ^^^ reference local48
+//                       ^^^^^^^^ reference upickle/core/ObjVisitor#visitKey().
+//                                ^ reference ujson/CharParser#visitStringKey().(i)
+    obj.visitKeyValue(keyVisitor.visitString(s, i))
+//  ^^^ reference local48
+//      ^^^^^^^^^^^^^ reference upickle/core/ObjVisitor#visitKeyValue().
+//                    ^^^^^^^^^^ reference local49
+//                               ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                           ^ reference ujson/CharParser#visitStringKey().(s)
+//                                              ^ reference ujson/CharParser#visitStringKey().(i)
+  }
+
+
+  protected[this] final def parseStringTopLevel(i: Int, facade: Visitor[_, J]): (J, Int) = {
+//                          ^^^^^^^^^^^^^^^^^^^ definition ujson/CharParser#parseStringTopLevel().
+//                                              ^ definition ujson/CharParser#parseStringTopLevel().(i)
+//                                                 ^^^ reference scala/Int#
+//                                                      ^^^^^^ definition ujson/CharParser#parseStringTopLevel().(facade)
+//                                                              ^^^^^^^ reference upickle/core/Visitor#
+//                                                                         ^ reference ujson/CharParser#[J]
+//                                                                               ^ reference ujson/CharParser#[J]
+//                                                                                  ^^^ reference scala/Int#
+
+    val k = parseStringSimple(i + 1)
+//      ^ definition local50
+//          ^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringSimple().
+//                            ^ reference ujson/CharParser#parseStringTopLevel().(i)
+//                              ^ reference scala/Int#`+`(+4).
+    if (k >= 0) {
+//      ^ reference local50
+//        ^^ reference scala/Int#`>=`(+3).
+      val res = facade.visitString(unsafeCharSeqForRange(i + 1, k - i - 2), i)
+//        ^^^ definition local51
+//              ^^^^^^ reference ujson/CharParser#parseStringTopLevel().(facade)
+//                     ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                 ^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingCharParser#unsafeCharSeqForRange().
+//                                                       ^ reference ujson/CharParser#parseStringTopLevel().(i)
+//                                                         ^ reference scala/Int#`+`(+4).
+//                                                              ^ reference local50
+//                                                                ^ reference scala/Int#`-`(+3).
+//                                                                  ^ reference ujson/CharParser#parseStringTopLevel().(i)
+//                                                                    ^ reference scala/Int#`-`(+3).
+//                                                                          ^ reference ujson/CharParser#parseStringTopLevel().(i)
+      (res, k)
+//     ^^^ reference local51
+//          ^ reference local50
+    } else {
+      val k2 = parseStringToOutputBuilder(i, k)
+//        ^^ definition local52
+//             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference ujson/CharParser#parseStringToOutputBuilder().
+//                                        ^ reference ujson/CharParser#parseStringTopLevel().(i)
+//                                           ^ reference local50
+      val res = facade.visitString(outputBuilder.makeString(), i)
+//        ^^^ definition local53
+//              ^^^^^^ reference ujson/CharParser#parseStringTopLevel().(facade)
+//                     ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                 ^^^^^^^^^^^^^ reference ujson/CharParser#outputBuilder.
+//                                               ^^^^^^^^^^ reference upickle/core/CharBuilder#makeString().
+//                                                             ^ reference ujson/CharParser#parseStringTopLevel().(i)
+      (res, k2)
+//     ^^^ reference local53
+//          ^^ reference local52
+    }
+  }
+}
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyController.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyController.java
index d870eea9e..8a71ae671 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyController.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyController.java
@@ -23,7 +23,7 @@
  * See https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#asynchronous-support
  */
 public abstract class AsyncEpoxyController extends EpoxyController {
-//                    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyController# public abstract class AsyncEpoxyController extends EpoxyController
+//                    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyController# public abstract class AsyncEpoxyController
 //                                                 ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyController#
 
   /**
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyDiffer.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyDiffer.java
index 1137e049c..e8c993296 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyDiffer.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyDiffer.java
@@ -494,7 +494,7 @@ synchronized boolean finishGeneration(int runGeneration) {
   }
 
   private static class DiffCallback extends DiffUtil.Callback {
-//                     ^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#DiffCallback# private static class DiffCallback extends unresolved_type
+//                     ^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#DiffCallback# private static class DiffCallback
 //                                          ^^^^^^^^ reference DiffUtil/
 //                                                   ^^^^^^^^ reference DiffUtil/Callback#
 
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/BaseEpoxyAdapter.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/BaseEpoxyAdapter.java
index 967bbf1b3..a2439e1dd 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/BaseEpoxyAdapter.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/BaseEpoxyAdapter.java
@@ -60,7 +60,7 @@
 //                                  ^^^^^^^^^^^^ reference androidx/recyclerview/widget/RecyclerView#
 
 public abstract class BaseEpoxyAdapter
-//                    ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BaseEpoxyAdapter# public abstract class BaseEpoxyAdapter extends unresolved_type implements unresolved_type
+//                    ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BaseEpoxyAdapter# public abstract class BaseEpoxyAdapter
     extends RecyclerView.Adapter<EpoxyViewHolder>
 //          ^^^^^^^^^^^^ reference RecyclerView/
 //                       ^^^^^^^ reference RecyclerView/Adapter#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/BoundViewHolders.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/BoundViewHolders.java
index bf9fa1ab3..6f5448e93 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/BoundViewHolders.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/BoundViewHolders.java
@@ -23,7 +23,7 @@
 @SuppressWarnings("WeakerAccess")
 //^^^^^^^^^^^^^^^ reference java/lang/SuppressWarnings#
 public class BoundViewHolders implements Iterable<EpoxyViewHolder> {
-//           ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders# @SuppressWarnings("WeakerAccess") public class BoundViewHolders implements Iterable<EpoxyViewHolder>
+//           ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders# @SuppressWarnings("WeakerAccess") public class BoundViewHolders
 //           ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#`<init>`(). public BoundViewHolders()
 //                                       ^^^^^^^^ reference java/lang/Iterable#
 //                                                ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyViewHolder#
@@ -102,7 +102,7 @@ public EpoxyViewHolder getHolderForModel(EpoxyModel<?> model) {
   }
 
   private class HolderIterator implements Iterator<EpoxyViewHolder> {
-//              ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#HolderIterator# private class HolderIterator implements Iterator<EpoxyViewHolder>
+//              ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#HolderIterator# private class HolderIterator
 //              ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#HolderIterator#`<init>`(). private HolderIterator()
 //                                        ^^^^^^^^ reference java/util/Iterator#
 //                                                 ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyViewHolder#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Carousel.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Carousel.java
index 366f83ded..52dce887c 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Carousel.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Carousel.java
@@ -110,7 +110,7 @@
 //                                            ^^^^ reference com/airbnb/epoxy/ModelView#Size#
 //                                                 ^^^^^^^^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/ModelView#Size#MATCH_WIDTH_WRAP_HEIGHT.
 public class Carousel extends EpoxyRecyclerView {
-//           ^^^^^^^^ definition com/airbnb/epoxy/Carousel# @ModelView(saveViewState = true, autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT) public class Carousel extends unresolved_type
+//           ^^^^^^^^ definition com/airbnb/epoxy/Carousel# @ModelView(saveViewState = true, autoLayout = Size.MATCH_WIDTH_WRAP_HEIGHT) public class Carousel
 //                            ^^^^^^^^^^^^^^^^^ reference _root_/
   public static final int NO_VALUE_SET = -1;
 //                        ^^^^^^^^^^^^ definition com/airbnb/epoxy/Carousel#NO_VALUE_SET. public static final int NO_VALUE_SET
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ControllerModelList.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ControllerModelList.java
index e1f8b46f0..02716f544 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ControllerModelList.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ControllerModelList.java
@@ -8,7 +8,7 @@
  * why it doesn't do anything.
  */
 class ControllerModelList extends ModelList {
-//    ^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ControllerModelList# class ControllerModelList extends ModelList
+//    ^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ControllerModelList# class ControllerModelList
 //                                ^^^^^^^^^ reference com/airbnb/epoxy/ModelList#
 
   private static final ModelListObserver OBSERVER = new ModelListObserver() {
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/DebugTimer.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/DebugTimer.java
index db70bedc6..761e2ca05 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/DebugTimer.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/DebugTimer.java
@@ -6,7 +6,7 @@
 //                  ^^^ reference android/util/Log#
 
 class DebugTimer implements Timer {
-//    ^^^^^^^^^^ definition com/airbnb/epoxy/DebugTimer# class DebugTimer implements Timer
+//    ^^^^^^^^^^ definition com/airbnb/epoxy/DebugTimer# class DebugTimer
 //                          ^^^^^ reference com/airbnb/epoxy/Timer#
 
   private final String tag;
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyAdapter.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyAdapter.java
index 5c524fe42..f176990db 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyAdapter.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyAdapter.java
@@ -35,7 +35,7 @@
 @SuppressWarnings("WeakerAccess")
 //^^^^^^^^^^^^^^^ reference java/lang/SuppressWarnings#
 public abstract class EpoxyAdapter extends BaseEpoxyAdapter {
-//                    ^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAdapter# @SuppressWarnings("WeakerAccess") public abstract class EpoxyAdapter extends BaseEpoxyAdapter
+//                    ^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAdapter# @SuppressWarnings("WeakerAccess") public abstract class EpoxyAdapter
 //                    ^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyAdapter#`<init>`(). public EpoxyAdapter()
 //                                         ^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/BaseEpoxyAdapter#
   private final HiddenEpoxyModel hiddenModel = new HiddenEpoxyModel();
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyController.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyController.java
index fdc0c0687..0049ab766 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyController.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyController.java
@@ -112,7 +112,7 @@
  * accurate.
  */
 public abstract class EpoxyController implements ModelCollector, StickyHeaderCallbacks {
-//                    ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyController# public abstract class EpoxyController implements unresolved_type, unresolved_type
+//                    ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyController# public abstract class EpoxyController
 //                                               ^^^^^^^^^^^^^^ reference _root_/
 //                                                               ^^^^^^^^^^^^^^^^^^^^^ reference _root_/
 
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyControllerAdapter.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyControllerAdapter.java
index 3a2b0665e..b03f9d5a5 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyControllerAdapter.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyControllerAdapter.java
@@ -56,7 +56,7 @@
 //                                  ^^^^^^^^^^^^ reference androidx/recyclerview/widget/RecyclerView#
 
 public final class EpoxyControllerAdapter extends BaseEpoxyAdapter implements ResultCallback {
-//                 ^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyControllerAdapter# public final class EpoxyControllerAdapter extends BaseEpoxyAdapter implements ResultCallback
+//                 ^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyControllerAdapter# public final class EpoxyControllerAdapter
 //                                                ^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/BaseEpoxyAdapter#
 //                                                                            ^^^^^^^^^^^^^^ reference com/airbnb/epoxy/AsyncEpoxyDiffer#ResultCallback#
   private final NotifyBlocker notifyBlocker = new NotifyBlocker();
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDiffLogger.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDiffLogger.java
index d8260c9f3..a5c8b71f2 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDiffLogger.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDiffLogger.java
@@ -28,7 +28,7 @@
  * optimization.
  */
 public class EpoxyDiffLogger extends AdapterDataObserver {
-//           ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyDiffLogger# public class EpoxyDiffLogger extends unresolved_type
+//           ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyDiffLogger# public class EpoxyDiffLogger
 //                                   ^^^^^^^^^^^^^^^^^^^ reference _root_/
   private final String tag;
 //              ^^^^^^ reference java/lang/String#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDragCallback.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDragCallback.java
index 1686d2a40..7dd27af1b 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDragCallback.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyDragCallback.java
@@ -9,7 +9,7 @@
  * For use with {@link EpoxyModelTouchCallback}
  */
 public interface EpoxyDragCallback<T extends EpoxyModel> extends BaseEpoxyTouchCallback<T> {
-//               ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyDragCallback# public interface EpoxyDragCallback<T extends EpoxyModel> extends BaseEpoxyTouchCallback<T>
+//               ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyDragCallback# public interface EpoxyDragCallback<T extends EpoxyModel>
 //                                 ^ definition com/airbnb/epoxy/EpoxyDragCallback#[T] T extends EpoxyModel
 //                                           ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
 //                                                               ^^^^^^^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/BaseEpoxyTouchCallback#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyItemSpacingDecorator.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyItemSpacingDecorator.java
index e6ab81bfc..d77550993 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyItemSpacingDecorator.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyItemSpacingDecorator.java
@@ -57,7 +57,7 @@
  * are on the grid. Only designed to work with standard linear or grid layout managers.
  */
 public class EpoxyItemSpacingDecorator extends RecyclerView.ItemDecoration {
-//           ^^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyItemSpacingDecorator# public class EpoxyItemSpacingDecorator extends unresolved_type
+//           ^^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyItemSpacingDecorator# public class EpoxyItemSpacingDecorator
 //                                             ^^^^^^^^^^^^ reference RecyclerView/
 //                                                          ^^^^^^^^^^^^^^ reference RecyclerView/ItemDecoration#
   private int pxBetweenItems;
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelGroup.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelGroup.java
index 6ac9437ba..9178ecbcb 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelGroup.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelGroup.java
@@ -97,7 +97,7 @@
 @SuppressWarnings("rawtypes")
 //^^^^^^^^^^^^^^^ reference java/lang/SuppressWarnings#
 public class EpoxyModelGroup extends EpoxyModelWithHolder<ModelGroupHolder> {
-//           ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelGroup# @SuppressWarnings("rawtypes") public class EpoxyModelGroup extends EpoxyModelWithHolder<unresolved_type>
+//           ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelGroup# @SuppressWarnings("rawtypes") public class EpoxyModelGroup
 //                                   ^^^^^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModelWithHolder#
 //                                                        ^^^^^^^^^^^^^^^^ reference _root_/
 
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelTouchCallback.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelTouchCallback.java
index 975d6c98d..afb711f1e 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelTouchCallback.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelTouchCallback.java
@@ -39,7 +39,7 @@
  * your own {@link ItemTouchHelper} if you need extra flexibility or customization.
  */
 public abstract class EpoxyModelTouchCallback<T extends EpoxyModel>
-//                    ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelTouchCallback# public abstract class EpoxyModelTouchCallback<T extends EpoxyModel> extends EpoxyTouchHelperCallback implements EpoxyDragCallback<T>, EpoxySwipeCallback<T>
+//                    ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelTouchCallback# public abstract class EpoxyModelTouchCallback<T extends EpoxyModel>
 //                                            ^ definition com/airbnb/epoxy/EpoxyModelTouchCallback#[T] T extends EpoxyModel
 //                                                      ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
     extends EpoxyTouchHelperCallback implements EpoxyDragCallback<T>, EpoxySwipeCallback<T> {
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithHolder.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithHolder.java
index 78765eba6..f58d1897e 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithHolder.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithHolder.java
@@ -35,7 +35,7 @@
  * instead of a specific view when binding to your model.
  */
 public abstract class EpoxyModelWithHolder<T extends EpoxyHolder> extends EpoxyModel<T> {
-//                    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelWithHolder# public abstract class EpoxyModelWithHolder<T extends EpoxyHolder> extends EpoxyModel<T>
+//                    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelWithHolder# public abstract class EpoxyModelWithHolder<T extends EpoxyHolder>
 //                                         ^ definition com/airbnb/epoxy/EpoxyModelWithHolder#[T] T extends EpoxyHolder
 //                                                   ^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyHolder#
 //                                                                        ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithView.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithView.java
index 3f4fd9ab6..fe323e60b 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithView.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyModelWithView.java
@@ -35,7 +35,7 @@
  * resource file.
  */
 public abstract class EpoxyModelWithView<T extends View> extends EpoxyModel<T> {
-//                    ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelWithView# public abstract class EpoxyModelWithView<T extends unresolved_type> extends EpoxyModel<T>
+//                    ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelWithView# public abstract class EpoxyModelWithView<T extends unresolved_type>
 //                    ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyModelWithView#`<init>`(). public EpoxyModelWithView()
 //                                       ^ definition com/airbnb/epoxy/EpoxyModelWithView#[T] T extends unresolved_type
 //                                                 ^^^^ reference _root_/
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxySwipeCallback.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxySwipeCallback.java
index b5684a6a5..62931ce7f 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxySwipeCallback.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxySwipeCallback.java
@@ -19,7 +19,7 @@
  * For use with {@link EpoxyModelTouchCallback}
  */
 public interface EpoxySwipeCallback<T extends EpoxyModel> extends BaseEpoxyTouchCallback<T> {
-//               ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxySwipeCallback# public interface EpoxySwipeCallback<T extends EpoxyModel> extends BaseEpoxyTouchCallback<T>
+//               ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxySwipeCallback# public interface EpoxySwipeCallback<T extends EpoxyModel>
 //                                  ^ definition com/airbnb/epoxy/EpoxySwipeCallback#[T] T extends EpoxyModel
 //                                            ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
 //                                                                ^^^^^^^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/BaseEpoxyTouchCallback#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelper.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelper.java
index ae406b9c1..0238286d2 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelper.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelper.java
@@ -516,7 +516,7 @@ public void clearView(U model, View itemView) {
   }
 
   public abstract static class DragCallbacks<T extends EpoxyModel>
-//                             ^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelper#DragCallbacks# public abstract static class DragCallbacks<T extends EpoxyModel> implements EpoxyDragCallback<T>
+//                             ^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelper#DragCallbacks# public abstract static class DragCallbacks<T extends EpoxyModel>
 //                             ^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelper#DragCallbacks#`<init>`(). public DragCallbacks()
 //                                           ^ definition com/airbnb/epoxy/EpoxyTouchHelper#DragCallbacks#[T] T extends EpoxyModel
 //                                                     ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
@@ -992,7 +992,7 @@ public void clearView(U model, View itemView) {
   }
 
   public abstract static class SwipeCallbacks<T extends EpoxyModel>
-//                             ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelper#SwipeCallbacks# public abstract static class SwipeCallbacks<T extends EpoxyModel> implements EpoxySwipeCallback<T>
+//                             ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelper#SwipeCallbacks# public abstract static class SwipeCallbacks<T extends EpoxyModel>
 //                             ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelper#SwipeCallbacks#`<init>`(). public SwipeCallbacks()
 //                                            ^ definition com/airbnb/epoxy/EpoxyTouchHelper#SwipeCallbacks#[T] T extends EpoxyModel
 //                                                      ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelperCallback.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelperCallback.java
index ab949ec02..425d27d46 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelperCallback.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyTouchHelperCallback.java
@@ -32,7 +32,7 @@
  * view holders to {@link com.airbnb.epoxy.EpoxyViewHolder} for simpler use with Epoxy.
  */
 public abstract class EpoxyTouchHelperCallback extends ItemTouchHelper.Callback {
-//                    ^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelperCallback# public abstract class EpoxyTouchHelperCallback extends unresolved_type
+//                    ^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelperCallback# public abstract class EpoxyTouchHelperCallback
 //                    ^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyTouchHelperCallback#`<init>`(). public EpoxyTouchHelperCallback()
 //                                                     ^^^^^^^^^^^^^^^ reference ItemTouchHelper/
 //                                                                     ^^^^^^^^ reference ItemTouchHelper/Callback#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyViewHolder.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyViewHolder.java
index 34cef4f8d..5d0cc539c 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyViewHolder.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/EpoxyViewHolder.java
@@ -52,7 +52,7 @@
 @SuppressWarnings("WeakerAccess")
 //^^^^^^^^^^^^^^^ reference java/lang/SuppressWarnings#
 public class EpoxyViewHolder extends RecyclerView.ViewHolder {
-//           ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyViewHolder# @SuppressWarnings("WeakerAccess") public class EpoxyViewHolder extends unresolved_type
+//           ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/EpoxyViewHolder# @SuppressWarnings("WeakerAccess") public class EpoxyViewHolder
 //                                   ^^^^^^^^^^^^ reference RecyclerView/
 //                                                ^^^^^^^^^^ reference RecyclerView/ViewHolder#
   @SuppressWarnings("rawtypes") private EpoxyModel epoxyModel;
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/HandlerExecutor.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/HandlerExecutor.java
index 8a5344678..204bb6eab 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/HandlerExecutor.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/HandlerExecutor.java
@@ -27,7 +27,7 @@
  * same as the handler's thread.
  */
 class HandlerExecutor implements Executor {
-//    ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/HandlerExecutor# class HandlerExecutor implements Executor
+//    ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/HandlerExecutor# class HandlerExecutor
 //                               ^^^^^^^^ reference java/util/concurrent/Executor#
   final Handler handler;
 //      ^^^^^^^ reference _root_/
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/HiddenEpoxyModel.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/HiddenEpoxyModel.java
index 8fc473144..b9d74ada9 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/HiddenEpoxyModel.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/HiddenEpoxyModel.java
@@ -18,7 +18,7 @@
  * view.
  */
 class HiddenEpoxyModel extends EpoxyModel<Space> {
-//    ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/HiddenEpoxyModel# class HiddenEpoxyModel extends EpoxyModel<unresolved_type>
+//    ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/HiddenEpoxyModel# class HiddenEpoxyModel
 //    ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/HiddenEpoxyModel#`<init>`(). HiddenEpoxyModel()
 //                             ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
 //                                        ^^^^^ reference _root_/
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/IllegalEpoxyUsage.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/IllegalEpoxyUsage.java
index 6bc3d912e..07011276d 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/IllegalEpoxyUsage.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/IllegalEpoxyUsage.java
@@ -1,7 +1,7 @@
 package com.airbnb.epoxy;
 
 public class IllegalEpoxyUsage extends RuntimeException {
-//           ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/IllegalEpoxyUsage# public class IllegalEpoxyUsage extends RuntimeException
+//           ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/IllegalEpoxyUsage# public class IllegalEpoxyUsage
 //                                     ^^^^^^^^^^^^^^^^ reference java/lang/RuntimeException#
   public IllegalEpoxyUsage(String message) {
 //       ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/IllegalEpoxyUsage#`<init>`(). public IllegalEpoxyUsage(String message)
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ImmutableModelException.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ImmutableModelException.java
index c9512b8fe..bc2fe906a 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ImmutableModelException.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ImmutableModelException.java
@@ -9,7 +9,7 @@
  * Thrown if a model is changed after it is added to an {@link com.airbnb.epoxy.EpoxyController}.
  */
 class ImmutableModelException extends RuntimeException {
-//    ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ImmutableModelException# class ImmutableModelException extends RuntimeException
+//    ^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ImmutableModelException# class ImmutableModelException
 //                                    ^^^^^^^^^^^^^^^^ reference java/lang/RuntimeException#
   private static final String MODEL_CANNOT_BE_CHANGED_MESSAGE =
 //                     ^^^^^^ reference java/lang/String#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/MainThreadExecutor.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/MainThreadExecutor.java
index a322eafca..4fbf8ad98 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/MainThreadExecutor.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/MainThreadExecutor.java
@@ -12,7 +12,7 @@
 //                             ^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyAsyncUtil#
 
 class MainThreadExecutor extends HandlerExecutor {
-//    ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/MainThreadExecutor# class MainThreadExecutor extends HandlerExecutor
+//    ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/MainThreadExecutor# class MainThreadExecutor
 //                               ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/HandlerExecutor#
   static final MainThreadExecutor INSTANCE = new MainThreadExecutor(false);
 //             ^^^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/MainThreadExecutor#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ModelList.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ModelList.java
index e15d89d4b..5ec45f1cb 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ModelList.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ModelList.java
@@ -44,7 +44,7 @@
  * diffing since we have a knowledge of what changed in the list.
  */
 class ModelList extends ArrayList<EpoxyModel<?>> {
-//    ^^^^^^^^^ definition com/airbnb/epoxy/ModelList# class ModelList extends ArrayList<EpoxyModel<?>>
+//    ^^^^^^^^^ definition com/airbnb/epoxy/ModelList# class ModelList
 //                      ^^^^^^^^^ reference java/util/ArrayList#
 //                                ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
 
@@ -410,7 +410,7 @@ public Iterator<EpoxyModel<?>> iterator() {
    * the parent methods so that the proper notifications are done.
    */
   private class Itr implements Iterator<EpoxyModel<?>> {
-//              ^^^ definition com/airbnb/epoxy/ModelList#Itr# private class Itr implements Iterator<EpoxyModel<?>>
+//              ^^^ definition com/airbnb/epoxy/ModelList#Itr# private class Itr
 //              ^^^ definition com/airbnb/epoxy/ModelList#Itr#`<init>`(). private Itr()
 //                             ^^^^^^^^ reference java/util/Iterator#
 //                                      ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
@@ -528,7 +528,7 @@ public ListIterator<EpoxyModel<?>> listIterator(int index) {
    * notifications are done.
    */
   private class ListItr extends Itr implements ListIterator<EpoxyModel<?>> {
-//              ^^^^^^^ definition com/airbnb/epoxy/ModelList#ListItr# private class ListItr extends Itr implements ListIterator<EpoxyModel<?>>
+//              ^^^^^^^ definition com/airbnb/epoxy/ModelList#ListItr# private class ListItr
 //                              ^^^ reference com/airbnb/epoxy/ModelList#Itr#
 //                                             ^^^^^^^^^^^^ reference java/util/ListIterator#
 //                                                          ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
@@ -684,7 +684,7 @@ public List<EpoxyModel<?>> subList(int start, int end) {
    * the implementation to call the parent methods so that the proper notifications are done.
    */
   private static class SubList extends AbstractList<EpoxyModel<?>> {
-//                     ^^^^^^^ definition com/airbnb/epoxy/ModelList#SubList# private static class SubList extends AbstractList<EpoxyModel<?>>
+//                     ^^^^^^^ definition com/airbnb/epoxy/ModelList#SubList# private static class SubList
 //                                     ^^^^^^^^^^^^ reference java/util/AbstractList#
 //                                                  ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
     private final ModelList fullList;
@@ -696,7 +696,7 @@ private static class SubList extends AbstractList<EpoxyModel<?>> {
 //              ^^^^ definition com/airbnb/epoxy/ModelList#SubList#size. private int size
 
     private static final class SubListIterator implements ListIterator<EpoxyModel<?>> {
-//                             ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelList#SubList#SubListIterator# private static final class SubListIterator implements ListIterator<EpoxyModel<?>>
+//                             ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ModelList#SubList#SubListIterator# private static final class SubListIterator
 //                                                        ^^^^^^^^^^^^ reference java/util/ListIterator#
 //                                                                     ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
       private final SubList subList;
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpControllerHelper.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpControllerHelper.java
index 1f55ed97e..e0757acd5 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpControllerHelper.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpControllerHelper.java
@@ -5,7 +5,7 @@
  * com.airbnb.epoxy.AutoModel} usage.
  */
 class NoOpControllerHelper extends ControllerHelper<EpoxyController> {
-//    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/NoOpControllerHelper# class NoOpControllerHelper extends ControllerHelper<EpoxyController>
+//    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/NoOpControllerHelper# class NoOpControllerHelper
 //    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/NoOpControllerHelper#`<init>`(). NoOpControllerHelper()
 //                                 ^^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/ControllerHelper#
 //                                                  ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyController#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpTimer.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpTimer.java
index ea5eaf506..70db7f42a 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpTimer.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpTimer.java
@@ -1,7 +1,7 @@
 package com.airbnb.epoxy;
 
 class NoOpTimer implements Timer {
-//    ^^^^^^^^^ definition com/airbnb/epoxy/NoOpTimer# class NoOpTimer implements Timer
+//    ^^^^^^^^^ definition com/airbnb/epoxy/NoOpTimer# class NoOpTimer
 //    ^^^^^^^^^ definition com/airbnb/epoxy/NoOpTimer#`<init>`(). NoOpTimer()
 //                         ^^^^^ reference com/airbnb/epoxy/Timer#
   @Override
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/NotifyBlocker.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/NotifyBlocker.java
index d08ac1067..bcc29bcb7 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/NotifyBlocker.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/NotifyBlocker.java
@@ -15,7 +15,7 @@
  * This observer throws upon any changes done outside of diffing.
  */
 class NotifyBlocker extends AdapterDataObserver {
-//    ^^^^^^^^^^^^^ definition com/airbnb/epoxy/NotifyBlocker# class NotifyBlocker extends unresolved_type
+//    ^^^^^^^^^^^^^ definition com/airbnb/epoxy/NotifyBlocker# class NotifyBlocker
 //    ^^^^^^^^^^^^^ definition com/airbnb/epoxy/NotifyBlocker#`<init>`(). NotifyBlocker()
 //                          ^^^^^^^^^^^^^^^^^^^ reference _root_/
 
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyAdapter.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyAdapter.java
index eb34cdb9e..49305de1c 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyAdapter.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyAdapter.java
@@ -15,7 +15,7 @@
  * to modify the adapter from elsewhere, such as from an activity.
  */
 public class SimpleEpoxyAdapter extends EpoxyAdapter {
-//           ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyAdapter# public class SimpleEpoxyAdapter extends EpoxyAdapter
+//           ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyAdapter# public class SimpleEpoxyAdapter
 //           ^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyAdapter#`<init>`(). public SimpleEpoxyAdapter()
 //                                      ^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyAdapter#
 
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyController.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyController.java
index 426c4f8f3..76daf4806 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyController.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyController.java
@@ -10,7 +10,7 @@
  * models directly.
  */
 public class SimpleEpoxyController extends EpoxyController {
-//           ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyController# public class SimpleEpoxyController extends EpoxyController
+//           ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyController# public class SimpleEpoxyController
 //           ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyController#`<init>`(). public SimpleEpoxyController()
 //                                         ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyController#
   private List<? extends EpoxyModel<?>> currentModels;
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyModel.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyModel.java
index 310e9fff4..956371359 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyModel.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/SimpleEpoxyModel.java
@@ -25,7 +25,7 @@
  * span size.
  */
 public class SimpleEpoxyModel extends EpoxyModel<View> {
-//           ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyModel# public class SimpleEpoxyModel extends EpoxyModel<unresolved_type>
+//           ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/SimpleEpoxyModel# public class SimpleEpoxyModel
 //                                    ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
 //                                               ^^^^ reference _root_/
   @LayoutRes private final int layoutRes;
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed2EpoxyController.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed2EpoxyController.java
index 6683bc472..232199f30 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed2EpoxyController.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed2EpoxyController.java
@@ -20,7 +20,7 @@
  * @see Typed4EpoxyController
  */
 public abstract class Typed2EpoxyController<T, U> extends EpoxyController {
-//                    ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/Typed2EpoxyController# public abstract class Typed2EpoxyController<T, U> extends EpoxyController
+//                    ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/Typed2EpoxyController# public abstract class Typed2EpoxyController<T, U>
 //                                          ^ definition com/airbnb/epoxy/Typed2EpoxyController#[T] T
 //                                             ^ definition com/airbnb/epoxy/Typed2EpoxyController#[U] U
 //                                                        ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyController#
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed3EpoxyController.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed3EpoxyController.java
index 9d4727037..9810b619e 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed3EpoxyController.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed3EpoxyController.java
@@ -20,7 +20,7 @@
  * @see Typed4EpoxyController
  */
 public abstract class Typed3EpoxyController<T, U, V> extends EpoxyController {
-//                    ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/Typed3EpoxyController# public abstract class Typed3EpoxyController<T, U, V> extends EpoxyController
+//                    ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/Typed3EpoxyController# public abstract class Typed3EpoxyController<T, U, V>
 //                                          ^ definition com/airbnb/epoxy/Typed3EpoxyController#[T] T
 //                                             ^ definition com/airbnb/epoxy/Typed3EpoxyController#[U] U
 //                                                ^ definition com/airbnb/epoxy/Typed3EpoxyController#[V] V
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed4EpoxyController.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed4EpoxyController.java
index e93a49431..cf333e58e 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed4EpoxyController.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/Typed4EpoxyController.java
@@ -20,7 +20,7 @@
  * @see Typed3EpoxyController
  */
 public abstract class Typed4EpoxyController<T, U, V, W> extends EpoxyController {
-//                    ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/Typed4EpoxyController# public abstract class Typed4EpoxyController<T, U, V, W> extends EpoxyController
+//                    ^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/Typed4EpoxyController# public abstract class Typed4EpoxyController<T, U, V, W>
 //                                          ^ definition com/airbnb/epoxy/Typed4EpoxyController#[T] T
 //                                             ^ definition com/airbnb/epoxy/Typed4EpoxyController#[U] U
 //                                                ^ definition com/airbnb/epoxy/Typed4EpoxyController#[V] V
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/TypedEpoxyController.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/TypedEpoxyController.java
index 656dee730..3640a3f4c 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/TypedEpoxyController.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/TypedEpoxyController.java
@@ -24,7 +24,7 @@
  * @see Typed4EpoxyController
  */
 public abstract class TypedEpoxyController<T> extends EpoxyController {
-//                    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/TypedEpoxyController# public abstract class TypedEpoxyController<T> extends EpoxyController
+//                    ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/TypedEpoxyController# public abstract class TypedEpoxyController<T>
 //                                         ^ definition com/airbnb/epoxy/TypedEpoxyController#[T] T
 //                                                    ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyController#
   private T currentData;
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ViewHolderState.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ViewHolderState.java
index 7e53abd12..f1400c638 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/ViewHolderState.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/ViewHolderState.java
@@ -59,7 +59,7 @@
 @SuppressWarnings("WeakerAccess")
 //^^^^^^^^^^^^^^^ reference java/lang/SuppressWarnings#
 class ViewHolderState extends LongSparseArray<ViewState> implements Parcelable {
-//    ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ViewHolderState# @SuppressWarnings("WeakerAccess") class ViewHolderState extends LongSparseArray<ViewState> implements unresolved_type
+//    ^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/ViewHolderState# @SuppressWarnings("WeakerAccess") class ViewHolderState
 //                            ^^^^^^^^^^^^^^^ reference androidx/collection/LongSparseArray#
 //                                            ^^^^^^^^^ reference com/airbnb/epoxy/ViewHolderState#ViewState#
 //                                                                  ^^^^^^^^^^ reference _root_/
@@ -281,7 +281,7 @@ public void restore(EpoxyViewHolder holder) {
    * parcelable support.
    */
   public static class ViewState extends SparseArray<Parcelable> implements Parcelable {
-//                    ^^^^^^^^^ definition com/airbnb/epoxy/ViewHolderState#ViewState# public static class ViewState extends unresolved_type implements unresolved_type
+//                    ^^^^^^^^^ definition com/airbnb/epoxy/ViewHolderState#ViewState# public static class ViewState
 //                                      ^^^^^^^^^^^ reference _root_/
 //                                                  ^^^^^^^^^^ reference _root_/
 //                                                                         ^^^^^^^^^^ reference _root_/
diff --git a/tests/snapshots/src/main/generated/com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener.java b/tests/snapshots/src/main/generated/com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener.java
index 2a84a7e22..c41b49b08 100644
--- a/tests/snapshots/src/main/generated/com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener.java
+++ b/tests/snapshots/src/main/generated/com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener.java
@@ -21,7 +21,7 @@
  * checked change.
  */
 public class WrappedEpoxyModelCheckedChangeListener<T extends EpoxyModel<?>, V>
-//           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener# public class WrappedEpoxyModelCheckedChangeListener<T extends EpoxyModel<?>, V> implements unresolved_type
+//           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener# public class WrappedEpoxyModelCheckedChangeListener<T extends EpoxyModel<?>, V>
 //                                                  ^ definition com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener#[T] T extends EpoxyModel<?>
 //                                                            ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
 //                                                                           ^ definition com/airbnb/epoxy/WrappedEpoxyModelCheckedChangeListener#[V] V
diff --git a/tests/snapshots/src/main/generated/minimized/InnerClasses.java b/tests/snapshots/src/main/generated/minimized/InnerClasses.java
index 6cfa5467f..66e83c129 100644
--- a/tests/snapshots/src/main/generated/minimized/InnerClasses.java
+++ b/tests/snapshots/src/main/generated/minimized/InnerClasses.java
@@ -67,7 +67,7 @@ public static void innerStaticMethod() {}
   }
 
   public class InnerClass implements InnerInterface<Integer, Integer> {
-//             ^^^^^^^^^^ definition minimized/InnerClasses#InnerClass# public class InnerClass implements InnerInterface<Integer, Integer>
+//             ^^^^^^^^^^ definition minimized/InnerClasses#InnerClass# public class InnerClass
 //                                   ^^^^^^^^^^^^^^ reference minimized/InnerClasses#InnerInterface#
 //                                                  ^^^^^^^ reference java/lang/Integer#
 //                                                           ^^^^^^^ reference java/lang/Integer#
diff --git a/tests/snapshots/src/main/generated/minimized/MinimizedScalaMain.scala b/tests/snapshots/src/main/generated/minimized/MinimizedScalaMain.scala
index 4cbbb4d64..78281bd83 100644
--- a/tests/snapshots/src/main/generated/minimized/MinimizedScalaMain.scala
+++ b/tests/snapshots/src/main/generated/minimized/MinimizedScalaMain.scala
@@ -3,10 +3,10 @@ package minimized
 
 // format: off
 object MinimizedScalaMain {
-//     ^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaMain. public final MinimizedScalaMain
+//     ^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaMain. object MinimizedScalaMain
   def main(args: Array[String]): Unit = {
-//    ^^^^ definition minimized/MinimizedScalaMain.main(). public void main(String[] args)
-//         ^^^^ definition minimized/MinimizedScalaMain.main().(args) String[] args
+//    ^^^^ definition minimized/MinimizedScalaMain.main(). def main(args: Array[String]): Unit
+//         ^^^^ definition minimized/MinimizedScalaMain.main().(args) args: Array[String]
 //               ^^^^^ reference scala/Array#
 //                     ^^^^^^ reference scala/Predef.String#
 //                               ^^^^ reference scala/Unit#
diff --git a/tests/snapshots/src/main/generated/minimized/MinimizedScalaSignatures.scala b/tests/snapshots/src/main/generated/minimized/MinimizedScalaSignatures.scala
new file mode 100644
index 000000000..cfc5b78af
--- /dev/null
+++ b/tests/snapshots/src/main/generated/minimized/MinimizedScalaSignatures.scala
@@ -0,0 +1,175 @@
+package minimized
+//      ^^^^^^^^^ definition minimized/
+
+// format: off
+
+
+case class MinimizedCaseClass(value: String) {
+//         ^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedCaseClass# case class MinimizedCaseClass(value: String)
+//                            definition minimized/MinimizedCaseClass#`<init>`(). def this(value: String):
+//                            ^^^^^ definition minimized/MinimizedCaseClass#value. val value: String
+//                                   ^^^^^^ reference scala/Predef.String#
+  def this() = this("value")
+//    ^^^^ definition minimized/MinimizedCaseClass#`<init>`(+1). def this():
+//                  reference minimized/MinimizedCaseClass#`<init>`().
+}
+
+trait MinimizedTrait[T] extends AutoCloseable {
+//    ^^^^^^^^^^^^^^ definition minimized/MinimizedTrait# trait MinimizedTrait[T]
+//                   ^ definition minimized/MinimizedTrait#[T] T
+//                              ^^^^^^^^^^^^^ reference java/lang/AutoCloseable#
+  def add(e: T): T
+//    ^^^ definition minimized/MinimizedTrait#add(). def add(e: T): T
+//        ^ definition minimized/MinimizedTrait#add().(e) e: T
+//           ^ reference minimized/MinimizedTrait#[T]
+//               ^ reference minimized/MinimizedTrait#[T]
+  final def +(e: T): T = add(e)
+//          ^ definition minimized/MinimizedTrait#`+`(). final def +(e: T): T
+//            ^ definition minimized/MinimizedTrait#`+`().(e) e: T
+//               ^ reference minimized/MinimizedTrait#[T]
+//                   ^ reference minimized/MinimizedTrait#[T]
+//                       ^^^ reference minimized/MinimizedTrait#add().
+//                           ^ reference minimized/MinimizedTrait#`+`().(e)
+}
+
+class MinimizedScalaSignatures extends AutoCloseable with java.io.Serializable {
+//    ^^^^^^^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures# class MinimizedScalaSignatures
+//                              definition minimized/MinimizedScalaSignatures#`<init>`(). def this():
+//                                     ^^^^^^^^^^^^^ reference java/lang/AutoCloseable#
+//                                                    reference java/lang/Object#`<init>`().
+//                                                        ^^^^ reference java/
+//                                                             ^^ reference java/io/
+//                                                                ^^^^^^^^^^^^ reference java/io/Serializable#
+  def close(): Unit = ()
+//    ^^^^^ definition minimized/MinimizedScalaSignatures#close(). def close(): Unit
+//             ^^^^ reference scala/Unit#
+}
+
+object MinimizedScalaSignatures extends MinimizedScalaSignatures with Comparable[Int] {
+//     ^^^^^^^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures. object MinimizedScalaSignatures
+//                                      ^^^^^^^^^^^^^^^^^^^^^^^^ reference minimized/MinimizedScalaSignatures#
+//                                                                reference minimized/MinimizedScalaSignatures#`<init>`().
+//                                                                    ^^^^^^^^^^ reference java/lang/Comparable#
+//                                                                               ^^^ reference scala/Int#
+  @inline def annotation(x: Int): Int = x + 1
+// ^^^^^^ reference scala/inline#
+//         reference scala/inline#`<init>`().
+//            ^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.annotation(). @inline def annotation(x: Int): Int
+//                       ^ definition minimized/MinimizedScalaSignatures.annotation().(x) x: Int
+//                          ^^^ reference scala/Int#
+//                                ^^^ reference scala/Int#
+//                                      ^ reference minimized/MinimizedScalaSignatures.annotation().(x)
+//                                        ^ reference scala/Int#`+`(+4).
+  @deprecated("2020-07-27") def annotationMessage(x: Int): Int = x + 1
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+//                              ^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.annotationMessage(). @deprecated def annotationMessage(x: Int): Int
+//                                                ^ definition minimized/MinimizedScalaSignatures.annotationMessage().(x) x: Int
+//                                                   ^^^ reference scala/Int#
+//                                                         ^^^ reference scala/Int#
+//                                                               ^ reference minimized/MinimizedScalaSignatures.annotationMessage().(x)
+//                                                                 ^ reference scala/Int#`+`(+4).
+  def compareTo(x: Int): Int = ???
+//    ^^^^^^^^^ definition minimized/MinimizedScalaSignatures.compareTo(). def compareTo(x: Int): Int
+//              ^ definition minimized/MinimizedScalaSignatures.compareTo().(x) x: Int
+//                 ^^^ reference scala/Int#
+//                       ^^^ reference scala/Int#
+//                             ^^^ reference scala/Predef.`???`().
+  def identity[T](e: T): T = e
+//    ^^^^^^^^ definition minimized/MinimizedScalaSignatures.identity(). def identity(e: T): T
+//             ^ definition minimized/MinimizedScalaSignatures.identity().[T] T
+//                ^ definition minimized/MinimizedScalaSignatures.identity().(e) e: T
+//                   ^ reference minimized/MinimizedScalaSignatures.identity().[T]
+//                       ^ reference minimized/MinimizedScalaSignatures.identity().[T]
+//                           ^ reference minimized/MinimizedScalaSignatures.identity().(e)
+  def tuple(): (Int, String) = null
+//    ^^^^^ definition minimized/MinimizedScalaSignatures.tuple(). def tuple(): (Int, String)
+//              ^^^ reference scala/Int#
+//                   ^^^^^^ reference scala/Predef.String#
+  def function0(): () => String = null
+//    ^^^^^^^^^ definition minimized/MinimizedScalaSignatures.function0(). def function0(): String=> String
+//                       ^^^^^^ reference scala/Predef.String#
+  def function1(): Int => String = null
+//    ^^^^^^^^^ definition minimized/MinimizedScalaSignatures.function1(). def function1(): (Int) => String
+//                 ^^^ reference scala/Int#
+//                        ^^^^^^ reference scala/Predef.String#
+  def function2(): (Int, String) => Unit = null
+//    ^^^^^^^^^ definition minimized/MinimizedScalaSignatures.function2(). def function2(): (Int, String) => Unit
+//                  ^^^ reference scala/Int#
+//                       ^^^^^^ reference scala/Predef.String#
+//                                  ^^^^ reference scala/Unit#
+  def typeParameter(): Map[Int, String] = null
+//    ^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.typeParameter(). def typeParameter(): Map[Int, String]
+//                     ^^^ reference scala/Predef.Map#
+//                         ^^^ reference scala/Int#
+//                              ^^^^^^ reference scala/Predef.String#
+  def termParameter(a: Int, b: String): String = null
+//    ^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.termParameter(). def termParameter(a: Int, b: String): String
+//                  ^ definition minimized/MinimizedScalaSignatures.termParameter().(a) a: Int
+//                     ^^^ reference scala/Int#
+//                          ^ definition minimized/MinimizedScalaSignatures.termParameter().(b) b: String
+//                             ^^^^^^ reference scala/Predef.String#
+//                                      ^^^^^^ reference scala/Predef.String#
+  def singletonType(e: String): e.type = e
+//    ^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.singletonType(). def singletonType(e: String): e.type
+//                  ^ definition minimized/MinimizedScalaSignatures.singletonType().(e) e: String
+//                     ^^^^^^ reference scala/Predef.String#
+//                              ^ reference minimized/MinimizedScalaSignatures.singletonType().(e)
+//                                       ^ reference minimized/MinimizedScalaSignatures.singletonType().(e)
+  def thisType(): this.type = this
+//    ^^^^^^^^ definition minimized/MinimizedScalaSignatures.thisType(). def thisType(): this.type
+  def constantInt(): 1 = 1
+//    ^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.constantInt(). def constantInt(): 1
+  def constantString(): "string" = "string"
+//    ^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.constantString(). def constantString(): "string"
+  def constantBoolean(): true = true
+//    ^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.constantBoolean(). def constantBoolean(): true
+  def constantFloat(): 1.2f = 1.2f
+//    ^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.constantFloat(). def constantFloat(): 1.2f
+  def constantChar(): 'a' = 'a'
+//    ^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.constantChar(). def constantChar(): 'a'
+  def structuralType(): { val x: Int; def foo(a: Int): String } = null
+//    ^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.structuralType(). def structuralType(): { val x: Int; def foo(a: Int): String }
+//                            ^ definition local1 val x: Int
+//                               ^^^ reference scala/Int#
+//                                        ^^^ definition local2 def foo(a: Int): String
+//                                            ^ definition local3 a: Int
+//                                               ^^^ reference scala/Int#
+//                                                     ^^^^^^ reference scala/Predef.String#
+  def byNameType(a: => Int): Unit = ()
+//    ^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.byNameType(). def byNameType(a: => Int): Unit
+//               ^ definition minimized/MinimizedScalaSignatures.byNameType().(a) a: => Int
+//                     ^^^ reference scala/Int#
+//                           ^^^^ reference scala/Unit#
+  def repeatedType(a: Int*): Unit = ()
+//    ^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.repeatedType(). def repeatedType(a: Int*): Unit
+//                 ^ definition minimized/MinimizedScalaSignatures.repeatedType().(a) a: Int*
+//                    ^^^ reference scala/Int#
+//                           ^^^^ reference scala/Unit#
+
+  type TypeAlias = Int
+//     ^^^^^^^^^ definition minimized/MinimizedScalaSignatures.TypeAlias# type TypeAlias >: Int <: Int
+//                 ^^^ reference scala/Int#
+  type ParameterizedTypeAlias[A] = () => A
+//     ^^^^^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.ParameterizedTypeAlias# type ParameterizedTypeAlias >: A=> A <: A=> A
+//                            ^ definition minimized/MinimizedScalaSignatures.ParameterizedTypeAlias#[A] A
+//                                       ^ reference minimized/MinimizedScalaSignatures.ParameterizedTypeAlias#[A]
+  type ParameterizedTypeAlias2[A, B] = A => B
+//     ^^^^^^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.ParameterizedTypeAlias2# type ParameterizedTypeAlias2 >: (A) => B <: (A) => B
+//                             ^ definition minimized/MinimizedScalaSignatures.ParameterizedTypeAlias2#[A] A
+//                                ^ definition minimized/MinimizedScalaSignatures.ParameterizedTypeAlias2#[B] B
+//                                     ^ reference minimized/MinimizedScalaSignatures.ParameterizedTypeAlias2#[A]
+//                                          ^ reference minimized/MinimizedScalaSignatures.ParameterizedTypeAlias2#[B]
+  type TypeBound
+//     ^^^^^^^^^ definition minimized/MinimizedScalaSignatures.TypeBound# type TypeBound
+  type TypeUpperBound <: String
+//     ^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.TypeUpperBound# type TypeUpperBound <: String
+//                       ^^^^^^ reference scala/Predef.String#
+  type TypeLowerBound >: CharSequence
+//     ^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.TypeLowerBound# type TypeLowerBound >: CharSequence
+//                       ^^^^^^^^^^^^ reference java/lang/CharSequence#
+  type TypeLowerUpperBound >: String <: CharSequence 
+//     ^^^^^^^^^^^^^^^^^^^ definition minimized/MinimizedScalaSignatures.TypeLowerUpperBound# type TypeLowerUpperBound >: String <: CharSequence
+//                            ^^^^^^ reference scala/Predef.String#
+//                                      ^^^^^^^^^^^^ reference java/lang/CharSequence#
+}
diff --git a/tests/snapshots/src/main/generated/minimized/SubClasses.java b/tests/snapshots/src/main/generated/minimized/SubClasses.java
index 03cc043b0..3ed26557c 100644
--- a/tests/snapshots/src/main/generated/minimized/SubClasses.java
+++ b/tests/snapshots/src/main/generated/minimized/SubClasses.java
@@ -1,7 +1,7 @@
 package minimized;
 
 public class SubClasses extends AbstractClasses implements Interfaces {
-//           ^^^^^^^^^^ definition minimized/SubClasses# public class SubClasses extends AbstractClasses implements Interfaces
+//           ^^^^^^^^^^ definition minimized/SubClasses# public class SubClasses
 //           ^^^^^^^^^^ definition minimized/SubClasses#`<init>`(). public SubClasses()
 //                              ^^^^^^^^^^^^^^^ reference minimized/AbstractClasses#
 //                                                         ^^^^^^^^^^ reference minimized/Interfaces#
diff --git a/tests/snapshots/src/main/generated/minimized/TypeVariables.java b/tests/snapshots/src/main/generated/minimized/TypeVariables.java
index df8605d32..557b936cb 100644
--- a/tests/snapshots/src/main/generated/minimized/TypeVariables.java
+++ b/tests/snapshots/src/main/generated/minimized/TypeVariables.java
@@ -24,7 +24,7 @@ interface I {
   }
 
   static class CT extends C implements I {
-//             ^^ definition minimized/TypeVariables#CT# static class CT extends C implements I
+//             ^^ definition minimized/TypeVariables#CT# static class CT
 //             ^^ definition minimized/TypeVariables#CT#`<init>`(). CT()
 //                        ^ reference minimized/TypeVariables#C#
 //                                     ^ reference minimized/TypeVariables#I#
diff --git a/tests/snapshots/src/main/generated/ujson/AstTransformer.scala b/tests/snapshots/src/main/generated/ujson/AstTransformer.scala
new file mode 100644
index 000000000..5a88db4f8
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/AstTransformer.scala
@@ -0,0 +1,211 @@
+package ujson
+//      ^^^^^ definition ujson/
+import upickle.core._
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+
+import upickle.core.compat._
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                  ^^^^^^ reference upickle/core/compat/
+
+trait AstTransformer[I] extends Transformer[I] with JsVisitor[I, I]{
+//    ^^^^^^^^^^^^^^ definition ujson/AstTransformer#
+//                   ^ definition ujson/AstTransformer#[I]
+//                              ^^^^^^^^^^^ reference ujson/Transformer#
+//                                          ^ reference ujson/AstTransformer#[I]
+//                                                  ^^^^^^^^^ reference ujson/JsVisitor#
+//                                                            ^ reference ujson/AstTransformer#[I]
+//                                                               ^ reference ujson/AstTransformer#[I]
+  def apply(t: Readable): I = t.transform(this)
+//    ^^^^^ definition ujson/AstTransformer#apply().
+//          ^ definition ujson/AstTransformer#apply().(t)
+//             ^^^^^^^^ reference ujson/Readable#
+//                        ^ reference ujson/AstTransformer#[I]
+//                            ^ reference ujson/AstTransformer#apply().(t)
+//                              ^^^^^^^^^ reference ujson/Readable#transform().
+
+  def transformArray[T](f: Visitor[_, T], items: Iterable[I]) = {
+//    ^^^^^^^^^^^^^^ definition ujson/AstTransformer#transformArray().
+//                   ^ definition ujson/AstTransformer#transformArray().[T]
+//                      ^ definition ujson/AstTransformer#transformArray().(f)
+//                         ^^^^^^^ reference upickle/core/Visitor#
+//                                    ^ reference ujson/AstTransformer#transformArray().[T]
+//                                        ^^^^^ definition ujson/AstTransformer#transformArray().(items)
+//                                               ^^^^^^^^ reference scala/package.Iterable#
+//                                                        ^ reference ujson/AstTransformer#[I]
+    val ctx = f.visitArray(items.size, -1).narrow
+//      ^^^ definition local0
+//            ^ reference ujson/AstTransformer#transformArray().(f)
+//              ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                         ^^^^^ reference ujson/AstTransformer#transformArray().(items)
+//                               ^^^^ reference scala/collection/IterableOnceOps#size().
+//                                         ^^^^^^ reference upickle/core/ArrVisitor#narrow().
+    for(item <- items) ctx.visitValue(transform(item, ctx.subVisitor), -1)
+//      ^^^^ definition local1
+//              ^^^^^ reference ujson/AstTransformer#transformArray().(items)
+//                     ^^^ reference local0
+//                         ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                                    ^^^^^^^^^ reference ujson/Transformer#transform().
+//                                              ^^^^ reference local1
+//                                                    ^^^ reference local0
+//                                                        ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+    ctx.visitEnd(-1)
+//  ^^^ reference local0
+//      ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+  }
+  def transformObject[T](f: Visitor[_, T], items: Iterable[(String, I)]) = {
+//    ^^^^^^^^^^^^^^^ definition ujson/AstTransformer#transformObject().
+//                    ^ definition ujson/AstTransformer#transformObject().[T]
+//                       ^ definition ujson/AstTransformer#transformObject().(f)
+//                          ^^^^^^^ reference upickle/core/Visitor#
+//                                     ^ reference ujson/AstTransformer#transformObject().[T]
+//                                         ^^^^^ definition ujson/AstTransformer#transformObject().(items)
+//                                                ^^^^^^^^ reference scala/package.Iterable#
+//                                                          ^^^^^^ reference scala/Predef.String#
+//                                                                  ^ reference ujson/AstTransformer#[I]
+    val ctx = f.visitObject(items.size, -1).narrow
+//      ^^^ definition local3
+//            ^ reference ujson/AstTransformer#transformObject().(f)
+//              ^^^^^^^^^^^ reference upickle/core/Visitor#visitObject().
+//                          ^^^^^ reference ujson/AstTransformer#transformObject().(items)
+//                                ^^^^ reference scala/collection/IterableOnceOps#size().
+//                                          ^^^^^^ reference upickle/core/ObjVisitor#narrow().
+    for(kv <- items) {
+//      ^^ definition local4
+//            ^^^^^ reference ujson/AstTransformer#transformObject().(items)
+      val keyVisitor = ctx.visitKey(-1)
+//        ^^^^^^^^^^ definition local5
+//                     ^^^ reference local3
+//                         ^^^^^^^^ reference upickle/core/ObjVisitor#visitKey().
+      ctx.visitKeyValue(keyVisitor.visitString(kv._1, -1))
+//    ^^^ reference local3
+//        ^^^^^^^^^^^^^ reference upickle/core/ObjVisitor#visitKeyValue().
+//                      ^^^^^^^^^^ reference local5
+//                                 ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                             ^^ reference local4
+//                                                ^^ reference scala/Tuple2#_1.
+      ctx.visitValue(transform(kv._2, ctx.subVisitor), -1)
+//    ^^^ reference local3
+//        ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                   ^^^^^^^^^ reference ujson/Transformer#transform().
+//                             ^^ reference local4
+//                                ^^ reference scala/Tuple2#_2.
+//                                    ^^^ reference local3
+//                                        ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+    }
+    ctx.visitEnd(-1)
+//  ^^^ reference local3
+//      ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+  }
+
+  class AstObjVisitor[T](build: T => I)
+//      ^^^^^^^^^^^^^ definition ujson/AstTransformer#AstObjVisitor#
+//                    ^ definition ujson/AstTransformer#AstObjVisitor#[T]
+//                       definition ujson/AstTransformer#AstObjVisitor#`<init>`().
+//                       ^^^^^ definition ujson/AstTransformer#AstObjVisitor#build.
+//                              ^ reference ujson/AstTransformer#AstObjVisitor#[T]
+//                                   ^ reference ujson/AstTransformer#[I]
+                        (implicit factory: Factory[(String, I), T])extends ObjVisitor[I, I] {
+//                                ^^^^^^^ definition ujson/AstTransformer#AstObjVisitor#factory.
+//                                         ^^^^^^^ reference upickle/core/compat/package.Factory#
+//                                                  ^^^^^^ reference scala/Predef.String#
+//                                                          ^ reference ujson/AstTransformer#[I]
+//                                                              ^ reference ujson/AstTransformer#AstObjVisitor#[T]
+//                                                                         ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                                                                    ^ reference ujson/AstTransformer#[I]
+//                                                                                       ^ reference ujson/AstTransformer#[I]
+//                                                                                           reference java/lang/Object#`<init>`().
+
+    private[this] var key: String = null
+//                    ^^^ definition ujson/AstTransformer#AstObjVisitor#key().
+//                         ^^^^^^ reference scala/Predef.String#
+    private[this] val vs = factory.newBuilder
+//                    ^^ definition ujson/AstTransformer#AstObjVisitor#vs.
+//                         ^^^^^^^ reference ujson/AstTransformer#AstObjVisitor#factory.
+//                                 ^^^^^^^^^^ reference scala/collection/Factory#newBuilder().
+    def subVisitor = AstTransformer.this
+//      ^^^^^^^^^^ definition ujson/AstTransformer#AstObjVisitor#subVisitor().
+//                   ^^^^^^^^^^^^^^ reference ujson/AstTransformer#
+    def visitKey(index: Int) = upickle.core.StringVisitor
+//      ^^^^^^^^ definition ujson/AstTransformer#AstObjVisitor#visitKey().
+//               ^^^^^ definition ujson/AstTransformer#AstObjVisitor#visitKey().(index)
+//                      ^^^ reference scala/Int#
+//                             ^^^^^^^ reference upickle/
+//                                     ^^^^ reference upickle/core/
+//                                          ^^^^^^^^^^^^^ reference upickle/core/StringVisitor.
+    def visitKeyValue(s: Any): Unit = key = s.toString
+//      ^^^^^^^^^^^^^ definition ujson/AstTransformer#AstObjVisitor#visitKeyValue().
+//                    ^ definition ujson/AstTransformer#AstObjVisitor#visitKeyValue().(s)
+//                       ^^^ reference scala/Any#
+//                             ^^^^ reference scala/Unit#
+//                                    ^^^ reference ujson/AstTransformer#AstObjVisitor#key().
+//                                          ^ reference ujson/AstTransformer#AstObjVisitor#visitKeyValue().(s)
+//                                            ^^^^^^^^ reference scala/Any#toString().
+
+    def visitValue(v: I, index: Int): Unit = vs += (key -> v)
+//      ^^^^^^^^^^ definition ujson/AstTransformer#AstObjVisitor#visitValue().
+//                 ^ definition ujson/AstTransformer#AstObjVisitor#visitValue().(v)
+//                    ^ reference ujson/AstTransformer#[I]
+//                       ^^^^^ definition ujson/AstTransformer#AstObjVisitor#visitValue().(index)
+//                              ^^^ reference scala/Int#
+//                                    ^^^^ reference scala/Unit#
+//                                           ^^ reference ujson/AstTransformer#AstObjVisitor#vs.
+//                                              ^^ reference scala/collection/mutable/Growable#`+=`().
+//                                                  ^^^ reference ujson/AstTransformer#AstObjVisitor#key().
+//                                                      ^^ reference scala/Predef.ArrowAssoc#`->`().
+//                                                         ^ reference ujson/AstTransformer#AstObjVisitor#visitValue().(v)
+
+    def visitEnd(index: Int) = build(vs.result)
+//      ^^^^^^^^ definition ujson/AstTransformer#AstObjVisitor#visitEnd().
+//               ^^^^^ definition ujson/AstTransformer#AstObjVisitor#visitEnd().(index)
+//                      ^^^ reference scala/Int#
+//                             ^^^^^ reference ujson/AstTransformer#AstObjVisitor#build.
+//                                   ^^ reference ujson/AstTransformer#AstObjVisitor#vs.
+//                                      ^^^^^^ reference scala/collection/mutable/Builder#result().
+  }
+  class AstArrVisitor[T[_]](build: T[I] => I)
+//      ^^^^^^^^^^^^^ definition ujson/AstTransformer#AstArrVisitor#
+//                    ^ definition ujson/AstTransformer#AstArrVisitor#[T]
+//                          definition ujson/AstTransformer#AstArrVisitor#`<init>`().
+//                          ^^^^^ definition ujson/AstTransformer#AstArrVisitor#build.
+//                                 ^ reference ujson/AstTransformer#AstArrVisitor#[T]
+//                                   ^ reference ujson/AstTransformer#[I]
+//                                         ^ reference ujson/AstTransformer#[I]
+                           (implicit factory: Factory[I, T[I]]) extends ArrVisitor[I, I]{
+//                                   ^^^^^^^ definition ujson/AstTransformer#AstArrVisitor#factory.
+//                                            ^^^^^^^ reference upickle/core/compat/package.Factory#
+//                                                    ^ reference ujson/AstTransformer#[I]
+//                                                       ^ reference ujson/AstTransformer#AstArrVisitor#[T]
+//                                                         ^ reference ujson/AstTransformer#[I]
+//                                                                      ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                                                                                 ^ reference ujson/AstTransformer#[I]
+//                                                                                    ^ reference ujson/AstTransformer#[I]
+//                                                                                       reference java/lang/Object#`<init>`().
+    def subVisitor = AstTransformer.this
+//      ^^^^^^^^^^ definition ujson/AstTransformer#AstArrVisitor#subVisitor().
+//                   ^^^^^^^^^^^^^^ reference ujson/AstTransformer#
+    private[this] val vs = factory.newBuilder
+//                    ^^ definition ujson/AstTransformer#AstArrVisitor#vs.
+//                         ^^^^^^^ reference ujson/AstTransformer#AstArrVisitor#factory.
+//                                 ^^^^^^^^^^ reference scala/collection/Factory#newBuilder().
+    def visitValue(v: I, index: Int): Unit = vs += v
+//      ^^^^^^^^^^ definition ujson/AstTransformer#AstArrVisitor#visitValue().
+//                 ^ definition ujson/AstTransformer#AstArrVisitor#visitValue().(v)
+//                    ^ reference ujson/AstTransformer#[I]
+//                       ^^^^^ definition ujson/AstTransformer#AstArrVisitor#visitValue().(index)
+//                              ^^^ reference scala/Int#
+//                                    ^^^^ reference scala/Unit#
+//                                           ^^ reference ujson/AstTransformer#AstArrVisitor#vs.
+//                                              ^^ reference scala/collection/mutable/Growable#`+=`().
+//                                                 ^ reference ujson/AstTransformer#AstArrVisitor#visitValue().(v)
+
+    def visitEnd(index: Int) = build(vs.result())
+//      ^^^^^^^^ definition ujson/AstTransformer#AstArrVisitor#visitEnd().
+//               ^^^^^ definition ujson/AstTransformer#AstArrVisitor#visitEnd().(index)
+//                      ^^^ reference scala/Int#
+//                             ^^^^^ reference ujson/AstTransformer#AstArrVisitor#build.
+//                                   ^^ reference ujson/AstTransformer#AstArrVisitor#vs.
+//                                      ^^^^^^ reference scala/collection/mutable/Builder#result().
+  }
+}
diff --git a/tests/snapshots/src/main/generated/ujson/ByteArrayParser.scala b/tests/snapshots/src/main/generated/ujson/ByteArrayParser.scala
new file mode 100644
index 000000000..c65ab6456
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/ByteArrayParser.scala
@@ -0,0 +1,99 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import scala.annotation.{switch, tailrec}
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                       ^^^^^^ reference scala/annotation/switch#
+//                               ^^^^^^^ reference scala/annotation/tailrec#
+import java.nio.ByteBuffer
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^^^^ reference java/nio/ByteBuffer#
+import java.nio.charset.StandardCharsets
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^ reference java/nio/charset/
+//                      ^^^^^^^^^^^^^^^^ reference java/nio/charset/StandardCharsets#
+
+import upickle.core.{ObjArrVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                  ^^^^^^^ reference upickle/core/Visitor.
+//                                  ^^^^^^^ reference upickle/core/Visitor#
+/**
+  * Basic ByteBuffer parser.
+  *
+  * This assumes that the provided ByteBuffer is ready to be read. The
+  * user is responsible for any necessary flipping/resetting of the
+  * ByteBuffer before parsing.
+  *
+  * The parser makes absolute calls to the ByteBuffer, which will not
+  * update its own mutable position fields.
+  */
+final class ByteArrayParser[J](src: Array[Byte]) extends ByteParser[J]{
+//          ^^^^^^^^^^^^^^^ definition ujson/ByteArrayParser#
+//                          ^ definition ujson/ByteArrayParser#[J]
+//                             definition ujson/ByteArrayParser#`<init>`().
+//                             ^^^ definition ujson/ByteArrayParser#src.
+//                                  ^^^^^ reference scala/Array#
+//                                        ^^^^ reference scala/Byte#
+//                                                       ^^^^^^^^^^ reference ujson/ByteParser#
+//                                                                  ^ reference ujson/ByteArrayParser#[J]
+//                                                                     reference ujson/ByteParser#`<init>`().
+
+  val srcLength = src.length
+//    ^^^^^^^^^ definition ujson/ByteArrayParser#srcLength.
+//                ^^^ reference ujson/ByteArrayParser#src.
+//                    ^^^^^^ reference scala/Array#length().
+  protected[this] final def close() = {}
+//                          ^^^^^ definition ujson/ByteArrayParser#close().
+
+  // Never grow the buffer since it's a directly using the original
+  override def growBuffer(until: Int): Unit = ()
+//             ^^^^^^^^^^ definition ujson/ByteArrayParser#growBuffer().
+//                        ^^^^^ definition ujson/ByteArrayParser#growBuffer().(until)
+//                               ^^^ reference scala/Int#
+//                                     ^^^^ reference scala/Unit#
+
+  def readDataIntoBuffer(buffer: Array[Byte], bufferOffset: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/ByteArrayParser#readDataIntoBuffer().
+//                       ^^^^^^ definition ujson/ByteArrayParser#readDataIntoBuffer().(buffer)
+//                               ^^^^^ reference scala/Array#
+//                                     ^^^^ reference scala/Byte#
+//                                            ^^^^^^^^^^^^ definition ujson/ByteArrayParser#readDataIntoBuffer().(bufferOffset)
+//                                                          ^^^ reference scala/Int#
+    if(buffer == null) (src, srcLength == 0, srcLength)
+//     ^^^^^^ reference ujson/ByteArrayParser#readDataIntoBuffer().(buffer)
+//            ^^ reference java/lang/Object#`==`().
+//                      ^^^ reference ujson/ByteArrayParser#src.
+//                           ^^^^^^^^^ reference ujson/ByteArrayParser#srcLength.
+//                                     ^^ reference scala/Int#`==`(+3).
+//                                           ^^^^^^^^^ reference ujson/ByteArrayParser#srcLength.
+    else (src, true, -1)
+//        ^^^ reference ujson/ByteArrayParser#src.
+  }
+}
+
+object ByteArrayParser extends Transformer[Array[Byte]]{
+//     ^^^^^^^^^^^^^^^ definition ujson/ByteArrayParser.
+//                             ^^^^^^^^^^^ reference ujson/Transformer#
+//                                         ^^^^^ reference scala/Array#
+//                                               ^^^^ reference scala/Byte#
+//                                                      reference java/lang/Object#`<init>`().
+  def transform[T](j: Array[Byte], f: Visitor[_, T]) = new ByteArrayParser(j).parse(f)
+//    ^^^^^^^^^ definition ujson/ByteArrayParser.transform().
+//              ^ definition ujson/ByteArrayParser.transform().[T]
+//                 ^ definition ujson/ByteArrayParser.transform().(j)
+//                    ^^^^^ reference scala/Array#
+//                          ^^^^ reference scala/Byte#
+//                                 ^ definition ujson/ByteArrayParser.transform().(f)
+//                                    ^^^^^^^ reference upickle/core/Visitor#
+//                                               ^ reference ujson/ByteArrayParser.transform().[T]
+//                                                         ^^^^^^^^^^^^^^^ reference ujson/ByteArrayParser#
+//                                                                         reference ujson/ByteArrayParser#`<init>`().
+//                                                                         ^ reference ujson/ByteArrayParser.transform().(j)
+//                                                                            ^^^^^ reference ujson/ByteParser#parse().
+//                                                                                  ^ reference ujson/ByteArrayParser.transform().(f)
+}
diff --git a/tests/snapshots/src/main/generated/ujson/ByteBufferParser.scala b/tests/snapshots/src/main/generated/ujson/ByteBufferParser.scala
new file mode 100644
index 000000000..cc531396e
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/ByteBufferParser.scala
@@ -0,0 +1,113 @@
+package ujson
+//      ^^^^^ definition ujson/
+import upickle.core.{ObjArrVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                  ^^^^^^^ reference upickle/core/Visitor.
+//                                  ^^^^^^^ reference upickle/core/Visitor#
+
+import scala.annotation.{switch, tailrec}
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                       ^^^^^^ reference scala/annotation/switch#
+//                               ^^^^^^^ reference scala/annotation/tailrec#
+import java.nio.ByteBuffer
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^^^^ reference java/nio/ByteBuffer#
+import java.nio.charset.StandardCharsets
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^ reference java/nio/charset/
+//                      ^^^^^^^^^^^^^^^^ reference java/nio/charset/StandardCharsets#
+
+/**
+ * Basic ByteBuffer parser.
+ *
+ * This assumes that the provided ByteBuffer is ready to be read. The
+ * user is responsible for any necessary flipping/resetting of the
+ * ByteBuffer before parsing.
+ *
+ * The parser makes absolute calls to the ByteBuffer, which will not
+ * update its own mutable position fields.
+ */
+final class ByteBufferParser[J](src: ByteBuffer) extends ByteParser[J]{
+//          ^^^^^^^^^^^^^^^^ definition ujson/ByteBufferParser#
+//                           ^ definition ujson/ByteBufferParser#[J]
+//                              definition ujson/ByteBufferParser#`<init>`().
+//                              ^^^ definition ujson/ByteBufferParser#src.
+//                                   ^^^^^^^^^^ reference java/nio/ByteBuffer#
+//                                                       ^^^^^^^^^^ reference ujson/ByteParser#
+//                                                                  ^ reference ujson/ByteBufferParser#[J]
+//                                                                     reference ujson/ByteParser#`<init>`().
+  private[this] final val start = src.position()
+//                        ^^^^^ definition ujson/ByteBufferParser#start.
+//                                ^^^ reference ujson/ByteBufferParser#src.
+//                                    ^^^^^^^^ reference java/nio/Buffer#position().
+  private[this] final val limit = src.limit() - start
+//                        ^^^^^ definition ujson/ByteBufferParser#limit.
+//                                ^^^ reference ujson/ByteBufferParser#src.
+//                                    ^^^^^ reference java/nio/Buffer#limit().
+//                                            ^ reference scala/Int#`-`(+3).
+//                                              ^^^^^ reference ujson/ByteBufferParser#start.
+
+
+  protected[this] final def close() = { src.position(start) }
+//                          ^^^^^ definition ujson/ByteBufferParser#close().
+//                                      ^^^ reference ujson/ByteBufferParser#src.
+//                                          ^^^^^^^^ reference java/nio/ByteBuffer#position().
+//                                                   ^^^^^ reference ujson/ByteBufferParser#start.
+  override def growBuffer(until: Int): Unit = ()
+//             ^^^^^^^^^^ definition ujson/ByteBufferParser#growBuffer().
+//                        ^^^^^ definition ujson/ByteBufferParser#growBuffer().(until)
+//                               ^^^ reference scala/Int#
+//                                     ^^^^ reference scala/Unit#
+  def readDataIntoBuffer(buffer: Array[Byte], bufferOffset: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/ByteBufferParser#readDataIntoBuffer().
+//                       ^^^^^^ definition ujson/ByteBufferParser#readDataIntoBuffer().(buffer)
+//                               ^^^^^ reference scala/Array#
+//                                     ^^^^ reference scala/Byte#
+//                                            ^^^^^^^^^^^^ definition ujson/ByteBufferParser#readDataIntoBuffer().(bufferOffset)
+//                                                          ^^^ reference scala/Int#
+
+    if(buffer == null) (java.util.Arrays.copyOfRange(src.array(), start, src.limit()), limit == 0, limit)
+//     ^^^^^^ reference ujson/ByteBufferParser#readDataIntoBuffer().(buffer)
+//            ^^ reference java/lang/Object#`==`().
+//                      ^^^^ reference java/
+//                           ^^^^ reference java/util/
+//                                ^^^^^^ reference java/util/Arrays#
+//                                       ^^^^^^^^^^^ reference java/util/Arrays#copyOfRange(+2).
+//                                                   ^^^ reference ujson/ByteBufferParser#src.
+//                                                       ^^^^^ reference java/nio/ByteBuffer#array().
+//                                                                ^^^^^ reference ujson/ByteBufferParser#start.
+//                                                                       ^^^ reference ujson/ByteBufferParser#src.
+//                                                                           ^^^^^ reference java/nio/Buffer#limit().
+//                                                                                     ^^^^^ reference ujson/ByteBufferParser#limit.
+//                                                                                           ^^ reference scala/Int#`==`(+3).
+//                                                                                                 ^^^^^ reference ujson/ByteBufferParser#limit.
+    else (src.array(), true, -1)
+//        ^^^ reference ujson/ByteBufferParser#src.
+//            ^^^^^ reference java/nio/ByteBuffer#array().
+  }
+}
+
+object ByteBufferParser extends Transformer[ByteBuffer]{
+//     ^^^^^^^^^^^^^^^^ definition ujson/ByteBufferParser.
+//                              ^^^^^^^^^^^ reference ujson/Transformer#
+//                                          ^^^^^^^^^^ reference java/nio/ByteBuffer#
+//                                                      reference java/lang/Object#`<init>`().
+  def transform[T](j: ByteBuffer, f: Visitor[_, T]) = new ByteBufferParser(j).parse(f)
+//    ^^^^^^^^^ definition ujson/ByteBufferParser.transform().
+//              ^ definition ujson/ByteBufferParser.transform().[T]
+//                 ^ definition ujson/ByteBufferParser.transform().(j)
+//                    ^^^^^^^^^^ reference java/nio/ByteBuffer#
+//                                ^ definition ujson/ByteBufferParser.transform().(f)
+//                                   ^^^^^^^ reference upickle/core/Visitor#
+//                                              ^ reference ujson/ByteBufferParser.transform().[T]
+//                                                        ^^^^^^^^^^^^^^^^ reference ujson/ByteBufferParser#
+//                                                                         reference ujson/ByteBufferParser#`<init>`().
+//                                                                         ^ reference ujson/ByteBufferParser.transform().(j)
+//                                                                            ^^^^^ reference ujson/ByteParser#parse().
+//                                                                                  ^ reference ujson/ByteBufferParser.transform().(f)
+}
diff --git a/tests/snapshots/src/main/generated/ujson/CharSequenceParser.scala b/tests/snapshots/src/main/generated/ujson/CharSequenceParser.scala
new file mode 100644
index 000000000..2e5db22eb
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/CharSequenceParser.scala
@@ -0,0 +1,73 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import upickle.core.{ObjArrVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                  ^^^^^^^ reference upickle/core/Visitor.
+//                                  ^^^^^^^ reference upickle/core/Visitor#
+/**
+ * Lazy character sequence parsing.
+ *
+ * This is similar to StringParser, but acts on character sequences.
+ */
+private[ujson] final class CharSequenceParser[J](cs: CharSequence) extends CharParser[J]{
+//      ^^^^^ reference ujson/
+//                         ^^^^^^^^^^^^^^^^^^ definition ujson/CharSequenceParser#
+//                                            ^ definition ujson/CharSequenceParser#[J]
+//                                               definition ujson/CharSequenceParser#`<init>`().
+//                                               ^^ definition ujson/CharSequenceParser#cs.
+//                                                   ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                                                         ^^^^^^^^^^ reference ujson/CharParser#
+//                                                                                    ^ reference ujson/CharSequenceParser#[J]
+//                                                                                       reference ujson/CharParser#`<init>`().
+  override def growBuffer(until: Int): Unit = ()
+//             ^^^^^^^^^^ definition ujson/CharSequenceParser#growBuffer().
+//                        ^^^^^ definition ujson/CharSequenceParser#growBuffer().(until)
+//                               ^^^ reference scala/Int#
+//                                     ^^^^ reference scala/Unit#
+  def readDataIntoBuffer(buffer: Array[Char], bufferOffset: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/CharSequenceParser#readDataIntoBuffer().
+//                       ^^^^^^ definition ujson/CharSequenceParser#readDataIntoBuffer().(buffer)
+//                               ^^^^^ reference scala/Array#
+//                                     ^^^^ reference scala/Char#
+//                                            ^^^^^^^^^^^^ definition ujson/CharSequenceParser#readDataIntoBuffer().(bufferOffset)
+//                                                          ^^^ reference scala/Int#
+    if(buffer == null) (cs.toString.toCharArray, cs.length == 0, cs.length)
+//     ^^^^^^ reference ujson/CharSequenceParser#readDataIntoBuffer().(buffer)
+//            ^^ reference java/lang/Object#`==`().
+//                      ^^ reference ujson/CharSequenceParser#cs.
+//                         ^^^^^^^^ reference java/lang/Object#toString().
+//                                  ^^^^^^^^^^^ reference java/lang/String#toCharArray().
+//                                               ^^ reference ujson/CharSequenceParser#cs.
+//                                                  ^^^^^^ reference java/lang/CharSequence#length().
+//                                                         ^^ reference scala/Int#`==`(+3).
+//                                                               ^^ reference ujson/CharSequenceParser#cs.
+//                                                                  ^^^^^^ reference java/lang/CharSequence#length().
+    else (buffer, true, -1)
+//        ^^^^^^ reference ujson/CharSequenceParser#readDataIntoBuffer().(buffer)
+  }
+  final def close() = ()
+//          ^^^^^ definition ujson/CharSequenceParser#close().
+}
+
+object CharSequenceParser extends Transformer[CharSequence]{
+//     ^^^^^^^^^^^^^^^^^^ definition ujson/CharSequenceParser.
+//                                ^^^^^^^^^^^ reference ujson/Transformer#
+//                                            ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                                          reference java/lang/Object#`<init>`().
+  def transform[T](j: CharSequence, f: Visitor[_, T]) = new CharSequenceParser(j).parse(f)
+//    ^^^^^^^^^ definition ujson/CharSequenceParser.transform().
+//              ^ definition ujson/CharSequenceParser.transform().[T]
+//                 ^ definition ujson/CharSequenceParser.transform().(j)
+//                    ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                  ^ definition ujson/CharSequenceParser.transform().(f)
+//                                     ^^^^^^^ reference upickle/core/Visitor#
+//                                                ^ reference ujson/CharSequenceParser.transform().[T]
+//                                                          ^^^^^^^^^^^^^^^^^^ reference ujson/CharSequenceParser#
+//                                                                             reference ujson/CharSequenceParser#`<init>`().
+//                                                                             ^ reference ujson/CharSequenceParser.transform().(j)
+//                                                                                ^^^^^ reference ujson/CharParser#parse().
+//                                                                                      ^ reference ujson/CharSequenceParser.transform().(f)
+}
diff --git a/tests/snapshots/src/main/generated/ujson/Exceptions.scala b/tests/snapshots/src/main/generated/ujson/Exceptions.scala
new file mode 100644
index 000000000..e689c3a69
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/Exceptions.scala
@@ -0,0 +1,34 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+
+sealed trait ParsingFailedException extends Exception
+//           ^^^^^^^^^^^^^^^^^^^^^^ definition ujson/ParsingFailedException#
+//                                          ^^^^^^^^^ reference scala/package.Exception#
+
+case class ParseException(clue: String, index: Int)
+//         ^^^^^^^^^^^^^^ definition ujson/ParseException#
+//                        definition ujson/ParseException#`<init>`().
+//                        ^^^^ definition ujson/ParseException#clue.
+//                              ^^^^^^ reference scala/Predef.String#
+//                                      ^^^^^ definition ujson/ParseException#index.
+//                                             ^^^ reference scala/Int#
+  extends Exception(clue + " at index " + index) with ParsingFailedException
+//        ^^^^^^^^^ reference scala/package.Exception#
+//                  reference java/lang/Exception#`<init>`(+1).
+//                  ^^^^ reference ujson/ParseException#`<init>`().(clue)
+//                       ^ reference java/lang/String#`+`().
+//                                      ^ reference java/lang/String#`+`().
+//                                        ^^^^^ reference ujson/ParseException#`<init>`().(index)
+//                                                    ^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ParsingFailedException#
+
+case class IncompleteParseException(msg: String)
+//         ^^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/IncompleteParseException#
+//                                  definition ujson/IncompleteParseException#`<init>`().
+//                                  ^^^ definition ujson/IncompleteParseException#msg.
+//                                       ^^^^^^ reference scala/Predef.String#
+  extends Exception(msg) with ParsingFailedException
+//        ^^^^^^^^^ reference scala/package.Exception#
+//                  reference java/lang/Exception#`<init>`(+1).
+//                  ^^^ reference ujson/IncompleteParseException#`<init>`().(msg)
+//                            ^^^^^^^^^^^^^^^^^^^^^^ reference ujson/ParsingFailedException#
diff --git a/tests/snapshots/src/main/generated/ujson/IndexedValue.scala b/tests/snapshots/src/main/generated/ujson/IndexedValue.scala
new file mode 100644
index 000000000..381753ea2
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/IndexedValue.scala
@@ -0,0 +1,454 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import upickle.core.Util.reject
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                  ^^^^ reference upickle/core/Util.
+//                       ^^^^^^ reference upickle/core/Util.reject().
+import scala.collection.mutable
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/collection/
+//                      ^^^^^^^ reference scala/collection/mutable/
+import upickle.core.{Visitor, ObjVisitor, ArrVisitor, Abort, AbortException}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^ reference upickle/core/Visitor.
+//                   ^^^^^^^ reference upickle/core/Visitor#
+//                            ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                        ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                                                    ^^^^^ reference upickle/core/Abort.
+//                                                    ^^^^^ reference upickle/core/Abort#
+//                                                           ^^^^^^^^^^^^^^ reference upickle/core/AbortException.
+//                                                           ^^^^^^^^^^^^^^ reference upickle/core/AbortException#
+
+/**
+  * A version of [[ujson.Value]] that keeps the index positions of the various AST
+  * nodes it is constructing. Usually not necessary, but sometimes useful if you
+  * want to work with an AST but still provide source-index error positions if
+  * something goes wrong
+  */
+sealed trait IndexedValue {
+//           ^^^^^^^^^^^^ definition ujson/IndexedValue#
+  def index: Int
+//    ^^^^^ definition ujson/IndexedValue#index().
+//           ^^^ reference scala/Int#
+}
+
+object IndexedValue extends Transformer[IndexedValue]{
+//     ^^^^^^^^^^^^ definition ujson/IndexedValue.
+//                          ^^^^^^^^^^^ reference ujson/Transformer#
+//                                      ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                    reference java/lang/Object#`<init>`().
+  
+  case class Str(index: Int, value0: java.lang.CharSequence) extends IndexedValue
+//           ^^^ definition ujson/IndexedValue.Str#
+//               definition ujson/IndexedValue.Str#`<init>`().
+//               ^^^^^ definition ujson/IndexedValue.Str#index.
+//                      ^^^ reference scala/Int#
+//                           ^^^^^^ definition ujson/IndexedValue.Str#value0.
+//                                   ^^^^ reference java/
+//                                        ^^^^ reference java/lang/
+//                                             ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                                                   ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                                                reference java/lang/Object#`<init>`().
+  case class Obj(index: Int, value0: (java.lang.CharSequence, IndexedValue)*) extends IndexedValue
+//           ^^^ definition ujson/IndexedValue.Obj#
+//               definition ujson/IndexedValue.Obj#`<init>`().
+//               ^^^^^ definition ujson/IndexedValue.Obj#index.
+//                      ^^^ reference scala/Int#
+//                           ^^^^^^ definition ujson/IndexedValue.Obj#value0.
+//                                    ^^^^ reference java/
+//                                         ^^^^ reference java/lang/
+//                                              ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                                            ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                                                    ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                                                                 reference java/lang/Object#`<init>`().
+  case class Arr(index: Int, value: IndexedValue*) extends IndexedValue
+//           ^^^ definition ujson/IndexedValue.Arr#
+//               definition ujson/IndexedValue.Arr#`<init>`().
+//               ^^^^^ definition ujson/IndexedValue.Arr#index.
+//                      ^^^ reference scala/Int#
+//                           ^^^^^ definition ujson/IndexedValue.Arr#value.
+//                                  ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                         ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                                      reference java/lang/Object#`<init>`().
+  case class Num(index: Int, s: CharSequence, decIndex: Int, expIndex: Int) extends IndexedValue
+//           ^^^ definition ujson/IndexedValue.Num#
+//               definition ujson/IndexedValue.Num#`<init>`().
+//               ^^^^^ definition ujson/IndexedValue.Num#index.
+//                      ^^^ reference scala/Int#
+//                           ^ definition ujson/IndexedValue.Num#s.
+//                              ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                            ^^^^^^^^ definition ujson/IndexedValue.Num#decIndex.
+//                                                      ^^^ reference scala/Int#
+//                                                           ^^^^^^^^ definition ujson/IndexedValue.Num#expIndex.
+//                                                                     ^^^ reference scala/Int#
+//                                                                                  ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                                                               reference java/lang/Object#`<init>`().
+  case class NumRaw(index: Int, d: Double) extends IndexedValue
+//           ^^^^^^ definition ujson/IndexedValue.NumRaw#
+//                  definition ujson/IndexedValue.NumRaw#`<init>`().
+//                  ^^^^^ definition ujson/IndexedValue.NumRaw#index.
+//                         ^^^ reference scala/Int#
+//                              ^ definition ujson/IndexedValue.NumRaw#d.
+//                                 ^^^^^^ reference scala/Double#
+//                                                 ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                              reference java/lang/Object#`<init>`().
+  case class False(index: Int) extends IndexedValue{
+//           ^^^^^ definition ujson/IndexedValue.False#
+//                 definition ujson/IndexedValue.False#`<init>`().
+//                 ^^^^^ definition ujson/IndexedValue.False#index.
+//                        ^^^ reference scala/Int#
+//                                     ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                  reference java/lang/Object#`<init>`().
+    def value = false
+//      ^^^^^ definition ujson/IndexedValue.False#value().
+  }
+  case class True(index: Int) extends IndexedValue{
+//           ^^^^ definition ujson/IndexedValue.True#
+//                definition ujson/IndexedValue.True#`<init>`().
+//                ^^^^^ definition ujson/IndexedValue.True#index.
+//                       ^^^ reference scala/Int#
+//                                    ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                 reference java/lang/Object#`<init>`().
+    def value = true
+//      ^^^^^ definition ujson/IndexedValue.True#value().
+  }
+  case class Null(index: Int) extends IndexedValue{
+//           ^^^^ definition ujson/IndexedValue.Null#
+//                definition ujson/IndexedValue.Null#`<init>`().
+//                ^^^^^ definition ujson/IndexedValue.Null#index.
+//                       ^^^ reference scala/Int#
+//                                    ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                 reference java/lang/Object#`<init>`().
+    def value = null
+//      ^^^^^ definition ujson/IndexedValue.Null#value().
+  }
+
+  def transform[T](j: IndexedValue, f: Visitor[_, T]): T = try{
+//    ^^^^^^^^^ definition ujson/IndexedValue.transform().
+//              ^ definition ujson/IndexedValue.transform().[T]
+//                 ^ definition ujson/IndexedValue.transform().(j)
+//                    ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                  ^ definition ujson/IndexedValue.transform().(f)
+//                                     ^^^^^^^ reference upickle/core/Visitor#
+//                                                ^ reference ujson/IndexedValue.transform().[T]
+//                                                     ^ reference ujson/IndexedValue.transform().[T]
+    j match{
+//  ^ reference ujson/IndexedValue.transform().(j)
+      case IndexedValue.Null(i) => f.visitNull(i)
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^^ reference ujson/IndexedValue.Null.
+//                           ^ definition local0
+//                                 ^ reference ujson/IndexedValue.transform().(f)
+//                                   ^^^^^^^^^ reference upickle/core/Visitor#visitNull().
+//                                             ^ reference local0
+      case IndexedValue.True(i) => f.visitTrue(i)
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^^ reference ujson/IndexedValue.True.
+//                           ^ definition local1
+//                                 ^ reference ujson/IndexedValue.transform().(f)
+//                                   ^^^^^^^^^ reference upickle/core/Visitor#visitTrue().
+//                                             ^ reference local1
+      case IndexedValue.False(i) => f.visitFalse(i)
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^^^ reference ujson/IndexedValue.False.
+//                            ^ definition local2
+//                                  ^ reference ujson/IndexedValue.transform().(f)
+//                                    ^^^^^^^^^^ reference upickle/core/Visitor#visitFalse().
+//                                               ^ reference local2
+      case IndexedValue.Str(i, s) => f.visitString(s, i)
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^ reference ujson/IndexedValue.Str.
+//                          ^ definition local3
+//                             ^ definition local4
+//                                   ^ reference ujson/IndexedValue.transform().(f)
+//                                     ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                                 ^ reference local4
+//                                                    ^ reference local3
+      case IndexedValue.Num(i, s, d, e) => f.visitFloat64StringParts(s, d, e, i)
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^ reference ujson/IndexedValue.Num.
+//                          ^ definition local5
+//                             ^ definition local6
+//                                ^ definition local7
+//                                   ^ definition local8
+//                                         ^ reference ujson/IndexedValue.transform().(f)
+//                                           ^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64StringParts().
+//                                                                   ^ reference local6
+//                                                                      ^ reference local7
+//                                                                         ^ reference local8
+//                                                                            ^ reference local5
+      case IndexedValue.NumRaw(i, d) => f.visitFloat64(d, i)
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^^^^ reference ujson/IndexedValue.NumRaw.
+//                             ^ definition local9
+//                                ^ definition local10
+//                                      ^ reference ujson/IndexedValue.transform().(f)
+//                                        ^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64().
+//                                                     ^ reference local10
+//                                                        ^ reference local9
+      case IndexedValue.Arr(i, items @_*) =>
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^ reference ujson/IndexedValue.Arr.
+//                          ^ definition local11
+//                             ^^^^^ definition local12
+        val ctx = f.visitArray(-1, -1).narrow
+//          ^^^ definition local13
+//                ^ reference ujson/IndexedValue.transform().(f)
+//                  ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                                     ^^^^^^ reference upickle/core/ArrVisitor#narrow().
+        for(item <- items) try ctx.visitValue(transform(item, ctx.subVisitor), item.index) catch reject(item.index)
+//          ^^^^ definition local14
+//                  ^^^^^ reference local12
+//                             ^^^ reference local13
+//                                 ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                                            ^^^^^^^^^ reference ujson/IndexedValue.transform().
+//                                                      ^^^^ reference local14
+//                                                            ^^^ reference local13
+//                                                                ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                                                             ^^^^ reference local14
+//                                                                                  ^^^^^ reference ujson/IndexedValue#index().
+//                                                                                               ^^^^^^ reference upickle/core/Util.reject().
+//                                                                                                      ^^^^ reference local14
+//                                                                                                           ^^^^^ reference ujson/IndexedValue#index().
+        ctx.visitEnd(i)
+//      ^^^ reference local13
+//          ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+//                   ^ reference local11
+      case IndexedValue.Obj(i, items @_*) =>
+//         ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                      ^^^ reference ujson/IndexedValue.Obj.
+//                          ^ definition local16
+//                             ^^^^^ definition local17
+        val ctx = f.visitObject(-1, -1).narrow
+//          ^^^ definition local18
+//                ^ reference ujson/IndexedValue.transform().(f)
+//                  ^^^^^^^^^^^ reference upickle/core/Visitor#visitObject().
+//                                      ^^^^^^ reference upickle/core/ObjVisitor#narrow().
+        for((k, item) <- items) {
+//           ^ definition local21
+//              ^^^^ definition local22
+//                       ^^^^^ reference scala/collection/IterableOps#withFilter().
+          val keyVisitor = try ctx.visitKey(i) catch reject(i)
+//            ^^^^^^^^^^ definition local23
+//                             ^^^ reference local18
+//                                 ^^^^^^^^ reference upickle/core/ObjVisitor#visitKey().
+//                                          ^ reference local16
+//                                                   ^^^^^^ reference upickle/core/Util.reject().
+//                                                          ^ reference local16
+
+          ctx.visitKeyValue(keyVisitor.visitString(k, i))
+//        ^^^ reference local18
+//            ^^^^^^^^^^^^^ reference upickle/core/ObjVisitor#visitKeyValue().
+//                          ^^^^^^^^^^ reference local23
+//                                     ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                                 ^ reference local21
+//                                                    ^ reference local16
+          try ctx.visitValue(transform(item, ctx.subVisitor), item.index) catch reject(item.index)
+//            ^^^ reference local18
+//                ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                           ^^^^^^^^^ reference ujson/IndexedValue.transform().
+//                                     ^^^^ reference local22
+//                                           ^^^ reference local18
+//                                               ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                                            ^^^^ reference local22
+//                                                                 ^^^^^ reference ujson/IndexedValue#index().
+//                                                                              ^^^^^^ reference upickle/core/Util.reject().
+//                                                                                     ^^^^ reference local22
+//                                                                                          ^^^^^ reference ujson/IndexedValue#index().
+        }
+        ctx.visitEnd(i)
+//      ^^^ reference local18
+//          ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+//                   ^ reference local16
+    }
+  } catch reject(j.index)
+//        ^^^^^^ reference upickle/core/Util.reject().
+//               ^ reference ujson/IndexedValue.transform().(j)
+//                 ^^^^^ reference ujson/IndexedValue#index().
+
+
+  object Builder extends JsVisitor[IndexedValue, IndexedValue]{
+//       ^^^^^^^ definition ujson/IndexedValue.Builder.
+//                       ^^^^^^^^^ reference ujson/JsVisitor#
+//                                 ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                               ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                             reference java/lang/Object#`<init>`().
+    def visitArray(length: Int, i: Int) = new ArrVisitor[IndexedValue, IndexedValue.Arr] {
+//      ^^^^^^^^^^ definition ujson/IndexedValue.Builder.visitArray().
+//                 ^^^^^^ definition ujson/IndexedValue.Builder.visitArray().(length)
+//                         ^^^ reference scala/Int#
+//                              ^ definition ujson/IndexedValue.Builder.visitArray().(i)
+//                                 ^^^ reference scala/Int#
+//                                            ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                                                       ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                                     ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                                                  ^^^ reference ujson/IndexedValue.Arr#
+//                                                                                        reference java/lang/Object#`<init>`().
+      val out = mutable.Buffer.empty[IndexedValue]
+//        ^^^ definition local25
+//              ^^^^^^^ reference scala/collection/mutable/
+//                      ^^^^^^ reference scala/collection/mutable/Buffer.
+//                             ^^^^^ reference scala/collection/SeqFactory.Delegate#empty().
+//                                   ^^^^^^^^^^^^ reference ujson/IndexedValue#
+      def subVisitor = Builder
+//        ^^^^^^^^^^ definition local26
+//                     ^^^^^^^ reference ujson/IndexedValue.Builder.
+      def visitValue(v: IndexedValue, index: Int): Unit = {
+//        ^^^^^^^^^^ definition local27
+//                   ^ definition local28
+//                      ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                    ^^^^^ definition local29
+//                                           ^^^ reference scala/Int#
+//                                                 ^^^^ reference scala/Unit#
+        out.append(v)
+//      ^^^ reference local25
+//          ^^^^^^ reference scala/collection/mutable/Buffer#append().
+//                 ^ reference local28
+      }
+      def visitEnd(index: Int): IndexedValue.Arr = IndexedValue.Arr(i, out.toSeq:_*)
+//        ^^^^^^^^ definition local30
+//                 ^^^^^ definition local31
+//                        ^^^ reference scala/Int#
+//                              ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                           ^^^ reference ujson/IndexedValue.Arr#
+//                                                 ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                              ^^^ reference ujson/IndexedValue.Arr.
+//                                                                  ^ reference ujson/IndexedValue.Builder.visitArray().(i)
+//                                                                     ^^^ reference local25
+//                                                                         ^^^^^ reference scala/collection/IterableOnceOps#toSeq().
+    }
+
+    def visitObject(length: Int, i: Int) = new ObjVisitor[IndexedValue, IndexedValue.Obj] {
+//      ^^^^^^^^^^^ definition ujson/IndexedValue.Builder.visitObject().
+//                  ^^^^^^ definition ujson/IndexedValue.Builder.visitObject().(length)
+//                          ^^^ reference scala/Int#
+//                               ^ definition ujson/IndexedValue.Builder.visitObject().(i)
+//                                  ^^^ reference scala/Int#
+//                                             ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                                        ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                                                      ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                                                   ^^^ reference ujson/IndexedValue.Obj#
+//                                                                                         reference java/lang/Object#`<init>`().
+      val out = mutable.Buffer.empty[(String, IndexedValue)]
+//        ^^^ definition local32
+//              ^^^^^^^ reference scala/collection/mutable/
+//                      ^^^^^^ reference scala/collection/mutable/Buffer.
+//                             ^^^^^ reference scala/collection/SeqFactory.Delegate#empty().
+//                                    ^^^^^^ reference scala/Predef.String#
+//                                            ^^^^^^^^^^^^ reference ujson/IndexedValue#
+      var currentKey: String = _
+//        ^^^^^^^^^^ definition local33
+//                    ^^^^^^ reference scala/Predef.String#
+      def subVisitor = Builder
+//        ^^^^^^^^^^ definition local34
+//                     ^^^^^^^ reference ujson/IndexedValue.Builder.
+      def visitKey(index: Int) = IndexedValue.Builder
+//        ^^^^^^^^ definition local35
+//                 ^^^^^ definition local36
+//                        ^^^ reference scala/Int#
+//                               ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                            ^^^^^^^ reference ujson/IndexedValue.Builder.
+      def visitKeyValue(s: Any): Unit = currentKey = s.asInstanceOf[IndexedValue.Str].value0.toString
+//        ^^^^^^^^^^^^^ definition local37
+//                      ^ definition local38
+//                         ^^^ reference scala/Any#
+//                               ^^^^ reference scala/Unit#
+//                                      ^^^^^^^^^^ reference local39
+//                                                   ^ reference local38
+//                                                     ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                                  ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                                               ^^^ reference ujson/IndexedValue.Str#
+//                                                                                    ^^^^^^ reference ujson/IndexedValue.Str#value0.
+//                                                                                           ^^^^^^^^ reference java/lang/Object#toString().
+      def visitValue(v: IndexedValue, index: Int): Unit = {
+//        ^^^^^^^^^^ definition local40
+//                   ^ definition local41
+//                      ^^^^^^^^^^^^ reference ujson/IndexedValue#
+//                                    ^^^^^ definition local42
+//                                           ^^^ reference scala/Int#
+//                                                 ^^^^ reference scala/Unit#
+        out.append((currentKey, v))
+//      ^^^ reference local32
+//          ^^^^^^ reference scala/collection/mutable/Buffer#append().
+//                  ^^^^^^^^^^ reference local33
+//                              ^ reference local41
+      }
+      def visitEnd(index: Int): IndexedValue.Obj = IndexedValue.Obj(i, out.toSeq:_*)
+//        ^^^^^^^^ definition local43
+//                 ^^^^^ definition local44
+//                        ^^^ reference scala/Int#
+//                              ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                           ^^^ reference ujson/IndexedValue.Obj#
+//                                                 ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                              ^^^ reference ujson/IndexedValue.Obj.
+//                                                                  ^ reference ujson/IndexedValue.Builder.visitObject().(i)
+//                                                                     ^^^ reference local32
+//                                                                         ^^^^^ reference scala/collection/IterableOnceOps#toSeq().
+    }
+
+    def visitNull(i: Int) = IndexedValue.Null(i)
+//      ^^^^^^^^^ definition ujson/IndexedValue.Builder.visitNull().
+//                ^ definition ujson/IndexedValue.Builder.visitNull().(i)
+//                   ^^^ reference scala/Int#
+//                          ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                       ^^^^ reference ujson/IndexedValue.Null.
+//                                            ^ reference ujson/IndexedValue.Builder.visitNull().(i)
+
+    def visitFalse(i: Int) = IndexedValue.False(i)
+//      ^^^^^^^^^^ definition ujson/IndexedValue.Builder.visitFalse().
+//                 ^ definition ujson/IndexedValue.Builder.visitFalse().(i)
+//                    ^^^ reference scala/Int#
+//                           ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                        ^^^^^ reference ujson/IndexedValue.False.
+//                                              ^ reference ujson/IndexedValue.Builder.visitFalse().(i)
+
+    def visitTrue(i: Int) = IndexedValue.True(i)
+//      ^^^^^^^^^ definition ujson/IndexedValue.Builder.visitTrue().
+//                ^ definition ujson/IndexedValue.Builder.visitTrue().(i)
+//                   ^^^ reference scala/Int#
+//                          ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                       ^^^^ reference ujson/IndexedValue.True.
+//                                            ^ reference ujson/IndexedValue.Builder.visitTrue().(i)
+
+    def visitFloat64StringParts(s: CharSequence, decIndex: Int, expIndex: Int, i: Int) = IndexedValue.Num(i, s, decIndex, expIndex)
+//      ^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/IndexedValue.Builder.visitFloat64StringParts().
+//                              ^ definition ujson/IndexedValue.Builder.visitFloat64StringParts().(s)
+//                                 ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                               ^^^^^^^^ definition ujson/IndexedValue.Builder.visitFloat64StringParts().(decIndex)
+//                                                         ^^^ reference scala/Int#
+//                                                              ^^^^^^^^ definition ujson/IndexedValue.Builder.visitFloat64StringParts().(expIndex)
+//                                                                        ^^^ reference scala/Int#
+//                                                                             ^ definition ujson/IndexedValue.Builder.visitFloat64StringParts().(i)
+//                                                                                ^^^ reference scala/Int#
+//                                                                                       ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                                                                    ^^^ reference ujson/IndexedValue.Num.
+//                                                                                                        ^ reference ujson/IndexedValue.Builder.visitFloat64StringParts().(i)
+//                                                                                                           ^ reference ujson/IndexedValue.Builder.visitFloat64StringParts().(s)
+//                                                                                                              ^^^^^^^^ reference ujson/IndexedValue.Builder.visitFloat64StringParts().(decIndex)
+//                                                                                                                        ^^^^^^^^ reference ujson/IndexedValue.Builder.visitFloat64StringParts().(expIndex)
+    override def visitFloat64(d: Double, i: Int) = IndexedValue.NumRaw(i, d)
+//               ^^^^^^^^^^^^ definition ujson/IndexedValue.Builder.visitFloat64().
+//                            ^ definition ujson/IndexedValue.Builder.visitFloat64().(d)
+//                               ^^^^^^ reference scala/Double#
+//                                       ^ definition ujson/IndexedValue.Builder.visitFloat64().(i)
+//                                          ^^^ reference scala/Int#
+//                                                 ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                              ^^^^^^ reference ujson/IndexedValue.NumRaw.
+//                                                                     ^ reference ujson/IndexedValue.Builder.visitFloat64().(i)
+//                                                                        ^ reference ujson/IndexedValue.Builder.visitFloat64().(d)
+
+    def visitString(s: CharSequence, i: Int) = IndexedValue.Str(i, s)
+//      ^^^^^^^^^^^ definition ujson/IndexedValue.Builder.visitString().
+//                  ^ definition ujson/IndexedValue.Builder.visitString().(s)
+//                     ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                   ^ definition ujson/IndexedValue.Builder.visitString().(i)
+//                                      ^^^ reference scala/Int#
+//                                             ^^^^^^^^^^^^ reference ujson/IndexedValue.
+//                                                          ^^^ reference ujson/IndexedValue.Str.
+//                                                              ^ reference ujson/IndexedValue.Builder.visitString().(i)
+//                                                                 ^ reference ujson/IndexedValue.Builder.visitString().(s)
+  }
+}
diff --git a/tests/snapshots/src/main/generated/ujson/InputStreamParser.scala b/tests/snapshots/src/main/generated/ujson/InputStreamParser.scala
new file mode 100644
index 000000000..2003ccea6
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/InputStreamParser.scala
@@ -0,0 +1,88 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import scala.annotation.{switch, tailrec}
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                       ^^^^^^ reference scala/annotation/switch#
+//                               ^^^^^^^ reference scala/annotation/tailrec#
+import java.nio.ByteBuffer
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^^^^ reference java/nio/ByteBuffer#
+
+import upickle.core.{BufferingInputStreamParser, ObjArrVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingInputStreamParser.
+//                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingInputStreamParser#
+//                                               ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                                              ^^^^^^^ reference upickle/core/Visitor.
+//                                                              ^^^^^^^ reference upickle/core/Visitor#
+/**
+  * Parser that reads in bytes from an InputStream, buffering them in memory
+  * until a `reset` call discards them.
+  *
+  * Mostly the same as ByteArrayParser, except using an UberBuffer rather than
+  * reading directly from an Array[Byte].
+  *
+  * Generally not meant to be used directly, but via [[ujson.Readable.fromReadable]]
+  */
+final class InputStreamParser[J](val inputStream: java.io.InputStream,
+//          ^^^^^^^^^^^^^^^^^ definition ujson/InputStreamParser#
+//                            ^ definition ujson/InputStreamParser#[J]
+//                               definition ujson/InputStreamParser#`<init>`().
+//                                   ^^^^^^^^^^^ definition ujson/InputStreamParser#inputStream.
+//                                                ^^^^ reference java/
+//                                                     ^^ reference java/io/
+//                                                        ^^^^^^^^^^^ reference java/io/InputStream#
+                                 val minBufferStartSize: Int = BufferingInputStreamParser.defaultMinBufferStartSize,
+//                                   ^^^^^^^^^^^^^^^^^^ definition ujson/InputStreamParser#minBufferStartSize.
+//                                                       ^^^ reference scala/Int#
+//                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingInputStreamParser.
+//                                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingInputStreamParser.defaultMinBufferStartSize.
+                                 val maxBufferStartSize: Int = BufferingInputStreamParser.defaultMaxBufferStartSize)
+//                                   ^^^^^^^^^^^^^^^^^^ definition ujson/InputStreamParser#maxBufferStartSize.
+//                                                       ^^^ reference scala/Int#
+//                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingInputStreamParser.
+//                                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingInputStreamParser.defaultMaxBufferStartSize.
+extends ByteParser[J] with upickle.core.BufferingInputStreamParser{
+//      ^^^^^^^^^^ reference ujson/ByteParser#
+//                 ^ reference ujson/InputStreamParser#[J]
+//                     reference ujson/ByteParser#`<init>`().
+//                         ^^^^^^^ reference upickle/
+//                                 ^^^^ reference upickle/core/
+//                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/BufferingInputStreamParser#
+  protected[this] final def close() = {}
+//                          ^^^^^ definition ujson/InputStreamParser#close().
+}
+
+object InputStreamParser extends Transformer[java.io.InputStream]{
+//     ^^^^^^^^^^^^^^^^^ definition ujson/InputStreamParser.
+//                               ^^^^^^^^^^^ reference ujson/Transformer#
+//                                           ^^^^ reference java/
+//                                                ^^ reference java/io/
+//                                                   ^^^^^^^^^^^ reference java/io/InputStream#
+//                                                                reference java/lang/Object#`<init>`().
+  def transform[T](j: java.io.InputStream, f: Visitor[_, T]) = {
+//    ^^^^^^^^^ definition ujson/InputStreamParser.transform().
+//              ^ definition ujson/InputStreamParser.transform().[T]
+//                 ^ definition ujson/InputStreamParser.transform().(j)
+//                    ^^^^ reference java/
+//                         ^^ reference java/io/
+//                            ^^^^^^^^^^^ reference java/io/InputStream#
+//                                         ^ definition ujson/InputStreamParser.transform().(f)
+//                                            ^^^^^^^ reference upickle/core/Visitor#
+//                                                       ^ reference ujson/InputStreamParser.transform().[T]
+    val p = new InputStreamParser[T](j)
+//      ^ definition local0
+//              ^^^^^^^^^^^^^^^^^ reference ujson/InputStreamParser#
+//                                ^ reference ujson/InputStreamParser.transform().[T]
+//                                   reference ujson/InputStreamParser#`<init>`().
+//                                   ^ reference ujson/InputStreamParser.transform().(j)
+    p.parse(f)
+//  ^ reference local0
+//    ^^^^^ reference ujson/ByteParser#parse().
+//          ^ reference ujson/InputStreamParser.transform().(f)
+  }
+}
diff --git a/tests/snapshots/src/main/generated/ujson/JsVisitor.scala b/tests/snapshots/src/main/generated/ujson/JsVisitor.scala
new file mode 100644
index 000000000..5dd97b8a8
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/JsVisitor.scala
@@ -0,0 +1,264 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import upickle.core.{ArrVisitor, ObjVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                               ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                           ^^^^^^^ reference upickle/core/Visitor.
+//                                           ^^^^^^^ reference upickle/core/Visitor#
+
+/**
+  * A [[Visitor]] specialized to work with JSON types. Forwards the
+  * not-JSON-related methods to their JSON equivalents.
+  */
+trait JsVisitor[-T, +J] extends Visitor[T, J]{
+//    ^^^^^^^^^ definition ujson/JsVisitor#
+//               ^ definition ujson/JsVisitor#[T]
+//                   ^ definition ujson/JsVisitor#[J]
+//                              ^^^^^^^ reference upickle/core/Visitor#
+//                                      ^ reference ujson/JsVisitor#[T]
+//                                         ^ reference ujson/JsVisitor#[J]
+  def visitFloat64(d: Double, index: Int): J = {
+//    ^^^^^^^^^^^^ definition ujson/JsVisitor#visitFloat64().
+//                 ^ definition ujson/JsVisitor#visitFloat64().(d)
+//                    ^^^^^^ reference scala/Double#
+//                            ^^^^^ definition ujson/JsVisitor#visitFloat64().(index)
+//                                   ^^^ reference scala/Int#
+//                                         ^ reference ujson/JsVisitor#[J]
+    val i = d.toLong
+//      ^ definition local0
+//          ^ reference ujson/JsVisitor#visitFloat64().(d)
+//            ^^^^^^ reference scala/Double#toLong().
+    if(i == d) visitFloat64StringParts(i.toString, -1, -1, index)
+//     ^ reference local0
+//       ^^ reference scala/Long#`==`(+6).
+//          ^ reference ujson/JsVisitor#visitFloat64().(d)
+//             ^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64StringParts().
+//                                     ^ reference local0
+//                                       ^^^^^^^^ reference scala/Any#toString().
+//                                                         ^^^^^ reference ujson/JsVisitor#visitFloat64().(index)
+    else visitFloat64String(d.toString, index)
+//       ^^^^^^^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64String().
+//                          ^ reference ujson/JsVisitor#visitFloat64().(d)
+//                            ^^^^^^^^ reference scala/Any#toString().
+//                                      ^^^^^ reference ujson/JsVisitor#visitFloat64().(index)
+
+  }
+
+  def visitFloat32(d: Float, index: Int): J = visitFloat64(d, index)
+//    ^^^^^^^^^^^^ definition ujson/JsVisitor#visitFloat32().
+//                 ^ definition ujson/JsVisitor#visitFloat32().(d)
+//                    ^^^^^ reference scala/Float#
+//                           ^^^^^ definition ujson/JsVisitor#visitFloat32().(index)
+//                                  ^^^ reference scala/Int#
+//                                        ^ reference ujson/JsVisitor#[J]
+//                                            ^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64().
+//                                                         ^ reference scala/Float#toDouble().
+//                                                            ^^^^^ reference ujson/JsVisitor#visitFloat32().(index)
+  def visitInt32(i: Int, index: Int): J = visitFloat64(i, index)
+//    ^^^^^^^^^^ definition ujson/JsVisitor#visitInt32().
+//               ^ definition ujson/JsVisitor#visitInt32().(i)
+//                  ^^^ reference scala/Int#
+//                       ^^^^^ definition ujson/JsVisitor#visitInt32().(index)
+//                              ^^^ reference scala/Int#
+//                                    ^ reference ujson/JsVisitor#[J]
+//                                        ^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64().
+//                                                     ^ reference scala/Int#toDouble().
+//                                                        ^^^^^ reference ujson/JsVisitor#visitInt32().(index)
+  def visitInt64(i: Long, index: Int): J = {
+//    ^^^^^^^^^^ definition ujson/JsVisitor#visitInt64().
+//               ^ definition ujson/JsVisitor#visitInt64().(i)
+//                  ^^^^ reference scala/Long#
+//                        ^^^^^ definition ujson/JsVisitor#visitInt64().(index)
+//                               ^^^ reference scala/Int#
+//                                     ^ reference ujson/JsVisitor#[J]
+    if (math.abs(i) > math.pow(2, 53) || i == -9223372036854775808L) visitString(i.toString, index)
+//      ^^^^ reference scala/math/
+//           ^^^ reference scala/math/package.abs(+1).
+//               ^ reference ujson/JsVisitor#visitInt64().(i)
+//                  ^ reference scala/Long#`>`(+6).
+//                    ^^^^ reference scala/math/
+//                         ^^^ reference scala/math/package.pow().
+//                                    ^^ reference scala/Boolean#`||`().
+//                                       ^ reference ujson/JsVisitor#visitInt64().(i)
+//                                         ^^ reference scala/Long#`==`(+4).
+//                                                                   ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                                                               ^ reference ujson/JsVisitor#visitInt64().(i)
+//                                                                                 ^^^^^^^^ reference scala/Any#toString().
+//                                                                                           ^^^^^ reference ujson/JsVisitor#visitInt64().(index)
+    else visitFloat64(i, index)
+//       ^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64().
+//                    ^ reference scala/Long#toDouble().
+//                       ^^^^^ reference ujson/JsVisitor#visitInt64().(index)
+  }
+  def visitUInt64(i: Long, index: Int): J = {
+//    ^^^^^^^^^^^ definition ujson/JsVisitor#visitUInt64().
+//                ^ definition ujson/JsVisitor#visitUInt64().(i)
+//                   ^^^^ reference scala/Long#
+//                         ^^^^^ definition ujson/JsVisitor#visitUInt64().(index)
+//                                ^^^ reference scala/Int#
+//                                      ^ reference ujson/JsVisitor#[J]
+    if (i > math.pow(2, 53) || i < 0) visitString(java.lang.Long.toUnsignedString(i), index)
+//      ^ reference ujson/JsVisitor#visitUInt64().(i)
+//        ^ reference scala/Long#`>`(+6).
+//          ^^^^ reference scala/math/
+//               ^^^ reference scala/math/package.pow().
+//                          ^^ reference scala/Boolean#`||`().
+//                             ^ reference ujson/JsVisitor#visitUInt64().(i)
+//                               ^ reference scala/Long#`<`(+3).
+//                                    ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                                ^^^^ reference java/
+//                                                     ^^^^ reference java/lang/
+//                                                          ^^^^ reference java/lang/Long#
+//                                                               ^^^^^^^^^^^^^^^^ reference java/lang/Long#toUnsignedString(+1).
+//                                                                                ^ reference ujson/JsVisitor#visitUInt64().(i)
+//                                                                                    ^^^^^ reference ujson/JsVisitor#visitUInt64().(index)
+    else visitFloat64(i, index)
+//       ^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64().
+//                    ^ reference scala/Long#toDouble().
+//                       ^^^^^ reference ujson/JsVisitor#visitUInt64().(index)
+  }
+
+  def visitFloat64String(s: String, index: Int): J = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/JsVisitor#visitFloat64String().
+//                       ^ definition ujson/JsVisitor#visitFloat64String().(s)
+//                          ^^^^^^ reference scala/Predef.String#
+//                                  ^^^^^ definition ujson/JsVisitor#visitFloat64String().(index)
+//                                         ^^^ reference scala/Int#
+//                                               ^ reference ujson/JsVisitor#[J]
+    visitFloat64StringParts(
+//  ^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64StringParts().
+      s,
+//    ^ reference ujson/JsVisitor#visitFloat64String().(s)
+      s.indexOf('.'),
+//    ^ reference ujson/JsVisitor#visitFloat64String().(s)
+//      ^^^^^^^ reference java/lang/String#indexOf().
+      s.indexOf('E') match{
+//    ^ reference ujson/JsVisitor#visitFloat64String().(s)
+//      ^^^^^^^ reference java/lang/String#indexOf().
+        case -1 => s.indexOf('e')
+//                 ^ reference ujson/JsVisitor#visitFloat64String().(s)
+//                   ^^^^^^^ reference java/lang/String#indexOf().
+        case n => n
+//           ^ definition local1
+//                ^ reference local1
+      },
+      -1
+    )
+  }
+
+  def visitBinary(bytes: Array[Byte], offset: Int, len: Int, index: Int): J = {
+//    ^^^^^^^^^^^ definition ujson/JsVisitor#visitBinary().
+//                ^^^^^ definition ujson/JsVisitor#visitBinary().(bytes)
+//                       ^^^^^ reference scala/Array#
+//                             ^^^^ reference scala/Byte#
+//                                    ^^^^^^ definition ujson/JsVisitor#visitBinary().(offset)
+//                                            ^^^ reference scala/Int#
+//                                                 ^^^ definition ujson/JsVisitor#visitBinary().(len)
+//                                                      ^^^ reference scala/Int#
+//                                                           ^^^^^ definition ujson/JsVisitor#visitBinary().(index)
+//                                                                  ^^^ reference scala/Int#
+//                                                                        ^ reference ujson/JsVisitor#[J]
+    val arr = visitArray(len, index)
+//      ^^^ definition local2
+//            ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                       ^^^ reference ujson/JsVisitor#visitBinary().(len)
+//                            ^^^^^ reference ujson/JsVisitor#visitBinary().(index)
+    var i = 0
+//      ^ definition local3
+    while (i < len){
+//         ^ reference local3
+//           ^ reference scala/Int#`<`(+3).
+//             ^^^ reference ujson/JsVisitor#visitBinary().(len)
+      arr.visitValue(arr.subVisitor.visitInt32(bytes(offset + i), index).asInstanceOf[T], index)
+//    ^^^ reference local2
+//        ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                   ^^^ reference local2
+//                       ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#subVisitor().
+//                                  ^^^^^^^^^^ reference upickle/core/Visitor#visitInt32().
+//                                             ^^^^^ reference ujson/JsVisitor#visitBinary().(bytes)
+//                                                   ^^^^^^ reference ujson/JsVisitor#visitBinary().(offset)
+//                                                          ^ reference scala/Int#`+`(+4).
+//                                                            ^ reference local3
+//                                                                ^^^^^ reference ujson/JsVisitor#visitBinary().(index)
+//                                                                       ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                                                    ^ reference ujson/JsVisitor#[T]
+//                                                                                        ^^^^^ reference ujson/JsVisitor#visitBinary().(index)
+      i += 1
+//    ^ reference local3
+//      ^^ reference scala/Int#`+`(+4).
+    }
+    arr.visitEnd(index)
+//  ^^^ reference local2
+//      ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+//               ^^^^^ reference ujson/JsVisitor#visitBinary().(index)
+  }
+
+  def visitFloat64StringParts(s: CharSequence, decIndex: Int, expIndex: Int): J = visitFloat64StringParts(s, decIndex, expIndex, -1)
+//    ^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/JsVisitor#visitFloat64StringParts().
+//                            ^ definition ujson/JsVisitor#visitFloat64StringParts().(s)
+//                               ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                             ^^^^^^^^ definition ujson/JsVisitor#visitFloat64StringParts().(decIndex)
+//                                                       ^^^ reference scala/Int#
+//                                                            ^^^^^^^^ definition ujson/JsVisitor#visitFloat64StringParts().(expIndex)
+//                                                                      ^^^ reference scala/Int#
+//                                                                            ^ reference ujson/JsVisitor#[J]
+//                                                                                ^^^^^^^^^^^^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64StringParts().
+//                                                                                                        ^ reference ujson/JsVisitor#visitFloat64StringParts().(s)
+//                                                                                                           ^^^^^^^^ reference ujson/JsVisitor#visitFloat64StringParts().(decIndex)
+//                                                                                                                     ^^^^^^^^ reference ujson/JsVisitor#visitFloat64StringParts().(expIndex)
+
+  def visitExt(tag: Byte, bytes: Array[Byte], offset: Int, len: Int, index: Int): J = {
+//    ^^^^^^^^ definition ujson/JsVisitor#visitExt().
+//             ^^^ definition ujson/JsVisitor#visitExt().(tag)
+//                  ^^^^ reference scala/Byte#
+//                        ^^^^^ definition ujson/JsVisitor#visitExt().(bytes)
+//                               ^^^^^ reference scala/Array#
+//                                     ^^^^ reference scala/Byte#
+//                                            ^^^^^^ definition ujson/JsVisitor#visitExt().(offset)
+//                                                    ^^^ reference scala/Int#
+//                                                         ^^^ definition ujson/JsVisitor#visitExt().(len)
+//                                                              ^^^ reference scala/Int#
+//                                                                   ^^^^^ definition ujson/JsVisitor#visitExt().(index)
+//                                                                          ^^^ reference scala/Int#
+//                                                                                ^ reference ujson/JsVisitor#[J]
+    val arr = visitArray(-1, index)
+//      ^^^ definition local4
+//            ^^^^^^^^^^ reference upickle/core/Visitor#visitArray().
+//                           ^^^^^ reference ujson/JsVisitor#visitExt().(index)
+    arr.visitValue(visitFloat64(tag, index).asInstanceOf[T], -1)
+//  ^^^ reference local4
+//      ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                 ^^^^^^^^^^^^ reference ujson/JsVisitor#visitFloat64().
+//                              ^^^ reference scala/Byte#toDouble().
+//                                   ^^^^^ reference ujson/JsVisitor#visitExt().(index)
+//                                          ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                       ^ reference ujson/JsVisitor#[T]
+    arr.visitValue(visitBinary(bytes, offset, len, index).asInstanceOf[T], -1)
+//  ^^^ reference local4
+//      ^^^^^^^^^^ reference upickle/core/ObjArrVisitor#visitValue().
+//                 ^^^^^^^^^^^ reference ujson/JsVisitor#visitBinary().
+//                             ^^^^^ reference ujson/JsVisitor#visitExt().(bytes)
+//                                    ^^^^^^ reference ujson/JsVisitor#visitExt().(offset)
+//                                            ^^^ reference ujson/JsVisitor#visitExt().(len)
+//                                                 ^^^^^ reference ujson/JsVisitor#visitExt().(index)
+//                                                        ^^^^^^^^^^^^ reference scala/Any#asInstanceOf().
+//                                                                     ^ reference ujson/JsVisitor#[T]
+    arr.visitEnd(-1)
+//  ^^^ reference local4
+//      ^^^^^^^^ reference upickle/core/ObjArrVisitor#visitEnd().
+  }
+
+  def visitChar(s: Char, index: Int) = visitString(s.toString, index)
+//    ^^^^^^^^^ definition ujson/JsVisitor#visitChar().
+//              ^ definition ujson/JsVisitor#visitChar().(s)
+//                 ^^^^ reference scala/Char#
+//                       ^^^^^ definition ujson/JsVisitor#visitChar().(index)
+//                              ^^^ reference scala/Int#
+//                                     ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                                 ^ reference ujson/JsVisitor#visitChar().(s)
+//                                                   ^^^^^^^^ reference scala/Any#toString().
+//                                                             ^^^^^ reference ujson/JsVisitor#visitChar().(index)
+}
diff --git a/tests/snapshots/src/main/generated/ujson/Readable.scala b/tests/snapshots/src/main/generated/ujson/Readable.scala
new file mode 100644
index 000000000..7e74b6ca0
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/Readable.scala
@@ -0,0 +1,175 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import java.nio.ByteBuffer
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^^^^ reference java/nio/ByteBuffer#
+import java.nio.channels.ReadableByteChannel
+//     ^^^^ reference java/
+//          ^^^ reference java/nio/
+//              ^^^^^^^^ reference java/nio/channels/
+//                       ^^^^^^^^^^^^^^^^^^^ reference java/nio/channels/ReadableByteChannel#
+import upickle.core.{Visitor, ObjArrVisitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^ reference upickle/core/Visitor.
+//                   ^^^^^^^ reference upickle/core/Visitor#
+//                            ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+trait Readable {
+//    ^^^^^^^^ definition ujson/Readable#
+  def transform[T](f: Visitor[_, T]): T
+//    ^^^^^^^^^ definition ujson/Readable#transform().
+//              ^ definition ujson/Readable#transform().[T]
+//                 ^ definition ujson/Readable#transform().(f)
+//                    ^^^^^^^ reference upickle/core/Visitor#
+//                               ^ reference ujson/Readable#transform().[T]
+//                                    ^ reference ujson/Readable#transform().[T]
+}
+
+object Readable extends ReadableLowPri{
+//     ^^^^^^^^ definition ujson/Readable.
+//                      ^^^^^^^^^^^^^^ reference ujson/ReadableLowPri#
+//                                     reference java/lang/Object#`<init>`().
+  case class fromTransformer[T](t: T, w: Transformer[T]) extends Readable{
+//           ^^^^^^^^^^^^^^^ definition ujson/Readable.fromTransformer#
+//                           ^ definition ujson/Readable.fromTransformer#[T]
+//                              definition ujson/Readable.fromTransformer#`<init>`().
+//                              ^ definition ujson/Readable.fromTransformer#t.
+//                                 ^ reference ujson/Readable.fromTransformer#[T]
+//                                    ^ definition ujson/Readable.fromTransformer#w.
+//                                       ^^^^^^^^^^^ reference ujson/Transformer#
+//                                                   ^ reference ujson/Readable.fromTransformer#[T]
+//                                                               ^^^^^^^^ reference ujson/Readable#
+//                                                                        reference java/lang/Object#`<init>`().
+    def transform[T](f: Visitor[_, T]): T = {
+//      ^^^^^^^^^ definition ujson/Readable.fromTransformer#transform().
+//                ^ definition ujson/Readable.fromTransformer#transform().[T]
+//                   ^ definition ujson/Readable.fromTransformer#transform().(f)
+//                      ^^^^^^^ reference upickle/core/Visitor#
+//                                 ^ reference ujson/Readable.fromTransformer#transform().[T]
+//                                      ^ reference ujson/Readable.fromTransformer#transform().[T]
+      w.transform(t, f)
+//    ^ reference ujson/Readable.fromTransformer#w.
+//      ^^^^^^^^^ reference ujson/Transformer#transform().
+//                ^ reference ujson/Readable.fromTransformer#t.
+//                   ^ reference ujson/Readable.fromTransformer#transform().(f)
+    }
+  }
+  implicit def fromString(s: String): fromTransformer[String] = new fromTransformer(s, StringParser)
+//             ^^^^^^^^^^ definition ujson/Readable.fromString().
+//                        ^ definition ujson/Readable.fromString().(s)
+//                           ^^^^^^ reference scala/Predef.String#
+//                                    ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                    ^^^^^^ reference scala/Predef.String#
+//                                                                  ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                                                  reference ujson/Readable.fromTransformer#`<init>`().
+//                                                                                  ^ reference ujson/Readable.fromString().(s)
+//                                                                                     ^^^^^^^^^^^^ reference ujson/StringParser.
+  implicit def fromCharSequence(s: CharSequence): fromTransformer[CharSequence] = new fromTransformer(s, CharSequenceParser)
+//             ^^^^^^^^^^^^^^^^ definition ujson/Readable.fromCharSequence().
+//                              ^ definition ujson/Readable.fromCharSequence().(s)
+//                                 ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                                ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                                ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                                                                    ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                                                                    reference ujson/Readable.fromTransformer#`<init>`().
+//                                                                                                    ^ reference ujson/Readable.fromCharSequence().(s)
+//                                                                                                       ^^^^^^^^^^^^^^^^^^ reference ujson/CharSequenceParser.
+  implicit def fromPath(s: java.nio.file.Path): Readable = new Readable {
+//             ^^^^^^^^ definition ujson/Readable.fromPath().
+//                      ^ definition ujson/Readable.fromPath().(s)
+//                         ^^^^ reference java/
+//                              ^^^ reference java/nio/
+//                                  ^^^^ reference java/nio/file/
+//                                       ^^^^ reference java/nio/file/Path#
+//                                              ^^^^^^^^ reference ujson/Readable#
+//                                                             ^^^^^^^^ reference ujson/Readable#
+//                                                                       reference java/lang/Object#`<init>`().
+    override def transform[T](f: Visitor[_, T]) = {
+//               ^^^^^^^^^ definition local0
+//                         ^ definition local1
+//                            ^ definition local2
+//                               ^^^^^^^ reference upickle/core/Visitor#
+//                                          ^ reference local1
+      val inputStream = java.nio.file.Files.newInputStream(s)
+//        ^^^^^^^^^^^ definition local3
+//                      ^^^^ reference java/
+//                           ^^^ reference java/nio/
+//                               ^^^^ reference java/nio/file/
+//                                    ^^^^^ reference java/nio/file/Files#
+//                                          ^^^^^^^^^^^^^^ reference java/nio/file/Files#newInputStream().
+//                                                         ^ reference ujson/Readable.fromPath().(s)
+      try InputStreamParser.transform(inputStream, f)
+//        ^^^^^^^^^^^^^^^^^ reference ujson/InputStreamParser.
+//                          ^^^^^^^^^ reference ujson/InputStreamParser.transform().
+//                                    ^^^^^^^^^^^ reference local3
+//                                                 ^ reference local2
+      finally inputStream.close()
+//            ^^^^^^^^^^^ reference local3
+//                        ^^^^^ reference java/io/InputStream#close().
+    }
+  }
+  implicit def fromFile(s: java.io.File): Readable = fromPath(s.toPath)
+//             ^^^^^^^^ definition ujson/Readable.fromFile().
+//                      ^ definition ujson/Readable.fromFile().(s)
+//                         ^^^^ reference java/
+//                              ^^ reference java/io/
+//                                 ^^^^ reference java/io/File#
+//                                        ^^^^^^^^ reference ujson/Readable#
+//                                                   ^^^^^^^^ reference ujson/Readable.fromPath().
+//                                                            ^ reference ujson/Readable.fromFile().(s)
+//                                                              ^^^^^^ reference java/io/File#toPath().
+  implicit def fromByteBuffer(s: ByteBuffer): fromTransformer[ByteBuffer] = new fromTransformer(s, ByteBufferParser)
+//             ^^^^^^^^^^^^^^ definition ujson/Readable.fromByteBuffer().
+//                            ^ definition ujson/Readable.fromByteBuffer().(s)
+//                               ^^^^^^^^^^ reference java/nio/ByteBuffer#
+//                                            ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                            ^^^^^^^^^^ reference java/nio/ByteBuffer#
+//                                                                              ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                                                              reference ujson/Readable.fromTransformer#`<init>`().
+//                                                                                              ^ reference ujson/Readable.fromByteBuffer().(s)
+//                                                                                                 ^^^^^^^^^^^^^^^^ reference ujson/ByteBufferParser.
+  implicit def fromByteArray(s: Array[Byte]): fromTransformer[Array[Byte]] = new fromTransformer(s, ByteArrayParser)
+//             ^^^^^^^^^^^^^ definition ujson/Readable.fromByteArray().
+//                           ^ definition ujson/Readable.fromByteArray().(s)
+//                              ^^^^^ reference scala/Array#
+//                                    ^^^^ reference scala/Byte#
+//                                            ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                            ^^^^^ reference scala/Array#
+//                                                                  ^^^^ reference scala/Byte#
+//                                                                               ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer#
+//                                                                                               reference ujson/Readable.fromTransformer#`<init>`().
+//                                                                                               ^ reference ujson/Readable.fromByteArray().(s)
+//                                                                                                  ^^^^^^^^^^^^^^^ reference ujson/ByteArrayParser.
+}
+
+trait ReadableLowPri{
+//    ^^^^^^^^^^^^^^ definition ujson/ReadableLowPri#
+  implicit def fromReadable[T](s: T)(implicit conv: T => geny.Readable): Readable = new Readable{
+//             ^^^^^^^^^^^^ definition ujson/ReadableLowPri#fromReadable().
+//                          ^ definition ujson/ReadableLowPri#fromReadable().[T]
+//                             ^ definition ujson/ReadableLowPri#fromReadable().(s)
+//                                ^ reference ujson/ReadableLowPri#fromReadable().[T]
+//                                            ^^^^ definition ujson/ReadableLowPri#fromReadable().(conv)
+//                                                  ^ reference ujson/ReadableLowPri#fromReadable().[T]
+//                                                       ^^^^ reference geny/
+//                                                            ^^^^^^^^ reference geny/Readable#
+//                                                                       ^^^^^^^^ reference ujson/Readable#
+//                                                                                      ^^^^^^^^ reference ujson/Readable#
+//                                                                                               reference java/lang/Object#`<init>`().
+    def transform[T](f: Visitor[_, T]): T = conv(s).readBytesThrough(InputStreamParser.transform(_, f))
+//      ^^^^^^^^^ definition local4
+//                ^ definition local5
+//                   ^ definition local6
+//                      ^^^^^^^ reference upickle/core/Visitor#
+//                                 ^ reference local5
+//                                      ^ reference local5
+//                                          ^^^^ reference ujson/ReadableLowPri#fromReadable().(conv)
+//                                               ^ reference ujson/ReadableLowPri#fromReadable().(s)
+//                                                  ^^^^^^^^^^^^^^^^ reference geny/Readable#readBytesThrough().
+//                                                                   ^^^^^^^^^^^^^^^^^ reference ujson/InputStreamParser.
+//                                                                                     ^^^^^^^^^ reference ujson/InputStreamParser.transform().
+//                                                                                                  ^ reference local6
+  }
+}
diff --git a/tests/snapshots/src/main/generated/ujson/Renderer.scala b/tests/snapshots/src/main/generated/ujson/Renderer.scala
new file mode 100644
index 000000000..572d53e13
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/Renderer.scala
@@ -0,0 +1,75 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import java.io.ByteArrayOutputStream
+//     ^^^^ reference java/
+//          ^^ reference java/io/
+//             ^^^^^^^^^^^^^^^^^^^^^ reference java/io/ByteArrayOutputStream#
+
+import upickle.core.{ArrVisitor, ObjVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^ reference upickle/core/ArrVisitor#
+//                               ^^^^^^^^^^ reference upickle/core/ObjVisitor#
+//                                           ^^^^^^^ reference upickle/core/Visitor.
+//                                           ^^^^^^^ reference upickle/core/Visitor#
+
+import scala.annotation.switch
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/annotation/
+//                      ^^^^^^ reference scala/annotation/switch#
+
+case class BytesRenderer(indent: Int = -1, escapeUnicode: Boolean = false)
+//         ^^^^^^^^^^^^^ definition ujson/BytesRenderer#
+//                       definition ujson/BytesRenderer#`<init>`().
+//                       ^^^^^^ definition ujson/BytesRenderer#indent.
+//                               ^^^ reference scala/Int#
+//                                         ^^^^^^^^^^^^^ definition ujson/BytesRenderer#escapeUnicode.
+//                                                        ^^^^^^^ reference scala/Boolean#
+  extends BaseByteRenderer(new ByteArrayOutputStream(), indent, escapeUnicode){
+//        ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#
+//                         reference ujson/BaseByteRenderer#`<init>`().
+//                             ^^^^^^^^^^^^^^^^^^^^^ reference java/io/ByteArrayOutputStream#
+//                                                   reference java/io/ByteArrayOutputStream#`<init>`().
+//                                                      ^^^^^^ reference ujson/BytesRenderer#`<init>`().(indent)
+//                                                              ^^^^^^^^^^^^^ reference ujson/BytesRenderer#`<init>`().(escapeUnicode)
+}
+
+
+case class StringRenderer(indent: Int = -1,
+//         ^^^^^^^^^^^^^^ definition ujson/StringRenderer#
+//                        definition ujson/StringRenderer#`<init>`().
+//                        ^^^^^^ definition ujson/StringRenderer#indent.
+//                                ^^^ reference scala/Int#
+                          escapeUnicode: Boolean = false)
+//                        ^^^^^^^^^^^^^ definition ujson/StringRenderer#escapeUnicode.
+//                                       ^^^^^^^ reference scala/Boolean#
+  extends BaseCharRenderer(new java.io.StringWriter(), indent, escapeUnicode)
+//        ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#
+//                         reference ujson/BaseCharRenderer#`<init>`().
+//                             ^^^^ reference java/
+//                                  ^^ reference java/io/
+//                                     ^^^^^^^^^^^^ reference java/io/StringWriter#
+//                                                  reference java/io/StringWriter#`<init>`().
+//                                                     ^^^^^^ reference ujson/StringRenderer#`<init>`().(indent)
+//                                                             ^^^^^^^^^^^^^ reference ujson/StringRenderer#`<init>`().(escapeUnicode)
+
+case class Renderer(out: java.io.Writer,
+//         ^^^^^^^^ definition ujson/Renderer#
+//                  definition ujson/Renderer#`<init>`().
+//                  ^^^ definition ujson/Renderer#out.
+//                       ^^^^ reference java/
+//                            ^^ reference java/io/
+//                               ^^^^^^ reference java/io/Writer#
+                    indent: Int = -1,
+//                  ^^^^^^ definition ujson/Renderer#indent.
+//                          ^^^ reference scala/Int#
+                    escapeUnicode: Boolean = false)
+//                  ^^^^^^^^^^^^^ definition ujson/Renderer#escapeUnicode.
+//                                 ^^^^^^^ reference scala/Boolean#
+  extends BaseCharRenderer(out, indent, escapeUnicode)
+//        ^^^^^^^^^^^^^^^^ reference ujson/BaseCharRenderer#
+//                         reference ujson/BaseCharRenderer#`<init>`().
+//                         ^^^ reference ujson/Renderer#`<init>`().(out)
+//                              ^^^^^^ reference ujson/Renderer#`<init>`().(indent)
+//                                      ^^^^^^^^^^^^^ reference ujson/Renderer#`<init>`().(escapeUnicode)
diff --git a/tests/snapshots/src/main/generated/ujson/StringParser.scala b/tests/snapshots/src/main/generated/ujson/StringParser.scala
new file mode 100644
index 000000000..9ef03b54f
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/StringParser.scala
@@ -0,0 +1,82 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+import upickle.core.{ObjArrVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                  ^^^^^^^ reference upickle/core/Visitor.
+//                                  ^^^^^^^ reference upickle/core/Visitor#
+
+/**
+ * Basic in-memory string parsing.
+ *
+ * This is probably the simplest Parser implementation, since there is
+ * no UTF-8 decoding, and the data is already fully available.
+ *
+ * This parser is limited to the maximum string size (~2G). Obviously
+ * for large JSON documents it's better to avoid using this parser and
+ * go straight from disk, to avoid having to load the whole thing into
+ * memory at once. So this limit will probably not be a problem in
+ * practice.
+ */
+private[ujson] final class StringParser[J](s: String) extends CharParser[J]{
+//      ^^^^^ reference ujson/
+//                         ^^^^^^^^^^^^ definition ujson/StringParser#
+//                                      ^ definition ujson/StringParser#[J]
+//                                         definition ujson/StringParser#`<init>`().
+//                                         ^ definition ujson/StringParser#s.
+//                                            ^^^^^^ reference scala/Predef.String#
+//                                                            ^^^^^^^^^^ reference ujson/CharParser#
+//                                                                       ^ reference ujson/StringParser#[J]
+//                                                                          reference ujson/CharParser#`<init>`().
+  private[this] val sLength = s.length
+//                  ^^^^^^^ definition ujson/StringParser#sLength.
+//                            ^ reference ujson/StringParser#s.
+//                              ^^^^^^ reference java/lang/String#length().
+  override def growBuffer(until: Int): Unit = ()
+//             ^^^^^^^^^^ definition ujson/StringParser#growBuffer().
+//                        ^^^^^ definition ujson/StringParser#growBuffer().(until)
+//                               ^^^ reference scala/Int#
+//                                     ^^^^ reference scala/Unit#
+  def readDataIntoBuffer(buffer: Array[Char], bufferOffset: Int) = {
+//    ^^^^^^^^^^^^^^^^^^ definition ujson/StringParser#readDataIntoBuffer().
+//                       ^^^^^^ definition ujson/StringParser#readDataIntoBuffer().(buffer)
+//                               ^^^^^ reference scala/Array#
+//                                     ^^^^ reference scala/Char#
+//                                            ^^^^^^^^^^^^ definition ujson/StringParser#readDataIntoBuffer().(bufferOffset)
+//                                                          ^^^ reference scala/Int#
+    if(buffer == null) (s.toCharArray, sLength == 0, sLength)
+//     ^^^^^^ reference ujson/StringParser#readDataIntoBuffer().(buffer)
+//            ^^ reference java/lang/Object#`==`().
+//                      ^ reference ujson/StringParser#s.
+//                        ^^^^^^^^^^^ reference java/lang/String#toCharArray().
+//                                     ^^^^^^^ reference ujson/StringParser#sLength.
+//                                             ^^ reference scala/Int#`==`(+3).
+//                                                   ^^^^^^^ reference ujson/StringParser#sLength.
+    else (buffer, true, -1)
+//        ^^^^^^ reference ujson/StringParser#readDataIntoBuffer().(buffer)
+  }
+  final def close() = ()
+//          ^^^^^ definition ujson/StringParser#close().
+}
+
+object StringParser extends Transformer[String]{
+//     ^^^^^^^^^^^^ definition ujson/StringParser.
+//                          ^^^^^^^^^^^ reference ujson/Transformer#
+//                                      ^^^^^^ reference scala/Predef.String#
+//                                              reference java/lang/Object#`<init>`().
+  def transform[T](j: String, f: Visitor[_, T]) = new StringParser(j).parse(f)
+//    ^^^^^^^^^ definition ujson/StringParser.transform().
+//              ^ definition ujson/StringParser.transform().[T]
+//                 ^ definition ujson/StringParser.transform().(j)
+//                    ^^^^^^ reference scala/Predef.String#
+//                            ^ definition ujson/StringParser.transform().(f)
+//                               ^^^^^^^ reference upickle/core/Visitor#
+//                                          ^ reference ujson/StringParser.transform().[T]
+//                                                    ^^^^^^^^^^^^ reference ujson/StringParser#
+//                                                                 reference ujson/StringParser#`<init>`().
+//                                                                 ^ reference ujson/StringParser.transform().(j)
+//                                                                    ^^^^^ reference ujson/CharParser#parse().
+//                                                                          ^ reference ujson/StringParser.transform().(f)
+}
diff --git a/tests/snapshots/src/main/generated/ujson/Transformer.scala b/tests/snapshots/src/main/generated/ujson/Transformer.scala
new file mode 100644
index 000000000..160ce74b2
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/Transformer.scala
@@ -0,0 +1,29 @@
+package ujson
+//      ^^^^^ definition ujson/
+import upickle.core.Visitor
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                  ^^^^^^^ reference upickle/core/Visitor.
+//                  ^^^^^^^ reference upickle/core/Visitor#
+
+trait Transformer[I] {
+//    ^^^^^^^^^^^ definition ujson/Transformer#
+//                ^ definition ujson/Transformer#[I]
+  def transform[T](j: I, f: Visitor[_, T]): T
+//    ^^^^^^^^^ definition ujson/Transformer#transform().
+//              ^ definition ujson/Transformer#transform().[T]
+//                 ^ definition ujson/Transformer#transform().(j)
+//                    ^ reference ujson/Transformer#[I]
+//                       ^ definition ujson/Transformer#transform().(f)
+//                          ^^^^^^^ reference upickle/core/Visitor#
+//                                     ^ reference ujson/Transformer#transform().[T]
+//                                          ^ reference ujson/Transformer#transform().[T]
+  def transformable[T](j: I) = Readable.fromTransformer(j, this)
+//    ^^^^^^^^^^^^^ definition ujson/Transformer#transformable().
+//                  ^ definition ujson/Transformer#transformable().[T]
+//                     ^ definition ujson/Transformer#transformable().(j)
+//                        ^ reference ujson/Transformer#[I]
+//                             ^^^^^^^^ reference ujson/Readable.
+//                                      ^^^^^^^^^^^^^^^ reference ujson/Readable.fromTransformer.
+//                                                      ^ reference ujson/Transformer#transformable().(j)
+}
diff --git a/tests/snapshots/src/main/generated/ujson/Value.scala b/tests/snapshots/src/main/generated/ujson/Value.scala
new file mode 100644
index 000000000..bf6e68375
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/Value.scala
@@ -0,0 +1,976 @@
+package ujson
+//      ^^^^^ definition ujson/
+
+
+
+import upickle.core.Util
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                  ^^^^ reference upickle/core/Util.
+import upickle.core.{ObjArrVisitor, Visitor}
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                   ^^^^^^^^^^^^^ reference upickle/core/ObjArrVisitor#
+//                                  ^^^^^^^ reference upickle/core/Visitor.
+//                                  ^^^^^^^ reference upickle/core/Visitor#
+
+import upickle.core.compat._
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                  ^^^^^^ reference upickle/core/compat/
+import scala.collection.mutable
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/collection/
+//                      ^^^^^^^ reference scala/collection/mutable/
+import scala.collection.mutable.ArrayBuffer
+//     ^^^^^ reference scala/
+//           ^^^^^^^^^^ reference scala/collection/
+//                      ^^^^^^^ reference scala/collection/mutable/
+//                              ^^^^^^^^^^^ reference scala/collection/mutable/ArrayBuffer.
+//                              ^^^^^^^^^^^ reference scala/collection/mutable/ArrayBuffer#
+
+sealed trait Value extends Readable with geny.Writable{
+//           ^^^^^ definition ujson/Value#
+//                         ^^^^^^^^ reference ujson/Readable#
+//                                       ^^^^ reference geny/
+//                                            ^^^^^^^^ reference geny/Writable#
+  override def httpContentType = Some("application/json")
+//             ^^^^^^^^^^^^^^^ definition ujson/Value#httpContentType().
+//                               ^^^^ reference scala/Some.
+  def value: Any
+//    ^^^^^ definition ujson/Value#value().
+//           ^^^ reference scala/Any#
+
+  /**
+    * Returns the `String` value of this [[Value]], fails if it is not
+    * a [[ujson.Str]]
+    */
+  def str = this match{
+//    ^^^ definition ujson/Value#str().
+    case ujson.Str(value) => value
+//       ^^^^^ reference ujson/
+//             ^^^ reference ujson/Str.
+//                 ^^^^^ definition local0
+//                           ^^^^^ reference local0
+    case _ => throw Value.InvalidData(this, "Expected ujson.Str")
+//                  ^^^^^ reference ujson/Value.
+//                        ^^^^^^^^^^^ reference ujson/Value.InvalidData.
+  }
+
+  /**
+    * Returns an Optional `String` value of this [[Value]] in case this [[Value]] is a 'String'.
+    */
+  def strOpt = this match{
+//    ^^^^^^ definition ujson/Value#strOpt().
+    case Str(value) => Some(value)
+//       ^^^ reference ujson/Str.
+//           ^^^^^ definition local1
+//                     ^^^^ reference scala/Some.
+//                          ^^^^^ reference local1
+    case _ => None
+//            ^^^^ reference scala/None.
+  }
+
+  /**
+    * Returns the key/value map of this [[Value]], fails if it is not
+    * a [[ujson.Obj]]
+    */
+  def obj = this match{
+//    ^^^ definition ujson/Value#obj().
+    case ujson.Obj(value) => value
+//       ^^^^^ reference ujson/
+//             ^^^ reference ujson/Obj.
+//                 ^^^^^ definition local2
+//                           ^^^^^ reference local2
+    case _ => throw Value.InvalidData(this, "Expected ujson.Obj")
+//                  ^^^^^ reference ujson/Value.
+//                        ^^^^^^^^^^^ reference ujson/Value.InvalidData.
+  }
+  /**
+    * Returns an Optional key/value map of this [[Value]] in case this [[Value]] is a 'Obj'.
+    */
+  def objOpt = this match{
+//    ^^^^^^ definition ujson/Value#objOpt().
+    case Obj(value) => Some(value)
+//       ^^^ reference ujson/Obj.
+//           ^^^^^ definition local3
+//                     ^^^^ reference scala/Some.
+//                          ^^^^^ reference local3
+    case _ => None
+//            ^^^^ reference scala/None.
+  }
+  /**
+    * Returns the elements of this [[Value]], fails if it is not
+    * a [[ujson.Arr]]
+    */
+  def arr = this match{
+//    ^^^ definition ujson/Value#arr().
+    case ujson.Arr(value) => value
+//       ^^^^^ reference ujson/
+//             ^^^ reference ujson/Arr.
+//                 ^^^^^ definition local4
+//                           ^^^^^ reference local4
+    case _ => throw Value.InvalidData(this, "Expected ujson.Arr")
+//                  ^^^^^ reference ujson/Value.
+//                        ^^^^^^^^^^^ reference ujson/Value.InvalidData.
+  }
+  /**
+    * Returns The optional elements of this [[Value]] in case this [[Value]] is a 'Arr'.
+    */
+  def arrOpt = this match{
+//    ^^^^^^ definition ujson/Value#arrOpt().
+    case Arr(value) => Some(value)
+//       ^^^ reference ujson/Arr.
+//           ^^^^^ definition local5
+//                     ^^^^ reference scala/Some.
+//                          ^^^^^ reference local5
+    case _ => None
+//            ^^^^ reference scala/None.
+  }
+  /**
+    * Returns the `Double` value of this [[Value]], fails if it is not
+    * a [[ujson.Num]]
+    */
+  def num = this match{
+//    ^^^ definition ujson/Value#num().
+    case ujson.Num(value) => value
+//       ^^^^^ reference ujson/
+//             ^^^ reference ujson/Num.
+//                 ^^^^^ definition local6
+//                           ^^^^^ reference local6
+    case _ => throw Value.InvalidData(this, "Expected ujson.Num")
+//                  ^^^^^ reference ujson/Value.
+//                        ^^^^^^^^^^^ reference ujson/Value.InvalidData.
+  }
+  /**
+    * Returns an Option[Double] in case this [[Value]] is a 'Num'.
+    */
+  def numOpt = this match{
+//    ^^^^^^ definition ujson/Value#numOpt().
+    case Num(value) => Some(value)
+//       ^^^ reference ujson/Num.
+//           ^^^^^ definition local7
+//                     ^^^^ reference scala/Some.
+//                          ^^^^^ reference local7
+    case _ => None
+//            ^^^^ reference scala/None.
+  }
+  /**
+    * Returns the `Boolean` value of this [[Value]], fails if it is not
+    * a [[ujson.Bool]]
+    */
+  def bool = this match{
+//    ^^^^ definition ujson/Value#bool().
+    case ujson.Bool(value) => value
+//       ^^^^^ reference ujson/
+//             ^^^^ reference ujson/Bool.
+//                  ^^^^^ definition local8
+//                            ^^^^^ reference local8
+    case _ => throw Value.InvalidData(this, "Expected ujson.Bool")
+//                  ^^^^^ reference ujson/Value.
+//                        ^^^^^^^^^^^ reference ujson/Value.InvalidData.
+  }
+  /**
+    * Returns an Optional `Boolean` value of this [[Value]] in case this [[Value]] is a 'Bool'.
+    */
+  def boolOpt = this match{
+//    ^^^^^^^ definition ujson/Value#boolOpt().
+    case Bool(value) => Some(value)
+//       ^^^^ reference ujson/Bool.
+//            ^^^^^ definition local9
+//                      ^^^^ reference scala/Some.
+//                           ^^^^^ reference local9
+    case _ => None
+//            ^^^^ reference scala/None.
+  }
+  /**
+    * Returns true if the value of this [[Value]] is ujson.Null, false otherwise
+    */
+  def isNull = this match {
+//    ^^^^^^ definition ujson/Value#isNull().
+    case ujson.Null => true
+//       ^^^^^ reference ujson/
+//             ^^^^ reference ujson/Null.
+    case _ => false
+  }
+
+  def apply(s: Value.Selector): Value = s(this)
+//    ^^^^^ definition ujson/Value#apply().
+//          ^ definition ujson/Value#apply().(s)
+//             ^^^^^ reference ujson/Value.
+//                   ^^^^^^^^ reference ujson/Value.Selector#
+//                              ^^^^^ reference ujson/Value#
+//                                      ^ reference ujson/Value#apply().(s)
+  def update(s: Value.Selector, v: Value): Unit = s(this) = v
+//    ^^^^^^ definition ujson/Value#update().
+//           ^ definition ujson/Value#update().(s)
+//              ^^^^^ reference ujson/Value.
+//                    ^^^^^^^^ reference ujson/Value.Selector#
+//                              ^ definition ujson/Value#update().(v)
+//                                 ^^^^^ reference ujson/Value#
+//                                         ^^^^ reference scala/Unit#
+//                                                ^ reference ujson/Value#update().(s)
+//                                                          ^ reference ujson/Value#update().(v)
+
+  /**
+    * Update a value in-place. Takes an `Int` or a `String`, through the
+    * implicitly-constructe [[Value.Selector]] type.
+    *
+    * We cannot just overload `update` on `s: Int` and `s: String` because
+    * of type inference problems in Scala 2.11.
+    */
+  def update(s: Value.Selector, f: Value => Value): Unit = s(this) = f(s(this))
+//    ^^^^^^ definition ujson/Value#update(+1).
+//           ^ definition ujson/Value#update(+1).(s)
+//              ^^^^^ reference ujson/Value.
+//                    ^^^^^^^^ reference ujson/Value.Selector#
+//                              ^ definition ujson/Value#update(+1).(f)
+//                                 ^^^^^ reference ujson/Value#
+//                                          ^^^^^ reference ujson/Value#
+//                                                  ^^^^ reference scala/Unit#
+//                                                         ^ reference ujson/Value#update(+1).(s)
+//                                                                   ^ reference ujson/Value#update(+1).(f)
+//                                                                     ^ reference ujson/Value#update(+1).(s)
+
+  def transform[T](f: Visitor[_, T]) = Value.transform(this, f)
+//    ^^^^^^^^^ definition ujson/Value#transform().
+//              ^ definition ujson/Value#transform().[T]
+//                 ^ definition ujson/Value#transform().(f)
+//                    ^^^^^^^ reference upickle/core/Visitor#
+//                               ^ reference ujson/Value#transform().[T]
+//                                     ^^^^^ reference ujson/Value.
+//                                           ^^^^^^^^^ reference ujson/Value.transform().
+//                                                           ^ reference ujson/Value#transform().(f)
+  override def toString = render()
+//             ^^^^^^^^ definition ujson/Value#toString().
+//                        ^^^^^^ reference ujson/Value#render().
+  def render(indent: Int = -1, escapeUnicode: Boolean = false) = this.transform(StringRenderer(indent, escapeUnicode)).toString
+//    ^^^^^^ definition ujson/Value#render().
+//           ^^^^^^ definition ujson/Value#render().(indent)
+//                   ^^^ reference scala/Int#
+//                             ^^^^^^^^^^^^^ definition ujson/Value#render().(escapeUnicode)
+//                                            ^^^^^^^ reference scala/Boolean#
+//                                                                    ^^^^^^^^^ reference ujson/Value#transform().
+//                                                                              ^^^^^^^^^^^^^^ reference ujson/StringRenderer.
+//                                                                                             ^^^^^^ reference ujson/Value#render().(indent)
+//                                                                                                     ^^^^^^^^^^^^^ reference ujson/Value#render().(escapeUnicode)
+//                                                                                                                     ^^^^^^^^ reference java/io/StringWriter#toString().
+
+  def writeBytesTo(out: java.io.OutputStream, indent: Int = -1, escapeUnicode: Boolean = false): Unit = {
+//    ^^^^^^^^^^^^ definition ujson/Value#writeBytesTo().
+//                 ^^^ definition ujson/Value#writeBytesTo().(out)
+//                      ^^^^ reference java/
+//                           ^^ reference java/io/
+//                              ^^^^^^^^^^^^ reference java/io/OutputStream#
+//                                            ^^^^^^ definition ujson/Value#writeBytesTo().(indent)
+//                                                    ^^^ reference scala/Int#
+//                                                              ^^^^^^^^^^^^^ definition ujson/Value#writeBytesTo().(escapeUnicode)
+//                                                                             ^^^^^^^ reference scala/Boolean#
+//                                                                                               ^^^^ reference scala/Unit#
+    this.transform(new ujson.BaseByteRenderer(out, indent, escapeUnicode))
+//       ^^^^^^^^^ reference ujson/Value#transform().
+//                     ^^^^^ reference ujson/
+//                           ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#
+//                                            reference ujson/BaseByteRenderer#`<init>`().
+//                                            ^^^ reference ujson/Value#writeBytesTo().(out)
+//                                                 ^^^^^^ reference ujson/Value#writeBytesTo().(indent)
+//                                                         ^^^^^^^^^^^^^ reference ujson/Value#writeBytesTo().(escapeUnicode)
+  }
+  def writeBytesTo(out: java.io.OutputStream): Unit = writeBytesTo(out, -1, false)
+//    ^^^^^^^^^^^^ definition ujson/Value#writeBytesTo(+1).
+//                 ^^^ definition ujson/Value#writeBytesTo(+1).(out)
+//                      ^^^^ reference java/
+//                           ^^ reference java/io/
+//                              ^^^^^^^^^^^^ reference java/io/OutputStream#
+//                                             ^^^^ reference scala/Unit#
+//                                                    ^^^^^^^^^^^^ reference ujson/Value#writeBytesTo().
+//                                                                 ^^^ reference ujson/Value#writeBytesTo(+1).(out)
+}
+
+/**
+* A very small, very simple JSON AST that uPickle uses as part of its
+* serialization process. A common standard between the Jawn AST (which
+* we don't use so we don't pull in the bulk of Spire) and the Javascript
+* JSON AST.
+*/
+object Value extends AstTransformer[Value]{
+//     ^^^^^ definition ujson/Value.
+//                   ^^^^^^^^^^^^^^ reference ujson/AstTransformer#
+//                                  ^^^^^ reference ujson/Value#
+//                                         reference java/lang/Object#`<init>`().
+  type Value = ujson.Value
+//     ^^^^^ definition ujson/Value.Value#
+//             ^^^^^ reference ujson/
+//                   ^^^^^ reference ujson/Value#
+  sealed trait Selector{
+//             ^^^^^^^^ definition ujson/Value.Selector#
+    def apply(x: Value): Value
+//      ^^^^^ definition ujson/Value.Selector#apply().
+//            ^ definition ujson/Value.Selector#apply().(x)
+//               ^^^^^ reference ujson/Value.Value#
+//                       ^^^^^ reference ujson/Value.Value#
+    def update(x: Value, y: Value): Unit
+//      ^^^^^^ definition ujson/Value.Selector#update().
+//             ^ definition ujson/Value.Selector#update().(x)
+//                ^^^^^ reference ujson/Value.Value#
+//                       ^ definition ujson/Value.Selector#update().(y)
+//                          ^^^^^ reference ujson/Value.Value#
+//                                  ^^^^ reference scala/Unit#
+  }
+  object Selector{
+//       ^^^^^^^^ definition ujson/Value.Selector.
+    implicit class IntSelector(i: Int) extends Selector{
+//                 ^^^^^^^^^^^ definition ujson/Value.Selector.IntSelector#
+//                             definition ujson/Value.Selector.IntSelector#`<init>`().
+//                             ^ definition ujson/Value.Selector.IntSelector#i.
+//                                ^^^ reference scala/Int#
+//                                             ^^^^^^^^ reference ujson/Value.Selector#
+//                                                      reference java/lang/Object#`<init>`().
+      def apply(x: Value): Value = x.arr(i)
+//        ^^^^^ definition ujson/Value.Selector.IntSelector#apply().
+//              ^ definition ujson/Value.Selector.IntSelector#apply().(x)
+//                 ^^^^^ reference ujson/Value.Value#
+//                         ^^^^^ reference ujson/Value.Value#
+//                                 ^ reference ujson/Value.Selector.IntSelector#apply().(x)
+//                                   ^^^ reference ujson/Value#arr().
+//                                       ^ reference ujson/Value.Selector.IntSelector#i.
+      def update(x: Value, y: Value) = x.arr(i) = y
+//        ^^^^^^ definition ujson/Value.Selector.IntSelector#update().
+//               ^ definition ujson/Value.Selector.IntSelector#update().(x)
+//                  ^^^^^ reference ujson/Value.Value#
+//                         ^ definition ujson/Value.Selector.IntSelector#update().(y)
+//                            ^^^^^ reference ujson/Value.Value#
+//                                     ^ reference ujson/Value.Selector.IntSelector#update().(x)
+//                                       ^^^ reference ujson/Value#arr().
+//                                           ^ reference ujson/Value.Selector.IntSelector#i.
+//                                                ^ reference ujson/Value.Selector.IntSelector#update().(y)
+    }
+    implicit class StringSelector(i: String) extends Selector{
+//                 ^^^^^^^^^^^^^^ definition ujson/Value.Selector.StringSelector#
+//                                definition ujson/Value.Selector.StringSelector#`<init>`().
+//                                ^ definition ujson/Value.Selector.StringSelector#i.
+//                                   ^^^^^^ reference scala/Predef.String#
+//                                                   ^^^^^^^^ reference ujson/Value.Selector#
+//                                                            reference java/lang/Object#`<init>`().
+      def apply(x: Value): Value = x.obj(i)
+//        ^^^^^ definition ujson/Value.Selector.StringSelector#apply().
+//              ^ definition ujson/Value.Selector.StringSelector#apply().(x)
+//                 ^^^^^ reference ujson/Value.Value#
+//                         ^^^^^ reference ujson/Value.Value#
+//                                 ^ reference ujson/Value.Selector.StringSelector#apply().(x)
+//                                   ^^^ reference ujson/Value#obj().
+//                                       ^ reference ujson/Value.Selector.StringSelector#i.
+      def update(x: Value, y: Value) = x.obj(i) = y
+//        ^^^^^^ definition ujson/Value.Selector.StringSelector#update().
+//               ^ definition ujson/Value.Selector.StringSelector#update().(x)
+//                  ^^^^^ reference ujson/Value.Value#
+//                         ^ definition ujson/Value.Selector.StringSelector#update().(y)
+//                            ^^^^^ reference ujson/Value.Value#
+//                                     ^ reference ujson/Value.Selector.StringSelector#update().(x)
+//                                       ^^^ reference ujson/Value#obj().
+//                                           ^ reference ujson/Value.Selector.StringSelector#i.
+//                                                ^ reference ujson/Value.Selector.StringSelector#update().(y)
+    }
+  }
+
+  @deprecated("use ujson.Str")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val Str = ujson.Str
+//    ^^^ definition ujson/Value.Str.
+//          ^^^^^ reference ujson/
+//                ^^^ reference ujson/Str.
+  @deprecated("use ujson.Str")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  type Str = ujson.Str
+//     ^^^ definition ujson/Value.Str#
+//           ^^^^^ reference ujson/
+//                 ^^^ reference ujson/Str#
+  @deprecated("use ujson.Obj")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val Obj = ujson.Obj
+//    ^^^ definition ujson/Value.Obj.
+//          ^^^^^ reference ujson/
+//                ^^^ reference ujson/Obj.
+  @deprecated("use ujson.Obj")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  type Obj = ujson.Obj
+//     ^^^ definition ujson/Value.Obj#
+//           ^^^^^ reference ujson/
+//                 ^^^ reference ujson/Obj#
+  @deprecated("use ujson.Arr")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val Arr = ujson.Arr
+//    ^^^ definition ujson/Value.Arr.
+//          ^^^^^ reference ujson/
+//                ^^^ reference ujson/Arr.
+  @deprecated("use ujson.Arr")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  type Arr = ujson.Arr
+//     ^^^ definition ujson/Value.Arr#
+//           ^^^^^ reference ujson/
+//                 ^^^ reference ujson/Arr#
+  @deprecated("use ujson.Num")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val Num = ujson.Num
+//    ^^^ definition ujson/Value.Num.
+//          ^^^^^ reference ujson/
+//                ^^^ reference ujson/Num.
+  @deprecated("use ujson.Num")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  type Num = ujson.Num
+//     ^^^ definition ujson/Value.Num#
+//           ^^^^^ reference ujson/
+//                 ^^^ reference ujson/Num#
+  @deprecated("use ujson.Bool")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val Bool = ujson.Bool
+//    ^^^^ definition ujson/Value.Bool.
+//           ^^^^^ reference ujson/
+//                 ^^^^ reference ujson/Bool.
+  @deprecated("use ujson.Bool")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  type Bool = ujson.Bool
+//     ^^^^ definition ujson/Value.Bool#
+//            ^^^^^ reference ujson/
+//                  ^^^^ reference ujson/Bool#
+  @deprecated("use ujson.True")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val True = ujson.True
+//    ^^^^ definition ujson/Value.True.
+//           ^^^^^ reference ujson/
+//                 ^^^^ reference ujson/True.
+  @deprecated("use ujson.False")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val False = ujson.False
+//    ^^^^^ definition ujson/Value.False.
+//            ^^^^^ reference ujson/
+//                  ^^^^^ reference ujson/False.
+  @deprecated("use ujson.Null")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val Null = ujson.Null
+//    ^^^^ definition ujson/Value.Null.
+//           ^^^^^ reference ujson/
+//                 ^^^^ reference ujson/Null.
+  implicit def JsonableSeq[T](items: TraversableOnce[T])
+//             ^^^^^^^^^^^ definition ujson/Value.JsonableSeq().
+//                         ^ definition ujson/Value.JsonableSeq().[T]
+//                            ^^^^^ definition ujson/Value.JsonableSeq().(items)
+//                                   ^^^^^^^^^^^^^^^ reference scala/package.TraversableOnce#
+//                                                   ^ reference ujson/Value.JsonableSeq().[T]
+                             (implicit f: T => Value): Arr = Arr.from(items.map(f))
+//                                     ^ definition ujson/Value.JsonableSeq().(f)
+//                                        ^ reference ujson/Value.JsonableSeq().[T]
+//                                             ^^^^^ reference ujson/Value.Value#
+//                                                     ^^^ reference ujson/Value.Arr#
+//                                                           ^^^ reference ujson/Value.Arr.
+//                                                               ^^^^ reference ujson/Arr.from().
+//                                                                    ^^^^^ reference ujson/Value.JsonableSeq().(items)
+//                                                                          ^^^ reference scala/collection/IterableOnceExtensionMethods#map().
+//                                                                              ^ reference ujson/Value.JsonableSeq().(f)
+  implicit def JsonableDict[T](items: TraversableOnce[(String, T)])
+//             ^^^^^^^^^^^^ definition ujson/Value.JsonableDict().
+//                          ^ definition ujson/Value.JsonableDict().[T]
+//                             ^^^^^ definition ujson/Value.JsonableDict().(items)
+//                                    ^^^^^^^^^^^^^^^ reference scala/package.TraversableOnce#
+//                                                     ^^^^^^ reference scala/Predef.String#
+//                                                             ^ reference ujson/Value.JsonableDict().[T]
+                              (implicit f: T => Value): Obj = Obj.from(items.map(x => (x._1, f(x._2))))
+//                                      ^ definition ujson/Value.JsonableDict().(f)
+//                                         ^ reference ujson/Value.JsonableDict().[T]
+//                                              ^^^^^ reference ujson/Value.Value#
+//                                                      ^^^ reference ujson/Value.Obj#
+//                                                            ^^^ reference ujson/Value.Obj.
+//                                                                ^^^^ reference ujson/Obj.from().
+//                                                                     ^^^^^ reference ujson/Value.JsonableDict().(items)
+//                                                                           ^^^ reference scala/collection/IterableOnceExtensionMethods#map().
+//                                                                               ^ definition local10
+//                                                                                     ^ reference local10
+//                                                                                       ^^ reference scala/Tuple2#_1.
+//                                                                                           ^ reference ujson/Value.JsonableDict().(f)
+//                                                                                             ^ reference local10
+//                                                                                               ^^ reference scala/Tuple2#_2.
+  implicit def JsonableBoolean(i: Boolean): Bool = if (i) ujson.True else ujson.False
+//             ^^^^^^^^^^^^^^^ definition ujson/Value.JsonableBoolean().
+//                             ^ definition ujson/Value.JsonableBoolean().(i)
+//                                ^^^^^^^ reference scala/Boolean#
+//                                          ^^^^ reference ujson/Value.Bool#
+//                                                     ^ reference ujson/Value.JsonableBoolean().(i)
+//                                                        ^^^^^ reference ujson/
+//                                                              ^^^^ reference ujson/True.
+//                                                                        ^^^^^ reference ujson/
+//                                                                              ^^^^^ reference ujson/False.
+  implicit def JsonableByte(i: Byte): Num = Num(i)
+//             ^^^^^^^^^^^^ definition ujson/Value.JsonableByte().
+//                          ^ definition ujson/Value.JsonableByte().(i)
+//                             ^^^^ reference scala/Byte#
+//                                    ^^^ reference ujson/Value.Num#
+//                                          ^^^ reference ujson/Value.Num.
+//                                              ^ reference scala/Byte#toDouble().
+  implicit def JsonableShort(i: Short): Num = Num(i)
+//             ^^^^^^^^^^^^^ definition ujson/Value.JsonableShort().
+//                           ^ definition ujson/Value.JsonableShort().(i)
+//                              ^^^^^ reference scala/Short#
+//                                      ^^^ reference ujson/Value.Num#
+//                                            ^^^ reference ujson/Value.Num.
+//                                                ^ reference scala/Short#toDouble().
+  implicit def JsonableInt(i: Int): Num = Num(i)
+//             ^^^^^^^^^^^ definition ujson/Value.JsonableInt().
+//                         ^ definition ujson/Value.JsonableInt().(i)
+//                            ^^^ reference scala/Int#
+//                                  ^^^ reference ujson/Value.Num#
+//                                        ^^^ reference ujson/Value.Num.
+//                                            ^ reference scala/Int#toDouble().
+  implicit def JsonableLong(i: Long): Str = Str(i.toString)
+//             ^^^^^^^^^^^^ definition ujson/Value.JsonableLong().
+//                          ^ definition ujson/Value.JsonableLong().(i)
+//                             ^^^^ reference scala/Long#
+//                                    ^^^ reference ujson/Value.Str#
+//                                          ^^^ reference ujson/Value.Str.
+//                                              ^ reference ujson/Value.JsonableLong().(i)
+//                                                ^^^^^^^^ reference scala/Any#toString().
+  implicit def JsonableFloat(i: Float): Num = Num(i)
+//             ^^^^^^^^^^^^^ definition ujson/Value.JsonableFloat().
+//                           ^ definition ujson/Value.JsonableFloat().(i)
+//                              ^^^^^ reference scala/Float#
+//                                      ^^^ reference ujson/Value.Num#
+//                                            ^^^ reference ujson/Value.Num.
+//                                                ^ reference scala/Float#toDouble().
+  implicit def JsonableDouble(i: Double): Num = Num(i)
+//             ^^^^^^^^^^^^^^ definition ujson/Value.JsonableDouble().
+//                            ^ definition ujson/Value.JsonableDouble().(i)
+//                               ^^^^^^ reference scala/Double#
+//                                        ^^^ reference ujson/Value.Num#
+//                                              ^^^ reference ujson/Value.Num.
+//                                                  ^ reference ujson/Value.JsonableDouble().(i)
+  implicit def JsonableNull(i: Null): Null.type = Null
+//             ^^^^^^^^^^^^ definition ujson/Value.JsonableNull().
+//                          ^ definition ujson/Value.JsonableNull().(i)
+//                             ^^^^ reference scala/Null#
+//                                    ^^^^ reference ujson/Value.Null.
+//                                                ^^^^ reference ujson/Value.Null.
+  implicit def JsonableString(s: CharSequence): Str = Str(s.toString)
+//             ^^^^^^^^^^^^^^ definition ujson/Value.JsonableString().
+//                            ^ definition ujson/Value.JsonableString().(s)
+//                               ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                              ^^^ reference ujson/Value.Str#
+//                                                    ^^^ reference ujson/Value.Str.
+//                                                        ^ reference ujson/Value.JsonableString().(s)
+//                                                          ^^^^^^^^ reference java/lang/Object#toString().
+
+
+  def transform[T](j: Value, f: Visitor[_, T]): T = {
+//    ^^^^^^^^^ definition ujson/Value.transform().
+//              ^ definition ujson/Value.transform().[T]
+//                 ^ definition ujson/Value.transform().(j)
+//                    ^^^^^ reference ujson/Value.Value#
+//                           ^ definition ujson/Value.transform().(f)
+//                              ^^^^^^^ reference upickle/core/Visitor#
+//                                         ^ reference ujson/Value.transform().[T]
+//                                              ^ reference ujson/Value.transform().[T]
+    j match{
+//  ^ reference ujson/Value.transform().(j)
+      case ujson.Null => f.visitNull(-1)
+//         ^^^^^ reference ujson/
+//               ^^^^ reference ujson/Null.
+//                       ^ reference ujson/Value.transform().(f)
+//                         ^^^^^^^^^ reference upickle/core/Visitor#visitNull().
+      case ujson.True => f.visitTrue(-1)
+//         ^^^^^ reference ujson/
+//               ^^^^ reference ujson/True.
+//                       ^ reference ujson/Value.transform().(f)
+//                         ^^^^^^^^^ reference upickle/core/Visitor#visitTrue().
+      case ujson.False => f.visitFalse(-1)
+//         ^^^^^ reference ujson/
+//               ^^^^^ reference ujson/False.
+//                        ^ reference ujson/Value.transform().(f)
+//                          ^^^^^^^^^^ reference upickle/core/Visitor#visitFalse().
+      case ujson.Str(s) => f.visitString(s, -1)
+//         ^^^^^ reference ujson/
+//               ^^^ reference ujson/Str.
+//                   ^ definition local11
+//                         ^ reference ujson/Value.transform().(f)
+//                           ^^^^^^^^^^^ reference upickle/core/Visitor#visitString().
+//                                       ^ reference local11
+      case ujson.Num(d) => f.visitFloat64(d, -1)
+//         ^^^^^ reference ujson/
+//               ^^^ reference ujson/Num.
+//                   ^ definition local12
+//                         ^ reference ujson/Value.transform().(f)
+//                           ^^^^^^^^^^^^ reference upickle/core/Visitor#visitFloat64().
+//                                        ^ reference local12
+      case ujson.Arr(items) => transformArray(f, items)
+//         ^^^^^ reference ujson/
+//               ^^^ reference ujson/Arr.
+//                   ^^^^^ definition local13
+//                             ^^^^^^^^^^^^^^ reference ujson/AstTransformer#transformArray().
+//                                            ^ reference ujson/Value.transform().(f)
+//                                               ^^^^^ reference local13
+      case ujson.Obj(items) => transformObject(f, items)
+//         ^^^^^ reference ujson/
+//               ^^^ reference ujson/Obj.
+//                   ^^^^^ definition local14
+//                             ^^^^^^^^^^^^^^^ reference ujson/AstTransformer#transformObject().
+//                                             ^ reference ujson/Value.transform().(f)
+//                                                ^^^^^ reference local14
+    }
+  }
+
+  def visitArray(length: Int, index: Int) = new AstArrVisitor[ArrayBuffer](xs => ujson.Arr(xs))
+//    ^^^^^^^^^^ definition ujson/Value.visitArray().
+//               ^^^^^^ definition ujson/Value.visitArray().(length)
+//                       ^^^ reference scala/Int#
+//                            ^^^^^ definition ujson/Value.visitArray().(index)
+//                                   ^^^ reference scala/Int#
+//                                              ^^^^^^^^^^^^^ reference ujson/AstTransformer#AstArrVisitor#
+//                                                            ^^^^^^^^^^^ reference scala/collection/mutable/ArrayBuffer#
+//                                                                         reference ujson/AstTransformer#AstArrVisitor#`<init>`().
+//                                                                         ^^ definition local15
+//                                                                               ^^^^^ reference ujson/
+//                                                                                     ^^^ reference ujson/Arr.
+//                                                                                         ^^ reference local15
+
+  def visitObject(length: Int, index: Int) = new AstObjVisitor[mutable.LinkedHashMap[String, Value]](xs => ujson.Obj(xs))
+//    ^^^^^^^^^^^ definition ujson/Value.visitObject().
+//                ^^^^^^ definition ujson/Value.visitObject().(length)
+//                        ^^^ reference scala/Int#
+//                             ^^^^^ definition ujson/Value.visitObject().(index)
+//                                    ^^^ reference scala/Int#
+//                                               ^^^^^^^^^^^^^ reference ujson/AstTransformer#AstObjVisitor#
+//                                                             ^^^^^^^ reference scala/collection/mutable/
+//                                                                     ^^^^^^^^^^^^^ reference scala/collection/mutable/LinkedHashMap#
+//                                                                                   ^^^^^^ reference scala/Predef.String#
+//                                                                                           ^^^^^ reference ujson/Value.Value#
+//                                                                                                   reference ujson/AstTransformer#AstObjVisitor#`<init>`().
+//                                                                                                   ^^ definition local16
+//                                                                                                         ^^^^^ reference ujson/
+//                                                                                                               ^^^ reference ujson/Obj.
+//                                                                                                                   ^^ reference local16
+
+  def visitNull(index: Int) = ujson.Null
+//    ^^^^^^^^^ definition ujson/Value.visitNull().
+//              ^^^^^ definition ujson/Value.visitNull().(index)
+//                     ^^^ reference scala/Int#
+//                            ^^^^^ reference ujson/
+//                                  ^^^^ reference ujson/Null.
+
+  def visitFalse(index: Int) = ujson.False
+//    ^^^^^^^^^^ definition ujson/Value.visitFalse().
+//               ^^^^^ definition ujson/Value.visitFalse().(index)
+//                      ^^^ reference scala/Int#
+//                             ^^^^^ reference ujson/
+//                                   ^^^^^ reference ujson/False.
+
+  def visitTrue(index: Int) = True
+//    ^^^^^^^^^ definition ujson/Value.visitTrue().
+//              ^^^^^ definition ujson/Value.visitTrue().(index)
+//                     ^^^ reference scala/Int#
+//                            ^^^^ reference ujson/Value.True.
+
+
+  override def visitFloat64StringParts(s: CharSequence, decIndex: Int, expIndex: Int, index: Int) = {
+//             ^^^^^^^^^^^^^^^^^^^^^^^ definition ujson/Value.visitFloat64StringParts().
+//                                     ^ definition ujson/Value.visitFloat64StringParts().(s)
+//                                        ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                                      ^^^^^^^^ definition ujson/Value.visitFloat64StringParts().(decIndex)
+//                                                                ^^^ reference scala/Int#
+//                                                                     ^^^^^^^^ definition ujson/Value.visitFloat64StringParts().(expIndex)
+//                                                                               ^^^ reference scala/Int#
+//                                                                                    ^^^^^ definition ujson/Value.visitFloat64StringParts().(index)
+//                                                                                           ^^^ reference scala/Int#
+    ujson.Num(
+//  ^^^^^ reference ujson/
+//        ^^^ reference ujson/Num.
+      if (decIndex != -1 || expIndex != -1) s.toString.toDouble
+//        ^^^^^^^^ reference ujson/Value.visitFloat64StringParts().(decIndex)
+//                 ^^ reference scala/Int#`!=`(+3).
+//                       ^^ reference scala/Boolean#`||`().
+//                          ^^^^^^^^ reference ujson/Value.visitFloat64StringParts().(expIndex)
+//                                   ^^ reference scala/Int#`!=`(+3).
+//                                          ^ reference ujson/Value.visitFloat64StringParts().(s)
+//                                            ^^^^^^^^ reference java/lang/Object#toString().
+//                                                     ^^^^^^^^ reference scala/collection/StringOps#toDouble().
+      else Util.parseIntegralNum(s, decIndex, expIndex, index)
+//         ^^^^ reference upickle/core/Util.
+//              ^^^^^^^^^^^^^^^^ reference upickle/core/Util.parseIntegralNum().
+//                               ^ reference ujson/Value.visitFloat64StringParts().(s)
+//                                  ^^^^^^^^ reference ujson/Value.visitFloat64StringParts().(decIndex)
+//                                            ^^^^^^^^ reference ujson/Value.visitFloat64StringParts().(expIndex)
+//                                                      ^^^^^ reference ujson/Value.visitFloat64StringParts().(index)
+    )
+  }
+
+  override def visitFloat64(d: Double, index: Int) = ujson.Num(d)
+//             ^^^^^^^^^^^^ definition ujson/Value.visitFloat64().
+//                          ^ definition ujson/Value.visitFloat64().(d)
+//                             ^^^^^^ reference scala/Double#
+//                                     ^^^^^ definition ujson/Value.visitFloat64().(index)
+//                                            ^^^ reference scala/Int#
+//                                                   ^^^^^ reference ujson/
+//                                                         ^^^ reference ujson/Num.
+//                                                             ^ reference ujson/Value.visitFloat64().(d)
+
+  def visitString(s: CharSequence, index: Int) = ujson.Str(s.toString)
+//    ^^^^^^^^^^^ definition ujson/Value.visitString().
+//                ^ definition ujson/Value.visitString().(s)
+//                   ^^^^^^^^^^^^ reference java/lang/CharSequence#
+//                                 ^^^^^ definition ujson/Value.visitString().(index)
+//                                        ^^^ reference scala/Int#
+//                                               ^^^^^ reference ujson/
+//                                                     ^^^ reference ujson/Str.
+//                                                         ^ reference ujson/Value.visitString().(s)
+//                                                           ^^^^^^^^ reference java/lang/Object#toString().
+
+  /**
+    * Thrown when uPickle tries to convert a JSON blob into a given data
+    * structure but fails because part the blob is invalid
+    *
+    * @param data The section of the JSON blob that uPickle tried to convert.
+    *             This could be the entire blob, or it could be some subtree.
+    * @param msg Human-readable text saying what went wrong
+    */
+  case class InvalidData(data: Value, msg: String)
+//           ^^^^^^^^^^^ definition ujson/Value.InvalidData#
+//                       definition ujson/Value.InvalidData#`<init>`().
+//                       ^^^^ definition ujson/Value.InvalidData#data.
+//                             ^^^^^ reference ujson/Value.Value#
+//                                    ^^^ definition ujson/Value.InvalidData#msg.
+//                                         ^^^^^^ reference scala/Predef.String#
+    extends Exception(s"$msg (data: $data)")
+//          ^^^^^^^^^ reference scala/package.Exception#
+//                    reference java/lang/Exception#`<init>`(+1).
+//                    ^ reference scala/StringContext#s().
+//                       ^^^ reference ujson/Value.InvalidData#`<init>`().(msg)
+//                                   ^^^^ reference ujson/Value.InvalidData#`<init>`().(data)
+}
+
+case class Str(value: String) extends Value
+//         ^^^ definition ujson/Str#
+//             definition ujson/Str#`<init>`().
+//             ^^^^^ definition ujson/Str#value.
+//                    ^^^^^^ reference scala/Predef.String#
+//                                    ^^^^^ reference ujson/Value#
+//                                          reference java/lang/Object#`<init>`().
+case class Obj(value: mutable.LinkedHashMap[String, Value]) extends Value
+//         ^^^ definition ujson/Obj#
+//             definition ujson/Obj#`<init>`().
+//             ^^^^^ definition ujson/Obj#value.
+//                    ^^^^^^^ reference scala/collection/mutable/
+//                            ^^^^^^^^^^^^^ reference scala/collection/mutable/LinkedHashMap#
+//                                          ^^^^^^ reference scala/Predef.String#
+//                                                  ^^^^^ reference ujson/Value#
+//                                                                  ^^^^^ reference ujson/Value#
+
+// reference java/lang/Object#`<init>`().
+object Obj{
+//     ^^^ definition ujson/Obj.
+  implicit def from(items: TraversableOnce[(String, Value)]): Obj = {
+//             ^^^^ definition ujson/Obj.from().
+//                  ^^^^^ definition ujson/Obj.from().(items)
+//                         ^^^^^^^^^^^^^^^ reference scala/package.TraversableOnce#
+//                                          ^^^^^^ reference scala/Predef.String#
+//                                                  ^^^^^ reference ujson/Value#
+//                                                            ^^^ reference ujson/Obj#
+    Obj(mutable.LinkedHashMap(items.toSeq:_*))
+//  ^^^ reference ujson/Obj.
+//      ^^^^^^^ reference scala/collection/mutable/
+//              ^^^^^^^^^^^^^ reference scala/collection/mutable/LinkedHashMap.
+//                            ^^^^^ reference ujson/Obj.from().(items)
+//                                  ^^^^^ reference scala/collection/IterableOnceExtensionMethods#toSeq().
+  }
+  // Weird telescoped version of `apply(items: (String, Value)*)`, to avoid
+  // type inference issues due to overloading the existing `apply` method
+  // generated by the case class itself
+  // https://github.com/lihaoyi/upickle/issues/230
+  def apply[V](item: (String, V),
+//    ^^^^^ definition ujson/Obj.apply().
+//          ^ definition ujson/Obj.apply().[V]
+//             ^^^^ definition ujson/Obj.apply().(item)
+//                    ^^^^^^ reference scala/Predef.String#
+//                            ^ reference ujson/Obj.apply().[V]
+                        items: (String, Value)*)(implicit conv: V => Value): Obj = {
+//                      ^^^^^ definition ujson/Obj.apply().(items)
+//                              ^^^^^^ reference scala/Predef.String#
+//                                      ^^^^^ reference ujson/Value#
+//                                                        ^^^^ definition ujson/Obj.apply().(conv)
+//                                                              ^ reference ujson/Obj.apply().[V]
+//                                                                   ^^^^^ reference ujson/Value#
+//                                                                           ^^^ reference ujson/Obj#
+    val map = new mutable.LinkedHashMap[String, Value]()
+//      ^^^ definition local17
+//                ^^^^^^^ reference scala/collection/mutable/
+//                        ^^^^^^^^^^^^^ reference scala/collection/mutable/LinkedHashMap#
+//                                      ^^^^^^ reference scala/Predef.String#
+//                                              ^^^^^ reference ujson/Value#
+//                                                     reference scala/collection/mutable/LinkedHashMap#`<init>`().
+    map.put(item._1, conv(item._2))
+//  ^^^ reference local17
+//      ^^^ reference scala/collection/mutable/LinkedHashMap#put().
+//          ^^^^ reference ujson/Obj.apply().(item)
+//               ^^ reference scala/Tuple2#_1.
+//                   ^^^^ reference ujson/Obj.apply().(conv)
+//                        ^^^^ reference ujson/Obj.apply().(item)
+//                             ^^ reference scala/Tuple2#_2.
+    for (i <- items) map.put(i._1, i._2)
+//       ^ definition local18
+//            ^^^^^ reference ujson/Obj.apply().(items)
+//                   ^^^ reference local17
+//                       ^^^ reference scala/collection/mutable/LinkedHashMap#put().
+//                           ^ reference local18
+//                             ^^ reference scala/Tuple2#_1.
+//                                 ^ reference local18
+//                                   ^^ reference scala/Tuple2#_2.
+    Obj(map)
+//  ^^^ reference ujson/Obj.
+//      ^^^ reference local17
+  }
+
+  def apply(): Obj = Obj(new mutable.LinkedHashMap[String, Value]())
+//    ^^^^^ definition ujson/Obj.apply(+1).
+//             ^^^ reference ujson/Obj#
+//                   ^^^ reference ujson/Obj.
+//                           ^^^^^^^ reference scala/collection/mutable/
+//                                   ^^^^^^^^^^^^^ reference scala/collection/mutable/LinkedHashMap#
+//                                                 ^^^^^^ reference scala/Predef.String#
+//                                                         ^^^^^ reference ujson/Value#
+//                                                                reference scala/collection/mutable/LinkedHashMap#`<init>`().
+}
+case class Arr(value: ArrayBuffer[Value]) extends Value
+//         ^^^ definition ujson/Arr#
+//             definition ujson/Arr#`<init>`().
+//             ^^^^^ definition ujson/Arr#value.
+//                    ^^^^^^^^^^^ reference scala/collection/mutable/ArrayBuffer#
+//                                ^^^^^ reference ujson/Value#
+//                                                ^^^^^ reference ujson/Value#
+
+// reference java/lang/Object#`<init>`().
+object Arr{
+//     ^^^ definition ujson/Arr.
+  implicit def from[T](items: TraversableOnce[T])(implicit conv: T => Value): Arr = {
+//             ^^^^ definition ujson/Arr.from().
+//                  ^ definition ujson/Arr.from().[T]
+//                     ^^^^^ definition ujson/Arr.from().(items)
+//                            ^^^^^^^^^^^^^^^ reference scala/package.TraversableOnce#
+//                                            ^ reference ujson/Arr.from().[T]
+//                                                         ^^^^ definition ujson/Arr.from().(conv)
+//                                                               ^ reference ujson/Arr.from().[T]
+//                                                                    ^^^^^ reference ujson/Value#
+//                                                                            ^^^ reference ujson/Arr#
+    val buf = new mutable.ArrayBuffer[Value]()
+//      ^^^ definition local19
+//                ^^^^^^^ reference scala/collection/mutable/
+//                        ^^^^^^^^^^^ reference scala/collection/mutable/ArrayBuffer#
+//                                    ^^^^^ reference ujson/Value#
+//                                           reference scala/collection/mutable/ArrayBuffer#`<init>`(+1).
+    items.foreach{ item =>
+//  ^^^^^ reference ujson/Arr.from().(items)
+//        ^^^^^^^ reference scala/collection/IterableOnceExtensionMethods#foreach().
+//                 ^^^^ definition local20
+      buf += (conv(item): Value)
+//    ^^^ reference local19
+//        ^^ reference scala/collection/mutable/Growable#`+=`().
+//            ^^^^ reference ujson/Arr.from().(conv)
+//                 ^^^^ reference local20
+//                        ^^^^^ reference ujson/Value#
+    }
+    Arr(buf)
+//  ^^^ reference ujson/Arr.
+//      ^^^ reference local19
+  }
+
+  def apply(items: Value*): Arr = {
+//    ^^^^^ definition ujson/Arr.apply().
+//          ^^^^^ definition ujson/Arr.apply().(items)
+//                 ^^^^^ reference ujson/Value#
+//                          ^^^ reference ujson/Arr#
+    val buf = new mutable.ArrayBuffer[Value](items.length)
+//      ^^^ definition local21
+//                ^^^^^^^ reference scala/collection/mutable/
+//                        ^^^^^^^^^^^ reference scala/collection/mutable/ArrayBuffer#
+//                                    ^^^^^ reference ujson/Value#
+//                                           reference scala/collection/mutable/ArrayBuffer#`<init>`(+2).
+//                                           ^^^^^ reference ujson/Arr.apply().(items)
+//                                                 ^^^^^^ reference scala/collection/SeqOps#length().
+    items.foreach{ item =>
+//  ^^^^^ reference ujson/Arr.apply().(items)
+//        ^^^^^^^ reference scala/collection/IterableOnceOps#foreach().
+//                 ^^^^ definition local22
+      buf += item
+//    ^^^ reference local21
+//        ^^ reference scala/collection/mutable/Growable#`+=`().
+//           ^^^^ reference local22
+    }
+    Arr(buf)
+//  ^^^ reference ujson/Arr.
+//      ^^^ reference local21
+  }
+}
+case class Num(value: Double) extends Value
+//         ^^^ definition ujson/Num#
+//             definition ujson/Num#`<init>`().
+//             ^^^^^ definition ujson/Num#value.
+//                    ^^^^^^ reference scala/Double#
+//                                    ^^^^^ reference ujson/Value#
+//                                          reference java/lang/Object#`<init>`().
+sealed abstract class Bool extends Value{
+//                    ^^^^ definition ujson/Bool#
+//                          definition ujson/Bool#`<init>`().
+//                                 ^^^^^ reference ujson/Value#
+//                                       reference java/lang/Object#`<init>`().
+  def value: Boolean
+//    ^^^^^ definition ujson/Bool#value().
+//           ^^^^^^^ reference scala/Boolean#
+}
+object Bool{
+//     ^^^^ definition ujson/Bool.
+  def apply(value: Boolean): Bool = if (value) True else False
+//    ^^^^^ definition ujson/Bool.apply().
+//          ^^^^^ definition ujson/Bool.apply().(value)
+//                 ^^^^^^^ reference scala/Boolean#
+//                           ^^^^ reference ujson/Bool#
+//                                      ^^^^^ reference ujson/Bool.apply().(value)
+//                                             ^^^^ reference ujson/True.
+//                                                       ^^^^^ reference ujson/False.
+  def unapply(bool: Bool): Option[Boolean] = Some(bool.value)
+//    ^^^^^^^ definition ujson/Bool.unapply().
+//            ^^^^ definition ujson/Bool.unapply().(bool)
+//                  ^^^^ reference ujson/Bool#
+//                         ^^^^^^ reference scala/Option#
+//                                ^^^^^^^ reference scala/Boolean#
+//                                           ^^^^ reference scala/Some.
+//                                                ^^^^ reference ujson/Bool.unapply().(bool)
+//                                                     ^^^^^ reference ujson/Bool#value().
+}
+case object False extends Bool{
+//          ^^^^^ definition ujson/False.
+//                        ^^^^ reference ujson/Bool#
+//                             reference ujson/Bool#`<init>`().
+  def value = false
+//    ^^^^^ definition ujson/False.value().
+}
+case object True extends Bool{
+//          ^^^^ definition ujson/True.
+//                       ^^^^ reference ujson/Bool#
+//                            reference ujson/Bool#`<init>`().
+  def value = true
+//    ^^^^^ definition ujson/True.value().
+}
+case object Null extends Value{
+//          ^^^^ definition ujson/Null.
+//                       ^^^^^ reference ujson/Value#
+//                             reference java/lang/Object#`<init>`().
+  def value = null
+//    ^^^^^ definition ujson/Null.value().
+}
diff --git a/tests/snapshots/src/main/generated/ujson/package.scala b/tests/snapshots/src/main/generated/ujson/package.scala
new file mode 100644
index 000000000..bec287a5b
--- /dev/null
+++ b/tests/snapshots/src/main/generated/ujson/package.scala
@@ -0,0 +1,302 @@
+import upickle.core.NoOpVisitor
+//     ^^^^^^^ reference upickle/
+//             ^^^^ reference upickle/core/
+//                  ^^^^^^^^^^^ reference upickle/core/NoOpVisitor.
+
+package object ujson{
+//             ^^^^^ definition ujson/package.
+  def transform[T](t: Readable, v: upickle.core.Visitor[_, T]) = t.transform(v)
+//    ^^^^^^^^^ definition ujson/package.transform().
+//              ^ definition ujson/package.transform().[T]
+//                 ^ definition ujson/package.transform().(t)
+//                    ^^^^^^^^ reference ujson/Readable#
+//                              ^ definition ujson/package.transform().(v)
+//                                 ^^^^^^^ reference upickle/
+//                                         ^^^^ reference upickle/core/
+//                                              ^^^^^^^ reference upickle/core/Visitor#
+//                                                         ^ reference ujson/package.transform().[T]
+//                                                               ^ reference ujson/package.transform().(t)
+//                                                                 ^^^^^^^^^ reference ujson/Readable#transform().
+//                                                                           ^ reference ujson/package.transform().(v)
+
+  /**
+    * Read the given JSON input as a JSON struct
+    */
+  def read(s: Readable, trace: Boolean = false): Value.Value =
+//    ^^^^ definition ujson/package.read().
+//         ^ definition ujson/package.read().(s)
+//            ^^^^^^^^ reference ujson/Readable#
+//                      ^^^^^ definition ujson/package.read().(trace)
+//                             ^^^^^^^ reference scala/Boolean#
+//                                               ^^^^^ reference ujson/Value.
+//                                                     ^^^^^ reference ujson/Value.Value#
+    upickle.core.TraceVisitor.withTrace(trace, Value)(transform(s, _))
+//  ^^^^^^^ reference upickle/
+//          ^^^^ reference upickle/core/
+//               ^^^^^^^^^^^^ reference upickle/core/TraceVisitor.
+//                            ^^^^^^^^^ reference upickle/core/TraceVisitor.withTrace().
+//                                      ^^^^^ reference ujson/package.read().(trace)
+//                                             ^^^^^ reference ujson/Value.
+//                                                    ^^^^^^^^^ reference ujson/package.transform().
+//                                                              ^ reference ujson/package.read().(s)
+
+  def copy(t: Value.Value): Value.Value = transform(t, Value)
+//    ^^^^ definition ujson/package.copy().
+//         ^ definition ujson/package.copy().(t)
+//            ^^^^^ reference ujson/Value.
+//                  ^^^^^ reference ujson/Value.Value#
+//                          ^^^^^ reference ujson/Value.
+//                                ^^^^^ reference ujson/Value.Value#
+//                                        ^^^^^^^^^ reference ujson/package.transform().
+//                                                  ^ reference ujson/package.copy().(t)
+//                                                     ^^^^^ reference ujson/Value.
+
+  /**
+    * Write the given JSON struct as a JSON String
+    */
+  def write(t: Value.Value,
+//    ^^^^^ definition ujson/package.write().
+//          ^ definition ujson/package.write().(t)
+//             ^^^^^ reference ujson/Value.
+//                   ^^^^^ reference ujson/Value.Value#
+            indent: Int = -1,
+//          ^^^^^^ definition ujson/package.write().(indent)
+//                  ^^^ reference scala/Int#
+            escapeUnicode: Boolean = false): String = {
+//          ^^^^^^^^^^^^^ definition ujson/package.write().(escapeUnicode)
+//                         ^^^^^^^ reference scala/Boolean#
+//                                           ^^^^^^ reference scala/Predef.String#
+    val writer = new java.io.StringWriter
+//      ^^^^^^ definition local0
+//                   ^^^^ reference java/
+//                        ^^ reference java/io/
+//                           ^^^^^^^^^^^^ reference java/io/StringWriter#
+//                                        reference java/io/StringWriter#`<init>`().
+    writeTo(t, writer, indent, escapeUnicode)
+//  ^^^^^^^ reference ujson/package.writeTo().
+//          ^ reference ujson/package.write().(t)
+//             ^^^^^^ reference local0
+//                     ^^^^^^ reference ujson/package.write().(indent)
+//                             ^^^^^^^^^^^^^ reference ujson/package.write().(escapeUnicode)
+    writer.toString
+//  ^^^^^^ reference local0
+//         ^^^^^^^^ reference java/io/StringWriter#toString().
+  }
+
+  /**
+    * Write the given JSON struct as a JSON String to the given Writer
+    */
+  def writeTo(t: Value.Value,
+//    ^^^^^^^ definition ujson/package.writeTo().
+//            ^ definition ujson/package.writeTo().(t)
+//               ^^^^^ reference ujson/Value.
+//                     ^^^^^ reference ujson/Value.Value#
+              out: java.io.Writer,
+//            ^^^ definition ujson/package.writeTo().(out)
+//                 ^^^^ reference java/
+//                      ^^ reference java/io/
+//                         ^^^^^^ reference java/io/Writer#
+              indent: Int = -1,
+//            ^^^^^^ definition ujson/package.writeTo().(indent)
+//                    ^^^ reference scala/Int#
+              escapeUnicode: Boolean = false): Unit = {
+//            ^^^^^^^^^^^^^ definition ujson/package.writeTo().(escapeUnicode)
+//                           ^^^^^^^ reference scala/Boolean#
+//                                             ^^^^ reference scala/Unit#
+    transform(t, Renderer(out, indent, escapeUnicode))
+//  ^^^^^^^^^ reference ujson/package.transform().
+//            ^ reference ujson/package.writeTo().(t)
+//               ^^^^^^^^ reference ujson/Renderer.
+//                        ^^^ reference ujson/package.writeTo().(out)
+//                             ^^^^^^ reference ujson/package.writeTo().(indent)
+//                                     ^^^^^^^^^^^^^ reference ujson/package.writeTo().(escapeUnicode)
+  }
+  def writeToOutputStream(t: Value.Value,
+//    ^^^^^^^^^^^^^^^^^^^ definition ujson/package.writeToOutputStream().
+//                        ^ definition ujson/package.writeToOutputStream().(t)
+//                           ^^^^^ reference ujson/Value.
+//                                 ^^^^^ reference ujson/Value.Value#
+                          out: java.io.OutputStream,
+//                        ^^^ definition ujson/package.writeToOutputStream().(out)
+//                             ^^^^ reference java/
+//                                  ^^ reference java/io/
+//                                     ^^^^^^^^^^^^ reference java/io/OutputStream#
+                          indent: Int = -1,
+//                        ^^^^^^ definition ujson/package.writeToOutputStream().(indent)
+//                                ^^^ reference scala/Int#
+                          escapeUnicode: Boolean = false): Unit = {
+//                        ^^^^^^^^^^^^^ definition ujson/package.writeToOutputStream().(escapeUnicode)
+//                                       ^^^^^^^ reference scala/Boolean#
+//                                                         ^^^^ reference scala/Unit#
+    transform(t, new BaseByteRenderer(out, indent, escapeUnicode))
+//  ^^^^^^^^^ reference ujson/package.transform().
+//            ^ reference ujson/package.writeToOutputStream().(t)
+//                   ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#
+//                                    reference ujson/BaseByteRenderer#`<init>`().
+//                                    ^^^ reference ujson/package.writeToOutputStream().(out)
+//                                         ^^^^^^ reference ujson/package.writeToOutputStream().(indent)
+//                                                 ^^^^^^^^^^^^^ reference ujson/package.writeToOutputStream().(escapeUnicode)
+  }
+
+  def writeToByteArray(t: Value.Value,
+//    ^^^^^^^^^^^^^^^^ definition ujson/package.writeToByteArray().
+//                     ^ definition ujson/package.writeToByteArray().(t)
+//                        ^^^^^ reference ujson/Value.
+//                              ^^^^^ reference ujson/Value.Value#
+                       indent: Int = -1,
+//                     ^^^^^^ definition ujson/package.writeToByteArray().(indent)
+//                             ^^^ reference scala/Int#
+                       escapeUnicode: Boolean = false) = {
+//                     ^^^^^^^^^^^^^ definition ujson/package.writeToByteArray().(escapeUnicode)
+//                                    ^^^^^^^ reference scala/Boolean#
+    val baos = new java.io.ByteArrayOutputStream
+//      ^^^^ definition local1
+//                 ^^^^ reference java/
+//                      ^^ reference java/io/
+//                         ^^^^^^^^^^^^^^^^^^^^^ reference java/io/ByteArrayOutputStream#
+//                                               reference java/io/ByteArrayOutputStream#`<init>`().
+    writeToOutputStream(t, baos, indent, escapeUnicode)
+//  ^^^^^^^^^^^^^^^^^^^ reference ujson/package.writeToOutputStream().
+//                      ^ reference ujson/package.writeToByteArray().(t)
+//                         ^^^^ reference local1
+//                               ^^^^^^ reference ujson/package.writeToByteArray().(indent)
+//                                       ^^^^^^^^^^^^^ reference ujson/package.writeToByteArray().(escapeUnicode)
+    baos.toByteArray
+//  ^^^^ reference local1
+//       ^^^^^^^^^^^ reference java/io/ByteArrayOutputStream#toByteArray().
+  }
+
+  /**
+    * Parse the given JSON input, failing if it is invalid
+    */
+  def validate(s: Readable): Unit = transform(s, NoOpVisitor)
+//    ^^^^^^^^ definition ujson/package.validate().
+//             ^ definition ujson/package.validate().(s)
+//                ^^^^^^^^ reference ujson/Readable#
+//                           ^^^^ reference scala/Unit#
+//                                  ^^^^^^^^^ reference ujson/package.transform().
+//                                            ^ reference ujson/package.validate().(s)
+//                                               ^^^^^^^^^^^ reference upickle/core/NoOpVisitor.
+  /**
+    * Parse the given JSON input and write it to a string with
+    * the configured formatting
+    */
+  def reformat(s: Readable, indent: Int = -1, escapeUnicode: Boolean = false): String = {
+//    ^^^^^^^^ definition ujson/package.reformat().
+//             ^ definition ujson/package.reformat().(s)
+//                ^^^^^^^^ reference ujson/Readable#
+//                          ^^^^^^ definition ujson/package.reformat().(indent)
+//                                  ^^^ reference scala/Int#
+//                                            ^^^^^^^^^^^^^ definition ujson/package.reformat().(escapeUnicode)
+//                                                           ^^^^^^^ reference scala/Boolean#
+//                                                                             ^^^^^^ reference scala/Predef.String#
+    val writer = new java.io.StringWriter()
+//      ^^^^^^ definition local2
+//                   ^^^^ reference java/
+//                        ^^ reference java/io/
+//                           ^^^^^^^^^^^^ reference java/io/StringWriter#
+//                                        reference java/io/StringWriter#`<init>`().
+    reformatTo(s, writer, indent, escapeUnicode)
+//  ^^^^^^^^^^ reference ujson/package.reformatTo().
+//             ^ reference ujson/package.reformat().(s)
+//                ^^^^^^ reference local2
+//                        ^^^^^^ reference ujson/package.reformat().(indent)
+//                                ^^^^^^^^^^^^^ reference ujson/package.reformat().(escapeUnicode)
+    writer.toString
+//  ^^^^^^ reference local2
+//         ^^^^^^^^ reference java/io/StringWriter#toString().
+  }
+  /**
+    * Parse the given JSON input and write it to a string with
+    * the configured formatting to the given Writer
+    */
+  def reformatTo(s: Readable, out: java.io.Writer, indent: Int = -1, escapeUnicode: Boolean = false): Unit = {
+//    ^^^^^^^^^^ definition ujson/package.reformatTo().
+//               ^ definition ujson/package.reformatTo().(s)
+//                  ^^^^^^^^ reference ujson/Readable#
+//                            ^^^ definition ujson/package.reformatTo().(out)
+//                                 ^^^^ reference java/
+//                                      ^^ reference java/io/
+//                                         ^^^^^^ reference java/io/Writer#
+//                                                 ^^^^^^ definition ujson/package.reformatTo().(indent)
+//                                                         ^^^ reference scala/Int#
+//                                                                   ^^^^^^^^^^^^^ definition ujson/package.reformatTo().(escapeUnicode)
+//                                                                                  ^^^^^^^ reference scala/Boolean#
+//                                                                                                    ^^^^ reference scala/Unit#
+    transform(s, Renderer(out, indent, escapeUnicode))
+//  ^^^^^^^^^ reference ujson/package.transform().
+//            ^ reference ujson/package.reformatTo().(s)
+//               ^^^^^^^^ reference ujson/Renderer.
+//                        ^^^ reference ujson/package.reformatTo().(out)
+//                             ^^^^^^ reference ujson/package.reformatTo().(indent)
+//                                     ^^^^^^^^^^^^^ reference ujson/package.reformatTo().(escapeUnicode)
+  }
+  /**
+    * Parse the given JSON input and write it to a string with
+    * the configured formatting to the given Writer
+    */
+  def reformatToOutputStream(s: Readable,
+//    ^^^^^^^^^^^^^^^^^^^^^^ definition ujson/package.reformatToOutputStream().
+//                           ^ definition ujson/package.reformatToOutputStream().(s)
+//                              ^^^^^^^^ reference ujson/Readable#
+                             out: java.io.OutputStream,
+//                           ^^^ definition ujson/package.reformatToOutputStream().(out)
+//                                ^^^^ reference java/
+//                                     ^^ reference java/io/
+//                                        ^^^^^^^^^^^^ reference java/io/OutputStream#
+                             indent: Int = -1,
+//                           ^^^^^^ definition ujson/package.reformatToOutputStream().(indent)
+//                                   ^^^ reference scala/Int#
+                             escapeUnicode: Boolean = false): Unit = {
+//                           ^^^^^^^^^^^^^ definition ujson/package.reformatToOutputStream().(escapeUnicode)
+//                                          ^^^^^^^ reference scala/Boolean#
+//                                                            ^^^^ reference scala/Unit#
+    transform(s, new BaseByteRenderer(out, indent, escapeUnicode))
+//  ^^^^^^^^^ reference ujson/package.transform().
+//            ^ reference ujson/package.reformatToOutputStream().(s)
+//                   ^^^^^^^^^^^^^^^^ reference ujson/BaseByteRenderer#
+//                                    reference ujson/BaseByteRenderer#`<init>`().
+//                                    ^^^ reference ujson/package.reformatToOutputStream().(out)
+//                                         ^^^^^^ reference ujson/package.reformatToOutputStream().(indent)
+//                                                 ^^^^^^^^^^^^^ reference ujson/package.reformatToOutputStream().(escapeUnicode)
+  }
+  def reformatToByteArray(s: Readable,
+//    ^^^^^^^^^^^^^^^^^^^ definition ujson/package.reformatToByteArray().
+//                        ^ definition ujson/package.reformatToByteArray().(s)
+//                           ^^^^^^^^ reference ujson/Readable#
+                          indent: Int = -1,
+//                        ^^^^^^ definition ujson/package.reformatToByteArray().(indent)
+//                                ^^^ reference scala/Int#
+                          escapeUnicode: Boolean = false) = {
+//                        ^^^^^^^^^^^^^ definition ujson/package.reformatToByteArray().(escapeUnicode)
+//                                       ^^^^^^^ reference scala/Boolean#
+    val baos = new java.io.ByteArrayOutputStream
+//      ^^^^ definition local3
+//                 ^^^^ reference java/
+//                      ^^ reference java/io/
+//                         ^^^^^^^^^^^^^^^^^^^^^ reference java/io/ByteArrayOutputStream#
+//                                               reference java/io/ByteArrayOutputStream#`<init>`().
+    reformatToOutputStream(s, baos, indent, escapeUnicode)
+//  ^^^^^^^^^^^^^^^^^^^^^^ reference ujson/package.reformatToOutputStream().
+//                         ^ reference ujson/package.reformatToByteArray().(s)
+//                            ^^^^ reference local3
+//                                  ^^^^^^ reference ujson/package.reformatToByteArray().(indent)
+//                                          ^^^^^^^^^^^^^ reference ujson/package.reformatToByteArray().(escapeUnicode)
+    baos.toByteArray
+//  ^^^^ reference local3
+//       ^^^^^^^^^^^ reference java/io/ByteArrayOutputStream#toByteArray().
+  }
+  // End ujson
+  @deprecated("use ujson.Value")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  type Js = Value
+//     ^^ definition ujson/package.Js#
+//          ^^^^^ reference ujson/Value#
+  @deprecated("use ujson.Value")
+// ^^^^^^^^^^ reference scala/deprecated#
+//            reference scala/deprecated#`<init>`().
+  val Js = Value
+//    ^^ definition ujson/package.Js.
+//         ^^^^^ reference ujson/Value.
+}
diff --git a/tests/snapshots/src/main/scala/tests/LibrarySnapshotGenerator.scala b/tests/snapshots/src/main/scala/tests/LibrarySnapshotGenerator.scala
index 9678d59bd..df7c0881c 100644
--- a/tests/snapshots/src/main/scala/tests/LibrarySnapshotGenerator.scala
+++ b/tests/snapshots/src/main/scala/tests/LibrarySnapshotGenerator.scala
@@ -6,6 +6,8 @@ import java.nio.file.Files
 import java.nio.file.Path
 import java.util.concurrent.atomic.AtomicInteger
 
+import scala.util.Properties
+
 import scala.meta.inputs.Input
 import scala.meta.internal.io.FileIO
 import scala.meta.io.AbsolutePath
@@ -15,6 +17,7 @@ import com.sourcegraph.lsif_java.Dependencies
 import com.sourcegraph.lsif_java.SemanticdbPrinters
 
 class LibrarySnapshotGenerator extends SnapshotGenerator {
+  val scalaPattern = FileSystems.getDefault.getPathMatcher("glob:**.scala")
   val javaPattern = FileSystems.getDefault.getPathMatcher("glob:**.java")
   private case class IndexMetrics(occurrenceCount: Int, linesOfCode: Int)
 
@@ -24,6 +27,13 @@ class LibrarySnapshotGenerator extends SnapshotGenerator {
       "com.airbnb.android:epoxy:4.3.1",
       isIncluded = jar => jar.contains("epoxy")
     )
+    gen.checkLibrary(
+      "com.lihaoyi:ujson_2.13:1.4.0",
+      provided = List(
+        s"org.scala-lang:scala-library:${Properties.versionNumberString}"
+      ),
+      isIncluded = jar => jar.contains("ujson")
+    )
   }
   private class Gen(context: SnapshotContext, handler: SnapshotHandler) {
     def checkLibrary(
@@ -32,12 +42,17 @@ class LibrarySnapshotGenerator extends SnapshotGenerator {
         isIncluded: String => Boolean = _ => true
     ): Unit = {
       println(s"indexing library '$name'")
-      val deps = Dependencies.resolveDependencies(name :: provided.toList)
-      val options = List("-Xlint:none")
+      val deps = Dependencies.resolveDependencies(name :: provided)
       val counter = new AtomicInteger()
       val targetroot = Files.createTempDirectory("semanticdb-javac")
 
-      val compiler = new TestCompiler(deps.classpathSyntax, options, targetroot)
+      val compiler =
+        new TestCompiler(
+          deps.classpathSyntax,
+          javacOptions = List("-Xlint:none"),
+          scalacOptions = Nil,
+          targetroot
+        )
       val timer = new Timer()
       val toIndex = deps.sources.filter(p => isIncluded(p.getFileName.toString))
       toIndex.foreach { source =>
@@ -64,7 +79,10 @@ class LibrarySnapshotGenerator extends SnapshotGenerator {
               FileIO
                 .listAllFilesRecursively(root)
                 .iterator
-                .filter(file => javaPattern.matches(file.toNIO))
+                .filter(file =>
+                  javaPattern.matches(file.toNIO) ||
+                    scalaPattern.matches(file.toNIO)
+                )
                 .map { file =>
                   val relpath = file.toRelative(root).toString()
                   val text = FileIO.slurp(file, StandardCharsets.UTF_8)
diff --git a/tests/snapshots/src/main/scala/tests/LsifGraphSnapshotGenerator.scala b/tests/snapshots/src/main/scala/tests/LsifGraphSnapshotGenerator.scala
index 12f7fa167..47e7d249c 100644
--- a/tests/snapshots/src/main/scala/tests/LsifGraphSnapshotGenerator.scala
+++ b/tests/snapshots/src/main/scala/tests/LsifGraphSnapshotGenerator.scala
@@ -112,7 +112,8 @@ class LsifGraphSnapshotGenerator extends SnapshotGenerator {
           val compiler =
             new TestCompiler(
               TestCompiler.PROCESSOR_PATH,
-              Nil,
+              javacOptions = Nil,
+              scalacOptions = Nil,
               targetroot,
               sourceroot
             )
diff --git a/tests/unit/src/main/scala/tests/CompileResult.scala b/tests/unit/src/main/scala/tests/CompileResult.scala
index f40861bb4..108cbf130 100644
--- a/tests/unit/src/main/scala/tests/CompileResult.scala
+++ b/tests/unit/src/main/scala/tests/CompileResult.scala
@@ -11,4 +11,26 @@ case class CompileResult(
   def textDocument: Semanticdb.TextDocument = {
     textDocuments.getDocuments(0)
   }
+
+  def merge(other: CompileResult): CompileResult = {
+    copy(
+      byteCode = this.byteCode ++ other.byteCode,
+      stdout = this.stdout ++ other.stdout,
+      textDocuments = this
+        .textDocuments
+        .toBuilder
+        .addAllDocuments(other.textDocuments.getDocumentsList)
+        .build(),
+      isSuccess = this.isSuccess && other.isSuccess
+    )
+  }
+}
+
+object CompileResult {
+  val empty: CompileResult = CompileResult(
+    Array.emptyByteArray,
+    "",
+    Semanticdb.TextDocuments.getDefaultInstance,
+    isSuccess = true
+  )
 }
diff --git a/tests/unit/src/main/scala/tests/TestCompiler.scala b/tests/unit/src/main/scala/tests/TestCompiler.scala
index 40287137b..2fcf0fbbf 100644
--- a/tests/unit/src/main/scala/tests/TestCompiler.scala
+++ b/tests/unit/src/main/scala/tests/TestCompiler.scala
@@ -1,9 +1,11 @@
 package tests
 
 import java.io.StringWriter
+import java.net.URI
 import java.nio.charset.StandardCharsets
 import java.nio.file.Files
 import java.nio.file.Path
+import java.util.ServiceLoader
 import javax.tools.ToolProvider
 
 import scala.collection.mutable.ListBuffer
@@ -12,8 +14,12 @@ import scala.jdk.CollectionConverters._
 import scala.meta.Input
 import scala.meta.internal.io.FileIO
 import scala.meta.io.AbsolutePath
+import scala.meta.io.Classpath
+import scala.meta.pc.PresentationCompiler
 
 import com.sourcegraph.semanticdb_javac.Semanticdb
+import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocument
+import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocuments
 
 object TestCompiler {
   val PROCESSOR_PATH = System.getProperty("java.class.path")
@@ -21,7 +27,8 @@ object TestCompiler {
 
 class TestCompiler(
     val classpath: String,
-    val options: List[String],
+    val javacOptions: List[String],
+    val scalacOptions: List[String],
     val targetroot: Path,
     val sourceroot: Path = Files.createTempDirectory("semanticdb-javac")
 ) {
@@ -34,7 +41,7 @@ class TestCompiler(
     )
 
   def this(targetroot: Path) {
-    this(TestCompiler.PROCESSOR_PATH, Nil, targetroot)
+    this(TestCompiler.PROCESSOR_PATH, Nil, Nil, targetroot)
   }
 
   def compileSemanticdbDirectory(dir: Path): CompileResult = {
@@ -56,7 +63,58 @@ class TestCompiler(
 
   def compile(
       inputs: Seq[Input.VirtualFile],
-      extraArguments: Seq[String] = Nil
+      extraJavacOptions: Seq[String] = Nil,
+      extraScalacOptions: Seq[String] = Nil
+  ): CompileResult = {
+    val javacInputs = inputs.filter(_.path.endsWith(".java"))
+    val scalacInputs = inputs.filter(_.path.endsWith(".scala"))
+    val results = ListBuffer.empty[CompileResult]
+    if (javacInputs.nonEmpty) {
+      results += compileJavac(javacInputs, extraJavacOptions)
+    } else if (scalacInputs.nonEmpty) {
+      results += compileScalac(scalacInputs, extraScalacOptions)
+    }
+    results.foldLeft(CompileResult.empty)(_ merge _)
+  }
+
+  private def compileScalac(
+      inputs: Seq[Input.VirtualFile],
+      extraScalacOptions: Seq[String]
+  ): CompileResult = {
+    val List(compiler) =
+      ServiceLoader
+        .load(classOf[PresentationCompiler])
+        .iterator()
+        .asScala
+        .toList
+    val compilerWithClasspath = compiler.newInstance(
+      "file://lsif-java",
+      Classpath(classpath).entries.map(_.toNIO).asJava,
+      (scalacOptions ++ extraScalacOptions).asJava
+    )
+    val textDocuments =
+      try {
+        inputs.map { input =>
+          val uri = URI.create(s"file:///${input.path}")
+          val bytes = compilerWithClasspath
+            .semanticdbTextDocument(uri, input.text)
+            .get()
+          TextDocument.parseFrom(bytes).toBuilder.setUri(input.path).build
+        }
+      } finally {
+        compilerWithClasspath.shutdown()
+      }
+    CompileResult(
+      Array.emptyByteArray,
+      "",
+      TextDocuments.newBuilder().addAllDocuments(textDocuments.asJava).build(),
+      isSuccess = true
+    )
+  }
+
+  private def compileJavac(
+      inputs: Seq[Input.VirtualFile],
+      extraJavacOptions: Seq[String]
   ): CompileResult = {
     val output = new StringWriter
     val compilationUnits = inputs.map { input =>
@@ -68,8 +126,8 @@ class TestCompiler(
     arguments += TestCompiler.PROCESSOR_PATH
     arguments += "-classpath"
     arguments += classpath
-    arguments ++= extraArguments
-    arguments ++= options
+    arguments ++= extraJavacOptions
+    arguments ++= javacOptions
     val task = compiler.getTask(
       output,
       fileManager,
diff --git a/tests/unit/src/test/scala/tests/JavacClassesDirectorySuite.scala b/tests/unit/src/test/scala/tests/JavacClassesDirectorySuite.scala
index 6a3b72fd3..3038d0a7b 100644
--- a/tests/unit/src/test/scala/tests/JavacClassesDirectorySuite.scala
+++ b/tests/unit/src/test/scala/tests/JavacClassesDirectorySuite.scala
@@ -17,7 +17,8 @@ class JavacClassesDirectorySuite extends FunSuite with TempDirectories {
     val compiler =
       new TestCompiler(
         classpath = TestCompiler.PROCESSOR_PATH,
-        options = Nil,
+        javacOptions = Nil,
+        scalacOptions = Nil,
         targetroot = sourceroot(),
         sourceroot = sourceroot()
       )
diff --git a/tests/unit/src/test/scala/tests/ScalaVersionSuite.scala b/tests/unit/src/test/scala/tests/ScalaVersionSuite.scala
new file mode 100644
index 000000000..8dd707aba
--- /dev/null
+++ b/tests/unit/src/test/scala/tests/ScalaVersionSuite.scala
@@ -0,0 +1,38 @@
+package tests
+
+import java.nio.file.Paths
+
+import com.sourcegraph.lsif_java.buildtools.ScalaVersion
+import com.sourcegraph.lsif_java.{BuildInfo => V}
+import munit.FunSuite
+import munit.TestOptions
+
+class ScalaVersionSuite extends FunSuite {
+  def checkNone(original: TestOptions): Unit = {
+    test(original) {
+      assertEquals(ScalaVersion.inferFromJar(Paths.get(original.name)), None)
+    }
+  }
+  def check(original: TestOptions, expected: String): Unit = {
+    test(original) {
+      val Some(obtained) = ScalaVersion.inferFromJar(Paths.get(original.name))
+      assertNoDiff(obtained, expected)
+    }
+  }
+
+  checkNone("junit-4.13.2")
+  checkNone("scala-library-2.10.1.jar")
+  check("scala-library-2.11.1.jar", V.scala211)
+  check("scala-library-2.12.1.jar", V.scala212)
+  check("scala-compiler-2.13.1.jar", V.scala213)
+  check("scala-reflect-2.13.1.jar", V.scala213)
+  check("scala-library-2.13.1.jar", V.scala213)
+  check("scalap-2.13.1.jar", V.scala213)
+  checkNone("scala-library-2.14.1.jar")
+
+  check("geny_2.11-0.10.5.jar", V.scala211)
+  check("geny_2.12-0.10.5.jar", V.scala212)
+  check("geny_2.13-0.10.5.jar", V.scala213)
+  check("geny_3-0.10.5.jar", V.scala3)
+
+}
