diff --git a/src/main/scala/leon/repair/rules/Focus.scala b/src/main/scala/leon/repair/rules/Focus.scala
index a881953bb9354472703660cae8bacbb542e67596..e1f2f0cbd3b994a127425bfe1b3e9da17ee9ec3d 100644
--- a/src/main/scala/leon/repair/rules/Focus.scala
+++ b/src/main/scala/leon/repair/rules/Focus.scala
@@ -31,6 +31,8 @@ case object Focus extends PreprocessingRule("Focus") {
         
     }
 
+    val qeb = p.qebFiltered
+
     val fd      = hctx.functionContext
     val program = hctx.program
 
@@ -43,7 +45,7 @@ case object Focus extends PreprocessingRule("Focus") {
     def forAllTests(e: Expr, env: Map[Identifier, Expr], evaluator: Evaluator): Option[Boolean] = {
       var soFar: Option[Boolean] = None
 
-      p.eb.invalids.foreach { ex =>
+      qeb.invalids.foreach { ex =>
         evaluator.eval(e, (p.as zip ex.ins).toMap ++ env) match {
           case EvaluationResults.Successful(BooleanLiteral(b)) => 
             soFar match {
@@ -65,7 +67,7 @@ case object Focus extends PreprocessingRule("Focus") {
     }
 
     def existsFailing(e: Expr, env: Map[Identifier, Expr], evaluator: DeterministicEvaluator): Boolean = {
-      p.eb.invalids.exists { ex =>
+      qeb.invalids.exists { ex =>
         evaluator.eval(e, (p.as zip ex.ins).toMap ++ env).result match {
           case Some(BooleanLiteral(b)) => b
           case _ => true
@@ -105,7 +107,7 @@ case object Focus extends PreprocessingRule("Focus") {
           case Some(true) =>
             val cx = FreshIdentifier("cond", BooleanType)
             // Focus on condition
-            val np = Problem(p.as, ws(c), p.pc, letTuple(p.xs, IfExpr(cx.toVariable, thn, els), p.phi), List(cx), p.eb.stripOuts)
+            val np = Problem(p.as, ws(c), p.pc, letTuple(p.xs, IfExpr(cx.toVariable, thn, els), p.phi), List(cx), qeb.stripOuts)
 
             Some(decomp(List(np), termWrap(IfExpr(_, thn, els)), s"Focus on if-cond '${c.asString}'")(p))
 
@@ -113,17 +115,17 @@ case object Focus extends PreprocessingRule("Focus") {
             // Try to focus on branches
             forAllTests(c, Map(), evaluator) match {
               case Some(true) =>
-                val np = Problem(p.as, ws(thn), p.pc withCond c, p.phi, p.xs, p.qeb.filterIns(c))
+                val np = Problem(p.as, ws(thn), p.pc withCond c, p.phi, p.xs, qeb.filterIns(c))
 
                 Some(decomp(List(np), termWrap(IfExpr(c, _, els), c), s"Focus on if-then")(p))
               case Some(false) =>
-                val np = Problem(p.as, ws(els), p.pc withCond not(c), p.phi, p.xs, p.qeb.filterIns(not(c)))
+                val np = Problem(p.as, ws(els), p.pc withCond not(c), p.phi, p.xs, qeb.filterIns(not(c)))
 
                 Some(decomp(List(np), termWrap(IfExpr(c, thn, _), not(c)), s"Focus on if-else")(p))
               case None =>
                 // We split
-                val sub1 = p.copy(ws = ws(thn), pc = p.pc map (replace(Map(g -> thn), _)) withCond     c , eb = p.qeb.filterIns(c))
-                val sub2 = p.copy(ws = ws(els), pc = p.pc map (replace(Map(g -> thn), _)) withCond Not(c), eb = p.qeb.filterIns(Not(c)))
+                val sub1 = p.copy(ws = ws(thn), pc = p.pc map (replace(Map(g -> thn), _)) withCond     c , eb = qeb.filterIns(c))
+                val sub2 = p.copy(ws = ws(els), pc = p.pc map (replace(Map(g -> thn), _)) withCond Not(c), eb = qeb.filterIns(Not(c)))
 
                 val onSuccess: List[Solution] => Option[Solution] = { 
                   case List(s1, s2) =>
@@ -151,7 +153,7 @@ case object Focus extends PreprocessingRule("Focus") {
             val vars = map.toSeq.map(_._1)
 
             // Filter tests by the path-condition
-            val eb2 = p.qeb.filterIns(cond.toClause)
+            val eb2 = qeb.filterIns(cond.toClause)
 
             // Augment test with the additional variables and their valuations
             val ebF: (Seq[Expr] => List[Seq[Expr]]) = { (e: Seq[Expr]) =>
@@ -185,7 +187,7 @@ case object Focus extends PreprocessingRule("Focus") {
         if (existsFailing(elsePc.toClause, Map(), evaluator)) {
           val newCase    = MatchCase(WildcardPattern(None), None, NoTree(scrut.getType))
 
-          val eb = p.qeb.filterIns(elsePc.toClause)
+          val eb = qeb.filterIns(elsePc.toClause)
 
           val newProblem = Problem(p.as, andJoin(wss), p.pc merge elsePc, p.phi, p.xs, eb)
 
@@ -232,7 +234,6 @@ case object Focus extends PreprocessingRule("Focus") {
           None
         }
 
-
       case Let(id, value, body) =>
         val ebF: (Seq[Expr] => List[Seq[Expr]]) = { (e: Seq[Expr]) =>
           val map = (p.as zip e).toMap
@@ -242,7 +243,7 @@ case object Focus extends PreprocessingRule("Focus") {
           }.toList
         }
 
-        val np = Problem(p.as, ws(body), p.pc withBinding (id -> value), p.phi, p.xs, p.eb.mapIns(ebF))
+        val np = Problem(p.as, ws(body), p.pc withBinding (id -> value), p.phi, p.xs, qeb.mapIns(ebF))
 
         Some(decomp(List(np), termWrap(Let(id, value, _)), s"Focus on let-body")(p))
 
diff --git a/src/main/scala/leon/synthesis/ExamplesBank.scala b/src/main/scala/leon/synthesis/ExamplesBank.scala
index 6cababe398c6159ec4e5cce721b795a751825bda..e8d831a5c60f86c02e6faa3c7f7def2d766e8220 100644
--- a/src/main/scala/leon/synthesis/ExamplesBank.scala
+++ b/src/main/scala/leon/synthesis/ExamplesBank.scala
@@ -3,6 +3,7 @@
 package leon
 package synthesis
 
+import evaluators.DefaultEvaluator
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.Constructors._
@@ -167,6 +168,8 @@ object ExamplesBank {
   * allows us to evaluate expressions. */
 case class QualifiedExamplesBank(as: List[Identifier], xs: List[Identifier], eb: ExamplesBank)(implicit hctx: SearchContext) {
 
+  lazy val evaluator = new DefaultEvaluator(hctx, hctx.program).setEvaluationFailOnChoose(true)
+
   def removeOuts(toRemove: Set[Identifier]): QualifiedExamplesBank = {
     val nxs    = xs.filterNot(toRemove)
     val toKeep = xs.zipWithIndex.filterNot(x => toRemove(x._1)).map(_._2)
@@ -183,9 +186,7 @@ case class QualifiedExamplesBank(as: List[Identifier], xs: List[Identifier], eb:
 
   /** Filter inputs through expr which is an expression evaluating to a boolean */
   def filterIns(expr: Expr): QualifiedExamplesBank = {
-    filterIns(m =>
-      hctx.defaultEvaluator.eval(expr, m)
-      .result == Some(BooleanLiteral(true)))
+    filterIns(m => evaluator.eval(expr, m).result.contains(BooleanLiteral(true)))
   }
 
   /** Filters inputs through the predicate pred, with an assignment of input variables to expressions. */
@@ -203,6 +204,7 @@ case class QualifiedExamplesBank(as: List[Identifier], xs: List[Identifier], eb:
   }
 
   /** Maps inputs through the function f
+    *
     * @return A new ExampleBank */
   def mapIns(f: Seq[(Identifier, Expr)] => List[Seq[Expr]]) = {
     eb map {
diff --git a/src/main/scala/leon/synthesis/Problem.scala b/src/main/scala/leon/synthesis/Problem.scala
index 4127a28f5ebda80ecbfec4c3960b9d8fa18680b3..2a9b113e761d3aa820cd76f3cfb15c0c1ca23791 100644
--- a/src/main/scala/leon/synthesis/Problem.scala
+++ b/src/main/scala/leon/synthesis/Problem.scala
@@ -10,7 +10,7 @@ import purescala.Types._
 import purescala.Common._
 import purescala.Constructors._
 import purescala.Extractors._
-import purescala.Definitions.FunDef
+import leon.purescala.Definitions.FunDef
 import Witnesses._
 
 /** Defines a synthesis triple of the form:
@@ -21,6 +21,8 @@ import Witnesses._
   * @param pc The path condition so far
   * @param phi The formula on `as` and `xs` to satisfy
   * @param xs The list of output identifiers for which we want to compute a function
+  * @note Since the examples are not eagerly filtered by [[Rule]]s, some may not
+  *       pass the path condition. Use [[qebFiltered]] to get the legal ones.
   */
 case class Problem(as: List[Identifier], ws: Expr, pc: Path, phi: Expr, xs: List[Identifier], eb: ExamplesBank = ExamplesBank.empty) extends Printable {
 
@@ -50,12 +52,15 @@ case class Problem(as: List[Identifier], ws: Expr, pc: Path, phi: Expr, xs: List
     copy(ws = andJoin(wsList ++ es))
   }
 
+  def qebFiltered(implicit sctx: SearchContext) = qeb.filterIns(pc.fullClause)
+
   // Qualified example bank, allows us to perform operations (e.g. filter) with expressions
   def qeb(implicit sctx: SearchContext) = QualifiedExamplesBank(this.as, this.xs, eb)
 
 }
 
 object Problem {
+
   def fromSpec(
     spec: Expr,
     pc: Path = Path.empty,
diff --git a/src/main/scala/leon/synthesis/rules/ADTSplit.scala b/src/main/scala/leon/synthesis/rules/ADTSplit.scala
index 317f63807bf990624160e2f0cca40a332c3be879..56d28d01e82b17640a27738df7d6c9e65e6c2b73 100644
--- a/src/main/scala/leon/synthesis/rules/ADTSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/ADTSplit.scala
@@ -19,15 +19,6 @@ import evaluators.DefaultEvaluator
   * it will create a match case statement on all known subtypes. */
 case object ADTSplit extends Rule("ADT Split.") {
 
-  protected class NoChooseEvaluator(ctx: LeonContext, prog: Program) extends DefaultEvaluator(ctx, prog) {
-    override def e(expr: Expr)(implicit rctx: RC, gctx: GC): Expr = expr match {
-      case ch: Choose =>
-        throw new EvalError("Choose!")
-      case _ =>
-        super.e(expr)
-    }
-  }
-
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
     // We approximate knowledge of types based on facts found at the top-level
     // we don't care if the variables are known to be equal or not, we just
@@ -75,8 +66,6 @@ case object ADTSplit extends Rule("ADT Split.") {
       case Some((id, act, cases)) =>
         val oas = p.as.filter(_ != id)
 
-        val evaluator = new NoChooseEvaluator(hctx, hctx.program)
-
         val subInfo0 = for(ccd <- cases) yield {
           val isInputVar = p.as.contains(id)
           val cct = CaseClassType(ccd, act.tps)
@@ -101,6 +90,7 @@ case object ADTSplit extends Rule("ADT Split.") {
           val eb2 = {
             if (isInputVar) {
               // Filter out examples where id has the wrong type, and fix input variables
+              // Note: It is fine to filter here as no evaluation is required
               p.qeb.mapIns { inInfo =>
                 inInfo.toMap.apply(id) match {
                   case CaseClass(`cct`, vs) =>
@@ -110,10 +100,7 @@ case object ADTSplit extends Rule("ADT Split.") {
                 }
               }
             } else {
-              // Filter out examples where id has the wrong type
-              p.qeb.filterIns { inValues =>
-                evaluator.eval(id.toVariable, inValues ++ p.pc.bindings).result.exists(_.getType == cct)
-              }.eb
+              p.eb
             }
           }
           val newAs = if (isInputVar) args ::: oas else p.as
@@ -128,7 +115,6 @@ case object ADTSplit extends Rule("ADT Split.") {
           cct.fieldsTypes.count { t => t == act }
         }
 
-
         val onSuccess: List[Solution] => Option[Solution] = {
           case sols =>
             var globalPre = List[Expr]()
diff --git a/src/main/scala/leon/synthesis/rules/Assert.scala b/src/main/scala/leon/synthesis/rules/Assert.scala
index 61b356415f833f493bfc9d7ebf2bbf9c17676a9a..4b29537db8118ddf70d68b0c1024a1b950650e95 100644
--- a/src/main/scala/leon/synthesis/rules/Assert.scala
+++ b/src/main/scala/leon/synthesis/rules/Assert.scala
@@ -29,7 +29,7 @@ case object Assert extends NormalizingRule("Assert") {
               Some(solve(Solution(pre = andJoin(exprsA), defs = Set(), term = simplestOut)))
             }
           } else {
-            val sub = p.copy(pc = p.pc withConds exprsA, phi = andJoin(others), eb = p.qeb.filterIns(andJoin(exprsA)))
+            val sub = p.copy(pc = p.pc withConds exprsA, phi = andJoin(others))
 
             Some(decomp(List(sub), {
               case List(s @ Solution(pre, defs, term, isTrusted)) =>
diff --git a/src/main/scala/leon/synthesis/rules/CEGISLike.scala b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
index 3f2b23292619f6aa5b56eecf74f307b2c180289d..4a9a277b6851b25d6999436a61e0237e1be56129 100644
--- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
@@ -772,7 +772,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
           }
         }
 
-        val baseExampleInputs = p.qeb.filterIns(p.pc.fullClause).eb.examples ++ solverExample
+        val baseExampleInputs = p.qebFiltered.examples ++ solverExample
 
         ifDebug { debug =>
           baseExampleInputs.foreach { in =>
diff --git a/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala b/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala
index 6df6624bc2c54c9ef9637b9ca65ade8fe9fae977..8f1324828fc613a0bf277189b43bb583cd5a6bf5 100644
--- a/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala
+++ b/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala
@@ -50,16 +50,13 @@ case object GenericTypeEqualitySplit extends Rule("Eq. Split") {
             pc = p.pc map (subst(f -> t, _)),
             ws = subst(f -> t, p.ws),
             phi = subst(f -> t, p.phi),
-            eb = p.qeb.filterIns(Equals(v1, v2)).removeIns(Set(f))
+            eb = p.qeb.removeIns(Set(f))
           )
         } else {
           p.copy(pc = p.pc withCond Equals(v1,v2)).withWs(Seq(Inactive(f))) // FIXME!
         }
 
-        val neq = p.copy(
-          pc = p.pc withCond not(Equals(v1, v2)),
-          eb = p.qeb.filterIns(not(Equals(v1, v2))) // FIXME!
-        )
+        val neq = p.copy(pc = p.pc withCond not(Equals(v1, v2)))
 
         val subProblems = List(eq, neq)
 
diff --git a/src/main/scala/leon/synthesis/rules/IfSplit.scala b/src/main/scala/leon/synthesis/rules/IfSplit.scala
index 3d0c0d0ba406c7ba34ff83b80e4e62faabb51959..16e0f3066998b7e0fca0a63647e554b01d37ccf0 100644
--- a/src/main/scala/leon/synthesis/rules/IfSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/IfSplit.scala
@@ -13,8 +13,8 @@ case object IfSplit extends Rule("If-Split") {
 
     def split(i: IfExpr, description: String): RuleInstantiation = {
       val subs = List(
-        Problem(p.as, p.ws, p.pc withCond i.cond, replace(Map(i -> i.thenn), p.phi), p.xs, p.qeb.filterIns(i.cond)),
-        Problem(p.as, p.ws, p.pc withCond not(i.cond), replace(Map(i -> i.elze), p.phi), p.xs, p.qeb.filterIns(not(i.cond)))
+        Problem(p.as, p.ws, p.pc withCond i.cond, replace(Map(i -> i.thenn), p.phi), p.xs),
+        Problem(p.as, p.ws, p.pc withCond not(i.cond), replace(Map(i -> i.elze), p.phi), p.xs)
       )
 
       val onSuccess: List[Solution] => Option[Solution] = {
diff --git a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala
index cacb44a4657ac15f1d1228026a521182501bb0e3..17a4c0d072c1d9a86156371565e812f11ec89314 100644
--- a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala
+++ b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala
@@ -57,12 +57,12 @@ case object InequalitySplit extends Rule("Ineq. Split.") {
 
         val lt = if (!facts.contains(LT(v1, v2))) {
           val pc = LessThan(v1, v2)
-          Some(pc, p.copy(pc = p.pc withCond pc, eb = p.qeb.filterIns(pc)))
+          Some(pc, p.copy(pc = p.pc withCond pc))
         } else None
 
         val gt = if (!facts.contains(LT(v2, v1))) {
           val pc = GreaterThan(v1, v2)
-          Some(pc, p.copy(pc = p.pc withCond pc, eb = p.qeb.filterIns(pc)))
+          Some(pc, p.copy(pc = p.pc withCond pc))
         } else None
 
         val eq = if (!facts.contains(EQ(v1, v2)) && !facts.contains(EQ(v2,v1))) {
@@ -79,7 +79,7 @@ case object InequalitySplit extends Rule("Ineq. Split.") {
               pc = p.pc map (subst(f -> t, _)),
               ws = subst(f -> t, p.ws),
               phi = subst(f -> t, p.phi),
-              eb = p.qeb.filterIns(Equals(v1, v2)).removeIns(Set(f))
+              eb = p.qeb.removeIns(Set(f))
             )
           } else {
             p.copy(pc = p.pc withCond pc).withWs(Seq(Inactive(f))) // equality in pc is fine for numeric types
diff --git a/src/main/scala/leon/synthesis/rules/InputSplit.scala b/src/main/scala/leon/synthesis/rules/InputSplit.scala
index a14078ec808d6effd0e9fe64b689ccf14f3d251e..fbdca3ad269868dde0c8865b348066e4905b877c 100644
--- a/src/main/scala/leon/synthesis/rules/InputSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/InputSplit.scala
@@ -15,12 +15,10 @@ case object InputSplit extends Rule("In. Split") {
     p.allAs.filter(_.getType == BooleanType).flatMap { a =>
       def getProblem(v: Boolean): Problem = {
         def replaceA(e: Expr) = replaceFromIDs(Map(a -> BooleanLiteral(v)), e)
-
-        val tests = QualifiedExamplesBank(p.as, p.xs, p.qeb.filterIns(m => m(a) == BooleanLiteral(v)))
         
         val newPc: Path = {
           val withoutA = p.pc -- Set(a) map replaceA
-          withoutA withConds (p.pc.bindings.find(_._1 == a).map { case (id, res) =>
+          withoutA withConds (p.pc.bindings.collectFirst { case (`a`, res) =>
             if (v) res else not(res)
           })
         }
@@ -30,7 +28,7 @@ case object InputSplit extends Rule("In. Split") {
           ws  = replaceA(p.ws),
           pc  = newPc,
           phi = replaceA(p.phi),
-          eb  = tests.removeIns(Set(a))
+          eb  = p.qeb.removeIns(Set(a))
         )
       }
 
@@ -42,7 +40,9 @@ case object InputSplit extends Rule("In. Split") {
           Some(Solution(or(and(    Variable(a) , s1.pre),
                            and(Not(Variable(a)), s2.pre)),
                         s1.defs ++ s2.defs,
-                        IfExpr(Variable(a), s1.term, s2.term), s1.isTrusted && s2.isTrusted))
+                        IfExpr(Variable(a), s1.term, s2.term),
+                        s1.isTrusted && s2.isTrusted
+          ))
         case _ =>
           None
       }
diff --git a/src/main/scala/leon/synthesis/rules/IntroduceRecCalls.scala b/src/main/scala/leon/synthesis/rules/IntroduceRecCalls.scala
index 22af64c189a33afe9890fa3a62d8b7c74bb1da62..8c2f14cc2e209378b03d3a3d813792f7c9b0831a 100644
--- a/src/main/scala/leon/synthesis/rules/IntroduceRecCalls.scala
+++ b/src/main/scala/leon/synthesis/rules/IntroduceRecCalls.scala
@@ -74,7 +74,7 @@ case object IntroduceRecCalls extends NormalizingRule("Introduce rec. calls") {
             as = p.as ++ (if (specifyCalls) Nil else recs.map(_._1)),
             pc = recs.map(_._2).foldLeft(p.pc)(_ merge _),
             ws = andJoin(ws ++ newWs),
-            eb = p.qeb//.filterIns(filter _)
+            eb = p.eb
           )
 
           RuleExpanded(List(newProblem))
diff --git a/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala b/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala
index 8ef51a44db038af0990f0a35e8bac5f154713a15..e809fe8e04bf11fa456c605030dbb458b814c9c8 100644
--- a/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala
@@ -173,7 +173,6 @@ case object IntegerInequalities extends Rule("Integer Inequalities") {
         val subProblemxs: List[Identifier] = quotientIds ++ otherVars
         val subProblem = Problem(problem.as ++ remainderIds, problem.ws, problem.pc, subProblemFormula, subProblemxs)
 
-
         def onSuccess(sols: List[Solution]): Option[Solution] = sols match {
           case List(s @ Solution(pre, defs, term, isTrusted)) =>
             if(remainderIds.isEmpty) {