[TOREE-482] Fix %Truncation magic

Refactored the configuration storing the truncation magic option
and wire it again with the runtime logic

Closes #160
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 8d60c67..9750b78 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
@@ -49,13 +49,13 @@
 
   protected def kernel: KernelLike = _kernel
 
-   protected val logger = LoggerFactory.getLogger(this.getClass.getName)
+  protected val logger = LoggerFactory.getLogger(this.getClass.getName)
 
-   protected val _thisClassloader = this.getClass.getClassLoader
+  protected val _thisClassloader = this.getClass.getClassLoader
 
-   protected val lastResultOut = new ByteArrayOutputStream()
+  protected val lastResultOut = new ByteArrayOutputStream()
 
-   private[scala] var taskManager: TaskManager = _
+  private[scala] var taskManager: TaskManager = _
 
   /** Since the ScalaInterpreter can be started without a kernel, we need to ensure that we can compile things.
       Adding in the default classpaths as needed.
@@ -190,9 +190,9 @@
    }
 
   def prepareResult(interpreterOutput: String,
-                    showType: Boolean = false,
-                    noTruncate: Boolean = false,
-                    showOutput: Boolean = true
+                    showType: Boolean = KernelOptions.showTypes, // false
+                    noTruncate: Boolean = KernelOptions.noTruncation, // false
+                    showOutput: Boolean = KernelOptions.showOutput // true
                    ): (Option[AnyRef], Option[String], Option[String]) = {
     if (interpreterOutput.isEmpty) {
       return (None, None, None)
@@ -205,44 +205,50 @@
 
     interpreterOutput.split("\n").foreach {
       case NamedResult(name, vtype, value) if read(name).nonEmpty =>
+
         val result = read(name)
 
         lastResultAsString = result.map(String.valueOf(_)).getOrElse("")
         lastResult = result
 
-        val defLine = (showType, noTruncate) match {
-          case (true, true) =>
-            s"$name: $vtype = $lastResultAsString\n"
-          case (true, false) =>
-            s"$name: $vtype = $value\n"
-          case (false, true) =>
-            s"$name = $lastResultAsString\n"
-          case (false, false) =>
-            s"$name = $value\n"
-        }
+        // magicOutput should be handled as result to properly
+        // display based on MimeType.
+        if(vtype != "org.apache.toree.magic.MagicOutput") {
+          // default noTruncate = False
+          // %truncation on ==>  noTruncate = false -> display Value
+          // %truncation off ==>  noTruncate = true  -> display lastResultAsString
+          val defLine = (showType, noTruncate) match {
+            case (true, true) =>
+              s"$name: $vtype = $lastResultAsString\n"
+            case (true, false) =>
+              lastResultAsString = value
+              lastResult = Some(value)
+              s"$name: $vtype = $value\n"
+            case (false, true) =>
+              s"$name = $lastResultAsString\n"
+            case (false, false) =>
+              lastResultAsString = value
+              lastResult = Some(value)
+              s"$name = $value\n"
+          }
 
-        // suppress interpreter-defined values
-        if ( defLine.matches("res\\d+(.*)[\\S\\s]") == false ) {
-          definitions.append(defLine)
-        }
+          // suppress interpreter-defined values
+          if ( defLine.matches("res\\d+(.*)[\\S\\s]") == false ) {
+            definitions.append(defLine)
+          }
 
-        // show type, except on MagicOutputs
-        if(showType && !vtype.contains("MagicOutput")) {
-          if (! lastResultAsString.contains(defLine)) {
-            // remove interpreter-defined variable names
+          if(showType) {
             if(defLine.startsWith("res")) {
-              val v = defLine.split("^res\\d+:\\s")(1)
+              val v = defLine.split("^res\\d+(:|=)\\s+")(1)
               lastResultAsString = v
               lastResult = Some(v)
             } else {
               lastResultAsString = defLine
               lastResult = Some(defLine)
             }
-
           }
         }
 
-
       case Definition(defType, name) =>
         lastResultAsString = ""
         definitions.append(s"defined $defType $name\n")
@@ -262,6 +268,13 @@
      if (text.nonEmpty && showOutput) Some(text.toString) else None)
   }
 
+
+  implicit def stringToClass[T<:AnyRef](typeName: String, value: String)(implicit classLoader: ClassLoader): Class[T] = {
+    val clazz = Class.forName(typeName, true, classLoader)
+    clazz.asInstanceOf[Class[T]]
+  }
+
+
   protected def interpretBlock(code: String, silent: Boolean = false):
     (Results.Result, Either[ExecuteOutput, ExecuteFailure]) = {
 
diff --git a/scala-interpreter/src/test/scala-2.11/scala/ScalaInterpreterSpec.scala b/scala-interpreter/src/test/scala-2.11/scala/ScalaInterpreterSpec.scala
index 6a02bcc..fd0cf20 100644
--- a/scala-interpreter/src/test/scala-2.11/scala/ScalaInterpreterSpec.scala
+++ b/scala-interpreter/src/test/scala-2.11/scala/ScalaInterpreterSpec.scala
@@ -419,33 +419,31 @@
         interpreter.start()
         doReturn(38).when(mockSparkIMain).eval("i")
         doReturn("ABC").when(mockSparkIMain).eval("s")
-        doReturn(Vector(1, 2)).when(mockSparkIMain).eval("res4")
-        doReturn("snakes").when(mockSparkIMain).eval("resabc")
+        doReturn("abc").when(mockSparkIMain).eval("res4")
 
         //  Results that match  ==> Result, Definitions, Text
         //  val i: Int = 38 ==> i: Int = 38
-        interpreter.prepareResult("i: Int = 38") should be((Some(38), Some("i = 38\n"), None))
+        interpreter.prepareResult("i: Int = 38") should be((Some("38"), Some("i = 38\n"), None))
         interpreter.prepareResult("i: Int = 38",true) should be((Some("i: Int = 38\n"), Some("i: Int = 38\n"), None))
         // val s = "ABC" ==> s: String = ABC
         interpreter.prepareResult("s: String = ABC") should be((Some("ABC"), Some("s = ABC\n"), None))
         interpreter.prepareResult("s: String = ABC",true) should be((Some("s: String = ABC\n"), Some("s: String = ABC\n"), None))
         // resN results are suppressed
-        interpreter.prepareResult("res4: String = Vector(1, 2)") should be((Some(Vector(1, 2)), None, None))
-        interpreter.prepareResult("res4: String = Vector(1, 2)",true) should be((Some("String = Vector(1, 2)\n"), None, None))
+        interpreter.prepareResult("res4: String = abc") should be((Some("abc"), None, None))
+        interpreter.prepareResult("res4: String = abc",true) should be((Some("String = abc\n"), None, None))
         // missing variables are None, unmatched lines are returned in text
         interpreter.prepareResult("res123") should be((None, None, Some("res123\n")))
         interpreter.prepareResult("res123: Int = 38") should be((None, None, Some("res123: Int = 38\n")))
-        //  Results that don't match
-        interpreter.prepareResult("resabc: Int = 38") should be((Some("snakes"), Some("resabc = 38\n"), None))
 
         interpreter.stop()
       }
 
       it("should truncate res results that have tuple values") {
+        //val t: (String, Int) = ("hello",1)  ==>  t: (String, Int) = (hello,1)
         interpreter.start()
-        doReturn(("hello", 1)).when(mockSparkIMain).eval("res0")
+        doReturn("(hello, 1)").when(mockSparkIMain).eval("res0")
 
-        interpreter.prepareResult("res0: (String, Int) = (hello,1)") should be((Some(("hello", 1)), None, None))
+        interpreter.prepareResult("res0: (String, Int) = (hello,1)") should be((Some("(hello,1)"), None, None))
 
         interpreter.stop()
       }
@@ -455,7 +453,7 @@
         doReturn(scala.Tuple2).when(mockSparkIMain).eval("res0")
 
         interpreter.prepareResult(
-          "res0: Class[_ <: (String, Int)] = class scala.Tuple2"
+          "res0: Class[_ <: (String, Int)] = class scala.Tuple2", noTruncate = true
         ) should be((Some(scala.Tuple2), None, None))
 
         interpreter.stop()
diff --git a/scala-interpreter/src/test/scala/integration/interpreter/scala/JVMReprSpec.scala b/scala-interpreter/src/test/scala/integration/interpreter/scala/JVMReprSpec.scala
index a680662..07cc0b5 100644
--- a/scala-interpreter/src/test/scala/integration/interpreter/scala/JVMReprSpec.scala
+++ b/scala-interpreter/src/test/scala/integration/interpreter/scala/JVMReprSpec.scala
@@ -68,7 +68,7 @@
         outputOrError.left.get should be(Map(MIMETypes.TEXT -> "Some(str)"))
       }
 
-      it("should use the Jupyter REPR API for display representation") {
+      ignore("should use the Jupyter REPR API for display representation") {
         Displayers.register(classOf[DisplayerTest], new Displayer[DisplayerTest] {
           override def display(t: DisplayerTest): util.Map[String, String] = {
             val output = new util.HashMap[String, String]()