diff --git a/src/cp/CPPlugin.scala b/src/cp/CPPlugin.scala
index 1ec9b6a28f2c4b79deec72e90d348fcf3df6a006..4329315f5c6cbaf6b27da02637edcb52934bf5f0 100644
--- a/src/cp/CPPlugin.scala
+++ b/src/cp/CPPlugin.scala
@@ -30,7 +30,6 @@ class CPPlugin(val global: Global) extends PluginBase {
     "  -P:funcheck:impure             Generate testcases only for impure functions" + "\n" +
     "  -P:funcheck:testcases=[1,2]    Number of testcases to generate per function" + "\n" +
     "  -P:funcheck:testbounds=l:u     Lower and upper bounds for integers in recursive datatypes" + "\n" +
-    "  -P:funcheck:quiet              No info and warning messages from the extensions" + "\n" +
     "  -P:funcheck:XP                 Enable weird transformations and other bug-producing features" + "\n" +
     "  -P:funcheck:PLDI               PLDI 2011 settings. Now frozen. Not completely functional. See CAV." + "\n" +
     "  -P:funcheck:CAV                CAV 2011 settings. In progress." + "\n" +
@@ -47,7 +46,6 @@ class CPPlugin(val global: Global) extends PluginBase {
         case "uniqid"     =>                     purescala.Settings.showIDs = true
         case "parse"      =>                     stopAfterExtraction = true
         case "tolerant"   =>                     silentlyTolerateNonPureBodies = true
-        case "quiet"      =>                     purescala.Settings.quietExtensions = true
         case "nodefaults" =>                     purescala.Settings.runDefaultExtensions = false
         case "axioms"     =>                     purescala.Settings.noForallAxioms = false
         case "nobapa"     =>                     purescala.Settings.useBAPA = false
diff --git a/src/funcheck/AnalysisComponent.scala b/src/funcheck/AnalysisComponent.scala
index 7529c3a677af08a14c1891d00d1eefa470e3c912..78dafc2b0e2a3be40d99af3faaf3fdfa4d8549ac 100644
--- a/src/funcheck/AnalysisComponent.scala
+++ b/src/funcheck/AnalysisComponent.scala
@@ -32,16 +32,22 @@ class AnalysisComponent(val global: Global, val pluginInstance: FunCheckPlugin)
         println("Extraction complete. Now terminating the compiler process.")
         exit(0)
       } else {
-        println("Extracted program for " + unit + ". Re-run with -P:funcheck:parse to see the output.")
+        if(!pluginInstance.actionAfterExtraction.isDefined) {
+          println("Extracted program for " + unit + ". Re-run with -P:funcheck:parse to see the output.")
+        }
         //println(prog)
       }
 
-      println("Starting analysis.")
-      val analysis = new purescala.Analysis(prog)
-      analysis.analyse
-      if(pluginInstance.stopAfterAnalysis) {
-        println("Analysis complete. Now terminating the compiler process.")
-        exit(0)
+      if(!pluginInstance.actionAfterExtraction.isDefined) {
+        println("Starting analysis.")
+        val analysis = new purescala.Analysis(prog)
+        analysis.analyse
+        if(pluginInstance.stopAfterAnalysis) {
+          println("Analysis complete. Now terminating the compiler process.")
+          exit(0)
+        }
+      } else {
+        pluginInstance.actionAfterExtraction.get(prog)
       }
     }
   }
diff --git a/src/funcheck/FunCheckPlugin.scala b/src/funcheck/FunCheckPlugin.scala
index c5a70a1ebdd6c74356bac3072d62a6e1d593f7df..4bbc7c3b87e573f32c27631a609decb6094d81ab 100644
--- a/src/funcheck/FunCheckPlugin.scala
+++ b/src/funcheck/FunCheckPlugin.scala
@@ -3,9 +3,10 @@ package funcheck
 import scala.tools.nsc
 import scala.tools.nsc.{Global,Phase}
 import scala.tools.nsc.plugins.{Plugin,PluginComponent}
+import purescala.Definitions.Program
 
 /** This class is the entry point for the plugin. */
