This is an automated email from the ASF dual-hosted git repository.

chengpan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-toree.git


The following commit(s) were added to refs/heads/master by this push:
     new e48d434c [TOREE-556] Support Scala 2.13 (#218)
e48d434c is described below

commit e48d434c917ed16d987d90e70cdea3b341cddd85
Author: Cheng Pan <[email protected]>
AuthorDate: Tue Oct 7 09:37:55 2025 +0800

    [TOREE-556] Support Scala 2.13 (#218)
    
    Support Scala 2.13
    
    ---------
    
    Co-authored-by: Neil Skinner <[email protected]>
---
 .github/workflows/build.yml                        |  11 +-
 Dockerfile                                         |   8 +-
 Dockerfile.toree-dev                               |  13 +-
 Makefile                                           |   7 +-
 build.sbt                                          |  19 +-
 .../kernel/protocol/v5/client/Utilities.scala      |  11 +-
 .../v5/client/socket/HeartbeatClient.scala         |   2 +-
 .../protocol/v5/client/socket/IOPubClient.scala    |   2 +-
 .../v5/client/socket/IOPubClientSpec.scala         |   4 +-
 .../security/SignatureCheckerActor.scala           |   2 +-
 .../security/SignatureProducerActor.scala          |   2 +-
 .../socket/ZeroMQSocketRunnable.scala              |   2 +-
 .../toree/communication/utils/OrderedSupport.scala |   2 +-
 .../CoursierDependencyDownloader.scala             |   2 +-
 .../org/apache/toree/interpreter/Interpreter.scala |   7 +-
 .../toree/interpreter/broker/BrokerService.scala   |   2 +-
 .../toree/interpreter/broker/BrokerState.scala     |   2 +-
 .../org/apache/toree/kernel/api/KernelLike.scala   |   2 +-
 .../apache/toree/magic/InternalClassLoader.scala   |   2 +-
 .../toree/security/KernelSecurityManager.scala     |   2 +-
 .../org/apache/toree/utils/MultiClassLoader.scala  |   8 +-
 kernel/src/main/scala/org/apache/toree/Main.scala  |   2 +-
 .../toree/boot/layer/ComponentInitialization.scala |   9 +-
 .../scala/org/apache/toree/kernel/api/Kernel.scala |  10 +-
 .../protocol/v5/dispatch/StatusDispatch.scala      |   2 +-
 .../protocol/v5/handler/CommCloseHandler.scala     |   2 +-
 .../v5/handler/CommInfoRequestHandler.scala        |  13 +-
 .../protocol/v5/handler/CommMsgHandler.scala       |   2 +-
 .../protocol/v5/handler/CommOpenHandler.scala      |   2 +-
 .../v5/handler/ExecuteRequestHandler.scala         |   4 +-
 .../v5/handler/InputRequestReplyHandler.scala      |   2 +-
 .../protocol/v5/interpreter/InterpreterActor.scala |   8 +-
 .../interpreter/tasks/CodeCompleteTaskActor.scala  |   4 +-
 .../tasks/ExecuteRequestTaskActor.scala            |  16 +-
 .../v5/interpreter/tasks/IsCompleteTaskActor.scala |   4 +-
 .../kernel/protocol/v5/kernel/Utilities.scala      |  11 +-
 .../protocol/v5/relay/ExecuteRequestRelay.scala    |   4 +-
 .../org/apache/toree/magic/builtin/AddDeps.scala   |   2 +-
 .../org/apache/toree/magic/builtin/Dataframe.scala |  16 +-
 .../apache/toree/utils/DataFrameConverter.scala    |   5 +-
 .../v5/kernel/socket/SocketConfigSpec.scala        |   2 +-
 .../protocol/v5/stream/KernelOuputStreamSpec.scala |   2 +-
 .../test/scala/test/utils/DummyInterpreter.scala   |   5 +-
 macros/project/plugins.sbt                         |   4 +-
 .../org/apache/toree/plugins/PluginManager.scala   |   4 +-
 .../org/apache/toree/plugins/PluginMethod.scala    |   6 +-
 .../org/apache/toree/plugins/PluginSearcher.scala  |   2 +-
 .../apache/toree/plugins/ClassFinderHelper.scala   |  12 +-
 .../apache/toree/plugins/ClassFinderHelper.scala   |  12 +-
 .../plugins/dependencies/ClassLoaderHelper.scala   |  14 +-
 .../apache/toree/plugins/PluginSearcherSpec.scala  |  26 +-
 project/plugins.sbt                                |   2 +-
 .../scala/org/apache/toree/comm/CommWriter.scala   |   2 +-
 .../toree/kernel/protocol/v5/KMBuilder.scala       |   4 +-
 .../toree/kernel/protocol/v5/KernelMessage.scala   |   6 +-
 .../apache/toree/kernel/protocol/v5/package.scala  |   2 +-
 .../toree/kernel/protocol/v5/HeaderSpec.scala      |   2 +-
 .../protocol/v5/content/ClearOutputSpec.scala      |   2 +-
 .../kernel/protocol/v5/content/CommCloseSpec.scala |   2 +-
 .../kernel/protocol/v5/content/CommMsgSpec.scala   |   2 +-
 .../kernel/protocol/v5/content/CommOpenSpec.scala  |   2 +-
 .../v5/content/CompleteReplyErrorSpec.scala        |   2 +-
 .../protocol/v5/content/CompleteReplyOkSpec.scala  |   2 +-
 .../protocol/v5/content/CompleteReplySpec.scala    |   2 +-
 .../protocol/v5/content/CompleteRequestSpec.scala  |   2 +-
 .../protocol/v5/content/ConnectReplySpec.scala     |   2 +-
 .../protocol/v5/content/ConnectRequestSpec.scala   |   2 +-
 .../protocol/v5/content/DisplayDataSpec.scala      |   2 +-
 .../protocol/v5/content/ErrorContentSpec.scala     |   2 +-
 .../protocol/v5/content/ExecuteInputSpec.scala     |   2 +-
 .../v5/content/ExecuteReplyAbortSpec.scala         |   2 +-
 .../v5/content/ExecuteReplyErrorSpec.scala         |   2 +-
 .../protocol/v5/content/ExecuteReplyOkSpec.scala   |   2 +-
 .../protocol/v5/content/ExecuteReplySpec.scala     |   2 +-
 .../protocol/v5/content/ExecuteRequestSpec.scala   |   2 +-
 .../protocol/v5/content/ExecuteResultSpec.scala    |   2 +-
 .../protocol/v5/content/HistoryReplySpec.scala     |   2 +-
 .../protocol/v5/content/HistoryRequestSpec.scala   |   2 +-
 .../protocol/v5/content/InputReplySpec.scala       |   2 +-
 .../protocol/v5/content/InputRequestSpec.scala     |   2 +-
 .../v5/content/InspectReplyErrorSpec.scala         |   2 +-
 .../protocol/v5/content/InspectReplyOkSpec.scala   |   2 +-
 .../protocol/v5/content/InspectReplySpec.scala     |   2 +-
 .../protocol/v5/content/InspectRequestSpec.scala   |   2 +-
 .../protocol/v5/content/KernelInfoReplySpec.scala  |   2 +-
 .../v5/content/KernelInfoRequestSpec.scala         |   2 +-
 .../protocol/v5/content/KernelStatusSpec.scala     |   2 +-
 .../protocol/v5/content/ShutdownReplySpec.scala    |   2 +-
 .../protocol/v5/content/ShutdownRequestSpec.scala  |   2 +-
 .../protocol/v5/content/StreamContentSpec.scala    |   2 +-
 .../scala/ScalaInterpreterSpecific.scala           | 456 +++++++++++++++++++++
 .../interpreter/scala/ScalaInterpreter.scala       |  36 +-
 .../kernel/interpreter/sql/SqlInterpreter.scala    |   2 +-
 .../toree/kernel/interpreter/sql/SqlService.scala  |   2 +-
 94 files changed, 699 insertions(+), 200 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b39afbee..cdf2ec1a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -31,6 +31,7 @@ jobs:
       fail-fast: false
       matrix:
         java: [ '8', '11' ]
+        scala: [ '2.12', '2.13' ]
     env:
       # define Java options for both official sbt and sbt-extras
       JAVA_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M 
-Dfile.encoding=UTF-8
@@ -54,14 +55,14 @@ jobs:
       uses: sbt/setup-sbt@v1        
     - name: Build
       run: |
-        make clean release
+        make SCALA_VERSION=${{ matrix.scala }} clean release
     - name: Run tests
       run: |
-        make test
+        make SCALA_VERSION=${{ matrix.scala }} test
 #    See https://issues.apache.org/jira/browse/TOREE-526
 #    - name: Run system tests
 #      run: |
-#        make system-test
-    - name: Run license eudit
+#        make SCALA_VERSION=${{ matrix.scala }} system-test
+    - name: Run license audit
       run: |
-        make audit-licenses
+        make SCALA_VERSION=${{ matrix.scala }} audit-licenses
diff --git a/Dockerfile b/Dockerfile
index 61fc8c2a..9b2eb1a7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -27,7 +27,7 @@ RUN curl -sL https://deb.nodesource.com/setup_0.12 | bash - 
&& \
 
 # for Apache Spark demos
 ENV APACHE_SPARK_VERSION 3.4.4
-ENV APACHE_SPARK_CUSTOM_NAME=hadoop3
+ARG SCALA_VERSION=2.12
 
 RUN apt-get -y update && \
     apt-get -y install software-properties-common
@@ -47,11 +47,11 @@ RUN echo "===> install Java"  && \
     update-java-alternatives -s java-8-oracle
 
 RUN cd /tmp && \
+    if [ "$SCALA_VERSION" = "2.13" ]; then 
APACHE_SPARK_CUSTOM_NAME=hadoop3-scala2.13; else 
APACHE_SPARK_CUSTOM_NAME=hadoop3; fi && \
     wget -q 
https://archive.apache.org/dist/spark/spark-${APACHE_SPARK_VERSION}/spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz
 && \
     tar xzf spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz 
-C /usr/local && \
-    rm spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz
-
-RUN cd /usr/local && ln -s 
spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME} spark
+    rm spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz && \
+    ln -snf 
/usr/local/spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME} 
/usr/local/spark
 
 # R support
 RUN apt-get update && \
diff --git a/Dockerfile.toree-dev b/Dockerfile.toree-dev
index fa3fc975..731b9c83 100644
--- a/Dockerfile.toree-dev
+++ b/Dockerfile.toree-dev
@@ -23,8 +23,8 @@ FROM jupyter/all-spark-notebook
 USER root
 
 # Spark dependencies
-ENV APACHE_SPARK_VERSION 3.3.2
-ENV APACHE_SPARK_CUSTOM_NAME=hadoop3
+ARG APACHE_SPARK_VERSION=3.4.4
+ARG SCALA_VERSION=2.12
 
 RUN apt-get -y update && \
     apt-get install -y --no-install-recommends openjdk-8-jdk 
ca-certificates-java  && \
@@ -36,14 +36,11 @@ RUN apt-get -y update && \
 
 # Installing Spark3
 RUN cd /tmp && \
+    if [ "$SCALA_VERSION" = "2.13" ]; then 
APACHE_SPARK_CUSTOM_NAME=hadoop3-scala2.13; else 
APACHE_SPARK_CUSTOM_NAME=hadoop3; fi && \
     wget -q 
https://archive.apache.org/dist/spark/spark-${APACHE_SPARK_VERSION}/spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz
 && \
     tar xzf spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz 
-C /usr/local && \
-    rm spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz
-
-# Overwrite symlink
-RUN cd /usr/local && \
-    rm spark && \
-    ln -s spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME} spark
+    rm spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME}.tgz && \
+    ln -snf 
/usr/local/spark-${APACHE_SPARK_VERSION}-bin-${APACHE_SPARK_CUSTOM_NAME} 
/usr/local/spark
 
 # Remove other scala kernels
 RUN cd /opt/conda/share/jupyter/kernels/ && \
diff --git a/Makefile b/Makefile
index a6a74b6b..a2bc3117 100644
--- a/Makefile
+++ b/Makefile
@@ -49,7 +49,7 @@ endef
 
 RUN=$(RUN_PREFIX)$(1)$(RUN_SUFFIX)
 
-ENV_OPTS:=APACHE_SPARK_VERSION=$(APACHE_SPARK_VERSION) VERSION=$(VERSION) 
IS_SNAPSHOT=$(IS_SNAPSHOT)
+ENV_OPTS:=APACHE_SPARK_VERSION=$(APACHE_SPARK_VERSION) 
SCALA_VERSION=$(SCALA_VERSION) VERSION=$(VERSION) IS_SNAPSHOT=$(IS_SNAPSHOT)
 
 ASSEMBLY_JAR:=toree-assembly-$(VERSION)$(SNAPSHOT).jar
 
@@ -83,7 +83,10 @@ clean: clean-dist
        @-docker rmi -f $(TOREE_DEV_IMAGE)
 
 .toree-dev-image:
