diff --git a/build.sbt b/build.sbt
index f279c4fc003ca0c05d962e1da1766ecd0ce02b2e..5195f4dacb600a4ef52fdab0cdc5d92b1295489d 100644
--- a/build.sbt
+++ b/build.sbt
@@ -120,10 +120,21 @@ testOptions in IntegrTest := Seq(Tests.Argument("-oDF"), Tests.Filter(_ startsWi
 
 
 
-// RegressionTest Tests
+// Regression Tests
 lazy val RegressionTest = config("regression") extend(Test)
 
-testOptions in RegressionTest  := Seq(Tests.Argument("-oDF"), Tests.Filter(_ startsWith "leon.regression."))
+testOptions in RegressionTest := Seq(Tests.Argument("-oDF"), Tests.Filter(_ startsWith "leon.regression."))
+
+
+
+// Isabelle Tests
+lazy val IsabelleTest = config("isabelle") extend(Test)
+
+testOptions in IsabelleTest := Seq(Tests.Argument("-oDF"), Tests.Filter(_ startsWith "leon.isabelle."))
+
+parallelExecution in IsabelleTest := false
+
+fork in IsabelleTest := true
 
 
 def ghProject(repo: String, version: String) = RootProject(uri(s"${repo}#${version}"))
@@ -133,9 +144,9 @@ lazy val bonsai      = ghProject("git://github.com/colder/bonsai.git",     "0fec
 lazy val scalaSmtLib = ghProject("git://github.com/regb/scala-smtlib.git", "8aa4a5588653ce4986e3721115a62cc386714cc2")
 
 lazy val root = (project in file(".")).
-  configs(RegressionTest).
-  configs(IntegrTest).
+  configs(RegressionTest, IsabelleTest, IntegrTest).
   dependsOn(bonsai, scalaSmtLib).
   settings(inConfig(RegressionTest)(Defaults.testTasks ++ testSettings): _*).
   settings(inConfig(IntegrTest)(Defaults.testTasks ++ testSettings): _*).
+  settings(inConfig(IsabelleTest)(Defaults.testTasks ++ testSettings): _*).
   settings(inConfig(Test)(Defaults.testTasks ++ testSettings): _*)
diff --git a/src/test/resources/regression/verification/isabelle/error/FunctionsWrong.scala b/src/test/resources/regression/verification/isabelle/error/FunctionsWrong.scala
new file mode 100644
index 0000000000000000000000000000000000000000..54b2bec14d62873d2334f191d93559cd2db2ae3a
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/error/FunctionsWrong.scala
@@ -0,0 +1,20 @@
+import leon._
+import leon.annotation._
+import leon.collection._
+import leon.lang._
+
+object FunctionsWrong {
+
+  def zero: BigInt = 0
+
+  // unsupported by Isabelle
+  // should report a 'fatal error' (not an 'internal error')
+
+  def length[A]: List[A] => BigInt = {
+    case Nil() => zero
+    case Cons(_, xs) => BigInt(1) + length(xs)
+  }
+
+  def test[A](xs: List[A]) = (length(xs) >= zero) holds
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/error/MutualWrong.scala b/src/test/resources/regression/verification/isabelle/error/MutualWrong.scala
new file mode 100644
index 0000000000000000000000000000000000000000..16fd3ee9bf446dc8d7176ca98b7a6122ad4329ea
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/error/MutualWrong.scala
@@ -0,0 +1,18 @@
+import leon.annotation._
+import leon.lang._
+
+object MutualWrong {
+
+  // unsupported by Isabelle
+  // should report a 'fatal error' (not an 'internal error')
+
+  sealed abstract class List1[A]
+  case class Cons1[A](head: A, tail: List2[A, A]) extends List1[A]
+
+  sealed abstract class List2[A, B]
+  case class Cons2[A, B](head: A, tail: List1[B]) extends List2[A, B]
+  case class Nil2[A, B]() extends List2[A, B]
+
+  def truth = true holds
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/error/TypesWrong.scala b/src/test/resources/regression/verification/isabelle/error/TypesWrong.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a3772cc75c8e834adb28926869afbbc9845b76f9
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/error/TypesWrong.scala
@@ -0,0 +1,11 @@
+import leon._
+import leon.collection._
+import leon.lang._
+
+object TypesWrong {
+
+  case class Data(xs: Array[Int])
+
+  def truth = true holds
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/unknown/Casts.scala b/src/test/resources/regression/verification/isabelle/unknown/Casts.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c1f8844f0e82b533c5d7ed0a74545293cfa10b1a
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/unknown/Casts.scala
@@ -0,0 +1,14 @@
+import leon._
+import leon.annotation._
+import leon.collection._
+import leon.lang._
+
+object Casts {
+
+  def check1[A](xs: List[A]) =
+    ((xs.size >= 1) || xs.asInstanceOf[Cons[A]].t == Nil[A]()).holds
+
+  def check2[A](xs: List[A]) =
+    ((xs.size != 1) || xs.asInstanceOf[Cons[A]].t == Nil[A]()).holds
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/unknown/Mutual.scala b/src/test/resources/regression/verification/isabelle/unknown/Mutual.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5b14a2b860115b7d1bdd1c88f2a1a173fe810d32
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/unknown/Mutual.scala
@@ -0,0 +1,22 @@
+import leon.annotation._
+import leon.lang._
+
+object Mutual {
+
+  sealed abstract class List1[A]
+  case class Cons1[A](head: A, tail: List2[A]) extends List1[A]
+
+  sealed abstract class List2[B]
+  case class Cons2[B](head: B, tail: List1[B]) extends List2[B]
+  case class Nil2[B]() extends List2[B]
+
+  def size1[A](list: List1[A]): BigInt = (list match {
+    case Cons1(_, t) => 1 + size2(t)
+  }) ensuring { _ >= BigInt(0) }
+
+  def size2[A](list: List2[A]): BigInt = (list match {
+    case Nil2() => BigInt(0)
+    case Cons2(_, t) => 1 + size1(t)
+  }) ensuring { _ >= BigInt(0) }
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/valid/Datatypes.scala b/src/test/resources/regression/verification/isabelle/valid/Datatypes.scala
new file mode 100644
index 0000000000000000000000000000000000000000..0da6b70265f8e207bd7a5198e9858bc2ef28eb60
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/valid/Datatypes.scala
@@ -0,0 +1,44 @@
+import leon.annotation._
+import leon.lang._
+
+object Datatypes {
+
+  sealed abstract class Foo[A]
+  sealed abstract class Bar[C] extends Foo[C]
+  case class Baz[B](underlying: B, rest: Baz[B]) extends Bar[B]
+  case class FooNil[D]() extends Foo[D]
+
+  def dest[B](baz1: Baz[B], baz2: Baz[B]) = {
+    require(baz1 == baz2)
+    baz1.underlying == baz2.underlying
+  } holds
+
+  def intro_dest[B](baz1: Baz[B], baz2: Baz[B], b1: B, b2: B) = {
+    require(b1 == b2)
+    val x1 = Baz(b1, baz1)
+    val x2 = Baz(b2, baz2)
+    x1.underlying == x2.underlying
+  } holds
+
+  def pm[A](foo: Foo[A]) = (foo match {
+    case Baz(x, y) => true
+    case FooNil() => true
+  }) holds
+
+  def pm2[A](foo: Foo[A]) = (foo match {
+    case Baz(x, y) => true
+    case z: FooNil[A] => true
+  }) holds
+
+  def pm3[A](int: BigInt) = (int match {
+    case BigInt(0) => true
+    case n => true
+  }) holds
+
+  def pm4[A](int: BigInt) = (int match {
+    case BigInt(0) => true
+    case n if false => true
+    case n => true
+  }) holds
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/valid/Lists.scala b/src/test/resources/regression/verification/isabelle/valid/Lists.scala
new file mode 100644
index 0000000000000000000000000000000000000000..be3292851d19c0d2a361594e66bd967d6f78a522
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/valid/Lists.scala
@@ -0,0 +1,90 @@
+import leon._
+import leon.annotation._
+import leon.collection._
+import leon.lang._
+
+object Lists {
+
+  @isabelle.script(
+    name = "Safe_Head",
+    source = """
+      fun safe_head where
+      "safe_head [] = None" |
+      "safe_head (x # _) = Some x"
+
+      lemma safe_head_eq_head[simp]:
+        assumes "~ List.null xs"
+        shows "safe_head xs = Some (hd xs)"
+      using assms
+      by (cases xs) auto
+    """
+  )
+  @isabelle.function(term = "Safe_Head.safe_head")
+  def safeHead[A](xs: List[A]): Option[A] = xs match {
+    case Nil() => None()
+    case Cons(x, _) => Some(x)
+  }
+
+  def lemma1[A](xs: List[A]) =
+    (xs.isEmpty || safeHead(xs) == Some(xs.asInstanceOf[Cons[A]].h)).holds
+
+  def lemma2[A](xs: List[A]) = {
+    require(!xs.isEmpty)
+    (xs.size > 0)
+  }.holds
+
+  def lemma3[A](xs: List[A], ys: List[A], zs: List[A]) =
+    ((xs ++ ys) ++ zs == xs ++ (ys ++ zs)).holds
+
+  def lemma4[A](xs: List[A], ys: List[A]) =
+    ((xs ++ ys).content == (ys ++ xs).content).holds
+
+  def lemma5[A](x: A, xs: List[A]) =
+    ((x :: xs).content == xs.content ++ Set(x)).holds
+
+  def lemma6[A](xs: List[A]) =
+    (xs.reverse.reverse == xs).holds
+
+  def lemma7[A, B](xs: List[A]) =
+    (xs.zip(Nil[B]()) == Nil[(A, B)]()).holds
+
+  def lemma7_check =
+    (lemma7[Int, Int](Nil())).holds
+
+  def lemma8[A](xs: List[A], x: A) =
+    ((xs - x).content == xs.content -- Set(x)).holds
+
+  def lemma9[A, B, C](xs: List[A], f: A => B, g: B => C) =
+    (xs.map(f).map(g) == xs.map(x => g(f(x)))).holds
+
+  @isabelle.function(term = "Fun.id")
+  def identity[A](x: A) = x
+
+  def lemma10[A](xs: List[A]) =
+    (xs.map(identity) == xs).holds
+
+  @isabelle.proof(method = """(induct "<var xs>", auto)""")
+  def lemma11[A, B, C](xs: List[A], f: A => List[B], g: B => List[C]) =
+    (xs.flatMap(f).flatMap(g) == xs.flatMap(x => f(x).flatMap(g))).holds
+
+  def safeHead2[A](xs: List[A]): A = {
+    require(xs.size > 0)
+    xs.asInstanceOf[Cons[A]].h
+  }
+
+  def lemma12[A](xs: List[A]) =
+    (xs.isEmpty || safeHead2(xs) == xs.asInstanceOf[Cons[A]].h).holds
+
+  def lemma13[A](xs: List[A], x: A) =
+    ((x :: xs).apply(0) == x).holds
+
+  def lenTailrec[T](xs: List[T], n: BigInt): BigInt = xs match {
+    case Nil() => n
+    case Cons(_, xs) => lenTailrec(xs, 1 + n)
+  }
+
+  @isabelle.proof(method = """(induct "<var xs>" "<var n>" rule: [[leon_induct lenTailrec]], auto)""")
+  def lemma14[A](xs: List[A], n: BigInt) =
+    (lenTailrec(xs, n) >= n).holds
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/valid/Overlapping.scala b/src/test/resources/regression/verification/isabelle/valid/Overlapping.scala
new file mode 100644
index 0000000000000000000000000000000000000000..330f755305e0dd60c8292e0cb4d8b581823deff9
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/valid/Overlapping.scala
@@ -0,0 +1,17 @@
+import leon.annotation._
+import leon.collection._
+import leon.lang._
+
+object Overlapping {
+
+  def overlapped[A](xs: List[A]) = {
+    require { xs.isInstanceOf[Cons[A]] }
+
+    xs match {
+      case Cons(x1, Cons(x2, xs)) => true
+      case Cons(x1, xs) => true
+      case _ => false
+    }
+  }.holds
+
+}
diff --git a/src/test/resources/regression/verification/isabelle/valid/Reals.scala b/src/test/resources/regression/verification/isabelle/valid/Reals.scala
new file mode 100644
index 0000000000000000000000000000000000000000..e4b963518924d603d0aedd22b32ad0335f4d5af2
--- /dev/null
+++ b/src/test/resources/regression/verification/isabelle/valid/Reals.scala
@@ -0,0 +1,13 @@
+import leon._
+import leon.lang._
+import leon.annotation._
+
+object Reals {
+
+  def comm(x: Real, y: Real) =
+    (x + y == y + x).holds
+
+  def assoc(x: Real, y: Real, z: Real) =
+    ((x * y) * z == x * (y * z)).holds
+
+}
diff --git a/src/test/scala/leon/isabelle/IsabelleLibrarySuite.scala b/src/test/scala/leon/isabelle/IsabelleLibrarySuite.scala
new file mode 100644
index 0000000000000000000000000000000000000000..08506febee6139c36527e8059998a8a2436337f4
--- /dev/null
+++ b/src/test/scala/leon/isabelle/IsabelleLibrarySuite.scala
@@ -0,0 +1,35 @@
+package leon.isabelle
+
+import scala.concurrent._
+import scala.concurrent.duration._
+import scala.concurrent.ExecutionContext.Implicits.global
+
+import leon._
+import leon.frontends.scalac.ExtractionPhase
+import leon.purescala.Definitions._
+import leon.utils._
+import leon.solvers.isabelle._
+import leon.test._
+import leon.utils.PreprocessingPhase
+
+class IsabelleLibrarySuite extends LeonRegressionSuite {
+
+  object IsabelleNoopPhase extends LeonPhase[Program, Unit] {
+    val name = "isabelle-noop"
+    val description = "Isabelle definitions"
+
+    implicit val debugSection = DebugSectionIsabelle
+
+    def run(context: LeonContext)(program: Program): Unit =
+      Await.result(IsabelleEnvironment(context, program).map(_ => ()), Duration.Inf)
+  }
+
+  test("Define the library") {
+    val pipeline = ExtractionPhase andThen new PreprocessingPhase andThen IsabelleNoopPhase
+
+    val ctx = Main.processOptions(Seq("--isabelle:download=true", "--functions=_")).copy(reporter = new TestSilentReporter())
+
+    pipeline.run(ctx)(Nil)
+  }
+
+}
diff --git a/src/test/scala/leon/isabelle/IsabelleVerificationSuite.scala b/src/test/scala/leon/isabelle/IsabelleVerificationSuite.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9892bdbf49dab37691e00da09b416a58b4710d9a
--- /dev/null
+++ b/src/test/scala/leon/isabelle/IsabelleVerificationSuite.scala
@@ -0,0 +1,16 @@
+package leon.isabelle
+
+import leon._
+import leon.regression.verification._
+import leon.solvers.isabelle.AdaptationPhase
+import leon.test._
+import leon.verification.AnalysisPhase
+
+class IsabelleVerificationSuite extends VerificationSuite {
+
+  val testDir = "regression/verification/isabelle/"
+  val pipeFront = xlang.NoXLangFeaturesChecking
+  val pipeBack = AdaptationPhase andThen AnalysisPhase
+  val optionVariants: List[List[String]] = List(List("--isabelle:download=true", "--solvers=isabelle"))
+
+}