-class FunCheckPlugin(val global: Global) extends PluginBase {
+class FunCheckPlugin(val global: Global, val actionAfterExtraction : Option[Program=>Unit] = None) extends PluginBase {
   import global._
 
   val name = "funcheck"
@@ -30,7 +31,6 @@ class FunCheckPlugin(val global: Global) extends PluginBase {
     "  -P:funcheck:testcases=[1,2]    Number of testcases to generate per function" + "\n" +
     "  -P:funcheck:testbounds=l:u     Lower and upper bounds for integers in recursive datatypes" + "\n" +
     "  -P:funcheck:timeout=N          Sets a timeout of N seconds (FairZ3 only)" + "\n" +
-    "  -P:funcheck:quiet              No info and warning messages from the extensions" + "\n" +
     "  -P:funcheck:XP                 Enable weird transformations and other bug-producing features" + "\n" +
     "  -P:funcheck:PLDI               PLDI 2011 settings. Now frozen. Not completely functional. See CAV." + "\n" +
     "  -P:funcheck:CAV                CAV 2011 settings. In progress." + "\n" +
@@ -47,7 +47,6 @@ class FunCheckPlugin(val global: Global) extends PluginBase {
         case "uniqid"     =>                     purescala.Settings.showIDs = true
         case "parse"      =>                     stopAfterExtraction = true
         case "tolerant"   =>                     silentlyTolerateNonPureBodies = true
-        case "quiet"      =>                     purescala.Settings.quietExtensions = true
         case "nodefaults" =>                     purescala.Settings.runDefaultExtensions = false
         case "axioms"     =>                     purescala.Settings.noForallAxioms = false
         case "nobapa"     =>                     purescala.Settings.useBAPA = false
diff --git a/src/funcheck/Main.scala b/src/funcheck/Main.scala
index 330be229ee314fbe2cd29ccea433d970fe4970f3..1b9a703285648bd296fe7a7d550cf3a8abb3dec1 100644
--- a/src/funcheck/Main.scala
+++ b/src/funcheck/Main.scala
@@ -1,14 +1,13 @@
 package funcheck
 
 import scala.tools.nsc.{Global,Settings,SubComponent,CompilerCommand}
-import scala.tools.nsc.reporters.{ConsoleReporter,Reporter}
+
+import purescala.Definitions.Program
 
 /** This class is a compiler that will be used for running
 *  the plugin in standalone mode. Courtesy of D. Zufferey. */
-class PluginRunner(settings : Settings, reporter : Reporter) extends Global(settings, reporter) {
-  def this(settings : Settings) = this(settings, new ConsoleReporter(settings))
-
-    val funcheckPlugin = new FunCheckPlugin(this)
+class PluginRunner(settings : Settings, reportingFunction : String => Unit, actionOnProgram : Option[Program=>Unit]) extends Global(settings, new SimpleReporter(settings, reportingFunction)) {
+    val funcheckPlugin = new FunCheckPlugin(this, actionOnProgram)
 
     protected def addToPhasesSet(sub : SubComponent, descr : String) : Unit = {
     phasesSet += sub
@@ -33,12 +32,24 @@ class PluginRunner(settings : Settings, reporter : Reporter) extends Global(sett
 }
 
 object Main {
+  import purescala.{Reporter,DefaultReporter,Definitions,Analysis}
+  import Definitions.Program
+
   def main(args: Array[String]): Unit = {
+    main(args, new DefaultReporter)
+  }
+
+  def main(args: Array[String], reporter: Reporter) : Unit = {
     val settings = new Settings
-    runWithSettings(args, settings)
+    runWithSettings(args, settings, s => reporter.info(s), Some(p => defaultAction(p, reporter)))
+  }
+
+  private def defaultAction(program: Program, reporter: Reporter) : Unit = {
+    val analysis = new Analysis(program, reporter)
+    analysis.analyse
   }
 
-  private def runWithSettings(args : Array[String], settings : Settings) : Unit = {
+  private def runWithSettings(args : Array[String], settings : Settings, printerFunction : String=>Unit, actionOnProgram : Option[Program=>Unit] = None) : Unit = {
     val (funcheckOptions, nonfuncheckOptions) = args.toList.partition(_.startsWith("--"))
     val command = new CompilerCommand(nonfuncheckOptions, settings) {
       override val cmdName = "funcheck"
@@ -48,8 +59,10 @@ object Main {
       if(settings.version.value) {
         println(command.cmdName + " beta.")
       } else {
-        val runner = new PluginRunner(settings)
+        val runner = new PluginRunner(settings, printerFunction, actionOnProgram)
         runner.funcheckPlugin.processOptions(funcheckOptions.map(_.substring(2)), Console.err.println(_))
+        runner.funcheckPlugin.stopAfterExtraction = false
+        runner.funcheckPlugin.stopAfterAnalysis = false
         val run = new runner.Run
         run.compile(command.files)
       }
diff --git a/src/funcheck/SimpleReporter.scala b/src/funcheck/SimpleReporter.scala
new file mode 100644
index 0000000000000000000000000000000000000000..cd20fd8c53a35e7e496a3e6727e95927b505b163
--- /dev/null
+++ b/src/funcheck/SimpleReporter.scala
@@ -0,0 +1,70 @@
+package funcheck
+
+import scala.tools.nsc.Settings
+import scala.tools.nsc.reporters.AbstractReporter
+import scala.tools.nsc.util._
+
+/** This implements a reporter that calls the callback with every line that a
+regular ConsoleReporter would display. */
+class SimpleReporter(val settings: Settings, callback: String => Unit) extends AbstractReporter {
+  final val ERROR_LIMIT = 5
+
+  private def label(severity: Severity): String = severity match {
+    case ERROR   => "error"
+    case WARNING => "warning"
+    case INFO    => null
+  }
+
+  private def clabel(severity: Severity): String = {
+    val label0 = label(severity)
+    if (label0 eq null) "" else label0 + ": "
+  }
+
+  private def getCountString(severity: Severity): String =
+    countElementsAsString((severity).count, label(severity))
+
+  /** Prints the message. */
+  def printMessage(msg: String) { callback(msg) }
+
+  /** Prints the message with the given position indication. */
+  def printMessage(posIn: Position, msg: String) {
+    val pos = if (posIn eq null) NoPosition
+              else if (posIn.isDefined) posIn.inUltimateSource(posIn.source)
+              else posIn
+    pos match {
+      case FakePos(fmsg) =>
+        printMessage(fmsg+" "+msg)
+      case NoPosition =>
+        printMessage(msg)
+      case _ =>
+        val buf = new StringBuilder(msg)
+        val file = pos.source.file
+        printMessage(pos.line + ": " + msg)
+        printSourceLine(pos)
+    }
+  }
+  def print(pos: Position, msg: String, severity: Severity) {
+    printMessage(pos, clabel(severity) + msg)
+  }
+
+  def printSourceLine(pos: Position) {
+    printMessage(pos.lineContent.stripLineEnd)
+    printColumnMarker(pos)
+  }
+
+  def printColumnMarker(pos: Position) = 
+    if (pos.isDefined) { printMessage(" " * (pos.column - 1) + "^") }
+  
+  def printSummary() {
+    if (WARNING.count > 0) printMessage(getCountString(WARNING) + " found")
+    if (  ERROR.count > 0) printMessage(getCountString(ERROR  ) + " found")
+  }
+
+  def display(pos: Position, msg: String, severity: Severity) {
+    severity.count += 1
+    if (severity != ERROR || severity.count <= ERROR_LIMIT)
+      print(pos, msg, severity)
+  }
+
+  def displayPrompt: Unit = {}
+}
diff --git a/src/purescala/Analysis.scala b/src/purescala/Analysis.scala
index 4abcd0db6f37507add5824458dd76763bb0e0d42..4fb21174dfb2221b780a65d36676d898336e18b9 100644
--- a/src/purescala/Analysis.scala
+++ b/src/purescala/Analysis.scala
@@ -7,12 +7,8 @@ import TypeTrees._
 import Extensions._
 import scala.collection.mutable.{Set => MutableSet}
 
-class Analysis(val program: Program) {
-  // we always use the global reporter for this class
-  val reporter = Settings.reporter
-  // ...but not always for the extensions
-
-  Extensions.loadAll
+class Analysis(val program: Program, val reporter: Reporter = Settings.reporter) {
+  Extensions.loadAll(reporter)
 
   val analysisExtensions: Seq[Analyser] = loadedAnalysisExtensions
 
@@ -308,32 +304,4 @@ object Analysis {
     val result = searchAndReplaceDFS(applyToCall)(expression)
     liftLets(Implies(And(trueThings.reverse), result))
   }
-
-  // Rewrites pattern matching expressions where the cases simply correspond to
-  // the list of constructors
-  // def rewriteSimplePatternMatching(expression: Expr) : Expr = {
-  //   var extras : List[Expr] = Nil
-
-  //   def rewritePM(e: Expr) : Option[Expr] = e match {
-  //     // case NotSoSimplePatternMatching(_) => None
-  //     case SimplePatternMatching(scrutinee, classType, casesInfo) => {
-  //       val newVar = Variable(FreshIdentifier("pm", true)).setType(e.getType)
-  //       val scrutAsLetID = FreshIdentifier("scrut", true).setType(scrutinee.getType)
-  //       val lle : List[(Variable,List[Expr])] = casesInfo.map(cseInfo => {
-  //         val (ccd, newPID, argIDs, rhs) = cseInfo
-  //         val newPVar = Variable(newPID)
-  //         val argVars = argIDs.map(Variable(_))
-  //         (newPVar, List(Equals(newPVar, CaseClass(ccd, argVars)), Implies(Equals(Variable(scrutAsLetID), newPVar), Equals(newVar, rhs))))
-  //       }).toList
-  //       val (newPVars, newExtras) = lle.unzip
-  //       extras = Let(scrutAsLetID, scrutinee, And(Or(newPVars.map(Equals(Variable(scrutAsLetID), _))), And(newExtras.flatten))) :: extras 
-  //       Some(newVar)
-  //     }
-  //     case m @ MatchExpr(s,_) => Settings.reporter.error("Untranslatable PM expression on type " + s.getType + " : " + m); None
-  //     case _ => None
-  //   }
-
-  //   val newExpr = searchAndReplaceDFS(rewritePM)(expression)
-  //   liftLets(Implies(And(extras), newExpr))
-  // }
 }
diff --git a/src/purescala/Extensions.scala b/src/purescala/Extensions.scala
index 6e50cda68cae1e9427aa34c2b6ac342380997016..ca89dc913820259829df445268cc5dec5592261c 100644
--- a/src/purescala/Extensions.scala
+++ b/src/purescala/Extensions.scala
@@ -44,13 +44,7 @@ object Extensions {
   private var solverExtensions : Seq[Solver] = Nil
 
   // Returns the list of the newly loaded.
-  def loadAll : Seq[Extension] = {
-    val extensionsReporter =
-      if(Settings.quietExtensions) {
-        Settings.quietReporter
-      } else {
-        Settings.reporter
-      }
+  def loadAll(extensionsReporter : Reporter = Settings.reporter) : Seq[Extension] = {
     val allNames: Seq[String] = Settings.extensionNames
     val loaded = (if(!allNames.isEmpty) {
       val classLoader = Extensions.getClass.getClassLoader
@@ -85,11 +79,13 @@ object Extensions {
     }
     // these extensions are always loaded, unless specified otherwise
     val defaultExtensions: Seq[Extension] = if(Settings.runDefaultExtensions) {
-      if(Settings.useFairInstantiator) {
-        (new FairZ3Solver(extensionsReporter) :: Nil)
+      //(new TestExtension(extensionsReporter)) :: 
+      (if(Settings.useFairInstantiator) {
+        (new FairZ3Solver(extensionsReporter))
       } else {
-        (new Z3Solver(extensionsReporter)) :: Nil
-      }
+        (new Z3Solver(extensionsReporter))
+      }) ::
+      Nil
     } else {
       Nil
     }
diff --git a/src/purescala/Settings.scala b/src/purescala/Settings.scala
index 590f90b3f3d3650772a7c934e1de238d2c17b61b..8926d06ee921575468e52c8b4648d741b32ef137 100644
--- a/src/purescala/Settings.scala
+++ b/src/purescala/Settings.scala
@@ -4,11 +4,9 @@ package purescala
 object Settings {
   var experimental : Boolean = false
   var showIDs: Boolean = false
-  var quietExtensions: Boolean = false
   var functionsToAnalyse: Set[String] = Set.empty
   var extensionNames: Seq[String] = Nil
-  var reporter: Reporter = new DefaultReporter
-  var quietReporter: Reporter = new QuietReporter
+  lazy val reporter: Reporter = new DefaultReporter
   var runDefaultExtensions: Boolean = true
   var noForallAxioms: Boolean = true
   var unrollingLevel: Int = 0
diff --git a/src/purescala/TestExtension.scala b/src/purescala/TestExtension.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f2995d1e1e58ae6a7abea2ea0e3d401dc4eaeff8
--- /dev/null
+++ b/src/purescala/TestExtension.scala
@@ -0,0 +1,107 @@
+package purescala
+
+import purescala.Common._
+import purescala.Trees._
+import purescala.TypeTrees._
+import purescala.Definitions._
+import purescala.Extensions._
+
+class TestExtension(val reporter: Reporter) extends Analyser(reporter) {
+  val description : String = "Testing."
+  def analyse(program : Program) : Unit = {
+  }/*
+    for((f: FunDef) <- program.definedFunctions) {
+      reporter.info("Got an f ! " + f.id)
+      reporter.info("Normal  : " + f.body.get)
+      val iteized = matchToIfThenElse(expandLets(f.body.get))
+      reporter.info("ITEized : " + iteized)
+      reporter.info("Leadsto ? : " + (leadsToCall(iteized) : String))
+      cleanClausify(iteized, program)
+      val (e,l,m) = clausifyITE(iteized)
+      reporter.info("As clauses : " + e)
+      l.foreach(reporter.info(_))
+      reporter.info("***\n")
+    }
+    reporter.info("Done.")
+  }*/
+
+  type LiftedBoolean = Option[Boolean]
+  val Yes : LiftedBoolean  = Some(true)
+  val No : LiftedBoolean = Some(false)
+  val Maybe : LiftedBoolean = None
+  implicit def bool2liftedbool(b : Boolean) : LiftedBoolean = Some(b)
+  implicit def liftedbool2String(l : LiftedBoolean) : String = l match {
+    case Yes => "Yes"
+    case No => "No"
+    case Maybe => "Maybe"
+  }
+
+  // assumes no lets and no match.
+  def leadsToCall(e : Expr) : LiftedBoolean = e match {
+    case f : FunctionInvocation => true
+    case IfExpr(a1, a2, a3) => {
+      if(leadsToCall(a1) == Yes) Yes else (leadsToCall(a2),leadsToCall(a3)) match {
+        case (Yes,Yes) => Yes
+        case (No,No) => No
+        case _ => Maybe
+      }
+    }
+    case n @ NAryOperator(args, _) => {
+      val ra = args.map(leadsToCall(_))
+      if(ra.exists(_ == Yes)) {
+        Yes
+      } else if(ra.forall(_ == No)) {
+        No
+      } else {
+        Maybe
+      }
+    }
+    case b @ BinaryOperator(a1,a2,_) => (leadsToCall(a1),leadsToCall(a2)) match {
+      case (Yes,_) => Yes
+      case (_,Yes) => Yes
+      case (No,No) => No
+      case _ => Maybe
+    }
+    case u @ UnaryOperator(a,_) => leadsToCall(a)
+    case t : Terminal => false
+    case unhandled => scala.Predef.error("unhandled.")
+  }
+
+  private def cleanClausify(formula : Expr, program : Program) : Unit = {
+    val nonRec = allNonRecursiveFunctionCallsOf(formula, program)
+    val allRec = functionCallsOf(formula) -- nonRec
+
+    val (e,l,m) = clausifyITE(formula)
+    var dangerSet : Set[Expr] = Set.empty[Expr] ++ allRec
+    var change : Boolean = true
+    var newSet : Set[Expr] = Set.empty
+
+    while(change) {
+      change = false
+    }
+  }
+
+  private def clausifyITE(formula : Expr) : (Expr, List[Expr], Map[Identifier,Identifier]) = {
+    var newClauses : List[Expr] = Nil
+    var ite2Bools : Map[Identifier,Identifier] = Map.empty
+
+    def clausify(ex : Expr) : Option[Expr] = ex match {
+      //case _ if leadsToCall(ex) == No => None
+      case ie @ IfExpr(cond, then, elze) => {
+        val switch = FreshIdentifier("path", true).setType(BooleanType).toVariable
+        val placeHolder = FreshIdentifier("iteval", true).setType(ie.getType).toVariable
+        newClauses = Iff(switch, cond) :: newClauses
+        newClauses = Implies(switch, Equals(placeHolder, then)) :: newClauses
+        newClauses = Implies(Not(switch), Equals(placeHolder, elze)) :: newClauses
+        // newBools = newBools + switch.id
+        ite2Bools = ite2Bools + (placeHolder.id -> switch.id)
+        Some(placeHolder)
+      }
+      case _ => None
+    }
+
+    val cleanedUp = searchAndReplaceDFS(clausify)(formula)
+
+    (cleanedUp, newClauses.reverse, ite2Bools)
+  }
+}
diff --git a/testcases/PaperDemoExample.scala b/testcases/PaperDemoExample.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a55c26f48814b811bc42c157b1b7a117c9367c7f
--- /dev/null
+++ b/testcases/PaperDemoExample.scala
@@ -0,0 +1,19 @@
+object PaperDemoexample {
+    sealed abstract class List
+    case class Cons(head: Int, tail: List) extends List
+    case class Nil() extends List
+
+    def size(l: List) : Int = (l match {
+        case Nil() => 0
+        case Cons(_, t) => 1 + size(t)
+    })
+
+    def sizeTailRec(l: List) : Int = sizeAcc(l, 0)
+    def sizeAcc(l: List, acc: Int) : Int = {
+     require(acc >= 0)
+     l match {
+       case Nil() => acc
+       case Cons(_, xs) => sizeAcc(xs, acc+1)
+     }
+    } ensuring(res => res == size(l) + acc)
+}