Merge branch 'stable-3.7' into stable-3.8

* stable-3.7:
  Use orNull instead of explicit null default
  Fix IterableOnce foreach deprecation warning
  Fix array splat deprecation warning
  Fix .toStream deprecation warning
  Fix deprecated `l` for Longs
  Remove use of deprecated JavaConverters class
  Fix TraversableOnce deprecation warnings
  Fix procedure syntax deprecation warnings
  Fix reflective structural type access warning
  Fix unable to check type warnings
  Fix override without parameter list warning
  Update Scala to 2.13.10
  Bump scalatest to 3.2.16
  Fix feature warnings
  Bump sbt to 1.8.3
  Add gitignore entries
  Set Gerrit API to v3.7.0-rc3
  Set Gerrit to v3.6.0-rc0

Change-Id: I3d5b19db244e9a15e4372b257c6ea2764271d150
diff --git a/.gitignore b/.gitignore
index f81b8e9..da80ec3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,5 +2,8 @@
 .project
 .classpath
 .settings/
+.vscode
+.bsp
 target/
 /bin/
+/project/project
diff --git a/build.sbt b/build.sbt
index 1c2f7be..5203e12 100644
--- a/build.sbt
+++ b/build.sbt
@@ -8,13 +8,15 @@
 
 concurrentRestrictions in Global += Tags.limit(Tags.Test, 1)
 
