diff --git a/src/main/scala/leon/invariant/factories/AxiomFactory.scala b/src/main/scala/leon/invariant/factories/AxiomFactory.scala
index 907db46ab1cf1fbd4efcc19f58ae5867142575f6..ebc33562c87f6db9c7b9db7514524956eb2eb3a3 100644
--- a/src/main/scala/leon/invariant/factories/AxiomFactory.scala
+++ b/src/main/scala/leon/invariant/factories/AxiomFactory.scala
@@ -25,19 +25,19 @@ class AxiomFactory(ctx : InferenceContext) {
     (callee.isMonotonic || callee.isDistributive)
   }
 
-  def unaryAxiom(call: Call) : (Expr,Expr) = {
+  def unaryAxiom(call: Call): (Expr, Expr) = {
     val callee = call.fi.tfd.fd
     val tfd = call.fi.tfd
 
-    if(callee.isCommutative) {
+    if (callee.isCommutative) {
       //note: commutativity is defined only for binary operations
       val Seq(a1, a2) = call.fi.args
-      val newret = TVarFactory.createTemp("cm").toVariable
-      val newfi = FunctionInvocation(tfd,Seq(a2,a1))
-      val newcall = Call(newret,newfi)
+      val newret = TVarFactory.createTempDefault("cm").toVariable
+      val newfi = FunctionInvocation(tfd, Seq(a2, a1))
+      val newcall = Call(newret, newfi)
       (tru, And(newcall.toExpr, Equals(newret, call.retexpr)))
     } else
-      throw new IllegalStateException("Call does not have unary axiom: "+call)
+      throw new IllegalStateException("Call does not have unary axiom: " + call)
   }
 
   def binaryAxiom(call1: Call, call2: Call): Seq[(Expr,Expr)] = {
@@ -81,7 +81,7 @@ class AxiomFactory(ctx : InferenceContext) {
     val r1 = call1.retexpr
     val r2 = call2.retexpr
 
-    val dret2 = TVarFactory.createTemp("dt", IntegerType).toVariable
+    val dret2 = TVarFactory.createTempDefault("dt", IntegerType).toVariable
     val dcall2 = Call(dret2, FunctionInvocation(tfd,Seq(Plus(a1,a2),b2)))
     (LessEquals(b1,b2), And(LessEquals(Plus(r1,r2),dret2), dcall2.toExpr))
   }
diff --git a/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala b/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala
index dbcdc4c5e1a2de62fb5a1c1e81ebe17b4449a584..fcf786d2845ea699fa541c131a81eaabbaf5649f 100644
--- a/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala
+++ b/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala
@@ -20,18 +20,13 @@ object TemplateInstantiator {
   def getAllInvariants(model: Model, templates: Map[FunDef, Expr], prettyInv: Boolean = false): Map[FunDef, Expr] = {
     val invs = templates.map((pair) => {
       val (fd, t) = pair
-      //flatten the template
-      val freevars = variablesOf(t)
       val template = ExpressionTransformer.FlattenFunction(t)
-
       val tempvars = getTemplateVars(template)
       val tempVarMap: Map[Expr, Expr] = tempvars.map((v) => {
         (v, model(v.id))
       }).toMap
-
       val instTemplate = instantiate(template, tempVarMap, prettyInv)
-      //now unflatten it
-      val comprTemp = ExpressionTransformer.unFlatten(instTemplate, freevars)
+      val comprTemp = ExpressionTransformer.unFlatten(instTemplate)
       (fd, comprTemp)
     })
     invs
diff --git a/src/main/scala/leon/invariant/structure/Formula.scala b/src/main/scala/leon/invariant/structure/Formula.scala
index c17711e102877861010359256ff902ad7d51d70b..83440a9fc9fd6ac54d54ceab6070e4110643ad02 100644
--- a/src/main/scala/leon/invariant/structure/Formula.scala
+++ b/src/main/scala/leon/invariant/structure/Formula.scala
@@ -18,12 +18,18 @@ import invariant.util._
 import leon.solvers.Model
 import Util._
 import PredicateUtil._
+import TVarFactory._
 
 /**
  * Data associated with a call
  */
 class CallData(val guard : Variable, val parents: List[FunDef])
 
+object Formula {
+  // a context for creating blockers
+  val blockContext = newContext
+}
+
 /**
  * Representation of an expression as a set of implications.
  * 'initexpr' is required to be in negation normal form and And/Ors have been pulled up
@@ -31,6 +37,8 @@ class CallData(val guard : Variable, val parents: List[FunDef])
  */
 class Formula(val fd: FunDef, initexpr: Expr, ctx: InferenceContext) {
 
+  import Formula._
+
   val fls = BooleanLiteral(false)
   val tru = BooleanLiteral(true)
   val useImplies = false
@@ -90,7 +98,7 @@ class Formula(val fd: FunDef, initexpr: Expr, ctx: InferenceContext) {
               case And(atms) => atms
               case _ => Seq(arg)
             }
-            val g = TVarFactory.createTemp("b", BooleanType).toVariable
+            val g = createTemp("b", BooleanType, blockContext).toVariable
             newDisjGuards :+= g
             //println("atoms: "+atoms)
             val ctrs = getCtrsFromExprs(g, atoms)
@@ -99,7 +107,7 @@ class Formula(val fd: FunDef, initexpr: Expr, ctx: InferenceContext) {
           }
         }
         //create a temporary for Or
-        val gor = TVarFactory.createTemp("b", BooleanType).toVariable
+        val gor = createTemp("b", BooleanType, blockContext).toVariable
         val newor = createOr(newargs)
         conjuncts += (gor -> newor)
         gor
@@ -109,7 +117,7 @@ class Formula(val fd: FunDef, initexpr: Expr, ctx: InferenceContext) {
           arg
         } else {
           //if the expression has template variables then we separate it using guards
-          val g = TVarFactory.createTemp("b", BooleanType).toVariable
+          val g = createTemp("b", BooleanType, blockContext).toVariable
           newDisjGuards :+= g
           val ctrs = getCtrsFromExprs(g, Seq(arg))
           disjuncts += (g -> ctrs)
@@ -133,7 +141,7 @@ class Formula(val fd: FunDef, initexpr: Expr, ctx: InferenceContext) {
           case And(atms) => atms
           case _ => Seq(f1)
         }
-        val g = TVarFactory.createTemp("b", BooleanType).toVariable
+        val g = createTemp("b", BooleanType, blockContext).toVariable
         val ctrs = getCtrsFromExprs(g, atoms)
         newDisjGuards :+= g
         disjuncts += (g -> ctrs)
diff --git a/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala b/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala
index d4d72a507b3f204170cee0e99b9522dc7e1ffc66..31f9e8b470adfd0ad6df2e86f658ebc843d32f9c 100644
--- a/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala
@@ -42,10 +42,10 @@ class NLTemplateSolver(ctx: InferenceContext, program: Program,
   val debugAxioms = false
   val verifyInvariant = false
   val debugReducedFormula = false
-  val trackUnpackedVCCTime = false
+  val trackUnpackedVCCTime = true
 
   //print flags
-  val verbose = false
+  val verbose = true
   val printCounterExample = false
   val printPathToConsole = false
   val dumpPathAsSMTLIB = false
@@ -60,7 +60,6 @@ class NLTemplateSolver(ctx: InferenceContext, program: Program,
   private val startFromEarlierModel = true
   private val disableCegis = true
   private val useIncrementalSolvingForVCs = true
-  private val useCVCToCheckVCs = false
   private val usePortfolio = false // portfolio has a bug in incremental solving
 
   //this is private mutable state used by initialized during every call to 'solve' and used by 'solveUNSAT'
@@ -78,15 +77,14 @@ class NLTemplateSolver(ctx: InferenceContext, program: Program,
     ctrTracker.getVC(fd).splitParamPart
   }
 
-  def getSolver =
-    if(this.usePortfolio) {
-      new PortfolioSolver(leonctx, Seq(new SMTLIBCVC4Solver(leonctx, program),
-          new SMTLIBZ3Solver(leonctx, program))) with TimeoutSolver
-    }
-    else if (this.useCVCToCheckVCs)
-      new SMTLIBCVC4Solver(leonctx, program) with TimeoutSolver
-    else
-      new SMTLIBZ3Solver(leonctx, program) with TimeoutSolver
+  val solverFactory =
+    if (this.usePortfolio) {
+      if (this.useIncrementalSolvingForVCs)
+        throw new IllegalArgumentException("Cannot perform incremental solving with portfolio solvers!")
+      SolverFactory(() => new PortfolioSolver(leonctx, Seq(new SMTLIBCVC4Solver(leonctx, program),
+        new SMTLIBZ3Solver(leonctx, program))) with TimeoutSolver)
+    } else
+      SolverFactory.uninterpreted(leonctx, program)
 
   def initVCSolvers = {
     funcVCs.keys.foreach { fd =>
@@ -100,7 +98,7 @@ class NLTemplateSolver(ctx: InferenceContext, program: Program,
         throw new IllegalStateException("Non-param Part has both integers and reals: " + rest)
 
       if (!ctx.abort) { // this is required to ensure that solvers are not created after interrupts
-        val vcSolver = getSolver
+        val vcSolver = solverFactory.getNewSolver()
         vcSolver.assertCnstr(rest)
 
         if (debugIncrementalVC) {
@@ -393,7 +391,7 @@ class NLTemplateSolver(ctx: InferenceContext, program: Program,
     val tempVarMap: Map[Expr, Expr] = inModel.map((elem) => (elem._1.toVariable, elem._2)).toMap
     val solver =
       if (this.useIncrementalSolvingForVCs) vcSolvers(fd)
-      else getSolver
+      else solverFactory.getNewSolver()
     val instExpr = if (this.useIncrementalSolvingForVCs) {
       val instParamPart = instantiateTemplate(this.paramParts(fd), tempVarMap)
       And(instParamPart, disableCounterExs)
@@ -451,7 +449,7 @@ class NLTemplateSolver(ctx: InferenceContext, program: Program,
       Stats.updateCounterStats(atomNum(upVCinst), "UP-VC-size", "disjuncts")
 
       t1 = System.currentTimeMillis()
-      val (res2, _) = SimpleSolverAPI(SolverFactory(() => getSolver)).solveSAT(upVCinst)
+      val (res2, _) = SimpleSolverAPI(SolverFactory(() => solverFactory.getNewSolver())).solveSAT(upVCinst)
       val unpackedTime = System.currentTimeMillis() - t1
       if (res != res2) {
         throw new IllegalStateException("Unpacked VC produces different result: " + upVCinst)
diff --git a/src/main/scala/leon/invariant/util/ExpressionTransformer.scala b/src/main/scala/leon/invariant/util/ExpressionTransformer.scala
index 6886b98bd77fabf7c13ce7cdcd88c1361245b49e..83ed0a86b86675b41a55b60b30783f79645bcfb5 100644
--- a/src/main/scala/leon/invariant/util/ExpressionTransformer.scala
+++ b/src/main/scala/leon/invariant/util/ExpressionTransformer.scala
@@ -12,6 +12,7 @@ import purescala.ScalaPrinter
 import leon.invariant.factories.TemplateIdFactory
 import PredicateUtil._
 import Util._
+import TVarFactory._
 
 /**
  * A collection of transformation on expressions and some utility methods.
@@ -26,6 +27,15 @@ object ExpressionTransformer {
   val fls = BooleanLiteral(false)
   val bone = BigInt(1)
 
+  // identifier for temporaries that are generated during flattening
+  val flatContext = newContext
+  // temporaries generated during conversion of field selects to ADT constructions
+  val fieldSelContext = newContext
+  // conversion of other language constructs
+  val langContext = newContext
+
+  def createFlatTemp(name: String, tpe: TypeTree = Untyped) = createTemp(name, tpe, flatContext)
+
   /**
    * This function conjoins the conjuncts created by 'transfomer' within the clauses containing Expr.
    * This is meant to be used by operations that may flatten subexpression using existential quantifiers.
@@ -77,7 +87,7 @@ object ExpressionTransformer {
       e match {
         // Handle asserts here. Return flattened body as the result
         case as @ Assert(pred, _, body) => {
-          val freshvar = TVarFactory.createTemp("asrtres", e.getType).toVariable
+          val freshvar = createFlatTemp("asrtres", e.getType).toVariable
           val newexpr = Equals(freshvar, body)
           val resset = transform(newexpr, insideFunction)
           (freshvar, resset._2 + resset._1)
@@ -85,7 +95,7 @@ object ExpressionTransformer {
         //handles division by constant
         case Division(lhs, rhs @ InfiniteIntegerLiteral(v)) => {
           //this models floor and not integer division
-          val quo = TVarFactory.createTemp("q", IntegerType).toVariable
+          val quo = createTemp("q", IntegerType, langContext).toVariable
           var possibs = Seq[Expr]()
           for (i <- v - 1 to 0 by -1) {
             if (i == 0) possibs :+= Equals(lhs, Times(rhs, quo))
@@ -100,8 +110,8 @@ object ExpressionTransformer {
         //handles division by variables
         case Division(lhs, rhs) => {
           //this models floor and not integer division
-          val quo = TVarFactory.createTemp("q", IntegerType).toVariable
-          val rem = TVarFactory.createTemp("r", IntegerType).toVariable
+          val quo = createTemp("q", IntegerType, langContext).toVariable
+          val rem = createTemp("r", IntegerType, langContext).toVariable
           val mult = multop(quo, rhs)
           val divsem = Equals(lhs, Plus(mult, rem))
           //TODO: here, we have to use |rhs|
@@ -111,7 +121,7 @@ object ExpressionTransformer {
         }
         case err @ Error(_, msg) => {
           //replace this by a fresh variable of the error type
-          (TVarFactory.createTemp("err", err.getType).toVariable, Set[Expr]())
+          (createTemp("err", err.getType, langContext).toVariable, Set[Expr]())
         }
         case Equals(lhs, rhs) => {
           val (nexp1, ncjs1) = transform(lhs, true)
@@ -119,7 +129,7 @@ object ExpressionTransformer {
           (Equals(nexp1, nexp2), ncjs1 ++ ncjs2)
         }
         case IfExpr(cond, thn, elze) => {
-          val freshvar = TVarFactory.createTemp("ifres", e.getType).toVariable
+          val freshvar = createTemp("ifres", e.getType, langContext).toVariable
           val newexpr = Or(And(cond, Equals(freshvar, thn)), And(Not(cond), Equals(freshvar, elze)))
           val resset = transform(newexpr, insideFunction)
           (freshvar, resset._2 + resset._1)
@@ -150,7 +160,7 @@ object ExpressionTransformer {
               val (resvalue2, cjs) = resvalue match {
                 case t: Terminal => (t, Seq())
                 case _ => {
-                  val freshres = TVarFactory.createTemp("tres", resvalue.getType).toVariable
+                  val freshres = createTemp("tres", resvalue.getType, langContext).toVariable
                   (freshres, Seq(Equals(freshres, resvalue)))
                 }
               }
@@ -195,86 +205,69 @@ object ExpressionTransformer {
      */
     def flattenFunc(e: Expr, insideFunction: Boolean): (Expr, Set[Expr]) = {
       e match {
-        case fi @ FunctionInvocation(fd, args) => {
-          //now also flatten the args. The following is slightly tricky
+        case fi @ FunctionInvocation(fd, args) =>
           val (newargs, newConjuncts) = flattenArgs(args, true)
-          //create a new equality in UIFs
           val newfi = FunctionInvocation(fd, newargs)
-          //create a new variable to represent the function
-          val freshResVar = Variable(TVarFactory.createTemp("r", fi.getType))
+          val freshResVar = Variable(createFlatTemp("r", fi.getType))
           val res = (freshResVar, newConjuncts + Equals(freshResVar, newfi))
           res
-        }
-        case inst @ IsInstanceOf(e1, cd) => {
+
+        case inst @ IsInstanceOf(e1, cd) =>
           //replace e by a variable
           val (newargs, newcjs) = flattenArgs(Seq(e1), true)
           var newConjuncts = newcjs
-
           val freshArg = newargs(0)
           val newInst = IsInstanceOf(freshArg, cd)
-          val freshResVar = Variable(TVarFactory.createTemp("ci", inst.getType))
+          val freshResVar = Variable(createFlatTemp("ci", inst.getType))
           newConjuncts += Equals(freshResVar, newInst)
           (freshResVar, newConjuncts)
-        }
-        case cs @ CaseClassSelector(cd, e1, sel) => {
+
+        case cs @ CaseClassSelector(cd, e1, sel) =>
           val (newargs, newcjs) = flattenArgs(Seq(e1), true)
           var newConjuncts = newcjs
-
           val freshArg = newargs(0)
           val newCS = CaseClassSelector(cd, freshArg, sel)
-          val freshResVar = Variable(TVarFactory.createTemp("cs", cs.getType))
+          val freshResVar = Variable(createFlatTemp("cs", cs.getType))
           newConjuncts += Equals(freshResVar, newCS)
-
           (freshResVar, newConjuncts)
-        }
-        case ts @ TupleSelect(e1, index) => {
+
+        case ts @ TupleSelect(e1, index) =>
           val (newargs, newcjs) = flattenArgs(Seq(e1), true)
           var newConjuncts = newcjs
-
           val freshArg = newargs(0)
           val newTS = TupleSelect(freshArg, index)
-          val freshResVar = Variable(TVarFactory.createTemp("ts", ts.getType))
+          val freshResVar = Variable(createFlatTemp("ts", ts.getType))
           newConjuncts += Equals(freshResVar, newTS)
-
           (freshResVar, newConjuncts)
-        }
-        case cc @ CaseClass(cd, args) => {
 
+        case cc @ CaseClass(cd, args) =>
           val (newargs, newcjs) = flattenArgs(args, true)
           var newConjuncts = newcjs
-
           val newCC = CaseClass(cd, newargs)
-          val freshResVar = Variable(TVarFactory.createTemp("cc", cc.getType))
+          val freshResVar = Variable(createFlatTemp("cc", cc.getType))
           newConjuncts += Equals(freshResVar, newCC)
-
           (freshResVar, newConjuncts)
-        }
+
         case tp @ Tuple(args) => {
           val (newargs, newcjs) = flattenArgs(args, true)
           var newConjuncts = newcjs
-
           val newTP = Tuple(newargs)
-          val freshResVar = Variable(TVarFactory.createTemp("tp", tp.getType))
-          // if(freshResVar.id.toString == "tp6"){
-          //   println("Creating temporary tp6 type: "+tp.getType+" expr: "+tp)
-          //   throw new IllegalStateException("")
-          // }
+          val freshResVar = Variable(createFlatTemp("tp", tp.getType))
           newConjuncts += Equals(freshResVar, newTP)
-
           (freshResVar, newConjuncts)
         }
         case SetUnion(_, _) | ElementOfSet(_, _) | SubsetOf(_, _) =>
           val Operator(args, op) = e
           val (Seq(a1, a2), newcjs) = flattenArgs(args, true)
           val newexpr = op(Seq(a1, a2))
-          val freshResVar = Variable(TVarFactory.createTemp("set", e.getType))
+          val freshResVar = Variable(createFlatTemp("set", e.getType))
           (freshResVar, newcjs + Equals(freshResVar, newexpr))
 
         case fs @ FiniteSet(es, typ) =>
           val args = es.toSeq
           val (nargs, newcjs) = flattenArgs(args, true)
           val newexpr = FiniteSet(nargs.toSet, typ)
-          val freshResVar = Variable(TVarFactory.createTemp("fset", fs.getType))
+          val freshResVar = Variable(createFlatTemp("fset", fs.getType))
           (freshResVar, newcjs + Equals(freshResVar, newexpr))
 
         case _ => conjoinWithinClause(e, flattenFunc, insideFunction)
@@ -286,25 +279,20 @@ object ExpressionTransformer {
       val newargs = args.map {
         case v: Variable => v
         case r: ResultVariable => r
-        case arg => {
+        case arg =>
           val (nexpr, ncjs) = flattenFunc(arg, insideFunction)
-
           newConjuncts ++= ncjs
-
           nexpr match {
             case v: Variable => v
             case r: ResultVariable => r
-            case _ => {
-              val freshArgVar = Variable(TVarFactory.createTemp("arg", arg.getType))
+            case _ =>
+              val freshArgVar = Variable(createFlatTemp("arg", arg.getType))
               newConjuncts += Equals(freshArgVar, nexpr)
               freshArgVar
-            }
           }
-        }
       }
       (newargs, newConjuncts)
     }
-
     val (nexp, ncjs) = flattenFunc(inExpr, false)
     if (ncjs.nonEmpty) {
       createAnd(nexp +: ncjs.toSeq)
@@ -339,10 +327,6 @@ object ExpressionTransformer {
    */
   def TransformNot(expr: Expr, retainNEQ: Boolean = false): Expr = { // retainIff : Boolean = false
     def nnf(inExpr: Expr): Expr = {
-//      if(inExpr.getType == Untyped){
-//        testHelp(inExpr)
-//        println(s"Warning: $inExpr is untyped")
-//      }
       if (inExpr.getType != BooleanType) inExpr
       else {
         inExpr match {
@@ -440,7 +424,7 @@ object ExpressionTransformer {
       if (fld.id == ccfld) r
       else {
         //create a dummy identifier there
-        TVarFactory.createDummy(fld.getType).toVariable
+        createTemp("fld", fld.getType, fieldSelContext).toVariable
       }
     })
     Equals(ccvar, CaseClass(cd, args))
@@ -458,7 +442,7 @@ object ExpressionTransformer {
       if (i == index) r
       else {
         //create a dummy identifier there (note that here we have to use i-1)
-        TVarFactory.createDummy(tupleType.bases(i - 1)).toVariable
+        createTemp("fld", tupleType.bases(i - 1), fieldSelContext).toVariable
       }
     })
     Equals(tpvar, Tuple(args))
@@ -483,24 +467,23 @@ object ExpressionTransformer {
   }
 
   /**
-   * This is the inverse operation of flattening, this is mostly
-   * used to produce a readable formula.
-   * Freevars is a set of identifiers that are program variables
-   * This assumes that temporary identifiers (which are not freevars) are not reused across clauses.
+   * This is the inverse operation of flattening.
+   * This is used to produce a readable formula or more efficiently
+   * solvable formulas.
    */
-  def unFlatten(ine: Expr, freevars: Set[Identifier]): Expr = {
-    var tempMap = Map[Expr, Expr]()
-    val newinst = simplePostTransform {
-      case e @ Equals(v @ Variable(id), rhs @ _) if !freevars.contains(id) =>
-        if (tempMap.contains(v)) e
+  def unFlatten(ine: Expr): Expr = {
+    var idMap = Map[Identifier, Expr]()
+    val newe = simplePostTransform {
+      case e @ Equals(Variable(id), rhs @ _) if isTemp(id, flatContext) =>
+        if (idMap.contains(id)) e
         else {
-          tempMap += (v -> rhs)
+          idMap += (id -> rhs)
           tru
         }
       case e => e
     }(ine)
-    val closure = (e: Expr) => replace(tempMap, e)
-    fix(closure)(newinst)
+    val closure = (e: Expr) => replaceFromIDs(idMap, e)
+    fix(closure)(newe)
   }
 
   /**
@@ -532,7 +515,6 @@ object ExpressionTransformer {
    * TODO: fix this
    */
   def isSubExpr(key: Expr, expr: Expr): Boolean = {
-
     var found = false
     simplePostTransform {
       case e if (e == key) =>
@@ -546,7 +528,6 @@ object ExpressionTransformer {
    * Some simplification rules (keep adding more and more rules)
    */
   def simplify(expr: Expr): Expr = {
-
     //Note: some simplification are already performed by the class constructors (see Tree.scala)
     simplePostTransform {
       case Equals(lhs, rhs) if (lhs == rhs) => tru
@@ -600,8 +581,6 @@ object ExpressionTransformer {
         else args.forall(arg => uniOP(arg, 2))
       }
       case t: Terminal => true
-      /*case u @ UnaryOperator(e1, op) => uniOP(e1, seen)
-      case b @ BinaryOperator(e1, e2, op) => uniOP(e1, seen) && uniOP(e2, seen)*/
       case n @ Operator(args, op) => args.forall(arg => uniOP(arg, seen))
     }
 
diff --git a/src/main/scala/leon/invariant/util/LetTupleSimplification.scala b/src/main/scala/leon/invariant/util/LetTupleSimplification.scala
index 7052328e10adc9faa832c2907bca6832924b3993..641f6045e004df79be1a30fccf24b385c490a384 100644
--- a/src/main/scala/leon/invariant/util/LetTupleSimplification.scala
+++ b/src/main/scala/leon/invariant/util/LetTupleSimplification.scala
@@ -12,10 +12,10 @@ import java.io._
 import purescala.ScalaPrinter
 import leon.utils._
 import PredicateUtil._
-
 import invariant.structure.Call
 import invariant.structure.FunctionUtils._
 import leon.transformations.InstUtil._
+import TVarFactory._
 
 /**
  * A collection of transformation on expressions and some utility methods.
@@ -29,6 +29,8 @@ object LetTupleSimplification {
   val tru = BooleanLiteral(true)
   val fls = BooleanLiteral(false)
   val bone = BigInt(1)
+  // fresh ids created during simplification
+  val simpContext = newContext
 
   def letSanityChecks(ine: Expr) = {
     simplePostTransform(_ match {
@@ -62,7 +64,7 @@ object LetTupleSimplification {
             case TupleType(argTypes) =>
               var freshBinders = Set[Identifier]()
               def freshBinder(typ: TypeTree) = {
-                val freshid = TVarFactory.createTemp(binderId.name, typ)
+                val freshid = createTemp(binderId.name, typ, simpContext)
                 freshBinders += freshid
                 freshid.toVariable
               }
@@ -235,7 +237,7 @@ object LetTupleSimplification {
               //here we can use 'b' in 'body'
               Let(id, v, body(b))
             case _ =>
-              val mt = TVarFactory.createTemp("mt", value.getType)
+              val mt = createTemp("mt", value.getType, simpContext)
               Let(mt, value, body(mt.toVariable))
           }
         }
diff --git a/src/main/scala/leon/invariant/util/SolverUtil.scala b/src/main/scala/leon/invariant/util/SolverUtil.scala
index 466ec1d2def3831b42c1f0b4bc6eaad3351ef716..6b4641e039887bd734fee18e0a33e37f83221b23 100644
--- a/src/main/scala/leon/invariant/util/SolverUtil.scala
+++ b/src/main/scala/leon/invariant/util/SolverUtil.scala
@@ -70,7 +70,7 @@ object SolverUtil {
     val solver = new ExtendedUFSolver(ctx, prog)
     val newe = simplePostTransform {
       case e@(And(_) | Or(_)) => {
-        val v = TVarFactory.createTemp("a", BooleanType).toVariable
+        val v = TVarFactory.createTempDefault("a", BooleanType).toVariable
         newEqs += (v -> e)
         val newe = Equals(v, e)
 
@@ -106,8 +106,7 @@ object SolverUtil {
 
     solver.free
     //cores
-    ExpressionTransformer.unFlatten(cores,
-      variablesOf(ine).filterNot(TVarFactory.isTemporary _))
+    ExpressionTransformer.unFlatten(cores)
   }
 
   //tests if the solver uses nlsat
diff --git a/src/main/scala/leon/invariant/util/TVarFactory.scala b/src/main/scala/leon/invariant/util/TVarFactory.scala
index 6743e802b27ef44b1b966555d6965130373b5f8b..7fdebb008ec6529914c4f40aeb6451ed22f9aaef 100644
--- a/src/main/scala/leon/invariant/util/TVarFactory.scala
+++ b/src/main/scala/leon/invariant/util/TVarFactory.scala
@@ -3,26 +3,33 @@ package invariant.util
 
 import purescala.Common._
 import purescala.Types._
-import scala.collection.mutable.{ Set => MutableSet}
+import scala.collection.mutable.{ Set => MutableSet, Map => MutableMap}
 
 object TVarFactory {
 
-  val temporaries = MutableSet[Identifier]()
-  //these are dummy identifiers used in 'CaseClassSelector' conversion
-  val dummyIds = MutableSet[Identifier]()
+  type Context = Int
+  val temporaries = MutableMap[Context, MutableSet[Identifier]]()
+  private var context: Context = 0
 
-  def createTemp(name: String, tpe: TypeTree = Untyped): Identifier = {
+  def newContext = {
+    context += 1
+    temporaries += (context -> MutableSet())
+    context
+  }
+  val defaultContext = newContext
+
+  def createTemp(name: String, tpe: TypeTree = Untyped, context: Context): Identifier = {
     val freshid = FreshIdentifier(name, tpe, true)
-    temporaries.add(freshid)
+    temporaries(context) += freshid
     freshid
   }
 
-  def createDummy(tpe: TypeTree): Identifier = {
-    val freshid = FreshIdentifier("dy", tpe, true)
-    dummyIds.add(freshid)
+  def createTempDefault(name: String, tpe: TypeTree = Untyped): Identifier = {
+    val freshid = FreshIdentifier(name, tpe, true)
+    temporaries(defaultContext) += freshid
     freshid
   }
 
-  def isTemporary(id: Identifier): Boolean = temporaries.contains(id)
-  def isDummy(id: Identifier): Boolean = dummyIds.contains(id)
+  def isTemp(id: Identifier, context: Context): Boolean =
+    temporaries.contains(context) && temporaries(context)(id)
 }
diff --git a/src/main/scala/leon/laziness/LazinessEliminationPhase.scala b/src/main/scala/leon/laziness/LazinessEliminationPhase.scala
index 929ee38e2f5c9d3712f48a146d730f0f62f65fbd..439dc5f8b7ed81492581df370e41554276e14d0b 100644
--- a/src/main/scala/leon/laziness/LazinessEliminationPhase.scala
+++ b/src/main/scala/leon/laziness/LazinessEliminationPhase.scala
@@ -51,7 +51,7 @@ object LazinessEliminationPhase extends TransformationPhase {
   val dumpProgWOInstSpecs = true
   val dumpInstrumentedProgram = true
   val debugSolvers = false
-  val skipStateVerification = false
+  val skipStateVerification = true
   val skipResourceVerification = false
 
   val name = "Laziness Elimination Phase"
diff --git a/src/main/scala/leon/laziness/LazyVerificationPhase.scala b/src/main/scala/leon/laziness/LazyVerificationPhase.scala
index 41375996956a49d5f3d61fe74add146d04266440..3f1a8ce00c9830eae59eb171e1d6096c61018091 100644
--- a/src/main/scala/leon/laziness/LazyVerificationPhase.scala
+++ b/src/main/scala/leon/laziness/LazyVerificationPhase.scala
@@ -134,7 +134,7 @@ object LazyVerificationPhase {
     val funsToCheck = p.definedFunctions.filter(shouldGenerateVC)
     if (useOrb) {
       // create an inference context
-      val inferOpts = Main.processOptions(Seq("--disableInfer", "--assumepreInf", "--minbounds"))
+      val inferOpts = Main.processOptions(Seq("--disableInfer", "--assumepreInf", "--minbounds","--solvers=smt-cvc4"))
       val ctxForInf = LeonContext(checkCtx.reporter, checkCtx.interruptManager,
         inferOpts.options ++ checkCtx.options)
       val inferctx = new InferenceContext(p,  ctxForInf)
diff --git a/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala b/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala
index 85c898d81548800735be9cdf6b1b718b1e052a29..ebde5cc5d0e1d93638b0e4698306196827f8eaa5 100644
--- a/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala
+++ b/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala
@@ -19,8 +19,7 @@ class OrbRegressionSuite extends LeonRegressionSuite {
   }
 
   private def testInference(f: File, bound: Option[Int] = None) {
-
-    val ctx = createLeonContext("--inferInv")
+    val ctx = createLeonContext("--inferInv","--solvers=smt-z3")
     val beginPipe = leon.frontends.scalac.ExtractionPhase andThen
       new leon.utils.PreprocessingPhase
     val (ctx2, program) = beginPipe.run(ctx, f.getAbsolutePath :: Nil)