diff --git a/cp-demo/Assuming.scala b/cp-demo/Assuming.scala
index eadd00cfe71bd7c77c30d33b14d1b5acd8d4b235..6180393d7e7c057bc744aa011064ad360ffe2ebb 100644
--- a/cp-demo/Assuming.scala
+++ b/cp-demo/Assuming.scala
@@ -2,20 +2,32 @@ import cp.Definitions._
 import cp.Terms._
 
 object Assuming {
-  def assuming(c: Constraint0)(block: => Unit) : Unit = {
-    for (u <- c.lazyFindAll) {
-      block
-    }
-  }
-
   def main(args: Array[String]): Unit = {
     for (x <- ((x: Int) => x >= 0 && x < 4).lazyFindAll) {
-      assuming(() => x <= 1) {
-        println("hey!")
-      }
-      assuming(() => x > 1) {
-        println("ho!")
+      when (x < 3) {
+        println("I'm assuming x is less than three")
       }
+
+      println(when(x < 2) {
+        "furthermore, less than two"
+      } otherwise {
+        "ok, not less than two"
+      })
+
+      val anInt: Int = when (x < 1) { 42 }
+
+      // cif (x <= 1) {
+      //   println(x)
+      //   println("hi")
+      // } celse {
+      //   println(x)
+      //   println("hola")
+      // }
+
+      // assuming(x == 0) {
+      //   println(x)
+      //   println("I assume this was zero!")
+      // }
     }
   }
 }
diff --git a/src/cp/CallTransformation.scala b/src/cp/CallTransformation.scala
index bc5f43601ac961006f554406f1c1cd69f1cf53bd..1ae9a8e95a8d7d8ab7abb189b5dea851a6a97d19 100644
--- a/src/cp/CallTransformation.scala
+++ b/src/cp/CallTransformation.scala
@@ -54,6 +54,9 @@ trait CallTransformation
         val Function(funValDefs, funBody) = predicate
         extracted += (predicate.pos -> extractWithFilterPredicate(unit, funValDefs, funBody))
       }
+      case Apply(Select(lhs, boolean2constraint0Name), List(b: Tree)) if boolean2constraint0Name.toString == "boolean2constraint0" => {
+        extracted += (b.pos -> extractFunction(unit, Nil, b))
+      }
       case _ => 
     }
     new ForeachTreeTraverser(extractFunDefs).traverse(unit.body)
@@ -72,9 +75,7 @@ trait CallTransformation
 
     val extractedFunDefs : Map[Position,FunDef] = funDefMap(unit)
 
