diff --git a/project/Build.scala b/project/Build.scala
index cad27e6d3252ec65ecf6c974791ac5d8818ddc4c..9fb755bee863d37219eedbe014adb577238420cc 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -77,9 +77,9 @@ object Leon extends Build {
   ).dependsOn(Github.bonsai, Github.scalaSmtLib)
 
   object Github {
-    lazy val bonsai = RootProject(uri("git://github.com/colder/bonsai.git#8f485605785bda98ac61885b0c8036133783290a"))
+    def project(repo: String, version: String) = RootProject(uri(s"${repo}#${version}"))
 
-    private val scalaSmtLibVersion = "4cc4cb1ce38fe62790b674666ab141d0430b0f00"
-    lazy val scalaSmtLib = RootProject(uri("git://github.com/regb/scala-smtlib.git#%s".format(scalaSmtLibVersion)))
+    lazy val bonsai      = project("git://github.com/colder/bonsai.git",     "8f485605785bda98ac61885b0c8036133783290a")
+    lazy val scalaSmtLib = project("git://github.com/regb/scala-smtlib.git", "51742fa4652243827c34703365e26f0d34adec81")
   }
 }
diff --git a/src/main/scala/leon/Settings.scala b/src/main/scala/leon/Settings.scala
index 0165a03b9f5e493fbd4ea306f446c973f3bf8f39..52ede3a613f3314b995696243b6dfb027103c60a 100644
--- a/src/main/scala/leon/Settings.scala
+++ b/src/main/scala/leon/Settings.scala
@@ -12,6 +12,5 @@ case class Settings(
   val xlang: Boolean                   = false,
   val verify: Boolean                  = true,
   val injectLibrary: Boolean           = false,
-  val classPath: List[String]          = Settings.defaultClassPath(),
   val selectedSolvers: Set[String]     = Set("fairz3")
 )
