diff --git a/src/main/scala/leon/synthesis/rules/CEGISLike.scala b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
index 238d3198f355b7e0bb8a07c75fbcac938530c7a2..1a6a5bb2ffa3dcf80a2b5373db87f8aedc50cced 100644
--- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
@@ -37,6 +37,8 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
 
+    import hctx.reporter._
+
     val exSolverTo  = 2000L
     val cexSolverTo = 3000L
 
@@ -184,7 +186,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
           c
         }
 
-        hctx.reporter.ifDebug { printer =>
+        ifDebug { printer =>
           printer("Grammar so far:")
           grammar.printProductions(printer)
           printer("")
@@ -226,7 +228,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
         val c = allProgramsCount()
 
         if (c > nProgramsLimit) {
-          hctx.reporter.debug(s"Exceeded program limit: $c > $nProgramsLimit")
+          debug(s"Exceeded program limit: $c > $nProgramsLimit")
           return Seq()
         }
 
@@ -279,7 +281,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
         val outerSolution = {
           new PartialSolution(hctx.search.strat, true)
             .solutionAround(hctx.currentNode)(FunctionInvocation(cTreeFd.typed, p.as.map(_.toVariable)))
-            .getOrElse(hctx.reporter.fatalError("Unable to get outer solution"))
+            .getOrElse(fatalError("Unable to get outer solution"))
         }
 
         val program0 = addFunDefs(hctx.program, Seq(cTreeFd, phiFd) ++ outerSolution.defs, hctx.functionContext)
@@ -476,11 +478,11 @@ abstract class CEGISLike(name: String) extends Rule(name) {
               println(err)
               println()
             }*/
-            hctx.reporter.debug("RE testing CE: "+err)
+            debug("RE testing CE: "+err)
             Some(false)
 
           case EvaluationResults.EvaluatorError(err) =>
-            hctx.reporter.debug("Error testing CE: "+err)
+            debug("Error testing CE: "+err)
             None
         }
 
@@ -525,7 +527,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
           val eval = new DefaultEvaluator(hctx, innerProgram)
 
           if (cexs exists (cex => eval.eval(cnstr, p.as.zip(cex).toMap).result == Some(BooleanLiteral(true)))) {
-            hctx.reporter.debug(s"Rejected by CEX: $outerSol")
+            debug(s"Rejected by CEX: $outerSol")
             excludeProgram(bs, true)
             cTreeFd.fullBody = origImpl
           } else {
@@ -534,11 +536,11 @@ abstract class CEGISLike(name: String) extends Rule(name) {
             val solverf = SolverFactory.getFromSettings(hctx, innerProgram).withTimeout(cexSolverTo)
             val solver = solverf.getNewSolver()
             try {
-              hctx.reporter.debug("Sending candidate to solver...")
+              debug("Sending candidate to solver...")
               solver.assertCnstr(cnstr)
               solver.check match {
                 case Some(true) =>
-                  hctx.reporter.debug(s"Proven invalid: $outerSol")
+                  debug(s"Proven invalid: $outerSol")
                   excludeProgram(bs, true)
                   val model = solver.getModel
                   //println("Found counter example: ")
@@ -553,13 +555,13 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
                 case Some(false) =>
                   // UNSAT, valid program
-                  hctx.reporter.debug("Found valid program!")
+                  debug("Found valid program!")
                   return Right(Solution(BooleanLiteral(true), Set(), outerSol, true))
 
                 case None =>
+                  debug("Found a non-verifiable solution...")
                   if (useOptTimeout) {
                     // Optimistic valid solution
-                    hctx.reporter.debug("Found a non-verifiable solution...")
                     best = Some(Solution(BooleanLiteral(true), Set(), outerSol, false))
                   }
               }
@@ -573,12 +575,16 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
         best.map{ sol =>
           // Interpret timeout in CE search as "the candidate is valid"
-          hctx.reporter.info("CEGIS could not prove the validity of the resulting expression")
+          info("CEGIS could not prove the validity of the resulting expression")
           Right(sol)
         }.getOrElse(Left(cexs))
       }
 
       def allProgramsClosed = prunedPrograms.isEmpty
+      def closeAllPrograms() = {
+        excludedPrograms ++= prunedPrograms
+        prunedPrograms = Set()
+      }
 
       // Explicitly remove program computed by bValues from the search space
       //
@@ -673,8 +679,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
                * might timeout instead of returning Some(false). We might still
                * benefit from unfolding further
                */
-              hctx.reporter.debug("Timeout while getting tentative program!")
-              Some(None)
+              None
           }
         } finally {
           timers.tentative.stop()
@@ -735,7 +740,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
         implicit val ic = hctx
 
-        hctx.reporter.debug("Acquiring initial list of examples")
+        debug("Acquiring initial list of examples")
 
         // To the list of known examples, we add an additional one produced by the solver
         val solverExample = if (p.pc == BooleanLiteral(true)) {
@@ -753,12 +758,12 @@ abstract class CEGISLike(name: String) extends Rule(name) {
                 List(InExample(p.as.map(a => model.getOrElse(a, simplestValue(a.getType)))))
 
               case Some(false) =>
-                hctx.reporter.debug("Path-condition seems UNSAT")
+                debug("Path-condition seems UNSAT")
                 return RuleFailed()
 
               case None =>
                 if (!interruptManager.isInterrupted) {
-                  hctx.reporter.warning("Solver could not solve path-condition")
+                  warning("Solver could not solve path-condition")
                 }
                 Nil
                 //return RuleFailed() // This is not necessary though, but probably wanted
@@ -770,7 +775,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
         val baseExampleInputs = p.eb.examples ++ solverExample
 
-        hctx.reporter.ifDebug { debug =>
+        ifDebug { debug =>
           baseExampleInputs.foreach { in =>
             debug("  - "+in.asString)
           }
@@ -816,7 +821,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
             ndProgram.unfold()
 
             val nInitial = ndProgram.prunedPrograms.size
-            hctx.reporter.debug("#Programs: "+nInitial)
+            debug(s"#Programs: $nInitial")
 
             def nPassing = ndProgram.prunedPrograms.size
 
@@ -843,8 +848,8 @@ abstract class CEGISLike(name: String) extends Rule(name) {
             //  }
             //}
     
-            hctx.reporter.debug("#Tests: "+baseExampleInputs.size)
-            hctx.reporter.ifDebug{ printer =>
+            debug(s"#Tests: >= ${gi.bufferedCount}")
+            ifDebug{ printer =>
               for (e <- baseExampleInputs.take(10)) {
                 printer(" - "+e.asString)
               }
@@ -867,11 +872,11 @@ abstract class CEGISLike(name: String) extends Rule(name) {
                       // Program fails the test
                       stop = true
                       failedTestsStats(e) += 1
-                      hctx.reporter.debug(f" Program: ${ndProgram.getExpr(bs).asString}%-80s failed on: ${e.asString}")
+                      debug(f" Program: ${ndProgram.getExpr(bs).asString}%-80s failed on: ${e.asString}")
                       ndProgram.excludeProgram(bs, true)
                     case None =>
                       // Eval. error -> bad example
-                      hctx.reporter.debug(s" Test $e failed, removing...")
+                      debug(s" Test $e crashed the evaluator, removing...")
                       badExamples ::= e
                   }
                 }
@@ -880,8 +885,8 @@ abstract class CEGISLike(name: String) extends Rule(name) {
               timers.filter.stop()
             }
 
-            hctx.reporter.debug(s"#Programs passing tests: $nPassing out of $nInitial")
-            hctx.reporter.ifDebug{ printer =>
+            debug(s"#Programs passing tests: $nPassing out of $nInitial")
+            ifDebug{ printer =>
               for (p <- ndProgram.prunedPrograms.take(100)) {
                 printer(" - "+ndProgram.getExpr(p).asString)
               }
@@ -891,39 +896,39 @@ abstract class CEGISLike(name: String) extends Rule(name) {
             }
               // CEGIS Loop at a given unfolding level
             while (result.isEmpty && !interruptManager.isInterrupted && !ndProgram.allProgramsClosed) {
-              hctx.reporter.debug("Programs left: " + ndProgram.prunedPrograms.size)
+              debug("Programs left: " + ndProgram.prunedPrograms.size)
 
               // Phase 0: If the number of remaining programs is small, validate them individually
               if (programsReduced()) {
                 timers.validate.start()
                 val programsToValidate = ndProgram.prunedPrograms
-                hctx.reporter.debug(s"Will send ${programsToValidate.size} program(s) to validate individually")
+                debug(s"Will send ${programsToValidate.size} program(s) to validate individually")
                 ndProgram.validatePrograms(programsToValidate) match {
                   case Right(sol) =>
                     // Found solution! Exit CEGIS
                     result = Some(RuleClosed(sol))
                   case Left(cexs) =>
-                    hctx.reporter.debug(s"Found cexs! $cexs")
+                    debug(s"Found cexs! $cexs")
                     // Found some counterexamples
                     // (bear in mind that these will in fact exclude programs within validatePrograms())
                     val newCexs = cexs.map(InExample)
                     newCexs foreach (failedTestsStats(_) += 1)
                     gi ++= newCexs
                 }
-                hctx.reporter.debug(s"#Programs after validating individually: ${ndProgram.prunedPrograms.size}")
+                debug(s"#Programs after validating individually: ${ndProgram.prunedPrograms.size}")
                 timers.validate.stop()
               }
 
               if (result.isEmpty && !ndProgram.allProgramsClosed) {
                 // Phase 1: Find a candidate program that works for at least 1 input
-                hctx.reporter.debug("Looking for program that works on at least 1 input...")
+                debug("Looking for program that works on at least 1 input...")
                 ndProgram.solveForTentativeProgram() match {
                   case Some(Some(bs)) =>
-                    hctx.reporter.debug(s"Found tentative model ${ndProgram.getExpr(bs)}, need to validate!")
+                    debug(s"Found tentative model ${ndProgram.getExpr(bs)}, need to validate!")
                     // Phase 2: Validate candidate model
                     ndProgram.solveForCounterExample(bs) match {
                       case Some(Some(inputsCE)) =>
-                        hctx.reporter.debug("Found counter-example:" + inputsCE)
+                        debug("Found counter-example:" + inputsCE)
                         val ce = InExample(inputsCE)
                         // Found counterexample! Exclude this program
                         gi += ce
@@ -935,11 +940,11 @@ abstract class CEGISLike(name: String) extends Rule(name) {
                           ndProgram.testForProgram(p)(ce) match {
                             case Some(true) =>
                             case Some(false) =>
-                              hctx.reporter.debug(f" Program: ${ndProgram.getExpr(p).asString}%-80s failed on: ${ce.asString}")
+                              debug(f" Program: ${ndProgram.getExpr(p).asString}%-80s failed on: ${ce.asString}")
                               failedTestsStats(ce) += 1
                               ndProgram.excludeProgram(p, true)
                             case None =>
-                              hctx.reporter.debug(s" Test $ce failed, removing...")
+                              debug(s" Test $ce failed, removing...")
                               gi -= ce
                           }
                         }
@@ -951,26 +956,29 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
                       case None =>
                         // We are not sure
-                        hctx.reporter.debug("Unknown")
+                        debug("Unknown")
                         if (useOptTimeout) {
                           // Interpret timeout in CE search as "the candidate is valid"
-                          hctx.reporter.info("CEGIS could not prove the validity of the resulting expression")
+                          info("CEGIS could not prove the validity of the resulting expression")
                           val expr = ndProgram.getExpr(bs)
                           result = Some(RuleClosed(Solution(BooleanLiteral(true), Set(), expr, isTrusted = false)))
                         } else {
                           // Ok, we failed to validate, exclude this program
                           ndProgram.excludeProgram(bs, false)
-                          // TODO: Make CEGIS fail early when it fails on 1 program?
+                          // TODO: Make CEGIS fail early when it times out when verifying 1 program?
                           // result = Some(RuleFailed())
                         }
                     }
 
                   case Some(None) =>
-                    hctx.reporter.debug("There exists no candidate program!")
-                    ndProgram.prunedPrograms foreach (ndProgram.excludeProgram(_, true))
+                    debug("There exists no candidate program!")
+                    ndProgram.closeAllPrograms()
 
                   case None =>
-                    result = Some(RuleFailed())
+                    debug("Timeout while getting tentative program!")
+                    ndProgram.closeAllPrograms()
+                    // TODO: Make CEGIS fail early when it times out when looking for tentative program?
+                    //result = Some(RuleFailed())
                 }
               }
             }
@@ -982,7 +990,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
         } catch {
           case e: Throwable =>
-            hctx.reporter.warning("CEGIS crashed: "+e.getMessage)
+            warning("CEGIS crashed: "+e.getMessage)
             e.printStackTrace()
             RuleFailed()
         }
diff --git a/src/main/scala/leon/utils/GrowableIterable.scala b/src/main/scala/leon/utils/GrowableIterable.scala
index 1ef76649a6d22abdbb1d6032683f4ce1fac1a0e0..3c595814993c9fc41da86bc84ee49cdcf9a546ec 100644
--- a/src/main/scala/leon/utils/GrowableIterable.scala
+++ b/src/main/scala/leon/utils/GrowableIterable.scala
@@ -19,15 +19,17 @@ class GrowableIterable[T](init: Seq[T], growth: Iterator[T]) extends Iterable[T]
     }
   }
 
-  def += (more: T)      = buffer +=  more
-  def ++=(more: Seq[T]) = buffer ++= more
-  def -= (less: T)      = buffer -=  less
-  def --=(less: Seq[T]) = buffer --= less
+  def += (more: T)           = buffer +=  more
+  def ++=(more: Iterable[T]) = buffer ++= more
+  def -= (less: T)           = buffer -=  less
+  def --=(less: Iterable[T]) = buffer --= less
 
   def iterator: Iterator[T] = {
     buffer.iterator ++ cachingIterator
   }
 
+  def bufferedCount = buffer.size
+
   def sortBufferBy[B](f: T => B)(implicit ord: math.Ordering[B]) = {
     buffer = buffer.sortBy(f)
   }