diff --git a/src/funcheck/FunCheckPlugin.scala b/src/funcheck/FunCheckPlugin.scala
index 40ecbc08b5dd1e3b6db38bfd35f3fba62a1db66d..8799f320fad7f16eb89581d1d82abeddb89773b7 100644
--- a/src/funcheck/FunCheckPlugin.scala
+++ b/src/funcheck/FunCheckPlugin.scala
@@ -38,6 +38,7 @@ class FunCheckPlugin(val global: Global, val actionAfterExtraction : Option[Prog
     "  -P:funcheck:cores              Use UNSAT cores in the unrolling/refinement step" + "\n" +
     "  -P:funcheck:quickcheck         Use QuickCheck-like random search" + "\n" +
     "  -P:funcheck:parallel           Run all solvers in parallel" + "\n" +
+    "  -P:funcheck:templates          Use new ``FunctionTemplate'' technique" + "\n" +
     "  -P:funcheck:noLuckyTests       Do not perform additional tests to potentially find models early"
   )
 
@@ -60,6 +61,7 @@ class FunCheckPlugin(val global: Global, val actionAfterExtraction : Option[Prog
         case "cores"      =>                     purescala.Settings.useCores = true
         case "quickcheck" =>                     purescala.Settings.useQuickCheck = true
         case "parallel"   =>                     purescala.Settings.useParallel = true
+        case "templates"  =>                     purescala.Settings.useTemplates = true
         case "noLuckyTests" =>                   purescala.Settings.luckyTest = false
         case s if s.startsWith("unrolling=") =>  purescala.Settings.unrollingLevel = try { s.substring("unrolling=".length, s.length).toInt } catch { case _ => 0 }
         case s if s.startsWith("functions=") =>  purescala.Settings.functionsToAnalyse = Set(splitList(s.substring("functions=".length, s.length)): _*)
diff --git a/src/purescala/Analysis.scala b/src/purescala/Analysis.scala
index 0336206dcda337adc2d3b0bf0301b191815b7bcf..7f2bfad064c2fe027c945bee813630811f17ccc9 100644
--- a/src/purescala/Analysis.scala
+++ b/src/purescala/Analysis.scala
@@ -23,24 +23,11 @@ class Analysis(val program: Program, val reporter: Reporter = Settings.reporter)
   val inductionTactic = new InductionTactic(reporter)
   inductionTactic.setProgram(program)
 
-  def analyse : Unit = {
-    for(funDef <- program.definedFunctions.toList.sortWith((fd1, fd2) => fd1 < fd2)) {
-      if(funDef.hasImplementation) {
-        reporter.info("Creating template for " + funDef.id + "...") 
-
-        val t : FunctionTemplate = FunctionTemplate.mkTemplate(funDef)
-        reporter.info("The template : " + t)
-      } else {
-        reporter.info("Skipping template creating for " + funDef.id + " as it doesn't have a known implementation.")
-      }
-    }
-  }
-
   // Calling this method will run all analyses on the program passed at
   // construction time. If at least one solver is loaded, verification
   // conditions are generated and passed to all solvers. Otherwise, only the
   // Analysis extensions are run on the program.
-  def analyseReal : Unit = {
+  def analyse : Unit = {
     if(solverExtensions.size > 1) {
       reporter.info("Running verification condition generation...")
 
diff --git a/src/purescala/FairZ3Solver.scala b/src/purescala/FairZ3Solver.scala
index c0d0d48b770a11765ccefac10a88faa45f57dea3..d09b1399e470a21b788538b35d6791f52001d304 100644
--- a/src/purescala/FairZ3Solver.scala
+++ b/src/purescala/FairZ3Solver.scala
@@ -74,7 +74,11 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
     prepareSorts
     prepareFunctions
 
-    unrollingBank = new UnrollingBank
+    unrollingBank = if(Settings.useTemplates) {
+      new NewUnrollingBank
+    } else {
+      new UnrollingBank
+    }
     blockingSet = Set.empty
     toCheckAgainstModels = BooleanLiteral(true)
     varsInVC = Set.empty
@@ -488,17 +492,8 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
     varsInVC ++= variablesOf(expandedVC)
 
     reporter.info(" - Initial unrolling...")
-    val (basis, clauses, guards) = unrollingBank.closeUnrollings(expandedVC)
-    // println("Here is what we want to check against models : " + toCheckAgainstModels)
-    // println("New basis: " + e)
-    // println("Bunch of clauses:\n" + se.map(_.toString).mkString("\n"))
-    // println("Bunch of blocking bools: " + sib.map(_.toString).mkString(", "))
-
-    // println("Basis : " + basis)
-    val bb = toZ3Formula(z3, basis).get
-    // println("Base : " + bb)
-    z3.assertCnstr(bb)
-    // println(toZ3Formula(z3, basis).get)
+    val (clauses, guards) = unrollingBank.initialUnrolling(expandedVC)
+
     // for(clause <- clauses) {
     //   println("we're getting a new clause " + clause)
     //   z3.assertCnstr(toZ3Formula(z3, clause).get)
@@ -1136,7 +1131,7 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
       !filtered.isEmpty
     }
 
-    def wasUnrolledBefore(functionInvocation : FunctionInvocation) : Boolean = {
+    private def wasUnrolledBefore(functionInvocation : FunctionInvocation) : Boolean = {
       everythingEverUnrolled(functionInvocation)
     }
 
@@ -1144,7 +1139,12 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
       everythingEverUnrolled += functionInvocation
     }
 
-    def closeUnrollings(formula : Expr) : (Expr, Seq[Expr], Seq[(Identifier,Boolean)]) = {
+    def initialUnrolling(formula : Expr) : (Seq[Expr], Seq[(Identifier,Boolean)]) = {
+      val (e,s,ss) = closeUnrollings(formula)
+      (e +: s, ss)
+    }
+
+    private def closeUnrollings(formula : Expr) : (Expr, Seq[Expr], Seq[(Identifier,Boolean)]) = {
       var (basis, clauses, ite2Bools) = clausifyITE(formula)
 
       var unrolledNow : Set[FunctionInvocation] = Set.empty
@@ -1210,6 +1210,8 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
 
     // takes in a conjunction and returns a new conjunction, where all
     // non-recursive function calls are "defined" and "contracted"
+    // NEVER USED !!!
+    /*
     def expandAllNonRecursive(exprs: List[Expr]) : List[Expr] = {
       val todo : MutableSet[FunctionInvocation] = MutableSet.empty
       val todo2 : MutableSet[FunctionInvocation] = MutableSet.empty
@@ -1235,7 +1237,7 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
       }
 
       resulting
-    }
+    }*/
 
     // Returns between 0 and 2 tautologies with respect to the interpretation of
     // the function and its postcondition.
@@ -1284,13 +1286,23 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
       }
     }
 
-    private var invocations : List[FunctionInvocation] = Nil
+    // Old junk?
+    /*private var invocations : List[FunctionInvocation] = Nil
 
     def addInvocation(blocker: Identifier, polarity: Boolean, invocation: FunctionInvocation) : Unit = {
       invocations = invocation :: invocations
-    }
+    }*/
+  }
 
+  class NewUnrollingBank extends UnrollingBank {
+    // This is called just once, for the "initial unrolling".
+    override def initialUnrolling(formula : Expr) : (Seq[Expr], Seq[(Identifier,Boolean)]) = {
+      sys.error("Not implemented.")
+    }
 
+    override def unlock(id: Identifier, polarity: Boolean) : (Seq[Expr], Seq[(Identifier,Boolean)]) = {
+      sys.error("Not implemented.")
+    }
   }
 }
 
diff --git a/src/purescala/Settings.scala b/src/purescala/Settings.scala
index 900e9062b33102794278345e832e1fc7d23aec80..e2be9ef6e4a5fc8ac7763d43b6bc00eb834acea2 100644
--- a/src/purescala/Settings.scala
+++ b/src/purescala/Settings.scala
@@ -26,4 +26,5 @@ object Settings {
   var useParallel : Boolean = false
   // When this is None, use real integers
   var bitvectorBitwidth : Option[Int] = None
+  var useTemplates : Boolean = false
 }