diff --git a/src/main/scala/leon/codegen/CodeGeneration.scala b/src/main/scala/leon/codegen/CodeGeneration.scala
index 36a2a18d11fcb2c5f69d5a708a8185264a4ccc85..89dca4fcbae9866abb336e27bcadd97d2ad4ee60 100644
--- a/src/main/scala/leon/codegen/CodeGeneration.scala
+++ b/src/main/scala/leon/codegen/CodeGeneration.scala
@@ -786,10 +786,7 @@ trait CodeGeneration {
         ch << InvokeSpecial(ErrorClass, constructorName, "(Ljava/lang/String;)V")
         ch << ATHROW
 
-      case Choose(_, Some(e)) =>
-        mkExpr(e, ch)
-
-      case choose @ Choose(_, None) =>
+      case choose: Choose =>
         val prob = synthesis.Problem.fromChoose(choose)
 
         val id = runtime.ChooseEntryPoint.register(prob, this)
diff --git a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
index fa5ebb6c3c6458e14897341a7a582a5994ea2813..aac2586ed1cc0286593ad6458ff713dd5a352516 100644
--- a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
+++ b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
@@ -506,10 +506,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int
     case p : Passes => 
       e(p.asConstraint)
 
-    case choose @ Choose(_, Some(impl)) =>
-      e(impl)
-
-    case choose @ Choose(_, None) =>
+    case choose: Choose =>
 
       implicit val debugSection = utils.DebugSectionSynthesis
 
diff --git a/src/main/scala/leon/purescala/ExprOps.scala b/src/main/scala/leon/purescala/ExprOps.scala
index c8e6886ba3079d40955f5fa62dd9fa8327e5c753..2b2b2b36976703d1c8f268af0e9558e64461e555 100644
--- a/src/main/scala/leon/purescala/ExprOps.scala
+++ b/src/main/scala/leon/purescala/ExprOps.scala
@@ -1292,7 +1292,7 @@ object ExprOps {
 
   def isDeterministic(e: Expr): Boolean = {
     preTraversal{
-      case Choose(_, None) => return false
+      case Choose(_) => return false
       case Hole(_, _) => return false
       //@EK FIXME: do we need it? 
       //case Error(_, _) => return false
@@ -1518,7 +1518,7 @@ object ExprOps {
         case (Variable(i1), Variable(i2)) =>
           idHomo(i1, i2)
 
-        case (Choose(e1, _), Choose(e2, _)) =>
+        case (Choose(e1), Choose(e2)) =>
           isHomo(e1, e2)
 
         case (Let(id1, v1, e1), Let(id2, v2, e2)) =>
diff --git a/src/main/scala/leon/purescala/Expressions.scala b/src/main/scala/leon/purescala/Expressions.scala
index 03385aec2645a0945ebd549e7f22a50bca8beb4b..580388348445316d04f32381661edd818b2ea7ed 100644
--- a/src/main/scala/leon/purescala/Expressions.scala
+++ b/src/main/scala/leon/purescala/Expressions.scala
@@ -51,25 +51,13 @@ object Expressions {
     val getType = body.getType
   }
 
-  case class Choose(pred: Expr, private var impl_ : Option[Expr] = None) extends Expr {
+  case class Choose(pred: Expr) extends Expr {
     val getType = pred.getType match {
       case FunctionType(from, to) if from.nonEmpty => // @mk why nonEmpty? 
         tupleTypeWrap(from)
       case _ =>
         Untyped
     }
-
-    require(impl_ forall { imp => isSubtypeOf(imp.getType, this.getType)})
-
-    def impl_= (newImpl: Option[Expr]) = { 
-      require(
-        newImpl forall {imp => isSubtypeOf(imp.getType,this.getType)}, 
-        newImpl.get +":" + newImpl.get.getType + " vs " + this + ":" + this.getType
-      )
-      impl_ = newImpl
-    }
-
-    def impl = impl_
   }
 
   /* Like vals */
diff --git a/src/main/scala/leon/purescala/Extractors.scala b/src/main/scala/leon/purescala/Extractors.scala
index 8b5b3cf240957a1d7cf0aab08a0fa1aad27157b9..d6e5ba0d9a7bc66551d302cfbf4cc98c0706b283 100644
--- a/src/main/scala/leon/purescala/Extractors.scala
+++ b/src/main/scala/leon/purescala/Extractors.scala
@@ -15,6 +15,7 @@ object Extractors {
   object UnaryOperator {
     def unapply(expr: Expr) : Option[(Expr,(Expr)=>Expr)] = expr match {
       case Not(t) => Some((t,not))
+      case Choose(expr) => Some((expr,Choose))
       case UMinus(t) => Some((t,UMinus))
       case BVUMinus(t) => Some((t,BVUMinus))
       case BVNot(t) => Some((t,BVNot))
@@ -99,10 +100,6 @@ object Extractors {
 
   object NAryOperator {
     def unapply(expr: Expr) : Option[(Seq[Expr],(Seq[Expr])=>Expr)] = expr match {
-      case Choose(pred, impl) => Some((Seq(pred) ++ impl.toSeq, {
-        case Seq(pred) => Choose(pred, None)
-        case Seq(pred, impl) => Choose(pred, Some(impl))
-      }))
       case fi @ FunctionInvocation(fd, args) => Some((args, FunctionInvocation(fd, _)))
       case mi @ MethodInvocation(rec, cd, tfd, args) => Some((rec +: args, as => MethodInvocation(as.head, cd, tfd, as.tail)))
       case fa @ Application(caller, args) => Some(caller +: args, as => application(as.head, as.tail))
diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala
index e273e9e62f9e6b953602b0c0e9b29854d83bbdc6..57269f7cedaa5cb84697e78dd6bc54ed110b6d63 100644
--- a/src/main/scala/leon/purescala/PrettyPrinter.scala
+++ b/src/main/scala/leon/purescala/PrettyPrinter.scala
@@ -184,13 +184,7 @@ class PrettyPrinter(opts: PrinterOptions,
       case Tuple(exprs)         => p"($exprs)"
       case TupleSelect(t, i)    => p"$t._$i"
       case NoTree(tpe)          => p"???($tpe)"
-      case Choose(pred, oimpl) => 
-        oimpl match {
-          case Some(e) =>
-            p"$e /* choose: $pred */"
-          case None =>
-            p"choose($pred)"
-        }
+      case Choose(pred)         => p"choose($pred)"
       case e @ Error(tpe, err)       => p"""error[$tpe]("$err")"""
       case CaseClassInstanceOf(cct, e)         =>
         if (cct.classDef.isCaseObject) {
diff --git a/src/main/scala/leon/purescala/ScalaPrinter.scala b/src/main/scala/leon/purescala/ScalaPrinter.scala
index 4eb039e6e3e1d8670992b5cc7c2fb53af7cfb5a7..0bf34096ce0fc61a98063a9f2e449dd0787a65ff 100644
--- a/src/main/scala/leon/purescala/ScalaPrinter.scala
+++ b/src/main/scala/leon/purescala/ScalaPrinter.scala
@@ -27,7 +27,7 @@ class ScalaPrinter(opts: PrinterOptions,
         }))
       case Not(Equals(l, r))    => p"$l != $r"
       case Implies(l,r)         => pp(or(not(l), r))
-      case Choose(pred, None) => p"choose($pred)"
+      case Choose(pred)         => p"choose($pred)"
       case s @ FiniteSet(rss, t) => p"Set[$t](${rss.toSeq})"
       case m @ FiniteMap(els, k, v) => p"Map[$k,$v]($els)"
       
diff --git a/src/main/scala/leon/purescala/TypeOps.scala b/src/main/scala/leon/purescala/TypeOps.scala
index 635f8a03128d3d896b942c7c1bdab7ff2d506065..1ab068c7bfc91aa82dcf26d772287ee537010d9e 100644
--- a/src/main/scala/leon/purescala/TypeOps.scala
+++ b/src/main/scala/leon/purescala/TypeOps.scala
@@ -279,8 +279,8 @@ object TypeOps {
             val newId = freshId(id, tpeSub(id.getType))
             Let(newId, srec(value), rec(idsMap + (id -> newId))(body)).copiedFrom(l)
 
-          case c @ Choose(pred, oimpl) =>
-            Choose(rec(idsMap)(pred), oimpl.map(srec)).copiedFrom(c)
+          case c @ Choose(pred) =>
+            Choose(rec(idsMap)(pred)).copiedFrom(c)
 
           case l @ Lambda(args, body) =>
             val newArgs = args.map { arg =>
diff --git a/src/main/scala/leon/repair/Repairman.scala b/src/main/scala/leon/repair/Repairman.scala
index 0449334d3702fd4164274b7b494642c647db994f..b8214d456ea8e6259e5df7fc4c24e3fc2d7fbed2 100644
--- a/src/main/scala/leon/repair/Repairman.scala
+++ b/src/main/scala/leon/repair/Repairman.scala
@@ -96,32 +96,21 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
   }
 
   def getSynthesizer(tb: TestBank): Synthesizer = {
-    val (np, fdMap) = replaceFunDefs(program)({ fd =>
-      if (fd == this.fd) {
-        Some(fd.duplicate)
-      } else {
-        None
-      }
-    })
-
-    val nfd = fdMap(fd)
 
-    val origBody = nfd.body.get
+    val origBody = fd.body.get
 
-    val spec = nfd.postcondition.getOrElse(
-      Lambda(Seq(ValDef(FreshIdentifier("res", nfd.returnType))), BooleanLiteral(true))
+    val spec = fd.postcondition.getOrElse(
+      Lambda(Seq(ValDef(FreshIdentifier("res", fd.returnType))), BooleanLiteral(true))
     )
 
     val choose = Choose(spec)
-    choose.impl = Some(origBody)
-    nfd.body = Some(choose)
 
-    val term  = Terminating(nfd.typed, nfd.params.map(_.id.toVariable))
+    val term  = Terminating(fd.typed, fd.params.map(_.id.toVariable))
     val guide = Guide(origBody)
-    val pre   = nfd.precondition.getOrElse(BooleanLiteral(true))
+    val pre   = fd.precondition.getOrElse(BooleanLiteral(true))
 
     val ci = ChooseInfo(
-      nfd,
+      fd,
       andJoin(Seq(pre, guide, term)),
       origBody,
       choose,
@@ -143,7 +132,7 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
       )) diff Seq(ADTInduction, TEGIS, IntegerInequalities, IntegerEquation)
     )
 
-    new Synthesizer(ctx, np, ci, soptions)
+    new Synthesizer(ctx, program, ci, soptions)
   }
 
   def getVerificationCExs(fd: FunDef): Seq[Example] = {
diff --git a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
index fd3af5c50278afd441804b0962a36613f4c89d41..fc0826dbbc8bc78552e94a672d463c7ae7de6deb 100644
--- a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
+++ b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
@@ -244,10 +244,7 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T],
           }
         }
 
-        case c @ Choose(cond, Some(impl)) =>
-          rec(pathVar, impl)
-
-        case c @ Choose(cond, None) =>
+        case c @ Choose(cond) =>
           val cid = FreshIdentifier("choose", c.getType, true)
           storeExpr(cid)
           storeGuarded(pathVar, application(cond, Seq(Variable(cid))))
diff --git a/src/main/scala/leon/synthesis/rules/CEGISLike.scala b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
index ca53ba5ae5f045bb1a451ae94508f16ecd6e42a3..884c18254fe97cf3cd61d450d70e5ca3d6165252 100644
--- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
@@ -355,7 +355,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) {
             val nfd = fd.duplicate
 
             nfd.fullBody = postMap {
-              case ch if ch eq hctx.ci.ch =>
+              case src if src eq hctx.ci.source =>
                 Some(outerSolution.term)
 
               case _ => None
@@ -363,6 +363,8 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) {
 
             Some(nfd)
 
+          // We freshen/duplicate every functions, except these two as they are
+          // fresh anyway and we refer to them directly.
           case `cTreeFd` | `phiFd` =>
             None
 
@@ -373,10 +375,10 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) {
       }
 
       /**
-       * Since CEGIS works with a copy of the outer program,
-       * it needs to map outer function calls to inner function calls
-       * and vice-versa. 'inner' refers to the CEGIS-specific program,
-       * 'outer' refers to the actual program on which we do synthesis.
+       * Since CEGIS works with a copy of the program, it needs to map outer
+       * function calls to inner function calls and vice-versa. 'inner' refers
+       * to the CEGIS-specific program, 'outer' refers to the actual program on
+       * which we do synthesis.
        */
       private def outerExprToInnerExpr(e: Expr): Expr = {
         replaceFunCalls(e, {fd => origFdMap.getOrElse(fd, fd) })
diff --git a/src/main/scala/leon/xlang/ImperativeCodeElimination.scala b/src/main/scala/leon/xlang/ImperativeCodeElimination.scala
index ec24b4c93f642e02390c5add25fde7a13910684f..e6ef2c65d717f4956844dba3f681e5a1cea92b1b 100644
--- a/src/main/scala/leon/xlang/ImperativeCodeElimination.scala
+++ b/src/main/scala/leon/xlang/ImperativeCodeElimination.scala
@@ -233,7 +233,7 @@ object ImperativeCodeElimination extends TransformationPhase {
         val (bodyRes, bodyScope, bodyFun) = toFunction(b)
         (bodyRes, (b2: Expr) => LetDef(newFd, bodyScope(b2)).copiedFrom(expr), bodyFun)
       }
-      case c @ Choose(b, _) => {
+      case c @ Choose(b) => {
         //Recall that Choose cannot mutate variables from the scope
         (c, (b2: Expr) => b2, Map())
       }