-    private def transformHelper(tree : Tree, function : Function, codeGen : CodeGenerator) : Option[(Serialized, Serialized, Serialized, Serialized, Tree, Tree, Tree, Int)] = {
-      val Function(funValDefs, funBody) = function
-
+    private def transformHelper(tree : Tree, function : Tree, codeGen : CodeGenerator) : Option[(Serialized, Serialized, Serialized, Serialized, Tree, Tree, Tree, Int)] = {
       val fd = extractedFunDefs(function.pos)
       val outputVars : Seq[Identifier] = fd.args.map(_.id)
       
@@ -82,7 +83,7 @@ trait CallTransformation
       purescalaReporter.info(fd)
 
       fd.body match {
-        case None => purescalaReporter.error("Could not extract function: " + funBody); None
+        case None => purescalaReporter.error("Could not extract : " + function); None
         case Some(b) =>
           // serialize expression
           val serializedExpr = serialize(matchToIfThenElse(b))
@@ -119,7 +120,7 @@ trait CallTransformation
     override def transform(tree: Tree) : Tree = {
       tree match {
         /** Transform implicit conversions to terms into instantiation of base terms */
-        case Apply(TypeApply(Select(Select(cpIdent, definitionsName), func2termName), typeTreeList), List(function: Function)) if 
+        case Apply(TypeApply(Select(Select(cpIdent, definitionsName), func2termName), typeTreeList), List(function: Tree)) if 
           (definitionsName.toString == "Definitions" && func2termName.toString.matches("func2term\\d")) => {
           val codeGen = new CodeGenerator(unit, currentOwner, tree.pos)
 
@@ -135,6 +136,22 @@ trait CallTransformation
             case None => super.transform(tree)
           }
         }
+        case Apply(Select(Select(cpIdent, definitionsName), boolean2constraint0Name), List(function: Tree)) if 
+          (definitionsName.toString == "Definitions" && boolean2constraint0Name.toString.matches("boolean2constraint0")) => {
+          val codeGen = new CodeGenerator(unit, currentOwner, tree.pos)
+
+          transformHelper(tree, function, codeGen) match {
+            case Some((serializedInputVarList, serializedLVarList, serializedOutputVars, serializedExpr, inputVarValues, lVarValues, actualLVars, arity)) => {
+              // create constraint instance
+              val code = codeGen.newBaseTerm(exprToScalaSym, serializedProg, serializedInputVarList, serializedLVarList, serializedOutputVars, serializedExpr, inputVarValues, lVarValues, actualLVars, NULL, List(TypeTree(definitions.BooleanClass.tpe)), arity)
+
+              typer.typed(atOwner(currentOwner) {
+                code
+              })
+            }
+            case None => super.transform(tree)
+          }
+        }
         case Apply(Select(lhs, withFilterName), List(predicate: Function)) if withFilterName.toString == "withFilter" && hasLIteratorType(lhs) => {
           val codeGen = new CodeGenerator(unit, currentOwner, tree.pos)
 
diff --git a/src/cp/Definitions.scala b/src/cp/Definitions.scala
index 9caa35be3a44caff6a82c75e14473d5ca37d66f1..ff91c55018710de486b2d62bc5cdd7bf8ae72c85 100644
--- a/src/cp/Definitions.scala
+++ b/src/cp/Definitions.scala
@@ -11,18 +11,59 @@ object Definitions {
   final class UnsatisfiableConstraintException extends Exception
   final class UnknownConstraintException extends Exception
 
-  implicit def func2term0[R](func : () => R) : Term0[R] = throw new NotImplementedException
-  implicit def func2term1[T1,R](func : T1 => R) : Term1[T1,R] = throw new NotImplementedException
-  implicit def func2term2[T1,T2,R](func : (T1,T2) => R) : Term2[T1,T2,R] = throw new NotImplementedException
-  implicit def func2term3[T1,T2,T3,R](func : (T1,T2,T3) => R) : Term3[T1,T2,T3,R] = throw new NotImplementedException
-  implicit def func2term4[T1,T2,T3,T4,R](func : (T1,T2,T3,T4) => R) : Term4[T1,T2,T3,T4,R] = throw new NotImplementedException
-  implicit def func2term5[T1,T2,T3,T4,T5,R](func : (T1,T2,T3,T4,T5) => R) : Term5[T1,T2,T3,T4,T5,R] = throw new NotImplementedException
-  implicit def func2term6[T1,T2,T3,T4,T5,T6,R](func : (T1,T2,T3,T4,T5,T6) => R) : Term6[T1,T2,T3,T4,T5,T6,R] = throw new NotImplementedException
-  implicit def func2term7[T1,T2,T3,T4,T5,T6,T7,R](func : (T1,T2,T3,T4,T5,T6,T7) => R) : Term7[T1,T2,T3,T4,T5,T6,T7,R] = throw new NotImplementedException
-  implicit def func2term8[T1,T2,T3,T4,T5,T6,T7,T8,R](func : (T1,T2,T3,T4,T5,T6,T7,T8) => R) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] = throw new NotImplementedException
-  implicit def func2term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R](func : (T1,T2,T3,T4,T5,T6,T7,T8,T9) => R) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] = throw new NotImplementedException
-
-  implicit def force[T](l : L[T]): T = {
+  def assuming(cond: Constraint0)(block: => Unit): Unit = {
+    for (u <- cond.lazyFindAll) {
+      block
+    }
+  }
+
+  def when[A](cond: Constraint0)(block: => A): When[A] = {
+    var v: Option[A] = None
+    for (i <- cond.lazyFindAll)
+      v = Some(block)
+    new When(v)
+  }
+
+  final class When[A](val thenResult: Option[A]) {
+    def otherwise(elseBlock: => A): A = thenResult match {
+      case None => elseBlock
+      case Some(tr) => tr
+    }
+  }
+
+  implicit def when2value[A](w: When[A]): A = w.thenResult match {
+    case Some(tr) => tr
+    case None => throw new Exception("Cannot find value for result of `when'")
+  }
+
+  def cif[A](cond: Constraint0)(block: => A): CIf[A] = new CIf(cond, block)
+
+  final class CIf[A](cond: Constraint0, ifBlock: => A) {
+    def celse(elseBlock: => A): A = {
+      var enteredIf = false
+      for (u <- cond.lazyFindAll) {
+        enteredIf = true
+      }
+      if (enteredIf)
+        ifBlock
+      else
+        elseBlock
+    }
+  }
+
+  implicit def boolean2constraint0(b: Boolean): Constraint0 = throw new NotImplementedException
+  implicit def func2term0[R](func: () => R): Term0[R] = throw new NotImplementedException
+  implicit def func2term1[T1,R](func: T1 => R): Term1[T1,R] = throw new NotImplementedException
+  implicit def func2term2[T1,T2,R](func: (T1,T2) => R): Term2[T1,T2,R] = throw new NotImplementedException
+  implicit def func2term3[T1,T2,T3,R](func: (T1,T2,T3) => R): Term3[T1,T2,T3,R] = throw new NotImplementedException
+  implicit def func2term4[T1,T2,T3,T4,R](func: (T1,T2,T3,T4) => R): Term4[T1,T2,T3,T4,R] = throw new NotImplementedException
+  implicit def func2term5[T1,T2,T3,T4,T5,R](func: (T1,T2,T3,T4,T5) => R): Term5[T1,T2,T3,T4,T5,R] = throw new NotImplementedException
+  implicit def func2term6[T1,T2,T3,T4,T5,T6,R](func: (T1,T2,T3,T4,T5,T6) => R): Term6[T1,T2,T3,T4,T5,T6,R] = throw new NotImplementedException
+  implicit def func2term7[T1,T2,T3,T4,T5,T6,T7,R](func: (T1,T2,T3,T4,T5,T6,T7) => R): Term7[T1,T2,T3,T4,T5,T6,T7,R] = throw new NotImplementedException
+  implicit def func2term8[T1,T2,T3,T4,T5,T6,T7,T8,R](func: (T1,T2,T3,T4,T5,T6,T7,T8) => R): Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] = throw new NotImplementedException
+  implicit def func2term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R](func: (T1,T2,T3,T4,T5,T6,T7,T8,T9) => R): Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] = throw new NotImplementedException
+
+  implicit def force[T](l: L[T]): T = {
     l.value
   }
 
@@ -45,7 +86,7 @@ object Definitions {
   implicit def tupleOfL2lTuple8[T1,T2,T3,T4,T5,T6,T7,T8](lt: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6],L[T7],L[T8])): LTuple8[T1,T2,T3,T4,T5,T6,T7,T8] = new LTuple8(lt._1,lt._2,lt._3,lt._4,lt._5,lt._6,lt._7,lt._8)
   implicit def tupleOfL2lTuple9[T1,T2,T3,T4,T5,T6,T7,T8,T9](lt: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6],L[T7],L[T8],L[T9])): LTuple9[T1,T2,T3,T4,T5,T6,T7,T8,T9] = new LTuple9(lt._1,lt._2,lt._3,lt._4,lt._5,lt._6,lt._7,lt._8,lt._9)
 
-  def distinct[A](args: A*) : Boolean = {
+  def distinct[A](args: A*): Boolean = {
     args.toList.distinct.size == args.size
   }
 }
diff --git a/src/cp/Extractors.scala b/src/cp/Extractors.scala
index 2274840337a5aff2c9b4574c34ee111de06af2ad..0fe539602a2d5f260c48412a2e788fe314cd1292 100644
--- a/src/cp/Extractors.scala
+++ b/src/cp/Extractors.scala
@@ -375,10 +375,13 @@ trait Extractors {
 
     // extracts a tree typed as L, returns parameter type tree and tree itself
     object ExLTyped {
-      def unapply(tree: Tree): Option[(Type,Tree)] = tree.tpe match {
-        case TypeRef(_, sym, List(t)) if sym == lClassSym =>
-          Some((t, tree))
-        case _ => None
+      def unapply(tree: Tree): Option[(Type,Tree)] = {
+        val tpe = if (tree.symbol == null) tree.tpe else tree.symbol.tpe
+        tpe match {
+          case TypeRef(_, sym, List(t)) if sym == lClassSym =>
+            Some((t, tree))
+          case _ => None
+        }
       }
     }