From 8f2438cc67f4718d80e0f1b6f7e4156b31d812ab Mon Sep 17 00:00:00 2001
From: Etienne Kneuss <colder@php.net>
Date: Wed, 9 Apr 2014 12:51:15 +0200
Subject: [PATCH] All-seeing synthesis with Oracles, library reorganisation

- NormalizationRule becomes priorities, so that we can have multiple
  distinct layers

- Use the @library annotation, move synthesis stuff to synthesis,
  Oracles.

- Make sure tests use PreprocessingPhase and import synthesis when
  adequate

- Extract proper package objects fix patternRecons and simplifiers

- Reorganize library:
  - leon.{choose,???} -> leon.lang.synthesis
  - leon.{waypoint,epsilon} -> leon.lang.xlang
---
 library/Option.scala                          |   6 +-
 library/annotation/package.scala              |  15 +-
 library/collection/List.scala                 |  19 +-
 library/lang/package.scala                    |  22 +-
 library/lang/xlang/package.scala              |  13 +
 scripts/applyLicense.sh                       |   5 +-
 src/main/scala/leon/LeonOption.scala          |  36 +++
 src/main/scala/leon/Main.scala                |  23 +-
 src/main/scala/leon/Pipeline.scala            |   6 +-
 src/main/scala/leon/Reporter.scala            |   2 +-
 src/main/scala/leon/Settings.scala            |   6 +-
 .../scala/leon/codegen/CodeGeneration.scala   |   4 +
 .../scala/leon/datagen/NaiveDataGen.scala     |  15 +-
 .../leon/evaluators/CodeGenEvaluator.scala    |   2 +-
 .../leon/evaluators/RecursiveEvaluator.scala  |   2 +-
 .../leon/frontends/scalac/ASTExtractors.scala | 114 +++++----
 .../frontends/scalac/CodeExtraction.scala     | 232 ++++++++++++------
 .../frontends/scalac/ExtractionPhase.scala    |  21 +-
 .../scala/leon/purescala/Definitions.scala    |   2 +-
 .../scala/leon/purescala/PrettyPrinter.scala  |   8 +-
 .../leon/purescala/SimplifierWithPaths.scala  |   9 +-
 src/main/scala/leon/purescala/TreeOps.scala   |  99 +++++++-
 src/main/scala/leon/purescala/Trees.scala     |   9 +-
 .../leon/solvers/z3/AbstractZ3Solver.scala    |   7 +-
 .../leon/solvers/z3/FunctionTemplate.scala    |   5 +-
 .../scala/leon/synthesis/BoundedSearch.scala  |   5 +-
 .../scala/leon/synthesis/ChooseInfo.scala     |  30 ++-
 .../scala/leon/synthesis/ConvertHoles.scala   | 101 --------
 src/main/scala/leon/synthesis/CostModel.scala |   8 +-
 .../scala/leon/synthesis/Heuristics.scala     |  31 ---
 .../scala/leon/synthesis/ManualSearch.scala   |  25 +-
 .../scala/leon/synthesis/ParallelSearch.scala |  21 +-
 src/main/scala/leon/synthesis/Rules.scala     |  92 ++++++-
 .../scala/leon/synthesis/SimpleSearch.scala   |  21 +-
 src/main/scala/leon/synthesis/Solution.scala  |  32 ++-
 .../leon/synthesis/SynthesisContext.scala     |   2 +
 .../leon/synthesis/SynthesisOptions.scala     |   1 +
 .../scala/leon/synthesis/SynthesisPhase.scala |  17 +-
 .../scala/leon/synthesis/Synthesizer.scala    |   4 +-
 .../synthesis/heuristics/ADTInduction.scala   |   2 +-
 .../heuristics/ADTLongInduction.scala         |   4 +-
 .../synthesis/heuristics/IntInduction.scala   |   2 +-
 .../heuristics/OptimisticInjection.scala      |   2 +-
 .../heuristics/SelectiveInlining.scala        |   2 +-
 .../leon/synthesis/rules/AngelicHoles.scala   |  50 ++++
 .../scala/leon/synthesis/rules/AsChoose.scala |   2 +-
 .../scala/leon/synthesis/rules/Cegis.scala    |  10 +-
 .../scala/leon/synthesis/rules/Ground.scala   |   2 +-
 .../leon/synthesis/rules/InlineHoles.scala    | 103 ++++++++
 .../scala/leon/synthesis/rules/OnePoint.scala |   9 +-
 .../synthesis/rules/OptimisticGround.scala    |   2 +-
 .../scala/leon/utils/OracleTraverser.scala    |  32 +++
 .../scala/leon/utils/PreprocessingPhase.scala |  24 ++
 src/main/scala/leon/utils/TypingPhase.scala   |  16 +-
 .../leon/verification/AnalysisPhase.scala     |  33 ++-
 .../leon/verification/InductionTactic.scala   |   4 +-
 .../regression/synthesis/Church/Add.scala     |   2 +
 .../synthesis/Church/Distinct.scala           |   1 +
 .../regression/synthesis/Church/Mult.scala    |   2 +
 .../regression/synthesis/Church/Squared.scala |   2 +
 .../regression/synthesis/Holes/Hole1.scala    |  13 +
 .../regression/synthesis/Holes/Hole2.scala    |  17 ++
 .../regression/synthesis/List/Delete.scala    |   1 +
 .../regression/synthesis/List/Diff.scala      |   1 +
 .../regression/synthesis/List/Insert.scala    |   1 +
 .../regression/synthesis/List/Split.scala     |   1 +
 .../regression/synthesis/List/Union.scala     |   1 +
 .../purescala/invalid/Choose1.scala           |   1 +
 .../purescala/valid/Choose1.scala             |   1 +
 .../purescala/valid/IsolatedAbstract.scala    |  23 --
 .../verification/xlang/invalid/Epsilon1.scala |   1 +
 .../verification/xlang/invalid/Epsilon2.scala |   1 +
 .../verification/xlang/invalid/Epsilon3.scala |   1 +
 .../verification/xlang/invalid/Epsilon4.scala |   1 +
 .../verification/xlang/invalid/Epsilon5.scala |   1 +
 .../verification/xlang/invalid/Epsilon6.scala |   1 +
 .../verification/xlang/valid/Choose1.scala    |   1 +
 .../verification/xlang/valid/Epsilon1.scala   |   1 +
 .../verification/xlang/valid/Epsilon2.scala   |   1 +
 .../verification/xlang/valid/Epsilon3.scala   |   1 +
 .../verification/xlang/valid/Epsilon4.scala   |   1 +
 .../verification/xlang/valid/Epsilon5.scala   |   1 +
 src/test/scala/leon/test/LeonTestSuite.scala  |  15 +-
 .../test/evaluators/EvaluatorsTests.scala     |   5 +-
 .../scala/leon/test/purescala/DataGen.scala   |  26 +-
 .../test/purescala/TransformationTests.scala  |   4 +-
 .../synthesis/SynthesisRegressionSuite.scala  |  21 +-
 .../leon/test/synthesis/SynthesisSuite.scala  |  48 ++--
 .../termination/TerminationRegression.scala   |   2 +-
 .../LibraryVerificationRegression.scala       |  12 +-
 .../PureScalaVerificationRegression.scala     |   9 +-
 .../XLangVerificationRegression.scala         |   9 +-
 testcases/case-studies/Lambda.scala           |   1 +
 .../AddressesMakeAddressBook.scala            |   2 +-
 .../AddressesMakeAddressBookWithHelpers.scala |   2 +-
 .../AddressesMergeAddressBooks.scala          |   2 +-
 .../BatchedQueue/BatchedQueueCheckf.scala     |   3 +-
 .../BatchedQueue/BatchedQueueSnoc.scala       |   3 +-
 .../BatchedQueue/BatchedQueueSnocWeird.scala  |   3 +-
 .../BatchedQueue/BatchedQueueTail.scala       |   3 +-
 .../condabd/benchmarks/BinarySearch.scala     |   1 +
 .../BinarySearchTreeMember.scala              |   3 +-
 .../InsertionSort/InsertionSortInsert.scala   |   2 +-
 .../InsertionSort/InsertionSortSort.scala     |   2 +-
 .../condabd/benchmarks/List/ListConcat.scala  |   3 +-
 .../benchmarks/MergeSort/MergeSortMerge.scala |   3 +-
 .../benchmarks/MergeSort/MergeSortSort.scala  |   3 +-
 .../MergeSort/MergeSortSortWithVal.scala      |   3 +-
 .../RedBlackTree/RedBlackTreeInsert.scala     |   1 +
 .../condabd/test/insynth/Addresses.scala      |   2 +-
 .../test/insynth/AddressesWithAddition.scala  |   2 +-
 .../condabd/test/insynth/ListConcat.scala     |   3 +-
 .../condabd/test/lesynth/Addresses.scala      |   2 +-
 .../lesynth/AddressesMergeAddressBooks.scala  |   2 +-
 .../test/lesynth/BinarySearchTree.scala       |   3 +-
 .../test/lesynth/InsertionSortInsert.scala    |   2 +-
 .../condabd/test/lesynth/ListConcat.scala     |   3 +-
 .../test/lesynth/ListConcatVerifierTest.scala |   3 +-
 .../test/lesynth/ListConcatWithEmpty.scala    |   3 +-
 .../condabd/test/lesynth/MergeSortSort.scala  |   3 +-
 .../test/lesynth/RedBlackTreeInsert.scala     |   1 +
 testcases/graveyard/Choose.scala              |   1 +
 testcases/graveyard/Sat.scala                 |   1 +
 testcases/runtime/CachedList.scala            |   1 +
 testcases/runtime/SquareRoot.scala            |   1 +
 testcases/synthesis/ADTInduction.scala        |   2 +-
 testcases/synthesis/BinaryTree.scala          |   2 +-
 testcases/synthesis/CegisExamples.scala       |   1 +
 testcases/synthesis/CegisFunctions.scala      |   1 +
 testcases/synthesis/ChooseArith.scala         |   1 +
 testcases/synthesis/ChooseIneq.scala          |   1 +
 testcases/synthesis/ChoosePos.scala           |   1 +
 testcases/synthesis/ChurchNumerals.scala      |   2 +
 testcases/synthesis/DrSuter.scala             |   1 +
 testcases/synthesis/FastExp.scala             |   1 +
 testcases/synthesis/FiniteSort.scala          |   1 +
 testcases/synthesis/Injection.scala           |   2 +-
 testcases/synthesis/InnerSplit.scala          |   1 +
 testcases/synthesis/Justify.scala             |   1 +
 testcases/synthesis/Matching.scala            |   1 +
 testcases/synthesis/NewYearsSong.scala        |   2 +-
 testcases/synthesis/ScaleWeight.scala         |   1 +
 testcases/synthesis/Sec2Time.scala            |   1 +
 testcases/synthesis/Simple.scala              |   1 +
 testcases/synthesis/SimplestCegis.scala       |   2 +-
 testcases/synthesis/SortedList.scala          |   2 +-
 testcases/synthesis/Spt.scala                 |   1 +
 testcases/synthesis/Unification.scala         |   1 +
 testcases/synthesis/cav2013/AVLTree.scala     |   2 +-
 testcases/synthesis/cav2013/BinaryTree.scala  |   2 +-
 testcases/synthesis/cav2013/List.scala        |   2 +-
 .../synthesis/cav2013/ListByExample.scala     |   2 +-
 testcases/synthesis/cav2013/ManyTimeSec.scala |   2 +-
 testcases/synthesis/cav2013/SortedList.scala  |   2 +-
 testcases/synthesis/cav2013/Sorting.scala     |   1 +
 .../cav2013/StrictlySortedList.scala          |   2 +-
 .../synthesis/cav2013/SynAddresses.scala      |   2 +-
 .../synthesis/cav2013/SynTreeListSet.scala    |   2 +-
 .../AddressesMakeAddressBook.scala            |   2 +-
 .../AddressesMakeAddressBookStrong.scala      |   2 +-
 .../AddressesMakeAddressBookSynthWrong.scala  |   2 +-
 .../AddressesMakeAddressBookWithHelpers.scala |   2 +-
 .../AddressesMergeAddressBooks.scala          |   2 +-
 .../AddressesMergeAddressBooksStep1.scala     |   2 +-
 .../AddressesMergeAddressBooksStep2.scala     |   2 +-
 .../BatchedQueue/BatchedQueueCheckf.scala     |   3 +-
 .../BatchedQueue/BatchedQueueSnoc.scala       |   3 +-
 .../oopsla2013/BinaryTree/Batch.scala         |   1 +
 .../oopsla2013/BinaryTree/Complete.scala      |   1 +
 .../oopsla2013/BinaryTree/Delete.scala        |   1 +
 .../oopsla2013/BinaryTree/Diff.scala          |   1 +
 .../oopsla2013/BinaryTree/Insert.scala        |   1 +
 .../oopsla2013/BinaryTree/Union.scala         |   1 +
 .../synthesis/oopsla2013/Church/Add.scala     |   2 +
 .../synthesis/oopsla2013/Church/Batch.scala   |   2 +
 .../oopsla2013/Church/Complete.scala          |   2 +
 .../oopsla2013/Church/Distinct.scala          |   2 +
 .../synthesis/oopsla2013/Church/Mult.scala    |   2 +
 .../synthesis/oopsla2013/Church/Squared.scala |   2 +
 .../oopsla2013/InsertionSort/Insert.scala     |   2 +-
 .../oopsla2013/InsertionSort/Sort.scala       |   2 +-
 .../synthesis/oopsla2013/List/Batch.scala     |   1 +
 .../synthesis/oopsla2013/List/Complete.scala  |   1 +
 .../synthesis/oopsla2013/List/Delete.scala    |   1 +
 .../synthesis/oopsla2013/List/Diff.scala      |   1 +
 .../synthesis/oopsla2013/List/Insert.scala    |   1 +
 .../synthesis/oopsla2013/List/Split.scala     |   1 +
 .../synthesis/oopsla2013/List/Union.scala     |   1 +
 .../oopsla2013/MergeSort/MergeSortSort.scala  |   3 +-
 .../MergeSort/MergeSortSortWithVal.scala      |   3 +-
 .../oopsla2013/SortedBinaryTree/Batch.scala   |   2 +-
 .../oopsla2013/SortedList/Batch.scala         |   1 +
 .../oopsla2013/SortedList/Complete.scala      |   1 +
 .../oopsla2013/SortedList/Delete.scala        |   1 +
 .../oopsla2013/SortedList/Diff.scala          |   1 +
 .../oopsla2013/SortedList/Insert1.scala       |   1 +
 .../oopsla2013/SortedList/Insert2.scala       |   1 +
 .../oopsla2013/SortedList/Sort.scala          |   1 +
 .../oopsla2013/SortedList/SortInsert.scala    |   1 +
 .../oopsla2013/SortedList/SortMerge.scala     |   1 +
 .../SortedList/SortMergeWithHint.scala        |   1 +
 .../oopsla2013/SortedList/Split.scala         |   1 +
 .../oopsla2013/SortedList/Split1.scala        |   1 +
 .../oopsla2013/SortedList/Split2.scala        |   1 +
 .../oopsla2013/SortedList/Split3.scala        |   1 +
 .../oopsla2013/SortedList/Union.scala         |   2 +-
 .../oopsla2013/SortedList/UnionIO.scala       |   2 +-
 .../oopsla2013/SparseVector/Batch.scala       |   1 +
 .../oopsla2013/SparseVector/Complete.scala    |   1 +
 .../oopsla2013/SparseVector/Delete.scala      |   1 +
 .../oopsla2013/SparseVector/Get.scala         |   1 +
 .../oopsla2013/SparseVector/Set.scala         |   1 +
 .../oopsla2013/StrictSortedList/Batch.scala   |   1 +
 .../StrictSortedList/Complete.scala           |   1 +
 .../oopsla2013/StrictSortedList/Delete.scala  |   1 +
 .../oopsla2013/StrictSortedList/Diff.scala    |   1 +
 .../oopsla2013/StrictSortedList/Insert.scala  |   1 +
 .../oopsla2013/StrictSortedList/Union.scala   |   1 +
 218 files changed, 1187 insertions(+), 622 deletions(-)
 create mode 100644 library/lang/xlang/package.scala
 delete mode 100644 src/main/scala/leon/synthesis/ConvertHoles.scala
 create mode 100644 src/main/scala/leon/synthesis/rules/AngelicHoles.scala
 create mode 100644 src/main/scala/leon/synthesis/rules/InlineHoles.scala
 create mode 100644 src/main/scala/leon/utils/OracleTraverser.scala
 create mode 100644 src/main/scala/leon/utils/PreprocessingPhase.scala
 create mode 100644 src/test/resources/regression/synthesis/Holes/Hole1.scala
 create mode 100644 src/test/resources/regression/synthesis/Holes/Hole2.scala
 delete mode 100644 src/test/resources/regression/verification/purescala/valid/IsolatedAbstract.scala

diff --git a/library/Option.scala b/library/Option.scala
index 8aff85e7c..e35fc9a0f 100644
--- a/library/Option.scala
+++ b/library/Option.scala
@@ -4,29 +4,25 @@ package leon
 
 import leon.annotation._
 
+@library
 sealed abstract class Option[T] {
-  @verified
   def getOrElse(default: T) = this match {
     case Some(v) => v
     case None()  => default
   }
 
-  @verified
   def orElse(or: Option[T]) = this match {
     case Some(v) => this
     case None() => or
   }
 
-  @verified
   def isEmpty = this match {
     case Some(v) => false
     case None() =>  true
   }
 
-  @verified
   def nonEmpty  = !isEmpty
 
-  @verified
   def isDefined = !isEmpty
 }
 
diff --git a/library/annotation/package.scala b/library/annotation/package.scala
index 68cf4e4c6..1aa564cbd 100644
--- a/library/annotation/package.scala
+++ b/library/annotation/package.scala
@@ -4,13 +4,22 @@ package leon
 
 import scala.annotation.StaticAnnotation
 
