diff --git a/cp-demo/LazyVars.scala b/cp-demo/LazyVars.scala
index bca91fc7494ae3787b7246ffba58f6e538a902c1..cc9714fa7412dadfac46b0052214828a07652dbf 100644
--- a/cp-demo/LazyVars.scala
+++ b/cp-demo/LazyVars.scala
@@ -3,47 +3,49 @@ import cp.Definitions._
 import cp.LTrees._
 
 object LazyVars {
-  // def NonnegativeInt = ((x: Int) => x >= 0).lazyFindAll
-  // def chooseInt(lower: Int, upper: Int) = ((x: Int) => x >= lower && x <= upper).lazyFindAll
+  def NonnegativeInt = ((x: Int) => x >= 0).lazyFindAll
+  def chooseInt(lower: Int, upper: Int) = ((x: Int) => x >= lower && x <= upper).lazyFindAll
 
   def main(args: Array[String]): Unit = {
-    f4()
+    f1()
+    f2()
+    f3()
   }
 
-  // def f1() {
-  //   for {
-  //     x <- chooseInt(0, 5)
-  //     y <- chooseInt(1, 3)
-  //     if x > y
-  //   } {
-  //     val a: Int = x
-  //     val b: Int = y
-  //     println(a, b)
-  //   }
-  // }
+  def f1() {
+    for {
+      x <- chooseInt(0, 5)
+      y <- chooseInt(1, 3)
+      if x > y
+    } {
+      val a: Int = x
+      val b: Int = y
+      println(a, b)
+    }
+  }
 
-  // def f2() {
-  //   // will loop forever if Scala Stream.from(0) is used instead.
-  //   for {
-  //     x <- NonnegativeInt
-  //     if x < 3
-  //     y <- NonnegativeInt
-  //     if x > y
-  //   } {
-  //     val i: Int = x
-  //     val j: Int = y
-  //     println(i, j)
-  //   }
-  // }
+  def f2() {
+    // will loop forever if Scala Stream.from(0) is used instead.
+    for {
+      x <- NonnegativeInt
+      if x < 3
+      y <- NonnegativeInt
+      if x > y
+    } {
+      val i: Int = x
+      val j: Int = y
+      println(i, j)
+    }
+  }
 
-  // def f3() {
-  //   for {
-  //     i <- chooseInt(0, 3)
-  //     pair <- ((x: Int, y: Int) => x > 0 && y == 2 * x && x <= i).lazyFindAll
-  //   } {
-  //     println("i, (a, b):" + i.value + ", " + pair.value)
-  //   }
-  // }
+  def f3() {
+    for {
+      i <- chooseInt(0, 3)
+      pair <- ((x: Int, y: Int) => x > 0 && y == 2 * x && x <= i).lazyFindAll
+    } {
+      println("i, (a, b):" + i.value + ", " + pair.value)
+    }
+  }
 
   def f4() {
     val (x, y) = ((x: Int, y: Int) => x > 0 && y == 2 * x && x <= 5).lazySolve
diff --git a/src/cp/LTrees.scala b/src/cp/LTrees.scala
index b9d2991e895b0f53d81a6b2005fbc2b0b8243fd0..b21e675a6d51980e1421a2ff117bb027ef780738 100644
--- a/src/cp/LTrees.scala
+++ b/src/cp/LTrees.scala
@@ -16,7 +16,7 @@ object LTrees {
   /** Handler for converting values from Expr to Scala and reporting forced
    * values */
   trait LHandler[T] {
-    val converter: Converter
+    def convert(s: Seq[Expr]): T
     def enqueueAsForced(ids: Seq[Identifier], values: Seq[Expr]): Unit
   }
 
@@ -36,7 +36,7 @@ object LTrees {
       case Some(value) => value
       case None =>
         val model = GlobalContext.findValues(ids)
-        val toRet = handler.converter.exprSeq2scala1[T](model)
+        val toRet = handler.convert(model)
         handler.enqueueAsForced(ids, model)
         cache = Some(toRet)
         toRet
@@ -132,40 +132,8 @@ object LTrees {
   }
   /** END OF GENERATED CODE ***/
 
-  def dummyL[T]: L[T] = new L[T](null, Seq(FreshIdentifier("dummy", true).setType(BottomType)))
-  def dummyTuple1[T1]: Tuple1[L[T1]] = Tuple1(dummyL[T1])
-  def dummyTuple2[T1,T2]: (L[T1],L[T2]) = (dummyL[T1],dummyL[T2])
-  def dummyTuple3[T1,T2,T3]: (L[T1],L[T2],L[T3]) = (dummyL[T1],dummyL[T2],dummyL[T3])
-  def dummyTuple4[T1,T2,T3,T4]: (L[T1],L[T2],L[T3],L[T4]) = (dummyL[T1],dummyL[T2],dummyL[T3],dummyL[T4])
-  def dummyTuple5[T1,T2,T3,T4,T5]: (L[T1],L[T2],L[T3],L[T4],L[T5]) = (dummyL[T1],dummyL[T2],dummyL[T3],dummyL[T4],dummyL[T5])
-  def dummyTuple6[T1,T2,T3,T4,T5,T6]: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6]) = (dummyL[T1],dummyL[T2],dummyL[T3],dummyL[T4],dummyL[T5],dummyL[T6])
-  def dummyTuple7[T1,T2,T3,T4,T5,T6,T7]: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6],L[T7]) = (dummyL[T1],dummyL[T2],dummyL[T3],dummyL[T4],dummyL[T5],dummyL[T6],dummyL[T7])
-  def dummyTuple8[T1,T2,T3,T4,T5,T6,T7,T8]: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6],L[T7],L[T8]) = (dummyL[T1],dummyL[T2],dummyL[T3],dummyL[T4],dummyL[T5],dummyL[T6],dummyL[T7],dummyL[T8])
-  def dummyTuple9[T1,T2,T3,T4,T5,T6,T7,T8,T9]: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6],L[T7],L[T8],L[T9]) = (dummyL[T1],dummyL[T2],dummyL[T3],dummyL[T4],dummyL[T5],dummyL[T6],dummyL[T7],dummyL[T8],dummyL[T9])
-
-  class LIterator1[T1](val constraintGivenTuple: (L[T1]) => Constraint1[T1]) extends LIterator[T1,(L[T1])] {
-    val dummyTuple: Tuple1[L[T1]] = dummyTuple1[T1]
-    val constraint: Constraint[T1] = constraintGivenTuple(dummyTuple._1)
-
-    def withFilter2(p: (L[T1]) => Constraint[T1]): LIterator1[T1] = {
-      new LIterator1[T1]((l: L[T1]) => this.constraintGivenTuple(l).asInstanceOf[Constraint1[T1]] && p(l).asInstanceOf[Constraint1[T1]])
-    }
-  }
-
-  class LIterator2[T1,T2](val constraintGivenTuple: ((L[T1], L[T2])) => Constraint2[T1,T2]) extends LIterator[(T1,T2),(L[T1],L[T2])] {
-    val dummyTuple: (L[T1],L[T2]) = dummyTuple2[T1,T2]
-    val constraint: Constraint[(T1,T2)] = constraintGivenTuple(dummyTuple)
-
-    def withFilter2(p: ((L[T1],L[T2])) => Constraint[(T1,T2)]): LIterator2[T1,T2] = {
-      new LIterator2[T1,T2]((t: (L[T1],L[T2])) => this.constraintGivenTuple(t).asInstanceOf[Constraint2[T1,T2]] && p(t).asInstanceOf[Constraint2[T1,T2]])
-    }
-  }
-
-  /** A lazy iterator for symbolic variables. S denotes the Scala value type
-   * (which can be a tuple) and T denotes the corresponding L tuple type. */
-  abstract class LIterator[S,T] extends Iterator[T] {
-    val dummyTuple: Product
-    val constraint: Constraint[S]
+  /** A stream for symbolic variables */
+  class LIterator[T](val constraint: (L[T]) => Constraint[T]) extends Iterator[L[T]] {
 
     import ConstraintSolving.GlobalContext
     private var guards: Map[Seq[Identifier],Identifier] = Map.empty
@@ -174,7 +142,7 @@ object LTrees {
     private var forcedQueue: Seq[Seq[Identifier]] = Seq.empty
 
     // we don't have this until we first instantiate a constraint
-    // private var convertingFunction: (Seq[Expr]) => T = null
+    private var convertingFunction: (Seq[Expr]) => T = null
 
     def enqueueAsForcedInStream(ids: Seq[Identifier], values: Seq[Expr]): Unit = {
       // assert value
@@ -226,7 +194,7 @@ object LTrees {
     }
 
     private def handler(): LHandler[T] = new LHandler[T] {
-      val converter: Converter = constraint.converter
+      def convert(s: Seq[Expr]): T = convertingFunction(s)
       def enqueueAsForced(ids: Seq[Identifier], values: Seq[Expr]): Unit =
         enqueueAsForcedInStream(ids, values)
     }
@@ -238,18 +206,15 @@ object LTrees {
       // set of tricks to overcome circular dependency between creation of L's
       // and Constraints
 
-      val placeHolders: Seq[Identifier] = (for (l <- dummyTuple.productIterator) yield {
-        assert(l.isInstanceOf[L[_]])
-        val castedL = l.asInstanceOf[L[_]]
-        assert(castedL.ids.size == 1)
-        castedL.ids.head
-      }).toSeq
+      val placeHolders = Seq(FreshIdentifier("placeholder", true).setType(BottomType))
+      val candidateL = new L[T](handler(), placeHolders)
+      val instantiatedCnstr = constraint(candidateL)
 
       // now that we have a Constraint, we can perform some actions such as:
-      GlobalContext.initializeIfNeeded(constraint.program)
-      // convertingFunction = constraint.convertingFunction
+      GlobalContext.initializeIfNeeded(instantiatedCnstr.program)
+      convertingFunction = instantiatedCnstr.convertingFunction
 
-      val (newConsts, newExpr) = combineConstraint(constraint)
+      val (newConsts, newExpr) = combineConstraint(instantiatedCnstr)
       val typedPlaceHolders = newConsts map {
         case cst => FreshIdentifier("fresh", true).setType(cst.getType)
       }
@@ -266,16 +231,15 @@ object LTrees {
     }
 
     def hasNext: Boolean = !underlying.isEmpty
-    def next: T = {
+    def next: L[T] = {
       val toRet = underlying.head
       underlying = underlying.tail
-      // toRet
-      throw new Exception()
+      toRet
     }
 
-    def withFilter2(p: (T) => Constraint[S]): LIterator[S,T] /*= {
+    def withFilter2(p: (L[T]) => Constraint[T]): LIterator[T] = {
       new LIterator[T]((l: L[T]) => this.constraint(l).asInstanceOf[Constraint1[T]] && p(l).asInstanceOf[Constraint1[T]])
-    }*/
+    }
   }
 
 }
diff --git a/src/cp/Terms.scala b/src/cp/Terms.scala
index f101f2b44fc82efe37c95753bbf75bd0b0a5065d..4c907dc417fccdfd9765cb1c54de439d3d6c9c54 100644
--- a/src/cp/Terms.scala
+++ b/src/cp/Terms.scala
@@ -35,9 +35,9 @@ object Terms {
       findAllExprSeq(asConstraint(this)).map(convertingFunction(_))
     }
 
-    // def lazyFindAll(implicit asConstraint: (Term[T,R]) => Constraint[T]): LIterator[T] = {
-    //   new LIterator((l: L[T]) => asConstraint(this))
-    // }
+    def lazyFindAll(implicit asConstraint: (Term[T,R]) => Constraint[T]): LIterator[T] = {
+      new LIterator((l: L[T]) => asConstraint(this))
+    }
   }
 
   def removeGuard(g: Identifier): Unit = {
@@ -48,7 +48,7 @@ object Terms {
 
   def createL[T](constraint: Constraint[_], constant: Identifier, guard: Identifier): L[T] = {
     val handler = new LHandler[T] {
-      val converter: Converter = constraint.converter
+      def convert(s: Seq[Expr]): T = constraint.converter.exprSeq2scala1[T](s)
       def enqueueAsForced(ids: Seq[Identifier], values: Seq[Expr]): Unit = {
         val haveValues = And((ids zip values) map {
           case (i, v) => Equals(Variable(i), v)
@@ -185,10 +185,6 @@ object Terms {
       val (constants, guards) = constantsAndGuards(constraint)
       (createL[T1](constraint, constants(0), guards(0)))
     }
-
-    def lazyFindAll(implicit asConstraint: (Term1[T1,R]) => Constraint1[T1]): LIterator1[T1] = {
-      new LIterator1((l: L[T1]) => asConstraint(this))
-    }
   
     def compose0[A1](other : Term1[A1, T1]) : Term1[A1, R] = {
       val (newExpr, newTypes) = Terms.compose(other, this, 0, 1, 1)