diff --git a/src/main/scala/leon/Main.scala b/src/main/scala/leon/Main.scala
index 12d03362a6b34ea021649f56363bf5c85791ef12..4e91b91918b095e5bd83d7d71123e8d42e3c2e6e 100644
--- a/src/main/scala/leon/Main.scala
+++ b/src/main/scala/leon/Main.scala
@@ -15,9 +15,12 @@ object Main {
   }
 
   // Add whatever you need here.
-  lazy val allComponents : List[LeonComponent] = allPhases ++ Nil
+  lazy val allComponents : Set[LeonComponent] = allPhases.toSet ++ Set(
+    // It's a little unfortunate that we need to build one...
+    new solvers.z3.FairZ3Solver(LeonContext())
+  )
 
-  lazy val allOptions = allPhases.flatMap(_.definedOptions) ++ Set(
+  lazy val topLevelOptions : Set[LeonOptionDef] = Set(
       LeonFlagOptionDef ("synthesis",    "--synthesis",   "Partial synthesis of choose() constructs"),
       LeonFlagOptionDef ("xlang",        "--xlang",       "Support for extra program constructs (imperative,...)"),
       LeonFlagOptionDef ("parse",        "--parse",       "Checks only whether the program is valid PureScala"),
@@ -27,31 +30,26 @@ object Main {
       //  Unimplemented Options:
       //
       //  LeonFlagOptionDef("uniqid",        "--uniqid",             "When pretty-printing purescala trees, show identifiers IDs"),
-      //  LeonValueOptionDef("extensions",   "--extensions=ex1:...", "Specifies a list of qualified class names of extensions to be loaded"),
-      //  LeonFlagOptionDef("nodefaults",    "--nodefaults",         "Runs only the analyses provided by the extensions"),
-      //  LeonValueOptionDef("functions",    "--functions=fun1:...", "Only generates verification conditions for the specified functions"),
-      //  LeonFlagOptionDef("unrolling",     "--unrolling=[0,1,2]",  "Unrolling depth for recursive functions" ),
-      //  LeonFlagOptionDef("axioms",        "--axioms",             "Generate simple forall axioms for recursive functions when possible" ),
       //  LeonFlagOptionDef("tolerant",      "--tolerant",           "Silently extracts non-pure function bodies as ''unknown''"),
       //  LeonFlagOptionDef("bapa",          "--bapa",               "Use BAPA Z3 extension (incompatible with many other things)"),
       //  LeonFlagOptionDef("impure",        "--impure",             "Generate testcases only for impure functions"),
       //  LeonValueOptionDef("testcases",    "--testcases=[1,2]",    "Number of testcases to generate per function"),
       //  LeonValueOptionDef("testbounds",   "--testbounds=l:u",     "Lower and upper bounds for integers in recursive datatypes"),
       //  LeonValueOptionDef("timeout",      "--timeout=N",          "Sets a timeout of N seconds"),
-      //  LeonFlagOptionDef("XP",            "--XP",                 "Enable weird transformations and other bug-producing features"),
       //  LeonFlagOptionDef("BV",            "--BV",                 "Use bit-vectors for integers"),
-      //  LeonFlagOptionDef("prune",         "--prune",              "Use additional SMT queries to rule out some unrollings"),
-      //  LeonFlagOptionDef("cores",         "--cores",              "Use UNSAT cores in the unrolling/refinement step"),
       //  LeonFlagOptionDef("quickcheck",    "--quickcheck",         "Use QuickCheck-like random search"),
       //  LeonFlagOptionDef("parallel",      "--parallel",           "Run all solvers in parallel"),
-      //  LeonFlagOptionDef("noLuckyTests",  "--noLuckyTests",       "Do not perform additional tests to potentially find models early"),
-      //  LeonFlagOptionDef("noverifymodel", "--noverifymodel",      "Do not verify the correctness of models returned by Z3"),
       //  LeonValueOptionDef("tags",         "--tags=t1:...",        "Filter out debug information that are not of one of the given tags"),
     )
 
+  lazy val allOptions = allComponents.flatMap(_.definedOptions) ++ topLevelOptions
+
   def displayHelp(reporter: Reporter) {
     reporter.info("usage: leon [--xlang] [--synthesis] [--help] [--debug=<N>] [..] <files>")
     reporter.info("")
+    for (opt <- topLevelOptions.toSeq.sortBy(_.name)) {
+      reporter.info("%-20s %s".format(opt.usageOption, opt.usageDesc))
+    }
     reporter.info("(By default, Leon verifies PureScala programs.)")
     reporter.info("")
     reporter.info("Additional options, by component:")
@@ -96,7 +94,7 @@ object Main {
           case (false, LeonValueOption(name, value)) =>
             Some(leonOpt)
           case _ =>
-            reporter.error("Invalid option usage: "+opt)
+            reporter.error("Invalid option usage: " + opt)
             displayHelp(reporter)
             None
         }
diff --git a/src/main/scala/leon/Settings.scala b/src/main/scala/leon/Settings.scala
index 5536471de0c28dad8eadc8e8b1de7f4dd482252b..ffcf50c8b008d00b49d161cf525e8b2ac5a60fbb 100644
--- a/src/main/scala/leon/Settings.scala
+++ b/src/main/scala/leon/Settings.scala
@@ -5,17 +5,11 @@ package leon
 object Settings {
   var showIDs: Boolean = false
   lazy val reporter: Reporter = new DefaultReporter
-  var noForallAxioms: Boolean = true
-  var unrollingLevel: Int = 0
   var useBAPA: Boolean = false
   var impureTestcases: Boolean = false
   var nbTestcases: Int = 1
   var testBounds: (Int, Int) = (0, 3)
-  var useCores : Boolean = false
-  var pruneBranches : Boolean = false
   var solverTimeout : Option[Int] = None
-  var luckyTest : Boolean = true
-  var verifyModel : Boolean = true
   var useQuickCheck : Boolean = false
   var useParallel : Boolean = false
   // When this is None, use real integers
diff --git a/src/main/scala/leon/plugin/LeonPlugin.scala b/src/main/scala/leon/plugin/LeonPlugin.scala
index af25f91d36ae4a653a830fcec6d6d481c9fa76c8..bb03f0d7999cd937d35a7638cc2116b437a1d54c 100644
--- a/src/main/scala/leon/plugin/LeonPlugin.scala
+++ b/src/main/scala/leon/plugin/LeonPlugin.scala
@@ -18,7 +18,6 @@ class LeonPlugin(val global: PluginRunner) extends Plugin {
     "  --uniqid             When pretty-printing purescala trees, show identifiers IDs" + "\n" +
     "  --with-code          Allows the compiler to keep running after the static analysis" + "\n" +
     "  --parse              Checks only whether the program is valid PureScala" + "\n" +
-    "  --unrolling=[0,1,2]  Unrolling depth for recursive functions" + "\n" + 
     "  --axioms             Generate simple forall axioms for recursive functions when possible" + "\n" + 
     "  --tolerant           Silently extracts non-pure function bodies as ''unknown''" + "\n" +
     "  --bapa               Use BAPA Z3 extension (incompatible with many other things)" + "\n" +
@@ -27,11 +26,8 @@ class LeonPlugin(val global: PluginRunner) extends Plugin {
     "  --testbounds=l:u     Lower and upper bounds for integers in recursive datatypes" + "\n" +
     "  --timeout=N          Sets a timeout of N seconds" + "\n" +
     "  --BV                 Use bit-vectors for integers" + "\n" +
-    "  --prune              Use additional SMT queries to rule out some unrollings" + "\n" +
-    "  --cores              Use UNSAT cores in the unrolling/refinement step" + "\n" +
     "  --quickcheck         Use QuickCheck-like random search" + "\n" +
     "  --parallel           Run all solvers in parallel" + "\n" +
-    "  --noverifymodel      Do not verify the correctness of models returned by Z3" + "\n" +
     "  --debug=[1-5]        Debug level" + "\n" +
     "  --imperative         Preprocessing and transformation from imperative programs" + "\n" +
     "  --synthesis          Magic!"
@@ -46,15 +42,11 @@ class LeonPlugin(val global: PluginRunner) extends Plugin {
         case "uniqid"        =>                     leon.Settings.showIDs = true
         case "parse"         =>                     leon.Settings.stopAfterExtraction = true
         case "tolerant"      =>                     leon.Settings.silentlyTolerateNonPureBodies = true
-        case "axioms"        =>                     leon.Settings.noForallAxioms = false
         case "bapa"          =>                     leon.Settings.useBAPA = true
         case "impure"        =>                     leon.Settings.impureTestcases = true
         case "BV"            =>                     leon.Settings.bitvectorBitwidth = Some(32)
-        case "prune"         =>                     leon.Settings.pruneBranches = true
-        case "cores"         =>                     leon.Settings.useCores = true
         case "quickcheck"    =>                     leon.Settings.useQuickCheck = true
         case "parallel"      =>                     leon.Settings.useParallel = true
-        case "noverifymodel" =>                     leon.Settings.verifyModel = false
         case "imperative"     =>                    leon.Settings.synthesis = false;
                                                     leon.Settings.transformProgram = true;
         case "synthesis"     =>                     leon.Settings.synthesis = true;
@@ -62,7 +54,6 @@ class LeonPlugin(val global: PluginRunner) extends Plugin {
                                                     leon.Settings.stopAfterTransformation = true;
 
         case s if s.startsWith("debug=") =>       leon.Settings.debugLevel = try { s.substring("debug=".length, s.length).toInt } catch { case _ => 0 }
-        case s if s.startsWith("unrolling=") =>  leon.Settings.unrollingLevel = try { s.substring("unrolling=".length, s.length).toInt } catch { case _ => 0 }
         case s if s.startsWith("testbounds=") => leon.Settings.testBounds = try { val l = splitList(s.substring("testBounds=".length, s.length)).map(_.toInt); if (l.size != 2) (0, 3) else (l(0), l(1)) } catch { case _ => (0, 3) }
         case s if s.startsWith("timeout=") => leon.Settings.solverTimeout = try { Some(s.substring("timeout=".length, s.length).toInt) } catch { case _ => None }
         case s if s.startsWith("testcases=") =>  leon.Settings.nbTestcases = try { s.substring("testcases=".length, s.length).toInt } catch { case _ => 1 }
diff --git a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala
index 5990c71655a60f9231a470fafd31c4fbf1e483ae..395bf29f067a0454f5fb33d2687f8c531495cae9 100644
--- a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala
+++ b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala
@@ -21,9 +21,29 @@ class FairZ3Solver(context : LeonContext)
      with Z3ModelReconstruction 
      with LeonComponent {
 
+  enclosing =>
+
   val name = "Z3-f"
   val description = "Fair Z3 Solver"
 
+  override val definedOptions : Set[LeonOptionDef] = Set(
+    LeonFlagOptionDef("checkmodels",  "--checkmodels",  "Double-check counter-examples"),
+    LeonFlagOptionDef("feelinglucky", "--feelinglucky", "Use evaluator to find counter-examples early")
+  )
+
+  val (feelingLucky, checkModels) = locally {
+    var lucky = false
+    var check = false
+
+    for(opt <- context.options) opt match {
+      case LeonFlagOption("checkmodels") => check = true
+      case LeonFlagOption("feelinglucky") => lucky = true
+      case _ =>
+    }
+
+    (lucky,check)
+  }
+
   // this is fixed
   protected[leon] val z3cfg = new Z3Config(
     "MODEL" -> true,
@@ -60,59 +80,6 @@ class FairZ3Solver(context : LeonContext)
     }
   }
 
-  private def prepareAxioms(solver: Z3Solver): Unit = {
-    assert(!Settings.noForallAxioms)
-    program.definedFunctions.foreach(_ match {
-      case fd @ Catamorphism(acd, cases) => {
-        assert(!fd.hasPrecondition && fd.hasImplementation)
-        reporter.info("Will attempt to axiomatize the function definition:")
-        reporter.info(fd)
-        for(cse <- cases) {
-          val (cc @ CaseClass(ccd, args), expr) = cse
-          assert(args.forall(_.isInstanceOf[Variable]))
-          val argsAsIDs = args.map(_.asInstanceOf[Variable].id)
-          assert(variablesOf(expr) -- argsAsIDs.toSet == Set.empty)
-          val axiom : Z3AST = if(args.isEmpty) {
-            val eq = Equals(FunctionInvocation(fd, Seq(cc)), expr)
-            toZ3Formula(eq).get
-          } else {
-            val z3ArgSorts = argsAsIDs.map(i => typeToSort(i.getType))
-            val boundVars = z3ArgSorts.zipWithIndex.map(p => z3.mkBound(p._2, p._1))
-            val map : Map[Identifier,Z3AST] = (argsAsIDs zip boundVars).toMap
-            val eq = Equals(FunctionInvocation(fd, Seq(cc)), expr)
-            val z3IzedEq = toZ3Formula(eq, map).get
-            val z3IzedCC = toZ3Formula(cc, map).get
-            val pattern = z3.mkPattern(functionDefToDecl(fd)(z3IzedCC))
-            val nameTypePairs = z3ArgSorts.map(s => (z3.mkFreshIntSymbol, s))
-            z3.mkForAll(0, List(pattern), nameTypePairs, z3IzedEq)
-          }
-          // println("I'll assert now an axiom: " + axiom)
-          // println("Case axiom:")
-          // println(axiom)
-          solver.assertCnstr(axiom)
-        }
-
-        if(fd.hasPostcondition) {
-          // we know it doesn't contain any function invocation
-          val cleaned = matchToIfThenElse(expandLets(fd.postcondition.get))
-          val argSort = typeToSort(fd.args(0).getType)
-          val bound = z3.mkBound(0, argSort)
-          val subst = replace(Map(ResultVariable() -> FunctionInvocation(fd, Seq(fd.args(0).toVariable))), cleaned)
-          val z3IzedPost = toZ3Formula(subst, Map(fd.args(0).id -> bound)).get
-          val pattern = z3.mkPattern(functionDefToDecl(fd)(bound))
-          val nameTypePairs = Seq((z3.mkFreshIntSymbol, argSort))
-          val postAxiom = z3.mkForAll(0, List(pattern), nameTypePairs, z3IzedPost)
-          //println("Post axiom:")
-          //println(postAxiom)
-          solver.assertCnstr(postAxiom)
-        }
-
-        axiomatizedFunctions += fd
-      }
-      case _ => ;
-    })
-  }
-
   override def solve(vc: Expr) = {
     val solver = getNewSolver
     solver.assertCnstr(Not(vc))
@@ -271,17 +238,12 @@ class FairZ3Solver(context : LeonContext)
 
     val solver = z3.mkSolver
 
-    if(!Settings.noForallAxioms) {
-      prepareAxioms(solver)
-    }
-
     for(funDef <- program.definedFunctions) {
       if (funDef.annotations.contains("axiomatize") && !axiomatizedFunctions(funDef)) {
         reporter.warning("Function " + funDef.id + " was marked for axiomatization but could not be handled.")
       }
     }
 
-
     private var frameGuards      = List[Z3AST](z3.mkFreshConst("frame", z3.mkBoolSort))
     private var frameExpressions = List[List[Expr]](Nil)
     private var varsInVC         = Set[Identifier]()
@@ -368,10 +330,7 @@ class FairZ3Solver(context : LeonContext)
       // these are the optional sequence of assumption literals
       val assumptionsAsZ3: Seq[Z3AST] = frameGuards ++ assumptions.map(toZ3Formula(_).get)
 
-      var iterationsLeft : Int = if(Settings.unrollingLevel > 0) Settings.unrollingLevel else 16121984
-
       while(!foundDefinitiveAnswer && !forceStop) {
-        iterationsLeft -= 1
 
         //val blockingSetAsZ3 : Seq[Z3AST] = blockingSet.toSeq.map(toZ3Formula(_).get)
         // println("Blocking set : " + blockingSet)
@@ -398,7 +357,7 @@ class FairZ3Solver(context : LeonContext)
 
             val z3model = solver.getModel
 
-            if (Settings.verifyModel && false) {
+            if (enclosing.checkModels) {
               val (isValid, model) = validateAndDeleteModel(z3model, entireFormula, varsInVC)
 
               if (isValid) {
@@ -432,7 +391,7 @@ class FairZ3Solver(context : LeonContext)
             reporter.info("UNSAT BECAUSE: "+core.mkString(" AND "))
 
             if (!forceStop) {
-              if (Settings.luckyTest && false) { //TODO: something with false
+              if (enclosing.feelingLucky) {
                 // we need the model to perform the additional test
                 reporter.info(" - Running search without blocked literals (w/ lucky test)")
               } else {
@@ -449,7 +408,7 @@ class FairZ3Solver(context : LeonContext)
                   foundAnswer(Some(false), core = z3CoreToCore(solver.getUnsatCore))
                 case Some(true) =>
                   //reporter.info("SAT WITHOUT Blockers")
-                  if (Settings.luckyTest && !forceStop) { //TODO: still with the above "false"
+                  if (enclosing.feelingLucky) {
                     // we might have been lucky :D
                     luckyTime.start
                     val (wereWeLucky, cleanModel) = validateAndDeleteModel(solver.getModel, entireFormula, varsInVC)
@@ -470,52 +429,6 @@ class FairZ3Solver(context : LeonContext)
             if(!foundDefinitiveAnswer) { 
               reporter.info("- We need to keep going.")
 
-              // reporter.info(" - toRelease   : " + toRelease)
-              // reporter.info(" - blockingSet : " + blockingSet)
-
-              //var fixedForEver : Set[Expr] = Set.empty
-
-              //if(Settings.pruneBranches) {
-              //  z3Time.start
-              //  for(ex <- blockingSet) ex match {
-              //    case Not(Variable(b)) =>
-              //      solver.push
-              //      solver.assertCnstr(toZ3Formula(Variable(b)).get)
-              //      solver.check match {
-              //        case Some(false) =>
-              //          //println("We had ~" + b + " in the blocking set. We now know it should stay there forever.")
-              //          solver.pop(1)
-              //          solver.assertCnstr(toZ3Formula(Not(Variable(b))).get)
-              //          fixedForEver = fixedForEver + ex
-
-              //        case _ =>
-              //          solver.pop(1)
-              //      }
-
-              //    case Variable(b) =>
-              //      solver.push
-              //      solver.assertCnstr(toZ3Formula(Not(Variable(b))).get)
-              //      solver.check match {
-              //        case Some(false) =>
-              //          //println("We had " + b + " in the blocking set. We now know it should stay there forever.")
-              //          solver.pop(1)
-              //          solver.assertCnstr(toZ3Formula(Variable(b)).get)
-              //          fixedForEver = fixedForEver + ex
-
-              //        case _ =>
-              //          solver.pop(1)
-              //      }
-
-              //    case _ =>
-              //      scala.sys.error("Should not have happened.")
-              //  }
-
-              //  if(fixedForEver.size > 0) {
-              //    reporter.info("- Pruned out " + fixedForEver.size + " branches.")
-              //  }
-              //  z3Time.stop
-              //}
-
               val toReleaseAsPairs = unrollingBank.getBlockersToUnlock
 
               reporter.info(" - more unrollings")
@@ -533,11 +446,6 @@ class FairZ3Solver(context : LeonContext)
               reporter.info(" - finished unrolling")
             }
         }
-
-        if(iterationsLeft <= 0) {
-          reporter.error(" - Max. number of iterations reached.")
-          foundAnswer(None)
-        }
       }
 
       totalTime.stop