diff --git a/build.sbt b/build.sbt
index b825fa5ba9146d4bb9e2c23f41edf3e6f756188f..0e3e147a10e395fb58a0ebb3f981b9919deb56b9 100644
--- a/build.sbt
+++ b/build.sbt
@@ -141,6 +141,14 @@ parallelExecution in IsabelleTest := false
 
 fork in IsabelleTest := true
 
+// GenC Tests
+lazy val GenCTest = config("genc") extend(Test)
+
+testOptions in GenCTest := Seq(Tests.Argument("-oDF"), Tests.Filter(_ startsWith "leon.genc."))
+
+parallelExecution in GenCTest := false
+
+
 
 def ghProject(repo: String, version: String) = RootProject(uri(s"${repo}#${version}"))
 
@@ -148,9 +156,11 @@ lazy val bonsai      = ghProject("git://github.com/colder/bonsai.git",     "10ea
 lazy val scalaSmtLib = ghProject("git://github.com/regb/scala-smtlib.git", "372bb14d0c84953acc17f9a7e1592087adb0a3e1")
 
 lazy val root = (project in file(".")).
-  configs(RegressionTest, IsabelleTest, IntegrTest).
+  configs(RegressionTest, IsabelleTest, GenCTest, IntegrTest).
   dependsOn(bonsai, scalaSmtLib).
   settings(inConfig(RegressionTest)(Defaults.testTasks ++ testSettings): _*).
   settings(inConfig(IntegrTest)(Defaults.testTasks ++ testSettings): _*).
   settings(inConfig(IsabelleTest)(Defaults.testTasks ++ testSettings): _*).
+  settings(inConfig(GenCTest)(Defaults.testTasks ++ testSettings): _*).
   settings(inConfig(Test)(Defaults.testTasks ++ testSettings): _*)
+
diff --git a/src/test/resources/regression/genc/invalid/AbsFun.scala b/src/test/resources/regression/genc/invalid/AbsFun.scala
new file mode 100644
index 0000000000000000000000000000000000000000..aff9a2c80f70f5e3aef079220c1c36b29b40b2e3
--- /dev/null
+++ b/src/test/resources/regression/genc/invalid/AbsFun.scala
@@ -0,0 +1,66 @@
+import leon.lang._
+
+object AbsFun {
+
+
+  def isPositive(a : Array[Int], size : Int) : Boolean = {
+    require(a.length >= 0 && size <= a.length)
+    rec(0, a, size)
+  }
+
+  def rec(i: Int, a: Array[Int], size: Int) : Boolean = {
+    require(a.length >= 0 && size <= a.length && i >= 0)
+
+    if(i >= size) true
+    else {
+      if (a(i) < 0)
+        false
+      else
+        rec(i + 1, a, size)
+    }
+  }
+
+  // Returning Arrays is not supported by GenC
+  def abs(tab: Array[Int]): Array[Int] = {
+    require(tab.length >= 0)
+    val t = while0(Array.fill(tab.length)(0), 0, tab)
+    t._1
+  } ensuring(res => isPositive(res, res.length))
+
+
+  def while0(t: Array[Int], k: Int, tab: Array[Int]): (Array[Int], Int) = {
+    require(tab.length >= 0 &&
+            t.length == tab.length &&
+            k >= 0 &&
+            k <= tab.length &&
+            isPositive(t, k))
+
+    if(k < tab.length) {
+      val nt = if(tab(k) < 0) {
+        t.updated(k, -tab(k))
+      } else {
+        t.updated(k, tab(k))
+      }
+      while0(nt, k+1, tab)
+    } else {
+      (t, k)
+    }
+  } ensuring(res =>
+      res._2 >= tab.length &&
+      res._1.length == tab.length &&
+      res._2 >= 0 &&
+      res._2 <= tab.length &&
+      isPositive(res._1, res._2))
+
+  def property(t: Array[Int], k: Int): Boolean = {
+    require(isPositive(t, k) && t.length >= 0 && k >= 0)
+    if(k < t.length) {
+      val nt = if(t(k) < 0) {
+        t.updated(k, -t(k))
+      } else {
+        t.updated(k, t(k))
+      }
+      isPositive(nt, k+1)
+    } else true
+  } holds
+}
diff --git a/src/test/resources/regression/genc/invalid/LinearSearch.scala b/src/test/resources/regression/genc/invalid/LinearSearch.scala
new file mode 100644
index 0000000000000000000000000000000000000000..88cadb0ef7dc5ca5425a3f1661495cb08af4df65
--- /dev/null
+++ b/src/test/resources/regression/genc/invalid/LinearSearch.scala
@@ -0,0 +1,40 @@
+import leon.lang._
+
+/* The calculus of Computation textbook */
+
+object LinearSearch {
+
+  def linearSearch(a: Array[Int], c: Int): Boolean = ({
+    require(a.length >= 0)
+    var i = 0
+    var found = false
+    (while(i < a.length) {
+      if(a(i) == c)
+        found = true
+      i = i + 1
+    }) invariant(
+         i <= a.length &&
+         i >= 0 &&
+         (if(found) contains(a, i, c) else !contains(a, i, c))
+       )
+    found
+  }) ensuring(res => if(res) contains(a, a.length, c) else !contains(a, a.length, c))
+
+  def contains(a: Array[Int], size: Int, c: Int): Boolean = {
+    require(a.length >= 0 && size >= 0 && size <= a.length)
+    content(a, size).contains(c)
+  }
+
+  // Set not supported by GenC
+  def content(a: Array[Int], size: Int): Set[Int] = {
+    require(a.length >= 0 && size >= 0 && size <= a.length)
+    var set = Set.empty[Int]
+    var i = 0
+    (while(i < size) {
+      set = set ++ Set(a(i))
+      i = i + 1
+    }) invariant(i >= 0 && i <= size)
+    set
+  }
+
+}
diff --git a/src/test/resources/regression/genc/valid/BinarySearch.scala b/src/test/resources/regression/genc/valid/BinarySearch.scala
new file mode 100644
index 0000000000000000000000000000000000000000..75e1219a0427aa66c5388f03e7e10d435e1389fb
--- /dev/null
+++ b/src/test/resources/regression/genc/valid/BinarySearch.scala
@@ -0,0 +1,81 @@
+import leon.lang._
+
+/* VSTTE 2008 - Dafny paper */
+
+object BinarySearch {
+
+  def binarySearch(a: Array[Int], key: Int): Int = ({
+    require(a.length > 0 && sorted(a, 0, a.length - 1))
+    var low = 0
+    var high = a.length - 1
+    var res = -1
+
+    (while(low <= high && res == -1) {
+      val i = (high + low) / 2
+      val v = a(i)
+
+      if(v == key)
+        res = i
+
+      if(v > key)
+        high = i - 1
+      else if(v < key)
+        low = i + 1
+    }) invariant(
+        res >= -1 &&
+        res < a.length &&
+        0 <= low &&
+        low <= high + 1 &&
+        high >= -1 &&
+        high < a.length &&
+        (if (res >= 0)
+            a(res) == key else
+            (!occurs(a, 0, low, key) && !occurs(a, high + 1, a.length, key))
+        )
+       )
+    res
+  }) ensuring(res =>
+      res >= -1 &&
+      res < a.length &&
+      (if(res >= 0) a(res) == key else !occurs(a, 0, a.length, key)))
+
+
+  def occurs(a: Array[Int], from: Int, to: Int, key: Int): Boolean = {
+    require(a.length >= 0 && to <= a.length && from >= 0)
+    def rec(i: Int): Boolean = {
+      require(i >= 0)
+      if(i >= to)
+        false
+      else {
+       if(a(i) == key) true else rec(i+1)
+      }
+    }
+    if(from >= to)
+      false
+    else
+      rec(from)
+  }
+
+
+  def sorted(a: Array[Int], l: Int, u: Int) : Boolean = {
+    require(a.length >= 0 && l >= 0 && l <= u && u < a.length)
+    val t = sortedWhile(true, l, l, u, a)
+    t._1
+  }
+
+  def sortedWhile(isSorted: Boolean, k: Int, l: Int, u: Int, a: Array[Int]): (Boolean, Int) = {
+    require(a.length >= 0 && l >= 0 && l <= u && u < a.length && k >= l && k <= u)
+    if(k < u) {
+      sortedWhile(if(a(k) > a(k + 1)) false else isSorted, k + 1, l, u, a)
+    } else (isSorted, k)
+  }
+
+
+  def main = {
+    val a = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+    val i = binarySearch(a, 2)
+    i - 2 // i should be 2
+  }
+
+}
+
diff --git a/src/test/resources/regression/genc/valid/BinarySearchFun.scala b/src/test/resources/regression/genc/valid/BinarySearchFun.scala
new file mode 100644
index 0000000000000000000000000000000000000000..feb7c8cc60eaba0fc119d98c87bf55106e47fb1e
--- /dev/null
+++ b/src/test/resources/regression/genc/valid/BinarySearchFun.scala
@@ -0,0 +1,66 @@
+import leon.lang._
+
+object BinarySearchFun {
+
+  def binarySearch(a: Array[Int], key: Int, low: Int, high: Int): Int = ({
+    require(a.length > 0 && sorted(a, low, high) &&
+        0 <= low && low <= high + 1 && high < a.length
+    )
+
+    if(low <= high) {
+      val i = (high + low) / 2
+      val v = a(i)
+
+      if(v == key) i
+      else if (v > key) binarySearch(a, key, low, i - 1)
+      else binarySearch(a, key, i + 1, high)
+    } else -1
+  }) ensuring(res =>
+      res >= -1 &&
+      res < a.length &&
+      (if (res >= 0)
+          a(res) == key else
+          (high < 0 || (!occurs(a, low, (high+low)/2, key) && !occurs(a, (high+low)/2, high, key)))
+      )
+    )
+
+
+  def occurs(a: Array[Int], from: Int, to: Int, key: Int): Boolean = {
+    require(a.length >= 0 && to <= a.length && from >= 0)
+    def rec(i: Int): Boolean = {
+      require(i >= 0)
+      if(i >= to)
+        false
+      else {
+       if(a(i) == key) true else rec(i+1)
+      }
+    }
+    if(from >= to)
+      false
+    else
+      rec(from)
+  }
+
+
+  def sorted(a: Array[Int], l: Int, u: Int) : Boolean = {
+    require(a.length >= 0 && l >= 0 && l <= u + 1 && u < a.length)
+    val t = sortedWhile(true, l, l, u, a)
+    t._1
+  }
+
+  def sortedWhile(isSorted: Boolean, k: Int, l: Int, u: Int, a: Array[Int]): (Boolean, Int) = {
+    require(a.length >= 0 && l >= 0 && l <= u+1 && u < a.length && k >= l && k <= u + 1)
+    if(k < u) {
+      sortedWhile(if(a(k) > a(k + 1)) false else isSorted, k + 1, l, u, a)
+    } else (isSorted, k)
+  }
+
+  def main = {
+    val a = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+    val i = binarySearch(a, 2, 0, a.length - 1) // should be 2
+    val j = binarySearch(a, 11, 0, a.length - 1) // should be -1
+
+    (i - 2) + (j + 1) // == 0
+  }
+}
+
diff --git a/src/test/resources/regression/genc/valid/ExpressionOrder.scala b/src/test/resources/regression/genc/valid/ExpressionOrder.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f86f3e8d25919e18e6efa329e08ce71951fe6d78
--- /dev/null
+++ b/src/test/resources/regression/genc/valid/ExpressionOrder.scala
@@ -0,0 +1,119 @@
+import leon.lang._
+
+object ExpressionOrder {
+  case class Pixel(rgb: Int)
+  case class Matrix(data: Array[Int], w: Int, h: Int)
+
+  def fun = 0xffffff
+  def foo = 4
+  def bar(i: Int) = i * 2
+  def baz(i: Int, j: Int) = bar(i) - bar(j)
+
+  def syntaxCheck {
+    val p = Pixel(fun)
+    val m = Matrix(Array(0, 1, 2, 3), 2, 2)
+
+    val z = baz(foo, bar(foo))
+    val a = Array(0, 1, foo / 2, 3, bar(2), z / 1)
+
+    val t = (true, foo, bar(a(0)))
+  }
+
+  def main =
+      bool2int(test0(false), 1)  +
+      bool2int(test1(42),    2)  +
+      bool2int(test2(58),    4)  +
+      bool2int(test3(false), 8)  +
+      bool2int(test4(false), 16) +
+      bool2int(test6,        32) +
+      bool2int(test7,        64)
+
+  def test0(b: Boolean) = {
+    val f = b && !b // == false
+
+    var c = 0
+
+    val x = f && { c = 1; true }
+
+    c == 0
+  }
+
+  def test1(i: Int) = {
+    require(i > 0)
+
+    val j = i / i * 3 // == 3
+
+    var c = 0
+    val x = { c = c + 3; j } + { c = c + 1; j } * { c = c * 2; j }
+
+    c == 8 && j == 3 && x == 12
+  }
+
+  def test2(i: Int) = {
+    var c = 0;
+    val x = if (i < 0) { c = 1; -i } else { c = 2; i }
+
+    if (i < 0) c == 1
+    else c == 2
+  }
+
+  def test3(b: Boolean) = {
+    val f = b && !b // == false
+
+    var c = 0
+    val x = f || { c = 1; true } || { c = 2; false }
+
+    c == 1
+  }
+
+  def test4(b: Boolean) = {
+    var i = 10
+    var c = 0
+
+    val f = b && !b // == false
+    val t = b || !b // == true
+
+    // The following condition is executed 11 times,
+    // and only during the last execution is the last
+    // operand evaluated
+    while ({ c = c + 1; t } && i > 0 || { c = c * 2; f }) {
+      i = i - 1
+    }
+
+    i == 0 && c == 22
+  }
+
+  def test5(b: Boolean) = {
+    val f = b && !b // == false
+
+    var c = if (f) 0 else -1
+
+    c = c + (if (f) 0 else 1)
+
+    c == 0
+  }
+
+  def test6 = {
+    val a = Array(0, 1, 2, 3, 4)
+    def rec(b: Boolean, i: Int): Boolean = {
+      if (a.length <= i + 1) b
+      else rec(if (a(i) < a(i + 1)) b else false, i + 1)
+    }
+
+    rec(true, 0)
+  }
+
+  def test7 = {
+    var c = 1
+
+    val a = Array(0, 1, 2, 3, 4)
+
+    a(if(a(0) == 0) { c = c + 1; 0 } else { c = c + 2; 1 }) = { c = c * 2; -1 }
+
+    c == 4
+  }
+
+  def bool2int(b: Boolean, f: Int) = if (b) 0 else f;
+}
+
+
diff --git a/src/test/resources/regression/genc/valid/MaxSum.scala b/src/test/resources/regression/genc/valid/MaxSum.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1c6fc2432408132dd67505c450c8c6aa00c9c90c
--- /dev/null
+++ b/src/test/resources/regression/genc/valid/MaxSum.scala
@@ -0,0 +1,71 @@
+import leon.lang._
+
+/* VSTTE 2010 challenge 1 */
+
+object MaxSum {
+
+  def maxSum(a: Array[Int]): (Int, Int) = ({
+    require(a.length >= 0 && isPositive(a))
+    var sum = 0
+    var max = 0
+    var i = 0
+    (while(i < a.length) {
+      if(max < a(i))
+        max = a(i)
+      sum = sum + a(i)
+      i = i + 1
+    }) invariant (sum <= i * max && i >= 0 && i <= a.length)
+    (sum, max)
+  }) ensuring(res => res._1 <= a.length * res._2)
+
+
+  def isPositive(a: Array[Int]): Boolean = {
+    require(a.length >= 0)
+    def rec(i: Int): Boolean = {
+      require(i >= 0)
+      if(i >= a.length)
+        true
+      else {
+        if(a(i) < 0)
+          false
+        else
+          rec(i+1)
+      }
+    }
+    rec(0)
+  }
+
+  def summ(to : Int): Int = ({
+    require(to >= 0)
+    var i = 0
+    var s = 0
+    (while (i < to) {
+      s = s + i
+      i = i + 1
+    }) invariant (s >= 0 && i >= 0 && s == i*(i-1)/2 && i <= to)
+    s
+  }) ensuring(res => res >= 0 && res == to*(to-1)/2)
+
+
+  def sumsq(to : Int): Int = ({
+    require(to >= 0)
+    var i = 0
+    var s = 0
+    (while (i < to) {
+      s = s + i*i
+      i = i + 1
+    }) invariant (s >= 0 && i >= 0 && s == (i-1)*i*(2*i-1)/6 && i <= to)
+    s
+  }) ensuring(res => res >= 0 && res == (to-1)*to*(2*to-1)/6)
+
+  def main = {
+    val a = Array(1, 4, 6, 0, 234, 999)
+    val sm = maxSum(a)
+    val sum = sm._1
+    val max = sm._2
+    if (sum == 1244 && max == 999) 0
+    else -1
+  }
+
+}
+
diff --git a/src/test/resources/regression/genc/valid/RecursionAndNestedFunctions.scala b/src/test/resources/regression/genc/valid/RecursionAndNestedFunctions.scala
new file mode 100644
index 0000000000000000000000000000000000000000..70f5c150a585d6981a1e656e07f4148a407f0058
--- /dev/null
+++ b/src/test/resources/regression/genc/valid/RecursionAndNestedFunctions.scala
@@ -0,0 +1,34 @@
+import leon.lang._
+
+object RecursionAndNestedFunctions {
+
+  // Complex way to return i
+  def zzz(i: Int): Int = {
+    val x = 0
+    def rec(j: Int): Int = {
+      if (i - x == j)     i
+      else if (j > i) rec(j - 1)
+      else            rec(j + 1)
+    }
+
+    rec(4)
+  }
+
+
+  // Complex way to compute 100 + 2 * i
+  def foo(i: Int) = {
+    var j = i
+    def bar(x: Int) = {
+      //j = j - 1 <- not supported by leon
+      val y = x + i
+      def baz(z: Int) = z + y + i
+      //j = j + 1 <- not supported by leon
+      baz(42)
+    }
+    bar(58) + j - i
+  }
+
+  def main() = foo(2) - zzz(104)
+
+}
+
diff --git a/src/test/resources/regression/genc/valid/TupleArray.scala b/src/test/resources/regression/genc/valid/TupleArray.scala
new file mode 100644
index 0000000000000000000000000000000000000000..576ac3d270e6258ea3c73c48d7d91bfa6e9ed113
--- /dev/null
+++ b/src/test/resources/regression/genc/valid/TupleArray.scala
@@ -0,0 +1,22 @@
+import leon.lang._
+
+object TupleArray {
+  def exists(av: (Array[Int], Int)): Boolean = {
+    var i = 0;
+    var found = false;
+    while (!found && i < av._1.length) {
+      found = av._1(i) == av._2
+      i = i + 1
+    }
+    found
+  }
+
+  def main = {
+    val a = Array(0, 1, 5, -5, 9)
+    val e1 = exists((a, 0))
+    val e2 = exists((a, -1))
+    if (e1 && !e2) 0
+    else -1
+  }
+
+}
diff --git a/src/test/scala/leon/genc/GenCSuite.scala b/src/test/scala/leon/genc/GenCSuite.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c452c948c3567e02524d098388437bc6c6225838
--- /dev/null
+++ b/src/test/scala/leon/genc/GenCSuite.scala
@@ -0,0 +1,194 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package genc
+
+import leon.test.LeonRegressionSuite
+
+import leon.frontends.scalac.ExtractionPhase
+import leon.purescala.Definitions.Program
+import leon.utils.{ PreprocessingPhase, UniqueCounter }
+
+import scala.concurrent._
+import ExecutionContext.Implicits.global
+import scala.sys.process._
+
+import org.scalatest.{ Args, Status }
+
+import java.nio.file.{ Files, Path }
+
+class GenCSuite extends LeonRegressionSuite {
+
+  private val testDir = "regression/genc/"
+  private lazy val tmpDir = Files.createTempDirectory("genc")
+  private val ccflags = "-std=c99 -g -O0"
+  private val maxExecutionTime = 2 // seconds
+
+  private val counter = new UniqueCounter[Unit]
+  counter.nextGlobal // Start with 1
+
+  private case class ExtendedContext(leon: LeonContext, tmpDir: Path, progName: String)
+
+  // Tests are run as follows:
+  // - The classic ExtractionPhase & PreprocessingPhase are run on all input files
+  //   (this way the libraries are evaluated only once)
+  // - A Program is constructed for each input file
+  // - At this point no error should have occurred or something would be wrong
+  //   with the extraction phases
+  // - For each Program P:
+  //   + if P is expected to be convertible to C, then we make sure that:
+  //     * the GenerateCPhase run without trouble,
+  //     * the generated C code compiles using a C99 compiler without error,
+  //     * and that, when run, the exit code is 0
+  //   + if P is expected to be non-convertible to C, then we make sure that:
+  //     * the GenerateCPhase fails
+  private def mkTest(files: List[String], cat: String)(block: (ExtendedContext, Program) => Unit) = {
+    val extraction =
+      ExtractionPhase andThen
+      new PreprocessingPhase(true, true)
+
+    val ctx = createLeonContext(files:_*)
+
+    try {
+      val (_, ast) = extraction.run(ctx, files)
+
+      val programs = {
+        val (user, lib) = ast.units partition { _.isMainUnit }
+        user map ( u => Program(u :: lib) )
+      }
+
+      for { prog <- programs } {
+        val name = prog.units.head.id.name
+        val ctx  = createLeonContext(s"--o=$tmpDir/$name.c")
+        val xCtx = ExtendedContext(ctx, tmpDir, name)
+
+        val displayName = s"$cat/$name.scala"
+        val index       = counter.nextGlobal
+
+        test(f"$index%3d: $displayName") {
+          block(xCtx, prog)
+        }
+      }
+    } catch {
+      case fe: LeonFatalError =>
+        test("Compilation") {
+          fail(ctx, "Unexpected fatal error while setting up tests", fe)
+        }
+    }
+  }
+
+  // Run a process with a timeout and return the status code
+  private def runProcess(pb: ProcessBuilder): Int = runProcess(pb.run)
+  private def runProcess(p: Process): Int = {
+    val f = Future(blocking(p.exitValue()))
+    try {
+      Await.result(f, duration.Duration(maxExecutionTime, "sec"))
+    } catch {
+      case _: TimeoutException =>
+        p.destroy()
+        p.exitValue()
+    }
+  }
+
+  // Determine which C compiler is available
+  private def detectCompiler: Option[String] = {
+    val testCode = "int main() { return 0; }"
+    val testBinary = s"$tmpDir/test"
+
+    // NOTE this code might print error on stderr when a non-existing compiler
+    // is used. It seems that even with a special ProcessLogger the RuntimeException
+    // is printed for some reason.
+
+    def testCompiler(cc: String): Boolean = try {
+      val process = s"echo $testCode" #| s"$cc $ccflags -o $testBinary -xc -" #&& s"$testBinary"
+      runProcess(process) == 0
+    } catch {
+      case _: java.lang.RuntimeException => false
+    }
+
+    val knownCompiler = "cc" :: "clang" :: "gcc" :: "mingw" :: Nil
+    // Note that VS is not in the list as we cannot specify C99 dialect
+
+    knownCompiler find testCompiler
+  }
+
+  private def convert(xCtx: ExtendedContext)(prog: Program) = {
+    try {
+      GenerateCPhase(xCtx.leon, prog)
+    } catch {
+      case fe: LeonFatalError =>
+        fail(xCtx.leon, "Convertion to C unexpectedly failed", fe)
+    }
+  }
+
+  private def saveToFile(xCtx: ExtendedContext)(cprog: CAST.Prog) = {
+    CFileOutputPhase(xCtx.leon, cprog)
+  }
+
+  private def compile(xCtx: ExtendedContext, cc: String)(unused: Unit) = {
+    val basename     = s"${xCtx.tmpDir}/${xCtx.progName}"
+    val sourceFile   = s"$basename.c"
+    val compiledProg = basename
+
+    val process = Process(s"$cc $ccflags $sourceFile -o $compiledProg")
+    val status = runProcess(process)
+
+    assert(status == 0, "Compilation of converted program failed")
+  }
+
+  private def evaluate(xCtx: ExtendedContext)(unused: Unit) = {
+    val compiledProg = s"${xCtx.tmpDir}/${xCtx.progName}"
+
+    // TODO memory limit
+    val process = Process(compiledProg)
+
+    val status = runProcess(process)
+    assert(status == 0, s"Evaluation of converted program failed with status [$status]")
+  }
+
+  private def forEachFileIn(cat: String)(block: (ExtendedContext, Program) => Unit) {
+    val fs = filesInResourceDir(testDir + cat, _.endsWith(".scala")).toList
+
+    fs foreach { file =>
+      assert(file.exists && file.isFile && file.canRead,
+        s"Benchmark ${file.getName} is not a readable file")
+    }
+
+    val files = fs map { _.getPath }
+
+    mkTest(files, cat)(block)
+  }
+
+  protected def testValid(cc: String) = forEachFileIn("valid") { (xCtx, prog) =>
+    val converter = convert(xCtx) _
+    val saver     = saveToFile(xCtx) _
+    val compiler  = compile(xCtx, cc) _
+    val evaluator = evaluate(xCtx) _
+
+    val pipeline  = converter andThen saver andThen compiler andThen evaluator
+
+    pipeline(prog)
+  }
+
+  protected def testInvalid() = forEachFileIn("invalid") { (xCtx, prog) =>
+    intercept[LeonFatalError] {
+      GenerateCPhase(xCtx.leon, prog)
+    }
+  }
+
+  protected def testAll() = {
+    // Set C compiler according to the platform we're currently running on
+    detectCompiler match {
+      case Some(cc) => testValid(cc)
+      case None     => test("dectecting C compiler") { fail("no C compiler found") }
+    }
+
+    testInvalid()
+  }
+
+  override def run(testName: Option[String], args: Args): Status = {
+    testAll()
+    super.run(testName, args)
+  }
+}
+