diff --git a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala
index 96450da434f8e1e23029bf48a0a7cbcd9e2d66f2..56f7f4af4caf561d324c3a5144cbeeca9d064290 100644
--- a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala
+++ b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala
@@ -128,6 +128,10 @@ class UnrollingSolver(val context: LeonContext, program: Program, underlying: In
         reporter.debug("- Invalid model.")
         false
 
+      case Successful(e) =>
+        reporter.warning("- Model leads unexpected result: "+e)
+        false
+
       case RuntimeError(msg) =>
         reporter.debug("- Model leads to runtime error.")
         false
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
index cf2ae8760ac2e4df282d21ad9911b0049875da65..155e84522b4a383da933c15d9148dafdf6702d5d 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
@@ -11,9 +11,9 @@ import Trees._
 import Extractors._
 import TypeTrees._
 
-import _root_.smtlib.sexpr.SExprs._
+import _root_.smtlib.parser.Terms.{Identifier => SMTIdentifier, _}
+import _root_.smtlib.parser.Commands._
 import _root_.smtlib.interpreters.CVC4Interpreter
-import _root_.smtlib.Commands.{Identifier => _, _}
 
 trait SMTLIBCVC4Target extends SMTLIBTarget {
   this: SMTLIBSolver =>
@@ -22,35 +22,35 @@ trait SMTLIBCVC4Target extends SMTLIBTarget {
 
   def getNewInterpreter() = new CVC4Interpreter
 
-  override def declareSort(t: TypeTree): SExpr = {
+  override def declareSort(t: TypeTree): Sort = {
     val tpe = normalizeType(t)
     sorts.cachedB(tpe) {
       tpe match {
         case TypeParameter(id) =>
           val s = id2sym(id)
-          val cmd = NonStandardCommand(SList(SSymbol("declare-sort"), s, SInt(0)))
+          val cmd = DeclareSort(s, 0)
           sendCommand(cmd)
-          s
+          Sort(SMTIdentifier(s))
         case SetType(base) =>
-          SList(SSymbol("Set"), declareSort(base))
+          Sort(SMTIdentifier(SSymbol("Set")), Seq(declareSort(base)))
         case _ =>
           super[SMTLIBTarget].declareSort(t)
       }
     }
   }
 
-  override def fromSMT(s: SExpr, tpe: TypeTree)(implicit letDefs: Map[SSymbol, SExpr]): Expr = (s, tpe) match {
-    case (s: SSymbol, tp: TypeParameter) =>
-      val n = s.s.split("_").toList.last
+  override def fromSMT(s: Term, tpe: TypeTree)(implicit letDefs: Map[SSymbol, Term]): Expr = (s, tpe) match {
+    case (SimpleSymbol(s), tp: TypeParameter) =>
+      val n = s.name.split("_").toList.last
       GenericValue(tp, n.toInt)
 
-    case (SList(SSymbol("as") ::  SSymbol("emptyset") :: _), SetType(base)) =>
+    case (QualifiedIdentifier(SMTIdentifier(SSymbol("emptyset"), Seq()), _), SetType(base)) =>
       FiniteSet(Seq()).setType(tpe)
 
-    case (SList(SSymbol("setenum") :: elems), SetType(base)) =>
+    case (FunctionApplication(SimpleSymbol(SSymbol("setenum")), elems), SetType(base)) =>
       FiniteSet(elems.map(fromSMT(_, base))).setType(tpe)
 
-    case (SList(SSymbol("union") :: elems), SetType(base)) =>
+    case (FunctionApplication(SimpleSymbol(SSymbol("union")), elems), SetType(base)) =>
       FiniteSet(elems.map(fromSMT(_, tpe) match {
         case FiniteSet(elems) => elems
       }).flatten).setType(tpe)
@@ -59,43 +59,43 @@ trait SMTLIBCVC4Target extends SMTLIBTarget {
       super[SMTLIBTarget].fromSMT(s, tpe)
   }
 
-  override def toSMT(e: Expr)(implicit bindings: Map[Identifier, SExpr]) = e match {
-    case a @ FiniteArray(elems) =>
-      val tpe @ ArrayType(base) = normalizeType(a.getType)
-      declareSort(tpe)
+  override def toSMT(e: Expr)(implicit bindings: Map[Identifier, Term]) = e match {
+    //case a @ FiniteArray(elems) =>
+    //  val tpe @ ArrayType(base) = normalizeType(a.getType)
+    //  declareSort(tpe)
 
-      var ar: SExpr = declareVariable(FreshIdentifier("arrayconst").setType(RawArrayType(Int32Type, base)))
+    //  var ar: SExpr = declareVariable(FreshIdentifier("arrayconst").setType(RawArrayType(Int32Type, base)))
 
-      for ((e, i) <- elems.zipWithIndex) {
-        ar = SList(SSymbol("store"), ar, toSMT(IntLiteral(i)), toSMT(e))
-      }
+    //  for ((e, i) <- elems.zipWithIndex) {
+    //    ar = SList(SSymbol("store"), ar, toSMT(IntLiteral(i)), toSMT(e))
+    //  }
 
-      SList(constructors.toB(tpe), toSMT(IntLiteral(elems.size)), ar)
+    //  SList(constructors.toB(tpe), toSMT(IntLiteral(elems.size)), ar)
 
-    /**
-     * ===== Set operations =====
-     */
-    case fs @ FiniteSet(elems) =>
-      if (elems.isEmpty) {
-        SList(SSymbol("as"), SSymbol("emptyset"), declareSort(fs.getType))
-      } else {
-        SList(SSymbol("setenum") :: elems.map(toSMT).toList)
-      }
+    ///**
+    // * ===== Set operations =====
+    // */
+    //case fs @ FiniteSet(elems) =>
+    //  if (elems.isEmpty) {
+    //    SList(SSymbol("as"), SSymbol("emptyset"), declareSort(fs.getType))
+    //  } else {
+    //    SList(SSymbol("setenum") :: elems.map(toSMT).toList)
+    //  }
 
-    case SubsetOf(ss, s) =>
-      SList(SSymbol("subseteq"), toSMT(ss), toSMT(s))
+    //case SubsetOf(ss, s) =>
+    //  SList(SSymbol("subseteq"), toSMT(ss), toSMT(s))
 
-    case ElementOfSet(e, s) =>
-      SList(SSymbol("in"), toSMT(e), toSMT(s))
+    //case ElementOfSet(e, s) =>
+    //  SList(SSymbol("in"), toSMT(e), toSMT(s))
 
-    case SetDifference(a, b) =>
-      SList(SSymbol("setminus"), toSMT(a), toSMT(b))
+    //case SetDifference(a, b) =>
+    //  SList(SSymbol("setminus"), toSMT(a), toSMT(b))
 
-    case SetUnion(a, b) =>
-      SList(SSymbol("union"), toSMT(a), toSMT(b))
+    //case SetUnion(a, b) =>
+    //  SList(SSymbol("union"), toSMT(a), toSMT(b))
 
-    case SetIntersection(a, b) =>
-      SList(SSymbol("intersection"), toSMT(a), toSMT(b))
+    //case SetIntersection(a, b) =>
+    //  SList(SSymbol("intersection"), toSMT(a), toSMT(b))
 
     case _ =>
       super[SMTLIBTarget].toSMT(e)
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
index 720e238f83117e60a477246928bd5ffee0107b34..51ea6f67e6af29c97898316ece355c17073255a3 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
@@ -12,11 +12,13 @@ import TypeTrees._
 import Definitions._
 import utils.Bijection
 
-import _root_.smtlib.{PrettyPrinter => SMTPrinter, Interpreter => SMTInterpreter}
-import _root_.smtlib.Commands.{Identifier => _, _}
-import _root_.smtlib.CommandResponses.{Error => ErrorResponse, _}
-import _root_.smtlib.sexpr.SExprs._
-import _root_.smtlib.interpreters._
+import _root_.smtlib.common._
+import _root_.smtlib.printer.{PrettyPrinter => SMTPrinter}
+import _root_.smtlib.parser.Commands.{Constructor => SMTConstructor, _}
+import _root_.smtlib.parser.Terms.{Identifier => SMTIdentifier, Let => SMTLet, _}
+import _root_.smtlib.parser.CommandsResponses.{Error => ErrorResponse, _}
+import _root_.smtlib.theories._
+import _root_.smtlib.{Interpreter => SMTInterpreter}
 
 trait SMTLIBTarget {
   this: SMTLIBSolver =>
@@ -40,7 +42,7 @@ trait SMTLIBTarget {
   val selectors    = new Bijection[(TypeTree, Int), SSymbol]()
   val testers      = new Bijection[TypeTree, SSymbol]()
   val variables    = new Bijection[Identifier, SSymbol]()
-  val sorts        = new Bijection[TypeTree, SExpr]()
+  val sorts        = new Bijection[TypeTree, Sort]()
   val functions    = new Bijection[TypedFunDef, SSymbol]()
 
   def normalizeType(t: TypeTree): TypeTree = t match {
@@ -59,21 +61,21 @@ trait SMTLIBTarget {
 
   def unsupported(str: Any) = reporter.fatalError(s"Unsupported in smt-$targetName: $str")
 
-  def declareSort(t: TypeTree): SExpr = {
+  def declareSort(t: TypeTree): Sort = {
     val tpe = normalizeType(t)
     sorts.cachedB(tpe) {
       tpe match {
-        case BooleanType => SSymbol("Bool")
-        case Int32Type => SSymbol("Int")
+        case BooleanType => Core.BoolSort()
+        case Int32Type => Ints.IntSort()
 
         case RawArrayType(from, to) =>
-          SList(SSymbol("Array"), declareSort(from), declareSort(to))
+          Sort(SMTIdentifier(SSymbol("Array")), Seq(declareSort(from), declareSort(to)))
 
         case TypeParameter(id) =>
           val s = id2sym(id)
-          val cmd = NonStandardCommand(SList(SSymbol("declare-sort"), s))
+          val cmd = DeclareSort(s, 0)
           sendCommand(cmd)
-          s
+          Sort(SMTIdentifier(s))
         case _: ClassType | _: TupleType | _: ArrayType | UnitType =>
           declareStructuralSort(tpe)
         case _ =>
@@ -85,7 +87,7 @@ trait SMTLIBTarget {
   def freshSym(id: Identifier): SSymbol = freshSym(id.name)
   def freshSym(name: String): SSymbol = id2sym(FreshIdentifier(name))
 
-  def declareStructuralSort(t: TypeTree): SExpr = {
+  def declareStructuralSort(t: TypeTree): Sort = {
 
     def getHierarchy(ct: ClassType): (ClassType, Seq[CaseClassType]) = ct match {
       case act: AbstractClassType =>
@@ -125,7 +127,7 @@ trait SMTLIBTarget {
         if (!(datatypes contains t) && !(sorts containsA t)) {
           val sym = freshSym("tuple"+bases.size)
 
-          val c = Constructor(freshSym(sym.s), tt, bases.zipWithIndex.map {
+          val c = Constructor(freshSym(sym.name), tt, bases.zipWithIndex.map {
             case (tpe, i) => (freshSym("_"+(i+1)), tpe)
           })
 
@@ -139,14 +141,14 @@ trait SMTLIBTarget {
 
           val sym = freshSym("Unit")
 
-          datatypes += t -> DataType(sym, Seq(Constructor(freshSym(sym.s), t, Nil)))
+          datatypes += t -> DataType(sym, Seq(Constructor(freshSym(sym.name), t, Nil)))
         }
 
       case at @ ArrayType(base) =>
         if (!(datatypes contains t) && !(sorts containsA t)) {
           val sym = freshSym("array")
 
-          val c = Constructor(freshSym(sym.s), at, List(
+          val c = Constructor(freshSym(sym.name), at, List(
             (freshSym("size"), Int32Type),
             (freshSym("content"), RawArrayType(Int32Type, base))
           ))
@@ -164,28 +166,28 @@ trait SMTLIBTarget {
 
     // We pre-declare ADTs
     for ((tpe, DataType(sym, _)) <- datatypes) {
-      sorts += tpe -> sym
+      sorts += tpe -> Sort(SMTIdentifier(sym))
     }
 
-    def toDecl(c: Constructor): SExpr = {
+    def toDecl(c: Constructor): SMTConstructor = {
       val s = c.sym
 
-      testers += c.tpe -> SSymbol("is-"+s.s)
+      testers += c.tpe -> SSymbol("is-"+s.name)
       constructors += c.tpe -> s
 
-      SList(s :: c.fields.zipWithIndex.map {
+      SMTConstructor(s, c.fields.zipWithIndex.map {
         case ((cs, t), i) =>
           selectors += (c.tpe, i) -> cs
-          SList(cs, declareSort(t))
-      }.toList)
+          (cs, declareSort(t))
+      })
     }
 
     val adts = for ((tpe, DataType(sym, cases)) <- datatypes.toList) yield {
-      SList(sym :: cases.map(toDecl).toList)
+      (sym, cases.map(toDecl))
     }
 
 
-    val cmd = NonStandardCommand(SList(SSymbol("declare-datatypes"), SList(), SList(adts)))
+    val cmd = DeclareDatatypes(adts)
     sendCommand(cmd)
 
     sorts.toB(t)
@@ -194,7 +196,7 @@ trait SMTLIBTarget {
   def declareVariable(id: Identifier): SSymbol = {
     variables.cachedB(id) {
       val s = id2sym(id)
-      val cmd = NonStandardCommand(SList(SSymbol("declare-const"), s, declareSort(id.getType)))
+      val cmd = DeclareFun(s, List(), declareSort(id.getType))
       sendCommand(cmd)
       s
     }
@@ -208,142 +210,149 @@ trait SMTLIBTarget {
         FreshIdentifier(tfd.id.name)
       }
       val s = id2sym(id)
-      sendCommand(DeclareFun(s.s, tfd.params.map(p => declareSort(p.tpe)), declareSort(tfd.returnType)))
+      sendCommand(DeclareFun(s, tfd.params.map(p => declareSort(p.tpe)), declareSort(tfd.returnType)))
       s
     }
   }
 
-  def toSMT(e: Expr)(implicit bindings: Map[Identifier, SExpr]): SExpr = {
+  def toSMT(e: Expr)(implicit bindings: Map[Identifier, Term]): Term = {
     e match {
       case Variable(id) =>
         declareSort(e.getType)
-        bindings.getOrElse(id, variables.toB(id))
+        bindings.getOrElse(id, QualifiedIdentifier(SMTIdentifier(variables.toB(id))))
 
       case UnitLiteral() =>
         declareSort(UnitType)
-        declareVariable(FreshIdentifier("Unit").setType(UnitType))
+        QualifiedIdentifier(SMTIdentifier(
+          declareVariable(FreshIdentifier("Unit").setType(UnitType))
+        ))
 
-      case IntLiteral(i) => if (i > 0) SInt(i) else SList(SSymbol("-"), SInt(-i))
-      case BooleanLiteral(v) => SSymbol(if (v) "true" else "false")
+      case IntLiteral(i) => if (i > 0) Ints.NumeralLit(i) else Ints.Neg(Ints.NumeralLit(-i))
+      case BooleanLiteral(v) => Core.BoolConst(v)
       case StringLiteral(s) => SString(s)
       case Let(b,d,e) =>
         val id      = id2sym(b)
         val value   = toSMT(d)
-        val newBody = toSMT(e)(bindings + (b -> id))
+        val newBody = toSMT(e)(bindings + (b -> QualifiedIdentifier(SMTIdentifier(id))))
 
-        SList(
-          SSymbol("let"),
-          SList(
-            SList(id, value)
-          ),
+        SMTLet(
+          VarBinding(id, value),
+          Seq(),
           newBody
         )
 
       case er @ Error(_) =>
-        declareVariable(FreshIdentifier("error_value").setType(er.getType))
+        val s = declareVariable(FreshIdentifier("error_value").setType(er.getType))
+        QualifiedIdentifier(SMTIdentifier(s))
 
       case s @ CaseClassSelector(cct, e, id) =>
         declareSort(cct)
-        SList(selectors.toB((cct, s.selectorIndex)), toSMT(e))
+        val selector = selectors.toB((cct, s.selectorIndex))
+        FunctionApplication(QualifiedIdentifier(SMTIdentifier(selector)), Seq(toSMT(e)))
 
       case CaseClassInstanceOf(cct, e) =>
         declareSort(cct)
-        SList(testers.toB(cct), toSMT(e))
+        val tester = testers.toB(cct)
+        FunctionApplication(QualifiedIdentifier(SMTIdentifier(tester)), Seq(toSMT(e)))
 
       case CaseClass(cct, es) =>
         declareSort(cct)
+        val constructor = constructors.toB(cct)
         if (es.isEmpty) {
-          constructors.toB(cct)
+          QualifiedIdentifier(SMTIdentifier(constructor))
         } else {
-          SList(constructors.toB(cct) :: es.map(toSMT).toList)
+          FunctionApplication(QualifiedIdentifier(SMTIdentifier(constructor)), es.map(toSMT))
         }
 
       case t @ Tuple(es) =>
         val tpe = normalizeType(t.getType)
         declareSort(tpe)
-        SList(constructors.toB(tpe) :: es.map(toSMT).toList)
+        val constructor = constructors.toB(tpe)
+        FunctionApplication(QualifiedIdentifier(SMTIdentifier(constructor)), es.map(toSMT))
 
       case ts @ TupleSelect(t, i) =>
         val tpe = normalizeType(t.getType)
         declareSort(tpe)
-        SList(selectors.toB((tpe, i-1)), toSMT(t))
+        val selector = selectors.toB((tpe, i-1))
+        FunctionApplication(QualifiedIdentifier(SMTIdentifier(selector)), Seq(toSMT(t)))
 
-      case al @ ArrayLength(a) =>
-        val tpe = normalizeType(a.getType)
-        SList(selectors.toB((tpe, 0)), toSMT(a))
+      //TODO
+      //case al @ ArrayLength(a) =>
+      //  val tpe = normalizeType(a.getType)
+      //  SList(selectors.toB((tpe, 0)), toSMT(a))
 
-      case as @ ArraySelect(a, i) =>
-        val tpe = normalizeType(a.getType)
-        SList(SSymbol("select"), SList(selectors.toB((tpe, 1)), toSMT(a)), toSMT(i))
+      //case as @ ArraySelect(a, i) =>
+      //  val tpe = normalizeType(a.getType)
+      //  SList(SSymbol("select"), SList(selectors.toB((tpe, 1)), toSMT(a)), toSMT(i))
 
-      case as @ ArrayUpdated(a, i, e) =>
-        val tpe = normalizeType(a.getType)
+      //case as @ ArrayUpdated(a, i, e) =>
+      //  val tpe = normalizeType(a.getType)
 
-        val ssize    = SList(selectors.toB((tpe, 0)), toSMT(a))
-        val scontent = SList(selectors.toB((tpe, 1)), toSMT(a))
+      //  val ssize    = SList(selectors.toB((tpe, 0)), toSMT(a))
+      //  val scontent = SList(selectors.toB((tpe, 1)), toSMT(a))
 
-        SList(constructors.toB(tpe), ssize, SList(SSymbol("store"), scontent, toSMT(i), toSMT(e)))
+      //  SList(constructors.toB(tpe), ssize, SList(SSymbol("store"), scontent, toSMT(i), toSMT(e)))
 
 
       case e @ UnaryOperator(u, _) =>
-        val op = e match {
-          case _: Not => SSymbol("not")
-          case _: UMinus => SSymbol("-")
+        e match {
+          case (_: Not) => Core.Not(toSMT(u))
+          case (_: UMinus) => Ints.Neg(toSMT(u))
           case _ => reporter.fatalError("Unhandled unary "+e)
         }
 
-        SList(op :: List(u).map(toSMT))
-
       case e @ BinaryOperator(a, b, _) =>
-        val op = e match {
-          case _: Equals => SSymbol("=")
-          case _: Implies => SSymbol("=>")
-          case _: Iff => SSymbol("=")
-          case _: Plus => SSymbol("+")
-          case _: Minus => SSymbol("-")
-          case _: Times => SSymbol("*")
-          case _: Division => SSymbol("div")
-          case _: Modulo => SSymbol("mod")
-          case _: LessThan => SSymbol("<")
-          case _: LessEquals => SSymbol("<=")
-          case _: GreaterThan => SSymbol(">")
-          case _: GreaterEquals => SSymbol(">=")
+        e match {
+          case (_: Equals) => Core.Equals(toSMT(a), toSMT(b))
+          case (_: Implies) => Core.Implies(toSMT(a), toSMT(b))
+          case (_: Iff) => Core.Equals(toSMT(a), toSMT(b))
+          case (_: Plus) => Ints.Add(toSMT(a), toSMT(b))
+          case (_: Minus) => Ints.Sub(toSMT(a), toSMT(b))
+          case (_: Times) => Ints.Mul(toSMT(a), toSMT(b))
+          case (_: Division) => Ints.Div(toSMT(a), toSMT(b))
+          case (_: Modulo) => Ints.Mod(toSMT(a), toSMT(b))
+          case (_: LessThan) => Ints.LessThan(toSMT(a), toSMT(b))
+          case (_: LessEquals) => Ints.LessEquals(toSMT(a), toSMT(b))
+          case (_: GreaterThan) => Ints.GreaterThan(toSMT(a), toSMT(b))
+          case (_: GreaterEquals) => Ints.GreaterEquals(toSMT(a), toSMT(b))
           case _ => reporter.fatalError("Unhandled binary "+e)
         }
 
-        SList(op :: List(a, b).map(toSMT))
-
       case e @ NAryOperator(sub, _) =>
-        val op = e match {
-          case _: And => SSymbol("and")
-          case _: Or => SSymbol("or")
-          case _: IfExpr => SSymbol("ite")
-          case f: FunctionInvocation => declareFunction(f.tfd)
+        e match {
+          case (_: And) => Core.And(sub.map(toSMT): _*)
+          case (_: Or) => Core.Or(sub.map(toSMT): _*)
+          case (_: IfExpr) => Core.ITE(toSMT(sub(0)), toSMT(sub(1)), toSMT(sub(2))) 
+          case (f: FunctionInvocation) => 
+            FunctionApplication(
+              QualifiedIdentifier(SMTIdentifier(declareFunction(f.tfd))),
+              sub.map(toSMT)
+            )
           case _ => reporter.fatalError("Unhandled nary "+e)
         }
 
-        SList(op :: sub.map(toSMT).toList)
-
 
       case o => unsupported("Tree: " + o)
     }
   }
 
-  def fromSMT(pair: (SExpr, TypeTree))(implicit letDefs: Map[SSymbol, SExpr]): Expr = {
+  def fromSMT(pair: (Term, TypeTree))(implicit letDefs: Map[SSymbol, Term]): Expr = {
     fromSMT(pair._1, pair._2)
   }
 
-  def fromSMT(s: SExpr, tpe: TypeTree)(implicit letDefs: Map[SSymbol, SExpr]): Expr = (s, tpe) match {
+  def fromSMT(s: Term, tpe: TypeTree)(implicit letDefs: Map[SSymbol, Term]): Expr = (s, tpe) match {
     case (_, UnitType) =>
       UnitLiteral()
 
-    case (SInt(n), Int32Type) =>
+    case (SNumeral(n), Int32Type) =>
       IntLiteral(n.toInt)
 
-    case (SSymbol(s), BooleanType)  =>
-      BooleanLiteral(s == "true")
+    case (Core.True(), BooleanType)  => BooleanLiteral(true)
+    case (Core.False(), BooleanType)  => BooleanLiteral(false)
 
-    case (s: SSymbol, _: ClassType) if constructors.containsB(s) =>
+    case (SHexadecimal(hexa), Int32Type) => IntLiteral(hexa.toInt)
+
+    case (SimpleSymbol(s), _: ClassType) if constructors.containsB(s) =>
       constructors.toA(s) match {
         case cct: CaseClassType =>
           CaseClass(cct, Nil)
@@ -351,15 +360,15 @@ trait SMTLIBTarget {
           unsupported("woot? for a single constructor for non-case-object: "+t)
       }
 
-    case (s: SSymbol, tpe) if letDefs contains s =>
+    case (SimpleSymbol(s), tpe) if letDefs contains s =>
       fromSMT(letDefs(s), tpe)
 
-    case (s: SSymbol, _) =>
+    case (SimpleSymbol(s), _) =>
       variables.getA(s).map(_.toVariable).getOrElse {
         unsupported("Unknown symbol: "+s)
       }
 
-    case (SList((s: SSymbol) :: args), tpe) if constructors.containsB(s) =>
+    case (FunctionApplication(SimpleSymbol(s), args), tpe) if constructors.containsB(s) =>
       constructors.toA(s) match {
         case cct: CaseClassType =>
           val rargs = args.zip(cct.fields.map(_.tpe)).map(fromSMT)
@@ -382,16 +391,15 @@ trait SMTLIBTarget {
 
     // EK: Since we have no type information, we cannot do type-directed
     // extraction of defs, instead, we expand them in smt-world
-    case (SList(List(SSymbol("let"), SList(defs), body)), tpe) =>
-      val defsMap: Map[SSymbol, SExpr] = defs.map {
-        case SList(List(s : SSymbol, value)) =>
-          (s, value)
+    case (SMTLet(binding, bindings, body), tpe) =>
+      val defsMap: Map[SSymbol, Term] = (binding +: bindings).map {
+        case VarBinding(s, value) => (s, value)
       }.toMap
 
       fromSMT(body, tpe)(letDefs ++ defsMap)
 
-    case (SList(SSymbol(app) :: args), tpe) => {
-      app match {
+    case (FunctionApplication(SimpleSymbol(SSymbol(app)), args), tpe) => {
+      name match {
         case "-" =>
           args match {
             case List(a) => UMinus(fromSMT(a, Int32Type))
@@ -403,12 +411,12 @@ trait SMTLIBTarget {
       }
     }
     case _ =>
-      unsupported(s)
+      unsupported("Unhandled case in fromSMT: " + (s, tpe))
   }
 
   def sendCommand(cmd: Command): CommandResponse = {
     reporter.ifDebug { debug =>
-      SMTPrinter(cmd, out)
+      SMTPrinter.printCommand(cmd, out)
       out.write("\n")
       out.flush
     }
@@ -422,24 +430,29 @@ trait SMTLIBTarget {
 
   override def assertCnstr(expr: Expr): Unit = {
     variablesOf(expr).foreach(declareVariable)
-    val sexpr = toSMT(expr)(Map())
-    sendCommand(Assert(sexpr))
+    val term = toSMT(expr)(Map())
+    sendCommand(Assert(term))
   }
 
-  override def check: Option[Boolean] = sendCommand(CheckSat) match {
+  override def check: Option[Boolean] = sendCommand(CheckSat()) match {
     case CheckSatResponse(SatStatus)     => Some(true)
     case CheckSatResponse(UnsatStatus)   => Some(false)
     case CheckSatResponse(UnknownStatus) => None
+    case _                               => None
   }
 
   override def getModel: Map[Identifier, Expr] = {
     val syms = variables.bSet.toList
-    val cmd: Command = GetValue(syms.head, syms.tail)
+    val cmd: Command = 
+      GetValue(QualifiedIdentifier(SMTIdentifier(syms.head)), 
+               syms.tail.map(s => QualifiedIdentifier(SMTIdentifier(s)))
+              )
+
 
     val GetValueResponse(valuationPairs) = sendCommand(cmd)
 
     valuationPairs.collect {
-      case (sym: SSymbol, value) if variables.containsB(sym) =>
+      case (SimpleSymbol(sym), value) if variables.containsB(sym) =>
         val id = variables.toA(sym)
 
         (id, fromSMT(value, id.getType)(Map()))
@@ -452,4 +465,14 @@ trait SMTLIBTarget {
   override def pop(lvl: Int = 1): Unit = {
     sendCommand(Pop(1))
   }
+
+  protected object SimpleSymbol {
+
+    def unapply(term: Term): Option[SSymbol] = term match {
+      case QualifiedIdentifier(SMTIdentifier(sym, Seq()), None) => Some(sym)
+      case _ => None
+    }
+
+  }
+
 }
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
index 1bd4f6b13f6bc4ea5a05278f30195a4823cbc0c1..779d759c165bab114700f129f61989d3704f768e 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
@@ -12,10 +12,12 @@ import Extractors._
 import TypeTrees._
 import TreeOps.simplestValue
 
-import _root_.smtlib.sexpr.SExprs._
+import _root_.smtlib.parser.Terms.{Identifier => SMTIdentifier, _}
+import _root_.smtlib.parser.Commands.{DefineSort, GetValue, NonStandardCommand, GetModel, DefineFun}
 import _root_.smtlib.interpreters.Z3Interpreter
-import _root_.smtlib.Commands.{GetValue, NonStandardCommand}
-import _root_.smtlib.CommandResponses.SExprResponse
+import _root_.smtlib.parser.CommandsResponses.{SExprResponse, GetModelResponse}
+import _root_.smtlib.theories.Core._
+import _root_.smtlib.theories.ArraysEx
 
 trait SMTLIBZ3Target extends SMTLIBTarget {
   this: SMTLIBSolver =>
@@ -30,7 +32,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
   var mapSort: Option[SSymbol] = None
   var optionSort: Option[SSymbol] = None
 
-  override def declareSort(t: TypeTree): SExpr = {
+  override def declareSort(t: TypeTree): Sort = {
     val tpe = normalizeType(t)
     sorts.cachedB(tpe) {
       tpe match {
@@ -44,22 +46,25 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
     }
   }
 
-  def declareSetSort(of: TypeTree) = {
+  def declareSetSort(of: TypeTree): Sort = {
     setSort match {
       case None =>
         val s = SSymbol("Set")
         val t = SSymbol("T")
         setSort = Some(s)
 
-        val cmd = NonStandardCommand(SList(SSymbol("define-sort"), s, SList(t), SList(SSymbol("Array"), t, SSymbol("Bool"))))
+        val arraySort = Sort(SMTIdentifier(SSymbol("Array")), 
+                             Seq(Sort(SMTIdentifier(t)), BoolSort()))
+
+        val cmd = DefineSort(s, Seq(t), arraySort)
         sendCommand(cmd)
       case _ =>
     }
 
-    SList(setSort.get, declareSort(of))
+    Sort(SMTIdentifier(setSort.get), Seq(declareSort(of)))
   }
 
-  def declareOptionSort(of: TypeTree) = {
+  def declareOptionSort(of: TypeTree): Sort = {
     optionSort match {
       case None =>
         val t      = SSymbol("T")
@@ -79,10 +84,10 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
       case _ =>
     }
 
-    SList(optionSort.get, declareSort(of))
+    Sort(SMTIdentifier(optionSort.get), Seq(declareSort(of)))
   }
 
-  def declareMapSort(from: TypeTree, to: TypeTree) = {
+  def declareMapSort(from: TypeTree, to: TypeTree): Sort = {
     mapSort match {
       case None =>
         val m = SSymbol("Map")
@@ -91,127 +96,135 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
         mapSort = Some(m)
         declareOptionSort(to)
 
-        val cmd = NonStandardCommand(SList(SSymbol("define-sort"), m, SList(a, b), SList(SSymbol("Array"), a, SList(optionSort.get, b))))
+        val arraySort = Sort(SMTIdentifier(SSymbol("Array")),
+                             Seq(Sort(SMTIdentifier(optionSort.get)), Sort(SMTIdentifier(b))))
+
+        val cmd = DefineSort(m, Seq(a, b), arraySort)
         sendCommand(cmd)
       case _ =>
     }
 
-    SList(mapSort.get, declareSort(from), declareSort(to))
+    Sort(SMTIdentifier(mapSort.get), Seq(declareSort(from), declareSort(to)))
   }
 
-  override def fromSMT(s: SExpr, tpe: TypeTree)(implicit letDefs: Map[SSymbol, SExpr]): Expr = (s, tpe) match {
-    case (s: SSymbol, tp: TypeParameter) =>
-      val n = s.s.split("!").toList.last
+  override def fromSMT(s: Term, tpe: TypeTree)(implicit letDefs: Map[SSymbol, Term]): Expr = (s, tpe) match {
+    case (SimpleSymbol(s), tp: TypeParameter) =>
+      val n = s.name.split("!").toList.last
       GenericValue(tp, n.toInt)
 
 
-    case (SList(List(`extSym`, SSymbol("as-array"), k: SSymbol)), tpe) =>
-      if (letDefs contains k) {
-        // Need to recover value form function model
-        fromRawArray(extractRawArray(letDefs(k)), tpe)
-      } else {
-        unsupported(" as-array on non-function or unknown symbol "+k)
-      }
+    //case (SList(List(`extSym`, SSymbol("as-array"), k: SSymbol)), tpe) =>
+    //  if (letDefs contains k) {
+    //    // Need to recover value form function model
+    //    fromRawArray(extractRawArray(letDefs(k)), tpe)
+    //  } else {
+    //    unsupported(" as-array on non-function or unknown symbol "+k)
+    //  }
 
     // SMT representation for empty sets: Array(* -> false)
-    case (SList(List(SList(List(SSymbol("as"), SSymbol("const"), SList(List(SSymbol("Array"), k, v)))), defV)), tpe) =>
-      val ktpe = sorts.fromB(k)
-      val vtpe = sorts.fromB(v)
+    //case (SList(List(SList(List(SSymbol("as"), SSymbol("const"), SList(List(SSymbol("Array"), k, v)))), defV)), tpe) =>
+    //  val ktpe = sorts.fromB(Sort(SMTIdentifier(k)))
+    //  val vtpe = sorts.fromB(Sort(SMTIdentifier(v)))
 
-      fromRawArray(RawArrayValue(ktpe, Map(), fromSMT(defV, vtpe)), tpe)
+    //  fromRawArray(RawArrayValue(ktpe, Map(), fromSMT(defV, vtpe)), tpe)
 
     case _ =>
       super[SMTLIBTarget].fromSMT(s, tpe)
   }
 
-  override def toSMT(e: Expr)(implicit bindings: Map[Identifier, SExpr]) = e match {
-      case a @ FiniteArray(elems) =>
-        val tpe @ ArrayType(base) = normalizeType(a.getType)
-        declareSort(tpe)
+  override def toSMT(e: Expr)(implicit bindings: Map[Identifier, Term]): Term = e match {
+      //case a @ FiniteArray(elems) =>
+      //  val tpe @ ArrayType(base) = normalizeType(a.getType)
+      //  declareSort(tpe)
 
-        var ar = SList(SList(SSymbol("as"), SSymbol("const"), declareSort(RawArrayType(Int32Type, base))), toSMT(simplestValue(base)))
+      //  var ar = SList(SList(SSymbol("as"), SSymbol("const"), declareSort(RawArrayType(Int32Type, base))), toSMT(simplestValue(base)))
 
-        for ((e, i) <- elems.zipWithIndex) {
-          ar = SList(SSymbol("store"), ar, toSMT(IntLiteral(i)), toSMT(e))
-        }
+      //  for ((e, i) <- elems.zipWithIndex) {
+      //    ar = SList(SSymbol("store"), ar, toSMT(IntLiteral(i)), toSMT(e))
+      //  }
 
-        SList(constructors.toB(tpe), toSMT(IntLiteral(elems.size)), ar)
+      //  SList(constructors.toB(tpe), toSMT(IntLiteral(elems.size)), ar)
 
-      /**
-       * ===== Map operations =====
-       */
-      case MapGet(m, k) =>
-        declareSort(m.getType)
-        SList(SSymbol("Some_v"), SList(SSymbol("select"), toSMT(m), toSMT(k)))
+      ///**
+      // * ===== Map operations =====
+      // */
+      //case MapGet(m, k) =>
+      //  declareSort(m.getType)
+      //  SList(SSymbol("Some_v"), SList(SSymbol("select"), toSMT(m), toSMT(k)))
 
-      case MapIsDefinedAt(m, k) =>
-        declareSort(m.getType)
-        SList(SSymbol("is-Some"), SList(SSymbol("select"), toSMT(m), toSMT(k)))
+      //case MapIsDefinedAt(m, k) =>
+      //  declareSort(m.getType)
+      //  SList(SSymbol("is-Some"), SList(SSymbol("select"), toSMT(m), toSMT(k)))
 
-      case m @ FiniteMap(elems) =>
-        val ms = declareSort(m.getType)
+      //case m @ FiniteMap(elems) =>
+      //  val ms = declareSort(m.getType)
 
-        var res = SList(SList(SSymbol("as"), SSymbol("const"), ms), SSymbol("None"))
-        for ((k, v) <- elems) {
-          res = SList(SSymbol("store"), res, toSMT(k), SList(SSymbol("Some"), toSMT(v)))
-        }
+      //  var res = SList(SList(SSymbol("as"), SSymbol("const"), ms), SSymbol("None"))
+      //  for ((k, v) <- elems) {
+      //    res = SList(SSymbol("store"), res, toSMT(k), SList(SSymbol("Some"), toSMT(v)))
+      //  }
 
-        res
+      //  res
 
       /**
        * ===== Set operations =====
        */
       case fs @ FiniteSet(elems) =>
         val ss = declareSort(fs.getType)
-        var res = SList(SList(SSymbol("as"), SSymbol("const"), ss), toSMT(BooleanLiteral(false)))
+        var res: Term = FunctionApplication(
+          QualifiedIdentifier(SMTIdentifier(SSymbol("const")), Some(ss)),
+          Seq(toSMT(BooleanLiteral(false)))
+        )
 
         for (e <- elems) {
-          res = SList(SSymbol("store"), res, toSMT(e), toSMT(BooleanLiteral(true)))
+          res = ArraysEx.Store(res, toSMT(e), toSMT(BooleanLiteral(true)))
         }
 
         res
 
-      case SubsetOf(ss, s) =>
-        // a isSubset b   ==>   (a zip b).map(implies) == (* => true)
-        val allTrue    = SList(SList(SSymbol("as"), SSymbol("const"), declareSort(s.getType)), SSymbol("true"))
-        val mapImplies = SList(SList(extSym, SSymbol("map"), SSymbol("implies")), toSMT(ss), toSMT(s))
+      //case SubsetOf(ss, s) =>
+      //  // a isSubset b   ==>   (a zip b).map(implies) == (* => true)
+      //  val allTrue    = SList(SList(SSymbol("as"), SSymbol("const"), declareSort(s.getType)), SSymbol("true"))
+      //  val mapImplies = SList(SList(extSym, SSymbol("map"), SSymbol("implies")), toSMT(ss), toSMT(s))
 
-        SList(SSymbol("="), mapImplies, allTrue)
+      //  SList(SSymbol("="), mapImplies, allTrue)
 
-      case ElementOfSet(e, s) =>
-        SList(SSymbol("select"), toSMT(s), toSMT(e))
+      //case ElementOfSet(e, s) =>
+      //  SList(SSymbol("select"), toSMT(s), toSMT(e))
 
-      case SetDifference(a, b) =>
-        // a -- b
-        // becomes:
-        // a && not(b)
-        SList(SList(extSym, SSymbol("map"), SSymbol("and")), toSMT(a), SList(SList(extSym, SSymbol("map"), SSymbol("not")), toSMT(b)))
+      //case SetDifference(a, b) =>
+      //  // a -- b
+      //  // becomes:
+      //  // a && not(b)
+      //  SList(SList(extSym, SSymbol("map"), SSymbol("and")), toSMT(a), SList(SList(extSym, SSymbol("map"), SSymbol("not")), toSMT(b)))
       case SetUnion(l, r) =>
-        SList(SList(extSym, SSymbol("map"), SSymbol("or")), toSMT(l), toSMT(r))
+        FunctionApplication(
+          QualifiedIdentifier(SMTIdentifier(SSymbol("(_ map or)"))), //hack to get around Z3 syntax
+          Seq(toSMT(l), toSMT(r)))
 
-      case SetIntersection(l, r) =>
-        SList(SList(extSym, SSymbol("map"), SSymbol("and")), toSMT(l), toSMT(r))
+      //case SetIntersection(l, r) =>
+      //  SList(SList(extSym, SSymbol("map"), SSymbol("and")), toSMT(l), toSMT(r))
 
       case _ =>
         super.toSMT(e)
   }
 
   def extractRawArray(s: SExpr)(implicit letDefs: Map[SSymbol, SExpr]): RawArrayValue = s match {
-    case SList(List(SSymbol("define-fun"), a: SSymbol, SList(SList(List(arg, akind)) :: Nil), rkind, body)) =>
-      val argTpe = sorts.toA(akind)
-      val retTpe = sorts.toA(rkind)
-
-      def extractCases(e: SExpr): (Map[Expr, Expr], Expr) = e match {
-        case SList(SSymbol("ite") :: SList(SSymbol("=") :: `arg` :: k :: Nil) :: v :: e :: Nil) =>
-          val (cs, d) = extractCases(e)
-          (Map(fromSMT(k, argTpe) -> fromSMT(v, retTpe)) ++ cs, d)
-        case e =>
-          (Map(),fromSMT(e, retTpe))
-      }
+    //case SList(List(SSymbol("define-fun"), a: SSymbol, SList(SList(List(arg, akind)) :: Nil), rkind, body)) =>
+    //  val argTpe = sorts.toA(Sort(SMTIdentifier(akind)))
+    //  val retTpe = sorts.toA(Sort(SMTIdentifier(rkind)))
 
-      val (cases, default) = extractCases(body)
+    //  def extractCases(e: SExpr): (Map[Expr, Expr], Expr) = e match {
+    //    case SList(SSymbol("ite") :: SList(SSymbol("=") :: `arg` :: k :: Nil) :: v :: e :: Nil) =>
+    //      val (cs, d) = extractCases(e)
+    //      (Map(fromSMT(k, argTpe) -> fromSMT(v, retTpe)) ++ cs, d)
+    //    case e =>
+    //      (Map(),fromSMT(e, retTpe))
+    //  }
 
-      RawArrayValue(argTpe, cases, default)
+    //  val (cases, default) = extractCases(body)
+
+    //  RawArrayValue(argTpe, cases, default)
     case _ =>
       unsupported("Unable to extract "+s)
   }
@@ -232,20 +245,20 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
   // EK: We use get-model instead in order to extract models for arrays
   override def getModel: Map[Identifier, Expr] = {
 
-    val cmd = NonStandardCommand(SList(SSymbol("get-model")))
+    val cmd = GetModel()
 
     val res = sendCommand(cmd)
 
-    val smodel = res match {
-      case SExprResponse(SList(SSymbol("model") :: entries)) => entries
+    val smodel: Seq[DefineFun] = res match {
+      case GetModelResponse(model) => model
       case _ => Nil
     }
 
-    var modelFunDefs = Map[SSymbol, SExpr]()
+    var modelFunDefs = Map[SSymbol, DefineFun]()
 
     // First pass to gather functions (arrays defs)
     for (me <- smodel) me match {
-      case SList(List(SSymbol("define-fun"), a: SSymbol, SList(args), _, _)) if args.nonEmpty =>
+      case DefineFun(a, args, _, _) if args.nonEmpty =>
         modelFunDefs += a -> me
       case _ =>
     }
@@ -253,21 +266,12 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
     var model = Map[Identifier, Expr]()
 
     for (me <- smodel) me match {
-      case SList(List(SSymbol("define-fun"), s: SSymbol, SList(args), kind, e)) =>
-        if (args.isEmpty) {
+      case DefineFun(s, args, kind, e) =>
+        if(args.isEmpty) {
           val id = variables.toA(s)
           // EK: this is a little hack, we pass models for array functions as let-defs
-          model += id -> fromSMT(e, id.getType)(modelFunDefs)
+          model += id -> fromSMT(e, id.getType)(null)//modelFunDefs)
         }
-
-      case SList(SSymbol("forall") :: _) => // no body
-        // Ignore
-
-      case SList(SSymbol("declare-fun") :: _) => // no body
-        // Ignore
-
-      case _ =>
-        unsupported("Unknown model entry: "+me)
     }
 
 
diff --git a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
index 72ffca0b55f3b2cb8bda6edcdec50f82138dfee8..cfe2c42218f49950d7a6fc24ed93dc0478106a38 100644
--- a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
+++ b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
@@ -26,7 +26,8 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T]) {
     val fakeFunDef = new FunDef(FreshIdentifier("fake", true),
                                 Nil,
                                 body.getType,
-                                variablesOf(body).toSeq.map(id => ValDef(id, id.getType)))
+                                variablesOf(body).toSeq.map(id => ValDef(id, id.getType)),
+                                DefType.MethodDef)
 
     fakeFunDef.body = Some(body)