+ThisBuild / scalacOptions ++= Seq("-deprecation", "-feature")
+
 lazy val root = (project in file("."))
   .settings(
     name := pluginName,
     resolvers += Resolver.mavenLocal,
     version := gerritApiVersion,
 
-    scalaVersion := "2.11.12",
+    scalaVersion := "2.13.10",
 
     libraryDependencies ++= Seq(
       "io.fabric8" % "gitective-core" % "0.9.54"
@@ -28,12 +30,12 @@
 
       "com.google.gerrit" % "gerrit-acceptance-framework" % gerritApiVersion % Test,
       "org.bouncycastle" % "bcpg-jdk15on" % "1.61" % Test,
-      "org.scalatest" %% "scalatest" % "3.0.1" % Test,
+      "org.scalatest" %% "scalatest" % "3.2.16" % Test,
       "net.codingwell" %% "scala-guice" % "5.0.0" % Test),
 
-    assemblyJarName in assembly := s"$pluginName.jar",
+    assembly / assemblyJarName := s"$pluginName.jar",
 
-    packageOptions in(Compile, packageBin) += Package.ManifestAttributes(
+    Compile / packageBin / packageOptions += Package.ManifestAttributes(
       ("Gerrit-ApiType", "plugin"),
       ("Gerrit-PluginName", pluginName),
       ("Gerrit-Module", "com.googlesource.gerrit.plugins.analytics.Module"),
diff --git a/project/build.properties b/project/build.properties
index 0cd8b07..72413de 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=1.2.3
+sbt.version=1.8.3
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
index 98e4e06..5b4f172 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Contributors.scala
@@ -24,6 +24,8 @@
 import com.googlesource.gerrit.plugins.analytics.common._
 import org.kohsuke.args4j.{Option => ArgOption}
 
+import scala.util.Using
+
 @CommandMetaData(name = "contributors", description = "Extracts the list of contributors to a project")
 class ContributorsCommand @Inject()(val executor: ContributorsService,
                                     val projects: ProjectsCollection,
@@ -42,9 +44,9 @@
 
   @ArgOption(name = "--since", aliases = Array("--after", "-b"),
     usage = "(included) begin timestamp. Must be in the format 2006-01-02[ 15:04:05[.890][ -0700]]")
-  def setBeginDate(date: String) {
+  def setBeginDate(date: String) = {
     try {
-      beginDate = Some(date)
+      beginDate = Some(date.isoStringToLongDate)
     } catch {
       case e: Exception => throw die(s"Invalid begin date ${e.getMessage}")
     }
@@ -52,9 +54,9 @@
 
   @ArgOption(name = "--until", aliases = Array("--before", "-e"),
     usage = "(excluded) end timestamp. Must be in the format 2006-01-02[ 15:04:05[.890][ -0700]]")
-  def setEndDate(date: String) {
+  def setEndDate(date: String) = {
     try {
-      endDate = Some(date)
+      endDate = Some(date.isoStringToLongDate)
     } catch {
       case e: Exception => throw die(s"Invalid end date ${e.getMessage}")
     }
@@ -62,7 +64,7 @@
 
   @ArgOption(name = "--aggregate", aliases = Array("-g"),
     usage = "Type of aggregation requested. ")
-  def setGranularity(value: String) {
+  def setGranularity(value: String) = {
     try {
       granularity = Some(AggregationStrategy.apply(value))
     } catch {
@@ -88,9 +90,9 @@
 
   @ArgOption(name = "--since", aliases = Array("--after", "-b"), metaVar = "QUERY",
     usage = "(included) begin timestamp. Must be in the format 2006-01-02[ 15:04:05[.890][ -0700]]")
-  def setBeginDate(date: String) {
+  def setBeginDate(date: String) = {
     try {
-      beginDate = Some(date)
+      beginDate = Some(date.isoStringToLongDate)
     } catch {
       case e: Exception => throw new BadRequestException(s"Invalid begin date ${e.getMessage}")
     }
@@ -98,9 +100,9 @@
 
   @ArgOption(name = "--until", aliases = Array("--before", "-e"), metaVar = "QUERY",
     usage = "(excluded) end timestamp. Must be in the format 2006-01-02[ 15:04:05[.890][ -0700]]")
-  def setEndDate(date: String) {
+  def setEndDate(date: String) = {
     try {
-      endDate = Some(date)
+      endDate = Some(date.isoStringToLongDate)
     } catch {
       case e: Exception => throw new BadRequestException(s"Invalid end date ${e.getMessage}")
     }
@@ -108,7 +110,7 @@
 
   @ArgOption(name = "--granularity", aliases = Array("--aggregate", "-g"), metaVar = "QUERY",
     usage = "can be one of EMAIL, EMAIL_HOUR, EMAIL_DAY, EMAIL_MONTH, EMAIL_YEAR, defaulting to EMAIL")
-  def setGranularity(value: String) {
+  def setGranularity(value: String) = {
     try {
       granularity = Some(AggregationStrategy.apply(value))
     } catch {
@@ -137,15 +139,15 @@
 
   def get(projectRes: ProjectResource, startDate: Option[Long], stopDate: Option[Long],
           aggregationStrategy: AggregationStrategy, extractBranches: Boolean)
-  : TraversableOnce[UserActivitySummary] = {
+  : IterableOnce[UserActivitySummary] = {
 
-    ManagedResource.use(repoManager.openRepository(projectRes.getNameKey)) { repo =>
+    Using.resource(repoManager.openRepository(projectRes.getNameKey)) { repo =>
       val stats = new Statistics(projectRes.getNameKey, commitsStatisticsCache)
       val branchesExtractor = extractBranches.option(new BranchesExtractor(repo))
 
       histogram.get(repo, new AggregatedHistogramFilterByDates(startDate, stopDate, branchesExtractor, aggregationStrategy))
         .flatMap(aggregatedCommitActivity => UserActivitySummary.apply(stats)(aggregatedCommitActivity))
-        .toStream
+        .to(LazyList)
     }
   }
 }
@@ -178,7 +180,7 @@
   def apply(statisticsHandler: Statistics)(uca: AggregatedUserCommitActivity)
   : Iterable[UserActivitySummary] = {
 
-    statisticsHandler.forCommits(uca.getIds: _*).map { stat =>
+    statisticsHandler.forCommits(uca.getIds.toIndexedSeq: _*).map { stat =>
       val maybeBranches =
         uca.key.branch.fold(Array.empty[String])(Array(_))
 
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Module.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Module.scala
index b0c643e..a57ebac 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/Module.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/Module.scala
@@ -22,7 +22,7 @@
 
 class Module extends AbstractModule {
 
-  override protected def configure() {
+  override protected def configure() = {
     bind(classOf[BotLikeExtractor]).to(classOf[BotLikeExtractorImpl])
 
     install(new CommitsStatisticsCacheModule())
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/SshModule.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/SshModule.scala
index 48a48b4..01fe36d 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/SshModule.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/SshModule.scala
@@ -18,7 +18,7 @@
 
 class SshModule extends PluginCommandModule {
 
-  override protected def configureCommands {
+  override protected def configureCommands = {
     command(classOf[ContributorsCommand])
   }
 }
\ No newline at end of file
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/AggregatedHistogramFilterByDates.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/AggregatedHistogramFilterByDates.scala
index bc1315e..305c388 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/AggregatedHistogramFilterByDates.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/AggregatedHistogramFilterByDates.scala
@@ -29,7 +29,7 @@
     val commitDate = commit.getCommitterIdent.getWhen.getTime
     val author = commit.getAuthorIdent
 
-    if (from.fold(true)(commitDate >=) && to.fold(true)(commitDate <)) {
+    if (from.fold(true)(commitDate >= _) && to.fold(true)(commitDate < _)) {
       if(branchesExtractor.isDefined) {
         val branches = branchesExtractor.get.branchesOfCommit(commit.getId)
         getHistogram.includeWithBranches(commit, author, branches)
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractor.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractor.scala
index 9703da1..1725835 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractor.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractor.scala
@@ -14,28 +14,27 @@
 
 package com.googlesource.gerrit.plugins.analytics.common
 
-import com.googlesource.gerrit.plugins.analytics.common.ManagedResource.use
 import org.eclipse.jgit.api.Git
 import org.eclipse.jgit.lib.{Constants, ObjectId, Repository}
 import org.eclipse.jgit.revwalk.RevWalk
 
-import scala.collection.JavaConversions._
+import scala.jdk.CollectionConverters._
+import scala.util.Using
 
 case class BranchesExtractor(repo: Repository) {
   lazy val branchesOfCommit: Map[ObjectId, Set[String]] = {
 
-    use(new Git(repo)) { git =>
-      git.branchList.call.foldLeft(Map.empty[ObjectId, Set[String]]) { (branchesAcc, ref) =>
+    Using.resources(new Git(repo), new RevWalk(repo)) { (git, rw) =>
+      git.branchList.call.asScala.foldLeft(Map.empty[ObjectId, Set[String]]) { (branchesAcc, ref) =>
         val branchName = ref.getName.drop(Constants.R_HEADS.length)
 
-        use(new RevWalk(repo)) { rw: RevWalk =>
-          rw.markStart(rw.parseCommit(ref.getObjectId))
-          rw.foldLeft(branchesAcc) { (thisBranchAcc, rev) =>
-            val sha1 = rev.getId
-            thisBranchAcc.get(sha1) match {
-              case Some(set) => thisBranchAcc + (sha1 -> (set + branchName))
-              case None      => thisBranchAcc + (sha1 -> Set(branchName))
-            }
+        rw.reset()
+        rw.markStart(rw.parseCommit(ref.getObjectId))
+        rw.asScala.foldLeft(branchesAcc) { (thisBranchAcc, rev) =>
+          val sha1 = rev.getId
+          thisBranchAcc.get(sha1) match {
+            case Some(set) => thisBranchAcc + (sha1 -> (set + branchName))
+            case None      => thisBranchAcc + (sha1 -> Set(branchName))
           }
         }
       }
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala
index 08843fd..e95eef6 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/CommitsStatisticsLoader.scala
@@ -21,14 +21,14 @@
 import com.google.gerrit.server.project.ProjectCache
 import com.google.inject.Inject
 import com.googlesource.gerrit.plugins.analytics.{AnalyticsConfig, CommitInfo, IssueInfo}
-import com.googlesource.gerrit.plugins.analytics.common.ManagedResource.use
 import org.eclipse.jgit.diff.{DiffFormatter, RawTextComparator}
 import org.eclipse.jgit.revwalk.RevWalk
 import org.eclipse.jgit.treewalk.{CanonicalTreeParser, EmptyTreeIterator}
 import org.eclipse.jgit.util.io.DisabledOutputStream
-import scala.compat.java8.OptionConverters._
 
-import scala.collection.JavaConverters._
+import scala.jdk.CollectionConverters._
+import scala.jdk.OptionConverters._
+import scala.util.Using
 import scala.util.matching.Regex
 
 class CommitsStatisticsLoader @Inject() (
@@ -38,6 +38,7 @@
   config: AnalyticsConfig,
   ignoreFileSuffixFilter: IgnoreFileSuffixFilter
 ) extends CacheLoader[CommitsStatisticsCacheKey, CommitsStatistics] {
+  import CommitsStatisticsLoader._
 
   override def load(cacheKey: CommitsStatisticsCacheKey): CommitsStatistics = {
     import RevisionBrowsingSupport._
@@ -45,51 +46,51 @@
     val objectId = cacheKey.commitId
     val nameKey = Project.nameKey(cacheKey.projectName)
     val commentInfoList: Seq[CommentLinkInfo] =
-      if(config.isExtractIssues) projectCache.get(nameKey).asScala.toList.flatMap(_.getCommentLinks.asScala) else Seq.empty
+      if(config.isExtractIssues) projectCache.get(nameKey).toScala.toList.flatMap(_.getCommentLinks.asScala) else Seq.empty
     val replacers = commentInfoList.flatMap(info =>
       Option(info.link).map(link => Replacer(info.`match`.r, link))
     )
 
-    use(gitRepositoryManager.openRepository(nameKey)) { repo =>
+    Using.Manager { use =>
+      val repo = use(gitRepositoryManager.openRepository(nameKey))
 
       // I can imagine this kind of statistics is already being available in Gerrit but couldn't understand how to access it
       // which Injection can be useful for this task?
-        use(new RevWalk(repo)) { rw =>
-          val reader = repo.newObjectReader()
-          val commit = rw.parseCommit(objectId)
-          val commitMessage = commit.getFullMessage
+      val rw = use(new RevWalk(repo))
+      val reader = repo.newObjectReader()
+      val commit = rw.parseCommit(objectId)
+      val commitMessage = commit.getFullMessage
 
-          val oldTree = {
-            // protects against initial commit
-            if (commit.getParentCount == 0)
-              new EmptyTreeIterator
-            else
-              new CanonicalTreeParser(null, reader, rw.parseCommit(commit.getParent(0).getId).getTree)
-          }
+      val oldTree = {
+        // protects against initial commit
+        if (commit.getParentCount == 0)
+          new EmptyTreeIterator
+        else
+          new CanonicalTreeParser(null, reader, rw.parseCommit(commit.getParent(0).getId).getTree)
+      }
 
-          val newTree = new CanonicalTreeParser(null, reader, commit.getTree)
+      val newTree = new CanonicalTreeParser(null, reader, commit.getTree)
 
-          val df = new DiffFormatter(DisabledOutputStream.INSTANCE)
-          df.setRepository(repo)
-          df.setPathFilter(ignoreFileSuffixFilter)
-          df.setDiffComparator(RawTextComparator.DEFAULT)
-          df.setDetectRenames(true)
-          val diffs = df.scan(oldTree, newTree).asScala
+      val df = new DiffFormatter(DisabledOutputStream.INSTANCE)
+      df.setRepository(repo)
+      df.setPathFilter(ignoreFileSuffixFilter)
+      df.setDiffComparator(RawTextComparator.DEFAULT)
+      df.setDetectRenames(true)
+      val diffs = df.scan(oldTree, newTree).asScala
 
-          val lines = (for {
-            diff <- diffs
-            edit <- df.toFileHeader(diff).toEditList.asScala
-          } yield Lines(edit.getEndA - edit.getBeginA, edit.getEndB - edit.getBeginB)).fold(Lines(0, 0))(_ + _)
+      val lines = (for {
+        diff <- diffs
+        edit <- df.toFileHeader(diff).toEditList.asScala
+      } yield Lines(edit.getEndA - edit.getBeginA, edit.getEndB - edit.getBeginB)).fold(Lines(0, 0))(_ + _)
 
-          val files: Set[String] = diffs.map(df.toFileHeader(_).getNewPath).toSet
+      val files: Set[String] = diffs.map(df.toFileHeader(_).getNewPath).toSet
 
-          val commitInfo = CommitInfo(objectId.getName, commit.getAuthorIdent.getWhen.getTime, commit.isMerge, botLikeExtractor.isBotLike(files), files)
-          val commitsStats = CommitsStatistics(lines.added, lines.deleted, commitInfo.merge, commitInfo.botLike, List(commitInfo), extractIssues(commitMessage, replacers).toList)
+      val commitInfo = CommitInfo(objectId.getName, commit.getAuthorIdent.getWhen.getTime, commit.isMerge, botLikeExtractor.isBotLike(files), files)
+      val commitsStats = CommitsStatistics(lines.added, lines.deleted, commitInfo.merge, commitInfo.botLike, List(commitInfo), extractIssues(commitMessage, replacers).toList)
 
-          commitsStats
-        }
+      commitsStats
     }
-  }
+  }.get
 
   private def extractIssues(commitMessage: String, replacers: Seq[Replacer]): Seq[IssueInfo] =
     replacers.flatMap {
@@ -100,9 +101,9 @@
             IssueInfo(code, transformed)
           })
     }
+}
 
-
-
+object CommitsStatisticsLoader {
   final private case class Replacer(pattern: Regex, replaced: String)
 
   final private case class Lines(deleted: Int, added: Int) {
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/DateConversions.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/DateConversions.scala
index 874dc0d..4bf7dfe 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/DateConversions.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/DateConversions.scala
@@ -18,5 +18,7 @@
 
 object DateConversions {
 
-  implicit def isoStringToLongDate(s: String): Long = JavaSqlTimestampHelper.parseTimestamp(s).getTime
+  implicit class StringOps(val s: String) extends AnyVal {
+    def isoStringToLongDate: Long = JavaSqlTimestampHelper.parseTimestamp(s).getTime
+  }
 }
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/GsonFormatter.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/GsonFormatter.scala
index b054554..585447f 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/GsonFormatter.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/GsonFormatter.scala
@@ -28,10 +28,10 @@
       .registerTypeHierarchyAdapter(classOf[Iterable[Any]], new IterableSerializer)
       .registerTypeHierarchyAdapter(classOf[Option[Any]], new OptionSerializer())
 
-  def format[T](values: TraversableOnce[T], out: PrintWriter) {
+  def format[T](values: IterableOnce[T], out: PrintWriter) = {
     val gson: Gson = gsonBuilder.create
 
-    for (value <- values) {
+    values.iterator.foreach {value =>
       gson.toJson(value, out)
       out.println()
     }
@@ -39,7 +39,7 @@
 
   class IterableSerializer extends JsonSerializer[Iterable[Any]] {
     override def serialize(src: Iterable[Any], typeOfSrc: Type, context: JsonSerializationContext): JsonElement = {
-      import scala.collection.JavaConverters._
+      import scala.jdk.CollectionConverters._
       context.serialize(src.asJava)
     }
   }
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/JsonStreamedResultBuilder.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/JsonStreamedResultBuilder.scala
index 004259e..7e3c507 100644
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/JsonStreamedResultBuilder.scala
+++ b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/JsonStreamedResultBuilder.scala
@@ -18,8 +18,10 @@
 
 import com.google.gerrit.extensions.restapi.BinaryResult
 
+import scala.util.Using
+
 class GsonStreamedResult[T](val jsonFmt: GsonFormatter,
-                            val committers: TraversableOnce[T]) extends BinaryResult {
+                            val committers: IterableOnce[T]) extends BinaryResult {
   override def writeTo(os: OutputStream) =
-    ManagedResource.use(new PrintWriter(os))(jsonFmt.format(committers, _))
+    Using.resource(new PrintWriter(os))(jsonFmt.format(committers, _))
 }
diff --git a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/ManagedResources.scala b/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/ManagedResources.scala
deleted file mode 100644
index 5cf2b74..0000000
--- a/src/main/scala/com/googlesource/gerrit/plugins/analytics/common/ManagedResources.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.googlesource.gerrit.plugins.analytics.common
-
-object ManagedResource {
-  def use[A <: { def close(): Unit }, B](resource: A)(code: A ⇒ B): B =
-    try
-      code(resource)
-    finally
-      resource.close()
-}
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
index 42b0d1c..83e3871 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BotLikeExtractorImplSpec.scala
@@ -16,9 +16,10 @@
 
 import com.googlesource.gerrit.plugins.analytics.AnalyticsConfig
 import com.googlesource.gerrit.plugins.analytics.test.GerritTestDaemon
-import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
-class BotLikeExtractorImplSpec extends FlatSpec with Matchers with GerritTestDaemon {
+class BotLikeExtractorImplSpec extends AnyFlatSpecLike with Matchers with GerritTestDaemon {
 
   behavior of "isBotLike"
 
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractorSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractorSpec.scala
index 07909ff..d765af3 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractorSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/BranchesExtractorSpec.scala
@@ -2,10 +2,11 @@
 
 import com.google.gerrit.acceptance.UseLocalDisk
 import com.googlesource.gerrit.plugins.analytics.test.GerritTestDaemon
-import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
 @UseLocalDisk
-class BranchesExtractorSpec extends FlatSpec with Matchers with GerritTestDaemon {
+class BranchesExtractorSpec extends AnyFlatSpecLike with Matchers with GerritTestDaemon {
   def commitsBranches = new BranchesExtractor(testFileRepository.getRepository)
 
   behavior of "branchesOfCommit"
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/IgnoreFileSuffixFilterSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/IgnoreFileSuffixFilterSpec.scala
index 4ed373c..aefd3c2 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/IgnoreFileSuffixFilterSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/IgnoreFileSuffixFilterSpec.scala
@@ -18,10 +18,11 @@
 import com.googlesource.gerrit.plugins.analytics.AnalyticsConfig
 import com.googlesource.gerrit.plugins.analytics.test.GerritTestDaemon
 import org.eclipse.jgit.treewalk.TreeWalk
-import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
 @UseLocalDisk
-class IgnoreFileSuffixFilterSpec extends FlatSpec with Matchers with GerritTestDaemon {
+class IgnoreFileSuffixFilterSpec extends AnyFlatSpecLike with Matchers with GerritTestDaemon {
 
   behavior of "IgnoreFileSuffixFilter"
 
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/UserActivityHistogramSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/UserActivityHistogramSpec.scala
index 7dbe121..2c680e8 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/UserActivityHistogramSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/common/UserActivityHistogramSpec.scala
@@ -17,10 +17,11 @@
 import com.google.gerrit.acceptance.UseLocalDisk
 import com.googlesource.gerrit.plugins.analytics.common.AggregationStrategy.EMAIL_YEAR
 import com.googlesource.gerrit.plugins.analytics.test.GerritTestDaemon
-import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
 @UseLocalDisk
-class UserActivityHistogramSpec extends FlatSpec with Matchers with GerritTestDaemon {
+class UserActivityHistogramSpec extends AnyFlatSpecLike with Matchers with GerritTestDaemon {
 
   "UserActivityHistogram" should "return no activities" in {
     val filter = new AggregatedHistogramFilterByDates(aggregationStrategy = EMAIL_YEAR)
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregatedHistogramFilterByDatesSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregatedHistogramFilterByDatesSpec.scala
index 3128b2c..c21d52d 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregatedHistogramFilterByDatesSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregatedHistogramFilterByDatesSpec.scala
@@ -21,10 +21,12 @@
 import com.googlesource.gerrit.plugins.analytics.common.{AggregatedHistogramFilterByDates, BranchesExtractor}
 import org.eclipse.jgit.lib.PersonIdent
 import org.gitective.core.CommitFinder
-import org.scalatest.{BeforeAndAfterEach, FlatSpec, Matchers}
+import org.scalatest.BeforeAndAfterEach
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
 @UseLocalDisk
-class AggregatedHistogramFilterByDatesSpec extends FlatSpec with GerritTestDaemon with BeforeAndAfterEach with Matchers {
+class AggregatedHistogramFilterByDatesSpec extends AnyFlatSpecLike with GerritTestDaemon with BeforeAndAfterEach with Matchers {
 
   "Author history filter" should
     "select one commit without intervals restriction" in {
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregationSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregationSpec.scala
index c3d2087..063045b 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregationSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/AggregationSpec.scala
@@ -15,19 +15,20 @@
 package com.googlesource.gerrit.plugins.analytics.test
 
 import java.util.Date
-
 import com.google.gerrit.acceptance.UseLocalDisk
 import com.googlesource.gerrit.plugins.analytics.common.AggregationStrategy._
-import com.googlesource.gerrit.plugins.analytics.common.DateConversions.isoStringToLongDate
+import com.googlesource.gerrit.plugins.analytics.common.DateConversions.StringOps
 import com.googlesource.gerrit.plugins.analytics.common.TestUtils
 import org.eclipse.jgit.revwalk.RevCommit
-import org.scalatest.{FlatSpec, Inspectors, Matchers}
+import org.scalatest.Inspectors
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
 @UseLocalDisk
-class AggregationSpec extends FlatSpec with Matchers with GerritTestDaemon with TestUtils with Inspectors {
+class AggregationSpec extends AnyFlatSpecLike with Matchers with GerritTestDaemon with TestUtils with Inspectors {
 
   def commitAtDate(committer: String, when: String, content: String): RevCommit = {
-    val personIdent = newPersonIdent(committer, committer, new Date(isoStringToLongDate(when)))
+    val personIdent = newPersonIdent(committer, committer, new Date(when.isoStringToLongDate))
     testFileRepository.commitFile("somefile", content, committer = personIdent, author = personIdent)
   }
 
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala
index 4873328..178de2f 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitInfoSpec.scala
@@ -2,12 +2,13 @@
 
 import com.googlesource.gerrit.plugins.analytics.CommitInfo
 import com.googlesource.gerrit.plugins.analytics.common.GsonFormatter
-import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
-class CommitInfoSpec extends FlatSpec with Matchers {
+class CommitInfoSpec extends AnyFlatSpecLike with Matchers {
 
   "CommitInfo" should "be serialised as JSON correctly" in {
-    val commitInfo = CommitInfo(sha1 = "sha", date = 1000l, merge = false, botLike = false, files = Set("file1", "file2"))
+    val commitInfo = CommitInfo(sha1 = "sha", date = 1000L, merge = false, botLike = false, files = Set("file1", "file2"))
 
     val gsonBuilder = new GsonFormatter().gsonBuilder
 
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala
index b89bf5e..53593e1 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsCommentLinkSpec.scala
@@ -19,12 +19,14 @@
 import com.googlesource.gerrit.plugins.analytics.IssueInfo
 import com.googlesource.gerrit.plugins.analytics.common.{CommitsStatistics, Statistics}
 import org.eclipse.jgit.lib.Repository
-import org.scalatest.{FlatSpec, Inside, Matchers}
+import org.scalatest.Inside
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
-import scala.collection.JavaConverters._
+import scala.jdk.CollectionConverters._
 
 @UseLocalDisk
-class CommitStatisticsCommentLinkSpec extends FlatSpec with GerritTestDaemon with TestCommitStatisticsNoCache with Matchers with Inside {
+class CommitStatisticsCommentLinkSpec extends AnyFlatSpecLike with GerritTestDaemon with TestCommitStatisticsNoCache with Matchers with Inside {
 
   class TestEnvironment(val repo: Repository = fileRepository) {
     lazy val stats = new Statistics(fileRepositoryName, commitsStatisticsNoCache)
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala
index cb000e6..e78c1d9 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/CommitStatisticsSpec.scala
@@ -18,10 +18,12 @@
 import com.google.gerrit.entities.Project
 import com.googlesource.gerrit.plugins.analytics.CommitInfo
 import com.googlesource.gerrit.plugins.analytics.common.{CommitsStatistics, Statistics}
-import org.scalatest.{FlatSpec, Inside, Matchers}
+import org.scalatest.Inside
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
 @UseLocalDisk
-class CommitStatisticsSpec extends FlatSpec with GerritTestDaemon with TestCommitStatisticsNoCache with Matchers with Inside {
+class CommitStatisticsSpec extends AnyFlatSpecLike with GerritTestDaemon with TestCommitStatisticsNoCache with Matchers with Inside {
   class TestEnvironment {
     val repo = fileRepository
     val stats = new Statistics(fileRepositoryName, commitsStatisticsNoCache)
@@ -38,10 +40,10 @@
   }
 
   it should "sum to another compatible CommitStatistics generating an aggregated stat" in {
-    val commit1 = CommitInfo("sha_1", 1000l, false, botLike = false, Set("file1"))
-    val commit2 = CommitInfo("sha_2", 2000l, false, botLike = false, Set("file1"))
-    val commit3 = CommitInfo("sha_3", 3000l, false, botLike = false, Set("file2"))
-    val commit4 = CommitInfo("sha_4", 1000l, false, botLike = false, Set("file1"))
+    val commit1 = CommitInfo("sha_1", 1000L, false, botLike = false, Set("file1"))
+    val commit2 = CommitInfo("sha_2", 2000L, false, botLike = false, Set("file1"))
+    val commit3 = CommitInfo("sha_3", 3000L, false, botLike = false, Set("file2"))
+    val commit4 = CommitInfo("sha_4", 1000L, false, botLike = false, Set("file1"))
 
     val stat1 = CommitsStatistics(3, 4, false, false, List(commit1, commit2))
     val stat2 = CommitsStatistics(5, 7, false, false, List(commit3, commit4))
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/ContributorsServiceSpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/ContributorsServiceSpec.scala
index acefed1..a5d5558 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/ContributorsServiceSpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/ContributorsServiceSpec.scala
@@ -22,12 +22,14 @@
 import com.googlesource.gerrit.plugins.analytics.common.AggregationStrategy.EMAIL_HOUR
 import com.googlesource.gerrit.plugins.analytics.common.GsonFormatter
 import com.googlesource.gerrit.plugins.analytics.test.TestAnalyticsConfig.IGNORED_FILE_SUFFIX
-import org.scalatest.{FlatSpec, Inside, Matchers}
+import org.scalatest.Inside
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
-import scala.collection.JavaConverters._
+import scala.jdk.CollectionConverters._
 
 @UseLocalDisk
-class ContributorsServiceSpec extends FlatSpec with Matchers with GerritTestDaemon with Inside {
+class ContributorsServiceSpec extends AnyFlatSpecLike with Matchers with GerritTestDaemon with Inside {
 
   "ContributorsService" should "get commit statistics" in {
     val aContributorName = "Contributor Name"
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala
index bfd5a20..4d0df87 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/GerritTestDaemon.scala
@@ -71,7 +71,7 @@
   def newPersonIdent(name: String = "Test Person", email: String = "person@test.com", ts: Date = new Date()) =
     new PersonIdent(new PersonIdent(name, email), ts)
 
-  override def beforeEach {
+  override def beforeEach() = {
     daemonTest.setUpTestPlugin()
     fileRepositoryName = daemonTest.newProject(testSpecificRepositoryName)
     fileRepository = daemonTest.getRepository(fileRepositoryName)
diff --git a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala
index a5a5e10..3e2289e 100644
--- a/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala
+++ b/src/test/scala/com/googlesource/gerrit/plugins/analytics/test/UserActivitySummarySpec.scala
@@ -6,10 +6,11 @@
 import com.googlesource.gerrit.plugins.analytics.common.AggregationStrategy.EMAIL
 import com.googlesource.gerrit.plugins.analytics.common.{Statistics, TestUtils}
 import org.eclipse.jgit.lib.Repository
-import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.flatspec.AnyFlatSpecLike
+import org.scalatest.matchers.should.Matchers
 
 @UseLocalDisk
-class UserActivitySummarySpec extends FlatSpec with GerritTestDaemon with TestCommitStatisticsNoCache with TestUtils with Matchers {
+class UserActivitySummarySpec extends AnyFlatSpecLike with GerritTestDaemon with TestCommitStatisticsNoCache with TestUtils with Matchers {
 
   "numCommits" should "count only comments filtered by their merge status" in {
     val personEmail = "aCommitter@aCompany.com"