-       @docker build -t $(TOREE_DEV_IMAGE) -f Dockerfile.toree-dev .
+       @docker build -t $(TOREE_DEV_IMAGE) -f Dockerfile.toree-dev \
+               --build-arg APACHE_SPARK_VERSION=$(APACHE_SPARK_VERSION) \
+               --build-arg SCALA_VERSION=$(SCALA_VERSION) \
+               .
        touch $@
 
 .clean-binder-image:
diff --git a/build.sbt b/build.sbt
index 6f147628..3fb4030b 100644
--- a/build.sbt
+++ b/build.sbt
@@ -18,13 +18,20 @@
 import scala.util.Properties
 import sbtassembly.AssemblyOption
 
+lazy val scala212 = "2.12.17"
+lazy val scala213 = "2.13.8"
+lazy val defaultScalaVersion = sys.env.get("SCALA_VERSION") match {
+  case Some("2.13") => scala213
+  case _ => scala212
+}
+
 // Version settings
 ThisBuild / version := Properties.envOrElse("VERSION", "0.0.0-dev") +
   (if ((ThisBuild / isSnapshot ).value) "-SNAPSHOT" else "")
 ThisBuild / isSnapshot := Properties.envOrElse("IS_SNAPSHOT","true").toBoolean
 ThisBuild / organization := "org.apache.toree.kernel"
-ThisBuild / crossScalaVersions := Seq("2.12.17")
-ThisBuild / scalaVersion := (ThisBuild / crossScalaVersions ).value.head
+ThisBuild / crossScalaVersions := Seq(scala212, scala213)
+ThisBuild / scalaVersion := defaultScalaVersion
 ThisBuild / Dependencies.sparkVersion := {
   val envVar = "APACHE_SPARK_VERSION"
   val defaultVersion = "3.4.4"
@@ -44,7 +51,6 @@ ThisBuild / scalacOptions ++= Seq(
   "-deprecation",
   "-unchecked",
   "-feature",
-  "-Xfatal-warnings",
   "-language:reflectiveCalls",
   "-target:jvm-1.8"
 )
@@ -118,7 +124,7 @@ ThisBuild / credentials += Credentials(Path.userHome / 
".ivy2" / ".credentials")
 
 /** Root Toree project. */
 lazy val root = (project in file("."))
-  .settings(name := "toree", crossScalaVersions := Nil)
+  .settings(name := "toree")
   .aggregate(
     
macros,protocol,plugins,communication,kernelApi,client,scalaInterpreter,sqlInterpreter,kernel
   )
@@ -203,10 +209,7 @@ lazy val kernel = (project in file("kernel"))
 enablePlugins(ScalaUnidocPlugin)
 (ScalaUnidoc / unidoc / scalacOptions) ++= Seq(
   "-Ymacro-expand:none",
-  "-skip-packages", Seq(
-    "org.apache.pekko",
-    "scala"
-  ).mkString(":"),
+  "-skip-packages", "org.apache.pekko:scala",
   "-no-link-warnings" // Suppresses problems with Scaladoc @throws links
 )
 
diff --git 
a/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/Utilities.scala
 
b/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/Utilities.scala
index ff294b13..b1fc1549 100644
--- 
a/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/Utilities.scala
+++ 
b/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/Utilities.scala
@@ -26,6 +26,7 @@ import 
org.apache.toree.kernel.protocol.v5.content.ExecuteRequest
 import org.apache.toree.utils.LogLike
 import play.api.libs.json.{JsPath, Json, JsonValidationError, Reads}
 
+import scala.collection.mutable
 import scala.concurrent.duration._
 
 object Utilities extends LogLike {
@@ -64,7 +65,7 @@ object Utilities extends LogLike {
     val header = Json.parse(message.frames(delimiterIndex + 2)).as[Header]
     val parentHeader = Json.parse(message.frames(delimiterIndex + 
3)).validate[ParentHeader].fold[ParentHeader](
       // TODO: Investigate better solution than setting parentHeader to null 
for {}
-      (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => null, 
//HeaderBuilder.empty,
+      (invalid: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]) 
=> null, //HeaderBuilder.empty,
       (valid: ParentHeader) => valid
     )
     val metadata = Json.parse(message.frames(delimiterIndex + 4)).as[Metadata]
@@ -78,20 +79,20 @@ object Utilities extends LogLike {
   }
 
   implicit def KernelMessageToZMQMessage(kernelMessage : KernelMessage) : 
ZMQMessage = {
-    val frames: scala.collection.mutable.ListBuffer[ByteString] = 
scala.collection.mutable.ListBuffer()
-    kernelMessage.ids.map((id : Array[Byte]) => frames += ByteString.apply(id) 
)
+    val frames: mutable.ListBuffer[ByteString] = mutable.ListBuffer()
+    kernelMessage.ids.map((id: Array[Byte]) => frames += ByteString.apply(id))
     frames += "<IDS|MSG>"
     frames += kernelMessage.signature
     frames += Json.toJson(kernelMessage.header).toString()
     frames += Json.toJson(kernelMessage.parentHeader).toString()
     frames += Json.toJson(kernelMessage.metadata).toString
     frames += kernelMessage.contentString
-    ZMQMessage(frames  : _*)
+    ZMQMessage(frames.toSeq : _*)
   }
 
   def parseAndHandle[T](json: String, reads: Reads[T], handler: T => Unit) : 
Unit = {
     Json.parse(json).validate[T](reads).fold(
-      (invalid: Seq[(JsPath, Seq[JsonValidationError])]) =>
+      (invalid: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]) 
=>
         logger.error(s"Could not parse JSON, ${json}"),
       (content: T) => handler(content)
     )
diff --git 
a/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/HeartbeatClient.scala
 
b/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/HeartbeatClient.scala
index 8cdaf7b7..48f6b4e8 100644
--- 
a/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/HeartbeatClient.scala
+++ 
b/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/HeartbeatClient.scala
@@ -60,7 +60,7 @@ class HeartbeatClient(
     case HeartbeatMessage =>
       import scala.concurrent.ExecutionContext.Implicits.global
       val id = java.util.UUID.randomUUID().toString
-      futureMap += (id -> sender)
+      futureMap += (id -> sender())
       logger.info(s"Heartbeat client send: $id")
       val future = socket ? ZMQMessage(ByteString(id.getBytes))
       future.onComplete {
diff --git 
a/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClient.scala
 
b/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClient.scala
index eee8daad..17985c57 100644
--- 
a/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClient.scala
+++ 
b/client/src/main/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClient.scala
@@ -76,7 +76,7 @@ class IOPubClient(
     } else {
       logger.warn("Received message with null parent header.")
       logger.debug(s"Kernel message is: $kernelMessage")
-      sender.forward(Failure(new RuntimeException(PARENT_HEADER_NULL_MESSAGE)))
+      sender().forward(Failure(new 
RuntimeException(PARENT_HEADER_NULL_MESSAGE)))
     }
   }
 
diff --git 
a/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala
 
b/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala
index 9cae4fb1..f7b19ab3 100644
--- 
a/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala
+++ 
b/client/src/test/scala/org/apache/toree/kernel/protocol/v5/client/socket/IOPubClientSpec.scala
@@ -36,7 +36,7 @@ import org.mockito.ArgumentMatchers.{eq => mockEq, _}
 import org.mockito.Mockito._
 import org.scalatest.concurrent.{Eventually, ScalaFutures}
 import org.scalatestplus.mockito.MockitoSugar
-import org.scalatest.time.{Milliseconds, Span}
+import org.scalatest.time.{Milliseconds, Seconds, Span}
 import org.scalatest.funspec.AnyFunSpecLike
 import org.scalatest.matchers.should.Matchers
 import org.scalatest.BeforeAndAfterEach
@@ -60,7 +60,7 @@ class IOPubClientSpec extends TestKit(ActorSystem(
 {
   private val TestTimeout = Timeout(10.seconds)
   implicit override val patienceConfig = PatienceConfig(
-    timeout = scaled(Span(200, Milliseconds)),
+    timeout = scaled(Span(1, Seconds)),
     interval = scaled(Span(5, Milliseconds))
   )
   private val SignatureEnabled = true
diff --git 
a/communication/src/main/scala/org/apache/toree/communication/security/SignatureCheckerActor.scala
 
b/communication/src/main/scala/org/apache/toree/communication/security/SignatureCheckerActor.scala
index e6b8329a..fba44696 100644
--- 
a/communication/src/main/scala/org/apache/toree/communication/security/SignatureCheckerActor.scala
+++ 
b/communication/src/main/scala/org/apache/toree/communication/security/SignatureCheckerActor.scala
@@ -35,7 +35,7 @@ class SignatureCheckerActor(
       val isValidSignature = hmacString == signature
       logger.trace(s"Signature ${signature} validity checked against " +
         s"hmac ${hmacString} with outcome ${isValidSignature}")
-      sender ! isValidSignature
+      sender() ! isValidSignature
     }
   }
 
diff --git 
a/communication/src/main/scala/org/apache/toree/communication/security/SignatureProducerActor.scala
 
b/communication/src/main/scala/org/apache/toree/communication/security/SignatureProducerActor.scala
index 1e303e5e..0161c04f 100644
--- 
a/communication/src/main/scala/org/apache/toree/communication/security/SignatureProducerActor.scala
+++ 
b/communication/src/main/scala/org/apache/toree/communication/security/SignatureProducerActor.scala
@@ -38,7 +38,7 @@ class SignatureProducerActor(
         Json.stringify(Json.toJson(message.metadata)),
         message.contentString
       )
-      sender ! signature
+      sender() ! signature
     }
   }
 
diff --git 
a/communication/src/main/scala/org/apache/toree/communication/socket/ZeroMQSocketRunnable.scala
 
b/communication/src/main/scala/org/apache/toree/communication/socket/ZeroMQSocketRunnable.scala
index a515e946..66e71648 100644
--- 
a/communication/src/main/scala/org/apache/toree/communication/socket/ZeroMQSocketRunnable.scala
+++ 
b/communication/src/main/scala/org/apache/toree/communication/socket/ZeroMQSocketRunnable.scala
@@ -170,7 +170,7 @@ class ZeroMQSocketRunnable(
         socket.close()
       } catch {
         case ex: Exception =>
-          logger.error("Failed to close socket!", _: Throwable)
+          logger.error("Failed to close socket!", ex: Throwable)
       }
     }
   }
diff --git 
a/communication/src/main/scala/org/apache/toree/communication/utils/OrderedSupport.scala
 
b/communication/src/main/scala/org/apache/toree/communication/utils/OrderedSupport.scala
index 31e6c6fd..da970415 100644
--- 
a/communication/src/main/scala/org/apache/toree/communication/utils/OrderedSupport.scala
+++ 
b/communication/src/main/scala/org/apache/toree/communication/utils/OrderedSupport.scala
@@ -52,7 +52,7 @@ trait OrderedSupport extends Actor with Stash with LogLike {
    */
   def startProcessing(): Unit = {
     logger.debug("Actor is in processing state and will stash messages of " +
-      s"types: ${orderedTypes.mkString(" ")}")
+      s"types: ${orderedTypes().mkString(" ")}")
     context.become(waiting, discardOld = false)
   }
 
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/dependencies/CoursierDependencyDownloader.scala
 
b/kernel-api/src/main/scala/org/apache/toree/dependencies/CoursierDependencyDownloader.scala
index fb88aad5..a7e8478e 100644
--- 
a/kernel-api/src/main/scala/org/apache/toree/dependencies/CoursierDependencyDownloader.scala
+++ 
b/kernel-api/src/main/scala/org/apache/toree/dependencies/CoursierDependencyDownloader.scala
@@ -105,7 +105,7 @@ class CoursierDependencyDownloader extends 
DependencyDownloader {
             artifactClassifier.map(c => 
Classifier(c)).getOrElse(Classifier.empty)
           )
         }
-    ))
+    ).toSeq)
 
     printStream.println(s"Marking $groupId:$artifactId:$version for download")
 
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/interpreter/Interpreter.scala 
b/kernel-api/src/main/scala/org/apache/toree/interpreter/Interpreter.scala
index 5a02f9d4..97deabfa 100644
--- a/kernel-api/src/main/scala/org/apache/toree/interpreter/Interpreter.scala
+++ b/kernel-api/src/main/scala/org/apache/toree/interpreter/Interpreter.scala
@@ -20,8 +20,7 @@ package org.apache.toree.interpreter
 import java.net.URL
 
 import org.apache.toree.kernel.api.KernelLike