-@annotation.ignore
-object annotation {
+package object annotation {
+  @ignore
+  class library    extends StaticAnnotation
+  @ignore
+  class verified   extends StaticAnnotation
+
+  @ignore
   class induct     extends StaticAnnotation
+  @ignore
   class axiomatize extends StaticAnnotation
+  @ignore
   class main       extends StaticAnnotation
-  class verified   extends StaticAnnotation
+  @ignore
   class proxy      extends StaticAnnotation
+  @ignore
   class ignore     extends StaticAnnotation
+
 }
 
diff --git a/library/collection/List.scala b/library/collection/List.scala
index 622cdb77b..f2f629243 100644
--- a/library/collection/List.scala
+++ b/library/collection/List.scala
@@ -5,33 +5,29 @@ package leon.collection
 import leon.lang._
 import leon.annotation._
 
+@library
 sealed abstract class List[T] {
-  @verified
   def size: Int = (this match {
     case Nil() => 0
     case Cons(h, t) => 1 + t.size
   }) ensuring (_ >= 0)
 
-  @verified
   def content: Set[T] = this match {
     case Nil() => Set()
     case Cons(h, t) => Set(h) ++ t.content
   }
 
-  @verified
   def contains(v: T): Boolean = (this match {
     case Cons(h, t) if h == v => true
     case Cons(_, t) => t.contains(v)
     case Nil() => false
   }) ensuring { res => res == (content contains v) }
 
-  @verified
   def ++(that: List[T]): List[T] = (this match {
     case Nil() => that
     case Cons(x, xs) => Cons(x, xs ++ that)
   }) ensuring { res => (res.content == this.content ++ that.content) && (res.size == this.size + that.size)}
 
-  @verified
   def head: T = {
     require(this != Nil[T]())
     this match {
@@ -39,7 +35,6 @@ sealed abstract class List[T] {
     }
   }
 
-  @verified
   def tail: List[T] = {
     require(this != Nil[T]())
     this match {
@@ -47,7 +42,6 @@ sealed abstract class List[T] {
     }
   }
 
-  @verified
   def apply(index: Int): T = {
     require(0 <= index && index < size)
     if (index == 0) {
@@ -57,7 +51,6 @@ sealed abstract class List[T] {
     }
   }
 
-  @verified
   def :+(t:T): List[T] = {
     this match {
       case Nil() => Cons(t, this)
@@ -65,7 +58,6 @@ sealed abstract class List[T] {
     }
   } ensuring(res => (res.size == size + 1) && (res.content == content ++ Set(t)))
 
-  @verified
   def reverse: List[T] = {
     this match {
       case Nil() => this
@@ -78,8 +70,8 @@ sealed abstract class List[T] {
 case class Cons[T](h: T, t: List[T]) extends List[T]
 case class Nil[T]() extends List[T]
 
+@library
 object ListSpecs {
-  @verified
   def snocIndex[T](l : List[T], t : T, i : Int) : Boolean = {
     require(0 <= i && i < l.size + 1)
     // proof:
@@ -91,7 +83,6 @@ object ListSpecs {
     ((l :+ t).apply(i) == (if (i < l.size) l(i) else t))
   }.holds
 
-  @verified
   def reverseIndex[T](l : List[T], i : Int) : Boolean = {
     require(0 <= i && i < l.size)
     (l match {
@@ -101,7 +92,6 @@ object ListSpecs {
     (l.reverse.apply(i) == l.apply(l.size - 1 - i))
   }.holds
 
-  @verified
   def appendIndex[T](l1 : List[T], l2 : List[T], i : Int) : Boolean = {
     require(0 <= i && i < l1.size + l2.size)
     (l1 match {
@@ -111,7 +101,6 @@ object ListSpecs {
     ((l1 ++ l2).apply(i) == (if (i < l1.size) l1(i) else l2(i - l1.size)))
   }.holds
 
-  @verified
   def appendAssoc[T](l1 : List[T], l2 : List[T], l3 : List[T]) : Boolean = {
     (l1 match {
       case Nil() => true
@@ -120,7 +109,6 @@ object ListSpecs {
     (((l1 ++ l2) ++ l3) == (l1 ++ (l2 ++ l3)))
   }.holds
 
-  @verified
   def snocIsAppend[T](l : List[T], t : T) : Boolean = {
     (l match {
       case Nil() => true
@@ -129,7 +117,6 @@ object ListSpecs {
     ((l :+ t) == l ++ Cons[T](t, Nil()))
   }.holds
 
-  @verified
   def snocAfterAppend[T](l1 : List[T], l2 : List[T], t : T) : Boolean = {
     (l1 match {
       case Nil() => true
@@ -138,7 +125,6 @@ object ListSpecs {
     ((l1 ++ l2) :+ t == (l1 ++ (l2 :+ t)))
   }.holds
 
-  @verified
   def snocReverse[T](l : List[T], t : T) : Boolean = {
     (l match {
       case Nil() => true
@@ -147,7 +133,6 @@ object ListSpecs {
     ((l :+ t).reverse == Cons(t, l.reverse))
   }.holds
 
-  @verified
   def reverseReverse[T](l : List[T]) : Boolean = {
     (l match {
       case Nil() => true
diff --git a/library/lang/package.scala b/library/lang/package.scala
index 8cb68e7a1..41cd25b65 100644
--- a/library/lang/package.scala
+++ b/library/lang/package.scala
@@ -5,8 +5,8 @@ package leon
 import leon.annotation._
 import scala.language.implicitConversions
 
-@ignore
-object lang {
+package object lang {
+  @ignore
   sealed class IsValid(val property : Boolean) {
     def holds : Boolean = {
       assert(property)
@@ -14,27 +14,17 @@ object lang {
     }
   }
 
+  @ignore
   implicit def any2IsValid(x: Boolean) : IsValid = new IsValid(x)
 
-  def epsilon[A](pred: (A) => Boolean): A = throw new RuntimeException("Implementation not supported")
-
+  @ignore
   object InvariantFunction {
     def invariant(x: Boolean): Unit = ()
   }
 
+  @ignore
   implicit def while2Invariant(u: Unit) = InvariantFunction
 
-  def waypoint[A](i: Int, expr: A): A = expr
-
-  private def noChoose = throw new RuntimeException("Implementation not supported")
-
-  def choose[A](predicate: A => Boolean): A = noChoose
-  def choose[A, B](predicate: (A, B) => Boolean): (A, B) = noChoose
-  def choose[A, B, C](predicate: (A, B, C) => Boolean): (A, B, C) = noChoose
-  def choose[A, B, C, D](predicate: (A, B, C, D) => Boolean): (A, B, C, D) = noChoose
-  def choose[A, B, C, D, E](predicate: (A, B, C, D, E) => Boolean): (A, B, C, D, E) = noChoose
-
-  def ???[A]: A = throw new RuntimeException("Implementation not supported")
-
+  @ignore
   def error[T](reason: String): T = sys.error(reason)
 }
diff --git a/library/lang/xlang/package.scala b/library/lang/xlang/package.scala
new file mode 100644
index 000000000..928498a47
--- /dev/null
+++ b/library/lang/xlang/package.scala
@@ -0,0 +1,13 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+
+package leon.lang
+
+import leon.annotation._
+
+package object xlang {
+  @ignore
+  def waypoint[A](i: Int, expr: A): A = expr
+
+  @ignore
+  def epsilon[A](pred: (A) => Boolean): A = throw new RuntimeException("Implementation not supported")
+}
diff --git a/scripts/applyLicense.sh b/scripts/applyLicense.sh
index 7bf0aa64f..cc809905d 100755
--- a/scripts/applyLicense.sh
+++ b/scripts/applyLicense.sh
@@ -9,6 +9,9 @@ for f in $(find {src,library} -name "*.java" -o -name "*.scala") ;do
       else
           cat $f >> /tmp/newfile
       fi
-      mv /tmp/newfile "$f"
+      if ! cmp --silent /tmp/newfile "$f"; then
+          echo $f
+          mv /tmp/newfile "$f"
+      fi
   fi
 done
diff --git a/src/main/scala/leon/LeonOption.scala b/src/main/scala/leon/LeonOption.scala
index c9c989e23..fa5c0929f 100644
--- a/src/main/scala/leon/LeonOption.scala
+++ b/src/main/scala/leon/LeonOption.scala
@@ -60,3 +60,39 @@ object ListValue {
     }
   }
 }
+
+object OptionsHelpers {
+  // helper for options that include patterns
+
+  def matcher(patterns: Traversable[String]): String => Boolean = {
+    val regexPatterns = patterns map { s =>
+      import java.util.regex.Pattern
+
+      val p = s.replaceAll("\\.", "\\\\.").replaceAll("_", ".+")
+      Pattern.compile(p)
+    }
+
+    { (name: String) => regexPatterns.exists(p => p.matcher(name).matches()) }
+  }
+
+  import purescala.Definitions.FunDef
+
+  def fdMatcher(patterns: Traversable[String]): FunDef => Boolean = {
+    { (fd: FunDef) => fd.id.name } andThen matcher(patterns)
+  }
+
+  def filterInclusive[T](included: Option[T => Boolean], excluded: Option[T => Boolean]): T => Boolean = {
+    included match {
+      case Some(i) =>
+        i
+      case None =>
+        excluded match {
+          case Some(f) =>
+            { (t: T) => !f(t) }
+
+          case None =>
+            { (t: T) => true }
+        }
+    }
+  }
+}
diff --git a/src/main/scala/leon/Main.scala b/src/main/scala/leon/Main.scala
index 7a30d6530..f2cba94b7 100644
--- a/src/main/scala/leon/Main.scala
+++ b/src/main/scala/leon/Main.scala
@@ -187,26 +187,29 @@ object Main {
 
   def computePipeline(settings: Settings): Pipeline[List[String], Any] = {
     import purescala.Definitions.Program
+    import frontends.scalac.ExtractionPhase
+    import synthesis.SynthesisPhase
+    import termination.TerminationPhase
+    import xlang.XlangAnalysisPhase
+    import verification.AnalysisPhase
 
     val pipeBegin : Pipeline[List[String],Program] =
-      frontends.scalac.ExtractionPhase andThen
-      purescala.MethodLifting andThen
-      utils.TypingPhase andThen
-      purescala.CompleteAbstractDefinitions andThen
-      synthesis.ConvertHoles
+      ExtractionPhase andThen
+      PreprocessingPhase
 
-    val pipeProcess: Pipeline[Program, Any] =
+    val pipeProcess: Pipeline[Program, Any] = {
       if (settings.synthesis) {
-        synthesis.SynthesisPhase
+        SynthesisPhase
       } else if (settings.termination) {
-        termination.TerminationPhase
+        TerminationPhase
       } else if (settings.xlang) {
-        xlang.XlangAnalysisPhase
+        XlangAnalysisPhase
       } else if (settings.verify) {
-        verification.AnalysisPhase
+        AnalysisPhase
       } else {
         NoopPhase()
       }
+    }
 
     pipeBegin andThen
     pipeProcess
diff --git a/src/main/scala/leon/Pipeline.scala b/src/main/scala/leon/Pipeline.scala
index 82125a9af..64a618129 100644
--- a/src/main/scala/leon/Pipeline.scala
+++ b/src/main/scala/leon/Pipeline.scala
@@ -6,7 +6,11 @@ abstract class Pipeline[-F, +T] {
   self =>
 
   def andThen[G](thenn: Pipeline[T, G]): Pipeline[F, G] = new Pipeline[F,G] {
-    def run(ctx : LeonContext)(v : F) : G = thenn.run(ctx)(self.run(ctx)(v))
+    def run(ctx : LeonContext)(v : F) : G = {
+      val s = self.run(ctx)(v)
+      ctx.reporter.terminateIfError()
+      thenn.run(ctx)(s)
+    }
   }
 
   def run(ctx: LeonContext)(v: F): T
diff --git a/src/main/scala/leon/Reporter.scala b/src/main/scala/leon/Reporter.scala
index 4e4963bdb..18e93f870 100644
--- a/src/main/scala/leon/Reporter.scala
+++ b/src/main/scala/leon/Reporter.scala
@@ -147,7 +147,7 @@ class DefaultReporter(settings: Settings) extends Reporter(settings) {
               val width = Math.max(ep.col - bp.col, 1)
               ("^" * width)
             } else {
-              val width = Math.max(line.length-bp.col, 1)
+              val width = Math.max(line.length+1-bp.col, 1)
               ("^" * width)+"..."
             }
 
diff --git a/src/main/scala/leon/Settings.scala b/src/main/scala/leon/Settings.scala
index bd4910f4c..66034599f 100644
--- a/src/main/scala/leon/Settings.scala
+++ b/src/main/scala/leon/Settings.scala
@@ -22,7 +22,9 @@ object Settings {
 
   private def defaultClassPath() = {
     val scalaHome = System.getenv("SCALA_HOME")
-    val scalaCPs = if (scalaHome != "") {
+    assert(scalaHome ne null, "SCALA_HOME was not found in the environment, did you run `source setupenv.sh` ?")
+
+    if (scalaHome != "") {
       val f = new java.io.File(scalaHome+"/lib")
 
       f.listFiles().collect {
@@ -32,8 +34,6 @@ object Settings {
     } else {
       Nil
     }
-
-    scalaCPs
   }
 
   private[leon] def defaultLibFiles() = {
diff --git a/src/main/scala/leon/codegen/CodeGeneration.scala b/src/main/scala/leon/codegen/CodeGeneration.scala
index f1ff028aa..9a36ab329 100644
--- a/src/main/scala/leon/codegen/CodeGeneration.scala
+++ b/src/main/scala/leon/codegen/CodeGeneration.scala
@@ -7,6 +7,7 @@ import purescala.Common._
 import purescala.Definitions._
 import purescala.Trees._
 import purescala.TypeTrees._
+import utils._
 
 import cafebabe._
 import cafebabe.AbstractByteCodes._
@@ -414,6 +415,9 @@ trait CodeGeneration {
         ch << InvokeSpecial(ErrorClass, constructorName, "(Ljava/lang/String;)V")
         ch << ATHROW
 
+      case hole @ Hole(oracle) =>
+        mkExpr(OracleTraverser(oracle, hole.getType, program).value, ch)
+
       case choose @ Choose(_, _) =>
         val prob = synthesis.Problem.fromChoose(choose)
 
diff --git a/src/main/scala/leon/datagen/NaiveDataGen.scala b/src/main/scala/leon/datagen/NaiveDataGen.scala
index 6dc3865c9..b1727fb71 100644
--- a/src/main/scala/leon/datagen/NaiveDataGen.scala
+++ b/src/main/scala/leon/datagen/NaiveDataGen.scala
@@ -63,11 +63,16 @@ class NaiveDataGen(ctx: LeonContext, p: Program, evaluator: Evaluator, _bounds :
   private val streamCache : MutableMap[TypeTree,Stream[Expr]] = MutableMap.empty
 
   def generate(tpe : TypeTree, bounds : Map[TypeTree,Seq[Expr]] = defaultBounds) : Stream[Expr] = {
-    streamCache.getOrElse(tpe, {
-      val s = generate0(tpe, bounds)
-      streamCache(tpe) = s
-      s
-    })
+    try {
+      streamCache.getOrElse(tpe, {
+        val s = generate0(tpe, bounds)
+        streamCache(tpe) = s
+        s
+      })
+    } catch {
+      case so: StackOverflowError =>
+        Stream.empty
+    }
   }
 
   // TODO We should make sure the cache depends on the bounds (i.e. is not reused for different bounds.)
diff --git a/src/main/scala/leon/evaluators/CodeGenEvaluator.scala b/src/main/scala/leon/evaluators/CodeGenEvaluator.scala
index 158547f13..abdbec318 100644
--- a/src/main/scala/leon/evaluators/CodeGenEvaluator.scala
+++ b/src/main/scala/leon/evaluators/CodeGenEvaluator.scala
@@ -52,7 +52,7 @@ class CodeGenEvaluator(ctx : LeonContext, val unit : CompilationUnit) extends Ev
       })
     } catch {
       case t: Throwable =>
-        ctx.reporter.warning("Error while compiling expression: "+t.getMessage)
+        ctx.reporter.warning(expression.getPos, "Error while compiling expression: "+t.getMessage)
         None
     }
   }
diff --git a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
index ecad71452..92f2b579f 100644
--- a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
+++ b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
@@ -409,7 +409,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program) extends Evalu
       }
 
     case other =>
-      context.reporter.error("Error: don't know how to handle " + other + " in Evaluator.")
+      context.reporter.error(other.getPos, "Error: don't know how to handle " + other + " in Evaluator.")
       throw EvalError("Unhandled case in Evaluator : " + other) 
   }
 
diff --git a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
index d5aec11a0..97fbbc2ac 100644
--- a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
+++ b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
@@ -15,6 +15,7 @@ trait ASTExtractors {
   def classFromName(str: String) = {
     rootMirror.getClassByName(newTypeName(str))
   }
+
   def objectFromName(str: String) = {
     rootMirror.getClassByName(newTermName(str))
   }
@@ -30,12 +31,14 @@ trait ASTExtractors {
   protected lazy val arraySym           = classFromName("scala.Array")
   protected lazy val someClassSym       = classFromName("scala.Some")
   protected lazy val function1TraitSym  = classFromName("scala.Function1")
+  protected lazy val byNameSym          = classFromName("scala.<byname>")
 
   def isTuple2(sym : Symbol) : Boolean = sym == tuple2Sym
   def isTuple3(sym : Symbol) : Boolean = sym == tuple3Sym
   def isTuple4(sym : Symbol) : Boolean = sym == tuple4Sym
   def isTuple5(sym : Symbol) : Boolean = sym == tuple5Sym
 
+  def isByNameSym(sym : Symbol) : Boolean = getResolvedTypeSym(sym) == byNameSym
 
   // Resolve type aliases
   def getResolvedTypeSym(sym: Symbol): Symbol = {
@@ -89,6 +92,12 @@ trait ASTExtractors {
       def unapply(name: Name): Option[String] = Some(name.toString)
     }
 
+    object ExSymbol {
+      def unapplySeq(t: Tree): Option[Seq[String]] = {
+        Some(t.symbol.fullName.toString.split('.').toSeq)
+      }
+    }
+
     object ExSelected {
       def unapplySeq(select: Select): Option[Seq[String]] = select match {
         case Select(This(scalaName), name) =>
@@ -122,7 +131,7 @@ trait ASTExtractors {
 
     object ExHoldsExpression {
       def unapply(tree: Select) : Option[Tree] = tree match {
-        case Select(Apply(ExSelected("leon", "lang", "any2IsValid"), realExpr :: Nil), ExNamed("holds")) =>
+        case Select(Apply(ExSymbol("leon", "lang", "any2IsValid"), realExpr :: Nil), ExNamed("holds")) =>
             Some(realExpr)
         case _ => None
        }
@@ -147,7 +156,7 @@ trait ASTExtractors {
        * visibility. Does not match on the automatically generated companion
        * objects of case classes (or any synthetic class). */
       def unapply(cd: ClassDef): Option[(String,Template)] = cd match {
-        case ClassDef(_, name, tparams, impl) if (cd.symbol.isModuleClass && tparams.isEmpty && !cd.symbol.isSynthetic) => {
+        case ClassDef(_, name, tparams, impl) if ((cd.symbol.isModuleClass || cd.symbol.isPackage) && tparams.isEmpty && !cd.symbol.isSynthetic) => {
           Some((name.toString, impl))
         }
         case _ => None
@@ -174,7 +183,7 @@ trait ASTExtractors {
             case _ => false
           }).get.asInstanceOf[DefDef]
 
-          val args = constructor.vparamss(0).map(vd => (vd.name.toString, vd.tpt))
+          val args = constructor.vparamss.flatten.map(vd => (vd.name.toString, vd.tpt))
 
           Some((name.toString, cd.symbol, args, impl))
         }
@@ -201,7 +210,7 @@ trait ASTExtractors {
 
     object ExConstructorDef {
       def unapply(dd: DefDef): Boolean = dd match {
-        case DefDef(_, name, tparams, vparamss, tpt, rhs) if(name == nme.CONSTRUCTOR && tparams.isEmpty && vparamss.size == 1) => true
+        case DefDef(_, name, tparams, vparamss, tpt, rhs) if(name == nme.CONSTRUCTOR && tparams.isEmpty) => true
         case _ => false
       }
     }
@@ -219,8 +228,8 @@ trait ASTExtractors {
       /** Matches a function with a single list of arguments, no type
        * parameters and regardless of its visibility. */
       def unapply(dd: DefDef): Option[(Symbol, Seq[Symbol], Seq[ValDef], Type, Tree)] = dd match {
-        case DefDef(_, name, tparams, vparamss, tpt, rhs) if(vparamss.size <= 1 && name != nme.CONSTRUCTOR) =>
-          Some((dd.symbol, tparams.map(_.symbol), vparamss.headOption.getOrElse(Nil), tpt.tpe, rhs))
+        case DefDef(_, name, tparams, vparamss, tpt, rhs) if(name != nme.CONSTRUCTOR) =>
+          Some((dd.symbol, tparams.map(_.symbol), vparamss.flatten, tpt.tpe, rhs))
         case _ => None
       }
     }
@@ -231,48 +240,50 @@ trait ASTExtractors {
     import ExtractorHelpers._
 
     object ExEpsilonExpression {
-      def unapply(tree: Apply) : Option[(Type, Symbol, Tree)] = tree match {
+      def unapply(tree: Apply) : Option[(Tree, Symbol, Tree)] = tree match {
         case Apply(
-              TypeApply(ExSelected("leon", "lang", "epsilon"), typeTree :: Nil),
+              TypeApply(ExSymbol("leon", "lang", "xlang", "epsilon"), typeTree :: Nil),
               Function((vd @ ValDef(_, _, _, EmptyTree)) :: Nil, predicateBody) :: Nil) =>
-            Some((typeTree.tpe, vd.symbol, predicateBody))
+            Some((typeTree, vd.symbol, predicateBody))
+        case _ => None
+      }
+    }
+
+    object ExWaypointExpression {
+      def unapply(tree: Apply) : Option[(Tree, Tree, Tree)] = tree match {
+        case Apply(
+              TypeApply(ExSymbol("leon", "lang", "xlang", "waypoint"), typeTree :: Nil),
+              List(i, expr)) =>
+            Some((typeTree, i, expr))
         case _ => None
       }
     }
 
     object ExErrorExpression {
-      def unapply(tree: Apply) : Option[(String, Type)] = tree match {
-        case a @ Apply(TypeApply(ExSelected("leon", "lang", "error"), List(tpe)), List(lit : Literal)) =>
-          Some((lit.value.stringValue, tpe.tpe))
+      def unapply(tree: Apply) : Option[(String, Tree)] = tree match {
+        case a @ Apply(TypeApply(ExSymbol("leon", "lang", "error"), List(tpe)), List(lit : Literal)) =>
+          Some((lit.value.stringValue, tpe))
         case _ =>
           None
       }
     }
 
-    object ExHole {
-      def unapply(tree: TypeApply) : Option[Type] = tree match {
-        case a @ TypeApply(s @ ExSelected("leon", "lang", _), List(tpe)) if s.symbol.name.decoded == "???"  =>
-            Some(a.tpe)
+    object ExHoleExpression {
+      def unapply(tree: Tree) : Option[(Tree, List[Tree], List[Tree])] = tree match {
+        case a @ Apply(Apply(TypeApply(s @ ExSymbol("leon", "lang", "synthesis", "$qmark"), List(tpt)), args1), args2)  =>
+            Some((tpt, args1, args2))
+        case a @ Apply(TypeApply(s @ ExSymbol("leon", "lang", "synthesis", "$qmark$qmark$qmark"), List(tpt)), List(o)) =>
+            Some((tpt, Nil, List(o)))
         case _ => None
       }
     }
 
     object ExChooseExpression {
-      def unapply(tree: Apply) : Option[(List[(Type, Symbol)], Type, Tree, Tree)] = tree match {
+      def unapply(tree: Apply) : Option[(List[(Tree, Symbol)], Tree, Tree, Tree)] = tree match {
         case a @ Apply(
-              TypeApply(s @ ExSelected("leon", "lang", "choose"), types),
+              TypeApply(s @ ExSymbol("leon", "lang", "synthesis", "choose"), types),
               Function(vds, predicateBody) :: Nil) =>
-            Some(((types.map(_.tpe) zip vds.map(_.symbol)).toList, a.tpe, predicateBody, s))
-        case _ => None
-      }
-    }
-
-    object ExWaypointExpression {
-      def unapply(tree: Apply) : Option[(Type, Tree, Tree)] = tree match {
-        case Apply(
-              TypeApply(ExSelected("leon", "lang", "waypoint"), typeTree :: Nil),
-              List(i, expr)) =>
-            Some((typeTree.tpe, i, expr))
+            Some(((types zip vds.map(_.symbol)).toList, a, predicateBody, s))
         case _ => None
       }
     }
@@ -681,29 +692,44 @@ trait ASTExtractors {
       }
     }
 
-    object ExCall { 
-      def unapply(tree: Tree): Option[(Tree, Symbol, Seq[Tree], Seq[Tree])] = tree match {
+    object ExParameterLessCall {
+      def unapply(tree: Tree): Option[(Tree, Symbol, Seq[Tree])] = tree match {
         case s @ Select(t, _) =>
-          Some((t, s.symbol, Nil, Nil))
-
-        case TypeApply(s @ Select(t, _), tps) => 
-          Some((t, s.symbol, tps, Nil))
+          Some((t, s.symbol, Nil))
 
-        case TypeApply(i: Ident, tps) => 
-          Some((i, i.symbol, tps, Nil))
+        case TypeApply(s @ Select(t, _), tps) =>
+          Some((t, s.symbol, tps))
 
-        case Apply(TypeApply(s @ Select(t, _), tps), args) => 
-          Some((t, s.symbol, tps, args))
+        case TypeApply(i: Ident, tps) =>
+          Some((i, i.symbol, tps))
 
-        case Apply(TypeApply(i: Ident, tps), args) => 
-          Some((i, i.symbol, tps, args))
+        case _ =>
+          None
+      }
+    }
 
-        case Apply(s @ Select(t, _), args) => 
-          Some((t, s.symbol, Nil, args))
+    object ExCall { 
+      def unapply(tree: Tree): Option[(Tree, Symbol, Seq[Tree], Seq[Tree])] = tree match {
+        // foo / foo[T]
+        case ExParameterLessCall(t, s, tps) =>
+          Some((t, s, tps, Nil))
 
-        case Apply(i: Ident, args) => 
+        // foo(args)
+        case Apply(i: Ident, args) =>
           Some((i, i.symbol, Nil, args))
 
+        // foo(args1)(args2)
+        case Apply(Apply(i: Ident, args1), args2) =>
+          Some((i, i.symbol, Nil, args1 ++ args2))
+
+        // foo[T](args)
+        case Apply(ExParameterLessCall(t, s, tps), args) =>
+          Some((t, s, tps, args))
+
+        // foo[T](args1)(args2)
+        case Apply(Apply(ExParameterLessCall(t, s, tps), args1), args2) =>
+          Some((t, s, tps, args1 ++ args2))
+
         case _ => None
       }
     }
diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
index 720aef319..95912df29 100644
--- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
+++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
@@ -32,9 +32,11 @@ trait CodeExtraction extends ASTExtractors {
   import ExtractorHelpers._
   import scala.collection.immutable.Set
 
+  val reporter = self.ctx.reporter
+
   def annotationsOf(s: Symbol): Set[String] = {
-    (for(a <- s.annotations) yield {
-      val name = a.atp.safeToString
+    (for(a <- s.annotations ++ s.owner.annotations) yield {
+      val name = a.atp.safeToString.replaceAll("\\.package\\.", ".")
       if (name startsWith "leon.annotation.") {
         Some(name.split("\\.", 3)(2))
       } else {
@@ -58,10 +60,13 @@ trait CodeExtraction extends ASTExtractors {
     }
   }
 
-  def leonPosToScalaPos(sf: SourceFile, p: LeonPosition): global.Position = {
-    p match {
-      case dp: DefinedPosition =>
-        new OffsetPosition(sf, dp.focusBegin.point)
+  def leonPosToScalaPos(spos: global.Position, p: LeonPosition): global.Position = {
+    (spos, p) match {
+      case (NoPosition, _) =>
+        NoPosition
+
+      case (p, dp: DefinedPosition) =>
+        new OffsetPosition(p.source, dp.focusBegin.point)
 
       case _ =>
         NoPosition
@@ -117,7 +122,7 @@ trait CodeExtraction extends ASTExtractors {
     }
 
     // This one never fails, on error, it returns Untyped
-    def toPureScalaType(tpt: Type)(implicit dctx: DefContext): LeonType = {
+    def toPureScalaType(tpt: Type)(implicit dctx: DefContext, pos: Position): LeonType = {
       try {
         extractType(tpt)
       } catch {
@@ -156,6 +161,14 @@ trait CodeExtraction extends ASTExtractors {
       }
     }
 
+    def isIgnored(s: Symbol) = {
+      (annotationsOf(s) contains "ignore") || (s.fullName.toString.endsWith(".main"))
+    }
+
+    def isProxy(s: Symbol) = {
+      annotationsOf(s) contains "proxy"
+    }
+
     def extractModules: List[LeonModuleDef] = {
       try {
         val templates: List[(String, List[Tree])] = units.reverse.flatMap { u => u.body match {
@@ -163,9 +176,12 @@ trait CodeExtraction extends ASTExtractors {
             var standaloneDefs = List[Tree]()
 
             val modules: List[(String, List[Tree])] = lst.flatMap { _ match {
-              case od @ ExObjectDef(_, _) if annotationsOf(od.symbol) contains "ignore" =>
+              case t if isIgnored(t.symbol) =>
                 None
 
+              case PackageDef(_, List(ExObjectDef(n, templ))) =>
+                Some((n.toString, templ.body))
+
               case ExObjectDef(n, templ) =>
                 Some((n.toString, templ.body))
 
@@ -222,9 +238,19 @@ trait CodeExtraction extends ASTExtractors {
     private var seenClasses = Map[Symbol, (Seq[(String, Tree)], Template)]()
     private var classesToClasses  = Map[Symbol, LeonClassDef]()
 
+
+    def libraryMethod(classname: String, methodName: String): Option[(LeonClassDef, FunDef)] = {
+      classesToClasses.values.find(_.id.name == classname).flatMap { cl =>
+        cl.methods.find(_.id.name == methodName).map { fd => (cl, fd) }
+      }
+    }
+
     private def collectClassSymbols(defs: List[Tree]) {
       // We collect all defined classes
       for (t <- defs) t match {
+        case t if isIgnored(t.symbol) =>
+          // ignore
+
         case ExAbstractClass(o2, sym, tmpl) =>
           seenClasses += sym -> ((Nil, tmpl))
 
@@ -238,11 +264,14 @@ trait CodeExtraction extends ASTExtractors {
     private def extractClassDefs(defs: List[Tree]) {
       // We collect all defined classes
       for (t <- defs) t match {
+        case t if isIgnored(t.symbol) =>
+          // ignore
+
         case ExAbstractClass(o2, sym, _) =>
-          getClassDef(sym, NoPosition)
+          getClassDef(sym, t.pos)
 
         case ExCaseClass(o2, sym, args, _) =>
-          getClassDef(sym, NoPosition)
+          getClassDef(sym, t.pos)
 
         case _ =>
       }
@@ -257,6 +286,9 @@ trait CodeExtraction extends ASTExtractors {
 
             extractClassDef(sym, args, tmpl)
           } else {
+            if (sym.name.toString == "synthesis") {
+              new Exception().printStackTrace()
+            }
             outOfSubsetError(pos, "Class "+sym.name+" not defined?")
           }
       }
@@ -292,7 +324,7 @@ trait CodeExtraction extends ASTExtractors {
         case Some(TypeRef(_, parentSym, tps)) if seenClasses contains parentSym =>
           getClassDef(parentSym, sym.pos) match {
             case acd: AbstractClassDef =>
-              val newTps = tps.map(extractType(_)(defCtx))
+              val newTps = tps.map(extractType(_)(defCtx, sym.pos))
               Some(AbstractClassType(acd, newTps))
 
             case cd =>
@@ -318,7 +350,7 @@ trait CodeExtraction extends ASTExtractors {
         classesToClasses += sym -> ccd
 
         val fields = args.map { case (name, t) =>
-          val tpe = toPureScalaType(t.tpe)(defCtx)
+          val tpe = toPureScalaType(t.tpe)(defCtx, sym.pos)
           LeonValDef(FreshIdentifier(name).setType(tpe).setPos(t.pos), tpe).setPos(t.pos)
         }
 
@@ -349,6 +381,9 @@ trait CodeExtraction extends ASTExtractors {
 
       // We collect the methods
       for (d <- tmpl.body) d match {
+        case t if isIgnored(t.symbol) =>
+          //ignore
+
         case t @ ExFunctionDef(fsym, _, _, _, _) if !fsym.isSynthetic && !fsym.isAccessor =>
           if (parent.isDefined) {
             outOfSubsetError(t, "Only hierarchy roots can define methods")
@@ -372,12 +407,10 @@ trait CodeExtraction extends ASTExtractors {
       // Type params of the function itself
       val tparams = extractTypeParams(sym.typeParams.map(_.tpe))
 
-      val isProxy = annotationsOf(sym) contains "proxy"
-
-      val nctx = dctx.copy(tparams = dctx.tparams ++ tparams.toMap, isProxy = isProxy)
+      val nctx = dctx.copy(tparams = dctx.tparams ++ tparams.toMap, isProxy = isProxy(sym))
 
       val newParams = sym.info.paramss.flatten.map{ sym =>
-        val ptpe = toPureScalaType(sym.tpe)(nctx)
+        val ptpe = toPureScalaType(sym.tpe)(nctx, sym.pos)
         val newID = FreshIdentifier(sym.name.toString).setType(ptpe).setPos(sym.pos)
         owners += (newID -> None)
         LeonValDef(newID, ptpe).setPos(sym.pos)
@@ -385,7 +418,7 @@ trait CodeExtraction extends ASTExtractors {
 
       val tparamsDef = tparams.map(t => TypeParameterDef(t._2))
 
-      val returnType = toPureScalaType(sym.info.finalResultType)(nctx)
+      val returnType = toPureScalaType(sym.info.finalResultType)(nctx, sym.pos)
 
       val name = sym.name.toString
 
@@ -403,8 +436,8 @@ trait CodeExtraction extends ASTExtractors {
     private def collectFunSigs(defs: List[Tree]) = {
       // We collect defined function bodies
       for (d <- defs) d match {
-        case ExMainFunctionDef() =>
-          // Ignoring...
+        case t if isIgnored(t.symbol) =>
+          //ignore
 
         case ExFunctionDef(sym, _, _, _, _) =>
           defineFunDef(sym)(DefContext())
@@ -442,6 +475,9 @@ trait CodeExtraction extends ASTExtractors {
         }
       }
       for (d <- defs) d match {
+        case t if isIgnored(t.symbol) =>
+          // ignore
+
         case ExAbstractClass(_, csym, tmpl) =>
           extractFromClass(csym, tmpl)
 
@@ -455,15 +491,15 @@ trait CodeExtraction extends ASTExtractors {
     private def extractFunDefs(defs: List[Tree]) = {
       // We collect defined function bodies
       for (d <- defs) d match {
-        case ExMainFunctionDef() =>
-          // Ignoring...
+        case t if isIgnored(t.symbol) =>
+          // ignore
 
         case ExFunctionDef(sym, tparams, params, _, body) =>
           val fd = defsToDefs(sym)
 
           val tparamsMap = (tparams zip fd.tparams.map(_.tp)).toMap
 
-          extractFunBody(fd, params, body)(DefContext(tparamsMap))
+          extractFunBody(fd, params, body)(DefContext(tparamsMap, isProxy = isProxy(sym)))
 
         case _ =>
       }
@@ -482,16 +518,15 @@ trait CodeExtraction extends ASTExtractors {
     private def extractObjectDef(nameStr: String, defs: List[Tree]): LeonModuleDef = {
 
       val newDefs = defs.flatMap{ t => t match {
+        case t if isIgnored(t.symbol) =>
+          None
+
         case ExAbstractClass(o2, sym, _) =>
           Some(classesToClasses(sym))
 
         case ExCaseClass(o2, sym, args, _) =>
           Some(classesToClasses(sym))
 
-        case ExMainFunctionDef() =>
-          // Ignoring...
-          None
-
         case ExFunctionDef(sym, tparams, params, _, body) =>
           Some(defsToDefs(sym))
 
@@ -505,9 +540,8 @@ trait CodeExtraction extends ASTExtractors {
         case ExAbstractClass(_,_,_) =>
         case ExCaseClass(_,_,_,_) =>
         case ExConstructorDef() =>
-        case ExMainFunctionDef() =>
         case ExFunctionDef(_, _, _, _, _) =>
-        case defn if annotationsOf(defn.symbol) contains "ignore" =>
+        case d if isIgnored(d.symbol) =>
         case tree =>
           outOfSubsetError(tree, "Don't know what to do with this. Not purescala?");
       }
@@ -568,15 +602,14 @@ trait CodeExtraction extends ASTExtractors {
         })
       } catch {
         case e: ImpureCodeEncounteredException =>
-        if (funDef.annotations contains "proxy") {
+        if (dctx.isProxy) {
           // We actually expect errors, no point reporting
         } else {
           e.emit()
-          val pos = if (body.pos == NoPosition) NoPosition else leonPosToScalaPos(body.pos.source, funDef.getPos)
           if (ctx.settings.strictCompilation) {
-            reporter.error(pos, "Function "+funDef.id.name+" could not be extracted. (Forgot @proxy ?)")
+            reporter.error(funDef.getPos, "Function "+funDef.id.name+" could not be extracted. (Forgot @proxy ?)")
           } else {
-            reporter.warning(pos, "Function "+funDef.id.name+" is not fully unavailable to Leon.")
+            reporter.warning(funDef.getPos, "Function "+funDef.id.name+" is not fully unavailable to Leon.")
           }
         }
 
@@ -609,18 +642,18 @@ trait CodeExtraction extends ASTExtractors {
     }
 
     private def extractPattern(p: Tree, binder: Option[Identifier] = None)(implicit dctx: DefContext): (Pattern, DefContext) = p match {
-      case b @ Bind(name, t @ Typed(pat, tpe)) =>
-        val newID = FreshIdentifier(name.toString).setType(extractType(tpe.tpe)).setPos(b.pos)
+      case b @ Bind(name, t @ Typed(pat, tpt)) =>
+        val newID = FreshIdentifier(name.toString).setType(extractType(tpt)).setPos(b.pos)
         val pctx = dctx.withNewVar(b.symbol -> (() => Variable(newID)))
         extractPattern(t, Some(newID))(pctx)
 
       case b @ Bind(name, pat) =>
-        val newID = FreshIdentifier(name.toString).setType(extractType(b.symbol.tpe)).setPos(b.pos)
+        val newID = FreshIdentifier(name.toString).setType(extractType(b)).setPos(b.pos)
         val pctx = dctx.withNewVar(b.symbol -> (() => Variable(newID)))
         extractPattern(pat, Some(newID))(pctx)
 
       case t @ Typed(Ident(nme.WILDCARD), tpt) =>
-        extractType(tpt.tpe) match {
+        extractType(tpt) match {
           case ct: ClassType =>
             (InstanceOfPattern(binder, ct).setPos(p.pos), dctx)
 
@@ -633,7 +666,7 @@ trait CodeExtraction extends ASTExtractors {
 
       case s @ Select(_, b) if s.tpe.typeSymbol.isCase  =>
         // case Obj =>
-        extractType(s.tpe) match {
+        extractType(s) match {
           case ct: CaseClassType =>
             assert(ct.classDef.fields.size == 0)
             (CaseClassPattern(binder, ct, Seq()).setPos(p.pos), dctx)
@@ -643,7 +676,7 @@ trait CodeExtraction extends ASTExtractors {
 
       case a @ Apply(fn, args) =>
 
-        extractType(a.tpe) match {
+        extractType(a) match {
           case ct: CaseClassType =>
             assert(args.size == ct.classDef.fields.size)
             val (subPatterns, subDctx) = args.map(extractPattern(_)).unzip
@@ -698,7 +731,7 @@ trait CodeExtraction extends ASTExtractors {
 
       val res = current match {
         case ExArrayLiteral(tpe, args) =>
-          FiniteArray(args.map(extractTree)).setType(ArrayType(extractType(tpe)))
+          FiniteArray(args.map(extractTree)).setType(ArrayType(extractType(tpe)(dctx, current.pos)))
 
         case ExCaseObject(sym) =>
           getClassDef(sym, current.pos) match {
@@ -713,8 +746,8 @@ trait CodeExtraction extends ASTExtractors {
           val tupleType = TupleType(tupleExprs.map(expr => expr.getType))
           Tuple(tupleExprs)
 
-        case ExErrorExpression(str, tpe) =>
-          Error(str).setType(extractType(tpe))
+        case ExErrorExpression(str, tpt) =>
+          Error(str).setType(extractType(tpt))
 
         case ExTupleExtract(tuple, index) =>
           val tupleExpr = extractTree(tuple)
@@ -728,7 +761,7 @@ trait CodeExtraction extends ASTExtractors {
           }
 
         case ExValDef(vs, tpt, bdy) =>
-          val binderTpe = extractType(tpt.tpe)
+          val binderTpe = extractType(tpt)
           val newID = FreshIdentifier(vs.name.toString).setType(binderTpe)
           val valTree = extractTree(bdy)
 
@@ -760,7 +793,7 @@ trait CodeExtraction extends ASTExtractors {
 
           fd.addAnnotation(annotationsOf(d.symbol).toSeq : _*)
 
-          val newDctx = dctx.copy(tparams = dctx.tparams ++ tparamsMap)
+          val newDctx = dctx.copy(tparams = dctx.tparams ++ tparamsMap, isProxy = isProxy(sym))
 
           val oldCurrentFunDef = currentFunDef
 
@@ -780,7 +813,7 @@ trait CodeExtraction extends ASTExtractors {
          */
 
         case ExVarDef(vs, tpt, bdy) => {
-          val binderTpe = extractType(tpt.tpe)
+          val binderTpe = extractType(tpt)
           val newID = FreshIdentifier(vs.name.toString).setType(binderTpe)
           val valTree = extractTree(bdy)
 
@@ -834,8 +867,8 @@ trait CodeExtraction extends ASTExtractors {
           w.invariant = Some(invTree)
           w
 
-        case epsi @ ExEpsilonExpression(tpe, varSym, predBody) =>
-          val pstpe = extractType(tpe)
+        case epsi @ ExEpsilonExpression(tpt, varSym, predBody) =>
+          val pstpe = extractType(tpt)
           val nctx = dctx.withNewVar(varSym -> (() => EpsilonVariable(epsi.pos).setType(pstpe)))
           val c1 = extractTree(predBody)(nctx)
           if(containsEpsilon(c1)) {
@@ -843,8 +876,8 @@ trait CodeExtraction extends ASTExtractors {
           }
           Epsilon(c1).setType(pstpe)
 
-        case ExWaypointExpression(tpe, i, tree) =>
-          val pstpe = extractType(tpe)
+        case ExWaypointExpression(tpt, i, tree) =>
+          val pstpe = extractType(tpt)
           val IntLiteral(ri) = extractTree(i)
           Waypoint(ri, extractTree(tree)).setType(pstpe)
 
@@ -896,15 +929,39 @@ trait CodeExtraction extends ASTExtractors {
               outOfSubsetError(tr, "Unidentified variable "+sym+" "+sym.id+".")
           }
 
-        case chs @ ExHole(tpe) =>
-          val cTpe  = extractType(tpe)
-          Hole().setType(cTpe).setPos(chs.pos)
+        case hole @ ExHoleExpression(tpt, exprs, os) =>
+          val leonTpe = extractType(tpt)
+          val leonExprs = exprs.map(extractTree)
+          val leonOracles = os.map(extractTree)
+
+          leonExprs match {
+            case Nil =>
+              Hole(leonOracles(0)).setType(leonTpe)
+
+            case List(e) =>
+              IfExpr(Hole(leonOracles(0)).setType(BooleanType), e, Hole(leonOracles(1)).setType(leonTpe))
+
+            case exs =>
+              val l = exs.last
+              var o = leonOracles(0)
+
+              def rightOf(o: LeonExpr): LeonExpr = {
+                val Some((cl, fd)) = libraryMethod("Oracle", "right")
+                MethodInvocation(o, cl, fd.typed(Nil), Nil)
+              }
+
+              exs.init.foldRight(l)({ (e: LeonExpr, r: LeonExpr) =>
+                val res = IfExpr(Hole(o).setType(BooleanType), e, r)
+                o = rightOf(o)
+                res
+              })
+          }
 
-        case chs @ ExChooseExpression(args, tpe, body, select) =>
-          val cTpe  = extractType(tpe)
+        case chs @ ExChooseExpression(args, tpt, body, select) =>
+          val cTpe  = extractType(tpt)
 
-          val vars = args map { case (tpe, sym) =>
-            val aTpe  = extractType(tpe)
+          val vars = args map { case (tpt, sym) =>
+            val aTpe  = extractType(tpt)
             val newID = FreshIdentifier(sym.name.toString).setType(aTpe)
             owners += (newID -> None)
             newID
@@ -920,7 +977,7 @@ trait CodeExtraction extends ASTExtractors {
           Choose(vars, cBody)
 
         case ExCaseClassConstruction(tpt, args) =>
-          extractType(tpt.tpe) match {
+          extractType(tpt) match {
             case cct: CaseClassType =>
               val nargs = args.map(extractTree(_))
               CaseClass(cct, nargs)
@@ -963,31 +1020,31 @@ trait CodeExtraction extends ASTExtractors {
           }
 
         case ExFiniteSet(tt, args)  =>
-          val underlying = extractType(tt.tpe)
+          val underlying = extractType(tt)
           FiniteSet(args.map(extractTree(_))).setType(SetType(underlying))
 
         case ExFiniteMultiset(tt, args) =>
-          val underlying = extractType(tt.tpe)
+          val underlying = extractType(tt)
           FiniteMultiset(args.map(extractTree(_))).setType(MultisetType(underlying))
 
         case ExEmptySet(tt) =>
-          val underlying = extractType(tt.tpe)
+          val underlying = extractType(tt)
           FiniteSet(Seq()).setType(SetType(underlying))
 
         case ExEmptyMultiset(tt) =>
-          val underlying = extractType(tt.tpe)
+          val underlying = extractType(tt)
           EmptyMultiset(underlying).setType(MultisetType(underlying))
 
         case ExEmptyMap(ft, tt) =>
-          val fromUnderlying = extractType(ft.tpe)
-          val toUnderlying   = extractType(tt.tpe)
+          val fromUnderlying = extractType(ft)
+          val toUnderlying   = extractType(tt)
           val tpe = MapType(fromUnderlying, toUnderlying)
 
           FiniteMap(Seq()).setType(tpe)
 
         case ExLiteralMap(ft, tt, elems) =>
-          val fromUnderlying = extractType(ft.tpe)
-          val toUnderlying   = extractType(tt.tpe)
+          val fromUnderlying = extractType(ft)
+          val toUnderlying   = extractType(tt)
           val tpe = MapType(fromUnderlying, toUnderlying)
 
           val singletons: Seq[(LeonExpr, LeonExpr)] = elems.collect {
@@ -1002,7 +1059,7 @@ trait CodeExtraction extends ASTExtractors {
           FiniteMap(singletons).setType(tpe)
 
         case ExArrayFill(baseType, length, defaultValue) =>
-          val underlying = extractType(baseType.tpe)
+          val underlying = extractType(baseType)
           val lengthRec = extractTree(length)
           val defaultValueRec = extractTree(defaultValue)
           ArrayFill(lengthRec, defaultValueRec).setType(ArrayType(underlying))
@@ -1025,7 +1082,7 @@ trait CodeExtraction extends ASTExtractors {
 
         case ExIsInstanceOf(tt, cc) => {
           val ccRec = extractTree(cc)
-          val checkType = extractType(tt.tpe)
+          val checkType = extractType(tt)
           checkType match {
             case cct @ CaseClassType(ccd, tps) => {
               val rootType: LeonClassDef  = if(ccd.parent != None) ccd.parent.get.classDef else ccd
@@ -1057,7 +1114,7 @@ trait CodeExtraction extends ASTExtractors {
           MatchExpr(rs, rc).setType(rt)
 
         case t: This =>
-          extractType(t.tpe) match {
+          extractType(t) match {
             case ct: ClassType =>
               LeonThis(ct)
             case _ =>
@@ -1085,7 +1142,7 @@ trait CodeExtraction extends ASTExtractors {
             case (null, _, args) =>
               val fd = getFunDef(sym, c.pos)
 
-              val newTps = tps.map(t => extractType(t.tpe))
+              val newTps = tps.map(t => extractType(t))
 
               FunctionInvocation(fd.typed(newTps), args).setType(fd.returnType)
 
@@ -1093,7 +1150,7 @@ trait CodeExtraction extends ASTExtractors {
               val fd = getFunDef(sym, c.pos)
               val cd = methodToClass(fd)
 
-              val newTps = tps.map(t => extractType(t.tpe))
+              val newTps = tps.map(t => extractType(t))
 
               MethodInvocation(rec, cd, fd.typed(newTps), args)
 
@@ -1188,7 +1245,11 @@ trait CodeExtraction extends ASTExtractors {
       }
     }
 
-    private def extractType(tpt: Type)(implicit dctx: DefContext): LeonType = tpt match {
+    private def extractType(t: Tree)(implicit dctx: DefContext): LeonType = {
+      extractType(t.tpe)(dctx, t.pos)
+    }
+
+    private def extractType(tpt: Type)(implicit dctx: DefContext, pos: Position): LeonType = tpt match {
       case tpe if tpe == IntClass.tpe =>
         Int32Type
 
@@ -1225,6 +1286,9 @@ trait CodeExtraction extends ASTExtractors {
       case TypeRef(_, sym, btt :: Nil) if isArrayClassSym(sym) =>
         ArrayType(extractType(btt))
 
+      case TypeRef(_, sym, tps) if isByNameSym(sym) =>
+        extractType(tps.head)
+
       case TypeRef(_, sym, tps) =>
         val leontps = tps.map(extractType)
 
@@ -1232,19 +1296,43 @@ trait CodeExtraction extends ASTExtractors {
           if(dctx.tparams contains sym) {
             dctx.tparams(sym)
           } else {
-            outOfSubsetError(NoPosition, "Unknown type parameter "+sym)
+            outOfSubsetError(pos, "Unknown type parameter "+sym)
           }
         } else {
           getClassType(sym, leontps)
         }
 
       case tt: ThisType =>
-        val cd = getClassDef(tt.sym, NoPosition)
+        val cd = getClassDef(tt.sym, pos)
         classDefToClassType(cd, cd.tparams.map(_.tp)) // Typed using own's type parameters
 
       case SingleType(_, sym) =>
         getClassType(sym.moduleClass, Nil)
 
+      case RefinedType(parents, defs) if defs.isEmpty =>
+        /**
+         * For cases like if(a) e1 else e2 where 
+         *   e1 <: C1,
+         *   e2 <: C2,
+         *   with C1,C2 <: C
+         * 
+         * Scala might infer a type for C such as: Product with Serializable with C
+         * we generalize to the first known type, e.g. C.
+         */
+        parents.flatMap { ptpe =>
+          try {
+            Some(extractType(ptpe))
+          } catch {
+            case e: ImpureCodeEncounteredException =>
+              None
+        }}.headOption match {
+          case Some(tpe) =>
+            tpe
+
+          case None =>
+            outOfSubsetError(tpt.typeSymbol.pos, "Could not extract refined type as PureScala: "+tpt+" ("+tpt.getClass+")")
+        }
+
       case _ =>
         outOfSubsetError(tpt.typeSymbol.pos, "Could not extract type as PureScala: "+tpt+" ("+tpt.getClass+")")
     }
diff --git a/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala b/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala
index cb771c9d2..f538a0d92 100644
--- a/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala
+++ b/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala
@@ -22,6 +22,7 @@ object ExtractionPhase extends LeonPhase[List[String], Program] {
     val settings = new NSCSettings
 
     settings.classpath.value = ctx.settings.classPath.mkString(":")
+    settings.usejavacp.value = false
     settings.skip.value      = List("patmat")
 
     val libFiles = Settings.defaultLibFiles()
@@ -50,22 +51,10 @@ object ExtractionPhase extends LeonPhase[List[String], Program] {
       val run = new compiler.Run
       run.compile(command.files)
 
-      (compiler.leonExtraction.units, compiler.leonExtraction.modules) match {
-        case (Nil, Nil) =>
-          ctx.reporter.fatalError("Error while compiling. Empty input?")
-
-        case (_, Nil) =>
-          ctx.reporter.fatalError("Error while compiling.")
-
-        case (_, modules) =>
-          if (ctx.reporter.errorCount > 0 && ctx.settings.strictCompilation) {
-            ctx.reporter.fatalError("Error while compiling.")
-          } else {
-            val pgm = Program(FreshIdentifier("<program>"), modules)
-            ctx.reporter.debug(pgm.asString(ctx))
-            pgm
-          }
-      }
+
+      val pgm = Program(FreshIdentifier("<program>"), compiler.leonExtraction.modules)
+      ctx.reporter.debug(pgm.asString(ctx))
+      pgm
     } else {
       ctx.reporter.fatalError("No input program.")
     }
diff --git a/src/main/scala/leon/purescala/Definitions.scala b/src/main/scala/leon/purescala/Definitions.scala
index a82ff2446..ac99c1146 100644
--- a/src/main/scala/leon/purescala/Definitions.scala
+++ b/src/main/scala/leon/purescala/Definitions.scala
@@ -130,7 +130,7 @@ object Definitions {
       knownChildren ++ (knownChildren.map(c => c match {
         case acd: AbstractClassDef => acd.knownDescendents
         case _ => Nil
-      }).reduceLeft(_ ++ _))
+      }).foldLeft(List[ClassDef]())(_ ++ _))
     }
 
     def knownCCDescendents: Seq[CaseClassDef] = knownDescendents.collect {
diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala
index b04aa62fc..c8a1f666b 100644
--- a/src/main/scala/leon/purescala/PrettyPrinter.scala
+++ b/src/main/scala/leon/purescala/PrettyPrinter.scala
@@ -126,10 +126,12 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe
         pp(t, p)
         sb.append("._" + i)
 
-      case h @ Hole() =>
+      case h @ Hole(o) =>
         sb.append("???[")
         pp(h.getType, p)
-        sb.append("]")
+        sb.append("](")
+        pp(o, p)
+        sb.append(")")
 
       case c@Choose(vars, pred) =>
         sb.append("choose(")
@@ -329,7 +331,7 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe
         sb.append(")")
 
       case WildcardPattern(None)     => sb.append("_")
-      case WildcardPattern(Some(id)) => pp(id, p)
+      case WildcardPattern(Some(id)) => pp(id.toVariable, p)
       case InstanceOfPattern(bndr, cct) =>
         bndr.foreach(b => sb.append(b + " : "))
         pp(cct, p)
diff --git a/src/main/scala/leon/purescala/SimplifierWithPaths.scala b/src/main/scala/leon/purescala/SimplifierWithPaths.scala
index 70cc667a4..406e4c46b 100644
--- a/src/main/scala/leon/purescala/SimplifierWithPaths.scala
+++ b/src/main/scala/leon/purescala/SimplifierWithPaths.scala
@@ -69,7 +69,7 @@ class SimplifierWithPaths(sf: SolverFactory[Solver]) extends TransformerWithPC {
         // unsupported for now
         e
       } else {
-        MatchExpr(rs, cases.flatMap { c =>
+        val newCases = cases.flatMap { c =>
           val patternExpr = conditionForPattern(rs, c.pattern, includeBinders = true)
 
           if (stillPossible && !contradictedBy(patternExpr, path)) {
@@ -87,7 +87,12 @@ class SimplifierWithPaths(sf: SolverFactory[Solver]) extends TransformerWithPC {
           } else {
             None
           }
-        }).copiedFrom(e)
+        }
+        if (newCases.nonEmpty) {
+          MatchExpr(rs, newCases).copiedFrom(e)
+        } else {
+          Error("Unreachable code").copiedFrom(e)
+        }
       }
 
     case Or(es) =>
diff --git a/src/main/scala/leon/purescala/TreeOps.scala b/src/main/scala/leon/purescala/TreeOps.scala
index 5a8eb3913..e68f47a48 100644
--- a/src/main/scala/leon/purescala/TreeOps.scala
+++ b/src/main/scala/leon/purescala/TreeOps.scala
@@ -371,6 +371,58 @@ object TreeOps {
     })(expr)
   }
 
+  def normalizeExpression(expr: Expr) : Expr = {
+    def rec(e: Expr): Option[Expr] = e match {
+      case TupleSelect(Let(id, v, b), ts) =>
+        Some(Let(id, v, TupleSelect(b, ts)))
+
+      case TupleSelect(LetTuple(ids, v, b), ts) =>
+        Some(LetTuple(ids, v, TupleSelect(b, ts)))
+
+      case IfExpr(c, thenn, elze) if (thenn == elze) =>
+        Some(thenn)
+
+      case IfExpr(c, BooleanLiteral(true), BooleanLiteral(false)) =>
+        Some(c)
+
+      case IfExpr(Not(c), thenn, elze) =>
+        Some(IfExpr(c, elze, thenn).copiedFrom(e))
+
+      case IfExpr(c, BooleanLiteral(false), BooleanLiteral(true)) =>
+        Some(Not(c))
+
+      case FunctionInvocation(tfd, List(IfExpr(c, thenn, elze))) =>
+        Some(IfExpr(c, FunctionInvocation(tfd, List(thenn)), FunctionInvocation(tfd, List(elze))))
+
+      case _ =>
+        None
+    }
+
+    fixpoint(postMap(rec))(expr)
+  }
+
+
+  def evalGround(ctx: LeonContext, program: Program): Expr => Expr = {
+    import evaluators._
+
+    val eval = new DefaultEvaluator(ctx, program)
+
+    def isGround(e: Expr): Boolean = {
+      variablesOf(e).isEmpty  && !usesHoles(e) && !containsChoose(e)
+    }
+
+    def rec(e: Expr): Option[Expr] = e match {
+      case l: Terminal => None
+      case e if isGround(e) => eval.eval(e) match {
+        case EvaluationResults.Successful(v) => Some(v)
+        case _ => None
+      }
+      case _ => None
+    }
+
+    preMap(rec)
+  }
+
   /**
    * Simplifies let expressions:
    *  - removes lets when expression never occurs
@@ -922,12 +974,12 @@ object TreeOps {
             substMap += prefix -> Variable(binder)
             substMap += CaseClassInstanceOf(ct, prefix) -> BooleanLiteral(true)
 
-            val subconds = for (id <- ct.classDef.fieldsIds) yield {
-              val fieldSel = CaseClassSelector(ct, prefix, id)
+            val subconds = for (f <- ct.fields) yield {
+              val fieldSel = CaseClassSelector(ct, prefix, f.id)
               if (conditions contains fieldSel) {
                 computePatternFor(conditions(fieldSel), fieldSel)
               } else {
-                val b = FreshIdentifier(id.name, true).setType(id.getType)
+                val b = FreshIdentifier(f.id.name, true).setType(f.tpe)
                 substMap += fieldSel -> Variable(b)
                 WildcardPattern(Some(b))
               }
@@ -1156,10 +1208,9 @@ object TreeOps {
       case ft : FunctionType => None // FIXME
 
       case a : AbstractClassType => None
-      case c : CaseClassType     =>
+      case cct : CaseClassType     =>
         // This is really just one big assertion. We don't rewrite class defs.
-        val ccd = c.classDef
-        val fieldTypes = ccd.fields.map(_.tpe)
+        val fieldTypes = cct.fields.map(_.tpe)
         if(fieldTypes.exists(t => t match {
           case TupleType(ts) if ts.size <= 1 => true
           case _ => false
@@ -1246,13 +1297,45 @@ object TreeOps {
   }
 
   def containsChoose(e: Expr): Boolean = {
-    simplePreTransform{
+    preTraversal{
       case Choose(_, _) => return true
-      case e => e
+      case _ =>
     }(e)
     false
   }
 
+  def containsHoles(e: Expr): Boolean = {
+    preTraversal{
+      case Hole(_) => return true
+      case _ =>
+    }(e)
+    false
+  }
+
+  /**
+   * Returns true if the expression directly or indirectly relies on a Hole
+   */
+  def usesHoles(e: Expr): Boolean = {
+    var cache = Map[FunDef, Boolean]()
+
+    def callsHolesExpr(e: Expr): Boolean = {
+      containsHoles(e) || functionCallsOf(e).exists(fi => callsHoles(fi.tfd.fd))
+    }
+
+    def callsHoles(fd: FunDef): Boolean = cache.get(fd) match {
+      case Some(r) => r
+      case None =>
+        cache += fd -> false
+
+        val res = fd.body.map(callsHolesExpr _).getOrElse(false)
+
+        cache += fd -> res
+        res
+    }
+
+    callsHolesExpr(e)
+  }
+
   /**
    * Returns the value for an identifier given a model.
    */
diff --git a/src/main/scala/leon/purescala/Trees.scala b/src/main/scala/leon/purescala/Trees.scala
index a7a46e3c6..b7624a842 100644
--- a/src/main/scala/leon/purescala/Trees.scala
+++ b/src/main/scala/leon/purescala/Trees.scala
@@ -26,8 +26,6 @@ object Trees {
    * the expected type. */
   case class Error(description: String) extends Expr with Terminal
 
-  case class Hole() extends Expr with Terminal
-
   case class Choose(vars: List[Identifier], pred: Expr) extends Expr with FixedType with UnaryExtractable {
 
     assert(!vars.isEmpty)
@@ -39,6 +37,13 @@ object Trees {
     }
   }
 
+  // A hole is like a all-seeing choose
+  case class Hole(oracle: Expr) extends Expr with UnaryExtractable {
+    def extract = {
+      Some((oracle, (o: Expr) => Hole(o).copiedFrom(this)))
+    }
+  }
+
   /* Like vals */
   case class Let(binder: Identifier, value: Expr, body: Expr) extends Expr with FixedType {
     val fixedType = body.getType
diff --git a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala
index 35b50b8ee..168b8e193 100644
--- a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala
+++ b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala
@@ -451,7 +451,7 @@ trait AbstractZ3Solver
 
     case other =>
       sorts.toZ3OrCompute(other) {
-        reporter.warning("Resorting to uninterpreted type for : " + other)
+        reporter.warning(other.getPos, "Resorting to uninterpreted type for : " + other)
         val symbol = z3.mkIntSymbol(nextIntForSymbol())
         z3.mkUninterpretedSort(symbol)
       }
@@ -638,8 +638,11 @@ trait AbstractZ3Solver
       case gv @ GenericValue(tp, id) =>
         z3.mkApp(genericValueToDecl(gv))
 
+      case h @ Hole(o) =>
+        rec(OracleTraverser(o, h.getType, program).value)
+
       case _ => {
-        reporter.warning("Can't handle this in translation to Z3: " + ex)
+        reporter.warning(ex.getPos, "Can't handle this in translation to Z3: " + ex)
         throw new CantTranslateException
       }
     }
diff --git a/src/main/scala/leon/solvers/z3/FunctionTemplate.scala b/src/main/scala/leon/solvers/z3/FunctionTemplate.scala
index ad173d712..9fe4be2cc 100644
--- a/src/main/scala/leon/solvers/z3/FunctionTemplate.scala
+++ b/src/main/scala/leon/solvers/z3/FunctionTemplate.scala
@@ -59,7 +59,7 @@ class FunctionTemplate private(
   }
 
   val asZ3Clauses: Seq[Z3AST] = asClauses.map {
-    solver.toZ3Formula(_, idToZ3Ids).getOrElse(sys.error("Could not translate to z3. Did you forget --xlang?"))
+    cl => solver.toZ3Formula(cl, idToZ3Ids).getOrElse(sys.error("Could not translate to z3. Did you forget --xlang? @"+cl.getPos))
   }
 
   private val blockers : Map[Identifier,Set[FunctionInvocation]] = {
@@ -252,7 +252,6 @@ object FunctionTemplate {
               val partitions = groupWhile((e: Expr) => !containsFunctionCalls(e), parts)
 
               val ifExpr = partitions.map(Or(_)).reduceRight{ (a: Expr, b: Expr) => IfExpr(a, BooleanLiteral(true), b) }
-
               rec(pathVar, ifExpr)
             } else {
               o
@@ -262,7 +261,7 @@ object FunctionTemplate {
           }
 
         case i @ IfExpr(cond, thenn, elze) => {
-          if(!containsFunctionCalls(cond) && !containsFunctionCalls(thenn) && !containsFunctionCalls(elze)) {
+          if(!containsFunctionCalls(i)) {
             i
           } else {
             val newBool1 : Identifier = FreshIdentifier("b", true).setType(BooleanType)
diff --git a/src/main/scala/leon/synthesis/BoundedSearch.scala b/src/main/scala/leon/synthesis/BoundedSearch.scala
index 41bc86894..5430d05d2 100644
--- a/src/main/scala/leon/synthesis/BoundedSearch.scala
+++ b/src/main/scala/leon/synthesis/BoundedSearch.scala
@@ -5,12 +5,11 @@ package synthesis
 
 class BoundedSearch(synth: Synthesizer,
                    problem: Problem,
-                   rules: Seq[Rule],
                    costModel: CostModel,
-                   searchBound: Int) extends SimpleSearch(synth, problem, rules, costModel) {
+                   searchBound: Int) extends SimpleSearch(synth, problem, costModel) {
 
   def this(synth: Synthesizer, problem: Problem, searchBound: Int) = {
-    this(synth, problem, synth.rules, synth.options.costModel, searchBound)
+    this(synth, problem, synth.options.costModel, searchBound)
   }
 
   override def searchStep() {
diff --git a/src/main/scala/leon/synthesis/ChooseInfo.scala b/src/main/scala/leon/synthesis/ChooseInfo.scala
index 2295ff3dc..85f51ee66 100644
--- a/src/main/scala/leon/synthesis/ChooseInfo.scala
+++ b/src/main/scala/leon/synthesis/ChooseInfo.scala
@@ -3,14 +3,16 @@
 package leon
 package synthesis
 
+import purescala.Common._
 import purescala.Definitions._
 import purescala.Trees._
-import purescala.TreeOps.ChooseCollectorWithPaths
+import purescala.TreeOps._
 
 case class ChooseInfo(ctx: LeonContext,
                       prog: Program,
                       fd: FunDef,
                       pc: Expr,
+                      source: Expr,
                       ch: Choose,
                       options: SynthesisOptions) {
 
@@ -25,14 +27,34 @@ object ChooseInfo {
     var results = List[ChooseInfo]()
 
     // Look for choose()
-    for (f <- prog.definedFunctions.sortBy(_.id.toString) if f.body.isDefined) {
+    for (f <- prog.definedFunctions if f.body.isDefined) {
       val actualBody = And(f.precondition.getOrElse(BooleanLiteral(true)), f.body.get)
 
       for ((ch, path) <- new ChooseCollectorWithPaths().traverse(actualBody)) {
-        results = ChooseInfo(ctx, prog, f, path, ch, options) :: results
+        results = ChooseInfo(ctx, prog, f, path, ch, ch, options) :: results
       }
     }
 
-    results.reverse
+
+    if (options.allSeeing) {
+      // Functions that call holes are also considered for (all-seeing) synthesis
+
+      val holesFd = prog.definedFunctions.filter(fd => fd.hasBody && containsHoles(fd.body.get)).toSet
+
+      val callers = prog.callGraph.transitiveCallers(holesFd) ++ holesFd
+
+      for (f <- callers if f.hasPostcondition && f.hasBody) {
+        val path = f.precondition.getOrElse(BooleanLiteral(true))
+
+        val x = FreshIdentifier("x", true).setType(f.returnType)
+        val (pid, pex) = f.postcondition.get
+
+        val ch = Choose(List(x), And(Equals(x.toVariable, f.body.get), replaceFromIDs(Map(pid -> x.toVariable), pex)))
+
+        results = ChooseInfo(ctx, prog, f, path, f.body.get, ch, options) :: results
+      }
+    }
+
+    results.sortBy(_.fd.id.toString)
   }
 }
diff --git a/src/main/scala/leon/synthesis/ConvertHoles.scala b/src/main/scala/leon/synthesis/ConvertHoles.scala
deleted file mode 100644
index 57cc7bf59..000000000
--- a/src/main/scala/leon/synthesis/ConvertHoles.scala
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2009-2014 EPFL, Lausanne */
-
-package leon
-package synthesis
-
-import purescala.Common._
-import purescala.Trees._
-import purescala.TreeOps._
-import purescala.Definitions._
-
-object ConvertHoles extends LeonPhase[Program, Program] {
-  val name        = "Convert Holes to Choose"
-  val description = "Convert holes found in bodies to equivalent Choose"
-
-  /**
-   * This phase converts a body with "holes" into a choose construct:
-   *
-   * def foo(a: T) {
-   *   require(..a..)
-   *   expr(???, ???)
-   * } ensuring { res => 
-   *   pred(res)
-   * }
-   *
-   * gets converted into:
-   *
-   * def foo(a: T) {
-   *   require(..a..)
-   *   choose { (c1, c2) => {
-   *     val res = expr(c1, c2)
-   *     pred(res)
-   *   }
-   * } ensuring { res => 
-   *   pred(res)
-   * }
-   *
-   */
-  def run(ctx: LeonContext)(pgm: Program): Program = {
-    pgm.definedFunctions.foreach(fd => {
-      if (fd.hasPostcondition && fd.hasBody) {
-        var holes = List[Identifier]()
-        val body = preMap {
-          case h @ Hole() =>
-            val id = FreshIdentifier("c", true).copiedFrom(h)
-            holes ::= id
-
-            Some(id.toVariable)
-          case _ => None
-        }(fd.body.get)
-
-        holes = holes.reverse
-
-        if (holes.nonEmpty) {
-          val res = FreshIdentifier("b", true).copiedFrom(body)
-          val (pid, pbody) = fd.postcondition.get
-
-          val c = Choose(holes, Let(res, body, replaceFromIDs(Map(pid -> res.toVariable), pbody)))
-
-          if (holes.size > 1) {
-            val newHoles = holes.map(_.freshen)
-            fd.body = Some(LetTuple(newHoles, c.setPos(body), replaceFromIDs((holes zip newHoles.map(_.toVariable)).toMap, body)).setPos(body))
-          } else {
-            fd.body = Some(preMap {
-              case h @ Hole() => Some(c.setPos(h))
-              case _ => None
-            }(fd.body.get))
-          }
-        }
-      } else {
-        // No post-condition: we replace holes with local-chooses without
-        // predicates
-        fd.body = fd.body.map { preMap {
-          case h @ Hole() =>
-            val id = FreshIdentifier("c", true).copiedFrom(h)
-            Some(Choose(List(id), BooleanLiteral(true)).copiedFrom(h))
-          case _ => None
-        } }
-      }
-      
-      // Ensure that holes are not found in pre and/or post conditions
-      fd.precondition.foreach {
-        preTraversal{
-          case Hole() =>
-            ctx.reporter.error("Hole expressions are not supported in preconditions. (function "+fd.id.asString(ctx)+")")
-          case _ =>
-        }
-      }
-
-      fd.postcondition.foreach { case (id, post) =>
-        preTraversal{
-          case Hole() =>
-            ctx.reporter.error("Hole expressions are not supported in postconditions. (function "+fd.id.asString(ctx)+")")
-          case _ =>
-        }(post)
-      }
-
-    })
-
-    pgm
-  }
-}
diff --git a/src/main/scala/leon/synthesis/CostModel.scala b/src/main/scala/leon/synthesis/CostModel.scala
index 75bdb7f4a..85e5285ee 100644
--- a/src/main/scala/leon/synthesis/CostModel.scala
+++ b/src/main/scala/leon/synthesis/CostModel.scala
@@ -97,7 +97,13 @@ case object WeightedBranchesCostModel extends CostModel("WeightedBranches") {
   }
 
   def problemCost(p: Problem): Cost = new Cost {
-    val value = p.xs.size
+    val value = {
+      if (usesHoles(p.phi)) {
+        p.xs.size + 50
+      } else {
+        p.xs.size 
+      }
+    }
   }
 
 }
diff --git a/src/main/scala/leon/synthesis/Heuristics.scala b/src/main/scala/leon/synthesis/Heuristics.scala
index d48e94385..5c3fe9a07 100644
--- a/src/main/scala/leon/synthesis/Heuristics.scala
+++ b/src/main/scala/leon/synthesis/Heuristics.scala
@@ -25,34 +25,3 @@ trait Heuristic {
   override def toString = "H: "+name
 
 }
-
-object HeuristicInstantiation {
-  def verifyPre(sctx: SynthesisContext, problem: Problem)(s: Solution): Option[Solution] = {
-    //sctx.solver.solveSAT(And(Not(s.pre), problem.phi)) match {
-    //  case (Some(true), model) =>
-    //    sctx.reporter.warning("Heuristic failed to produce weakest precondition:")
-    //    sctx.reporter.warning(" - problem: "+problem)
-    //    sctx.reporter.warning(" - precondition: "+s.pre)
-    //    None
-    //  case _ =>
-    //    Some(s)
-    //}
-
-    Some(s)
-  }
-
-  def apply(problem: Problem, rule: Rule, subProblems: List[Problem], onSuccess: List[Solution] => Option[Solution], description: String): RuleInstantiation = {
-    val subTypes = subProblems.map(p => TupleType(p.xs.map(_.getType)))
-
-    val builder = new SolutionBuilder(subProblems.size, subTypes) {
-      def apply(sols: List[Solution]) = {
-        onSuccess(sols)
-      }
-    }
-
-    new RuleInstantiation(problem, rule, builder, description) {
-      def apply(sctx: SynthesisContext) = RuleDecomposed(subProblems)
-
-    }
-  }
-}
diff --git a/src/main/scala/leon/synthesis/ManualSearch.scala b/src/main/scala/leon/synthesis/ManualSearch.scala
index 5964eadc4..137d79c68 100644
--- a/src/main/scala/leon/synthesis/ManualSearch.scala
+++ b/src/main/scala/leon/synthesis/ManualSearch.scala
@@ -7,11 +7,10 @@ import leon.purescala.ScalaPrinter
 
 class ManualSearch(synth: Synthesizer,
                    problem: Problem,
-                   rules: Seq[Rule],
-                   costModel: CostModel) extends SimpleSearch(synth, problem, rules, costModel) {
+                   costModel: CostModel) extends SimpleSearch(synth, problem, costModel) {
 
   def this(synth: Synthesizer, problem: Problem) = {
-    this(synth, problem, synth.rules, synth.options.costModel)
+    this(synth, problem, synth.options.costModel)
   }
 
   import synth.reporter._
@@ -33,24 +32,32 @@ class ManualSearch(synth: Synthesizer,
     def failed(str: String) = "\033[31m"+str+"\033[0m"
     def solved(str: String) = "\033[32m"+str+"\033[0m"
 
+    def displayApp(app: RuleInstantiation): String = {
+      f"(${costModel.ruleAppCost(app).value}%3d) $app"
+    }
+
+    def displayProb(p: Problem): String = {
+      f"(${costModel.problemCost(p).value}%3d) $p"
+    }
+
     def traversePathFrom(n: g.Tree, prefix: List[Int]) {
       n match {
         case l: g.AndLeaf =>
           if (prefix.endsWith(cd.reverse)) {
-            println(pathToString(prefix)+" \u2508 "+l.task.app)
+            println(pathToString(prefix)+" \u2508 "+displayApp(l.task.app))
           }
         case l: g.OrLeaf =>
           if (prefix.endsWith(cd.reverse)) {
-            println(pathToString(prefix)+" \u2508 "+l.task.p)
+            println(pathToString(prefix)+" \u2508 "+displayProb(l.task.p))
           }
         case an: g.AndNode =>
           if (an.isSolved) {
             if (prefix.endsWith(cd.reverse)) {
-              println(solved(pathToString(prefix)+" \u2508 "+an.task.app))
+              println(solved(pathToString(prefix)+" \u2508 "+displayApp(an.task.app)))
             }
           } else {
             if (prefix.endsWith(cd.reverse)) {
-              println(title(pathToString(prefix)+" \u2510 "+an.task.app))
+              println(title(pathToString(prefix)+" \u2510 "+displayApp(an.task.app)))
             }
             for ((st, i) <- an.subTasks.zipWithIndex) {
               traversePathFrom(an.subProblems(st), i :: prefix)
@@ -64,12 +71,12 @@ class ManualSearch(synth: Synthesizer,
             }
           } else {
             if (prefix.endsWith(cd.reverse)) {
-              println(title(pathToString(prefix)+" \u2510 "+on.task.p))
+              println(title(pathToString(prefix)+" \u2510 "+displayProb(on.task.p)))
             }
             for ((at, i) <- on.altTasks.zipWithIndex) {
               if (on.triedAlternatives contains at) {
                 if (prefix.endsWith(cd.reverse)) {
-                  println(failed(pathToString(i :: prefix)+" \u2508 "+at.app))
+                  println(failed(pathToString(i :: prefix)+" \u2508 "+displayApp(at.app)))
                 }
               } else {
                 traversePathFrom(on.alternatives(at), i :: prefix)
diff --git a/src/main/scala/leon/synthesis/ParallelSearch.scala b/src/main/scala/leon/synthesis/ParallelSearch.scala
index e8eb0fbce..b0af9cab8 100644
--- a/src/main/scala/leon/synthesis/ParallelSearch.scala
+++ b/src/main/scala/leon/synthesis/ParallelSearch.scala
@@ -9,12 +9,11 @@ import solvers.z3._
 
 class ParallelSearch(synth: Synthesizer,
                      problem: Problem,
-                     rules: Seq[Rule],
                      costModel: CostModel,
                      nWorkers: Int) extends AndOrGraphParallelSearch[SynthesisContext, TaskRunRule, TaskTryRules, Solution](new AndOrGraph(TaskTryRules(problem), SearchCostModel(costModel)), nWorkers) {
 
   def this(synth: Synthesizer, problem: Problem, nWorkers: Int) = {
-    this(synth, problem, synth.rules, synth.options.costModel, nWorkers)
+    this(synth, problem, synth.options.costModel, nWorkers)
   }
 
   import synth.reporter._
@@ -60,22 +59,12 @@ class ParallelSearch(synth: Synthesizer,
   }
 
   def expandOrTask(ref: ActorRef, sctx: SynthesisContext)(t: TaskTryRules) = {
-    val (normRules, otherRules) = rules.partition(_.isInstanceOf[NormalizingRule])
+    val apps = Rules.getInstantiations(sctx, t.p)
 
-    val normApplications = normRules.flatMap(_.instantiateOn(sctx, t.p))
-
-    if (!normApplications.isEmpty) {
-      Expanded(List(TaskRunRule(normApplications.head)))
+    if (apps.nonEmpty) {
+      Expanded(apps.map(TaskRunRule(_)))
     } else {
-      val sub = otherRules.flatMap { r =>
-        r.instantiateOn(sctx, t.p).map(TaskRunRule(_))
-      }
-
-      if (!sub.isEmpty) {
-        Expanded(sub.toList)
-      } else {
-        ExpandFailure()
-      }
+      ExpandFailure()
     }
   }
 }
diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala
index 9fd44cb0f..aa79a1470 100644
--- a/src/main/scala/leon/synthesis/Rules.scala
+++ b/src/main/scala/leon/synthesis/Rules.scala
@@ -29,9 +29,25 @@ object Rules {
     DetupleOutput,
     DetupleInput,
     ADTSplit,
+    InlineHoles,
     IntegerEquation,
-    IntegerInequalities
+    IntegerInequalities,
+    AngelicHoles
   )
+
+  def getInstantiations(sctx: SynthesisContext, problem: Problem) = {
+    val sub = sctx.rules.flatMap { r =>
+      r.instantiateOn(sctx, problem)
+    }
+
+    val res = sub.groupBy(_.priority).toSeq.sortBy(_._1)
+
+    if (res.nonEmpty) {
+      res.head._2.toList
+    } else {
+      Nil
+    }
+  }
 }
 
 abstract class SolutionBuilder(val arity: Int, val types: Seq[TypeTree]) {
@@ -53,7 +69,13 @@ object SolutionBuilder {
   }
 }
 
-abstract class RuleInstantiation(val problem: Problem, val rule: Rule, val onSuccess: SolutionBuilder, val description: String) {
+abstract class RuleInstantiation(
+  val problem: Problem,
+  val rule: Rule,
+  val onSuccess: SolutionBuilder,
+  val description: String,
+  val priority: RulePriority) {
+
   def apply(sctx: SynthesisContext): RuleApplicationResult
 
   override def toString = description
@@ -64,17 +86,56 @@ case class RuleSuccess(solution: Solution, isTrusted: Boolean = true)  extends R
 case class RuleDecomposed(sub: List[Problem])                          extends RuleApplicationResult
 case object RuleApplicationImpossible                                  extends RuleApplicationResult
 
+sealed abstract class RulePriority(val v: Int) extends Ordered[RulePriority] {
+  def compare(that: RulePriority) = this.v - that.v
+}
+
+case object RulePriorityDefault     extends RulePriority(2)
+case object RulePriorityNormalizing extends RulePriority(0)
+case object RulePriorityHoles       extends RulePriority(1)
+
 object RuleInstantiation {
-  def immediateDecomp(problem: Problem, rule: Rule, sub: List[Problem], onSuccess: List[Solution] => Option[Solution], description: String) = {
+  def immediateDecomp(problem: Problem,
+                      rule: Rule,
+                      sub: List[Problem],
+                      onSuccess: List[Solution] => Option[Solution]): RuleInstantiation = {
+
+    immediateDecomp(problem, rule, sub, onSuccess, rule.name, rule.priority)
+  }
+
+  def immediateDecomp(problem: Problem,
+                      rule: Rule,
+                      sub: List[Problem],
+                      onSuccess: List[Solution] => Option[Solution],
+                      description: String): RuleInstantiation = {
+    immediateDecomp(problem, rule, sub, onSuccess, description, rule.priority)
+  }
+
+  def immediateDecomp(problem: Problem,
+                      rule: Rule,
+                      sub: List[Problem],
+                      onSuccess: List[Solution] => Option[Solution],
+                      description: String,
+                      priority: RulePriority): RuleInstantiation = {
     val subTypes = sub.map(p => TupleType(p.xs.map(_.getType)))
 
-    new RuleInstantiation(problem, rule, new SolutionCombiner(sub.size, subTypes, onSuccess), description) {
+    new RuleInstantiation(problem, rule, new SolutionCombiner(sub.size, subTypes, onSuccess), description, priority) {
       def apply(sctx: SynthesisContext) = RuleDecomposed(sub)
     }
   }
 
-  def immediateSuccess(problem: Problem, rule: Rule, solution: Solution) = {
-    new RuleInstantiation(problem, rule, new SolutionCombiner(0, Seq(), ls => Some(solution)), "Solve with "+solution) {
+  def immediateSuccess(problem: Problem,
+                       rule: Rule,
+                       solution: Solution): RuleInstantiation = {
+    immediateSuccess(problem, rule, solution, rule.priority)
+
+  }
+
+  def immediateSuccess(problem: Problem,
+                       rule: Rule,
+                       solution: Solution,
+                       priority: RulePriority): RuleInstantiation = {
+    new RuleInstantiation(problem, rule, new SolutionCombiner(0, Seq(), ls => Some(solution)), "Solve with "+solution, priority) {
       def apply(sctx: SynthesisContext) = RuleSuccess(solution)
     }
   }
@@ -83,6 +144,8 @@ object RuleInstantiation {
 abstract class Rule(val name: String) {
   def instantiateOn(sctx: SynthesisContext, problem: Problem): Traversable[RuleInstantiation]
 
+  val priority: RulePriority = RulePriorityDefault 
+
   def subst(what: Tuple2[Identifier, Expr], in: Expr): Expr = replace(Map(Variable(what._1) -> what._2), in)
   def substAll(what: Map[Identifier, Expr], in: Expr): Expr = replace(what.map(w => Variable(w._1) -> w._2), in)
 
@@ -95,12 +158,21 @@ abstract class Rule(val name: String) {
       None
   }
 
+  def project(firstN: Int): List[Solution] => Option[Solution] = {
+    project(0 until firstN)
+  }
+
+
+  def project(ids: Seq[Int]): List[Solution] => Option[Solution] = {
+    case List(s) =>
+      Some(s.project(ids))
+    case _ =>
+      None
+  }
+
   override def toString = "R: "+name
 }
 
-// Note: Rules that extend NormalizingRule should all be commutative, The will
-// be applied before others in a deterministic order and their application
-// should never fail!
 abstract class NormalizingRule(name: String) extends Rule(name) {
-  override def toString = "N: "+name
+  override val priority = RulePriorityNormalizing
 }
diff --git a/src/main/scala/leon/synthesis/SimpleSearch.scala b/src/main/scala/leon/synthesis/SimpleSearch.scala
index 491188cef..b069a1c73 100644
--- a/src/main/scala/leon/synthesis/SimpleSearch.scala
+++ b/src/main/scala/leon/synthesis/SimpleSearch.scala
@@ -9,11 +9,10 @@ import synthesis.search._
 
 class SimpleSearch(synth: Synthesizer,
                    problem: Problem,
-                   rules: Seq[Rule],
                    costModel: CostModel) extends AndOrGraphSearch[TaskRunRule, TaskTryRules, Solution](new AndOrGraph(TaskTryRules(problem), SearchCostModel(costModel))) with Interruptible {
 
   def this(synth: Synthesizer, problem: Problem) = {
-    this(synth, problem, synth.rules, synth.options.costModel)
+    this(synth, problem, synth.options.costModel)
   }
 
   import synth.reporter._
@@ -45,22 +44,12 @@ class SimpleSearch(synth: Synthesizer,
   }
 
   def expandOrTask(t: TaskTryRules): ExpandResult[TaskRunRule] = {
-    val (normRules, otherRules) = rules.partition(_.isInstanceOf[NormalizingRule])
+    val apps = Rules.getInstantiations(sctx, t.p)
 
-    val normApplications = normRules.flatMap(_.instantiateOn(sctx, t.p))
-
-    if (!normApplications.isEmpty) {
-      Expanded(List(TaskRunRule(normApplications.head)))
+    if (apps.nonEmpty) {
+      Expanded(apps.map(TaskRunRule(_)))
     } else {
-      val sub = otherRules.flatMap { r =>
-        r.instantiateOn(sctx, t.p).map(TaskRunRule(_))
-      }
-
-      if (!sub.isEmpty) {
-        Expanded(sub.toList)
-      } else {
-        ExpandFailure()
-      }
+      ExpandFailure()
     }
   }
 
diff --git a/src/main/scala/leon/synthesis/Solution.scala b/src/main/scala/leon/synthesis/Solution.scala
index ef04d34b8..c504eadac 100644
--- a/src/main/scala/leon/synthesis/Solution.scala
+++ b/src/main/scala/leon/synthesis/Solution.scala
@@ -3,6 +3,7 @@
 package leon
 package synthesis
 
+import purescala.Common._
 import purescala.Trees._
 import purescala.TypeTrees.{TypeTree,TupleType}
 import purescala.Definitions._
@@ -28,6 +29,20 @@ class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr) {
     defs.foldLeft(result){ case (t, fd) => LetDef(fd, t) }
   }
 
+  // Projects a solution (ignore several output variables)
+  // 
+  // e.g. Given solution for [[ a < .. > x1, x2, x3, x4 ]] and List(0, 1, 3)
+  // It produces a solution for [[ a < .. > x1, x2, x4 ]]
+  //
+  // Indices are 0-indexed
+  def project(indices: Seq[Int]): Solution = {
+    val t = FreshIdentifier("t", true).setType(term.getType)
+    val newTerm = Let(t, term, Tuple(indices.map(i => TupleSelect(t.toVariable, i+1))))
+
+    Solution(pre, defs, newTerm)
+  }
+
+
   def fullTerm =
     defs.foldLeft(term){ case (t, fd) => LetDef(fd, t) }
 
@@ -41,13 +56,22 @@ class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr) {
       matchToIfThenElse _,
       simplifyPaths(uninterpretedZ3)(_),
       patternMatchReconstruction _,
-      simplifyTautologies(uninterpretedZ3)(_),
-      simplifyLets _,
       rewriteTuples _,
-      (new ScopeSimplifier).transform _
+      evalGround(ctx, p),
+      normalizeExpression _
     )
 
-    simplifiers.foldLeft(toExpr){ (x, sim) => sim(x) }
+    val simple = { expr: Expr =>
+      simplifiers.foldLeft(expr){ case (x, sim) => 
+        sim(x)
+      }
+    }
+
+    // Simplify first using stable simplifiers
+    val s = fixpoint(simple)(toExpr)
+
+    // Clean up ids/names
+    (new ScopeSimplifier).transform(s)
   }
 }
 
diff --git a/src/main/scala/leon/synthesis/SynthesisContext.scala b/src/main/scala/leon/synthesis/SynthesisContext.scala
index b699c8bc8..47bac7559 100644
--- a/src/main/scala/leon/synthesis/SynthesisContext.scala
+++ b/src/main/scala/leon/synthesis/SynthesisContext.scala
@@ -21,6 +21,8 @@ case class SynthesisContext(
   reporter: Reporter
 ) {
 
+  val rules = options.rules
+
   val allSolvers: Map[String, SolverFactory[SynthesisContext.SynthesisSolver]] = Map(
     "fairz3" -> SolverFactory(() => new FairZ3Solver(context, program) with TimeoutAssumptionSolver),
     "enum"   -> SolverFactory(() => new EnumerationSolver(context, program) with TimeoutAssumptionSolver)
diff --git a/src/main/scala/leon/synthesis/SynthesisOptions.scala b/src/main/scala/leon/synthesis/SynthesisOptions.scala
index 90f0e3c84..706fc69ff 100644
--- a/src/main/scala/leon/synthesis/SynthesisOptions.scala
+++ b/src/main/scala/leon/synthesis/SynthesisOptions.scala
@@ -5,6 +5,7 @@ package synthesis
 
 case class SynthesisOptions(
   inPlace: Boolean                    = false,
+  allSeeing: Boolean                  = false,
   generateDerivationTrees: Boolean    = false,
   filterFuns: Option[Set[String]]     = None,
   searchWorkers: Int                  = 1,
diff --git a/src/main/scala/leon/synthesis/SynthesisPhase.scala b/src/main/scala/leon/synthesis/SynthesisPhase.scala
index 98e8a8d6e..e68dbf292 100644
--- a/src/main/scala/leon/synthesis/SynthesisPhase.scala
+++ b/src/main/scala/leon/synthesis/SynthesisPhase.scala
@@ -17,6 +17,7 @@ object SynthesisPhase extends LeonPhase[Program, Program] {
 
   override val definedOptions : Set[LeonOptionDef] = Set(
     LeonFlagOptionDef( "inplace",         "--inplace",         "Debug level"),
+    LeonFlagOptionDef( "allseeing",       "--allseeing",       "Also synthesize functions using holes"),
     LeonValueOptionDef("parallel",        "--parallel[=N]",    "Parallel synthesis search using N workers", Some("5")),
     LeonFlagOptionDef( "manual",          "--manual",          "Manual search"),
     LeonFlagOptionDef( "derivtrees",      "--derivtrees",      "Generate derivation trees"),
@@ -43,6 +44,9 @@ object SynthesisPhase extends LeonPhase[Program, Program] {
       case LeonFlagOption("manual", v) =>
         options = options.copy(manualSearch = v)
 
+      case LeonFlagOption("allseeing", v) =>
+        options = options.copy(allSeeing = v)
+
       case LeonFlagOption("inplace", v) =>
         options = options.copy(inPlace = v)
 
@@ -122,11 +126,16 @@ object SynthesisPhase extends LeonPhase[Program, Program] {
   def run(ctx: LeonContext)(p: Program): Program = {
     val options = processOptions(ctx)
 
-    def toProcess(ci: ChooseInfo) = {
-      options.filterFuns.isEmpty || options.filterFuns.get.contains(ci.fd.id.toString)
+    def excludeByDefault(fd: FunDef): Boolean = (fd.annotations contains "library")
+
+    val fdFilter = {
+      import OptionsHelpers._
+      val ciTofd = { (ci: ChooseInfo) => ci.fd }
+
+      filterInclusive(options.filterFuns.map(fdMatcher), Some(excludeByDefault _)) compose ciTofd
     }
 
-    var chooses = ChooseInfo.extractFromProgram(ctx, p, options).filter(toProcess)
+    var chooses = ChooseInfo.extractFromProgram(ctx, p, options).filter(fdFilter)
 
     var functions = Set[FunDef]()
 
@@ -136,7 +145,7 @@ object SynthesisPhase extends LeonPhase[Program, Program] {
       val fd = ci.fd
 
       val expr = sol.toSimplifiedExpr(ctx, p)
-      fd.body = fd.body.map(b => replace(Map(ci.ch -> expr), b))
+      fd.body = fd.body.map(b => replace(Map(ci.source -> expr), b))
 
       functions += fd
 
diff --git a/src/main/scala/leon/synthesis/Synthesizer.scala b/src/main/scala/leon/synthesis/Synthesizer.scala
index 11189cefc..483dc9b36 100644
--- a/src/main/scala/leon/synthesis/Synthesizer.scala
+++ b/src/main/scala/leon/synthesis/Synthesizer.scala
@@ -23,8 +23,6 @@ class Synthesizer(val context : LeonContext,
                   val problem: Problem,
                   val options: SynthesisOptions) {
 
-  val rules: Seq[Rule] = options.rules
-
   val reporter = context.reporter
 
   def synthesize(): (Solution, Boolean) = {
@@ -84,7 +82,7 @@ class Synthesizer(val context : LeonContext,
     val solverf = SolverFactory(() => (new FairZ3Solver(context, npr) with TimeoutSolver).setTimeout(timeoutMs))
 
     val vctx = VerificationContext(context, npr, solverf, context.reporter)
-    val vcs = generateVerificationConditions(vctx, fds.map(_.id.name))
+    val vcs = generateVerificationConditions(vctx, Some(fds.map(_.id.name).toSeq))
     val vcreport = checkVerificationConditions(vctx, vcs)
 
     if (vcreport.totalValid == vcreport.totalConditions) {
diff --git a/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala b/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala
index f3136fbbb..87e4b14c8 100644
--- a/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala
+++ b/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala
@@ -110,7 +110,7 @@ case object ADTInduction extends Rule("ADT Induction") with Heuristic {
             }
         }
 
-        Some(HeuristicInstantiation(p, this, subProblemsInfo.map(_._1).toList, onSuccess, "ADT Induction on '"+origId+"'"))
+        Some(RuleInstantiation.immediateDecomp(p, this, subProblemsInfo.map(_._1).toList, onSuccess, "ADT Induction on '"+origId+"'"))
       } else {
         None
       }
diff --git a/src/main/scala/leon/synthesis/heuristics/ADTLongInduction.scala b/src/main/scala/leon/synthesis/heuristics/ADTLongInduction.scala
index 5ab3f672b..9c29ec859 100644
--- a/src/main/scala/leon/synthesis/heuristics/ADTLongInduction.scala
+++ b/src/main/scala/leon/synthesis/heuristics/ADTLongInduction.scala
@@ -71,7 +71,7 @@ case object ADTLongInduction extends Rule("ADT Long Induction") with Heuristic {
 
                 val newIds = ids.filterNot(_ == id) ++ subIds
                 val newCalls = if (!subIds.isEmpty) {
-                  List(subIds.find(isRec).get)
+                  List(subIds.find(isRec)).flatten
                 } else {
                   List()
                 }
@@ -159,7 +159,7 @@ case object ADTLongInduction extends Rule("ADT Long Induction") with Heuristic {
             }
         }
 
-        Some(HeuristicInstantiation(p, this, subProblemsInfo.map(_._1).toList, onSuccess, "ADT Long Induction on '"+origId+"'"))
+        Some(RuleInstantiation.immediateDecomp(p, this, subProblemsInfo.map(_._1).toList, onSuccess, "ADT Long Induction on '"+origId+"'"))
       } else {
         None
       }
diff --git a/src/main/scala/leon/synthesis/heuristics/IntInduction.scala b/src/main/scala/leon/synthesis/heuristics/IntInduction.scala
index ac01105b4..37cf77a0b 100644
--- a/src/main/scala/leon/synthesis/heuristics/IntInduction.scala
+++ b/src/main/scala/leon/synthesis/heuristics/IntInduction.scala
@@ -65,7 +65,7 @@ case object IntInduction extends Rule("Int Induction") with Heuristic {
             None
         }
 
-        Some(HeuristicInstantiation(p, this, List(subBase, subGT, subLT), onSuccess, "Int Induction on '"+origId+"'"))
+        Some(RuleInstantiation.immediateDecomp(p, this, List(subBase, subGT, subLT), onSuccess, "Int Induction on '"+origId+"'"))
       case _ =>
         None
     }
diff --git a/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala b/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala
index e33c3eee3..7cd1e2342 100644
--- a/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala
+++ b/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala
@@ -38,7 +38,7 @@ case object OptimisticInjection extends Rule("Opt. Injection") with Heuristic {
 
       val sub = p.copy(phi = And(newExprs))
 
-      Some(HeuristicInstantiation(p, this, List(sub), forward, this.name))
+      Some(RuleInstantiation.immediateDecomp(p, this, List(sub), forward))
     } else {
       None
     }
diff --git a/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala b/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala
index 3de094c8c..dc7bf0526 100644
--- a/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala
+++ b/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala
@@ -38,7 +38,7 @@ case object SelectiveInlining extends Rule("Sel. Inlining") with Heuristic {
 
       val sub = p.copy(phi = And(newExprs))
 
-      Some(HeuristicInstantiation(p, this, List(sub), forward, this.name))
+      Some(RuleInstantiation.immediateDecomp(p, this, List(sub), forward))
     } else {
       None
     }
diff --git a/src/main/scala/leon/synthesis/rules/AngelicHoles.scala b/src/main/scala/leon/synthesis/rules/AngelicHoles.scala
new file mode 100644
index 000000000..07c5f687f
--- /dev/null
+++ b/src/main/scala/leon/synthesis/rules/AngelicHoles.scala
@@ -0,0 +1,50 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+
+package leon
+package synthesis
+package rules
+
+import purescala.Common._
+import purescala.Definitions._
+import purescala.Trees._
+import purescala.TreeOps._
+import purescala.TypeTrees._
+import purescala.Extractors._
+
+// Synthesizing a function with Hole is actually synthesizing an Oracle, so Oracle becomes output:
+// [[ a,o < Phi(a,o,x) > x ]]   --->  [[ a < Phi(a,o,x) > x, o ]]
+case object AngelicHoles extends NormalizingRule("Angelic Holes") {
+  def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
+    val oracleClass = sctx.program.definedClasses.find(_.id.name == "Oracle").getOrElse {
+      sctx.reporter.fatalError("Can't find Oracle class")
+    }
+
+    def isOracle(i: Identifier) = {
+      i.getType match {
+        case AbstractClassType(acd, _) if acd == oracleClass => true
+        case _ => false
+      }
+    }
+
+    if (usesHoles(p.phi)) {
+      val (oracles, as) = p.as.partition(isOracle)
+
+      if (oracles.nonEmpty) {
+        val sub = p.copy(as = as, xs = p.xs ++ oracles)
+        List(RuleInstantiation.immediateDecomp(p, this, List(sub), {
+          case List(s) =>
+            // We ignore the last output params that are oracles
+            Some(s.project(0 until p.xs.size))
+
+          case _ =>
+            None
+        }, "Hole Semantics"))
+      } else {
+        Nil
+      }
+    } else {
+      Nil
+    }
+  }
+}
+
diff --git a/src/main/scala/leon/synthesis/rules/AsChoose.scala b/src/main/scala/leon/synthesis/rules/AsChoose.scala
index 5aefa03dc..fc43972f0 100644
--- a/src/main/scala/leon/synthesis/rules/AsChoose.scala
+++ b/src/main/scala/leon/synthesis/rules/AsChoose.scala
@@ -6,7 +6,7 @@ package rules
 
 case object AsChoose extends Rule("As Choose") {
   def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
-      Some(new RuleInstantiation(p, this, SolutionBuilder.none, this.name) {
+      Some(new RuleInstantiation(p, this, SolutionBuilder.none, this.name, this.priority) {
         def apply(sctx: SynthesisContext) = {
           RuleSuccess(Solution.choose(p))
         }
diff --git a/src/main/scala/leon/synthesis/rules/Cegis.scala b/src/main/scala/leon/synthesis/rules/Cegis.scala
index 4cd54bf9e..83c5a3bf4 100644
--- a/src/main/scala/leon/synthesis/rules/Cegis.scala
+++ b/src/main/scala/leon/synthesis/rules/Cegis.scala
@@ -20,6 +20,7 @@ import scala.collection.mutable.{Map=>MutableMap}
 
 import evaluators._
 import datagen._
+import codegen.CodeGenParams
 
 
 case object CEGIS extends Rule("CEGIS") {
@@ -38,7 +39,8 @@ case object CEGIS extends Rule("CEGIS") {
     val testUpTo              = 5
     val useBssFiltering       = sctx.options.cegisUseBssFiltering
     val filterThreshold       = 1.0/2
-    val evaluator             = new CodeGenEvaluator(sctx.context, sctx.program)
+    val evalParams            = CodeGenParams(maxFunctionInvocations = 2000)
+    val evaluator             = new CodeGenEvaluator(sctx.context, sctx.program, evalParams)
 
     val interruptManager      = sctx.context.interruptManager
 
@@ -71,7 +73,7 @@ case object CEGIS extends Rule("CEGIS") {
             { () =>
               val alts: Seq[(Expr, Set[Identifier])] = cd.knownDescendents.flatMap(i => i match {
                   case acd: AbstractClassDef =>
-                    sctx.reporter.error("Unnexpected abstract class in descendants!")
+                    sctx.reporter.error(acd.getPos, "Unnexpected abstract class in descendants!")
                     None
                   case cd: CaseClassDef =>
                     val cct = CaseClassType(cd, tpes)
@@ -110,7 +112,7 @@ case object CEGIS extends Rule("CEGIS") {
 
           val isNotSynthesizable = fd.body match {
             case Some(b) =>
-              !containsChoose(b)
+              !containsChoose(b) && !usesHoles(b)
 
             case None =>
               false
@@ -437,7 +439,7 @@ case object CEGIS extends Rule("CEGIS") {
       def css : Set[Identifier] = mappings.values.map(_._1).toSet ++ guardedTerms.flatMap(_._2)
     }
 
-    List(new RuleInstantiation(p, this, SolutionBuilder.none, "CEGIS") {
+    List(new RuleInstantiation(p, this, SolutionBuilder.none, this.name, this.priority) {
       def apply(sctx: SynthesisContext): RuleApplicationResult = {
         var result: Option[RuleApplicationResult]   = None
 
diff --git a/src/main/scala/leon/synthesis/rules/Ground.scala b/src/main/scala/leon/synthesis/rules/Ground.scala
index 96a1e1250..52e5e0c13 100644
--- a/src/main/scala/leon/synthesis/rules/Ground.scala
+++ b/src/main/scala/leon/synthesis/rules/Ground.scala
@@ -13,7 +13,7 @@ import purescala.Extractors._
 case object Ground extends Rule("Ground") {
   def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
     if (p.as.isEmpty) {
-      List(new RuleInstantiation(p, this, SolutionBuilder.none, "Ground") {
+      List(new RuleInstantiation(p, this, SolutionBuilder.none, this.name, this.priority) {
         def apply(sctx: SynthesisContext): RuleApplicationResult = {
           val solver = SimpleSolverAPI(new TimeoutSolverFactory(sctx.solverFactory, 10000L))
 
diff --git a/src/main/scala/leon/synthesis/rules/InlineHoles.scala b/src/main/scala/leon/synthesis/rules/InlineHoles.scala
new file mode 100644
index 000000000..82fb1d135
--- /dev/null
+++ b/src/main/scala/leon/synthesis/rules/InlineHoles.scala
@@ -0,0 +1,103 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+
+package leon
+package synthesis
+package rules
+
+import scala.annotation.tailrec
+
+import leon.utils._
+
+import solvers._
+
+import purescala.Common._
+import purescala.Trees._
+import purescala.TreeOps._
+import purescala.TypeTrees._
+import purescala.Extractors._
+
+case object InlineHoles extends Rule("Inline-Holes") {
+  override val priority = RulePriorityHoles
+
+  def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
+
+    @tailrec
+    def inlineUntilHoles(e: Expr): Expr = {
+      if (containsHoles(e)) {
+        // Holes are exposed, no need to inline (yet)
+        e
+      } else {
+        // Inline all functions "once" that contain holes
+        val newE = postMap {
+          case fi @ FunctionInvocation(tfd, args) if usesHoles(fi) && tfd.hasBody =>
+            val inlined = replaceFromIDs((tfd.params.map(_.id) zip args).toMap, tfd.body.get)
+            Some(inlined)
+
+          case _ => None
+        }(e)
+
+        inlineUntilHoles(newE)
+      }
+    }
+
+    def inlineHoles(phi: Expr): (List[Identifier], Expr) = {
+      var newXs = List[Identifier]()
+
+      val res = preMap {
+        case h @ Hole(o) =>
+          val tpe = h.getType
+          val x = FreshIdentifier("h", true).setType(tpe)
+          newXs ::= x
+
+          Some(x.toVariable)
+
+        case _ => None
+      }(phi)
+
+      (newXs.reverse, res)
+    }
+
+    if (usesHoles(p.phi)) {
+      val pathsToCalls = new CollectorWithPaths({
+          case fi: FunctionInvocation if usesHoles(fi) => fi
+      }).traverse(p.phi).map(_._2)
+
+      val pc = if (pathsToCalls.nonEmpty) {
+        Not(Or(pathsToCalls))
+      } else {
+        BooleanLiteral(false)
+      }
+
+      // Creates two alternative branches:
+      // 1) a version with holes unreachable, on which this rule won't re-apply
+      val sfact  = new TimeoutSolverFactory(sctx.solverFactory, 500L)
+      val solver = SimpleSolverAPI(new TimeoutSolverFactory(sctx.solverFactory, 2000L))
+
+      val(holesAvoidable, _) = solver.solveSAT(And(p.pc, pc))
+
+      val avoid = if (holesAvoidable != Some(false)) {
+        val newPhi = simplifyPaths(sfact)(And(pc, p.phi))
+        val newProblem1 = p.copy(phi = newPhi)
+
+        Some(RuleInstantiation.immediateDecomp(p, this, List(newProblem1), {
+          case List(s) if (s.pre != BooleanLiteral(false)) => Some(s)
+          case _ => None
+        }, "Avoid Holes"))
+      } else {
+        None
+      }
+
+
+      // 2) a version with holes reachable to continue applying itself
+      val newPhi                 = inlineUntilHoles(p.phi)
+      val (newXs, newPhiInlined) = inlineHoles(newPhi)
+
+      val newProblem2 = p.copy(phi = newPhiInlined, xs = p.xs ::: newXs)
+      val rec = Some(RuleInstantiation.immediateDecomp(p, this, List(newProblem2), project(p.xs.size), "Inline Holes"))
+
+      List(rec, avoid).flatten
+    } else {
+      Nil
+    }
+  }
+}
diff --git a/src/main/scala/leon/synthesis/rules/OnePoint.scala b/src/main/scala/leon/synthesis/rules/OnePoint.scala
index df0e4965f..2091e67dc 100644
--- a/src/main/scala/leon/synthesis/rules/OnePoint.scala
+++ b/src/main/scala/leon/synthesis/rules/OnePoint.scala
@@ -4,6 +4,7 @@ package leon
 package synthesis
 package rules
 
+import purescala.Common._
 import purescala.Trees._
 import purescala.TreeOps._
 import purescala.Extractors._
@@ -12,10 +13,14 @@ case object OnePoint extends NormalizingRule("One-point") {
   def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
     val TopLevelAnds(exprs) = p.phi
 
+    def validOnePoint(x: Identifier, e: Expr) = {
+      !(variablesOf(e) contains x) && !usesHoles(e)
+    }
+
     val candidates = exprs.collect {
-      case eq @ Equals(Variable(x), e) if (p.xs contains x) && !(variablesOf(e) contains x) =>
+      case eq @ Equals(Variable(x), e) if (p.xs contains x) && validOnePoint(x, e) =>
         (x, e, eq)
-      case eq @ Equals(e, Variable(x)) if (p.xs contains x) && !(variablesOf(e) contains x) =>
+      case eq @ Equals(e, Variable(x)) if (p.xs contains x) && validOnePoint(x, e) =>
         (x, e, eq)
     }
 
diff --git a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala
index f5cdb08ac..148085a5a 100644
--- a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala
+++ b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala
@@ -14,7 +14,7 @@ import solvers._
 case object OptimisticGround extends Rule("Optimistic Ground") {
   def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
     if (!p.as.isEmpty && !p.xs.isEmpty) {
-      val res = new RuleInstantiation(p, this, SolutionBuilder.none, this.name) {
+      val res = new RuleInstantiation(p, this, SolutionBuilder.none, this.name, this.priority) {
         def apply(sctx: SynthesisContext) = {
 
           val solver = SimpleSolverAPI(sctx.fastSolverFactory) // Optimistic ground is given a simple solver (uninterpreted)
diff --git a/src/main/scala/leon/utils/OracleTraverser.scala b/src/main/scala/leon/utils/OracleTraverser.scala
new file mode 100644
index 000000000..d70d1fb5d
--- /dev/null
+++ b/src/main/scala/leon/utils/OracleTraverser.scala
@@ -0,0 +1,32 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+
+package leon
+package utils
+
+import purescala.Trees._
+import purescala.TypeTrees._
+import purescala.Definitions._
+import utils._
+
+case class OracleTraverser(oracle: Expr, tpe: TypeTree, program: Program) {
+  private def call(name: String) = {
+    program.definedFunctions.find(_.id.name == "Oracle."+name) match {
+      case Some(fd) =>
+        FunctionInvocation(fd.typed(List(tpe)), List(oracle))
+      case None =>
+        sys.error("Unable to find Oracle."+name)
+    }
+  }
+
+  def value: Expr = {
+    call("head")
+  }
+
+  def left: OracleTraverser = {
+    OracleTraverser(call("left"), tpe, program)
+  }
+
+  def right: OracleTraverser = {
+    OracleTraverser(call("right"), tpe, program)
+  }
+}
diff --git a/src/main/scala/leon/utils/PreprocessingPhase.scala b/src/main/scala/leon/utils/PreprocessingPhase.scala
new file mode 100644
index 000000000..896e16c78
--- /dev/null
+++ b/src/main/scala/leon/utils/PreprocessingPhase.scala
@@ -0,0 +1,24 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+
+package leon
+package utils
+
+import purescala.Definitions.Program
+
+import purescala.{MethodLifting, CompleteAbstractDefinitions}
+
+object PreprocessingPhase extends TransformationPhase {
+
+  val name = "preprocessing"
+  val description = "Various preprocessings on Leon programs"
+
+  def apply(ctx: LeonContext, p: Program): Program = {
+
+    val phases =
+      MethodLifting                 andThen
+      TypingPhase                   andThen
+      CompleteAbstractDefinitions
+
+    phases.run(ctx)(p)
+  }
+}
diff --git a/src/main/scala/leon/utils/TypingPhase.scala b/src/main/scala/leon/utils/TypingPhase.scala
index 1dc7b5616..a3e1f3e61 100644
--- a/src/main/scala/leon/utils/TypingPhase.scala
+++ b/src/main/scala/leon/utils/TypingPhase.scala
@@ -24,6 +24,8 @@ object TypingPhase extends LeonPhase[Program, Program] {
    *
    * 2) Report warnings in case parts of the tree are not correctly typed
    *    (Untyped).
+   * 
+   * 3) Make sure that abstract classes have at least one descendent
    */
   def run(ctx: LeonContext)(pgm: Program): Program = {
     pgm.definedFunctions.foreach(fd => {
@@ -63,12 +65,24 @@ object TypingPhase extends LeonPhase[Program, Program] {
       fd.body.foreach {
         preTraversal{
           case t if !t.isTyped =>
-            ctx.reporter.warning("Tree "+t.asString(ctx)+" is not properly typed ("+t.getPos.fullString+")")
+            ctx.reporter.warning(t.getPos, "Tree "+t.asString(ctx)+" is not properly typed ("+t.getPos.fullString+")")
           case _ =>
         }
       }
 
+
     })
+
+    // Part (3)
+    pgm.definedClasses.foreach {
+      case acd: AbstractClassDef =>
+        if (acd.knownCCDescendents.isEmpty) {
+          ctx.reporter.error(acd.getPos, "Class "+acd.id.asString(ctx)+" has no concrete descendent!")
+        }
+      case _ =>
+    }
+
+
     pgm
   }
 
diff --git a/src/main/scala/leon/verification/AnalysisPhase.scala b/src/main/scala/leon/verification/AnalysisPhase.scala
index 7b1a1bea3..17d0222b3 100644
--- a/src/main/scala/leon/verification/AnalysisPhase.scala
+++ b/src/main/scala/leon/verification/AnalysisPhase.scala
@@ -27,7 +27,7 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
     LeonValueOptionDef("timeout",   "--timeout=T",       "Timeout after T seconds when trying to prove a verification condition.")
   )
 
-  def generateVerificationConditions(vctx: VerificationContext, functionsToAnalyse: Set[String]): Map[FunDef, List[VerificationCondition]] = {
+  def generateVerificationConditions(vctx: VerificationContext, filterFuns: Option[Seq[String]]): Map[FunDef, List[VerificationCondition]] = {
 
     import vctx.reporter
     import vctx.program
@@ -39,25 +39,20 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
 
     var allVCs = Map[FunDef, List[VerificationCondition]]()
 
-    val patterns = functionsToAnalyse.map{ s =>
-      import java.util.regex.Pattern
-
-      val p = s.replaceAll("\\.", "\\\\.").replaceAll("_", ".+")
-      Pattern.compile(p)
+    def excludeByDefault(fd: FunDef): Boolean = {
+      (fd.annotations contains "verified") || (fd.annotations contains "library")
     }
 
-    def markedForVerification(name: String): Boolean = {
-      patterns.exists(p => p.matcher(name).matches())
-    }
+    val fdFilter = {
+      import OptionsHelpers._
 
-    val toVerify = program.definedFunctions.toList.sortWith((fd1, fd2) => fd1.getPos < fd2.getPos).filter {
-      fd =>
-        (functionsToAnalyse.isEmpty && !(fd.annotations contains "verified")) || 
-        (markedForVerification(fd.id.name))
+      filterInclusive(filterFuns.map(fdMatcher), Some(excludeByDefault _))
     }
 
+    val toVerify = program.definedFunctions.toList.sortWith((fd1, fd2) => fd1.getPos < fd2.getPos).filter(fdFilter)
+
     for(funDef <- toVerify) {
-      if (funDef.annotations contains "verified") {
+      if (excludeByDefault(funDef)) {
         reporter.warning("Forcing verification of "+funDef.id.name+" which was assumed verified")
       }
 
@@ -156,9 +151,9 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
   }
 
   def run(ctx: LeonContext)(program: Program) : VerificationReport = {
-    var functionsToAnalyse   = Set[String]()
-    var timeout: Option[Int] = None
-    var selectedSolvers      = Set[String]("fairz3")
+    var filterFuns: Option[Seq[String]] = None
+    var timeout: Option[Int]             = None
+    var selectedSolvers                  = Set[String]("fairz3")
 
     val allSolvers = Map(
       "fairz3" -> SolverFactory(() => new FairZ3Solver(ctx, program) with TimeoutSolver),
@@ -169,7 +164,7 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
 
     for(opt <- ctx.options) opt match {
       case LeonValueOption("functions", ListValue(fs)) =>
-        functionsToAnalyse = Set() ++ fs
+        filterFuns = Some(fs)
 
       case LeonValueOption("solvers", ListValue(ss)) =>
         val unknownSolvers = ss.toSet -- allSolvers.keySet
@@ -206,7 +201,7 @@ object AnalysisPhase extends LeonPhase[Program,VerificationReport] {
     val vctx = VerificationContext(ctx, program, mainSolver, reporter)
 
     reporter.debug("Running verification condition generation...")
-    val vcs = generateVerificationConditions(vctx, functionsToAnalyse)
+    val vcs = generateVerificationConditions(vctx, filterFuns)
     checkVerificationConditions(vctx, vcs)
   }
 }
diff --git a/src/main/scala/leon/verification/InductionTactic.scala b/src/main/scala/leon/verification/InductionTactic.scala
index df08846ca..70824c7ed 100644
--- a/src/main/scala/leon/verification/InductionTactic.scala
+++ b/src/main/scala/leon/verification/InductionTactic.scala
@@ -64,7 +64,7 @@ class InductionTactic(reporter: Reporter) extends DefaultTactic(reporter) {
         }
 
       case None =>
-        reporter.warning("Could not find abstract class type argument to induct on")
+        reporter.warning(funDef.getPos, "Could not find abstract class type argument to induct on")
         super.generatePostconditions(funDef)
     }
   }
@@ -132,7 +132,7 @@ class InductionTactic(reporter: Reporter) extends DefaultTactic(reporter) {
         toRet
       }
       case None => {
-        reporter.warning("Induction tactic currently supports exactly one argument of abstract class type")
+        reporter.warning(function.getPos, "Induction tactic currently supports exactly one argument of abstract class type")
         defaultPrec
       }
     }
diff --git a/src/test/resources/regression/synthesis/Church/Add.scala b/src/test/resources/regression/synthesis/Church/Add.scala
index 542550eb1..d060360c2 100644
--- a/src/test/resources/regression/synthesis/Church/Add.scala
+++ b/src/test/resources/regression/synthesis/Church/Add.scala
@@ -1,6 +1,8 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/src/test/resources/regression/synthesis/Church/Distinct.scala b/src/test/resources/regression/synthesis/Church/Distinct.scala
index c702d3c14..3e503f4ab 100644
--- a/src/test/resources/regression/synthesis/Church/Distinct.scala
+++ b/src/test/resources/regression/synthesis/Church/Distinct.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.synthesis._
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/src/test/resources/regression/synthesis/Church/Mult.scala b/src/test/resources/regression/synthesis/Church/Mult.scala
index 8251e0a2f..39c0286d0 100644
--- a/src/test/resources/regression/synthesis/Church/Mult.scala
+++ b/src/test/resources/regression/synthesis/Church/Mult.scala
@@ -1,6 +1,8 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/src/test/resources/regression/synthesis/Church/Squared.scala b/src/test/resources/regression/synthesis/Church/Squared.scala
index bf390fea7..9328e70ff 100644
--- a/src/test/resources/regression/synthesis/Church/Squared.scala
+++ b/src/test/resources/regression/synthesis/Church/Squared.scala
@@ -1,6 +1,8 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/src/test/resources/regression/synthesis/Holes/Hole1.scala b/src/test/resources/regression/synthesis/Holes/Hole1.scala
new file mode 100644
index 000000000..084185b0e
--- /dev/null
+++ b/src/test/resources/regression/synthesis/Holes/Hole1.scala
@@ -0,0 +1,13 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+
+import leon.lang._
+import leon.annotation._
+import leon.lang.synthesis._
+import leon.collection._
+import leon._
+
+object Hole1 {
+  def largestInt(a: Int, b: Int)(implicit o: Oracle[Boolean]) = {
+    ?(a, b)
+  } ensuring { r => r >= b && r >= a }
+}
diff --git a/src/test/resources/regression/synthesis/Holes/Hole2.scala b/src/test/resources/regression/synthesis/Holes/Hole2.scala
new file mode 100644
index 000000000..3a10748eb
--- /dev/null
+++ b/src/test/resources/regression/synthesis/Holes/Hole2.scala
@@ -0,0 +1,17 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+
+import leon.lang._
+import leon.annotation._
+import leon.lang.synthesis._
+import leon.collection._
+import leon._
+
+object Hole2 {
+  def genList()(implicit o: Oracle[Boolean]): List[Int] = ?(Nil[Int](), Cons[Int](0, genList()(o.right)))
+
+  def listOfSize2(implicit o: Oracle[Boolean]) = {
+    genList()
+  } ensuring {
+    _.size == 2
+  }
+}
diff --git a/src/test/resources/regression/synthesis/List/Delete.scala b/src/test/resources/regression/synthesis/List/Delete.scala
index 113eedb44..02f13ec38 100644
--- a/src/test/resources/regression/synthesis/List/Delete.scala
+++ b/src/test/resources/regression/synthesis/List/Delete.scala
@@ -2,6 +2,7 @@
 
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Delete {
   sealed abstract class List
diff --git a/src/test/resources/regression/synthesis/List/Diff.scala b/src/test/resources/regression/synthesis/List/Diff.scala
index a6bebd642..5ae469ea7 100644
--- a/src/test/resources/regression/synthesis/List/Diff.scala
+++ b/src/test/resources/regression/synthesis/List/Diff.scala
@@ -2,6 +2,7 @@
 
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Diff {
   sealed abstract class List
diff --git a/src/test/resources/regression/synthesis/List/Insert.scala b/src/test/resources/regression/synthesis/List/Insert.scala
index 21a758ece..13c1294d7 100644
--- a/src/test/resources/regression/synthesis/List/Insert.scala
+++ b/src/test/resources/regression/synthesis/List/Insert.scala
@@ -2,6 +2,7 @@
 
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Insert {
   sealed abstract class List
diff --git a/src/test/resources/regression/synthesis/List/Split.scala b/src/test/resources/regression/synthesis/List/Split.scala
index 944ee9d0b..989d509da 100644
--- a/src/test/resources/regression/synthesis/List/Split.scala
+++ b/src/test/resources/regression/synthesis/List/Split.scala
@@ -2,6 +2,7 @@
 
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/src/test/resources/regression/synthesis/List/Union.scala b/src/test/resources/regression/synthesis/List/Union.scala
index 3b3130d7f..a4acf629b 100644
--- a/src/test/resources/regression/synthesis/List/Union.scala
+++ b/src/test/resources/regression/synthesis/List/Union.scala
@@ -2,6 +2,7 @@
 
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Union {
   sealed abstract class List
diff --git a/src/test/resources/regression/verification/purescala/invalid/Choose1.scala b/src/test/resources/regression/verification/purescala/invalid/Choose1.scala
index 74e7f0db5..20d588523 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Choose1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Choose1.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.annotation._
+import leon.lang.synthesis._
 import leon.lang._
 
 object Choose1 {
diff --git a/src/test/resources/regression/verification/purescala/valid/Choose1.scala b/src/test/resources/regression/verification/purescala/valid/Choose1.scala
index 408dafa87..2b033c809 100644
--- a/src/test/resources/regression/verification/purescala/valid/Choose1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Choose1.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.annotation._
+import leon.lang.synthesis._
 import leon.lang._
 
 object Choose1 {
diff --git a/src/test/resources/regression/verification/purescala/valid/IsolatedAbstract.scala b/src/test/resources/regression/verification/purescala/valid/IsolatedAbstract.scala
deleted file mode 100644
index 52077b354..000000000
--- a/src/test/resources/regression/verification/purescala/valid/IsolatedAbstract.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright 2009-2014 EPFL, Lausanne */
-
-import leon.lang._
-import leon.annotation._
-
-object LoneAbstract {
-
-  /* 
-   * create a structure with all these fields
-   */
-  sealed abstract class TrackedFields
-  case class TreeFields(isBST: Boolean)
-
-  /* add this structure to Tree class */
-  sealed abstract class Tree
-  case class Leaf(fields:TreeFields) extends Tree
-  case class Node(left : Tree, value : Int, right: Tree, fields:TreeFields) extends Tree
-
-
-  def foo(): Int = {
-    42
-  } ensuring ( _ > 0 )
-}
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala
index b6eb6a05d..f1878f35d 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon1 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala
index ee620237f..45c4adf79 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon1 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala
index b12fcbbe0..ec44138ca 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon3 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala
index 22beb0849..5437d93b3 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon4 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala
index 75f9dd813..18eb98709 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon5 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala
index 0fadb7414..7cdf4fc28 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon6 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Choose1.scala b/src/test/resources/regression/verification/xlang/valid/Choose1.scala
index 0ea5e5122..893db3e78 100644
--- a/src/test/resources/regression/verification/xlang/valid/Choose1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Choose1.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.synthesis._
 
 object Test {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala
index 108ea6477..b9af3dc12 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala
index dbdb96c9a..289bdd4d1 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala
index 541933cd8..ece6f7bf0 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon3 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala
index 8b7f7af3b..49cd971fa 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon4 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala
index 565e99ec2..008cef836 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala
@@ -1,6 +1,7 @@
 /* Copyright 2009-2014 EPFL, Lausanne */
 
 import leon.lang._
+import leon.lang.xlang._
 
 object Epsilon5 {
 
diff --git a/src/test/scala/leon/test/LeonTestSuite.scala b/src/test/scala/leon/test/LeonTestSuite.scala
index be5f00802..9b460d584 100644
--- a/src/test/scala/leon/test/LeonTestSuite.scala
+++ b/src/test/scala/leon/test/LeonTestSuite.scala
@@ -35,17 +35,16 @@ trait LeonTestSuite extends FunSuite with Timeouts {
   }
 
 
+  def createLeonContext(opts: String*): LeonContext = {
+    val reporter = new TestSilentReporter
+
+    Main.processOptions(opts.toList).copy(reporter = reporter, interruptManager = new InterruptManager(reporter))
+  }
+
   var testContext = generateContext
 
   def generateContext = {
-    val reporter = new TestSilentReporter
-
-    LeonContext(
-      settings = Settings(),
-      files = List(),
-      reporter = reporter,
-      interruptManager = new InterruptManager(reporter)
-    )
+    createLeonContext()
   }
 
   def testIdentifier(name: String): String = {
diff --git a/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala b/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala
index 77237afc0..055eb3ed6 100644
--- a/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala
+++ b/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala
@@ -7,7 +7,7 @@ import leon._
 
 import leon.evaluators._
 
-import leon.utils.TemporaryInputPhase
+import leon.utils.{TemporaryInputPhase, PreprocessingPhase}
 import leon.frontends.scalac.ExtractionPhase
 
 import leon.purescala.Common._
@@ -26,7 +26,7 @@ class EvaluatorsTests extends LeonTestSuite {
   private def prepareEvaluators(implicit ctx : LeonContext, prog : Program) : List[Evaluator] = evaluatorConstructors.map(c => c(leonContext, prog))
 
   private def parseString(str : String) : Program = {
-    val pipeline = TemporaryInputPhase andThen ExtractionPhase
+    val pipeline = TemporaryInputPhase andThen ExtractionPhase andThen PreprocessingPhase
 
     val errorsBefore   = leonContext.reporter.errorCount
     val warningsBefore = leonContext.reporter.warningCount
@@ -431,6 +431,7 @@ class EvaluatorsTests extends LeonTestSuite {
   test("Executing Chooses") {
     val p = """|object Program {
                |  import leon.lang._
+               |  import leon.lang.synthesis._
                |
                |  def c(i : Int) : Int = choose { (j : Int) => j > i && j < i + 2 }
                |}
diff --git a/src/test/scala/leon/test/purescala/DataGen.scala b/src/test/scala/leon/test/purescala/DataGen.scala
index c9b19e5e4..9259e483a 100644
--- a/src/test/scala/leon/test/purescala/DataGen.scala
+++ b/src/test/scala/leon/test/purescala/DataGen.scala
@@ -4,7 +4,7 @@ package leon.test
 package purescala
 
 import leon._
-import leon.utils.TemporaryInputPhase
+import leon.utils.{TemporaryInputPhase, PreprocessingPhase}
 import leon.frontends.scalac.ExtractionPhase
 
 import leon.purescala.Common._
@@ -19,7 +19,7 @@ import org.scalatest.FunSuite
 
 class DataGen extends LeonTestSuite {
   private def parseString(str : String) : Program = {
-    val pipeline = TemporaryInputPhase andThen ExtractionPhase
+    val pipeline = TemporaryInputPhase andThen ExtractionPhase andThen PreprocessingPhase
 
     val errorsBefore   = testContext.reporter.errorCount
     val warningsBefore = testContext.reporter.warningCount
@@ -67,15 +67,19 @@ class DataGen extends LeonTestSuite {
     generator.generate(BooleanType).toSet.size === 2
     generator.generate(TupleType(Seq(BooleanType,BooleanType))).toSet.size === 4
 
-    val listType : TypeTree = classDefToClassType(prog.classHierarchyRoots.head)
-    val sizeDef    : FunDef = prog.definedFunctions.find(_.id.name == "size").get
-    val sortedDef  : FunDef = prog.definedFunctions.find(_.id.name == "isSorted").get
-    val contentDef : FunDef = prog.definedFunctions.find(_.id.name == "content").get
-    val insSpecDef : FunDef = prog.definedFunctions.find(_.id.name == "insertSpec").get
+    // Make sure we target our own lists
+    val module = prog.modules.find(_.id.name == "Program").get
+    val listType : TypeTree = classDefToClassType(module.classHierarchyRoots.head)
+    val sizeDef    : FunDef = module.definedFunctions.find(_.id.name == "size").get
+    val sortedDef  : FunDef = module.definedFunctions.find(_.id.name == "isSorted").get
+    val contentDef : FunDef = module.definedFunctions.find(_.id.name == "content").get
+    val insSpecDef : FunDef = module.definedFunctions.find(_.id.name == "insertSpec").get
 
-    val consDef : CaseClassDef = prog.caseClassDef("Cons")
+    val consDef : CaseClassDef = module.definedClasses.collect {
+      case ccd: CaseClassDef if ccd.id.name == "Cons" => ccd
+    }.head
 
-    generator.generate(listType).take(100).toSet.size === 100
+    assert(generator.generate(listType).take(100).toSet.size === 100, "Should be able to generate 100 different lists")
 
     val evaluator = new CodeGenEvaluator(testContext, prog)
 
@@ -95,14 +99,14 @@ class DataGen extends LeonTestSuite {
       GreaterThan(sizeX, IntLiteral(0)),
       10,
       500
-    ).size === 10)
+    ).size === 10, "Should find 10 non-empty lists in the first 500 enumerated")
 
     assert(generator.generateFor(
       Seq(x.id, y.id),
       And(Equals(contentX, contentY), sortedY),
       10,
       500
-    ).size === 10)
+    ).size === 10, "Should find 2x 10 lists with same content in the first 500 enumerated")
 
     assert(generator.generateFor(
       Seq(x.id, y.id),
diff --git a/src/test/scala/leon/test/purescala/TransformationTests.scala b/src/test/scala/leon/test/purescala/TransformationTests.scala
index e358e1436..d3123f4d2 100644
--- a/src/test/scala/leon/test/purescala/TransformationTests.scala
+++ b/src/test/scala/leon/test/purescala/TransformationTests.scala
@@ -4,7 +4,7 @@ package leon.test
 package purescala
 
 import leon._
-import leon.utils.TemporaryInputPhase
+import leon.utils.{TemporaryInputPhase, PreprocessingPhase}
 import leon.frontends.scalac.ExtractionPhase
 
 import leon.purescala.ScalaPrinter
@@ -16,7 +16,7 @@ import leon.purescala.TypeTrees._
 
 class TransformationTests extends LeonTestSuite {
 
-  val pipeline = ExtractionPhase andThen leon.utils.TypingPhase
+  val pipeline = ExtractionPhase andThen PreprocessingPhase
 
   filesInResourceDir("regression/transformations").foreach { file =>
     val ctx = testContext.copy(
diff --git a/src/test/scala/leon/test/synthesis/SynthesisRegressionSuite.scala b/src/test/scala/leon/test/synthesis/SynthesisRegressionSuite.scala
index 38971a80b..32eee19c2 100644
--- a/src/test/scala/leon/test/synthesis/SynthesisRegressionSuite.scala
+++ b/src/test/scala/leon/test/synthesis/SynthesisRegressionSuite.scala
@@ -25,15 +25,12 @@ class SynthesisRegressionSuite extends LeonTestSuite {
   }
 
   private def testSynthesis(cat: String, f: File, bound: Int) {
-    val ctx = testContext.copy(settings = Settings(
-        synthesis = true,
-        xlang     = false,
-        verify    = false
-      ))
 
-    val opts = SynthesisOptions(searchBound = Some(bound))
+    val ctx = createLeonContext("--synthesis", "--library")
 
-    val pipeline = frontends.scalac.ExtractionPhase andThen leon.utils.TypingPhase
+    val opts = SynthesisOptions(searchBound = Some(bound), allSeeing = true)
+
+    val pipeline = frontends.scalac.ExtractionPhase andThen leon.utils.PreprocessingPhase
 
     val program = pipeline.run(ctx)(f.getAbsolutePath :: Nil)
 
@@ -57,11 +54,7 @@ class SynthesisRegressionSuite extends LeonTestSuite {
     testSynthesis("List", f, 200)
   }
 
-  //forEachFileIn("regression/synthesis/SortedList/") { f =>
-  //  testSynthesis("SortedList", f, 400)
-  //}
-
-  //forEachFileIn("regression/synthesis/StrictSortedList/") { f =>
-  //  testSynthesis("StrictSortedList", f, 400)
-  //}
+  forEachFileIn("regression/synthesis/Holes/") { f =>
+    testSynthesis("Holes", f, 1000)
+  }
 }
diff --git a/src/test/scala/leon/test/synthesis/SynthesisSuite.scala b/src/test/scala/leon/test/synthesis/SynthesisSuite.scala
index b7cefba50..ab07f8116 100644
--- a/src/test/scala/leon/test/synthesis/SynthesisSuite.scala
+++ b/src/test/scala/leon/test/synthesis/SynthesisSuite.scala
@@ -11,6 +11,7 @@ import leon.solvers.z3._
 import leon.solvers.Solver
 import leon.synthesis._
 import leon.synthesis.utils._
+import leon.utils.PreprocessingPhase
 
 import org.scalatest.matchers.ShouldMatchers._
 
@@ -31,34 +32,34 @@ class SynthesisSuite extends LeonTestSuite {
         verify    = false
       ))
 
-    val pipeline = leon.utils.TemporaryInputPhase andThen leon.frontends.scalac.ExtractionPhase andThen SynthesisProblemExtractionPhase
+    try {
+      val pipeline = leon.utils.TemporaryInputPhase andThen leon.frontends.scalac.ExtractionPhase andThen PreprocessingPhase andThen SynthesisProblemExtractionPhase
 
-    val (program, results) = pipeline.run(ctx)((content, Nil))
+      val (program, results) = pipeline.run(ctx)((content, Nil))
 
-    for ((f, ps) <- results; p <- ps) {
-      test("Synthesizing %3d: %-20s [%s]".format(nextInt(), f.id.toString, title)) {
-        val sctx = SynthesisContext(ctx,
-                                    opts,
-                                    Some(f),
-                                    program,
-                                    ctx.reporter)
+      for ((f, ps) <- results; p <- ps) {
+        test("Synthesizing %3d: %-20s [%s]".format(nextInt(), f.id.toString, title)) {
+          val sctx = SynthesisContext(ctx,
+                                      opts,
+                                      Some(f),
+                                      program,
+                                      ctx.reporter)
 
-        block(sctx, f, p)
+          block(sctx, f, p)
+        }
       }
+    } catch {
+      case lfe: LeonFatalError =>
+        test("Synthesizing %3d: %-20s [%s]".format(nextInt(), "", title)) {
+          assert(false, "Failed to compile "+title)
+        }
     }
   }
 
   case class Apply(desc: String, andThen: List[Apply] = Nil)
 
   def synthesizeWith(sctx: SynthesisContext, p: Problem, ss: Apply): Solution = {
-    val (normRules, otherRules) = sctx.options.rules.partition(_.isInstanceOf[NormalizingRule])
-    val normApplications = normRules.flatMap(_.instantiateOn(sctx, p))
-
-    val apps = if (!normApplications.isEmpty) {
-      normApplications
-    } else {
-      otherRules.flatMap { r => r.instantiateOn(sctx, p) }
-    }
+    val apps = Rules.getInstantiations(sctx, p)
 
     def matchingDesc(app: RuleInstantiation, ss: Apply): Boolean = {
       import java.util.regex.Pattern;
@@ -123,9 +124,9 @@ class SynthesisSuite extends LeonTestSuite {
 
   forProgram("Ground Enum", SynthesisOptions(selectedSolvers = Set("enum")))(
     """
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Injection {
   sealed abstract class List
@@ -148,9 +149,9 @@ object Injection {
 
   forProgram("Cegis 1")(
     """
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Injection {
   sealed abstract class List
@@ -173,9 +174,9 @@ object Injection {
 
   forProgram("Cegis 2")(
     """
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Injection {
   sealed abstract class List
@@ -212,6 +213,7 @@ object Injection {
 
   synthesize("Lists")("""
 import leon.lang._
+import leon.lang.synthesis._
 
 object SortedList {
   sealed abstract class List
@@ -277,6 +279,8 @@ object SortedList {
 
   synthesize("Church")("""
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
@@ -310,6 +314,8 @@ object ChurchNumerals {
 
   synthesize("Church")("""
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/src/test/scala/leon/test/termination/TerminationRegression.scala b/src/test/scala/leon/test/termination/TerminationRegression.scala
index 6fa590904..65f20d036 100644
--- a/src/test/scala/leon/test/termination/TerminationRegression.scala
+++ b/src/test/scala/leon/test/termination/TerminationRegression.scala
@@ -17,7 +17,7 @@ class TerminationRegression extends LeonTestSuite {
   private case class Output(report : TerminationReport, reporter : Reporter)
 
   private def mkPipeline : Pipeline[List[String],TerminationReport] =
-    leon.frontends.scalac.ExtractionPhase andThen leon.utils.TypingPhase andThen leon.termination.TerminationPhase
+    leon.frontends.scalac.ExtractionPhase andThen leon.utils.PreprocessingPhase andThen leon.termination.TerminationPhase
 
   private def mkTest(file : File, leonOptions: Seq[LeonOption], forError: Boolean)(block: Output=>Unit) = {
     val fullName = file.getPath()
diff --git a/src/test/scala/leon/test/verification/LibraryVerificationRegression.scala b/src/test/scala/leon/test/verification/LibraryVerificationRegression.scala
index bf54de007..a1d7c2690 100644
--- a/src/test/scala/leon/test/verification/LibraryVerificationRegression.scala
+++ b/src/test/scala/leon/test/verification/LibraryVerificationRegression.scala
@@ -6,13 +6,15 @@ package verification
 
 import java.io.File
 
+import leon.frontends.scalac.ExtractionPhase
+import leon.utils.PreprocessingPhase
+import leon.verification.AnalysisPhase
+
 class LibraryVerificationRegression extends LeonTestSuite {
   test("Verify the library") {
-      val pipeline = leon.frontends.scalac.ExtractionPhase andThen
-                     leon.purescala.MethodLifting andThen
-                     leon.utils.TypingPhase andThen
-                     leon.purescala.CompleteAbstractDefinitions andThen
-                     leon.verification.AnalysisPhase
+      val pipeline = ExtractionPhase    andThen
+                     PreprocessingPhase andThen
+                     AnalysisPhase
 
       val ctx = Main.processOptions(Seq("--library", "--functions=_")).copy(reporter = new TestSilentReporter())
 
diff --git a/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala b/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
index 18d39fa76..4bfd35e92 100644
--- a/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
+++ b/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
@@ -6,6 +6,9 @@ package verification
 
 import leon.verification.{AnalysisPhase,VerificationReport}
 
+import leon.frontends.scalac.ExtractionPhase
+import leon.utils.PreprocessingPhase
+
 import java.io.File
 
 class PureScalaVerificationRegression extends LeonTestSuite {
@@ -16,8 +19,10 @@ class PureScalaVerificationRegression extends LeonTestSuite {
   }
   private case class Output(report : VerificationReport, reporter : Reporter)
 
-  private def mkPipeline : Pipeline[List[String],VerificationReport] =
-    leon.frontends.scalac.ExtractionPhase andThen leon.utils.TypingPhase andThen leon.verification.AnalysisPhase
+  private def mkPipeline : Pipeline[List[String], VerificationReport] =
+    ExtractionPhase     andThen 
+    PreprocessingPhase  andThen 
+    AnalysisPhase
 
   private def mkTest(file : File, leonOptions : Seq[LeonOption], forError: Boolean)(block: Output=>Unit) = {
     val fullName = file.getPath()
diff --git a/src/test/scala/leon/test/verification/XLangVerificationRegression.scala b/src/test/scala/leon/test/verification/XLangVerificationRegression.scala
index 89eaaca64..726b039e0 100644
--- a/src/test/scala/leon/test/verification/XLangVerificationRegression.scala
+++ b/src/test/scala/leon/test/verification/XLangVerificationRegression.scala
@@ -4,7 +4,10 @@ package leon
 package test
 package verification
 
-import leon.verification.{AnalysisPhase,VerificationReport}
+import leon.verification.VerificationReport
+import leon.xlang.XlangAnalysisPhase
+import leon.frontends.scalac.ExtractionPhase
+import leon.utils.PreprocessingPhase
 
 import java.io.File
 
@@ -17,7 +20,9 @@ class XLangVerificationRegression extends LeonTestSuite {
   private case class Output(report : VerificationReport, reporter : Reporter)
 
   private def mkPipeline : Pipeline[List[String],VerificationReport] =
-    leon.frontends.scalac.ExtractionPhase andThen leon.utils.TypingPhase andThen xlang.XlangAnalysisPhase
+    ExtractionPhase     andThen
+    PreprocessingPhase  andThen
+    XlangAnalysisPhase
 
   private def mkTest(file : File, forError: Boolean = false)(block: Output=>Unit) = {
     val fullName = file.getPath()
diff --git a/testcases/case-studies/Lambda.scala b/testcases/case-studies/Lambda.scala
index ecc82053d..05df4cf57 100644
--- a/testcases/case-studies/Lambda.scala
+++ b/testcases/case-studies/Lambda.scala
@@ -1,6 +1,7 @@
 import leon.lang._
 import leon.annotation._
 import leon.collection._
+import leon.lang.synthesis._
 import leon._
 
 object Lang {
diff --git a/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBook.scala b/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBook.scala
index ccd1d6ad3..e7067c756 100644
--- a/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBook.scala
+++ b/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBook.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBookWithHelpers.scala b/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBookWithHelpers.scala
index f04399105..3dfd21465 100644
--- a/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBookWithHelpers.scala
+++ b/testcases/condabd/benchmarks/AddressBook/AddressesMakeAddressBookWithHelpers.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   
diff --git a/testcases/condabd/benchmarks/AddressBook/AddressesMergeAddressBooks.scala b/testcases/condabd/benchmarks/AddressBook/AddressesMergeAddressBooks.scala
index a9154bc76..8436ef25f 100644
--- a/testcases/condabd/benchmarks/AddressBook/AddressesMergeAddressBooks.scala
+++ b/testcases/condabd/benchmarks/AddressBook/AddressesMergeAddressBooks.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueCheckf.scala b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueCheckf.scala
index 52e582ffb..7d85a2c9b 100644
--- a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueCheckf.scala
+++ b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueCheckf.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object BatchedQueue {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnoc.scala b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnoc.scala
index 26e70e649..c595f8253 100644
--- a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnoc.scala
+++ b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnoc.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object BatchedQueue {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnocWeird.scala b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnocWeird.scala
index f74b8d8ea..2a82511d5 100644
--- a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnocWeird.scala
+++ b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueSnocWeird.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object BatchedQueue {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueTail.scala b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueTail.scala
index 31b67f6a8..4c7d22df9 100644
--- a/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueTail.scala
+++ b/testcases/condabd/benchmarks/BatchedQueue/BatchedQueueTail.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object BatchedQueue {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/BinarySearch.scala b/testcases/condabd/benchmarks/BinarySearch.scala
index b8883a3bb..40f91c988 100644
--- a/testcases/condabd/benchmarks/BinarySearch.scala
+++ b/testcases/condabd/benchmarks/BinarySearch.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinarySearch {
 
diff --git a/testcases/condabd/benchmarks/BinarySearchTree/BinarySearchTreeMember.scala b/testcases/condabd/benchmarks/BinarySearchTree/BinarySearchTreeMember.scala
index 5ca4fb8c3..661e02e5c 100644
--- a/testcases/condabd/benchmarks/BinarySearchTree/BinarySearchTreeMember.scala
+++ b/testcases/condabd/benchmarks/BinarySearchTree/BinarySearchTreeMember.scala
@@ -1,7 +1,6 @@
-import scala.collection.immutable.Set
-
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinarySearchTree {
   sealed abstract class Tree
diff --git a/testcases/condabd/benchmarks/InsertionSort/InsertionSortInsert.scala b/testcases/condabd/benchmarks/InsertionSort/InsertionSortInsert.scala
index 7afa8f2b8..7aa7fdd52 100644
--- a/testcases/condabd/benchmarks/InsertionSort/InsertionSortInsert.scala
+++ b/testcases/condabd/benchmarks/InsertionSort/InsertionSortInsert.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object InsertionSort {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/InsertionSort/InsertionSortSort.scala b/testcases/condabd/benchmarks/InsertionSort/InsertionSortSort.scala
index 823011be4..21fc426ca 100644
--- a/testcases/condabd/benchmarks/InsertionSort/InsertionSortSort.scala
+++ b/testcases/condabd/benchmarks/InsertionSort/InsertionSortSort.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object InsertionSort {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/List/ListConcat.scala b/testcases/condabd/benchmarks/List/ListConcat.scala
index 271082886..a4c452345 100644
--- a/testcases/condabd/benchmarks/List/ListConcat.scala
+++ b/testcases/condabd/benchmarks/List/ListConcat.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object ListOperations {
     sealed abstract class List
diff --git a/testcases/condabd/benchmarks/MergeSort/MergeSortMerge.scala b/testcases/condabd/benchmarks/MergeSort/MergeSortMerge.scala
index c43a3c598..1fadb1d80 100644
--- a/testcases/condabd/benchmarks/MergeSort/MergeSortMerge.scala
+++ b/testcases/condabd/benchmarks/MergeSort/MergeSortMerge.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object MergeSort {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/MergeSort/MergeSortSort.scala b/testcases/condabd/benchmarks/MergeSort/MergeSortSort.scala
index e96b37543..feff019ed 100644
--- a/testcases/condabd/benchmarks/MergeSort/MergeSortSort.scala
+++ b/testcases/condabd/benchmarks/MergeSort/MergeSortSort.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object MergeSort {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/MergeSort/MergeSortSortWithVal.scala b/testcases/condabd/benchmarks/MergeSort/MergeSortSortWithVal.scala
index 8df35ea8f..2f59d1ca5 100644
--- a/testcases/condabd/benchmarks/MergeSort/MergeSortSortWithVal.scala
+++ b/testcases/condabd/benchmarks/MergeSort/MergeSortSortWithVal.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object MergeSort {
   sealed abstract class List
diff --git a/testcases/condabd/benchmarks/RedBlackTree/RedBlackTreeInsert.scala b/testcases/condabd/benchmarks/RedBlackTree/RedBlackTreeInsert.scala
index b32b6165a..b6336fab5 100644
--- a/testcases/condabd/benchmarks/RedBlackTree/RedBlackTreeInsert.scala
+++ b/testcases/condabd/benchmarks/RedBlackTree/RedBlackTreeInsert.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object RedBlackTree {
   sealed abstract class Color
diff --git a/testcases/condabd/test/insynth/Addresses.scala b/testcases/condabd/test/insynth/Addresses.scala
index 8a958cca4..48fa32d73 100644
--- a/testcases/condabd/test/insynth/Addresses.scala
+++ b/testcases/condabd/test/insynth/Addresses.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   
diff --git a/testcases/condabd/test/insynth/AddressesWithAddition.scala b/testcases/condabd/test/insynth/AddressesWithAddition.scala
index c5df95077..b9371603a 100644
--- a/testcases/condabd/test/insynth/AddressesWithAddition.scala
+++ b/testcases/condabd/test/insynth/AddressesWithAddition.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object AddressesWithAddition {
   
diff --git a/testcases/condabd/test/insynth/ListConcat.scala b/testcases/condabd/test/insynth/ListConcat.scala
index 3091e9e47..bce1c20ea 100644
--- a/testcases/condabd/test/insynth/ListConcat.scala
+++ b/testcases/condabd/test/insynth/ListConcat.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object ListOperations {
 
diff --git a/testcases/condabd/test/lesynth/Addresses.scala b/testcases/condabd/test/lesynth/Addresses.scala
index 8a958cca4..848707311 100644
--- a/testcases/condabd/test/lesynth/Addresses.scala
+++ b/testcases/condabd/test/lesynth/Addresses.scala
@@ -1,5 +1,5 @@
-import scala.collection.immutable.Set
 import leon.annotation._
+import leon.lang.synthesis._
 import leon.lang._
 
 object Addresses {
diff --git a/testcases/condabd/test/lesynth/AddressesMergeAddressBooks.scala b/testcases/condabd/test/lesynth/AddressesMergeAddressBooks.scala
index a9154bc76..8436ef25f 100644
--- a/testcases/condabd/test/lesynth/AddressesMergeAddressBooks.scala
+++ b/testcases/condabd/test/lesynth/AddressesMergeAddressBooks.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/condabd/test/lesynth/BinarySearchTree.scala b/testcases/condabd/test/lesynth/BinarySearchTree.scala
index fc49d721c..aee07c367 100644
--- a/testcases/condabd/test/lesynth/BinarySearchTree.scala
+++ b/testcases/condabd/test/lesynth/BinarySearchTree.scala
@@ -1,7 +1,6 @@
-import scala.collection.immutable.Set
-
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinarySearchTree {
   sealed abstract class Tree
diff --git a/testcases/condabd/test/lesynth/InsertionSortInsert.scala b/testcases/condabd/test/lesynth/InsertionSortInsert.scala
index 7afa8f2b8..7aa7fdd52 100644
--- a/testcases/condabd/test/lesynth/InsertionSortInsert.scala
+++ b/testcases/condabd/test/lesynth/InsertionSortInsert.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object InsertionSort {
   sealed abstract class List
diff --git a/testcases/condabd/test/lesynth/ListConcat.scala b/testcases/condabd/test/lesynth/ListConcat.scala
index 3091e9e47..bce1c20ea 100644
--- a/testcases/condabd/test/lesynth/ListConcat.scala
+++ b/testcases/condabd/test/lesynth/ListConcat.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object ListOperations {
 
diff --git a/testcases/condabd/test/lesynth/ListConcatVerifierTest.scala b/testcases/condabd/test/lesynth/ListConcatVerifierTest.scala
index d3e1446ff..51876f0d9 100644
--- a/testcases/condabd/test/lesynth/ListConcatVerifierTest.scala
+++ b/testcases/condabd/test/lesynth/ListConcatVerifierTest.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object ListOperations {
     sealed abstract class List
diff --git a/testcases/condabd/test/lesynth/ListConcatWithEmpty.scala b/testcases/condabd/test/lesynth/ListConcatWithEmpty.scala
index 5b6ae3e46..8c6f1662f 100644
--- a/testcases/condabd/test/lesynth/ListConcatWithEmpty.scala
+++ b/testcases/condabd/test/lesynth/ListConcatWithEmpty.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object ListOperations {
     sealed abstract class List
diff --git a/testcases/condabd/test/lesynth/MergeSortSort.scala b/testcases/condabd/test/lesynth/MergeSortSort.scala
index e96b37543..feff019ed 100644
--- a/testcases/condabd/test/lesynth/MergeSortSort.scala
+++ b/testcases/condabd/test/lesynth/MergeSortSort.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object MergeSort {
   sealed abstract class List
diff --git a/testcases/condabd/test/lesynth/RedBlackTreeInsert.scala b/testcases/condabd/test/lesynth/RedBlackTreeInsert.scala
index b32b6165a..b6336fab5 100644
--- a/testcases/condabd/test/lesynth/RedBlackTreeInsert.scala
+++ b/testcases/condabd/test/lesynth/RedBlackTreeInsert.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object RedBlackTree {
   sealed abstract class Color
diff --git a/testcases/graveyard/Choose.scala b/testcases/graveyard/Choose.scala
index 0584edd43..7e69f6d92 100644
--- a/testcases/graveyard/Choose.scala
+++ b/testcases/graveyard/Choose.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object ChooseTest {
 
diff --git a/testcases/graveyard/Sat.scala b/testcases/graveyard/Sat.scala
index 28dd0057e..9e19d4666 100644
--- a/testcases/graveyard/Sat.scala
+++ b/testcases/graveyard/Sat.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object Sat {
 
diff --git a/testcases/runtime/CachedList.scala b/testcases/runtime/CachedList.scala
index bf56ed8d1..031503a9d 100644
--- a/testcases/runtime/CachedList.scala
+++ b/testcases/runtime/CachedList.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object SortedList {
   abstract class List
diff --git a/testcases/runtime/SquareRoot.scala b/testcases/runtime/SquareRoot.scala
index 9b0ea5c49..87b3e985a 100644
--- a/testcases/runtime/SquareRoot.scala
+++ b/testcases/runtime/SquareRoot.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object SquareRoot {
 
diff --git a/testcases/synthesis/ADTInduction.scala b/testcases/synthesis/ADTInduction.scala
index edd5ab101..0824a9928 100644
--- a/testcases/synthesis/ADTInduction.scala
+++ b/testcases/synthesis/ADTInduction.scala
@@ -1,5 +1,5 @@
-import scala.collection.immutable.Set
 import leon.annotation._
+import leon.lang.synthesis._
 import leon.lang._
 
 object SortedList {
diff --git a/testcases/synthesis/BinaryTree.scala b/testcases/synthesis/BinaryTree.scala
index a298ca980..b24a6ddbc 100644
--- a/testcases/synthesis/BinaryTree.scala
+++ b/testcases/synthesis/BinaryTree.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/CegisExamples.scala b/testcases/synthesis/CegisExamples.scala
index 1c077055c..a43a3e948 100644
--- a/testcases/synthesis/CegisExamples.scala
+++ b/testcases/synthesis/CegisExamples.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object CegisTests {
   sealed abstract class List
diff --git a/testcases/synthesis/CegisFunctions.scala b/testcases/synthesis/CegisFunctions.scala
index 3139d130e..92d79426e 100644
--- a/testcases/synthesis/CegisFunctions.scala
+++ b/testcases/synthesis/CegisFunctions.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object CegisTests {
   sealed abstract class List
diff --git a/testcases/synthesis/ChooseArith.scala b/testcases/synthesis/ChooseArith.scala
index bee28c19d..572cf790d 100644
--- a/testcases/synthesis/ChooseArith.scala
+++ b/testcases/synthesis/ChooseArith.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object ChooseArith {
   def c1(a : Int) : (Int, Int) = 
diff --git a/testcases/synthesis/ChooseIneq.scala b/testcases/synthesis/ChooseIneq.scala
index bb5921bea..127b047d3 100644
--- a/testcases/synthesis/ChooseIneq.scala
+++ b/testcases/synthesis/ChooseIneq.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object ChooseIneq {
   def c1(a: Int, b: Int): (Int, Int) = { 
diff --git a/testcases/synthesis/ChoosePos.scala b/testcases/synthesis/ChoosePos.scala
index decf2875d..cdacbd72b 100644
--- a/testcases/synthesis/ChoosePos.scala
+++ b/testcases/synthesis/ChoosePos.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object ChoosePos {
 
diff --git a/testcases/synthesis/ChurchNumerals.scala b/testcases/synthesis/ChurchNumerals.scala
index ba8587410..5f6f6c1cd 100644
--- a/testcases/synthesis/ChurchNumerals.scala
+++ b/testcases/synthesis/ChurchNumerals.scala
@@ -1,4 +1,6 @@
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case class Zero() extends Num
diff --git a/testcases/synthesis/DrSuter.scala b/testcases/synthesis/DrSuter.scala
index 39b5d7edc..42adaa55b 100644
--- a/testcases/synthesis/DrSuter.scala
+++ b/testcases/synthesis/DrSuter.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object DrSuter {
 
diff --git a/testcases/synthesis/FastExp.scala b/testcases/synthesis/FastExp.scala
index c23077128..ef288f3bb 100644
--- a/testcases/synthesis/FastExp.scala
+++ b/testcases/synthesis/FastExp.scala
@@ -1,4 +1,5 @@
 import leon.annotation._
+import leon.lang.synthesis._
 import leon.lang._
 
 object FastExp {
diff --git a/testcases/synthesis/FiniteSort.scala b/testcases/synthesis/FiniteSort.scala
index e4660ebb4..afe827bb7 100644
--- a/testcases/synthesis/FiniteSort.scala
+++ b/testcases/synthesis/FiniteSort.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object FiniteSort {
 
diff --git a/testcases/synthesis/Injection.scala b/testcases/synthesis/Injection.scala
index 43a4be676..5bc7a41b5 100644
--- a/testcases/synthesis/Injection.scala
+++ b/testcases/synthesis/Injection.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Injection {
   sealed abstract class List
diff --git a/testcases/synthesis/InnerSplit.scala b/testcases/synthesis/InnerSplit.scala
index 7b2be7741..1db595ba9 100644
--- a/testcases/synthesis/InnerSplit.scala
+++ b/testcases/synthesis/InnerSplit.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object Test {
   def test(x: Int, y: Int) = choose((z: Int) => z >= x && z >= y && (z == x || z == y))
diff --git a/testcases/synthesis/Justify.scala b/testcases/synthesis/Justify.scala
index 53a362f8a..c396d6a01 100644
--- a/testcases/synthesis/Justify.scala
+++ b/testcases/synthesis/Justify.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object Justify {
 
diff --git a/testcases/synthesis/Matching.scala b/testcases/synthesis/Matching.scala
index 393d64c53..861798cf7 100644
--- a/testcases/synthesis/Matching.scala
+++ b/testcases/synthesis/Matching.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object Matching {
   def t1(a: NatList) = choose( (x: Nat) => Cons(x, Nil()) == a)
diff --git a/testcases/synthesis/NewYearsSong.scala b/testcases/synthesis/NewYearsSong.scala
index 9a25333f5..0bcdf0130 100644
--- a/testcases/synthesis/NewYearsSong.scala
+++ b/testcases/synthesis/NewYearsSong.scala
@@ -1,4 +1,4 @@
-import scala.collection.immutable.Set
+import leon.lang.synthesis._
 import leon.annotation._
 import leon.lang._
 
diff --git a/testcases/synthesis/ScaleWeight.scala b/testcases/synthesis/ScaleWeight.scala
index 6a47e2886..52081df23 100644
--- a/testcases/synthesis/ScaleWeight.scala
+++ b/testcases/synthesis/ScaleWeight.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object ScaleWeight {
 
diff --git a/testcases/synthesis/Sec2Time.scala b/testcases/synthesis/Sec2Time.scala
index 68e5963c5..02ab40320 100644
--- a/testcases/synthesis/Sec2Time.scala
+++ b/testcases/synthesis/Sec2Time.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object Sec2Time {
 
diff --git a/testcases/synthesis/Simple.scala b/testcases/synthesis/Simple.scala
index c8a7e24f8..0f1d8b76b 100644
--- a/testcases/synthesis/Simple.scala
+++ b/testcases/synthesis/Simple.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object SimpleSynthesis {
 
diff --git a/testcases/synthesis/SimplestCegis.scala b/testcases/synthesis/SimplestCegis.scala
index b4b574d64..804279046 100644
--- a/testcases/synthesis/SimplestCegis.scala
+++ b/testcases/synthesis/SimplestCegis.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Injection {
   sealed abstract class List
diff --git a/testcases/synthesis/SortedList.scala b/testcases/synthesis/SortedList.scala
index 378b182ec..b97642ef3 100644
--- a/testcases/synthesis/SortedList.scala
+++ b/testcases/synthesis/SortedList.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SortedList {
   sealed abstract class List
diff --git a/testcases/synthesis/Spt.scala b/testcases/synthesis/Spt.scala
index 22d2457c8..98cb72e9e 100644
--- a/testcases/synthesis/Spt.scala
+++ b/testcases/synthesis/Spt.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 // Examples taken from http://lara.epfl.ch/~psuter/spt/
 object SynthesisProceduresToolkit {
diff --git a/testcases/synthesis/Unification.scala b/testcases/synthesis/Unification.scala
index a73a470c3..121644dec 100644
--- a/testcases/synthesis/Unification.scala
+++ b/testcases/synthesis/Unification.scala
@@ -1,4 +1,5 @@
 import leon.lang._
+import leon.lang.synthesis._
 
 object UnificationSynthesis {
 
diff --git a/testcases/synthesis/cav2013/AVLTree.scala b/testcases/synthesis/cav2013/AVLTree.scala
index b5e7c1dd8..c9b4b116e 100644
--- a/testcases/synthesis/cav2013/AVLTree.scala
+++ b/testcases/synthesis/cav2013/AVLTree.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object AVLTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/cav2013/BinaryTree.scala b/testcases/synthesis/cav2013/BinaryTree.scala
index e8c1bc742..84894af10 100644
--- a/testcases/synthesis/cav2013/BinaryTree.scala
+++ b/testcases/synthesis/cav2013/BinaryTree.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/cav2013/List.scala b/testcases/synthesis/cav2013/List.scala
index 37129a90d..08fcfc4c1 100644
--- a/testcases/synthesis/cav2013/List.scala
+++ b/testcases/synthesis/cav2013/List.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object List {
   sealed abstract class List
diff --git a/testcases/synthesis/cav2013/ListByExample.scala b/testcases/synthesis/cav2013/ListByExample.scala
index 87737d02c..9b450f4ab 100644
--- a/testcases/synthesis/cav2013/ListByExample.scala
+++ b/testcases/synthesis/cav2013/ListByExample.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Lists {
   sealed abstract class List
diff --git a/testcases/synthesis/cav2013/ManyTimeSec.scala b/testcases/synthesis/cav2013/ManyTimeSec.scala
index 2589c99ea..3aba9ecac 100644
--- a/testcases/synthesis/cav2013/ManyTimeSec.scala
+++ b/testcases/synthesis/cav2013/ManyTimeSec.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object ManyTimeSec { 
   case class Time(h:Int,m:Int,s:Int)
diff --git a/testcases/synthesis/cav2013/SortedList.scala b/testcases/synthesis/cav2013/SortedList.scala
index ba9bb3802..32b59d601 100644
--- a/testcases/synthesis/cav2013/SortedList.scala
+++ b/testcases/synthesis/cav2013/SortedList.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SortedList {
   sealed abstract class List
diff --git a/testcases/synthesis/cav2013/Sorting.scala b/testcases/synthesis/cav2013/Sorting.scala
index e031995d5..bdbd870c9 100644
--- a/testcases/synthesis/cav2013/Sorting.scala
+++ b/testcases/synthesis/cav2013/Sorting.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 // Sorting lists is a fundamental problem in CS.
 object Sorting {
diff --git a/testcases/synthesis/cav2013/StrictlySortedList.scala b/testcases/synthesis/cav2013/StrictlySortedList.scala
index efd57e78f..dd6beeb36 100644
--- a/testcases/synthesis/cav2013/StrictlySortedList.scala
+++ b/testcases/synthesis/cav2013/StrictlySortedList.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SortedList {
   sealed abstract class List
diff --git a/testcases/synthesis/cav2013/SynAddresses.scala b/testcases/synthesis/cav2013/SynAddresses.scala
index cf33e9a73..efb9a76a1 100644
--- a/testcases/synthesis/cav2013/SynAddresses.scala
+++ b/testcases/synthesis/cav2013/SynAddresses.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   // list of integers
diff --git a/testcases/synthesis/cav2013/SynTreeListSet.scala b/testcases/synthesis/cav2013/SynTreeListSet.scala
index d5b4d972a..23be38f87 100644
--- a/testcases/synthesis/cav2013/SynTreeListSet.scala
+++ b/testcases/synthesis/cav2013/SynTreeListSet.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   // list of integers
diff --git a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBook.scala b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBook.scala
index 02348024d..cdcb8b1c9 100644
--- a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBook.scala
+++ b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBook.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookStrong.scala b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookStrong.scala
index 9d3087669..5d4a788b8 100644
--- a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookStrong.scala
+++ b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookStrong.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookSynthWrong.scala b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookSynthWrong.scala
index 76537952f..548bb9849 100644
--- a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookSynthWrong.scala
+++ b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookSynthWrong.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookWithHelpers.scala b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookWithHelpers.scala
index 96b1e6fd8..194d194c3 100644
--- a/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookWithHelpers.scala
+++ b/testcases/synthesis/oopsla2013/AddressBook/AddressesMakeAddressBookWithHelpers.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   
diff --git a/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooks.scala b/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooks.scala
index 21fde00c5..a281e7423 100644
--- a/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooks.scala
+++ b/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooks.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep1.scala b/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep1.scala
index 5235d651d..e3b6c8c7e 100644
--- a/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep1.scala
+++ b/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep1.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep2.scala b/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep2.scala
index de45e44e8..6729bbb2d 100644
--- a/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep2.scala
+++ b/testcases/synthesis/oopsla2013/AddressBook/AddressesMergeAddressBooksStep2.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Addresses {
   case class Info(
diff --git a/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueCheckf.scala b/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueCheckf.scala
index 52e582ffb..7d85a2c9b 100644
--- a/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueCheckf.scala
+++ b/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueCheckf.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object BatchedQueue {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueSnoc.scala b/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueSnoc.scala
index 26e70e649..c595f8253 100644
--- a/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueSnoc.scala
+++ b/testcases/synthesis/oopsla2013/BatchedQueue/BatchedQueueSnoc.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object BatchedQueue {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/BinaryTree/Batch.scala b/testcases/synthesis/oopsla2013/BinaryTree/Batch.scala
index 093c645f2..1329aa1fe 100644
--- a/testcases/synthesis/oopsla2013/BinaryTree/Batch.scala
+++ b/testcases/synthesis/oopsla2013/BinaryTree/Batch.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/oopsla2013/BinaryTree/Complete.scala b/testcases/synthesis/oopsla2013/BinaryTree/Complete.scala
index c30bcdf78..c86316773 100644
--- a/testcases/synthesis/oopsla2013/BinaryTree/Complete.scala
+++ b/testcases/synthesis/oopsla2013/BinaryTree/Complete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/oopsla2013/BinaryTree/Delete.scala b/testcases/synthesis/oopsla2013/BinaryTree/Delete.scala
index 38b85a263..905c1aea4 100644
--- a/testcases/synthesis/oopsla2013/BinaryTree/Delete.scala
+++ b/testcases/synthesis/oopsla2013/BinaryTree/Delete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/oopsla2013/BinaryTree/Diff.scala b/testcases/synthesis/oopsla2013/BinaryTree/Diff.scala
index 450cecc28..1b95fabe5 100644
--- a/testcases/synthesis/oopsla2013/BinaryTree/Diff.scala
+++ b/testcases/synthesis/oopsla2013/BinaryTree/Diff.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/oopsla2013/BinaryTree/Insert.scala b/testcases/synthesis/oopsla2013/BinaryTree/Insert.scala
index d0a7e50f3..5a4ce2059 100644
--- a/testcases/synthesis/oopsla2013/BinaryTree/Insert.scala
+++ b/testcases/synthesis/oopsla2013/BinaryTree/Insert.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/oopsla2013/BinaryTree/Union.scala b/testcases/synthesis/oopsla2013/BinaryTree/Union.scala
index 776c21f0d..40d20ec46 100644
--- a/testcases/synthesis/oopsla2013/BinaryTree/Union.scala
+++ b/testcases/synthesis/oopsla2013/BinaryTree/Union.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/oopsla2013/Church/Add.scala b/testcases/synthesis/oopsla2013/Church/Add.scala
index f9374897c..937a13e38 100644
--- a/testcases/synthesis/oopsla2013/Church/Add.scala
+++ b/testcases/synthesis/oopsla2013/Church/Add.scala
@@ -1,4 +1,6 @@
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/testcases/synthesis/oopsla2013/Church/Batch.scala b/testcases/synthesis/oopsla2013/Church/Batch.scala
index 4129382d2..b511b94e6 100644
--- a/testcases/synthesis/oopsla2013/Church/Batch.scala
+++ b/testcases/synthesis/oopsla2013/Church/Batch.scala
@@ -1,4 +1,6 @@
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/testcases/synthesis/oopsla2013/Church/Complete.scala b/testcases/synthesis/oopsla2013/Church/Complete.scala
index 049bf442c..94e94cc21 100644
--- a/testcases/synthesis/oopsla2013/Church/Complete.scala
+++ b/testcases/synthesis/oopsla2013/Church/Complete.scala
@@ -1,4 +1,6 @@
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/testcases/synthesis/oopsla2013/Church/Distinct.scala b/testcases/synthesis/oopsla2013/Church/Distinct.scala
index 9472f04f7..5e718f3a0 100644
--- a/testcases/synthesis/oopsla2013/Church/Distinct.scala
+++ b/testcases/synthesis/oopsla2013/Church/Distinct.scala
@@ -1,4 +1,6 @@
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/testcases/synthesis/oopsla2013/Church/Mult.scala b/testcases/synthesis/oopsla2013/Church/Mult.scala
index bb51979ea..70a6d68f4 100644
--- a/testcases/synthesis/oopsla2013/Church/Mult.scala
+++ b/testcases/synthesis/oopsla2013/Church/Mult.scala
@@ -1,4 +1,6 @@
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/testcases/synthesis/oopsla2013/Church/Squared.scala b/testcases/synthesis/oopsla2013/Church/Squared.scala
index 08a71c462..b5b764d06 100644
--- a/testcases/synthesis/oopsla2013/Church/Squared.scala
+++ b/testcases/synthesis/oopsla2013/Church/Squared.scala
@@ -1,4 +1,6 @@
 import leon.lang._
+import leon.lang.synthesis._
+
 object ChurchNumerals {
   sealed abstract class Num
   case object Z extends Num
diff --git a/testcases/synthesis/oopsla2013/InsertionSort/Insert.scala b/testcases/synthesis/oopsla2013/InsertionSort/Insert.scala
index a79a06133..cff8535f3 100644
--- a/testcases/synthesis/oopsla2013/InsertionSort/Insert.scala
+++ b/testcases/synthesis/oopsla2013/InsertionSort/Insert.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object InsertionSort {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/InsertionSort/Sort.scala b/testcases/synthesis/oopsla2013/InsertionSort/Sort.scala
index 081819ec0..11f930279 100644
--- a/testcases/synthesis/oopsla2013/InsertionSort/Sort.scala
+++ b/testcases/synthesis/oopsla2013/InsertionSort/Sort.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object InsertionSort {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/List/Batch.scala b/testcases/synthesis/oopsla2013/List/Batch.scala
index c19c5347f..c7fcf02d0 100644
--- a/testcases/synthesis/oopsla2013/List/Batch.scala
+++ b/testcases/synthesis/oopsla2013/List/Batch.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object List {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/List/Complete.scala b/testcases/synthesis/oopsla2013/List/Complete.scala
index 9a0a19d84..75377777e 100644
--- a/testcases/synthesis/oopsla2013/List/Complete.scala
+++ b/testcases/synthesis/oopsla2013/List/Complete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/List/Delete.scala b/testcases/synthesis/oopsla2013/List/Delete.scala
index 998249371..a61e312c9 100644
--- a/testcases/synthesis/oopsla2013/List/Delete.scala
+++ b/testcases/synthesis/oopsla2013/List/Delete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Delete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/List/Diff.scala b/testcases/synthesis/oopsla2013/List/Diff.scala
index a6c2c181d..dcf4f372c 100644
--- a/testcases/synthesis/oopsla2013/List/Diff.scala
+++ b/testcases/synthesis/oopsla2013/List/Diff.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Diff {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/List/Insert.scala b/testcases/synthesis/oopsla2013/List/Insert.scala
index 91862f1a6..3f6fcd23a 100644
--- a/testcases/synthesis/oopsla2013/List/Insert.scala
+++ b/testcases/synthesis/oopsla2013/List/Insert.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Insert {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/List/Split.scala b/testcases/synthesis/oopsla2013/List/Split.scala
index 649f0b8b1..e02c0a7a0 100644
--- a/testcases/synthesis/oopsla2013/List/Split.scala
+++ b/testcases/synthesis/oopsla2013/List/Split.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/List/Union.scala b/testcases/synthesis/oopsla2013/List/Union.scala
index c92d0c6c0..17dda5cfd 100644
--- a/testcases/synthesis/oopsla2013/List/Union.scala
+++ b/testcases/synthesis/oopsla2013/List/Union.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Union {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/MergeSort/MergeSortSort.scala b/testcases/synthesis/oopsla2013/MergeSort/MergeSortSort.scala
index e96b37543..feff019ed 100644
--- a/testcases/synthesis/oopsla2013/MergeSort/MergeSortSort.scala
+++ b/testcases/synthesis/oopsla2013/MergeSort/MergeSortSort.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object MergeSort {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/MergeSort/MergeSortSortWithVal.scala b/testcases/synthesis/oopsla2013/MergeSort/MergeSortSortWithVal.scala
index 8df35ea8f..2f59d1ca5 100644
--- a/testcases/synthesis/oopsla2013/MergeSort/MergeSortSortWithVal.scala
+++ b/testcases/synthesis/oopsla2013/MergeSort/MergeSortSortWithVal.scala
@@ -1,6 +1,5 @@
-import scala.collection.immutable.Set
-
 import leon.lang._
+import leon.lang.synthesis._
 
 object MergeSort {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedBinaryTree/Batch.scala b/testcases/synthesis/oopsla2013/SortedBinaryTree/Batch.scala
index 643e82421..a35eaca9f 100644
--- a/testcases/synthesis/oopsla2013/SortedBinaryTree/Batch.scala
+++ b/testcases/synthesis/oopsla2013/SortedBinaryTree/Batch.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object BinaryTree {
   sealed abstract class Tree
diff --git a/testcases/synthesis/oopsla2013/SortedList/Batch.scala b/testcases/synthesis/oopsla2013/SortedList/Batch.scala
index f96978e6c..35e60c8d8 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Batch.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Batch.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SortedList {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Complete.scala b/testcases/synthesis/oopsla2013/SortedList/Complete.scala
index fecaa26a9..b2465c970 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Complete.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Complete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Delete.scala b/testcases/synthesis/oopsla2013/SortedList/Delete.scala
index e858390aa..b66aa8b33 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Delete.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Delete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Diff.scala b/testcases/synthesis/oopsla2013/SortedList/Diff.scala
index df5427f89..45ff51338 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Diff.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Diff.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Insert1.scala b/testcases/synthesis/oopsla2013/SortedList/Insert1.scala
index fdd5d1d5f..b785401c1 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Insert1.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Insert1.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Insert2.scala b/testcases/synthesis/oopsla2013/SortedList/Insert2.scala
index 159ebeaf2..9b86ba2a0 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Insert2.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Insert2.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Sort.scala b/testcases/synthesis/oopsla2013/SortedList/Sort.scala
index bd4054c0d..28e6de67b 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Sort.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Sort.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/SortInsert.scala b/testcases/synthesis/oopsla2013/SortedList/SortInsert.scala
index 6be3478ef..b53ca0d05 100644
--- a/testcases/synthesis/oopsla2013/SortedList/SortInsert.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/SortInsert.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/SortMerge.scala b/testcases/synthesis/oopsla2013/SortedList/SortMerge.scala
index 8fefa5089..fb216a4c4 100644
--- a/testcases/synthesis/oopsla2013/SortedList/SortMerge.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/SortMerge.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/SortMergeWithHint.scala b/testcases/synthesis/oopsla2013/SortedList/SortMergeWithHint.scala
index d9b74a8cd..06ed93ba9 100644
--- a/testcases/synthesis/oopsla2013/SortedList/SortMergeWithHint.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/SortMergeWithHint.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Split.scala b/testcases/synthesis/oopsla2013/SortedList/Split.scala
index 10118f274..77a883c60 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Split.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Split.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Split1.scala b/testcases/synthesis/oopsla2013/SortedList/Split1.scala
index 6ddf97b38..69a604755 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Split1.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Split1.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Split2.scala b/testcases/synthesis/oopsla2013/SortedList/Split2.scala
index 4317e9932..c3f30be7f 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Split2.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Split2.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Split3.scala b/testcases/synthesis/oopsla2013/SortedList/Split3.scala
index 02d678eb3..eb27d4414 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Split3.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Split3.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/Union.scala b/testcases/synthesis/oopsla2013/SortedList/Union.scala
index c5b8ec138..7681b838f 100644
--- a/testcases/synthesis/oopsla2013/SortedList/Union.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/Union.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SortedList/UnionIO.scala b/testcases/synthesis/oopsla2013/SortedList/UnionIO.scala
index 6590525f8..8e851fd9b 100644
--- a/testcases/synthesis/oopsla2013/SortedList/UnionIO.scala
+++ b/testcases/synthesis/oopsla2013/SortedList/UnionIO.scala
@@ -1,6 +1,6 @@
-import scala.collection.immutable.Set
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/SparseVector/Batch.scala b/testcases/synthesis/oopsla2013/SparseVector/Batch.scala
index 5a0582c98..f7b603cd1 100644
--- a/testcases/synthesis/oopsla2013/SparseVector/Batch.scala
+++ b/testcases/synthesis/oopsla2013/SparseVector/Batch.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SparseVector {
   sealed abstract class SparseVector
diff --git a/testcases/synthesis/oopsla2013/SparseVector/Complete.scala b/testcases/synthesis/oopsla2013/SparseVector/Complete.scala
index 66be72a51..2cf542ae5 100644
--- a/testcases/synthesis/oopsla2013/SparseVector/Complete.scala
+++ b/testcases/synthesis/oopsla2013/SparseVector/Complete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SparseVector {
   sealed abstract class SparseVector
diff --git a/testcases/synthesis/oopsla2013/SparseVector/Delete.scala b/testcases/synthesis/oopsla2013/SparseVector/Delete.scala
index b821b2c80..1f94b2635 100644
--- a/testcases/synthesis/oopsla2013/SparseVector/Delete.scala
+++ b/testcases/synthesis/oopsla2013/SparseVector/Delete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SparseVector {
   sealed abstract class SparseVector
diff --git a/testcases/synthesis/oopsla2013/SparseVector/Get.scala b/testcases/synthesis/oopsla2013/SparseVector/Get.scala
index 87e133dd6..53e0c5752 100644
--- a/testcases/synthesis/oopsla2013/SparseVector/Get.scala
+++ b/testcases/synthesis/oopsla2013/SparseVector/Get.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SparseVector {
   sealed abstract class SparseVector
diff --git a/testcases/synthesis/oopsla2013/SparseVector/Set.scala b/testcases/synthesis/oopsla2013/SparseVector/Set.scala
index 2699fe291..8a5f379ea 100644
--- a/testcases/synthesis/oopsla2013/SparseVector/Set.scala
+++ b/testcases/synthesis/oopsla2013/SparseVector/Set.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object SparseVector {
   sealed abstract class SparseVector
diff --git a/testcases/synthesis/oopsla2013/StrictSortedList/Batch.scala b/testcases/synthesis/oopsla2013/StrictSortedList/Batch.scala
index e5f8e4536..58d0e8b42 100644
--- a/testcases/synthesis/oopsla2013/StrictSortedList/Batch.scala
+++ b/testcases/synthesis/oopsla2013/StrictSortedList/Batch.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object StrictSortedList {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/StrictSortedList/Complete.scala b/testcases/synthesis/oopsla2013/StrictSortedList/Complete.scala
index 07ac7201a..fca32e4f1 100644
--- a/testcases/synthesis/oopsla2013/StrictSortedList/Complete.scala
+++ b/testcases/synthesis/oopsla2013/StrictSortedList/Complete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/StrictSortedList/Delete.scala b/testcases/synthesis/oopsla2013/StrictSortedList/Delete.scala
index b75f09401..3fa6e78c7 100644
--- a/testcases/synthesis/oopsla2013/StrictSortedList/Delete.scala
+++ b/testcases/synthesis/oopsla2013/StrictSortedList/Delete.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Delete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/StrictSortedList/Diff.scala b/testcases/synthesis/oopsla2013/StrictSortedList/Diff.scala
index cd059f68d..31481b52e 100644
--- a/testcases/synthesis/oopsla2013/StrictSortedList/Diff.scala
+++ b/testcases/synthesis/oopsla2013/StrictSortedList/Diff.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/StrictSortedList/Insert.scala b/testcases/synthesis/oopsla2013/StrictSortedList/Insert.scala
index e8d7ff7f4..d21176df0 100644
--- a/testcases/synthesis/oopsla2013/StrictSortedList/Insert.scala
+++ b/testcases/synthesis/oopsla2013/StrictSortedList/Insert.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
diff --git a/testcases/synthesis/oopsla2013/StrictSortedList/Union.scala b/testcases/synthesis/oopsla2013/StrictSortedList/Union.scala
index 4d835f51a..595b11257 100644
--- a/testcases/synthesis/oopsla2013/StrictSortedList/Union.scala
+++ b/testcases/synthesis/oopsla2013/StrictSortedList/Union.scala
@@ -1,5 +1,6 @@
 import leon.annotation._
 import leon.lang._
+import leon.lang.synthesis._
 
 object Complete {
   sealed abstract class List
-- 
GitLab