-
-import scala.tools.nsc.interpreter._
+import java.io.{InputStream, OutputStream}
 
 case class LanguageInfo(
                  name: String,
@@ -90,7 +89,7 @@ trait Interpreter {
    * @param value The value of the variable binding
    * @param modifiers Any annotation, scoping modifiers, etc on the variable
    */
-  def bind(variableName: String, typeName: String, value: Any, modifiers: 
List[String])
+  def bind(variableName: String, typeName: String, value: Any, modifiers: 
List[String]): Unit
 
   /**
    * Retrieves the contents of the variable with the provided name from the
@@ -109,7 +108,7 @@ trait Interpreter {
    * @param out The new output stream
    * @param err The new error stream
    */
-  def updatePrintStreams(in: InputStream, out: OutputStream, err: OutputStream)
+  def updatePrintStreams(in: InputStream, out: OutputStream, err: 
OutputStream): Unit
 
   /**
    * Attempts to perform code completion via the <TAB> command.
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerService.scala
 
b/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerService.scala
index 0be0fc10..64206b7c 100644
--- 
a/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerService.scala
+++ 
b/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerService.scala
@@ -20,7 +20,7 @@ package org.apache.toree.interpreter.broker
 import org.apache.toree.interpreter.broker.BrokerTypes.{Code, CodeResults}
 
 import scala.concurrent.Future
-import scala.tools.nsc.interpreter._
+import java.io.{InputStream, OutputStream}
 
 /**
  * Represents the service that provides the high-level interface between the
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerState.scala
 
b/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerState.scala
index 3d1e3abe..55d33189 100644
--- 
a/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerState.scala
+++ 
b/kernel-api/src/main/scala/org/apache/toree/interpreter/broker/BrokerState.scala
@@ -23,7 +23,7 @@ import org.apache.toree.interpreter.broker.BrokerTypes._
 import org.slf4j.LoggerFactory
 
 import scala.concurrent.{Future, Promise}
-import scala.tools.nsc.interpreter.OutputStream
+import java.io.{InputStream, OutputStream}
 
 /**
  * Represents the state structure of broker.
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/kernel/api/KernelLike.scala 
b/kernel-api/src/main/scala/org/apache/toree/kernel/api/KernelLike.scala
index b2f96e9b..127bda24 100644
--- a/kernel-api/src/main/scala/org/apache/toree/kernel/api/KernelLike.scala
+++ b/kernel-api/src/main/scala/org/apache/toree/kernel/api/KernelLike.scala
@@ -102,7 +102,7 @@ trait KernelLike {
 
   def config: Config
 
-  def addJars(uris: URI*)
+  def addJars(uris: URI*): Unit
 
   def sparkContext: SparkContext
 
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/magic/InternalClassLoader.scala 
b/kernel-api/src/main/scala/org/apache/toree/magic/InternalClassLoader.scala
index b79a7015..6d571d23 100644
--- a/kernel-api/src/main/scala/org/apache/toree/magic/InternalClassLoader.scala
+++ b/kernel-api/src/main/scala/org/apache/toree/magic/InternalClassLoader.scala
@@ -29,7 +29,7 @@ class InternalClassLoader(
 
   // TODO: Provides an exposed reference to the super loadClass to be stubbed
   // out in tests.
-  private[magic] def parentLoadClass(name: String, resolve: Boolean) =
+  private[magic] def parentLoadClass(name: String, resolve: Boolean): Class[_] 
=
     super.loadClass(name, resolve)
 
   /**
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/security/KernelSecurityManager.scala
 
b/kernel-api/src/main/scala/org/apache/toree/security/KernelSecurityManager.scala
index 0b595543..54d48cfb 100644
--- 
a/kernel-api/src/main/scala/org/apache/toree/security/KernelSecurityManager.scala
+++ 
b/kernel-api/src/main/scala/org/apache/toree/security/KernelSecurityManager.scala
@@ -70,7 +70,7 @@ object KernelSecurityManager {
     * the only path by which we should permit System.exit to succeed within 
the notebook.
     * Note that dual SIGINTs occur from a non-restricted thread group and are 
also permitted.
     */
-  def enableRestrictedExit() {
+  def enableRestrictedExit(): Unit = {
     val currentGroup = Thread.currentThread().getThreadGroup
     tlEnableRestrictedExit.set(currentGroup.getName == RestrictedGroupName)
   }
diff --git 
a/kernel-api/src/main/scala/org/apache/toree/utils/MultiClassLoader.scala 
b/kernel-api/src/main/scala/org/apache/toree/utils/MultiClassLoader.scala
index 62427353..a7cb5d9b 100644
--- a/kernel-api/src/main/scala/org/apache/toree/utils/MultiClassLoader.scala
+++ b/kernel-api/src/main/scala/org/apache/toree/utils/MultiClassLoader.scala
@@ -77,20 +77,20 @@ class MultiClassLoader(
     }
 
     // NOTE: Using iterator to evaluate elements one at a time
-    classLoaders.toIterator
+    classLoaders.iterator
       .map(classLoader => tryFindClass(classLoader, name))
       .find(_.isSuccess)
       .map(_.get)
       .getOrElse(throw new ClassNotFoundException(name))
   }
 
-  override protected def findResource(name: String): URL = {
+  override def findResource(name: String): URL = {
     // NOTE: Using iterator to evaluate elements one at a time
-    classLoaders.toIterator.map(cl => _findResource(cl, name)).find(_ != null)
+    classLoaders.iterator.map(cl => _findResource(cl, name)).find(_ != null)
       .getOrElse(super.findResource(name))
   }
 
-  override protected def findResources(name: String): util.Enumeration[URL] = {
+  override def findResources(name: String): util.Enumeration[URL] = {
     val internalResources = classLoaders
       .flatMap(cl => Try(_findResources(cl, name)).toOption)
       .map(_.asScala)
diff --git a/kernel/src/main/scala/org/apache/toree/Main.scala 
b/kernel/src/main/scala/org/apache/toree/Main.scala
index 57563363..0e304a00 100644
--- a/kernel/src/main/scala/org/apache/toree/Main.scala
+++ b/kernel/src/main/scala/org/apache/toree/Main.scala
@@ -22,7 +22,7 @@ import org.apache.toree.boot.{CommandLineOptions, 
KernelBootstrap}
 import org.apache.toree.kernel.BuildInfo
 
 object Main extends App {
-  private val options = new CommandLineOptions(args)
+  private val options = new CommandLineOptions(args.toIndexedSeq)
 
   if (options.help) {
     options.printHelpOn(System.out)
diff --git 
a/kernel/src/main/scala/org/apache/toree/boot/layer/ComponentInitialization.scala
 
b/kernel/src/main/scala/org/apache/toree/boot/layer/ComponentInitialization.scala
index 47d2ac0d..31bcecf9 100644
--- 
a/kernel/src/main/scala/org/apache/toree/boot/layer/ComponentInitialization.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/boot/layer/ComponentInitialization.scala
@@ -204,7 +204,7 @@ trait StandardComponentInitialization extends 
ComponentInitialization {
   private def initializePlugins(
     config: Config,
     pluginManager: PluginManager
-  ) = {
+  ): Unit = {
     val magicUrlArray = config.getStringList("magic_urls").asScala
       .map(s => new java.net.URL(s)).toArray
 
@@ -217,17 +217,18 @@ trait StandardComponentInitialization extends 
ComponentInitialization {
     // Load internal plugins under kernel module
     logger.debug("Loading internal plugins")
     val internalPlugins = pluginManager.initialize()
-    logger.info(internalPlugins.size + " internal plugins loaded")
+    val internalPluginsSize = internalPlugins.size
+    logger.info(s"$internalPluginsSize internal plugins loaded")
 
     // Load external plugins if provided
     logger.debug("Loading external plugins")
     val externalPlugins = if (magicUrlArray.nonEmpty) {
       val externalPlugins = pluginManager.loadPlugins(
-        magicUrlArray.map(_.getFile).map(new File(_)): _*
+        magicUrlArray.map(_.getFile).map(new File(_)).toSeq: _*
       )
       pluginManager.initializePlugins(externalPlugins)
       externalPlugins
     } else Nil
-    logger.info(externalPlugins.size + " external plugins loaded")
+    logger.info(s"${externalPlugins.size} external plugins loaded")
   }
 }
diff --git a/kernel/src/main/scala/org/apache/toree/kernel/api/Kernel.scala 
b/kernel/src/main/scala/org/apache/toree/kernel/api/Kernel.scala
index cb90b81e..3b410b6a 100644
--- a/kernel/src/main/scala/org/apache/toree/kernel/api/Kernel.scala
+++ b/kernel/src/main/scala/org/apache/toree/kernel/api/Kernel.scala
@@ -138,9 +138,9 @@ class Kernel (
     val (success, result) = output
     success match {
       case Results.Success =>
-        (true, result.left.get)
+        (true, result.swap.toOption.get)
       case Results.Error =>
-        (false, Map("text/plain" -> result.right.getOrElse("").toString))
+        (false, Map("text/plain" -> result.getOrElse("").toString))
       case Results.Aborted =>
         (false, Map("text/plain" -> "Aborted!"))
       case Results.Incomplete =>
@@ -413,7 +413,7 @@ class Kernel (
 
     if(config.getString("spark_context_initialization_mode") == "eager") {
       // explicitly enable eager initialization of spark context
-      SparkSession.builder.config(defaultSparkConf).getOrCreate
+      SparkSession.builder().config(defaultSparkConf).getOrCreate()
     } else {
       // default lazy initialization of spark context
       defaultSparkConf.getOption("spark.master") match {
@@ -425,7 +425,7 @@ class Kernel (
           // default timeout is 100ms and it is specified in reference.conf.
           import scala.concurrent.ExecutionContext.Implicits.global
           val sessionFuture = Future {
-            SparkSession.builder.config(defaultSparkConf).getOrCreate
+            SparkSession.builder().config(defaultSparkConf).getOrCreate()
           }
 
           try {
@@ -441,7 +441,7 @@ class Kernel (
           }
 
         case _ =>
-          SparkSession.builder.config(defaultSparkConf).getOrCreate
+          SparkSession.builder().config(defaultSparkConf).getOrCreate()
       }
     }
   }
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/dispatch/StatusDispatch.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/dispatch/StatusDispatch.scala
index 7a793e78..2e59517d 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/dispatch/StatusDispatch.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/dispatch/StatusDispatch.scala
@@ -26,7 +26,7 @@ import org.apache.toree.utils.LogLike
 import play.api.libs.json.Json
 
 class StatusDispatch(actorLoader: ActorLoader) extends Actor with LogLike {
-  private def sendStatusMessage(kernelStatus: KernelStatusType, parentHeader: 
Header) {
+  private def sendStatusMessage(kernelStatus: KernelStatusType, parentHeader: 
Header): Unit = {
     //  Create the status message and send it to the relay
     val km : KernelMessage = KMBuilder()
       .withIds(Seq(MessageType.Outgoing.Status.toString.getBytes))
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommCloseHandler.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommCloseHandler.scala
index 7f27177c..2e7e6267 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommCloseHandler.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommCloseHandler.scala
@@ -78,7 +78,7 @@ class CommCloseHandler(
     }
   }
 
-  private def handleParseError(invalid: Seq[(JsPath, 
Seq[JsonValidationError])]) = {
+  private def handleParseError(invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]): Unit = {
     // TODO: Determine proper response for a parse failure
     logger.warn("Parse error for Comm Close! Not responding!")
   }
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommInfoRequestHandler.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommInfoRequestHandler.scala
index eeda7183..8018a9a1 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommInfoRequestHandler.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommInfoRequestHandler.scala
@@ -40,10 +40,10 @@ class CommInfoRequestHandler(
   extends BaseHandler(actorLoader) with MessageLogSupport
 {
 
-  def buildCommMap(targetName: String) = {
+  def buildCommMap(targetName: String): Map[UUID, Map[UUID, UUID]] = {
     commStorage.getCommIdsFromTarget(targetName) match {
       case Some(commVector) => {
-        commVector.map(x => Map(x -> Map("target_name" -> 
targetName))).flatten.toMap
+        commVector.flatMap(x => Map(x -> Map("target_name" -> 
targetName))).toMap
       }
       case _ => {
         Map()
@@ -53,14 +53,15 @@ class CommInfoRequestHandler(
 
   override def process(kernelMessage: KernelMessage): Future[_] = Future {
     logKernelMessageAction("Initiating CommInfo request for", kernelMessage)
-
-    val commMap = (Json.parse(kernelMessage.contentString) \ 
"target_name").asOpt[String] match {
+    import scala.language.existentials
+    val commMap: Map[String, Map[String, String]] =
+      (Json.parse(kernelMessage.contentString) \ "target_name").asOpt[String] 
match {
       case Some(targetName) => {
         buildCommMap(targetName)
       }
       case None => {
-        //target_name is missing from the kernel message so return all comms 
over every target
-        commStorage.getTargets().map(buildCommMap(_)).reduce(_ ++ _)
+        // target_name is missing from the kernel message so return all comms 
over every target
+        commStorage.getTargets().map(buildCommMap).reduce(_ ++ _)
       }
     }
     val commInfoReply = CommInfoReplyOk(commMap.asInstanceOf[Map[String, 
Map[String, String]]])
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommMsgHandler.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommMsgHandler.scala
index 37e95896..ea4ffd5c 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommMsgHandler.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommMsgHandler.scala
@@ -78,7 +78,7 @@ class CommMsgHandler(
     }
   }
 
-  private def handleParseError(invalid: Seq[(JsPath, 
Seq[JsonValidationError])]) = {
+  private def handleParseError(invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]): Unit = {
     // TODO: Determine proper response for a parse failure
     logger.warn("Parse error for Comm Msg! Not responding!")
   }
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommOpenHandler.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommOpenHandler.scala
index 6590eefa..08a33cbe 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommOpenHandler.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/CommOpenHandler.scala
@@ -82,7 +82,7 @@ class CommOpenHandler(
     }
   }
 
-  private def handleParseError(invalid: Seq[(JsPath, 
Seq[JsonValidationError])]) = {
+  private def handleParseError(invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]): Unit = {
     // TODO: Determine proper response for a parse failure
     logger.warn("Parse error for Comm Open! Not responding!")
   }
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/ExecuteRequestHandler.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/ExecuteRequestHandler.scala
index 4f2fd5e7..82465b1d 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/ExecuteRequestHandler.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/ExecuteRequestHandler.scala
@@ -131,7 +131,7 @@ class ExecuteRequestHandler(
       }
     }
 
-    def parseErrorHandler(invalid: Seq[(JsPath, Seq[JsonValidationError])]) = {
+    def parseErrorHandler(invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) = {
       val errs = invalid.map (e => s"JSPath ${e._1} has error ${e._2}").toList
       logger.error(s"Validation errors when parsing ExecuteRequest: ${errs}")
       val replyError: ExecuteReply = ExecuteReplyError(
@@ -161,7 +161,7 @@ class ExecuteRequestHandler(
    */
   def relayErrorMessages(relayActor: ActorSelection,
                          replyError: ExecuteReply,
-                         skeletonBuilder: KMBuilder) {
+                         skeletonBuilder: KMBuilder): Unit = {
     val executeReplyMsg = skeletonBuilder
       .withHeader(MessageType.Outgoing.ExecuteReply)
       .withMetadata(Metadata("status" -> replyError.status))
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/InputRequestReplyHandler.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/InputRequestReplyHandler.scala
index 94595d1c..33e290f4 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/InputRequestReplyHandler.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/handler/InputRequestReplyHandler.scala
@@ -53,7 +53,7 @@ class InputRequestReplyHandler(
       // Is this an outgoing message to request data?
       if (kernelMessageType == inputRequestType) {
         val session = kernelMessage.parentHeader.session
-        responseMap(session) = sender
+        responseMap(session) = sender()
 
         logger.debug("Associating input request with session " + session)
 
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/InterpreterActor.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/InterpreterActor.scala
index c95e1059..dd8eef30 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/InterpreterActor.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/InterpreterActor.scala
@@ -63,7 +63,7 @@ class InterpreterActor(
   /**
    * Initializes all child actors performing tasks for the interpreter.
    */
-  override def preStart = {
+  override def preStart() = {
     executeRequestTask = interpreterTaskFactory.ExecuteRequestTask(
       context, InterpreterChildActorType.ExecuteRequestTask.toString)
     completeCodeTask = interpreterTaskFactory.CodeCompleteTask(
@@ -85,7 +85,7 @@ class InterpreterActor(
             ex.getLocalizedMessage,
             ex.getStackTrace.map(_.toString).toList)
           )
-      } pipeTo sender
+      } pipeTo sender()
     case (completeRequest: CompleteRequest) =>
       logger.debug(s"InterpreterActor requesting code completion for code " +
         s"${completeRequest.code}")
@@ -98,7 +98,7 @@ class InterpreterActor(
             ex.getLocalizedMessage,
             ex.getStackTrace.map(_.toString).toList)
           )
-      } pipeTo sender
+      } pipeTo sender()
     case (isCompleteRequest: IsCompleteRequest) =>
       logger.debug(s"InterpreterActor requesting is complete code 
${isCompleteRequest.code}")
       (isCompleteTask ? isCompleteRequest) recover {
@@ -106,6 +106,6 @@ class InterpreterActor(
           logger.warn(s"Could not determine completeness for code 
${isCompleteRequest.code}: " +
             s"${ex.getMessage}")
           Left(IsCompleteReply("unknown", ""))
-      } pipeTo sender
+      } pipeTo sender()
   }
 }
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/CodeCompleteTaskActor.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/CodeCompleteTaskActor.scala
index dfe26c32..7cc3a942 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/CodeCompleteTaskActor.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/CodeCompleteTaskActor.scala
@@ -34,8 +34,8 @@ class CodeCompleteTaskActor(interpreter: Interpreter)
   override def receive: Receive = {
     case completeRequest: CompleteRequest =>
       logger.debug("Invoking the interpreter completion")
-      sender ! interpreter.completion(completeRequest.code, 
completeRequest.cursor_pos)
+      sender() ! interpreter.completion(completeRequest.code, 
completeRequest.cursor_pos)
     case _ =>
-      sender ! "Unknown message" // TODO: Provide a failure message type to be 
passed around?
+      sender() ! "Unknown message" // TODO: Provide a failure message type to 
be passed around?
   }
 }
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/ExecuteRequestTaskActor.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/ExecuteRequestTaskActor.scala
index 0905871f..d32220c7 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/ExecuteRequestTaskActor.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/ExecuteRequestTaskActor.scala
@@ -82,25 +82,25 @@ class ExecuteRequestTaskActor(interpreter: Interpreter) 
extends Actor with LogLi
         logger.debug(s"Interpreter execution result was ${success}")
         success match {
           case Results.Success =>
-            val output = result.left.get
-            sender ! Left(output)
+            val output = result.swap.toOption.get
+            sender() ! Left(output)
           case Results.Error =>
-            val error = result.right.get
-            sender ! Right(error)
+            val error = result.toOption.get
+            sender() ! Right(error)
           case Results.Aborted =>
-            sender ! Right(new ExecuteAborted)
+            sender() ! Right(new ExecuteAborted)
           case Results.Incomplete =>
             // If we get an incomplete it's most likely a syntax error, so
             // let the user know.
-            sender ! Right(new ExecuteError("Syntax Error.", "", List()))
+            sender() ! Right(new ExecuteError("Syntax Error.", "", List()))
         }
       } else {
         // If we get empty code from a cell then just return ExecuteReplyOk
-        sender ! Left("")
+        sender() ! Left("")
       }
     case unknownValue =>
       logger.warn(s"Received unknown message type ${unknownValue}")
-      sender ! "Unknown message" // TODO: Provide a failure message type to be 
passed around?
+      sender() ! "Unknown message" // TODO: Provide a failure message type to 
be passed around?
   }
 
   private def buildOutputStream(
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/IsCompleteTaskActor.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/IsCompleteTaskActor.scala
index 3bfef8e2..78a66806 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/IsCompleteTaskActor.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/interpreter/tasks/IsCompleteTaskActor.scala
@@ -34,8 +34,8 @@ class IsCompleteTaskActor(interpreter: Interpreter)
   override def receive: Receive = {
     case req: IsCompleteRequest =>
       logger.debug("Invoking the interpreter completion")
-      sender ! interpreter.isComplete(req.code)
+      sender() ! interpreter.isComplete(req.code)
     case _ =>
-      sender ! "Unknown message" // TODO: Provide a failure message type to be 
passed around?
+      sender() ! "Unknown message" // TODO: Provide a failure message type to 
be passed around?
   }
 }
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/kernel/Utilities.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/kernel/Utilities.scala
index 6dd1224e..da89a1bc 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/kernel/Utilities.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/kernel/Utilities.scala
@@ -26,6 +26,7 @@ import org.apache.toree.utils.LogLike
 import play.api.libs.json.JsonValidationError
 import play.api.libs.json.{JsPath, Json, Reads}
 
+import scala.collection.mutable
 import scala.concurrent.duration._
 
 object Utilities extends LogLike {
@@ -77,21 +78,21 @@ object Utilities extends LogLike {
   }
 
   implicit def KernelMessageToZMQMessage(kernelMessage : KernelMessage) : 
ZMQMessage = {
-    val frames: scala.collection.mutable.ListBuffer[ByteString] = 
scala.collection.mutable.ListBuffer()
-    kernelMessage.ids.map((id : Array[Byte]) => frames += ByteString.apply(id) 
)
+    val frames: mutable.ListBuffer[ByteString] = mutable.ListBuffer()
+    kernelMessage.ids.map((id: Array[Byte]) => frames += ByteString.apply(id))
     frames += "<IDS|MSG>"
     frames += kernelMessage.signature
     frames += Json.toJson(kernelMessage.header).toString()
     frames += Json.toJson(kernelMessage.parentHeader).toString()
     frames += Json.toJson(kernelMessage.metadata).toString
     frames += kernelMessage.contentString
-    ZMQMessage(frames  : _*)
+    ZMQMessage(frames.toSeq : _*)
   }
 
   def parseAndHandle[T, U](json: String, reads: Reads[T],
                            handler: T => U) : U = {
     parseAndHandle(json, reads, handler,
-      (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => {
+      (invalid: collection.Seq[(JsPath, collection.Seq[JsonValidationError])]) 
=> {
         logger.error(s"Could not parse JSON, ${json}")
         throw new Throwable(s"Could not parse JSON, ${json}")
       }
@@ -100,7 +101,7 @@ object Utilities extends LogLike {
 
   def parseAndHandle[T, U](json: String, reads: Reads[T],
                            handler: T => U,
-                           errHandler: Seq[(JsPath, Seq[JsonValidationError])] 
=> U) : U = {
+                           errHandler: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])] => U) : U = {
     Json.parse(json).validate[T](reads).fold(
       errHandler,
       (content: T) => handler(content)
diff --git 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/relay/ExecuteRequestRelay.scala
 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/relay/ExecuteRequestRelay.scala
index 4284a0a1..d00923c1 100644
--- 
a/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/relay/ExecuteRequestRelay.scala
+++ 
b/kernel/src/main/scala/org/apache/toree/kernel/protocol/v5/relay/ExecuteRequestRelay.scala
@@ -75,13 +75,13 @@ case class ExecuteRequestRelay(
     future: Future[Either[ExecuteOutput, ExecuteFailure]]
   ): Future[(ExecuteReply, ExecuteResult)] = future.map { value =>
     if (value.isLeft) {
-      val data = value.left.get
+      val data = value.swap.toOption.get
       (
         ExecuteReplyOk(1, Some(Payloads()), Some(UserExpressions())),
         ExecuteResult(1, data, Metadata())
       )
     } else {
-      failureMatch(value.right.get)
+      failureMatch(value.toOption.get)
     }
   }
 
diff --git a/kernel/src/main/scala/org/apache/toree/magic/builtin/AddDeps.scala 
b/kernel/src/main/scala/org/apache/toree/magic/builtin/AddDeps.scala
index 913d64e2..466dce10 100644
--- a/kernel/src/main/scala/org/apache/toree/magic/builtin/AddDeps.scala
+++ b/kernel/src/main/scala/org/apache/toree/magic/builtin/AddDeps.scala
@@ -112,7 +112,7 @@ class AddDeps extends LineMagic with IncludeInterpreter
       )
 
       // pass the new Jars to the kernel
-      kernel.addJars(uris.filter(_.getPath.endsWith(".jar")): _*)
+      kernel.addJars(uris.filter(_.getPath.endsWith(".jar")).toSeq: _*)
     } else {
       printHelp(printStream, """%AddDeps my.company artifact-id version""")
     }
diff --git 
a/kernel/src/main/scala/org/apache/toree/magic/builtin/Dataframe.scala 
b/kernel/src/main/scala/org/apache/toree/magic/builtin/Dataframe.scala
index 3f00f820..bf51390b 100644
--- a/kernel/src/main/scala/org/apache/toree/magic/builtin/Dataframe.scala
+++ b/kernel/src/main/scala/org/apache/toree/magic/builtin/Dataframe.scala
@@ -84,7 +84,7 @@ class DataFrame extends CellMagic with 
IncludeKernelInterpreter
   }
   
   private def outputTypeToMimeType(): String = {
-    outputTypeMap.getOrElse(outputType, MIMEType.PlainText)
+    outputTypeMap.getOrElse(outputType(), MIMEType.PlainText)
   }
   
   private def convertToJson(rddCode: String): CellMagicOutput = {
@@ -95,20 +95,20 @@ class DataFrame extends CellMagic with 
IncludeKernelInterpreter
         kernelInterpreter.read(rddVarName).map(variableVal => {
           _dataFrameConverter.convert(
             variableVal.asInstanceOf[org.apache.spark.sql.DataFrame],
-            outputType,
-            limit
+            outputType(),
+            limit()
           ).map(output =>
-            CellMagicOutput(outputTypeToMimeType -> output)
+            CellMagicOutput(outputTypeToMimeType() -> output)
           ).get
         }).getOrElse(CellMagicOutput(MIMEType.PlainText -> 
DataFrameResponses.NoVariableFound(rddVarName)))
       case Results.Aborted =>
-        logger.error(DataFrameResponses.ErrorMessage(outputType, 
DataFrameResponses.MagicAborted))
+        logger.error(DataFrameResponses.ErrorMessage(outputType(), 
DataFrameResponses.MagicAborted))
         CellMagicOutput(
-          MIMEType.PlainText -> DataFrameResponses.ErrorMessage(outputType, 
DataFrameResponses.MagicAborted)
+          MIMEType.PlainText -> DataFrameResponses.ErrorMessage(outputType(), 
DataFrameResponses.MagicAborted)
         )
       case Results.Error =>
-        val error = message.right.get.asInstanceOf[ExecuteError]
-        val errorMessage = DataFrameResponses.ErrorMessage(outputType, 
error.value)
+        val error = message.toOption.get.asInstanceOf[ExecuteError]
+        val errorMessage = DataFrameResponses.ErrorMessage(outputType(), 
error.value)
         logger.error(errorMessage)
         CellMagicOutput(MIMEType.PlainText -> errorMessage)
       case Results.Incomplete =>
diff --git 
a/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala 
b/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala
index ba75daa2..5ea98c3c 100644
--- a/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala
+++ b/kernel/src/main/scala/org/apache/toree/utils/DataFrameConverter.scala
@@ -21,6 +21,8 @@ import org.apache.spark.sql.{Dataset, Row}
 import org.apache.toree.plugins.Plugin
 import play.api.libs.json.{JsObject, Json}
 
+import scala.collection.immutable
+import scala.collection.mutable
 import scala.util.Try
 import org.apache.toree.plugins.annotations.Init
 
@@ -84,7 +86,8 @@ object DataFrameConverter {
   def fieldToString(any: Any): String =
     any match {
       case null => "null"
-      case seq: Seq[_] => seq.mkString("[", ", ", "]")
+      case seq: immutable.Seq[_] => seq.mkString("[", ", ", "]")
+      case seq: mutable.Seq[_] => seq.mkString("[", ", ", "]")
       case _ => any.toString
     }
 
diff --git 
a/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/kernel/socket/SocketConfigSpec.scala
 
b/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/kernel/socket/SocketConfigSpec.scala
index f276ed13..c516aeab 100644
--- 
a/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/kernel/socket/SocketConfigSpec.scala
+++ 
b/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/kernel/socket/SocketConfigSpec.scala
@@ -71,7 +71,7 @@ class SocketConfigSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = socketConfigJson.validate[SocketConfig]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: SocketConfig) => valid
         ) should be (socketConfig)
       }
diff --git 
a/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/stream/KernelOuputStreamSpec.scala
 
b/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/stream/KernelOuputStreamSpec.scala
index 44b42932..7881eb0c 100644
--- 
a/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/stream/KernelOuputStreamSpec.scala
+++ 
b/kernel/src/test/scala/org/apache/toree/kernel/protocol/v5/stream/KernelOuputStreamSpec.scala
@@ -239,7 +239,7 @@ class KernelOuputStreamSpec
         val message = kernelOutputRelayProbe
           .receiveOne(MaxAkkaTestTimeout).asInstanceOf[KernelMessage]
         
-        message.ids(0).deep should equal 
(MessageType.Outgoing.Stream.toString.getBytes.deep)
+        message.ids.head.toIndexedSeq should equal 
(MessageType.Outgoing.Stream.toString.getBytes.toIndexedSeq)
       }
 
       it("should set the message type in the header of the kernel message to 
an execute_result") {
diff --git a/kernel/src/test/scala/test/utils/DummyInterpreter.scala 
b/kernel/src/test/scala/test/utils/DummyInterpreter.scala
index d7c7fab5..2ef0434c 100644
--- a/kernel/src/test/scala/test/utils/DummyInterpreter.scala
+++ b/kernel/src/test/scala/test/utils/DummyInterpreter.scala
@@ -17,13 +17,12 @@
 
 package test.utils
 
-import java.net.URL
-
 import org.apache.toree.interpreter.Results.Result
 import org.apache.toree.interpreter.{ExecuteFailure, ExecuteOutput, 
Interpreter, LanguageInfo}
 import org.apache.toree.kernel.api.KernelLike
 
-import scala.tools.nsc.interpreter.{InputStream, OutputStream}
+import java.io.{InputStream, OutputStream}
+import java.net.URL
 
 class DummyInterpreter(kernel: KernelLike) extends Interpreter {
   /**
diff --git a/macros/project/plugins.sbt b/macros/project/plugins.sbt
index 982bb4ed..10643043 100644
--- a/macros/project/plugins.sbt
+++ b/macros/project/plugins.sbt
@@ -16,4 +16,6 @@
  */
 resolvers += Resolver.sonatypeRepo("releases")
 
-addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross 
CrossVersion.full)
+if (scalaBinaryVersion.value == "2.12") {
+  addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross 
CrossVersion.full)
+}
diff --git 
a/plugins/src/main/scala/org/apache/toree/plugins/PluginManager.scala 
b/plugins/src/main/scala/org/apache/toree/plugins/PluginManager.scala
index 25deefed..8162f19e 100644
--- a/plugins/src/main/scala/org/apache/toree/plugins/PluginManager.scala
+++ b/plugins/src/main/scala/org/apache/toree/plugins/PluginManager.scala
@@ -96,7 +96,7 @@ class PluginManager(
     // Search for plugins in our new paths, then add loaded plugins to list
     // NOTE: Iterator returned from plugin searcher, so avoid building a
     //       large collection by performing all tasks together
-    @volatile var newPlugins = collection.mutable.Seq[Plugin]()
+    @volatile var newPlugins = Seq[Plugin]()
     pluginSearcher.search(paths: _*).foreach(ci => {
       // Add valid path to class loader
       pluginClassLoader.addURL(ci.location.toURI.toURL)
@@ -110,7 +110,7 @@ class PluginManager(
       // Load the plugin using the given name and class
       loadPlugin(ci.name, klass).foreach(newPlugins :+= _)
     })
-    newPlugins
+    newPlugins.toSeq
   }
 
   /**
diff --git a/plugins/src/main/scala/org/apache/toree/plugins/PluginMethod.scala 
b/plugins/src/main/scala/org/apache/toree/plugins/PluginMethod.scala
index 50aafe34..3b5a554f 100644
--- a/plugins/src/main/scala/org/apache/toree/plugins/PluginMethod.scala
+++ b/plugins/src/main/scala/org/apache/toree/plugins/PluginMethod.scala
@@ -110,11 +110,11 @@ case class PluginMethod(
     } }
 
     // Validate arguments
-    val arguments: Seq[AnyRef] = dependencies.map(_.value.asInstanceOf[AnyRef])
+    val arguments: Seq[AnyRef] = 
dependencies.map(_.value.asInstanceOf[AnyRef]).toSeq
 
     // Invoke plugin method
-    method.invoke(plugin, arguments: _*)
-  }).map(SuccessPluginMethodResult.apply(this, _: AnyRef)).recover {
+    method.invoke(plugin, arguments.toSeq: _*)
+  }).map(SuccessPluginMethodResult.apply(this, _: Object)).recover {
     case i: InvocationTargetException =>
       FailurePluginMethodResult(this, i.getTargetException)
     case throwable: Throwable =>
diff --git 
a/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala 
b/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala
index b63545d2..75fa6f92 100644
--- a/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala
+++ b/plugins/src/main/scala/org/apache/toree/plugins/PluginSearcher.scala
@@ -120,7 +120,7 @@ class PluginSearcher {
       }
     }
 
-    classes.values.toIterator
+    classes.values.iterator
       .filter(_.isConcrete)
       .filter(c => classMatches(Seq(c)))
   }
diff --git a/macros/project/plugins.sbt 
b/plugins/src/test/scala-2.12/org/apache/toree/plugins/ClassFinderHelper.scala
similarity index 80%
copy from macros/project/plugins.sbt
copy to 
plugins/src/test/scala-2.12/org/apache/toree/plugins/ClassFinderHelper.scala
index 982bb4ed..81b7c95e 100644
--- a/macros/project/plugins.sbt
+++ 
b/plugins/src/test/scala-2.12/org/apache/toree/plugins/ClassFinderHelper.scala
@@ -14,6 +14,14 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-resolvers += Resolver.sonatypeRepo("releases")
 
-addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross 
CrossVersion.full)
+package org.apache.toree.plugins
+
+import org.clapper.classutil.ClassInfo
+
+trait ClassFinderHelper {
+
+  def wrappedGetClassesReturnVal(classes: Seq[ClassInfo]): Object = {
+    classes.toStream
+  }
+}
diff --git a/macros/project/plugins.sbt 
b/plugins/src/test/scala-2.13/org/apache/toree/plugins/ClassFinderHelper.scala
similarity index 79%
copy from macros/project/plugins.sbt
copy to 
plugins/src/test/scala-2.13/org/apache/toree/plugins/ClassFinderHelper.scala
index 982bb4ed..ea725155 100644
--- a/macros/project/plugins.sbt
+++ 
b/plugins/src/test/scala-2.13/org/apache/toree/plugins/ClassFinderHelper.scala
@@ -14,6 +14,14 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-resolvers += Resolver.sonatypeRepo("releases")
 
-addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross 
CrossVersion.full)
+package org.apache.toree.plugins
+
+import org.clapper.classutil.ClassInfo
+
+trait ClassFinderHelper {
+
+  def wrappedGetClassesReturnVal(classes: Seq[ClassInfo]): Object = {
+    LazyList.from(classes)
+  }
+}
diff --git a/macros/project/plugins.sbt 
b/plugins/src/test/scala-2.13/org/apache/toree/plugins/dependencies/ClassLoaderHelper.scala
similarity index 68%
copy from macros/project/plugins.sbt
copy to 
plugins/src/test/scala-2.13/org/apache/toree/plugins/dependencies/ClassLoaderHelper.scala
index 982bb4ed..20e18565 100644
--- a/macros/project/plugins.sbt
+++ 
b/plugins/src/test/scala-2.13/org/apache/toree/plugins/dependencies/ClassLoaderHelper.scala
@@ -14,6 +14,16 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-resolvers += Resolver.sonatypeRepo("releases")
+package org.apache.toree.plugins.dependencies
 
-addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross 
CrossVersion.full)
+import java.net.URL
+import java.lang.{ClassLoader => JClassLoader}
+
+import scala.reflect.internal.util.ScalaClassLoader
+
+object ClassLoaderHelper {
+
+  def URLClassLoader(urls: Seq[URL], parent: JClassLoader): 
ScalaClassLoader.URLClassLoader = {
+    new scala.reflect.internal.util.ScalaClassLoader.URLClassLoader(urls, 
parent)
+  }
+}
diff --git 
a/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala 
b/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala
index 36e46ee4..6c90793f 100644
--- a/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala
+++ b/plugins/src/test/scala/org/apache/toree/plugins/PluginSearcherSpec.scala
@@ -17,8 +17,9 @@
 package org.apache.toree.plugins
 
 import java.io.File
+import scala.collection.immutable
 
-import org.clapper.classutil.{Modifier, ClassFinder}
+import org.clapper.classutil.{ClassFinder, Modifier}
 import org.scalatestplus.mockito.MockitoSugar
 import org.scalatest.OneInstancePerTest
 import org.scalatest.funspec.AnyFunSpec
@@ -27,8 +28,9 @@ import org.scalatest.matchers.should.Matchers
 import org.mockito.Mockito._
 import test.utils.TestClassInfo
 
+
 class PluginSearcherSpec extends AnyFunSpec with Matchers
-  with OneInstancePerTest with MockitoSugar
+  with OneInstancePerTest with MockitoSugar with ClassFinderHelper
 {
   private val mockClassFinder = mock[ClassFinder]
   private val pluginSearcher = new PluginSearcher {
@@ -77,7 +79,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins directly extending the Plugin class") {
         val expected = directPluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.internal.map(_.name)
 
@@ -87,7 +89,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins directly extending the Plugin trait") {
         val expected = directAsInterfacePluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.internal.map(_.name)
 
@@ -97,7 +99,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins indirectly extending the Plugin class") {
         val expected = indirectPluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.internal.map(_.name)
 
@@ -107,7 +109,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins indirectly extending the Plugin trait") {
         val expected = indirectAsInterfacePluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.internal.map(_.name)
 
@@ -120,7 +122,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
           traitPluginClassInfo.name
         )
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.internal.map(_.name)
 
@@ -132,7 +134,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins directly extending the Plugin class") {
         val expected = directPluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.search().map(_.name).toSeq
 
@@ -142,7 +144,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins directly extending the Plugin trait") {
         val expected = directAsInterfacePluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.search().map(_.name).toSeq
 
@@ -152,7 +154,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins indirectly extending the Plugin class") {
         val expected = indirectPluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.search().map(_.name).toSeq
 
@@ -162,7 +164,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
       it("should find any plugins indirectly extending the Plugin trait") {
         val expected = indirectAsInterfacePluginClassInfo.name
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.search().map(_.name).toSeq
 
@@ -175,7 +177,7 @@ class PluginSearcherSpec extends AnyFunSpec with Matchers
           traitPluginClassInfo.name
         )
 
-        doReturn(classInfos.toStream, Nil: 
_*).when(mockClassFinder).getClasses()
+        doReturn(wrappedGetClassesReturnVal(classInfos), Nil: 
_*).when(mockClassFinder).getClasses()
 
         val actual = pluginSearcher.search().map(_.name).toSeq
 
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 44754e6e..bd3e2046 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -30,4 +30,4 @@ addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0")
 addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1")
 
 // Provides the ability to generate dependency graphs
-addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.10.0-RC1")
+addDependencyTreePlugin
diff --git a/protocol/src/main/scala/org/apache/toree/comm/CommWriter.scala 
b/protocol/src/main/scala/org/apache/toree/comm/CommWriter.scala
index 8a668a86..ef146a1b 100644
--- a/protocol/src/main/scala/org/apache/toree/comm/CommWriter.scala
+++ b/protocol/src/main/scala/org/apache/toree/comm/CommWriter.scala
@@ -108,5 +108,5 @@ abstract class CommWriter(
    */
   protected[comm] def sendCommKernelMessage[
     T <: KernelMessageContent with CommContent
-  ](commContent: T)
+  ](commContent: T): Unit
 }
diff --git 
a/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KMBuilder.scala 
b/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KMBuilder.scala
index ccc69a30..6acdeb8d 100644
--- 
a/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KMBuilder.scala
+++ 
b/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KMBuilder.scala
@@ -39,7 +39,7 @@ import 
org.apache.toree.kernel.protocol.v5.MessageType.MessageType
   *               .withContentString("content").build
 **/
 case class KMBuilder(km: KernelMessage = KernelMessage(
-                                            ids           = Seq(),
+                                            ids           = Seq.empty.toSeq,
                                             signature     = "",
                                             header        = 
HeaderBuilder.empty,
                                             parentHeader  = 
HeaderBuilder.empty,
@@ -49,7 +49,7 @@ case class KMBuilder(km: KernelMessage = KernelMessage(
   require(km != null)
 
   def withIds(newVal: Seq[Array[Byte]]) : KMBuilder =
-    KMBuilder(this.km.copy(ids = newVal))
+    KMBuilder(this.km.copy(ids = newVal.toSeq))
 
   def withSignature(newVal: String) : KMBuilder =
     KMBuilder(this.km.copy(signature = newVal))
diff --git 
a/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KernelMessage.scala
 
b/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KernelMessage.scala
index 8eeb5368..40a9354d 100644
--- 
a/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KernelMessage.scala
+++ 
b/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/KernelMessage.scala
@@ -17,6 +17,8 @@
 
 package org.apache.toree.kernel.protocol.v5
 
+import java.util.Objects
+
 case class KernelMessage(
   ids: Seq[Array[Byte]],
   signature: String,
@@ -26,13 +28,13 @@ case class KernelMessage(
   contentString: String
 ) 
 {
-  override def equals ( o: Any ) = o match {
+  override def equals(o: Any): Boolean = o match {
     case km: KernelMessage => {
       var equal = ( ids.length == km.ids.length && signature == km.signature 
&& header == km.header && parentHeader == km.parentHeader && metadata == 
km.metadata && contentString == km.contentString )
       var i = ids.length
       while ( equal && ( 0 < i ) ) {
         i = i - 1
-        equal = (ids(i).deep == km.ids(i).deep )
+        equal = Objects.deepEquals(ids(i), km.ids(i))
       }
       equal = true
       equal
diff --git 
a/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/package.scala 
b/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/package.scala
index 466a3ec9..45c06063 100644
--- a/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/package.scala
+++ b/protocol/src/main/scala/org/apache/toree/kernel/protocol/v5/package.scala
@@ -36,7 +36,7 @@ package object v5 {
         Map.empty
       } else {
         // triple quotes due https://github.com/scala/bug/issues/6476
-        kv.toMap.mapValues(v => Json.parse(s""""$v""""))
+        kv.toMap.mapValues(v => Json.parse(s""""$v"""")).toMap
       }
     }
 
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/HeaderSpec.scala 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/HeaderSpec.scala
index 798ed38b..92cf21c4 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/HeaderSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/HeaderSpec.scala
@@ -63,7 +63,7 @@ class HeaderSpec extends AnyFunSpec with Matchers {
         val headerResults = headerJson.validate[Header]
 
         headerResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: Header) => valid
         ) should be (header)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ClearOutputSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ClearOutputSpec.scala
index d951d7a9..50c01e8c 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ClearOutputSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ClearOutputSpec.scala
@@ -59,7 +59,7 @@ class ClearOutputSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = clearOutputJson.validate[ClearOutput]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ClearOutput) => valid
         ) should be (clearOutput)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommCloseSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommCloseSpec.scala
index c0ee54c7..815fd16e 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommCloseSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommCloseSpec.scala
@@ -60,7 +60,7 @@ class CommCloseSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = commCloseJson.validate[CommClose]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: CommClose) => valid
         ) should be (commClose)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommMsgSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommMsgSpec.scala
index a018f725..3e353b14 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommMsgSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommMsgSpec.scala
@@ -88,7 +88,7 @@ class CommMsgSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = commMsgJson.validate[CommMsg]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: CommMsg) => valid
         ) should be (commMsg)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommOpenSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommOpenSpec.scala
index 364a6b4d..b45b80ca 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommOpenSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CommOpenSpec.scala
@@ -61,7 +61,7 @@ class CommOpenSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = commOpenJson.validate[CommOpen]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: CommOpen) => valid
         ) should be (commOpen)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyErrorSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyErrorSpec.scala
index 47ddbf8a..63646c7c 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyErrorSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyErrorSpec.scala
@@ -61,7 +61,7 @@ class CompleteReplyErrorSpec extends AnyFunSpec with Matchers 
{
         val CompleteReplyOkResults = 
completeReplyErrorJson.validate[CompleteReplyError]
 
         CompleteReplyOkResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: CompleteReplyError) => valid
         ) should be (completeReplyError)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyOkSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyOkSpec.scala
index eecda707..95fbf7f4 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyOkSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplyOkSpec.scala
@@ -57,7 +57,7 @@ class CompleteReplyOkSpec extends AnyFunSpec with Matchers {
         val CompleteReplyOkResults = 
completeReplyOkJson.validate[CompleteReplyOk]
 
         CompleteReplyOkResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: CompleteReplyOk) => valid
         ) should be (completeReplyOk)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplySpec.scala
index a37a5a3f..c9754628 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteReplySpec.scala
@@ -64,7 +64,7 @@ class CompleteReplySpec extends AnyFunSpec with Matchers {
         val CompleteReplyResults = completeReplyJson.validate[CompleteReply]
 
         CompleteReplyResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: CompleteReply) => valid
         ) should be (completeReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteRequestSpec.scala
index afec715d..8e7a8f06 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/CompleteRequestSpec.scala
@@ -60,7 +60,7 @@ class CompleteRequestSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = 
completeRequestJson.validate[CompleteRequest]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: CompleteRequest) => valid
         ) should be (completeRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectReplySpec.scala
index 94c6dcee..e8a2f52d 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectReplySpec.scala
@@ -62,7 +62,7 @@ class ConnectReplySpec extends AnyFunSpec with Matchers {
         val ConnectReplyResults = connectReplyJson.validate[ConnectReply]
 
         ConnectReplyResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ConnectReply) => valid
         ) should be (connectReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectRequestSpec.scala
index 59318110..e3465b81 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ConnectRequestSpec.scala
@@ -55,7 +55,7 @@ class ConnectRequestSpec extends AnyFunSpec with Matchers {
         val ConnectRequestResults = connectRequestJson.validate[ConnectRequest]
 
         ConnectRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ConnectRequest) => valid
         ) should be (connectRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/DisplayDataSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/DisplayDataSpec.scala
index 20610429..0e45087d 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/DisplayDataSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/DisplayDataSpec.scala
@@ -62,7 +62,7 @@ class DisplayDataSpec extends AnyFunSpec with Matchers {
         val displayDataResults = displayDataJson.validate[DisplayData]
 
         displayDataResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: DisplayData) => valid
         ) should be (displayData)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ErrorContentSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ErrorContentSpec.scala
index ac9b57a4..9095097f 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ErrorContentSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ErrorContentSpec.scala
@@ -58,7 +58,7 @@ class ErrorContentSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = errorJson.validate[ErrorContent]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ErrorContent) => valid
         ) should be (error)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteInputSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteInputSpec.scala
index 5a360a47..7f2647f2 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteInputSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteInputSpec.scala
@@ -60,7 +60,7 @@ class ExecuteInputSpec extends AnyFunSpec with Matchers {
         val executeInputResults = executeInputJson.validate[ExecuteInput]
 
         executeInputResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ExecuteInput) => valid
         ) should be (executeInput)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyAbortSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyAbortSpec.scala
index 9669f2b8..33bd0f08 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyAbortSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyAbortSpec.scala
@@ -55,7 +55,7 @@ class ExecuteReplyAbortSpec extends AnyFunSpec with Matchers {
         val ExecuteReplyAbortResults = 
executeReplyAbortJson.validate[ExecuteReplyAbort]
 
         ExecuteReplyAbortResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ExecuteReplyAbort) => valid
         ) should be (executeReplyAbort)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyErrorSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyErrorSpec.scala
index 4140e5de..df371be0 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyErrorSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyErrorSpec.scala
@@ -59,7 +59,7 @@ class ExecuteReplyErrorSpec extends AnyFunSpec with Matchers {
         val ExecuteReplyErrorResults = 
executeReplyErrorJson.validate[ExecuteReplyError]
 
         ExecuteReplyErrorResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ExecuteReplyError) => valid
         ) should be (executeReplyError)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyOkSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyOkSpec.scala
index bb235b01..8bf3ad2f 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyOkSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplyOkSpec.scala
@@ -58,7 +58,7 @@ class ExecuteReplyOkSpec extends AnyFunSpec with Matchers {
         val executeReplyOkResults = executeReplyOkJson.validate[ExecuteReplyOk]
 
         executeReplyOkResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ExecuteReplyOk) => valid
         ) should be (executeReplyOk)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplySpec.scala
index d7abd0f0..0016ad63 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteReplySpec.scala
@@ -61,7 +61,7 @@ class ExecuteReplySpec extends AnyFunSpec with Matchers {
         val executeReplyResults = executeReplyJson.validate[ExecuteReply]
 
         executeReplyResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ExecuteReply) => valid
         ) should be (executeReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteRequestSpec.scala
index 2678af28..e712b9c2 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteRequestSpec.scala
@@ -64,7 +64,7 @@ class ExecuteRequestSpec extends AnyFunSpec with Matchers {
         val executeRequestResults = executeRequestJson.validate[ExecuteRequest]
 
         executeRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ExecuteRequest) => valid
         ) should be (executeRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteResultSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteResultSpec.scala
index e5155e58..dd40618f 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteResultSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ExecuteResultSpec.scala
@@ -97,7 +97,7 @@ class ExecuteResultSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = executeResultJson.validate[ExecuteResult]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ExecuteResult) => valid
         ) should be (executeResult)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryReplySpec.scala
index 4eb13c85..c616c0ba 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryReplySpec.scala
@@ -62,7 +62,7 @@ class HistoryReplySpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = historyReplyJson.validate[HistoryReply]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: HistoryReply) => valid
         ) should be (historyReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryRequestSpec.scala
index b7934844..7d5cdcb3 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/HistoryRequestSpec.scala
@@ -67,7 +67,7 @@ class HistoryRequestSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = 
historyRequestJson.validate[HistoryRequest]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: HistoryRequest) => valid
         ) should be (historyRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputReplySpec.scala
index 5127d2d9..87d47a66 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputReplySpec.scala
@@ -60,7 +60,7 @@ class InputReplySpec extends AnyFunSpec with Matchers {
         val CompleteReplyResults = inputReplyJson.validate[InputReply]
 
         CompleteReplyResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: InputReply) => valid
         ) should be (inputReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputRequestSpec.scala
index ce98889b..9b7b657a 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InputRequestSpec.scala
@@ -60,7 +60,7 @@ class InputRequestSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = inputRequestJson.validate[InputRequest]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: InputRequest) => valid
         ) should be (inputRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyErrorSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyErrorSpec.scala
index dcbb4436..34ab89b2 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyErrorSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyErrorSpec.scala
@@ -59,7 +59,7 @@ class InspectReplyErrorSpec extends AnyFunSpec with Matchers {
         val InspectReplyErrorResults = 
inspectReplyErrorJson.validate[InspectReplyError]
 
         InspectReplyErrorResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: InspectReplyError) => valid
         ) should be (inspectReplyError)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyOkSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyOkSpec.scala
index d31f349a..a474cb3a 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyOkSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplyOkSpec.scala
@@ -57,7 +57,7 @@ class InspectReplyOkSpec extends AnyFunSpec with Matchers {
         val InspectReplyOkResults = inspectReplyOkJson.validate[InspectReplyOk]
 
         InspectReplyOkResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: InspectReplyOk) => valid
         ) should be (inspectReplyOk)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplySpec.scala
index 5d7ab6b7..4917cae6 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectReplySpec.scala
@@ -61,7 +61,7 @@ class InspectReplySpec extends AnyFunSpec with Matchers {
         val InspectReplyResults = inspectReplyJson.validate[InspectReply]
 
         InspectReplyResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: InspectReply) => valid
         ) should be (inspectReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectRequestSpec.scala
index 127e720f..3fb8aa83 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/InspectRequestSpec.scala
@@ -61,7 +61,7 @@ class InspectRequestSpec extends AnyFunSpec with Matchers {
         val InspectRequestResults = inspectRequestJson.validate[InspectRequest]
 
         InspectRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: InspectRequest) => valid
         ) should be (inspectRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoReplySpec.scala
index 4d562fbc..e10432db 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoReplySpec.scala
@@ -65,7 +65,7 @@ class KernelInfoReplySpec extends AnyFunSpec with Matchers {
         val kernelInfoReplyResults = 
kernelInfoReplyJson.validate[KernelInfoReply]
 
         kernelInfoReplyResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: KernelInfoReply) => valid
         ) should be (kernelInfoReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoRequestSpec.scala
index a35496d2..1f7cc241 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelInfoRequestSpec.scala
@@ -56,7 +56,7 @@ class KernelInfoRequestSpec extends AnyFunSpec with Matchers {
         val KernelInfoRequestResults = 
kernelInfoRequestJson.validate[KernelInfoRequest]
 
         KernelInfoRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: KernelInfoRequest) => valid
         ) should be (kernelInfoRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelStatusSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelStatusSpec.scala
index 5be37963..814283fc 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelStatusSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/KernelStatusSpec.scala
@@ -57,7 +57,7 @@ class KernelStatusSpec extends AnyFunSpec with Matchers {
         val kernelStatusResults = kernelStatusJson.validate[KernelStatus]
 
         kernelStatusResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: KernelStatus) => valid
         ) should be (kernelStatus)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownReplySpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownReplySpec.scala
index 32e451b4..185a2e15 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownReplySpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownReplySpec.scala
@@ -60,7 +60,7 @@ class ShutdownReplySpec extends AnyFunSpec with Matchers {
         val ShutdownReplyResults = shutdownReplyJson.validate[ShutdownReply]
 
         ShutdownReplyResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ShutdownReply) => valid
         ) should be (shutdownReply)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownRequestSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownRequestSpec.scala
index afa4798f..bd956416 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownRequestSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/ShutdownRequestSpec.scala
@@ -59,7 +59,7 @@ class ShutdownRequestSpec extends AnyFunSpec with Matchers {
         val ShutdownRequestResults = 
shutdownRequestJson.validate[ShutdownRequest]
 
         ShutdownRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: ShutdownRequest) => valid
         ) should be (shutdownRequest)
       }
diff --git 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/StreamContentSpec.scala
 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/StreamContentSpec.scala
index abd66003..aeaad77a 100644
--- 
a/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/StreamContentSpec.scala
+++ 
b/protocol/src/test/scala/org/apache/toree/kernel/protocol/v5/content/StreamContentSpec.scala
@@ -58,7 +58,7 @@ class StreamContentSpec extends AnyFunSpec with Matchers {
         val CompleteRequestResults = streamJson.validate[StreamContent]
 
         CompleteRequestResults.fold(
-          (invalid: Seq[(JsPath, Seq[JsonValidationError])]) => 
println("Failed!"),
+          (invalid: collection.Seq[(JsPath, 
collection.Seq[JsonValidationError])]) => println("Failed!"),
           (valid: StreamContent) => valid
         ) should be (stream)
       }
diff --git 
a/scala-interpreter/src/main/scala-2.13/org/apache/toree/kernel/interpreter/scala/ScalaInterpreterSpecific.scala
 
b/scala-interpreter/src/main/scala-2.13/org/apache/toree/kernel/interpreter/scala/ScalaInterpreterSpecific.scala
new file mode 100644
index 00000000..177eb54d
--- /dev/null
+++ 
b/scala-interpreter/src/main/scala-2.13/org/apache/toree/kernel/interpreter/scala/ScalaInterpreterSpecific.scala
@@ -0,0 +1,456 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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 org.apache.toree.kernel.interpreter.scala
+
+import java.io._
+import java.net.URL
+
+import org.apache.toree.global.StreamState
+import org.apache.toree.interpreter.imports.printers.{WrapperConsole, 
WrapperSystem}
+import org.apache.toree.interpreter.{ExecuteError, Interpreter}
+import scala.tools.nsc.interpreter._
+import scala.tools.nsc.interpreter.shell._
+import scala.language.postfixOps
+import scala.concurrent.Future
+import scala.tools.nsc.{Global, Settings, util}
+import scala.util.Try
+
+trait ScalaInterpreterSpecific extends SettingsProducerLike { this: 
ScalaInterpreter =>
+  private val ExecutionExceptionName = "lastException"
+
+  private[toree] var iMain: IMain = _
+  private var completer: Completion = _
+  private val exceptionHack = new ExceptionHack()
+
+  def _runtimeClassloader = {
+    _thisClassloader
+  }
+
+  protected def newIMain(settings: Settings, out: PrintWriter): IMain = {
+    val s = new IMain(settings, new ReplReporterImpl(settings, out))
+    s.initializeCompiler()
+    s
+  }
+
+  protected def convertAnnotationsToModifiers(
+                                               annotationInfos: 
List[Global#AnnotationInfo]
+                                             ) = annotationInfos map {
+    case a if a.toString == "transient" => "@transient"
+    case a =>
+      logger.debug(s"Ignoring unknown annotation: $a")
+      ""
+  } filterNot {
+    _.isEmpty
+  }
+
+  protected def convertScopeToModifiers(scopeSymbol: Global#Symbol) = {
+    (if (scopeSymbol.isImplicit) "implicit" else "") ::
+      Nil
+  }
+
+  protected def buildModifierList(termNameString: String) = {
+    import scala.language.existentials
+    val termSymbol = iMain.symbolOfTerm(termNameString)
+
+
+    convertAnnotationsToModifiers(
+      if (termSymbol.hasAccessorFlag) termSymbol.accessed.annotations
+      else termSymbol.annotations
+    ) ++ convertScopeToModifiers(termSymbol)
+  }
+
+
+  protected def refreshDefinitions(): Unit = {
+    iMain.definedTerms.foreach(termName => {
+      val termNameString = termName.toString
+      val termTypeString = iMain.typeOfTerm(termNameString).toLongString
+      iMain.valueOfTerm(termNameString) match {
+        case Some(termValue)  =>
+          val modifiers = buildModifierList(termNameString)
+          logger.debug(s"Rebinding of $termNameString as " +
+            s"${modifiers.mkString(" ")} $termTypeString")
+          Try(iMain.beQuietDuring {
+            iMain.bind(
+              termNameString, termTypeString, termValue, modifiers
+            )
+          })
+        case None             =>
+          logger.debug(s"Ignoring rebinding of $termNameString")
+      }
+    })
+  }
+
+  protected def reinitializeSymbols(): Unit = {
+    val global = iMain.global
+    import global._
+    new Run // Initializes something needed for Scala classes
+  }
+
+  /**
+   * Adds jars to the runtime and compile time classpaths. Does not work with
+   * directories or expanding star in a path.
+   * @param jars The list of jar locations
+   */
+  override def addJars(jars: URL*): Unit = {
+    iMain.addUrlsToClassPath(jars:_*)
+    // the Scala interpreter will invalidate definitions for any package 
defined in
+    // the new Jars. This can easily include org.* and make the kernel 
inaccessible
+    // because it is bound using the previous package definition. To avoid 
problems,
+    // it is necessary to refresh variable definitions to use the new packages 
and
+    // to rebind the global definitions.
+    refreshDefinitions()
+    bindVariables()
+  }
+
+  /**
+   * Binds a variable in the interpreter to a value.
+   * @param variableName The name to expose the value in the interpreter
+   * @param typeName The type of the variable, must be the fully qualified 
class name
+   * @param value The value of the variable binding
+   * @param modifiers Any annotation, scoping modifiers, etc on the variable
+   */
+  override def bind(
+    variableName: String,
+    typeName: String,
+    value: Any,
+    modifiers: List[String]
+  ): Unit = {
+    logger.warn(s"Binding $modifiers $variableName $typeName $value")
+    require(iMain != null)
+    val sIMain = iMain
+
+    val bindRep = new sIMain.ReadEvalPrint()
+    iMain.interpret(s"import $typeName")
+    bindRep.compile("""
+                      |object %s {
+                      |  var value: %s = _
+                      |  def set(x: Any) = value = x.asInstanceOf[%s]
+                      |}
+                    """.stripMargin.format(bindRep.evalName, typeName, 
typeName)
+    )
+    bindRep.callEither("set", value) match {
+      case Left(ex) =>
+        logger.error("Set failed in bind(%s, %s, %s)".format(variableName, 
typeName, value))
+        logger.error(util.stackTraceString(ex))
+        Results.Error
+
+      case Right(_) =>
+        val line = "%sval %s = %s.value".format(modifiers map (_ + " ") 
mkString, variableName, bindRep.evalPath)
+        logger.debug("Interpreting: " + line)
+        iMain.interpret(line)
+    }
+
+  }
+
+
+  /**
+   * Executes body and will not print anything to the console during the 
execution
+   * @param body The function to execute
+   * @tparam T The return type of body
+   * @return The return value of body
+   */
+  override def doQuietly[T](body: => T): T = {
+    require(iMain != null)
+    iMain.withoutWarnings[T](body)
+  }
+
+
+  /**
+   * Stops the interpreter, removing any previous internal state.
+   * @return A reference to the interpreter
+   */
+  override def stop(): Interpreter = {
+    logger.info("Shutting down interpreter")
+
+    // Shut down the task manager (kills current execution
+    if (taskManager != null) taskManager.stop()
+    taskManager = null
+
+    // Erase our completer
+    completer = null
+
+    // Close the entire interpreter (loses all state)
+    if (iMain != null) iMain.close()
+    iMain = null
+
+    this
+  }
+
+  /**
+   * Returns the name of the variable created from the last execution.
+   * @return Some String name if a variable was created, otherwise None
+   */
+  override def lastExecutionVariableName: Option[String] = {
+    require(iMain != null)
+
+    // TODO: Get this API method changed back to public in Apache Spark
+    val lastRequestMethod = classOf[IMain].getDeclaredMethod("lastRequest")
+    lastRequestMethod.setAccessible(true)
+
+    val mostRecentVariableName = iMain.mostRecentVar
+
+    iMain.allDefinedNames.map(_.toString).find(_ == mostRecentVariableName)
+  }
+
+  /**
+   * Mask the Console and System objects with our wrapper implementations
+   * and dump the Console methods into the public namespace (similar to
+   * the Predef approach).
+   * @param in The new input stream
+   * @param out The new output stream
+   * @param err The new error stream
+   */
+  override def updatePrintStreams(
+    in: InputStream,
+    out: OutputStream,
+    err: OutputStream
+  ): Unit = {
+    val inReader = new BufferedReader(new InputStreamReader(in))
+    val outPrinter = new PrintStream(out)
+    val errPrinter = new PrintStream(err)
+
+    iMain.beQuietDuring {
+      iMain.bind(
+        "Console", classOf[WrapperConsole].getName,
+        new WrapperConsole(inReader, outPrinter, errPrinter),
+        List("""@transient""")
+      )
+      iMain.bind(
+        "System", classOf[WrapperSystem].getName,
+        new WrapperSystem(in, out, err),
+        List("""@transient""")
+      )
+      iMain.interpret("import Console._")
+    }
+  }
+
+  /**
+   * Retrieves the contents of the variable with the provided name from the
+   * interpreter.
+   * @param variableName The name of the variable whose contents to read
+   * @return An option containing the variable contents or None if the
+   *         variable does not exist
+   */
+  override def read(variableName: String): Option[Any] = {
+    require(iMain != null)
+
+    try {
+      iMain.valueOfTerm(variableName)
+    } catch {
+      // if any error returns None
+      case e: Throwable => {
+        logger.debug(s"Error reading variable name: ${variableName}", e)
+        clearLastException()
+        None
+      }
+    }
+  }
+
+  /**
+   * Starts the interpreter, initializing any internal state.
+   * @return A reference to the interpreter
+   */
+  override def start(): Interpreter = {
+    require(iMain == null && taskManager == null)
+
+    taskManager = newTaskManager()
+
+    logger.debug("Initializing task manager")
+    taskManager.start()
+
+    iMain = newIMain(settings, new PrintWriter(lastResultOut, true))
+
+    //logger.debug("Initializing interpreter")
+    //iMain.initializeSynchronous()
+
+    logger.debug("Initializing completer")
+    completer = new ReplCompletion(iMain)
+
+    iMain.beQuietDuring {
+      //logger.info("Rerouting Console and System related input and output")
+      //updatePrintStreams(System.in, multiOutputStream, multiOutputStream)
+
+      //   ADD IMPORTS generates too many classes, client is responsible for 
adding import
+      logger.debug("Adding org.apache.spark.SparkContext._ to imports")
+      iMain.interpret("import org.apache.spark.SparkContext._")
+
+      logger.debug("Adding the hack for the exception handling retrieval.")
+      iMain.bind("_exceptionHack", classOf[ExceptionHack].getName, 
exceptionHack, List("@transient"))
+    }
+
+    this
+  }
+
+  /**
+   * Attempts to perform code completion via the <TAB> command.
+   * @param code The current cell to complete
+   * @param pos The cursor position
+   * @return The cursor position and list of possible completions
+   */
+  override def completion(code: String, pos: Int): (Int, List[String]) = {
+
+    require(completer != null)
+
+    logger.debug(s"Attempting code completion for ${code}")
+    val result = completer.complete(code, pos)
+
+    (result.cursor, result.candidates.map(_.toString))
+  }
+
+  /**
+    * Attempts to perform completeness checking for a statement by seeing if 
we can parse it
+    * using the scala parser.
+    *
+    * @param code The current cell to complete
+    * @return tuple of (completeStatus, indent)
+    */
+  override def isComplete(code: String): (String, String) = {
+    import scala.language.existentials
+    val result = iMain.withoutWarnings {
+      val parse = iMain.parse(code)
+      parse match {
+        case Left(Results.Error) => ("invalid", "")
+        case Right(_) => ("invalid", "")
+        case Left(Results.Success) =>
+          val lines = code.split("\n", -1)
+          val numLines = lines.length
+          // for multiline code blocks, require an empty line before executing
+          // to mimic the behavior of ipython
+          if (numLines > 1 && lines.last.matches("\\s*\\S.*")) {
+            ("incomplete", startingWhiteSpace(lines.last))
+          } else {
+            ("complete", "")
+          }
+        case Left(Results.Incomplete) =>
+          val lines = code.split("\n", -1)
+          // For now lets just grab the indent of the current line, if none 
default to 2 spaces.
+          ("incomplete", startingWhiteSpace(lines.last))
+      }
+    }
+    lastResultOut.reset()
+    result
+  }
+
+  private def startingWhiteSpace(line: String): String = {
+    val indent = "^\\s+".r.findFirstIn(line).getOrElse("")
+    // increase the indent if the line ends with => or {
+    if (line.matches(".*(?:(?:\\{)|(?:=>))\\s*")) {
+      indent + "  "
+    } else {
+      indent
+    }
+  }
+
+  override def newSettings(args: List[String]): Settings = {
+    val s = new Settings()
+
+    val dir = ScalaInterpreter.ensureTemporaryFolder()
+
+    s.processArguments(args ++
+      List(
+        "-Yrepl-class-based",
+        "-Yrepl-outdir", s"$dir"
+        // useful for debugging compiler classpath or package issues
+        // "-uniqid", "-explaintypes", "-usejavacp", "-Ylog-classpath"
+    ), processAll = true)
+    s
+  }
+
+  protected def interpretAddTask(code: String, silent: Boolean): 
Future[Results.Result] = {
+    if (iMain == null) throw new IllegalArgumentException("Interpreter not 
started yet!")
+
+    taskManager.add {
+      // Add a task using the given state of our streams
+      StreamState.withStreams {
+        if (silent) {
+          iMain.withoutWarnings {
+            iMain.interpret(code)
+          }
+        } else {
+          iMain.interpret(code)
+        }
+      }
+    }
+  }
+
+  private def retrieveLastException: Throwable = {
+    iMain.withoutWarnings {
+      iMain.interpret("_exceptionHack.lastException = lastException")
+    }
+    exceptionHack.lastException
+  }
+
+  private def clearLastException(): Unit = {
+    iMain.directBind(
+      ExecutionExceptionName,
+      classOf[Throwable].getName,
+      null
+    )
+    exceptionHack.lastException = null
+  }
+
+  protected def interpretConstructExecuteError(output: String) = {
+    Option(retrieveLastException) match {
+      // Runtime error
+      case Some(e) =>
+        val ex = e.asInstanceOf[Throwable]
+        clearLastException()
+
+        // The scala REPL does a pretty good job of returning us a stack trace 
that is free from all the bits that the
+        // interpreter uses before it.
+        //
+        // The REPL emits its message as something like this, so trim off the 
first and last element
+        //
+        //    java.lang.ArithmeticException: / by zero
+        //    at failure(<console>:17)
+        //    at call_failure(<console>:19)
+        //    ... 40 elided
+
+        val formattedException = output.split("\n")
+
+        ExecuteError(
+          ex.getClass.getName,
+          ex.getLocalizedMessage,
+          formattedException.toList
+        )
+      // Compile time error, need to check internal reporter
+      case _ =>
+        if (iMain.reporter.hasErrors)
+        // TODO: This wrapper is not needed when just getting compile
+        // error that we are not parsing... maybe have it be purely
+        // output and have the error check this?
+          ExecuteError(
+            "Compile Error", output, List()
+          )
+        else
+        // May as capture the output here.  Could be useful
+          ExecuteError("Unknown Error", output, List())
+    }
+  }
+}
+
+/**
+  * Due to a bug in the scala interpreter under scala 2.11 (SI-8935) with 
IMain.valueOfTerm we can hack around it by
+  * binding an instance of ExceptionHack into iMain and interpret the 
"_exceptionHack.lastException = lastException".
+  * This makes it possible to extract the exception.
+  *
+  * TODO: Revisit this once Scala 2.12 is released.
+  */
+class ExceptionHack {
+  var lastException: Throwable = _
+}
diff --git 
a/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala
 
b/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala
index eb365027..e2c21ed0 100644
--- 
a/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala
+++ 
b/scala-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/scala/ScalaInterpreter.scala
@@ -25,6 +25,7 @@ import org.apache.spark.SparkContext
 import org.apache.spark.sql.SparkSession
 import org.apache.spark.repl.Main
 import org.apache.toree.interpreter._
+import org.apache.toree.interpreter.{Results => ToreeResults}
 import org.apache.toree.kernel.api.{KernelLike, KernelOptions}
 import org.apache.toree.utils.TaskManager
 import org.slf4j.LoggerFactory
@@ -35,7 +36,8 @@ import scala.collection.JavaConverters._
 import scala.concurrent.{Await, Future}
 import scala.language.reflectiveCalls
 import scala.tools.nsc.Settings
-import scala.tools.nsc.interpreter.{IR, OutputStream}
+import scala.tools.nsc.interpreter.Results
+import java.io.OutputStream
 import scala.tools.nsc.util.ClassPath
 import scala.util.matching.Regex
 import scala.concurrent.duration.Duration
@@ -190,7 +192,7 @@ class ScalaInterpreter(private val config:Config = 
ConfigFactory.load) extends I
    }
 
    override def interpret(code: String, silent: Boolean = false, output: 
Option[OutputStream]):
-    (Results.Result, Either[ExecuteOutput, ExecuteFailure]) = {
+    (ToreeResults.Result, Either[ExecuteOutput, ExecuteFailure]) = {
      interpretBlock(code, silent)
    }
 
@@ -214,7 +216,7 @@ class ScalaInterpreter(private val config:Config = 
ConfigFactory.load) extends I
 
         definitions.append(s"$name: $func$funcType").append("\n")
 
-      case NamedResult(name, vtype, value) if read(name).nonEmpty =>
+      case NamedResult(_, _, name, vtype, value) if read(name).nonEmpty =>
 
         val result = read(name)
 
@@ -279,7 +281,7 @@ class ScalaInterpreter(private val config:Config = 
ConfigFactory.load) extends I
   }
 
   protected def interpretBlock(code: String, silent: Boolean = false):
-    (Results.Result, Either[ExecuteOutput, ExecuteFailure]) = {
+    (ToreeResults.Result, Either[ExecuteOutput, ExecuteFailure]) = {
 
      logger.trace(s"Interpreting line: $code")
 
@@ -296,23 +298,23 @@ class ScalaInterpreter(private val config:Config = 
ConfigFactory.load) extends I
      Await.result(futureResultAndExecuteInfo, Duration.Inf)
    }
 
-   protected def interpretMapToCustomResult(future: Future[IR.Result]): 
Future[Results.Result] = {
+   protected def interpretMapToCustomResult(future: Future[Results.Result]): 
Future[ToreeResults.Result] = {
      import scala.concurrent.ExecutionContext.Implicits.global
      future map {
-       case IR.Success             => Results.Success
-       case IR.Error               => Results.Error
-       case IR.Incomplete          => Results.Incomplete
+       case Results.Success             => ToreeResults.Success
+       case Results.Error               => ToreeResults.Error
+       case Results.Incomplete          => ToreeResults.Incomplete
      } recover {
-       case ex: ExecutionException => Results.Aborted
+       case ex: ExecutionException => ToreeResults.Aborted
      }
    }
 
-   protected def interpretMapToResultAndOutput(future: Future[Results.Result]):
-      Future[(Results.Result, Either[Map[String, String], ExecuteError])] = {
+   protected def interpretMapToResultAndOutput(future: 
Future[ToreeResults.Result]):
+      Future[(ToreeResults.Result, Either[Map[String, String], ExecuteError])] 
= {
      import scala.concurrent.ExecutionContext.Implicits.global
 
      future map {
-       case result @ (Results.Success | Results.Incomplete) =>
+       case result @ (ToreeResults.Success | ToreeResults.Incomplete) =>
          val lastOutput = lastResultOut.toString("UTF-8").trim
          lastResultOut.reset()
 
@@ -322,17 +324,17 @@ class ScalaInterpreter(private val config:Config = 
ConfigFactory.load) extends I
          val output = 
obj.map(Displayers.display(_).asScala.toMap).getOrElse(Map.empty)
          (result, Left(output))
 
-       case Results.Error =>
+       case ToreeResults.Error =>
          val lastOutput = lastResultOut.toString("UTF-8").trim
          lastResultOut.reset()
 
          val (obj, defStr, text) = prepareResult(lastOutput)
          defStr.foreach(kernel.display.content(MIMEType.PlainText, _))
          val output = interpretConstructExecuteError(text.get)
-         (Results.Error, Right(output))
+         (ToreeResults.Error, Right(output))
 
-       case Results.Aborted =>
-         (Results.Aborted, Right(null))
+       case ToreeResults.Aborted =>
+         (ToreeResults.Aborted, Right(null))
      }
    }
 
@@ -420,7 +422,7 @@ class ScalaInterpreter(private val config:Config = 
ConfigFactory.load) extends I
 object ScalaInterpreter {
 
   val HigherOrderFunction: Regex = 
"""(\w+):\s+(\(\s*.*=>\s*\w+\))(\w+)\s*.*""".r
-  val NamedResult: Regex = """(\w+):\s+([^=]+)\s+=\s*(.*)""".r
+  val NamedResult: Regex = """((val|var)\s+)?(\w+):\s+([^=]+)\s+=\s*(.*)""".r
   val Definition: Regex = """defined\s+(\w+)\s+(.+)""".r
   val Import: Regex = """import\s+([\w\.,\{\}\s]+)""".r
 
diff --git 
a/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlInterpreter.scala
 
b/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlInterpreter.scala
index 29e988aa..871db33e 100644
--- 
a/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlInterpreter.scala
+++ 
b/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlInterpreter.scala
@@ -25,7 +25,7 @@ import org.apache.toree.kernel.BuildInfo
 
 import scala.concurrent.Await
 import scala.concurrent.duration._
-import scala.tools.nsc.interpreter.{InputStream, OutputStream}
+import java.io.{InputStream, OutputStream}
 
 /**
  * Represents an interpreter interface to Spark SQL.
diff --git 
a/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlService.scala
 
b/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlService.scala
index 4c6fd1a3..0c0c6e54 100644
--- 
a/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlService.scala
+++ 
b/sql-interpreter/src/main/scala/org/apache/toree/kernel/interpreter/sql/SqlService.scala
@@ -16,7 +16,7 @@
  */
 package org.apache.toree.kernel.interpreter.sql
 
-import java.io.ByteArrayOutputStream
+import java.io.{ByteArrayOutputStream, OutputStream}
 
 import org.apache.toree.interpreter.broker.BrokerService
 import org.apache.toree.kernel.api.KernelLike

Reply via email to