diff --git a/CHANGELOG.md b/CHANGELOG.md
index 862ea523b088bf5a2a0e4893e83742f75bb9790c..9ea1ad0fe669f6a4b8b93bced958a9bc8ca81520 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,9 @@ Among the changes are (see the commits for details):
 * Many additions to Leon's library, including the state monad
 * Numerous refactorings and bug fixes thanks to relentless work of Manos
 * Add --watch option to automatically re-run Leon after file modifications, thanks to Etienne
+* Somewhat extended source language that allows for deep type hierarchies (Manos)
+* Synthesis improvements: nore specific grammar for CEGIS and various optimizations, new synthesis rules 
+  and new design of the exploration strategy (Etienne and Manos)
 
 #### v3.0
 *Released 17.02.2015*
diff --git a/build.sbt b/build.sbt
index 6507f84a78b8bb3528d58121fe16e40b88f9ce09..cafc0af35392aa20dac26ea2cea2cc31af77a2f5 100644
--- a/build.sbt
+++ b/build.sbt
@@ -42,7 +42,8 @@ libraryDependencies ++= Seq(
   "info.hupel" %% "pide-2015" % libisabelleVersion,
   "org.slf4j" % "slf4j-nop" % "1.7.13",
   "org.ow2.asm" % "asm-all" % "5.0.4",
-  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.6.0-rc2"
+  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.6.0-rc2",
+  "com.regblanc" %% "scala-smtlib" % "0.2"
 )
 
 lazy val scriptName = "leon"
@@ -169,11 +170,10 @@ parallelExecution in GenCTest := false
 def ghProject(repo: String, version: String) = RootProject(uri(s"${repo}#${version}"))
 
 lazy val bonsai      = ghProject("git://github.com/colder/bonsai.git",     "10eaaee4ea0ff6567f4f866922cb871bae2da0ac")
-lazy val scalaSmtLib = ghProject("git://github.com/regb/scala-smtlib.git", "372bb14d0c84953acc17f9a7e1592087adb0a3e1")
 
 lazy val root = (project in file(".")).
   configs(RegressionTest, IsabelleTest, GenCTest, IntegrTest).
-  dependsOn(bonsai, scalaSmtLib).
+  dependsOn(bonsai).
   settings(inConfig(RegressionTest)(Defaults.testTasks ++ testSettings): _*).
   settings(inConfig(IntegrTest)(Defaults.testTasks ++ testSettings): _*).
   settings(inConfig(IsabelleTest)(Defaults.testTasks ++ testSettings): _*).
diff --git a/library/annotation/isabelle.scala b/library/annotation/isabelle.scala
index bfb4b39ec1499f270907a861c4d339d82a2d963d..db1c94cdc0bf0a0c4f8b57501bfa4a14a0173096 100644
--- a/library/annotation/isabelle.scala
+++ b/library/annotation/isabelle.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.annotation
 
 import scala.annotation.StaticAnnotation
diff --git a/library/annotation/package.scala b/library/annotation/package.scala
index 0e844188f55e3c1737beab20c359309019793f3c..fc4012a94417075b0a742bd63b0cb3ce83fc3c02 100644
--- a/library/annotation/package.scala
+++ b/library/annotation/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/library/collection/List.scala b/library/collection/List.scala
index 74a0f0c66e3bc23780076e16acdc6f7035c6986b..69c30d39fdede10c93a2fea69093f6b8a6503c99 100644
--- a/library/collection/List.scala
+++ b/library/collection/List.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.collection
 
diff --git a/library/collection/package.scala b/library/collection/package.scala
index 8a5ae170763909c20153f373915d6a4e9e726ca0..db83501a2d41345f3287c0f069c78076863aa753 100644
--- a/library/collection/package.scala
+++ b/library/collection/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/library/instrumentation/package.scala b/library/instrumentation/package.scala
index a6e7545c0b4ab2bae468b0cc6556f67784487b17..dc8ee71bd3036cbb35f02b30ddc9aa3dd8a0dbfa 100644
--- a/library/instrumentation/package.scala
+++ b/library/instrumentation/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/library/invariant/package.scala b/library/invariant/package.scala
index 0cc7919d0194a5dff25457c38db8cd00c78db8bd..e6534f423733ba430e7383dac1b1f322e3c74523 100644
--- a/library/invariant/package.scala
+++ b/library/invariant/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/library/lang/Dummy.scala b/library/lang/Dummy.scala
index 41dbe4f90ccea298a17de70caa2f3d04ebdc0def..9c88117962d574654ffe406d5635440bb9236bc2 100644
--- a/library/lang/Dummy.scala
+++ b/library/lang/Dummy.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.lang
 
 case class Dummy[T]()
diff --git a/library/lang/Either.scala b/library/lang/Either.scala
index 9cc2ea4e9537b424cbce6963e2a4038f3480d01a..67caad70d7b2aa51fcee7b2c3b47767dd720f5c4 100644
--- a/library/lang/Either.scala
+++ b/library/lang/Either.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.lang
 
diff --git a/library/lang/Map.scala b/library/lang/Map.scala
index aff6f26f80d5e4abc7d8fa70d3a6553ebdff1c17..2a08449cc50d0b7a032a826a5aea563f6f284181 100644
--- a/library/lang/Map.scala
+++ b/library/lang/Map.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.lang
 import leon.annotation._
 
diff --git a/library/lang/Option.scala b/library/lang/Option.scala
index a6f09db68f3fecc7ad8095506a49d21e4d8ac7ad..b1fed6d4d682ac814070889559c027c89f16c625 100644
--- a/library/lang/Option.scala
+++ b/library/lang/Option.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.lang
 
diff --git a/library/lang/Rational.scala b/library/lang/Rational.scala
index 1bcb679a0d4abf6b168117b2af819fa41e027315..4699f08bebc3a3c80d1c9f3f7beafd8a8ca5d9ea 100644
--- a/library/lang/Rational.scala
+++ b/library/lang/Rational.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.lang
 
@@ -13,31 +13,31 @@ case class Rational(numerator: BigInt, denominator: BigInt) {
 
   def +(that: Rational): Rational = {
     Rational(this.numerator*that.denominator + that.numerator*this.denominator, this.denominator*that.denominator)
-  } ensuring(res => res.isRational)
+  }
 
   def -(that: Rational): Rational = {
     Rational(this.numerator*that.denominator - that.numerator*this.denominator, this.denominator*that.denominator)
-  } ensuring(res => res.isRational)
+  }
 
   def unary_- : Rational = {
     Rational(-this.numerator, this.denominator)
-  } ensuring(res => res.isRational)
+  }
 
   def *(that: Rational): Rational = {
     Rational(this.numerator*that.numerator, this.denominator*that.denominator)
-  } ensuring(res => res.isRational)
+  }
 
   def /(that: Rational): Rational = {
     require(that.nonZero)
     val newNumerator = this.numerator*that.denominator
     val newDenominator = this.denominator*that.numerator
     normalize(newNumerator, newDenominator)
-  } ensuring(res => res.isRational)
+  }
 
   def reciprocal: Rational = {
     require(this.nonZero)
     normalize(this.denominator, this.numerator)
-  } ensuring(res => res.isRational)
+  }
 
 
   def ~(that: Rational): Boolean = {
diff --git a/library/lang/Real.scala b/library/lang/Real.scala
index 9d600b3b6c584355dacfc10ed6d4d6b0c58fd631..450cfb246a25d01e9d909dee5fb75ed32a7cdfa1 100644
--- a/library/lang/Real.scala
+++ b/library/lang/Real.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.lang
 import leon.annotation._
 
diff --git a/library/lang/Set.scala b/library/lang/Set.scala
index 8f4595d33fada35acfa38435c3cd542116cf3cbd..d27fd18bbab181e148c1246dd104f322a69e7c4a 100644
--- a/library/lang/Set.scala
+++ b/library/lang/Set.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.lang
 import leon.annotation._
 
diff --git a/library/lang/StrOps.scala b/library/lang/StrOps.scala
index 723ce5be82d7a841c743640ba4f10284076c0dfe..6628fdd55391f85a0a75b074fc50c094cd36ab3c 100644
--- a/library/lang/StrOps.scala
+++ b/library/lang/StrOps.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.lang
 
 import leon.annotation._
diff --git a/library/lang/package.scala b/library/lang/package.scala
index ab713a588e5451ba8ab61533d6037bd2bd572de8..6da0ba224d797d05d062a92ed600d3d57cad7139 100644
--- a/library/lang/package.scala
+++ b/library/lang/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/library/lang/synthesis/Oracle.scala b/library/lang/synthesis/Oracle.scala
index 7af697638880232c9248cbe98e01e0327552bccb..399b52b8d82fc7250d827516596a569e51adebdb 100644
--- a/library/lang/synthesis/Oracle.scala
+++ b/library/lang/synthesis/Oracle.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.lang.synthesis
 
diff --git a/library/lang/synthesis/package.scala b/library/lang/synthesis/package.scala
index cb56992797715423aa1b0c45f94946778cb5780e..07635f1a69ede6ffacf894bb3438b9bd34555f5a 100644
--- a/library/lang/synthesis/package.scala
+++ b/library/lang/synthesis/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.lang
 
diff --git a/library/lang/xlang/package.scala b/library/lang/xlang/package.scala
index 6f29c5d33e3fc8dff8a26d526cf7ef2c6f2f0837..c394f9508238d97ba85d07e0b491f754908d6e4e 100644
--- a/library/lang/xlang/package.scala
+++ b/library/lang/xlang/package.scala
@@ -1,13 +1,10 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 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/library/math/package.scala b/library/math/package.scala
index 8eb5f347963f4599faeca8e1c58adda74b259aef..51fe7fdb2de334478ec3d98dc5e3937b0dd9a697 100644
--- a/library/math/package.scala
+++ b/library/math/package.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 import leon.annotation._
 
diff --git a/library/monads/state/State.scala b/library/monads/state/State.scala
index ad47c2464f54c9e40fc430528c561ad40032ac1f..7bb12881ca5dce8acc3df59517e624b92e5785c0 100644
--- a/library/monads/state/State.scala
+++ b/library/monads/state/State.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.monads.state
 
 import leon.collection._
diff --git a/library/par/package.scala b/library/par/package.scala
index 5842210fce915df2c02a0f69b6000703c8865af9..1c542dd48d64d97daae7b60dee5b8223b21ccc0c 100644
--- a/library/par/package.scala
+++ b/library/par/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/library/proof/Internal.scala b/library/proof/Internal.scala
index 0962c371c670d2b08db797a9f24542195c78bac8..5dcd34867c8c3854425b611b9368e6707536ca96 100644
--- a/library/proof/Internal.scala
+++ b/library/proof/Internal.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 package leon.proof
 
 import leon.lang._
diff --git a/library/proof/package.scala b/library/proof/package.scala
index 3f097864964a8d2d724a8ec1256dd803c5c048c5..46ac1588321e976ec3a9dd0066b29c7032c97d3c 100644
--- a/library/proof/package.scala
+++ b/library/proof/package.scala
@@ -1,4 +1,5 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 
 import leon.annotation._
diff --git a/scripts/applyLicense.sh b/scripts/applyLicense.sh
index f949a4becafedc167b909f08ab4ad0b60c9bd088..781901c5cffe8542ed656a479a888b3e36cee64d 100755
--- a/scripts/applyLicense.sh
+++ b/scripts/applyLicense.sh
@@ -1,4 +1,4 @@
-printf "/* Copyright 2009-2015 EPFL, Lausanne */\n\n" > /tmp/Leon-license
+printf "/* Copyright 2009-2016 EPFL, Lausanne */\n\n" > /tmp/Leon-license
 
 for f in $(find {src,library} -name "*.java" -o -name "*.scala") ;do
   if [ -f $f ]; then
diff --git a/src/main/java/leon/codegen/runtime/ArrayBox.java b/src/main/java/leon/codegen/runtime/ArrayBox.java
index b4dee425546953998a22527a54640c554c2d73cb..0da4e64ca22a3430b6177483ddbd9a1c528d2692 100644
--- a/src/main/java/leon/codegen/runtime/ArrayBox.java
+++ b/src/main/java/leon/codegen/runtime/ArrayBox.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/BigInt.java b/src/main/java/leon/codegen/runtime/BigInt.java
index f2b99a6d9b07234ef247bb6c18bdbd0a37e73733..c4e3412b3539d56b21880734a8c63b36d06a38db 100644
--- a/src/main/java/leon/codegen/runtime/BigInt.java
+++ b/src/main/java/leon/codegen/runtime/BigInt.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/CaseClass.java b/src/main/java/leon/codegen/runtime/CaseClass.java
index 9f159b7e2fad89cc11ca19575f77372ea0341ec6..aeeb14a1bce2772366a96c6d3e89c8d9c31e1890 100644
--- a/src/main/java/leon/codegen/runtime/CaseClass.java
+++ b/src/main/java/leon/codegen/runtime/CaseClass.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/Lambda.java b/src/main/java/leon/codegen/runtime/Lambda.java
index a6abbef37edbe8f87f480a21a6200e32a9e0206b..edb740d480f9619e0c4ec2620fa440efdbdd5f09 100644
--- a/src/main/java/leon/codegen/runtime/Lambda.java
+++ b/src/main/java/leon/codegen/runtime/Lambda.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/LeonCodeGenEvaluationException.java b/src/main/java/leon/codegen/runtime/LeonCodeGenEvaluationException.java
index 77561659626244e9dfdfe415c99f4a14e042c516..69da9c5ea1d09a4311f7a68d8c09ac0bfa183d11 100644
--- a/src/main/java/leon/codegen/runtime/LeonCodeGenEvaluationException.java
+++ b/src/main/java/leon/codegen/runtime/LeonCodeGenEvaluationException.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeException.java b/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeException.java
index 77d05d97d39dd7a087563e1821e9e347b783d344..63abf63a5f41fdbb5ed9edbb764d2b8a0e98f2e3 100644
--- a/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeException.java
+++ b/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeException.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeHashing.java b/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeHashing.java
index b3f21df7655da6f3720de530f91fc2fd19174631..feb40c3bd581055d8f65af336f83020e8be92201 100644
--- a/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeHashing.java
+++ b/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeHashing.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeMonitor.java b/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeMonitor.java
index c289a6beaf614e0436473d8a4ba49c734d022666..c89d49705d028ffd23965d7512ac85de0f851716 100644
--- a/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeMonitor.java
+++ b/src/main/java/leon/codegen/runtime/LeonCodeGenRuntimeMonitor.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/Map.java b/src/main/java/leon/codegen/runtime/Map.java
index 000cc073b8d3f7e7732ddd8c79470d4d56eb74b1..19c94b4c2a331f3fe5b7d14f77358fb7f5147f1a 100644
--- a/src/main/java/leon/codegen/runtime/Map.java
+++ b/src/main/java/leon/codegen/runtime/Map.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/Rational.java b/src/main/java/leon/codegen/runtime/Rational.java
index fc409434b05216591069a94d79af6000c75e62d2..2d09905d4839edbc97233f217f685b3d04f79178 100644
--- a/src/main/java/leon/codegen/runtime/Rational.java
+++ b/src/main/java/leon/codegen/runtime/Rational.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/Real.java b/src/main/java/leon/codegen/runtime/Real.java
index 9d80935eb2f189bac1464d7d134a314b04d2ae0a..84aefb2419ef01f308461c8c9f10c0cf73871b8d 100644
--- a/src/main/java/leon/codegen/runtime/Real.java
+++ b/src/main/java/leon/codegen/runtime/Real.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/Set.java b/src/main/java/leon/codegen/runtime/Set.java
index 522dbe6589eac54bf2acac3e1f81ee4b4c7c962c..42cadce43616eeafaaf7133d3ac7b55d229c56fb 100644
--- a/src/main/java/leon/codegen/runtime/Set.java
+++ b/src/main/java/leon/codegen/runtime/Set.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/java/leon/codegen/runtime/StrOps.java b/src/main/java/leon/codegen/runtime/StrOps.java
index 34abc12d7703c8751fe01fe5c60f1efa18b57715..0c258b3cb7f4cdbf89a89fc16b3aa7c6c88caad6 100644
--- a/src/main/java/leon/codegen/runtime/StrOps.java
+++ b/src/main/java/leon/codegen/runtime/StrOps.java
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.codegen.runtime;
 
 import org.apache.commons.lang3.StringEscapeUtils;
diff --git a/src/main/java/leon/codegen/runtime/Tuple.java b/src/main/java/leon/codegen/runtime/Tuple.java
index 3b72931da6fc04b3504d7f3bee2056560c269634..0b0405f04e61971a6ea0fe36f1d99b0b3646fe58 100644
--- a/src/main/java/leon/codegen/runtime/Tuple.java
+++ b/src/main/java/leon/codegen/runtime/Tuple.java
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime;
 
diff --git a/src/main/scala/leon/SharedOptions.scala b/src/main/scala/leon/GlobalOptions.scala
similarity index 77%
rename from src/main/scala/leon/SharedOptions.scala
rename to src/main/scala/leon/GlobalOptions.scala
index b68e64c83a6fd42e445dd4b5fa3b3bd42a935de4..9632926a6e7a3fb511c25e50bd77ecb2193fb242 100644
--- a/src/main/scala/leon/SharedOptions.scala
+++ b/src/main/scala/leon/GlobalOptions.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
@@ -10,7 +10,7 @@ import OptionParsers._
   * Options that determine the pipeline of Leon are not stored here,
   * but in [[Main.MainComponent]] instead.
   */
-object SharedOptions extends LeonComponent {
+object GlobalOptions extends LeonComponent {
 
   val name = "sharedOptions"
   val description = "Options shared by multiple components of Leon"
@@ -51,22 +51,24 @@ object SharedOptions extends LeonComponent {
     }
     val default = Set[DebugSection]()
     val usageRhs = "d1,d2,..."
-    val debugParser: OptionParser[Set[DebugSection]] = s => {
+    private val debugParser: OptionParser[Set[DebugSection]] = s => {
       if (s == "all") {
-        DebugSections.all
+        Some(DebugSections.all)
       } else {
-        DebugSections.all.find(_.name == s) match {
-          case Some(rs) =>
-            Set(rs)
-          case None =>
-            throw new IllegalArgumentException
-        }
+        DebugSections.all.find(_.name == s).map(Set(_))
       }
     }
-    val parser: String => Set[DebugSection] = setParser[Set[DebugSection]](debugParser)(_).flatten
+    val parser: String => Option[Set[DebugSection]] = {
+      setParser[Set[DebugSection]](debugParser)(_).map(_.flatten)
+    }
   }
 
-  val optTimeout = LeonLongOptionDef("timeout", "Set a timeout for attempting to prove a verification condition/ repair a function (in sec.)", 0L, "t")
+  val optTimeout = LeonLongOptionDef(
+    "timeout",
+    "Set a timeout for attempting to prove a verification condition/ repair a function (in sec.)",
+    0L,
+    "t"
+  )
 
   override val definedOptions: Set[LeonOptionDef[Any]] = Set(
     optStrictPhases,
diff --git a/src/main/scala/leon/LeonComponent.scala b/src/main/scala/leon/LeonComponent.scala
index 74a8865a85cb283d544a66c18533e59ab26bb4e6..0b33fde0940c2ddba8030d95349571531f394a11 100644
--- a/src/main/scala/leon/LeonComponent.scala
+++ b/src/main/scala/leon/LeonComponent.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/src/main/scala/leon/LeonContext.scala b/src/main/scala/leon/LeonContext.scala
index 6fde42aecd40673887f723438b9ab2acbdbb3ef6..f46e53d0461d862a29d8778f9b32379fbe8409ea 100644
--- a/src/main/scala/leon/LeonContext.scala
+++ b/src/main/scala/leon/LeonContext.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
@@ -9,7 +9,7 @@ import java.io.File
 import scala.reflect.ClassTag
 
 /** Everything that is part of a compilation unit, except the actual program tree.
-  * Contexts are immutable, and so should all there fields (with the possible
+  * LeonContexts are immutable, and so should all their fields (with the possible
   * exception of the reporter).
   */
 case class LeonContext(
@@ -36,8 +36,11 @@ object LeonContext {
   }
 
   def printNames = {
-    empty.copy(options =
-      Seq(LeonOption[Set[DebugSection]](SharedOptions.optDebug)(Set(DebugSectionTrees)))
+    val reporter = new DefaultReporter(Set())
+    LeonContext(
+      reporter,
+      new InterruptManager(reporter),
+      options = Seq(LeonOption[Set[DebugSection]](GlobalOptions.optDebug)(Set(DebugSectionTrees)))
     )
   }
 }
diff --git a/src/main/scala/leon/LeonExceptions.scala b/src/main/scala/leon/LeonExceptions.scala
index eeaadd09a736416aa6f6eeab93cc7e51a17e8072..ad526d782fa3a04fb618b518d49bbe3befe3c7c2 100644
--- a/src/main/scala/leon/LeonExceptions.scala
+++ b/src/main/scala/leon/LeonExceptions.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/src/main/scala/leon/LeonOption.scala b/src/main/scala/leon/LeonOption.scala
index f079399f9995e409b6b72881ef8f81d92c273556..d1f93981f6ad34f3ceef2c28c83cddcaf362b776 100644
--- a/src/main/scala/leon/LeonOption.scala
+++ b/src/main/scala/leon/LeonOption.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
@@ -7,6 +7,8 @@ import OptionParsers._
 import purescala.Definitions._
 import purescala.DefOps.fullName
 
+import scala.util.Try
+
 abstract class LeonOptionDef[+A] {
   val name: String
   val description: String
@@ -22,14 +24,12 @@ abstract class LeonOptionDef[+A] {
   }
 
   private def parseValue(s: String)(implicit reporter: Reporter): A = {
-    try { parser(s) }
-    catch {
-      case _ : IllegalArgumentException =>
-        reporter.fatalError(
-          s"Invalid option usage: --$name\n" +
-          "Try 'leon --help' for more information."
-        )
-    }
+    parser(s).getOrElse(
+      reporter.fatalError(
+        s"Invalid option usage: --$name\n" +
+        "Try 'leon --help' for more information."
+      )
+    )
   }
 
   def parse(s: String)(implicit reporter: Reporter): LeonOption[A] =
@@ -67,7 +67,7 @@ class LeonOption[+A] private (val optionDef: LeonOptionDef[A], val value: A) {
       optionDef.name == this.optionDef.name && value == this.value
     case _ => false
   }
-  override def hashCode = optionDef.hashCode
+  override def hashCode = optionDef.hashCode + value.hashCode
 }
 
 object LeonOption {
@@ -78,20 +78,28 @@ object LeonOption {
 }
 
 object OptionParsers {
-  type OptionParser[A] = String => A
-
-  val longParser: OptionParser[Long] = _.toLong
-  val stringParser: OptionParser[String] = x => x
-  def booleanParser: OptionParser[Boolean] = {
-    case "on"  | "true"  | "yes" | "" => true
-    case "off" | "false" | "no"       => false
-    case _  => throw new IllegalArgumentException
+  type OptionParser[A] = String => Option[A]
+
+  val longParser: OptionParser[Long] = { s =>
+    Try(s.toLong).toOption
   }
+  val stringParser: OptionParser[String] = Some(_)
+  val booleanParser: OptionParser[Boolean] = {
+    case "on"  | "true"  | "yes" | "" => Some(true)
+    case "off" | "false" | "no"       => Some(false)
+    case _  => None
+  }
+
   def seqParser[A](base: OptionParser[A]): OptionParser[Seq[A]] = s => {
-    s.split(",").filter(_.nonEmpty).map(base)
+    @inline def foo: Option[Seq[A]] = Some(
+      s.split(",")
+        .filter(_.nonEmpty)
+        .map(base andThen (_.getOrElse(return None)))
+    )
+    foo
   }
-  def setParser[A](base: OptionParser[A]): OptionParser[Set[A]] = s => {
-    s.split(",").filter(_.nonEmpty).map(base).toSet
+  def setParser[A](base: OptionParser[A]): OptionParser[Set[A]] = {
+    seqParser(base)(_).map(_.toSet)
   }
 
 }
@@ -103,9 +111,9 @@ object OptionsHelpers {
   private val matcherWithout = s"--(.*)".r
 
   def nameValue(s: String) = s match {
-    case matcher(name, value) => (name, value)
-    case matcherWithout(name) => (name, "")
-    case _ => throw new IllegalArgumentException
+    case matcher(name, value) => Some(name, value)
+    case matcherWithout(name) => Some(name, "")
+    case _ => None
   }
 
   // helper for options that include patterns
@@ -131,7 +139,7 @@ object OptionsHelpers {
       Pattern.compile("(.+\\.)?"+p)
     }
 
-    { (name: String) => regexPatterns.exists(p => p.matcher(name).matches()) }
+    (name: String) => regexPatterns.exists(p => p.matcher(name).matches())
   }
 
   def fdMatcher(pgm: Program)(patterns: Traversable[String]): FunDef => Boolean = {
@@ -144,11 +152,8 @@ object OptionsHelpers {
         i
       case None =>
         excluded match {
-          case Some(f) =>
-            { (t: T) => !f(t) }
-
-          case None =>
-            { (t: T) => true }
+          case Some(f) => (t: T) => !f(t)
+          case None    => (t: T) => true
         }
     }
   }
diff --git a/src/main/scala/leon/LeonPhase.scala b/src/main/scala/leon/LeonPhase.scala
index ea8c2531660c522017e0abd32b4c1220acd33649..8fb5307955305fb6612cd7b3933fcda553cd0fe7 100644
--- a/src/main/scala/leon/LeonPhase.scala
+++ b/src/main/scala/leon/LeonPhase.scala
@@ -1,11 +1,10 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
 import purescala.Definitions.Program
 
 trait LeonPhase[-F, +T] extends Pipeline[F, T] with LeonComponent {
-
   // def run(ac: LeonContext)(v: F): T
 }
 
@@ -22,13 +21,14 @@ abstract class TransformationPhase extends LeonPhase[Program, Program] {
     ctx.reporter.debug("Running transformation phase: " + name)(utils.DebugSectionLeon)
     (ctx, apply(ctx, p))
   }
+
 }
 
 abstract class UnitPhase[T] extends LeonPhase[T, T] {
   def apply(ctx: LeonContext, p: T): Unit
 
   override def run(ctx: LeonContext, p: T) = {
-    ctx.reporter.debug("Running unit phase phase: " + name)(utils.DebugSectionLeon)
+    ctx.reporter.debug("Running unit phase: " + name)(utils.DebugSectionLeon)
     apply(ctx, p)
     (ctx, p)
   }
diff --git a/src/main/scala/leon/Main.scala b/src/main/scala/leon/Main.scala
index 509a04d38788c922d4fcc3ca9bf5ed4355e2be5c..1c1e52b17bc57537128e2186f342937aab62ecd0 100644
--- a/src/main/scala/leon/Main.scala
+++ b/src/main/scala/leon/Main.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
@@ -11,9 +11,9 @@ object Main {
       frontends.scalac.ExtractionPhase,
       frontends.scalac.ClassgenPhase,
       utils.TypingPhase,
-      FileOutputPhase,
+      utils.FileOutputPhase,
       purescala.RestoreMethods,
-      xlang.ArrayTransformation,
+      xlang.AntiAliasingPhase,
       xlang.EpsilonElimination,
       xlang.ImperativeCodeElimination,
       xlang.FixReportLabels,
@@ -30,12 +30,13 @@ object Main {
       invariant.engine.InferInvariantsPhase,
       laziness.LazinessEliminationPhase,
       genc.GenerateCPhase,
-      genc.CFileOutputPhase)
+      genc.CFileOutputPhase
+    )
   }
 
   // Add whatever you need here.
   lazy val allComponents : Set[LeonComponent] = allPhases.toSet ++ Set(
-    solvers.combinators.UnrollingProcedure, MainComponent, SharedOptions, solvers.smtlib.SMTLIBCVC4Component, solvers.isabelle.Component
+    solvers.combinators.UnrollingProcedure, MainComponent, GlobalOptions, solvers.smtlib.SMTLIBCVC4Component, solvers.isabelle.Component
   )
 
   /*
@@ -56,7 +57,7 @@ object Main {
     val optHelp        = LeonFlagOptionDef("help",        "Show help message",                                         false)
     val optInstrument  = LeonFlagOptionDef("instrument",  "Instrument the code for inferring time/depth/stack bounds", false)
     val optInferInv    = LeonFlagOptionDef("inferInv",    "Infer invariants from (instrumented) the code",             false)
-    val optLazyEval = LeonFlagOptionDef("lazy", "Handles programs that may use the lazy construct", false)
+    val optLazyEval    = LeonFlagOptionDef("lazy",        "Handles programs that may use the 'lazy' construct",        false)
     val optGenc        = LeonFlagOptionDef("genc",        "Generate C code",                                           false)
 
     override val definedOptions: Set[LeonOptionDef[Any]] =
@@ -74,14 +75,14 @@ object Main {
     reporter.info("")
 
     reporter.title("Additional global options")
-    for (opt <- SharedOptions.definedOptions.toSeq.sortBy(_.name)) {
+    for (opt <- GlobalOptions.definedOptions.toSeq.sortBy(_.name)) {
       reporter.info(opt.helpString)
     }
     reporter.info("")
 
     reporter.title("Additional options, by component:")
 
-    for (c <- (allComponents - MainComponent - SharedOptions).toSeq.sortBy(_.name) if c.definedOptions.nonEmpty) {
+    for (c <- (allComponents - MainComponent - GlobalOptions).toSeq.sortBy(_.name) if c.definedOptions.nonEmpty) {
       reporter.info("")
       reporter.info(s"${c.name} (${c.description})")
       for (opt <- c.definedOptions.toSeq.sortBy(_.name)) {
@@ -103,20 +104,18 @@ object Main {
 
     val initReporter = new DefaultReporter(Set())
 
-    val options = args.filter(_.startsWith("--")).toSet
+    val options = args.filter(_.startsWith("--"))
 
     val files = args.filterNot(_.startsWith("-")).map(new java.io.File(_))
 
-    val leonOptions: Set[LeonOption[Any]] = options.map { opt =>
-      val (name, value) = try {
-        OptionsHelpers.nameValue(opt)
-      } catch {
-        case _: IllegalArgumentException =>
-          initReporter.fatalError(
-            s"Malformed option $opt. Options should have the form --name or --name=value")
-      }
+    val leonOptions: Seq[LeonOption[Any]] = options.map { opt =>
+      val (name, value) = OptionsHelpers.nameValue(opt).getOrElse(
+        initReporter.fatalError(
+          s"Malformed option $opt. Options should have the form --name or --name=value"
+        )
+      )
       // Find respective LeonOptionDef, or report an unknown option
-      val df = allOptions.find(_. name == name).getOrElse{
+      val df = allOptions.find(_.name == name).getOrElse{
         initReporter.fatalError(
           s"Unknown option: $name\n" +
           "Try 'leon --help' for more information."
@@ -127,8 +126,10 @@ object Main {
 
     val reporter = new DefaultReporter(
       leonOptions.collectFirst {
-        case LeonOption(SharedOptions.optDebug, sections) => sections.asInstanceOf[Set[DebugSection]]
-      }.getOrElse(Set[DebugSection]()))
+        case LeonOption(GlobalOptions.optDebug, sections) =>
+          sections.asInstanceOf[Set[DebugSection]]
+      }.getOrElse(Set[DebugSection]())
+    )
 
     reporter.whenDebug(DebugSectionOptions) { debug =>
       debug("Options considered by Leon:")
@@ -138,8 +139,9 @@ object Main {
     LeonContext(
       reporter = reporter,
       files = files,
-      options = leonOptions.toSeq,
-      interruptManager = new InterruptManager(reporter))
+      options = leonOptions,
+      interruptManager = new InterruptManager(reporter)
+    )
   }
 
   def computePipeline(ctx: LeonContext): Pipeline[List[String], Any] = {
@@ -159,13 +161,13 @@ object Main {
     import genc.CFileOutputPhase
     import MainComponent._
     import invariant.engine.InferInvariantsPhase
-    import transformations._
+    import transformations.InstrumentationPhase
     import laziness._
 
     val helpF = ctx.findOptionOrDefault(optHelp)
     val noopF = ctx.findOptionOrDefault(optNoop)
     val synthesisF = ctx.findOptionOrDefault(optSynthesis)
-    val xlangF = ctx.findOptionOrDefault(SharedOptions.optXLang)
+    val xlangF = ctx.findOptionOrDefault(GlobalOptions.optXLang)
     val repairF = ctx.findOptionOrDefault(optRepair)
     val isabelleF = ctx.findOptionOrDefault(optIsabelle)
     val terminationF = ctx.findOptionOrDefault(optTermination)
@@ -190,14 +192,18 @@ object Main {
           ExtractionPhase andThen
           new PreprocessingPhase(xlangF)
 
-      val verification = if (xlangF) VerificationPhase andThen FixReportLabels else VerificationPhase
+      val verification =
+        VerificationPhase andThen
+        FixReportLabels.when(xlangF) andThen
+        PrintReportPhase
+      val termination  = TerminationPhase andThen PrintReportPhase
 
       val pipeProcess: Pipeline[Program, Any] = {
         if (noopF) RestoreMethods andThen FileOutputPhase
         else if (synthesisF) SynthesisPhase
         else if (repairF) RepairPhase
-        else if (analysisF) Pipeline.both(verification, TerminationPhase)
-        else if (terminationF) TerminationPhase
+        else if (analysisF) Pipeline.both(verification, termination)
+        else if (terminationF) termination
         else if (isabelleF) IsabellePhase
         else if (evalF) EvaluationPhase
         else if (inferInvF) InferInvariantsPhase
@@ -220,7 +226,6 @@ object Main {
     // Process options
     val ctx = try {
       processOptions(argsl)
-
     } catch {
       case LeonFatalError(None) =>
         exit(error = true)
@@ -239,7 +244,7 @@ object Main {
 
     ctx.interruptManager.registerSignalHandler()
 
-    val doWatch = ctx.findOptionOrDefault(SharedOptions.optWatch)
+    val doWatch = ctx.findOptionOrDefault(GlobalOptions.optWatch)
 
     if (doWatch) {
       val watcher = new FilesWatcher(ctx, ctx.files ++ Build.libFiles.map { new java.io.File(_) })
@@ -263,23 +268,7 @@ object Main {
       val timer = ctx.timers.total.start()
 
       // Run pipeline
-      val ctx2 = pipeline.run(ctx, args.toList) match {
-        case (ctx2, (vReport: verification.VerificationReport, tReport: termination.TerminationReport)) =>
-          ctx2.reporter.info(vReport.summaryString)
-          ctx2.reporter.info(tReport.summaryString)
-          ctx2
-
-        case (ctx2, report: verification.VerificationReport) =>
-          ctx2.reporter.info(report.summaryString)
-          ctx2
-
-        case (ctx2, report: termination.TerminationReport) =>
-          ctx2.reporter.info(report.summaryString)
-          ctx2
-
-        case (ctx2, _) =>
-          ctx2
-      }
+      val (ctx2, _) = pipeline.run(ctx, args.toList)
 
       timer.stop()
 
diff --git a/src/main/scala/leon/Pipeline.scala b/src/main/scala/leon/Pipeline.scala
index aa1471cb8b962e4261f116fe98699f5eed94b3ec..48f4192e3058548af64ddab922e84c4149299b61 100644
--- a/src/main/scala/leon/Pipeline.scala
+++ b/src/main/scala/leon/Pipeline.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
@@ -8,11 +8,17 @@ abstract class Pipeline[-F, +T] {
   def andThen[G](thenn: Pipeline[T, G]): Pipeline[F, G] = new Pipeline[F,G] {
     def run(ctx: LeonContext, v: F): (LeonContext, G) = {
       val (ctx2, s) = self.run(ctx, v)
-      if(ctx.findOptionOrDefault(SharedOptions.optStrictPhases)) ctx.reporter.terminateIfError()
+      if(ctx.findOptionOrDefault(GlobalOptions.optStrictPhases)) ctx.reporter.terminateIfError()
       thenn.run(ctx2, s)
     }
   }
 
+  def when[F2 <: F, T2 >: T](cond: Boolean)(implicit tps: F2 =:= T2): Pipeline[F2, T2] = {
+    if (cond) this else new Pipeline[F2, T2] {
+      def run(ctx: LeonContext, v: F2): (LeonContext, T2) = (ctx, v)
+    }
+  }
+
   def run(ctx: LeonContext, v: F): (LeonContext, T)
 }
 
diff --git a/src/main/scala/leon/Printable.scala b/src/main/scala/leon/Printable.scala
new file mode 100644
index 0000000000000000000000000000000000000000..e55272e57e02fa5d8413db719cd7d1e8b5e02366
--- /dev/null
+++ b/src/main/scala/leon/Printable.scala
@@ -0,0 +1,8 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+
+/** A trait for objects that can be pretty-printed given a [[leon.LeonContext]] */
+trait Printable {
+  def asString(implicit ctx: LeonContext): String
+}
diff --git a/src/main/scala/leon/Reporter.scala b/src/main/scala/leon/Reporter.scala
index 5013809fb046038f03dca19d22d6bd5bb875785a..7330ca605f4c478c9e4aa025e727fc465f46b333 100644
--- a/src/main/scala/leon/Reporter.scala
+++ b/src/main/scala/leon/Reporter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/src/main/scala/leon/Stopwatch.scala b/src/main/scala/leon/Stopwatch.scala
deleted file mode 100644
index 5168bfba66a23e7dbcf9ceafcf922601aadf03f6..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/Stopwatch.scala
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-
-class StopwatchCollection(name: String) {
-  var acc: Long = 0L
-  
-  var stopwatches = List[Stopwatch]()
-
-  def +=(sw: Stopwatch) = synchronized { acc += sw.getMillis }
-
-  def getMillis = {
-    val running =
-	    (0L /: stopwatches) {
-	      (res, sw) => res + sw.getMillis
-	    }
-      
-    acc + running
-  }
-  
-  def newStopwatch = {
-    val result = new Stopwatch()
-    stopwatches :+= result
-    result
-  }
-
-  override def toString = f"$name%20s: ${acc}%5dms"
-}
-
-/** Implements a stopwatch for profiling purposes */
-class Stopwatch(name: String = "Stopwatch") {
-  var beginning: Long = 0L
-  var end: Long = 0L
-  var acc: Long = 0L
-
-  def start: this.type = {
-    beginning = System.currentTimeMillis
-    end       = 0L
-    this
-  }
-
-  def stop() {
-    end        = System.currentTimeMillis
-    acc       += (end - beginning)
-    beginning  = 0L
-  }
-
-  def getMillis: Long = {
-    if (isRunning) {
-      acc + (System.currentTimeMillis-beginning)
-    } else {
-      acc
-    }
-  }
-    
-  def profile[T](block: => T): T = {
-    if (isRunning) stop()
-    
-    start
-    val result = block    // call-by-name
-    stop()
-    
-    result
-  }
-
-  def isRunning = beginning != 0L
-
-  override def toString = f"$name%20s: $getMillis%5d${if (isRunning) "..." else ""}ms"
-}
-
-object StopwatchCollections {
-  private var all = Map[String, StopwatchCollection]()
-
-  def get(name: String): StopwatchCollection = all.getOrElse(name, {
-    val sw = new StopwatchCollection(name)
-    all += name -> sw
-    sw
-  })
-
-  def getAll = all
-}
diff --git a/src/main/scala/leon/codegen/CodeGenParams.scala b/src/main/scala/leon/codegen/CodeGenParams.scala
index be0bf64b560914c203ed8bbc34ad8f71d0ed080c..ff99627659ddd7ef26b736f245d702d70e0318c2 100644
--- a/src/main/scala/leon/codegen/CodeGenParams.scala
+++ b/src/main/scala/leon/codegen/CodeGenParams.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package codegen
diff --git a/src/main/scala/leon/codegen/CodeGeneration.scala b/src/main/scala/leon/codegen/CodeGeneration.scala
index 14b8f5cdf5fb00237282ac231ed881b9179e053d..0e2a3fe235621adf8db2746f56e96db338479929 100644
--- a/src/main/scala/leon/codegen/CodeGeneration.scala
+++ b/src/main/scala/leon/codegen/CodeGeneration.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package codegen
@@ -200,7 +200,12 @@ trait CodeGeneration {
     val body = if (params.checkContracts) {
       funDef.fullBody
     } else {
-      funDef.body.getOrElse(throw CompilationException("Can't compile a FunDef without body: "+funDef.id.name))
+      funDef.body.getOrElse(
+        if(funDef.annotations contains "extern") {
+          Error(funDef.id.getType, "Body of " + funDef.id.name + " not implemented at compile-time and still executed.")
+        } else {
+          throw CompilationException("Can't compile a FunDef without body: "+funDef.id.name)
+        })
     }
 
     val locals = NoLocals.withVars(newMapping).withTypes(funDef.tparams.map(_.tp))
diff --git a/src/main/scala/leon/codegen/CompilationException.scala b/src/main/scala/leon/codegen/CompilationException.scala
index 9cb392ce8f845f8441f6a2f8426d374bdcdbba2c..a782e5c1f9a9d786a4e594e0b386dd333900945c 100644
--- a/src/main/scala/leon/codegen/CompilationException.scala
+++ b/src/main/scala/leon/codegen/CompilationException.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package codegen
diff --git a/src/main/scala/leon/codegen/CompilationUnit.scala b/src/main/scala/leon/codegen/CompilationUnit.scala
index 9cef8cd0452fa6596f1ebc2e86ed5d6f4d394c1f..1bc3600fb74e3af430167431cc68abdb050b95c2 100644
--- a/src/main/scala/leon/codegen/CompilationUnit.scala
+++ b/src/main/scala/leon/codegen/CompilationUnit.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package codegen
diff --git a/src/main/scala/leon/codegen/CompiledExpression.scala b/src/main/scala/leon/codegen/CompiledExpression.scala
index 6467a2068cf56227f26d01df6bec2287d515d48d..d6cb9a11eb611aabbf95519e1e9309c8562812f5 100644
--- a/src/main/scala/leon/codegen/CompiledExpression.scala
+++ b/src/main/scala/leon/codegen/CompiledExpression.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package codegen
diff --git a/src/main/scala/leon/codegen/runtime/GenericValues.scala b/src/main/scala/leon/codegen/runtime/GenericValues.scala
index 710371fea3c351aa76a16c7ae94b459feb144ce0..58ecf8547d07c3c964017d8014b5dd86ca9d6358 100644
--- a/src/main/scala/leon/codegen/runtime/GenericValues.scala
+++ b/src/main/scala/leon/codegen/runtime/GenericValues.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package codegen.runtime
diff --git a/src/main/scala/leon/codegen/runtime/RuntimeResources.scala b/src/main/scala/leon/codegen/runtime/RuntimeResources.scala
index 86c84d78396b0a59a6371906a90d4325b6bca0fd..f18f23b3f2c92cb93e2842695874d3b4ee661d55 100644
--- a/src/main/scala/leon/codegen/runtime/RuntimeResources.scala
+++ b/src/main/scala/leon/codegen/runtime/RuntimeResources.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.codegen.runtime
 
@@ -6,7 +6,6 @@ import leon.utils.UniqueCounter
 
 import java.util.WeakHashMap
 import java.lang.ref.WeakReference
-import scala.collection.mutable.{HashMap => MutableMap}
 
 /**
  * This class allows an evaluator to statically register a resource, identified
diff --git a/src/main/scala/leon/datagen/DataGenerator.scala b/src/main/scala/leon/datagen/DataGenerator.scala
index f2c1193f0438a7b168a0e9697ef5d8d11f50ce91..ea6aac313f357fd6c04577d8a00261e4dfa0fe5c 100644
--- a/src/main/scala/leon/datagen/DataGenerator.scala
+++ b/src/main/scala/leon/datagen/DataGenerator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package datagen
diff --git a/src/main/scala/leon/datagen/GrammarDataGen.scala b/src/main/scala/leon/datagen/GrammarDataGen.scala
index 04541e78a6e63d1fa8670f4d4aeb12dd9c4417a2..619b7660686c9ff984e85aaa867eab9f522aecd9 100644
--- a/src/main/scala/leon/datagen/GrammarDataGen.scala
+++ b/src/main/scala/leon/datagen/GrammarDataGen.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package datagen
@@ -19,7 +19,7 @@ import utils.SeqUtils.cartesianProduct
 /** Utility functions to generate values of a given type.
   * In fact, it could be used to generate *terms* of a given type,
   * e.g. by passing trees representing variables for the "bounds". */
-class GrammarDataGen(evaluator: Evaluator, grammar: ExpressionGrammar[TypeTree] = ValueGrammar) extends DataGenerator {
+class GrammarDataGen(evaluator: Evaluator, grammar: ExpressionGrammar = ValueGrammar) extends DataGenerator {
   implicit val ctx = evaluator.context
 
   // Assume e contains generic values with index 0.
@@ -54,8 +54,8 @@ class GrammarDataGen(evaluator: Evaluator, grammar: ExpressionGrammar[TypeTree]
   }
 
   def generate(tpe: TypeTree): Iterator[Expr] = {
-    val enum = new MemoizedEnumerator[TypeTree, Expr, ProductionRule[TypeTree, Expr]](grammar.getProductions)
-    enum.iterator(tpe).flatMap(expandGenerics)
+    val enum = new MemoizedEnumerator[Label, Expr, ProductionRule[Label, Expr]](grammar.getProductions)
+    enum.iterator(Label(tpe)).flatMap(expandGenerics)
   }
 
   def generateFor(ins: Seq[Identifier], satisfying: Expr, maxValid: Int, maxEnumerated: Int): Iterator[Seq[Expr]] = {
diff --git a/src/main/scala/leon/datagen/NaiveDataGen.scala b/src/main/scala/leon/datagen/NaiveDataGen.scala
index 121c42b8cd561fe5faecd6d59662e66f1c1c3e02..e40359e686e76030fb29171fe18c6eab82482898 100644
--- a/src/main/scala/leon/datagen/NaiveDataGen.scala
+++ b/src/main/scala/leon/datagen/NaiveDataGen.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package datagen
diff --git a/src/main/scala/leon/datagen/SolverDataGen.scala b/src/main/scala/leon/datagen/SolverDataGen.scala
index 3b20e3e357d72b0c6dd520830fbb6394b59115f7..3a222bd6b75cffe2909d6276c24019e9a7682963 100644
--- a/src/main/scala/leon/datagen/SolverDataGen.scala
+++ b/src/main/scala/leon/datagen/SolverDataGen.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package datagen
diff --git a/src/main/scala/leon/datagen/VanuatooDataGen.scala b/src/main/scala/leon/datagen/VanuatooDataGen.scala
index 1975400500b741a8fb59fe953b72faf08bf8968e..0b533e631dee5b0a41181262e0d8c8702b40ea62 100644
--- a/src/main/scala/leon/datagen/VanuatooDataGen.scala
+++ b/src/main/scala/leon/datagen/VanuatooDataGen.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package datagen
diff --git a/src/main/scala/leon/evaluators/AngelicEvaluator.scala b/src/main/scala/leon/evaluators/AngelicEvaluator.scala
index 57f233cf44caa63dd587e0d792eb33ec62b89d55..8230aa85845d35e0113aec976800cbe5a5f49799 100644
--- a/src/main/scala/leon/evaluators/AngelicEvaluator.scala
+++ b/src/main/scala/leon/evaluators/AngelicEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/CodeGenEvaluator.scala b/src/main/scala/leon/evaluators/CodeGenEvaluator.scala
index 59e9be41863b313202f3821e137419e8872cbc01..8521094fababa7b0679dee1bc84691a22048e822 100644
--- a/src/main/scala/leon/evaluators/CodeGenEvaluator.scala
+++ b/src/main/scala/leon/evaluators/CodeGenEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/ContextualEvaluator.scala b/src/main/scala/leon/evaluators/ContextualEvaluator.scala
index 51205fc5c8221c439801786b3c9ee3cc7b2e3287..90d1ac97070133d4d39f30a0ffcda84e7424e550 100644
--- a/src/main/scala/leon/evaluators/ContextualEvaluator.scala
+++ b/src/main/scala/leon/evaluators/ContextualEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/DefaultEvaluator.scala b/src/main/scala/leon/evaluators/DefaultEvaluator.scala
index 18a9159c3cb0e29f47e0757314f935865f6b10cf..b62446c8d1916537afb315dcac7e88c69b707e21 100644
--- a/src/main/scala/leon/evaluators/DefaultEvaluator.scala
+++ b/src/main/scala/leon/evaluators/DefaultEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
@@ -6,6 +6,6 @@ package evaluators
 import purescala.Definitions.Program
 
 class DefaultEvaluator(ctx: LeonContext, prog: Program)
-  extends RecursiveEvaluator(ctx, prog, 5000)
+  extends RecursiveEvaluator(ctx, prog, 50000)
   with HasDefaultGlobalContext
   with HasDefaultRecContext
diff --git a/src/main/scala/leon/evaluators/DualEvaluator.scala b/src/main/scala/leon/evaluators/DualEvaluator.scala
index 7976dbfc207679ee92f81b86fd4f00d582b2e9f0..a59559185cf1b2fde266dfc20b5802867d9444a1 100644
--- a/src/main/scala/leon/evaluators/DualEvaluator.scala
+++ b/src/main/scala/leon/evaluators/DualEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/EvaluationPhase.scala b/src/main/scala/leon/evaluators/EvaluationPhase.scala
index df2f4c42aebc0533fe6fb4b59d263067fa4804a3..a06d1b39a6be43d64832f5d5527fb34e74ce6c06 100644
--- a/src/main/scala/leon/evaluators/EvaluationPhase.scala
+++ b/src/main/scala/leon/evaluators/EvaluationPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
@@ -15,7 +15,7 @@ object EvaluationPhase extends UnitPhase[Program] {
   implicit val debugSection = utils.DebugSectionEvaluation
 
   def apply(ctx: LeonContext, program: Program): Unit = {
-    val evalFuns: Option[Seq[String]] = ctx.findOption(SharedOptions.optFunctions)
+    val evalFuns: Option[Seq[String]] = ctx.findOption(GlobalOptions.optFunctions)
 
     val evaluator = ctx.findOptionOrDefault(MainComponent.optEval)
 
diff --git a/src/main/scala/leon/evaluators/EvaluationResults.scala b/src/main/scala/leon/evaluators/EvaluationResults.scala
index b9cbecdde4cdd31b2b29dcb82fdd23c50aaf9a24..f7da29504b6143a15552818841685124204184f8 100644
--- a/src/main/scala/leon/evaluators/EvaluationResults.scala
+++ b/src/main/scala/leon/evaluators/EvaluationResults.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/Evaluator.scala b/src/main/scala/leon/evaluators/Evaluator.scala
index 400409577ac7aebf490d8a961ac44c67036989c7..a15febb65c31129db2d5ee37da88cd148dce3806 100644
--- a/src/main/scala/leon/evaluators/Evaluator.scala
+++ b/src/main/scala/leon/evaluators/Evaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/EvaluatorContexts.scala b/src/main/scala/leon/evaluators/EvaluatorContexts.scala
index a63ee6483bfcdb7804cd95bfcb32df83a66e235b..859e960d5d7aadbc63de656fd3c340fbc60b30f1 100644
--- a/src/main/scala/leon/evaluators/EvaluatorContexts.scala
+++ b/src/main/scala/leon/evaluators/EvaluatorContexts.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
index 689980682c86d03bb715b50e0dd2ff6ce530c331..f752b1895d9ac04a629d1b9b68c2a36d447cf07e 100644
--- a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
+++ b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
@@ -29,7 +29,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int
 
   lazy val scalaEv = new ScalacEvaluator(this, ctx, prog)
 
-  protected var clpCache = Map[(Choose, Seq[Expr]), Expr]()
+  protected val clpCache = MutableMap[(Choose, Seq[Expr]), Expr]()
   protected var frlCache = Map[(Forall, Seq[Expr]), Expr]()
 
   private var evaluationFailsOnChoose = false
diff --git a/src/main/scala/leon/evaluators/ScalacEvaluator.scala b/src/main/scala/leon/evaluators/ScalacEvaluator.scala
index 63bb9f6fa1193dee0fbda7a69500bd4c2e9fa9b8..db855fbcd77d78f51e0fef778c14cc565b4cf187 100644
--- a/src/main/scala/leon/evaluators/ScalacEvaluator.scala
+++ b/src/main/scala/leon/evaluators/ScalacEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/StreamEvaluator.scala b/src/main/scala/leon/evaluators/StreamEvaluator.scala
index 3fff6e523a945b23761a232094c9327ba276e201..16d42e892881044e7892de1de7bd23de8daf9911 100644
--- a/src/main/scala/leon/evaluators/StreamEvaluator.scala
+++ b/src/main/scala/leon/evaluators/StreamEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/evaluators/TracingEvaluator.scala b/src/main/scala/leon/evaluators/TracingEvaluator.scala
index 4c0b1f39c9126e4ccf0da6db389394fe0c33d294..4c9f81f2f28f573c24e8c2f60d5a5d7688b0bcb9 100644
--- a/src/main/scala/leon/evaluators/TracingEvaluator.scala
+++ b/src/main/scala/leon/evaluators/TracingEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package evaluators
diff --git a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
index f8509be9c4d678b10a52f7736a406bb078b6bfbc..7890d7a229da487e8ae8152ae92c7b0b066eb12e 100644
--- a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
+++ b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
@@ -399,14 +399,17 @@ trait ASTExtractors {
           }.get.asInstanceOf[DefDef]
 
           val valDefs = constructor.vparamss.flatten
+          //println("valDefs: " + valDefs)
 
           //impl.children foreach println
 
           val symbols = impl.children.collect {
-            case df: DefDef if df.symbol.isStable && df.symbol.isAccessor &&
-                df.symbol.isParamAccessor =>
-              df.symbol
+            case df@DefDef(_, name, _, _, _, _) if 
+              df.symbol.isAccessor && df.symbol.isParamAccessor 
+              && !name.endsWith("_$eq") => df.symbol
           }
+          //println("symbols: " + symbols)
+          //println("symbols accessed: " + symbols.map(_.accessed))
 
           //if (symbols.size != valDefs.size) {
           //  println(" >>>>> " + cd.name)
@@ -500,6 +503,36 @@ trait ASTExtractors {
         case _ => None
       }
     }
+
+    object ExMutatorAccessorFunction {
+      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 && 
+          !dd.symbol.isSynthetic && dd.symbol.isAccessor && name.endsWith("_$eq")
+        ) =>
+          Some((dd.symbol, tparams.map(_.symbol), vparamss.flatten, tpt.tpe, rhs))
+        case _ => None
+      }
+    }
+    object ExMutableFieldDef {
+
+      /** Matches a definition of a strict var field inside a class constructor */
+      def unapply(vd: SymTree) : Option[(Symbol, Type, Tree)] = {
+        val sym = vd.symbol
+        vd match {
+          // Implemented fields
+          case ValDef(mods, name, tpt, rhs) if (
+            !sym.isCaseAccessor && !sym.isParamAccessor && 
+            !sym.isLazy && !sym.isSynthetic && !sym.isAccessor && sym.isVar
+          ) =>
+            println("matched a var accessor field: sym is: " + sym)
+            println("getterIn is: " + sym.getterIn(sym.owner))
+            // Since scalac uses the accessor symbol all over the place, we pass that instead:
+            Some( (sym.getterIn(sym.owner),tpt.tpe,rhs) )
+          case _ => None
+        }
+      }
+    }
        
     object ExFieldDef {
       /** Matches a definition of a strict field inside a class constructor */
@@ -509,7 +542,7 @@ trait ASTExtractors {
           // Implemented fields
           case ValDef(mods, name, tpt, rhs) if (
             !sym.isCaseAccessor && !sym.isParamAccessor && 
-            !sym.isLazy && !sym.isSynthetic && !sym.isAccessor 
+            !sym.isLazy && !sym.isSynthetic && !sym.isAccessor && !sym.isVar
           ) =>
             // Since scalac uses the accessor symbol all over the place, we pass that instead:
             Some( (sym.getterIn(sym.owner),tpt.tpe,rhs) )
@@ -602,16 +635,6 @@ trait ASTExtractors {
       }
     }
 
-    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, Tree)] = tree match {
         case a @ Apply(TypeApply(ExSymbol("leon", "lang", "error"), List(tpe)), List(lit : Literal)) =>
@@ -705,6 +728,7 @@ trait ASTExtractors {
     object ExAssign {
       def unapply(tree: Assign): Option[(Symbol,Tree)] = tree match {
         case Assign(id@Ident(_), rhs) => Some((id.symbol, rhs))
+        //case Assign(sym@Select(This(_), v), rhs) => Some((sym.symbol, rhs))
         case _ => None
       }
     }
diff --git a/src/main/scala/leon/frontends/scalac/ClassgenPhase.scala b/src/main/scala/leon/frontends/scalac/ClassgenPhase.scala
index 3ac856763e13222f606e5e645d2f06a31e7fa60c..c7f5823ae6bf5e997758266693782df3a3e72518 100644
--- a/src/main/scala/leon/frontends/scalac/ClassgenPhase.scala
+++ b/src/main/scala/leon/frontends/scalac/ClassgenPhase.scala
@@ -1,9 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
 
-import purescala.Definitions.Program
 import utils._
 
 import scala.tools.nsc.{Settings,CompilerCommand}
diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
index 0451b4c08603fb1b10ae91e2e38cc8902cd1649d..85e587444a41b59e38a057ac6fc8e1c6e616b8e5 100644
--- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
+++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
@@ -71,7 +71,7 @@ trait CodeExtraction extends ASTExtractors {
   /** An exception thrown when non-purescala compatible code is encountered. */
   sealed class ImpureCodeEncounteredException(pos: Position, msg: String, ot: Option[Tree]) extends Exception(msg) {
     def emit() {
-      val debugInfo = if (ctx.findOptionOrDefault(SharedOptions.optDebug) contains utils.DebugSectionTrees) {
+      val debugInfo = if (ctx.findOptionOrDefault(GlobalOptions.optDebug) contains utils.DebugSectionTrees) {
         ot.map { t =>
           val strWr = new java.io.StringWriter()
           new global.TreePrinter(new java.io.PrintWriter(strWr)).printTree(t)
@@ -133,6 +133,10 @@ trait CodeExtraction extends ASTExtractors {
       def withNewMutableVar(nvar: (Symbol, () => LeonExpr)) = {
         copy(mutableVars = mutableVars + nvar)
       }
+
+      def withNewMutableVars(nvars: Traversable[(Symbol, () => LeonExpr)]) = {
+        copy(mutableVars = mutableVars ++ nvars)
+      }
     }
 
     private var currentFunDef: FunDef = null
@@ -281,6 +285,10 @@ trait CodeExtraction extends ASTExtractors {
             case ExFieldDef(sym, _, _) =>
               Some(defineFieldFunDef(sym, false)(DefContext()))
 
+            // var
+            case ExMutableFieldDef(sym, _, _) =>
+              Some(defineFieldFunDef(sym, false)(DefContext()))
+
             // All these are expected, but useless
             case ExCaseClassSyntheticJunk()
                | ExConstructorDef()
@@ -290,6 +298,12 @@ trait CodeExtraction extends ASTExtractors {
             case d if (d.symbol.isImplicit && d.symbol.isSynthetic) =>
               None
 
+            //vars are never accessed directly so we extract accessors and mutators and
+            //ignore bare variables
+            case d if d.symbol.isVar =>
+              None
+
+
             // Everything else is unexpected
             case tree =>
               println(tree)
@@ -463,6 +477,7 @@ trait CodeExtraction extends ASTExtractors {
     }
 
     private var isMethod = Set[Symbol]()
+    private var isMutator = Set[Symbol]()
     private var methodToClass = Map[FunDef, LeonClassDef]()
     private var classToInvariants = Map[Symbol, Set[Tree]]()
 
@@ -564,7 +579,7 @@ trait CodeExtraction extends ASTExtractors {
             val tpe = leonType(t.tpt.tpe)(defCtx, fsym.pos)
             val id = cachedWithOverrides(fsym, Some(ccd), tpe)
             if (tpe != id.getType) println(tpe, id.getType)
-            LeonValDef(id.setPos(t.pos)).setPos(t.pos)
+            LeonValDef(id.setPos(t.pos)).setPos(t.pos).setIsVar(fsym.accessed.isVar)
           }
 
           //println(s"Fields of $sym")
@@ -670,6 +685,25 @@ trait CodeExtraction extends ASTExtractors {
 
           cd.registerMethod(fd)
 
+        case t @ ExMutableFieldDef(fsym, _, _) =>
+          //println(fsym + "matched as ExMutableFieldDef")
+          // we will be using the accessor method of this field everywhere
+          //isMethod += fsym
+          //val fd = defineFieldFunDef(fsym, false, Some(cd))(defCtx)
+          //methodToClass += fd -> cd
+
+          //cd.registerMethod(fd)
+
+        case t@ ExMutatorAccessorFunction(fsym, _, _, _, _) =>
+          //println("FOUND mutator: " + t)
+          //println("accessed: " + fsym.accessed)
+          isMutator += fsym
+          //val fd = defineFunDef(fsym, Some(cd))(defCtx)
+
+          //methodToClass += fd -> cd
+
+          //cd.registerMethod(fd)
+
         case other =>
 
       }
@@ -688,7 +722,7 @@ trait CodeExtraction extends ASTExtractors {
       val topOfHierarchy = sym.overrideChain.last
 
       funOrFieldSymsToIds.cachedB(topOfHierarchy){
-        FreshIdentifier(sym.name.toString, tpe)
+        FreshIdentifier(sym.name.toString.trim, tpe) //trim because sometimes Scala names end with a trailing space, looks nicer without the space
       }
     }
 
@@ -827,6 +861,31 @@ trait CodeExtraction extends ASTExtractors {
             extractFunBody(fd, Seq(), body)(DefContext(tparamsMap.toMap))
           }
 
+        case t @ ExMutableFieldDef(sym, _, body) => // if !sym.isSynthetic && !sym.isAccessor =>
+          //val fd = defsToDefs(sym)
+          //val tparamsMap = ctparamsMap
+
+          //if(body != EmptyTree) {
+          //  extractFunBody(fd, Seq(), body)(DefContext(tparamsMap.toMap))
+          //}
+
+        case ExMutatorAccessorFunction(sym, tparams, params, _, body) =>
+          //val fd = defsToDefs(sym)
+
+          //val tparamsMap = (tparams zip fd.tparams.map(_.tp)).toMap ++ ctparamsMap
+
+          //val classSym = ocsym.get
+          //val cd = classesToClasses(classSym).asInstanceOf[CaseClassDef]
+          //val classVarDefs = seenClasses(classSym)._2
+          //val mutableFields = classVarDefs.zip(cd.varFields).map(p => (p._1._1, () => p._2.toVariable))
+
+          //val dctx = DefContext(tparamsMap)
+          //val pctx = dctx.withNewMutableVars(mutableFields)
+
+          //if(body != EmptyTree) {
+          //  extractFunBody(fd, params, body)(pctx)
+          //}
+
         case _ =>
       }
     }
@@ -1234,15 +1293,16 @@ trait CodeExtraction extends ASTExtractors {
           LetVar(newID, valTree, restTree)
         }
 
-        case ExAssign(sym, rhs) => dctx.mutableVars.get(sym) match {
+        case a@ExAssign(sym, rhs) => {
+          dctx.mutableVars.get(sym) match {
           case Some(fun) =>
             val Variable(id) = fun()
             val rhsTree = extractTree(rhs)
             Assignment(id, rhsTree)
 
           case None =>
-            outOfSubsetError(tr, "Undeclared variable.")
-        }
+            outOfSubsetError(a, "Undeclared variable.")
+        }}
 
         case wh @ ExWhile(cond, body) =>
           val condTree = extractTree(cond)
@@ -1267,11 +1327,6 @@ trait CodeExtraction extends ASTExtractors {
           }
           Epsilon(c1, pstpe)
 
-        case ExWaypointExpression(tpt, i, tree) =>
-          val pstpe = extractType(tpt)
-          val IntLiteral(ri) = extractTree(i)
-          Waypoint(ri, extractTree(tree), pstpe)
-
         case update @ ExUpdate(lhs, index, newValue) =>
           val lhsRec = extractTree(lhs)
           lhsRec match {
@@ -1568,7 +1623,7 @@ trait CodeExtraction extends ASTExtractors {
         case c @ ExCall(rec, sym, tps, args) =>
           // The object on which it is called is null if the symbol sym is a valid function in the scope and not a method.
           val rrec = rec match {
-            case t if (defsToDefs contains sym) && !isMethod(sym) =>
+            case t if (defsToDefs contains sym) && !isMethod(sym) && !isMutator(sym) =>
               null
             case _ =>
               extractTree(rec)
@@ -1605,6 +1660,11 @@ trait CodeExtraction extends ASTExtractors {
 
               caseClassSelector(cct, rec, fieldID)
 
+            //mutable variables
+            case (IsTyped(rec, cct: CaseClassType), name, List(e1)) if isMutator(sym) =>
+              val id = cct.classDef.fields.find(_.id.name == name.dropRight(2)).get.id
+              FieldAssignment(rec, id, e1)
+
             //String methods
             case (IsTyped(a1, StringType), "toString", List()) =>
               a1
@@ -1798,6 +1858,7 @@ trait CodeExtraction extends ASTExtractors {
             case (IsTyped(a1, CharType), "<=", List(IsTyped(a2, CharType))) =>
               LessEquals(a1, a2)
 
+
             case (a1, name, a2) =>
               val typea1 = a1.getType
               val typea2 = a2.map(_.getType).mkString(",")
diff --git a/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala b/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala
index ffb4fa90c3bb15c682f7886f3d3bbf9ee79c508b..3a338b9f00be52c27afbf5893843a233112dd37e 100644
--- a/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala
+++ b/src/main/scala/leon/frontends/scalac/ExtractionPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
diff --git a/src/main/scala/leon/frontends/scalac/FullScalaCompiler.scala b/src/main/scala/leon/frontends/scalac/FullScalaCompiler.scala
index 2ae74e2020ccc391f5b478d60fda42d5f2809ab5..72e98e01561d954abe1048d80753228b0459e935 100644
--- a/src/main/scala/leon/frontends/scalac/FullScalaCompiler.scala
+++ b/src/main/scala/leon/frontends/scalac/FullScalaCompiler.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
diff --git a/src/main/scala/leon/frontends/scalac/LeonExtraction.scala b/src/main/scala/leon/frontends/scalac/LeonExtraction.scala
index 3bc1a0d05396479bd4d4d723ee8e1aca5a53c488..10ca2cb97214a5046dbabaedf060352402582ed8 100644
--- a/src/main/scala/leon/frontends/scalac/LeonExtraction.scala
+++ b/src/main/scala/leon/frontends/scalac/LeonExtraction.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
diff --git a/src/main/scala/leon/frontends/scalac/SaveImports.scala b/src/main/scala/leon/frontends/scalac/SaveImports.scala
index b9e557ff76b9043fce199f52a0951136795ddcd3..bed944f38b15568509de54fcb26aebf30eec127d 100644
--- a/src/main/scala/leon/frontends/scalac/SaveImports.scala
+++ b/src/main/scala/leon/frontends/scalac/SaveImports.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
diff --git a/src/main/scala/leon/frontends/scalac/ScalaCompiler.scala b/src/main/scala/leon/frontends/scalac/ScalaCompiler.scala
index a98bd86fbe23cc698456c8319379b6b06f5b90ec..0ae89a4633c0e5a7c87c35d965b2653418e443cf 100644
--- a/src/main/scala/leon/frontends/scalac/ScalaCompiler.scala
+++ b/src/main/scala/leon/frontends/scalac/ScalaCompiler.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
diff --git a/src/main/scala/leon/frontends/scalac/SimpleReporter.scala b/src/main/scala/leon/frontends/scalac/SimpleReporter.scala
index c203ee63c17585c9bcf5922762e3046e8662c888..79a3495c64c26e7ca7111811d0a84318ce3f5ba1 100644
--- a/src/main/scala/leon/frontends/scalac/SimpleReporter.scala
+++ b/src/main/scala/leon/frontends/scalac/SimpleReporter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package frontends.scalac
diff --git a/src/main/scala/leon/genc/CAST.scala b/src/main/scala/leon/genc/CAST.scala
index 9a9242859e799488eeb8a42170f6fcedd1b0dd13..a05f3beb98d21e0c77a3222004645af5e35555fe 100644
--- a/src/main/scala/leon/genc/CAST.scala
+++ b/src/main/scala/leon/genc/CAST.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package genc
diff --git a/src/main/scala/leon/genc/CConverter.scala b/src/main/scala/leon/genc/CConverter.scala
index a979fd8dd0c28351948270048adf53ed597a1317..ea3130d4c337bbfb4812269dcbe73fa63c9420eb 100644
--- a/src/main/scala/leon/genc/CConverter.scala
+++ b/src/main/scala/leon/genc/CConverter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package genc
@@ -156,7 +156,7 @@ class CConverter(val ctx: LeonContext, val prog: Program) {
     val extraParams = funCtx.toParams
     val params      = extraParams ++ stdParams
 
-    // Function Context:
+    // Function LeonContext:
     // 1) Save the variables of the current context for later function invocation
     // 2) Lift & augment funCtx with the current function's arguments
     // 3) Propagate it to the current function's body
diff --git a/src/main/scala/leon/genc/CFileOutputPhase.scala b/src/main/scala/leon/genc/CFileOutputPhase.scala
index f2b7797183da17ccb6e326a85a779a4ef58be9e2..2e687e0b7056bc2c777e0516c304b02014e4ed1e 100644
--- a/src/main/scala/leon/genc/CFileOutputPhase.scala
+++ b/src/main/scala/leon/genc/CFileOutputPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package genc
diff --git a/src/main/scala/leon/genc/CPrinter.scala b/src/main/scala/leon/genc/CPrinter.scala
index eec404f0c5283bbf09e56dbe79e8335286f61ae6..9c38fcf81574a2223c0f084f7ddb2f8e45f8c537 100644
--- a/src/main/scala/leon/genc/CPrinter.scala
+++ b/src/main/scala/leon/genc/CPrinter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package genc
diff --git a/src/main/scala/leon/genc/CPrinterHelper.scala b/src/main/scala/leon/genc/CPrinterHelper.scala
index 5c32df8b7289b0ca5510d04680ab449e915a12dd..a173aa24b5df3ef352f2ef4bb49a79d88ccefc7f 100644
--- a/src/main/scala/leon/genc/CPrinterHelper.scala
+++ b/src/main/scala/leon/genc/CPrinterHelper.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package genc
diff --git a/src/main/scala/leon/genc/GenerateCPhase.scala b/src/main/scala/leon/genc/GenerateCPhase.scala
index c30d32274db7370a8f9af5616df3cbe505b0389e..2d66adbc969d0fe8ad8488c25e6cf9a12362fb69 100644
--- a/src/main/scala/leon/genc/GenerateCPhase.scala
+++ b/src/main/scala/leon/genc/GenerateCPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package genc
diff --git a/src/main/scala/leon/grammars/Aspect.scala b/src/main/scala/leon/grammars/Aspect.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a7761faab9ff18955f7f489c7196d94424ee6d30
--- /dev/null
+++ b/src/main/scala/leon/grammars/Aspect.scala
@@ -0,0 +1,34 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+
+import purescala.Expressions.Expr
+import utils.SeqUtils._
+import Tags._
+
+/**
+ * An Aspect applies to a label, and attaches information to it.
+ *
+ * For instance, the "size" aspect provides information about the size of
+ * expressions the label represents, (displayed as |5|).
+ *
+ * Int|5| is thus a Label "Int" with aspect "Sized(5)". The applyTo method of
+ * the aspect can filter/modify/generate sub-productions:
+ * If the grammar contains a Int -> Int + Int production, then
+ * Int|5| will generate productions by doing: |5|.applyTo(Int + Int),
+ * which itself returns:
+ *   - Int|1| + Int|3|
+ *   - Int|3| + Int|1|
+ *   - Int|2| + Int|2|
+ *
+ */
+
+
+abstract class Aspect {
+  type Production = ProductionRule[Label, Expr]
+
+  def asString(implicit ctx: LeonContext): String
+
+  def applyTo(l: Label, ps: Seq[Production])(implicit ctx: LeonContext): Seq[Production]
+}
diff --git a/src/main/scala/leon/grammars/BaseGrammar.scala b/src/main/scala/leon/grammars/BaseGrammar.scala
index 6e0a2ee5e6842255aac5755c9ee27005e5360eb5..ee3a85791f7bbcbc620736188caa5de0f1df2d84 100644
--- a/src/main/scala/leon/grammars/BaseGrammar.scala
+++ b/src/main/scala/leon/grammars/BaseGrammar.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -12,7 +12,7 @@ import purescala.Constructors._
   * without regard of context (variables in scope, current function etc.)
   * Also does some trivial simplifications.
   */
-case object BaseGrammar extends ExpressionGrammar[TypeTree] {
+case object BaseGrammar extends SimpleExpressionGrammar {
 
   def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = t match {
     case BooleanType =>
@@ -42,9 +42,9 @@ case object BaseGrammar extends ExpressionGrammar[TypeTree] {
         terminal(InfiniteIntegerLiteral(1), Tags.One ),
         nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => plus(a, b)  }, Tags.Plus ),
         nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => minus(a, b) }, Tags.Minus),
-        nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => times(a, b) }, Tags.Times),
-        nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => Modulo(a, b)   }, Tags.Mod),
-        nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => Division(a, b) }, Tags.Div)
+        nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => times(a, b) }, Tags.Times)//,
+        //nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => Modulo(a, b)   }, Tags.Mod),
+        //nonTerminal(List(IntegerType, IntegerType), { case Seq(a,b) => Division(a, b) }, Tags.Div)
       )
 
     case TupleType(stps) =>
diff --git a/src/main/scala/leon/grammars/Closures.scala b/src/main/scala/leon/grammars/Closures.scala
new file mode 100644
index 0000000000000000000000000000000000000000..10153430291cd32c4cb842622cea742ed09b1831
--- /dev/null
+++ b/src/main/scala/leon/grammars/Closures.scala
@@ -0,0 +1,29 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+
+import purescala.Types._
+import purescala.TypeOps._
+import purescala.Definitions._
+import purescala.Expressions._
+import purescala.Common._
+import purescala.Constructors._
+
+case object Closures extends ExpressionGrammar {
+  def computeProductions(lab: Label)(implicit ctx: LeonContext): Seq[ProductionRule[Label, Expr]] = lab.getType match {
+    case FunctionType(argsTpes, ret) =>
+      val args = argsTpes.zipWithIndex.map { case (tpe, i) =>
+        ValDef(FreshIdentifier("a"+i, tpe))
+      }
+
+      val rlab = Label(ret).withAspect(aspects.ExtraTerminals(args.map(_.toVariable).toSet))
+
+      applyAspects(lab, List(
+        ProductionRule(List(rlab), { case List(body) => Lambda(args, body) }, Tags.Top, 1)
+      ))
+
+    case _ =>
+      Nil
+  }
+}
diff --git a/src/main/scala/leon/grammars/Constants.scala b/src/main/scala/leon/grammars/Constants.scala
index 81c55346052668e0d82b05ee240867eb1e5c468c..a542a9a0e5bcd22468d88bfdfa2f4e953c9bd43c 100644
--- a/src/main/scala/leon/grammars/Constants.scala
+++ b/src/main/scala/leon/grammars/Constants.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -11,7 +11,7 @@ import purescala.Extractors.IsTyped
 /** Generates constants found in an [[leon.purescala.Expressions.Expr]].
   * Some constants that are generated by other grammars (like 0, 1) will be excluded
   */
-case class Constants(e: Expr) extends ExpressionGrammar[TypeTree] {
+case class Constants(e: Expr) extends SimpleExpressionGrammar {
 
   private val excluded: Set[Expr] = Set(
     InfiniteIntegerLiteral(1),
@@ -30,4 +30,4 @@ case class Constants(e: Expr) extends ExpressionGrammar[TypeTree] {
 
     (literals -- excluded map (terminal(_, Tags.Constant))).toSeq
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/leon/grammars/Empty.scala b/src/main/scala/leon/grammars/Empty.scala
index 737f9cdf389454f403a6581e13eec7fafa383f34..79f3918206008f708bb2c3cd5c850819b67a1a64 100644
--- a/src/main/scala/leon/grammars/Empty.scala
+++ b/src/main/scala/leon/grammars/Empty.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -6,6 +6,6 @@ package grammars
 import purescala.Types.Typed
 
 /** The empty expression grammar */
-case class Empty[T <: Typed]() extends ExpressionGrammar[T] {
-  def computeProductions(t: T)(implicit ctx: LeonContext): Seq[Prod] = Nil
+case class Empty() extends ExpressionGrammar {
+  def computeProductions(l: Label)(implicit ctx: LeonContext) = Nil
 }
diff --git a/src/main/scala/leon/grammars/EqualityGrammar.scala b/src/main/scala/leon/grammars/EqualityGrammar.scala
index a2f9c41360ada03334ace63eca3ca46f9f6d5ff7..8ffa268788fd94f96d9d4f89079a1f56a90601bd 100644
--- a/src/main/scala/leon/grammars/EqualityGrammar.scala
+++ b/src/main/scala/leon/grammars/EqualityGrammar.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -10,7 +10,7 @@ import purescala.Constructors._
   *
   * @param types The set of types for which equalities will be generated
   */
-case class EqualityGrammar(types: Set[TypeTree]) extends ExpressionGrammar[TypeTree] {
+case class EqualityGrammar(types: Set[TypeTree]) extends SimpleExpressionGrammar {
   def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = t match {
     case BooleanType =>
       types.toList map { tp =>
diff --git a/src/main/scala/leon/grammars/ExpressionGrammar.scala b/src/main/scala/leon/grammars/ExpressionGrammar.scala
index 3179312b7f65444eb3e8c39357fd449e13339c8f..8c5e304e531442acab8b5dbf17c7d03863191528 100644
--- a/src/main/scala/leon/grammars/ExpressionGrammar.scala
+++ b/src/main/scala/leon/grammars/ExpressionGrammar.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -6,74 +6,81 @@ package grammars
 import purescala.Expressions._
 import purescala.Types._
 import purescala.Common._
-import transformers.Union
-import utils.Timer
 
 import scala.collection.mutable.{HashMap => MutableMap}
 
 /** Represents a context-free grammar of expressions
-  *
-  * @tparam T The type of nonterminal symbols for this grammar
   */
-abstract class ExpressionGrammar[T <: Typed] {
+abstract class ExpressionGrammar {
 
-  type Prod = ProductionRule[T, Expr]
-
-  private[this] val cache = new MutableMap[T, Seq[Prod]]()
-
-  /** Generates a [[ProductionRule]] without nonterminal symbols */
-  def terminal(builder: => Expr, tag: Tags.Tag = Tags.Top, cost: Int = 1) = {
-    ProductionRule[T, Expr](Nil, { (subs: Seq[Expr]) => builder }, tag, cost)
-  }
-
-  /** Generates a [[ProductionRule]] with nonterminal symbols */
-  def nonTerminal(subs: Seq[T], builder: (Seq[Expr] => Expr), tag: Tags.Tag = Tags.Top, cost: Int = 1): ProductionRule[T, Expr] = {
-    ProductionRule[T, Expr](subs, builder, tag, cost)
-  }
+  private[this] val cache = new MutableMap[Label, Seq[ProductionRule[Label, Expr]]]()
 
   /** The list of production rules for this grammar for a given nonterminal.
     * This is the cached version of [[getProductions]] which clients should use.
     *
-    * @param t The nonterminal for which production rules will be generated
+    * @param lab The nonterminal for which production rules will be generated
     */
-  def getProductions(t: T)(implicit ctx: LeonContext): Seq[Prod] = {
-    cache.getOrElse(t, {
-      val res = computeProductions(t)
-      cache += t -> res
+  def getProductions(lab: Label)(implicit ctx: LeonContext) = {
+    cache.getOrElse(lab, {
+      val res = applyAspects(lab, computeProductions(lab))
+      cache += lab -> res
       res
     })
   }
 
   /** The list of production rules for this grammar for a given nonterminal
     *
-    * @param t The nonterminal for which production rules will be generated
+    * @param lab The nonterminal for which production rules will be generated
     */
-  def computeProductions(t: T)(implicit ctx: LeonContext): Seq[Prod]
+  def computeProductions(lab: Label)(implicit ctx: LeonContext): Seq[ProductionRule[Label, Expr]]
+
 
-  def filter(f: Prod => Boolean) = {
-    new ExpressionGrammar[T] {
-      def computeProductions(t: T)(implicit ctx: LeonContext) = ExpressionGrammar.this.computeProductions(t).filter(f)
+  def applyAspects(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
+    lab.aspects.foldLeft(ps) {
+      case (ps, a) => a.applyTo(lab, ps)
     }
   }
 
-  final def ||(that: ExpressionGrammar[T]): ExpressionGrammar[T] = {
+  final def ||(that: ExpressionGrammar): ExpressionGrammar = {
     Union(Seq(this, that))
   }
 
-
   final def printProductions(printer: String => Unit)(implicit ctx: LeonContext) {
-    for ((t, gs) <- cache) {
-      val lhs = f"${Console.BOLD}${t.asString}%50s${Console.RESET} ::="
-      if (gs.isEmpty) {
-        printer(s"$lhs ε")
-      } else for (g <- gs) {
-        val subs = g.subTrees.map { t =>
-          FreshIdentifier(Console.BOLD + t.asString + Console.RESET, t.getType).toVariable
-        }
+    def sorter(lp1: (Label, Seq[ProductionRule[Label, Expr]]), lp2: (Label, Seq[ProductionRule[Label, Expr]])): Boolean = {
+      val l1 = lp1._1
+      val l2 = lp2._1
+
+      val os1 = l1.aspects.collectFirst { case aspects.Sized(size) => size }
+      val os2 = l2.aspects.collectFirst { case aspects.Sized(size) => size }
+
+      (os1, os2) match {
+        case (Some(s1), Some(s2)) =>
+          if (s1 > s2) {
+            true
+          } else if (s1 == s2) {
+            l1.asString < l2.asString
+          } else {
+            false
+          }
+        case _ => l1.asString < l2.asString
+      }
+    }
 
-        val gen = g.builder(subs).asString
 
-        printer(s"$lhs $gen")
+    for ((lab, gs) <- cache.toSeq.sortWith(sorter)) {
+      val lhs = f"${Console.BOLD}${lab.asString}%50s${Console.RESET} ::= "
+
+      if (gs.isEmpty) {
+        printer(s"${lhs}ε")
+      } else {
+        val rhs = for (g <- gs) yield {
+          val subs = g.subTrees.map { t =>
+            FreshIdentifier(Console.BOLD + t.asString + Console.RESET, t.getType).toVariable
+          }
+
+          g.builder(subs).asString
+        }
+        printer(lhs + rhs.mkString("\n" + " " * 55))
       }
     }
   }
diff --git a/src/main/scala/leon/grammars/FunctionCalls.scala b/src/main/scala/leon/grammars/FunctionCalls.scala
index 1233fb1931a83b5ca674019be0c85144339dd19f..c8110a0208d5c893b2b56bb33751586436fe8ca8 100644
--- a/src/main/scala/leon/grammars/FunctionCalls.scala
+++ b/src/main/scala/leon/grammars/FunctionCalls.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -16,7 +16,7 @@ import purescala.Expressions._
   * @param types The candidate real type parameters for [[currentFunction]]
   * @param exclude An additional set of functions for which no calls will be generated
   */
-case class FunctionCalls(prog: Program, currentFunction: FunDef, types: Seq[TypeTree], exclude: Set[FunDef]) extends ExpressionGrammar[TypeTree] {
+case class FunctionCalls(prog: Program, currentFunction: FunDef, types: Seq[TypeTree], exclude: Set[FunDef]) extends SimpleExpressionGrammar {
   def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = {
 
      def getCandidates(fd: FunDef): Seq[TypedFunDef] = {
@@ -63,8 +63,7 @@ case class FunctionCalls(prog: Program, currentFunction: FunDef, types: Seq[Type
                  }
                }
              } else {
-               /* All type parameters that used to be free are assigned
-                */
+               // All type parameters that used to be free are assigned
                List(tfd)
              }
            case None =>
@@ -75,7 +74,7 @@ case class FunctionCalls(prog: Program, currentFunction: FunDef, types: Seq[Type
        }
      }
 
-     val filter = (tfd:TypedFunDef) => tfd.fd.isSynthetic || (exclude contains tfd.fd)
+     val filter = (tfd:TypedFunDef) => tfd.fd.isSynthetic || tfd.fd.isInner || (exclude contains tfd.fd)
      val funcs = visibleFunDefsFromMain(prog).toSeq.sortBy(_.id).flatMap(getCandidates).filterNot(filter)
 
      funcs.map{ tfd =>
diff --git a/src/main/scala/leon/grammars/Grammars.scala b/src/main/scala/leon/grammars/Grammars.scala
index 06aba3d5f5343cc7e2807854f0b4665bfa1a602c..7ed0760f4c3ff639f938cac6e274e4bf04fee395 100644
--- a/src/main/scala/leon/grammars/Grammars.scala
+++ b/src/main/scala/leon/grammars/Grammars.scala
@@ -1,33 +1,34 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
 
+import synthesis.Witnesses.Hint
 import purescala.Expressions._
 import purescala.Definitions._
 import purescala.Types._
 import purescala.TypeOps._
-import transformers.OneOf
+import purescala.Extractors.TopLevelAnds
+import purescala.ExprOps.formulaSize
 
 import synthesis.{SynthesisContext, Problem}
 
 object Grammars {
 
-  def default(prog: Program, inputs: Seq[Expr], currentFunction: FunDef, exclude: Set[FunDef], ws: Expr, pc: Expr): ExpressionGrammar[TypeTree] = {
+  def default(prog: Program, inputs: Seq[Expr], currentFunction: FunDef, exclude: Set[FunDef]): ExpressionGrammar = {
     BaseGrammar ||
+    Closures ||
     EqualityGrammar(Set(IntegerType, Int32Type, BooleanType) ++ inputs.map { _.getType }) ||
     OneOf(inputs) ||
     Constants(currentFunction.fullBody) ||
-    FunctionCalls(prog, currentFunction, inputs.map(_.getType), exclude) ||
-    SafeRecursiveCalls(prog, ws, pc)
+    // SafeRecursiveCalls(prog, ws, pc) ||
+    FunctionCalls(prog, currentFunction, inputs.map(_.getType), exclude)
   }
 
-  def default(sctx: SynthesisContext, p: Problem): ExpressionGrammar[TypeTree] = {
-    default(sctx.program, p.as.map(_.toVariable), sctx.functionContext, sctx.settings.functionsToIgnore,  p.ws, p.pc)
-  }
-
-  def typeDepthBound[T <: Typed](g: ExpressionGrammar[T], b: Int) = {
-    g.filter(g => g.subTrees.forall(t => typeDepth(t.getType) <= b))
+  def default(sctx: SynthesisContext, p: Problem, extraHints: Seq[Expr] = Seq()): ExpressionGrammar = {
+    val TopLevelAnds(ws) = p.ws
+    val hints = ws.collect{ case Hint(e) if formulaSize(e) >= 4 => e }
+    default(sctx.program, p.as.map(_.toVariable) ++ hints ++ extraHints, sctx.functionContext, sctx.settings.functionsToIgnore)
   }
 }
 
diff --git a/src/main/scala/leon/grammars/Label.scala b/src/main/scala/leon/grammars/Label.scala
new file mode 100644
index 0000000000000000000000000000000000000000..dc3e98ea9be6334699a2001009e58922a470acd5
--- /dev/null
+++ b/src/main/scala/leon/grammars/Label.scala
@@ -0,0 +1,20 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+
+import purescala.Types._
+import purescala.Expressions._
+import purescala.Constructors._
+
+case class Label(tpe: TypeTree, aspects: List[Aspect] = Nil) extends Typed {
+  val getType = tpe
+
+  def asString(implicit ctx: LeonContext): String = {
+    val ts = tpe.asString
+
+    ts + aspects.map(_.asString).mkString
+  }
+
+  def withAspect(a: Aspect) = Label(tpe, aspects :+ a)
+}
diff --git a/src/main/scala/leon/grammars/NonTerminal.scala b/src/main/scala/leon/grammars/NonTerminal.scala
index 600189ffa06378841f6bf3285f7f1bd7bb6116f5..c57283f264833a358a13ceb8a590f302df9e6143 100644
--- a/src/main/scala/leon/grammars/NonTerminal.scala
+++ b/src/main/scala/leon/grammars/NonTerminal.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
diff --git a/src/main/scala/leon/grammars/OneOf.scala b/src/main/scala/leon/grammars/OneOf.scala
new file mode 100644
index 0000000000000000000000000000000000000000..cad657b839ced11133f0dabb1d7b53bd806ff7a9
--- /dev/null
+++ b/src/main/scala/leon/grammars/OneOf.scala
@@ -0,0 +1,18 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package grammars
+
+import purescala.Expressions.Expr
+import purescala.TypeOps._
+import purescala.Types.TypeTree
+
+/** Generates one production rule for each expression in a sequence that has compatible type */
+case class OneOf(inputs: Seq[Expr]) extends SimpleExpressionGrammar {
+  def computeProductions(lab: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = {
+    inputs.collect {
+      case i if isSubtypeOf(i.getType, lab.getType) =>
+        terminal(i)
+    }
+  }
+}
diff --git a/src/main/scala/leon/grammars/ProductionRule.scala b/src/main/scala/leon/grammars/ProductionRule.scala
index fc493a7d9d17557a26a8e54ff4615d39ba922190..ad740484708a2e8a1a2a6b4224a8ee17b762c2c4 100644
--- a/src/main/scala/leon/grammars/ProductionRule.scala
+++ b/src/main/scala/leon/grammars/ProductionRule.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -14,5 +14,5 @@ import bonsai.Generator
  *  @tparam T The type of nonterminal symbols of the grammar
  *  @tparam R The type of syntax trees of the grammar
  */
-case class ProductionRule[T, R](override val subTrees: Seq[T], override val builder: Seq[R] => R, tag: Tags.Tag, cost: Int = 1)
+case class ProductionRule[T, R](override val subTrees: Seq[T], override val builder: Seq[R] => R, tag: Tags.Tag, cost: Int)
   extends Generator[T,R](subTrees, builder)
diff --git a/src/main/scala/leon/grammars/SafeRecursiveCalls.scala b/src/main/scala/leon/grammars/SafeRecursiveCalls.scala
index f3234176a8c17378a7a5f027f38cbd42069ae7d6..679f6f76447ba52bf6eb2f3884e5780c30e6d951 100644
--- a/src/main/scala/leon/grammars/SafeRecursiveCalls.scala
+++ b/src/main/scala/leon/grammars/SafeRecursiveCalls.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -14,20 +14,20 @@ import synthesis.utils.Helpers._
   * @param ws An expression that contains the known set [[synthesis.Witnesses.Terminating]] expressions
   * @param pc The path condition for the generated [[Expr]] by this grammar
   */
-case class SafeRecursiveCalls(prog: Program, ws: Expr, pc: Expr) extends ExpressionGrammar[TypeTree] {
+case class SafeRecursiveCalls(prog: Program, ws: Expr, pc: Expr) extends SimpleExpressionGrammar {
   def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = {
-    val calls = terminatingCalls(prog, t, ws, pc)
+    val calls = terminatingCalls(prog,ws, pc, Some(t), true)
 
-    calls.map {
-      case (fi, free) =>
+    calls.map { c => (c: @unchecked) match {
+      case (fi, Some(free)) =>
         val freeSeq = free.toSeq
 
         nonTerminal(
           freeSeq.map(_.getType),
-          { sub => replaceFromIDs(freeSeq.zip(sub).toMap, fi) },
+          sub => replaceFromIDs(freeSeq.zip(sub).toMap, fi),
           Tags.tagOf(fi.tfd.fd, isSafe = true),
-          2
+          formulaSize(fi) - freeSeq.size
         )
-    }
+    }}
   }
 }
diff --git a/src/main/scala/leon/grammars/SimilarTo.scala b/src/main/scala/leon/grammars/SimilarTo.scala
index 3a7708e9a77960ffbfde98d478d2ca7c73c713d0..295f18311213ff6b93316477c09926957f777527 100644
--- a/src/main/scala/leon/grammars/SimilarTo.scala
+++ b/src/main/scala/leon/grammars/SimilarTo.scala
@@ -1,9 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
 
-import transformers._
 import purescala.Types._
 import purescala.TypeOps._
 import purescala.Extractors._
@@ -14,164 +13,160 @@ import synthesis._
 
 /** A grammar that generates expressions by inserting small variations in [[e]]
  * @param e The [[Expr]] to which small variations will be inserted
- * @param terminals A set of [[Expr]]s that may be inserted into [[e]] as small variations
  */
-case class SimilarTo(e: Expr, terminals: Set[Expr] = Set(), sctx: SynthesisContext, p: Problem) extends ExpressionGrammar[NonTerminal[String]] {
-
-  val excludeFCalls = sctx.settings.functionsToIgnore
-
-  val normalGrammar: ExpressionGrammar[NonTerminal[String]] = DepthBoundedGrammar(EmbeddedGrammar(
-      BaseGrammar ||
-      EqualityGrammar(Set(IntegerType, Int32Type, BooleanType) ++ terminals.map { _.getType }) ||
-      OneOf(terminals.toSeq :+ e) ||
-      FunctionCalls(sctx.program, sctx.functionContext, p.as.map(_.getType), excludeFCalls) ||
-      SafeRecursiveCalls(sctx.program, p.ws, p.pc),
-    { (t: TypeTree)      => NonTerminal(t, "B", None)},
-    { (l: NonTerminal[String]) => l.getType }
-  ), 1)
-
-  type L = NonTerminal[String]
-
-  val getNext: () => Int = {
-    var counter = -1
-    () => {
-      counter += 1
-      counter
-    }
-  }
-
-  private[this] var similarCache: Option[Map[L, Seq[Prod]]] = None
-
-  def computeProductions(t: L)(implicit ctx: LeonContext): Seq[Prod] = {
-    t match {
-      case NonTerminal(_, "B", _) => normalGrammar.computeProductions(t)
-      case _                =>
-
-        val allSimilar = similarCache.getOrElse {
-          val res = computeSimilar(e).groupBy(_._1).mapValues(_.map(_._2))
-          similarCache = Some(res)
-          res
-        }
-
-        allSimilar.getOrElse(t, Nil)
-    }
-  }
-
-  def computeSimilar(e : Expr)(implicit ctx: LeonContext): Seq[(L, Prod)] = {
-
-    def getLabel(t: TypeTree) = {
-      val tpe = bestRealType(t)
-      val c = getNext()
-      NonTerminal(tpe, "G"+c)
-    }
-
-    def isCommutative(e: Expr) = e match {
-      case _: Plus | _: Times => true
-      case _ => false
-    }
-
-    def rec(e: Expr, gl: L): Seq[(L, Prod)] = {
-
-      def gens(e: Expr, gl: L, subs: Seq[Expr], builder: (Seq[Expr] => Expr)): Seq[(L, Prod)] = {
-        val subGls = subs.map { s => getLabel(s.getType) }
-
-        // All the subproductions for sub gl
-        val allSubs = (subs zip subGls).flatMap { case (e, gl) => rec(e, gl) }
-
-        // Inject fix at one place
-        val injectG = for ((sgl, i) <- subGls.zipWithIndex) yield {
-          gl -> nonTerminal(Seq(sgl), { case Seq(ge) => builder(subs.updated(i, ge)) } )
-        }
-
-        val swaps = if (subs.size > 1 && !isCommutative(e)) {
-          (for (i <- subs.indices;
-                j <- i+1 until subs.size) yield {
-
-            if (subs(i).getType == subs(j).getType) {
-              val swapSubs = subs.updated(i, subs(j)).updated(j, subs(i))
-              Some(gl -> terminal(builder(swapSubs)))
-            } else {
-              None
-            }
-          }).flatten
-        } else {
-          Nil
-        }
-
-        allSubs ++ injectG ++ swaps
-      }
-
-      def cegis(gl: L): Seq[(L, Prod)] = {
-        normalGrammar.getProductions(gl).map(gl -> _)
-      }
-
-      def int32Variations(gl: L, e : Expr): Seq[(L, Prod)] = {
-        Seq(
-          gl -> terminal(BVMinus(e, IntLiteral(1))),
-          gl -> terminal(BVPlus (e, IntLiteral(1)))
-        )
-      }
-
-      def intVariations(gl: L, e : Expr): Seq[(L, Prod)] = {
-        Seq(
-          gl -> terminal(Minus(e, InfiniteIntegerLiteral(1))),
-          gl -> terminal(Plus (e, InfiniteIntegerLiteral(1)))
-        )
-      }
-
-      // Find neighbor case classes that are compatible with the arguments:
-      // Turns And(e1, e2) into Or(e1, e2)...
-      def ccVariations(gl: L, cc: CaseClass): Seq[(L, Prod)] = {
-        val CaseClass(cct, args) = cc
-
-        val neighbors = cct.root.knownCCDescendants diff Seq(cct)
-
-        for (scct <- neighbors if scct.fieldsTypes == cct.fieldsTypes) yield {
-          gl -> terminal(CaseClass(scct, args))
-        }
-      }
-
-      val funFilter = (fd: FunDef) => fd.isSynthetic || (excludeFCalls contains fd)
-      val subs: Seq[(L, Prod)] = e match {
-        
-        case _: Terminal | _: Let | _: LetDef | _: MatchExpr =>
-          gens(e, gl, Nil, { _ => e }) ++ cegis(gl)
-
-        case cc @ CaseClass(cct, exprs) =>
-          gens(e, gl, exprs, { case ss => CaseClass(cct, ss) }) ++ ccVariations(gl, cc)
-
-        case FunctionInvocation(TypedFunDef(fd, _), _) if funFilter(fd) =>
-          // We allow only exact call, and/or cegis extensions
-          /*Seq(el -> Generator[L, Expr](Nil, { _ => e })) ++*/ cegis(gl)
-
-        case Operator(subs, builder) =>
-          gens(e, gl, subs, { case ss => builder(ss) })
-      }
-
-      val terminalsMatching = terminals.collect {
-        case IsTyped(term, tpe) if tpe == gl.getType && term != e =>
-          gl -> terminal(term)
-      }
-
-      val variations = e.getType match {
-        case IntegerType => intVariations(gl, e)
-        case Int32Type => int32Variations(gl, e)
-        case _ => Nil
-      }
-
-      subs ++ terminalsMatching ++ variations
-    }
-
-    val gl = getLabel(e.getType)
-
-    val res = rec(e, gl)
-
-    //for ((t, g) <- res) {
-    //  val subs = g.subTrees.map { t => FreshIdentifier(t.asString, t.getType).toVariable}
-    //  val gen = g.builder(subs)
-
-    //  println(f"$t%30s ::= "+gen)
-    //}
-    res
-  }
+case class SimilarTo(e: Expr, sctx: SynthesisContext, p: Problem) extends ExpressionGrammar {
+
+  def computeProductions(l: Label)(implicit ctx: LeonContext) = Nil
+//  val excludeFCalls = sctx.settings.functionsToIgnore
+//
+//  val normalGrammar: ExpressionGrammar[NonTerminal[String]] = DepthBoundedGrammar(EmbeddedGrammar(
+//    Grammars.default(sctx, p, Seq(e)),
+//    (t: TypeTree) => NonTerminal(t, "B", None),
+//    (l: NonTerminal[String]) => l.getType
+//  ), 1)
+//
+//  type L = NonTerminal[String]
+//
+//  val getNext: () => Int = {
+//    var counter = -1
+//    () => {
+//      counter += 1
+//      counter
+//    }
+//  }
+//
+//  private[this] var similarCache: Option[Map[L, Seq[Prod]]] = None
+//
+//  def computeProductions(t: L)(implicit ctx: LeonContext): Seq[Prod] = {
+//    t match {
+//      case NonTerminal(_, "B", _) => normalGrammar.computeProductions(t)
+//      case _                =>
+//
+//        val allSimilar = similarCache.getOrElse {
+//          val res = computeSimilar(e).groupBy(_._1).mapValues(_.map(_._2))
+//          similarCache = Some(res)
+//          res
+//        }
+//
+//        allSimilar.getOrElse(t, Nil)
+//    }
+//  }
+//
+//  def computeSimilar(e : Expr)(implicit ctx: LeonContext): Seq[(L, Prod)] = {
+//
+//    def getLabel(t: TypeTree) = {
+//      val tpe = bestRealType(t)
+//      val c = getNext()
+//      NonTerminal(tpe, "G"+c)
+//    }
+//
+//    def isCommutative(e: Expr) = e match {
+//      case _: Plus | _: Times => true
+//      case _ => false
+//    }
+//
+//    def rec(e: Expr, gl: L): Seq[(L, Prod)] = {
+//
+//      def gens(e: Expr, gl: L, subs: Seq[Expr], builder: (Seq[Expr] => Expr)): Seq[(L, Prod)] = {
+//        val subGls = subs.map { s => getLabel(s.getType) }
+//
+//        // All the subproductions for sub gl
+//        val allSubs = (subs zip subGls).flatMap { case (e, gl) => rec(e, gl) }
+//
+//        // Inject fix at one place
+//        val injectG = for ((sgl, i) <- subGls.zipWithIndex) yield {
+//          gl -> nonTerminal(Seq(sgl), { case Seq(ge) => builder(subs.updated(i, ge)) } )
+//        }
+//
+//        val swaps = if (subs.size > 1 && !isCommutative(e)) {
+//          (for (i <- subs.indices;
+//                j <- i+1 until subs.size) yield {
+//
+//            if (subs(i).getType == subs(j).getType) {
+//              val swapSubs = subs.updated(i, subs(j)).updated(j, subs(i))
+//              Some(gl -> terminal(builder(swapSubs)))
+//            } else {
+//              None
+//            }
+//          }).flatten
+//        } else {
+//          Nil
+//        }
+//
+//        allSubs ++ injectG ++ swaps
+//      }
+//
+//      def cegis(gl: L): Seq[(L, Prod)] = {
+//        normalGrammar.getProductions(gl).map(gl -> _)
+//      }
+//
+//      def int32Variations(gl: L, e : Expr): Seq[(L, Prod)] = {
+//        Seq(
+//          gl -> terminal(BVMinus(e, IntLiteral(1))),
+//          gl -> terminal(BVPlus (e, IntLiteral(1)))
+//        )
+//      }
+//
+//      def intVariations(gl: L, e : Expr): Seq[(L, Prod)] = {
+//        Seq(
+//          gl -> terminal(Minus(e, InfiniteIntegerLiteral(1))),
+//          gl -> terminal(Plus (e, InfiniteIntegerLiteral(1)))
+//        )
+//      }
+//
+//      // Find neighbor case classes that are compatible with the arguments:
+//      // Turns And(e1, e2) into Or(e1, e2)...
+//      def ccVariations(gl: L, cc: CaseClass): Seq[(L, Prod)] = {
+//        val CaseClass(cct, args) = cc
+//
+//        val neighbors = cct.root.knownCCDescendants diff Seq(cct)
+//
+//        for (scct <- neighbors if scct.fieldsTypes == cct.fieldsTypes) yield {
+//          gl -> terminal(CaseClass(scct, args))
+//        }
+//      }
+//
+//      val funFilter = (fd: FunDef) => fd.isSynthetic || (excludeFCalls contains fd)
+//      val subs: Seq[(L, Prod)] = e match {
+//        
+//        case _: Terminal | _: Let | _: LetDef | _: MatchExpr =>
+//          gens(e, gl, Nil, { _ => e }) ++ cegis(gl)
+//
+//        case cc @ CaseClass(cct, exprs) =>
+//          gens(e, gl, exprs, { case ss => CaseClass(cct, ss) }) ++ ccVariations(gl, cc)
+//
+//        case FunctionInvocation(TypedFunDef(fd, _), _) if funFilter(fd) =>
+//          // We allow only exact call, and/or cegis extensions
+//          /*Seq(el -> Generator[L, Expr](Nil, { _ => e })) ++*/ cegis(gl)
+//
+//        case Operator(subs, builder) =>
+//          gens(e, gl, subs, { case ss => builder(ss) })
+//      }
+//
+//      val terminalsMatching = p.as.collect {
+//        case IsTyped(term, tpe) if tpe == gl.getType && Variable(term) != e =>
+//          gl -> terminal(Variable(term))
+//      }
+//
+//      val variations = e.getType match {
+//        case IntegerType => intVariations(gl, e)
+//        case Int32Type => int32Variations(gl, e)
+//        case _ => Nil
+//      }
+//
+//      subs ++ terminalsMatching ++ variations
+//    }
+//
+//    val gl = getLabel(e.getType)
+//
+//    val res = rec(e, gl)
+//
+//    //for ((t, g) <- res) {
+//    //  val subs = g.subTrees.map { t => FreshIdentifier(t.asString, t.getType).toVariable}
+//    //  val gen = g.builder(subs)
+//
+//    //  println(f"$t%30s ::= "+gen)
+//    //}
+//    res
+//  }
 }
diff --git a/src/main/scala/leon/grammars/SimpleExpressionGrammar.scala b/src/main/scala/leon/grammars/SimpleExpressionGrammar.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f128495219ec8798051273ade231b3b6c49f24ff
--- /dev/null
+++ b/src/main/scala/leon/grammars/SimpleExpressionGrammar.scala
@@ -0,0 +1,42 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+
+import purescala.Expressions._
+import purescala.Types._
+
+abstract class SimpleExpressionGrammar extends ExpressionGrammar {
+
+  type Prod = ProductionRule[TypeTree, Expr]
+
+  /** Generates a [[ProductionRule]] without nonterminal symbols */
+  def terminal(builder: => Expr, tag: Tags.Tag = Tags.Top, cost: Int = 1) = {
+    ProductionRule[TypeTree, Expr](Nil, { (subs: Seq[Expr]) => builder }, tag, cost)
+  }
+
+  /** Generates a [[ProductionRule]] with nonterminal symbols */
+  def nonTerminal(subs: Seq[TypeTree], builder: (Seq[Expr] => Expr), tag: Tags.Tag = Tags.Top, cost: Int = 1) = {
+    ProductionRule[TypeTree, Expr](subs, builder, tag, cost)
+  }
+
+  def filter(f: Prod => Boolean) = {
+    new SimpleExpressionGrammar {
+      def computeProductions(lab: TypeTree)(implicit ctx: LeonContext) = {
+        SimpleExpressionGrammar.this.computeProductions(lab).filter(f)
+      }
+    }
+  }
+
+  /** The list of production rules for this grammar for a given nonterminal
+    *
+    * @param lab The nonterminal for which production rules will be generated
+    */
+  def computeProductions(lab: Label)(implicit ctx: LeonContext): Seq[ProductionRule[Label, Expr]] = {
+    computeProductions(lab.getType).map { p =>
+      ProductionRule(p.subTrees.map(Label(_)), p.builder, p.tag, p.cost)
+    }
+  }
+
+  def computeProductions(tpe: TypeTree)(implicit ctx: LeonContext): Seq[ProductionRule[TypeTree, Expr]]
+}
diff --git a/src/main/scala/leon/grammars/Tags.scala b/src/main/scala/leon/grammars/Tags.scala
index 4a6b6fca491b8db6f74622edd9298ec5cd6053b0..3686fd462e9560b457fa535a8fe88afb0a5816b4 100644
--- a/src/main/scala/leon/grammars/Tags.scala
+++ b/src/main/scala/leon/grammars/Tags.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
diff --git a/src/main/scala/leon/grammars/Union.scala b/src/main/scala/leon/grammars/Union.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8d5d5a42f2f8b5313e9c6aafb64d31f18bf47be5
--- /dev/null
+++ b/src/main/scala/leon/grammars/Union.scala
@@ -0,0 +1,17 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+
+import purescala.Expressions.Expr
+import purescala.Types.Typed
+
+case class Union(gs: Seq[ExpressionGrammar]) extends ExpressionGrammar {
+  val subGrammars: Seq[ExpressionGrammar] = gs.flatMap {
+    case u: Union => u.subGrammars
+    case g => Seq(g)
+  }
+
+  def computeProductions(label: Label)(implicit ctx: LeonContext): Seq[ProductionRule[Label, Expr]] =
+    subGrammars.flatMap(_.computeProductions(label))
+}
diff --git a/src/main/scala/leon/grammars/ValueGrammar.scala b/src/main/scala/leon/grammars/ValueGrammar.scala
index d3c42201728f4b03d9518b3db503cff9189dcc8b..996debb8525d94080f4368722ee9b92ff4bd3e40 100644
--- a/src/main/scala/leon/grammars/ValueGrammar.scala
+++ b/src/main/scala/leon/grammars/ValueGrammar.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package grammars
@@ -7,7 +7,7 @@ import purescala.Types._
 import purescala.Expressions._
 
 /** A grammar of values (ground terms) */
-case object ValueGrammar extends ExpressionGrammar[TypeTree] {
+case object ValueGrammar extends SimpleExpressionGrammar {
   def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = t match {
     case BooleanType =>
       List(
diff --git a/src/main/scala/leon/grammars/aspects/ExtraTerminals.scala b/src/main/scala/leon/grammars/aspects/ExtraTerminals.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f2d0f46d0ec0dcaf7a2627e0ab0f89a0eb281b35
--- /dev/null
+++ b/src/main/scala/leon/grammars/aspects/ExtraTerminals.scala
@@ -0,0 +1,28 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+package aspects
+
+import purescala.Expressions.Expr
+import purescala.ExprOps.formulaSize
+import purescala.TypeOps.isSubtypeOf
+
+/**
+ * Informs sub-productions that there are extra terminals available (used by
+ * grammars.ExtraTerminals).
+ */
+case class ExtraTerminals(s: Set[Expr]) extends PersistantAspect {
+  def asString(implicit ctx: LeonContext) = {
+    s.toList.map(_.asString).mkString("{", ",", "}")
+  }
+
+
+  override def applyTo(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
+    super.applyTo(lab, ps) ++ {
+      s.filter(e => isSubtypeOf(e.getType, lab.getType)).map { e =>
+        ProductionRule[Label, Expr](Nil, { (es: Seq[Expr]) => e }, Tags.Top, formulaSize(e))
+      }
+    }
+  }
+}
diff --git a/src/main/scala/leon/grammars/aspects/PersistantAspect.scala b/src/main/scala/leon/grammars/aspects/PersistantAspect.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4d8670bd457779e157719feaa1a8607fe8f83cfa
--- /dev/null
+++ b/src/main/scala/leon/grammars/aspects/PersistantAspect.scala
@@ -0,0 +1,28 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+package aspects
+
+import purescala.Expressions.Expr
+
+/**
+ * Persistant aspects allow label information to be propagated down:
+ * Int{e} means (Int with a terminal 'e'). And thus, the Closure grammar
+ * is able to have, as production:
+ *   Int=>Int  :=  (e: Int) => Int{e}
+ * In turn, all Int productions, e.g. Int := Int + Int, gets transformed by the
+ * aspect and generate:
+ *   Int{e}  :=  Int{e} + Int{e}
+ *
+ * This with the ExtraTerminals grammar, enables the generation of expressions
+ * like:
+ *   e + 1
+ */
+abstract class PersistantAspect extends Aspect {
+  def applyTo(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
+    ps.map { p =>
+      p.copy(subTrees = p.subTrees.map(lab => lab.withAspect(this)))
+    }
+  }
+}
diff --git a/src/main/scala/leon/grammars/aspects/SimilarTo.scala b/src/main/scala/leon/grammars/aspects/SimilarTo.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4685f9a3ce25a88366e4aedb2675aa73562822d6
--- /dev/null
+++ b/src/main/scala/leon/grammars/aspects/SimilarTo.scala
@@ -0,0 +1,136 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+package aspects
+
+import purescala.Expressions._
+import purescala.Types._
+import purescala.TypeOps._
+import purescala.Constructors._
+import purescala.Extractors._
+import utils.SeqUtils._
+
+/**
+ * Attach sizes to labels and transmit them down accordingly
+ */
+case class SimilarTo(e: Expr) extends Aspect {
+  type Prods = Seq[ProductionRule[Label, Expr]]
+
+  def asString(implicit ctx: LeonContext) = "~"+e.asString+"~"
+
+  def term(e: Expr, tag: Tags.Tag = Tags.Top, cost: Int = 1): ProductionRule[Label, Expr] = {
+    ProductionRule(Nil, { case Seq() => e }, tag, cost)
+  }
+
+  /**
+   * ~f(a,b)~  ::=  f(~a~, b)
+   *                f(a, ~b~)
+   *                f(b, a)   // if non-commut
+   */
+  def applyTo(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
+    def isCommutative(e: Expr) = e match {
+      case _: Plus | _: Times => true
+      case _ => false
+    }
+
+    val similarProds: Prods = if (isSubtypeOf(e.getType, lab.getType)) {
+      val swaps: Prods = e match {
+        case Operator(as, b) if as.nonEmpty && !isCommutative(e) =>
+          val ast = as.zipWithIndex.groupBy(_._1.getType).mapValues(_.map(_._2).toList)
+
+          val perms = ast.values.map { is =>
+            is.permutations.toList.filter(p => p != is).map(ps => (is zip ps).toMap)
+          }.filter(_.nonEmpty).toList
+
+          //println("Perms:")
+          //for (ps <- perms) {
+          //  println(" - "+ps.mkString(", "))
+          //}
+
+          for (ps <- cartesianProduct(perms)) yield {
+            val perm = ps.foldLeft(Map[Int, Int]())( _ ++ _ )
+
+            //println("Trying permutation "+perm+": "+
+            //    b(as.indices.map { i =>
+            //      as(perm.getOrElse(i, i))
+            //    }))
+
+            term(b(as.indices.map { i => as(perm.getOrElse(i, i)) }))
+          }
+        case _ =>
+          Nil
+      }
+
+      val subs: Prods = e match {
+        case Operator(as, b) if as.size > 0 =>
+          for ((a, i) <- as.zipWithIndex) yield {
+            ProductionRule[Label, Expr](
+              List(Label(a.getType).withAspect(SimilarTo(a))),
+              { case Seq(e) =>
+                b(as.updated(i, e))
+              },
+              Tags.Top,
+              1
+            )
+          }
+        case _ =>
+          Nil
+      }
+
+      val typeVariations: Prods = e match {
+        case InfiniteIntegerLiteral(v) =>
+          List(
+            term(InfiniteIntegerLiteral(v + 1)),
+            term(InfiniteIntegerLiteral(v - 1))
+          )
+
+        case IntLiteral(v) =>
+          List(
+            term(IntLiteral(v + 1)),
+            term(IntLiteral(v - 1))
+          )
+
+        case BooleanLiteral(v) =>
+          List(
+            term(BooleanLiteral(!v))
+          )
+
+        case IsTyped(e, IntegerType) =>
+          List(
+            term(Plus(e, InfiniteIntegerLiteral(1))),
+            term(Minus(e, InfiniteIntegerLiteral(1)))
+          )
+        case IsTyped(e, Int32Type) =>
+          List(
+            term(BVPlus(e, IntLiteral(1))),
+            term(BVMinus(e, IntLiteral(1)))
+          )
+        case IsTyped(e, BooleanType) =>
+          List(
+            term(not(e))
+          )
+
+        case _ =>
+          Nil
+      }
+
+      val ccVariations: Prods = e match {
+        case CaseClass(cct, args) =>
+          val neighbors = cct.root.knownCCDescendants diff Seq(cct)
+
+          for (scct <- neighbors if scct.fieldsTypes == cct.fieldsTypes) yield {
+            term(CaseClass(scct, args))
+          }
+        case _ =>
+          Nil
+      }
+
+      swaps ++ subs ++ typeVariations ++ ccVariations
+    } else {
+      Nil
+    }
+
+    ps ++ similarProds
+  }
+}
diff --git a/src/main/scala/leon/grammars/aspects/Sized.scala b/src/main/scala/leon/grammars/aspects/Sized.scala
new file mode 100644
index 0000000000000000000000000000000000000000..66485257847b6dbe12b1a7ab227d5207f618fa81
--- /dev/null
+++ b/src/main/scala/leon/grammars/aspects/Sized.scala
@@ -0,0 +1,45 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+package aspects
+
+import purescala.Expressions.Expr
+import utils.SeqUtils._
+
+/**
+ * Attach sizes to labels and transmit them down accordingly
+ */
+case class Sized(size: Int) extends Aspect {
+  def asString(implicit ctx: LeonContext) = "|"+size+"|"
+
+  def applyTo(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
+    val optimizeCommut = true
+
+    ps.flatMap { p =>
+      if (size <= 0) {
+        Nil
+      } else if (p.arity == 0) {
+        if (size == p.cost) {
+          List(p)
+        } else {
+          Nil
+        }
+      } else {
+        val sizes = if(optimizeCommut && Tags.isCommut(p.tag) && p.subTrees.toSet.size == 1) {
+          sumToOrdered(size - p.cost, p.arity)
+        } else {
+          sumTo(size - p.cost, p.arity)
+        }
+
+        for (ss <- sizes) yield {
+          val newSubTrees = (p.subTrees zip ss).map {
+            case (lab, s) => lab.withAspect(Sized(s))
+          }
+
+          ProductionRule(newSubTrees, p.builder, p.tag, p.cost)
+        }
+      }
+    }
+  }
+}
diff --git a/src/main/scala/leon/grammars/aspects/Tagged.scala b/src/main/scala/leon/grammars/aspects/Tagged.scala
new file mode 100644
index 0000000000000000000000000000000000000000..be097ac12cff6b4cec9e157f4b1d63003c931241
--- /dev/null
+++ b/src/main/scala/leon/grammars/aspects/Tagged.scala
@@ -0,0 +1,93 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon
+package grammars
+package aspects
+
+import purescala.Expressions.Expr
+import utils.SeqUtils._
+import Tags._
+
+case class Tagged(tag: Tag, pos: Int, isConst: Option[Boolean]) extends Aspect {
+  private val cString = isConst match {
+    case Some(true) => "↓"
+    case Some(false) => "↑"
+    case None => "â—‹"
+  }
+
+  /** [[isConst]] is printed as follows: ↓ for constants only, ↑ for nonconstants only,
+    * â—‹ for anything allowed.
+    */
+  override def asString(implicit ctx: LeonContext): String = s"$tag@$pos$cString"
+
+
+  override def applyTo(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
+
+    // Tags to avoid depending on parent aspect
+    val excludedTags: Set[Tag] = (tag, pos) match {
+      case (Top,   _)             => Set()
+      case (And,   0)             => Set(And, BooleanC)
+      case (And,   1)             => Set(BooleanC)
+      case (Or,    0)             => Set(Or, BooleanC)
+      case (Or,    1)             => Set(BooleanC)
+      case (Plus,  0)             => Set(Plus, Zero, One)
+      case (Plus,  1)             => Set(Zero)
+      case (Minus, 1)             => Set(Zero)
+      case (Not,   _)             => Set(Not, BooleanC)
+      case (Times, 0)             => Set(Times, Zero, One)
+      case (Times, 1)             => Set(Zero, One)
+      case (Equals,_)             => Set(Not, BooleanC)
+      case (Div | Mod, 0 | 1)     => Set(Zero, One)
+      case (FunCall(true, _), 0)  => Set(Constructor(true)) // Don't allow Nil().size etc.
+      case _                      => Set()
+    }
+
+    def powerSet[A](t: Set[A]): Set[Set[A]] = {
+      @scala.annotation.tailrec
+      def pwr(t: Set[A], ps: Set[Set[A]]): Set[Set[A]] =
+        if (t.isEmpty) ps
+        else pwr(t.tail, ps ++ (ps map (_ + t.head)))
+
+      pwr(t, Set(Set.empty[A]))
+    }
+
+
+    ps.flatMap { p =>
+      val tagsValid = !(excludedTags contains p.tag)
+
+      // If const-ness is explicit, make sure the production has similar const-ness
+      val constValid = isConst match {
+        case Some(b) => Tags.isConst(p.tag) == b
+        case None    => true
+      }
+
+      if (constValid && tagsValid) {
+        val subAspects = if (p.isTerminal || Tags.allConstArgsAllowed(p.tag)) {
+          Seq(p.subTrees.indices.map { i =>
+            Tagged(p.tag, i, None)
+          })
+        } else {
+          // All positions are either forced to be const or forced to be
+          // non-const. We don't want all consts though.
+          val indices = p.subTrees.indices.toSet
+
+          (powerSet(indices) - indices) map { isConst =>
+            p.subTrees.indices.map { i =>
+              Tagged(p.tag, i, Some(isConst(i)))
+            }
+          }
+        }
+
+        for (as <- subAspects) yield {
+          val newSubTrees = (p.subTrees zip as).map { case (lab, a) =>
+            lab.withAspect(a)
+          }
+
+          ProductionRule(newSubTrees, p.builder, p.tag, p.cost)
+        }
+      } else {
+        Nil
+      }
+    }
+  }
+}
diff --git a/src/main/scala/leon/grammars/transformers/DepthBoundedGrammar.scala b/src/main/scala/leon/grammars/transformers/DepthBoundedGrammar.scala
deleted file mode 100644
index 02e045497a28db205d4a33a300ac0b742510920a..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/grammars/transformers/DepthBoundedGrammar.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package grammars
-package transformers
-
-/** Limits a grammar to a specific expression depth */
-case class DepthBoundedGrammar[L](g: ExpressionGrammar[NonTerminal[L]], bound: Int) extends ExpressionGrammar[NonTerminal[L]] {
-  def computeProductions(l: NonTerminal[L])(implicit ctx: LeonContext): Seq[Prod] = g.computeProductions(l).flatMap {
-    case gen =>
-      if (l.depth == Some(bound) && gen.isNonTerminal) {
-        Nil
-      } else if (l.depth.exists(_ > bound)) {
-        Nil
-      } else {
-        List (
-          nonTerminal(gen.subTrees.map(sl => sl.copy(depth = l.depth.map(_+1).orElse(Some(1)))), gen.builder)
-        )
-      }
-  }
-}
diff --git a/src/main/scala/leon/grammars/transformers/EmbeddedGrammar.scala b/src/main/scala/leon/grammars/transformers/EmbeddedGrammar.scala
deleted file mode 100644
index d989a8804b32f62697b7f31e498e61393a12c35b..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/grammars/transformers/EmbeddedGrammar.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package grammars
-package transformers
-
-import leon.purescala.Types.Typed
-
-/**
- * Embed a grammar Li->Expr within a grammar Lo->Expr
- * 
- * We rely on a bijection between Li and Lo labels
- */
-case class EmbeddedGrammar[Ti <: Typed, To <: Typed](innerGrammar: ExpressionGrammar[Ti], iToo: Ti => To, oToi: To => Ti) extends ExpressionGrammar[To] {
-  def computeProductions(t: To)(implicit ctx: LeonContext): Seq[Prod] = {
-    innerGrammar.computeProductions(oToi(t)).map { innerGen =>
-      nonTerminal(innerGen.subTrees.map(iToo), innerGen.builder, innerGen.tag)
-    }
-  }
-}
diff --git a/src/main/scala/leon/grammars/transformers/OneOf.scala b/src/main/scala/leon/grammars/transformers/OneOf.scala
deleted file mode 100644
index 5c57c6a1a48179e2d813398aa651022df6cae35a..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/grammars/transformers/OneOf.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package grammars
-package transformers
-
-import purescala.Expressions.Expr
-import purescala.Types.TypeTree
-import purescala.TypeOps.isSubtypeOf
-
-/** Generates one production rule for each expression in a sequence that has compatible type */
-case class OneOf(inputs: Seq[Expr]) extends ExpressionGrammar[TypeTree] {
-  def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = {
-    inputs.collect {
-      case i if isSubtypeOf(i.getType, t) =>
-        terminal(i)
-    }
-  }
-}
diff --git a/src/main/scala/leon/grammars/transformers/SizeBoundedGrammar.scala b/src/main/scala/leon/grammars/transformers/SizeBoundedGrammar.scala
deleted file mode 100644
index 1b605359fdf18d02f08d105a9cccc58757b99262..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/grammars/transformers/SizeBoundedGrammar.scala
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package grammars
-package transformers
-
-import purescala.Types.Typed
-import utils.SeqUtils._
-
-/** Adds information about size to a nonterminal symbol */
-case class SizedNonTerm[T <: Typed](underlying: T, size: Int) extends Typed {
-  val getType = underlying.getType
-
-  override def asString(implicit ctx: LeonContext) = underlying.asString+"|"+size+"|"
-}
-
-/** Limits a grammar by producing expressions of size bounded by the [[SizedNonTerm.size]] of a given [[SizedNonTerm]].
-  *
-  * In case of commutative operations, the grammar will produce trees skewed to the right
-  * (i.e. the right subtree will always be larger). Notice we do not lose generality in case of
-  * commutative operations.
-  */
-case class SizeBoundedGrammar[T <: Typed](g: ExpressionGrammar[T], optimizeCommut: Boolean) extends ExpressionGrammar[SizedNonTerm[T]] {
-  def computeProductions(sl: SizedNonTerm[T])(implicit ctx: LeonContext): Seq[Prod] = {
-    if (sl.size <= 0) {
-      Nil
-    } else if (sl.size == 1) {
-      g.getProductions(sl.underlying).filter(_.isTerminal).map { gen =>
-        terminal(gen.builder(Seq()), gen.tag)
-      }
-    } else {
-      g.getProductions(sl.underlying).filter(_.isNonTerminal).flatMap { gen =>
-
-        // Ad-hoc equality that does not take into account position etc.of TaggedNonTerminal's
-        // TODO: Ugly and hacky
-        def characteristic(t: T): Typed = t match {
-          case TaggedNonTerm(underlying, _, _, _) =>
-            underlying
-          case other =>
-            other
-        }
-
-        // Optimization: When we have a commutative operation and all the labels are the same,
-        // we can skew the expression to always be right-heavy
-        val sizes = if(optimizeCommut && Tags.isCommut(gen.tag) && gen.subTrees.map(characteristic).toSet.size == 1) {
-          sumToOrdered(sl.size-gen.cost, gen.arity)
-        } else {
-          sumTo(sl.size-gen.cost, gen.arity)
-        }
-
-        for (ss <- sizes) yield {
-          val subSizedLabels = (gen.subTrees zip ss) map (s => SizedNonTerm(s._1, s._2))
-
-          nonTerminal(subSizedLabels, gen.builder, gen.tag)
-        }
-      }
-    }
-  }
-}
diff --git a/src/main/scala/leon/grammars/transformers/TaggedGrammar.scala b/src/main/scala/leon/grammars/transformers/TaggedGrammar.scala
deleted file mode 100644
index 43ce13e850ed1b52460ef1a74d7b039adacbd519..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/grammars/transformers/TaggedGrammar.scala
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package grammars
-package transformers
-
-import leon.purescala.Types.Typed
-import Tags._
-
-/** Adds to a nonterminal information about about the tag of its parent's [[leon.grammars.ProductionRule.tag]]
-  * and additional information.
-  * 
-  * @param underlying The underlying nonterminal
-  * @param tag The tag of the parent of this nonterminal
-  * @param pos The index of this nonterminal in its father's production rule
-  * @param isConst Whether this nonterminal is obliged to generate/not generate constants.
-  *
-  */
-case class TaggedNonTerm[T <: Typed](underlying: T, tag: Tag, pos: Int, isConst: Option[Boolean]) extends Typed {
-  val getType = underlying.getType
-
-  private val cString = isConst match {
-    case Some(true) => "↓"
-    case Some(false) => "↑"
-    case None => "â—‹"
-  }
-
-  /** [[isConst]] is printed as follows: ↓ for constants only, ↑ for nonconstants only,
-    * â—‹ for anything allowed.
-    */
-  override def asString(implicit ctx: LeonContext): String = s"$underlying%$tag@$pos$cString"
-}
-
-/** Constraints a grammar to reduce redundancy by utilizing information provided by the [[TaggedNonTerm]].
-  *
-  * 1) In case of associative operations, right associativity is enforced.
-  * 2) Does not generate
-  *    - neutral and absorbing elements (incl. boolean equality)
-  *    - nested negations
-  * 3) Excludes method calls on nullary case objects, e.g. Nil().size
-  * 4) Enforces that no constant trees are generated (and recursively for each subtree)
-  *
-  * @param g The underlying untagged grammar
-  */
-case class TaggedGrammar[T <: Typed](g: ExpressionGrammar[T]) extends ExpressionGrammar[TaggedNonTerm[T]] {
-
-  private def exclude(tag: Tag, pos: Int): Set[Tag] = (tag, pos) match {
-    case (Top,   _) => Set()
-    case (And,   0) => Set(And, BooleanC)
-    case (And,   1) => Set(BooleanC)
-    case (Or,    0) => Set(Or, BooleanC)
-    case (Or,    1) => Set(BooleanC)
-    case (Plus,  0) => Set(Plus, Zero, One)
-    case (Plus,  1) => Set(Zero)
-    case (Minus, 1) => Set(Zero)
-    case (Not,   _) => Set(Not, BooleanC)
-    case (Times, 0) => Set(Times, Zero, One)
-    case (Times, 1) => Set(Zero, One)
-    case (Equals,_) => Set(Not, BooleanC)
-    case (Div | Mod, 0 | 1) => Set(Zero, One)
-    case (FunCall(true, _), 0) => Set(Constructor(true)) // Don't allow Nil().size etc.
-    case _ => Set()
-  }
-
-  def computeProductions(t: TaggedNonTerm[T])(implicit ctx: LeonContext): Seq[Prod] = {
-
-    // Point (4) for this level
-    val constFilter: g.Prod => Boolean = t.isConst match {
-      case Some(b) =>
-        innerGen => isConst(innerGen.tag) == b
-      case None =>
-        _ => true
-    }
-
-    g.computeProductions(t.underlying)
-      // Include only constants iff constants are forced, only non-constants iff they are forced
-      .filter(constFilter)
-      // Points (1), (2). (3)
-      .filterNot { innerGen => exclude(t.tag, t.pos)(innerGen.tag) }
-      .flatMap   { innerGen =>
-
-        def nt(isConst: Int => Option[Boolean]) = nonTerminal(
-          innerGen.subTrees.zipWithIndex.map {
-            case (t, pos) => TaggedNonTerm(t, innerGen.tag, pos, isConst(pos))
-          },
-          innerGen.builder,
-          innerGen.tag
-        )
-
-        def powerSet[A](t: Set[A]): Set[Set[A]] = {
-          @scala.annotation.tailrec
-          def pwr(t: Set[A], ps: Set[Set[A]]): Set[Set[A]] =
-            if (t.isEmpty) ps
-            else pwr(t.tail, ps ++ (ps map (_ + t.head)))
-
-          pwr(t, Set(Set.empty[A]))
-        }
-
-        // Allow constants everywhere if this is allowed, otherwise demand at least 1 variable.
-        // Aka. tag subTrees correctly so point (4) is enforced in the lower level
-        // (also, make sure we treat terminals correctly).
-        if (innerGen.isTerminal || allConstArgsAllowed(innerGen.tag)) {
-          Seq(nt(_ => None))
-        } else {
-          val indices = innerGen.subTrees.indices.toSet
-          (powerSet(indices) - indices) map (indices => nt(x => Some(indices(x))))
-        }
-      }
-  }
-
-}
diff --git a/src/main/scala/leon/grammars/transformers/Union.scala b/src/main/scala/leon/grammars/transformers/Union.scala
deleted file mode 100644
index 471625ac3c22c22456f49f366ed26e5195b5f4ab..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/grammars/transformers/Union.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package grammars
-package transformers
-
-import purescala.Types.Typed
-
-case class Union[T <: Typed](gs: Seq[ExpressionGrammar[T]]) extends ExpressionGrammar[T] {
-  val subGrammars: Seq[ExpressionGrammar[T]] = gs.flatMap {
-    case u: Union[T] => u.subGrammars
-    case g => Seq(g)
-  }
-
-  def computeProductions(t: T)(implicit ctx: LeonContext): Seq[Prod] =
-    subGrammars.flatMap(_.getProductions(t))
-}
diff --git a/src/main/scala/leon/invariant/datastructure/DisjointSets.scala b/src/main/scala/leon/invariant/datastructure/DisjointSets.scala
index 003bb31d1233ce7ab3ad1fe0dbe775008ae7f806..d9bb73e39c70072a1719549470db10f0fe41875f 100644
--- a/src/main/scala/leon/invariant/datastructure/DisjointSets.scala
+++ b/src/main/scala/leon/invariant/datastructure/DisjointSets.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.datastructure
 
diff --git a/src/main/scala/leon/invariant/datastructure/Graph.scala b/src/main/scala/leon/invariant/datastructure/Graph.scala
index e8c8a729688e9ea6c79898113404229d0e4ff15f..8af783f52d8cf033fc471a7c4ed522195547d514 100644
--- a/src/main/scala/leon/invariant/datastructure/Graph.scala
+++ b/src/main/scala/leon/invariant/datastructure/Graph.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.datastructure
 
diff --git a/src/main/scala/leon/invariant/datastructure/Maps.scala b/src/main/scala/leon/invariant/datastructure/Maps.scala
index ca2dcb98e99f247651dfd1b8632c570630fce7f0..7bd237a74c95a5da247442c13fa463a1a6889042 100644
--- a/src/main/scala/leon/invariant/datastructure/Maps.scala
+++ b/src/main/scala/leon/invariant/datastructure/Maps.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.datastructure
 
diff --git a/src/main/scala/leon/invariant/engine/CompositionalTimeBoundSolver.scala b/src/main/scala/leon/invariant/engine/CompositionalTimeBoundSolver.scala
index 7713195169d4732fba1e2961b548a908516d16ec..576d28dbd7fbcf4d2919152a83f22433dff519ab 100644
--- a/src/main/scala/leon/invariant/engine/CompositionalTimeBoundSolver.scala
+++ b/src/main/scala/leon/invariant/engine/CompositionalTimeBoundSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
diff --git a/src/main/scala/leon/invariant/engine/ConstraintTracker.scala b/src/main/scala/leon/invariant/engine/ConstraintTracker.scala
index 6c7d1e2ec7d6c170cb66505357b515f73de521ab..488ce7e3a6d952005c4ae0dcf28a3f1913eb0973 100644
--- a/src/main/scala/leon/invariant/engine/ConstraintTracker.scala
+++ b/src/main/scala/leon/invariant/engine/ConstraintTracker.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
diff --git a/src/main/scala/leon/invariant/engine/InferInvariantsPhase.scala b/src/main/scala/leon/invariant/engine/InferInvariantsPhase.scala
index 78fc476dd8ab9f3b8bc70010a40e021e2424f367..e6c62ee93f28eb483c251ab775260cb354d6c8c6 100644
--- a/src/main/scala/leon/invariant/engine/InferInvariantsPhase.scala
+++ b/src/main/scala/leon/invariant/engine/InferInvariantsPhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
diff --git a/src/main/scala/leon/invariant/engine/InferenceContext.scala b/src/main/scala/leon/invariant/engine/InferenceContext.scala
index c8020acb5f9ff6e3582a258fe0c8806745a533a5..750c156e00fa795b6d60a4959be94a33f471b7c3 100644
--- a/src/main/scala/leon/invariant/engine/InferenceContext.scala
+++ b/src/main/scala/leon/invariant/engine/InferenceContext.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
@@ -33,13 +35,13 @@ class InferenceContext(val initProgram: Program, val leonContext: LeonContext) {
   val withmult = leonContext.findOption(optWithMult).getOrElse(false)
   val usereals = leonContext.findOption(optUseReals).getOrElse(false)
   val useCegis: Boolean = leonContext.findOption(optCegis).getOrElse(false)
-  val dumpStats = leonContext.findOption(SharedOptions.optBenchmark).getOrElse(false)
+  val dumpStats = leonContext.findOption(GlobalOptions.optBenchmark).getOrElse(false)
 
   // the following options have default values
   val vcTimeout = leonContext.findOption(optVCTimeout).getOrElse(15L) // in secs
   val nlTimeout = leonContext.findOption(optNLTimeout).getOrElse(15L)
-  val totalTimeout = leonContext.findOption(SharedOptions.optTimeout) // in secs
-  val functionsToInfer = leonContext.findOption(SharedOptions.optFunctions)
+  val totalTimeout = leonContext.findOption(GlobalOptions.optTimeout) // in secs
+  val functionsToInfer = leonContext.findOption(GlobalOptions.optFunctions)
   val reporter = leonContext.reporter
   val maxCegisBound = 1000
   val statsSuffix = leonContext.findOption(optStatsSuffix).getOrElse("-stats" + FileCountGUID.getID)
diff --git a/src/main/scala/leon/invariant/engine/InferenceEngine.scala b/src/main/scala/leon/invariant/engine/InferenceEngine.scala
index 17c246b47c9cbca0dc70f2c8832ae9d8172d6180..db4eadea6005b3fe38cece24483112d9b63cb5fd 100644
--- a/src/main/scala/leon/invariant/engine/InferenceEngine.scala
+++ b/src/main/scala/leon/invariant/engine/InferenceEngine.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
diff --git a/src/main/scala/leon/invariant/engine/InferenceReport.scala b/src/main/scala/leon/invariant/engine/InferenceReport.scala
index 4b0fb349f591780da0856e4ccbbe7e49f30c8d83..b782aa5e0b82915b248af0114bc8714d8b2bd7eb 100644
--- a/src/main/scala/leon/invariant/engine/InferenceReport.scala
+++ b/src/main/scala/leon/invariant/engine/InferenceReport.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package invariant.engine
diff --git a/src/main/scala/leon/invariant/engine/RefinementEngine.scala b/src/main/scala/leon/invariant/engine/RefinementEngine.scala
index 9502cefad49fb3a44242194e880caeaca74b6dab..3d849ac4684aee0efca93f75b43b17b8d64ff0d7 100644
--- a/src/main/scala/leon/invariant/engine/RefinementEngine.scala
+++ b/src/main/scala/leon/invariant/engine/RefinementEngine.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
diff --git a/src/main/scala/leon/invariant/engine/SpecInstantiator.scala b/src/main/scala/leon/invariant/engine/SpecInstantiator.scala
index 1398270d0a39ffad5d0e7cfa0a8017b679b5dff6..dfd5292f4c8d7be528d72e652dd929e9b0a221d5 100644
--- a/src/main/scala/leon/invariant/engine/SpecInstantiator.scala
+++ b/src/main/scala/leon/invariant/engine/SpecInstantiator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 import z3.scala._
diff --git a/src/main/scala/leon/invariant/engine/TemplateEnumerator.scala b/src/main/scala/leon/invariant/engine/TemplateEnumerator.scala
index 1e717dbc1a23723680ecdffeb27b3f78553d1747..e830d91b2e7f2bff1268b6e00f03f121539b7b59 100644
--- a/src/main/scala/leon/invariant/engine/TemplateEnumerator.scala
+++ b/src/main/scala/leon/invariant/engine/TemplateEnumerator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
diff --git a/src/main/scala/leon/invariant/engine/UnfoldingTemplateSolver.scala b/src/main/scala/leon/invariant/engine/UnfoldingTemplateSolver.scala
index 15063dd35ae1812c42ef9d1831a10406c4ae84ae..7634da75ad61fca3613566861457c3d77ed6784b 100644
--- a/src/main/scala/leon/invariant/engine/UnfoldingTemplateSolver.scala
+++ b/src/main/scala/leon/invariant/engine/UnfoldingTemplateSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.engine
 
diff --git a/src/main/scala/leon/invariant/factories/AxiomFactory.scala b/src/main/scala/leon/invariant/factories/AxiomFactory.scala
index ebc33562c87f6db9c7b9db7514524956eb2eb3a3..126e3d1db01c122a2a9b115b19dd218dd67f5ec2 100644
--- a/src/main/scala/leon/invariant/factories/AxiomFactory.scala
+++ b/src/main/scala/leon/invariant/factories/AxiomFactory.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.factories
 
diff --git a/src/main/scala/leon/invariant/factories/TemplateFactory.scala b/src/main/scala/leon/invariant/factories/TemplateFactory.scala
index 110ac75cb47dd73d2f8b871faaa18105b5d1a825..06798e870d2fed8e3e0b5ed77ca6a0e773092b39 100644
--- a/src/main/scala/leon/invariant/factories/TemplateFactory.scala
+++ b/src/main/scala/leon/invariant/factories/TemplateFactory.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.factories
 
diff --git a/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala b/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala
index dc7caf9b3406e6e4d47e7908bc6400d1c24b4c3a..ea810b82843b9eeb25464ac70dc6c75f78000d3c 100644
--- a/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala
+++ b/src/main/scala/leon/invariant/factories/TemplateInstantiator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.factories
 
diff --git a/src/main/scala/leon/invariant/factories/TemplateSolverFactory.scala b/src/main/scala/leon/invariant/factories/TemplateSolverFactory.scala
index 96c8d212a59cfc39c8cc428dc521f8e4a278a004..888c579bf047c017dfa2c68baa5e7dc5441955d7 100644
--- a/src/main/scala/leon/invariant/factories/TemplateSolverFactory.scala
+++ b/src/main/scala/leon/invariant/factories/TemplateSolverFactory.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.factories
 
diff --git a/src/main/scala/leon/invariant/structure/Constraint.scala b/src/main/scala/leon/invariant/structure/Constraint.scala
index 513bfd9687e0881491307ab53807b344fd7994c8..e55481b359de198b1f41fdc76b8bd1ea8ad1d13e 100644
--- a/src/main/scala/leon/invariant/structure/Constraint.scala
+++ b/src/main/scala/leon/invariant/structure/Constraint.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.structure
 
diff --git a/src/main/scala/leon/invariant/structure/Formula.scala b/src/main/scala/leon/invariant/structure/Formula.scala
index 588cf86ea7b87c4e8840bf288e78a2baa87d3c33..da56f3a8ed987505520c3246fd527c9b371dc36b 100644
--- a/src/main/scala/leon/invariant/structure/Formula.scala
+++ b/src/main/scala/leon/invariant/structure/Formula.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.structure
 
diff --git a/src/main/scala/leon/invariant/structure/FunctionUtils.scala b/src/main/scala/leon/invariant/structure/FunctionUtils.scala
index ccee2b16f2be7040b36c77b88703fa19239b2463..3d56016892223b5c30ce293857716c4decc53c70 100644
--- a/src/main/scala/leon/invariant/structure/FunctionUtils.scala
+++ b/src/main/scala/leon/invariant/structure/FunctionUtils.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.structure
 
diff --git a/src/main/scala/leon/invariant/structure/LinearConstraintUtil.scala b/src/main/scala/leon/invariant/structure/LinearConstraintUtil.scala
index 0f2c84350f95c9f5f3383a6bf55af3f5cfdf9500..5c48b2aeb7b6fb044aeca6111bef3d96f9c42c10 100644
--- a/src/main/scala/leon/invariant/structure/LinearConstraintUtil.scala
+++ b/src/main/scala/leon/invariant/structure/LinearConstraintUtil.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.structure
 
diff --git a/src/main/scala/leon/invariant/templateSolvers/CegisSolver.scala b/src/main/scala/leon/invariant/templateSolvers/CegisSolver.scala
index 0465199421bf61a5721fad33e2a94795f6ef8406..da717fe778a33335ad77845ebbad7af97d649f65 100644
--- a/src/main/scala/leon/invariant/templateSolvers/CegisSolver.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/CegisSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.templateSolvers
 
diff --git a/src/main/scala/leon/invariant/templateSolvers/ExtendedUFSolver.scala b/src/main/scala/leon/invariant/templateSolvers/ExtendedUFSolver.scala
index 9a9c1b0b4290b07408adb33c0e174813de831a29..f81d340c73b37346e2b69d3d2574787dbe858d76 100644
--- a/src/main/scala/leon/invariant/templateSolvers/ExtendedUFSolver.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/ExtendedUFSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package invariant.templateSolvers
diff --git a/src/main/scala/leon/invariant/templateSolvers/FarkasLemmaSolver.scala b/src/main/scala/leon/invariant/templateSolvers/FarkasLemmaSolver.scala
index 96d57a83403a9f4b43a21de0173a4bd25adf1aeb..5831fcda02e1a14e9f0aa6bb0085b6b87fbcc22e 100644
--- a/src/main/scala/leon/invariant/templateSolvers/FarkasLemmaSolver.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/FarkasLemmaSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.templateSolvers
 
diff --git a/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala b/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala
index f0da67891a2240fbb175957a192d39b926f5939f..7a5dd39a921944d067697dc7eef721a172ba56c7 100644
--- a/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.templateSolvers
 
diff --git a/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolverWithMult.scala b/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolverWithMult.scala
index 40ecbf14c8e30bede887e380b1fd27243a6e5de8..78746330187015714b04dee7c9b2cb25d0440b66 100644
--- a/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolverWithMult.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/NLTemplateSolverWithMult.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.templateSolvers
 
diff --git a/src/main/scala/leon/invariant/templateSolvers/TemplateSolver.scala b/src/main/scala/leon/invariant/templateSolvers/TemplateSolver.scala
index e42817a1e51bea5cd4c65e08f549489add3249f0..c46228f3c99e71e49227ed5e6c1094537ca22d48 100644
--- a/src/main/scala/leon/invariant/templateSolvers/TemplateSolver.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/TemplateSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.templateSolvers
 
diff --git a/src/main/scala/leon/invariant/templateSolvers/UFADTEliminator.scala b/src/main/scala/leon/invariant/templateSolvers/UFADTEliminator.scala
index 4edc0f59a9e12ad702e4913b5d7080e716177b56..2ad934ed1994e2876a8392a28e6a54c39b3f88fa 100644
--- a/src/main/scala/leon/invariant/templateSolvers/UFADTEliminator.scala
+++ b/src/main/scala/leon/invariant/templateSolvers/UFADTEliminator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.templateSolvers
 
diff --git a/src/main/scala/leon/invariant/util/CallGraph.scala b/src/main/scala/leon/invariant/util/CallGraph.scala
index 7f49738744db2aa663dc1ca6bdc891b444c8dc66..ede408c37badd0a5727fe5e7f46e7afe099ec26f 100644
--- a/src/main/scala/leon/invariant/util/CallGraph.scala
+++ b/src/main/scala/leon/invariant/util/CallGraph.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/ExpressionTransformer.scala b/src/main/scala/leon/invariant/util/ExpressionTransformer.scala
index 716b977bf9efe379d451a4421ef6781ba3faccae..139319a3bf3767d24921596c3b8e16bc0e9cd695 100644
--- a/src/main/scala/leon/invariant/util/ExpressionTransformer.scala
+++ b/src/main/scala/leon/invariant/util/ExpressionTransformer.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/LetTupleSimplification.scala b/src/main/scala/leon/invariant/util/LetTupleSimplification.scala
index d560f5bc2719797679f64ec99e3d9806b12227b4..72b814904a28207791043588d4bbbc908d0663a3 100644
--- a/src/main/scala/leon/invariant/util/LetTupleSimplification.scala
+++ b/src/main/scala/leon/invariant/util/LetTupleSimplification.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/Minimizer.scala b/src/main/scala/leon/invariant/util/Minimizer.scala
index 267f66bae0043a0265dd8eda71dc9bd40eef7119..ddf7c01dda693e9067376a2f1b01942ad7e007c2 100644
--- a/src/main/scala/leon/invariant/util/Minimizer.scala
+++ b/src/main/scala/leon/invariant/util/Minimizer.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/RealValuedExprEvaluator.scala b/src/main/scala/leon/invariant/util/RealValuedExprEvaluator.scala
index 9fd5c324eab5719fe47981d807ed8005138e67ff..8f334c0b660104c466012970964667545da6bca1 100644
--- a/src/main/scala/leon/invariant/util/RealValuedExprEvaluator.scala
+++ b/src/main/scala/leon/invariant/util/RealValuedExprEvaluator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/SolverUtil.scala b/src/main/scala/leon/invariant/util/SolverUtil.scala
index a9ff8b0f19cfb4733243b28ce59d6379ff372727..e0f3fe000b8ddd332f7cf6557b6874613c7c3982 100644
--- a/src/main/scala/leon/invariant/util/SolverUtil.scala
+++ b/src/main/scala/leon/invariant/util/SolverUtil.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/Stats.scala b/src/main/scala/leon/invariant/util/Stats.scala
index eb5dc6efd83c35226fe90409482955357843ea89..9b957d3aced36c2f4c4c881d4dd8337d24ae5922 100644
--- a/src/main/scala/leon/invariant/util/Stats.scala
+++ b/src/main/scala/leon/invariant/util/Stats.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/TVarFactory.scala b/src/main/scala/leon/invariant/util/TVarFactory.scala
index 7fdebb008ec6529914c4f40aeb6451ed22f9aaef..cafad81b885c81cb3be4e8626954246564831796 100644
--- a/src/main/scala/leon/invariant/util/TVarFactory.scala
+++ b/src/main/scala/leon/invariant/util/TVarFactory.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/TimerUtil.scala b/src/main/scala/leon/invariant/util/TimerUtil.scala
index 77e9b520116234e1d4bb6fee6ddf7563deed1640..22dfffa24ec2c400126ea1df913377e511b9a4e0 100644
--- a/src/main/scala/leon/invariant/util/TimerUtil.scala
+++ b/src/main/scala/leon/invariant/util/TimerUtil.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/TreeUtil.scala b/src/main/scala/leon/invariant/util/TreeUtil.scala
index df6f64b0c7eda9640a77de2b4b9d2bf847eccc4c..597aa270edad551f186006b12ac3af5442be3b4c 100644
--- a/src/main/scala/leon/invariant/util/TreeUtil.scala
+++ b/src/main/scala/leon/invariant/util/TreeUtil.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/invariant/util/Util.scala b/src/main/scala/leon/invariant/util/Util.scala
index c660b065062ca99c5f4e87d18a259b7d1abbbeb7..472bc11921501ff7fa2ac3c604f13740fe714250 100644
--- a/src/main/scala/leon/invariant/util/Util.scala
+++ b/src/main/scala/leon/invariant/util/Util.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package invariant.util
 
diff --git a/src/main/scala/leon/laziness/ClosurePreAsserter.scala b/src/main/scala/leon/laziness/ClosurePreAsserter.scala
index a55cbbc00e7747835a9751e9c9140c1ebd761188..18398850ca56ec07407bf24041802919a6dd4469 100644
--- a/src/main/scala/leon/laziness/ClosurePreAsserter.scala
+++ b/src/main/scala/leon/laziness/ClosurePreAsserter.scala
@@ -1,20 +1,15 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
 import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
 import purescala.DefOps._
-import purescala.Extractors._
 import purescala.Types._
 import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
 import leon.invariant.util.ProgramUtil._
 import leon.invariant.util.PredicateUtil._
 import LazinessUtil._
diff --git a/src/main/scala/leon/laziness/FreeVariableFactory.scala b/src/main/scala/leon/laziness/FreeVariableFactory.scala
index 9e93edb5e92e7d8b49a2dbab7346260867d1bc17..441da84ba6844b3922456d2d63f45d600bcc05d4 100644
--- a/src/main/scala/leon/laziness/FreeVariableFactory.scala
+++ b/src/main/scala/leon/laziness/FreeVariableFactory.scala
@@ -1,31 +1,11 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
-import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
-import purescala.ExprOps._
-import purescala.DefOps._
-import purescala.Extractors._
 import purescala.Types._
-import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
-import LazinessUtil._
-import invariant.util.ProgramUtil._
 
 /**
  * A class that maintains a data type that can used to
diff --git a/src/main/scala/leon/laziness/LazinessEliminationPhase.scala b/src/main/scala/leon/laziness/LazinessEliminationPhase.scala
index a3256232264b208b2e780f7bc9352c203cff0906..847dc3d062a254c67669cb7546c6845d786c491c 100644
--- a/src/main/scala/leon/laziness/LazinessEliminationPhase.scala
+++ b/src/main/scala/leon/laziness/LazinessEliminationPhase.scala
@@ -1,40 +1,13 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
 import invariant.structure.FunctionUtils._
 import purescala.ScalaPrinter
-import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
-import purescala.DefOps._
-import purescala.Extractors._
-import purescala.Types._
-import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import leon.verification.VerificationPhase
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.solvers._
-import leon.solvers.z3._
-import leon.transformations._
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
 import LazinessUtil._
-import invariant.datastructure._
-import invariant.util.ProgramUtil._
-import purescala.Constructors._
-import leon.verification._
-import PredicateUtil._
-import leon.invariant.engine._
 import LazyVerificationPhase._
 import utils._
 import java.io.
@@ -115,7 +88,7 @@ object LazinessEliminationPhase extends TransformationPhase {
       checkInstrumentationSpecs(instProg, checkCtx,
         checkCtx.findOption(LazinessEliminationPhase.optUseOrb).getOrElse(false))
     // dump stats
-    if (ctx.findOption(SharedOptions.optBenchmark).getOrElse(false)) {
+    if (ctx.findOption(GlobalOptions.optBenchmark).getOrElse(false)) {
       val modid = prog.units.find(_.isMainUnit).get.id
       val filename = modid + "-stats.txt"
       val pw = new PrintWriter(filename)
diff --git a/src/main/scala/leon/laziness/LazinessUtil.scala b/src/main/scala/leon/laziness/LazinessUtil.scala
index 79f6fae0b62b334948051146106626da07671008..eb9e35c31119cb216f356e88777a9e762417359b 100644
--- a/src/main/scala/leon/laziness/LazinessUtil.scala
+++ b/src/main/scala/leon/laziness/LazinessUtil.scala
@@ -1,30 +1,17 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
-import invariant.util._
-import invariant.structure.FunctionUtils._
 import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
-import purescala.ExprOps._
 import purescala.DefOps._
-import purescala.Extractors._
 import purescala.Types._
-import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
 import java.io.File
 import java.io.FileWriter
 import java.io.BufferedWriter
 import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
-import purescala.PrinterOptions
+import utils.FileOutputPhase
 
 object LazinessUtil {
 
@@ -33,13 +20,7 @@ object LazinessUtil {
   }
 
   def prettyPrintProgramToFile(p: Program, ctx: LeonContext, suffix: String, uniqueIds: Boolean = false) {
-    val optOutputDirectory = new LeonOptionDef[String] {
-      val name = "o"
-      val description = "Output directory"
-      val default = "leon.out"
-      val usageRhs = "dir"
-      val parser = (x: String) => x
-    }
+    val optOutputDirectory = FileOutputPhase.optOutputDirectory
     val outputFolder = ctx.findOptionOrDefault(optOutputDirectory)
     try {
       new File(outputFolder).mkdir()
diff --git a/src/main/scala/leon/laziness/LazyClosureConverter.scala b/src/main/scala/leon/laziness/LazyClosureConverter.scala
index a47855f267eeabfe2d30587a3b0a7720a1372f27..58fa1674135b4b2f07aaf2b94f4a44b0715d1e7a 100644
--- a/src/main/scala/leon/laziness/LazyClosureConverter.scala
+++ b/src/main/scala/leon/laziness/LazyClosureConverter.scala
@@ -1,29 +1,15 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
 import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
-import purescala.DefOps._
 import purescala.Extractors._
 import purescala.Types._
 import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
 import LazinessUtil._
 import ProgramUtil._
 import PredicateUtil._
diff --git a/src/main/scala/leon/laziness/LazyClosureFactory.scala b/src/main/scala/leon/laziness/LazyClosureFactory.scala
index faab5ef4dc21771530c319d80e53a55108f262af..1a69fa89dd438210969981f1cd452e4ac6ba90cf 100644
--- a/src/main/scala/leon/laziness/LazyClosureFactory.scala
+++ b/src/main/scala/leon/laziness/LazyClosureFactory.scala
@@ -1,29 +1,13 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
-import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
-import purescala.DefOps._
-import purescala.Extractors._
 import purescala.Types._
 import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
 import LazinessUtil._
 
 //case class ClosureData(tpe: TypeTree, absDef: AbstractClassDef, caseClass: Seq[CaseClassDef])
diff --git a/src/main/scala/leon/laziness/LazyExpressionLifter.scala b/src/main/scala/leon/laziness/LazyExpressionLifter.scala
index bed858694e3efff10742daf73f0638cec21b6ec3..1aa312c7ac87243f0aa63299466132a0ea12d600 100644
--- a/src/main/scala/leon/laziness/LazyExpressionLifter.scala
+++ b/src/main/scala/leon/laziness/LazyExpressionLifter.scala
@@ -1,41 +1,18 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
 import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
-import purescala.DefOps._
 import purescala.Extractors._
 import purescala.Types._
 import purescala.TypeOps._
 import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import leon.verification.VerificationPhase
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.solvers._
-import leon.solvers.z3._
-import leon.transformations._
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
 import LazinessUtil._
-import invariant.datastructure._
 import invariant.util.ProgramUtil._
-import purescala.Constructors._
-import leon.verification._
-import PredicateUtil._
-import leon.invariant.engine._
 import FreeVariableFactory._
 
 object LazyExpressionLifter {
diff --git a/src/main/scala/leon/laziness/LazyFunctionsManager.scala b/src/main/scala/leon/laziness/LazyFunctionsManager.scala
index b5197ac4ca2d5ec6dacdd9a320e51a6b5cdd5795..46220895e63bc872014283950cdbeee854381f65 100644
--- a/src/main/scala/leon/laziness/LazyFunctionsManager.scala
+++ b/src/main/scala/leon/laziness/LazyFunctionsManager.scala
@@ -1,29 +1,11 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
-import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
-import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
-import purescala.DefOps._
 import purescala.Extractors._
-import purescala.Types._
-import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
 import LazinessUtil._
 
 class LazyFunctionsManager(p: Program) {
diff --git a/src/main/scala/leon/laziness/LazyInstrumenter.scala b/src/main/scala/leon/laziness/LazyInstrumenter.scala
index 764a5606f74ab86edf11d6df81a07681519d6b87..6dc5a7e50f184daa34907ca12bc58e285539a318 100644
--- a/src/main/scala/leon/laziness/LazyInstrumenter.scala
+++ b/src/main/scala/leon/laziness/LazyInstrumenter.scala
@@ -1,28 +1,11 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
-import invariant.util._
-import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
-import purescala.ExprOps._
-import purescala.DefOps._
-import purescala.Extractors._
 import purescala.Types._
 import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
 import leon.transformations._
 import LazinessUtil._
 
diff --git a/src/main/scala/leon/laziness/LazyVerificationPhase.scala b/src/main/scala/leon/laziness/LazyVerificationPhase.scala
index ac4f04faef23e903787792aaf74b40c96da872af..b72bf59f701bf251a9b22b353ae4cfbad6d7af6c 100644
--- a/src/main/scala/leon/laziness/LazyVerificationPhase.scala
+++ b/src/main/scala/leon/laziness/LazyVerificationPhase.scala
@@ -1,40 +1,19 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
 import invariant.util._
 import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
-import purescala.DefOps._
-import purescala.Extractors._
-import purescala.Types._
-import leon.invariant.util.TypeUtil._
-import leon.invariant.util.LetTupleSimplification._
-import leon.verification.VerificationPhase
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.solvers._
-import leon.solvers.z3._
-import leon.transformations._
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
+import solvers._
+import transformations._
 import LazinessUtil._
-import invariant.datastructure._
-import invariant.util.ProgramUtil._
 import purescala.Constructors._
-import leon.verification._
+import verification._
 import PredicateUtil._
-import leon.invariant.engine._
+import invariant.engine._
 
 object LazyVerificationPhase {
 
diff --git a/src/main/scala/leon/laziness/TypeChecker.scala b/src/main/scala/leon/laziness/TypeChecker.scala
index 96687b85645037f2d5beb9e374f9397eda25c675..ab9c1b3e02a41b1a27c564b6ee845981ab8133d9 100644
--- a/src/main/scala/leon/laziness/TypeChecker.scala
+++ b/src/main/scala/leon/laziness/TypeChecker.scala
@@ -1,15 +1,13 @@
 package leon
 package laziness
 
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
-import purescala.ExprOps._
 import purescala.Extractors._
 import purescala.Types._
 import purescala.TypeOps._
-import leon.invariant.util.TypeUtil._
+import invariant.util.TypeUtil._
 
 object TypeChecker {
    /**
diff --git a/src/main/scala/leon/laziness/TypeRectifier.scala b/src/main/scala/leon/laziness/TypeRectifier.scala
index a048a969afd4fa9dcf091c5465494e2880bbc5a8..72d61bd7c33d8dcf6bcfc894dbde864921bd33f5 100644
--- a/src/main/scala/leon/laziness/TypeRectifier.scala
+++ b/src/main/scala/leon/laziness/TypeRectifier.scala
@@ -1,29 +1,15 @@
 package leon
 package laziness
 
-import invariant.factories._
-import invariant.util.Util._
-import invariant.util._
 import invariant.structure.FunctionUtils._
-import purescala.ScalaPrinter
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.ExprOps._
-import purescala.DefOps._
 import purescala.Extractors._
 import purescala.Types._
 import leon.invariant.util.TypeUtil._
 import leon.invariant.util.LetTupleSimplification._
-import java.io.File
-import java.io.FileWriter
-import java.io.BufferedWriter
-import scala.util.matching.Regex
-import leon.purescala.PrettyPrinter
-import leon.LeonContext
-import leon.LeonOptionDef
-import leon.Main
-import leon.TransformationPhase
 import LazinessUtil._
 import leon.invariant.datastructure.DisjointSets
 import invariant.util.ProgramUtil._
@@ -34,14 +20,11 @@ import invariant.util.ProgramUtil._
  * Result is a program in which all type paramters of functions, types of
  * parameters of functions are correct.
  * The subsequent phase performs a local type inference.
- * @param placeHolderParameter Expected to returns true iff a type parameter
- * 														is meant as a placeholder and cannot be used
- * 														to represent a unified type
  */
 class TypeRectifier(p: Program, clFactory: LazyClosureFactory) {
 
   val typeClasses = {
-    var tc = new DisjointSets[TypeTree]()
+    val tc = new DisjointSets[TypeTree]()
     p.definedFunctions.foreach {
       case fd if fd.hasBody && !fd.isLibrary && !fd.isInvariant =>
         postTraversal {
diff --git a/src/main/scala/leon/package.scala b/src/main/scala/leon/package.scala
index 1471097242f07e3ca001255015ec8dc6a8c84a96..8a6a6904f3e6c2450f48b30cc939fe1d7f3b4368 100644
--- a/src/main/scala/leon/package.scala
+++ b/src/main/scala/leon/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 /** Core package of the Leon system 
   *
diff --git a/src/main/scala/leon/purescala/CallGraph.scala b/src/main/scala/leon/purescala/CallGraph.scala
index edeaab26953ef6734b2a334e440e04dfb59d38c5..63fe2c570977b0f913f29db8874c4132bf191d94 100644
--- a/src/main/scala/leon/purescala/CallGraph.scala
+++ b/src/main/scala/leon/purescala/CallGraph.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/Common.scala b/src/main/scala/leon/purescala/Common.scala
index 8b9ecba6ce5d18b7e431500cf7ce86f4e2dd6d10..848ded806dc049df282c85b022c3c35a09be10da 100644
--- a/src/main/scala/leon/purescala/Common.scala
+++ b/src/main/scala/leon/purescala/Common.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -10,7 +10,6 @@ import Definitions.Program
 
 object Common {
 
-
   abstract class Tree extends Positioned with Serializable with Printable {
     def copiedFrom(o: Tree): this.type = {
       setPos(o)
@@ -43,8 +42,6 @@ object Common {
     private val alwaysShowUniqueID: Boolean = false
   ) extends Tree with Typed with Ordered[Identifier] {
 
-    self: Serializable =>
-
     val getType = tpe
 
     override def equals(other: Any): Boolean = other match {
@@ -116,6 +113,7 @@ object Common {
     id1.toString == id2.toString
   }
 
+  /** Returns true if the two group of identifiers ovelap. */
   def aliased(ids1 : Set[Identifier], ids2 : Set[Identifier]) = {
     val s1 = ids1.groupBy{ _.toString }.keySet
     val s2 = ids2.groupBy{ _.toString }.keySet
diff --git a/src/main/scala/leon/purescala/Constructors.scala b/src/main/scala/leon/purescala/Constructors.scala
index 95218cb2857a97c6834ac039f20c426a0736be8f..24c0f000c4ac5b9d1d0f19d531772fe22a53d516 100644
--- a/src/main/scala/leon/purescala/Constructors.scala
+++ b/src/main/scala/leon/purescala/Constructors.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/DefOps.scala b/src/main/scala/leon/purescala/DefOps.scala
index f713cab8f1a20d54a1fb47254f2c09e9e2655d2c..1b9d146d15765fe88b3ebf8d034ba9ac66a361a6 100644
--- a/src/main/scala/leon/purescala/DefOps.scala
+++ b/src/main/scala/leon/purescala/DefOps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.purescala
 
@@ -371,12 +371,12 @@ object DefOps {
 
   def replaceFunCalls(e: Expr, fdMapF: FunDef => FunDef, fiMapF: (FunctionInvocation, FunDef) => Option[Expr] = defaultFiMap): Expr = {
     preMap {
-      case MatchExpr(scrut, cases) =>
+      case me@MatchExpr(scrut, cases) =>
         Some(MatchExpr(scrut, cases.map(matchcase => matchcase match {
-          case MatchCase(pattern, guard, rhs) => MatchCase(replaceFunCalls(pattern, fdMapF), guard, rhs)
-        })))
+          case mc@MatchCase(pattern, guard, rhs) => MatchCase(replaceFunCalls(pattern, fdMapF), guard, rhs).copiedFrom(mc)
+        })).copiedFrom(me))
       case fi @ FunctionInvocation(TypedFunDef(fd, tps), args) =>
-        fiMapF(fi, fdMapF(fd)).map(_.setPos(fi))
+        fiMapF(fi, fdMapF(fd)).map(_.copiedFrom(fi))
       case _ =>
         None
     }(e)
@@ -388,7 +388,7 @@ object DefOps {
   }(p)
 
   private def defaultCdMap(cc: CaseClass, ccd: CaseClassType): Option[Expr] = (cc, ccd) match {
-    case (CaseClass(old, args), newCcd) if old.classDef != newCcd =>
+    case (CaseClass(old, args), newCcd) if old.classDef != newCcd.classDef =>
       Some(CaseClass(newCcd, args))
     case _ =>
       None
@@ -401,7 +401,7 @@ object DefOps {
     * @param ciMapF Given a previous case class invocation and its new case class definition, returns the expression to use.
     *               By default it is the case class construction using the new case class definition.
     * @return the new program with a map from the old case classes to the new case classes, with maps concerning identifiers and function definitions. */
-  def replaceCaseClassDefs(p: Program)(_cdMapF: CaseClassDef => Option[Option[AbstractClassType] => CaseClassDef],
+  def replaceCaseClassDefs(p: Program)(cdMapF: CaseClassDef => Option[Option[AbstractClassType] => CaseClassDef],
                                        ciMapF: (CaseClass, CaseClassType) => Option[Expr] = defaultCdMap)
                                        : (Program, Map[ClassDef, ClassDef], Map[Identifier, Identifier], Map[FunDef, FunDef]) = {
     var cdMapFCache = Map[CaseClassDef, Option[Option[AbstractClassType] => CaseClassDef]]()
@@ -413,7 +413,7 @@ object DefOps {
       cd match {
         case ccd: CaseClassDef =>
           cdMapFCache.getOrElse(ccd, {
-            val new_cd_potential = _cdMapF(ccd)
+            val new_cd_potential = cdMapF(ccd)
             cdMapFCache += ccd -> new_cd_potential
             new_cd_potential
           })
@@ -711,4 +711,27 @@ object DefOps {
     )
   }
 
+  def augmentCaseClassFields(extras: Seq[(CaseClassDef, Seq[(ValDef, Expr)])])
+                            (program: Program) = {
+
+    def updateBody(body: Expr): Expr = {
+      preMap({
+        case CaseClass(ct, args) => extras.find(p => p._1 == ct.classDef).map{
+          case (ccd, extraFields) =>
+            CaseClass(CaseClassType(ccd, ct.tps), args ++ extraFields.map{ case (_, v) => v })
+        }
+        case _ => None
+      })(body)
+    }
+
+    extras.foreach{ case (ccd, extraFields) => ccd.setFields(ccd.fields ++ extraFields.map(_._1)) }
+    for {
+      fd <- program.definedFunctions
+    } {
+      fd.body = fd.body.map(body => updateBody(body))
+      fd.precondition = fd.precondition.map(pre => updateBody(pre))
+      fd.postcondition = fd.postcondition.map(post => updateBody(post))
+    }
+  }
+
 }
diff --git a/src/main/scala/leon/purescala/Definitions.scala b/src/main/scala/leon/purescala/Definitions.scala
index 733eaf124dbb6dd8499c81347f7fc864c23ca453..98497afd31586ef8cff40eec4a68ef36da63162b 100644
--- a/src/main/scala/leon/purescala/Definitions.scala
+++ b/src/main/scala/leon/purescala/Definitions.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -16,7 +16,7 @@ object Definitions {
     
     val id: Identifier
 
-    def subDefinitions : Seq[Definition]      // The enclosed scopes/definitions by this definition
+    def subDefinitions: Seq[Definition] // The enclosed scopes/definitions by this definition
   
     def containsDef(df: Definition): Boolean = {
       subDefinitions.exists { sd =>
@@ -52,6 +52,10 @@ object Definitions {
 
     var defaultValue : Option[FunDef] = None
 
+    var isVar: Boolean = false
+
+    def setIsVar(b: Boolean): this.type = { this.isVar = b; this }
+
     def subDefinitions = Seq()
 
     /** Transform this [[ValDef]] into a [[Expressions.Variable Variable]] */
@@ -113,14 +117,21 @@ object Definitions {
       }
     }
   }
-  
-  /** Object definition */
+
+  /** Definition of a compilation unit, corresponding to a source file
+    *
+    * @param id The name of the file this [[UnitDef]] was compiled from
+    * @param pack The package of this [[UnitDef]]
+    * @param imports The imports of this [[UnitDef]]
+    * @param defs The [[Definition]]s (classes and objects) in this [[UnitDef]]
+    * @param isMainUnit Whether this is a user-provided file or a library file
+    */
   case class UnitDef(
     id: Identifier,
-    pack : PackageRef,
-    imports : Seq[Import],
-    defs : Seq[Definition],
-    isMainUnit : Boolean // false for libraries/imports
+    pack: PackageRef,
+    imports: Seq[Import],
+    defs: Seq[Definition],
+    isMainUnit: Boolean
   ) extends Definition {
      
     def subDefinitions = defs
@@ -161,8 +172,7 @@ object Definitions {
       UnitDef(id, Nil, Nil, modules, true)
   }
   
-  /** Objects work as containers for class definitions, functions (def's) and
-   * val's. */
+  /** Corresponds to an '''object''' in scala. Contains [[FunDef]]s, [[ClassDef]]s and [[ValDef]]s. */
   case class ModuleDef(id: Identifier, defs: Seq[Definition], isPackageObject: Boolean) extends Definition {
     
     def subDefinitions = defs
@@ -184,7 +194,14 @@ object Definitions {
     }
   }
 
-  // A class that represents flags that annotate a FunDef with different attributes
+  /** A trait that represents flags that annotate a ClassDef with different attributes */
+  sealed trait ClassFlag
+
+  object ClassFlag {
+    def fromName(name: String, args: Seq[Option[Any]]): ClassFlag = Annotation(name, args)
+  }
+
+  /** A trait that represents flags that annotate a FunDef with different attributes */
   sealed trait FunctionFlag
 
   object FunctionFlag {
@@ -194,13 +211,6 @@ object Definitions {
     }
   }
 
-  // A class that represents flags that annotate a ClassDef with different attributes
-  sealed trait ClassFlag
-
-  object ClassFlag {
-    def fromName(name: String, args: Seq[Option[Any]]): ClassFlag = Annotation(name, args)
-  }
-
   // Whether this FunDef was originally a (lazy) field
   case class IsField(isLazy: Boolean) extends FunctionFlag
   // Compiler annotations given in the source code as @annot
@@ -218,9 +228,9 @@ object Definitions {
   case object IsInlined extends FunctionFlag
   // Is an ADT invariant method
   case object IsADTInvariant extends FunctionFlag with ClassFlag
+  case object IsInner extends FunctionFlag
 
-  /** Useful because case classes and classes are somewhat unified in some
-   * patterns (of pattern-matching, that is) */
+  /** Represents a class definition (either an abstract- or a case-class) */
   sealed trait ClassDef extends Definition {
     self =>
 
@@ -352,12 +362,12 @@ object Definitions {
     ): AbstractClassDef = {
       val acd = new AbstractClassDef(id, tparams, parent)
       acd.addFlags(this.flags)
-      parent.map(_.classDef.ancestors.map(_.registerChild(acd)))
+      parent.foreach(_.classDef.ancestors.foreach(_.registerChild(acd)))
       acd.copiedFrom(this)
     }
   }
 
-  /** Case classes/objects. */
+  /** Case classes/ case objects. */
   case class CaseClassDef(id: Identifier,
                           tparams: Seq[TypeParameterDef],
                           parent: Option[AbstractClassType],
@@ -393,7 +403,7 @@ object Definitions {
     def typed: CaseClassType = typed(tparams.map(_.tp))
     
     /** Duplication of this [[CaseClassDef]].
-      * @note This will not replace recursive case class def calls in [[arguments]] nor the parent abstract class types
+      * @note This will not replace recursive [[CaseClassDef]] calls in [[fields]] nor the parent abstract class types
       */
     def duplicate(
       id: Identifier                    = this.id.freshen,
@@ -406,7 +416,7 @@ object Definitions {
       cd.setFields(fields)
       cd.addFlags(this.flags)
       cd.copiedFrom(this)
-      parent.map(_.classDef.ancestors.map(_.registerChild(cd)))
+      parent.foreach(_.classDef.ancestors.foreach(_.registerChild(cd)))
       cd
     }
   }
@@ -501,6 +511,7 @@ object Definitions {
     def isRealFunction    = !canBeField
     def isSynthetic       = flags contains IsSynthetic
     def isInvariant       = flags contains IsADTInvariant
+    def isInner           = flags contains IsInner
     def methodOwner       = flags collectFirst { case IsMethod(cd) => cd }
 
     /* Wrapping in TypedFunDef */
@@ -519,6 +530,9 @@ object Definitions {
     def isRecursive(p: Program) = p.callGraph.transitiveCallees(this) contains this
 
     def paramIds = params map { _.id }
+
+    def applied(args: Seq[Expr]): FunctionInvocation = Constructors.functionInvocation(this, args)
+    def applied = FunctionInvocation(this.typed, this.paramIds map Variable)
   }
 
 
@@ -603,6 +617,8 @@ object Definitions {
       })
     }
 
+    // Methods that extract expressions from the underlying FunDef, using a cache
+
     def fullBody      = cached(fd.fullBody)
     def body          = fd.body map cached
     def precondition  = fd.precondition map cached
diff --git a/src/main/scala/leon/purescala/ExprOps.scala b/src/main/scala/leon/purescala/ExprOps.scala
index 058e3a0ead6262f367ef5c4441dd075dd9e79be7..9724d846cedbcc10b2c22b26cd095832b53e1b27 100644
--- a/src/main/scala/leon/purescala/ExprOps.scala
+++ b/src/main/scala/leon/purescala/ExprOps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -43,33 +43,33 @@ object ExprOps extends { val Deconstructor = Operator } with SubTreeOps[Expr] {
 
   def preTransformWithBinders(f: (Expr, Set[Identifier]) => Expr, initBinders: Set[Identifier] = Set())(e: Expr) = {
     import xlang.Expressions.LetVar
-    def rec(binders: Set[Identifier], e: Expr): Expr = (f(e, binders) match {
-      case LetDef(fds, bd) =>
+    def rec(binders: Set[Identifier], e: Expr): Expr = f(e, binders) match {
+      case ld@LetDef(fds, bd) =>
         fds.foreach(fd => {
           fd.fullBody = rec(binders ++ fd.paramIds, fd.fullBody)
         })
-        LetDef(fds, rec(binders, bd))
-      case Let(i, v, b) =>
-        Let(i, rec(binders + i, v), rec(binders + i, b))
-      case LetVar(i, v, b) =>
-        LetVar(i, rec(binders + i, v), rec(binders + i, b))
-      case MatchExpr(scrut, cses) =>
-        MatchExpr(rec(binders, scrut), cses map { case MatchCase(pat, og, rhs) =>
+        LetDef(fds, rec(binders, bd)).copiedFrom(ld)
+      case l@Let(i, v, b) =>
+        Let(i, rec(binders + i, v), rec(binders + i, b)).copiedFrom(l)
+      case lv@LetVar(i, v, b) =>
+        LetVar(i, rec(binders + i, v), rec(binders + i, b)).copiedFrom(lv)
+      case m@MatchExpr(scrut, cses) =>
+        MatchExpr(rec(binders, scrut), cses map { case mc@MatchCase(pat, og, rhs) =>
           val newBs = binders ++ pat.binders
-          MatchCase(pat, og map (rec(newBs, _)), rec(newBs, rhs))
-        })
-      case Passes(in, out, cses) =>
-        Passes(rec(binders, in), rec(binders, out), cses map { case MatchCase(pat, og, rhs) =>
+          MatchCase(pat, og map (rec(newBs, _)), rec(newBs, rhs)).copiedFrom(mc)
+        }).copiedFrom(m)
+      case p@Passes(in, out, cses) =>
+        Passes(rec(binders, in), rec(binders, out), cses map { case mc@MatchCase(pat, og, rhs) =>
           val newBs = binders ++ pat.binders
-          MatchCase(pat, og map (rec(newBs, _)), rec(newBs, rhs))
-        })
-      case Lambda(args, bd) =>
-        Lambda(args, rec(binders ++ args.map(_.id), bd))
-      case Forall(args, bd) =>
-        Forall(args, rec(binders ++ args.map(_.id), bd))
-      case Deconstructor(subs, builder) =>
-        builder(subs map (rec(binders, _)))
-    }).copiedFrom(e)
+          MatchCase(pat, og map (rec(newBs, _)), rec(newBs, rhs)).copiedFrom(mc)
+        }).copiedFrom(p)
+      case l@Lambda(args, bd) =>
+        Lambda(args, rec(binders ++ args.map(_.id), bd)).copiedFrom(l)
+      case f@Forall(args, bd) =>
+        Forall(args, rec(binders ++ args.map(_.id), bd)).copiedFrom(f)
+      case d@Deconstructor(subs, builder) =>
+        builder(subs map (rec(binders, _))).copiedFrom(d)
+    }
 
     rec(initBinders, e)
   }
@@ -287,9 +287,9 @@ object ExprOps extends { val Deconstructor = Operator } with SubTreeOps[Expr] {
       case Lambda(args, body) => Some(Lambda(args.map(vd => vd.copy(id = subst(vd.id))), body))
       case Forall(args, body) => Some(Forall(args.map(vd => vd.copy(id = subst(vd.id))), body))
       case Let(i, e, b)       => Some(Let(subst(i), e, b))
-      case MatchExpr(scrut, cses) => Some(MatchExpr(scrut, cses.map { cse =>
+      case m@MatchExpr(scrut, cses) => Some(MatchExpr(scrut, cses.map { cse =>
         cse.copy(pattern = replacePatternBinders(cse.pattern, subst))
-      }))
+      }).copiedFrom(m))
       case Passes(in, out, cses) => Some(Passes(in, out, cses.map { cse =>
         cse.copy(pattern = replacePatternBinders(cse.pattern, subst))
       }))
@@ -1436,10 +1436,6 @@ object ExprOps extends { val Deconstructor = Operator } with SubTreeOps[Expr] {
               else (m: Apriori) => None} &&
           (args1 zip args2).mergeall{ case (a1, a2) => isHomo(a1, a2) }
 
-        case (Terminating(tfd1, args1), Terminating(tfd2, args2)) =>
-          idHomo(tfd1.fd.id, tfd2.fd.id)(apriori) && tfd1.tps.zip(tfd2.tps).mergeall{ case (t1, t2) => if(t1 == t2) (m: Apriori) => Option(m) else (m: Apriori) => None} &&
-          (args1 zip args2).mergeall{ case (a1, a2) => isHomo(a1, a2) }
-
         case (Lambda(defs, body), Lambda(defs2, body2)) =>
           // We remove variables introduced by lambdas.
           ((defs zip defs2).mergeall{ case (ValDef(a1), ValDef(a2)) =>
@@ -1558,8 +1554,6 @@ object ExprOps extends { val Deconstructor = Operator } with SubTreeOps[Expr] {
 
       }
 
-      import synthesis.Witnesses.Terminating
-
       val res = (t1, t2) match {
         case (Variable(i1), Variable(i2)) =>
           idHomo(i1, i2)
@@ -1589,14 +1583,6 @@ object ExprOps extends { val Deconstructor = Operator } with SubTreeOps[Expr] {
           fdHomo(tfd1.fd, tfd2.fd) &&
           (args1 zip args2).forall{ case (a1, a2) => isHomo(a1, a2) }
 
-        case (Terminating(tfd1, args1), Terminating(tfd2, args2)) =>
-          // TODO: Check type params
-          fdHomo(tfd1.fd, tfd2.fd) &&
-          (args1 zip args2).forall{ case (a1, a2) => isHomo(a1, a2) }
-
-        case (v1, v2) if isValue(v1) && isValue(v2) =>
-          v1 == v2
-
         case Same(Deconstructor(es1, _), Deconstructor(es2, _)) =>
           (es1.size == es2.size) &&
           (es1 zip es2).forall{ case (e1, e2) => isHomo(e1, e2) }
@@ -2050,7 +2036,6 @@ object ExprOps extends { val Deconstructor = Operator } with SubTreeOps[Expr] {
   def liftClosures(e: Expr): (Set[FunDef], Expr) = {
     var fds: Map[FunDef, FunDef] = Map()
 
-    import synthesis.Witnesses.Terminating
     val res1 = preMap({
       case LetDef(lfds, b) =>
         val nfds = lfds.map(fd => fd -> fd.duplicate())
@@ -2066,13 +2051,6 @@ object ExprOps extends { val Deconstructor = Operator } with SubTreeOps[Expr] {
           None
         }
 
-      case Terminating(tfd, args) =>
-        if (fds contains tfd.fd) {
-          Some(Terminating(fds(tfd.fd).typed(tfd.tps), args))
-        } else {
-          None
-        }
-
       case _ =>
         None
     })(e)
diff --git a/src/main/scala/leon/purescala/Expressions.scala b/src/main/scala/leon/purescala/Expressions.scala
index dba3903654592da7000912b43bd1a5b6a5d55ed5..6d6382709e704d4562a5a0027005d7b0ef4c4264 100644
--- a/src/main/scala/leon/purescala/Expressions.scala
+++ b/src/main/scala/leon/purescala/Expressions.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.purescala
 
@@ -787,7 +787,7 @@ object Expressions {
     *
     * [[exprs]] should always contain at least 2 elements.
     * If you are not sure about this requirement, you should use
-    * [[leon.purescala.Constructors#tupleWrap purescala's constructor tupleWrap]]
+    * [[leon.purescala.Constructors.tupleWrap purescala's constructor tupleWrap]]
     *
     * @param exprs The expressions in the tuple
     */
diff --git a/src/main/scala/leon/purescala/Extractors.scala b/src/main/scala/leon/purescala/Extractors.scala
index 49e6afd3aeea07ad6ec48813d8ced497374b79c3..c7d8a1a40ac9d2bf7f1386311941fe1006881ad3 100644
--- a/src/main/scala/leon/purescala/Extractors.scala
+++ b/src/main/scala/leon/purescala/Extractors.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -7,7 +7,6 @@ import Expressions._
 import Common._
 import Types._
 import Constructors._
-import Definitions.{Program, AbstractClassDef, CaseClassDef}
 
 object Extractors {
 
@@ -210,7 +209,7 @@ object Extractors {
         Seq(cond, thenn, elze),
         { case Seq(c, t, e) => IfExpr(c, t, e) }
       ))
-      case MatchExpr(scrut, cases) => Some((
+      case m@MatchExpr(scrut, cases) => Some((
         scrut +: cases.flatMap { _.expressions },
         (es: Seq[Expr]) => {
           var i = 1
@@ -219,7 +218,7 @@ object Extractors {
             case GuardedCase(b, _, _) => i += 2; GuardedCase(b, es(i - 2), es(i - 1))
           }
 
-          matchExpr(es.head, newcases)
+          matchExpr(es.head, newcases).copiedFrom(m)
         }
       ))
       case Passes(in, out, cases) => Some((
diff --git a/src/main/scala/leon/purescala/FunctionClosure.scala b/src/main/scala/leon/purescala/FunctionClosure.scala
index 07c6781a8389be1df4e16681cd518bb043cb608a..1ffaccef7b1fd4bddf0f5f5d40bdd9ac0b9b5df0 100644
--- a/src/main/scala/leon/purescala/FunctionClosure.scala
+++ b/src/main/scala/leon/purescala/FunctionClosure.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -8,8 +8,8 @@ import Expressions._
 import ExprOps._
 import Constructors._
 import TypeOps.instantiateType
-import leon.purescala.Common.Identifier
-import leon.purescala.Types.TypeParameter
+import Common.Identifier
+import Types.TypeParameter
 import utils.GraphOps._
 
 object FunctionClosure extends TransformationPhase {
@@ -108,6 +108,7 @@ object FunctionClosure extends TransformationPhase {
     }
 
     val funs = closed.values.toSeq.map{ _.newFd }
+    funs foreach (_.addFlag(IsInner))
 
     // Recursively close new functions
     fd +: funs.flatMap(close)
diff --git a/src/main/scala/leon/purescala/FunctionMapping.scala b/src/main/scala/leon/purescala/FunctionMapping.scala
index 34a9c2d8087c76dc31dd0e9a81c650e75239b1f5..cee6df3d2ccc562ecd98625b73fd5532cc873fb9 100644
--- a/src/main/scala/leon/purescala/FunctionMapping.scala
+++ b/src/main/scala/leon/purescala/FunctionMapping.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/MethodLifting.scala b/src/main/scala/leon/purescala/MethodLifting.scala
index 0e9e11d171a15e2b0b5fb77d0b3f0e65d44be38b..957505f297b551ff0bab84955015de35b0a0d7e2 100644
--- a/src/main/scala/leon/purescala/MethodLifting.scala
+++ b/src/main/scala/leon/purescala/MethodLifting.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -11,6 +11,7 @@ import ExprOps._
 import Types._
 import Constructors._
 import TypeOps.instantiateType
+import xlang.Expressions._
 
 object MethodLifting extends TransformationPhase {
 
diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala
index 8b681460826345dad6078145bb9cb01e1be73eb9..3773ebce48b3c51e056cee01f1ed059288d25bc5 100644
--- a/src/main/scala/leon/purescala/PrettyPrinter.scala
+++ b/src/main/scala/leon/purescala/PrettyPrinter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -367,6 +367,8 @@ class PrettyPrinter(opts: PrinterOptions,
       case Not(expr) => p"\u00AC$expr"
 
       case vd @ ValDef(id) =>
+        if(vd.isVar)
+          p"var "
         p"$id : ${vd.getType}"
         vd.defaultValue.foreach { fd => p" = ${fd.body.get}" }
 
@@ -392,11 +394,9 @@ class PrettyPrinter(opts: PrinterOptions,
               |}"""
         }
 
-      /*
       case LetPattern(p,s,rhs) =>
         p"""|val $p = $s
             |$rhs"""
-      */
 
       case MatchExpr(s, csc) =>
         optP {
@@ -530,7 +530,7 @@ class PrettyPrinter(opts: PrinterOptions,
 
         if (ccd.methods.nonEmpty) {
           p"""| {
-              |  ${nary(ccd.methods, "\n\n")}
+              |  ${nary(ccd.methods, "\n\n") }
               |}"""
         }
 
@@ -658,8 +658,8 @@ class PrettyPrinter(opts: PrinterOptions,
     case (pa: PrettyPrintable, _) => pa.printRequiresParentheses(within)
     case (_, None) => false
     case (_, Some(
-      _: Ensuring | _: Assert | _: Require | _: Definition | _: MatchExpr |
-      _: MatchCase | _: Let | _: LetDef | _: IfExpr | _ : CaseClass | _ : Lambda | _ : Choose
+      _: Ensuring | _: Assert | _: Require | _: Definition | _: MatchExpr | _: MatchCase |
+      _: Let | _: LetDef | _: IfExpr | _ : CaseClass | _ : Lambda | _ : Choose | _ : Tuple
     )) => false
     case (ex: StringConcat, Some(_: StringConcat)) => false
     case (b1 @ BinaryMethodCall(_, _, _), Some(b2 @ BinaryMethodCall(_, _, _))) if precedence(b1) > precedence(b2) => false
diff --git a/src/main/scala/leon/purescala/Printable.scala b/src/main/scala/leon/purescala/Printable.scala
deleted file mode 100644
index 27be035386699e945610cdc7857bbb9b5f8e73d3..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/purescala/Printable.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-package leon
-package purescala
-
-
-trait Printable {
-  def asString(implicit ctx: LeonContext): String
-}
diff --git a/src/main/scala/leon/purescala/PrinterHelpers.scala b/src/main/scala/leon/purescala/PrinterHelpers.scala
index 17ae02e0cbcbbb91c724225b165868d8d74db619..9cc4706972ff5bfc23bcf0b0016470c1aee0a6d2 100644
--- a/src/main/scala/leon/purescala/PrinterHelpers.scala
+++ b/src/main/scala/leon/purescala/PrinterHelpers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/PrinterOptions.scala b/src/main/scala/leon/purescala/PrinterOptions.scala
index 6a95b265d7871df9c5575a2ea605e457097b4e3f..b44b5a90561f57b8882a8ad0564cc6b7123cf2f0 100644
--- a/src/main/scala/leon/purescala/PrinterOptions.scala
+++ b/src/main/scala/leon/purescala/PrinterOptions.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -14,9 +14,9 @@ case class PrinterOptions (
 
 object PrinterOptions {
   def fromContext(ctx: LeonContext): PrinterOptions = {
-    val debugTrees     = ctx.findOptionOrDefault(SharedOptions.optDebug) contains DebugSectionTrees
-    val debugTypes     = ctx.findOptionOrDefault(SharedOptions.optDebug) contains DebugSectionTypes
-    val debugPositions = ctx.findOptionOrDefault(SharedOptions.optDebug) contains DebugSectionPositions
+    val debugTrees     = ctx.findOptionOrDefault(GlobalOptions.optDebug) contains DebugSectionTrees
+    val debugTypes     = ctx.findOptionOrDefault(GlobalOptions.optDebug) contains DebugSectionTypes
+    val debugPositions = ctx.findOptionOrDefault(GlobalOptions.optDebug) contains DebugSectionPositions
 
     PrinterOptions(
       baseIndent     = 0,
diff --git a/src/main/scala/leon/purescala/Quantification.scala b/src/main/scala/leon/purescala/Quantification.scala
index 21608b0facdb2d2318320a0e58974d23f56dc491..079be92d12c0ebaf8913842207a3ba1a65a387fd 100644
--- a/src/main/scala/leon/purescala/Quantification.scala
+++ b/src/main/scala/leon/purescala/Quantification.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/RestoreMethods.scala b/src/main/scala/leon/purescala/RestoreMethods.scala
index 7b18cde5018192fc01f3355107bf407d9465604d..5c0abc5e5472a52ed750444366e8c5eff38e10f5 100644
--- a/src/main/scala/leon/purescala/RestoreMethods.scala
+++ b/src/main/scala/leon/purescala/RestoreMethods.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/ScalaPrinter.scala b/src/main/scala/leon/purescala/ScalaPrinter.scala
index 11f0c187e144873c386a01702326056e636e1225..03c50eb2e752ad0dd3827703eff4fc44542e5b2c 100644
--- a/src/main/scala/leon/purescala/ScalaPrinter.scala
+++ b/src/main/scala/leon/purescala/ScalaPrinter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/ScopeSimplifier.scala b/src/main/scala/leon/purescala/ScopeSimplifier.scala
index e06055dc4d9dfce8b24d2d8ddb698ebbbc781079..4e149303a6bd0ae9b2a9418b7aac35b980b6101a 100644
--- a/src/main/scala/leon/purescala/ScopeSimplifier.scala
+++ b/src/main/scala/leon/purescala/ScopeSimplifier.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/SelfPrettyPrinter.scala b/src/main/scala/leon/purescala/SelfPrettyPrinter.scala
index d1cc5f86c6659b2fca51d42b3ebbb0feab20d084..c9f86a404bac39d3cd5bfec8b16e6d48eba2d968 100644
--- a/src/main/scala/leon/purescala/SelfPrettyPrinter.scala
+++ b/src/main/scala/leon/purescala/SelfPrettyPrinter.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.purescala
 
 import leon.purescala
@@ -34,8 +36,7 @@ object SelfPrettyPrinter {
 
 /** This pretty-printer uses functions defined in Leon itself.
   * If not pretty printing function is defined, return the default value instead
-  * @param The list of functions which should be excluded from pretty-printing (to avoid rendering counter-examples of toString methods using the method itself)
-  * @return a user defined string for the given typed expression. */
+  */
 class SelfPrettyPrinter {
   implicit val section = leon.utils.DebugSectionEvaluation
   private var allowedFunctions = Set[FunDef]()
@@ -49,16 +50,18 @@ class SelfPrettyPrinter {
   /** Returns a list of possible lambdas that can transform the input type to a String.
     * At this point, it does not consider yet the inputType. Only [[prettyPrinterFromCandidate]] will consider it. */
   def prettyPrintersForType(inputType: TypeTree/*, existingPp: Map[TypeTree, List[Lambda]] = Map()*/)(implicit ctx: LeonContext, program: Program): Stream[Lambda] = {
-    program.definedFunctions.toStream flatMap {
-      fd =>
-        val isCandidate = fd.returnType == StringType &&
-        fd.params.length >= 1 &&
+    program.definedFunctions.toStream flatMap { fd =>
+      val isCandidate =
+        fd.returnType == StringType &&
+        fd.params.nonEmpty &&
         !excluded(fd) &&
-        (allowedFunctions(fd) || (
-        fd.id.name.toLowerCase().endsWith("tostring")))
-        if(isCandidate) {
-          prettyPrinterFromCandidate(fd, inputType)
-        } else Stream.Empty
+        (allowedFunctions(fd) || fd.id.name.toLowerCase().endsWith("tostring"))
+
+      if(isCandidate) {
+        prettyPrinterFromCandidate(fd, inputType)
+      } else {
+        Stream.Empty
+      }
     }
   }
   
@@ -88,19 +91,24 @@ class SelfPrettyPrinter {
       case None => Stream.empty
     }
   }
-  
-  
-  /** Actually prints the expression with as alternative the given orElse */
+
+
+  /** Actually prints the expression with as alternative the given orElse
+    * @param excluded The list of functions which should be excluded from pretty-printing
+    *                 (to avoid rendering counter-examples of toString methods using the method itself)
+    * @return a user defined string for the given typed expression.
+    **/
   def print(v: Expr, orElse: =>String, excluded: Set[FunDef] = Set())(implicit ctx: LeonContext, program: Program): String = {
     this.excluded = excluded
     val s = prettyPrintersForType(v.getType)   // TODO: Included the variable excluded if necessary.
-    s.take(100).find(l => l match { // Limit the number of pretty-printers.
+    s.take(100).find {
+      // Limit the number of pretty-printers.
       case Lambda(_, FunctionInvocation(TypedFunDef(fd, _), _)) =>
-        (program.callGraph.transitiveCallees(fd) + fd).forall { fde => 
-        !ExprOps.exists( _.isInstanceOf[Choose])(fde.fullBody)
-      }
+        (program.callGraph.transitiveCallees(fd) + fd).forall { fde =>
+          !ExprOps.exists(_.isInstanceOf[Choose])(fde.fullBody)
+        }
       case _ => false
-    }) match {
+    } match {
       case None => orElse
       case Some(l) =>
         ctx.reporter.debug("Executing pretty printer for type " + v.getType + " : " + l + " on " + v)
diff --git a/src/main/scala/leon/purescala/SimplifierWithPaths.scala b/src/main/scala/leon/purescala/SimplifierWithPaths.scala
index dc4dfce46aba691026123801b24285a216637ac5..a53b3b17698ccacd435978b8b36da139491cef17 100644
--- a/src/main/scala/leon/purescala/SimplifierWithPaths.scala
+++ b/src/main/scala/leon/purescala/SimplifierWithPaths.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/SubTreeOps.scala b/src/main/scala/leon/purescala/SubTreeOps.scala
index 140bd5edc2ff5f316a7afb0d90442df12b78ced8..39ed1a45509648ed5bdc26b92f5006d815f8f941 100644
--- a/src/main/scala/leon/purescala/SubTreeOps.scala
+++ b/src/main/scala/leon/purescala/SubTreeOps.scala
@@ -3,8 +3,6 @@
 package leon
 package purescala
 
-import Expressions.Expr
-import Types.TypeTree
 import Common._
 import utils._
 
@@ -278,6 +276,19 @@ trait SubTreeOps[SubTree <: Tree]  {
     rec(e, c)
   }
 
+  def preFoldWithContext[C](f: (SubTree, C) => C, combiner: (SubTree, C, Seq[C]) => C)
+                           (e: SubTree, c: C): C = {
+
+    def rec(eIn: SubTree, cIn: C): C = {
+      val ctx = f(eIn, cIn)
+      val Deconstructor(es, _) = eIn
+      val cs = es.map{ rec(_, ctx) }
+      combiner(eIn, ctx, cs)
+    }
+
+    rec(e, c)
+  }
+
   /*
    * =============
    * Auxiliary API
@@ -324,4 +335,4 @@ trait SubTreeOps[SubTree <: Tree]  {
     res
   }
 
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/leon/purescala/Transformer.scala b/src/main/scala/leon/purescala/Transformer.scala
index bddbe0325ea1f48564d095dee91dd9ed6dcdae5b..c44d56a6768a3fafa346ff1f2b0afe685703eca0 100644
--- a/src/main/scala/leon/purescala/Transformer.scala
+++ b/src/main/scala/leon/purescala/Transformer.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/TransformerWithPC.scala b/src/main/scala/leon/purescala/TransformerWithPC.scala
index 3fc618d67c925ec9367c7274d0b9e0671788682e..9411bf68d091136fddc5b0cb78a66e8e7ef2e8ad 100644
--- a/src/main/scala/leon/purescala/TransformerWithPC.scala
+++ b/src/main/scala/leon/purescala/TransformerWithPC.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/TreeNormalizations.scala b/src/main/scala/leon/purescala/TreeNormalizations.scala
index d3dff445cc0b5151a75776b583b2d864a77952db..4f5f5ffa9df53681ebccbc230262004cc39596e1 100644
--- a/src/main/scala/leon/purescala/TreeNormalizations.scala
+++ b/src/main/scala/leon/purescala/TreeNormalizations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/TypeOps.scala b/src/main/scala/leon/purescala/TypeOps.scala
index fedac58ec483953a58c6cb9576ba0340da30b720..99da89dbc20e7def4e5dcb7a2cc1cfc97fb21577 100644
--- a/src/main/scala/leon/purescala/TypeOps.scala
+++ b/src/main/scala/leon/purescala/TypeOps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
@@ -9,24 +9,20 @@ import Common._
 import Expressions._
 import Extractors._
 import Constructors._
-import ExprOps.preMap
 
 object TypeOps extends { val Deconstructor = NAryType } with SubTreeOps[TypeTree] {
   def typeDepth(t: TypeTree): Int = t match {
     case NAryType(tps, builder) => 1 + (0 +: (tps map typeDepth)).max
   }
 
-  def typeParamsOf(t: TypeTree): Set[TypeParameter] = {
-    collect[TypeParameter]({
-      case tp: TypeParameter => Set(tp)
-      case _ => Set.empty
-    })(t)
+  def typeParamsOf(expr: Expr): Set[TypeParameter] = {
+    ExprOps.collect(e => typeParamsOf(e.getType))(expr)
   }
 
-  def typeParamsOf(expr: Expr): Set[TypeParameter] = {
-    var tparams: Set[TypeParameter] = Set.empty
-    ExprOps.preTraversal(e => typeParamsOf(e.getType))(expr)
-    tparams
+  def typeParamsOf(t: TypeTree): Set[TypeParameter] = t match {
+    case tp: TypeParameter => Set(tp)
+    case NAryType(subs, _) =>
+      subs.flatMap(typeParamsOf).toSet
   }
 
   def canBeSubtypeOf(
@@ -345,7 +341,7 @@ object TypeOps extends { val Deconstructor = NAryType } with SubTreeOps[TypeTree
             Let(newId, srec(value), rec(idsMap + (id -> newId))(body)).copiedFrom(l)
 
           case l @ LetDef(fds, bd) =>
-            val fds_mapping = for(fd <- fds) yield {
+            val fdsMapping = for(fd <- fds) yield {
               val id = fd.id.freshen
               val tparams = fd.tparams map { p => 
                 TypeParameterDef(tpeSub(p.tp).asInstanceOf[TypeParameter])
@@ -362,13 +358,10 @@ object TypeOps extends { val Deconstructor = NAryType } with SubTreeOps[TypeTree
               (fd, newFd, subCalls)
             }
             // We group the subcalls functions all in once
-            val subCalls = (((None:Option[Expr => Expr]) /: fds_mapping) {
-              case (None, (_, _, subCalls)) => Some(subCalls)
-              case (Some(fn), (_, _, subCalls)) => Some(fn andThen subCalls)
-            }).get
+            val subCalls = fdsMapping.map(_._3).reduceLeft { _ andThen _ }
             
             // We apply all the functions mappings at once
-            val newFds = for((fd, newFd, _) <- fds_mapping) yield {
+            val newFds = for((fd, newFd, _) <- fdsMapping) yield {
               val fullBody = rec(idsMap ++ fd.paramIds.zip(newFd.paramIds))(subCalls(fd.fullBody))
               newFd.fullBody = fullBody
               newFd
@@ -436,16 +429,7 @@ object TypeOps extends { val Deconstructor = NAryType } with SubTreeOps[TypeTree
         }
       }
 
-      //println("\\\\"*80)
-      //println(tps)
-      //println(ids.map{ case (k,v) => k.uniqueName+" -> "+v.uniqueName })
-      //println("\\\\"*80)
-      //println(e)
-      val res = rec(ids)(e)
-      //println(".."*80)
-      //println(res)
-      //println("//"*80)
-      res
+      rec(ids)(e)
     }
   }
 }
diff --git a/src/main/scala/leon/purescala/Types.scala b/src/main/scala/leon/purescala/Types.scala
index 6f2518d549be6b1d439ff9cb08594558d02449d5..0ee936c813b942d3e55564506a200b31630f0283 100644
--- a/src/main/scala/leon/purescala/Types.scala
+++ b/src/main/scala/leon/purescala/Types.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package purescala
diff --git a/src/main/scala/leon/purescala/package.scala b/src/main/scala/leon/purescala/package.scala
index 03ab3061f760f0c54fef270c631db2d280cfdebd..669bc61a1b0ede48975ac1f4c5d4ea6590e57bea 100644
--- a/src/main/scala/leon/purescala/package.scala
+++ b/src/main/scala/leon/purescala/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/src/main/scala/leon/repair/RepairCostModel.scala b/src/main/scala/leon/repair/RepairCostModel.scala
deleted file mode 100644
index e098157c04466c4d098f69e9708561712f061ffa..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/repair/RepairCostModel.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package repair
-
-import synthesis._
-import synthesis.rules._
-import repair.rules._
-
-case class RepairCostModel(cm: CostModel) extends WrappedCostModel(cm, "Repair("+cm.name+")") {
-  import graph._
-
-  override def andNode(an: AndNode, subs: Option[Seq[Cost]]) = {
-    val h = cm.andNode(an, subs).minSize
-
-    Cost(an.ri.rule match {
-      case Focus        => -10
-      case CEGLESS      => 0
-      case TEGLESS      => 1
-      case _            => h+1
-    })
-  }
-}
diff --git a/src/main/scala/leon/repair/RepairNDEvaluator.scala b/src/main/scala/leon/repair/RepairNDEvaluator.scala
index 56e8467478f5f0135945b9a72da0e525e4ac2c70..7859f7957d59eaefd9f1dfcfd03cbded09f724b9 100644
--- a/src/main/scala/leon/repair/RepairNDEvaluator.scala
+++ b/src/main/scala/leon/repair/RepairNDEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package repair
diff --git a/src/main/scala/leon/repair/RepairPhase.scala b/src/main/scala/leon/repair/RepairPhase.scala
index 342d41dddb28acf9312e5b5b5388ec2023318529..aff7747ad53eaa54ccc2d7864da154c4793985b2 100644
--- a/src/main/scala/leon/repair/RepairPhase.scala
+++ b/src/main/scala/leon/repair/RepairPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package repair
@@ -13,8 +13,8 @@ object RepairPhase extends UnitPhase[Program]() {
   implicit val debugSection = utils.DebugSectionRepair
 
   def apply(ctx: LeonContext, program: Program) = {
-    val repairFuns: Option[Seq[String]] = ctx.findOption(SharedOptions.optFunctions)
-    val verifTimeoutMs: Option[Long] = ctx.findOption(SharedOptions.optTimeout) map { _ * 1000 }
+    val repairFuns: Option[Seq[String]] = ctx.findOption(GlobalOptions.optFunctions)
+    val verifTimeoutMs: Option[Long] = ctx.findOption(GlobalOptions.optTimeout) map { _ * 1000 }
 
     val reporter = ctx.reporter
 
diff --git a/src/main/scala/leon/repair/RepairTrackingEvaluator.scala b/src/main/scala/leon/repair/RepairTrackingEvaluator.scala
index 429b34c19bbc20667bac9a6723c9c51740a57293..67707d6cfd7136c2145ff29c33cebde200cf18e7 100644
--- a/src/main/scala/leon/repair/RepairTrackingEvaluator.scala
+++ b/src/main/scala/leon/repair/RepairTrackingEvaluator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.repair
 
diff --git a/src/main/scala/leon/repair/Repairman.scala b/src/main/scala/leon/repair/Repairman.scala
index 9dcd782a3323138e5bfe4c68822fba614e2065e7..d941f1c0edc81b9501eb557e87405e6b7add14fd 100644
--- a/src/main/scala/leon/repair/Repairman.scala
+++ b/src/main/scala/leon/repair/Repairman.scala
@@ -1,18 +1,15 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package repair
 
 import leon.datagen.GrammarDataGen
-import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
 import purescala.Extractors._
 import purescala.ExprOps._
-import purescala.Types._
 import purescala.DefOps._
 import purescala.Constructors._
-import purescala.Extractors.unwrapTuple
 
 import evaluators._
 import solvers._
@@ -32,7 +29,7 @@ class Repairman(ctx0: LeonContext, initProgram: Program, fd: FunDef, verifTimeou
 
   val reporter = ctx.reporter
 
-  val doBenchmark = ctx.findOptionOrDefault(SharedOptions.optBenchmark)
+  val doBenchmark = ctx.findOptionOrDefault(GlobalOptions.optBenchmark)
 
   var program = initProgram
 
@@ -101,7 +98,6 @@ class Repairman(ctx0: LeonContext, initProgram: Program, fd: FunDef, verifTimeou
           }
 
           reporter.ifDebug { printer =>
-            import java.io.FileWriter
             import java.text.SimpleDateFormat
             import java.util.Date
 
@@ -112,15 +108,15 @@ class Repairman(ctx0: LeonContext, initProgram: Program, fd: FunDef, verifTimeou
               case fd: FunDef => 1 + fd.params.size + formulaSize(fd.fullBody)
             }
 
-            val pSize = defs.sum;
+            val pSize = defs.sum
             val fSize = formulaSize(fd.body.get)
 
             def localizedExprs(n: graph.Node): List[Expr] = {
               n match {
                 case on: graph.OrNode =>
-                  on.selected.map(localizedExprs).flatten
+                  on.selected.flatMap(localizedExprs)
                 case an: graph.AndNode if an.ri.rule == Focus =>
-                  an.selected.map(localizedExprs).flatten
+                  an.selected.flatMap(localizedExprs)
                 case an: graph.AndNode =>
                   val TopLevelAnds(clauses) = an.p.ws
 
@@ -132,11 +128,11 @@ class Repairman(ctx0: LeonContext, initProgram: Program, fd: FunDef, verifTimeou
               }
             }
 
-            val locSize = localizedExprs(search.g.root).map(formulaSize).sum;
+            val locSize = localizedExprs(search.g.root).map(formulaSize).sum
 
             val (solSize, proof) = solutions.headOption match {
               case Some((sol, trusted)) =>
-                val solExpr = sol.toSimplifiedExpr(ctx, program)
+                val solExpr = sol.toSimplifiedExpr(ctx, program, fd)
                 val totalSolSize = formulaSize(solExpr)
                 (locSize+totalSolSize-fSize, if (trusted) "$\\chmark$" else "")
               case _ =>
@@ -166,7 +162,7 @@ class Repairman(ctx0: LeonContext, initProgram: Program, fd: FunDef, verifTimeou
             reporter.info(ASCIIHelpers.title("Repair successful:"))
             for ( ((sol, isTrusted), i) <- solutions.zipWithIndex) {
               reporter.info(ASCIIHelpers.subTitle("Solution "+(i+1)+ (if(isTrusted) "" else " (untrusted)" ) + ":"))
-              val expr = sol.toSimplifiedExpr(ctx, synth.program)
+              val expr = sol.toSimplifiedExpr(ctx, synth.program, fd)
               reporter.info(expr.asString(program)(ctx))
             }
           }
@@ -183,29 +179,20 @@ class Repairman(ctx0: LeonContext, initProgram: Program, fd: FunDef, verifTimeou
 
     val origBody = fd.body.get
 
-    val term  = Terminating(fd.typed, fd.params.map(_.id.toVariable))
+    val term  = Terminating(fd.applied)
     val guide = Guide(origBody)
     val pre   = fd.precOrTrue
 
-    val ci = SourceInfo(
-      fd = fd,
-      pc = andJoin(Seq(pre, guide, term)),
-      source = origBody,
-      spec = fd.postOrTrue,
-      eb = eb
-    )
+    val prob = Problem.fromSpec(fd.postOrTrue, andJoin(Seq(pre, guide, term)), eb, Some(fd))
+
+    val ci = SourceInfo(fd, origBody, prob)
 
     // Return synthesizer for this choose
     val so0 = SynthesisPhase.processOptions(ctx)
 
     val soptions = so0.copy(
       functionsToIgnore = so0.functionsToIgnore + fd,
-      costModel = RepairCostModel(so0.costModel),
-      rules = (so0.rules ++ Seq(
-        Focus,
-        CEGLESS
-        //TEGLESS
-      )) diff Seq(ADTInduction, TEGIS, IntegerInequalities, IntegerEquation)
+      rules = Seq(Focus, CEGLESS) ++ so0.rules
     )
 
     new Synthesizer(ctx, program, ci, soptions)
diff --git a/src/main/scala/leon/repair/rules/Focus.scala b/src/main/scala/leon/repair/rules/Focus.scala
index 93520c5ea9cd467cf73a94392a565022782eb3d9..7ce3fd261cbd4b9f28fae11517bb7640895f5517 100644
--- a/src/main/scala/leon/repair/rules/Focus.scala
+++ b/src/main/scala/leon/repair/rules/Focus.scala
@@ -1,10 +1,9 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package repair
 package rules
 
-import sun.nio.cs.StreamEncoder
 import synthesis._
 import leon.evaluators._
 
@@ -31,11 +30,10 @@ case object Focus extends PreprocessingRule("Focus") {
         
     }
 
-    val fd      = hctx.ci.fd
-    val ctx     = hctx.sctx.context
-    val program = hctx.sctx.program
+    val fd      = hctx.functionContext
+    val program = hctx.program
 
-    val evaluator = new DefaultEvaluator(ctx, program)
+    val evaluator = new DefaultEvaluator(hctx, program)
 
     // Check how an expression behaves on tests
     //  - returns Some(true) if for all tests e evaluates to true
@@ -97,7 +95,7 @@ case object Focus extends PreprocessingRule("Focus") {
         case c if c eq cond => Some(not(cond))
         case _ => None
       }(fdSpec)
-      forAllTests(ndSpec, Map(), new AngelicEvaluator(new RepairNDEvaluator(ctx, program, cond)))
+      forAllTests(ndSpec, Map(), new AngelicEvaluator(new RepairNDEvaluator(hctx, program, cond)))
     }
 
     guides.flatMap {
@@ -166,7 +164,7 @@ case object Focus extends PreprocessingRule("Focus") {
             val eb3 = if (vars.nonEmpty) {
               eb2.mapIns(ebF)
             } else {
-              eb2
+              eb2.eb
             }
 
             val newPc = andJoin(cond +: vars.map { id => equality(id.toVariable, map(id)) })
diff --git a/src/main/scala/leon/solvers/ADTManager.scala b/src/main/scala/leon/solvers/ADTManager.scala
index e811feaa1dda6886fa9c9ad927c6f552efb7b7a1..b52be838a0c00417d76be9274a20e8588a8221be 100644
--- a/src/main/scala/leon/solvers/ADTManager.scala
+++ b/src/main/scala/leon/solvers/ADTManager.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
@@ -6,12 +6,12 @@ package solvers
 import purescala.Types._
 import purescala.Common._
 
-case class DataType(sym: Identifier, cases: Seq[Constructor]) {
+case class DataType(sym: Identifier, cases: Seq[Constructor]) extends Printable {
   def asString(implicit ctx: LeonContext) = {
     "Datatype: "+sym.asString+"\n"+cases.map(c => " - "+c.asString(ctx)).mkString("\n")
   }
 }
-case class Constructor(sym: Identifier, tpe: TypeTree, fields: Seq[(Identifier, TypeTree)]) {
+case class Constructor(sym: Identifier, tpe: TypeTree, fields: Seq[(Identifier, TypeTree)]) extends Printable {
   def asString(implicit ctx: LeonContext) = {
     sym.asString(ctx)+" ["+tpe.asString(ctx)+"] "+fields.map(f => f._1.asString(ctx)+": "+f._2.asString(ctx)).mkString("(", ", ", ")")
   }
diff --git a/src/main/scala/leon/solvers/CantResetException.scala b/src/main/scala/leon/solvers/CantResetException.scala
index 51646c8fe1ed92a171269a02fc299f03e715c9e1..d92b3617de8e7da06d8b74948807065f1cc4c7fc 100644
--- a/src/main/scala/leon/solvers/CantResetException.scala
+++ b/src/main/scala/leon/solvers/CantResetException.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers
 
 class CantResetException(s: Solver) extends Exception(s"Unable to reset solver $s")
diff --git a/src/main/scala/leon/solvers/EnumerationSolver.scala b/src/main/scala/leon/solvers/EnumerationSolver.scala
index a9bbe8b45823cde5776d67155642c6f819d3a76b..79f53ef9134a07198b8ef2c87f3deff0571e26ad 100644
--- a/src/main/scala/leon/solvers/EnumerationSolver.scala
+++ b/src/main/scala/leon/solvers/EnumerationSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/EvaluatingSolver.scala b/src/main/scala/leon/solvers/EvaluatingSolver.scala
index 75dcb5631dd0d57e7bbef24b9ce6d5d461d902c5..835d352ed7fe544b2f22c109bf3b3c6ca47d6315 100644
--- a/src/main/scala/leon/solvers/EvaluatingSolver.scala
+++ b/src/main/scala/leon/solvers/EvaluatingSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package solvers
 
diff --git a/src/main/scala/leon/solvers/GroundSolver.scala b/src/main/scala/leon/solvers/GroundSolver.scala
index f38ddd188f15f40058606e9d018f4b2b5b6f186b..130f8d86b32218bc7af5fc677dc43997c7cd5aac 100644
--- a/src/main/scala/leon/solvers/GroundSolver.scala
+++ b/src/main/scala/leon/solvers/GroundSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/Model.scala b/src/main/scala/leon/solvers/Model.scala
index 57f93655f5311655ffd1d479762dac839e750517..78b5b0501933305b91016fa193eb7d5c10203510 100644
--- a/src/main/scala/leon/solvers/Model.scala
+++ b/src/main/scala/leon/solvers/Model.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
@@ -9,7 +9,8 @@ import purescala.Quantification.Domains
 import purescala.ExprOps._
 
 trait AbstractModel[+This <: Model with AbstractModel[This]]
-  extends scala.collection.IterableLike[(Identifier, Expr), This] {
+  extends scala.collection.IterableLike[(Identifier, Expr), This]
+  with Printable {
 
   protected val mapping: Map[Identifier, Expr]
 
diff --git a/src/main/scala/leon/solvers/NaiveAssumptionSolver.scala b/src/main/scala/leon/solvers/NaiveAssumptionSolver.scala
index da1dfa7666a85799607773b967d77489b72b819c..a0dd48a7c80e3b04cd6336f27b60f9f0b0b78296 100644
--- a/src/main/scala/leon/solvers/NaiveAssumptionSolver.scala
+++ b/src/main/scala/leon/solvers/NaiveAssumptionSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/RawArray.scala b/src/main/scala/leon/solvers/RawArray.scala
index a527a98fa74bee1d04b093d16d4c05f32128ef0f..60212d0e6db2ce7282550808bcf5165c4eeec250 100644
--- a/src/main/scala/leon/solvers/RawArray.scala
+++ b/src/main/scala/leon/solvers/RawArray.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/SimpleSolverAPI.scala b/src/main/scala/leon/solvers/SimpleSolverAPI.scala
index 33f6f133644f55d24efddea8e4ce010516b0cba9..8f7c4b404cd9cec770800ad93d708cd844b1d71a 100644
--- a/src/main/scala/leon/solvers/SimpleSolverAPI.scala
+++ b/src/main/scala/leon/solvers/SimpleSolverAPI.scala
@@ -1,9 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
 
-import purescala.Common._
 import purescala.Expressions._
 
 class SimpleSolverAPI(sf: SolverFactory[Solver]) {
@@ -34,17 +33,17 @@ class SimpleSolverAPI(sf: SolverFactory[Solver]) {
     }
   }
 
-  def solveSATWithCores(expression: Expr, assumptions: Set[Expr]): (Option[Boolean], Model, Set[Expr]) = {
+  def solveSATWithCores(expression: Expr, assumptions: Set[Expr]): Option[Either[Set[Expr], Model]] = {
     val s = sf.getNewSolver()
     try {
       s.assertCnstr(expression)
       s.checkAssumptions(assumptions) match {
-        case Some(true) =>
-          (Some(true), s.getModel, Set())
         case Some(false) =>
-          (Some(false), Model.empty, s.getUnsatCore)
+          Some(Left(s.getUnsatCore))
+        case Some(true) =>
+          Some(Right(s.getModel))
         case None =>
-          (None, Model.empty, Set())
+          None
       }
     } finally {
       sf.reclaim(s)
diff --git a/src/main/scala/leon/solvers/Solver.scala b/src/main/scala/leon/solvers/Solver.scala
index c8e4bd9b95c0b25f5fbf0c869062ac89dbcc7728..e1c9525ae3e20b24f6ee474634b07dc91647fcf3 100644
--- a/src/main/scala/leon/solvers/Solver.scala
+++ b/src/main/scala/leon/solvers/Solver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/SolverFactory.scala b/src/main/scala/leon/solvers/SolverFactory.scala
index 4f8b1f50ae346887c945823ff429761be1a34a78..8656515790b90c7d828a267b025ed40f87f8e094 100644
--- a/src/main/scala/leon/solvers/SolverFactory.scala
+++ b/src/main/scala/leon/solvers/SolverFactory.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
@@ -49,7 +49,7 @@ object SolverFactory {
     }.mkString("")
 
   def getFromSettings(implicit ctx: LeonContext, program: Program): SolverFactory[TimeoutSolver] = {
-    val names = ctx.findOptionOrDefault(SharedOptions.optSelectedSolvers)
+    val names = ctx.findOptionOrDefault(GlobalOptions.optSelectedSolvers)
 
     if (((names contains "fairz3") || (names contains "unrollz3")) && !hasNativeZ3) {
       if (hasZ3) {
@@ -138,7 +138,7 @@ object SolverFactory {
 
   // Fast solver used by simplifications, to discharge simple tautologies
   def uninterpreted(ctx: LeonContext, program: Program): SolverFactory[TimeoutSolver] = {
-    val names = ctx.findOptionOrDefault(SharedOptions.optSelectedSolvers)
+    val names = ctx.findOptionOrDefault(GlobalOptions.optSelectedSolvers)
     
     if ((names contains "fairz3") && !hasNativeZ3) {
       if (hasZ3) {
diff --git a/src/main/scala/leon/solvers/SolverUnsupportedError.scala b/src/main/scala/leon/solvers/SolverUnsupportedError.scala
index 2efc8ea39b0da8494b2cd1309b3dcf9c2ca9cec3..8d42223c814ae6b91020328a7a4f07661c4fa19a 100644
--- a/src/main/scala/leon/solvers/SolverUnsupportedError.scala
+++ b/src/main/scala/leon/solvers/SolverUnsupportedError.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/TimeoutSolver.scala b/src/main/scala/leon/solvers/TimeoutSolver.scala
index 723b48886dd903f5ac17eb0cad5212a260864659..90ce09b793caf0678424eb4783407d27e2949632 100644
--- a/src/main/scala/leon/solvers/TimeoutSolver.scala
+++ b/src/main/scala/leon/solvers/TimeoutSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/TimeoutSolverFactory.scala b/src/main/scala/leon/solvers/TimeoutSolverFactory.scala
index b5a042147d256bd60be6f947fd62c93aaf1e0974..f3f8ca200f0d8abba7e867a39ebca39d98be2318 100644
--- a/src/main/scala/leon/solvers/TimeoutSolverFactory.scala
+++ b/src/main/scala/leon/solvers/TimeoutSolverFactory.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala b/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala
index 4bfc179a10bcdb48a697ccd6b8d33ea85161e725..f374344e56bbbd388f9d9d8c8ef82065860780d1 100644
--- a/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala
+++ b/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/combinators/PortfolioSolverFactory.scala b/src/main/scala/leon/solvers/combinators/PortfolioSolverFactory.scala
index 7c29a16d0e8965fe0720c0714b3fb2a32598c430..f6a70043182fc237298c30d3b6ffa5c943233bea 100644
--- a/src/main/scala/leon/solvers/combinators/PortfolioSolverFactory.scala
+++ b/src/main/scala/leon/solvers/combinators/PortfolioSolverFactory.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/combinators/RewritingSolver.scala b/src/main/scala/leon/solvers/combinators/RewritingSolver.scala
index 0419d7d6e4b2c4064e83d8a03e2a3430d2f70929..ff0c8bf6f9fce09b748765de544873800cb67a63 100644
--- a/src/main/scala/leon/solvers/combinators/RewritingSolver.scala
+++ b/src/main/scala/leon/solvers/combinators/RewritingSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/combinators/SolverPool.scala b/src/main/scala/leon/solvers/combinators/SolverPool.scala
index 296e6b7131830535401aeaa6618c64e3acf4f6b4..2d38591f69b3bcb3417ab59f335edc5e20543bd0 100644
--- a/src/main/scala/leon/solvers/combinators/SolverPool.scala
+++ b/src/main/scala/leon/solvers/combinators/SolverPool.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala
index 95a8cdd67722660f666a9256a0020fab9d93b5d2..6594eb07e239876a5e046ebb3a99606f91225a93 100644
--- a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala
+++ b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala
@@ -1,10 +1,9 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
 package combinators
 
-import purescala.Printable
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Quantification._
@@ -664,7 +663,7 @@ class UnrollingSolver(val context: LeonContext, val program: Program, underlying
   override def foundAnswer(res: Option[Boolean], model: Model = Model.empty, core: Set[Expr] = Set.empty) = {
     super.foundAnswer(res, model, core)
 
-    if (!interrupted && res == None && model == None) {
+    if (!interrupted && res.isEmpty && model.isEmpty) {
       reporter.ifDebug { debug =>
         debug("Unknown result!?")
       }
diff --git a/src/main/scala/leon/solvers/isabelle/AdaptationPhase.scala b/src/main/scala/leon/solvers/isabelle/AdaptationPhase.scala
index 2d3218c7b09edfa465618117a66b7f428f755b1c..d0b342b816a2e2b4ddb41073a8586f03d6de15d9 100644
--- a/src/main/scala/leon/solvers/isabelle/AdaptationPhase.scala
+++ b/src/main/scala/leon/solvers/isabelle/AdaptationPhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import leon._
@@ -32,7 +34,7 @@ object AdaptationPhase extends TransformationPhase {
       CaseClass(CaseClassType(dummy, List(tree)), Nil)
 
     val enabled =
-      context.findOptionOrDefault(SharedOptions.optSelectedSolvers).contains("isabelle") ||
+      context.findOptionOrDefault(GlobalOptions.optSelectedSolvers).contains("isabelle") ||
       context.findOptionOrDefault(Main.MainComponent.optIsabelle)
 
     if (!enabled) program
diff --git a/src/main/scala/leon/solvers/isabelle/Component.scala b/src/main/scala/leon/solvers/isabelle/Component.scala
index 4f66f3a6da61dbfbe6be5e9c335dcb9633981bcd..55e2eef1ed068a63d9e5ccab66dbf0ca57dfeb49 100644
--- a/src/main/scala/leon/solvers/isabelle/Component.scala
+++ b/src/main/scala/leon/solvers/isabelle/Component.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import java.nio.file.Paths
diff --git a/src/main/scala/leon/solvers/isabelle/Functions.scala b/src/main/scala/leon/solvers/isabelle/Functions.scala
index bad4b96acc157392278ae80787f0b537b4b13f77..9e221e988f7e0671ccbe9ac21a8b0c2acf8c24e2 100644
--- a/src/main/scala/leon/solvers/isabelle/Functions.scala
+++ b/src/main/scala/leon/solvers/isabelle/Functions.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import scala.concurrent._
diff --git a/src/main/scala/leon/solvers/isabelle/IsabelleEnvironment.scala b/src/main/scala/leon/solvers/isabelle/IsabelleEnvironment.scala
index 5856374e289d5f39c9669ec93ba6bef0e91e2693..944a2e2490db8e3745228a0f5ac0864592c427ff 100644
--- a/src/main/scala/leon/solvers/isabelle/IsabelleEnvironment.scala
+++ b/src/main/scala/leon/solvers/isabelle/IsabelleEnvironment.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import java.io.FileWriter
@@ -9,7 +11,7 @@ import scala.concurrent.ExecutionContext.Implicits.global
 
 import leon.LeonContext
 import leon.OptionsHelpers._
-import leon.SharedOptions
+import leon.GlobalOptions
 import leon.purescala.Definitions._
 import leon.purescala.Expressions._
 import leon.purescala.Common._
@@ -34,7 +36,7 @@ object IsabelleEnvironment {
 
     val funFilter =
       // FIXME duplicated from AnalysisPhase
-      filterInclusive[FunDef](context.findOption(SharedOptions.optFunctions).map(fdMatcher(program)), Some(_.annotations contains "library"))
+      filterInclusive[FunDef](context.findOption(GlobalOptions.optFunctions).map(fdMatcher(program)), Some(_.annotations contains "library"))
 
     val funs = program.definedFunctions.filter(funFilter)
 
diff --git a/src/main/scala/leon/solvers/isabelle/IsabellePhase.scala b/src/main/scala/leon/solvers/isabelle/IsabellePhase.scala
index 47edf6b7f0219bc5042011dcd5afa6d559dad07e..3cfe02990a70c14abf3a0df83536b21e6c18cd22 100644
--- a/src/main/scala/leon/solvers/isabelle/IsabellePhase.scala
+++ b/src/main/scala/leon/solvers/isabelle/IsabellePhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import scala.concurrent._
diff --git a/src/main/scala/leon/solvers/isabelle/IsabelleSolver.scala b/src/main/scala/leon/solvers/isabelle/IsabelleSolver.scala
index 3b3e81860e38a1da24d0ce41f2d53a73a449732d..9bf81247d5a6648c1cdb10eae23b1d8d30791f3b 100644
--- a/src/main/scala/leon/solvers/isabelle/IsabelleSolver.scala
+++ b/src/main/scala/leon/solvers/isabelle/IsabelleSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import scala.concurrent._
diff --git a/src/main/scala/leon/solvers/isabelle/IsabelleSolverFactory.scala b/src/main/scala/leon/solvers/isabelle/IsabelleSolverFactory.scala
index 190224cb661991095bd4eb791b79cafbdd426066..0e356aa5559c4d00326971401f3e9c7e79546327 100644
--- a/src/main/scala/leon/solvers/isabelle/IsabelleSolverFactory.scala
+++ b/src/main/scala/leon/solvers/isabelle/IsabelleSolverFactory.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import scala.concurrent._
diff --git a/src/main/scala/leon/solvers/isabelle/Translator.scala b/src/main/scala/leon/solvers/isabelle/Translator.scala
index c0c9446f169e74aba27d19876e23d66915fbfd75..79c4cfea7c520383a3aaa1f05b824f9535bca504 100644
--- a/src/main/scala/leon/solvers/isabelle/Translator.scala
+++ b/src/main/scala/leon/solvers/isabelle/Translator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import scala.concurrent._
diff --git a/src/main/scala/leon/solvers/isabelle/Types.scala b/src/main/scala/leon/solvers/isabelle/Types.scala
index 7d2b4d1d8d54667343ae8e6d6a458130c5baef13..268a1b7885d10867e6284042716b1abdbe95175a 100644
--- a/src/main/scala/leon/solvers/isabelle/Types.scala
+++ b/src/main/scala/leon/solvers/isabelle/Types.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.isabelle
 
 import scala.concurrent._
diff --git a/src/main/scala/leon/solvers/isabelle/package.scala b/src/main/scala/leon/solvers/isabelle/package.scala
index 26f01fb5caa1afaae1a14d7d910ae9ff6045eef2..49046965365633b0632534d1be2661b1c7fac9c6 100644
--- a/src/main/scala/leon/solvers/isabelle/package.scala
+++ b/src/main/scala/leon/solvers/isabelle/package.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package solvers.isabelle
 
diff --git a/src/main/scala/leon/solvers/package.scala b/src/main/scala/leon/solvers/package.scala
index e08e536da7f534383fa674ac04107b46d086b94c..34215c07e63f02f33310fa007d2a0b5cc8427667 100644
--- a/src/main/scala/leon/solvers/package.scala
+++ b/src/main/scala/leon/solvers/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4CounterExampleSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4CounterExampleSolver.scala
index 3a64bd19737e9f7c7f15c78c0044a71f49721df8..973546c6891e3a321c05a4777e873bdb2dff35fd 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4CounterExampleSolver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4CounterExampleSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.smtlib
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala
index eaf78aca5e78cb49fe1ccf3bb7d07556514c61d0..8c16d013fb34e653f99abd207fff7fcbc3f2e202 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.smtlib
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala
index 16068794f5d0af0c63e87ffea54a9caed6729be6..39d83d7c7354fab56ad7fd73ac72e8dc3e137384 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.smtlib
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedTarget.scala
index 737b8535cdb684123163576400d8858adf4fd944..b67140f4b8db84784395f892d19c3694ffee787d 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedTarget.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala
index b71af967f9671fd13f7c6a4625e592649fb470ba..4c17f80892dfad288c0522e3c918a31eb4cef9ae 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.smtlib
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
index 03cf3aef32fc59c33283c70cebfa2f918e549e76..d9deb8790f129b7d81a103ef9e25853ae332694e 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedSolver.scala
index f98b4f7e45fa71e4456da8ae9934d221feddbbe1..d4819cfbae997d729e064926b98cc879f0effeb0 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedSolver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedTarget.scala
index d52ac0704e65d119bf3f81c4a30d58723f9aea81..980d87fa8ae2b443ae1c954594297e753449114b 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBQuantifiedTarget.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala
index 72ecfb9d34039ad03675d2d5523c34462f9de20e..78b9ccbd90f00260ab04c8d0a55da2ed00c24f5f 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
index 4b838694956205c17432abc229012eb19f98b143..242f321219eebb34c93c4756dd10a4ba92d114df 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
@@ -31,7 +31,7 @@ import _root_.smtlib.parser.Terms.{
   _
 }
 import _root_.smtlib.parser.CommandsResponses.{ Error => ErrorResponse, _ }
-import _root_.smtlib.theories._
+import _root_.smtlib.theories.{Constructors => SmtLibConstructors, _}
 import _root_.smtlib.theories.experimental._
 import _root_.smtlib.interpreters.ProcessInterpreter
 
@@ -415,7 +415,7 @@ trait SMTLIBTarget extends Interruptible {
           case more =>
             val es = freshSym("e")
             SMTLet(VarBinding(es, toSMT(e)), Seq(),
-              Core.Or(oneOf.map(FunctionApplication(_, Seq(es: Term))): _*))
+              SmtLibConstructors.or(oneOf.map(FunctionApplication(_, Seq(es: Term)))))
         }
 
       case CaseClass(cct, es) =>
@@ -615,8 +615,8 @@ trait SMTLIBTarget extends Interruptible {
       case RealTimes(a, b)           => Reals.Mul(toSMT(a), toSMT(b))
       case RealDivision(a, b)        => Reals.Div(toSMT(a), toSMT(b))
 
-      case And(sub)                  => Core.And(sub.map(toSMT): _*)
-      case Or(sub)                   => Core.Or(sub.map(toSMT): _*)
+      case And(sub)                  => SmtLibConstructors.and(sub.map(toSMT))
+      case Or(sub)                   => SmtLibConstructors.or(sub.map(toSMT))
       case IfExpr(cond, thenn, elze) => Core.ITE(toSMT(cond), toSMT(thenn), toSMT(elze))
       case f @ FunctionInvocation(_, sub) =>
         if (sub.isEmpty) declareFunction(f.tfd) else {
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBUnsupportedError.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBUnsupportedError.scala
index 0a48c2988fa3cf6dcdeb8cc3f19118a43826227b..3575f9fd30c50f1a05292fc616715bd24ef4e446 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBUnsupportedError.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBUnsupportedError.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala
index aa78b97f04bcafaa1db5b91b197383f690ecd525..083e07f34b76cbd118727c326803e521d4967ba6 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.smtlib
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala
index f3c7cb69e83490f25c6b8dec79d082cb6f8f2c75..fbd4b581c7c34835c6deb1845c04717e0beafd2c 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala
index dc56d76d7037ae3c0c14907bdecb38dff92a99a8..58a88d1a6153bed23c38e059d54c8e8a46a5f1fd 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
index f9f8e386c628c3550983afece5a984197e3e07ba..5744e1a107f8c1c25b8e82e02c0619b50ca9c5c9 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/string/StringSolver.scala b/src/main/scala/leon/solvers/string/StringSolver.scala
index d681d500f42611e19b241ddb5f22425eef8dad33..bc9ee8419713dcbf63222164f12c32d04a30d1a8 100644
--- a/src/main/scala/leon/solvers/string/StringSolver.scala
+++ b/src/main/scala/leon/solvers/string/StringSolver.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.solvers.string
 
 import leon.purescala.Common._
diff --git a/src/main/scala/leon/solvers/sygus/CVC4SygusSolver.scala b/src/main/scala/leon/solvers/sygus/CVC4SygusSolver.scala
index 0771504fa1acd020a5e221049d628ed08af9fa3e..564dc67fe75fe016bcbba38a62dfbb6ba0544efc 100644
--- a/src/main/scala/leon/solvers/sygus/CVC4SygusSolver.scala
+++ b/src/main/scala/leon/solvers/sygus/CVC4SygusSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/sygus/SygusSolver.scala b/src/main/scala/leon/solvers/sygus/SygusSolver.scala
index 6d2c7678947c07fb6c53da2beac902e1fb25dbd5..816872492f722b49bb47e18a77aaf778e5ff20a9 100644
--- a/src/main/scala/leon/solvers/sygus/SygusSolver.scala
+++ b/src/main/scala/leon/solvers/sygus/SygusSolver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/templates/LambdaManager.scala b/src/main/scala/leon/solvers/templates/LambdaManager.scala
index a63fdd7a6e06d7ea9cc0b9d8b7ac1f0b89219bab..f80a143a5095f0f0ccc25cd836a4c27f96be72dc 100644
--- a/src/main/scala/leon/solvers/templates/LambdaManager.scala
+++ b/src/main/scala/leon/solvers/templates/LambdaManager.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/templates/QuantificationManager.scala b/src/main/scala/leon/solvers/templates/QuantificationManager.scala
index 85a2add2721a8b03cb3399bdbc73d796d74853e4..d10b786e5ac3c01a188e1d05f54cebf8add5d362 100644
--- a/src/main/scala/leon/solvers/templates/QuantificationManager.scala
+++ b/src/main/scala/leon/solvers/templates/QuantificationManager.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/templates/TemplateEncoder.scala b/src/main/scala/leon/solvers/templates/TemplateEncoder.scala
index 16d7b3cdc7f695eb7524895fd880de4f23a1083c..c2a2051b15f3e3a857deb52d73d9d973362ffd56 100644
--- a/src/main/scala/leon/solvers/templates/TemplateEncoder.scala
+++ b/src/main/scala/leon/solvers/templates/TemplateEncoder.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
index 4556f7dd6507f9a8c8a745b0323dbbdb9cf0032b..34b7b35f428bff701af9a25c06258da5a43443ed 100644
--- a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
+++ b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
@@ -219,7 +219,7 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T],
     //    id => expr && ... && expr
     var guardedExprs = Map[Identifier, Seq[Expr]]()
     def storeGuarded(guardVar: Identifier, expr: Expr) : Unit = {
-      assert(expr.getType == BooleanType, expr.asString(Program.empty)(LeonContext.empty) + " is not of type Boolean." + (
+      assert(expr.getType == BooleanType, expr.asString(Program.empty)(LeonContext.empty) + " is not of type Boolean. " + (
         purescala.ExprOps.fold[String]{ (e, se) => 
           s"$e is of type ${e.getType}" + se.map(child => "\n  " + "\n".r.replaceAllIn(child, "\n  ")).mkString
         }(expr)
diff --git a/src/main/scala/leon/solvers/templates/TemplateInfo.scala b/src/main/scala/leon/solvers/templates/TemplateInfo.scala
index dfdd664cbdf1f110690d05e959bc1a14cc615327..455704dc43928c473108d29fbb8789d13e6a78a3 100644
--- a/src/main/scala/leon/solvers/templates/TemplateInfo.scala
+++ b/src/main/scala/leon/solvers/templates/TemplateInfo.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/templates/TemplateManager.scala b/src/main/scala/leon/solvers/templates/TemplateManager.scala
index c81abc384934aea21fb1d5d183925e7c6d013fb7..2bb0cbbd0b00abdfdc21b04b2067a68bd5a6134d 100644
--- a/src/main/scala/leon/solvers/templates/TemplateManager.scala
+++ b/src/main/scala/leon/solvers/templates/TemplateManager.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
diff --git a/src/main/scala/leon/solvers/templates/UnrollingBank.scala b/src/main/scala/leon/solvers/templates/UnrollingBank.scala
index cb7fe90d280160d03a5b9fbc190a7851b3cd3c1b..acee03b73ece82c3e64eeb2d8c9149929a052aac 100644
--- a/src/main/scala/leon/solvers/templates/UnrollingBank.scala
+++ b/src/main/scala/leon/solvers/templates/UnrollingBank.scala
@@ -1,10 +1,9 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
 package templates
 
-import purescala.Printable
 import purescala.Common._
 import purescala.Expressions._
 import purescala.Types._
diff --git a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala
index 7ae02d83e0a6245c7345ef7349211e6c246221ac..01a86e2b91289487940f5875becdd30e05716b63 100644
--- a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala
+++ b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.z3
@@ -13,12 +13,9 @@ import purescala.Constructors._
 import purescala.Extractors._
 import purescala.Expressions._
 import purescala.TypeOps._
-import xlang.Expressions._
 import purescala.ExprOps._
 import purescala.Types._
 
-import scala.collection.mutable.{Map => MutableMap}
-
 case class UnsoundExtractionException(ast: Z3AST, msg: String)
   extends Exception("Can't extract " + ast + " : " + msg)
 
@@ -273,7 +270,7 @@ trait AbstractZ3Solver extends Solver {
     def rec(ex: Expr): Z3AST = ex match {
 
       // TODO: Leave that as a specialization?
-      case LetTuple(ids, e, b) => {
+      case LetTuple(ids, e, b) =>
         z3Vars = z3Vars ++ ids.zipWithIndex.map { case (id, ix) =>
           val entry = id -> rec(tupleSelect(e, ix + 1, ids.size))
           entry
@@ -281,7 +278,6 @@ trait AbstractZ3Solver extends Solver {
         val rb = rec(b)
         z3Vars = z3Vars -- ids
         rb
-      }
 
       case p @ Passes(_, _, _) =>
         rec(p.asConstraint)
@@ -289,40 +285,30 @@ trait AbstractZ3Solver extends Solver {
       case me @ MatchExpr(s, cs) =>
         rec(matchToIfThenElse(me))
 
-      case Let(i, e, b) => {
+      case Let(i, e, b) =>
         val re = rec(e)
         z3Vars = z3Vars + (i -> re)
         val rb = rec(b)
         z3Vars = z3Vars - i
         rb
-      }
 
-      case Waypoint(_, e, _) => rec(e)
       case a @ Assert(cond, err, body) =>
         rec(IfExpr(cond, body, Error(a.getType, err.getOrElse("Assertion failed")).setPos(a.getPos)).setPos(a.getPos))
 
-      case e @ Error(tpe, _) => {
+      case e @ Error(tpe, _) =>
         val newAST = z3.mkFreshConst("errorValue", typeToSort(tpe))
         // Might introduce dupplicates (e), but no worries here
         variables += (e -> newAST)
         newAST
-      }
-      case v @ Variable(id) => z3Vars.get(id) match {
-        case Some(ast) => 
-          ast
-        case None => {
-          variables.getB(v) match {
-            case Some(ast) =>
-              ast
-
-            case None =>
+
+      case v @ Variable(id) => z3Vars.getOrElse(id,
+        variables.getB(v).getOrElse {
           val newAST = z3.mkFreshConst(id.uniqueName, typeToSort(v.getType))
           z3Vars = z3Vars + (id -> newAST)
           variables += (v -> newAST)
           newAST
         }
-      }
-      }
+      )
 
       case ite @ IfExpr(c, t, e) => z3.mkITE(rec(c), rec(t), rec(e))
       case And(exs) => z3.mkAnd(exs.map(rec): _*)
@@ -339,7 +325,7 @@ trait AbstractZ3Solver extends Solver {
       case Plus(l, r) => z3.mkAdd(rec(l), rec(r))
       case Minus(l, r) => z3.mkSub(rec(l), rec(r))
       case Times(l, r) => z3.mkMul(rec(l), rec(r))
-      case Division(l, r) => {
+      case Division(l, r) =>
         val rl = rec(l)
         val rr = rec(r)
         z3.mkITE(
@@ -347,14 +333,11 @@ trait AbstractZ3Solver extends Solver {
           z3.mkDiv(rl, rr),
           z3.mkUnaryMinus(z3.mkDiv(z3.mkUnaryMinus(rl), rr))
         )
-      }
-      case Remainder(l, r) => {
+      case Remainder(l, r) =>
         val q = rec(Division(l, r))
         z3.mkSub(rec(l), z3.mkMul(rec(r), q))
-      }
-      case Modulo(l, r) => {
+      case Modulo(l, r) =>
         z3.mkMod(rec(l), rec(r))
-      }
       case UMinus(e) => z3.mkUnaryMinus(rec(e))
 
       case RealPlus(l, r) => z3.mkAdd(rec(l), rec(r))
@@ -705,7 +688,7 @@ trait AbstractZ3Solver extends Solver {
                     val elems = r.elems.flatMap {
                       case (k, CaseClass(leonSome, Seq(x))) => Some(k -> x)
                       case (k, _) => None
-                    }.toMap
+                    }
 
                     FiniteMap(elems, from, to)
                 }
diff --git a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala
index 5c12fd3863da241f09a667133731a9b31182f10f..fa3352b1ef2b5810afd063e0eb28f503e9d4a57d 100644
--- a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala
+++ b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers
@@ -7,22 +7,14 @@ package z3
 import utils._
 import _root_.z3.scala._
 
-import purescala.Printable
 import purescala.Common._
 import purescala.Definitions._
 import purescala.Expressions._
-import purescala.Constructors._
-import purescala.Quantification._
 import purescala.ExprOps._
 import purescala.Types._
 
 import solvers.templates._
 import solvers.combinators._
-import Template._
-
-import evaluators._
-
-import termination._
 
 class FairZ3Solver(val context: LeonContext, val program: Program)
   extends AbstractZ3Solver
@@ -212,7 +204,7 @@ class FairZ3Solver(val context: LeonContext, val program: Program)
   override def foundAnswer(res: Option[Boolean], model: Model = Model.empty, core: Set[Expr] = Set.empty) = {
     super.foundAnswer(res, model, core)
 
-    if (!interrupted && res == None && model == None) {
+    if (!interrupted && res.isEmpty && model.isEmpty) {
       reporter.ifDebug { debug => 
         if (solver.getReasonUnknown != "canceled") {
           debug("Z3 returned unknown: " + solver.getReasonUnknown)
diff --git a/src/main/scala/leon/solvers/z3/UninterpretedZ3Solver.scala b/src/main/scala/leon/solvers/z3/UninterpretedZ3Solver.scala
index f755f2a4a95c6b55774d966abda7b659206c96d6..6f40151cf396348822e2ab3b6e5cdde07a6e8b93 100644
--- a/src/main/scala/leon/solvers/z3/UninterpretedZ3Solver.scala
+++ b/src/main/scala/leon/solvers/z3/UninterpretedZ3Solver.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.z3
diff --git a/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala b/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala
index 4383f8f31fe6eeaccb8e174aa0c0251638f581ba..a626199f1fc326d172ce22a8c7a1816c1f5cb098 100644
--- a/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala
+++ b/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package solvers.z3
diff --git a/src/main/scala/leon/solvers/z3/Z3StringConversion.scala b/src/main/scala/leon/solvers/z3/Z3StringConversion.scala
index b644f687af3950d03bb062f0ef0f030c3691f6b4..fa262caa6ede90a8c5196090364a80a0be9dc0fc 100644
--- a/src/main/scala/leon/solvers/z3/Z3StringConversion.scala
+++ b/src/main/scala/leon/solvers/z3/Z3StringConversion.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package solvers
 package z3
@@ -156,8 +158,8 @@ trait Z3StringConverters  {
     def convertExpr(expr: Expr)(implicit bindings: Map[Identifier, Expr]): Expr
     object TypeConverted {
       def unapply(t: TypeTree): Option[TypeTree] = Some(t match {
-        case cct@CaseClassType(ccd, args) => CaseClassType(convertClassDef(ccd).asInstanceOf[CaseClassDef], args)
-        case act@AbstractClassType(acd, args) => AbstractClassType(convertClassDef(acd).asInstanceOf[AbstractClassDef], args)
+        case cct@CaseClassType(ccd, args) => CaseClassType(convertClassDef(ccd).asInstanceOf[CaseClassDef], args map convertType)
+        case act@AbstractClassType(acd, args) => AbstractClassType(convertClassDef(acd).asInstanceOf[AbstractClassDef], args map convertType)
         case NAryType(es, builder) => 
           builder(es map convertType)
       })
@@ -280,7 +282,7 @@ trait Z3StringConverters  {
     def isTypeToConvert(tpe: TypeTree): Boolean = 
       TypeOps.exists(StringType == _)(tpe)
     def convertType(tpe: TypeTree): TypeTree = tpe match {
-      case StringType => StringList.typed
+      case StringType => StringListTyped
       case TypeConverted(t) => t
     }
     def convertPattern(e: Pattern): Pattern = e match {
@@ -344,7 +346,7 @@ trait Z3StringConverters  {
     def isTypeToConvert(tpe: TypeTree): Boolean = 
       TypeOps.exists(t => TypeOps.isSubtypeOf(t, StringListTyped))(tpe)
     def convertType(tpe: TypeTree): TypeTree = tpe match {
-      case StringList | StringCons | StringNil => StringType
+      case StringListTyped | StringConsTyped | StringNilTyped => StringType
       case TypeConverted(t) => t
     }
     def convertPattern(e: Pattern): Pattern = e match {
diff --git a/src/main/scala/leon/synthesis/Algebra.scala b/src/main/scala/leon/synthesis/Algebra.scala
index 92ee346e0871ba6381a2d65bdea9d90ac608454f..3ba54147d0974bf9f48aac183fd47942540d9d8f 100644
--- a/src/main/scala/leon/synthesis/Algebra.scala
+++ b/src/main/scala/leon/synthesis/Algebra.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.synthesis
 
diff --git a/src/main/scala/leon/synthesis/ConversionPhase.scala b/src/main/scala/leon/synthesis/ConversionPhase.scala
index ce9f1525f5e012800400c7b9c0776914d989b43b..d6329768e42e561c92d76c55a39764b11b650f66 100644
--- a/src/main/scala/leon/synthesis/ConversionPhase.scala
+++ b/src/main/scala/leon/synthesis/ConversionPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/CostModel.scala b/src/main/scala/leon/synthesis/CostModel.scala
index f2d422468431b9406dd64be264f0c2157853aad5..781940e71ec6d62c57895a9cafee2b4073e704bf 100644
--- a/src/main/scala/leon/synthesis/CostModel.scala
+++ b/src/main/scala/leon/synthesis/CostModel.scala
@@ -1,18 +1,14 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 
-import graph._
-
 import purescala.Expressions._
 import purescala.ExprOps._
 
 /** A named way of computing the cost of problem and solutions.*/
 abstract class CostModel(val name: String) {
   def solution(s: Solution): Cost
-  def problem(p: Problem): Cost
-  def andNode(an: AndNode, subs: Option[Seq[Cost]]): Cost
 
   def impossible: Cost
 
@@ -27,14 +23,14 @@ case class Cost(minSize: Int) extends AnyVal with Ordered[Cost] {
     this.minSize-that.minSize
   }
 
-  def asString: String = {
+  override def toString: String = {
     f"$minSize%3d"
   }
 }
 
 /** Contains all and the default [CostModel] */
 object CostModels {
-  def default: CostModel = WeightedBranchesCostModel
+  def default: CostModel = NaiveCostModel
 
   def all: Set[CostModel] = Set(
     NaiveCostModel,
@@ -47,10 +43,6 @@ class WrappedCostModel(cm: CostModel, name: String) extends CostModel(name) {
 
   def solution(s: Solution): Cost = cm.solution(s)
 
-  def problem(p: Problem): Cost = cm.problem(p)
-
-  def andNode(an: AndNode, subs: Option[Seq[Cost]]): Cost = cm.andNode(an, subs)
-
   def impossible = cm.impossible
 }
 
@@ -58,34 +50,10 @@ class WrappedCostModel(cm: CostModel, name: String) extends CostModel(name) {
   * For problems, returns a cost of 1 */
 class SizeBasedCostModel(name: String) extends CostModel(name) {
   def solution(s: Solution) = {
-    Cost(formulaSize(s.toExpr)/10)
-  }
-
-  def problem(p: Problem) = {
-    Cost(1)
-  }
-
-  def andNode(an: AndNode, subs: Option[Seq[Cost]]) = {
-
-    subs match {
-      case Some(subs) if subs.isEmpty =>
-        impossible
-
-      case osubs =>
-        val app = an.ri
-
-        val subSols = app.onSuccess.types.map {t => Solution.simplest(t) }.toList
-        val selfCost = app.onSuccess(subSols) match {
-          case Some(sol) =>
-            solution(sol).minSize - subSols.size
-          case None =>
-            1
-        }
-        Cost(osubs.toList.flatten.foldLeft(selfCost)(_ + _.minSize))
-    }   
+    Cost(formulaSize(s.term))
   }
 
-  def impossible = Cost(200)
+  def impossible = Cost(1000)
 }
 
 case object NaiveCostModel extends SizeBasedCostModel("Naive")
diff --git a/src/main/scala/leon/synthesis/ExamplesBank.scala b/src/main/scala/leon/synthesis/ExamplesBank.scala
index 265b35a5e5136bdcbfbd6e458350580c42bae9e3..35a6986864dde1a97fdca214536dac6a21b52c57 100644
--- a/src/main/scala/leon/synthesis/ExamplesBank.scala
+++ b/src/main/scala/leon/synthesis/ExamplesBank.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package synthesis
 
@@ -158,38 +160,44 @@ case class ExamplesBank(valids: Seq[Example], invalids: Seq[Example]) {
 
 object ExamplesBank {
   def empty = ExamplesBank(Nil, Nil)
+
 }
 
 /** Same as an ExamplesBank, but with identifiers corresponding to values. This
   * allows us to evaluate expressions. */
 case class QualifiedExamplesBank(as: List[Identifier], xs: List[Identifier], eb: ExamplesBank)(implicit hctx: SearchContext) {
 
-  def removeOuts(toRemove: Set[Identifier]) = {
+  def removeOuts(toRemove: Set[Identifier]): QualifiedExamplesBank = {
+    val nxs    = xs.filterNot(toRemove)
     val toKeep = xs.zipWithIndex.filterNot(x => toRemove(x._1)).map(_._2)
 
-    eb mapOuts { out => List(toKeep.map(out)) }
+    QualifiedExamplesBank(as, nxs, eb mapOuts { out => List(toKeep.map(out)) })
   }
 
   def removeIns(toRemove: Set[Identifier]) = {
+    val nas = as.filterNot(toRemove)
     val toKeep: List[Int] = as.zipWithIndex.filterNot(a => toRemove(a._1)).map(_._2)
-    eb mapIns { (in: Seq[Expr]) => List(toKeep.map(in)) }
+
+    QualifiedExamplesBank(nas, xs, eb mapIns { (in: Seq[Expr]) => List(toKeep.map(in)) })
   }
 
   /** Filter inputs throught expr which is an expression evaluating to a boolean */
-  def filterIns(expr: Expr): ExamplesBank = {
-    filterIns(m => hctx.sctx.defaultEvaluator.eval(expr, m).result == Some(BooleanLiteral(true)))
+  def filterIns(expr: Expr): QualifiedExamplesBank = {
+    filterIns(m => hctx.defaultEvaluator.eval(expr, m).result == Some(BooleanLiteral(true)))
   }
 
   /** Filters inputs through the predicate pred, with an assignment of input variables to expressions. */
-  def filterIns(pred: Map[Identifier, Expr] => Boolean): ExamplesBank = {
-    eb mapIns { in =>
-      val m = (as zip in).toMap
-      if(pred(m)) {
-        List(in)
-      } else {
-        Nil
+  def filterIns(pred: Map[Identifier, Expr] => Boolean): QualifiedExamplesBank = {
+    QualifiedExamplesBank(as, xs,
+      eb mapIns { in =>
+        val m = (as zip in).toMap
+        if(pred(m)) {
+          List(in)
+        } else {
+          Nil
+        }
       }
-    }
+    )
   }
 
   /** Maps inputs through the function f
@@ -204,3 +212,9 @@ case class QualifiedExamplesBank(as: List[Identifier], xs: List[Identifier], eb:
     }
   }
 }
+
+import scala.language.implicitConversions
+
+object QualifiedExamplesBank {
+  implicit def qebToEb(qeb: QualifiedExamplesBank): ExamplesBank = qeb.eb
+}
diff --git a/src/main/scala/leon/synthesis/ExamplesFinder.scala b/src/main/scala/leon/synthesis/ExamplesFinder.scala
index 1c562d887c4338e1db90fee5af8c98c0e011bac6..7079f905461f9912973fa7010e9fda809815538e 100644
--- a/src/main/scala/leon/synthesis/ExamplesFinder.scala
+++ b/src/main/scala/leon/synthesis/ExamplesFinder.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -57,7 +57,7 @@ class ExamplesFinder(ctx0: LeonContext, program: Program) {
       def isValidTest(e: Example): Boolean = {
         e match {
           case InOutExample(ins, outs) =>
-            evaluator.eval(Equals(outs.head, FunctionInvocation(fd.typed(fd.tparams.map(_.tp)), ins))) match {
+            evaluator.eval(Equals(outs.head, FunctionInvocation(fd.typed, ins))) match {
               case EvaluationResults.Successful(BooleanLiteral(true)) => true
               case _                                                  => false
             }
diff --git a/src/main/scala/leon/synthesis/FileInterface.scala b/src/main/scala/leon/synthesis/FileInterface.scala
index cba6629dad2aab1cddc0b857bc0fbe7bd4d66d76..f40255815ac96bde3f574f53626d5f92659303d9 100644
--- a/src/main/scala/leon/synthesis/FileInterface.scala
+++ b/src/main/scala/leon/synthesis/FileInterface.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/Histogram.scala b/src/main/scala/leon/synthesis/Histogram.scala
index 9982e117fb4080f2d4bca3d3de0b3187ee2cbe51..7950d1ce714a55785e9776e64d4649ed793a02cc 100644
--- a/src/main/scala/leon/synthesis/Histogram.scala
+++ b/src/main/scala/leon/synthesis/Histogram.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.synthesis
 
diff --git a/src/main/scala/leon/synthesis/InOutExample.scala b/src/main/scala/leon/synthesis/InOutExample.scala
index ae6e24bbc6b7a678460b4ab109520c3bd36485dd..244515d3addb359a28e2507782536730f33cc5ab 100644
--- a/src/main/scala/leon/synthesis/InOutExample.scala
+++ b/src/main/scala/leon/synthesis/InOutExample.scala
@@ -1,12 +1,11 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 
 import purescala.Expressions._
-import leon.utils.ASCIIHelpers._
 
-sealed abstract class Example {
+sealed abstract class Example extends Printable {
   def ins: Seq[Expr]
 
   def asString(implicit ctx: LeonContext) = {
diff --git a/src/main/scala/leon/synthesis/LinearEquations.scala b/src/main/scala/leon/synthesis/LinearEquations.scala
index 546bcd3d932c6a6f13bbdd10930f02843e63fff0..3069c90aeaa67a07c450684f5856210955d30dcd 100644
--- a/src/main/scala/leon/synthesis/LinearEquations.scala
+++ b/src/main/scala/leon/synthesis/LinearEquations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/PartialSolution.scala b/src/main/scala/leon/synthesis/PartialSolution.scala
index d3443db76c73e403ca287f754a07a0c6c0f060f1..4f46997a83deed858f6cb13d4e1d086a00f77946 100644
--- a/src/main/scala/leon/synthesis/PartialSolution.scala
+++ b/src/main/scala/leon/synthesis/PartialSolution.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -6,8 +6,9 @@ package synthesis
 import purescala.Expressions._
 
 import graph._
+import strategies._
 
-class PartialSolution(g: Graph, includeUntrusted: Boolean = false) {
+class PartialSolution(strat: Strategy, includeUntrusted: Boolean = false) {
 
   def includeSolution(s: Solution) = {
     includeUntrusted || s.isTrusted
@@ -48,11 +49,6 @@ class PartialSolution(g: Graph, includeUntrusted: Boolean = false) {
 
   }
 
-
-  def getSolution: Solution = {
-    getSolutionFor(g.root)
-  }
-
   def getSolutionFor(n: Node): Solution = {
     n match {
       case on: OrNode =>
@@ -66,11 +62,9 @@ class PartialSolution(g: Graph, includeUntrusted: Boolean = false) {
         }
 
         if (n.isExpanded) {
-          val descs = on.descendants.filterNot(_.isDeadEnd)
-          if (descs.isEmpty) {
-            completeProblem(on.p)
-          } else {
-            getSolutionFor(descs.minBy(_.cost))
+          strat.bestAlternative(on) match {
+            case None => completeProblem(on.p)
+            case Some(d) => getSolutionFor(d)
           }
         } else {
           completeProblem(on.p)
diff --git a/src/main/scala/leon/synthesis/Problem.scala b/src/main/scala/leon/synthesis/Problem.scala
index cf3640f70582fde36189bd4d525a2fc1903f26e6..f60b5fc5a661f7174ae7afb32f597a6ccae31cab 100644
--- a/src/main/scala/leon/synthesis/Problem.scala
+++ b/src/main/scala/leon/synthesis/Problem.scala
@@ -1,14 +1,15 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 
-import leon.purescala.Expressions._
-import leon.purescala.ExprOps._
-import leon.purescala.Types._
-import leon.purescala.Common._
-import leon.purescala.Constructors._
-import leon.purescala.Extractors._
+import purescala.Expressions._
+import purescala.ExprOps._
+import purescala.Types._
+import purescala.Common._
+import purescala.Constructors._
+import purescala.Extractors._
+import purescala.Definitions.FunDef
 import Witnesses._
 
 /** Defines a synthesis triple of the form:
@@ -20,7 +21,7 @@ import Witnesses._
   * @param phi The formula on `as` and `xs` to satisfy
   * @param xs The list of output identifiers for which we want to compute a function
   */
-case class Problem(as: List[Identifier], ws: Expr, pc: Expr, phi: Expr, xs: List[Identifier], eb: ExamplesBank = ExamplesBank.empty) {
+case class Problem(as: List[Identifier], ws: Expr, pc: Expr, phi: Expr, xs: List[Identifier], eb: ExamplesBank = ExamplesBank.empty) extends Printable {
 
   def inType  = tupleTypeWrap(as.map(_.getType))
   def outType = tupleTypeWrap(xs.map(_.getType))
@@ -30,15 +31,30 @@ case class Problem(as: List[Identifier], ws: Expr, pc: Expr, phi: Expr, xs: List
 
     val ebInfo = "/"+eb.valids.size+","+eb.invalids.size+"/"
 
-    "⟦ "+as.map(_.asString).mkString(";")+", "+(if (pcws != BooleanLiteral(true)) pcws.asString+" ≺ " else "")+" ⟨ "+phi.asString+" ⟩ "+xs.map(_.asString).mkString(";")+" ⟧  "+ebInfo
+    s"""|⟦  ${if (as.nonEmpty) as.map(_.asString).mkString(", ") else "()"}
+        |   ${pcws.asString} ≺
+        |   ⟨ ${phi.asString} ⟩ 
+        |   ${if (xs.nonEmpty) xs.map(_.asString).mkString(", ") else "()"}
+        |⟧  $ebInfo""".stripMargin
+  }
+
+  def withWs(es: Seq[Expr]) = {
+    val TopLevelAnds(prev) = ws
+    copy(ws = andJoin(prev ++ es))
   }
 
   // Qualified example bank, allows us to perform operations (e.g. filter) with expressions
   def qeb(implicit sctx: SearchContext) = QualifiedExamplesBank(this.as, this.xs, eb)
+
 }
 
 object Problem {
-  def fromSpec(spec: Expr, pc: Expr = BooleanLiteral(true), eb: ExamplesBank = ExamplesBank.empty): Problem = {
+  def fromSpec(
+    spec: Expr,
+    pc: Expr = BooleanLiteral(true),
+    eb: ExamplesBank = ExamplesBank.empty,
+    fd: Option[FunDef] = None
+  ): Problem = {
     val xs = {
       val tps = spec.getType.asInstanceOf[FunctionType].from
       tps map (FreshIdentifier("x", _, alwaysShowUniqueID = true))
@@ -47,6 +63,13 @@ object Problem {
     val phi = application(simplifyLets(spec), xs map { _.toVariable})
     val as = (variablesOf(And(pc, phi)) -- xs).toList.sortBy(_.name)
 
+    val sortedAs = fd match {
+      case None => as
+      case Some(fd) =>
+        val argsIndex = fd.params.map(_.id).zipWithIndex.toMap.withDefaultValue(100)
+        as.sortBy(a => argsIndex(a))
+    }
+
     val TopLevelAnds(clauses) = pc
 
     val (pcs, wss) = clauses.partition {
@@ -54,15 +77,7 @@ object Problem {
       case _ => true
     }
 
-    Problem(as, andJoin(wss), andJoin(pcs), phi, xs, eb)
+    Problem(sortedAs, andJoin(wss), andJoin(pcs), phi, xs, eb)
   }
 
-  def fromSourceInfo(ci: SourceInfo): Problem = {
-    // Same as fromChoose, but we order the input variables by the arguments of
-    // the functions, so that tests are compatible
-    val p = fromSpec(ci.spec, ci.pc, ci.eb)
-    val argsIndex = ci.fd.params.map(_.id).zipWithIndex.toMap.withDefaultValue(100)
-
-    p.copy( as = p.as.sortBy(a => argsIndex(a)))
-  }
 }
diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala
index 3a86ca64a79238aec4e59b197e001fd4c24660b4..ff92b251e76cce8508629fe3cafeb9e40f37cb74 100644
--- a/src/main/scala/leon/synthesis/Rules.scala
+++ b/src/main/scala/leon/synthesis/Rules.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -7,11 +7,11 @@ import purescala.Common._
 import purescala.Expressions._
 import purescala.Types._
 import purescala.ExprOps._
-import purescala.Constructors.and
+import purescala.Constructors._
 import rules._
 
 /** A Rule can be applied on a synthesis problem */
-abstract class Rule(val name: String) extends RuleDSL {
+abstract class Rule(val name: String) extends RuleDSL with Printable {
   def instantiateOn(implicit hctx: SearchContext, problem: Problem): Traversable[RuleInstantiation]
 
   val priority: RulePriority = RulePriorityDefault
@@ -20,8 +20,6 @@ abstract class Rule(val name: String) extends RuleDSL {
 
   implicit val thisRule = this
 
-  implicit def hctxToCtx(implicit hctx: SearchContext): LeonContext = hctx.sctx.context
-
   def asString(implicit ctx: LeonContext) = name
 }
 
@@ -53,25 +51,15 @@ object Rules {
     UnusedInput,
     EquivalentInputs,
     UnconstrainedOutput,
+    if(naiveGrammar) NaiveCEGIS else CEGIS,
     OptimisticGround,
-    EqualitySplit,
+    GenericTypeEqualitySplit,
     InequalitySplit,
-    if(naiveGrammar) NaiveCEGIS else CEGIS,
-    //TEGIS,
-    //BottomUpTEGIS,
+    IntroduceRecCalls,
     rules.Assert,
-    DetupleOutput,
     DetupleInput,
     ADTSplit,
-    //IntegerEquation,
-    //IntegerInequalities,
-    IntInduction,
     InnerCaseSplit
-    //new OptimisticInjection(_),
-    //new SelectiveInlining(_),
-    //ADTLongInduction,
-    //ADTInduction
-    //AngelicHoles // @EK: Disabled now as it is explicit with withOracle { .. }
   )
 
 }
@@ -79,7 +67,7 @@ object Rules {
 /** When applying this to a [SearchContext] it returns a wrapped stream of solutions or a new list of problems. */
 abstract class RuleInstantiation(val description: String,
                                  val onSuccess: SolutionBuilder = SolutionBuilderCloser())
-                                (implicit val problem: Problem, val rule: Rule) {
+                                (implicit val problem: Problem, val rule: Rule) extends Printable {
 
   def apply(hctx: SearchContext): RuleApplication
 
diff --git a/src/main/scala/leon/synthesis/Search.scala b/src/main/scala/leon/synthesis/Search.scala
new file mode 100644
index 0000000000000000000000000000000000000000..564c630fcb199b776805f17fd6f80c5e8752e3d7
--- /dev/null
+++ b/src/main/scala/leon/synthesis/Search.scala
@@ -0,0 +1,92 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+
+import strategies._
+import graph._
+
+import scala.annotation.tailrec
+
+import scala.collection.mutable.ArrayBuffer
+import leon.utils.Interruptible
+import java.util.concurrent.atomic.AtomicBoolean
+
+class Search(val ctx: LeonContext, ci: SourceInfo, p: Problem, val strat: Strategy) extends Interruptible {
+  val g = new Graph(p)
+
+  val interrupted = new AtomicBoolean(false)
+
+  strat.init(g.root)
+
+  def doExpand(n: Node, sctx: SynthesisContext): Unit = {
+    ctx.timers.synthesis.step.timed {
+      n match {
+        case an: AndNode =>
+          ctx.timers.synthesis.applications.get(an.ri.asString(sctx)).timed {
+            an.expand(new SearchContext(sctx, ci.source, an, this))
+          }
+
+        case on: OrNode =>
+          on.expand(new SearchContext(sctx, ci.source, on, this))
+      }
+    }
+  }
+
+  @tailrec
+  final def searchFrom(sctx: SynthesisContext, from: Node): Boolean = {
+    strat.getNextToExpand(from) match {
+      case Some(n) =>
+        strat.beforeExpand(n)
+
+        doExpand(n, sctx)
+
+        strat.afterExpand(n)
+
+        if (from.isSolved) {
+          true
+        } else if (interrupted.get) {
+          false
+        } else {
+          searchFrom(sctx, from)
+        }
+      case None =>
+        false
+    }
+  }
+
+  def traversePathFrom(n: Node, path: List[Int]): Option[Node] = path match {
+    case Nil =>
+      Some(n)
+    case x :: xs =>
+      if (n.isExpanded && n.descendants.size > x) {
+        traversePathFrom(n.descendants(x), xs)
+      } else {
+        None
+      }
+  }
+
+  def traversePath(path: List[Int]): Option[Node] = {
+    traversePathFrom(g.root, path)
+  }
+
+  def search(sctx: SynthesisContext): Stream[Solution] = {
+    if (searchFrom(sctx, g.root)) {
+      g.root.generateSolutions()
+    } else {
+      Stream.empty
+    }
+  }
+
+  def interrupt(): Unit = {
+    interrupted.set(true)
+    strat.interrupt()
+  }
+
+  def recoverInterrupt(): Unit = {
+    interrupted.set(false)
+    strat.recoverInterrupt()
+  }
+
+  ctx.interruptManager.registerForInterrupts(this)
+}
diff --git a/src/main/scala/leon/synthesis/SearchContext.scala b/src/main/scala/leon/synthesis/SearchContext.scala
index 1ee7361d5a878978fede4084b0909a8e711137cd..63683d9278e0219eaeb32c5755e0c8ed25f79836 100644
--- a/src/main/scala/leon/synthesis/SearchContext.scala
+++ b/src/main/scala/leon/synthesis/SearchContext.scala
@@ -1,23 +1,26 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 
 import graph._
+import purescala.Expressions.Expr
 
 /**
  * This is context passed down rules, and include search-wise context, as well
  * as current search location information
  */
-case class SearchContext (
+class SearchContext (
   sctx: SynthesisContext,
-  ci: SourceInfo,
-  currentNode: Node,
-  search: Search
+  val source: Expr,
+  val currentNode: Node,
+  val search: Search
+) extends SynthesisContext(
+  sctx,
+  sctx.settings,
+  sctx.functionContext,
+  sctx.program
 ) {
-  val context  = sctx.context
-  val reporter = sctx.reporter
-  val program  = sctx.program
 
   def searchDepth = {
     def depthOf(n: Node): Int = n.parent match {
@@ -29,4 +32,5 @@ case class SearchContext (
   }
 
   def parentNode: Option[Node] = currentNode.parent
+
 }
diff --git a/src/main/scala/leon/synthesis/Solution.scala b/src/main/scala/leon/synthesis/Solution.scala
index affa41df46292ae73a6b9a87150283ec8c0ee997..fd7d3fb6a52d95588c577d754fbcf5e2da91b20d 100644
--- a/src/main/scala/leon/synthesis/Solution.scala
+++ b/src/main/scala/leon/synthesis/Solution.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -14,7 +14,7 @@ import leon.utils.Simplifiers
 
 // Defines a synthesis solution of the form:
 // ⟨ P | T ⟩
-class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr, val isTrusted: Boolean = true) {
+class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr, val isTrusted: Boolean = true) extends Printable {
 
   def asString(implicit ctx: LeonContext) = {
     "⟨ "+pre.asString+" | "+defs.map(_.asString).mkString(" ")+" "+term.asString+" ⟩" 
@@ -54,8 +54,8 @@ class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr, val isTrust
   }
 
 
-  def toSimplifiedExpr(ctx: LeonContext, p: Program): Expr = {
-    Simplifiers.bestEffort(ctx, p)(toExpr)
+  def toSimplifiedExpr(ctx: LeonContext, p: Program, within: FunDef): Expr = {
+    withoutSpec(Simplifiers.bestEffort(ctx, p)(req(within.precOrTrue, toExpr))).get
   }
 }
 
@@ -96,6 +96,6 @@ object Solution {
 
   def UNSAT(implicit p: Problem): Solution = {
     val tpe = tupleTypeWrap(p.xs.map(_.getType))
-    Solution(BooleanLiteral(false), Set(), Error(tpe, p.phi+" is UNSAT!"))
+    Solution(BooleanLiteral(false), Set(), Error(tpe, "Path condition is UNSAT!"))
   }
 }
diff --git a/src/main/scala/leon/synthesis/SourceInfo.scala b/src/main/scala/leon/synthesis/SourceInfo.scala
index 8ab07929d78479656f18ce1fd652cfa7ef870e17..666c589c304a5d8d507bfcfe9d86fd2fbc17e1a5 100644
--- a/src/main/scala/leon/synthesis/SourceInfo.scala
+++ b/src/main/scala/leon/synthesis/SourceInfo.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -9,14 +9,7 @@ import purescala.Expressions._
 import purescala.ExprOps._
 import Witnesses._
 
-case class SourceInfo(fd: FunDef,
-                      pc: Expr,
-                      source: Expr,
-                      spec: Expr,
-                      eb: ExamplesBank) {
-
-  val problem = Problem.fromSourceInfo(this)
-}
+case class SourceInfo(fd: FunDef, source: Expr, problem: Problem)
 
 object SourceInfo {
 
@@ -28,7 +21,7 @@ object SourceInfo {
   }
 
   def extractFromProgram(ctx: LeonContext, prog: Program): List[SourceInfo] = {
-    val functions = ctx.findOption(SharedOptions.optFunctions) map { _.toSet }
+    val functions = ctx.findOption(GlobalOptions.optFunctions) map { _.toSet }
 
     def excludeByDefault(fd: FunDef): Boolean = {
       fd.annotations contains "library"
@@ -54,7 +47,7 @@ object SourceInfo {
 
   def extractFromFunction(ctx: LeonContext, prog: Program, fd: FunDef): Seq[SourceInfo] = {
 
-    val term = Terminating(fd.typed, fd.params.map(_.id.toVariable))
+    val term = Terminating(fd.applied)
 
     val eFinder = new ExamplesFinder(ctx, prog)
 
@@ -68,12 +61,15 @@ object SourceInfo {
         ExamplesBank.empty
       }
 
-      val ci = SourceInfo(fd, and(path, term), ch, ch.pred, outerEb)
+      val p = Problem.fromSpec(ch.pred, and(path, term), outerEb, Some(fd))
+
+      val pcEb = eFinder.generateForPC(p.as, path, 20)
+      val chooseEb = eFinder.extractFromProblem(p)
+      val eb = (outerEb union chooseEb) union pcEb
 
-      val pcEb = eFinder.generateForPC(ci.problem.as, path, 20)
-      val chooseEb = eFinder.extractFromProblem(ci.problem)
+      val betterP = p.copy(eb = eb)
 
-      ci.copy(eb = (outerEb union chooseEb) union pcEb)
+      SourceInfo(fd, ch, betterP)
     }
   }
 }
diff --git a/src/main/scala/leon/synthesis/SynthesisContext.scala b/src/main/scala/leon/synthesis/SynthesisContext.scala
index b01077ce751f6b53e397b15eb3d5126e560d1b56..812adba389500f0d03a78a03df3fb1160b1da4d2 100644
--- a/src/main/scala/leon/synthesis/SynthesisContext.scala
+++ b/src/main/scala/leon/synthesis/SynthesisContext.scala
@@ -1,42 +1,33 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 
 import solvers._
-import solvers.combinators._
 import purescala.Definitions.{Program, FunDef}
 import evaluators._
 
 /**
  * This is global information per entire search, contains necessary information
  */
-case class SynthesisContext(
+class SynthesisContext(
   context: LeonContext,
-  settings: SynthesisSettings,
-  functionContext: FunDef,
-  program: Program
+  val settings: SynthesisSettings,
+  val functionContext: FunDef,
+  val program: Program
+) extends LeonContext(
+    context.reporter,
+    context.interruptManager,
+    context.options,
+    context.files,
+    context.classDir,
+    context.timers
 ) {
 
-  val reporter = context.reporter
-
-  val rules = settings.rules
-
   val solverFactory = SolverFactory.getFromSettings(context, program)
 
   lazy val defaultEvaluator = {
     new DefaultEvaluator(context, program)
   }
-}
 
-object SynthesisContext {
-
-  def fromSynthesizer(synth: Synthesizer) = {
-    SynthesisContext(
-      synth.context,
-      synth.settings,
-      synth.ci.fd,
-      synth.program
-    )
-  }
 }
diff --git a/src/main/scala/leon/synthesis/SynthesisPhase.scala b/src/main/scala/leon/synthesis/SynthesisPhase.scala
index ac4d30614d8269ce78a92a95e232855eb40d9fbd..f40117cf140fadc374364bd9037478c64136ac03 100644
--- a/src/main/scala/leon/synthesis/SynthesisPhase.scala
+++ b/src/main/scala/leon/synthesis/SynthesisPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -10,7 +10,7 @@ import purescala.Definitions.{Program, FunDef}
 import leon.utils._
 import graph._
 
-object SynthesisPhase extends TransformationPhase {
+object SynthesisPhase extends UnitPhase[Program] {
   val name        = "Synthesis"
   val description = "Partial synthesis of \"choose\" constructs. Also used by repair during the synthesis stage."
 
@@ -22,14 +22,17 @@ object SynthesisPhase extends TransformationPhase {
   val optCEGISOptTimeout   = LeonFlagOptionDef("cegis:opttimeout", "Consider a time-out of CE-search as untrusted solution", true )
   val optCEGISVanuatoo     = LeonFlagOptionDef("cegis:vanuatoo",   "Generate inputs using new korat-style generator",        false)
   val optCEGISNaiveGrammar = LeonFlagOptionDef("cegis:naive",      "Use the old naive grammar for CEGIS",                    false)
-  val optCEGISMaxSize      = LeonLongOptionDef("cegis:maxsize",    "Maximum size of expressions synthesized by CEGIS", 5L, "N")
+  val optCEGISMaxSize      = LeonLongOptionDef("cegis:maxsize",    "Maximum size of expressions synthesized by CEGIS", 7L, "N")
+
+  // Other rule options
+  val optSpecifyRecCalls = LeonFlagOptionDef("reccalls", "Use full value as spec for introduced recursive calls", true)
 
   override val definedOptions : Set[LeonOptionDef[Any]] =
-    Set(optManual, optCostModel, optDerivTrees, optCEGISOptTimeout, optCEGISVanuatoo, optCEGISNaiveGrammar, optCEGISMaxSize)
+    Set(optManual, optCostModel, optDerivTrees, optCEGISOptTimeout, optCEGISVanuatoo, optCEGISNaiveGrammar, optCEGISMaxSize, optSpecifyRecCalls)
 
   def processOptions(ctx: LeonContext): SynthesisSettings = {
     val ms = ctx.findOption(optManual)
-    val timeout = ctx.findOption(SharedOptions.optTimeout)
+    val timeout = ctx.findOption(GlobalOptions.optTimeout)
     if (ms.isDefined && timeout.isDefined) {
       ctx.reporter.warning("Defining timeout with manual search")
     }
@@ -53,17 +56,16 @@ object SynthesisPhase extends TransformationPhase {
       timeoutMs = timeout map { _ * 1000 },
       generateDerivationTrees = ctx.findOptionOrDefault(optDerivTrees),
       costModel = costModel,
-      rules = Rules.all(ctx.findOptionOrDefault(optCEGISNaiveGrammar)) ++
-        (if(ms.isDefined) Seq(rules.AsChoose, rules.SygusCVC4) else Seq()),
+      rules = Rules.all(ctx.findOptionOrDefault(optCEGISNaiveGrammar)),
       manualSearch = ms,
-      functions = ctx.findOption(SharedOptions.optFunctions) map { _.toSet },
+      functions = ctx.findOption(GlobalOptions.optFunctions) map { _.toSet },
       cegisUseOptTimeout = ctx.findOptionOrDefault(optCEGISOptTimeout),
       cegisUseVanuatoo = ctx.findOptionOrDefault(optCEGISVanuatoo),
       cegisMaxSize = ctx.findOptionOrDefault(optCEGISMaxSize).toInt
     )
   }
 
-  def apply(ctx: LeonContext, program: Program): Program = {
+  def apply(ctx: LeonContext, program: Program): Unit = {
     val options = processOptions(ctx)
 
     val chooses = SourceInfo.extractFromProgram(ctx, program)
@@ -86,11 +88,12 @@ object SynthesisPhase extends TransformationPhase {
             dot.writeFile("derivation"+dotGenIds.nextGlobal+".dot")
           }
 
-          val (sol, _) = solutions.head
+          solutions.headOption foreach { case (sol, _) =>
+            val expr = sol.toSimplifiedExpr(ctx, program, ci.fd)
+            fd.body = fd.body.map(b => replace(Map(ci.source -> expr), b))
+            functions += fd
+          }
 
-          val expr = sol.toSimplifiedExpr(ctx, program)
-          fd.body = fd.body.map(b => replace(Map(ci.source -> expr), b))
-          functions += fd
         } finally {
           synthesizer.shutdown()
         }
@@ -103,7 +106,6 @@ object SynthesisPhase extends TransformationPhase {
       ctx.reporter.info("")
     }
 
-    program
   }
 
 }
diff --git a/src/main/scala/leon/synthesis/SynthesisSettings.scala b/src/main/scala/leon/synthesis/SynthesisSettings.scala
index 61dc24ece71081c0f02f5bdcb38d9d9eeb0fee14..5bbff9444ded17b5100b1bc5ba0c3949b7f4dc61 100644
--- a/src/main/scala/leon/synthesis/SynthesisSettings.scala
+++ b/src/main/scala/leon/synthesis/SynthesisSettings.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -18,6 +18,6 @@ case class SynthesisSettings(
   // Cegis related options
   cegisUseOptTimeout: Boolean = true,
   cegisUseVanuatoo  : Boolean = false,
-  cegisMaxSize: Int           = 5
+  cegisMaxSize: Int           = 7
 
 )
diff --git a/src/main/scala/leon/synthesis/Synthesizer.scala b/src/main/scala/leon/synthesis/Synthesizer.scala
index efd1ad13e0538f855487e94b7b1a35d7d893627f..c81b045d09c1aeccf8e2381afe9d14cb9a11db33 100644
--- a/src/main/scala/leon/synthesis/Synthesizer.scala
+++ b/src/main/scala/leon/synthesis/Synthesizer.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -12,7 +12,7 @@ import leon.utils._
 
 import scala.concurrent.duration._
 
-import synthesis.graph._
+import synthesis.strategies._
 
 class Synthesizer(val context : LeonContext,
                   val program: Program,
@@ -23,16 +23,27 @@ class Synthesizer(val context : LeonContext,
 
   val reporter = context.reporter
 
-  lazy val sctx = SynthesisContext.fromSynthesizer(this)
+  lazy val sctx = new SynthesisContext(context, settings, ci.fd, program)
 
   implicit val debugSection = leon.utils.DebugSectionSynthesis
 
   def getSearch: Search = {
-    if (settings.manualSearch.isDefined) {
-      new ManualSearch(context, ci, problem, settings.costModel, settings.manualSearch)
+    val strat0 = new CostBasedStrategy(context, settings.costModel)
+
+    val strat1 = if (settings.manualSearch.isDefined) {
+      new ManualStrategy(context, settings.manualSearch, strat0)
     } else {
-      new SimpleSearch(context, ci, problem, settings.costModel, settings.searchBound)
+      strat0
+    }
+
+    val strat2 = settings.searchBound match {
+      case Some(b) =>
+        BoundedStrategy(strat1, b)
+      case None =>
+        strat1
     }
+
+    new Search(context, ci, problem, strat2)
   }
 
   private var lastTime: Long = 0
@@ -63,7 +74,7 @@ class Synthesizer(val context : LeonContext,
 
     val result = sols.map {
       case sol if sol.isTrusted =>
-        (sol, true)
+        (sol, Some(true))
       case sol =>
         validateSolution(s, sol, 5.seconds)
     }
@@ -86,10 +97,15 @@ class Synthesizer(val context : LeonContext,
 
       val (size, calls, proof) = result.headOption match {
         case Some((sol, trusted)) =>
-          val expr = sol.toSimplifiedExpr(context, program)
-          (formulaSize(expr), functionCallsOf(expr).size, if (trusted) "$\\surd$" else "")
+          val expr = sol.toSimplifiedExpr(context, program, ci.fd)
+          val pr = trusted match {
+            case Some(true) => "✓"
+            case Some(false) => "✗"
+            case None => "?"
+          }
+          (formulaSize(expr), functionCallsOf(expr).size, pr)
         case _ =>
-          (0, 0, "X")
+          (0, 0, "F")
       }
 
       val date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())
@@ -97,20 +113,24 @@ class Synthesizer(val context : LeonContext,
       val fw = new java.io.FileWriter("synthesis-report.txt", true)
 
       try {
-        fw.write(f"$date:  $benchName%-50s & $psize%4d & $size%4d & $calls%4d & $proof%7s & $time%2.1f \\\\\n")
+        fw.write(f"$date:  $benchName%-50s | $psize%4d | $size%4d | $calls%4d | $proof%7s | $time%2.1f \n")
       } finally {
         fw.close
       }
     }(DebugSectionReport)
 
     (s, if (result.isEmpty && allowPartial) {
-      List((new PartialSolution(s.g, true).getSolution, false)).toStream
+      Stream((new PartialSolution(s.strat, true).getSolutionFor(s.g.root), false))
     } else {
-      result
+      // Discard invalid solutions
+      result collect {
+        case (sol, Some(true)) => (sol, true)
+        case (sol, None)       => (sol, false)
+      }
     })
   }
 
-  def validateSolution(search: Search, sol: Solution, timeout: Duration): (Solution, Boolean) = {
+  def validateSolution(search: Search, sol: Solution, timeout: Duration): (Solution, Option[Boolean]) = {
     import verification.VerificationPhase._
     import verification.VerificationContext
 
@@ -126,15 +146,15 @@ class Synthesizer(val context : LeonContext,
       val vcreport = checkVCs(vctx, vcs)
 
       if (vcreport.totalValid == vcreport.totalConditions) {
-        (sol, true)
+        (sol, Some(true))
       } else if (vcreport.totalValid + vcreport.totalUnknown == vcreport.totalConditions) {
         reporter.warning("Solution may be invalid:")
-        (sol, false)
+        (sol, None)
       } else {
-        reporter.warning("Solution was invalid:")
-        reporter.warning(fds.map(ScalaPrinter(_)).mkString("\n\n"))
-        reporter.warning(vcreport.summaryString)
-        (new PartialSolution(search.g, false).getSolution, false)
+        reporter.error("Solution was invalid:")
+        reporter.error(fds.map(ScalaPrinter(_)).mkString("\n\n"))
+        reporter.error(vcreport.summaryString)
+        (new PartialSolution(search.strat, false).getSolutionFor(search.g.root), Some(false))
       }
     } finally {
       solverf.shutdown()
@@ -145,7 +165,7 @@ class Synthesizer(val context : LeonContext,
   def solutionToProgram(sol: Solution): (Program, List[FunDef]) = {
     // We replace the choose with the body of the synthesized solution
 
-    val solutionExpr = sol.toSimplifiedExpr(context, program)
+    val solutionExpr = sol.toSimplifiedExpr(context, program, ci.fd)
 
     val (npr, fdMap) = replaceFunDefs(program)({
       case fd if fd eq ci.fd =>
diff --git a/src/main/scala/leon/synthesis/Witnesses.scala b/src/main/scala/leon/synthesis/Witnesses.scala
index 0325c4a8a10bbe460050a63ff0c65d326fd9662e..884eee9f03413502dc965bf959cc0e49ffd24542 100644
--- a/src/main/scala/leon/synthesis/Witnesses.scala
+++ b/src/main/scala/leon/synthesis/Witnesses.scala
@@ -1,10 +1,9 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.synthesis
 
 import leon.purescala._
 import Types._
-import Definitions.TypedFunDef
 import Extractors._
 import Expressions.Expr
 import PrinterHelpers._
@@ -13,21 +12,30 @@ object Witnesses {
   
   abstract class Witness extends Expr with Extractable with PrettyPrintable {
     val getType = BooleanType
+    override def isSimpleExpr = true
   }
   
   case class Guide(e : Expr) extends Witness {
     def extract: Option[(Seq[Expr], Seq[Expr] => Expr)] = Some((Seq(e), (es: Seq[Expr]) => Guide(es.head)))
 
     override def printWith(implicit pctx: PrinterContext): Unit = {
-      p"⊙ {$e}"
+      p"⊙{$e}"
     }
   }
-  
-  case class Terminating(tfd: TypedFunDef, args: Seq[Expr]) extends Witness {
-    def extract: Option[(Seq[Expr], Seq[Expr] => Expr)] = Some((args, Terminating(tfd, _)))
+
+  case class Terminating(fi: Expr) extends Witness {
+    def extract: Option[(Seq[Expr], Seq[Expr] => Expr)] = Some(( Seq(fi), { case Seq(fi) => Terminating(fi) }))
+
+    override def printWith(implicit pctx: PrinterContext): Unit = {
+      p"↓$fi"
+    }
+  }
+
+  case class Hint(e: Expr) extends Witness {
+    def extract: Option[(Seq[Expr], Seq[Expr] => Expr)] = Some(( Seq(e), { case Seq(e) => Hint(e) }))
 
     override def printWith(implicit pctx: PrinterContext): Unit = {
-      p"↓ ${tfd.id}($args)"
+      p"è°¶$e"
     }
   }
   
diff --git a/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala b/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala
index e5071b9b4ecbdcde1d1b5a339b486c7820d20bfc..8f0eb70cd9f9939e2b82f16b3bb12e8827b0ea92 100644
--- a/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala
+++ b/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala
@@ -1,15 +1,17 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package synthesis
 package disambiguation
 
 import purescala.Types.FunctionType
-import purescala.Common.FreshIdentifier
+import purescala.Common.{FreshIdentifier, Identifier}
 import purescala.Constructors.{ and, tupleWrap }
 import purescala.Definitions.{ FunDef, Program, ValDef }
 import purescala.ExprOps
 import purescala.Extractors.TopLevelAnds
 import purescala.Expressions._
+import leon.utils.Simplifiers
 
 /**
  * @author Mikael
@@ -53,6 +55,37 @@ class ExamplesAdder(ctx0: LeonContext, program: Program) {
   
   private def filterCases(cases: Seq[MatchCase]) = cases.filter(c => c.optGuard != Some(BooleanLiteral(false)))
   
+  def addToExpr(_post: Expr, id: Identifier, inputVariables: Expr, newCases: Seq[MatchCase]): Expr = {
+    val post=  Simplifiers.bestEffort(ctx0, program)(_post)
+    if(purescala.ExprOps.exists(_.isInstanceOf[Passes])(post)) {
+      post match {
+        case TopLevelAnds(exprs) =>
+          val i = exprs.lastIndexWhere { x => x match {
+            case Passes(in, out, cases) if in == inputVariables && out == Variable(id) => true
+            case _ => false
+          } }
+          if(i == -1) {
+            Lambda(Seq(ValDef(id)), and(post, Passes(inputVariables, Variable(id), newCases)))
+            //ctx0.reporter.info("No top-level passes in postcondition, adding it:  " + fd)
+          } else {
+            val newPasses = exprs(i) match {
+              case Passes(in, out, cases) =>
+                Passes(in, out, (filterCases(cases) ++ newCases).distinct )
+              case _ => ???
+            }
+            val newPost = and(exprs.updated(i, newPasses) : _*)
+            Lambda(Seq(ValDef(id)), newPost)
+            //ctx0.reporter.info("Adding the example to the passes postcondition: " + fd)
+          }
+      }
+    } else {
+      Lambda(Seq(ValDef(id)), and(post, Passes(inputVariables, Variable(id), newCases)))
+      //ctx0.reporter.info("No passes in postcondition, adding it:" + fd)
+    }
+    
+    
+  }
+  
   /** Adds the given input/output examples to the function definitions */
   def addToFunDef(fd: FunDef, examples: Seq[(Expr, Expr)]): Unit = {
     val params = if(_removeFunctionParameters) fd.params.filter(x => !x.getType.isInstanceOf[FunctionType]) else fd.params
@@ -60,38 +93,14 @@ class ExamplesAdder(ctx0: LeonContext, program: Program) {
     val newCases = examples.map{ case (in, out) => exampleToCase(in, out) }
     fd.postcondition match {
       case Some(Lambda(Seq(ValDef(id)), post)) =>
-        if(fd.postcondition.exists { e => purescala.ExprOps.exists(_.isInstanceOf[Passes])(e) }) {
-          post match {
-            case TopLevelAnds(exprs) =>
-              val i = exprs.lastIndexWhere { x => x match {
-                case Passes(in, out, cases) if in == inputVariables && out == Variable(id) => true
-                case _ => false
-              } }
-              if(i == -1) {
-                fd.postcondition = Some(Lambda(Seq(ValDef(id)), and(post, Passes(inputVariables, Variable(id), newCases))))
-                //ctx0.reporter.info("No top-level passes in postcondition, adding it:  " + fd)
-              } else {
-                val newPasses = exprs(i) match {
-                  case Passes(in, out, cases) =>
-                    Passes(in, out, (filterCases(cases) ++ newCases).distinct )
-                  case _ => ???
-                }
-                val newPost = and(exprs.updated(i, newPasses) : _*)
-                fd.postcondition = Some(Lambda(Seq(ValDef(id)), newPost))
-                //ctx0.reporter.info("Adding the example to the passes postcondition: " + fd)
-              }
-          }
-        } else {
-          fd.postcondition = Some(Lambda(Seq(ValDef(id)), and(post, Passes(inputVariables, Variable(id), newCases))))
-          //ctx0.reporter.info("No passes in postcondition, adding it:" + fd)
-        }
+        fd.postcondition = Some(addToExpr(post, id, inputVariables, newCases))
       case None =>
         val id = FreshIdentifier("res", fd.returnType, false)
-        fd.postcondition = Some(Lambda(Seq(ValDef(id)), Passes(inputVariables, Variable(id), newCases)))
-        //ctx0.reporter.info("No postcondition, adding it: " + fd)
+        fd.postcondition = Some(addToExpr(BooleanLiteral(true), id, inputVariables, newCases))
     }
     fd.body match { // TODO: Is it correct to discard the choose construct inside the body?
-      case Some(Choose(Lambda(Seq(ValDef(id)), bodyChoose))) => fd.body = Some(Hole(id.getType, Nil))
+      case Some(Choose(Lambda(Seq(ValDef(id)), bodyChoose))) =>
+        fd.body = Some(Choose(addToExpr(bodyChoose, id, inputVariables, newCases)))
       case _ =>
     }
   }
diff --git a/src/main/scala/leon/synthesis/disambiguation/Question.scala b/src/main/scala/leon/synthesis/disambiguation/Question.scala
index eed7bfc1a7337a8282224677198286443335ea90..985efaed19d16350f248d3147d9b2a2010d7e91c 100644
--- a/src/main/scala/leon/synthesis/disambiguation/Question.scala
+++ b/src/main/scala/leon/synthesis/disambiguation/Question.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package synthesis.disambiguation
 
diff --git a/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala b/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala
index 81f98f86432dc54ffb446f473fee3a1afcf358ca..8e3947da0cffcacf6b3c0aad8339bef880fe4e1c 100644
--- a/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala
+++ b/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package synthesis.disambiguation
 
@@ -67,7 +69,7 @@ object QuestionBuilder {
   }
   
   /** Specific enumeration of strings, which can be used with the QuestionBuilder#setValueEnumerator method */
-  object SpecialStringValueGrammar extends ExpressionGrammar[TypeTree] {
+  object SpecialStringValueGrammar extends SimpleExpressionGrammar {
     def computeProductions(t: TypeTree)(implicit ctx: LeonContext): Seq[Prod] = t match {
       case StringType =>
         List(
@@ -107,7 +109,7 @@ class QuestionBuilder[T <: Expr](
   private var solutionsToTake = 30
   private var expressionsToTake = 30
   private var keepEmptyAlternativeQuestions: T => Boolean = Set()
-  private var value_enumerator: ExpressionGrammar[TypeTree] = ValueGrammar
+  private var value_enumerator: ExpressionGrammar = ValueGrammar
 
   /** Sets the way to sort questions. See [[QuestionSortingType]] */
   def setSortQuestionBy(questionSorMethod: QuestionSortingType) = { _questionSorMethod = questionSorMethod; this }
@@ -122,7 +124,7 @@ class QuestionBuilder[T <: Expr](
   /** Sets if when there is no alternative, the question should be kept. */
   def setKeepEmptyAlternativeQuestions(b: T => Boolean) = {keepEmptyAlternativeQuestions = b; this }
   /** Sets the way to enumerate expressions */
-  def setValueEnumerator(v: ExpressionGrammar[TypeTree]) = value_enumerator = v
+  def setValueEnumerator(v: ExpressionGrammar) = value_enumerator = v
   
   private def run(s: Solution, elems: Seq[(Identifier, Expr)]): Option[Expr] = {
     val newProgram = DefOps.addFunDefs(p, s.defs, p.definedFunctions.head)
diff --git a/src/main/scala/leon/synthesis/graph/DotGenerator.scala b/src/main/scala/leon/synthesis/graph/DotGenerator.scala
index 78ef7b371487a6711d3508b9712f7806e9c551e0..d1ba7a040c276b83b64ee7e7f8ecd07ee1adefcc 100644
--- a/src/main/scala/leon/synthesis/graph/DotGenerator.scala
+++ b/src/main/scala/leon/synthesis/graph/DotGenerator.scala
@@ -1,16 +1,17 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
-package leon.synthesis.graph
+package leon.synthesis
+package graph
 
 import leon.utils.UniqueCounter
 
 import java.io.{File, FileWriter, BufferedWriter}
 
 class DotGenerator(search: Search) {
-
   implicit val ctx = search.ctx
 
   val g = search.g
+  val strat = search.strat
 
   private val idCounter = new UniqueCounter[Unit]
   idCounter.nextGlobal // Start with 1
@@ -35,7 +36,7 @@ class DotGenerator(search: Search) {
 
     // Print all nodes
     val edges = collectEdges(g.root)
-    val nodes = edges.flatMap(e => Set(e._1, e._2))
+    val nodes = edges.flatMap(e => Set(e._1, e._3))
 
     var nodesToNames = Map[Node, String]()
 
@@ -52,12 +53,12 @@ class DotGenerator(search: Search) {
       nodesToNames += n -> name
     }
 
-    for ((f,t) <- edges) {
+    for ((f,i,t) <- edges) {
       val label = f match {
         case ot: OrNode =>
           "or"
         case at: AndNode =>
-          ""
+          i.toString
       }
 
       val style = if (f.selected contains t) {
@@ -74,7 +75,7 @@ class DotGenerator(search: Search) {
     res.toString
   }
 
-  def limit(o: Any, length: Int = 40): String = {
+  def limit(o: Any, length: Int = 200): String = {
     val str = o.toString
     if (str.length > length) {
       str.substring(0, length-3)+"..."
@@ -107,13 +108,7 @@ class DotGenerator(search: Search) {
 
     res append " "+name+" [ label = <<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">"
     
-    //cost
-    n match {
-      case an: AndNode =>
-        res append "<TR><TD BORDER=\"0\">"+escapeHTML(n.cost.asString)+" ("+escapeHTML(g.cm.andNode(an, None).asString)+")</TD></TR>"
-      case on: OrNode =>
-        res append "<TR><TD BORDER=\"0\">"+escapeHTML(n.cost.asString)+"</TD></TR>"
-    }
+    res append "<TR><TD BORDER=\"0\">"+escapeHTML(strat.debugInfoFor(n))+"</TD></TR>"
 
     res append "<TR><TD BORDER=\"1\" BGCOLOR=\""+color+"\">"+escapeHTML(limit(index + nodeDesc(n)))+"</TD></TR>"
 
@@ -125,9 +120,9 @@ class DotGenerator(search: Search) {
 
   }
 
-  private def collectEdges(from: Node): Set[(Node, Node)] = {
-    from.descendants.flatMap { d =>
-      Set(from -> d) ++ collectEdges(d)
+  private def collectEdges(from: Node): Set[(Node, Int, Node)] = {
+    from.descendants.zipWithIndex.flatMap { case (d, i) =>
+      Set((from, i, d)) ++ collectEdges(d)
     }.toSet
   }
 }
diff --git a/src/main/scala/leon/synthesis/graph/Graph.scala b/src/main/scala/leon/synthesis/graph/Graph.scala
index 6183c2858d74ff3e82d5b5c4dc1a4354265d040f..af52ea5b91b52c062aea216d6548dfa4cf1af86a 100644
--- a/src/main/scala/leon/synthesis/graph/Graph.scala
+++ b/src/main/scala/leon/synthesis/graph/Graph.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -7,8 +7,8 @@ package graph
 import leon.utils.StreamUtils.cartesianProduct
 import leon.utils.DebugSectionSynthesis
 
-sealed class Graph(val cm: CostModel, problem: Problem) {
-  val root = new RootNode(cm, problem)
+sealed class Graph(problem: Problem) {
+  val root = new RootNode(problem)
 
   // Returns closed/total
   def getStats(from: Node = root): (Int, Int) = {
@@ -27,14 +27,15 @@ sealed class Graph(val cm: CostModel, problem: Problem) {
   }
 }
 
-sealed abstract class Node(cm: CostModel, val parent: Option[Node]) {
+sealed abstract class Node(val parent: Option[Node]) extends Printable {
 
   def asString(implicit ctx: LeonContext): String
 
   var descendants: List[Node] = Nil
   // indicates whether this particular node has already been expanded
   var isExpanded: Boolean = false
-  def expand(hctx: SearchContext)
+
+  def expand(implicit hctx: SearchContext)
 
   val p: Problem
 
@@ -45,12 +46,9 @@ sealed abstract class Node(cm: CostModel, val parent: Option[Node]) {
   var solutions: Option[Stream[Solution]] = None
   var selectedSolution = -1
 
-  // Costs
-  var cost: Cost = computeCost()
+  var isDeadEnd: Boolean = false
 
-  def isDeadEnd: Boolean = {
-    cm.isImpossible(cost)
-  }
+  def isOpen = !isDeadEnd && !isSolved
 
   // For non-terminals, selected children for solution
   var selected: List[Node] = Nil
@@ -63,96 +61,69 @@ sealed abstract class Node(cm: CostModel, val parent: Option[Node]) {
       composeSolutions(selected.map(n => n.generateSolutions()))
     }
   }
-
-  def computeCost(): Cost = solutions match {
-    case Some(sols) if sols.isEmpty =>
-      cm.impossible
-
-    case Some(sols) =>
-      if (sols.hasDefiniteSize) {
-        sols.map { sol => cm.solution(sol) } .min
-      } else {
-        cm.solution(sols.head)
-      }
-
-    case None =>
-      val costs = if (isExpanded) {
-        Some(descendants.map { _.cost })
-      } else {
-        None
-      }
-
-      this match {
-        case an: AndNode =>
-          cm.andNode(an, costs)
-
-        case on: OrNode =>
-          costs.map(_.min).getOrElse(cm.problem(on.p))
-      }
-  }
-
-  def updateCost(): Unit = {
-    cost = computeCost()
-    parent.foreach(_.updateCost())
-  }
 }
 
 /** Represents the conjunction of search nodes.
-  * @param cm The cost model used when prioritizing, evaluating and expanding
   * @param parent Some node. None if it is the root node.
   * @param ri The rule instantiation that created this AndNode.
   **/
-class AndNode(cm: CostModel, parent: Option[Node], val ri: RuleInstantiation) extends Node(cm, parent) {
+class AndNode(parent: Option[Node], val ri: RuleInstantiation) extends Node(parent) {
   val p = ri.problem
 
   override def asString(implicit ctx: LeonContext) = "\u2227 "+ri.asString
 
-  def expand(hctx: SearchContext): Unit = {
+  def expand(implicit hctx: SearchContext): Unit = {
     require(!isExpanded)
     isExpanded = true
 
-    implicit val ctx = hctx.sctx.context
+    def pad(prefix: String, message: String): String = {
+      val lines = message.split("\\n").toList
+      val padding = " " * (prefix.length + 1)
+      prefix + " " + lines.head + "\n" + lines.tail.map(padding + _).mkString("\n")
+    }
 
-    import hctx.sctx.reporter.info
+    import hctx.reporter.info
 
-    val prefix = f"[${Option(ri.rule).getOrElse("?")}%-20s] "
+    val prefix = f"[${Option(ri.rule.asString).getOrElse("?")}%-20s]"
 
-    info(prefix+ri.problem.asString)
+    info(pad(prefix, ri.problem.asString))
 
     ri.apply(hctx) match {
       case RuleClosed(sols) =>
         solutions = Some(sols)
         selectedSolution = 0
 
-        updateCost()
-
         isSolved = sols.nonEmpty
 
         if (sols.isEmpty) {
-          info(prefix+"Failed")
+          info(s"$prefix Failed")
+          isDeadEnd = true
         } else {
           val sol = sols.head
-          info(prefix+"Solved"+(if(sol.isTrusted) "" else " (untrusted)")+" with: "+sol.asString+"...")
+          val morePrefix = s"$prefix Solved ${if(sol.isTrusted) "" else "(untrusted)"} with: "
+          info(pad(morePrefix, sol.asString))
         }
 
         parent.foreach{ p =>
-          p.updateCost()
           if (isSolved) {
             p.onSolved(this)
           }
         }
 
       case RuleExpanded(probs) =>
-        info(prefix+"Decomposed into:")
-        for(p <- probs) {
-          info(prefix+"     - "+p.asString)
+        info(s"$prefix Decomposed into:")
+        val morePrefix = s"$prefix -"
+        for(p <- probs) { 
+          info(pad(morePrefix, p.asString))
         }
 
-        descendants = probs.map(p => new OrNode(cm, Some(this), p))
+        descendants = probs.map(p => new OrNode(Some(this), p))
 
-        selected = descendants
+        if (descendants.isEmpty) {
+          isDeadEnd = true
+        }
 
-        updateCost()
+        selected = descendants
     }
   }
 
@@ -177,43 +148,44 @@ class AndNode(cm: CostModel, parent: Option[Node], val ri: RuleInstantiation) ex
 
 }
 
-class OrNode(cm: CostModel, parent: Option[Node], val p: Problem) extends Node(cm, parent) {
+class OrNode(parent: Option[Node], val p: Problem) extends Node(parent) {
 
   override def asString(implicit ctx: LeonContext) = "\u2228 "+p.asString
 
   implicit val debugSection = DebugSectionSynthesis
   
   def getInstantiations(hctx: SearchContext): List[RuleInstantiation] = {
-    val rules = hctx.sctx.rules
+    val rules = hctx.settings.rules
 
     val rulesPrio = rules.groupBy(_.priority).toSeq.sortBy(_._1)
 
-    for ((_, rs) <- rulesPrio) {
+    for ((prio, rs) <- rulesPrio) {
       
       val results = rs.flatMap{ r =>
-        hctx.context.reporter.ifDebug(printer => printer("Testing rule: " + r))
-        hctx.context.timers.synthesis.instantiations.get(r.asString(hctx.sctx.context)).timed {
+        hctx.reporter.ifDebug(printer => printer("Testing rule: " + r))
+        hctx.timers.synthesis.instantiations.get(r.asString(hctx)).timed {
           r.instantiateOn(hctx, p)
         }
       }.toList
 
       if (results.nonEmpty) {
-        return results
+        // We want to force all NormalizingRule's anyway, so no need to branch out.
+        // Just force the first one, and the rest may be applied afterwards.
+        return if (prio == RulePriorityNormalizing) results.take(1) else results
       }
     }
+
     Nil
   }
 
-  def expand(hctx: SearchContext): Unit = {
+  def expand(implicit hctx: SearchContext): Unit = {
     require(!isExpanded)
 
     val ris = getInstantiations(hctx)
 
-    descendants = ris.map(ri => new AndNode(cm, Some(this), ri))
+    descendants = ris.map(ri => new AndNode(Some(this), ri))
     selected = List()
 
-    updateCost()
-
     isExpanded = true
   }
 
@@ -228,4 +200,4 @@ class OrNode(cm: CostModel, parent: Option[Node], val p: Problem) extends Node(c
   }
 }
 
-class RootNode(cm: CostModel, p: Problem) extends OrNode(cm, None, p)
+class RootNode(p: Problem) extends OrNode(None, p)
diff --git a/src/main/scala/leon/synthesis/graph/Search.scala b/src/main/scala/leon/synthesis/graph/Search.scala
deleted file mode 100644
index c630e315d9777110b5dcde7adc42cf6172161af3..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/synthesis/graph/Search.scala
+++ /dev/null
@@ -1,323 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package synthesis
-package graph
-
-import scala.annotation.tailrec
-
-import scala.collection.mutable.ArrayBuffer
-import leon.utils.Interruptible
-import java.util.concurrent.atomic.AtomicBoolean
-
-abstract class Search(val ctx: LeonContext, ci: SourceInfo, p: Problem, costModel: CostModel) extends Interruptible {
-  val g = new Graph(costModel, p)
-
-  def findNodeToExpandFrom(n: Node): Option[Node]
-
-  val interrupted = new AtomicBoolean(false)
-
-  def doStep(n: Node, sctx: SynthesisContext): Unit = {
-    ctx.timers.synthesis.step.timed {
-      n match {
-        case an: AndNode =>
-          ctx.timers.synthesis.applications.get(an.ri.asString(sctx.context)).timed {
-            an.expand(SearchContext(sctx, ci, an, this))
-          }
-
-        case on: OrNode =>
-          on.expand(SearchContext(sctx, ci, on, this))
-      }
-    }
-  }
-
-  @tailrec
-  final def searchFrom(sctx: SynthesisContext, from: Node): Boolean = {
-    findNodeToExpandFrom(from) match {
-      case Some(n) =>
-        doStep(n, sctx)
-
-        if (from.isSolved) {
-          true
-        } else if (interrupted.get) {
-          false
-        } else {
-          searchFrom(sctx, from)
-        }
-      case None =>
-        false
-    }
-  }
-
-  def traversePathFrom(n: Node, path: List[Int]): Option[Node] = path match {
-    case Nil =>
-      Some(n)
-    case x :: xs =>
-      if (n.isExpanded && n.descendants.size > x) {
-        traversePathFrom(n.descendants(x), xs)
-      } else {
-        None
-      }
-  }
-
-  def traversePath(path: List[Int]): Option[Node] = {
-    traversePathFrom(g.root, path)
-  }
-
-  def search(sctx: SynthesisContext): Stream[Solution] = {
-    if (searchFrom(sctx, g.root)) {
-      g.root.generateSolutions()
-    } else {
-      Stream.empty
-    }
-  }
-
-  def interrupt(): Unit = {
-    interrupted.set(true)
-  }
-
-  def recoverInterrupt(): Unit = {
-    interrupted.set(false)
-  }
-
-  ctx.interruptManager.registerForInterrupts(this)
-}
-
-class SimpleSearch(ctx: LeonContext, ci: SourceInfo, p: Problem, costModel: CostModel, bound: Option[Int]) extends Search(ctx, ci, p, costModel) {
-  val expansionBuffer = ArrayBuffer[Node]()
-
-  def findIn(n: Node) {
-    if (!n.isExpanded) {
-      expansionBuffer += n
-    } else if (!n.isDeadEnd) {
-      n match {
-        case an: AndNode =>
-          an.descendants.foreach(findIn)
-
-        case on: OrNode =>
-          if (on.descendants.nonEmpty) {
-            findIn(on.descendants.minBy(_.cost))
-          }
-      }
-    }
-  }
-
-  var counter = 0
-
-  def findNodeToExpandFrom(from: Node): Option[Node] = {
-    counter += 1
-    ctx.timers.synthesis.search.find.timed {
-      if (bound.isEmpty || counter <= bound.get) {
-        if (expansionBuffer.isEmpty) {
-          findIn(from)
-        }
-
-        if (expansionBuffer.nonEmpty) {
-          Some(expansionBuffer.remove(0))
-        } else {
-          None
-        }
-      } else {
-        None
-      }
-    }
-  }
-}
-
-class ManualSearch(ctx: LeonContext, ci: SourceInfo, problem: Problem, costModel: CostModel, initCmd: Option[String]) extends Search(ctx, ci, problem, costModel) {
-  import ctx.reporter._
-
-  abstract class Command
-  case class Cd(path: List[Int]) extends Command
-  case object Parent extends Command
-  case object Quit extends Command
-  case object Noop extends Command
-
-  // Manual search state:
-  var cd       = List[Int]()
-  var cmdQueue = initCmd.map( str => parseCommands(parseString(str))).getOrElse(Nil)
-
-  def getNextCommand(): Command = cmdQueue match {
-    case c :: cs =>
-      cmdQueue = cs
-      c
-
-    case Nil =>
-      print("Next action? (q to quit) "+cd.mkString(" ")+" $ ")
-      val line = scala.io.StdIn.readLine()
-      val parts = parseString(line)
-
-      cmdQueue = parseCommands(parts)
-      getNextCommand()
-  }
-
-  def parseString(s: String): List[String] = {
-    s.trim.split("\\s+|,").toList
-  }
-
-  def parseCommands(tokens: List[String]): List[Command] = tokens match {
-    case "cd" :: ".." :: ts =>
-      Parent :: parseCommands(ts)
-
-    case "cd" :: ts =>
-      val path = ts.takeWhile { t => t.forall(_.isDigit) }
-
-      if (path.isEmpty) {
-        parseCommands(ts)
-      } else {
-        Cd(path.map(_.toInt)) :: parseCommands(ts.drop(path.size))
-      }
-
-    case "q" :: ts =>
-      Quit :: Nil
-
-    case Nil  | "" :: Nil =>
-      Nil
-
-    case ts =>
-      val path = ts.takeWhile { t => t.forall(_.isDigit) }
-
-      if (path.isEmpty) {
-        error("Unknown command "+ts.head)
-        parseCommands(ts.tail)
-      } else {
-        Cd(path.map(_.toInt)) :: parseCommands(ts.drop(path.size))
-      }
-  }
-
-  override def doStep(n: Node, sctx: SynthesisContext) = {
-    super.doStep(n, sctx)
-
-    // Backtrack view to a point where node is neither closed nor solved
-    if (n.isDeadEnd || n.isSolved) {
-      var from: Node = g.root
-      var newCd = List[Int]()
-
-      while (!from.isSolved && !from.isDeadEnd && newCd.size < cd.size) {
-        val cdElem = cd(newCd.size)
-        from = traversePathFrom(from, List(cdElem)).get
-        if (!from.isSolved && !from.isDeadEnd) {
-          newCd = cdElem :: newCd
-        }
-      }
-
-      cd = newCd.reverse
-    }
-  }
-
-
-  def printGraph() {
-    def title(str: String)    = "\u001b[1m"  + str + "\u001b[0m"
-    def failed(str: String)   = "\u001b[31m" + str + "\u001b[0m"
-    def solved(str: String)   = "\u001b[32m" + str + "\u001b[0m"
-    def expanded(str: String) = "\u001b[33m" + str + "\u001b[0m"
-
-    def displayNode(n: Node): String = n match {
-      case an: AndNode =>
-        val app = an.ri.asString(ctx)
-        s"(${n.cost.asString}) ${indent(app)}"
-      case on: OrNode =>
-        val p = on.p.asString(ctx)
-        s"(${n.cost.asString}) ${indent(p)}"
-    }
-
-    def indent(a: String): String = {
-      a.replaceAll("\n", "\n"+(" "*12))
-    }
-
-    def pathToString(cd: List[Int]): String = {
-      cd.map(i => f"$i%2d").mkString(" ")
-    }
-
-    def displayPath(n: Node, cd: List[Int]) {
-      if (cd.isEmpty) {
-        println(title(pathToString(cd)+" \u2510 "+displayNode(n)))
-
-        for ((sn, i) <- n.descendants.zipWithIndex) {
-          val sp = cd ::: List(i)
-
-          if (sn.isSolved) {
-            println(solved(pathToString(sp)+" \u2508 "+displayNode(sn)))
-          } else if (sn.isDeadEnd) {
-            println(failed(pathToString(sp)+" \u2508 "+displayNode(sn)))
-          } else if (sn.isExpanded) {
-            println(expanded(pathToString(sp)+" \u2508 "+displayNode(sn)))
-          } else {
-            println(pathToString(sp)+" \u2508 "+displayNode(sn))
-          }
-        }
-      } else {
-        displayPath(n.descendants(cd.head), cd.tail)
-      }
-    }
-
-    println("-"*120)
-    displayPath(g.root, cd)
-    println("-"*120)
-  }
-
-  var continue = true
-
-  def findNodeToExpandFrom(from: Node): Option[Node] = {
-    if (!from.isExpanded) {
-      Some(from)
-    } else {
-      var res: Option[Option[Node]] = None
-
-      while(res.isEmpty) {
-        printGraph()
-
-        try {
-          getNextCommand() match {
-            case Quit =>
-              continue = false
-              res = Some(None)
-            case Parent =>
-              if (cd.nonEmpty) {
-                cd = cd.dropRight(1)
-              } else {
-                error("Already at root node")
-              }
-
-            case Cd(path) =>
-              var currentNode = from
-              var currentPath = cd ++ path
-              cd = Nil
-              while (currentPath.nonEmpty && currentNode.isExpanded && res.isEmpty) {
-                traversePathFrom(currentNode, List(currentPath.head)) match {
-                  case Some(n) =>
-                    cd = cd ::: List(currentPath.head)
-                    currentNode = n
-                    currentPath = currentPath.tail
-
-                  case None =>
-                    warning("Unknown path: "+ (path mkString "/"))
-                    //res = Some(None)
-                    return findNodeToExpandFrom(from) 
-                }
-              }
-
-              if (currentPath.nonEmpty) {
-                cmdQueue = Cd(currentPath) :: cmdQueue
-              }
-
-              if (!currentNode.isExpanded) {
-                res = Some(Some(currentNode))
-              }
-          }
-        } catch {
-          case e: java.lang.NumberFormatException =>
-
-          case e: java.io.IOException =>
-            continue = false
-
-          case e: Throwable =>
-            error("Woops: "+e.getMessage)
-            e.printStackTrace()
-        }
-      }
-
-      res.get
-    }
-  }
-}
diff --git a/src/main/scala/leon/synthesis/package.scala b/src/main/scala/leon/synthesis/package.scala
index 3cb5f541753f2188ea54c01e16868aa3dad5ca70..50bb935c0037cee52cb580920643cc63a0d501dd 100644
--- a/src/main/scala/leon/synthesis/package.scala
+++ b/src/main/scala/leon/synthesis/package.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 
diff --git a/src/main/scala/leon/synthesis/programsets/DirectProgramSet.scala b/src/main/scala/leon/synthesis/programsets/DirectProgramSet.scala
index 2887c57fcb80b26e40bf07324b8dc8a0bfc5b5eb..692bc2189c9e9717711c2533e0b825c9515d794f 100644
--- a/src/main/scala/leon/synthesis/programsets/DirectProgramSet.scala
+++ b/src/main/scala/leon/synthesis/programsets/DirectProgramSet.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.synthesis.programsets
 
 import leon.purescala
diff --git a/src/main/scala/leon/synthesis/programsets/JoinProgramSet.scala b/src/main/scala/leon/synthesis/programsets/JoinProgramSet.scala
index c0147227a9cacfa0d52b0d94728f1585d3e0cef7..90c9dc99a6f2bfd6f9d5006f7dda5bc2ea2ef413 100644
--- a/src/main/scala/leon/synthesis/programsets/JoinProgramSet.scala
+++ b/src/main/scala/leon/synthesis/programsets/JoinProgramSet.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package synthesis.programsets
 
diff --git a/src/main/scala/leon/synthesis/programsets/ProgramSet.scala b/src/main/scala/leon/synthesis/programsets/ProgramSet.scala
index ebfcf8fa19de9036c1b6d7e4d2c862038cde8756..2e2b1ab2f219aaa9869607a4ae3634a43e750945 100644
--- a/src/main/scala/leon/synthesis/programsets/ProgramSet.scala
+++ b/src/main/scala/leon/synthesis/programsets/ProgramSet.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.synthesis.programsets
 
 import leon.purescala
diff --git a/src/main/scala/leon/synthesis/programsets/UnionProgramset.scala b/src/main/scala/leon/synthesis/programsets/UnionProgramset.scala
index f57c53053fc661c6b0d644d720724fdd7a227bdc..bf49d819509cbd7b239573e0221f0c1e1e2b15fc 100644
--- a/src/main/scala/leon/synthesis/programsets/UnionProgramset.scala
+++ b/src/main/scala/leon/synthesis/programsets/UnionProgramset.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package synthesis.programsets
 
diff --git a/src/main/scala/leon/synthesis/rules/ADTDual.scala b/src/main/scala/leon/synthesis/rules/ADTDual.scala
index ed7c0652b60384f362bbecc9db8dd93d9a2e2523..40ab91bc6ad8d3a7843c38f3a96e46c1a0a9cd4c 100644
--- a/src/main/scala/leon/synthesis/rules/ADTDual.scala
+++ b/src/main/scala/leon/synthesis/rules/ADTDual.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/ADTSplit.scala b/src/main/scala/leon/synthesis/rules/ADTSplit.scala
index d3dc6347280a45642935e6ea3c314246a3cb6958..93e1488aee529515b3368c6a7ec2d29a83811eed 100644
--- a/src/main/scala/leon/synthesis/rules/ADTSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/ADTSplit.scala
@@ -1,9 +1,10 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 package rules
 
+import Witnesses.Hint
 import purescala.Expressions._
 import purescala.Common._
 import purescala.Types._
@@ -66,27 +67,29 @@ case object ADTSplit extends Rule("ADT Split.") {
         val oas = p.as.filter(_ != id)
 
         val subInfo0 = for(ccd <- cases) yield {
-           val cct    = CaseClassType(ccd, act.tps)
+          val cct    = CaseClassType(ccd, act.tps)
 
-           val args   = cct.fields.map { vd => FreshIdentifier(vd.id.name, vd.getType, true) }.toList
+          val args   = cct.fields.map { vd => FreshIdentifier(vd.id.name, vd.getType, true) }.toList
 
-           val subPhi = subst(id -> CaseClass(cct, args.map(Variable)), p.phi)
-           val subPC  = subst(id -> CaseClass(cct, args.map(Variable)), p.pc)
-           val subWS  = subst(id -> CaseClass(cct, args.map(Variable)), p.ws)
+          val whole =  CaseClass(cct, args.map(Variable))
 
-           val eb2 = p.qeb.mapIns { inInfo =>
-              inInfo.toMap.apply(id) match {
-                case CaseClass(`cct`, vs) =>
-                  List(vs ++ inInfo.filter(_._1 != id).map(_._2))
-                case _ =>
-                  Nil
-              }
-           }
+          val subPhi = subst(id -> whole, p.phi)
+          val subPC  = subst(id -> whole, p.pc)
+          val subWS  = subst(id -> whole, p.ws)
+
+          val eb2 = p.qeb.mapIns { inInfo =>
+             inInfo.toMap.apply(id) match {
+               case CaseClass(`cct`, vs) =>
+                 List(vs ++ inInfo.filter(_._1 != id).map(_._2))
+               case _ =>
+                 Nil
+             }
+          }
 
-           val subProblem = Problem(args ::: oas, subWS, subPC, subPhi, p.xs, eb2)
-           val subPattern = CaseClassPattern(None, cct, args.map(id => WildcardPattern(Some(id))))
+          val subProblem = Problem(args ::: oas, subWS, subPC, subPhi, p.xs, eb2).withWs(Seq(Hint(whole)))
+          val subPattern = CaseClassPattern(None, cct, args.map(id => WildcardPattern(Some(id))))
 
-           (cct, subProblem, subPattern)
+          (cct, subProblem, subPattern)
         }
 
         val subInfo = subInfo0.sortBy{ case (cct, _, _) =>
diff --git a/src/main/scala/leon/synthesis/rules/Assert.scala b/src/main/scala/leon/synthesis/rules/Assert.scala
index d2cdb5b69f1f88b847ad91499e3946257ef6c167..0acdc209ee00dc10647d2bfe8d48ff100e33e167 100644
--- a/src/main/scala/leon/synthesis/rules/Assert.scala
+++ b/src/main/scala/leon/synthesis/rules/Assert.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/CEGIS.scala b/src/main/scala/leon/synthesis/rules/CEGIS.scala
index b0de64ed05458d22cc113170dc850e2c1e2f6a3b..2ec177fc947e42b4810b4c4d16fb9407b592248d 100644
--- a/src/main/scala/leon/synthesis/rules/CEGIS.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGIS.scala
@@ -1,19 +1,22 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 package rules
 
 import grammars._
-import grammars.transformers._
+import grammars.Tags
+import grammars.aspects._
 import purescala.Types.TypeTree
 
 /** Basic implementation of CEGIS that uses a naive grammar */
-case object NaiveCEGIS extends CEGISLike[TypeTree]("Naive CEGIS") {
+case object NaiveCEGIS extends CEGISLike("Naive CEGIS") {
   def getParams(sctx: SynthesisContext, p: Problem) = {
     CegisParams(
-      grammar = Grammars.typeDepthBound(Grammars.default(sctx, p), 2), // This limits type depth
-      rootLabel = {(tpe: TypeTree) => tpe },
+      //grammar = Grammars.typeDepthBound(Grammars.default(sctx, p), 2), // This limits type depth
+      //rootLabel = {(tpe: TypeTree) => tpe },
+      grammar = Grammars.default(sctx, p), // This limits type depth
+      rootLabel = Label(_),
       optimizations = false
     )
   }
@@ -22,12 +25,13 @@ case object NaiveCEGIS extends CEGISLike[TypeTree]("Naive CEGIS") {
 /** More advanced implementation of CEGIS that uses a less permissive grammar
   * and some optimizations
   */
-case object CEGIS extends CEGISLike[TaggedNonTerm[TypeTree]]("CEGIS") {
+case object CEGIS extends CEGISLike("CEGIS") {
   def getParams(sctx: SynthesisContext, p: Problem) = {
-    val base = NaiveCEGIS.getParams(sctx,p).grammar
     CegisParams(
-      grammar = TaggedGrammar(base),
-      rootLabel = TaggedNonTerm(_, Tags.Top, 0, None),
+      //grammar = TaggedGrammar(base),
+      //rootLabel = TaggedNonTerm(_, Tags.Top, 0, None),
+      grammar = NaiveCEGIS.getParams(sctx,p).grammar,
+      rootLabel = Label(_).withAspect(Tagged(Tags.Top, 0, None)),
       optimizations = true
     )
   }
diff --git a/src/main/scala/leon/synthesis/rules/CEGISLike.scala b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
index 291e485d70b80b580095a484e02448166de9e18c..7ac1efc043cdf890fbf5cbfd5a3d3a935a15e892 100644
--- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -11,23 +11,24 @@ import purescala.Types._
 import purescala.ExprOps._
 import purescala.DefOps._
 import purescala.Constructors._
+import purescala.TypeOps.typeDepth
 
 import solvers._
 import grammars._
-import grammars.transformers._
+import grammars.aspects._
 import leon.utils._
 
 import evaluators._
 import datagen._
 import codegen.CodeGenParams
 
-import scala.collection.mutable.{HashMap=>MutableMap, ArrayBuffer}
+import scala.collection.mutable.{HashMap => MutableMap}
 
-abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
+abstract class CEGISLike(name: String) extends Rule(name) {
 
   case class CegisParams(
-    grammar: ExpressionGrammar[T],
-    rootLabel: TypeTree => T,
+    grammar: ExpressionGrammar,
+    rootLabel: TypeTree => Label,
     optimizations: Boolean,
     maxSize: Option[Int] = None
   )
@@ -37,59 +38,48 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
 
     val exSolverTo  = 2000L
-    val cexSolverTo = 2000L
+    val cexSolverTo = 3000L
 
     // Track non-deterministic programs up to 100'000 programs, or give up
     val nProgramsLimit = 100000
 
-    val sctx = hctx.sctx
-    val ctx  = sctx.context
-
-    val timers = ctx.timers.synthesis.cegis
+    val timers = hctx.timers.synthesis.cegis
 
     // CEGIS Flags to activate or deactivate features
-    val useOptTimeout    = sctx.settings.cegisUseOptTimeout
-    val useVanuatoo      = sctx.settings.cegisUseVanuatoo
+    val useOptTimeout = hctx.settings.cegisUseOptTimeout
+    val useVanuatoo   = hctx.settings.cegisUseVanuatoo
 
-    // Limits the number of programs CEGIS will specifically validate individually
-    val validateUpTo     = 3
-    val passingRatio     = 10
+    // The factor by which programs need to be reduced by testing before we validate them individually
+    val testReductionRatio = 10
 
-    val interruptManager = sctx.context.interruptManager
+    val interruptManager = hctx.interruptManager
 
-    val params = getParams(sctx, p)
+    val params = getParams(hctx, p)
 
     // If this CEGISLike forces a maxSize, take it, otherwise find it in the settings
-    val maxSize = params.maxSize.getOrElse(sctx.settings.cegisMaxSize)
-
-    ctx.reporter.debug(s"This is $name. Settings: optimizations = ${params.optimizations}, maxSize = $maxSize, vanuatoo=$useVanuatoo, optTimeout=$useOptTimeout")
+    val maxSize = params.maxSize.getOrElse(hctx.settings.cegisMaxSize)
 
     if (maxSize == 0) {
       return Nil
     }
 
-    class NonDeterministicProgram(val p: Problem, initTermSize: Int = 1) {
+    // Represents a non-deterministic program
+    object NonDeterministicProgram {
 
+      // Current synthesized term size
       private var termSize = 0
 
-      val grammar = SizeBoundedGrammar(params.grammar, params.optimizations)
+      def unfolding = termSize
 
-      def rootLabel = SizedNonTerm(params.rootLabel(tupleTypeWrap(p.xs.map(_.getType))), termSize)
+      private val targetType = tupleTypeWrap(p.xs.map(_.getType))
 
-      var nAltsCache = Map[SizedNonTerm[T], Int]()
+      val grammar = params.grammar
 
-      def countAlternatives(l: SizedNonTerm[T]): Int = {
-        if (!(nAltsCache contains l)) {
-          val count = grammar.getProductions(l).map { gen =>
-            gen.subTrees.map(countAlternatives).product
-          }.sum
-          nAltsCache += l -> count
-        }
-        nAltsCache(l)
-      }
+      //def rootLabel = SizedNonTerm(params.rootLabel(tupleTypeWrap(p.xs.map(_.getType))), termSize)
+      def rootLabel = params.rootLabel(targetType).withAspect(Sized(termSize))
 
-      def allProgramsCount(): Int = {
-        countAlternatives(rootLabel)
+      def init(): Unit = {
+        updateCTree()
       }
 
       /**
@@ -111,29 +101,29 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
        */
       private var cTree: Map[Identifier, Seq[(Identifier, Seq[Expr] => Expr, Seq[Identifier])]] = Map()
 
-
-      // C identifiers corresponding to p.xs
+      // Top-level C identifiers corresponding to p.xs
       private var rootC: Identifier          = _
 
+      // Blockers
       private var bs: Set[Identifier]        = Set()
 
       private var bsOrdered: Seq[Identifier] = Seq()
 
-
+      // Generator of fresh cs that minimizes labels
       class CGenerator {
-        private var buffers = Map[SizedNonTerm[T], Stream[Identifier]]()
+        private var buffers = Map[Label, Stream[Identifier]]()
 
-        private var slots = Map[SizedNonTerm[T], Int]().withDefaultValue(0)
+        private var slots = Map[Label, Int]().withDefaultValue(0)
 
-        private def streamOf(t: SizedNonTerm[T]): Stream[Identifier] = Stream.continually(
+        private def streamOf(t: Label): Stream[Identifier] = Stream.continually(
           FreshIdentifier(t.asString, t.getType, true)
         )
 
         def rewind(): Unit = {
-          slots = Map[SizedNonTerm[T], Int]().withDefaultValue(0)
+          slots = Map[Label, Int]().withDefaultValue(0)
         }
 
-        def getNext(t: SizedNonTerm[T]) = {
+        def getNext(t: Label) = {
           if (!(buffers contains t)) {
             buffers += t -> streamOf(t)
           }
@@ -145,27 +135,27 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
         }
       }
 
-      def init(): Unit = {
-        updateCTree()
-      }
-
+      // Programs we have manually excluded
+      var excludedPrograms = Set[Set[Identifier]]()
+      // Still live programs (allPrograms -- excludedPrograms)
+      var prunedPrograms   = Set[Set[Identifier]]()
 
+      // Update the c-tree after an increase in termsize
       def updateCTree(): Unit = {
-        ctx.timers.synthesis.cegis.updateCTree.start()
+        hctx.timers.synthesis.cegis.updateCTree.start()
         def freshB() = {
           val id = FreshIdentifier("B", BooleanType, true)
           bs += id
           id
         }
 
-        def defineCTreeFor(l: SizedNonTerm[T], c: Identifier): Unit = {
+        def defineCTreeFor(l: Label, c: Identifier): Unit = {
           if (!(cTree contains c)) {
             val cGen = new CGenerator()
 
             val alts = grammar.getProductions(l)
 
-            val cTreeData = for (gen <- alts) yield {
-              val b = freshB()
+            val cTreeData = alts flatMap { gen =>
 
               // Optimize labels
               cGen.rewind()
@@ -175,8 +165,11 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
                 defineCTreeFor(sl, subC)
                 subC
               }
-
-              (b, gen.builder, subCs)
+              
+              if (subCs.forall(sc => cTree(sc).nonEmpty)) {
+                val b = freshB()
+                Some((b, gen.builder, subCs))
+              } else None
             }
 
             cTree += c -> cTreeData
@@ -191,67 +184,70 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
           c
         }
 
-        sctx.reporter.ifDebug { printer =>
+        hctx.reporter.ifDebug { printer =>
           printer("Grammar so far:")
           grammar.printProductions(printer)
           printer("")
         }
 
         bsOrdered = bs.toSeq.sorted
-        excludedPrograms = ArrayBuffer()
+        setCExpr()
 
-        setCExpr(computeCExpr())
-        ctx.timers.synthesis.cegis.updateCTree.stop()
+        excludedPrograms = Set()
+        prunedPrograms = allPrograms().toSet
+
+        hctx.timers.synthesis.cegis.updateCTree.stop()
       }
 
-      /**
-       * Keeps track of blocked Bs and which C are affected, assuming cs are undefined:
-       *
-       * b2 -> Set(c4)
-       * b3 -> Set(c4)
-       */
-      private val closedBs: Map[Identifier, Set[Identifier]] = Map()
+      // Returns a count of all possible programs
+      val allProgramsCount: () => Int = {
+        var nAltsCache = Map[Label, Int]()
 
-      /**
-       * Checks if 'b' is closed (meaning it depends on uninterpreted terms)
-       */
-      def isBActive(b: Identifier) = !closedBs.contains(b)
+        def countAlternatives(l: Label): Int = {
+          if (!(nAltsCache contains l)) {
+            val count = grammar.getProductions(l).map { gen =>
+              gen.subTrees.map(countAlternatives).product
+            }.sum
+            nAltsCache += l -> count
+          }
+          nAltsCache(l)
+        }
 
+        () => countAlternatives(rootLabel)
+      }
 
       /**
        * Returns all possible assignments to Bs in order to enumerate all possible programs
        */
       def allPrograms(): Traversable[Set[Identifier]] = {
 
-        val allCount = allProgramsCount()
-        if (allCount > nProgramsLimit) {
-          ctx.reporter.debug(s"Exceeded program limit: $allCount > $nProgramsLimit")
+        var cache = Map[Identifier, Seq[Set[Identifier]]]()
+
+        val c = allProgramsCount()
+
+        if (c > nProgramsLimit) {
+          hctx.reporter.debug(s"Exceeded program limit: $c > $nProgramsLimit")
           return Seq()
         }
 
-        var cache = Map[Identifier, Seq[Set[Identifier]]]()
-
-        def allProgramsFor(cs: Seq[Identifier]): Seq[Set[Identifier]] = {
-          val seqs = for (c <- cs.toSeq) yield {
-            if (!(cache contains c)) {
-              val subs = for ((b, _, subcs) <- cTree(c) if isBActive(b)) yield {
-                if (subcs.isEmpty) {
-                  Seq(Set(b))
-                } else {
-                  for (p <- allProgramsFor(subcs)) yield {
-                    p + b
-                  }
-                }
+        def allProgramsFor(c: Identifier): Seq[Set[Identifier]] = {
+          if (!(cache contains c)) {
+            val subs = for ((b, _, subcs) <- cTree(c)) yield {
+              if (subcs.isEmpty) {
+                Seq(Set(b))
+              } else {
+                val subPs = subcs map (s => allProgramsFor(s))
+                val combos = SeqUtils.cartesianProduct(subPs).map(_.flatten.toSet)
+                combos map (_ + b)
               }
-              cache += c -> subs.flatten
             }
-            cache(c)
+            cache += c -> subs.flatten
           }
-
-          SeqUtils.cartesianProduct(seqs).map(_.flatten.toSet)
+          cache(c)
         }
 
-        allProgramsFor(Seq(rootC))
+        allProgramsFor(rootC)
+
       }
 
       private def debugCTree(cTree: Map[Identifier, Seq[(Identifier, Seq[Expr] => Expr, Seq[Identifier])]],
@@ -261,86 +257,35 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
           println()
           println(f"$c%-4s :=")
           for ((b, builder, cs) <- alts ) {
-            val active = if (isBActive(b)) " " else "⨯"
             val markS   = if (markedBs(b)) Console.GREEN else ""
             val markE   = if (markedBs(b)) Console.RESET else ""
 
             val ex = builder(cs.map(_.toVariable)).asString
 
-            println(f"      $markS$active  ${b.asString}%-4s => $ex%-40s [${cs.map(_.asString).mkString(", ")}]$markE")
+            println(f"      $markS  ${b.asString}%-4s => $ex%-40s [${cs.map(_.asString).mkString(", ")}]$markE")
           }
         }
       }
 
-      private def computeCExpr(): (Expr, Seq[FunDef]) = {
-        var cToFd = Map[Identifier, FunDef]()
-
-        def exprOf(alt: (Identifier, Seq[Expr] => Expr, Seq[Identifier])): Expr = {
-          val (_, builder, cs) = alt
-
-          val e = builder(cs.map { c =>
-            val fd = cToFd(c)
-            FunctionInvocation(fd.typed, fd.params.map(_.toVariable))
-          })
-
-          outerExprToInnerExpr(e)
-        }
-
-        // Define all C-def
-        for ((c, alts) <- cTree) yield {
-          cToFd += c -> new FunDef(FreshIdentifier(c.asString, alwaysShowUniqueID = true), Seq(), p.as.map(id => ValDef(id)), c.getType)
-        }
-
-        // Fill C-def bodies
-        for ((c, alts) <- cTree) {
-          val activeAlts = alts.filter(a => isBActive(a._1))
-
-          val body = if (activeAlts.nonEmpty) {
-            activeAlts.init.foldLeft(exprOf(activeAlts.last)) {
-              case (e, alt) => IfExpr(alt._1.toVariable, exprOf(alt), e)
-            }
-          } else {
-            Error(c.getType, s"Empty production rule: $c")
-          }
-
-          cToFd(c).fullBody = body
-        }
-
-        // Top-level expression for rootC
-        val expr = {
-          val fd = cToFd(rootC)
-          FunctionInvocation(fd.typed, fd.params.map(_.toVariable))
-        }
-
-        (expr, cToFd.values.toSeq)
-      }
-
-
-
+      // The function which calls the synthesized expression within programCTree
       private val cTreeFd = new FunDef(FreshIdentifier("cTree", alwaysShowUniqueID = true), Seq(), p.as.map(id => ValDef(id)), p.outType)
 
-      private val solFd = new FunDef(FreshIdentifier("solFd", alwaysShowUniqueID = true), Seq(), p.as.map(id => ValDef(id)), p.outType)
-
+      // The spec of the problem
       private val phiFd = new FunDef(FreshIdentifier("phiFd", alwaysShowUniqueID = true), Seq(), p.as.map(id => ValDef(id)), BooleanType)
 
-
+      // The program with the body of the current function replaced by the current partial solution
       private val (innerProgram, origFdMap) = {
 
         val outerSolution = {
-          new PartialSolution(hctx.search.g, true)
-            .solutionAround(hctx.currentNode)(FunctionInvocation(solFd.typed, p.as.map(_.toVariable)))
-            .getOrElse(ctx.reporter.fatalError("Unable to get outer solution"))
+          new PartialSolution(hctx.search.strat, true)
+            .solutionAround(hctx.currentNode)(FunctionInvocation(cTreeFd.typed, p.as.map(_.toVariable)))
+            .getOrElse(hctx.reporter.fatalError("Unable to get outer solution"))
         }
 
-        val program0 = addFunDefs(sctx.program, Seq(cTreeFd, solFd, phiFd) ++ outerSolution.defs, hctx.ci.fd)
+        val program0 = addFunDefs(hctx.program, Seq(cTreeFd, phiFd) ++ outerSolution.defs, hctx.functionContext)
 
         cTreeFd.body = None
 
-        solFd.fullBody = Ensuring(
-          FunctionInvocation(cTreeFd.typed, p.as.map(_.toVariable)),
-          Lambda(p.xs.map(ValDef), p.phi)
-        )
-
         phiFd.body = Some(
           letTuple(p.xs,
                    FunctionInvocation(cTreeFd.typed, p.as.map(_.toVariable)),
@@ -348,11 +293,11 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
         )
 
         replaceFunDefs(program0){
-          case fd if fd == hctx.ci.fd =>
+          case fd if fd == hctx.functionContext =>
             val nfd = fd.duplicate()
 
             nfd.fullBody = postMap {
-              case src if src eq hctx.ci.source =>
+              case src if src eq hctx.source =>
                 Some(outerSolution.term)
 
               case _ => None
@@ -362,7 +307,7 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
 
           // We freshen/duplicate every functions, except these two as they are
           // fresh anyway and we refer to them directly.
-          case `cTreeFd` | `phiFd` | `solFd` =>
+          case `cTreeFd` | `phiFd` =>
             None
 
           case fd =>
@@ -384,26 +329,119 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
       private val innerPc  = outerExprToInnerExpr(p.pc)
       private val innerPhi = outerExprToInnerExpr(p.phi)
 
+      // The program with the c-tree functions
       private var programCTree: Program = _
 
       private var evaluator: DefaultEvaluator = _
 
-      private def setCExpr(cTreeInfo: (Expr, Seq[FunDef])): Unit = {
-        val (cTree, newFds) = cTreeInfo
+      // Updates the program with the C tree after recalculating all relevant FunDef's
+      private def setCExpr(): Unit = {
+
+        // Computes a Seq of functions corresponding to the choices made at each non-terminal of the grammar,
+        // and an expression which calls the top-level one.
+        def computeCExpr(): (Expr, Seq[FunDef]) = {
+          var cToFd = Map[Identifier, FunDef]()
+
+          def exprOf(alt: (Identifier, Seq[Expr] => Expr, Seq[Identifier])): Expr = {
+            val (_, builder, cs) = alt
+
+            val e = builder(cs.map { c =>
+              val fd = cToFd(c)
+              fd.applied
+            })
+
+            outerExprToInnerExpr(e)
+          }
+
+          // Define all C-def
+          for ((c, alts) <- cTree) yield {
+            cToFd += c -> new FunDef(FreshIdentifier(c.asString, alwaysShowUniqueID = true), Seq(), p.as.map(id => ValDef(id)), c.getType)
+          }
+
+          // Fill C-def bodies
+          for ((c, alts) <- cTree) {
+
+            val body = if (alts.nonEmpty) {
+              alts.init.foldLeft(exprOf(alts.last)) {
+                case (e, alt) => IfExpr(alt._1.toVariable, exprOf(alt), e)
+              }
+            } else {
+              Error(c.getType, s"Empty production rule: $c")
+            }
+
+            cToFd(c).fullBody = body
+          }
+
+          // Top-level expression for rootC
+          val expr = {
+            val fd = cToFd(rootC)
+            fd.applied
+          }
+
+          (expr, cToFd.values.toSeq)
+        }
+
+
+        val (cExpr, newFds) = computeCExpr()
 
-        cTreeFd.body = Some(cTree)
+        cTreeFd.body = Some(cExpr)
         programCTree = addFunDefs(innerProgram, newFds, cTreeFd)
-        evaluator = new DefaultEvaluator(sctx.context, programCTree)
+        evaluator = new DefaultEvaluator(hctx, programCTree)
 
         //println("-- "*30)
         //println(programCTree.asString)
         //println(".. "*30)
       }
 
-      def testForProgram(bValues: Set[Identifier])(ex: Example): Boolean = {
+      // Tests a candidate solution against an example in the correct environment
+      // None -> evaluator error
+      def testForProgram(bValues: Set[Identifier])(ex: Example): Option[Boolean] = {
+
+        def redundant(e: Expr): Boolean = {
+          val (op1, op2) = e match {
+            case Minus(o1, o2) => (o1, o2)
+            case Modulo(o1, o2) => (o1, o2)
+            case Division(o1, o2) => (o1, o2)
+            case BVMinus(o1, o2) => (o1, o2)
+            case BVRemainder(o1, o2) => (o1, o2)
+            case BVDivision(o1, o2) => (o1, o2)
+
+            case And(Seq(Not(o1), Not(o2))) => (o1, o2)
+            case And(Seq(Not(o1), o2)) => (o1, o2)
+            case And(Seq(o1, Not(o2))) => (o1, o2)
+            case And(Seq(o1, o2)) => (o1, o2)
+
+            case Or(Seq(Not(o1), Not(o2))) => (o1, o2)
+            case Or(Seq(Not(o1), o2)) => (o1, o2)
+            case Or(Seq(o1, Not(o2))) => (o1, o2)
+            case Or(Seq(o1, o2)) => (o1, o2)
+
+            case SetUnion(o1, o2) => (o1, o2)
+            case SetIntersection(o1, o2) => (o1, o2)
+            case SetDifference(o1, o2) => (o1, o2)
+
+            case Equals(Not(o1), Not(o2)) => (o1, o2)
+            case Equals(Not(o1), o2) => (o1, o2)
+            case Equals(o1, Not(o2)) => (o1, o2)
+            case Equals(o1, o2) => (o1, o2)
+            case _ => return false
+          }
+
+          op1 == op2
+        }
 
         val origImpl = cTreeFd.fullBody
         val outerSol = getExpr(bValues)
+
+        val redundancyCheck = false
+
+        // This program contains a simplifiable expression,
+        // which means it is equivalent to a simpler one
+        // Deactivated for now, since it doesnot seem to help
+        if (redundancyCheck && params.optimizations && exists(redundant)(outerSol)) {
+          excludeProgram(bs, true)
+          return Some(false)
+        }
         val innerSol = outerExprToInnerExpr(outerSol)
         val cnstr = letTuple(p.xs, innerSol, innerPhi)
         cTreeFd.fullBody = innerSol
@@ -423,7 +461,7 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
 
         res match {
           case EvaluationResults.Successful(res) =>
-            res == BooleanLiteral(true)
+            Some(res == BooleanLiteral(true))
 
           case EvaluationResults.RuntimeError(err) =>
             /*if (err.contains("Empty production rule")) {
@@ -435,12 +473,12 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
               println(err)
               println()
             }*/
-            sctx.reporter.debug("RE testing CE: "+err)
-            false
+            hctx.reporter.debug("RE testing CE: "+err)
+            Some(false)
 
           case EvaluationResults.EvaluatorError(err) =>
-            sctx.reporter.debug("Error testing CE: "+err)
-            false
+            hctx.reporter.debug("Error testing CE: "+err)
+            None
         }
 
       }
@@ -461,37 +499,43 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
       }
 
       /**
-       * Here we check the validity of a given program in isolation, we compute
-       * the corresponding expr and replace it in place of the C-tree
+       * Here we check the validity of a (small) number of programs in isolation.
+       * We keep track of CEXs generated by invalid programs and preemptively filter the rest of the programs with them.
        */
-      def validatePrograms(bss: Set[Set[Identifier]]): Either[Stream[Solution], Seq[Seq[Expr]]] = {
+      def validatePrograms(bss: Set[Set[Identifier]]): Either[Seq[Seq[Expr]], Solution] = {
         val origImpl = cTreeFd.fullBody
 
         var cexs = Seq[Seq[Expr]]()
 
+        var best: Option[Solution] = None
+
         for (bs <- bss.toSeq) {
+          // We compute the corresponding expr and replace it in place of the C-tree
           val outerSol = getExpr(bs)
           val innerSol = outerExprToInnerExpr(outerSol)
-          //println(s"Testing $outerSol")
+          //println(s"Testing $innerSol")
+          //println(innerProgram)
           cTreeFd.fullBody = innerSol
 
           val cnstr = and(innerPc, letTuple(p.xs, innerSol, Not(innerPhi)))
 
-          val eval = new DefaultEvaluator(ctx, innerProgram)
+          val eval = new DefaultEvaluator(hctx, innerProgram)
 
           if (cexs exists (cex => eval.eval(cnstr, p.as.zip(cex).toMap).result == Some(BooleanLiteral(true)))) {
-            //println(s"Program $outerSol fails!")
+            hctx.reporter.debug(s"Rejected by CEX: $outerSol")
             excludeProgram(bs, true)
             cTreeFd.fullBody = origImpl
           } else {
             //println("Solving for: "+cnstr.asString)
 
-            val solverf = SolverFactory.getFromSettings(ctx, innerProgram).withTimeout(cexSolverTo)
+            val solverf = SolverFactory.getFromSettings(hctx, innerProgram).withTimeout(cexSolverTo)
             val solver = solverf.getNewSolver()
             try {
+              hctx.reporter.debug("Sending candidate to solver...")
               solver.assertCnstr(cnstr)
               solver.check match {
                 case Some(true) =>
+                  hctx.reporter.debug(s"Proven invalid: $outerSol")
                   excludeProgram(bs, true)
                   val model = solver.getModel
                   //println("Found counter example: ")
@@ -506,14 +550,14 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
 
                 case Some(false) =>
                   // UNSAT, valid program
-                  return Left(Stream(Solution(BooleanLiteral(true), Set(), outerSol, true)))
+                  hctx.reporter.debug("Found valid program!")
+                  return Right(Solution(BooleanLiteral(true), Set(), outerSol, true))
 
                 case None =>
                   if (useOptTimeout) {
-                    // Interpret timeout in CE search as "the candidate is valid"
-                    sctx.reporter.info("CEGIS could not prove the validity of the resulting expression")
                     // Optimistic valid solution
-                    return Left(Stream(Solution(BooleanLiteral(true), Set(), outerSol, false)))
+                    hctx.reporter.debug("Found a non-verifiable solution...")
+                    best = Some(Solution(BooleanLiteral(true), Set(), outerSol, false))
                   }
               }
             } finally {
@@ -524,24 +568,24 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
           }
         }
 
-        Right(cexs)
+        best.map{ sol =>
+          // Interpret timeout in CE search as "the candidate is valid"
+          hctx.reporter.info("CEGIS could not prove the validity of the resulting expression")
+          Right(sol)
+        }.getOrElse(Left(cexs))
       }
 
-      var excludedPrograms = ArrayBuffer[Set[Identifier]]()
-
-      def allProgramsClosed = allProgramsCount() <= excludedPrograms.size
+      def allProgramsClosed = prunedPrograms.isEmpty
 
       // Explicitly remove program computed by bValues from the search space
       //
       // If the bValues comes from models, we make sure the bValues we exclude
       // are minimal we make sure we exclude only Bs that are used.
-      def excludeProgram(bValues: Set[Identifier], isMinimal: Boolean): Unit = {
-        val bs = bValues.filter(isBActive)
+      def excludeProgram(bs: Set[Identifier], isMinimal: Boolean): Unit = {
 
         def filterBTree(c: Identifier): Set[Identifier] = {
-          (for ((b, _, subcs) <- cTree(c) if bValues(b)) yield {
-           Set(b) ++ subcs.flatMap(filterBTree)
-          }).toSet.flatten
+          val (b, _, subcs) = cTree(c).find(sub => bs(sub._1)).get
+          subcs.flatMap(filterBTree).toSet + b
         }
 
         val bvs = if (isMinimal) {
@@ -551,6 +595,7 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
         }
 
         excludedPrograms += bvs
+        prunedPrograms   -= bvs
       }
 
       def unfold() = {
@@ -559,12 +604,13 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
       }
 
       /**
-       * First phase of CEGIS: solve for potential programs (that work on at least one input)
+       * First phase of CEGIS: discover potential programs (that work on at least one input)
        */
       def solveForTentativeProgram(): Option[Option[Set[Identifier]]] = {
-        val solverf = SolverFactory.getFromSettings(ctx, programCTree).withTimeout(exSolverTo)
+        timers.tentative.start()
+        val solverf = SolverFactory.getFromSettings(hctx, programCTree).withTimeout(exSolverTo)
         val solver  = solverf.getNewSolver()
-        val cnstr = FunctionInvocation(phiFd.typed, phiFd.params.map(_.id.toVariable))
+        val cnstr = phiFd.applied
 
         //println("Program: ")
         //println("-"*80)
@@ -577,27 +623,23 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
           solver.assertCnstr(toFind)
 
           for ((c, alts) <- cTree) {
-            val activeBs = alts.map(_._1).filter(isBActive)
 
-            val either = for (a1 <- activeBs; a2 <- activeBs if a1 < a2) yield {
+            val bs = alts.map(_._1)
+
+            val either = for (a1 <- bs; a2 <- bs if a1 < a2) yield {
               Or(Not(a1.toVariable), Not(a2.toVariable))
             }
 
-            if (activeBs.nonEmpty) {
+            if (bs.nonEmpty) {
               //println(" - "+andJoin(either).asString)
               solver.assertCnstr(andJoin(either))
 
-              val oneOf = orJoin(activeBs.map(_.toVariable))
+              val oneOf = orJoin(bs.map(_.toVariable))
               //println(" - "+oneOf.asString)
               solver.assertCnstr(oneOf)
             }
           }
 
-          //println(" -- Active:")
-          val isActive = andJoin(bsOrdered.filterNot(isBActive).map(id => Not(id.toVariable)))
-          //println("  - "+isActive.asString)
-          solver.assertCnstr(isActive)
-
           //println(" -- Excluded:")
           for (ex <- excludedPrograms) {
             val notThisProgram = Not(andJoin(ex.map(_.toVariable).toSeq))
@@ -615,7 +657,7 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
               //println("Tentative model: "+model.asString)
               //println("Tentative model: "+bModel.filter(isBActive).map(_.asString).toSeq.sorted)
               //println("Tentative expr: "+getExpr(bModel))
-
+            
               Some(Some(bModel))
 
             case Some(false) =>
@@ -628,10 +670,11 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
                * might timeout instead of returning Some(false). We might still
                * benefit from unfolding further
                */
-              ctx.reporter.debug("Timeout while getting tentative program!")
+              hctx.reporter.debug("Timeout while getting tentative program!")
               Some(None)
           }
         } finally {
+          timers.tentative.stop()
           solverf.reclaim(solver)
           solverf.shutdown()
         }
@@ -641,11 +684,11 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
        * Second phase of CEGIS: verify a given program by looking for CEX inputs
        */
       def solveForCounterExample(bs: Set[Identifier]): Option[Option[Seq[Expr]]] = {
-        val solverf = SolverFactory.getFromSettings(ctx, programCTree).withTimeout(cexSolverTo)
+        timers.cex.start()
+        val solverf = SolverFactory.getFromSettings(hctx, programCTree).withTimeout(cexSolverTo)
         val solver  = solverf.getNewSolver()
         val cnstr = FunctionInvocation(phiFd.typed, phiFd.params.map(_.id.toVariable))
 
-
         try {
           solver.assertCnstr(andJoin(bsOrdered.map(b => if (bs(b)) b.toVariable else Not(b.toVariable))))
           solver.assertCnstr(innerPc)
@@ -673,6 +716,7 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
               None
           }
         } finally {
+          timers.cex.stop()
           solverf.reclaim(solver)
           solverf.shutdown()
         }
@@ -682,29 +726,19 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
     List(new RuleInstantiation(this.name) {
       def apply(hctx: SearchContext): RuleApplication = {
         var result: Option[RuleApplication] = None
-        val sctx = hctx.sctx
-        implicit val ctx = sctx.context
 
-        val ndProgram = new NonDeterministicProgram(p)
+        val ndProgram = NonDeterministicProgram
         ndProgram.init()
 
-        var unfolding = 1
-
-        var baseExampleInputs: ArrayBuffer[Example] = new ArrayBuffer[Example]()
-
-        sctx.reporter.ifDebug { printer =>
-          ndProgram.grammar.printProductions(printer)
-        }
-
-        // We populate the list of examples with a defined one
-        sctx.reporter.debug("Acquiring initial list of examples")
+        implicit val ic = hctx
 
-        baseExampleInputs ++= p.eb.examples
+        hctx.reporter.debug("Acquiring initial list of examples")
 
-        if (p.pc == BooleanLiteral(true)) {
-          baseExampleInputs += InExample(p.as.map(a => simplestValue(a.getType)))
+        // To the list of known examples, we add an additional one produced by the solver
+        val solverExample = if (p.pc == BooleanLiteral(true)) {
+          List(InExample(p.as.map(a => simplestValue(a.getType))))
         } else {
-          val solverf = sctx.solverFactory
+          val solverf = hctx.solverFactory
           val solver  = solverf.getNewSolver().setTimeout(exSolverTo)
 
           solver.assertCnstr(p.pc)
@@ -713,64 +747,86 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
             solver.check match {
               case Some(true) =>
                 val model = solver.getModel
-                baseExampleInputs += InExample(p.as.map(a => model.getOrElse(a, simplestValue(a.getType))))
+                List(InExample(p.as.map(a => model.getOrElse(a, simplestValue(a.getType)))))
 
               case Some(false) =>
-                sctx.reporter.debug("Path-condition seems UNSAT")
+                hctx.reporter.debug("Path-condition seems UNSAT")
                 return RuleFailed()
 
               case None =>
-                sctx.reporter.warning("Solver could not solve path-condition")
-                return RuleFailed() // This is not necessary though, but probably wanted
+                if (!interruptManager.isInterrupted) {
+                  hctx.reporter.warning("Solver could not solve path-condition")
+                }
+                Nil
+                //return RuleFailed() // This is not necessary though, but probably wanted
             }
           } finally {
             solverf.reclaim(solver)
           }
         }
 
-        sctx.reporter.ifDebug { debug =>
+        val baseExampleInputs = p.eb.examples ++ solverExample
+
+        hctx.reporter.ifDebug { debug =>
           baseExampleInputs.foreach { in =>
             debug("  - "+in.asString)
           }
         }
 
         /**
-         * We generate tests for discarding potential programs
+         * We (lazily) generate additional tests for discarding potential programs with a data generator
          */
         val nTests = if (p.pc == BooleanLiteral(true)) 50 else 20
 
-        val inputGenerator: Iterator[Example] = if (useVanuatoo) {
-          new VanuatooDataGen(sctx.context, sctx.program).generateFor(p.as, p.pc, nTests, 3000).map(InExample)
-        } else {
-          val evaluator = new DualEvaluator(sctx.context, sctx.program, CodeGenParams.default)
-          new GrammarDataGen(evaluator, ValueGrammar).generateFor(p.as, p.pc, nTests, 1000).map(InExample)
+        val inputGenerator: Iterator[Example] = {
+          val complicated = exists{
+            case FunctionInvocation(tfd, _) if tfd.fd == hctx.functionContext => true
+            case Choose(_) => true
+            case _ => false
+          }(p.pc)
+          if (complicated) {
+            Iterator()
+          } else {
+            if (useVanuatoo) {
+              new VanuatooDataGen(hctx, hctx.program).generateFor(p.as, p.pc, nTests, 3000).map(InExample)
+            } else {
+              val evaluator = new DualEvaluator(hctx, hctx.program, CodeGenParams.default)
+              new GrammarDataGen(evaluator, ValueGrammar).generateFor(p.as, p.pc, nTests, 1000).map(InExample)
+            }
+          }
         }
 
-        val gi = new GrowableIterable[Example](baseExampleInputs, inputGenerator)
-
+        // We keep number of failures per test to pull the better ones to the front
         val failedTestsStats = new MutableMap[Example, Int]().withDefaultValue(0)
 
+        // This is the starting test-base
+        val gi = new GrowableIterable[Example](baseExampleInputs, inputGenerator)
         def hasInputExamples = gi.nonEmpty
 
         var n = 1
-        def allInputExamples() = {
-          if (n == 10 || n == 50 || n % 500 == 0) {
-            gi.sortBufferBy(e => -failedTestsStats(e))
-          }
-          n += 1
-          gi.iterator
-        }
 
         try {
           do {
+            // Run CEGIS for one specific unfolding level
+
             // Unfold formula
             ndProgram.unfold()
 
-            // Compute all programs that have not been excluded yet
-            var prunedPrograms: Set[Set[Identifier]] = ndProgram.allPrograms().toSet
+            val nInitial = ndProgram.prunedPrograms.size
+            hctx.reporter.debug("#Programs: "+nInitial)
 
-            val nInitial = prunedPrograms.size
-            sctx.reporter.debug("#Programs: "+nInitial)
+            def nPassing = ndProgram.prunedPrograms.size
+
+            def programsReduced() = nPassing <= 10 || nInitial / nPassing > testReductionRatio
+            gi.canGrow = programsReduced
+
+            def allInputExamples() = {
+              if (n == 10 || n == 50 || n % 500 == 0) {
+                gi.sortBufferBy(e => -failedTestsStats(e))
+              }
+              n += 1
+              gi.iterator
+            }
 
             //sctx.reporter.ifDebug{ printer =>
             //  val limit = 100
@@ -783,152 +839,147 @@ abstract class CEGISLike[T <: Typed](name: String) extends Rule(name) {
             //    printer(" - ...")
             //  }
             //}
-
-            var wrongPrograms = Set[Set[Identifier]]()
+    
+            hctx.reporter.debug("#Tests: "+baseExampleInputs.size)
+            hctx.reporter.ifDebug{ printer =>
+              for (e <- baseExampleInputs.take(10)) {
+                printer(" - "+e.asString)
+              }
+              if(baseExampleInputs.size > 10) {
+                printer(" - ...")
+              }
+            }
 
             // We further filter the set of working programs to remove those that fail on known examples
             if (hasInputExamples) {
               timers.filter.start()
-              for (bs <- prunedPrograms if !interruptManager.isInterrupted) {
+              for (bs <- ndProgram.prunedPrograms if !interruptManager.isInterrupted) {
                 val examples = allInputExamples()
-                examples.find(e => !ndProgram.testForProgram(bs)(e)).foreach { e =>
-                  failedTestsStats(e) += 1
-                  sctx.reporter.debug(f" Program: ${ndProgram.getExpr(bs).asString}%-80s failed on: ${e.asString}")
-                  wrongPrograms += bs
-                  prunedPrograms -= bs
-                }
-
-                if (wrongPrograms.size+1 % 1000 == 0) {
-                  sctx.reporter.debug("..."+wrongPrograms.size)
+                var badExamples = List[Example]()
+                var stop = false
+                for (e <- examples if !stop) {
+                  ndProgram.testForProgram(bs)(e) match {
+                    case Some(true) => // ok, passes
+                    case Some(false) =>
+                      // Program fails the test
+                      stop = true
+                      failedTestsStats(e) += 1
+                      hctx.reporter.debug(f" Program: ${ndProgram.getExpr(bs).asString}%-80s failed on: ${e.asString}")
+                      ndProgram.excludeProgram(bs, true)
+                    case None =>
+                      // Eval. error -> bad example
+                      hctx.reporter.debug(s" Test $e failed, removing...")
+                      badExamples ::= e
+                  }
                 }
+                gi --= badExamples
               }
               timers.filter.stop()
             }
 
-            val nPassing = prunedPrograms.size
-            val nTotal   = ndProgram.allProgramsCount()
-            //println(s"Iotal: $nTotal, passing: $nPassing")
-
-            sctx.reporter.debug(s"#Programs passing tests: $nPassing out of $nTotal")
-            sctx.reporter.ifDebug{ printer =>
-              for (p <- prunedPrograms.take(100)) {
+            hctx.reporter.debug(s"#Programs passing tests: $nPassing out of $nInitial")
+            hctx.reporter.ifDebug{ printer =>
+              for (p <- ndProgram.prunedPrograms.take(100)) {
                 printer(" - "+ndProgram.getExpr(p).asString)
               }
               if(nPassing > 100) {
                 printer(" - ...")
               }
             }
-            sctx.reporter.debug("#Tests: "+baseExampleInputs.size)
-            sctx.reporter.ifDebug{ printer =>
-              for (e <- baseExampleInputs.take(10)) {
-                printer(" - "+e.asString)
-              }
-              if(baseExampleInputs.size > 10) {
-                printer(" - ...")
-              }
-            }
-
-            // We can skip CE search if - we have excluded all programs or - we do so with validatePrograms
-            var skipCESearch = nPassing == 0 || interruptManager.isInterrupted || {
-              // If the number of pruned programs is very small, or by far smaller than the number of total programs,
-              // we hypothesize it will be easier to just validate them individually.
-              // Otherwise, we validate a small number of programs just in case we are lucky FIXME is this last clause useful?
-              val (programsToValidate, otherPrograms) = if (nTotal / nPassing > passingRatio || nPassing < 10) {
-                (prunedPrograms, Nil)
-              } else {
-                prunedPrograms.splitAt(validateUpTo)
-              }
-
-              ndProgram.validatePrograms(programsToValidate) match {
-                case Left(sols) if sols.nonEmpty =>
-                  // Found solution! Exit CEGIS
-                  result = Some(RuleClosed(sols))
-                  true
-                case Right(cexs) =>
-                  // Found some counterexamples
-                  val newCexs = cexs.map(InExample)
-                  baseExampleInputs ++= newCexs
-                  // Retest whether the newly found C-E invalidates some programs
-                  for (p <- otherPrograms if !interruptManager.isInterrupted) {
-                    // Exclude any programs that fail at least one new cex
-                    newCexs.find { cex => !ndProgram.testForProgram(p)(cex) }.foreach { cex =>
-                      failedTestsStats(cex) += 1
-                      ndProgram.excludeProgram(p, true)
-                    }
-                  }
-                  // If we excluded all programs, we can skip CE search
-                  programsToValidate.size >= nPassing
-              }
-            }
-
-            if (!skipCESearch) {
-              sctx.reporter.debug("Excluding "+wrongPrograms.size+" programs")
-              wrongPrograms.foreach {
-                ndProgram.excludeProgram(_, true)
+              // CEGIS Loop at a given unfolding level
+            while (result.isEmpty && !interruptManager.isInterrupted && !ndProgram.allProgramsClosed) {
+              hctx.reporter.debug("Programs left: " + ndProgram.prunedPrograms.size)
+
+              // Phase 0: If the number of remaining programs is small, validate them individually
+              if (programsReduced()) {
+                timers.validate.start()
+                val programsToValidate = ndProgram.prunedPrograms
+                hctx.reporter.debug(s"Will send ${programsToValidate.size} program(s) to validate individually")
+                ndProgram.validatePrograms(programsToValidate) match {
+                  case Right(sol) =>
+                    // Found solution! Exit CEGIS
+                    result = Some(RuleClosed(sol))
+                  case Left(cexs) =>
+                    hctx.reporter.debug(s"Found cexs! $cexs")
+                    // Found some counterexamples
+                    // (bear in mind that these will in fact exclude programs within validatePrograms())
+                    val newCexs = cexs.map(InExample)
+                    newCexs foreach (failedTestsStats(_) += 1)
+                    gi ++= newCexs
+                }
+                hctx.reporter.debug(s"#Programs after validating individually: ${ndProgram.prunedPrograms.size}")
+                timers.validate.stop()
               }
-            }
 
-            // CEGIS Loop at a given unfolding level
-            while (result.isEmpty && !skipCESearch && !interruptManager.isInterrupted && !ndProgram.allProgramsClosed) {
-              timers.loop.start()
-              ndProgram.solveForTentativeProgram() match {
-                case Some(Some(bs)) =>
-                  // No inputs to test or all valid inputs also work with this.
-                  // We need to make sure by validating this candidate with z3
-                  sctx.reporter.debug("Found tentative model, need to validate!")
-                  ndProgram.solveForCounterExample(bs) match {
-                    case Some(Some(inputsCE)) =>
-                      sctx.reporter.debug("Found counter-example:" + inputsCE)
-                      val ce = InExample(inputsCE)
-                      // Found counter example! Exclude this program
-                      baseExampleInputs += ce
-                      ndProgram.excludeProgram(bs, false)
-
-                      // Retest whether the newly found C-E invalidates some programs
-                      prunedPrograms.foreach { p =>
-                        if (!ndProgram.testForProgram(p)(ce)) ndProgram.excludeProgram(p, true)
-                      }
-
-                    case Some(None) =>
-                      // Found no counter example! Program is a valid solution
-                      val expr = ndProgram.getExpr(bs)
-                      result = Some(RuleClosed(Solution(BooleanLiteral(true), Set(), expr)))
+              if (result.isEmpty && !ndProgram.allProgramsClosed) {
+                // Phase 1: Find a candidate program that works for at least 1 input
+                hctx.reporter.debug("Looking for program that works on at least 1 input...")
+                ndProgram.solveForTentativeProgram() match {
+                  case Some(Some(bs)) =>
+                    hctx.reporter.debug(s"Found tentative model ${ndProgram.getExpr(bs)}, need to validate!")
+                    // Phase 2: Validate candidate model
+                    ndProgram.solveForCounterExample(bs) match {
+                      case Some(Some(inputsCE)) =>
+                        hctx.reporter.debug("Found counter-example:" + inputsCE)
+                        val ce = InExample(inputsCE)
+                        // Found counterexample! Exclude this program
+                        gi += ce
+                        failedTestsStats(ce) += 1
+                        ndProgram.excludeProgram(bs, false)
 
-                    case None =>
-                      // We are not sure
-                      sctx.reporter.debug("Unknown")
-                      if (useOptTimeout) {
-                        // Interpret timeout in CE search as "the candidate is valid"
-                        sctx.reporter.info("CEGIS could not prove the validity of the resulting expression")
+                        // Retest whether the newly found C-E invalidates some programs
+                        ndProgram.prunedPrograms.foreach { p =>
+                          ndProgram.testForProgram(p)(ce) match {
+                            case Some(true) =>
+                            case Some(false) =>
+                              hctx.reporter.debug(f" Program: ${ndProgram.getExpr(p).asString}%-80s failed on: ${ce.asString}")
+                              failedTestsStats(ce) += 1
+                              ndProgram.excludeProgram(p, true)
+                            case None =>
+                              hctx.reporter.debug(s" Test $ce failed, removing...")
+                              gi -= ce
+                          }
+                        }
+
+                      case Some(None) =>
+                        // Found no counter example! Program is a valid solution
                         val expr = ndProgram.getExpr(bs)
-                        result = Some(RuleClosed(Solution(BooleanLiteral(true), Set(), expr, isTrusted = false)))
-                      } else {
-                        // Ok, we failed to validate, exclude this program
-                        ndProgram.excludeProgram(bs, false)
-                        // TODO: Make CEGIS fail early when it fails on 1 program?
-                        // result = Some(RuleFailed())
-                      }
-                  }
+                        result = Some(RuleClosed(Solution(BooleanLiteral(true), Set(), expr)))
+
+                      case None =>
+                        // We are not sure
+                        hctx.reporter.debug("Unknown")
+                        if (useOptTimeout) {
+                          // Interpret timeout in CE search as "the candidate is valid"
+                          hctx.reporter.info("CEGIS could not prove the validity of the resulting expression")
+                          val expr = ndProgram.getExpr(bs)
+                          result = Some(RuleClosed(Solution(BooleanLiteral(true), Set(), expr, isTrusted = false)))
+                        } else {
+                          // Ok, we failed to validate, exclude this program
+                          ndProgram.excludeProgram(bs, false)
+                          // TODO: Make CEGIS fail early when it fails on 1 program?
+                          // result = Some(RuleFailed())
+                        }
+                    }
 
-                case Some(None) =>
-                  skipCESearch = true
+                  case Some(None) =>
+                    hctx.reporter.debug("There exists no candidate program!")
+                    ndProgram.prunedPrograms foreach (ndProgram.excludeProgram(_, true))
 
-                case None =>
-                  result = Some(RuleFailed())
+                  case None =>
+                    result = Some(RuleFailed())
+                }
               }
-
-              timers.loop.stop()
             }
 
-            unfolding += 1
-          } while(unfolding <= maxSize && result.isEmpty && !interruptManager.isInterrupted)
+          } while(ndProgram.unfolding < maxSize && result.isEmpty && !interruptManager.isInterrupted)
 
           if (interruptManager.isInterrupted) interruptManager.recoverInterrupt()
           result.getOrElse(RuleFailed())
 
         } catch {
           case e: Throwable =>
-            sctx.reporter.warning("CEGIS crashed: "+e.getMessage)
+            hctx.reporter.warning("CEGIS crashed: "+e.getMessage)
             e.printStackTrace()
             RuleFailed()
         }
diff --git a/src/main/scala/leon/synthesis/rules/CEGLESS.scala b/src/main/scala/leon/synthesis/rules/CEGLESS.scala
index 36cc7f9e65dae8af9d8c17d4db936dc4400c0ece..e29c6d2bc2ceb6a1d01d1c56f42381427be90386 100644
--- a/src/main/scala/leon/synthesis/rules/CEGLESS.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGLESS.scala
@@ -1,40 +1,36 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 package rules
 
-import leon.grammars.transformers.Union
 import purescala.ExprOps._
 import purescala.Types._
 import purescala.Extractors._
 import grammars._
 import Witnesses._
 
-case object CEGLESS extends CEGISLike[NonTerminal[String]]("CEGLESS") {
+case object CEGLESS extends CEGISLike("CEGLESS") {
   def getParams(sctx: SynthesisContext, p: Problem) = {
     val TopLevelAnds(clauses) = p.ws
 
-    val ctx = sctx.context
-
     val guides = clauses.collect {
       case Guide(e) => e
     }
 
-    val inputs = p.as.map(_.toVariable)
-
     sctx.reporter.ifDebug { printer =>
       printer("Guides available:")
       for (g <- guides) {
-        printer(" - "+g.asString(ctx))
+        printer(" - "+g.asString(sctx))
       }
     }
 
-    val guidedGrammar = Union(guides.map(SimilarTo(_, inputs.toSet, sctx, p)))
+    val guidedGrammar = Union(guides.map(SimilarTo(_, sctx, p)))
 
     CegisParams(
       grammar = guidedGrammar,
-      rootLabel = { (tpe: TypeTree) => NonTerminal(tpe, "G0") },
+      //rootLabel = { (tpe: TypeTree) => NonTerminal(tpe, "G0") },
+      rootLabel = { (tpe: TypeTree) => Label(tpe) },
       optimizations = false,
       maxSize = Some((0 +: guides.map(depth(_) + 1)).max)
     )
diff --git a/src/main/scala/leon/synthesis/rules/CaseSplit.scala b/src/main/scala/leon/synthesis/rules/CaseSplit.scala
index 29f27a93128bc58acf97961d0314a8472391df2b..fd820f96dc4b0746849056e590deba79d1cdc993 100644
--- a/src/main/scala/leon/synthesis/rules/CaseSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/CaseSplit.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -25,7 +25,7 @@ case object CaseSplit extends Rule("Case-Split") {
         val pre = orJoin(sols.map(_.pre))
         val defs = sols.map(_.defs).reduceLeft(_ ++ _)
 
-        val (prefix, last) = (sols.dropRight(1), sols.last)
+        val (prefix, last) = (sols.init, sols.last)
 
         val term = prefix.foldRight(last.term) { (s, t) => IfExpr(s.pre, s.term, t) }
 
diff --git a/src/main/scala/leon/synthesis/rules/DetupleInput.scala b/src/main/scala/leon/synthesis/rules/DetupleInput.scala
index d3b4c823dd7110763316d121407bcf94820c5826..28d567e1b868a61980809ef84f9aaecdc2d2bd12 100644
--- a/src/main/scala/leon/synthesis/rules/DetupleInput.scala
+++ b/src/main/scala/leon/synthesis/rules/DetupleInput.scala
@@ -1,14 +1,16 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 package rules
 
+import Witnesses.Hint
 import purescala.Expressions._
 import purescala.Common._
 import purescala.Types._
-import purescala.ExprOps._
+import purescala.ExprOps.simplePostTransform
 import purescala.Constructors._
+import purescala.Extractors.LetPattern
 
 /** Rule for detupling input variables, to be able to use their sub-expressions. For example, the input variable:
   * {{{d: Cons(head: Int, tail: List)}}}
@@ -30,28 +32,24 @@ case object DetupleInput extends NormalizingRule("Detuple In") {
      * into a list of fresh typed identifiers, the tuple of these new identifiers,
      * and the mapping of those identifiers to their respective expressions.
      */
-    def decompose(id: Identifier): (List[Identifier], Expr, Map[Identifier, Expr], Expr => Seq[Expr]) = id.getType match {
+    def decompose(id: Identifier): (List[Identifier], Expr, Expr => Seq[Expr]) = id.getType match {
       case cct @ CaseClassType(ccd, _) if !ccd.isAbstract =>
         val newIds = cct.fields.map{ vd => FreshIdentifier(vd.id.name, vd.getType, true) }
 
-        val map = (ccd.fields zip newIds).map{ case (vd, nid) => nid -> caseClassSelector(cct, Variable(id), vd.id) }.toMap
-
         val tMap: (Expr => Seq[Expr]) = {
           case CaseClass(ccd, fields) => fields
         }
 
-        (newIds.toList, CaseClass(cct, newIds.map(Variable)), map, tMap)
+        (newIds.toList, CaseClass(cct, newIds.map(Variable)), tMap)
 
       case TupleType(ts) =>
         val newIds = ts.zipWithIndex.map{ case (t, i) => FreshIdentifier(id.name+"_"+(i+1), t, true) }
 
-        val map = newIds.zipWithIndex.map{ case (nid, i) => nid -> TupleSelect(Variable(id), i+1) }.toMap
-
         val tMap: (Expr => Seq[Expr]) = {
           case Tuple(fields) => fields
         }
 
-        (newIds.toList, tupleWrap(newIds.map(Variable)), map, tMap)
+        (newIds.toList, tupleWrap(newIds.map(Variable)), tMap)
 
       case _ => sys.error("woot")
     }
@@ -60,20 +58,33 @@ case object DetupleInput extends NormalizingRule("Detuple In") {
       var subProblem = p.phi
       var subPc      = p.pc
       var subWs      = p.ws
-
-      var reverseMap = Map[Identifier, Expr]()
+      var hints: Seq[Expr] = Nil
+      var patterns = List[(Identifier, Pattern)]()
+      var revMap = Map[Expr, Expr]().withDefault((e: Expr) => e)
 
       var ebMapInfo = Map[Identifier, Expr => Seq[Expr]]()
 
       val subAs = p.as.map { a =>
         if (isDecomposable(a)) {
-          val (newIds, expr, map, tMap) = decompose(a)
+          val (newIds, expr, tMap) = decompose(a)
 
           subProblem = subst(a -> expr, subProblem)
           subPc      = subst(a -> expr, subPc)
           subWs      = subst(a -> expr, subWs)
+          revMap     += expr -> Variable(a)
+          hints      +:= Hint(expr)
 
-          reverseMap ++= map
+          val patts = newIds map (id => WildcardPattern(Some(id)))
+
+          patterns +:= ((
+            a,
+            a.getType match {
+              case TupleType(_) =>
+                TuplePattern(None, patts)
+              case cct: CaseClassType =>
+                CaseClassPattern(None, cct, patts)
+            }
+          ))
 
           ebMapInfo += a -> tMap
 
@@ -96,40 +107,19 @@ case object DetupleInput extends NormalizingRule("Detuple In") {
 
       val newAs = subAs.flatten
 
-      // Recompose CaseClasses and Tuples.
-      // E.g. Cons(l.head, l.tail) ~~> l
-      // (t._1, t._2, t._3) ~~> t
-      def recompose(e : Expr) : Expr = e match {
-        case CaseClass(ct, args) =>
-          val (cts, es) = args.zip(ct.fields).map { 
-            case (CaseClassSelector(ct, e, id), field) if field.id == id => (ct, e)
-            case _ =>
-              return e
-          }.unzip
-
-          if (cts.distinct.size == 1 && es.distinct.size == 1) {
-            es.head
-          } else {
-            e
-          }
-        case Tuple(args) =>
-          val es = args.zipWithIndex.map {
-            case (TupleSelect(e, i), index) if i == index + 1 => e
-            case _ => return e
-          }
-          if (es.distinct.size == 1) {
-            es.head
-          } else {
-            e
-          }
-        case other => other
-      }
-      
-      val sub = Problem(newAs, subWs, subPc, subProblem, p.xs, eb)
+      val (as, patts) = patterns.unzip
 
-      val s = (substAll(reverseMap, _:Expr)) andThen simplePostTransform(recompose)
+      val sub = Problem(newAs, subWs, subPc, subProblem, p.xs, eb).withWs(hints)
+
+      val s = { (e: Expr) =>
+        LetPattern(
+          tuplePatternWrap(patts),
+          tupleWrap(as map Variable),
+          simplePostTransform(revMap)(e)
+        )
+      }
      
-      Some(decomp(List(sub), forwardMap(s), s"Detuple ${reverseMap.keySet.mkString(", ")}"))
+      Some(decomp(List(sub), forwardMap(s), s"Detuple ${as.mkString(", ")}"))
     } else {
       None
     }
diff --git a/src/main/scala/leon/synthesis/rules/Disunification.scala b/src/main/scala/leon/synthesis/rules/Disunification.scala
index 82a05717a0f9abef83f93467697c3faab62aba53..a380dec539110cd5ae0f030bc3b98da8a12609cc 100644
--- a/src/main/scala/leon/synthesis/rules/Disunification.scala
+++ b/src/main/scala/leon/synthesis/rules/Disunification.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala
deleted file mode 100644
index 79595656c4c53cca6e47747ac34a52f436697b31..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon
-package synthesis
-package rules
-
-import leon.purescala.Common.Identifier
-import purescala.Expressions._
-import purescala.Extractors._
-import purescala.Constructors._
-
-import solvers._
-
-import scala.concurrent.duration._
-
-/** For every pair of input variables of the same type,
-  * checks equality and output an If-Then-Else statement with the two new branches. */
-case object EqualitySplit extends Rule("Eq. Split") {
-  def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
-    // We approximate knowledge of equality based on facts found at the top-level
-    // we don't care if the variables are known to be equal or not, we just
-    // don't want to split on two variables for which only one split
-    // alternative is viable. This should be much less expensive than making
-    //  calls to a solver for each pair.
-    var facts = Set[Set[Identifier]]()
-
-    def addFacts(e: Expr): Unit = e match {
-      case Not(e) => addFacts(e)
-      case LessThan(Variable(a), Variable(b))      => facts += Set(a,b)
-      case LessEquals(Variable(a), Variable(b))    => facts += Set(a,b)
-      case GreaterThan(Variable(a), Variable(b))   => facts += Set(a,b)
-      case GreaterEquals(Variable(a), Variable(b)) => facts += Set(a,b)
-      case Equals(Variable(a), Variable(b))        => facts += Set(a,b)
-      case _ =>
-    }
-
-    val TopLevelAnds(as) = and(p.pc, p.phi)
-    for (e <- as) {
-      addFacts(e)
-    }
-
-    val candidates = p.as.groupBy(_.getType).mapValues{ as =>
-      as.combinations(2).filterNot(facts contains _.toSet)
-    }.values.flatten
-
-    candidates.flatMap {
-      case List(a1, a2) =>
-
-        val sub1 = p.copy(
-          pc = and(Equals(Variable(a1), Variable(a2)), p.pc),
-          eb = p.qeb.filterIns( (m: Map[Identifier, Expr]) => m(a1) == m(a2))
-        )
-        val sub2 = p.copy(
-          pc = and(not(Equals(Variable(a1), Variable(a2))), p.pc),
-          eb = p.qeb.filterIns( (m: Map[Identifier, Expr]) => m(a1) != m(a2))
-        )
-
-        val onSuccess: List[Solution] => Option[Solution] = {
-          case List(s1, s2) =>
-            Some(Solution(or(s1.pre, s2.pre), s1.defs ++ s2.defs, IfExpr(Equals(Variable(a1), Variable(a2)), s1.term, s2.term), s1.isTrusted && s2.isTrusted))
-          case _ =>
-            None
-        }
-
-        Some(decomp(List(sub1, sub2), onSuccess, s"Eq. Split on '$a1' and '$a2'"))
-      case _ =>
-        None
-    }
-  }
-}
diff --git a/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala b/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala
index 6b2f9e8585a98ab9677aa5f1c439b2a1afa136ef..2ee67ad7fa072f112c24fc2aab9183b79456de03 100644
--- a/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala
+++ b/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -17,7 +17,7 @@ case object EquivalentInputs extends NormalizingRule("EquivalentInputs") {
 
     def discoverEquivalences(allClauses: Seq[Expr]): Seq[(Expr, Expr)] = {
       val instanceOfs = allClauses.collect {
-        case ccio @ IsInstanceOf(cct, s) => ccio
+        case ccio: IsInstanceOf => ccio
       }
 
       val clauses = allClauses.filterNot(instanceOfs.toSet)
@@ -27,15 +27,9 @@ case object EquivalentInputs extends NormalizingRule("EquivalentInputs") {
         val fieldsVals = (for (f <- cct.classDef.fields) yield {
           val id = f.id
 
-          clauses.find {
-            case Equals(e, CaseClassSelector(`cct`, `s`, `id`)) => true
-            case Equals(e, CaseClassSelector(`cct`, AsInstanceOf(`s`, `cct`), `id`)) => true
-            case _ => false
-          } match {
-            case Some(Equals(e, _)) =>
-              Some(e)
-            case _ =>
-              None
+          clauses.collectFirst {
+            case Equals(e, CaseClassSelector(`cct`, `s`, `id`)) => e
+            case Equals(e, CaseClassSelector(`cct`, AsInstanceOf(`s`, `cct`), `id`)) => e
           }
 
         }).flatten
@@ -73,14 +67,20 @@ case object EquivalentInputs extends NormalizingRule("EquivalentInputs") {
     }
 
     if (substs.nonEmpty) {
-      val simplifier = Simplifiers.bestEffort(hctx.context, hctx.program) _
+      val simplifier = Simplifiers.bestEffort(hctx, hctx.program) _
 
-      val sub = p.copy(ws = replaceSeq(substs, p.ws), 
-                       pc = simplifier(andJoin(replaceSeq(substs, p.pc) +: postsToInject)),
-                       phi = simplifier(replaceSeq(substs, p.phi)))
+      val removedAs = substs.collect { case (Variable(from), _) => from }.toSet
+
+      val sub = p.copy(
+        as = p.as filterNot removedAs,
+        ws = replaceSeq(substs, p.ws),
+        pc = simplifier(andJoin(replaceSeq(substs, p.pc) +: postsToInject)),
+        phi = simplifier(replaceSeq(substs, p.phi)),
+        eb = p.qeb.removeIns(removedAs)
+      )
 
       val subst = replace(
-        substs.map{_.swap}.filter{ case (x,y) => formulaSize(x) > formulaSize(y) }.toMap, 
+        substs.map{_.swap}.filter{ case (x,y) => formulaSize(x) > formulaSize(y) }.toMap,
         _:Expr
       )
       
diff --git a/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala b/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8dce44d6878ad24ed96dd5c33b9461100cd9f417
--- /dev/null
+++ b/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala
@@ -0,0 +1,72 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package rules
+
+import leon.purescala.Common.Identifier
+import purescala.Constructors._
+import purescala.Expressions._
+import leon.purescala.Extractors.{IsTyped, TopLevelAnds}
+import purescala.Types._
+
+/** For every pair of input variables of the same generic type,
+  * checks equality and output an If-Then-Else statement with the two new branches.
+  */
+case object GenericTypeEqualitySplit extends Rule("Eq. Split") {
+  def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
+    // We approximate knowledge of equality based on facts found at the top-level
+    // we don't care if the variables are known to be equal or not, we just
+    // don't want to split on two variables for which only one split
+    // alternative is viable. This should be much less expensive than making
+    // calls to a solver for each pair.
+    def getFacts(e: Expr): Set[Set[Identifier]] = e match {
+      case Not(e)       => getFacts(e)
+      case Equals(Variable(a), Variable(b)) => Set(Set(a,b))
+      case _ => Set()
+    }
+
+    val TopLevelAnds(as) = and(p.pc, p.phi)
+
+    val facts = as.flatMap(getFacts).toSet
+
+    val candidates = p.as.combinations(2).collect {
+      case List(IsTyped(a1, TypeParameter(t1)), IsTyped(a2, TypeParameter(t2)))
+        if t1 == t2 && !facts(Set(a1, a2)) =>
+        (a1, a2)
+    }.toList
+
+    candidates.flatMap {
+      case (a1, a2) =>
+        val v1 = Variable(a1)
+        val v2 = Variable(a2)
+        val subProblems = List(
+          p.copy(as  = p.as.diff(Seq(a1)),
+                 pc  = subst(a1 -> v2, p.pc),
+                 ws  = subst(a1 -> v2, p.ws),
+                 phi = subst(a1 -> v2, p.phi),
+                 eb  = p.qeb.filterIns(Equals(v1, v2)).removeIns(Set(a1))),
+
+          p.copy(pc = and(p.pc, not(Equals(v1, v2))),
+                 eb = p.qeb.filterIns(not(Equals(v1, v2))))
+        )
+
+        val onSuccess: List[Solution] => Option[Solution] = {
+          case sols @ List(sEQ, sNE) =>
+            val pre = or(
+              and(Equals(v1, v2),      sEQ.pre),
+              and(not(Equals(v1, v2)), sNE.pre)
+            )
+
+            val term = IfExpr(Equals(v1, v2), sEQ.term, sNE.term)
+
+            Some(Solution(pre, sols.flatMap(_.defs).toSet, term, sols.forall(_.isTrusted)))
+        }
+
+        Some(decomp(subProblems, onSuccess, s"Eq. Split on '$v1' and '$v2'"))
+
+      case _ =>
+        None
+    }
+  }
+}
diff --git a/src/main/scala/leon/synthesis/rules/Ground.scala b/src/main/scala/leon/synthesis/rules/Ground.scala
index d36cb15c0ff6f487d5d7b5e296fda0c406406886..588f94c1807972d77f78cd9793f7f23fe4702557 100644
--- a/src/main/scala/leon/synthesis/rules/Ground.scala
+++ b/src/main/scala/leon/synthesis/rules/Ground.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -10,12 +10,12 @@ import purescala.ExprOps._
 import purescala.Constructors._
 import scala.concurrent.duration._
 
-case object Ground extends Rule("Ground") {
+case object Ground extends NormalizingRule("Ground") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
     if (p.as.isEmpty) {
       List(new RuleInstantiation(this.name) {
         def apply(hctx: SearchContext): RuleApplication = {
-          val solver = SimpleSolverAPI(hctx.sctx.solverFactory.withTimeout(10.seconds))
+          val solver = SimpleSolverAPI(hctx.solverFactory.withTimeout(10.seconds))
 
           val result = solver.solveSAT(p.phi) match {
             case (Some(true), model) =>
diff --git a/src/main/scala/leon/synthesis/rules/IfSplit.scala b/src/main/scala/leon/synthesis/rules/IfSplit.scala
index 0ff4cf4fdbfd555162c809071b1009e572d2a9a8..9b97898b910c1deba421da39c77372b8bf74f1ee 100644
--- a/src/main/scala/leon/synthesis/rules/IfSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/IfSplit.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/IndependentSplit.scala b/src/main/scala/leon/synthesis/rules/IndependentSplit.scala
index 72be06b9cff76a63ced4506ef086a58622326bef..fa8eceb3a7f70ab8a39644fdd60aa8014d516603 100644
--- a/src/main/scala/leon/synthesis/rules/IndependentSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/IndependentSplit.scala
@@ -1,20 +1,74 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 package rules
 
-import leon.utils._
 import purescala.Expressions._
+import purescala.Types._
 import purescala.ExprOps._
 import purescala.Extractors._
 import purescala.Constructors._
 import purescala.Common._
-import purescala.Types.CaseClassType
 
+/** Split output if parts of it are independent in the spec.
+  * Works in 2 phases:
+  * 1) Detuples output variables if they are tuples or case classes to their fields.
+  * 2) Tries to split spec in independent parts and solve them separately.
+  */
 case object IndependentSplit extends NormalizingRule("IndependentSplit") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
-    val TopLevelAnds(clauses) = and(p.pc, p.phi)
+
+    /**** Phase 1 ****/
+    def isDecomposable(id: Identifier) = id.getType match {
+      case CaseClassType(_, _) => true
+      case TupleType(_) => true
+      case _ => false
+    }
+
+    val (newP, recon) = if (p.xs.exists(isDecomposable)) {
+      var newPhi = p.phi
+
+      val (subOuts, outerOuts) = p.xs.map { x =>
+        x.getType match {
+          case ct: CaseClassType =>
+            val newIds = ct.fields.map { vd => FreshIdentifier(vd.id.name, vd.getType, true) }
+
+            val newCC = CaseClass(ct, newIds.map(Variable))
+
+            newPhi = subst(x -> newCC, newPhi)
+
+            (newIds, newCC)
+          case tt: TupleType =>
+            val newIds = tt.bases.zipWithIndex.map{ case (t, ind) =>
+              FreshIdentifier(s"${x}_${ind+1}", t, true)
+            }
+            val newTuple = Tuple(newIds map Variable)
+            newPhi = subst(x -> newTuple, newPhi)
+            (newIds, newTuple)
+          case _ =>
+            (List(x), Variable(x))
+        }
+      }.unzip
+
+      val newOuts = subOuts.flatten
+
+      val newEb = p.qeb.eb.mapOuts{ xs => List( (xs zip p.xs) flatMap {
+        case (CaseClass(_, args), id) if isDecomposable(id) => args.toList
+        case (Tuple(args), _) => args.toList
+        case (other, _) => List(other)
+      })}
+
+      val newProb = Problem(p.as, p.ws, p.pc, newPhi, newOuts, newEb)
+      (newProb, letTuple(newOuts, _:Expr, tupleWrap(outerOuts)))
+      //, s"Detuple out ${p.xs.filter(isDecomposable).mkString(", ")}"))
+    } else {
+      (p, (e: Expr) => e)
+    }
+
+    /**** Phase 2 ****/
+
+    val TopLevelAnds(clauses) = and(newP.pc, newP.phi)
 
     var independentClasses = Set[Set[Identifier]]()
 
@@ -37,23 +91,23 @@ case object IndependentSplit extends NormalizingRule("IndependentSplit") {
       independentClasses = newClasses + thisClass
     }
 
-    val outClasses = independentClasses.map(cl => cl & p.xs.toSet).filter(_.nonEmpty)
+    val outClasses = independentClasses.map(cl => cl & newP.xs.toSet).filter(_.nonEmpty)
 
     if (outClasses.size > 1) {
 
-      val TopLevelAnds(phiClauses) = p.phi
+      val TopLevelAnds(phiClauses) = newP.phi
 
       val subs = (for (cl <- outClasses.toList) yield {
-        val xs = p.xs.filter(cl)
+        val xs = newP.xs.filter(cl)
 
         if (xs.nonEmpty) {
           val phi = andJoin(phiClauses.filter(c => (variablesOf(c) & cl).nonEmpty))
 
-          val xsToRemove = p.xs.filterNot(cl).toSet
+          val xsToRemove = newP.xs.filterNot(cl).toSet
 
-          val eb = p.qeb.removeOuts(xsToRemove)
+          val eb = newP.qeb.removeOuts(xsToRemove)
 
-          Some(p.copy(phi = phi, xs = xs, eb = eb))
+          Some(newP.copy(phi = phi, xs = xs, eb = eb))
         } else {
           None
         }
@@ -63,15 +117,14 @@ case object IndependentSplit extends NormalizingRule("IndependentSplit") {
 
         val infos = subs.map(_.xs).zip(sols.map(_.term))
 
-        val term = infos.foldLeft(tupleWrap(p.xs.map(_.toVariable))) {
+        val term = infos.foldLeft(tupleWrap(newP.xs.map(_.toVariable))) {
           case (expr, (xs, term)) =>
             letTuple(xs, term, expr)
         }
 
-        Some(Solution(andJoin(sols.map(_.pre)), sols.map(_.defs).flatten.toSet, term, sols.forall(_.isTrusted)))
+        Some(Solution(andJoin(sols.map(_.pre)), sols.flatMap(_.defs).toSet, recon(term), sols.forall(_.isTrusted)))
       }
 
-
       List(decomp(subs, onSuccess, "Independent Clusters"))
     } else {
       Nil
diff --git a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala
index 8b728930a10ad7d73c121762bde43637ce988fbc..54445a5d48dc199440366aa8ac302d1c075bd4c2 100644
--- a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala
+++ b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -8,78 +8,99 @@ import purescala.Expressions._
 import purescala.Types._
 import purescala.Constructors._
 import purescala.Extractors._
-import purescala.Common._
-
-import scala.concurrent.duration._
 
+/** For every pair of variables of an integer type plus 0 of that type,
+  * splits for inequality between these variables
+  * and reconstructs the subproblems with a (nested) if-then-else.
+  *
+  * Takes into account knowledge about equality/inequality in the path condition.
+  *
+  */
 case object InequalitySplit extends Rule("Ineq. Split.") {
+
+  // Represents NEGATIVE knowledge
+  private abstract class Fact {
+    val l: Expr
+    val r: Expr
+  }
+  private case class LT(l: Expr, r: Expr) extends Fact
+  private case class EQ(l: Expr, r: Expr) extends Fact
+
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
-    // We approximate knowledge of equality based on facts found at the top-level
-    // we don't care if the variables are known to be equal or not, we just
-    // don't want to split on two variables for which only one split
-    // alternative is viable. This should be much less expensive than making
-    //  calls to a solver for each pair.
-    var facts = Set[Set[Identifier]]()
-
-    def addFacts(e: Expr): Unit = e match {
-      case Not(e) => addFacts(e)
-      case LessThan(Variable(a), Variable(b))      => facts += Set(a,b)
-      case LessEquals(Variable(a), Variable(b))    => facts += Set(a,b)
-      case GreaterThan(Variable(a), Variable(b))   => facts += Set(a,b)
-      case GreaterEquals(Variable(a), Variable(b)) => facts += Set(a,b)
-      case Equals(Variable(a), Variable(b))        => facts += Set(a,b)
-      case _ =>
-    }
 
     val TopLevelAnds(as) = and(p.pc, p.phi)
-    for (e <- as) {
-      addFacts(e)
+
+    def getFacts(e: Expr): Set[Fact] = e match {
+      case LessThan(a, b)           => Set(LT(b,a), EQ(a,b))
+      case LessEquals(a, b)         => Set(LT(b,a))
+      case GreaterThan(a, b)        => Set(LT(a,b), EQ(a,b))
+      case GreaterEquals(a, b)      => Set(LT(a,b))
+      case Equals(a, b)             => Set(LT(a,b), LT(b,a))
+      case Not(LessThan(a, b))      => Set(LT(a,b))
+      case Not(LessEquals(a, b))    => Set(LT(a,b), EQ(a,b))
+      case Not(GreaterThan(a, b))   => Set(LT(b,a))
+      case Not(GreaterEquals(a, b)) => Set(LT(b,a), EQ(a,b))
+      case Not(Equals(a, b))        => Set(EQ(a,b))
+      case _ => Set()
     }
 
-    val argsPairs = p.as.filter(_.getType == IntegerType).combinations(2) ++
-                    p.as.filter(_.getType == Int32Type).combinations(2)
-
-    val candidates = argsPairs.toList.filter { case List(a1, a2) => !(facts contains Set(a1, a2)) }
-
-    candidates.collect {
-      case List(a1, a2) =>
-        val onSuccess: List[Solution] => Option[Solution] = {
-          case sols@List(sLT, sEQ, sGT) =>
-            val pre = orJoin(sols.map(_.pre))
-            val defs = sLT.defs ++ sEQ.defs ++ sGT.defs
-
-            val term = IfExpr(
-              LessThan(Variable(a1), Variable(a2)),
-              sLT.term,
-              IfExpr(
-                Equals(Variable(a1), Variable(a2)),
-                sEQ.term,
-                sGT.term
-              )
-            )
-
-            Some(Solution(pre, defs, term, sols.forall(_.isTrusted)))
-          case _ =>
-            None
-        }
+    val facts = as flatMap getFacts
 
-        val subTypes = List(p.outType, p.outType, p.outType)
+    val candidates =
+      (p.as.map(_.toVariable).filter(_.getType == Int32Type) :+ IntLiteral(0)).combinations(2).toList ++
+      (p.as.map(_.toVariable).filter(_.getType == IntegerType) :+ InfiniteIntegerLiteral(0)).combinations(2).toList
 
-        new RuleInstantiation(s"Ineq. Split on '$a1' and '$a2'",
-                              SolutionBuilderDecomp(subTypes, onSuccess)) {
+    candidates.flatMap {
+      case List(v1, v2) =>
 
-          def apply(hctx: SearchContext) = {
-            implicit val _ = hctx
+        val lt = if (!facts.contains(LT(v1, v2))) {
+          val pc = LessThan(v1, v2)
+          Some(pc, p.copy(pc = and(p.pc, pc), eb = p.qeb.filterIns(pc)))
+        } else None
 
-            val subLT = p.copy(pc = and(LessThan(Variable(a1), Variable(a2)), p.pc),
-                               eb = p.qeb.filterIns(LessThan(Variable(a1), Variable(a2))))
-            val subEQ = p.copy(pc = and(Equals(Variable(a1), Variable(a2)), p.pc),
-                               eb = p.qeb.filterIns(Equals(Variable(a1), Variable(a2))))
-            val subGT = p.copy(pc = and(GreaterThan(Variable(a1), Variable(a2)), p.pc),
-                               eb = p.qeb.filterIns(GreaterThan(Variable(a1), Variable(a2))))
+        val gt = if (!facts.contains(LT(v2, v1))) {
+          val pc = GreaterThan(v1, v2)
+          Some(pc, p.copy(pc = and(p.pc, pc), eb = p.qeb.filterIns(pc)))
+        } else None
 
-            RuleExpanded(List(subLT, subEQ, subGT))
+        val eq = if (!facts.contains(EQ(v1, v2)) && !facts.contains(EQ(v2,v1))) {
+          val pc = Equals(v1, v2)
+          // One of v1, v2 will be an input variable
+          val a1 = (v1, v2) match {
+            case (Variable(a), _) => a
+            case (_, Variable(a)) => a
           }
+          val newP = p.copy(
+            as = p.as.diff(Seq(a1)),
+            pc = subst(a1 -> v2, p.pc),
+            ws = subst(a1 -> v2, p.ws),
+            phi = subst(a1 -> v2, p.phi),
+            eb = p.qeb.filterIns(Equals(v1, v2)).removeIns(Set(a1))
+          )
+          Some(pc, newP)
+        } else None
+
+        val (pcs, subProblems) = List(eq, lt, gt).flatten.unzip
+
+        if (pcs.size < 2) None
+        else {
+
+          val onSuccess: List[Solution] => Option[Solution] = { sols =>
+            val pre = orJoin(pcs.zip(sols).map { case (pc, sol) =>
+              and(pc, sol.pre)
+            })
+
+            val term = pcs.zip(sols) match {
+              case Seq((pc1, s1), (_, s2)) =>
+                IfExpr(pc1, s1.term, s2.term)
+              case Seq((pc1, s1), (pc2, s2), (_, s3)) =>
+                IfExpr(pc1, s1.term, IfExpr(pc2, s2.term, s3.term))
+            }
+
+            Some(Solution(pre, sols.flatMap(_.defs).toSet, term, sols.forall(_.isTrusted)))
+          }
+
+          Some(decomp(subProblems, onSuccess, s"Ineq. Split on '$v1' and '$v2'"))
         }
     }
   }
diff --git a/src/main/scala/leon/synthesis/rules/InnerCaseSplit.scala b/src/main/scala/leon/synthesis/rules/InnerCaseSplit.scala
index 858a10a96b2cb8ab84f401ffd878bd584bf1a055..dff8b6f23f66ad8a96957635313510e1dd525db5 100644
--- a/src/main/scala/leon/synthesis/rules/InnerCaseSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/InnerCaseSplit.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/InputSplit.scala b/src/main/scala/leon/synthesis/rules/InputSplit.scala
index 4b9ffef53793528b628b41485c0a9156e171f188..293c9767d09ac86f5953cd9422021caad955630d 100644
--- a/src/main/scala/leon/synthesis/rules/InputSplit.scala
+++ b/src/main/scala/leon/synthesis/rules/InputSplit.scala
@@ -1,47 +1,43 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
 package rules
 
-import leon.purescala.Common.Identifier
 import purescala.Expressions._
-import purescala.Extractors._
 import purescala.ExprOps._
 import purescala.Constructors._
 import purescala.Types._
 
-import solvers._
-
-import scala.concurrent.duration._
-
 case object InputSplit extends Rule("In. Split") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
     p.as.filter(_.getType == BooleanType).flatMap { a =>
-        def getProblem(v: Boolean): Problem = {
-          def replaceA(e: Expr) = replaceFromIDs(Map(a -> BooleanLiteral(v)), e)
-
-          p.copy(
-            as  = p.as.filterNot(_ == a),
-            ws  = replaceA(p.ws),
-            pc  = replaceA(p.pc),
-            phi = replaceA(p.phi),
-            eb  = p.qeb.removeIns(Set(a))
-          )
-        }
-
-        val sub1 = getProblem(true)
-        val sub2 = getProblem(false)
-
-        val onSuccess: List[Solution] => Option[Solution] = {
-          case List(s1, s2) =>
-            Some(Solution(or(and(Equals(Variable(a), BooleanLiteral(true)), s1.pre), 
-                             and(Equals(Variable(a), BooleanLiteral(false)), s2.pre)),
-                          s1.defs ++ s2.defs, 
-                          IfExpr(Variable(a), s1.term, s2.term), s1.isTrusted && s2.isTrusted))
-          case _ =>
-            None
-        }
+      def getProblem(v: Boolean): Problem = {
+        def replaceA(e: Expr) = replaceFromIDs(Map(a -> BooleanLiteral(v)), e)
+
+        val tests = QualifiedExamplesBank(p.as, p.xs, p.qeb.filterIns(m => m(a) == BooleanLiteral(v)))
+
+        p.copy(
+          as  = p.as.filterNot(_ == a),
+          ws  = replaceA(p.ws),
+          pc  = replaceA(p.pc),
+          phi = replaceA(p.phi),
+          eb  = tests.removeIns(Set(a))
+        )
+      }
+
+      val sub1 = getProblem(true)
+      val sub2 = getProblem(false)
+
+      val onSuccess: List[Solution] => Option[Solution] = {
+        case List(s1, s2) =>
+          Some(Solution(or(and(    Variable(a) , s1.pre),
+                           and(Not(Variable(a)), s2.pre)),
+                        s1.defs ++ s2.defs,
+                        IfExpr(Variable(a), s1.term, s2.term), s1.isTrusted && s2.isTrusted))
+        case _ =>
+          None
+      }
 
       Some(decomp(List(sub1, sub2), onSuccess, s"Split on '$a'"))
     }
diff --git a/src/main/scala/leon/synthesis/rules/IntroduceRecCalls.scala b/src/main/scala/leon/synthesis/rules/IntroduceRecCalls.scala
new file mode 100644
index 0000000000000000000000000000000000000000..aca95e883edbdbbd9f24f5ffc2ec8a0cfb4897b9
--- /dev/null
+++ b/src/main/scala/leon/synthesis/rules/IntroduceRecCalls.scala
@@ -0,0 +1,99 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package rules
+
+import evaluators.DefaultEvaluator
+import purescala.Definitions.Program
+import purescala.Extractors.TopLevelAnds
+import purescala.Expressions._
+import purescala.Constructors._
+import purescala.Common._
+import Witnesses.Terminating
+import utils.Helpers.terminatingCalls
+
+case object IntroduceRecCalls extends NormalizingRule("Introduce rec. calls") {
+
+  private class NoChooseEvaluator(ctx: LeonContext, prog: Program) extends DefaultEvaluator(ctx, prog) {
+    override def e(expr: Expr)(implicit rctx: RC, gctx: GC): Expr = expr match {
+      case ch: Choose =>
+        throw EvalError("Encountered choose!")
+      case _ =>
+        super.e(expr)
+    }
+  }
+
+  def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
+    val TopLevelAnds(pcs) = p.pc
+    val existingCalls = pcs.collect { case Equals(_, fi: FunctionInvocation) => fi }.toSet
+
+    val calls = terminatingCalls(hctx.program, p.ws, p.pc, None, false)
+      .map(_._1).distinct.filterNot(existingCalls)
+
+    if (calls.isEmpty) return Nil
+
+    val specifyCalls = hctx.findOptionOrDefault(SynthesisPhase.optSpecifyRecCalls)
+
+    val (recs, posts) = calls.map { newCall =>
+      val rec = FreshIdentifier("rec", newCall.getType, alwaysShowUniqueID = true)
+
+      // Assume the postcondition of recursive call
+      val post = if (specifyCalls) {
+        Equals(rec.toVariable, newCall)
+      } else {
+        application(
+          newCall.tfd.withParamSubst(newCall.args, newCall.tfd.postOrTrue),
+          Seq(rec.toVariable)
+        )
+      }
+      (rec, post)
+    }.unzip
+
+    val onSuccess = forwardMap(letTuple(recs, tupleWrap(calls), _))
+
+    List(new RuleInstantiation(s"Introduce recursive calls ${calls mkString ", "}", SolutionBuilderDecomp(List(p.outType), onSuccess)) {
+
+      def apply(nohctx: SearchContext): RuleApplication = {
+
+        val psol = new PartialSolution(hctx.search.strat, true)
+          .solutionAround(hctx.currentNode)(Error(p.outType, "Encountered choose!"))
+          .getOrElse(hctx.reporter.fatalError("Unable to get outer solution"))
+          .term
+
+        val origImpl = hctx.functionContext.fullBody
+        hctx.functionContext.fullBody = psol
+
+        val evaluator = new NoChooseEvaluator(hctx, hctx.program)
+        def mapExample(ex: Example): List[Example] = {
+          val results = calls map (evaluator.eval(_, p.as.zip(ex.ins).toMap).result)
+          if (results forall (_.isDefined)) List({
+            val extra = results map (_.get)
+            ex match {
+              case InExample(ins) =>
+                InExample(ins ++ extra)
+              case InOutExample(ins, outs) =>
+                InOutExample(ins ++ extra, outs)
+            }
+          }) else Nil
+        }
+
+        val newWs = calls map Terminating
+        val TopLevelAnds(ws) = p.ws
+        try {
+          val newProblem = p.copy(
+            as = p.as ++ recs,
+            pc = andJoin(p.pc +: posts),
+            ws = andJoin(ws ++ newWs),
+            eb = p.eb.map(mapExample)
+          )
+
+          RuleExpanded(List(newProblem))
+        } finally {
+          hctx.functionContext.fullBody = origImpl
+        }
+      }
+    })
+
+  }
+}
diff --git a/src/main/scala/leon/synthesis/rules/OnePoint.scala b/src/main/scala/leon/synthesis/rules/OnePoint.scala
index 3afcaf5729d215edbaea19e128fddb1bc27a6fe9..8665eaf3320757d8a4d295cc7953899d01d8f55d 100644
--- a/src/main/scala/leon/synthesis/rules/OnePoint.scala
+++ b/src/main/scala/leon/synthesis/rules/OnePoint.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala
index 679e49e38fb25ce3c4f79a26e1078651eccb69a5..775b496be24f105b83cb8af536cd193b7260c5ba 100644
--- a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala
+++ b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -18,7 +18,7 @@ case object OptimisticGround extends Rule("Optimistic Ground") {
       val res = new RuleInstantiation(this.name) {
         def apply(hctx: SearchContext) = {
 
-          val solver = SimpleSolverAPI(hctx.sctx.solverFactory.withTimeout(50.millis))
+          val solver = SimpleSolverAPI(hctx.solverFactory.withTimeout(50.millis))
 
           val xss = p.xs.toSet
           val ass = p.as.toSet
diff --git a/src/main/scala/leon/synthesis/rules/StringRender.scala b/src/main/scala/leon/synthesis/rules/StringRender.scala
index 715d54385e07a86f642fa454b78bcf72f020b528..ec681763eec062c7b6a29267f9ed209b4646460c 100644
--- a/src/main/scala/leon/synthesis/rules/StringRender.scala
+++ b/src/main/scala/leon/synthesis/rules/StringRender.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -6,10 +6,8 @@ package rules
 
 import scala.annotation.tailrec
 import scala.collection.mutable.ListBuffer
-import bonsai.enumerators.MemoizedEnumerator
-import evaluators.DefaultEvaluator
 import evaluators.AbstractEvaluator
-import purescala.Definitions.{FunDef, ValDef, Program, TypedFunDef, CaseClassDef, AbstractClassDef}
+import purescala.Definitions._
 import purescala.Common._
 import purescala.Types._
 import purescala.Constructors._
@@ -19,14 +17,10 @@ import purescala.TypeOps
 import purescala.DefOps
 import purescala.ExprOps
 import purescala.SelfPrettyPrinter
-import solvers.Model
 import solvers.ModelBuilder
 import solvers.string.StringSolver
-import synthesis.programsets.DirectProgramSet
-import synthesis.programsets.JoinProgramSet
-import leon.utils.DebugSectionSynthesis
-
-
+import programsets.DirectProgramSet
+import programsets.JoinProgramSet
 
 
 /** A template generator for a given type tree. 
@@ -148,7 +142,8 @@ case object StringRender extends Rule("StringRender") {
   
   /** Returns a stream of assignments compatible with input/output examples for the given template */
   def findAssignments(p: Program, inputs: Seq[Identifier], examples: ExamplesBank, template: Expr)(implicit hctx: SearchContext): Stream[Map[Identifier, String]] = {
-    val e = new AbstractEvaluator(hctx.context, p)
+
+    val e = new AbstractEvaluator(hctx, p)
     
     @tailrec def gatherEquations(s: List[InOutExample], acc: ListBuffer[Equation] = ListBuffer()): Option[SProblem] = s match {
       case Nil => Some(acc.toList)
@@ -201,7 +196,7 @@ case object StringRender extends Rule("StringRender") {
     
     def computeSolutions(funDefsBodies: Seq[(FunDef, WithIds[Expr])], template: WithIds[Expr]): Stream[Assignment] = {
       val funDefs = for((funDef, body) <- funDefsBodies) yield  { funDef.body = Some(body._1); funDef }
-      val newProgram = DefOps.addFunDefs(hctx.program, funDefs, hctx.sctx.functionContext)
+      val newProgram = DefOps.addFunDefs(hctx.program, funDefs, hctx.functionContext)
       findAssignments(newProgram, p.as.filter{ x => !x.getType.isInstanceOf[FunctionType] }, examples, template._1)
     }
     
@@ -327,9 +322,9 @@ case object StringRender extends Rule("StringRender") {
   /** Creates an empty function definition for the dependent type */
   def createEmptyFunDef(ctx: StringSynthesisContext, tpe: DependentType)(implicit hctx: SearchContext): FunDef = {
     def defaultFunName(t: TypeTree) = t match {
-      case AbstractClassType(c, d) => c.id.asString(hctx.context)
-      case CaseClassType(c, d) => c.id.asString(hctx.context)
-      case t => t.asString(hctx.context)
+      case AbstractClassType(c, d) => c.id.asString(hctx)
+      case CaseClassType(c, d) => c.id.asString(hctx)
+      case t => t.asString(hctx)
     }
     
     val funName2 = tpe.caseClassParent match {
@@ -339,10 +334,9 @@ case object StringRender extends Rule("StringRender") {
     val funName3 = funName2.replaceAll("[^a-zA-Z0-9_]","")
     val funName = funName3(0).toLower + funName3.substring(1) 
     val funId = FreshIdentifier(ctx.freshFunName(funName), alwaysShowUniqueID = true)
-    val argId= FreshIdentifier(tpe.typeToConvert.asString(hctx.context).toLowerCase()(0).toString, tpe.typeToConvert)
-    val tparams = hctx.sctx.functionContext.tparams
-    val fd = new FunDef(funId, tparams, ValDef(argId) :: ctx.provided_functions.map(ValDef(_)).toList, StringType) // Empty function.
-    fd
+    val argId= FreshIdentifier(tpe.typeToConvert.asString(hctx).toLowerCase()(0).toString, tpe.typeToConvert)
+    val tparams = hctx.functionContext.tparams
+    new FunDef(funId, tparams, ValDef(argId) :: ctx.provided_functions.map(ValDef).toList, StringType) // Empty function.
   }
   
   /** Pre-updates of the function definition */
@@ -354,7 +348,7 @@ case object StringRender extends Rule("StringRender") {
   }
 
   /** Assembles multiple MatchCase to a singleMatchExpr using the function definition fd */
-  private val mergeMatchCases = (fd: FunDef) => (cases: Seq[WithIds[MatchCase]]) => (MatchExpr(Variable(fd.params(0).id), cases.map(_._1)), cases.map(_._2).flatten.toList)
+  private val mergeMatchCases = (fd: FunDef) => (cases: Seq[WithIds[MatchCase]]) => (MatchExpr(Variable(fd.params(0).id), cases.map(_._1)), cases.flatMap(_._2).toList)
   
   /** Returns a (possibly recursive) template which can render the inputs in their order.
     * Returns an expression and path-dependent pretty printers which can be used.
@@ -414,23 +408,23 @@ case object StringRender extends Rule("StringRender") {
         result: ListBuffer[Stream[WithIds[Expr]]] = ListBuffer()): (List[Stream[WithIds[Expr]]], StringSynthesisResult) = inputs match {
       case Nil => (result.toList, ctx.result)
       case input::q => 
-        val dependentType = DependentType(ctx.currentCaseClassParent, input.asString(hctx.program)(hctx.context), input.getType)
+        val dependentType = DependentType(ctx.currentCaseClassParent, input.asString(hctx.program)(hctx), input.getType)
         ctx.result.adtToString.get(dependentType) match {
         case Some(fd) =>
           gatherInputs(ctx, q, result += Stream((functionInvocation(fd._1, input::ctx.provided_functions.toList.map(Variable)), Nil)))
         case None => // No function can render the current type.
           // We should not rely on calling the original function on the first line of the body of the function itself.
           val exprs1s = (new SelfPrettyPrinter)
-            .allowFunction(hctx.sctx.functionContext)
-            .excludeFunction(hctx.sctx.functionContext)
-            .prettyPrintersForType(input.getType)(hctx.context, hctx.program)
+            .allowFunction(hctx.functionContext)
+            .excludeFunction(hctx.functionContext)
+            .prettyPrintersForType(input.getType)(hctx, hctx.program)
             .map(l => (application(l, Seq(input)), List[Identifier]())) // Use already pre-defined pretty printers.
-          val exprs1 = exprs1s.toList.sortBy{ case (Lambda(_, FunctionInvocation(fd, _)), _) if fd == hctx.sctx.functionContext => 0 case _ => 1}
+          val exprs1 = exprs1s.toList.sortBy{ case (Lambda(_, FunctionInvocation(tfd, _)), _) if tfd.fd == hctx.functionContext => 0 case _ => 1}
           val exprs2 = ctx.abstractStringConverters.getOrElse(input.getType, Nil).map(f => (f(input), List[Identifier]()))
           val defaultConverters: Stream[WithIds[Expr]] = exprs1.toStream #::: exprs2.toStream
           val recursiveConverters: Stream[WithIds[Expr]] =
             (new SelfPrettyPrinter)
-            .prettyPrinterFromCandidate(hctx.sctx.functionContext, input.getType)(hctx.context, hctx.program)
+            .prettyPrinterFromCandidate(hctx.functionContext, input.getType)(hctx, hctx.program)
             .map(l => (application(l, Seq(input)), List[Identifier]()))
             
           def mergeResults(templateConverters: =>Stream[WithIds[Expr]]): Stream[WithIds[Expr]] = {
@@ -457,7 +451,7 @@ case object StringRender extends Rule("StringRender") {
             case WithStringconverter(converter) => // Base case
               gatherInputs(ctx, q, result += mergeResults(Stream((converter(input), Nil))))
             case t: ClassType =>
-              if(enforceDefaultStringMethodsIfAvailable && !defaultConverters.isEmpty) {
+              if(enforceDefaultStringMethodsIfAvailable && defaultConverters.nonEmpty) {
                 gatherInputs(ctx, q, result += defaultConverters)
               } else {
                 // Create the empty function body and updates the assignments parts.
@@ -467,10 +461,10 @@ case object StringRender extends Rule("StringRender") {
                   case act@AbstractClassType(acd@AbstractClassDef(id, tparams, parent), tps) =>
                     // Create a complete FunDef body with pattern matching
                     
-                    val allKnownDescendantsAreCCAndHaveZeroArgs = act.knownCCDescendants.forall { x => x match {
+                    val allKnownDescendantsAreCCAndHaveZeroArgs = act.knownCCDescendants.forall {
                       case CaseClassType(ccd@CaseClassDef(id, tparams, parent, isCaseObject), tparams2) => ccd.fields.isEmpty
                       case _ => false
-                    }}
+                    }
                     
                     //TODO: Test other templates not only with Wilcard patterns, but more cases options for non-recursive classes (e.g. Option, Boolean, Finite parameterless case classes.)
                     val (ctx3, cases) = ((ctx2, ListBuffer[Stream[WithIds[MatchCase]]]()) /: act.knownCCDescendants) {
@@ -542,18 +536,19 @@ case object StringRender extends Rule("StringRender") {
     //hctx.reporter.debug("StringRender:Output variables="+p.xs+", their types="+p.xs.map(_.getType))
     p.xs match {
       case List(IsTyped(v, StringType)) =>
-        val description = "Creates a standard string conversion function"
+        val examplesFinder = new ExamplesFinder(hctx, hctx.program)
+          .setKeepAbstractExamples(true)
+          .setEvaluationFailOnChoose(true)
 
-        val examplesFinder = new ExamplesFinder(hctx.context, hctx.program)
-        .setKeepAbstractExamples(true)
-        .setEvaluationFailOnChoose(true)
         val examples = examplesFinder.extractFromProblem(p)
         
-        val abstractStringConverters: StringConverters =
-          (p.as.flatMap { case x => x.getType match {
-            case FunctionType(Seq(aType), StringType) => List((aType, (arg: Expr) => application(Variable(x), Seq(arg))))
+        val abstractStringConverters: StringConverters = p.as.flatMap { case x =>
+          x.getType match {
+            case FunctionType(Seq(aType), StringType) =>
+              List((aType, (arg: Expr) => application(Variable(x), Seq(arg))))
             case _ => Nil
-          }}).groupBy(_._1).mapValues(_.map(_._2))
+          }
+        }.groupBy(_._1).mapValues(_.map(_._2))
        
         val (inputVariables, functionVariables) = p.as.partition ( x => x.getType match {
           case f: FunctionType => false
@@ -564,11 +559,12 @@ case object StringRender extends Rule("StringRender") {
         val originalInputs = inputVariables.map(Variable)
         ruleInstantiations += RuleInstantiation("String conversion") {
           val (expr, synthesisResult) = createFunDefsTemplates(
-              StringSynthesisContext.empty(
-                  abstractStringConverters,
-                  originalInputs.toSet,
-                  functionVariables
-                  ), originalInputs)
+            StringSynthesisContext.empty(
+              abstractStringConverters,
+              originalInputs.toSet,
+              functionVariables
+            ), originalInputs
+          )
           val funDefs = synthesisResult.adtToString
           
           /*val toDebug: String = (("\nInferred functions:" /: funDefs)( (t, s) =>
diff --git a/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala b/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala
index eb3d83ed8d13b8235a98b48d4c209a2db5a7f08c..089c3da45c45c22ef9ff4f84bb924a33f076bce8 100644
--- a/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala
+++ b/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/Unification.scala b/src/main/scala/leon/synthesis/rules/Unification.scala
index cd4f5cdf6079e67d3ef031b279d0b9196f1c1efb..419d256503de66f157094149e39cce0b0729d282 100644
--- a/src/main/scala/leon/synthesis/rules/Unification.scala
+++ b/src/main/scala/leon/synthesis/rules/Unification.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/UnusedInput.scala b/src/main/scala/leon/synthesis/rules/UnusedInput.scala
index 4570501d7646b3f8d77d4fb484451ff957ac723f..a72dfb633a7e7167b0ec133fd9e132cf6114c349 100644
--- a/src/main/scala/leon/synthesis/rules/UnusedInput.scala
+++ b/src/main/scala/leon/synthesis/rules/UnusedInput.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/synthesis/rules/ADTInduction.scala b/src/main/scala/leon/synthesis/rules/unused/ADTInduction.scala
similarity index 97%
rename from src/main/scala/leon/synthesis/rules/ADTInduction.scala
rename to src/main/scala/leon/synthesis/rules/unused/ADTInduction.scala
index 7461f4d58c1a9213dd68168e4f7e4551eeee1711..ab2720fb00f620c0800d6936c9e97b3be3deedac 100644
--- a/src/main/scala/leon/synthesis/rules/ADTInduction.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/ADTInduction.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Common._
 import purescala.Expressions._
@@ -17,7 +17,7 @@ case object ADTInduction extends Rule("ADT Induction") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
     /* All input variables which are inductive in the post condition, along with their abstract data type. */
     val candidates = p.as.collect {
-        case IsTyped(origId, act: AbstractClassType) if isInductiveOn(hctx.sctx.solverFactory)(p.pc, origId) => (origId, act)
+        case IsTyped(origId, act: AbstractClassType) if isInductiveOn(hctx.solverFactory)(p.pc, origId) => (origId, act)
     }
 
     val instances = for (candidate <- candidates) yield {
@@ -114,7 +114,6 @@ case object ADTInduction extends Rule("ADT Induction") {
               val funPre = substAll(substMap, and(p.pc, orJoin(globalPre)))
               val funPost = substAll(substMap, p.phi)
               val idPost = FreshIdentifier("res", resType)
-              val outerPre = orJoin(globalPre)
 
               newFun.precondition = Some(funPre)
               newFun.postcondition = Some(Lambda(Seq(ValDef(idPost)), letTuple(p.xs.toSeq, Variable(idPost), funPost)))
diff --git a/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala b/src/main/scala/leon/synthesis/rules/unused/ADTLongInduction.scala
similarity index 98%
rename from src/main/scala/leon/synthesis/rules/ADTLongInduction.scala
rename to src/main/scala/leon/synthesis/rules/unused/ADTLongInduction.scala
index 66b27a66a47085c8b9feb4f22be1b9c4da132c18..4ffd1a8c258a48007959f87cfb861812959517a8 100644
--- a/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/ADTLongInduction.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Common._
 import purescala.Expressions._
@@ -15,7 +15,7 @@ import purescala.Definitions._
 case object ADTLongInduction extends Rule("ADT Long Induction") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
     val candidates = p.as.collect {
-        case IsTyped(origId, act @ AbstractClassType(cd, tpe)) if isInductiveOn(hctx.sctx.solverFactory)(p.pc, origId) => (origId, act)
+        case IsTyped(origId, act @ AbstractClassType(cd, tpe)) if isInductiveOn(hctx.solverFactory)(p.pc, origId) => (origId, act)
     }
 
     val instances = for (candidate <- candidates) yield {
diff --git a/src/main/scala/leon/synthesis/rules/AsChoose.scala b/src/main/scala/leon/synthesis/rules/unused/AsChoose.scala
similarity index 65%
rename from src/main/scala/leon/synthesis/rules/AsChoose.scala
rename to src/main/scala/leon/synthesis/rules/unused/AsChoose.scala
index 88b5537018b4e2639953fd5ae6f71e749315dcec..06270b939929a96985719b78a3f58ee58d9ce931 100644
--- a/src/main/scala/leon/synthesis/rules/AsChoose.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/AsChoose.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
-package leon
-package synthesis
-package rules
+package leon.synthesis.rules.unused
+
+import leon.synthesis._
 
 case object AsChoose extends Rule("As Choose") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
diff --git a/src/main/scala/leon/synthesis/rules/BottomUpTegis.scala b/src/main/scala/leon/synthesis/rules/unused/BottomUpTegis.scala
similarity index 78%
rename from src/main/scala/leon/synthesis/rules/BottomUpTegis.scala
rename to src/main/scala/leon/synthesis/rules/unused/BottomUpTegis.scala
index 4c12f58224427c1d74654638e28965d746f93d54..9f5dff95eed832330677112833987e32da01c35f 100644
--- a/src/main/scala/leon/synthesis/rules/BottomUpTegis.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/BottomUpTegis.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Expressions._
 import purescala.Common._
@@ -15,18 +15,18 @@ import grammars._
 
 import bonsai.enumerators._
 
-case object BottomUpTEGIS extends BottomUpTEGISLike[TypeTree]("BU TEGIS") {
+case object BottomUpTEGIS extends BottomUpTEGISLike("BU TEGIS") {
   def getGrammar(sctx: SynthesisContext, p: Problem) = {
     Grammars.default(sctx, p)
   }
 
-  def getRootLabel(tpe: TypeTree): TypeTree = tpe
+  def getRootLabel(tpe: TypeTree): Label = Label(tpe)
 }
 
-abstract class BottomUpTEGISLike[T <: Typed](name: String) extends Rule(name) {
-  def getGrammar(sctx: SynthesisContext, p: Problem): ExpressionGrammar[T]
+abstract class BottomUpTEGISLike(name: String) extends Rule(name) {
+  def getGrammar(sctx: SynthesisContext, p: Problem): ExpressionGrammar
 
-  def getRootLabel(tpe: TypeTree): T
+  def getRootLabel(tpe: TypeTree): Label
 
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
 
@@ -37,26 +37,23 @@ abstract class BottomUpTEGISLike[T <: Typed](name: String) extends Rule(name) {
     if (tests.nonEmpty) {
       List(new RuleInstantiation(this.name) {
         def apply(hctx: SearchContext): RuleApplication = {
-          val sctx = hctx.sctx
-
-          implicit val ctx = sctx.context
 
           val evalParams            = CodeGenParams.default.copy(maxFunctionInvocations = 2000)
           //val evaluator             = new CodeGenEvaluator(sctx.context, sctx.program, evalParams)
           //val evaluator             = new DefaultEvaluator(sctx.context, sctx.program)
-          val evaluator             = new DualEvaluator(sctx.context, sctx.program, evalParams)
+          val evaluator             = new DualEvaluator(hctx, hctx.program, evalParams)
 
-          val grammar               = getGrammar(sctx, p)
+          val grammar               = getGrammar(hctx, p)
 
           val nTests = tests.size
 
-          var compiled = Map[ProductionRule[T, Expr], Vector[Vector[Expr]] => Option[Vector[Expr]]]()
+          var compiled = Map[ProductionRule[Label, Expr], Vector[Vector[Expr]] => Option[Vector[Expr]]]()
 
           /**
            * Compile Generators to functions from Expr to Expr. The compiled
            * generators will be passed to the enumerator
            */
-          def compile(gen: ProductionRule[T, Expr]): Vector[Vector[Expr]] => Option[Vector[Expr]] = {
+          def compile(gen: ProductionRule[Label, Expr]): Vector[Vector[Expr]] => Option[Vector[Expr]] = {
             compiled.getOrElse(gen, {
               val executor = if (gen.subTrees.isEmpty) {
 
@@ -107,8 +104,8 @@ abstract class BottomUpTEGISLike[T <: Typed](name: String) extends Rule(name) {
           val targetType   = tupleTypeWrap(p.xs.map(_.getType))
           val wrappedTests = tests.map { case (is, os) => (is, tupleWrap(os))}
 
-          val enum = new BottomUpEnumerator[T, Expr, Expr, ProductionRule[T, Expr]](
-            grammar.getProductions,
+          val enum = new BottomUpEnumerator[Label, Expr, Expr, ProductionRule[Label, Expr]](
+            grammar.getProductions(_)(hctx),
             wrappedTests,
             { (vecs, gen) =>
               compile(gen)(vecs)
@@ -116,9 +113,6 @@ abstract class BottomUpTEGISLike[T <: Typed](name: String) extends Rule(name) {
             3
           )
 
-
-          val timers = sctx.context.timers.synthesis.rules.tegis
-
           val matches = enum.iterator(getRootLabel(targetType))
 
           if (matches.hasNext) {
diff --git a/src/main/scala/leon/synthesis/rules/DetupleOutput.scala b/src/main/scala/leon/synthesis/rules/unused/DetupleOutput.scala
similarity index 95%
rename from src/main/scala/leon/synthesis/rules/DetupleOutput.scala
rename to src/main/scala/leon/synthesis/rules/unused/DetupleOutput.scala
index 39eabaf3730a57b6acd286775686137e78c2a14e..18067e9529596329d44cacf9672931c6e0178414 100644
--- a/src/main/scala/leon/synthesis/rules/DetupleOutput.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/DetupleOutput.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Expressions._
 import purescala.Common._
@@ -51,5 +51,6 @@ case object DetupleOutput extends Rule("Detuple Out") {
     } else {
       None
     }
+
   }
 }
diff --git a/src/main/scala/leon/synthesis/rules/IntInduction.scala b/src/main/scala/leon/synthesis/rules/unused/IntInduction.scala
similarity index 94%
rename from src/main/scala/leon/synthesis/rules/IntInduction.scala
rename to src/main/scala/leon/synthesis/rules/unused/IntInduction.scala
index eeabfff0c9032f639e28d0149870dfed12840a4b..6ef209fcb386a98046a0bd107dd94d4aa3c31403 100644
--- a/src/main/scala/leon/synthesis/rules/IntInduction.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/IntInduction.scala
@@ -1,15 +1,15 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
-import purescala.Common._
-import purescala.Expressions._
-import purescala.Extractors._
+import purescala.Common.FreshIdentifier
 import purescala.Constructors._
-import purescala.Types._
-import purescala.Definitions._
+import purescala.Definitions.{FunDef, ValDef}
+import purescala.Expressions._
+import purescala.Extractors.IsTyped
+import purescala.Types.IntegerType
 
 case object IntInduction extends Rule("Int Induction") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
diff --git a/src/main/scala/leon/synthesis/rules/IntegerEquation.scala b/src/main/scala/leon/synthesis/rules/unused/IntegerEquation.scala
similarity index 97%
rename from src/main/scala/leon/synthesis/rules/IntegerEquation.scala
rename to src/main/scala/leon/synthesis/rules/unused/IntegerEquation.scala
index 8aaa89ee1552417c21eeae14a090c58168322c2e..fdb59b00d7afabcb089b100a85381e646c89f5c7 100644
--- a/src/main/scala/leon/synthesis/rules/IntegerEquation.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/IntegerEquation.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Common._
 import purescala.Expressions._
@@ -23,7 +23,7 @@ case object IntegerEquation extends Rule("Integer Equation") {
     var candidates: Seq[Expr] = eqs
     var allOthers: Seq[Expr] = others
 
-    val evaluator = new DefaultEvaluator(hctx.context, hctx.program)
+    val evaluator = new DefaultEvaluator(hctx, hctx.program)
 
     var vars: Set[Identifier] = Set()
     var eqxs: List[Identifier] = List()
diff --git a/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala b/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala
similarity index 99%
rename from src/main/scala/leon/synthesis/rules/IntegerInequalities.scala
rename to src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala
index 5537dc8d5f9c4434dc42e308c9e257d45a4192c8..602a7e61ba1e94c174f44cc71c04790feeb636f6 100644
--- a/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Common._
 import purescala.Expressions._
diff --git a/src/main/scala/leon/synthesis/rules/OptimisticInjection.scala b/src/main/scala/leon/synthesis/rules/unused/OptimisticInjection.scala
similarity index 95%
rename from src/main/scala/leon/synthesis/rules/OptimisticInjection.scala
rename to src/main/scala/leon/synthesis/rules/unused/OptimisticInjection.scala
index 5d3a84f303ed65adb1c9cd3c01012f9f854d62bb..b3d35f8a090d8f1b85532040b558cb8abf5a0c8f 100644
--- a/src/main/scala/leon/synthesis/rules/OptimisticInjection.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/OptimisticInjection.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Expressions._
 import purescala.Extractors._
diff --git a/src/main/scala/leon/synthesis/rules/SelectiveInlining.scala b/src/main/scala/leon/synthesis/rules/unused/SelectiveInlining.scala
similarity index 87%
rename from src/main/scala/leon/synthesis/rules/SelectiveInlining.scala
rename to src/main/scala/leon/synthesis/rules/unused/SelectiveInlining.scala
index 634470cc073a0a6009d304b551c7155b88ffbf4b..9dd4e68e01ede5e953c3b0f06a573be505056dc3 100644
--- a/src/main/scala/leon/synthesis/rules/SelectiveInlining.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/SelectiveInlining.scala
@@ -1,12 +1,12 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
-import purescala.Expressions._
-import purescala.Extractors._
 import purescala.Constructors._
+import purescala.Expressions.{Equals, Expr, FunctionInvocation}
+import purescala.Extractors.TopLevelAnds
 
 case object SelectiveInlining extends Rule("Sel. Inlining") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
diff --git a/src/main/scala/leon/synthesis/rules/SygusCVC4.scala b/src/main/scala/leon/synthesis/rules/unused/SygusCVC4.scala
similarity index 66%
rename from src/main/scala/leon/synthesis/rules/SygusCVC4.scala
rename to src/main/scala/leon/synthesis/rules/unused/SygusCVC4.scala
index 7760b8c0d50f0f12958de870311ccba7daa85b22..800d1e5f84c3067fe94fb368a82f1302a8981c43 100644
--- a/src/main/scala/leon/synthesis/rules/SygusCVC4.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/SygusCVC4.scala
@@ -1,22 +1,17 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
-import solvers.sygus._
-
-import grammars._
+import leon.solvers.sygus.CVC4SygusSolver
 
 case object SygusCVC4 extends Rule("SygusCVC4") {
   def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = {
     List(new RuleInstantiation(this.name) {
       def apply(hctx: SearchContext): RuleApplication = {
 
-        val sctx = hctx.sctx
-        val grammar = Grammars.default(sctx, p)
-
-        val s = new CVC4SygusSolver(sctx.context, sctx.program, p)
+        val s = new CVC4SygusSolver(hctx, hctx.program, p)
 
         s.checkSynth() match {
           case Some(expr) =>
diff --git a/src/main/scala/leon/synthesis/rules/TEGIS.scala b/src/main/scala/leon/synthesis/rules/unused/TEGIS.scala
similarity index 56%
rename from src/main/scala/leon/synthesis/rules/TEGIS.scala
rename to src/main/scala/leon/synthesis/rules/unused/TEGIS.scala
index 3d496d0597e1947af0eb83504be5af449d7854f1..886d57719f18932de8207bb44f829803bcf1525c 100644
--- a/src/main/scala/leon/synthesis/rules/TEGIS.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/TEGIS.scala
@@ -1,17 +1,17 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Types._
 import grammars._
 
-case object TEGIS extends TEGISLike[TypeTree]("TEGIS") {
+case object TEGIS extends TEGISLike("TEGIS") {
   def getParams(sctx: SynthesisContext, p: Problem) = {
     TegisParams(
       grammar = Grammars.default(sctx, p),
-      rootLabel = {(tpe: TypeTree) => tpe }
+      rootLabel = Label(_)
     )
   }
 }
diff --git a/src/main/scala/leon/synthesis/rules/TEGISLike.scala b/src/main/scala/leon/synthesis/rules/unused/TEGISLike.scala
similarity index 78%
rename from src/main/scala/leon/synthesis/rules/TEGISLike.scala
rename to src/main/scala/leon/synthesis/rules/unused/TEGISLike.scala
index 93e97de6f1ad97c40def5b77c0d79fbb60282633..16eb701f9f88698fa8b944652b46869c58cfa07f 100644
--- a/src/main/scala/leon/synthesis/rules/TEGISLike.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/TEGISLike.scala
@@ -1,8 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Expressions._
 import purescala.Types._
@@ -18,10 +18,10 @@ import scala.collection.mutable.{HashMap => MutableMap}
 
 import bonsai.enumerators._
 
-abstract class TEGISLike[T <: Typed](name: String) extends Rule(name) {
+abstract class TEGISLike(name: String) extends Rule(name) {
   case class TegisParams(
-    grammar: ExpressionGrammar[T],
-    rootLabel: TypeTree => T,
+    grammar: ExpressionGrammar,
+    rootLabel: TypeTree => Label,
     enumLimit: Int = 10000,
     reorderInterval: Int = 50
   )
@@ -32,21 +32,18 @@ abstract class TEGISLike[T <: Typed](name: String) extends Rule(name) {
 
     List(new RuleInstantiation(this.name) {
       def apply(hctx: SearchContext): RuleApplication = {
-        val sctx = hctx.sctx
-
-        implicit val ctx = sctx.context
-
-        val params = getParams(sctx, p)
+        implicit val ci = hctx
+        val params = getParams(hctx, p)
         val grammar = params.grammar
 
         val nTests = if (p.pc == BooleanLiteral(true)) 50 else 20
 
-        val useVanuatoo = sctx.settings.cegisUseVanuatoo
+        val useVanuatoo = hctx.settings.cegisUseVanuatoo
 
         val inputGenerator: Iterator[Seq[Expr]] = if (useVanuatoo) {
-          new VanuatooDataGen(sctx.context, sctx.program).generateFor(p.as, p.pc, nTests, 3000)
+          new VanuatooDataGen(hctx, hctx.program).generateFor(p.as, p.pc, nTests, 3000)
         } else {
-          val evaluator = new DualEvaluator(sctx.context, sctx.program, CodeGenParams.default)
+          val evaluator = new DualEvaluator(hctx, hctx.program, CodeGenParams.default)
           new GrammarDataGen(evaluator, ValueGrammar).generateFor(p.as, p.pc, nTests, 1000)
         }
 
@@ -66,13 +63,13 @@ abstract class TEGISLike[T <: Typed](name: String) extends Rule(name) {
         if (gi.nonEmpty) {
 
           val evalParams = CodeGenParams.default.copy(maxFunctionInvocations = 2000)
-          val evaluator  = new DualEvaluator(sctx.context, sctx.program, evalParams)
+          val evaluator  = new DualEvaluator(hctx, hctx.program, evalParams)
 
-          val enum = new MemoizedEnumerator[T, Expr, ProductionRule[T, Expr]](grammar.getProductions)
+          val enum = new MemoizedEnumerator[Label, Expr, ProductionRule[Label, Expr]](grammar.getProductions)
 
           val targetType = tupleTypeWrap(p.xs.map(_.getType))
 
-          val timers = sctx.context.timers.synthesis.rules.tegis
+          val timers = hctx.timers.synthesis.rules.tegis
 
           val allExprs = enum.iterator(params.rootLabel(targetType))
 
@@ -113,7 +110,7 @@ abstract class TEGISLike[T <: Typed](name: String) extends Rule(name) {
 
           RuleClosed(toStream)
         } else {
-          sctx.reporter.debug("No test available")
+          hctx.reporter.debug("No test available")
           RuleFailed()
         }
       }
diff --git a/src/main/scala/leon/synthesis/rules/TEGLESS.scala b/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala
similarity index 56%
rename from src/main/scala/leon/synthesis/rules/TEGLESS.scala
rename to src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala
index f56b26b26d859566c77c91f484deac41930f2aa7..924e9567b04ba53c8eaf56da16bed8e6fba3cc0b 100644
--- a/src/main/scala/leon/synthesis/rules/TEGLESS.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala
@@ -1,16 +1,15 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
-package rules
+package rules.unused
 
 import purescala.Types._
 import purescala.Extractors._
-import utils._
 import Witnesses._
 import grammars._
 
-case object TEGLESS extends TEGISLike[NonTerminal[String]]("TEGLESS") {
+case object TEGLESS extends TEGISLike("TEGLESS") {
   def getParams(sctx: SynthesisContext, p: Problem) = {
 
     val TopLevelAnds(clauses) = p.ws
@@ -19,8 +18,6 @@ case object TEGLESS extends TEGISLike[NonTerminal[String]]("TEGLESS") {
       case Guide(expr) => expr
     }
 
-    val inputs = p.as.map(_.toVariable)
-
     sctx.reporter.ifDebug { printer =>
       printer("Guides available:")
       for (g <- guides) {
@@ -28,11 +25,12 @@ case object TEGLESS extends TEGISLike[NonTerminal[String]]("TEGLESS") {
       }
     }
 
-    val guidedGrammar = guides.map(SimilarTo(_, inputs.toSet, sctx, p)).foldLeft[ExpressionGrammar[NonTerminal[String]]](Empty())(_ || _)
+    val guidedGrammar = guides.map(SimilarTo(_, sctx, p)).foldLeft[ExpressionGrammar](Empty())(_ || _)
 
     TegisParams(
       grammar = guidedGrammar,
-      rootLabel = { (tpe: TypeTree) => NonTerminal(tpe, "G0") }
+      //rootLabel = { (tpe: TypeTree) => NonTerminal(tpe, "G0") }
+      rootLabel = { (tpe: TypeTree) => Label(tpe) }
     )
   }
 }
diff --git a/src/main/scala/leon/synthesis/strategies/BoundedStrategy.scala b/src/main/scala/leon/synthesis/strategies/BoundedStrategy.scala
new file mode 100644
index 0000000000000000000000000000000000000000..72074c5954ac2e643570543d06875af58d993ec2
--- /dev/null
+++ b/src/main/scala/leon/synthesis/strategies/BoundedStrategy.scala
@@ -0,0 +1,24 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package strategies
+
+import synthesis.graph._
+
+case class BoundedStrategy(underlying: Strategy, bound: Int) extends WrappedStrategy(underlying) {
+  private[this] var nSteps = 0
+
+  override def getNextToExpand(from: Node): Option[Node] = {
+    if (nSteps < bound) {
+      super.getNextToExpand(from)
+    } else {
+      None
+    }
+  }
+
+  override def afterExpand(n: Node) = {
+    super.afterExpand(n);
+    nSteps += 1
+  }
+}
diff --git a/src/main/scala/leon/synthesis/strategies/CostBasedStrategy.scala b/src/main/scala/leon/synthesis/strategies/CostBasedStrategy.scala
new file mode 100644
index 0000000000000000000000000000000000000000..de1f7d4105c1661a48f6d8a5696da1750c33bc51
--- /dev/null
+++ b/src/main/scala/leon/synthesis/strategies/CostBasedStrategy.scala
@@ -0,0 +1,94 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package strategies
+
+import synthesis.graph._
+
+class CostBasedStrategy(ctx: LeonContext, cm: CostModel) extends Strategy {
+  private var bestSols = Map[Node, Option[Solution]]()
+  private var bestCosts = Map[Node, Cost]()
+
+  override def init(root: RootNode): Unit = {
+    super.init(root)
+    computeBestSolutionFor(root)
+  }
+
+  def computeBestSolutionFor(n: Node): Option[Solution] = {
+    val res = if (n.isSolved) {
+      Some(n.generateSolutions().head)
+    } else if (n.isDeadEnd) {
+      None
+    } else if (!n.isExpanded) {
+      n match {
+        case an: AndNode =>
+          an.ri.onSuccess match {
+            case SolutionBuilderCloser(_) =>
+              Some(Solution.simplest(an.p.outType))
+
+            case SolutionBuilderDecomp(types, recomp) =>
+              recomp(types.toList.map(Solution.simplest))
+          }
+        case on: OrNode =>
+          Some(Solution.simplest(n.p.outType))
+      }
+    } else {
+      n match {
+        case an: AndNode =>
+          val subs = an.descendants.map(bestSolutionFor)
+
+          if (subs.forall(_.isDefined)) {
+            an.ri.onSuccess(subs.flatten)
+          } else {
+            None
+          }
+        case on: OrNode =>
+          on.descendants.foreach(bestSolutionFor)
+
+          bestSolutionFor(on.descendants.minBy(bestCosts))
+      }
+    }
+
+    bestSols += n -> res
+    bestCosts += n -> res.map(cm.solution _).getOrElse(cm.impossible)
+
+    res
+  }
+
+  def bestAlternative(on: OrNode): Option[Node] = {
+    if (on.isDeadEnd) {
+      None
+    } else {
+      Some(on.descendants.minBy(bestCosts))
+    }
+  }
+
+  def bestSolutionFor(n: Node): Option[Solution] = {
+    bestSols.get(n) match {
+      case Some(os) => os
+      case None => computeBestSolutionFor(n)
+    }
+  }
+
+  def recomputeCost(n: Node): Unit = {
+    val oldCost = bestCosts(n)
+    computeBestSolutionFor(n)
+
+    if (bestCosts(n) != oldCost) {
+      n.parent.foreach(recomputeCost)
+    }
+  }
+
+  override def afterExpand(n: Node): Unit = {
+    super.afterExpand(n)
+
+    for (d <- n.descendants) {
+      bestSolutionFor(d)
+    }
+
+    recomputeCost(n)
+  }
+
+  def debugInfoFor(n: Node) = bestCosts.get(n).map(_.toString).getOrElse("?")
+}
diff --git a/src/main/scala/leon/synthesis/strategies/ManualStrategy.scala b/src/main/scala/leon/synthesis/strategies/ManualStrategy.scala
new file mode 100644
index 0000000000000000000000000000000000000000..809c48786a984c224aa5a0d4a8f5d09fec34ca57
--- /dev/null
+++ b/src/main/scala/leon/synthesis/strategies/ManualStrategy.scala
@@ -0,0 +1,287 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package strategies
+
+import purescala.Common.FreshIdentifier
+
+import graph._
+
+class ManualStrategy(ctx: LeonContext, initCmd: Option[String], strat: Strategy) extends Strategy {
+  implicit val ctx_ = ctx
+
+  import ctx.reporter._
+
+  abstract class Command
+  case class Cd(path: List[Int]) extends Command
+  case object Parent extends Command
+  case object Quit extends Command
+  case object Noop extends Command
+  case object Best extends Command
+  case object Tree extends Command
+  case object Help extends Command
+
+  // Manual search state:
+  var rootNode: Node    = _
+
+  var path              = List[Int]()
+
+  override def init(n: RootNode) = {
+    super.init(n)
+    strat.init(n)
+
+    rootNode = n
+  }
+
+  def currentNode(path: List[Int]): Node = {
+    def findFrom(n: Node, path: List[Int]): Node = {
+      path match {
+        case Nil => n
+        case p :: ps =>
+          findDescendent(n, p) match {
+            case Some(d) =>
+              findFrom(d, ps)
+            case None =>
+              n
+          }
+      }
+    }
+
+    findFrom(rootNode, path)
+  }
+
+  override def beforeExpand(n: Node) = {
+    super.beforeExpand(n)
+    strat.beforeExpand(n)
+  }
+
+  override def afterExpand(n: Node) = {
+    super.afterExpand(n)
+    strat.afterExpand(n)
+
+    // Backtrack view to a point where node is neither closed nor solved
+    if (n.isDeadEnd || n.isSolved) {
+      val backtrackTo = findAncestor(n, n => !n.isDeadEnd && !n.isSolved)
+
+      path = backtrackTo.map(pathTo).getOrElse(Nil)
+    }
+  }
+
+  private def findAncestor(n: Node, f: Node => Boolean): Option[Node] = {
+    n.parent.flatMap { n =>
+      if (f(n)) Some(n) else findAncestor(n, f)
+    }
+  }
+
+  private def pathTo(n: Node): List[Int] = {
+    n.parent match {
+      case None => Nil
+      case Some(p) => pathTo(p) :+ p.descendants.indexOf(n)
+    }
+  }
+
+
+  def bestAlternative(n: OrNode) = strat.bestAlternative(n)
+
+
+  def printGraph() {
+    def title(str: String)    = "\u001b[1m"  + str + "\u001b[0m"
+    def failed(str: String)   = "\u001b[31m" + str + "\u001b[0m"
+    def solved(str: String)   = "\u001b[32m" + str + "\u001b[0m"
+    def expanded(str: String) = "\u001b[33m" + str + "\u001b[0m"
+
+    def displayNode(n: Node, inTitle: Boolean = false): String = {
+      n match {
+        case an: AndNode =>
+          val app = an.ri.asString(ctx)
+          s"(${debugInfoFor(n)}) ${indent(app, inTitle)}"
+        case on: OrNode =>
+          val p = on.p.asString(ctx)
+          s"(${debugInfoFor(n)}) ${indent(p, inTitle)}"
+      }
+    }
+
+    def indent(a: String, inTitle: Boolean): String = {
+      a.replaceAll("\n", "\n"+(" "*(if(inTitle) 11 else 13)))
+    }
+
+    def pathToString(cd: List[Int]): String = {
+      cd.map(i => f"$i%2d").mkString(" ")
+    }
+
+    val c = currentNode(path)
+
+    println("-"*120)
+    val at = path.lastOption.map(p => pathToString(List(p))).getOrElse(" R")
+
+    println(title(at+" \u2510 "+displayNode(c, true)))
+
+    for ((sn, i) <- c.descendants.zipWithIndex) {
+      val sp = List(i)
+
+      if (sn.isSolved) {
+        println(solved("  "+pathToString(sp)+" \u2508 "+displayNode(sn)))
+      } else if (sn.isDeadEnd) {
+        println(failed("  "+pathToString(sp)+" \u2508 "+displayNode(sn)))
+      } else if (sn.isExpanded) {
+        println(expanded("  "+pathToString(sp)+" \u2508 "+displayNode(sn)))
+      } else {
+        println("  "+pathToString(sp)+" \u2508 "+displayNode(sn))
+      }
+    }
+    println("-"*120)
+  }
+
+  var continue = true
+
+  def findDescendent(n: Node, index: Int): Option[Node] = {
+    n.descendants.zipWithIndex.find(_._2 == index).map(_._1)
+  }
+
+  def manualGetNext(): Option[Node] = {
+    val c = currentNode(path)
+
+    if (!c.isExpanded) {
+      Some(c)
+    } else {
+      printGraph()
+
+      nextCommand() match {
+        case Quit =>
+          None
+
+        case Help =>
+          val tOpen  = "\u001b[1m"
+          val tClose = "\u001b[0m"
+          println(s"""|
+                      |${tOpen}Available commands: $tClose
+                      |$tOpen  (cd) N  $tClose  Expand descendant N
+                      |$tOpen  cd ..   $tClose  Go one level up
+                      |$tOpen  b       $tClose  Expand best descendant
+                      |$tOpen  t       $tClose  Display the partial solution around the current node
+                      |$tOpen  q       $tClose  Quit the search
+                      |$tOpen  h       $tClose  Display this message
+                      |""".stripMargin)
+          manualGetNext()
+        case Parent =>
+          if (path.nonEmpty) {
+            path = path.dropRight(1)
+          } else {
+            error("Already at root node!")
+          }
+
+          manualGetNext()
+
+        case Tree =>
+          val hole = FreshIdentifier("\u001b[1;31m??? \u001b[0m", c.p.outType)
+          val ps = new PartialSolution(this, true)
+
+          ps.solutionAround(c)(hole.toVariable) match {
+            case Some(sol) =>
+              println("-"*120)
+              println(sol.toExpr.asString)
+            case None =>
+              error("woot!")
+          }
+          manualGetNext()
+
+
+        case Best =>
+          strat.bestNext(c) match {
+            case Some(n) =>
+              val i = c.descendants.indexOf(n)
+              path = path :+ i
+              Some(currentNode(path))
+
+            case None =>
+              error("Woot?")
+              manualGetNext()
+          }
+
+
+        case Cd(Nil) =>
+          error("Woot?")
+          None
+
+        case Cd(next :: rest) =>
+          findDescendent(c, next) match {
+            case Some(_) =>
+              path = path :+ next
+            case None =>
+              warning("Unknown descendant: "+next)
+          }
+
+          if (rest.nonEmpty) {
+            cmdQueue = Cd(rest) :: cmdQueue
+          }
+          manualGetNext()
+      }
+    }
+  }
+
+  override def getNextToExpand(root: Node): Option[Node] = {
+    manualGetNext()
+  }
+
+  def debugInfoFor(n: Node) = strat.debugInfoFor(n)
+
+  var cmdQueue = initCmd.map( str => parseCommands(parseString(str))).getOrElse(Nil)
+
+  private def parseString(s: String): List[String] = {
+    Option(s).map(_.trim.split("\\s+|,").toList).getOrElse(fatalError("End of stream"))
+  }
+
+  private def nextCommand(): Command = cmdQueue match {
+    case c :: cs =>
+      cmdQueue = cs
+      c
+
+    case Nil =>
+      print("Next action? (h for help) "+path.mkString(" ")+" $ ")
+      val line = scala.io.StdIn.readLine()
+      val parts = parseString(line)
+
+      cmdQueue = parseCommands(parts)
+      nextCommand()
+  }
+
+  private def parseCommands(tokens: List[String]): List[Command] = tokens match {
+    case "cd" :: ".." :: ts =>
+      Parent :: parseCommands(ts)
+
+    case "cd" :: ts =>
+      val path = ts.takeWhile { t => t.forall(_.isDigit) }
+
+      if (path.isEmpty) {
+        parseCommands(ts)
+      } else {
+        Cd(path.map(_.toInt)) :: parseCommands(ts.drop(path.size))
+      }
+
+    case "t" :: ts =>
+      Tree :: parseCommands(ts)
+
+    case "b" :: ts =>
+      Best :: parseCommands(ts)
+
+    case "h" :: ts =>
+      Help :: parseCommands(ts)
+
+    case "q" :: ts =>
+      Quit :: Nil
+
+    case Nil  | "" :: Nil =>
+      Nil
+
+    case ts =>
+      val path = ts.takeWhile { t => t.forall(_.isDigit) }
+
+      if (path.isEmpty) {
+        error("Unknown command "+ts.head)
+        parseCommands(ts.tail)
+      } else {
+        Cd(path.map(_.toInt)) :: parseCommands(ts.drop(path.size))
+      }
+  }
+}
diff --git a/src/main/scala/leon/synthesis/strategies/Strategy.scala b/src/main/scala/leon/synthesis/strategies/Strategy.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5b6253bd9b63ded24843de6764b0b003a88af4a1
--- /dev/null
+++ b/src/main/scala/leon/synthesis/strategies/Strategy.scala
@@ -0,0 +1,59 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package strategies
+
+import synthesis.graph._
+
+import leon.utils.Interruptible
+
+abstract class Strategy extends Interruptible {
+
+  // Nodes to consider next
+  private var openNodes = Set[Node]()
+
+  def init(root: RootNode): Unit = {
+    openNodes += root
+  }
+
+  /**
+   * Standard-next for AndNodes, strategy-best for OrNodes
+   */
+  def bestNext(n: Node): Option[Node] = {
+    n match {
+      case an: AndNode =>
+        an.descendants.find(_.isOpen)
+
+      case on: OrNode =>
+        bestAlternative(on)
+    }
+  }
+
+  def bestAlternative(on: OrNode): Option[Node]
+
+  def getNextToExpand(root: Node): Option[Node] = {
+    if (openNodes(root)) {
+      Some(root)
+    } else if (openNodes.isEmpty) {
+      None
+    } else {
+      bestNext(root).flatMap(getNextToExpand)
+    }
+  }
+
+  def beforeExpand(n: Node): Unit = {}
+
+  def afterExpand(n: Node): Unit = {
+    openNodes -= n
+    openNodes ++= n.descendants
+  }
+
+  def interrupt() = {}
+
+  def recoverInterrupt() = {}
+
+  def debugInfoFor(n: Node): String
+}
+
+
diff --git a/src/main/scala/leon/synthesis/strategies/TimeSlicingStrategy.scala b/src/main/scala/leon/synthesis/strategies/TimeSlicingStrategy.scala
new file mode 100644
index 0000000000000000000000000000000000000000..2ed3b56f22d85c5ea29b8fcf671d63434af1476d
--- /dev/null
+++ b/src/main/scala/leon/synthesis/strategies/TimeSlicingStrategy.scala
@@ -0,0 +1,40 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package strategies
+
+import synthesis.graph._
+
+class TimeSlicingStrategy(ctx: LeonContext) extends Strategy {
+
+  var timeSpent = Map[Node, Long]().withDefaultValue(0l)
+
+  def bestAlternative(on: OrNode): Option[Node] = {
+    on.descendants.filter(_.isOpen).sortBy(timeSpent).headOption
+  }
+
+  def recordTime(from: Node, t: Long): Unit = {
+    timeSpent += from -> (timeSpent(from) + t)
+
+    from.parent.foreach {
+      recordTime(_, t)
+    }
+  }
+
+  var tstart: Long = 0;
+
+  override def beforeExpand(n: Node): Unit = {
+    super.beforeExpand(n)
+    tstart = System.currentTimeMillis
+  }
+
+  override def afterExpand(n: Node): Unit = {
+    super.afterExpand(n)
+
+    val t = System.currentTimeMillis - tstart
+    recordTime(n, t)
+  }
+
+  def debugInfoFor(n: Node) = timeSpent.get(n).map(_.toString).getOrElse("?")
+}
diff --git a/src/main/scala/leon/synthesis/strategies/WrappedStrategy.scala b/src/main/scala/leon/synthesis/strategies/WrappedStrategy.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8e281ea3d1cc524fe46ef9a8fcdcbfe746bdffa1
--- /dev/null
+++ b/src/main/scala/leon/synthesis/strategies/WrappedStrategy.scala
@@ -0,0 +1,34 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package synthesis
+package strategies
+
+import synthesis.graph._
+
+class WrappedStrategy(underlying: Strategy) extends Strategy {
+
+  override def init(root: RootNode) = underlying.init(root)
+
+  override def getNextToExpand(from: Node): Option[Node] = {
+    underlying.getNextToExpand(from)
+  }
+
+  override def bestAlternative(on: OrNode): Option[Node] = {
+    underlying.bestAlternative(on)
+  }
+
+  override def beforeExpand(n: Node) = {
+    underlying.beforeExpand(n)
+  }
+
+  override def afterExpand(n: Node) = {
+    underlying.afterExpand(n);
+  }
+
+  override def interrupt() = underlying.interrupt()
+
+  override def recoverInterrupt() = underlying.recoverInterrupt()
+
+  def debugInfoFor(n: Node) = underlying.debugInfoFor(n)
+}
diff --git a/src/main/scala/leon/synthesis/utils/Helpers.scala b/src/main/scala/leon/synthesis/utils/Helpers.scala
index 4bfedc4acbe59440ac7f3382c8187ae201775f02..64a8f4d9d046464c8ebfe8e7ad157a1411740ae4 100644
--- a/src/main/scala/leon/synthesis/utils/Helpers.scala
+++ b/src/main/scala/leon/synthesis/utils/Helpers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
@@ -35,17 +35,18 @@ object Helpers {
   }
 
   /** Given an initial set of function calls provided by a list of [[Terminating]],
-   *  returns function calls that will hopefully be safe to call recursively from within this initial function calls.
-   *
-   *  For each returned call, one argument is substituted by a "smaller" one, while the rest are left as holes.
-   *
-   *  @param prog The current program
-   *  @param tpe The expected type for the returned function calls
-   *  @param ws Helper predicates that contain [[Terminating]]s with the initial calls
-   *  @param pc The path condition
-   *  @return A list of pairs of (safe function call, holes), where holes stand for the rest of the arguments of the function.
+    * returns function calls that will hopefully be safe to call recursively from within this initial function calls.
+    *
+    * For each returned call, one argument is substituted by a "smaller" one, while the rest are left as holes.
+    *
+    * @param prog The current program
+    * @param ws Helper predicates that contain [[Terminating]]s with the initial calls
+    * @param pc The path condition
+    * @param tpe The expected type for the returned function calls. If absent, all types are permitted.
+    * @return A list of pairs (safe function call, holes),
+    *         where holes stand for the rest of the arguments of the function.
    */
-  def terminatingCalls(prog: Program, tpe: TypeTree, ws: Expr, pc: Expr): List[(FunctionInvocation, Set[Identifier])] = {
+  def terminatingCalls(prog: Program, ws: Expr, pc: Expr, tpe: Option[TypeTree], introduceHoles: Boolean): List[(FunctionInvocation, Option[Set[Identifier]])] = {
 
     val TopLevelAnds(wss) = ws
     val TopLevelAnds(clauses) = pc
@@ -60,9 +61,19 @@ object Helpers {
       case _ => None
     }
     
+    val z   = InfiniteIntegerLiteral(0)
+    val one = InfiniteIntegerLiteral(1)
     val knownSmallers = clauses.collect {
       case Equals(v: Variable, s@CaseClassSelector(cct, r, _)) => subExprsOf(s, v)
       case Equals(s@CaseClassSelector(cct, r, _), v: Variable) => subExprsOf(s, v)
+      case GreaterThan(v: Variable, `z`) =>
+        Some(v -> Minus(v, one))
+      case LessThan(`z`, v: Variable) =>
+        Some(v -> Minus(v, one))
+      case LessThan(v: Variable, `z`) =>
+        Some(v -> Plus(v, one))
+      case GreaterThan(`z`, v: Variable) =>
+        Some(v -> Plus(v, one))
     }.flatten.groupBy(_._1).mapValues(v => v.map(_._2))
 
     def argsSmaller(e: Expr, tpe: TypeTree): Seq[Expr] = e match {
@@ -73,18 +84,17 @@ object Helpers {
         }.flatten
       case v: Variable =>
         knownSmallers.getOrElse(v, Seq())
-
       case _ => Nil
     }
 
     val res = gs.flatMap {
-      case Terminating(tfd, args) if isSubtypeOf(tfd.returnType, tpe) =>
+      case Terminating(FunctionInvocation(tfd, args)) if tpe forall (isSubtypeOf(tfd.returnType, _)) =>
         val ids = tfd.params.map(vd => FreshIdentifier("<hole>", vd.getType, true)).toList
 
         for (((a, i), tpe) <- args.zipWithIndex zip tfd.params.map(_.getType);
               smaller <- argsSmaller(a, tpe)) yield {
-          val args = ids.map(_.toVariable).updated(i, smaller)
-          (FunctionInvocation(tfd, args), ids.toSet - ids(i))
+          val newArgs = (if (introduceHoles) ids.map(_.toVariable) else args).updated(i, smaller)
+          (FunctionInvocation(tfd, newArgs), if(introduceHoles) Some(ids.toSet - ids(i)) else None)
         }
       case _ =>
         Nil
diff --git a/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala b/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala
index c3df2a38297ea7766cdb85cb011124a41d0fbb20..4bbd5ad693dea93ff9ac4f1bafff2365bbd88fb5 100644
--- a/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala
+++ b/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package synthesis
diff --git a/src/main/scala/leon/termination/ChainBuilder.scala b/src/main/scala/leon/termination/ChainBuilder.scala
index 0c6106127ce7187ff4dded02b18863fcd332677b..77b15659c3e2e7be97d36d9e5645af5daf9cfb58 100644
--- a/src/main/scala/leon/termination/ChainBuilder.scala
+++ b/src/main/scala/leon/termination/ChainBuilder.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/ChainComparator.scala b/src/main/scala/leon/termination/ChainComparator.scala
index 0c3cbd8756a79222d85468fea16b73ce7f73d9bd..a2c18e171bbe870534ceecf6f1165a8a0f956d67 100644
--- a/src/main/scala/leon/termination/ChainComparator.scala
+++ b/src/main/scala/leon/termination/ChainComparator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/ChainProcessor.scala b/src/main/scala/leon/termination/ChainProcessor.scala
index 799e51db6c1d08895ffb23793fc7328e881a7242..c01fa9fb3afe65e5b798b31db3ebc5cf23e9e626 100644
--- a/src/main/scala/leon/termination/ChainProcessor.scala
+++ b/src/main/scala/leon/termination/ChainProcessor.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/ComplexTerminationChecker.scala b/src/main/scala/leon/termination/ComplexTerminationChecker.scala
index 83638aa84233775b256e7e44d43d77b906c7a4c7..6d634f088e29dfac338b3c5cbc2ba9291da3b192 100644
--- a/src/main/scala/leon/termination/ComplexTerminationChecker.scala
+++ b/src/main/scala/leon/termination/ComplexTerminationChecker.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/LoopProcessor.scala b/src/main/scala/leon/termination/LoopProcessor.scala
index 790db91062742f6d2b30ec731677c3bf168ecc7e..e71c5282199a5acc9ea1653f8f355ce4ef56f5f7 100644
--- a/src/main/scala/leon/termination/LoopProcessor.scala
+++ b/src/main/scala/leon/termination/LoopProcessor.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/ProcessingPipeline.scala b/src/main/scala/leon/termination/ProcessingPipeline.scala
index 92a11c6452c88f49986cd9382cae9ed72f70619a..30cc87f558c129a47044c1a0ce9d667c3b3c322f 100644
--- a/src/main/scala/leon/termination/ProcessingPipeline.scala
+++ b/src/main/scala/leon/termination/ProcessingPipeline.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/Processor.scala b/src/main/scala/leon/termination/Processor.scala
index 3f7be09f145d2768ff00f8573f078d6e90bc1b2d..1d0527127344510b803a21666f0ade2d92537dff 100644
--- a/src/main/scala/leon/termination/Processor.scala
+++ b/src/main/scala/leon/termination/Processor.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/RecursionProcessor.scala b/src/main/scala/leon/termination/RecursionProcessor.scala
index 72c64f62aa1a3ceb28d3e23f9bace1e40e06209b..d8d31e2a39a926f07e00ddf87129a8c59686907f 100644
--- a/src/main/scala/leon/termination/RecursionProcessor.scala
+++ b/src/main/scala/leon/termination/RecursionProcessor.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/RelationBuilder.scala b/src/main/scala/leon/termination/RelationBuilder.scala
index d2edc62281298f812cc0348df161a289f2899846..127b64ec021c4feab69e3ccd504464bb7bc6ae14 100644
--- a/src/main/scala/leon/termination/RelationBuilder.scala
+++ b/src/main/scala/leon/termination/RelationBuilder.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/RelationComparator.scala b/src/main/scala/leon/termination/RelationComparator.scala
index c147f12aa83a22b4af95521553e2888e488c5c44..0d72d5021aafb233a54209165d4e0587be972323 100644
--- a/src/main/scala/leon/termination/RelationComparator.scala
+++ b/src/main/scala/leon/termination/RelationComparator.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/RelationProcessor.scala b/src/main/scala/leon/termination/RelationProcessor.scala
index d71a6fa3ae5c57e0244bf4a1e194605d9eda4a7d..1044e1be28cf65803471897cb9c0cb600a37ccc1 100644
--- a/src/main/scala/leon/termination/RelationProcessor.scala
+++ b/src/main/scala/leon/termination/RelationProcessor.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/SelfCallsProcessor.scala b/src/main/scala/leon/termination/SelfCallsProcessor.scala
index 320c230c2cae410d7862c9ec9c15ea2b849cdba6..6a14750224fa8766ffe6c9a4784e38a07d793b2d 100644
--- a/src/main/scala/leon/termination/SelfCallsProcessor.scala
+++ b/src/main/scala/leon/termination/SelfCallsProcessor.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/SimpleTerminationChecker.scala b/src/main/scala/leon/termination/SimpleTerminationChecker.scala
index 297d92d2aefcd5b5ed18ddf22c139b2d1cde55a9..a5864eeb4490c8d58a54589166b26933b329591d 100644
--- a/src/main/scala/leon/termination/SimpleTerminationChecker.scala
+++ b/src/main/scala/leon/termination/SimpleTerminationChecker.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/Strengthener.scala b/src/main/scala/leon/termination/Strengthener.scala
index e6c53a472da1f5d997f9eb8fde61892c16863b12..75a466001489a30c4f7e60124d835aca9fa66a41 100644
--- a/src/main/scala/leon/termination/Strengthener.scala
+++ b/src/main/scala/leon/termination/Strengthener.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/StructuralSize.scala b/src/main/scala/leon/termination/StructuralSize.scala
index 50de827c17168bacd3db23049ed76237f73f132b..e075c374e8d4796680c940f3cf6e4d3ec455df79 100644
--- a/src/main/scala/leon/termination/StructuralSize.scala
+++ b/src/main/scala/leon/termination/StructuralSize.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/TerminationChecker.scala b/src/main/scala/leon/termination/TerminationChecker.scala
index 6b8f5abb670a4d61192ace440b604d99d0f6d706..efe8bf4387f631799472b64905de9350bac1da64 100644
--- a/src/main/scala/leon/termination/TerminationChecker.scala
+++ b/src/main/scala/leon/termination/TerminationChecker.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
diff --git a/src/main/scala/leon/termination/TerminationPhase.scala b/src/main/scala/leon/termination/TerminationPhase.scala
index f75d388d4d2f63317f1c90d063a6404bc78e5edb..d5b07f276264c548e9b31a295ca1efdd101e0871 100644
--- a/src/main/scala/leon/termination/TerminationPhase.scala
+++ b/src/main/scala/leon/termination/TerminationPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
@@ -20,7 +20,7 @@ object TerminationPhase extends SimpleLeonPhase[Program, TerminationReport] {
     val fdFilter = {
       import OptionsHelpers._
 
-      filterInclusive(ctx.findOption(SharedOptions.optFunctions).map(fdMatcher(program)), Some(excludeByDefault _))
+      filterInclusive(ctx.findOption(GlobalOptions.optFunctions).map(fdMatcher(program)), Some(excludeByDefault _))
     }
 
     val toVerify = tc.program.definedFunctions.filter(fdFilter).sortWith((fd1, fd2) => fd1.getPos < fd2.getPos)
diff --git a/src/main/scala/leon/termination/TerminationReport.scala b/src/main/scala/leon/termination/TerminationReport.scala
index 57c3c03aebc3f0543cad09e84352106867c178c6..c7fc3a0b3d7a870b7730022da35e7c3fa3f7483d 100644
--- a/src/main/scala/leon/termination/TerminationReport.scala
+++ b/src/main/scala/leon/termination/TerminationReport.scala
@@ -1,12 +1,13 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package termination
 
 import purescala.Definitions._
+import utils.Report
 import utils.ASCIIHelpers._
 
-case class TerminationReport(ctx: LeonContext, results : Seq[(FunDef,TerminationGuarantee)], time : Double) {
+case class TerminationReport(ctx: LeonContext, results : Seq[(FunDef,TerminationGuarantee)], time : Double) extends Report {
 
   def summaryString : String = {
     var t = Table("Termination summary")
diff --git a/src/main/scala/leon/transformations/DepthInstPhase.scala b/src/main/scala/leon/transformations/DepthInstPhase.scala
index 3788602f6a67b87fbffc33c584199c7a7b89aa8c..96d47147e6a8439e8d37105feff523248963599c 100644
--- a/src/main/scala/leon/transformations/DepthInstPhase.scala
+++ b/src/main/scala/leon/transformations/DepthInstPhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/InstProgSimplifier.scala b/src/main/scala/leon/transformations/InstProgSimplifier.scala
index 56eecde2a89dc6f52cc966829417ba172d8f38ba..cc4ce609d0da066e70bbd8347dbe9d8220cafcf3 100644
--- a/src/main/scala/leon/transformations/InstProgSimplifier.scala
+++ b/src/main/scala/leon/transformations/InstProgSimplifier.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/InstrumentationUtil.scala b/src/main/scala/leon/transformations/InstrumentationUtil.scala
index 8e4c10451080f233aa1ac1bff4ae56dafb32d616..5c26b194a55900adcea0383fe1b469c299bab0af 100644
--- a/src/main/scala/leon/transformations/InstrumentationUtil.scala
+++ b/src/main/scala/leon/transformations/InstrumentationUtil.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/IntToRealProgram.scala b/src/main/scala/leon/transformations/IntToRealProgram.scala
index f585cf042177bdec7dea20585fb6d5a505825c9a..fa09f9dca145674224a067357192b41853631ad9 100644
--- a/src/main/scala/leon/transformations/IntToRealProgram.scala
+++ b/src/main/scala/leon/transformations/IntToRealProgram.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/NonRecursiveTimePhase.scala b/src/main/scala/leon/transformations/NonRecursiveTimePhase.scala
index d315bd76de619aa312bec59587e1d8efcbdb4cf3..7df3f03f081d7160f66d44ced7bd8f0550fafc11 100644
--- a/src/main/scala/leon/transformations/NonRecursiveTimePhase.scala
+++ b/src/main/scala/leon/transformations/NonRecursiveTimePhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/NonlinearityEliminationPhase.scala b/src/main/scala/leon/transformations/NonlinearityEliminationPhase.scala
index 68b89227251439c35ca338bf19867a21112d4f72..76d34c195bce7603eac0864f8ded92968bbb0b9a 100644
--- a/src/main/scala/leon/transformations/NonlinearityEliminationPhase.scala
+++ b/src/main/scala/leon/transformations/NonlinearityEliminationPhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/RecursionCountPhase.scala b/src/main/scala/leon/transformations/RecursionCountPhase.scala
index ad08c8d9d2c90669edd4240154917410e141c99e..729a8d45a6d6955fd31f1694fce03dade7c89e6d 100644
--- a/src/main/scala/leon/transformations/RecursionCountPhase.scala
+++ b/src/main/scala/leon/transformations/RecursionCountPhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/SerialInstrumentationPhase.scala b/src/main/scala/leon/transformations/SerialInstrumentationPhase.scala
index 7e60625c62e344792c3a5caa66b7a3b4045915e7..957074b485f4af3b66ec4d9aab021aa0ce05484f 100644
--- a/src/main/scala/leon/transformations/SerialInstrumentationPhase.scala
+++ b/src/main/scala/leon/transformations/SerialInstrumentationPhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/StackSpacePhase.scala b/src/main/scala/leon/transformations/StackSpacePhase.scala
index d80cb20dc46f2adacc1980d364ebf563eb1fb892..51c36bb93356fed867ecbbd0276eaf336f891606 100644
--- a/src/main/scala/leon/transformations/StackSpacePhase.scala
+++ b/src/main/scala/leon/transformations/StackSpacePhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/transformations/TimeStepsPhase.scala b/src/main/scala/leon/transformations/TimeStepsPhase.scala
index d43e7641c8bf95996502fa0a44cee9ce5c58543a..9180978ba63d33295aea1988602a48c8fdef8feb 100644
--- a/src/main/scala/leon/transformations/TimeStepsPhase.scala
+++ b/src/main/scala/leon/transformations/TimeStepsPhase.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package transformations
 
diff --git a/src/main/scala/leon/utils/ASCIIHelpers.scala b/src/main/scala/leon/utils/ASCIIHelpers.scala
index a2750e42340356f890b6f4822ba3d2f2d3f42643..0b5a746f540ef1ad49c4e5e88155a4228b33e15c 100644
--- a/src/main/scala/leon/utils/ASCIIHelpers.scala
+++ b/src/main/scala/leon/utils/ASCIIHelpers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/Benchmarks.scala b/src/main/scala/leon/utils/Benchmarks.scala
index 71d948949a6d7d9cf8f6ce8501d71c451f18c2f4..92c0e398c5880f0cd6f159d597e8435ca4f2ee44 100644
--- a/src/main/scala/leon/utils/Benchmarks.scala
+++ b/src/main/scala/leon/utils/Benchmarks.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/Bijection.scala b/src/main/scala/leon/utils/Bijection.scala
index 380799d25e1f73ddbbb57d7989706fd03e5f1821..fecf8a75603fb7f94791d11d184351c17e06508e 100644
--- a/src/main/scala/leon/utils/Bijection.scala
+++ b/src/main/scala/leon/utils/Bijection.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/DebugFiles.scala b/src/main/scala/leon/utils/DebugFiles.scala
deleted file mode 100644
index 1f006c42374bed0de9d23f7c9485aace022d05d3..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/utils/DebugFiles.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon.utils
diff --git a/src/main/scala/leon/utils/DebugSections.scala b/src/main/scala/leon/utils/DebugSections.scala
index b3133d700fed92bb500423201dc4288832b07319..7e454e7eaf61f7c6d0aa7a4c43ac95e7b3742a9c 100644
--- a/src/main/scala/leon/utils/DebugSections.scala
+++ b/src/main/scala/leon/utils/DebugSections.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/FileOutputPhase.scala b/src/main/scala/leon/utils/FileOutputPhase.scala
index 3862d9385b2474ad776f030773749f8cc658539e..140a863acb9dcde186c10456111514dd6eb9e442 100644
--- a/src/main/scala/leon/utils/FileOutputPhase.scala
+++ b/src/main/scala/leon/utils/FileOutputPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
@@ -11,13 +11,7 @@ object FileOutputPhase extends UnitPhase[Program] {
   val name = "File output"
   val description = "Output parsed/generated program to the specified directory (default: leon.out)"
 
-  val optOutputDirectory = new LeonOptionDef[String] {
-    val name = "o"
-    val description = "Output directory"
-    val default = "leon.out"
-    val usageRhs = "dir"
-    val parser = (x: String) => x
-  }
+  val optOutputDirectory = LeonStringOptionDef("o", "Output directory", "leon.out", "dir")
 
   override val definedOptions: Set[LeonOptionDef[Any]] = Set(optOutputDirectory)
 
diff --git a/src/main/scala/leon/utils/FilesWatcher.scala b/src/main/scala/leon/utils/FilesWatcher.scala
index ca4a6727e8c2920ad510ddd90732487e8aa441d4..b4e579f5a419ec54eb3a4f7ae0f1903b24a6a3e5 100644
--- a/src/main/scala/leon/utils/FilesWatcher.scala
+++ b/src/main/scala/leon/utils/FilesWatcher.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/FreeableIterator.scala b/src/main/scala/leon/utils/FreeableIterator.scala
index a790b2dbf7a713ea681888fa9719da913140ca5c..ad2942c93a40b0eab58a407d66262cf5a6920c6e 100644
--- a/src/main/scala/leon/utils/FreeableIterator.scala
+++ b/src/main/scala/leon/utils/FreeableIterator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package utils
 
diff --git a/src/main/scala/leon/utils/GraphOps.scala b/src/main/scala/leon/utils/GraphOps.scala
index 3fede60e6035f55dc33b7274e272641c4ef73834..576694d686469c711c39a9830cbae60ce1924215 100644
--- a/src/main/scala/leon/utils/GraphOps.scala
+++ b/src/main/scala/leon/utils/GraphOps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/GraphPrinters.scala b/src/main/scala/leon/utils/GraphPrinters.scala
index b86882f2d42d6e7ea1816b249b3d35689b31ab67..c5fb26a0904b5c47e0b6748be81a0dfaef9bdf50 100644
--- a/src/main/scala/leon/utils/GraphPrinters.scala
+++ b/src/main/scala/leon/utils/GraphPrinters.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/Graphs.scala b/src/main/scala/leon/utils/Graphs.scala
index 1910c2aa25715acd325c53c9874bd1b86ec2a6f5..9ac99b6703b2f498d2991d4c4dcf2fdfb701f86c 100644
--- a/src/main/scala/leon/utils/Graphs.scala
+++ b/src/main/scala/leon/utils/Graphs.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/GrowableIterable.scala b/src/main/scala/leon/utils/GrowableIterable.scala
index 0b32fe6261b3bd41cf6bb8ad11fcc6161b47d44b..1ef76649a6d22abdbb1d6032683f4ce1fac1a0e0 100644
--- a/src/main/scala/leon/utils/GrowableIterable.scala
+++ b/src/main/scala/leon/utils/GrowableIterable.scala
@@ -1,12 +1,16 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.utils
 
 import scala.collection.mutable.ArrayBuffer
 
 class GrowableIterable[T](init: Seq[T], growth: Iterator[T]) extends Iterable[T] {
-  var buffer = new ArrayBuffer[T]() ++ init
+  private var buffer = new ArrayBuffer[T]() ++ init
+
+  var canGrow = () => true
 
-  val cachingIterator = new Iterator[T] {
-    def hasNext = growth.hasNext
+  private val cachingIterator = new Iterator[T] {
+    def hasNext = canGrow() && growth.hasNext
 
     def next() = {
       val res = growth.next()
@@ -15,6 +19,11 @@ class GrowableIterable[T](init: Seq[T], growth: Iterator[T]) extends Iterable[T]
     }
   }
 
+  def += (more: T)      = buffer +=  more
+  def ++=(more: Seq[T]) = buffer ++= more
+  def -= (less: T)      = buffer -=  less
+  def --=(less: Seq[T]) = buffer --= less
+
   def iterator: Iterator[T] = {
     buffer.iterator ++ cachingIterator
   }
diff --git a/src/main/scala/leon/utils/IncrementalBijection.scala b/src/main/scala/leon/utils/IncrementalBijection.scala
index d90d68ec6a2fef80efff8ace6224c960007de5db..6dab6d670aafb289b9d4f328a13bdb7a687d5063 100644
--- a/src/main/scala/leon/utils/IncrementalBijection.scala
+++ b/src/main/scala/leon/utils/IncrementalBijection.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/IncrementalMap.scala b/src/main/scala/leon/utils/IncrementalMap.scala
index b07d8adc19d51573ef63784b2fc49dbea9c38ff8..aeaf32e093ead4aba05b128d3f543e53fffb8f13 100644
--- a/src/main/scala/leon/utils/IncrementalMap.scala
+++ b/src/main/scala/leon/utils/IncrementalMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/IncrementalSeq.scala b/src/main/scala/leon/utils/IncrementalSeq.scala
index fbf042868415378d4af4877ee8766f1303632373..7c7846c94d409c9b0bfde327528e8d36e8487363 100644
--- a/src/main/scala/leon/utils/IncrementalSeq.scala
+++ b/src/main/scala/leon/utils/IncrementalSeq.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/IncrementalSet.scala b/src/main/scala/leon/utils/IncrementalSet.scala
index 311e55096efe8a98d1ccb310f2dae39752e21a20..e0f8c9c53ed791348e80d8ac834f9d43c495f4f6 100644
--- a/src/main/scala/leon/utils/IncrementalSet.scala
+++ b/src/main/scala/leon/utils/IncrementalSet.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/IncrementalState.scala b/src/main/scala/leon/utils/IncrementalState.scala
index 32f6b7c2b11ec3405aeeb0a9f81b9bfb08076ad8..a4df1acbe1a242c6fab0be4c091332d1a20d7e4c 100644
--- a/src/main/scala/leon/utils/IncrementalState.scala
+++ b/src/main/scala/leon/utils/IncrementalState.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.utils
 
 trait IncrementalState {
diff --git a/src/main/scala/leon/utils/InliningPhase.scala b/src/main/scala/leon/utils/InliningPhase.scala
index d69bbb9c32d6cd9f0d32281ec7b5af628aac5a15..22b75e16227faff8cf0bf2e441e92b92d41ecd13 100644
--- a/src/main/scala/leon/utils/InliningPhase.scala
+++ b/src/main/scala/leon/utils/InliningPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/InterruptManager.scala b/src/main/scala/leon/utils/InterruptManager.scala
index 40d8dd1836a8eacecadbc823c68e29fa4b232ca7..17501875028ec1878c5b8225cc062d1160906b55 100644
--- a/src/main/scala/leon/utils/InterruptManager.scala
+++ b/src/main/scala/leon/utils/InterruptManager.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/Interruptible.scala b/src/main/scala/leon/utils/Interruptible.scala
index a57cb7a39027563b0025d1f287af7d77043c9064..8132c004ce6e4acf2e39006ac91912889ac93cb4 100644
--- a/src/main/scala/leon/utils/Interruptible.scala
+++ b/src/main/scala/leon/utils/Interruptible.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/Library.scala b/src/main/scala/leon/utils/Library.scala
index 0ddd21078ffe772986bd5487d964d352184cd2e6..18dc12938bd2dd55ff51e568e5af4bcd79cd245a 100644
--- a/src/main/scala/leon/utils/Library.scala
+++ b/src/main/scala/leon/utils/Library.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/ModelEnumerator.scala b/src/main/scala/leon/utils/ModelEnumerator.scala
index 7494e0c463051e0a1337287c4e9e8310d3d23106..75fd2a0a3de2a8bcb554b810e3538346443aaf19 100644
--- a/src/main/scala/leon/utils/ModelEnumerator.scala
+++ b/src/main/scala/leon/utils/ModelEnumerator.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 package utils
 
diff --git a/src/main/scala/leon/utils/OracleTraverser.scala b/src/main/scala/leon/utils/OracleTraverser.scala
index 507d2246e0b2742e2d0c06acab0692ca1d6e8d91..0044dc695e2448c8c5ff229411f56fe7d3550d32 100644
--- a/src/main/scala/leon/utils/OracleTraverser.scala
+++ b/src/main/scala/leon/utils/OracleTraverser.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/Positions.scala b/src/main/scala/leon/utils/Positions.scala
index b97a58d56bc123e4c78e9d4a51d2435d4712503a..74f999656c9911e88d2756eff5cbdf92c319ded0 100644
--- a/src/main/scala/leon/utils/Positions.scala
+++ b/src/main/scala/leon/utils/Positions.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/PreprocessingPhase.scala b/src/main/scala/leon/utils/PreprocessingPhase.scala
index 72103a4f70098527f4f80dba71c47a4b46c5d2d1..1d4fed4bc3d1a0d439e336603a2f5b2e9c5af50c 100644
--- a/src/main/scala/leon/utils/PreprocessingPhase.scala
+++ b/src/main/scala/leon/utils/PreprocessingPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
@@ -16,44 +16,28 @@ class PreprocessingPhase(desugarXLang: Boolean = false, genc: Boolean = false) e
 
   override def run(ctx: LeonContext, p: Program): (LeonContext, Program) = {
 
-    def debugTrees(title: String): LeonPhase[Program, Program] = {
-      if (ctx.reporter.isDebugEnabled(DebugSectionTrees)) {
-        PrintTreePhase(title)
-      } else {
-        NoopPhase[Program]()
-      }
-    }
-
-    val checkX = if (desugarXLang) {
-      NoopPhase[Program]()
-    } else {
-      NoXLangFeaturesChecking
-    }
+    def debugTrees(title: String) =
+      PrintTreePhase(title).when(ctx.reporter.isDebugEnabled(DebugSectionTrees))
 
     val pipeBegin =
-      debugTrees("Program after extraction") andThen
-      checkX                                 andThen
-      MethodLifting                          andThen
-      TypingPhase                            andThen
-      synthesis.ConversionPhase              andThen
+      debugTrees("Program after extraction")      andThen
+      NoXLangFeaturesChecking.when(!desugarXLang) andThen
+      MethodLifting                               andThen
+      TypingPhase                                 andThen
+      synthesis.ConversionPhase                   andThen
       InliningPhase
 
-    val pipeX = if (!genc && desugarXLang) {
-      // Do not desugar when generating C code
+    // Do not desugar xlang when generating C code
+    val pipeX = (
       XLangDesugaringPhase andThen
       debugTrees("Program after xlang desugaring")
-    } else {
-      NoopPhase[Program]()
-    }
+    ) when (!genc && desugarXLang)
 
-    def pipeEnd = if (genc) {
-      // No InjectAsserts, FunctionClosure and AdaptationPhase phases
-      NoopPhase[Program]()
-    } else {
+    def pipeEnd = (
       InjectAsserts  andThen
       FunctionClosure andThen
       AdaptationPhase
-    }
+    ) when (!genc)
 
     val phases =
       pipeBegin andThen
diff --git a/src/main/scala/leon/utils/PrintReportPhase.scala b/src/main/scala/leon/utils/PrintReportPhase.scala
new file mode 100644
index 0000000000000000000000000000000000000000..cf19df7575fd299254315eabcd3fdca4bd5fb568
--- /dev/null
+++ b/src/main/scala/leon/utils/PrintReportPhase.scala
@@ -0,0 +1,16 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package utils
+
+/** Pretty-prints a [[Report]] */
+case object PrintReportPhase extends UnitPhase[Report] {
+
+  override val description: String = "Print a Leon report"
+  override val name: String = "PrintReport"
+
+  override def apply(ctx: LeonContext, rep: Report): Unit = {
+    ctx.reporter.info(rep.summaryString)
+  }
+
+}
diff --git a/src/main/scala/leon/utils/PrintTreePhase.scala b/src/main/scala/leon/utils/PrintTreePhase.scala
index 90e12ee1c6e5dbc7e29cf684191069b5e0517b6e..87003c14d8fd77fb96e24eb5e9653d79f12e5fe5 100644
--- a/src/main/scala/leon/utils/PrintTreePhase.scala
+++ b/src/main/scala/leon/utils/PrintTreePhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/Report.scala b/src/main/scala/leon/utils/Report.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4e4a64dbe749f4cbf61f8036709936bbf68dd88e
--- /dev/null
+++ b/src/main/scala/leon/utils/Report.scala
@@ -0,0 +1,8 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon.utils
+
+/** Represents a pretty-printable report */
+abstract class Report {
+  def summaryString: String
+}
diff --git a/src/main/scala/leon/utils/SCC.scala b/src/main/scala/leon/utils/SCC.scala
index dbde69fc1e03b3a0e6655806b75c09fec93003bf..7f5212d5405017d83f8a690706d95b5b615efda4 100644
--- a/src/main/scala/leon/utils/SCC.scala
+++ b/src/main/scala/leon/utils/SCC.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/SearchSpace.scala b/src/main/scala/leon/utils/SearchSpace.scala
index b013077c9ad0feac378eba8d7142f37679495936..b514b72ffec351529ed8b9a14da82097a69287be 100644
--- a/src/main/scala/leon/utils/SearchSpace.scala
+++ b/src/main/scala/leon/utils/SearchSpace.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/SeqUtils.scala b/src/main/scala/leon/utils/SeqUtils.scala
index ada7499120353737d34bc79e2c9cc312d6702580..e55c1ac277be0d867547309684baf9f7560aa276 100644
--- a/src/main/scala/leon/utils/SeqUtils.scala
+++ b/src/main/scala/leon/utils/SeqUtils.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/Simplifiers.scala b/src/main/scala/leon/utils/Simplifiers.scala
index 4438b3840e62111e82c17f4db91456c8e30ba2cb..26a62b2983d2627ac4bb7c3a925f1e08f38f3969 100644
--- a/src/main/scala/leon/utils/Simplifiers.scala
+++ b/src/main/scala/leon/utils/Simplifiers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/StreamUtils.scala b/src/main/scala/leon/utils/StreamUtils.scala
index 521e98aa6eb35e28e820c4e0aea8ff11709643e1..32c8e7c4b19d2c45c2a5148f1ce6b054faadfa4f 100644
--- a/src/main/scala/leon/utils/StreamUtils.scala
+++ b/src/main/scala/leon/utils/StreamUtils.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/TemporaryInputPhase.scala b/src/main/scala/leon/utils/TemporaryInputPhase.scala
index 11b6efb68aa51fb46e2b23af82cbc834b0481abe..bf5101b4c2ac3acb676940b7c969f97b7bb383d1 100644
--- a/src/main/scala/leon/utils/TemporaryInputPhase.scala
+++ b/src/main/scala/leon/utils/TemporaryInputPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/TimeoutFor.scala b/src/main/scala/leon/utils/TimeoutFor.scala
index 7b11a9757931794a5ef38c82962a6445b07e16d9..fa2b9aeca28d6cb83cd6449075a3f2b1dff98124 100644
--- a/src/main/scala/leon/utils/TimeoutFor.scala
+++ b/src/main/scala/leon/utils/TimeoutFor.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/Timer.scala b/src/main/scala/leon/utils/Timer.scala
index 203f7b77360d445ed4cc5418f49f795cb6814ebf..db5070e0dc7892602613024ea04b33a09e530d34 100644
--- a/src/main/scala/leon/utils/Timer.scala
+++ b/src/main/scala/leon/utils/Timer.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/TypingPhase.scala b/src/main/scala/leon/utils/TypingPhase.scala
index 08b415c6b787a4f64dd7611ff8c755d2cdc419ba..ca4e3a72b85d0cf026abd32d45d7eb6b70145365 100644
--- a/src/main/scala/leon/utils/TypingPhase.scala
+++ b/src/main/scala/leon/utils/TypingPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
@@ -32,19 +32,19 @@ object TypingPhase extends SimpleLeonPhase[Program, Program] {
     pgm.definedFunctions.foreach(fd => {
 
       // Part (1)
-      fd.precondition = {
-        val argTypesPreconditions = fd.params.flatMap(arg => arg.getType match {
-          case cct: ClassType if cct.parent.isDefined =>
-            Seq(IsInstanceOf(arg.id.toVariable, cct))
-          case at: ArrayType =>
-            Seq(GreaterEquals(ArrayLength(arg.id.toVariable), IntLiteral(0)))
-          case _ =>
-            Seq()
-        })
-        argTypesPreconditions match {
-          case Nil => fd.precondition
-          case xs => fd.precondition match {
-            case Some(p) => Some(andJoin(xs :+ p))
+      val argTypesPreconditions = fd.params.flatMap(arg => arg.getType match {
+        case cct: ClassType if cct.parent.isDefined =>
+          Seq(IsInstanceOf(arg.id.toVariable, cct))
+        case at: ArrayType =>
+          Seq(GreaterEquals(ArrayLength(arg.id.toVariable), IntLiteral(0)))
+        case _ =>
+          Seq()
+      })
+      argTypesPreconditions match {
+        case Nil => ()
+        case xs => fd.precondition = {
+          fd.precondition match {
+            case Some(p) => Some(andJoin(xs :+ p).copiedFrom(p))
             case None => Some(andJoin(xs))
           }
         }
diff --git a/src/main/scala/leon/utils/UniqueCounter.scala b/src/main/scala/leon/utils/UniqueCounter.scala
index 7c7862747271a67d899b9a590bc2d9c5fbb7de40..e3c6ae0a1b5d43b65a77de046cffaabea1b50f34 100644
--- a/src/main/scala/leon/utils/UniqueCounter.scala
+++ b/src/main/scala/leon/utils/UniqueCounter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.utils
 
diff --git a/src/main/scala/leon/utils/UnitElimination.scala b/src/main/scala/leon/utils/UnitElimination.scala
index 45fa8bea46c71643c68a5a69f5f18e9318c4c449..d5aa0069e718649e3d72a8afe2dd12915c66af3f 100644
--- a/src/main/scala/leon/utils/UnitElimination.scala
+++ b/src/main/scala/leon/utils/UnitElimination.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package utils
diff --git a/src/main/scala/leon/utils/package.scala b/src/main/scala/leon/utils/package.scala
index 56ee940d24b2e0802c3947b409a5269088ccee22..09dc22742043e661fb14ac197a181e4d1fee54a0 100644
--- a/src/main/scala/leon/utils/package.scala
+++ b/src/main/scala/leon/utils/package.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon
 
 /** Various utilities used throughout the Leon system */
diff --git a/src/main/scala/leon/verification/DefaultTactic.scala b/src/main/scala/leon/verification/DefaultTactic.scala
index 244b38b30a885d588ef4b38336d9765c60e55417..9905d96ad466c25e7fbf8b690ba58cf8bad70ddf 100644
--- a/src/main/scala/leon/verification/DefaultTactic.scala
+++ b/src/main/scala/leon/verification/DefaultTactic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package verification
diff --git a/src/main/scala/leon/verification/InductionTactic.scala b/src/main/scala/leon/verification/InductionTactic.scala
index dd437c224170c908e9175815354748a4236e4880..d1ae3b0f9827e6bf547893b7ce47475656efd306 100644
--- a/src/main/scala/leon/verification/InductionTactic.scala
+++ b/src/main/scala/leon/verification/InductionTactic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package verification
diff --git a/src/main/scala/leon/verification/InjectAsserts.scala b/src/main/scala/leon/verification/InjectAsserts.scala
index aa88b39dec1e45377aa77f87ded6a0535abac782..faa5701f7a7f80bc29c81282696a898febcc6c80 100644
--- a/src/main/scala/leon/verification/InjectAsserts.scala
+++ b/src/main/scala/leon/verification/InjectAsserts.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package verification
diff --git a/src/main/scala/leon/verification/Tactic.scala b/src/main/scala/leon/verification/Tactic.scala
index 8f539708da8f9f4071a1843d8d711c55215ed344..008a03f5aca8d737b2e46de4e3b3ce42a83ead40 100644
--- a/src/main/scala/leon/verification/Tactic.scala
+++ b/src/main/scala/leon/verification/Tactic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package verification
diff --git a/src/main/scala/leon/verification/VerificationCondition.scala b/src/main/scala/leon/verification/VerificationCondition.scala
index 299307a87e6e1e4bd2470c377966419bc8c90f15..1cbbf2103913f07a490a5641040abd3927c71bf2 100644
--- a/src/main/scala/leon/verification/VerificationCondition.scala
+++ b/src/main/scala/leon/verification/VerificationCondition.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.verification
 
diff --git a/src/main/scala/leon/verification/VerificationContext.scala b/src/main/scala/leon/verification/VerificationContext.scala
index 2aaa910ab6450c0de300e36ec42ad71d7b073d84..be8f9efe56480b44c47aebc7c4eabeb4d3190975 100644
--- a/src/main/scala/leon/verification/VerificationContext.scala
+++ b/src/main/scala/leon/verification/VerificationContext.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package verification
diff --git a/src/main/scala/leon/verification/VerificationPhase.scala b/src/main/scala/leon/verification/VerificationPhase.scala
index 04c4ecdcce10e724c1fae82b8faff95e7a6a619c..c4b1427f04a87d10de6e9a19c56c5d6e46d0a9f3 100644
--- a/src/main/scala/leon/verification/VerificationPhase.scala
+++ b/src/main/scala/leon/verification/VerificationPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package verification
@@ -22,8 +22,8 @@ object VerificationPhase extends SimpleLeonPhase[Program,VerificationReport] {
   implicit val debugSection = utils.DebugSectionVerification
 
   def apply(ctx: LeonContext, program: Program): VerificationReport = {
-    val filterFuns: Option[Seq[String]] = ctx.findOption(SharedOptions.optFunctions)
-    val timeout:    Option[Long]        = ctx.findOption(SharedOptions.optTimeout)
+    val filterFuns: Option[Seq[String]] = ctx.findOption(GlobalOptions.optFunctions)
+    val timeout:    Option[Long]        = ctx.findOption(GlobalOptions.optTimeout)
 
     val reporter = ctx.reporter
 
diff --git a/src/main/scala/leon/verification/VerificationReport.scala b/src/main/scala/leon/verification/VerificationReport.scala
index 2875bf3ed074756c5089896c327b487cc029fe34..374122f72781e4e0c24ee05e6a96fa18cfed5be5 100644
--- a/src/main/scala/leon/verification/VerificationReport.scala
+++ b/src/main/scala/leon/verification/VerificationReport.scala
@@ -1,29 +1,12 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package verification
 
-import utils.DebugSectionSynthesis
-import utils.DebugSectionVerification
-import leon.purescala
 import purescala.Definitions.Program
-import purescala.Expressions._
-import purescala.Types.StringType
-import purescala.TypeOps
-import purescala.Quantification._
-import purescala.Constructors._
-import purescala.ExprOps._
-import purescala.Expressions.{Pattern, Expr}
-import purescala.Extractors._
-import purescala.TypeOps._
-import purescala.Types._
-import purescala.Common._
-import purescala.Expressions._
-import purescala.Definitions._
-import purescala.SelfPrettyPrinter
-import leon.solvers.{ PartialModel, Model, SolverFactory }
+import utils.Report
 
-case class VerificationReport(program: Program, results: Map[VC, Option[VCResult]]) {
+case class VerificationReport(program: Program, results: Map[VC, Option[VCResult]]) extends Report {
   val vrs: Seq[(VC, VCResult)] = results.toSeq.sortBy { case (vc, _) => (vc.fd.id.name, vc.kind.toString) }.map {
     case (vc, or) => (vc, or.getOrElse(VCResult.unknown))
   }
diff --git a/src/main/scala/leon/xlang/AntiAliasingPhase.scala b/src/main/scala/leon/xlang/AntiAliasingPhase.scala
index 7eb391088ea64c276aa0bbf7836e4a9511aa978c..f1ea90043736d1ea59a5ae0d9747e15905509cd6 100644
--- a/src/main/scala/leon/xlang/AntiAliasingPhase.scala
+++ b/src/main/scala/leon/xlang/AntiAliasingPhase.scala
@@ -19,12 +19,14 @@ object AntiAliasingPhase extends TransformationPhase {
   val description = "Make aliasing explicit"
 
   override def apply(ctx: LeonContext, pgm: Program): Program = {
+
     val fds = allFunDefs(pgm)
     fds.foreach(fd => checkAliasing(fd)(ctx))
 
     var updatedFunctions: Map[FunDef, FunDef] = Map()
 
     val effects = effectsAnalysis(pgm)
+    //println("effects: " + effects.filter(e => e._2.size > 0).map(e => (e._1.id, e._2)))
 
     //for each fun def, all the vars the the body captures. Only
     //mutable types.
@@ -33,7 +35,7 @@ object AntiAliasingPhase extends TransformationPhase {
     } yield {
       val allFreeVars = fd.body.map(bd => variablesOf(bd)).getOrElse(Set())
       val freeVars = allFreeVars -- fd.params.map(_.id)
-      val mutableFreeVars = freeVars.filter(id => id.getType.isInstanceOf[ArrayType])
+      val mutableFreeVars = freeVars.filter(id => isMutableType(id.getType))
       (fd, mutableFreeVars)
     }).toMap
 
@@ -61,8 +63,8 @@ object AntiAliasingPhase extends TransformationPhase {
   /*
    * Create a new FunDef for a given FunDef in the program.
    * Adapt the signature to express its effects. In case the
-   * function has no effect, this will still introduce a fresh
-   * FunDef as the body might have to be updated anyway.
+   * function has no effect, this will still return the original
+   * fundef.
    */
   private def updateFunDef(fd: FunDef, effects: Effects)(ctx: LeonContext): FunDef = {
 
@@ -85,13 +87,13 @@ object AntiAliasingPhase extends TransformationPhase {
     //  case _ => ()
     //})
 
-    val newReturnType: TypeTree = if(aliasedParams.isEmpty) fd.returnType else {
-      tupleTypeWrap(fd.returnType +: aliasedParams.map(_.getType))
+    if(aliasedParams.isEmpty) fd else {
+      val newReturnType: TypeTree = tupleTypeWrap(fd.returnType +: aliasedParams.map(_.getType))
+      val newFunDef = new FunDef(fd.id.freshen, fd.tparams, fd.params, newReturnType)
+      newFunDef.addFlags(fd.flags)
+      newFunDef.setPos(fd)
+      newFunDef
     }
-    val newFunDef = new FunDef(fd.id.freshen, fd.tparams, fd.params, newReturnType)
-    newFunDef.addFlags(fd.flags)
-    newFunDef.setPos(fd)
-    newFunDef
   }
 
   private def updateBody(fd: FunDef, effects: Effects, updatedFunDefs: Map[FunDef, FunDef], varsInScope: Map[FunDef, Set[Identifier]])
@@ -166,12 +168,25 @@ object AntiAliasingPhase extends TransformationPhase {
           (None, bindings)
       }
 
-      case l@Let(id, IsTyped(v, ArrayType(_)), b) => {
+      case as@FieldAssignment(o, id, v) => {
+        findReceiverId(o) match {
+          case None => 
+            ctx.reporter.fatalError(as.getPos, "Unsupported form of field assignment: " + as)
+          case Some(oid) => {
+            if(bindings.contains(oid))
+              (Some(Assignment(oid, deepCopy(o, id, v))), bindings)
+            else
+              (None, bindings)
+          }
+        }
+      }
+
+      case l@Let(id, IsTyped(v, tpe), b) if isMutableType(tpe) => {
         val varDecl = LetVar(id, v, b).setPos(l)
         (Some(varDecl), bindings + id)
       }
 
-      case l@LetVar(id, IsTyped(v, ArrayType(_)), b) => {
+      case l@LetVar(id, IsTyped(v, tpe), b) if isMutableType(tpe) => {
         (None, bindings + id)
       }
 
@@ -181,7 +196,7 @@ object AntiAliasingPhase extends TransformationPhase {
         //so we need to ignore the second times by checking if updatedFunDefs 
         //contains a mapping or not
         val nfds = fds.map(fd => updatedFunDefs.get(fd).getOrElse(fd))
-        (Some(LetDef(nfds, body)), bindings)
+        (Some(LetDef(nfds, body).copiedFrom(l)), bindings)
       }
 
       case fi@FunctionInvocation(fd, args) => {
@@ -196,21 +211,29 @@ object AntiAliasingPhase extends TransformationPhase {
         updatedFunDefs.get(fd.fd) match {
           case None => (None, bindings)
           case Some(nfd) => {
-            val nfi = FunctionInvocation(nfd.typed(fd.tps), args).setPos(fi)
+            val nfi = FunctionInvocation(nfd.typed(fd.tps), args).copiedFrom(fi)
             val fiEffects = effects.getOrElse(fd.fd, Set())
             if(fiEffects.nonEmpty) {
-              val modifiedArgs: Seq[Variable] = 
+              val modifiedArgs: Seq[(Identifier, Expr)] =// functionInvocationEffects(fi, fiEffects)
                 args.zipWithIndex.filter{ case (arg, i) => fiEffects.contains(i) }
-                    .map(_._1.asInstanceOf[Variable])
+                    .map(arg => (findReceiverId(arg._1).get, arg._1))
 
               val duplicatedParams = modifiedArgs.diff(modifiedArgs.distinct).distinct
               if(duplicatedParams.nonEmpty) 
                 ctx.reporter.fatalError(fi.getPos, "Illegal passing of aliased parameter: " + duplicatedParams.head)
 
-              val freshRes = FreshIdentifier("res", nfd.returnType)
+              val freshRes = FreshIdentifier("res", nfd.typed(fd.tps).returnType)
 
               val extractResults = Block(
-                modifiedArgs.zipWithIndex.map(p => Assignment(p._1.id, TupleSelect(freshRes.toVariable, p._2 + 2))),
+                modifiedArgs.zipWithIndex.map{ case ((id, expr), index) => {
+                  val resSelect = TupleSelect(freshRes.toVariable, index + 2)
+                  expr match {
+                    case CaseClassSelector(_, obj, mid) =>
+                      Assignment(id, deepCopy(obj, mid, resSelect))
+                    case _ =>
+                      Assignment(id, resSelect)
+                  }
+                }},
                 TupleSelect(freshRes.toVariable, 1))
 
 
@@ -228,9 +251,7 @@ object AntiAliasingPhase extends TransformationPhase {
     })(body, aliasedParams.toSet)
   }
 
-  //TODO: in the future, any object with vars could be aliased and so
-  //      we will need a general property
-
+  //for each fundef, the set of modified params (by index)
   private type Effects = Map[FunDef, Set[Int]]
 
   /*
@@ -253,14 +274,8 @@ object AntiAliasingPhase extends TransformationPhase {
         case None =>
           effects += (fd -> Set())
         case Some(body) => {
-          val mutableParams = fd.params.filter(vd => vd.getType match {
-            case ArrayType(_) => true
-            case _ => false
-          })
-          val mutatedParams = mutableParams.filter(vd => exists {
-            case ArrayUpdate(Variable(a), _, _) => a == vd.id
-            case _ => false
-          }(body))
+          val mutableParams = fd.params.filter(vd => isMutableType(vd.getType))
+          val mutatedParams = mutableParams.filter(vd => exists(expr => isMutationOf(expr, vd.id))(body))
           val mutatedParamsIndices = fd.params.zipWithIndex.flatMap{
             case (vd, i) if mutatedParams.contains(vd) => Some(i)
             case _ => None
@@ -306,10 +321,7 @@ object AntiAliasingPhase extends TransformationPhase {
       //TODO: the require should be fine once we consider nested functions as well
       //require(effects.isDefinedAt(fi.tfd.fd)
       val mutatedParams: Set[Int] = effects.get(fi.tfd.fd).getOrElse(Set())
-      fi.args.zipWithIndex.flatMap{
-        case (Variable(id), i) if mutatedParams.contains(i) => Some(id)
-        case _ => None
-      }.toSet
+      functionInvocationEffects(fi, mutatedParams).toSet
     }
 
     rec()
@@ -320,8 +332,11 @@ object AntiAliasingPhase extends TransformationPhase {
   def checkAliasing(fd: FunDef)(ctx: LeonContext): Unit = {
     def checkReturnValue(body: Expr, bindings: Set[Identifier]): Unit = {
       getReturnedExpr(body).foreach{
-        case IsTyped(v@Variable(id), ArrayType(_)) if bindings.contains(id) =>
-          ctx.reporter.fatalError(v.getPos, "Cannot return a shared reference to a mutable object: " + v)
+        case expr if isMutableType(expr.getType) => 
+          findReceiverId(expr).foreach(id =>
+            if(bindings.contains(id))
+              ctx.reporter.fatalError(expr.getPos, "Cannot return a shared reference to a mutable object: " + expr)
+          )
         case _ => ()
       }
     }
@@ -330,21 +345,23 @@ object AntiAliasingPhase extends TransformationPhase {
       val params = fd.params.map(_.id).toSet
       checkReturnValue(bd, params)
       preMapWithContext[Set[Identifier]]((expr, bindings) => expr match {
-        case l@Let(id, IsTyped(v, ArrayType(_)), b) => {
+        case l@Let(id, v, b) if isMutableType(v.getType) => {
           v match {
             case FiniteArray(_, _, _) => ()
             case FunctionInvocation(_, _) => ()
             case ArrayUpdated(_, _, _) => ()
-            case _ => ctx.reporter.fatalError(l.getPos, "Cannot alias array: " + l)
+            case CaseClass(_, _) => ()
+            case _ => ctx.reporter.fatalError(v.getPos, "Illegal aliasing: " + v)
           }
           (None, bindings + id)
         }
-        case l@LetVar(id, IsTyped(v, ArrayType(_)), b) => {
+        case l@LetVar(id, v, b) if isMutableType(v.getType) => {
           v match {
             case FiniteArray(_, _, _) => ()
             case FunctionInvocation(_, _) => ()
             case ArrayUpdated(_, _, _) => ()
-            case _ => ctx.reporter.fatalError(l.getPos, "Cannot alias array: " + l)
+            case CaseClass(_, _) => ()
+            case _ => ctx.reporter.fatalError(v.getPos, "Illegal aliasing: " + v)
           }
           (None, bindings + id)
         }
@@ -380,4 +397,69 @@ object AntiAliasingPhase extends TransformationPhase {
       pgm.definedFunctions.flatMap(fd => 
         fd.body.toSet.flatMap((bd: Expr) =>
           nestedFunDefsOf(bd)) + fd)
+
+
+  private def findReceiverId(o: Expr): Option[Identifier] = o match {
+    case Variable(id) => Some(id)
+    case CaseClassSelector(_, e, _) => findReceiverId(e)
+    case _ => None
+  }
+
+
+  private def isMutableType(tpe: TypeTree): Boolean = tpe match {
+    case (arr: ArrayType) => true
+    case CaseClassType(ccd, _) if ccd.fields.exists(vd => vd.isVar || isMutableType(vd.getType)) => true
+    case _ => false
+  }
+
+
+  /*
+   * Check if expr is mutating variable id
+   */
+  private def isMutationOf(expr: Expr, id: Identifier): Boolean = expr match {
+    case ArrayUpdate(Variable(a), _, _) => a == id
+    case FieldAssignment(obj, _, _) => findReceiverId(obj).exists(_ == id)
+    case _ => false
+  }
+
+  //return the set of modified variables arguments to a function invocation,
+  //given the effect of the fun def invoked.
+  private def functionInvocationEffects(fi: FunctionInvocation, effects: Set[Int]): Seq[Identifier] = {
+    fi.args.map(arg => findReceiverId(arg)).zipWithIndex.flatMap{
+      case (Some(id), i) if effects.contains(i) => Some(id)
+      case _ => None
+    }
+  }
+
+  //private def extractFieldPath(o: Expr): (Expr, List[Identifier]) = {
+  //  def rec(o: Expr): List[Identifier] = o match {
+  //    case CaseClassSelector(_, r, i) =>
+  //      val res = toFieldPath(r)
+  //      (res._1, i::res)
+  //    case expr => (expr, Nil)
+  //  }
+  //  val res = rec(o)
+  //  (res._1, res._2.reverse)
+  //}
+
+  private def deepCopy(rec: Expr, id: Identifier, nv: Expr): Expr = {
+    val sub = copy(rec, id, nv)
+    rec match {
+      case CaseClassSelector(_, r, i) =>
+        deepCopy(r, i, sub)
+      case expr => sub
+    }
+  }
+
+  private def copy(cc: Expr, id: Identifier, nv: Expr): Expr = {
+    val ct@CaseClassType(ccd, _) = cc.getType
+    val newFields = ccd.fields.map(vd =>
+      if(vd.id == id)
+        nv
+      else
+        CaseClassSelector(CaseClassType(ct.classDef, ct.tps), cc, vd.id)
+    )
+    CaseClass(CaseClassType(ct.classDef, ct.tps), newFields).setPos(cc.getPos)
+  }
+
 }
diff --git a/src/main/scala/leon/xlang/ArrayTransformation.scala b/src/main/scala/leon/xlang/ArrayTransformation.scala
deleted file mode 100644
index c283a1be7665a7bed4f084a9a4f47421e44ef681..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/xlang/ArrayTransformation.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-
-package leon.xlang
-
-import leon.UnitPhase
-import leon.LeonContext
-import leon.purescala.Definitions._
-import leon.purescala.Expressions._
-import leon.purescala.ExprOps.simplePostTransform
-import leon.purescala.Extractors.IsTyped
-import leon.purescala.Types.ArrayType
-import leon.xlang.Expressions._
-
-object ArrayTransformation extends UnitPhase[Program] {
-
-  val name = "Array Transformation"
-  val description = "Remove side-effectful array updates"
-
-  def apply(ctx: LeonContext, pgm: Program) = {
-    pgm.definedFunctions.foreach(fd =>
-      fd.fullBody = simplePostTransform {
-        case up@ArrayUpdate(a, i, v) =>
-          val ra@Variable(id) = a
-          Assignment(id, ArrayUpdated(ra, i, v).setPos(up)).setPos(up)
-
-        case l@Let(i, IsTyped(v, ArrayType(_)), b) =>
-          LetVar(i, v, b).setPos(l)
-
-        case e =>
-          e
-      }(fd.fullBody)
-    )
-  }
-
-}
diff --git a/src/main/scala/leon/xlang/EpsilonElimination.scala b/src/main/scala/leon/xlang/EpsilonElimination.scala
index 51b23be1b9a6e4fe62bc6ed0b1cad83d0c83ffea..5ab872b84d9d495ddec840889c98d2a10222c44f 100644
--- a/src/main/scala/leon/xlang/EpsilonElimination.scala
+++ b/src/main/scala/leon/xlang/EpsilonElimination.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.xlang
 
diff --git a/src/main/scala/leon/xlang/ExprOps.scala b/src/main/scala/leon/xlang/ExprOps.scala
index 0f2a4db3d926d889df6fd5d7fa0f2548c6578209..a5013e5f8d87ccd0b6bb66e1b6db91e8c0528d9a 100644
--- a/src/main/scala/leon/xlang/ExprOps.scala
+++ b/src/main/scala/leon/xlang/ExprOps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package xlang
diff --git a/src/main/scala/leon/xlang/Expressions.scala b/src/main/scala/leon/xlang/Expressions.scala
index 98214ee640bd95227c0b759113ab74d2c9555d94..20e14ed1f0bd0badefa1ffd7c44168c4909b9b27 100644
--- a/src/main/scala/leon/xlang/Expressions.scala
+++ b/src/main/scala/leon/xlang/Expressions.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package xlang
@@ -53,6 +53,18 @@ object Expressions {
     }
   }
 
+  case class FieldAssignment(obj: Expr, varId: Identifier, expr: Expr) extends XLangExpr with Extractable with PrettyPrintable {
+    val getType = UnitType
+
+    def extract: Option[(Seq[Expr], Seq[Expr]=>Expr)] = {
+      Some((Seq(obj, expr), (es: Seq[Expr]) => FieldAssignment(es(0), varId, es(1))))
+    }
+
+    def printWith(implicit pctx: PrinterContext) {
+      p"${obj}.${varId} = ${expr};"
+    }
+  }
+
   case class While(cond: Expr, body: Expr) extends XLangExpr with Extractable with PrettyPrintable {
     val getType = UnitType
     var invariant: Option[Expr] = None
@@ -119,18 +131,6 @@ object Expressions {
     override def isSimpleExpr = false
   }
 
-  case class Waypoint(i: Int, expr: Expr, tpe: TypeTree) extends XLangExpr with Extractable with PrettyPrintable{
-    def extract: Option[(Seq[Expr], Seq[Expr]=>Expr)] = {
-      Some((Seq(expr), (es: Seq[Expr]) => Waypoint(i, es.head, tpe)))
-    }
-
-    def printWith(implicit pctx: PrinterContext) {
-      p"waypoint_$i($expr)"
-    }
-
-    val getType = tpe
-  }
-
   case class ArrayUpdate(array: Expr, index: Expr, newValue: Expr) extends XLangExpr with Extractable with PrettyPrintable {
     val getType = UnitType
 
diff --git a/src/main/scala/leon/xlang/FixReportLabels.scala b/src/main/scala/leon/xlang/FixReportLabels.scala
index 187f45b49eac8eeea3188ec197c7de02dba2a760..7615ec437b487aa73c2d28257179b705c80fac18 100644
--- a/src/main/scala/leon/xlang/FixReportLabels.scala
+++ b/src/main/scala/leon/xlang/FixReportLabels.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package xlang
diff --git a/src/main/scala/leon/xlang/ImperativeCodeElimination.scala b/src/main/scala/leon/xlang/ImperativeCodeElimination.scala
index 506cb86ce95bb044f709e23b6483ec1dcfb6ff7e..de75b7a29c0494ba4052aefe9fcb4f974dd128a2 100644
--- a/src/main/scala/leon/xlang/ImperativeCodeElimination.scala
+++ b/src/main/scala/leon/xlang/ImperativeCodeElimination.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package xlang
@@ -21,7 +21,7 @@ object ImperativeCodeElimination extends UnitPhase[Program] {
   def apply(ctx: LeonContext, pgm: Program): Unit = {
     for {
       fd <- pgm.definedFunctions
-      body <- fd.body
+      body <- fd.body if exists(requireRewriting)(body)
     } {
       val (res, scope, _) = toFunction(body)(State(fd, Set(), Map()))
       fd.body = Some(scope(res))
@@ -351,4 +351,12 @@ object ImperativeCodeElimination extends UnitPhase[Program] {
     })(expr)
   }
 
+  private def requireRewriting(expr: Expr) = expr match {
+    case (e: Block) => true
+    case (e: Assignment) => true
+    case (e: While) => true
+    case (e: LetVar) => true
+    case _ => false
+  }
+
 }
diff --git a/src/main/scala/leon/xlang/NoXLangFeaturesChecking.scala b/src/main/scala/leon/xlang/NoXLangFeaturesChecking.scala
index d054887e9f33e5d67e0fadb71332d1b7fcd395d2..fc7c3f76b933b4b4d38da2391eaf5c6fcad9813e 100644
--- a/src/main/scala/leon/xlang/NoXLangFeaturesChecking.scala
+++ b/src/main/scala/leon/xlang/NoXLangFeaturesChecking.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package xlang
@@ -29,8 +29,6 @@ object NoXLangFeaturesChecking extends UnitPhase[Program] {
         Set((e.getPos, "Usage of epsilons requires xlang desugaring"))
       case (e: LetVar) =>
         Set((e.getPos, "Mutable variables (e.g. 'var x' instead of 'val x') require xlang desugaring"))
-      case (e: Waypoint) =>
-        Set((e.getPos, "Usage of waypoints requires xlang desugaring"))
       case (e: ArrayUpdate) =>
         Set((e.getPos, "In-place updates of arrays require xlang desugaring"))
       case _ =>
diff --git a/src/main/scala/leon/xlang/XLangDesugaringPhase.scala b/src/main/scala/leon/xlang/XLangDesugaringPhase.scala
index 59dd3217714f964be5f9ff6a1428617c6e54e17a..54e298a226704a78fb99abc445e55df8895bc98f 100644
--- a/src/main/scala/leon/xlang/XLangDesugaringPhase.scala
+++ b/src/main/scala/leon/xlang/XLangDesugaringPhase.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package xlang
@@ -12,7 +12,6 @@ object XLangDesugaringPhase extends LeonPhase[Program, Program] {
 
   override def run(ctx: LeonContext, pgm: Program): (LeonContext, Program) = {
     val phases =
-      //ArrayTransformation andThen
       AntiAliasingPhase andThen
       EpsilonElimination andThen
       ImperativeCodeElimination
diff --git a/src/sphinx/xlang.rst b/src/sphinx/xlang.rst
index 3f88e3e26386064efd82ce4f881164b126d8309b..d2eace3b9120397fcc3bcad70ca79bc167593e23 100644
--- a/src/sphinx/xlang.rst
+++ b/src/sphinx/xlang.rst
@@ -39,35 +39,16 @@ The above example illustrates three new features introduced by XLang:
 3. Assignments
 
 You can use Scala variables with a few restrictions. The variables can only be
-declared and used locally in the same function, and inner functions cannot
-close over them. XLang introduces the possibility to use sequences of
-expressions (blocks) -- a feature not available in :ref:`Pure Scala
-<purescala>`, where you're only option is a sequence of ``val`` which
-essentially introduce nested ``let`` declarations.
-
-.. warning::
-   Be careful when combining variables with nested functions from PureScala. Leon
-   will reject code with nested functions accessing a variable from an outside scope:
-   
-   .. code-block::  scala
-
-      def foo(x: Int) = {
-        var a = 12
-        def bar(y: Int): Int = {
-          a = a + 1
-          a + y
-        }
-        bar(17)
-      }
-
-   The problem with such code is the complications involved in representing closures as
-   they need a pointer to an environment containing the variables. Leon is only able
-   to handle closures with ``val``, where it is sufficient to explicitly pass the values
-   as parameters.
+declared and used locally, no variable declaration outside of a function body.
+There is also support for variables in case classes constructors. XLang
+introduces the possibility to use sequences of expressions (blocks) -- a
+feature not available in :ref:`Pure Scala <purescala>`, where you're only
+option is a sequence of ``val`` which essentially introduce nested ``let``
+declarations.
 
 
 While loops 
-***********
+-----------
 
 You can use the ``while`` keyword. While loops usually combine the ability to
 declare variables and make a sequence of assignments in order to compute
@@ -123,7 +104,7 @@ verification condition is used to prove the invariant on initialization of the
 loop.
 
 Arrays
-******
+------
 
 PureScala supports functional arrays, that is, the operations ``apply`` and
 ``updated`` which do not modify an array but only returns some result. In
@@ -146,8 +127,7 @@ XLang adds the usual ``update`` operation on arrays:
    a(1) = 10
    a(1) //10
 
-There are some limitations with what you can do with arrays. Leon simply
-rewrite arrays using ``update`` operation as assignment of function arrays
+Leon simply rewrite arrays using ``update`` operation as assignment of function arrays
 using ``updated``.  This leverages the built-in algorithm for functional array
 and rely on the elimination procedure for assignments. Concretely, it would
 transform the above on the following equivalent implementation:
@@ -161,8 +141,91 @@ transform the above on the following equivalent implementation:
 
 Then Leon would apply the same process as for any other XLang program.
 
-Due to the way Leon handles side-effects, you cannot update arrays passed
-to a function as a parameter.
+Mutable Objects
+---------------
+
+A restricted form of mutable classes is supported via case classes with ``var``
+arguments:
+
+.. code-block:: scala
+
+   case class A(var x: Int)
+   def f(): Int = {
+     val a = new A(10)
+     a.x = 13
+     a.x
+   }
+
+Mutable case classes are behaving similarly to ``Array``, and are handled with a
+rewriting, where each field updates becomes essentially a copy of the object with
+the modified parameter changed.
+
+Aliasing
+--------
+
+With mutable data structures comes the problem of aliasing. In Leon, we
+maintain the invariant that in any scope, there is at most one pointer to some
+mutable structure. Leon will issue an error if you try to create an alias to
+some mutable structure in the same scope:
+
+.. code-block:: scala
+
+   val a = Array(1,2,3,4)
+   val b = a //error: illegal aliasing
+   b(0) = 10
+   assert(a(0) == 10)
+
+However, Leon correctly supports aliasing mutable structures when passing it
+as a parameter to a function (assuming its scope is not shared with the call
+site, i.e. not a nested function). Essentially you can do:
+
+.. code-block:: scala
+    
+   case class A(var x: Int)
+   def updateA(a: A): Unit = {
+     a.x = 14
+   }
+   def f(): Unit = {
+     val a = A(10)
+     updateA(a)
+     assert(a.x == 14)
+   }
+
+The function ``updateA`` will have the side effect of updating its argument
+``a`` and this will be visible at the call site.
+
+Annotations for Imperative Programming
+--------------------------------------
+
+XLang introduces the special function ``old`` that can be used in postconditions to
+talk about the value of a variable before the execution of the block. When you refer to a variable
+or mutable structure in a post-condition, leon will always consider the current value of
+the object, so that in the case of a post-condition this would refer to the final value of the
+object. Using ``old``, you can refer to the original value of the variable and check some
+properties:
+
+.. code-block:: scala
+   
+   case class A(var x: Int)
+   def inc(a: A): Unit = {
+     a.x = a.x + 1
+   } ensuring(_ => a.x == old(a).x + 1)
+
+``old`` can be wrapped around any identifier that is affected by the body. You can also use
+``old`` for variables in scope, in case of nested functions:
+
+.. code-block:: scala
+   
+   def f(): Int = {
+     var x = 0
+     def inc(): Unit = {
+       x = x + 1
+     } ensuring(_ => x == old(x) + 1)
+
+     inc(); inc();
+     assert(x == 2)
+   }
+
 
 Epsilon
 -------
diff --git a/src/test/resources/regression/frontends/error/simple/ArrayEquals1.scala b/src/test/resources/regression/frontends/error/simple/ArrayEquals1.scala
index 39a9c4b2be2fd3a581ee3209f0d83f16dc8e03b7..a0c3bd956eadb23512fc87597070dd7ca4fb65ba 100644
--- a/src/test/resources/regression/frontends/error/simple/ArrayEquals1.scala
+++ b/src/test/resources/regression/frontends/error/simple/ArrayEquals1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.lang._
 
 object ArrayEqual1 {
diff --git a/src/test/resources/regression/frontends/error/simple/ArrayEquals2.scala b/src/test/resources/regression/frontends/error/simple/ArrayEquals2.scala
index 2035e0d45c3cc8236009c5b70f0c0e2ac3b95124..15557c92b23f77780b803894aa5e7c9b90483f59 100644
--- a/src/test/resources/regression/frontends/error/simple/ArrayEquals2.scala
+++ b/src/test/resources/regression/frontends/error/simple/ArrayEquals2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.lang._
 
 object ArrayEqual2 {
diff --git a/src/test/resources/regression/frontends/error/simple/Asserts.scala b/src/test/resources/regression/frontends/error/simple/Asserts.scala
index 3540c98ddf25ee54132bf523a1d59774c085b100..c841a166cd17b0acda0be2273d70178e738c5cc3 100644
--- a/src/test/resources/regression/frontends/error/simple/Asserts.scala
+++ b/src/test/resources/regression/frontends/error/simple/Asserts.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/frontends/error/simple/ConvertBigInt.scala b/src/test/resources/regression/frontends/error/simple/ConvertBigInt.scala
index 65584270278e4aa2266d80be7252538a72d3e19b..b55bfc3f52bab931981fc1b8f811f01d2dd2b767 100644
--- a/src/test/resources/regression/frontends/error/simple/ConvertBigInt.scala
+++ b/src/test/resources/regression/frontends/error/simple/ConvertBigInt.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object ConvertBigInt {
 
diff --git a/src/test/resources/regression/frontends/error/simple/InstanceOf1.scala b/src/test/resources/regression/frontends/error/simple/InstanceOf1.scala
index d9cd815f2d1a8e6620a39d950782f9f3ed88bedd..3136bcc0ba8f59701c99d2695cc16777791148f6 100644
--- a/src/test/resources/regression/frontends/error/simple/InstanceOf1.scala
+++ b/src/test/resources/regression/frontends/error/simple/InstanceOf1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object InstanceOf1 {
 
diff --git a/src/test/resources/regression/frontends/error/simple/LiteralBigInt.scala b/src/test/resources/regression/frontends/error/simple/LiteralBigInt.scala
index e13bce4aa0dc9b4b17e59e23ebf64ae1921623d2..68c1232f409e281da9d2a91cda921227fb417e70 100644
--- a/src/test/resources/regression/frontends/error/simple/LiteralBigInt.scala
+++ b/src/test/resources/regression/frontends/error/simple/LiteralBigInt.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object LiteralBigInt {
 
diff --git a/src/test/resources/regression/frontends/error/simple/NotEquals.scala b/src/test/resources/regression/frontends/error/simple/NotEquals.scala
index 7a6d2f70129bddfe59340c5c28cc1b66ed33c749..497e7d553a72a331be14541c03db6ddd8cdec75c 100644
--- a/src/test/resources/regression/frontends/error/simple/NotEquals.scala
+++ b/src/test/resources/regression/frontends/error/simple/NotEquals.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object NotEquals {
 
diff --git a/src/test/resources/regression/frontends/passing/ClassFields.scala b/src/test/resources/regression/frontends/passing/ClassFields.scala
index eda170f5074ec93cb5fbe6a159fb4006feeda0d6..f9253cc99750395ecd93cd4352a1c0391f144bbf 100644
--- a/src/test/resources/regression/frontends/passing/ClassFields.scala
+++ b/src/test/resources/regression/frontends/passing/ClassFields.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object ClassFields {
diff --git a/src/test/resources/regression/frontends/passing/Fields.scala b/src/test/resources/regression/frontends/passing/Fields.scala
index 4cf067d63ff18c85b37016ea54a188c74f98d090..f6c83deb4ffb5c740c7859d80984b4ce1d81e8d0 100644
--- a/src/test/resources/regression/frontends/passing/Fields.scala
+++ b/src/test/resources/regression/frontends/passing/Fields.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/frontends/passing/ImplicitDefs.scala b/src/test/resources/regression/frontends/passing/ImplicitDefs.scala
index 74f6f2b880b626cd5f8a0e8a8fe9d4dfa7beb73a..848aeb42831eec68a3f2bd5a625294be92707668 100644
--- a/src/test/resources/regression/frontends/passing/ImplicitDefs.scala
+++ b/src/test/resources/regression/frontends/passing/ImplicitDefs.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import scala.language.implicitConversions
 
diff --git a/src/test/resources/regression/frontends/passing/ImplicitDefs2.scala b/src/test/resources/regression/frontends/passing/ImplicitDefs2.scala
index dba63890bd682f1d392cfe719ffd851b25dfd695..d9b07c4bad8ca087a59799782af6a119e98dded3 100644
--- a/src/test/resources/regression/frontends/passing/ImplicitDefs2.scala
+++ b/src/test/resources/regression/frontends/passing/ImplicitDefs2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.blup
 
 import leon._
diff --git a/src/test/resources/regression/frontends/passing/Operators.scala b/src/test/resources/regression/frontends/passing/Operators.scala
index a26b5c75b91a1b1776eb49d3fe97bd10f863380c..ac539056d20d87f64c7775e588e79e43bffe60ca 100644
--- a/src/test/resources/regression/frontends/passing/Operators.scala
+++ b/src/test/resources/regression/frontends/passing/Operators.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Operators {
   
diff --git a/src/test/resources/regression/frontends/passing/OptParams.scala b/src/test/resources/regression/frontends/passing/OptParams.scala
index 5e4334acff32214e8e701435e6ce562d4a0d2d38..567cb842d0a1c466f9cd40fb5cbdc3795c5a55a2 100644
--- a/src/test/resources/regression/frontends/passing/OptParams.scala
+++ b/src/test/resources/regression/frontends/passing/OptParams.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object OptParams {
 
diff --git a/src/test/resources/regression/frontends/passing/Overrides.scala b/src/test/resources/regression/frontends/passing/Overrides.scala
index c3be61be2482367e28a2d54c49cd7c7c1a54e6ab..38342ce6ae266c61c97cbeff7a08c71cacbb0239 100644
--- a/src/test/resources/regression/frontends/passing/Overrides.scala
+++ b/src/test/resources/regression/frontends/passing/Overrides.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Overrides {
 
   abstract class A[T] {
diff --git a/src/test/resources/regression/frontends/passing/bigintExtr.scala b/src/test/resources/regression/frontends/passing/bigintExtr.scala
index 983bd750e44604aefc3eb171c5cfac666a2ba23f..349b75ec305b9e07908d7a0dcd563b1cb2a98ed1 100644
--- a/src/test/resources/regression/frontends/passing/bigintExtr.scala
+++ b/src/test/resources/regression/frontends/passing/bigintExtr.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 
diff --git a/src/test/resources/regression/genc/invalid/AbsFun.scala b/src/test/resources/regression/genc/invalid/AbsFun.scala
index aff9a2c80f70f5e3aef079220c1c36b29b40b2e3..db7a92312b6ddb52ade465a0b3d03cec6da24805 100644
--- a/src/test/resources/regression/genc/invalid/AbsFun.scala
+++ b/src/test/resources/regression/genc/invalid/AbsFun.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object AbsFun {
diff --git a/src/test/resources/regression/genc/invalid/LinearSearch.scala b/src/test/resources/regression/genc/invalid/LinearSearch.scala
index 88cadb0ef7dc5ca5425a3f1661495cb08af4df65..60e5befe7eba9071cc869799ca488130d3575a11 100644
--- a/src/test/resources/regression/genc/invalid/LinearSearch.scala
+++ b/src/test/resources/regression/genc/invalid/LinearSearch.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 /* The calculus of Computation textbook */
diff --git a/src/test/resources/regression/genc/unverified/BinarySearch.scala b/src/test/resources/regression/genc/unverified/BinarySearch.scala
index aec7d2b5ddabc0132d6f9e885eb18c80617f7dc9..666b98c4e621099bfa9b8ef23485b9764522034b 100644
--- a/src/test/resources/regression/genc/unverified/BinarySearch.scala
+++ b/src/test/resources/regression/genc/unverified/BinarySearch.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 /* VSTTE 2008 - Dafny paper */
diff --git a/src/test/resources/regression/genc/unverified/BinarySearchFun.scala b/src/test/resources/regression/genc/unverified/BinarySearchFun.scala
index ebc97f6c6d046e2907bda89c795def7026cb4c8f..2e9e95760ccfb213d5f81db13f31a3fd234f45df 100644
--- a/src/test/resources/regression/genc/unverified/BinarySearchFun.scala
+++ b/src/test/resources/regression/genc/unverified/BinarySearchFun.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object BinarySearchFun {
diff --git a/src/test/resources/regression/genc/unverified/MaxSum.scala b/src/test/resources/regression/genc/unverified/MaxSum.scala
index 033dfed30a6930f4041c60a1c4f8a9dfbb87d934..ce1072948c737555ee78c46ee830372e8f4a8514 100644
--- a/src/test/resources/regression/genc/unverified/MaxSum.scala
+++ b/src/test/resources/regression/genc/unverified/MaxSum.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 /* VSTTE 2010 challenge 1 */
diff --git a/src/test/resources/regression/genc/valid/AbsArray.scala b/src/test/resources/regression/genc/valid/AbsArray.scala
index 581684e7c50d6034e751c152be9afd185e227e73..a7f25b3bb831ce808d0e97516486aed1d050bfd7 100644
--- a/src/test/resources/regression/genc/valid/AbsArray.scala
+++ b/src/test/resources/regression/genc/valid/AbsArray.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object AbsArray {
diff --git a/src/test/resources/regression/genc/valid/CaseClass.scala b/src/test/resources/regression/genc/valid/CaseClass.scala
index 83f5988594336f12e67ca63980334a747fcadbb2..4731fca052e3771c6f8a5b8fe3f0f7e2a8db4b80 100644
--- a/src/test/resources/regression/genc/valid/CaseClass.scala
+++ b/src/test/resources/regression/genc/valid/CaseClass.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object CaseClass {
diff --git a/src/test/resources/regression/genc/valid/ExpressionOrder.scala b/src/test/resources/regression/genc/valid/ExpressionOrder.scala
index 21ea9766dffad887414d56fb3c281934ea429f1d..ec81d038a8a1ee8797e7fa09252dc05871e77c59 100644
--- a/src/test/resources/regression/genc/valid/ExpressionOrder.scala
+++ b/src/test/resources/regression/genc/valid/ExpressionOrder.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object ExpressionOrder {
diff --git a/src/test/resources/regression/genc/valid/IntegralColor.scala b/src/test/resources/regression/genc/valid/IntegralColor.scala
index c64cb0fa18ac395dad37b2a8a8ffa7fa187872a2..8c42a620e42d12b6daf85625239dc9074ba67868 100644
--- a/src/test/resources/regression/genc/valid/IntegralColor.scala
+++ b/src/test/resources/regression/genc/valid/IntegralColor.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object IntegralColor {
diff --git a/src/test/resources/regression/genc/valid/RecursionAndNestedFunctions.scala b/src/test/resources/regression/genc/valid/RecursionAndNestedFunctions.scala
index 25f69538a19412bd8ae8267446d4eb5f05f6247b..0202fae1eaea30d0a550a4a9679e5d6b6f5b8902 100644
--- a/src/test/resources/regression/genc/valid/RecursionAndNestedFunctions.scala
+++ b/src/test/resources/regression/genc/valid/RecursionAndNestedFunctions.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object RecursionAndNestedFunctions {
diff --git a/src/test/resources/regression/genc/valid/TupleArray.scala b/src/test/resources/regression/genc/valid/TupleArray.scala
index 1f2354e0613430fb95a995da6a741dda3939b143..c5ad57f1bb43ec9a42fc09a69895d5461994c20e 100644
--- a/src/test/resources/regression/genc/valid/TupleArray.scala
+++ b/src/test/resources/regression/genc/valid/TupleArray.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object TupleArray {
diff --git a/src/test/resources/regression/orb/combined/InsertionSort.scala b/src/test/resources/regression/orb/combined/InsertionSort.scala
index 8fd79a2e89f60441fd522584fae4197079f9294e..8f0d34367af1e60a78e20e20e6f8bf271f98aaf7 100644
--- a/src/test/resources/regression/orb/combined/InsertionSort.scala
+++ b/src/test/resources/regression/orb/combined/InsertionSort.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 import leon.instrumentation._
 
diff --git a/src/test/resources/regression/orb/depth/BinaryTrie.scala b/src/test/resources/regression/orb/depth/BinaryTrie.scala
old mode 100755
new mode 100644
index 562ab19ea8913551bafd45e429ec28c98cbee064..c71939f3b1bacb7c2ab1d735082d7236cfa6f22f
--- a/src/test/resources/regression/orb/depth/BinaryTrie.scala
+++ b/src/test/resources/regression/orb/depth/BinaryTrie.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.instrumentation._
 import leon.invariant._
 
diff --git a/src/test/resources/regression/orb/depth/Folds.scala b/src/test/resources/regression/orb/depth/Folds.scala
old mode 100755
new mode 100644
index 305446be53b27c976080968b881119ce06de11e6..b80235514595a6d08fbaff427493a434d5e32749
--- a/src/test/resources/regression/orb/depth/Folds.scala
+++ b/src/test/resources/regression/orb/depth/Folds.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.instrumentation._
 import leon.invariant._
 
diff --git a/src/test/resources/regression/orb/depth/ListOperations.scala b/src/test/resources/regression/orb/depth/ListOperations.scala
index 7d77ba83435f1e5d72951f1c8e0cd72ad8adbb7f..b9c9418de08ff0fa4d5b740d71d825aade3129dc 100644
--- a/src/test/resources/regression/orb/depth/ListOperations.scala
+++ b/src/test/resources/regression/orb/depth/ListOperations.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.instrumentation._
 import leon.invariant._
 import leon.annotation._
diff --git a/src/test/resources/regression/orb/depth/PropLogicDepth.scala b/src/test/resources/regression/orb/depth/PropLogicDepth.scala
index 881cd61a4b31ad2b40ab22b84651f4362e00878c..8470737ba091be527a12d9cbf7f0a71e12e78475 100644
--- a/src/test/resources/regression/orb/depth/PropLogicDepth.scala
+++ b/src/test/resources/regression/orb/depth/PropLogicDepth.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import scala.collection.immutable.Set
 import leon.instrumentation._
 import leon.invariant._
diff --git a/src/test/resources/regression/orb/numerical/ConcatVariationsAbs.scala b/src/test/resources/regression/orb/numerical/ConcatVariationsAbs.scala
index bff880ab30ac1495c7ab6c706265376f1fafe7ad..4c8c16722378c8f1e44aa3148aa83cbb33abdea3 100644
--- a/src/test/resources/regression/orb/numerical/ConcatVariationsAbs.scala
+++ b/src/test/resources/regression/orb/numerical/ConcatVariationsAbs.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 
 object ConcatVariationsAbs {
diff --git a/src/test/resources/regression/orb/numerical/QueueAbs.scala b/src/test/resources/regression/orb/numerical/QueueAbs.scala
index a7aee3a93d4ca9ee058b2f0695f001d29fdf3acc..caaae2d1df0174a965cdc70480c1a83e088a4aa2 100644
--- a/src/test/resources/regression/orb/numerical/QueueAbs.scala
+++ b/src/test/resources/regression/orb/numerical/QueueAbs.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 
 object AmortizedQueue {
diff --git a/src/test/resources/regression/orb/numerical/SimpleLoop.scala b/src/test/resources/regression/orb/numerical/SimpleLoop.scala
old mode 100755
new mode 100644
index 6a2cdb3d9958f5ad41783d3723b1c08ef7c0ba16..741d242bbf980de4848b5c461e291be37f0f650b
--- a/src/test/resources/regression/orb/numerical/SimpleLoop.scala
+++ b/src/test/resources/regression/orb/numerical/SimpleLoop.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object SimpleLoop
 {
 	def s(x: BigInt) : BigInt = {
diff --git a/src/test/resources/regression/orb/numerical/see-saw.scala b/src/test/resources/regression/orb/numerical/see-saw.scala
index 894a8caed2a298a22a89d8bb6925cc03f022407c..fe3c8dc6318633d7e8035620d8c2fce03bf9c487 100644
--- a/src/test/resources/regression/orb/numerical/see-saw.scala
+++ b/src/test/resources/regression/orb/numerical/see-saw.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object SeeSaw {
   def s(x: BigInt, y: BigInt, z: BigInt): BigInt = {
     require(y >= 0)
diff --git a/src/test/resources/regression/orb/stack/BinaryTrie.scala b/src/test/resources/regression/orb/stack/BinaryTrie.scala
index f2dfd876cdbc51c969f4afc7d1548810be111c02..21b7e7c895c64242e86981dfda72cf2abb13441c 100644
--- a/src/test/resources/regression/orb/stack/BinaryTrie.scala
+++ b/src/test/resources/regression/orb/stack/BinaryTrie.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 import leon.instrumentation._
 //import scala.collection.immutable.Set
diff --git a/src/test/resources/regression/orb/stack/ListOperations.scala b/src/test/resources/regression/orb/stack/ListOperations.scala
index 3ae4a2d1705051b185c444c7342bf9b180fc4086..7323f1a3e0ffe2b1c1c0d5b1d46cab915a8a1759 100644
--- a/src/test/resources/regression/orb/stack/ListOperations.scala
+++ b/src/test/resources/regression/orb/stack/ListOperations.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 import leon.instrumentation._
 
diff --git a/src/test/resources/regression/orb/stack/SpeedBenchmarks.scala b/src/test/resources/regression/orb/stack/SpeedBenchmarks.scala
index c1c59d592b2b0b59cfe79b780aaca479fcbb222d..8a65f13812fc0edc59528a6e63823a11512a7dc9 100644
--- a/src/test/resources/regression/orb/stack/SpeedBenchmarks.scala
+++ b/src/test/resources/regression/orb/stack/SpeedBenchmarks.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 import leon.instrumentation._
 import leon.math._
diff --git a/src/test/resources/regression/orb/timing/BinaryTrie.scala b/src/test/resources/regression/orb/timing/BinaryTrie.scala
index a1de6ee0e13bb53383b1bba6548e9e0fa449a166..431551014df1c9130d376065413324462523b2a1 100644
--- a/src/test/resources/regression/orb/timing/BinaryTrie.scala
+++ b/src/test/resources/regression/orb/timing/BinaryTrie.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 import leon.instrumentation._
 
diff --git a/src/test/resources/regression/orb/timing/ConcatVariations.scala b/src/test/resources/regression/orb/timing/ConcatVariations.scala
index a94fb418a48db5b27ab88cfbbe84a59233f394b0..519cef287a7c9b4d8d58a4b75817301ea6391dd1 100644
--- a/src/test/resources/regression/orb/timing/ConcatVariations.scala
+++ b/src/test/resources/regression/orb/timing/ConcatVariations.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 import leon.instrumentation._
 
diff --git a/src/test/resources/regression/orb/timing/ListOperations.scala b/src/test/resources/regression/orb/timing/ListOperations.scala
index 13b031b4da2cb89e5e2557af107a5757fef1e7f4..e4c486dcdd76fd281f21d602243d3a64b25330b3 100644
--- a/src/test/resources/regression/orb/timing/ListOperations.scala
+++ b/src/test/resources/regression/orb/timing/ListOperations.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.invariant._
 import leon.instrumentation._
 
diff --git a/src/test/resources/regression/orb/timing/PropositionalLogic.scala b/src/test/resources/regression/orb/timing/PropositionalLogic.scala
index 22dfdcdec06cef0760222140d669d11ae134a658..e7ed2b10a82fbe770d7d5734e015d30440d59b2f 100644
--- a/src/test/resources/regression/orb/timing/PropositionalLogic.scala
+++ b/src/test/resources/regression/orb/timing/PropositionalLogic.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import scala.collection.immutable.Set
 import leon.invariant._
 import leon.instrumentation._
diff --git a/src/test/resources/regression/orb/timing/SimpleMap.scala b/src/test/resources/regression/orb/timing/SimpleMap.scala
index 86e2c7b7b23d2b262379c34ecc78f6b5736086ca..3b347be92167b43bfa7d215303f4b8d40ae5f584 100644
--- a/src/test/resources/regression/orb/timing/SimpleMap.scala
+++ b/src/test/resources/regression/orb/timing/SimpleMap.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.instrumentation._
 import leon.invariant._
 
diff --git a/src/test/resources/regression/performance/cegis/Add.scala b/src/test/resources/regression/performance/cegis/Add.scala
index 5931eeb591cf61567d285e68fee9bb49f7c19c07..81cde689f4f14a6915a1deca21a3da09f03208ed 100644
--- a/src/test/resources/regression/performance/cegis/Add.scala
+++ b/src/test/resources/regression/performance/cegis/Add.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/performance/cegis/Distinct.scala b/src/test/resources/regression/performance/cegis/Distinct.scala
index a6fb4881c471d936e3627dcc7dd42e1189bdb89c..e47af67df2dbf4b6287d66f711ad0916af552e49 100644
--- a/src/test/resources/regression/performance/cegis/Distinct.scala
+++ b/src/test/resources/regression/performance/cegis/Distinct.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/performance/cegis/Hole1.scala b/src/test/resources/regression/performance/cegis/Hole1.scala
index 354dcb72cefbaa8dd9fb30c4fb10045346c98b96..ce983abae037c19a9fdf57f23d2da612d15269d0 100644
--- a/src/test/resources/regression/performance/cegis/Hole1.scala
+++ b/src/test/resources/regression/performance/cegis/Hole1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.collection._
diff --git a/src/test/resources/regression/performance/cegis/Length.scala b/src/test/resources/regression/performance/cegis/Length.scala
index 2e38e0a1898f67a8bea01a4be5c674943a13dc8c..04462a0b877f2a92bbaa23a88281455e060671bf 100644
--- a/src/test/resources/regression/performance/cegis/Length.scala
+++ b/src/test/resources/regression/performance/cegis/Length.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.collection._
 import leon.lang._
diff --git a/src/test/resources/regression/performance/cegis/Mult.scala b/src/test/resources/regression/performance/cegis/Mult.scala
index 9f8f422c689d741bf076605615e3f8cdf3039354..3b3b9b80da7904b9af7694f0e2354109586056b9 100644
--- a/src/test/resources/regression/performance/cegis/Mult.scala
+++ b/src/test/resources/regression/performance/cegis/Mult.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/performance/cegis/Squared.scala b/src/test/resources/regression/performance/cegis/Squared.scala
index 5d7877469d3cf5015b703e179fde86b8a6a234ea..1e2e6d27de60bb1d1fa0e6cea73e37f4b861f2f4 100644
--- a/src/test/resources/regression/performance/cegis/Squared.scala
+++ b/src/test/resources/regression/performance/cegis/Squared.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/repair/Compiler1.scala b/src/test/resources/regression/repair/Compiler1.scala
index 300868d67463da6ae3690b719c0bb7a74eae5b1b..ffd0bdaee24a0b1f4c32b820bab023f49539e975 100644
--- a/src/test/resources/regression/repair/Compiler1.scala
+++ b/src/test/resources/regression/repair/Compiler1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/repair/Heap3.scala b/src/test/resources/regression/repair/Heap3.scala
index 3305b5d15a0731bd3aeaa1269c2404807f49a266..7d788a3a082ee28f3b7d746003970ea8497bf83f 100644
--- a/src/test/resources/regression/repair/Heap3.scala
+++ b/src/test/resources/regression/repair/Heap3.scala
@@ -1,6 +1,6 @@
-/* Copyright 2009-2015 EPFL, Lausanne
- *
- * Author: Ravi
+/* Copyright 2009-2016 EPFL, Lausanne */
+ 
+/** Author: Ravi
  * Date: 20.11.2013
  **/
 
diff --git a/src/test/resources/regression/repair/Heap4.scala b/src/test/resources/regression/repair/Heap4.scala
index 937e29b5c41eadbc1939c7a7d8febb2956e026d0..ad09821eebde5471f3b663967178ba8251992ebf 100644
--- a/src/test/resources/regression/repair/Heap4.scala
+++ b/src/test/resources/regression/repair/Heap4.scala
@@ -1,7 +1,8 @@
-/* Copyright 2009-2015 EPFL, Lausanne
- * Author: Ravi
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+/* Author: Ravi
  * Date: 20.11.2013
- **/
+ */
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/repair/List1.scala b/src/test/resources/regression/repair/List1.scala
index 79b7ecb444be464b464202721dbebd0b4045c158..4031f652fe3c38c3ba5d0ca8993a0aacd24a91a4 100644
--- a/src/test/resources/regression/repair/List1.scala
+++ b/src/test/resources/regression/repair/List1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.custom
 
diff --git a/src/test/resources/regression/repair/ListEasy.scala b/src/test/resources/regression/repair/ListEasy.scala
index 13590231cf814df69eae69222ee458022c6fab8a..d22286dce124b611bd11e9c490a33c9afe87e75d 100644
--- a/src/test/resources/regression/repair/ListEasy.scala
+++ b/src/test/resources/regression/repair/ListEasy.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.custom
 
diff --git a/src/test/resources/regression/repair/MergeSort2.scala b/src/test/resources/regression/repair/MergeSort2.scala
index 4447edc40430d87690516ea86020095cb2727243..9435d1e3164baea46820779a3c3654ddae11345c 100644
--- a/src/test/resources/regression/repair/MergeSort2.scala
+++ b/src/test/resources/regression/repair/MergeSort2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.collection._
diff --git a/src/test/resources/regression/synthesis/Church/Add.scala b/src/test/resources/regression/synthesis/Church/Add.scala
index c94fc4c7f1cb29e2a1fb49d4b134bb163c5b69eb..460e1651e37fc66fe4752d3d2c6e38b87184be3d 100644
--- a/src/test/resources/regression/synthesis/Church/Add.scala
+++ b/src/test/resources/regression/synthesis/Church/Add.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/Church/Distinct.scala b/src/test/resources/regression/synthesis/Church/Distinct.scala
index b7f093e9f752adbee5ccc9f8833a34d71011022a..53379f02cbb42f2fa727f850b41f97c0b9c9bc79 100644
--- a/src/test/resources/regression/synthesis/Church/Distinct.scala
+++ b/src/test/resources/regression/synthesis/Church/Distinct.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/Church/Mult.scala b/src/test/resources/regression/synthesis/Church/Mult.scala
index bc4afe213fa9af7ac3174e11325e4bcbd29b8e20..6c8e0f088d34373832ff5ce3462f15e2182cb044 100644
--- a/src/test/resources/regression/synthesis/Church/Mult.scala
+++ b/src/test/resources/regression/synthesis/Church/Mult.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/Church/Squared.scala b/src/test/resources/regression/synthesis/Church/Squared.scala
index 92ac747b8fbe26afe008d1796dbd3ce5743b3a35..9c7f042332a035a4a684fb299e215deebc7b1680 100644
--- a/src/test/resources/regression/synthesis/Church/Squared.scala
+++ b/src/test/resources/regression/synthesis/Church/Squared.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/Examples/Length.scala b/src/test/resources/regression/synthesis/Examples/Length.scala
index 2e38e0a1898f67a8bea01a4be5c674943a13dc8c..04462a0b877f2a92bbaa23a88281455e060671bf 100644
--- a/src/test/resources/regression/synthesis/Examples/Length.scala
+++ b/src/test/resources/regression/synthesis/Examples/Length.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.collection._
 import leon.lang._
diff --git a/src/test/resources/regression/synthesis/Holes/Hole1.scala b/src/test/resources/regression/synthesis/Holes/Hole1.scala
index 354dcb72cefbaa8dd9fb30c4fb10045346c98b96..ce983abae037c19a9fdf57f23d2da612d15269d0 100644
--- a/src/test/resources/regression/synthesis/Holes/Hole1.scala
+++ b/src/test/resources/regression/synthesis/Holes/Hole1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.collection._
diff --git a/src/test/resources/regression/synthesis/List/Delete.scala b/src/test/resources/regression/synthesis/List/Delete.scala
index 0c82b3da420c405a86c6467e75070bb5761dca1b..15d6163694f3f2759de218b92119e6a5109f4458 100644
--- a/src/test/resources/regression/synthesis/List/Delete.scala
+++ b/src/test/resources/regression/synthesis/List/Delete.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/List/Diff.scala b/src/test/resources/regression/synthesis/List/Diff.scala
index 477ea0bdb32ea47b559815c3a39f3e20f6aadc93..2e1136aeaf74d216be3a097306a352ffd5665501 100644
--- a/src/test/resources/regression/synthesis/List/Diff.scala
+++ b/src/test/resources/regression/synthesis/List/Diff.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/List/Insert.scala b/src/test/resources/regression/synthesis/List/Insert.scala
index c98947bb1afaa8ce8038fb5aa184bf8f394b5bd9..831fa6815a4e3b041305479f0744d2e7d7361db1 100644
--- a/src/test/resources/regression/synthesis/List/Insert.scala
+++ b/src/test/resources/regression/synthesis/List/Insert.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/List/Split1.scala b/src/test/resources/regression/synthesis/List/Split1.scala
index 66def0ffa2a6980c7416bc18f5d6882d0c55c255..91b089a36e5e2a66899eeb1a5b533d07a9f08409 100644
--- a/src/test/resources/regression/synthesis/List/Split1.scala
+++ b/src/test/resources/regression/synthesis/List/Split1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/List/Split2.scala b/src/test/resources/regression/synthesis/List/Split2.scala
index 5d66b4a59da65f3bed57867f7a00b2465c92fe71..1bcfacd85f52ddc21231339e0c86b67ef3f44c35 100644
--- a/src/test/resources/regression/synthesis/List/Split2.scala
+++ b/src/test/resources/regression/synthesis/List/Split2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/List/Split3.scala b/src/test/resources/regression/synthesis/List/Split3.scala
index eca76884d352aeb72eb2af2cd098b0d6166a2a0a..35fe12e7e045fa21733d16c53f45e939b3fdc2b4 100644
--- a/src/test/resources/regression/synthesis/List/Split3.scala
+++ b/src/test/resources/regression/synthesis/List/Split3.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/List/Union.scala b/src/test/resources/regression/synthesis/List/Union.scala
index c36a5933c81393b5ab21bf3b9c463943b9f45e3c..8c4a4e71d21d1ab3dfb70024abd7ee5411d8b57b 100644
--- a/src/test/resources/regression/synthesis/List/Union.scala
+++ b/src/test/resources/regression/synthesis/List/Union.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/synthesis/Misc/HolesBug.scala b/src/test/resources/regression/synthesis/Misc/HolesBug.scala
index 47db91b9909f4a2f5f892cafb47394aeffff7ce0..4a7ccb5680a1a9b1dd3a618e1e427c38a32a9aa9 100644
--- a/src/test/resources/regression/synthesis/Misc/HolesBug.scala
+++ b/src/test/resources/regression/synthesis/Misc/HolesBug.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/Misc/Unapply.scala b/src/test/resources/regression/synthesis/Misc/Unapply.scala
index 0489202c0c195517cc1d6b97f2e794b53da9dd2e..f7f2c232d390a03f2d60e09ea0f3ae6408e7c148 100644
--- a/src/test/resources/regression/synthesis/Misc/Unapply.scala
+++ b/src/test/resources/regression/synthesis/Misc/Unapply.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._ 
 import leon.lang.synthesis._
 
diff --git a/src/test/resources/regression/synthesis/SortedList/Delete.scala b/src/test/resources/regression/synthesis/SortedList/Delete.scala
index 31305ca094ec78fa6896985fad04729879839baf..ca2886154cd1501e972bb24bc481e045bd8e0c12 100644
--- a/src/test/resources/regression/synthesis/SortedList/Delete.scala
+++ b/src/test/resources/regression/synthesis/SortedList/Delete.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/SortedList/Diff.scala b/src/test/resources/regression/synthesis/SortedList/Diff.scala
index 9e4e32baeebb42ca25bd4dfec41e7b0303c80f53..99813b1971717aec406853e95edb7157023f3712 100644
--- a/src/test/resources/regression/synthesis/SortedList/Diff.scala
+++ b/src/test/resources/regression/synthesis/SortedList/Diff.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/SortedList/Insert1.scala b/src/test/resources/regression/synthesis/SortedList/Insert1.scala
index affc5b45512a0383b49d11ca2c008df3d28b8d06..3aac75ecde19dcfcfe314a90421a88abd7d9e588 100644
--- a/src/test/resources/regression/synthesis/SortedList/Insert1.scala
+++ b/src/test/resources/regression/synthesis/SortedList/Insert1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/SortedList/Insert2.scala b/src/test/resources/regression/synthesis/SortedList/Insert2.scala
index e44eac286849ac69c19991168398ffad67726f5d..7327dafaf0c247bbd2ec345d4219aa606bfdc310 100644
--- a/src/test/resources/regression/synthesis/SortedList/Insert2.scala
+++ b/src/test/resources/regression/synthesis/SortedList/Insert2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/SortedList/InsertSort.scala b/src/test/resources/regression/synthesis/SortedList/InsertSort.scala
index 8f5b78247b9877952f9a7e17cdf507f424d16b05..4e319f35773e9c93869277fd3b0c1bc1bdc6111c 100644
--- a/src/test/resources/regression/synthesis/SortedList/InsertSort.scala
+++ b/src/test/resources/regression/synthesis/SortedList/InsertSort.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/SortedList/Union.scala b/src/test/resources/regression/synthesis/SortedList/Union.scala
index 95d17bb61bb48927a2d189ccecf1b7330b4bb46e..7df087b857e8ae3c2a99e130bc95bf6d1f8046c9 100644
--- a/src/test/resources/regression/synthesis/SortedList/Union.scala
+++ b/src/test/resources/regression/synthesis/SortedList/Union.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/StrictSortedList/Delete.scala b/src/test/resources/regression/synthesis/StrictSortedList/Delete.scala
index 81827ed03b80beddf664e2b0c2beb62a43dad078..6e75398bfc53cf911cf20665bb47f2f76111732e 100644
--- a/src/test/resources/regression/synthesis/StrictSortedList/Delete.scala
+++ b/src/test/resources/regression/synthesis/StrictSortedList/Delete.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/StrictSortedList/Insert.scala b/src/test/resources/regression/synthesis/StrictSortedList/Insert.scala
index 6c7543ad3847671bfc8657dc5c99e2bbd236ed93..4f9e644f8a83813d46e44e68373a9409a4e791ff 100644
--- a/src/test/resources/regression/synthesis/StrictSortedList/Insert.scala
+++ b/src/test/resources/regression/synthesis/StrictSortedList/Insert.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/synthesis/StrictSortedList/Union.scala b/src/test/resources/regression/synthesis/StrictSortedList/Union.scala
index cf2fcd727323d6b5c705522f3d37b884bdfd896d..3765c92eb096d0463b262ad0aab5ce97897c6f92 100644
--- a/src/test/resources/regression/synthesis/StrictSortedList/Union.scala
+++ b/src/test/resources/regression/synthesis/StrictSortedList/Union.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.annotation._
diff --git a/src/test/resources/regression/termination/looping/LambdaCalculus.scala b/src/test/resources/regression/termination/looping/LambdaCalculus.scala
index d24d8c31b998dc0226827f832409b685e3a1f47d..16026eed830a1eff0e2ec0b581d24c0e041cfb0b 100644
--- a/src/test/resources/regression/termination/looping/LambdaCalculus.scala
+++ b/src/test/resources/regression/termination/looping/LambdaCalculus.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/termination/looping/Numeric1.scala b/src/test/resources/regression/termination/looping/Numeric1.scala
index 877015620dbef1f7751f3602cc51e383b479eb08..aa5ecb6781cd92fb839d7628c045c486364b78ce 100644
--- a/src/test/resources/regression/termination/looping/Numeric1.scala
+++ b/src/test/resources/regression/termination/looping/Numeric1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/termination/looping/Numeric2.scala b/src/test/resources/regression/termination/looping/Numeric2.scala
index 4942b84563a40d9345726cf94b0273dd9da11eb9..0ce10f19818fe5f3b5878b42d83b86a4bd88b297 100644
--- a/src/test/resources/regression/termination/looping/Numeric2.scala
+++ b/src/test/resources/regression/termination/looping/Numeric2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/termination/looping/Numeric3.scala b/src/test/resources/regression/termination/looping/Numeric3.scala
index d093b3163632dbf386cbcccedf631169c3bfc616..adf5dbea6cac2f53771fed4633a5ae59a15b1c8f 100644
--- a/src/test/resources/regression/termination/looping/Numeric3.scala
+++ b/src/test/resources/regression/termination/looping/Numeric3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/termination/looping/OddEven.scala b/src/test/resources/regression/termination/looping/OddEven.scala
index 078b4c25834c8fc3a348f71771d6c21deb9698c1..1a2497777b389d881879f4cfe0e79715abdd7249 100644
--- a/src/test/resources/regression/termination/looping/OddEven.scala
+++ b/src/test/resources/regression/termination/looping/OddEven.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 object Test {
 
diff --git a/src/test/resources/regression/termination/looping/Queue.scala b/src/test/resources/regression/termination/looping/Queue.scala
index 3df1a9ac5a69ca639a88a335b70a260e6d7df8a5..7685817f075f330062c2dfb6deb503ebc9ecd258 100644
--- a/src/test/resources/regression/termination/looping/Queue.scala
+++ b/src/test/resources/regression/termination/looping/Queue.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/termination/looping/Termination_failling1.scala b/src/test/resources/regression/termination/looping/Termination_failling1.scala
index a901a791b46378339e819e0ed9b8e775da2b21bf..ecadd0e62ad62dad9cac6e5693d25e6857f79cae 100644
--- a/src/test/resources/regression/termination/looping/Termination_failling1.scala
+++ b/src/test/resources/regression/termination/looping/Termination_failling1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/termination/looping/UniversalEquality.scala b/src/test/resources/regression/termination/looping/UniversalEquality.scala
index 7b7181a6f3d90105d2a1c93603d86e32e025cdc5..15d8ec7e9c9bc3345e4ceb9e66bc4385cfc075e5 100644
--- a/src/test/resources/regression/termination/looping/UniversalEquality.scala
+++ b/src/test/resources/regression/termination/looping/UniversalEquality.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/termination/looping/WrongFibonacci.scala b/src/test/resources/regression/termination/looping/WrongFibonacci.scala
index 9911ee76dcdd83878b19a042bb9db44737848fb9..7e9b4938bd2ff018c49aae301c09e492bd86f52f 100644
--- a/src/test/resources/regression/termination/looping/WrongFibonacci.scala
+++ b/src/test/resources/regression/termination/looping/WrongFibonacci.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 object Test {
   
diff --git a/src/test/resources/regression/termination/valid/CountTowardsZero.scala b/src/test/resources/regression/termination/valid/CountTowardsZero.scala
index e0ce187ad4fddcd8b2aac5f973ba50fc1d589fb6..46163dbd0fd2bbb42805b9cf8989eb29d11585b5 100644
--- a/src/test/resources/regression/termination/valid/CountTowardsZero.scala
+++ b/src/test/resources/regression/termination/valid/CountTowardsZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 object Test {
   def f(x: BigInt): BigInt = {
diff --git a/src/test/resources/regression/termination/valid/Fibonacci.scala b/src/test/resources/regression/termination/valid/Fibonacci.scala
index dfa133e6bc73dbd2a47e28734afd9683929ebec6..8ea5571565a071b8d7646ed35aa0d15a7db046fe 100644
--- a/src/test/resources/regression/termination/valid/Fibonacci.scala
+++ b/src/test/resources/regression/termination/valid/Fibonacci.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Fibonacci {
   def fib(x: BigInt) : BigInt = {
diff --git a/src/test/resources/regression/termination/valid/HOTermination.scala b/src/test/resources/regression/termination/valid/HOTermination.scala
index da05e5ba83f64d29856339610b62ca0281e8189e..8947a89ca7aebf72027ce925ca488e2503ad4575 100644
--- a/src/test/resources/regression/termination/valid/HOTermination.scala
+++ b/src/test/resources/regression/termination/valid/HOTermination.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 
 import leon.lang._
diff --git a/src/test/resources/regression/termination/valid/ListWithSize.scala b/src/test/resources/regression/termination/valid/ListWithSize.scala
index af8aafeb8d5f669f8daf7fbc9b8c3abc69fd6f3e..b432e65542d73614888710b4f28a6d95dc343bbe 100644
--- a/src/test/resources/regression/termination/valid/ListWithSize.scala
+++ b/src/test/resources/regression/termination/valid/ListWithSize.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/termination/valid/NNF.scala b/src/test/resources/regression/termination/valid/NNF.scala
index 455cef7ec5201fd17edee71059dc38c9d7afa3d8..32ecd1916f33e3eec5fbcd52a9de2c2342792565 100644
--- a/src/test/resources/regression/termination/valid/NNF.scala
+++ b/src/test/resources/regression/termination/valid/NNF.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.annotation._
 
diff --git a/src/test/resources/regression/termination/valid/Numeric1.scala b/src/test/resources/regression/termination/valid/Numeric1.scala
index 60a9f841b5ebffc49a01c2d009cb758070d2ba1e..684aeb4035cc7552665e1743c71566a061f58a1d 100644
--- a/src/test/resources/regression/termination/valid/Numeric1.scala
+++ b/src/test/resources/regression/termination/valid/Numeric1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/termination/valid/Queue.scala b/src/test/resources/regression/termination/valid/Queue.scala
index dee019a41f27c7fca1f3e2cc7011ac544e18a541..742bc19824de9f7885d74a37676df7915be6d568 100644
--- a/src/test/resources/regression/termination/valid/Queue.scala
+++ b/src/test/resources/regression/termination/valid/Queue.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/termination/valid/QuickSort.scala b/src/test/resources/regression/termination/valid/QuickSort.scala
index d4fb11ea68a7e8c96f056754c24be2e9a5f9ef4e..ca3396ab83b0fb3f605eb5bde6c6528f31e6998e 100644
--- a/src/test/resources/regression/termination/valid/QuickSort.scala
+++ b/src/test/resources/regression/termination/valid/QuickSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/termination/valid/RedBlackTree.scala b/src/test/resources/regression/termination/valid/RedBlackTree.scala
index 2d48a25e0dee87ac6f94563e3b28cb48ca8eb567..9990cdc09f2a5880ba80d5a11bdf3174bdce3d2e 100644
--- a/src/test/resources/regression/termination/valid/RedBlackTree.scala
+++ b/src/test/resources/regression/termination/valid/RedBlackTree.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/termination/valid/SimpInterpret.scala b/src/test/resources/regression/termination/valid/SimpInterpret.scala
index c5255506dbb0b20308a0210ea3268a9432abaa14..dc9b5d5f96437a9d83c2c8bf3e4dbcfcb6d497a5 100644
--- a/src/test/resources/regression/termination/valid/SimpInterpret.scala
+++ b/src/test/resources/regression/termination/valid/SimpInterpret.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/termination/valid/Termination_passing1.scala b/src/test/resources/regression/termination/valid/Termination_passing1.scala
index 2f429ad05b0d4f7e6644d5177a3c0e94fa673b87..389e60a5f3f4230577441d1286c76dac88f9e2bd 100644
--- a/src/test/resources/regression/termination/valid/Termination_passing1.scala
+++ b/src/test/resources/regression/termination/valid/Termination_passing1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/transformations/SimplifyLets.scala b/src/test/resources/regression/transformations/SimplifyLets.scala
index 6d118e9bffaf0b970787645cff2d0a9b49907828..62fd3f7a4fa2578bee363a87d93ecfc30db7ef6c 100644
--- a/src/test/resources/regression/transformations/SimplifyLets.scala
+++ b/src/test/resources/regression/transformations/SimplifyLets.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/transformations/SimplifyPaths.scala b/src/test/resources/regression/transformations/SimplifyPaths.scala
index 1c5af48a7f6093cdaa673590aa3fd23a91122a8a..17d3a80b62ac947a7df09aa5e760a3d431339ba0 100644
--- a/src/test/resources/regression/transformations/SimplifyPaths.scala
+++ b/src/test/resources/regression/transformations/SimplifyPaths.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/isabelle/error/FunctionsWrong.scala b/src/test/resources/regression/verification/isabelle/error/FunctionsWrong.scala
index 54b2bec14d62873d2334f191d93559cd2db2ae3a..bd1a65c53ff9311df11d4fb1bf5907b0fec76da7 100644
--- a/src/test/resources/regression/verification/isabelle/error/FunctionsWrong.scala
+++ b/src/test/resources/regression/verification/isabelle/error/FunctionsWrong.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon._
 import leon.annotation._
 import leon.collection._
diff --git a/src/test/resources/regression/verification/isabelle/error/MutualWrong.scala b/src/test/resources/regression/verification/isabelle/error/MutualWrong.scala
index 16fd3ee9bf446dc8d7176ca98b7a6122ad4329ea..5a006fa7f997a7872f46c96f9292f4d887b463eb 100644
--- a/src/test/resources/regression/verification/isabelle/error/MutualWrong.scala
+++ b/src/test/resources/regression/verification/isabelle/error/MutualWrong.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/isabelle/error/TypesWrong.scala b/src/test/resources/regression/verification/isabelle/error/TypesWrong.scala
index a3772cc75c8e834adb28926869afbbc9845b76f9..505e23d8600a7b16419fbe16f0118ada92ea665f 100644
--- a/src/test/resources/regression/verification/isabelle/error/TypesWrong.scala
+++ b/src/test/resources/regression/verification/isabelle/error/TypesWrong.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon._
 import leon.collection._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/isabelle/unknown/Casts.scala b/src/test/resources/regression/verification/isabelle/unknown/Casts.scala
index c1f8844f0e82b533c5d7ed0a74545293cfa10b1a..2d0ef020ed7ef7ff8f4c406d55f1271a35debc47 100644
--- a/src/test/resources/regression/verification/isabelle/unknown/Casts.scala
+++ b/src/test/resources/regression/verification/isabelle/unknown/Casts.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon._
 import leon.annotation._
 import leon.collection._
diff --git a/src/test/resources/regression/verification/isabelle/unknown/Mutual.scala b/src/test/resources/regression/verification/isabelle/unknown/Mutual.scala
index 5b14a2b860115b7d1bdd1c88f2a1a173fe810d32..3f25ef9b2784956859e79c9ebec33e4aa0489f1c 100644
--- a/src/test/resources/regression/verification/isabelle/unknown/Mutual.scala
+++ b/src/test/resources/regression/verification/isabelle/unknown/Mutual.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/isabelle/valid/Datatypes.scala b/src/test/resources/regression/verification/isabelle/valid/Datatypes.scala
index 0da6b70265f8e207bd7a5198e9858bc2ef28eb60..feea22f60e16168d1bbf4c281e4baacb9feca818 100644
--- a/src/test/resources/regression/verification/isabelle/valid/Datatypes.scala
+++ b/src/test/resources/regression/verification/isabelle/valid/Datatypes.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/isabelle/valid/Lists.scala b/src/test/resources/regression/verification/isabelle/valid/Lists.scala
index be3292851d19c0d2a361594e66bd967d6f78a522..0eaeafc81babf173df3e5b2e91cb0f7bbd37e4df 100644
--- a/src/test/resources/regression/verification/isabelle/valid/Lists.scala
+++ b/src/test/resources/regression/verification/isabelle/valid/Lists.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon._
 import leon.annotation._
 import leon.collection._
diff --git a/src/test/resources/regression/verification/isabelle/valid/Nats.scala b/src/test/resources/regression/verification/isabelle/valid/Nats.scala
index 4838665b6f56dc0a9c84b79036049c8db869fecb..f679173dddc467d53e474d4aa6e26cf6b56cf74a 100644
--- a/src/test/resources/regression/verification/isabelle/valid/Nats.scala
+++ b/src/test/resources/regression/verification/isabelle/valid/Nats.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.collection._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/isabelle/valid/Overlapping.scala b/src/test/resources/regression/verification/isabelle/valid/Overlapping.scala
index 330f755305e0dd60c8292e0cb4d8b581823deff9..8c9d606f0e78d45d8a34998b5ec9126dc4e8b712 100644
--- a/src/test/resources/regression/verification/isabelle/valid/Overlapping.scala
+++ b/src/test/resources/regression/verification/isabelle/valid/Overlapping.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.collection._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/isabelle/valid/Quantifiers.scala b/src/test/resources/regression/verification/isabelle/valid/Quantifiers.scala
index b0e815c576ffd29db1f402a06da66f8046cbfe85..ba950b23976384159ade2cf5f072051a2dbb03d6 100644
--- a/src/test/resources/regression/verification/isabelle/valid/Quantifiers.scala
+++ b/src/test/resources/regression/verification/isabelle/valid/Quantifiers.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Quantifiers {
diff --git a/src/test/resources/regression/verification/isabelle/valid/Reals.scala b/src/test/resources/regression/verification/isabelle/valid/Reals.scala
index e4b963518924d603d0aedd22b32ad0335f4d5af2..c7f370bab038ff75e7074514ae0ab7b51a5e6dc7 100644
--- a/src/test/resources/regression/verification/isabelle/valid/Reals.scala
+++ b/src/test/resources/regression/verification/isabelle/valid/Reals.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon._
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/isabelle/valid/Unapply.scala b/src/test/resources/regression/verification/isabelle/valid/Unapply.scala
index 8a00fd5db94913f9540217b5e9132a5d4187c2a6..6569f180c34f26357d15985dd0f7e1c4ef55b22e 100644
--- a/src/test/resources/regression/verification/isabelle/valid/Unapply.scala
+++ b/src/test/resources/regression/verification/isabelle/valid/Unapply.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.collection._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Acc.scala b/src/test/resources/regression/verification/newsolvers/invalid/Acc.scala
index 2edd23ab78401f64fe7e6623cf3ace59d35007a7..2005a7d0310fabcaa611c5e71d7d3653b77b27d3 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Acc.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Acc.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/AddingNegativeNumbers.scala b/src/test/resources/regression/verification/newsolvers/invalid/AddingNegativeNumbers.scala
index 897aceefa1b30d6c5c2b2c200449746dfaa36250..98f5de2e248eb40fb6d4cbb6565093d725a2745e 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/AddingNegativeNumbers.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/AddingNegativeNumbers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package test.resources.regression.verification.purescala.invalid
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/AddingPositiveNumbers.scala b/src/test/resources/regression/verification/newsolvers/invalid/AddingPositiveNumbers.scala
index fa89830c4e7e0b24652eddde8c08c857d8e29387..6bebade9591e59f844fae5180d6b85401dc186ba 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/AddingPositiveNumbers.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/AddingPositiveNumbers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object AddingPositiveNumbers {
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Array1.scala b/src/test/resources/regression/verification/newsolvers/invalid/Array1.scala
index a7e3fea8e2ce79f419e976d5ee331d955de2be86..3707c62e6bc3a00c8f4cdcdde471c04b086a1476 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Array1.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Array1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Array2.scala b/src/test/resources/regression/verification/newsolvers/invalid/Array2.scala
index 3996f1fb77800cf2110dc5e32aa707981571ce37..b241dc8cbfd74991dd8ecec9f1c43cd165120942 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Array2.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Array2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Array3.scala b/src/test/resources/regression/verification/newsolvers/invalid/Array3.scala
index f5c75c5388a41114005a51a39e30d47a8e66303b..4307c3982dad5c88608091f5891ea5d227881819 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Array3.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Array3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Array4.scala b/src/test/resources/regression/verification/newsolvers/invalid/Array4.scala
index d7875d9b3ea09be869429c801fe59716213aac3a..35a6479b9e11d8d1917a554a0e36017af556f804 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Array4.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Array4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Asserts1.scala b/src/test/resources/regression/verification/newsolvers/invalid/Asserts1.scala
index 4375995d568160f565eb7d942e2ae9f66cc3ae51..73ec19af59f350a196970bc7249395e5df5a2288 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Asserts1.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Asserts1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/BVDivision.scala b/src/test/resources/regression/verification/newsolvers/invalid/BVDivision.scala
index a2572db84870fa38ab5f4f6a924ddbaa1641d47f..bbd8bb508ba9e01c5f96d56b8ed459adf605de59 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/BVDivision.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/BVDivision.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/BVDivision2.scala b/src/test/resources/regression/verification/newsolvers/invalid/BVDivision2.scala
index c11405429d270758774cf20ef5f8be650a375937..ab320c8c3bc9a90a83c85c253b58a4b9e048ad1e 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/BVDivision2.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/BVDivision2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/BigArray.scala b/src/test/resources/regression/verification/newsolvers/invalid/BigArray.scala
index 1395a1e89ddf94532385d7d26b47bbf6b2fe2038..a4a4a6a05c0836b19ec55ad4538bd264c2742799 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/BigArray.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/BigArray.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Division.scala b/src/test/resources/regression/verification/newsolvers/invalid/Division.scala
index 6b505a7732f6a6b0126e2c4b4106c16426069823..1678d2db8644d1560162c01a6b5a275a7151e7b1 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Division.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Division.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/EnsuringBoolean.scala b/src/test/resources/regression/verification/newsolvers/invalid/EnsuringBoolean.scala
index 239cb7db23095dbfb253d668b7ff77bfe2260ed0..32b47ae9c2d1f4adbc58d63a410e9177816bf848 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/EnsuringBoolean.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/EnsuringBoolean.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/FiniteSort.scala b/src/test/resources/regression/verification/newsolvers/invalid/FiniteSort.scala
index 0cb31c8909456aa2e3c9f5bdfdc54ff80b6ca350..17af7c45eab3dc211d85ecefd480e61a9387a775 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/FiniteSort.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/FiniteSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Generics.scala b/src/test/resources/regression/verification/newsolvers/invalid/Generics.scala
index 21971e521b8c6451ee4fb337819b2b764c646432..991b948d948b909badfabd9935d58e865b03995f 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Generics.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Generics.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Generics2.scala b/src/test/resources/regression/verification/newsolvers/invalid/Generics2.scala
index 32d97e00344824fdf9d80e1b16431ee79539d090..0c95c311e09c0c67c16bf510090723afb41b5768 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Generics2.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Generics2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/InsertionSort.scala b/src/test/resources/regression/verification/newsolvers/invalid/InsertionSort.scala
index d82f045b52c4870e0d243fd77777e1e19a5b60bd..ddf73528201ad5a07cbe61bc1afe440bcfc58f8d 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/InsertionSort.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/InsertionSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/ListOperations.scala b/src/test/resources/regression/verification/newsolvers/invalid/ListOperations.scala
index 196353358a7c6a6d15951a70302ec6d0e3ad79f4..cd801dc9ef23a1f43ef6a793a3102266af239bac 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/ListOperations.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/ListOperations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/MyTuple1.scala b/src/test/resources/regression/verification/newsolvers/invalid/MyTuple1.scala
index f2aa840a8dba4513879f452dd6925edee3fccd6b..394e2cd9fb8815514c7788481af2c0376af8e560 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/MyTuple1.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/MyTuple1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple1 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/MyTuple2.scala b/src/test/resources/regression/verification/newsolvers/invalid/MyTuple2.scala
index 0bd3d302fd0e30dbb68c35a0d5b32694983fa487..76b8e64cf243789f9eece4cf8dfc7131efb6ca82 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/MyTuple2.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/MyTuple2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple2 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/MyTuple3.scala b/src/test/resources/regression/verification/newsolvers/invalid/MyTuple3.scala
index cd514455b8eb62ec19464fd95117ee2388730a8d..abc0ffba3e654b80b3ac27450be7421496b9d53c 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/MyTuple3.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/MyTuple3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple3 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/PositiveMap.scala b/src/test/resources/regression/verification/newsolvers/invalid/PositiveMap.scala
index c9f29085398a289604769716aa54abddbe50958e..eaf345dd92979d9a754d2157611b2bf8f58266db 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/PositiveMap.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/PositiveMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/PropositionalLogic.scala b/src/test/resources/regression/verification/newsolvers/invalid/PropositionalLogic.scala
index 547978dbcca900272b76aac30dfd8e2a8f9e2c62..18b36ebf0b748488dc27ea88ce64626e04c064e5 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/PropositionalLogic.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/PropositionalLogic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/RedBlackTree.scala b/src/test/resources/regression/verification/newsolvers/invalid/RedBlackTree.scala
index c0d4fd9a6b2ae0d24bc42481a9ce52cda0f44ef4..7ac05413c0a958f4132393c4a4ffe4cba7142af5 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/RedBlackTree.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/RedBlackTree.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/invalid/Unit1.scala b/src/test/resources/regression/verification/newsolvers/invalid/Unit1.scala
index d286487c04b4fc6e8129f6d31d7a7d853847ff35..f937daaa922bc3039ca565d978905db3c23531fd 100644
--- a/src/test/resources/regression/verification/newsolvers/invalid/Unit1.scala
+++ b/src/test/resources/regression/verification/newsolvers/invalid/Unit1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Unit1 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Acc.scala b/src/test/resources/regression/verification/newsolvers/valid/Acc.scala
index 6dce9c294de8c788db4ffa7f205c1ac47905d5a5..6f93027c9fc03fded4a86923e54d3d8d0bf65a6f 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Acc.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Acc.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/AddingPositiveNumbers.scala b/src/test/resources/regression/verification/newsolvers/valid/AddingPositiveNumbers.scala
index 0b269ededa2e7bf3eb21203c4e1455d8fae9351f..84fca5dc63b3fb69504c65b2c38162879c8ec607 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/AddingPositiveNumbers.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/AddingPositiveNumbers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object AddingPositiveNumbers {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/AmortizedQueue.scala b/src/test/resources/regression/verification/newsolvers/valid/AmortizedQueue.scala
index d3ad0237a88c6592702f1479397997f0324dd108..5d60e67bfedfc3af133774abc73ed594bff24929 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/AmortizedQueue.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/AmortizedQueue.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/ArrayLiterals.scala b/src/test/resources/regression/verification/newsolvers/valid/ArrayLiterals.scala
index c3496b157e339725d823ff9f9d6fb586401d1e1d..450a07a7e65f5eea0bcadfe9cdf7d71574b9abfb 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/ArrayLiterals.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/ArrayLiterals.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 object ArrayLiterals {
diff --git a/src/test/resources/regression/verification/newsolvers/valid/ArrayUpdated.scala b/src/test/resources/regression/verification/newsolvers/valid/ArrayUpdated.scala
index e60918b6437d8a13d50fed7c793967d46aebd7aa..d501089cf77bb3c5dd30dea7ac6dfce557508f13 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/ArrayUpdated.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/ArrayUpdated.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Asserts1.scala b/src/test/resources/regression/verification/newsolvers/valid/Asserts1.scala
index 6d6ec65a398afb86f446fe16a8559ad6cd53959d..aadcfde990f31b4106f9e741457d0e04f6634e7b 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Asserts1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Asserts1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.annotation._
 import leon._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/AssociativeList.scala b/src/test/resources/regression/verification/newsolvers/valid/AssociativeList.scala
index 39cc5b7326c3d1aa964055f6335336943b2afcf7..bbc4edf5d8cd23e6b8ff37966bf2620e93acfde9 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/AssociativeList.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/AssociativeList.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/BestRealTypes.scala b/src/test/resources/regression/verification/newsolvers/valid/BestRealTypes.scala
index 6da51350f5bbf2abb6322393d96c4f3b3756ef6b..b40aac4f8d6b6342db76e21272dfa427c7d64c30 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/BestRealTypes.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/BestRealTypes.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/BitsTricks.scala b/src/test/resources/regression/verification/newsolvers/valid/BitsTricks.scala
index 561f38a190cd4edf8fdf1eaee7912e86493c97f7..6475d9117efb1d9dd152a03f234cf8119f7cf58f 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/BitsTricks.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/BitsTricks.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/CaseObject1.scala b/src/test/resources/regression/verification/newsolvers/valid/CaseObject1.scala
index 4a71c913afbde28a0e7cff3081cbeb68cecfa391..318af66807102bb5727b365aa9fa4b6f2139d366 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/CaseObject1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/CaseObject1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object CaseObject1 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Field1.scala b/src/test/resources/regression/verification/newsolvers/valid/Field1.scala
index be10c683da7f6bb8c940964ddf26f0ae3e3bec06..8c410b3d9ab93b3cb2dc6502a8b355b4722fcef4 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Field1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Field1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Field1 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Field2.scala b/src/test/resources/regression/verification/newsolvers/valid/Field2.scala
index 6b52ca258823af46754f7156a8cc78b2a741c3fd..db42516e5abc5dabad55ad1decb220e7bc5227f2 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Field2.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Field2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Field2 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/FiniteSort.scala b/src/test/resources/regression/verification/newsolvers/valid/FiniteSort.scala
index a9b5ff6b656a48675723dca9fc07dcd07f1d05cb..ab85023cb615b25ee57bd575b27ec847e4304ed2 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/FiniteSort.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/FiniteSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/FoolProofAdder.scala b/src/test/resources/regression/verification/newsolvers/valid/FoolProofAdder.scala
index 4fd46f85fc051b8de8d1025e74a7a6a6275e0611..dfc11de525aa88f8cc613fd8a78cd8a57cba9d03 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/FoolProofAdder.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/FoolProofAdder.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Generics.scala b/src/test/resources/regression/verification/newsolvers/valid/Generics.scala
index 14045bf32057cc50955acc0118d845b0afbab95b..86ee9d50c2fb06b03d117ab205f659ebd9e569b7 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Generics.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Generics.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Generics1.scala b/src/test/resources/regression/verification/newsolvers/valid/Generics1.scala
index d269f21785a401991a0bc077e3fc53ae2e42bf20..e054b629fbd05c17dc0aed5fe9bb6e713f8a8f01 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Generics1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Generics1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Heaps.scala b/src/test/resources/regression/verification/newsolvers/valid/Heaps.scala
index 876fb5a2ac6467c9679a86e0a27effa532c5d622..0e2ca340513497fe107d50d2526b7bee92a448ab 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Heaps.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Heaps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/InsertionSort.scala b/src/test/resources/regression/verification/newsolvers/valid/InsertionSort.scala
index 3252c9acf942d682f3cef10cc358cb7c837b44bb..655f84797c93e61dbe863e516c3b8204f5b4e133 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/InsertionSort.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/InsertionSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/InstanceOf1.scala b/src/test/resources/regression/verification/newsolvers/valid/InstanceOf1.scala
index 6543f94e5c66df0a073fe88770885e3bd408c0ac..6901da6c8d3cb85afe16343513cabebaa1fc59a0 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/InstanceOf1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/InstanceOf1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object InstanceOf1 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/ListOperations.scala b/src/test/resources/regression/verification/newsolvers/valid/ListOperations.scala
index d54b5b86ecf6137d084df96a45fe3852ae486c23..47283ef72c3862258c2800f83595812ad1a5cc40 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/ListOperations.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/ListOperations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/LiteralMaps.scala b/src/test/resources/regression/verification/newsolvers/valid/LiteralMaps.scala
index eea0009f2576c8a74b2a319b92bb768cb9a7870c..a0f2d22f389c81856a02a7e34ae57aaf2e13cfd9 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/LiteralMaps.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/LiteralMaps.scala
@@ -1,5 +1,5 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
-import leon.lang._
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 object LiteralMaps {
   def test(): Map[Int, Int] = {
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MergeSort.scala b/src/test/resources/regression/verification/newsolvers/valid/MergeSort.scala
index 2776a86c21baafc8b73112baaad01eab1357974f..99681add4516588b33dc62ddd255a0520598a299 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MergeSort.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MergeSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MyMap.scala b/src/test/resources/regression/verification/newsolvers/valid/MyMap.scala
index 4f656c5960aff42f2c28dd32f7765d22af6261e5..9cb5fa4b3f557670ef746a25b90f992acdd0bbf0 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MyMap.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MyMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MySet.scala b/src/test/resources/regression/verification/newsolvers/valid/MySet.scala
index b19be90e73d5b7981baefc3e8908c69719722de4..13efa589eba329e820726b7b8a0ba9f42907358c 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MySet.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MySet.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MyTuple1.scala b/src/test/resources/regression/verification/newsolvers/valid/MyTuple1.scala
index 9aa42ce056da6a877f59f99f4abbacd55060d65a..55ba48e8e56c4a2b755d759851bb88568a87f0eb 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MyTuple1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MyTuple1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple1 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MyTuple2.scala b/src/test/resources/regression/verification/newsolvers/valid/MyTuple2.scala
index 05124ffbe0d2cbd1edb448d2925d9762c767e443..8683adcdeeee636ed68e4e13f5d164f09c60688c 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MyTuple2.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MyTuple2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple2 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MyTuple3.scala b/src/test/resources/regression/verification/newsolvers/valid/MyTuple3.scala
index 20bb0eec9be4c735d6ef92abfd33e1d059fb8983..db4f82411b9e62b3a3a34cc57347a9b2c83247dd 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MyTuple3.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MyTuple3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple3 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MyTuple4.scala b/src/test/resources/regression/verification/newsolvers/valid/MyTuple4.scala
index 8b2ede8f299cc13fe70ee5bcf41fabca7b853e6c..6dd4d3c1c6e04d7662de02a0d956fdc7d95b9547 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MyTuple4.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MyTuple4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 
 object MyTuple4 {
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MyTuple5.scala b/src/test/resources/regression/verification/newsolvers/valid/MyTuple5.scala
index 78c93bc2a0f8e5bfcd4e58126d1ad8d5ec4bf695..d8fff88781251281e0c56c494a7f8e4d9b81bd5b 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MyTuple5.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MyTuple5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple5 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/MyTuple6.scala b/src/test/resources/regression/verification/newsolvers/valid/MyTuple6.scala
index e6cff3917d077ef83c11b5c3965204ccbe15da55..f8cc1b42393ae8bdb66f92b22061bff99c5a2cc2 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/MyTuple6.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/MyTuple6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple6 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Nat.scala b/src/test/resources/regression/verification/newsolvers/valid/Nat.scala
index 498373c4ac3cb0c95948ac6d0b6e0831f74352f0..b766230abd988de18b696266e8156ba1c48e6dae 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Nat.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Nat.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/NotEquals.scala b/src/test/resources/regression/verification/newsolvers/valid/NotEquals.scala
index f33e1bb5dd509a02e68eaf30d2164d5e5920e3c0..31a4bc763600ac9a8e0b5d0cc4bec308cc110955 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/NotEquals.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/NotEquals.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.annotation._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/PositiveMap.scala b/src/test/resources/regression/verification/newsolvers/valid/PositiveMap.scala
index 93c87331e272d6b9a989bdd757b8bcce5ce3072e..a9a07c9850de6d9e9c7de498996d9f1b16d6d532 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/PositiveMap.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/PositiveMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/PropositionalLogic.scala b/src/test/resources/regression/verification/newsolvers/valid/PropositionalLogic.scala
index 66e3f84ecfa11a460c6e721f69cb44d51def285e..fa7c0cf487cca517f1b134b0acb7ba02a93ebe3d 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/PropositionalLogic.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/PropositionalLogic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/RedBlackTree.scala b/src/test/resources/regression/verification/newsolvers/valid/RedBlackTree.scala
index e24935bbedb8f87e0778f29f44f3a4758560fc11..a40068e7081dc594d7419e38f436cbca3751f8da 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/RedBlackTree.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/RedBlackTree.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/SearchLinkedList.scala b/src/test/resources/regression/verification/newsolvers/valid/SearchLinkedList.scala
index ba2380c6a4fc1518a77281d4521840b5159bfbc2..49fad86821600124f2d336cc894f23ff76a1db2e 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/SearchLinkedList.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/SearchLinkedList.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Subtyping1.scala b/src/test/resources/regression/verification/newsolvers/valid/Subtyping1.scala
index e31801436891f05afd9e04cd01ef1274a6ef18f6..f971d2a596e3b0af47453c5ffbf89a4766e1ea44 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Subtyping1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Subtyping1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Subtyping2.scala b/src/test/resources/regression/verification/newsolvers/valid/Subtyping2.scala
index eef9c65da55c0b4d0ed76802a82c720f79fd44e7..bbb436b6a134a427e97aab1527fbaaeea49a16c9 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Subtyping2.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Subtyping2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Unit1.scala b/src/test/resources/regression/verification/newsolvers/valid/Unit1.scala
index a0683d303545f782004fda587e520c5abf676c02..596f7cc319bddcf495fd281e820a0f5bc7f1144f 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Unit1.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Unit1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Unit1 {
 
diff --git a/src/test/resources/regression/verification/newsolvers/valid/Unit2.scala b/src/test/resources/regression/verification/newsolvers/valid/Unit2.scala
index 8a285ff23af02ff1ae907fd714da0ae46141db50..1aa3cf55bdd9de42855d7a7311a73f47256c917a 100644
--- a/src/test/resources/regression/verification/newsolvers/valid/Unit2.scala
+++ b/src/test/resources/regression/verification/newsolvers/valid/Unit2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Unit2 {
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Acc.scala b/src/test/resources/regression/verification/purescala/invalid/Acc.scala
index d1f8810defbb9cd76434bc961413287dc652eb4e..2005a7d0310fabcaa611c5e71d7d3653b77b27d3 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Acc.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Acc.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/invalid/AddingNegativeNumbers.scala b/src/test/resources/regression/verification/purescala/invalid/AddingNegativeNumbers.scala
index 897aceefa1b30d6c5c2b2c200449746dfaa36250..98f5de2e248eb40fb6d4cbb6565093d725a2745e 100644
--- a/src/test/resources/regression/verification/purescala/invalid/AddingNegativeNumbers.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/AddingNegativeNumbers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package test.resources.regression.verification.purescala.invalid
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/AddingPositiveNumbers.scala b/src/test/resources/regression/verification/purescala/invalid/AddingPositiveNumbers.scala
index fa89830c4e7e0b24652eddde8c08c857d8e29387..6bebade9591e59f844fae5180d6b85401dc186ba 100644
--- a/src/test/resources/regression/verification/purescala/invalid/AddingPositiveNumbers.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/AddingPositiveNumbers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object AddingPositiveNumbers {
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Array1.scala b/src/test/resources/regression/verification/purescala/invalid/Array1.scala
index a7e3fea8e2ce79f419e976d5ee331d955de2be86..3707c62e6bc3a00c8f4cdcdde471c04b086a1476 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Array1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Array1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Array2.scala b/src/test/resources/regression/verification/purescala/invalid/Array2.scala
index 3996f1fb77800cf2110dc5e32aa707981571ce37..b241dc8cbfd74991dd8ecec9f1c43cd165120942 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Array2.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Array2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Array3.scala b/src/test/resources/regression/verification/purescala/invalid/Array3.scala
index f5c75c5388a41114005a51a39e30d47a8e66303b..4307c3982dad5c88608091f5891ea5d227881819 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Array3.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Array3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Array4.scala b/src/test/resources/regression/verification/purescala/invalid/Array4.scala
index d7875d9b3ea09be869429c801fe59716213aac3a..35a6479b9e11d8d1917a554a0e36017af556f804 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Array4.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Array4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Array5.scala b/src/test/resources/regression/verification/purescala/invalid/Array5.scala
index 2adb7e5c5e218505f9a391a28739f38abd621e5b..d988169400fc6d7db67a9595b54142935c2eba81 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Array5.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Array5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Array6.scala b/src/test/resources/regression/verification/purescala/invalid/Array6.scala
index 18a1e7ab0015edb8aeb4221ccbe7e558520bde85..d856d9e9e29584e34ef348ea8469393bf8f7309b 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Array6.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Array6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Array7.scala b/src/test/resources/regression/verification/purescala/invalid/Array7.scala
index dcf7059f82c714e941bf757a997405b1e868239c..9c2c788f7a90c787a44944c4b0e3fa14c89dcd1d 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Array7.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Array7.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Asserts1.scala b/src/test/resources/regression/verification/purescala/invalid/Asserts1.scala
index 7b36cead042de47b76e66f1411db1b965eb0d5fd..38c7eb435a6bab2b3cc77b340cf0bb910cb891e4 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Asserts1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Asserts1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/invalid/BVDivision2.scala b/src/test/resources/regression/verification/purescala/invalid/BVDivision2.scala
index c11405429d270758774cf20ef5f8be650a375937..ab320c8c3bc9a90a83c85c253b58a4b9e048ad1e 100644
--- a/src/test/resources/regression/verification/purescala/invalid/BVDivision2.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/BVDivision2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/invalid/BVDivisionByZero.scala b/src/test/resources/regression/verification/purescala/invalid/BVDivisionByZero.scala
index 54ac21fb62450e2f018a33c3e80be95edd8578c8..632a7f423a9d2678ab2aa2f7de830e8b1738bb4c 100644
--- a/src/test/resources/regression/verification/purescala/invalid/BVDivisionByZero.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/BVDivisionByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/invalid/BVRemainderByZero.scala b/src/test/resources/regression/verification/purescala/invalid/BVRemainderByZero.scala
index ed3ebf22a15764a06c65e3e55c219467987dc52a..2bec1b715434c9cbedf7328406e873a738a4299b 100644
--- a/src/test/resources/regression/verification/purescala/invalid/BVRemainderByZero.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/BVRemainderByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/invalid/BigArray.scala b/src/test/resources/regression/verification/purescala/invalid/BigArray.scala
index 1395a1e89ddf94532385d7d26b47bbf6b2fe2038..a4a4a6a05c0836b19ec55ad4538bd264c2742799 100644
--- a/src/test/resources/regression/verification/purescala/invalid/BigArray.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/BigArray.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/invalid/BinarySearchTreeQuant.scala b/src/test/resources/regression/verification/purescala/invalid/BinarySearchTreeQuant.scala
index 849de7d15c180c8d8ed945e2420043b36ba92152..260d33ad2e7d6757e0b0af784e9631138f95cb61 100644
--- a/src/test/resources/regression/verification/purescala/invalid/BinarySearchTreeQuant.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/BinarySearchTreeQuant.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/BraunTree.scala b/src/test/resources/regression/verification/purescala/invalid/BraunTree.scala
index b8ce261ad306e9f98e3baa5e303ba6a035f37a31..ff2144d1c3b07b3d295239703136b6d017abd6ef 100644
--- a/src/test/resources/regression/verification/purescala/invalid/BraunTree.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/BraunTree.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/CallByName1.scala b/src/test/resources/regression/verification/purescala/invalid/CallByName1.scala
index c96ab1617e254c19d8b08a8ecbd818d9cdc305e4..7aef4f08bdc980fb4f5a5db35f383309ebc4aa7b 100644
--- a/src/test/resources/regression/verification/purescala/invalid/CallByName1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/CallByName1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object CallByName1 {
diff --git a/src/test/resources/regression/verification/purescala/invalid/CharCompare.scala b/src/test/resources/regression/verification/purescala/invalid/CharCompare.scala
index 185aad5c98c20bc1e53b052e55e712a6785f92cc..f92657c784cc2ea96d2300d0d154aac151c5eac7 100644
--- a/src/test/resources/regression/verification/purescala/invalid/CharCompare.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/CharCompare.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object CharCompare {
diff --git a/src/test/resources/regression/verification/purescala/invalid/Choose1.scala b/src/test/resources/regression/verification/purescala/invalid/Choose1.scala
index cb3d8b3ffb95f7b896b31e6310c026c3601831d8..ac9922ed779b88cc0b83ce2ef7f07465432263be 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Choose1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Choose1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/verification/purescala/invalid/DivisionByZero.scala b/src/test/resources/regression/verification/purescala/invalid/DivisionByZero.scala
index 7415f2e6a8b1f0e9bded4fa90937f54bd0e0d5ea..95f435727d4691dd1c72b0ba2004385372dad297 100644
--- a/src/test/resources/regression/verification/purescala/invalid/DivisionByZero.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/DivisionByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/invalid/EnsuringBoolean.scala b/src/test/resources/regression/verification/purescala/invalid/EnsuringBoolean.scala
index 239cb7db23095dbfb253d668b7ff77bfe2260ed0..32b47ae9c2d1f4adbc58d63a410e9177816bf848 100644
--- a/src/test/resources/regression/verification/purescala/invalid/EnsuringBoolean.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/EnsuringBoolean.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/invalid/Existentials.scala b/src/test/resources/regression/verification/purescala/invalid/Existentials.scala
index 19679db9202b325edc0eb8dfff8eeea41bb47d36..4f3d358c772d273a306e55868fc8f960298b5381 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Existentials.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Existentials.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Existentials {
diff --git a/src/test/resources/regression/verification/purescala/invalid/FieldInheritance.scala b/src/test/resources/regression/verification/purescala/invalid/FieldInheritance.scala
index 7ef9d952264651e2ecb8256b1b2d986c77b56cc3..e183b615ad6fa3dea6d3eef63fe079198b9110d9 100644
--- a/src/test/resources/regression/verification/purescala/invalid/FieldInheritance.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/FieldInheritance.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object FieldInheritance {
diff --git a/src/test/resources/regression/verification/purescala/invalid/FiniteSort.scala b/src/test/resources/regression/verification/purescala/invalid/FiniteSort.scala
index 0cb31c8909456aa2e3c9f5bdfdc54ff80b6ca350..17af7c45eab3dc211d85ecefd480e61a9387a775 100644
--- a/src/test/resources/regression/verification/purescala/invalid/FiniteSort.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/FiniteSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/ForallAssoc.scala b/src/test/resources/regression/verification/purescala/invalid/ForallAssoc.scala
index 83773b2224fb8790acfc25125143b358c1226f05..dcd837a69dd6d2d78439def449d21815f3bffba5 100644
--- a/src/test/resources/regression/verification/purescala/invalid/ForallAssoc.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/ForallAssoc.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object ForallAssoc {
diff --git a/src/test/resources/regression/verification/purescala/invalid/Generics.scala b/src/test/resources/regression/verification/purescala/invalid/Generics.scala
index 21971e521b8c6451ee4fb337819b2b764c646432..991b948d948b909badfabd9935d58e865b03995f 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Generics.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Generics.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Generics2.scala b/src/test/resources/regression/verification/purescala/invalid/Generics2.scala
index 32d97e00344824fdf9d80e1b16431ee79539d090..0c95c311e09c0c67c16bf510090723afb41b5768 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Generics2.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Generics2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/HOInvocations.scala b/src/test/resources/regression/verification/purescala/invalid/HOInvocations.scala
index 0685b7b92ddc0db97d0b92f2e265eba21afb130e..c44cd759d15f36d17b346c700927e9c1a7885929 100644
--- a/src/test/resources/regression/verification/purescala/invalid/HOInvocations.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/HOInvocations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/HOInvocations2.scala b/src/test/resources/regression/verification/purescala/invalid/HOInvocations2.scala
index 1639def5dba3c6658fd4348dd6d0d96300cd4770..ba7c88c9cde4edd5c2bdc48c1da47f66a5e1f06c 100644
--- a/src/test/resources/regression/verification/purescala/invalid/HOInvocations2.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/HOInvocations2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object HOInvocations2 {
diff --git a/src/test/resources/regression/verification/purescala/invalid/InsertionSort.scala b/src/test/resources/regression/verification/purescala/invalid/InsertionSort.scala
index d82f045b52c4870e0d243fd77777e1e19a5b60bd..ddf73528201ad5a07cbe61bc1afe440bcfc58f8d 100644
--- a/src/test/resources/regression/verification/purescala/invalid/InsertionSort.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/InsertionSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/invalid/ListOperations.scala b/src/test/resources/regression/verification/purescala/invalid/ListOperations.scala
index 46e90ccfc64fc33383abcfac5db86e7060821b6e..82f4648a2d568d4b50d19c7a2a953cced7775cef 100644
--- a/src/test/resources/regression/verification/purescala/invalid/ListOperations.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/ListOperations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/invalid/Lists.scala b/src/test/resources/regression/verification/purescala/invalid/Lists.scala
index d691cae5b188bca45f6b249b1b194ffcc335af2d..c9594195d8a7e189007ca14852837334a5a7f07b 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Lists.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Lists.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/MatchExh.scala b/src/test/resources/regression/verification/purescala/invalid/MatchExh.scala
index 0f7f7d7360738be250e6a50fa89ff0aa6d4ed7e5..e5260ae1f147c71b2b8156c80b979be63220442d 100644
--- a/src/test/resources/regression/verification/purescala/invalid/MatchExh.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/MatchExh.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Mean.scala b/src/test/resources/regression/verification/purescala/invalid/Mean.scala
index 02240e73b2e04244e8a55c1881e21b0381852302..aa691fa159b313c9f5edc3196b69c1c731aa4c04 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Mean.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Mean.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/invalid/ModuloByZero.scala b/src/test/resources/regression/verification/purescala/invalid/ModuloByZero.scala
index 19eb0da32576052ae96ac66408b74e8cfb9b2563..114eb998bca464d637100307fa078da5fd1ce0b5 100644
--- a/src/test/resources/regression/verification/purescala/invalid/ModuloByZero.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/ModuloByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/invalid/Monotonic.scala b/src/test/resources/regression/verification/purescala/invalid/Monotonic.scala
index bc9a1bc76855e21d514a10ebdf257235480b1e10..ddb17ff3e015e196fa046a86aa189e37629ac467 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Monotonic.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Monotonic.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Monotonic {
diff --git a/src/test/resources/regression/verification/purescala/invalid/MyTuple1.scala b/src/test/resources/regression/verification/purescala/invalid/MyTuple1.scala
index f2aa840a8dba4513879f452dd6925edee3fccd6b..394e2cd9fb8815514c7788481af2c0376af8e560 100644
--- a/src/test/resources/regression/verification/purescala/invalid/MyTuple1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/MyTuple1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple1 {
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/MyTuple2.scala b/src/test/resources/regression/verification/purescala/invalid/MyTuple2.scala
index 0bd3d302fd0e30dbb68c35a0d5b32694983fa487..76b8e64cf243789f9eece4cf8dfc7131efb6ca82 100644
--- a/src/test/resources/regression/verification/purescala/invalid/MyTuple2.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/MyTuple2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple2 {
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/MyTuple3.scala b/src/test/resources/regression/verification/purescala/invalid/MyTuple3.scala
index cd514455b8eb62ec19464fd95117ee2388730a8d..abc0ffba3e654b80b3ac27450be7421496b9d53c 100644
--- a/src/test/resources/regression/verification/purescala/invalid/MyTuple3.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/MyTuple3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple3 {
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Nested15.scala b/src/test/resources/regression/verification/purescala/invalid/Nested15.scala
index 61ac54c4e924885c671544d6b5438db5e0183f31..d604082f6787cc0483fd210943b41d941acfde8f 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Nested15.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Nested15.scala
@@ -1,5 +1,7 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.collection._
+
 object Nested15 {
 
   def foo[A](i: List[A]): BigInt = {
diff --git a/src/test/resources/regression/verification/purescala/invalid/Overrides.scala b/src/test/resources/regression/verification/purescala/invalid/Overrides.scala
index ae6b4ebd4bea6dffdba88491ced95824719613c1..28c6e9dbc96407b6f63fd49baefc36ac74473c55 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Overrides.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Overrides.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Overrides {
   abstract class A {
     def x(a: Int): Int
diff --git a/src/test/resources/regression/verification/purescala/invalid/PositiveMap.scala b/src/test/resources/regression/verification/purescala/invalid/PositiveMap.scala
index c9f29085398a289604769716aa54abddbe50958e..eaf345dd92979d9a754d2157611b2bf8f58266db 100644
--- a/src/test/resources/regression/verification/purescala/invalid/PositiveMap.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/PositiveMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/PositiveMap2.scala b/src/test/resources/regression/verification/purescala/invalid/PositiveMap2.scala
index 713f901c9484184884e176d1a5ab0a51ced6d10f..c7cc782c632d463943dfaaa2e5c454cd2c759307 100644
--- a/src/test/resources/regression/verification/purescala/invalid/PositiveMap2.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/PositiveMap2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object PositiveMap2 {
diff --git a/src/test/resources/regression/verification/purescala/invalid/Postcondition.scala b/src/test/resources/regression/verification/purescala/invalid/Postcondition.scala
index d942f446e9ce75f42545e4078b56b89962df540c..be95028c0d80ed848c07bab072fba381a421e546 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Postcondition.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Postcondition.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Postconditions {
diff --git a/src/test/resources/regression/verification/purescala/invalid/PreInSpecs.scala b/src/test/resources/regression/verification/purescala/invalid/PreInSpecs.scala
index 4f184bac1d597ccaac1eee8e9e2a5cdb6f5cae26..03c795e336b25572e90703782dc8c7eb7088a7d5 100644
--- a/src/test/resources/regression/verification/purescala/invalid/PreInSpecs.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/PreInSpecs.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object PreInSpecs {
diff --git a/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala b/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala
index aa00e12d446e1b11984f741500279a5647cfe426..31790c96033bc72570a9cdc64393c8035b3cc25e 100644
--- a/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/invalid/RealDivisionByZero.scala b/src/test/resources/regression/verification/purescala/invalid/RealDivisionByZero.scala
index 418fbb9e81cb441518a616c506b467bfe912635e..efa3c4e0e0628bd2d46a330f174e28fdab92a65f 100644
--- a/src/test/resources/regression/verification/purescala/invalid/RealDivisionByZero.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/RealDivisionByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/invalid/RealNonDiscrete.scala b/src/test/resources/regression/verification/purescala/invalid/RealNonDiscrete.scala
index 3a234b88b83b50934cf3dcc7095b26e118ec30f2..65e7a655b4c3043a9add4710e8481843ceead172 100644
--- a/src/test/resources/regression/verification/purescala/invalid/RealNonDiscrete.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/RealNonDiscrete.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.annotation._
 
diff --git a/src/test/resources/regression/verification/purescala/invalid/RedBlackTree.scala b/src/test/resources/regression/verification/purescala/invalid/RedBlackTree.scala
index f56a174de585e0e17ee64ae989af8cbee56b4371..05004448d00a5a376cd81c8d4da084049b09ddb3 100644
--- a/src/test/resources/regression/verification/purescala/invalid/RedBlackTree.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/RedBlackTree.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/invalid/RemainderByZero.scala b/src/test/resources/regression/verification/purescala/invalid/RemainderByZero.scala
index 5fc587fe8cfdfeca00a1ffebf311059eb971eedd..c3b9e96f029376e18a2b4a6fb91f931c5245d64c 100644
--- a/src/test/resources/regression/verification/purescala/invalid/RemainderByZero.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/RemainderByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/invalid/SimpleQuantification.scala b/src/test/resources/regression/verification/purescala/invalid/SimpleQuantification.scala
index 7a3446612bd910dfbe7389b0d83001606640457c..b020f413c779d2239ec723d41985f8ab7900bd86 100644
--- a/src/test/resources/regression/verification/purescala/invalid/SimpleQuantification.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/SimpleQuantification.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Simple {
diff --git a/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala b/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala
index 9ee698e1d42d38214a0290cbad859b0b5ad87405..66ccb8f2eda1de78a0783795541e0525b43c9e58 100644
--- a/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object AndTest {
diff --git a/src/test/resources/regression/verification/purescala/invalid/Unapply1.scala b/src/test/resources/regression/verification/purescala/invalid/Unapply1.scala
index 674ca7c69fa29333755d8908f707ae9931d20bf2..cd78d47989f1007fffccdeccb0e94d8ef6764ce9 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Unapply1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Unapply1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Unap1 {
diff --git a/src/test/resources/regression/verification/purescala/invalid/Unapply2.scala b/src/test/resources/regression/verification/purescala/invalid/Unapply2.scala
index 7efd6e220fd1c7fcd08fbaa5b7016bf6801e151f..152f1445b97aaad91d008a62937b34d88ca658ea 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Unapply2.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Unapply2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._ 
 object Unap2 {
   def unapply[A, B](i: (Int, B, A)): Option[(A, B)] = 
diff --git a/src/test/resources/regression/verification/purescala/invalid/Unit1.scala b/src/test/resources/regression/verification/purescala/invalid/Unit1.scala
index d286487c04b4fc6e8129f6d31d7a7d853847ff35..f937daaa922bc3039ca565d978905db3c23531fd 100644
--- a/src/test/resources/regression/verification/purescala/invalid/Unit1.scala
+++ b/src/test/resources/regression/verification/purescala/invalid/Unit1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Unit1 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Acc.scala b/src/test/resources/regression/verification/purescala/valid/Acc.scala
index 9445ccaa84dd1418fc731e8dc8ca2a4689190331..6f93027c9fc03fded4a86923e54d3d8d0bf65a6f 100644
--- a/src/test/resources/regression/verification/purescala/valid/Acc.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Acc.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/AddingPositiveNumbers.scala b/src/test/resources/regression/verification/purescala/valid/AddingPositiveNumbers.scala
index 0b269ededa2e7bf3eb21203c4e1455d8fae9351f..84fca5dc63b3fb69504c65b2c38162879c8ec607 100644
--- a/src/test/resources/regression/verification/purescala/valid/AddingPositiveNumbers.scala
+++ b/src/test/resources/regression/verification/purescala/valid/AddingPositiveNumbers.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object AddingPositiveNumbers {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/AmortizedQueue.scala b/src/test/resources/regression/verification/purescala/valid/AmortizedQueue.scala
index 006fbde9ac76dd8f366fd0f495fe4f349b861eaf..dfb302cb9d7a98c7103d059a9cc4f5abb74cdc6f 100644
--- a/src/test/resources/regression/verification/purescala/valid/AmortizedQueue.scala
+++ b/src/test/resources/regression/verification/purescala/valid/AmortizedQueue.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/valid/Anonymous.scala b/src/test/resources/regression/verification/purescala/valid/Anonymous.scala
index 17f72fd089ac470331a087672219cdeb47553c7e..2239fb9a67c2d5636629e5f26fd8a6337a158ed9 100644
--- a/src/test/resources/regression/verification/purescala/valid/Anonymous.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Anonymous.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Array1.scala b/src/test/resources/regression/verification/purescala/valid/Array1.scala
index 4dbec292cbd7d332745c69dee5a6bf54ce782369..f1978f170bcbc74610a2dbf9e0b037ba9fae1f1a 100644
--- a/src/test/resources/regression/verification/purescala/valid/Array1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Array1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Array2.scala b/src/test/resources/regression/verification/purescala/valid/Array2.scala
index 53d30e9af2d51257cb3a5ac16487ae15d08a8aac..40b96f740074ac0a8025e73f18422d451395338d 100644
--- a/src/test/resources/regression/verification/purescala/valid/Array2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Array2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Array2 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Array3.scala b/src/test/resources/regression/verification/purescala/valid/Array3.scala
index b7ea754b4de89d701112d7ab234d0bfa55d90ad5..a9f98167f23e1117d407bd20440be47d32bc89f3 100644
--- a/src/test/resources/regression/verification/purescala/valid/Array3.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Array3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Array3 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/ArrayLiterals.scala b/src/test/resources/regression/verification/purescala/valid/ArrayLiterals.scala
index 34850fe4f7058befab21f5efeabe1efdfa5fe53f..4921b5e3661a178d5cc73e27d5792b402bde43f4 100644
--- a/src/test/resources/regression/verification/purescala/valid/ArrayLiterals.scala
+++ b/src/test/resources/regression/verification/purescala/valid/ArrayLiterals.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/ArrayUpdated.scala b/src/test/resources/regression/verification/purescala/valid/ArrayUpdated.scala
index e60918b6437d8a13d50fed7c793967d46aebd7aa..d501089cf77bb3c5dd30dea7ac6dfce557508f13 100644
--- a/src/test/resources/regression/verification/purescala/valid/ArrayUpdated.scala
+++ b/src/test/resources/regression/verification/purescala/valid/ArrayUpdated.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Asserts1.scala b/src/test/resources/regression/verification/purescala/valid/Asserts1.scala
index fce6728b6ae0f88101333ff6bafec484d762c62b..aadcfde990f31b4106f9e741457d0e04f6634e7b 100644
--- a/src/test/resources/regression/verification/purescala/valid/Asserts1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Asserts1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/valid/AssociativeList.scala b/src/test/resources/regression/verification/purescala/valid/AssociativeList.scala
index 39cc5b7326c3d1aa964055f6335336943b2afcf7..bbc4edf5d8cd23e6b8ff37966bf2620e93acfde9 100644
--- a/src/test/resources/regression/verification/purescala/valid/AssociativeList.scala
+++ b/src/test/resources/regression/verification/purescala/valid/AssociativeList.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/valid/BVDivSemantics.scala b/src/test/resources/regression/verification/purescala/valid/BVDivSemantics.scala
index a68525d813e41ae9ae5b0fa82c85c47eaaadebe3..29459bfca5fd7bb64b5fb060e6bc83aedcf37b9a 100644
--- a/src/test/resources/regression/verification/purescala/valid/BVDivSemantics.scala
+++ b/src/test/resources/regression/verification/purescala/valid/BVDivSemantics.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero.scala b/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero.scala
index 3de75f00349da0b93c61a33c3b38f9c252d60149..74a77460131bde77220a6c82d206d96b4e83a3e8 100644
--- a/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero.scala
+++ b/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero2.scala b/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero2.scala
index 382dbb1918d35f401af3c61d5d703e2a920cf2d6..78510863ce905ccf6f86acb50bf56bb9896635e9 100644
--- a/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/BVDivisionByZero2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/valid/BasicReal.scala b/src/test/resources/regression/verification/purescala/valid/BasicReal.scala
index 2250c5949517f03a744176bc857ca8255e31521b..fb8342da7e528679bfbd4265bf82891c647d6c94 100644
--- a/src/test/resources/regression/verification/purescala/valid/BasicReal.scala
+++ b/src/test/resources/regression/verification/purescala/valid/BasicReal.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.annotation._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/BestRealTypes.scala b/src/test/resources/regression/verification/purescala/valid/BestRealTypes.scala
index 6da51350f5bbf2abb6322393d96c4f3b3756ef6b..b40aac4f8d6b6342db76e21272dfa427c7d64c30 100644
--- a/src/test/resources/regression/verification/purescala/valid/BestRealTypes.scala
+++ b/src/test/resources/regression/verification/purescala/valid/BestRealTypes.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/BinarySearchTreeQuant.scala b/src/test/resources/regression/verification/purescala/valid/BinarySearchTreeQuant.scala
index a435e69ca7a0574937f7368e499c5750983133b3..4676dcd6a8faf5768dceeebe9f0f2293ae106ffd 100644
--- a/src/test/resources/regression/verification/purescala/valid/BinarySearchTreeQuant.scala
+++ b/src/test/resources/regression/verification/purescala/valid/BinarySearchTreeQuant.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/BitsTricks.scala b/src/test/resources/regression/verification/purescala/valid/BitsTricks.scala
index 2da2298eb2d3886212f41e1a655ba68b09a232d4..23cbe32a4d3a33609e9ad83f095d335a6e43fa9f 100644
--- a/src/test/resources/regression/verification/purescala/valid/BitsTricks.scala
+++ b/src/test/resources/regression/verification/purescala/valid/BitsTricks.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/CallByName1.scala b/src/test/resources/regression/verification/purescala/valid/CallByName1.scala
index 912acdc481e8191bd072bd7eaeb13684cd93c384..07247e0478aacfb2d3018f040948c212ac83f622 100644
--- a/src/test/resources/regression/verification/purescala/valid/CallByName1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/CallByName1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object CallByName1 {
diff --git a/src/test/resources/regression/verification/purescala/valid/CaseObject1.scala b/src/test/resources/regression/verification/purescala/valid/CaseObject1.scala
index 4a71c913afbde28a0e7cff3081cbeb68cecfa391..318af66807102bb5727b365aa9fa4b6f2139d366 100644
--- a/src/test/resources/regression/verification/purescala/valid/CaseObject1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/CaseObject1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object CaseObject1 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Choose1.scala b/src/test/resources/regression/verification/purescala/valid/Choose1.scala
index 19ca94fbbf4ee39baa2536e48f234809f39544f9..ee36ea5061a54664bc43e63b80695ae3354f8a3b 100644
--- a/src/test/resources/regression/verification/purescala/valid/Choose1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Choose1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/verification/purescala/valid/Choose2.scala b/src/test/resources/regression/verification/purescala/valid/Choose2.scala
index ad05bda101385ae70c32663e7d5451e09560a978..15a2e0c03ed8559a5bb3fae3d6594e0f17d0999f 100644
--- a/src/test/resources/regression/verification/purescala/valid/Choose2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Choose2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.synthesis._
diff --git a/src/test/resources/regression/verification/purescala/valid/Client.scala b/src/test/resources/regression/verification/purescala/valid/Client.scala
index c0dd37cda62e30202e9255b534685f9e0e9b840a..e58a05c99ed28f10c7f4f5142e2678bf0a737097 100644
--- a/src/test/resources/regression/verification/purescala/valid/Client.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Client.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.collection._
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Closures.scala b/src/test/resources/regression/verification/purescala/valid/Closures.scala
index 3ce765917487167238c8c1744d2e6aea82e6cc48..47aed6f0b5cc8a2a8f4522d5ac8c720e115c9d71 100644
--- a/src/test/resources/regression/verification/purescala/valid/Closures.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Closures.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Closures2.scala b/src/test/resources/regression/verification/purescala/valid/Closures2.scala
index 559eb27837229077c136a393d101fd65eee31d76..f77ae2dd3f93dd8095635824ecfbfbcb2fcd8684 100644
--- a/src/test/resources/regression/verification/purescala/valid/Closures2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Closures2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Composition.scala b/src/test/resources/regression/verification/purescala/valid/Composition.scala
index cd62eb8da69132b1825630d6a6d3885a06e951aa..64ac207269f38da7a67c72a90440e2bc357908aa 100644
--- a/src/test/resources/regression/verification/purescala/valid/Composition.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Composition.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/DivisionByZero.scala b/src/test/resources/regression/verification/purescala/valid/DivisionByZero.scala
index 559e13591a0b52bbee82ae42d1b5e37cfbe79a88..9ce813efee8c277b7880d04e20005b60522fc9f4 100644
--- a/src/test/resources/regression/verification/purescala/valid/DivisionByZero.scala
+++ b/src/test/resources/regression/verification/purescala/valid/DivisionByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/valid/Existentials.scala b/src/test/resources/regression/verification/purescala/valid/Existentials.scala
index 992d58cd0678e98146ad1085a22269671a35421c..471e4846363be5c06c5c86b0cabee9bf21c7f3a8 100644
--- a/src/test/resources/regression/verification/purescala/valid/Existentials.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Existentials.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Existentials {
diff --git a/src/test/resources/regression/verification/purescala/valid/Extern1.scala b/src/test/resources/regression/verification/purescala/valid/Extern1.scala
index fa48c90f7324f034b54e12c029f35e6a464cd75d..f0eb8963440eac66b053bbfb165b61b4abc96bb7 100644
--- a/src/test/resources/regression/verification/purescala/valid/Extern1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Extern1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.annotation._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Extern2.scala b/src/test/resources/regression/verification/purescala/valid/Extern2.scala
index ce5c7b683c11f27adf16cb54d416b5f860196669..aac01ec11e18b902523178422669df00e5970cce 100644
--- a/src/test/resources/regression/verification/purescala/valid/Extern2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Extern2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.annotation._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Field1.scala b/src/test/resources/regression/verification/purescala/valid/Field1.scala
index be10c683da7f6bb8c940964ddf26f0ae3e3bec06..8c410b3d9ab93b3cb2dc6502a8b355b4722fcef4 100644
--- a/src/test/resources/regression/verification/purescala/valid/Field1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Field1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Field1 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Field2.scala b/src/test/resources/regression/verification/purescala/valid/Field2.scala
index 6b52ca258823af46754f7156a8cc78b2a741c3fd..db42516e5abc5dabad55ad1decb220e7bc5227f2 100644
--- a/src/test/resources/regression/verification/purescala/valid/Field2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Field2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Field2 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/FieldInheritance.scala b/src/test/resources/regression/verification/purescala/valid/FieldInheritance.scala
index 9b99fc84c2bd3bbe8737332aa1d28576ebe4198c..68f7f4961ea9207dd757afaedad846a95b61255f 100644
--- a/src/test/resources/regression/verification/purescala/valid/FieldInheritance.scala
+++ b/src/test/resources/regression/verification/purescala/valid/FieldInheritance.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object FieldInheritance {
diff --git a/src/test/resources/regression/verification/purescala/valid/FiniteSort.scala b/src/test/resources/regression/verification/purescala/valid/FiniteSort.scala
index ead4c46cb384b28337978d67c1da9b11b6dde342..add622294d94640397d3f1ccb16595c3cea49c33 100644
--- a/src/test/resources/regression/verification/purescala/valid/FiniteSort.scala
+++ b/src/test/resources/regression/verification/purescala/valid/FiniteSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/FlatMap.scala b/src/test/resources/regression/verification/purescala/valid/FlatMap.scala
index 878b61456b6658b13f05d0e5f1b05dc25d959676..9ff0308e474ec9e679f5fa9a3c3504ae732f9da7 100644
--- a/src/test/resources/regression/verification/purescala/valid/FlatMap.scala
+++ b/src/test/resources/regression/verification/purescala/valid/FlatMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/FoldAssociative.scala b/src/test/resources/regression/verification/purescala/valid/FoldAssociative.scala
index 6920231115fea93a1b7c7cefc27691a0ee2471bb..f333c936fcc990e54e4b021fb3507ec585c68545 100644
--- a/src/test/resources/regression/verification/purescala/valid/FoldAssociative.scala
+++ b/src/test/resources/regression/verification/purescala/valid/FoldAssociative.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/FoolProofAdder.scala b/src/test/resources/regression/verification/purescala/valid/FoolProofAdder.scala
index 5e0b72e542b2c469458a226f53bdce96c9f20dfa..dfc11de525aa88f8cc613fd8a78cd8a57cba9d03 100644
--- a/src/test/resources/regression/verification/purescala/valid/FoolProofAdder.scala
+++ b/src/test/resources/regression/verification/purescala/valid/FoolProofAdder.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/ForallAssoc.scala b/src/test/resources/regression/verification/purescala/valid/ForallAssoc.scala
index ae90e9489678e1f4cc20d90b0cd23767cc317546..f001bc43563f9082a335210844f5eebdb9d8930f 100644
--- a/src/test/resources/regression/verification/purescala/valid/ForallAssoc.scala
+++ b/src/test/resources/regression/verification/purescala/valid/ForallAssoc.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object ForallAssoc {
diff --git a/src/test/resources/regression/verification/purescala/valid/Formulas.scala b/src/test/resources/regression/verification/purescala/valid/Formulas.scala
index 0fafe4158a2fcbd1b6654d21dbfa072ec42d614f..6a1529187b1c30deaf572ce18e822d636914597d 100644
--- a/src/test/resources/regression/verification/purescala/valid/Formulas.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Formulas.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Generics.scala b/src/test/resources/regression/verification/purescala/valid/Generics.scala
index 14045bf32057cc50955acc0118d845b0afbab95b..86ee9d50c2fb06b03d117ab205f659ebd9e569b7 100644
--- a/src/test/resources/regression/verification/purescala/valid/Generics.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Generics.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Generics1.scala b/src/test/resources/regression/verification/purescala/valid/Generics1.scala
index d269f21785a401991a0bc077e3fc53ae2e42bf20..e054b629fbd05c17dc0aed5fe9bb6e713f8a8f01 100644
--- a/src/test/resources/regression/verification/purescala/valid/Generics1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Generics1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/HOInvocations.scala b/src/test/resources/regression/verification/purescala/valid/HOInvocations.scala
index e536d19867234d271902b6d03e85f88edfaffc49..81fab89f9a09640347923dafdf9ef252a3176429 100644
--- a/src/test/resources/regression/verification/purescala/valid/HOInvocations.scala
+++ b/src/test/resources/regression/verification/purescala/valid/HOInvocations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/HOInvocations2.scala b/src/test/resources/regression/verification/purescala/valid/HOInvocations2.scala
index 0af2a6a0653ef86ac513ae29623f90ffb570a910..550da0cf20c0320640afbe121c8179d673b66e24 100644
--- a/src/test/resources/regression/verification/purescala/valid/HOInvocations2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/HOInvocations2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object HOInvocations2 {
diff --git a/src/test/resources/regression/verification/purescala/valid/Heaps.scala b/src/test/resources/regression/verification/purescala/valid/Heaps.scala
index aa66ca2f2a5e40ce80165a9cf0f0db8e00aa4d43..7379ad87db0455c162c24bd601c3d18695598b77 100644
--- a/src/test/resources/regression/verification/purescala/valid/Heaps.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Heaps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/InsertionSort.scala b/src/test/resources/regression/verification/purescala/valid/InsertionSort.scala
index 0ec78ff0d3050b6333e3fd1e229dd57f2e72cea2..157e3394e9e102dee74c377eea3340c69b41cdce 100644
--- a/src/test/resources/regression/verification/purescala/valid/InsertionSort.scala
+++ b/src/test/resources/regression/verification/purescala/valid/InsertionSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/InstanceOf1.scala b/src/test/resources/regression/verification/purescala/valid/InstanceOf1.scala
index 6543f94e5c66df0a073fe88770885e3bd408c0ac..6901da6c8d3cb85afe16343513cabebaa1fc59a0 100644
--- a/src/test/resources/regression/verification/purescala/valid/InstanceOf1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/InstanceOf1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object InstanceOf1 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Justify.scala b/src/test/resources/regression/verification/purescala/valid/Justify.scala
index e5b06bc94aa7228c5d1fba9e411f410a6a7a4615..b7517052c8e12650b468656df67825ea86029d7a 100644
--- a/src/test/resources/regression/verification/purescala/valid/Justify.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Justify.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.lang.synthesis._
 import leon.collection._
diff --git a/src/test/resources/regression/verification/purescala/valid/LambdaEquality.scala b/src/test/resources/regression/verification/purescala/valid/LambdaEquality.scala
index b7f589cf74109044c8caf3d86b1d04c65fb7b180..bf72524cf229b733c6e3746a2f5ceaf4d4234952 100644
--- a/src/test/resources/regression/verification/purescala/valid/LambdaEquality.scala
+++ b/src/test/resources/regression/verification/purescala/valid/LambdaEquality.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
  
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/valid/Lambdas.scala b/src/test/resources/regression/verification/purescala/valid/Lambdas.scala
index 7adbfe44856b63636c09ca661132d57504e1bbd1..b39d2c8037299e3b405721c1f553294e0d3278ce 100644
--- a/src/test/resources/regression/verification/purescala/valid/Lambdas.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Lambdas.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/ListOperations.scala b/src/test/resources/regression/verification/purescala/valid/ListOperations.scala
index 72a27c049c546696d8dd3853fe0ccdd26e077082..e711c9682ccf0f4ba08910999b5e781f977a5336 100644
--- a/src/test/resources/regression/verification/purescala/valid/ListOperations.scala
+++ b/src/test/resources/regression/verification/purescala/valid/ListOperations.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/Lists1.scala b/src/test/resources/regression/verification/purescala/valid/Lists1.scala
index 0b10f27d05354ef02fab45cc935f7f3695bee378..c946a4823151c9371a4c353b01e256e33d484593 100644
--- a/src/test/resources/regression/verification/purescala/valid/Lists1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Lists1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/Lists2.scala b/src/test/resources/regression/verification/purescala/valid/Lists2.scala
index 79126cb2226b55c811313c1c82375b977265ffc2..4edd2d1e1ec473cbec3ba5629bc59063fd485d67 100644
--- a/src/test/resources/regression/verification/purescala/valid/Lists2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Lists2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/Lists3.scala b/src/test/resources/regression/verification/purescala/valid/Lists3.scala
index dedab2a4e32aee2bf02e816ad8677e02a0a669a2..01fe747dff8b29c200c9bf84f152c62fa4d7d5f5 100644
--- a/src/test/resources/regression/verification/purescala/valid/Lists3.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Lists3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/Lists4.scala b/src/test/resources/regression/verification/purescala/valid/Lists4.scala
index 124d944da9e0769e74d43c4b3612f5a79657d9fa..1afde3867a14b3f766be00597db2e6f15a4f15dd 100644
--- a/src/test/resources/regression/verification/purescala/valid/Lists4.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Lists4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/Lists5.scala b/src/test/resources/regression/verification/purescala/valid/Lists5.scala
index 9826dc372a2a79ae733696126de8565394148ff8..627fdb9ed3ef0a1bde9886e9de849df0da0d98bc 100644
--- a/src/test/resources/regression/verification/purescala/valid/Lists5.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Lists5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/Lists6.scala b/src/test/resources/regression/verification/purescala/valid/Lists6.scala
index 763fabdaddab6a7d4732dcd2c102beb897b27d0e..13bd154b5fc69c2347d8b2b57052f26f97d88662 100644
--- a/src/test/resources/regression/verification/purescala/valid/Lists6.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Lists6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/LiteralMaps.scala b/src/test/resources/regression/verification/purescala/valid/LiteralMaps.scala
index 07894524aca4a8d5c6d1d1443df33cbdc3993058..6f03046d117c651ca00fd40dea64d46a15746f77 100644
--- a/src/test/resources/regression/verification/purescala/valid/LiteralMaps.scala
+++ b/src/test/resources/regression/verification/purescala/valid/LiteralMaps.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/MapGetOrElse2.scala b/src/test/resources/regression/verification/purescala/valid/MapGetOrElse2.scala
index 7b1e19418f09cdcf1df212934e7ca795780f4cf6..737432e7bdfe608e7065f9bb2589a422521321c0 100644
--- a/src/test/resources/regression/verification/purescala/valid/MapGetOrElse2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MapGetOrElse2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object MapGetOrElse2 {
diff --git a/src/test/resources/regression/verification/purescala/valid/MapGetPlus.scala b/src/test/resources/regression/verification/purescala/valid/MapGetPlus.scala
index 86a3d6d22b15764f66be716052ab6737f63dda91..79a1a287ca839e82ad75e5651f78b91f9dbcc11d 100644
--- a/src/test/resources/regression/verification/purescala/valid/MapGetPlus.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MapGetPlus.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object MapGetPlus {
diff --git a/src/test/resources/regression/verification/purescala/valid/MatchExh.scala b/src/test/resources/regression/verification/purescala/valid/MatchExh.scala
index 77251bc8cfc010b5adee1e662b4dfb7b1efd656a..e05c97de96670365bc36e342429f0daaf1282590 100644
--- a/src/test/resources/regression/verification/purescala/valid/MatchExh.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MatchExh.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Mean.scala b/src/test/resources/regression/verification/purescala/valid/Mean.scala
index 155b7095a112266b76fed38b3037e9412a0fa49e..9bdce687eec24155a127c2ef12018833c5fcb648 100644
--- a/src/test/resources/regression/verification/purescala/valid/Mean.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Mean.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/MergeSort.scala b/src/test/resources/regression/verification/purescala/valid/MergeSort.scala
index 9847aba0492b9760d8af766b2c5af2a34b4e24fc..5ebcc74cb5af4e42a6f034fa2c174e371bdc4e33 100644
--- a/src/test/resources/regression/verification/purescala/valid/MergeSort.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MergeSort.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/Methods.scala b/src/test/resources/regression/verification/purescala/valid/Methods.scala
index e3c71b2a552cf8cf2e86f975e59c8f55a45d1676..a2dac3cf4709c7ca5848a9fe1303a89b7de4a507 100644
--- a/src/test/resources/regression/verification/purescala/valid/Methods.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Methods.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Methods {
diff --git a/src/test/resources/regression/verification/purescala/valid/Monads1.scala b/src/test/resources/regression/verification/purescala/valid/Monads1.scala
index 19518ae9be770cccb3abf6ba0f20019b12dba240..bfaee154a03a13dbb91518a7a54b4ddb7603b863 100644
--- a/src/test/resources/regression/verification/purescala/valid/Monads1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Monads1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Monads2.scala b/src/test/resources/regression/verification/purescala/valid/Monads2.scala
index b9487c0c5f8825347f80cb0a9632ec18aa94f552..5d344032c38b223c7b4eb8388db6a9c526b15635 100644
--- a/src/test/resources/regression/verification/purescala/valid/Monads2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Monads2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Monads3.scala b/src/test/resources/regression/verification/purescala/valid/Monads3.scala
index fc0e7149b7f43455b0531c4f2502d592bbd764da..0f0e3c914b78f2762b6e098327e539f4a6a03602 100644
--- a/src/test/resources/regression/verification/purescala/valid/Monads3.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Monads3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.proof._
diff --git a/src/test/resources/regression/verification/purescala/valid/Monotonic.scala b/src/test/resources/regression/verification/purescala/valid/Monotonic.scala
index cef6be60f2d6d27ffd2eae005f649a44b9d94a2a..6a07df7d6ff35d264a85e564c41d5037f9f5fd44 100644
--- a/src/test/resources/regression/verification/purescala/valid/Monotonic.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Monotonic.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Monotonic {
diff --git a/src/test/resources/regression/verification/purescala/valid/MyMap.scala b/src/test/resources/regression/verification/purescala/valid/MyMap.scala
index b4652040a7bd9581c38475164707f13dd13060bd..f9b88ef2419cb481ee0408baa6ccbd1786b30676 100644
--- a/src/test/resources/regression/verification/purescala/valid/MyMap.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MyMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/MySet.scala b/src/test/resources/regression/verification/purescala/valid/MySet.scala
index b19be90e73d5b7981baefc3e8908c69719722de4..13efa589eba329e820726b7b8a0ba9f42907358c 100644
--- a/src/test/resources/regression/verification/purescala/valid/MySet.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MySet.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/MyTuple1.scala b/src/test/resources/regression/verification/purescala/valid/MyTuple1.scala
index 9aa42ce056da6a877f59f99f4abbacd55060d65a..55ba48e8e56c4a2b755d759851bb88568a87f0eb 100644
--- a/src/test/resources/regression/verification/purescala/valid/MyTuple1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MyTuple1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple1 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/MyTuple2.scala b/src/test/resources/regression/verification/purescala/valid/MyTuple2.scala
index 05124ffbe0d2cbd1edb448d2925d9762c767e443..8683adcdeeee636ed68e4e13f5d164f09c60688c 100644
--- a/src/test/resources/regression/verification/purescala/valid/MyTuple2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MyTuple2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple2 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/MyTuple3.scala b/src/test/resources/regression/verification/purescala/valid/MyTuple3.scala
index 20bb0eec9be4c735d6ef92abfd33e1d059fb8983..db4f82411b9e62b3a3a34cc57347a9b2c83247dd 100644
--- a/src/test/resources/regression/verification/purescala/valid/MyTuple3.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MyTuple3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple3 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/MyTuple4.scala b/src/test/resources/regression/verification/purescala/valid/MyTuple4.scala
index 8b2ede8f299cc13fe70ee5bcf41fabca7b853e6c..6dd4d3c1c6e04d7662de02a0d956fdc7d95b9547 100644
--- a/src/test/resources/regression/verification/purescala/valid/MyTuple4.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MyTuple4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 
 object MyTuple4 {
diff --git a/src/test/resources/regression/verification/purescala/valid/MyTuple5.scala b/src/test/resources/regression/verification/purescala/valid/MyTuple5.scala
index 78c93bc2a0f8e5bfcd4e58126d1ad8d5ec4bf695..d8fff88781251281e0c56c494a7f8e4d9b81bd5b 100644
--- a/src/test/resources/regression/verification/purescala/valid/MyTuple5.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MyTuple5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple5 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/MyTuple6.scala b/src/test/resources/regression/verification/purescala/valid/MyTuple6.scala
index e6cff3917d077ef83c11b5c3965204ccbe15da55..f8cc1b42393ae8bdb66f92b22061bff99c5a2cc2 100644
--- a/src/test/resources/regression/verification/purescala/valid/MyTuple6.scala
+++ b/src/test/resources/regression/verification/purescala/valid/MyTuple6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object MyTuple6 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nat.scala b/src/test/resources/regression/verification/purescala/valid/Nat.scala
index 2c6b8724aa090bb3420d8714153e59000a7b83d5..41b58248fe768b0498443806eab2e9616bf68c0b 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nat.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nat.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested1.scala b/src/test/resources/regression/verification/purescala/valid/Nested1.scala
index c705345925525557d2bbb45e4dd1dd75a4797f1c..165e42474eeb6f91ec83a285d6d59af89f91ba09 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested1 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested10.scala b/src/test/resources/regression/verification/purescala/valid/Nested10.scala
index 815582ef9964e6ab1ec75eae4ae9b2f881cef46b..d129c5313559a83ea5f730312c917afac040fac8 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested10.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested10.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested10 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested11.scala b/src/test/resources/regression/verification/purescala/valid/Nested11.scala
index 66fc9af749f887da93c06d669c09f872b71b6168..3982c342357df366a20502e58c71fd128ad2cc11 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested11.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested11.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested11 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested12.scala b/src/test/resources/regression/verification/purescala/valid/Nested12.scala
index 3ca2eb4721bfa6276b07b4995e9ae7ae9e92901e..2961a5b4ca88fba570ce9b82648a5e0a53a36df0 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested12.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested12.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested12 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested13.scala b/src/test/resources/regression/verification/purescala/valid/Nested13.scala
index 83d9a9eea3403452e305b2da1cf9d6ece0135e40..f4dc50e44b2def6bffe2350f26416ff49636db7a 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested13.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested13.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested13 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested14.scala b/src/test/resources/regression/verification/purescala/valid/Nested14.scala
index a5ac872f9d02a90e20772cc5f2c910d691f65f7c..82f4fd1b965dc06c2458d237c84eb96d23ba8349 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested14.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested14.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested14 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested15.scala b/src/test/resources/regression/verification/purescala/valid/Nested15.scala
index 5fd3650d62211bfafe18fc2f32c6da3c64f5a158..4ece21eaf45b35c0d37ef525f645a988576c6177 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested15.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested15.scala
@@ -1,5 +1,7 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.collection._
+
 object Nested15 {
 
   def foo[A](i: List[A]): BigInt = {
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested2.scala b/src/test/resources/regression/verification/purescala/valid/Nested2.scala
index 7824f983d006924d006003b5c8d05618f9fb6f16..7b70916c4e330433cc8edd2d14041baebca4baac 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested2 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested3.scala b/src/test/resources/regression/verification/purescala/valid/Nested3.scala
index 1018ff325d3bc81831cb66de130600381630965b..28ff445f84622f3dd619545296190f7b8bc05f06 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested3.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested3 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested4.scala b/src/test/resources/regression/verification/purescala/valid/Nested4.scala
index b1b8cb5c3adc1ea04833332955776b51dbee7ad9..397dd7484c3fc05feeaf024ee500360e88841088 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested4.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested4 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested5.scala b/src/test/resources/regression/verification/purescala/valid/Nested5.scala
index 0cbd6b509b6eb042ddb30ea3a29e00dcae7df4e3..736c0f6bf7fb3932e8531e7eca1e4777ea450a89 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested5.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested5 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested6.scala b/src/test/resources/regression/verification/purescala/valid/Nested6.scala
index 57e448444e9b5e977671af97268e695849263d72..6d6df90a40251625459f79efa7e9a5fa31493790 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested6.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested6 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested7.scala b/src/test/resources/regression/verification/purescala/valid/Nested7.scala
index 3238de81336ce76971fcdc9208789b375cdee29d..b9e986311ced8eba6b505e449d1ffaaab49be016 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested7.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested7.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested7 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested8.scala b/src/test/resources/regression/verification/purescala/valid/Nested8.scala
index 9f18dfe1d2a3d3ed18c74d25da9e442926486d7d..67c81f414d9a8a95443c2b0e6cc01049a9e9e4c0 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested8.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested8.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Nested9.scala b/src/test/resources/regression/verification/purescala/valid/Nested9.scala
index 3e7df6d9e5d250125d46f31f93bb301a870af764..ae029ad6804015161a952998a7700d5fd39e6d89 100644
--- a/src/test/resources/regression/verification/purescala/valid/Nested9.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Nested9.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Nested9 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/NotEquals.scala b/src/test/resources/regression/verification/purescala/valid/NotEquals.scala
index 23d857db511883d86d40b5a078f306e59eb9dd8e..31a4bc763600ac9a8e0b5d0cc4bec308cc110955 100644
--- a/src/test/resources/regression/verification/purescala/valid/NotEquals.scala
+++ b/src/test/resources/regression/verification/purescala/valid/NotEquals.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/Overrides.scala b/src/test/resources/regression/verification/purescala/valid/Overrides.scala
index 4b6767e6b80e7159c223a022762cd5080f65d84e..749fec7e04f03a76bdb8d806ac245cf3d26ead83 100644
--- a/src/test/resources/regression/verification/purescala/valid/Overrides.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Overrides.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Overrides {
   abstract class A {
     def x(a: Int): Int
diff --git a/src/test/resources/regression/verification/purescala/valid/ParBalance.scala b/src/test/resources/regression/verification/purescala/valid/ParBalance.scala
index 35ca7537645182c003ebd3e8003e6db7c5648de2..a1e5ea1edd578cfd59ddb81723acdb2fdb2d8dea 100644
--- a/src/test/resources/regression/verification/purescala/valid/ParBalance.scala
+++ b/src/test/resources/regression/verification/purescala/valid/ParBalance.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/PositiveMap.scala b/src/test/resources/regression/verification/purescala/valid/PositiveMap.scala
index 93c87331e272d6b9a989bdd757b8bcce5ce3072e..a9a07c9850de6d9e9c7de498996d9f1b16d6d532 100644
--- a/src/test/resources/regression/verification/purescala/valid/PositiveMap.scala
+++ b/src/test/resources/regression/verification/purescala/valid/PositiveMap.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/PositiveMap2.scala b/src/test/resources/regression/verification/purescala/valid/PositiveMap2.scala
index eb2262f02e3ebfc65dd7a40fa4db4741baafeb34..ea8ccbdf51ccde121fa76070123a49a9cd0f08c5 100644
--- a/src/test/resources/regression/verification/purescala/valid/PositiveMap2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/PositiveMap2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Postcondition.scala b/src/test/resources/regression/verification/purescala/valid/Postcondition.scala
index e044a9a3adc1214bb1ce917b6be3785be1fd93fe..d4303a79914c81743758fa049e1926032f2057f7 100644
--- a/src/test/resources/regression/verification/purescala/valid/Postcondition.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Postcondition.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Postconditions {
diff --git a/src/test/resources/regression/verification/purescala/valid/PreInSpecs.scala b/src/test/resources/regression/verification/purescala/valid/PreInSpecs.scala
index 988f7331aac7f839ff01d7550cfa9f72b90ecc71..314c2c5878937839a0a746d694c15556989a323f 100644
--- a/src/test/resources/regression/verification/purescala/valid/PreInSpecs.scala
+++ b/src/test/resources/regression/verification/purescala/valid/PreInSpecs.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object PreInSpecs {
diff --git a/src/test/resources/regression/verification/purescala/valid/Predicate.scala b/src/test/resources/regression/verification/purescala/valid/Predicate.scala
index c011d4b910c2d3859b0e2cca80e069de5b19788b..b1d560d7ac9cc248f0b294c3a4e04b2be3141e50 100644
--- a/src/test/resources/regression/verification/purescala/valid/Predicate.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Predicate.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.monads.predicate
 
 import leon.collection._
diff --git a/src/test/resources/regression/verification/purescala/valid/PropositionalLogic.scala b/src/test/resources/regression/verification/purescala/valid/PropositionalLogic.scala
index 66e3f84ecfa11a460c6e721f69cb44d51def285e..fa7c0cf487cca517f1b134b0acb7ba02a93ebe3d 100644
--- a/src/test/resources/regression/verification/purescala/valid/PropositionalLogic.scala
+++ b/src/test/resources/regression/verification/purescala/valid/PropositionalLogic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/valid/RealDivisionByZero.scala b/src/test/resources/regression/verification/purescala/valid/RealDivisionByZero.scala
index 3d8dcf5b24e4cf63688ac8d4786be52745e2dd81..c6d44938e0cd2aab612cc679dd2aa6a4b59e0277 100644
--- a/src/test/resources/regression/verification/purescala/valid/RealDivisionByZero.scala
+++ b/src/test/resources/regression/verification/purescala/valid/RealDivisionByZero.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/purescala/valid/RedBlackTree.scala b/src/test/resources/regression/verification/purescala/valid/RedBlackTree.scala
index e24935bbedb8f87e0778f29f44f3a4758560fc11..a40068e7081dc594d7419e38f436cbca3751f8da 100644
--- a/src/test/resources/regression/verification/purescala/valid/RedBlackTree.scala
+++ b/src/test/resources/regression/verification/purescala/valid/RedBlackTree.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/purescala/valid/SearchLinkedList.scala b/src/test/resources/regression/verification/purescala/valid/SearchLinkedList.scala
index 882dfa14001698091f09b51c67e346d1a74480b0..e35e6bc0e96ba7aaa322705f4cfe569a1bb1bf6a 100644
--- a/src/test/resources/regression/verification/purescala/valid/SearchLinkedList.scala
+++ b/src/test/resources/regression/verification/purescala/valid/SearchLinkedList.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.annotation._
diff --git a/src/test/resources/regression/verification/purescala/valid/Sets1.scala b/src/test/resources/regression/verification/purescala/valid/Sets1.scala
index 0cfc5426304ca464eeb3f61ce09cca5ffce6d88c..ff0d0421b0a344b248f445743dbfcd09bb101d06 100644
--- a/src/test/resources/regression/verification/purescala/valid/Sets1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Sets1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Sets2.scala b/src/test/resources/regression/verification/purescala/valid/Sets2.scala
index 6d798afcc387c4586bbf9d8ff0bf568648f51f9f..1ea7ca0238f5b01e5e18c77f677ddabec9831f0d 100644
--- a/src/test/resources/regression/verification/purescala/valid/Sets2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Sets2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/SimpleQuantification.scala b/src/test/resources/regression/verification/purescala/valid/SimpleQuantification.scala
index 5e7e9cb339037a0acc73a4f66e4c07bac61e7df1..4784d2c1786f5dbcd4ddd5f058f71ab8aa7c78d9 100644
--- a/src/test/resources/regression/verification/purescala/valid/SimpleQuantification.scala
+++ b/src/test/resources/regression/verification/purescala/valid/SimpleQuantification.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Simple {
diff --git a/src/test/resources/regression/verification/purescala/valid/Subtyping1.scala b/src/test/resources/regression/verification/purescala/valid/Subtyping1.scala
index c7e8bd533ed8e7b49301a903b79939810884a5f7..8b5d7e4b5ec0e55fffbabd949b7e6081827553a2 100644
--- a/src/test/resources/regression/verification/purescala/valid/Subtyping1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Subtyping1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Subtyping2.scala b/src/test/resources/regression/verification/purescala/valid/Subtyping2.scala
index eef9c65da55c0b4d0ed76802a82c720f79fd44e7..bbb436b6a134a427e97aab1527fbaaeea49a16c9 100644
--- a/src/test/resources/regression/verification/purescala/valid/Subtyping2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Subtyping2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/TransitiveQuantification.scala b/src/test/resources/regression/verification/purescala/valid/TransitiveQuantification.scala
index 5e7bb03cd858c34f9876de1ecc723e010fdab162..c622bc13921401d7d1dd7e4b5074e111bcbfffac 100644
--- a/src/test/resources/regression/verification/purescala/valid/TransitiveQuantification.scala
+++ b/src/test/resources/regression/verification/purescala/valid/TransitiveQuantification.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object Transitive {
diff --git a/src/test/resources/regression/verification/purescala/valid/Trees1.scala b/src/test/resources/regression/verification/purescala/valid/Trees1.scala
index de892510c72e681b874d946d11c33b0e25b2d1af..cb0b02900ae77bdce3043fe0b901ab055bcfee1e 100644
--- a/src/test/resources/regression/verification/purescala/valid/Trees1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Trees1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Unapply.scala b/src/test/resources/regression/verification/purescala/valid/Unapply.scala
index 1885837d990c32185a42c1232a53de48c3935340..0113f68d7e4ea324407feffbcf3b5293001ab7f4 100644
--- a/src/test/resources/regression/verification/purescala/valid/Unapply.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Unapply.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._ 
 object Unap {
   def unapply[A, B](i: (Int, B, A)): Option[(A, B)] = 
diff --git a/src/test/resources/regression/verification/purescala/valid/Unit1.scala b/src/test/resources/regression/verification/purescala/valid/Unit1.scala
index a0683d303545f782004fda587e520c5abf676c02..596f7cc319bddcf495fd281e820a0f5bc7f1144f 100644
--- a/src/test/resources/regression/verification/purescala/valid/Unit1.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Unit1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Unit1 {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/Unit2.scala b/src/test/resources/regression/verification/purescala/valid/Unit2.scala
index 8a285ff23af02ff1ae907fd714da0ae46141db50..1aa3cf55bdd9de42855d7a7311a73f47256c917a 100644
--- a/src/test/resources/regression/verification/purescala/valid/Unit2.scala
+++ b/src/test/resources/regression/verification/purescala/valid/Unit2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Unit2 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Array1.scala b/src/test/resources/regression/verification/xlang/invalid/Array1.scala
index 7dea56cb41783c40131e44dd087bd5c5a12d6bcc..b1e032aaafe435589e44f01c61fc7ec7d00defeb 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Array1.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Array1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Array1 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Array2.scala b/src/test/resources/regression/verification/xlang/invalid/Array2.scala
index 94fed91baa4407e901b8cfccd7c6ce9a06e40540..2785ca22853f1c597f7ab227c5bcb15999beb420 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Array2.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Array2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Array2 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Array3.scala b/src/test/resources/regression/verification/xlang/invalid/Array3.scala
index 23eeb888b3e7ae74ed4cae93e0da91aa06d78c45..4d785c176ecc84380919e2ee9eea6bd8a36bcbde 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Array3.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Array3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Assert1.scala b/src/test/resources/regression/verification/xlang/invalid/Assert1.scala
index 8027179df9bcda58c7300e571506f481bb78791e..8febd5aa3e3c1e4cc6fc119a8fa1265b9b59cb8f 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Assert1.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Assert1.scala
@@ -1,4 +1,4 @@
-package test.resources.regression.verification.xlang.invalid
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 /* Copyright 2009-2015 EPFL, Lausanne */
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Assert2.scala b/src/test/resources/regression/verification/xlang/invalid/Assert2.scala
index cc8b2a591015ea765a1549a75b51821770c3c9bf..1dee8a90f7ce907c033e0f469c01e4255e7328fd 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Assert2.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Assert2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Assert2 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/Asserts2.scala b/src/test/resources/regression/verification/xlang/invalid/Asserts2.scala
index bfda82471559f5ce6c631cf6fd2ca97cf2bbed06..3942d933790308440ff976070e523e9651873717 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Asserts2.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Asserts2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.annotation._
 import leon.lang._
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala
index af706720ad67e9fad8f0b93908e4174d7206a36e..c35318dfed394f4b6110d53406655144253a13fa 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala
index b6983c8161b7f26efe03bd1c70503b29bc88bc50..a7e89366e08778fdfe562299034520c5d1127d3e 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala
index 2e0609389afc8427975379386a034bd8a1436b61..d32c1ba84081174d2aa499002ff6c59bcfad3585 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala
index e5b9507b51af49df0c29ff4e3a07b0f83bb674ec..1fc7ebcd9a2efff9698d06c113e1350638f06cd6 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala
index 5d8cacbe815b10fccde1748588587e844cf3ed39..0ba2717472bfb71fa423c76afc435d33199ce077 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala b/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala
index 9ef936b5acc5a4afab6ae6b283cc4eaed6288b34..c2144cce492d8ea1babc2aca2006246234c530b0 100644
--- a/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/Epsilon6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/invalid/FunctionCaching.scala b/src/test/resources/regression/verification/xlang/invalid/FunctionCaching.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1ba4c5b2855f504cc8b0e669678dfd3ba47edbba
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/invalid/FunctionCaching.scala
@@ -0,0 +1,33 @@
+import leon.lang._
+import leon.collection._
+
+object FunctionCaching {
+
+  case class FunCache(var cached: Map[BigInt, BigInt])
+
+  def fun(x: BigInt)(implicit funCache: FunCache): BigInt = {
+    funCache.cached.get(x) match {
+      case None() => 
+        val res = 2*x + 42
+        funCache.cached = funCache.cached.updated(x, res)
+        res
+      case Some(cached) =>
+        cached + 1
+    }
+  }
+
+  def funWronglyCached(x: BigInt, trash: List[BigInt]): Boolean = {
+    implicit val cache = FunCache(Map())
+    val res1 = fun(x)
+    multipleCalls(trash)
+    val res2 = fun(x)
+    res1 == res2
+  } holds
+
+
+  def multipleCalls(args: List[BigInt])(implicit funCache: FunCache): Unit = args match {
+    case Nil() => ()
+    case x::xs => fun(x); multipleCalls(xs)
+  }
+
+}
diff --git a/src/test/resources/regression/verification/xlang/invalid/IfExpr1.scala b/src/test/resources/regression/verification/xlang/invalid/IfExpr1.scala
index 0e62acffeb9db3afef6d268407b0404c3f5d96a8..7ddaac162c1e9d02caac2c9e1028c188492ad3be 100644
--- a/src/test/resources/regression/verification/xlang/invalid/IfExpr1.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/IfExpr1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object IfExpr1 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/IfExpr2.scala b/src/test/resources/regression/verification/xlang/invalid/IfExpr2.scala
index 154c653700ed4625d9ef1b2fc4f2c7d78c72c446..4126d6636083f1f3a4bd374fa4572a67dc6089dd 100644
--- a/src/test/resources/regression/verification/xlang/invalid/IfExpr2.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/IfExpr2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object IfExpr2 {
 
diff --git a/src/test/resources/regression/verification/xlang/invalid/NestedFunState1.scala b/src/test/resources/regression/verification/xlang/invalid/NestedFunState1.scala
index 9372ea742a278a3da3d476dca57e52c55c09b978..abd623d29ec40f2b3a85f6ebfe77dc9ad4425309 100644
--- a/src/test/resources/regression/verification/xlang/invalid/NestedFunState1.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/NestedFunState1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object NestedFunState1 {
 
   def simpleSideEffect(n: BigInt): BigInt = {
diff --git a/src/test/resources/regression/verification/xlang/invalid/NestedFunState2.scala b/src/test/resources/regression/verification/xlang/invalid/NestedFunState2.scala
index 68769df28353c9defa6d33000bb8ae4de21c7ace..394feb4469cb4003074f1250ab36358eae62bc54 100644
--- a/src/test/resources/regression/verification/xlang/invalid/NestedFunState2.scala
+++ b/src/test/resources/regression/verification/xlang/invalid/NestedFunState2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object NestedFunState2 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Arithmetic.scala b/src/test/resources/regression/verification/xlang/valid/Arithmetic.scala
index 2952f49c5c43c16b95fffadb314761b6681dd965..7febf126c5dccd96f856aba9730b82e34c3fd8d4 100644
--- a/src/test/resources/regression/verification/xlang/valid/Arithmetic.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Arithmetic.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Array1.scala b/src/test/resources/regression/verification/xlang/valid/Array1.scala
index 644e0d5e9afc7ff5def3952eae4f89146a68cf06..09379018f760c6d3ddcc2ed11d7d877ebe4a1a42 100644
--- a/src/test/resources/regression/verification/xlang/valid/Array1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Array1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Array1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Array2.scala b/src/test/resources/regression/verification/xlang/valid/Array2.scala
index 85bcbb17affee3b011a0dd59cdcf73175262f65a..b5e23aa7affa9ba0e3afc60c9d84a5c6519cb002 100644
--- a/src/test/resources/regression/verification/xlang/valid/Array2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Array2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Array2 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Array3.scala b/src/test/resources/regression/verification/xlang/valid/Array3.scala
index 3cd26b2e8fc8b84398845f441bb814df5c94cf26..ece86335b47ac18e6ba99ddf893e626542b0b17e 100644
--- a/src/test/resources/regression/verification/xlang/valid/Array3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Array3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Array4.scala b/src/test/resources/regression/verification/xlang/valid/Array4.scala
index 6543a00c405346b407f47126db2a6e3455dbde2a..0b7374d6ecb2bbdee85c58a451eff80a04141c3a 100644
--- a/src/test/resources/regression/verification/xlang/valid/Array4.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Array4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Array5.scala b/src/test/resources/regression/verification/xlang/valid/Array5.scala
index 491205a038d7f99ec5b17fe54264a4ad86ae4c18..7cdc2173775c6c2a5b91b2b262e6356e2cc8ea0b 100644
--- a/src/test/resources/regression/verification/xlang/valid/Array5.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Array5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Array6.scala b/src/test/resources/regression/verification/xlang/valid/Array6.scala
index ffcc9e3621ede9050a85b19ce2651d57a71b3680..7c16ca9aed73fefbe21daa674d8757395639ceb8 100644
--- a/src/test/resources/regression/verification/xlang/valid/Array6.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Array6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Array7.scala b/src/test/resources/regression/verification/xlang/valid/Array7.scala
index aad31e4ff8453226d4ab367d6f1ed6ed85ee7308..0efc14e8fd74a08dac9d43c07aa3b801f98e59ed 100644
--- a/src/test/resources/regression/verification/xlang/valid/Array7.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Array7.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/valid/ArrayNested1.scala b/src/test/resources/regression/verification/xlang/valid/ArrayNested1.scala
index 196a6442bd544a3981e6a7de7e923e040cadd32d..f698242c17eed2338fb73625a344c1c0d1de651d 100644
--- a/src/test/resources/regression/verification/xlang/valid/ArrayNested1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/ArrayNested1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object ArrayNested1 {
diff --git a/src/test/resources/regression/verification/xlang/valid/ArrayNested2.scala b/src/test/resources/regression/verification/xlang/valid/ArrayNested2.scala
index a8935ab8c1d4eec6980b85f171e695071f2a9442..5b2407b57138ff2b8fd20c27b47bf8026f3f120d 100644
--- a/src/test/resources/regression/verification/xlang/valid/ArrayNested2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/ArrayNested2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object ArrayNested2 {
diff --git a/src/test/resources/regression/verification/xlang/valid/Assert1.scala b/src/test/resources/regression/verification/xlang/valid/Assert1.scala
index d9ae5c6753320b35d193042044144a91ecf19070..8f2199ad224d7224df85a9addd82e1be7279462d 100644
--- a/src/test/resources/regression/verification/xlang/valid/Assert1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Assert1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Assert1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Assert2.scala b/src/test/resources/regression/verification/xlang/valid/Assert2.scala
index 0f5131346f9e9b56ab3a08198cc8a3bb87049fd3..64002e2cf37d54d0ead83c643b69a1b0306c3677 100644
--- a/src/test/resources/regression/verification/xlang/valid/Assert2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Assert2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Assert2 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Assert3.scala b/src/test/resources/regression/verification/xlang/valid/Assert3.scala
index 49e2f6c55c0f43ffd8dc16b016b13d363f62735a..bd29aae41f726ddf700865cbb7d0782abf17c7f7 100644
--- a/src/test/resources/regression/verification/xlang/valid/Assert3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Assert3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Assign1.scala b/src/test/resources/regression/verification/xlang/valid/Assign1.scala
index cbf5c009d8e45928e2a6f059140f6cfaa001b57f..2f812d48a08e64eaf6161bae80b3aca75c12c5b6 100644
--- a/src/test/resources/regression/verification/xlang/valid/Assign1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Assign1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Assign1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala
index 93d5ae083c60b13b281ffe16af0f546176d47ce1..8c91e3f7ffa5dc81ce87bfdc7f9540d92c5add1c 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala
index 671ddb000f90b6087a62a920144f3467b9a31777..6506c4d97c71b59c1d3edb16dca33bdc238911eb 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala
index 64899cb7844d4e4310501d217f4ede8e881e83cd..e1103e2f1166c7b1cc2b4d10c900af06a12405d0 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala
index df8cd36b874bf4db01811b67b9aa87ca51b103f4..248bf0f1d562ed3dc1b72bbbed9b7180d8c2912c 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala b/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala
index 8d608604d69ddbd7394c81ca3dc29e24ad25be89..80cbb2bc9c79c02867d1c64af1b38ca81e2fb0e2 100644
--- a/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Epsilon5.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 import leon.lang._
 import leon.lang.xlang._
diff --git a/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder1.scala b/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder1.scala
index 8ef668a2afeb61a6b305831358a65e675bf670ed..23576c1fcdef0717d35ba362bb6043a4e3a86c24 100644
--- a/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object FunInvocEvaluationOrder1 {
 
   def test(): Int = {
diff --git a/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder2.scala b/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder2.scala
index 12090f0f3fad0a5fcf2451e30fdb6f25bb09c590..c37ab1045eec87938624f573ec2ea4b0a99f0c8a 100644
--- a/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object FunInvocEvaluationOrder2 {
 
   def leftToRight(n: BigInt): BigInt = {
diff --git a/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder3.scala b/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder3.scala
index f263529653486ee5477b9fd1934760bcdc737d15..e6c1b37ddff3a50f728d66b1855689175e2e1d01 100644
--- a/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/FunInvocEvaluationOrder3.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object FunInvocEvaluationOrder3 {
 
   def leftToRight(n: BigInt): BigInt = {
diff --git a/src/test/resources/regression/verification/xlang/valid/FunctionCaching.scala b/src/test/resources/regression/verification/xlang/valid/FunctionCaching.scala
new file mode 100644
index 0000000000000000000000000000000000000000..322cb592ee44a65add6f1eed42ba8fea7fba4155
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/FunctionCaching.scala
@@ -0,0 +1,40 @@
+import leon.lang._
+import leon.collection._
+
+object FunctionCaching {
+
+  case class FunCache(var cached: Map[BigInt, BigInt])
+
+  def fun(x: BigInt)(implicit funCache: FunCache): BigInt = {
+    funCache.cached.get(x) match {
+      case None() => 
+        val res = 2*x + 42
+        funCache.cached = funCache.cached.updated(x, res)
+        res
+      case Some(cached) =>
+        cached
+    }
+  } ensuring(res => old(funCache).cached.get(x) match {
+    case None() => true
+    case Some(v) => v == res
+  })
+
+  def funProperlyCached(x: BigInt, trash: List[BigInt]): Boolean = {
+    implicit val cache = FunCache(Map())
+    val res1 = fun(x)
+    multipleCalls(trash, x)
+    val res2 = fun(x)
+    res1 == res2
+  } holds
+
+  def multipleCalls(args: List[BigInt], x: BigInt)(implicit funCache: FunCache): Unit = {
+    require(funCache.cached.get(x).forall(_ == 2*x + 42))
+    args match {
+      case Nil() => ()
+      case y::ys => 
+        fun(y)
+        multipleCalls(ys, x)
+    }
+  } ensuring(_ => funCache.cached.get(x).forall(_ == 2*x + 42))
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/IfExpr1.scala b/src/test/resources/regression/verification/xlang/valid/IfExpr1.scala
index c32f4f97e63438e9862525390eb020ccf3e95064..a9ffdabcc84f9f8d2cd7a1e8ce715fa5ae09ec9d 100644
--- a/src/test/resources/regression/verification/xlang/valid/IfExpr1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/IfExpr1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object IfExpr1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/IfExpr2.scala b/src/test/resources/regression/verification/xlang/valid/IfExpr2.scala
index a848d20916bb8c132064918e9d1db46f634a94d7..c439ea5938b428b396f115d59ee584a82d025f4b 100644
--- a/src/test/resources/regression/verification/xlang/valid/IfExpr2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/IfExpr2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object IfExpr2 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/IfExpr3.scala b/src/test/resources/regression/verification/xlang/valid/IfExpr3.scala
index 352f89b9e1aa872592577959ddec622917b2a44f..f71fb9cbaa32266074940a44c507a00e8ccfb30e 100644
--- a/src/test/resources/regression/verification/xlang/valid/IfExpr3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/IfExpr3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object IfExpr3 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/IfExpr4.scala b/src/test/resources/regression/verification/xlang/valid/IfExpr4.scala
index 43c43fb15ac347f4fdd82f971947df638fdd270a..e0335300ec0c4dbd56e8ce75837c7f08252127b1 100644
--- a/src/test/resources/regression/verification/xlang/valid/IfExpr4.scala
+++ b/src/test/resources/regression/verification/xlang/valid/IfExpr4.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object IfExpr4 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedFunState1.scala b/src/test/resources/regression/verification/xlang/valid/NestedFunState1.scala
index 1ec0266f846dd55cfa1a6274d5c6dc7dc67dd125..cb649ef1cbc11be29b3249128744dbc7665447da 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedFunState1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedFunState1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object NestedFunState1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedFunState2.scala b/src/test/resources/regression/verification/xlang/valid/NestedFunState2.scala
index e48b1b959b3a83262329cf48c63370a2b591cd41..d42eb0d59f8b4b1cf74823504013d73e555ae812 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedFunState2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedFunState2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object NestedFunState2 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedFunState3.scala b/src/test/resources/regression/verification/xlang/valid/NestedFunState3.scala
index 650f5987dcd352a3f5c47d41c684e94d4b9be20c..3a796c0d10f236c09663d50b4d6a28a6d48f28c3 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedFunState3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedFunState3.scala
@@ -1,4 +1,5 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object NestedFunState3 {
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedFunState4.scala b/src/test/resources/regression/verification/xlang/valid/NestedFunState4.scala
index 9f4fb2621f60c60da3a677dc732e6c93f4d8ae72..4838242de9b983a1ab3d105fa67cfe9ef134237f 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedFunState4.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedFunState4.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object NestedFunState4 {
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedFunState5.scala b/src/test/resources/regression/verification/xlang/valid/NestedFunState5.scala
index 13f3cf47cd0ee6c831f12877493cbfe6c7edea5a..e60ff32cd6263f8978868b004d4c7e1437e56f81 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedFunState5.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedFunState5.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object NestedFunState5 {
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedFunState6.scala b/src/test/resources/regression/verification/xlang/valid/NestedFunState6.scala
index cea0f2e1900a00bc803df4107b46dd62cf082c68..15d2e75eb1373b7c369b2255c8b6d6ab2bcff480 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedFunState6.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedFunState6.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object NestedFunState6 {
 
   def simpleSideEffect(n: BigInt): BigInt = {
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedFunState7.scala b/src/test/resources/regression/verification/xlang/valid/NestedFunState7.scala
index ff2418a0c972add2d48c08f6319905f35d0493c2..e4d07f4ad1ee361a17243c2e0b475ae68a89b6e0 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedFunState7.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedFunState7.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object NestedFunState7 {
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedOld1.scala b/src/test/resources/regression/verification/xlang/valid/NestedOld1.scala
index 903dfd63aca5105c9366c459552865646139033e..d93276e0ed432ce015a927ab5231bf6be17efb5b 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedOld1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedOld1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object NestedOld1 {
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedOld2.scala b/src/test/resources/regression/verification/xlang/valid/NestedOld2.scala
index fe6143ecf623c295251ca2b9d75d6474d422fd4f..3bd75e35ca84ea7e0893ea552875410132623c6c 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedOld2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedOld2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object NestedOld2 {
diff --git a/src/test/resources/regression/verification/xlang/valid/NestedVar.scala b/src/test/resources/regression/verification/xlang/valid/NestedVar.scala
index 0aeb48be5fd9cb4242f03ea381275c85081fcd8c..a9b864cb4830a888feec4a8db82f7582752a5008 100644
--- a/src/test/resources/regression/verification/xlang/valid/NestedVar.scala
+++ b/src/test/resources/regression/verification/xlang/valid/NestedVar.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object NestedVar {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation1.scala b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation1.scala
new file mode 100644
index 0000000000000000000000000000000000000000..52e7083346486740d2915835ea584a7fcb020f06
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation1.scala
@@ -0,0 +1,13 @@
+import leon.lang._
+
+object ObjectHierarchyMutation1 {
+
+  case class A(var y: Int)
+  case class B(a: A)
+
+  def update(b: B): Int = {
+    b.a.y = 17
+    b.a.y
+  } ensuring(res => res == 17)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation2.scala b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation2.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1d1df5dc47dc202cb502e252614dfd3293f8d2d3
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation2.scala
@@ -0,0 +1,19 @@
+import leon.lang._
+
+object ObjectHierarchyMutation2 {
+
+  case class A(var y: Int)
+  case class B(a: A)
+
+  def update(b: B): Int = {
+    b.a.y = 17
+    b.a.y
+  }
+
+  def f(): Int = {
+    val b = B(A(10))
+    update(b)
+    b.a.y
+  } ensuring(res => res == 17)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation3.scala b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation3.scala
new file mode 100644
index 0000000000000000000000000000000000000000..67df97f0467312148b013569aede16c9c52f0480
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation3.scala
@@ -0,0 +1,19 @@
+import leon.lang._
+
+object ObjectHierarchyMutation3 {
+
+  case class A(var x: Int, var y: Int, var z: Int)
+  case class B(a1: A, a2: A, a3: A)
+
+  def update(b: B): Int = {
+    b.a2.y = 17
+    b.a2.y
+  } ensuring(res => res == 17)
+
+  def f(): Int = {
+    val b = B(A(10, 11, 12), A(11, 12, 13), A(13, 14, 15))
+    update(b)
+    b.a2.y
+  } ensuring(res => res == 17)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation4.scala b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation4.scala
new file mode 100644
index 0000000000000000000000000000000000000000..807142699cf8fbf85b200759936a612379fad7ac
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation4.scala
@@ -0,0 +1,27 @@
+import leon.lang._
+
+object ObjectHierarchyMutation4 {
+
+  case class A(var x: Int, var y: Int)
+  case class B(a1: A, a2: A)
+  case class C(b1: B, b2: B)
+
+  def update(c: C): Int = {
+    c.b1.a2.y = 17
+    c.b1.a2.y
+  } ensuring(res => res == 17)
+
+  def f(): Int = {
+    val c = C(B(A(10, 10), A(12, 13)), B(A(10, 10), A(14, 15)))
+    update(c)
+    c.b1.a2.y
+  } ensuring(res => res == 17)
+
+  def multipleUpdate(c: C): Unit = {
+    c.b1.a2.y = 13
+    c.b1.a2.x = 10
+    c.b1.a1.x = 15
+    c.b2.a1.y = 22
+  } ensuring(_ => c.b1.a2.y == 13 && c.b1.a2.x == 10 && c.b1.a1.x == 15 && c.b2.a1.y == 22 && c.b2.a2.y == old(c).b2.a2.y)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation5.scala b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation5.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ab237ab281d60effcf078bd0c536dacd0edb8aad
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation5.scala
@@ -0,0 +1,18 @@
+import leon.lang._
+
+object ObjectHierarchyMutation5 {
+
+  case class A(var x: Int)
+  case class B(a: A)
+  case class C(b: B)
+
+  def updateA(a: A): Unit = {
+    a.x = 43
+  }
+
+  def update(c: C): Int = {
+    updateA(c.b.a)
+    c.b.a.x
+  } ensuring(res => res == 43)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation6.scala b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation6.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7361adf0068fbad093382620c18c6aed40f9802e
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation6.scala
@@ -0,0 +1,18 @@
+import leon.lang._
+
+object ObjectHierarchyMutation6 {
+
+  case class A(var x: Int, var y: Int)
+  case class B(a1: A, a2: A)
+  case class C(b1: B, b2: B)
+
+  def updateA(a: A): Unit = {
+    a.x = 43
+  }
+
+  def update(c: C): Int = {
+    updateA(c.b2.a1)
+    c.b2.a1.x
+  } ensuring(res => res == 43)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation7.scala b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation7.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f9c7a9198dfb90cf3545e28beabdfe2489480983
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectHierarchyMutation7.scala
@@ -0,0 +1,18 @@
+import leon.lang._
+
+object ObjectHierarchyMutation7 {
+
+  case class A(var x: Int, var y: Int)
+  case class B(a1: A, a2: A)
+  case class C(b1: B, b2: B)
+
+  def updateB(b: B): Unit = {
+    b.a1.x = 43
+  }
+
+  def update(c: C): Int = {
+    updateB(c.b2)
+    c.b2.a1.x
+  } ensuring(res => res == 43)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation1.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation1.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b36fd6f1a3a59864c5cca195f17264b382b6652e
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation1.scala
@@ -0,0 +1,18 @@
+import leon.lang._
+
+object ObjectParamMutation1 {
+
+  case class A(var y: Int)
+
+  def update(a: A): Int = {
+    a.y = 12
+    a.y
+  } ensuring(res => res == 12)
+
+  def f(): Int = {
+    val a = A(10)
+    update(a)
+    a.y
+  } ensuring(res => res == 12)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation2.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation2.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7a7590eb3644633ac479de81e3a046109aa48b4c
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation2.scala
@@ -0,0 +1,17 @@
+import leon.lang._
+
+object ObjectParamMutation2 {
+
+  case class A(var y: Int)
+
+  def update(a: A): Unit = {
+    a.y = 12
+  } ensuring(_ => a.y == 12)
+
+  def f(): Int = {
+    val a = A(10)
+    update(a)
+    a.y
+  } ensuring(res => res == 12)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation3.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation3.scala
new file mode 100644
index 0000000000000000000000000000000000000000..95c88cb571e52e434155c052f0dba750a4fc81a6
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation3.scala
@@ -0,0 +1,17 @@
+import leon.lang._
+
+object ObjectParamMutation3 {
+
+  case class A(var y: Int)
+
+  def update(a: A): Unit = {
+    a.y = a.y + 3
+  } ensuring(_ => a.y == old(a).y + 3)
+
+  def f(): Int = {
+    val a = A(10)
+    update(a)
+    a.y
+  } ensuring(res => res == 13)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation4.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation4.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5b50ddb63a9be4ee36cfb39a71ea19b766da9d70
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation4.scala
@@ -0,0 +1,22 @@
+import leon.lang._
+
+object ObjectParamMutation4 {
+
+  case class A(var y: Int)
+
+  def swapY(a1: A, a2: A): Unit = {
+    val tmp = a1.y
+    a1.y = a2.y
+    a2.y = tmp
+  } ensuring(_ => a1.y == old(a2).y && a2.y == old(a1).y)
+
+  def f(): (Int, Int) = {
+    val a1 = A(10)
+    val a2 = A(10)
+    a1.y = 12
+    a2.y = 42
+    swapY(a1, a2)
+    (a1.y, a2.y)
+  } ensuring(res => res._1 == 42 && res._2 == 12)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation5.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation5.scala
new file mode 100644
index 0000000000000000000000000000000000000000..38580345d6540ab92625ba199da2f11b536ae3be
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation5.scala
@@ -0,0 +1,19 @@
+import leon.lang._
+
+object ObjectParamMutation5 {
+
+  case class A(var x: Int, var y: Int)
+
+  def swap(a: A): Unit = {
+    val tmp = a.x
+    a.x = a.y
+    a.y = tmp
+  } ensuring(_ => a.x == old(a).y && a.y == old(a).x)
+
+  def f(): A = {
+    val a = A(10, 13)
+    swap(a)
+    a
+  } ensuring(res => res.x == 13 && res.y == 10)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation6.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation6.scala
new file mode 100644
index 0000000000000000000000000000000000000000..6c917ff1b4c85e6deabf41cfbadfd0097138c315
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation6.scala
@@ -0,0 +1,17 @@
+import leon.lang._
+
+object ObjectParamMutation6 {
+
+  case class A(var x: BigInt)
+
+  def inc(a: A): Unit = {
+    a.x += 1
+  } ensuring(_ => a.x == old(a).x + 1)
+
+  def f(): BigInt = {
+    val a = A(0)
+    inc(a); inc(a); inc(a)
+    a.x
+  } ensuring(res => res == 3)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation7.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation7.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9f664837e3cc56cdd78a9daab7b3587f907e9798
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation7.scala
@@ -0,0 +1,20 @@
+import leon.lang._
+
+object ObjectParamMutation7 {
+
+  case class A(a: Int, var x: BigInt, var y: BigInt, var z: BigInt)
+
+  def inc(a: A): Unit = {
+    require(a.x >= 0 && a.y >= 0 && a.z >= 0)
+    a.x += 1
+    a.y += 1
+    a.z += 1
+  } ensuring(_ => a.x == old(a).x + 1 && a.y == old(a).y + 1 && a.z == old(a).z + 1)
+
+  def f(): A = {
+    val a = A(0, 0, 0, 0)
+    inc(a); inc(a); inc(a)
+    a
+  } ensuring(res => res.x == res.y && res.y == res.z && res.z == 3)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation8.scala b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation8.scala
new file mode 100644
index 0000000000000000000000000000000000000000..eb1d157c4d0936c8f28f37b8b69065e34d811253
--- /dev/null
+++ b/src/test/resources/regression/verification/xlang/valid/ObjectParamMutation8.scala
@@ -0,0 +1,18 @@
+import leon.lang._
+
+object ObjectParamMutation8 {
+
+  case class A[B](var y: B)
+
+  def update[B](a: A[B], b: B): B = {
+    a.y = b
+    a.y
+  } ensuring(res => res == b)
+
+  def f(): Int = {
+    val a = A(10)
+    update(a, 12)
+    a.y
+  } ensuring(res => res == 12)
+
+}
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing1.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing1.scala
index d1041aef525a2837fcbf9e9e4059d78308b773b7..238b9273e2ca866942869c4d8b47812ee85154c5 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing1.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Sequencing1 {
 
   def test(): Int = {
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing2.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing2.scala
index e152b00adb31cfa38183972c8d565c952b686730..f8f774fee1524f78a4d0beba5462bd11518ba473 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing2.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Sequencing2 {
 
   def test(): Int = {
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing3.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing3.scala
index cd9d94c465a6b47d2d0ee080fd8693a41bb58bd0..937938bc72ffcbdf823d60d7d5c29ff3d14474cc 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing3.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Sequencing3 {
 
   def f(x: Int): Int = {
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing4.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing4.scala
index fb6802192e0fd9e96531b4d886443e7a7efbdbdd..ef870c612d7adef244df84885ba96ab0c2718cf9 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing4.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing4.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Sequencing4 {
 
   def test(): Int = {
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing5.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing5.scala
index 1a958a5ffd5ce919b6f3f0f49b29abee1ab83050..7c904de5fe1e244cf91d4d9b6d1a4a895b7689c3 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing5.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing5.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Sequencing5 {
 
 
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing6.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing6.scala
index 26dd91b8db8c1965991d1f49fa9eae9f549c69d8..7822e71484d53dc524969a4bcc9da0ef56d58291 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing6.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing6.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Sequencing6 {
 
   def f(x1: Int, x2: Int, x3: Int): Int = {
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing7.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing7.scala
index f3628703bf5c0a073a05797b773246d8ff01960c..1c028d617bed8f4362301ababad157f89eccebb6 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing7.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing7.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package test.resources.regression.verification.xlang.valid
 
 object Sequencing7 {
diff --git a/src/test/resources/regression/verification/xlang/valid/Sequencing8.scala b/src/test/resources/regression/verification/xlang/valid/Sequencing8.scala
index a37092ecffa8a91f589bc2ec7e32328d1b56ceca..b4db8fcf24d3eabcdf92a2d2070dd43c0f924d63 100644
--- a/src/test/resources/regression/verification/xlang/valid/Sequencing8.scala
+++ b/src/test/resources/regression/verification/xlang/valid/Sequencing8.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 object Sequencing8 {
 
   def test(): Int = {
diff --git a/src/test/resources/regression/verification/xlang/valid/ShortCircuit.scala b/src/test/resources/regression/verification/xlang/valid/ShortCircuit.scala
index a35daf11ab00e9d1ab807aa215b981f5e52b9363..b3df2c796856ea1b096fdfdf81adc9e15b4a663b 100644
--- a/src/test/resources/regression/verification/xlang/valid/ShortCircuit.scala
+++ b/src/test/resources/regression/verification/xlang/valid/ShortCircuit.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/verification/xlang/valid/While1.scala b/src/test/resources/regression/verification/xlang/valid/While1.scala
index b74ffa287f1da5d493d07d60df15fae34a9ce40c..6cff049de628c82de6986aff35cf464670d8f891 100644
--- a/src/test/resources/regression/verification/xlang/valid/While1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/While1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object While1 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/While2.scala b/src/test/resources/regression/verification/xlang/valid/While2.scala
index 78c0a8880868bda0a62d11cfdff02e29619c59c4..93a56017752bec41d0b95d88d288001a258a7e2b 100644
--- a/src/test/resources/regression/verification/xlang/valid/While2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/While2.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object While2 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/While3.scala b/src/test/resources/regression/verification/xlang/valid/While3.scala
index 08f05d9542981af4e38d977110450193f688e972..e3283cfe2ad59f1fc097a03da433498831cc9f1b 100644
--- a/src/test/resources/regression/verification/xlang/valid/While3.scala
+++ b/src/test/resources/regression/verification/xlang/valid/While3.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object While3 {
 
diff --git a/src/test/resources/regression/verification/xlang/valid/WhileAsFun1.scala b/src/test/resources/regression/verification/xlang/valid/WhileAsFun1.scala
index b81ea38598aed9b208da96bc88cd9385260b2e5b..60a7e9737bbe6dbae8328937dff1b530000085f8 100644
--- a/src/test/resources/regression/verification/xlang/valid/WhileAsFun1.scala
+++ b/src/test/resources/regression/verification/xlang/valid/WhileAsFun1.scala
@@ -1,4 +1,5 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object WhileAsFun1 {
diff --git a/src/test/resources/regression/verification/xlang/valid/WhileAsFun2.scala b/src/test/resources/regression/verification/xlang/valid/WhileAsFun2.scala
index 968aadfdbf044fd057d3628a6adffd4e917fdf67..01d0ea6350b33fb8373678c5e607f5327b93b12e 100644
--- a/src/test/resources/regression/verification/xlang/valid/WhileAsFun2.scala
+++ b/src/test/resources/regression/verification/xlang/valid/WhileAsFun2.scala
@@ -1,4 +1,5 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 
 object WhileAsFun2 {
diff --git a/src/test/resources/regression/verification/xlang/valid/WhileConditionSubexpression.scala b/src/test/resources/regression/verification/xlang/valid/WhileConditionSubexpression.scala
index b57fc9d8ba3aa2e1f45a38116daf8a5ac7ba86c9..d53d4d2bc76f809f6469eb767f7a2364f8517dbd 100644
--- a/src/test/resources/regression/verification/xlang/valid/WhileConditionSubexpression.scala
+++ b/src/test/resources/regression/verification/xlang/valid/WhileConditionSubexpression.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 import leon.lang._
 import leon.collection._
 import leon._
diff --git a/src/test/resources/regression/xlang/error/Array1.scala b/src/test/resources/regression/xlang/error/Array1.scala
index 2a9813abc0a04ccf041085ca33de9e29d0fd2d37..4f1f6a6ff8b922a8222effba67bed3b1c1adb847 100644
--- a/src/test/resources/regression/xlang/error/Array1.scala
+++ b/src/test/resources/regression/xlang/error/Array1.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object Array1 {
 
diff --git a/src/test/resources/regression/xlang/error/ArrayAliasing6.scala b/src/test/resources/regression/xlang/error/ArrayAliasing6.scala
index 963a134bf71da7a625252411854d73272f56d574..660c98f3c4d0433c3e5889cadefab7233847b0d3 100644
--- a/src/test/resources/regression/xlang/error/ArrayAliasing6.scala
+++ b/src/test/resources/regression/xlang/error/ArrayAliasing6.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object ArrayAliasing6 {
 
diff --git a/src/test/resources/regression/xlang/error/ArrayAliasing8.scala b/src/test/resources/regression/xlang/error/ArrayAliasing8.scala
index e7c27cc9cebf657033da4c07936ce16a510075a0..c466d456457e3c3eada4087286e964a965dc6c01 100644
--- a/src/test/resources/regression/xlang/error/ArrayAliasing8.scala
+++ b/src/test/resources/regression/xlang/error/ArrayAliasing8.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object ArrayAliasing8 {
 
diff --git a/src/test/resources/regression/xlang/error/ArrayAliasing9.scala b/src/test/resources/regression/xlang/error/ArrayAliasing9.scala
index c84d29c3fbb4866100173b7ac0e7b4d0da9a1e57..72d26d87a8a0732d131acc07182b8ed44ac4d4a9 100644
--- a/src/test/resources/regression/xlang/error/ArrayAliasing9.scala
+++ b/src/test/resources/regression/xlang/error/ArrayAliasing9.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 object ArrayAliasing9 {
 
diff --git a/src/test/resources/regression/xlang/error/MutableFieldAliasing1.scala b/src/test/resources/regression/xlang/error/MutableFieldAliasing1.scala
new file mode 100644
index 0000000000000000000000000000000000000000..1d3e7ed03fdf778f52b12912521e9436c0d88e2e
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/MutableFieldAliasing1.scala
@@ -0,0 +1,22 @@
+import leon.lang._
+
+object MutableFieldAliasing1 {
+  
+  case class A(var x: Int)
+  case class B(a: A)
+
+  def f1(): Int = {
+    val b1 = B(A(10))
+    val b2 = b1
+    b2.a.x = 15
+    b1.a.x
+  } ensuring(_ == 15)
+
+
+  def build(x: Int): B = {
+    val a = A(x)
+    B(a)
+  }
+
+}
+
diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing1.scala b/src/test/resources/regression/xlang/error/ObjectAliasing1.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7634e1071e032719cbe6179300bc9dea50f11fc6
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/ObjectAliasing1.scala
@@ -0,0 +1,15 @@
+import leon.lang._
+
+object ObjectAliasing1 {
+
+  case class A(var x: Int)
+
+  def f1(): Int = {
+    val a = A(10)
+    val b = a
+    b.x = 15
+    a.x
+  } ensuring(_ == 15)
+
+}
+
diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing2.scala b/src/test/resources/regression/xlang/error/ObjectAliasing2.scala
new file mode 100644
index 0000000000000000000000000000000000000000..af39dba1e7612f64c0f1926d39f2fe601b2b36ae
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/ObjectAliasing2.scala
@@ -0,0 +1,13 @@
+import leon.lang._
+
+object ObjectAliasing2 {
+
+  case class A(var x: Int)
+
+  def f1(a: A): Int = {
+    val b = a
+    b.x = 10
+    a.x
+  } ensuring(_ == 10)
+
+}
diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing3.scala b/src/test/resources/regression/xlang/error/ObjectAliasing3.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9d419ea95e6e84d5f7b63f81cb2df5359ebe1711
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/ObjectAliasing3.scala
@@ -0,0 +1,13 @@
+import leon.lang._
+
+object ObjectAliasing3 {
+
+  case class A(var x: Int)
+
+  def f1(a: A, b: Boolean): Int = {
+    val c = if(b) a else A(42)
+    c.x = 10
+    a.x
+  } ensuring(_ == 10)
+
+}
diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing4.scala b/src/test/resources/regression/xlang/error/ObjectAliasing4.scala
new file mode 100644
index 0000000000000000000000000000000000000000..81cabf97be708e715245a27fb735e1a88ee00e82
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/ObjectAliasing4.scala
@@ -0,0 +1,12 @@
+import leon.lang._
+
+object ObjectAliasing4 {
+
+  case class A(var x: Int)
+
+  def f1(a: A): A = {
+    a.x = 10
+    a
+  } ensuring(res => res.x == 10)
+
+}
diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing5.scala b/src/test/resources/regression/xlang/error/ObjectAliasing5.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c94656fdb9fba7d52b8eef76a7acb547682a2cdc
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/ObjectAliasing5.scala
@@ -0,0 +1,12 @@
+import leon.lang._
+
+object ObjectAliasing5 {
+
+  case class A(var x: Int)
+  case class B(a: A)
+
+  def f1(b: B): A = {
+    b.a
+  }
+
+}
diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing6.scala b/src/test/resources/regression/xlang/error/ObjectAliasing6.scala
new file mode 100644
index 0000000000000000000000000000000000000000..793b9815d35635ae7539268e9b2d8878bc6a985d
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/ObjectAliasing6.scala
@@ -0,0 +1,14 @@
+import leon.lang._
+
+object ObjectAliasing6 {
+
+  case class A(var x: Int)
+  case class B(a: A)
+
+  def f1(b: B): Int = {
+    val a = b.a
+    a.x = 12
+    b.a.x
+  } ensuring(_ == 12)
+
+}
diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing7.scala b/src/test/resources/regression/xlang/error/ObjectAliasing7.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ea28fa5bb2e01970d64c0259fc4c8d97a6878584
--- /dev/null
+++ b/src/test/resources/regression/xlang/error/ObjectAliasing7.scala
@@ -0,0 +1,22 @@
+package test.resources.regression.xlang.error
+
+import leon.lang._
+
+object ObjectAliasing7 {
+
+  case class A(var x: Int)
+  case class B(a: A)
+
+  def f1(a1: A, a2: A): Int = {
+    val tmp = a1.x
+    a2.x = a1.x
+    a1.x = tmp
+    a1.x + a2.x
+  }
+
+  def f(): Int = {
+    val b = B(A(10))
+    f1(b.a, b.a)
+  } ensuring(_ == 20)
+
+}
diff --git a/src/test/resources/regression/xlang/passing/FunctionCaching.scala b/src/test/resources/regression/xlang/passing/FunctionCaching.scala
new file mode 100644
index 0000000000000000000000000000000000000000..322cb592ee44a65add6f1eed42ba8fea7fba4155
--- /dev/null
+++ b/src/test/resources/regression/xlang/passing/FunctionCaching.scala
@@ -0,0 +1,40 @@
+import leon.lang._
+import leon.collection._
+
+object FunctionCaching {
+
+  case class FunCache(var cached: Map[BigInt, BigInt])
+
+  def fun(x: BigInt)(implicit funCache: FunCache): BigInt = {
+    funCache.cached.get(x) match {
+      case None() => 
+        val res = 2*x + 42
+        funCache.cached = funCache.cached.updated(x, res)
+        res
+      case Some(cached) =>
+        cached
+    }
+  } ensuring(res => old(funCache).cached.get(x) match {
+    case None() => true
+    case Some(v) => v == res
+  })
+
+  def funProperlyCached(x: BigInt, trash: List[BigInt]): Boolean = {
+    implicit val cache = FunCache(Map())
+    val res1 = fun(x)
+    multipleCalls(trash, x)
+    val res2 = fun(x)
+    res1 == res2
+  } holds
+
+  def multipleCalls(args: List[BigInt], x: BigInt)(implicit funCache: FunCache): Unit = {
+    require(funCache.cached.get(x).forall(_ == 2*x + 42))
+    args match {
+      case Nil() => ()
+      case y::ys => 
+        fun(y)
+        multipleCalls(ys, x)
+    }
+  } ensuring(_ => funCache.cached.get(x).forall(_ == 2*x + 42))
+
+}
diff --git a/src/test/resources/regression/xlang/passing/FunctionCachingInvalid.scala b/src/test/resources/regression/xlang/passing/FunctionCachingInvalid.scala
new file mode 100644
index 0000000000000000000000000000000000000000..07a889f780cd1ab911fc072a92d5508f17de2579
--- /dev/null
+++ b/src/test/resources/regression/xlang/passing/FunctionCachingInvalid.scala
@@ -0,0 +1,33 @@
+import leon.lang._
+import leon.collection._
+
+object FunctionCachingInvalid {
+
+  case class FunCache(var cached: Map[BigInt, BigInt])
+
+  def fun(x: BigInt)(implicit funCache: FunCache): BigInt = {
+    funCache.cached.get(x) match {
+      case None() => 
+        val res = 2*x + 42
+        funCache.cached = funCache.cached.updated(x, res)
+        res
+      case Some(cached) =>
+        cached + 1
+    }
+  }
+
+  def funWronglyCached(x: BigInt, trash: List[BigInt]): Boolean = {
+    implicit val cache = FunCache(Map())
+    val res1 = fun(x)
+    multipleCalls(trash)
+    val res2 = fun(x)
+    res1 == res2
+  } holds
+
+
+  def multipleCalls(args: List[BigInt])(implicit funCache: FunCache): Unit = args match {
+    case Nil() => ()
+    case x::xs => fun(x); multipleCalls(xs)
+  }
+
+}
diff --git a/src/test/resources/regression/xlang/passing/ObjectParamMutation1.scala b/src/test/resources/regression/xlang/passing/ObjectParamMutation1.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b36fd6f1a3a59864c5cca195f17264b382b6652e
--- /dev/null
+++ b/src/test/resources/regression/xlang/passing/ObjectParamMutation1.scala
@@ -0,0 +1,18 @@
+import leon.lang._
+
+object ObjectParamMutation1 {
+
+  case class A(var y: Int)
+
+  def update(a: A): Int = {
+    a.y = 12
+    a.y
+  } ensuring(res => res == 12)
+
+  def f(): Int = {
+    val a = A(10)
+    update(a)
+    a.y
+  } ensuring(res => res == 12)
+
+}
diff --git a/src/test/resources/regression/xlang/passing/ObjectParamMutation7.scala b/src/test/resources/regression/xlang/passing/ObjectParamMutation7.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9f664837e3cc56cdd78a9daab7b3587f907e9798
--- /dev/null
+++ b/src/test/resources/regression/xlang/passing/ObjectParamMutation7.scala
@@ -0,0 +1,20 @@
+import leon.lang._
+
+object ObjectParamMutation7 {
+
+  case class A(a: Int, var x: BigInt, var y: BigInt, var z: BigInt)
+
+  def inc(a: A): Unit = {
+    require(a.x >= 0 && a.y >= 0 && a.z >= 0)
+    a.x += 1
+    a.y += 1
+    a.z += 1
+  } ensuring(_ => a.x == old(a).x + 1 && a.y == old(a).y + 1 && a.z == old(a).z + 1)
+
+  def f(): A = {
+    val a = A(0, 0, 0, 0)
+    inc(a); inc(a); inc(a)
+    a
+  } ensuring(res => res.x == res.y && res.y == res.z && res.z == 3)
+
+}
diff --git a/src/test/scala/leon/genc/GenCSuite.scala b/src/test/scala/leon/genc/GenCSuite.scala
index df6d30e5c0869cb6f05ba08195fab4ed73593d89..d1bd12f25ecabf8a632ad6a619c2c454334da30c 100644
--- a/src/test/scala/leon/genc/GenCSuite.scala
+++ b/src/test/scala/leon/genc/GenCSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon
 package genc
diff --git a/src/test/scala/leon/integration/evaluators/CodegenEvaluatorSuite.scala b/src/test/scala/leon/integration/evaluators/CodegenEvaluatorSuite.scala
index e5565e073dc629a546019e219297c841c9d84258..8882238999acebde711027ec6a8b1db152813b20 100644
--- a/src/test/scala/leon/integration/evaluators/CodegenEvaluatorSuite.scala
+++ b/src/test/scala/leon/integration/evaluators/CodegenEvaluatorSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.evaluators
 
diff --git a/src/test/scala/leon/integration/evaluators/EvaluatorSuite.scala b/src/test/scala/leon/integration/evaluators/EvaluatorSuite.scala
index 812cf88eac2508814b1218eeb85a787bcad2d4ff..5245c00c2b8147d62217d5d5bcecd89399427efe 100644
--- a/src/test/scala/leon/integration/evaluators/EvaluatorSuite.scala
+++ b/src/test/scala/leon/integration/evaluators/EvaluatorSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.evaluators
 
diff --git a/src/test/scala/leon/integration/grammars/GrammarsSuite.scala b/src/test/scala/leon/integration/grammars/GrammarsSuite.scala
new file mode 100644
index 0000000000000000000000000000000000000000..71fc0cb55fe92f37123d7c51be9f7984b29119ab
--- /dev/null
+++ b/src/test/scala/leon/integration/grammars/GrammarsSuite.scala
@@ -0,0 +1,243 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon.integration.grammars
+
+import leon._
+import leon.test._
+import leon.test.helpers._
+import leon.purescala.Common._
+import leon.purescala.Definitions._
+import leon.purescala.Constructors._
+import leon.purescala.Expressions._
+import leon.purescala.Types._
+import leon.codegen._
+import synthesis._
+import bonsai.enumerators._
+import grammars._
+import grammars.aspects.SimilarTo
+
+class SimilarToSuite extends LeonTestSuiteWithProgram with ExpressionsDSL {
+
+  val sources = List(
+    """|import leon.lang._
+       |import leon.annotation._
+       |import leon.collection._
+       |import leon._
+       |
+       |object Trees {
+       |  abstract class Expr
+       |  case class Plus(lhs: Expr, rhs: Expr) extends Expr
+       |  case class Minus(lhs: Expr, rhs: Expr) extends Expr
+       |  case class LessThan(lhs: Expr, rhs: Expr) extends Expr
+       |  case class And(lhs: Expr, rhs: Expr) extends Expr
+       |  case class Or(lhs: Expr, rhs: Expr) extends Expr
+       |  case class Not(e : Expr) extends Expr
+       |  case class Eq(lhs: Expr, rhs: Expr) extends Expr
+       |  case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr
+       |  case class IntLiteral(v: BigInt) extends Expr
+       |  case class BoolLiteral(b : Boolean) extends Expr
+       |}
+       |object STrees {
+       |  abstract class Expr
+       |  case class Plus(lhs : Expr, rhs : Expr) extends Expr
+       |  case class Neg(arg : Expr) extends Expr
+       |  case class Ite(cond : Expr, thn : Expr, els : Expr) extends Expr
+       |  case class Eq(lhs : Expr, rhs : Expr) extends Expr
+       |  case class LessThan(lhs : Expr, rhs : Expr) extends Expr
+       |  case class Literal(i : BigInt) extends Expr
+       |}
+       |
+       |object Desugar {
+       |  def desugar(e: Trees.Expr): STrees.Expr = {
+       |    STrees.Literal(0)
+       |  }
+       |} """.stripMargin,
+
+    """|import leon.lang._
+       |import leon.collection._
+       |
+       |object Heaps {
+       |
+       |  sealed abstract class Heap {
+       |    val rank : BigInt = this match {
+       |      case Leaf() => 0
+       |      case Node(_, l, r) => 
+       |        1 + max(l.rank, r.rank)
+       |    }
+       |    def content : Set[BigInt] = this match {
+       |      case Leaf() => Set[BigInt]()
+       |      case Node(v,l,r) => l.content ++ Set(v) ++ r.content
+       |    }
+       |  }
+       |  case class Leaf() extends Heap
+       |  case class Node(value:BigInt, left: Heap, right: Heap) extends Heap
+       |
+       |  def max(i1 : BigInt, i2 : BigInt) = if (i1 >= i2) i1 else i2
+       |
+       |  def hasHeapProperty(h : Heap) : Boolean = h match {
+       |    case Leaf() => true
+       |    case Node(v, l, r) => 
+       |      ( l match {
+       |        case Leaf() => true
+       |        case n@Node(v2,_,_) => v >= v2 && hasHeapProperty(n)
+       |      }) && 
+       |      ( r match {
+       |        case Leaf() => true
+       |        case n@Node(v2,_,_) => v >= v2 && hasHeapProperty(n)
+       |      })
+       |  }
+       |
+       |  def hasLeftistProperty(h: Heap) : Boolean = h match {
+       |    case Leaf() => true
+       |    case Node(_,l,r) => 
+       |      hasLeftistProperty(l) && 
+       |      hasLeftistProperty(r) && 
+       |      l.rank >= r.rank 
+       |  }
+       |
+       |  def heapSize(t: Heap): BigInt = { t match {
+       |    case Leaf() => BigInt(0)
+       |    case Node(v, l, r) => heapSize(l) + 1 + heapSize(r)
+       |  }} ensuring(_ >= 0)
+       |
+       |  private def merge(h1: Heap, h2: Heap) : Heap = {
+       |    require(
+       |      hasLeftistProperty(h1) && hasLeftistProperty(h2) && 
+       |      hasHeapProperty(h1) && hasHeapProperty(h2)
+       |    )
+       |    (h1,h2) match {
+       |      case (Leaf(), _) => h2
+       |      case (_, Leaf()) => h1
+       |      case (Node(v1, l1, r1), Node(v2, l2, r2)) =>
+       |        //if(v1 >= v2) // FIXME
+       |          makeN(v1, l1, merge(r1, h2))
+       |        //else
+       |        //  makeN(v2, l2, merge(h1, r2))
+       |    }
+       |  } ensuring { res => 
+       |    hasLeftistProperty(res) && hasHeapProperty(res) &&
+       |    heapSize(h1) + heapSize(h2) == heapSize(res) &&
+       |    h1.content ++ h2.content == res.content 
+       |  }
+       |
+       |  private def makeN(value: BigInt, left: Heap, right: Heap) : Heap = {
+       |    require(
+       |      hasLeftistProperty(left) && hasLeftistProperty(right)
+       |    )
+       |    if(left.rank >= right.rank)
+       |      Node(value, left, right)
+       |    else
+       |      Node(value, right, left)
+       |  } ensuring { res =>
+       |    hasLeftistProperty(res)  }
+       |}""".stripMargin
+
+  )
+
+  def runTests(tests: List[(List[Variable], Expr, Expr)], ofd: Option[FunDef] = None)(implicit fix: (LeonContext, Program)): Unit = {
+    for ((vs, from, exp) <- tests) {
+      // SimilarTo(<from>) should produce <exp>
+
+      val sctx = new SynthesisContext(fix._1, SynthesisSettings(), ofd.getOrElse(fix._2.definedFunctions.head), fix._2)
+      val p = Problem(vs.map(_.id), BooleanLiteral(true), BooleanLiteral(true), BooleanLiteral(true), Nil, ExamplesBank.empty)
+
+      val g = OneOf(vs)
+      val enum = new MemoizedEnumerator[Label, Expr, ProductionRule[Label, Expr]](g.getProductions)
+      val exprs = enum.iterator(Label(exp.getType).withAspect(SimilarTo(from)))
+
+      //println(s"SimilarTo(${from.asString}):")
+
+      if (!(exprs.exists { e => 
+        //println(s" - ${e.asString}")
+        e == exp
+      })) {
+        info("Productions: ")
+        g.printProductions(info(_))
+
+        fail(s"Unable to find ${exp.asString} in SimilarTo(${from.asString})")
+      }
+    }
+  }
+
+  test("Basic") { implicit fix =>
+
+    def _None = CaseClass(caseClassDef("leon.lang.None").typed(Seq(IntegerType)), Nil)
+    def _Some(e: Expr) = CaseClass(caseClassDef("leon.lang.Some").typed(Seq(IntegerType)), List(e))
+
+    val tests = List[(List[Variable], Expr, Expr)](
+      (List(x, y), GreaterThan(x, y), GreaterThan(y, x)),
+      (List(x, y), GreaterThan(x, y), not(GreaterThan(x, y))),
+      (List(x, y), equality(x, y), not(equality(x, y))),
+      (List(x, y), x, y),
+      (List(x), _Some(x), _Some(Plus(x, bi(1)))),
+      (List(x), _Some(Plus(x, bi(2))), _Some(Plus(x, bi(1))))
+    )
+
+    runTests(tests)
+  }
+
+  test("Desugar") { implicit fix =>
+    val e    = id("e", "Trees.Expr").toVariable
+    val cond = id("cond", "Trees.Expr").toVariable
+    val thn  = id("thn", "Trees.Expr").toVariable
+    val els  = id("els", "Trees.Expr").toVariable
+
+    def Ite(es: Expr*) = cc("STrees.Ite")(es: _*)
+    def Literal(es: Expr*) = cc("STrees.Literal")(es: _*)
+
+    val desugarfd = funDef("Desugar.desugar")
+    def desugar(es: Expr*) = fcall("Desugar.desugar")(es: _*)
+
+    val tests = List[(List[Variable], Expr, Expr)](
+      (List(cond, thn, els),
+       Ite(desugar(cond), desugar(els), desugar(thn)),
+       Ite(desugar(cond), desugar(thn), desugar(els))
+      ),
+      (List(e),
+       Ite(desugar(e), Literal(bi(1)), Literal(bi(1))),
+       Ite(desugar(e), Literal(bi(0)), Literal(bi(1)))
+      )
+    )
+
+    runTests(tests, Some(desugarfd))
+  }
+
+  test("Heap") { implicit fix =>
+    val v1   = id("v1", IntegerType).toVariable
+    val h1   = id("h1", "Heaps.Heap").toVariable
+    val l1   = id("l1", "Heaps.Heap").toVariable
+    val r1   = id("r1", "Heaps.Heap").toVariable
+
+    val v2   = id("v2", IntegerType).toVariable
+    val h2   = id("h2", "Heaps.Heap").toVariable
+    val l2   = id("l2", "Heaps.Heap").toVariable
+    val r2   = id("r2", "Heaps.Heap").toVariable
+
+    val mergefd = funDef("Heaps.merge")
+    def merge(es: Expr*) = fcall("Heaps.merge")(es: _*)
+
+    def makeN(es: Expr*) = fcall("Heaps.makeN")(es: _*)
+
+    def Node(es: Expr*) = cc("Heaps.Node")(es: _*)
+    def Leaf(es: Expr*) = cc("Heaps.Leaf")(es: _*)
+
+    def rank(es: Expr*) = fcall("Heap.rank")(es: _*)
+
+    val tests = List[(List[Variable], Expr, Expr)](
+      (List(h1, v1, l1, r1, h2, v2, l2, r2),
+       makeN(v2, l1, merge(h1, r2)),
+       makeN(v2, l2, merge(h1, r2))
+      ),
+      (List(v1, h1),
+       merge(Node(Plus(v1, bi(1)), Leaf(), Leaf()), h1),
+      merge(Node(v1, Leaf(), Leaf()), h1)
+      ),
+      (List(h1, h2),
+       GreaterThan(rank(h1), Plus(rank(h2), bi(1))),
+       GreaterThan(rank(h1), rank(h2))
+      )
+    )
+
+    runTests(tests, Some(mergefd))
+  }
+}
diff --git a/src/test/scala/leon/integration/purescala/CallGraphSuite.scala b/src/test/scala/leon/integration/purescala/CallGraphSuite.scala
index 636cd4f406d37c2786f3e3493e48db9a7a98bec7..1d9fa2124c977ecffcececd745d7fd80862fa242 100644
--- a/src/test/scala/leon/integration/purescala/CallGraphSuite.scala
+++ b/src/test/scala/leon/integration/purescala/CallGraphSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.purescala
 
diff --git a/src/test/scala/leon/integration/purescala/DataGenSuite.scala b/src/test/scala/leon/integration/purescala/DataGenSuite.scala
index b1acfd74c26a745c5016bd219716783a6bea0ccd..050176ef54ce165af558c638cb2ed7d607120472 100644
--- a/src/test/scala/leon/integration/purescala/DataGenSuite.scala
+++ b/src/test/scala/leon/integration/purescala/DataGenSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.purescala
 
diff --git a/src/test/scala/leon/integration/purescala/DefOpsSuite.scala b/src/test/scala/leon/integration/purescala/DefOpsSuite.scala
index c7aad05c63a2365e711a5f093853bd5524a87473..7c7b82b13864b587800a0b9bb36d3e73730143f5 100644
--- a/src/test/scala/leon/integration/purescala/DefOpsSuite.scala
+++ b/src/test/scala/leon/integration/purescala/DefOpsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.purescala
 
diff --git a/src/test/scala/leon/integration/purescala/ExprOpsSuite.scala b/src/test/scala/leon/integration/purescala/ExprOpsSuite.scala
index fe548c1b013e3cbef8e5a7024286c1e9e8781e0f..565dbdb1486f3c7c25553eda1151009ac2d3fefb 100644
--- a/src/test/scala/leon/integration/purescala/ExprOpsSuite.scala
+++ b/src/test/scala/leon/integration/purescala/ExprOpsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.purescala
 
diff --git a/src/test/scala/leon/integration/purescala/InliningSuite.scala b/src/test/scala/leon/integration/purescala/InliningSuite.scala
index 069a0e5badea7be393be043fba0793844aa3d3d8..973dd579a32f8d6f00f22caae943cb4fef9a9d1b 100644
--- a/src/test/scala/leon/integration/purescala/InliningSuite.scala
+++ b/src/test/scala/leon/integration/purescala/InliningSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.purescala
 
diff --git a/src/test/scala/leon/integration/purescala/SimplifyPathsSuite.scala b/src/test/scala/leon/integration/purescala/SimplifyPathsSuite.scala
index 7ebbe89513942bb7c139383ac2fcaae5e9a8e8bd..f70543fc98504e3f8ea4bc689530d1d9d0cf7dd9 100644
--- a/src/test/scala/leon/integration/purescala/SimplifyPathsSuite.scala
+++ b/src/test/scala/leon/integration/purescala/SimplifyPathsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.purescala
 
diff --git a/src/test/scala/leon/integration/solvers/EnumerationSolverSuite.scala b/src/test/scala/leon/integration/solvers/EnumerationSolverSuite.scala
index 89031230bf40c9bcf03a27f0f41bc5be06c125a7..50897d972c9808cb91258619061f9554235b76da 100644
--- a/src/test/scala/leon/integration/solvers/EnumerationSolverSuite.scala
+++ b/src/test/scala/leon/integration/solvers/EnumerationSolverSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.solvers
 
diff --git a/src/test/scala/leon/integration/solvers/FairZ3SolverTests.scala b/src/test/scala/leon/integration/solvers/FairZ3SolverTests.scala
index b08e7f9164173d12e681b6dce086a75a9e225990..91967c426ab02e3167b3dd724973708950717cdd 100644
--- a/src/test/scala/leon/integration/solvers/FairZ3SolverTests.scala
+++ b/src/test/scala/leon/integration/solvers/FairZ3SolverTests.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.solvers
 
diff --git a/src/test/scala/leon/integration/solvers/GlobalVariablesSuite.scala b/src/test/scala/leon/integration/solvers/GlobalVariablesSuite.scala
index 64cb3b70b062ba30ccf6223af587ed85c9b4ff88..466a16dade7850e2604d111b232ffc5d349ba97d 100644
--- a/src/test/scala/leon/integration/solvers/GlobalVariablesSuite.scala
+++ b/src/test/scala/leon/integration/solvers/GlobalVariablesSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.solvers
 
diff --git a/src/test/scala/leon/integration/solvers/LeonSolverSuite.scala b/src/test/scala/leon/integration/solvers/LeonSolverSuite.scala
index 6c2064f95584b718e00210a342a01e33beefe2fb..62b343df6c108d48e762e14b3ff655923cb0dfa8 100644
--- a/src/test/scala/leon/integration/solvers/LeonSolverSuite.scala
+++ b/src/test/scala/leon/integration/solvers/LeonSolverSuite.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.integration.solvers
 
 import leon.test._
diff --git a/src/test/scala/leon/integration/solvers/ModelEnumerationSuite.scala b/src/test/scala/leon/integration/solvers/ModelEnumerationSuite.scala
index 3b405720a004c288f33a25456b6cd961d7ed7e53..3d56b31ccb663171dff9c6d84e91795b00209baf 100644
--- a/src/test/scala/leon/integration/solvers/ModelEnumerationSuite.scala
+++ b/src/test/scala/leon/integration/solvers/ModelEnumerationSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.solvers
 
diff --git a/src/test/scala/leon/integration/solvers/SolversSuite.scala b/src/test/scala/leon/integration/solvers/SolversSuite.scala
index d2af2030bded5ae60375180661107346164ca0c6..2a42bc6a3ae82a0f830afc3787d696d1792f3865 100644
--- a/src/test/scala/leon/integration/solvers/SolversSuite.scala
+++ b/src/test/scala/leon/integration/solvers/SolversSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.solvers
 
diff --git a/src/test/scala/leon/integration/solvers/StringRenderSuite.scala b/src/test/scala/leon/integration/solvers/StringRenderSuite.scala
index cd6bd2ee75a9594d2c0be081db265e75c7a45620..c0c724c81580221a099e246332c7d3182b19d3f4 100644
--- a/src/test/scala/leon/integration/solvers/StringRenderSuite.scala
+++ b/src/test/scala/leon/integration/solvers/StringRenderSuite.scala
@@ -1,46 +1,26 @@
-package leon.integration.solvers
+package leon
+package integration
+package solvers
 
+import leon.test.LeonTestSuiteWithProgram
 
-import org.scalatest.FunSuite
-import org.scalatest.Matchers
-import leon.test.helpers.ExpressionsDSL
-import leon.solvers.string.StringSolver
 import leon.purescala.Common.FreshIdentifier
-import leon.purescala.Common.Identifier
 import leon.purescala.Expressions._
 import leon.purescala.Definitions._
 import leon.purescala.DefOps
 import leon.purescala.ExprOps
 import leon.purescala.Types._
-import leon.purescala.TypeOps
 import leon.purescala.Constructors._
+
+import leon.synthesis._
 import leon.synthesis.rules.{StringRender, TypedTemplateGenerator}
-import scala.collection.mutable.{HashMap => MMap}
-import scala.concurrent.Future
-import scala.concurrent.ExecutionContext.Implicits.global
-import org.scalatest.concurrent.Timeouts
-import org.scalatest.concurrent.ScalaFutures
-import org.scalatest.time.SpanSugar._
-import org.scalatest.FunSuite
-import org.scalatest.concurrent.Timeouts
-import org.scalatest.concurrent.ScalaFutures
-import org.scalatest.time.SpanSugar._
-import leon.purescala.Types.Int32Type
-import leon.test.LeonTestSuiteWithProgram
-import leon.synthesis.SourceInfo
-import leon.synthesis.CostModels
-import leon.synthesis.graph.SimpleSearch
+import leon.synthesis.strategies.CostBasedStrategy
 import leon.synthesis.graph.AndNode
-import leon.synthesis.SearchContext
-import leon.synthesis.Synthesizer
-import leon.synthesis.SynthesisSettings
-import leon.synthesis.RuleApplication
-import leon.synthesis.RuleClosed
+
 import leon.evaluators._
-import leon.LeonContext
-import leon.synthesis.rules.DetupleInput
-import leon.synthesis.Rules
-import leon.solvers.ModelBuilder
+
+import org.scalatest.concurrent.ScalaFutures
+import org.scalatest.Matchers
 import scala.language.implicitConversions
 
 class StringRenderSuite extends LeonTestSuiteWithProgram with Matchers with ScalaFutures {
@@ -102,11 +82,11 @@ class StringRenderSuite extends LeonTestSuiteWithProgram with Matchers with Scal
 
   def applyStringRenderOn(functionName: String): (FunDef, Program) = {
     val ci = synthesisInfos(functionName)
-    val search = new SimpleSearch(ctx, ci, ci.problem, CostModels.default, Some(200))
+    val search = new Search(ctx, ci, ci.problem, new CostBasedStrategy(ctx, CostModels.default))
     val synth = new Synthesizer(ctx, program, ci, SynthesisSettings(rules = Seq(StringRender)))
     val orNode = search.g.root
     if (!orNode.isExpanded) {
-      val hctx = SearchContext(synth.sctx, synth.ci, orNode, search)
+      val hctx = new SearchContext(synth.sctx, synth.ci.source, orNode, search)
       orNode.expand(hctx)
     }
     val andNodes = orNode.descendants.collect {
@@ -115,11 +95,6 @@ class StringRenderSuite extends LeonTestSuiteWithProgram with Matchers with Scal
     }
 
     val rulesApps = (for ((t, i) <- andNodes.zipWithIndex) yield {
-      val status = if (t.isDeadEnd) {
-        "closed"
-      } else {
-        "open"
-      }
       t.ri.asString -> i
     }).toMap
     rulesApps should contain key "String conversion"
@@ -129,7 +104,7 @@ class StringRenderSuite extends LeonTestSuiteWithProgram with Matchers with Scal
     
     val solutions = (search.traversePath(path) match {
       case Some(an: AndNode) =>
-        val hctx = SearchContext(synth.sctx, synth.ci, an, search)
+        val hctx = new SearchContext(synth.sctx, synth.ci.source, an, search)
         an.ri.apply(hctx)
       case _ => throw new Exception("Was not an and node")
     }) match {
@@ -241,7 +216,6 @@ class StringRenderSuite extends LeonTestSuiteWithProgram with Matchers with Scal
   def synthesizeAndTest(functionName: String, tests: (Seq[Expr], String)*) {
     val (fd, program) = applyStringRenderOn(functionName)
     val when = new DefaultEvaluator(ctx, program)
-    val args = getFunctionArguments(functionName)
     for((in, out) <- tests) {
       val expr = functionInvocation(fd, in)
       when.eval(expr) match {
@@ -254,7 +228,6 @@ class StringRenderSuite extends LeonTestSuiteWithProgram with Matchers with Scal
   def synthesizeAndAbstractTest(functionName: String)(tests: (FunDef, Program) => Seq[(Seq[Expr], Expr)]) {
     val (fd, program) = applyStringRenderOn(functionName)
     val when_abstract = new AbstractEvaluator(ctx, program)
-    val args = getFunctionArguments(functionName)
     for((in, out) <- tests(fd, program)) {
       val expr = functionInvocation(fd, in)
       when_abstract.eval(expr) match {
diff --git a/src/test/scala/leon/integration/solvers/StringSolverSuite.scala b/src/test/scala/leon/integration/solvers/StringSolverSuite.scala
index 7c0d3e13c044f4cd2491041cf28319986a6df42b..029bfb23394364ceb31db20f24b673ad7bf85478 100644
--- a/src/test/scala/leon/integration/solvers/StringSolverSuite.scala
+++ b/src/test/scala/leon/integration/solvers/StringSolverSuite.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.integration.solvers
 
 import org.scalatest.FunSuite
diff --git a/src/test/scala/leon/integration/solvers/TimeoutSolverSuite.scala b/src/test/scala/leon/integration/solvers/TimeoutSolverSuite.scala
index 4ee34098827272c7039b5865fb016b465ca9ccd4..e491737cdc12adcfd9331396e7cde874ee4c8c55 100644
--- a/src/test/scala/leon/integration/solvers/TimeoutSolverSuite.scala
+++ b/src/test/scala/leon/integration/solvers/TimeoutSolverSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.solvers
 
diff --git a/src/test/scala/leon/integration/solvers/UnrollingSolverSuite.scala b/src/test/scala/leon/integration/solvers/UnrollingSolverSuite.scala
index b3c0f82f2d98362c873c555992fca0367fe13ba1..f286d9d655a8f2a4d3ae83cf1e1f6f4a1c430c56 100644
--- a/src/test/scala/leon/integration/solvers/UnrollingSolverSuite.scala
+++ b/src/test/scala/leon/integration/solvers/UnrollingSolverSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.integration.solvers
 
diff --git a/src/test/scala/leon/isabelle/IsabelleLibrarySuite.scala b/src/test/scala/leon/isabelle/IsabelleLibrarySuite.scala
index 66994915993456e0c825fcaef18a84168c7b614d..bf4acc20261f11e6c64f4be5ce806ed21a6f8707 100644
--- a/src/test/scala/leon/isabelle/IsabelleLibrarySuite.scala
+++ b/src/test/scala/leon/isabelle/IsabelleLibrarySuite.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.isabelle
 
 import scala.concurrent._
diff --git a/src/test/scala/leon/isabelle/IsabelleVerificationSuite.scala b/src/test/scala/leon/isabelle/IsabelleVerificationSuite.scala
index 628a523ad62a37cdc30e8d8c0495ac54b15ae69d..d8a5ba46f202d5900d1babc6bf510a530ac105e6 100644
--- a/src/test/scala/leon/isabelle/IsabelleVerificationSuite.scala
+++ b/src/test/scala/leon/isabelle/IsabelleVerificationSuite.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.isabelle
 
 import leon.regression.verification.VerificationSuite
diff --git a/src/test/scala/leon/regression/frontends/FrontEndsSuite.scala b/src/test/scala/leon/regression/frontends/FrontEndsSuite.scala
index a0e52aa0b083c04a5a3e1141d2f3287a1995611e..599fb0a41a331ff86005338b50bb44fc7819eb5d 100644
--- a/src/test/scala/leon/regression/frontends/FrontEndsSuite.scala
+++ b/src/test/scala/leon/regression/frontends/FrontEndsSuite.scala
@@ -1,19 +1,19 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.frontends
 
 import leon._
 import leon.test._
-import purescala.Definitions.Program
 import java.io.File
 
 class FrontEndsSuite extends LeonRegressionSuite {
-  // Hard-code output directory, for Eclipse purposes
 
-  val pipeFront = frontends.scalac.ExtractionPhase andThen new utils.PreprocessingPhase
+  def testFrontend(f: File, xlang: Boolean, forError: Boolean) = {
+    val pipeline =
+      frontends.scalac.ExtractionPhase     andThen
+      new utils.PreprocessingPhase(xlang)  andThen
+      NoopPhase()
 
-  def testFrontend(f: File, pipeBack: Pipeline[Program, Program], forError: Boolean) = {
-    val pipeline = pipeFront andThen pipeBack
     test ("Testing " + f.getName) {
       val ctx = createLeonContext()
       if (forError) {
@@ -24,7 +24,6 @@ class FrontEndsSuite extends LeonRegressionSuite {
         pipeline.run(ctx, List(f.getAbsolutePath))
       }
     }
-
   }
 
   private def forEachFileIn(path : String)(block : File => Unit) {
@@ -35,14 +34,16 @@ class FrontEndsSuite extends LeonRegressionSuite {
     } 
   }
 
-  val pipeNormal = xlang.NoXLangFeaturesChecking andThen NoopPhase() // redundant NoopPhase to trigger throwing error between phases
   val baseDir = "regression/frontends/"
 
   forEachFileIn(baseDir+"passing/") { f => 
-    testFrontend(f, pipeNormal, false)
+    testFrontend(f, false, false)
   }
   forEachFileIn(baseDir+"error/simple/") { f =>
-    testFrontend(f, pipeNormal, true)
+    testFrontend(f, false, true)
+  }
+  forEachFileIn(baseDir+"error/xlang/") { f =>
+    testFrontend(f, true, true)
   }
-   
+
 }
diff --git a/src/test/scala/leon/regression/orb/OrbInstrumentationTestSuite.scala b/src/test/scala/leon/regression/orb/OrbInstrumentationTestSuite.scala
index 82288376e4b484ebd04ae125110ffa8f2c967157..bb4bb564e4c584c65dbdabe2d792fafcd1f5d5f8 100644
--- a/src/test/scala/leon/regression/orb/OrbInstrumentationTestSuite.scala
+++ b/src/test/scala/leon/regression/orb/OrbInstrumentationTestSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.orb
 import leon.test._
diff --git a/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala b/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala
index 00c01cf27fa7db43963028fda40bd9f7c3b8fa17..6c46aeb3451b740054d689e053011a1c999ddf3b 100644
--- a/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala
+++ b/src/test/scala/leon/regression/orb/OrbRegressionSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.orb
 import leon.test._
diff --git a/src/test/scala/leon/regression/repair/RepairSuite.scala b/src/test/scala/leon/regression/repair/RepairSuite.scala
index 6301f4ea1a61144f4b38cd2d7660579c192f5089..16f1ddb88e46e492589b21c46aed55aeb129ce3f 100644
--- a/src/test/scala/leon/regression/repair/RepairSuite.scala
+++ b/src/test/scala/leon/regression/repair/RepairSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.repair
 
@@ -34,13 +34,13 @@ class RepairSuite extends LeonRegressionSuite {
     val reporter = new TestSilentReporter
     //val reporter = new DefaultReporter(Set(utils.DebugSectionRepair))
 
-    val ctx = LeonContext(
+    val ctx = new LeonContext(
       reporter = reporter,
       interruptManager = new InterruptManager(reporter),
       options = Seq(
-        LeonOption(SharedOptions.optFunctions)(Seq(fileToFun(name))),
+        LeonOption(GlobalOptions.optFunctions)(Seq(fileToFun(name))),
         LeonOption(VerificationPhase.optParallelVCs)(true),
-        LeonOption(SharedOptions.optTimeout)(180L)
+        LeonOption(GlobalOptions.optTimeout)(180L)
       )
     )
 
diff --git a/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala b/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala
index c8bfc2688ec53e75e886cffc26621778675c454d..6ab235dd5dda3f1c9e087ca0c93b374f07dec5df 100644
--- a/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala
+++ b/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.synthesis
 
@@ -40,13 +40,10 @@ class StablePrintingSuite extends LeonRegressionSuite {
       EquivalentInputs,
       UnconstrainedOutput,
       OptimisticGround,
-      EqualitySplit,
       InequalitySplit,
       rules.Assert,
-      DetupleOutput,
       DetupleInput,
       ADTSplit,
-      IntInduction,
       InnerCaseSplit
     )
 
@@ -104,9 +101,9 @@ class StablePrintingSuite extends LeonRegressionSuite {
             val sctx = synthesizer.sctx
             try {
               val search = synthesizer.getSearch
-              val hctx = SearchContext(sctx, ci, search.g.root, search)
+              val hctx = new SearchContext(sctx, ci.source, search.g.root, search)
               val problem = ci.problem
-              info(j.info("synthesis "+problem.asString(sctx.context)))
+              info(j.info("synthesis "+problem.asString(sctx)))
               val apps = decompRules flatMap { _.instantiateOn(hctx, problem)}
 
               for (a <- apps) {
@@ -115,7 +112,7 @@ class StablePrintingSuite extends LeonRegressionSuite {
                   case RuleExpanded(sub) =>
                     a.onSuccess(sub.map(Solution.choose)) match {
                       case Some(sol) =>
-                        val result = sol.toSimplifiedExpr(ctx, pgm)
+                        val result = sol.toSimplifiedExpr(ctx, pgm, ci.fd)
 
                         val newContent = new FileInterface(ctx.reporter).substitute(j.content, ci.source, (indent: Int) => {
                           val p = new ScalaPrinter(PrinterOptions(), Some(pgm))
diff --git a/src/test/scala/leon/regression/synthesis/SynthesisRegressionSuite.scala b/src/test/scala/leon/regression/synthesis/SynthesisRegressionSuite.scala
index 9dbb0e36fc65223a06b132dc393ab62f7748948a..b676a3633f5def8701b940e01212a5631b10ab96 100644
--- a/src/test/scala/leon/regression/synthesis/SynthesisRegressionSuite.scala
+++ b/src/test/scala/leon/regression/synthesis/SynthesisRegressionSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.synthesis
 
diff --git a/src/test/scala/leon/regression/synthesis/SynthesisSuite.scala b/src/test/scala/leon/regression/synthesis/SynthesisSuite.scala
index ca2b4a3c98107c73c9244486200dd0a44a348cb2..3615b034029f46098c2a6e58b36e4ba72b55be96 100644
--- a/src/test/scala/leon/regression/synthesis/SynthesisSuite.scala
+++ b/src/test/scala/leon/regression/synthesis/SynthesisSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.synthesis
 
@@ -9,6 +9,7 @@ import leon.synthesis.graph._
 import leon.synthesis.utils._
 import leon.utils.PreprocessingPhase
 
+/*
 class SynthesisSuite extends LeonRegressionSuite {
   private var counter : Int = 0
   private def nextInt() : Int = {
@@ -345,3 +346,4 @@ object ChurchNumerals {
       Close("CEGIS")
   }
 }
+*/
diff --git a/src/test/scala/leon/regression/termination/TerminationSuite.scala b/src/test/scala/leon/regression/termination/TerminationSuite.scala
index 215c72272673c5c6e9bbd5173b2b334ed3fc753c..c9ccd0dd183f0eeaea95391096987bc84a05181e 100644
--- a/src/test/scala/leon/regression/termination/TerminationSuite.scala
+++ b/src/test/scala/leon/regression/termination/TerminationSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.termination
 
diff --git a/src/test/scala/leon/regression/testcases/TestCasesCompile.scala b/src/test/scala/leon/regression/testcases/TestCasesCompile.scala
index 333413721e1b1d1e6f058664997ec53209a0d886..f33f3e6f309d2c50de09440039321e750a4316ff 100644
--- a/src/test/scala/leon/regression/testcases/TestCasesCompile.scala
+++ b/src/test/scala/leon/regression/testcases/TestCasesCompile.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.testcases
 
diff --git a/src/test/scala/leon/regression/verification/LibraryVerificationSuite.scala b/src/test/scala/leon/regression/verification/LibraryVerificationSuite.scala
index d350bd04b4c68f7838676048b47b085b5d54e4b8..c122f704823b9ee71f27c7739d14f9a4b406d771 100644
--- a/src/test/scala/leon/regression/verification/LibraryVerificationSuite.scala
+++ b/src/test/scala/leon/regression/verification/LibraryVerificationSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.verification
 
diff --git a/src/test/scala/leon/regression/verification/NewSolversSuite.scala b/src/test/scala/leon/regression/verification/NewSolversSuite.scala
index 5a340d1f870e019f33460fb6e386c50e58fbcbff..d41ea95dceaaaa014b8d5dcb5eeed46244bb37cb 100644
--- a/src/test/scala/leon/regression/verification/NewSolversSuite.scala
+++ b/src/test/scala/leon/regression/verification/NewSolversSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.verification
 
diff --git a/src/test/scala/leon/regression/verification/VerificationSuite.scala b/src/test/scala/leon/regression/verification/VerificationSuite.scala
index 446d06675cdb9b3eb1c7095137ab95e8a928c399..d1b252e64e48fe03dd2e82759a08df3d896a2bb7 100644
--- a/src/test/scala/leon/regression/verification/VerificationSuite.scala
+++ b/src/test/scala/leon/regression/verification/VerificationSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.verification
 
@@ -37,9 +37,9 @@ trait VerificationSuite extends LeonRegressionSuite {
       new PreprocessingPhase(desugarXLang)
 
     val analysis =
-      (if (isabelle) AdaptationPhase else NoopPhase[Program]) andThen
+      AdaptationPhase.when(isabelle) andThen
       VerificationPhase andThen
-      (if (desugarXLang) FixReportLabels else NoopPhase[VerificationReport])
+      FixReportLabels.when(desugarXLang)
 
     val ctx = createLeonContext(files:_*).copy(reporter = new TestErrorReporter)
 
diff --git a/src/test/scala/leon/regression/verification/XLangVerificationSuite.scala b/src/test/scala/leon/regression/verification/XLangVerificationSuite.scala
index 6fe7b07408500929063b4f57f24e1147a6cfce35..efecaf71a5b027bbd88813d5a88971fa3f0184eb 100644
--- a/src/test/scala/leon/regression/verification/XLangVerificationSuite.scala
+++ b/src/test/scala/leon/regression/verification/XLangVerificationSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.verification
 
diff --git a/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala b/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala
index a0beb7fba142dccf9150cfaca0a0ad2329baa861..5d5679f95cadeb67e72b50532cede757cdf825cc 100644
--- a/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala
+++ b/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.regression.verification
 package purescala
diff --git a/src/test/scala/leon/test/LeonRegressionSuite.scala b/src/test/scala/leon/test/LeonRegressionSuite.scala
index 4181fee97e7a4a38e3f30349458366ba62138d12..ba4b51a1b71f2619acc608da8106debced6b9341 100644
--- a/src/test/scala/leon/test/LeonRegressionSuite.scala
+++ b/src/test/scala/leon/test/LeonRegressionSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.test
 
diff --git a/src/test/scala/leon/test/LeonTestSuite.scala b/src/test/scala/leon/test/LeonTestSuite.scala
index 18bd8fc1465988ed7c3894858cc266f975b2395c..2c9399f12106032138b6abbe2793e10b6f10ef92 100644
--- a/src/test/scala/leon/test/LeonTestSuite.scala
+++ b/src/test/scala/leon/test/LeonTestSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.test
 
diff --git a/src/test/scala/leon/test/LeonTestSuiteWithProgram.scala b/src/test/scala/leon/test/LeonTestSuiteWithProgram.scala
index 23f6de0689d6f9debd1d7eae39eb9ab5fd9053f8..9448147272939754b7e69e6b23e651836fe3b187 100644
--- a/src/test/scala/leon/test/LeonTestSuiteWithProgram.scala
+++ b/src/test/scala/leon/test/LeonTestSuiteWithProgram.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.test
 
diff --git a/src/test/scala/leon/test/TestSilentReporter.scala b/src/test/scala/leon/test/TestSilentReporter.scala
index 2a8761584222f02c1e4bf85b6fd031c603771079..a7b3535a26c9d10d2c40b1df18f2f8b970be96e8 100644
--- a/src/test/scala/leon/test/TestSilentReporter.scala
+++ b/src/test/scala/leon/test/TestSilentReporter.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.test
 
diff --git a/src/test/scala/leon/test/helpers/ExpressionsDSL.scala b/src/test/scala/leon/test/helpers/ExpressionsDSL.scala
index 715a874e6d7d29b471ee923dff682fc19b26881f..fa118cbcc94a14bce81ffdacd9af4c5f154f8c6e 100644
--- a/src/test/scala/leon/test/helpers/ExpressionsDSL.scala
+++ b/src/test/scala/leon/test/helpers/ExpressionsDSL.scala
@@ -1,3 +1,5 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
 package leon.test.helpers
 
 import org.scalatest.Assertions
@@ -34,6 +36,13 @@ trait ExpressionsDSL {
   val q = FreshIdentifier("q", BooleanType).toVariable
   val r = FreshIdentifier("r", BooleanType).toVariable
 
+  def id(name: String, tpe: TypeTree)(implicit pgm: Program): Identifier = {
+    FreshIdentifier(name, tpe)
+  }
+
+  def id(name: String, tpeName: String, tps: Seq[TypeTree] = Nil)(implicit pgm: Program): Identifier = {
+    id(name, classType(tpeName, tps))
+  }
 
   def funDef(name: String)(implicit pgm: Program): FunDef = {
     pgm.lookupAll(name).collect {
@@ -51,6 +60,13 @@ trait ExpressionsDSL {
     }
   }
 
+  def classType(name: String, tps: Seq[TypeTree] = Nil)(implicit pgm: Program): ClassType = {
+    classDef(name) match {
+      case acd: AbstractClassDef => AbstractClassType(acd, tps)
+      case ccd: CaseClassDef => CaseClassType(ccd, tps)
+    }
+  }
+
   def caseClassDef(name: String)(implicit pgm: Program): CaseClassDef = {
     pgm.lookupAll(name).collect {
       case ccd: CaseClassDef => ccd
diff --git a/src/test/scala/leon/test/helpers/WithLikelyEq.scala b/src/test/scala/leon/test/helpers/WithLikelyEq.scala
index d499f5617fb3edfbeae631836f1f4d07f604e0d5..9836fc151c7218e61f53cf7e3cff74da5ffc719a 100644
--- a/src/test/scala/leon/test/helpers/WithLikelyEq.scala
+++ b/src/test/scala/leon/test/helpers/WithLikelyEq.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.test.helpers
 
diff --git a/src/test/scala/leon/unit/evaluators/EvaluatorSuite.scala b/src/test/scala/leon/unit/evaluators/EvaluatorSuite.scala
index b510c01bb891532c60cace6017b2a61d09bfdbb3..e7c0f8d8f15eef2c5734218ec905c00a076486d9 100644
--- a/src/test/scala/leon/unit/evaluators/EvaluatorSuite.scala
+++ b/src/test/scala/leon/unit/evaluators/EvaluatorSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.evaluators
 
diff --git a/src/test/scala/leon/unit/purescala/ExprOpsSuite.scala b/src/test/scala/leon/unit/purescala/ExprOpsSuite.scala
index 4f74b00c5f93a3125caece106809dfd4182fa8a8..8d40aa5ce6672fe8fa6bb2e001ecb8797da68272 100644
--- a/src/test/scala/leon/unit/purescala/ExprOpsSuite.scala
+++ b/src/test/scala/leon/unit/purescala/ExprOpsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.purescala
 
diff --git a/src/test/scala/leon/unit/purescala/SimplifyLetsSuite.scala b/src/test/scala/leon/unit/purescala/SimplifyLetsSuite.scala
index 2dd956cdd2ddae2f072b6aeaaafd634f407772f8..13f54e9f4376afb7d5d2d020e5789fe0ec63d209 100644
--- a/src/test/scala/leon/unit/purescala/SimplifyLetsSuite.scala
+++ b/src/test/scala/leon/unit/purescala/SimplifyLetsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.purescala
 
diff --git a/src/test/scala/leon/unit/purescala/TreeNormalizationsSuite.scala b/src/test/scala/leon/unit/purescala/TreeNormalizationsSuite.scala
index 5337bc0c4c6ff290d2f97166c89291d0fb41b090..444a2904852476bc788902e596771575051047c3 100644
--- a/src/test/scala/leon/unit/purescala/TreeNormalizationsSuite.scala
+++ b/src/test/scala/leon/unit/purescala/TreeNormalizationsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.purescala
 
diff --git a/src/test/scala/leon/unit/purescala/TreeTestsSuite.scala b/src/test/scala/leon/unit/purescala/TreeTestsSuite.scala
index 33552066ec7e0dd630c37c06899758efc740f8fb..8c6b5c523b620a4ecb90429a30721b4e7bfd69c4 100644
--- a/src/test/scala/leon/unit/purescala/TreeTestsSuite.scala
+++ b/src/test/scala/leon/unit/purescala/TreeTestsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.purescala
 
diff --git a/src/test/scala/leon/unit/purescala/TypeOpsSuite.scala b/src/test/scala/leon/unit/purescala/TypeOpsSuite.scala
index c7ce03cf7e6a9ba856f6ffd462e0e390b2ca59b7..e24be6f2811da9e9a52bec29ef8786835e6f495e 100644
--- a/src/test/scala/leon/unit/purescala/TypeOpsSuite.scala
+++ b/src/test/scala/leon/unit/purescala/TypeOpsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.purescala
 
diff --git a/src/test/scala/leon/unit/solvers/SolverPoolSuite.scala b/src/test/scala/leon/unit/solvers/SolverPoolSuite.scala
index f6d334454bcb85462dbe08820aafba1e30ee6b78..eba92b1f00039287753a1db5a3e5b3bb660fd718 100644
--- a/src/test/scala/leon/unit/solvers/SolverPoolSuite.scala
+++ b/src/test/scala/leon/unit/solvers/SolverPoolSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.solvers
 
diff --git a/src/test/scala/leon/unit/synthesis/AlgebraSuite.scala b/src/test/scala/leon/unit/synthesis/AlgebraSuite.scala
index c54b8dda42c9a817cc739711197bce74516a59f9..b185454d9e2ed246a618172acd17bf6d24db2b0a 100644
--- a/src/test/scala/leon/unit/synthesis/AlgebraSuite.scala
+++ b/src/test/scala/leon/unit/synthesis/AlgebraSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.synthesis
 import leon.test._
diff --git a/src/test/scala/leon/unit/synthesis/LinearEquationsSuite.scala b/src/test/scala/leon/unit/synthesis/LinearEquationsSuite.scala
index a754d837bc2aa6ee428a2a366a9018face5f4040..260a8cce66aa6b700e8d6819c51077a5267e5c5b 100644
--- a/src/test/scala/leon/unit/synthesis/LinearEquationsSuite.scala
+++ b/src/test/scala/leon/unit/synthesis/LinearEquationsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.synthesis
 import leon.test._
diff --git a/src/test/scala/leon/unit/utils/GraphsSuite.scala b/src/test/scala/leon/unit/utils/GraphsSuite.scala
index 984a427fafa5632aacacd2d667f5f1d0dec7a435..fc3c45ad67f3ca859be670264b0cd40b8985a490 100644
--- a/src/test/scala/leon/unit/utils/GraphsSuite.scala
+++ b/src/test/scala/leon/unit/utils/GraphsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.utils
 
diff --git a/src/test/scala/leon/unit/utils/StreamsSuite.scala b/src/test/scala/leon/unit/utils/StreamsSuite.scala
index 0dd732adac01c1d018677bd96f6a85b229ff55f8..f11099437f3f7d17c8caaca70268ee48502f3445 100644
--- a/src/test/scala/leon/unit/utils/StreamsSuite.scala
+++ b/src/test/scala/leon/unit/utils/StreamsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.utils
 
diff --git a/src/test/scala/leon/unit/utils/UtilsSuite.scala b/src/test/scala/leon/unit/utils/UtilsSuite.scala
index fe0286a9747a58aa56d9d3334f92121f444390a5..090c4b3a895e98ee4a53fd5b790039673cafda83 100644
--- a/src/test/scala/leon/unit/utils/UtilsSuite.scala
+++ b/src/test/scala/leon/unit/utils/UtilsSuite.scala
@@ -1,4 +1,4 @@
-/* Copyright 2009-2015 EPFL, Lausanne */
+/* Copyright 2009-2016 EPFL, Lausanne */
 
 package leon.unit.utils
 
diff --git a/testcases/synthesis/PrimeHeuristic.scala.off b/testcases/synthesis/PrimeHeuristic.scala.off
deleted file mode 100644
index 31a68993597650b3c4c6242a53150456e8a34bd9..0000000000000000000000000000000000000000
--- a/testcases/synthesis/PrimeHeuristic.scala.off
+++ /dev/null
@@ -1,11 +0,0 @@
-import leon.lang._
-
-object PrimeHeuristic {
-  def maybePrime(n: Int): Boolean = n match {
-      case 2 * k     => false
-      case 3 * k     => false
-      case 6 * k - 1 => true
-      case 6 * k + 1 => true
-  }
-
-}
diff --git a/testcases/synthesis/ADTInduction.scala b/testcases/synthesis/archives/ADTInduction.scala
similarity index 100%
rename from testcases/synthesis/ADTInduction.scala
rename to testcases/synthesis/archives/ADTInduction.scala
diff --git a/testcases/synthesis/BinaryTree.scala b/testcases/synthesis/archives/BinaryTree.scala
similarity index 100%
rename from testcases/synthesis/BinaryTree.scala
rename to testcases/synthesis/archives/BinaryTree.scala
diff --git a/testcases/synthesis/CegisExamples.scala b/testcases/synthesis/archives/CegisExamples.scala
similarity index 100%
rename from testcases/synthesis/CegisExamples.scala
rename to testcases/synthesis/archives/CegisExamples.scala
diff --git a/testcases/synthesis/CegisFunctions.scala b/testcases/synthesis/archives/CegisFunctions.scala
similarity index 100%
rename from testcases/synthesis/CegisFunctions.scala
rename to testcases/synthesis/archives/CegisFunctions.scala
diff --git a/testcases/synthesis/ChooseArith.scala b/testcases/synthesis/archives/ChooseArith.scala
similarity index 100%
rename from testcases/synthesis/ChooseArith.scala
rename to testcases/synthesis/archives/ChooseArith.scala
diff --git a/testcases/synthesis/ChooseIneq.scala b/testcases/synthesis/archives/ChooseIneq.scala
similarity index 100%
rename from testcases/synthesis/ChooseIneq.scala
rename to testcases/synthesis/archives/ChooseIneq.scala
diff --git a/testcases/synthesis/ChoosePos.scala b/testcases/synthesis/archives/ChoosePos.scala
similarity index 100%
rename from testcases/synthesis/ChoosePos.scala
rename to testcases/synthesis/archives/ChoosePos.scala
diff --git a/testcases/synthesis/ChurchNumerals.scala b/testcases/synthesis/archives/ChurchNumerals.scala
similarity index 100%
rename from testcases/synthesis/ChurchNumerals.scala
rename to testcases/synthesis/archives/ChurchNumerals.scala
diff --git a/testcases/synthesis/DrSuter.scala b/testcases/synthesis/archives/DrSuter.scala
similarity index 100%
rename from testcases/synthesis/DrSuter.scala
rename to testcases/synthesis/archives/DrSuter.scala
diff --git a/testcases/synthesis/FastExp.scala b/testcases/synthesis/archives/FastExp.scala
similarity index 100%
rename from testcases/synthesis/FastExp.scala
rename to testcases/synthesis/archives/FastExp.scala
diff --git a/testcases/synthesis/FiniteSort.scala b/testcases/synthesis/archives/FiniteSort.scala
similarity index 100%
rename from testcases/synthesis/FiniteSort.scala
rename to testcases/synthesis/archives/FiniteSort.scala
diff --git a/testcases/synthesis/Injection.scala b/testcases/synthesis/archives/Injection.scala
similarity index 100%
rename from testcases/synthesis/Injection.scala
rename to testcases/synthesis/archives/Injection.scala
diff --git a/testcases/synthesis/InnerSplit.scala b/testcases/synthesis/archives/InnerSplit.scala
similarity index 100%
rename from testcases/synthesis/InnerSplit.scala
rename to testcases/synthesis/archives/InnerSplit.scala
diff --git a/testcases/synthesis/Justify.scala b/testcases/synthesis/archives/Justify.scala
similarity index 100%
rename from testcases/synthesis/Justify.scala
rename to testcases/synthesis/archives/Justify.scala
diff --git a/testcases/synthesis/Matching.scala b/testcases/synthesis/archives/Matching.scala
similarity index 100%
rename from testcases/synthesis/Matching.scala
rename to testcases/synthesis/archives/Matching.scala
diff --git a/testcases/synthesis/ScaleWeight.scala b/testcases/synthesis/archives/ScaleWeight.scala
similarity index 100%
rename from testcases/synthesis/ScaleWeight.scala
rename to testcases/synthesis/archives/ScaleWeight.scala
diff --git a/testcases/synthesis/Sec2Time.scala b/testcases/synthesis/archives/Sec2Time.scala
similarity index 100%
rename from testcases/synthesis/Sec2Time.scala
rename to testcases/synthesis/archives/Sec2Time.scala
diff --git a/testcases/synthesis/SimplestCegis.scala b/testcases/synthesis/archives/SimplestCegis.scala
similarity index 100%
rename from testcases/synthesis/SimplestCegis.scala
rename to testcases/synthesis/archives/SimplestCegis.scala
diff --git a/testcases/synthesis/Spt.scala b/testcases/synthesis/archives/Spt.scala
similarity index 100%
rename from testcases/synthesis/Spt.scala
rename to testcases/synthesis/archives/Spt.scala
diff --git a/testcases/synthesis/Unification.scala b/testcases/synthesis/archives/Unification.scala
similarity index 100%
rename from testcases/synthesis/Unification.scala
rename to testcases/synthesis/archives/Unification.scala
diff --git a/testcases/synthesis/ZuneBug.scala b/testcases/synthesis/archives/ZuneBug.scala
similarity index 100%
rename from testcases/synthesis/ZuneBug.scala
rename to testcases/synthesis/archives/ZuneBug.scala
diff --git a/testcases/synthesis/current/AddressBook/Make.scala b/testcases/synthesis/current/AddressBook/Make.scala
new file mode 100644
index 0000000000000000000000000000000000000000..612effe382140cfc87bd0c12d791c4de9ddfae8e
--- /dev/null
+++ b/testcases/synthesis/current/AddressBook/Make.scala
@@ -0,0 +1,66 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object AddressBookMake {
+
+  case class Address[A](info: A, priv: Boolean)
+
+  sealed abstract class AddressList[A] {
+    def size: BigInt = {
+      this match {
+        case Nil() => BigInt(0)
+        case Cons(head, tail) => BigInt(1) + tail.size
+      }
+    } ensuring { res => res >= 0 }
+
+    def content: Set[Address[A]] = this match {
+      case Nil() => Set[Address[A]]()
+      case Cons(addr, l1) => Set(addr) ++ l1.content
+    }
+  }
+
+  case class Cons[A](a: Address[A], tail: AddressList[A]) extends AddressList[A]
+  case class Nil[A]() extends AddressList[A]
+
+  def allPersonal[A](l: AddressList[A]): Boolean = l match {
+    case Nil() => true
+    case Cons(a, l1) =>
+      if (a.priv) allPersonal(l1)
+      else false
+  }
+
+  def allBusiness[A](l: AddressList[A]): Boolean = l match {
+    case Nil() => true
+    case Cons(a, l1) =>
+      if (a.priv) false
+      else allBusiness(l1)
+  }
+
+  case class AddressBook[A](business: AddressList[A], personal: AddressList[A]) {
+    def size: BigInt = business.size + personal.size
+
+    def content: Set[Address[A]] = business.content ++ personal.content
+
+    def invariant = {
+      allPersonal(personal) && allBusiness(business)
+    }
+  }
+
+  def makeAddressBook[A](as: AddressList[A]): AddressBook[A] = {
+    choose( (res: AddressBook[A]) => res.content == as.content && res.invariant )
+
+ /*   as match {
+      case Nil() => AddressBook[A](Nil[A](), Nil[A]())
+      case Cons(x, xs) =>
+        val AddressBook(b, p) = makeAddressBook(xs)
+        if(x.priv) AddressBook(b, Cons(x, p))
+        else AddressBook(Cons(x, b), p)
+    }
+
+  } ensuring { 
+    res => res.content == as.content && res.invariant */
+  }
+
+
+}
diff --git a/testcases/synthesis/current/AddressBook/Merge.scala b/testcases/synthesis/current/AddressBook/Merge.scala
new file mode 100644
index 0000000000000000000000000000000000000000..92a5b5bfef213e35c4f2a76bbbc9f295e406d1f4
--- /dev/null
+++ b/testcases/synthesis/current/AddressBook/Merge.scala
@@ -0,0 +1,69 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object AddressBookMake {
+
+  case class Address[A](info: A, priv: Boolean)
+
+  sealed abstract class AddressList[A] {
+    def size: BigInt = {
+      this match {
+        case Nil() => BigInt(0)
+        case Cons(head, tail) => BigInt(1) + tail.size
+      }
+    } ensuring { res => res >= 0 }
+
+    def content: Set[Address[A]] = this match {
+      case Nil() => Set[Address[A]]()
+      case Cons(addr, l1) => Set(addr) ++ l1.content
+    }
+
+    def ++(that: AddressList[A]): AddressList[A] = {
+      this match {
+        case Cons(h, t) => Cons(h, t ++ that)
+        case Nil() => that
+      }
+    } ensuring {
+      res => res.content == this.content ++ that.content
+    }
+  }
+
+  case class Cons[A](a: Address[A], tail: AddressList[A]) extends AddressList[A]
+  case class Nil[A]() extends AddressList[A]
+
+  def allPersonal[A](l: AddressList[A]): Boolean = l match {
+    case Nil() => true
+    case Cons(a, l1) =>
+      if (a.priv) allPersonal(l1)
+      else false
+  }
+
+  def allBusiness[A](l: AddressList[A]): Boolean = l match {
+    case Nil() => true
+    case Cons(a, l1) =>
+      if (a.priv) false
+      else allBusiness(l1)
+  }
+
+  case class AddressBook[A](business: AddressList[A], personal: AddressList[A]) {
+    def size: BigInt = business.size + personal.size
+
+    def content: Set[Address[A]] = business.content ++ personal.content
+
+    @inline
+    def invariant = {
+      allPersonal(personal) && allBusiness(business)
+    }
+  }
+
+  def merge[A](a1: AddressBook[A], a2: AddressBook[A]): AddressBook[A] = {
+    require(a1.invariant && a2.invariant)
+
+    choose( (res: AddressBook[A]) =>
+      res.personal.content == (a1.personal.content ++ a2.personal.content) &&
+      res.business.content == (a1.business.content ++ a2.business.content) &&
+      res.invariant
+    )
+  }
+}
diff --git a/testcases/synthesis/current/BatchedQueue/Dequeue.scala b/testcases/synthesis/current/BatchedQueue/Dequeue.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c44fc062847b9af2264a9b3bba05186a313ab36b
--- /dev/null
+++ b/testcases/synthesis/current/BatchedQueue/Dequeue.scala
@@ -0,0 +1,80 @@
+import leon.lang._
+import leon.lang.synthesis._
+
+object BatchedQueue {
+  sealed abstract class List[T] {
+    def content: Set[T] = {
+      this match {
+        case Cons(h, t) => Set(h) ++ t.content
+        case Nil() => Set()
+      }
+    }
+
+    def size: BigInt = {
+      this match {
+        case Cons(h, t) => BigInt(1) + t.size
+        case Nil() => BigInt(0)
+      }
+    } ensuring { _ >= 0 }
+
+    def reverse: List[T] = {
+      this match {
+        case Cons(h, t) => t.reverse.append(Cons(h, Nil[T]()))
+        case Nil() => Nil[T]()
+      }
+    } ensuring { res =>
+      this.content == res.content
+    }
+
+    def append(r: List[T]): List[T] = {
+      this match {
+        case Cons(h, t) => Cons(h, t.append(r))
+        case Nil() => r
+      }
+    }
+
+    def isEmpty: Boolean = {
+      this == Nil[T]()
+    }
+
+    def tail: List[T] = {
+      require(this != Nil[T]())
+      this match {
+        case Cons(h, t) => t
+      }
+    }
+
+    def head: T = {
+      require(this != Nil[T]())
+      this match {
+        case Cons(h, t) => h
+      }
+    }
+  }
+
+  case class Cons[T](h: T, t: List[T]) extends List[T]
+  case class Nil[T]() extends List[T]
+
+  case class Queue[T](f: List[T], r: List[T]) {
+    def content: Set[T] = f.content ++ r.content
+    def size: BigInt = f.size + r.size
+
+    def isEmpty: Boolean = f.isEmpty && r.isEmpty
+
+    def invariant: Boolean = {
+      (f.isEmpty) ==> (r.isEmpty)
+    }
+
+    def toList: List[T] = f.append(r.reverse)
+
+    def dequeue: Queue[T] = {
+      require(invariant && !isEmpty)
+
+      choose { (res: Queue[T]) =>
+        res.size == size-1 && res.toList == this.toList.tail && res.invariant
+      }
+    }
+  }
+
+  val test = Queue[BigInt](Cons(42, Nil()), Nil()).dequeue
+}
diff --git a/testcases/synthesis/current/BatchedQueue/Enqueue.scala b/testcases/synthesis/current/BatchedQueue/Enqueue.scala
new file mode 100644
index 0000000000000000000000000000000000000000..0f30a5ba1a95d39e78a1594f39804c8161e919a6
--- /dev/null
+++ b/testcases/synthesis/current/BatchedQueue/Enqueue.scala
@@ -0,0 +1,83 @@
+import leon.lang._
+import leon.lang.synthesis._
+
+object BatchedQueue {
+  sealed abstract class List[T] {
+    def content: Set[T] = {
+      this match {
+        case Cons(h, t) => Set(h) ++ t.content
+        case Nil() => Set()
+      }
+    }
+
+    def size: BigInt = {
+      this match {
+        case Cons(h, t) => BigInt(1) + t.size
+        case Nil() => BigInt(0)
+      }
+    } ensuring { _ >= 0 }
+
+    def reverse: List[T] = {
+      this match {
+        case Cons(h, t) => t.reverse.append(Cons(h, Nil[T]()))
+        case Nil() => Nil[T]()
+      }
+    } ensuring { res =>
+      this.content == res.content
+    }
+
+    def append(r: List[T]): List[T] = {
+      this match {
+        case Cons(h, t) => Cons(h, t.append(r))
+        case Nil() => r
+      }
+    }
+
+    def tail: List[T] = {
+      require(this != Nil[T]())
+      this match {
+        case Cons(h, t) => t
+      }
+    }
+
+    def head: T = {
+      require(this != Nil[T]())
+      this match {
+        case Cons(h, t) => h
+      }
+    }
+
+    def last: T = {
+      require(this != Nil[T]())
+      this match {
+        case Cons(h, Nil()) => h
+        case Cons(h, t) => t.last
+      }
+    }
+  }
+
+  case class Cons[T](h: T, t: List[T]) extends List[T]
+  case class Nil[T]() extends List[T]
+
+  case class Queue[T](f: List[T], r: List[T]) {
+    def content: Set[T] = f.content ++ r.content
+    def size: BigInt = f.size + r.size
+
+    def invariant: Boolean = {
+      (f == Nil[T]()) ==> (r == Nil[T]())
+    }
+
+    def toList: List[T] = f.append(r.reverse)
+
+    def enqueue(v: T): Queue[T] = {
+      require(invariant)
+
+      ???[Queue[T]]
+    } ensuring { (res: Queue[T]) =>
+      res.invariant &&
+      res.toList.last == v &&
+      res.size == size + 1 &&
+      res.content == this.content ++ Set(v)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/Compiler/Desugar.scala b/testcases/synthesis/current/Compiler/Desugar.scala
new file mode 100644
index 0000000000000000000000000000000000000000..2684c71b2b8bbc9e5fe6cc307899ca7b92d366b4
--- /dev/null
+++ b/testcases/synthesis/current/Compiler/Desugar.scala
@@ -0,0 +1,118 @@
+import leon.lang._
+import leon.lang.synthesis._
+import leon._
+
+object Compiler {
+  abstract class Expr
+  case class Plus(lhs: Expr, rhs: Expr) extends Expr
+  case class Minus(lhs: Expr, rhs: Expr) extends Expr
+  case class UMinus(e: Expr) extends Expr
+  case class LessThan(lhs: Expr, rhs: Expr) extends Expr
+  case class And(lhs: Expr, rhs: Expr) extends Expr
+  case class Implies(lhs: Expr, rhs: Expr) extends Expr
+  case class Or(lhs: Expr, rhs: Expr) extends Expr
+  case class Not(e : Expr) extends Expr
+  case class Eq(lhs: Expr, rhs: Expr) extends Expr
+  case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr
+  case class BoolLiteral(b : Boolean) extends Expr
+  case class IntLiteral(i: BigInt) extends Expr
+
+  abstract class Value
+  case class BoolValue(b: Boolean) extends Value
+  case class IntValue(i: BigInt) extends Value
+  case object Error extends Value
+
+  def eval(e: Expr): Value = e match {
+    case Plus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il+ir)
+        case _ => Error
+      }
+
+    case Minus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il-ir)
+        case _ => Error
+      }
+
+    case UMinus(l) =>
+      eval(l) match {
+        case IntValue(b) => IntValue(-b)
+        case _ => Error
+      }
+
+    case LessThan(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => BoolValue(il < ir)
+        case _ => Error
+      }
+
+    case And(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(false) => b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Or(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Implies(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          eval(r)
+        case b @ BoolValue(false) =>
+          BoolValue(true)
+        case _ => Error
+      }
+
+    case Not(l) =>
+      eval(l) match {
+        case BoolValue(b) => BoolValue(!b)
+        case _ => Error
+      }
+
+    case Eq(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir))   => BoolValue(il == ir)
+        case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir)
+        case _ => Error
+      }
+
+    case Ite(c, t, e) =>
+      eval(c) match {
+        case BoolValue(true) => eval(t)
+        case BoolValue(false) => eval(t)
+        case _ => Error
+      }
+
+    case IntLiteral(l)  => IntValue(l)
+    case BoolLiteral(b) => BoolValue(b)
+  }
+
+  def rewriteMinus(in: Minus): Expr = {
+    choose{ (out: Expr) =>
+      eval(in) == eval(out) && !(out.isInstanceOf[Minus])
+    }
+  }
+
+  def rewriteImplies(in: Implies): Expr = {
+    choose{ (out: Expr) =>
+      eval(in) == eval(out) && !(out.isInstanceOf[Implies])
+    }
+  }
+
+
+  def plop(x: Expr) = {
+    eval(x) == Error//eval(Not(IntLiteral(BigInt(2))))
+  }.holds
+}
diff --git a/testcases/synthesis/current/Compiler/DesugarImplies.scala b/testcases/synthesis/current/Compiler/DesugarImplies.scala
new file mode 100644
index 0000000000000000000000000000000000000000..de5c544ff368043ca7847376af8cd9ae6b513f4d
--- /dev/null
+++ b/testcases/synthesis/current/Compiler/DesugarImplies.scala
@@ -0,0 +1,144 @@
+import leon.lang._
+import leon.lang.synthesis._
+import leon._
+
+object Compiler {
+  abstract class Expr
+  case class Plus(lhs: Expr, rhs: Expr) extends Expr
+  case class Minus(lhs: Expr, rhs: Expr) extends Expr
+  case class UMinus(e: Expr) extends Expr
+  case class LessThan(lhs: Expr, rhs: Expr) extends Expr
+  case class And(lhs: Expr, rhs: Expr) extends Expr
+  case class Implies(lhs: Expr, rhs: Expr) extends Expr
+  case class Or(lhs: Expr, rhs: Expr) extends Expr
+  case class Not(e : Expr) extends Expr
+  case class Eq(lhs: Expr, rhs: Expr) extends Expr
+  case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr
+  case class BoolLiteral(b : Boolean) extends Expr
+  case class IntLiteral(i: BigInt) extends Expr
+
+  def exists(e: Expr, f: Expr => Boolean): Boolean = {
+    f(e) || (e match {
+      case Plus(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Minus(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case LessThan(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case And(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Or(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Implies(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Eq(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Ite(c, t, e) => exists(c, f) || exists(t, f) || exists(e, f)
+      case Not(e) => exists(e, f)
+      case UMinus(e) => exists(e, f)
+      case _ => false
+    })
+  }
+
+  abstract class Value
+  case class BoolValue(b: Boolean) extends Value
+  case class IntValue(i: BigInt) extends Value
+  case object Error extends Value
+
+  def eval(e: Expr): Value = e match {
+    case Plus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il+ir)
+        case _ => Error
+      }
+
+    case Minus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il-ir)
+        case _ => Error
+      }
+
+    case UMinus(l) =>
+      eval(l) match {
+        case IntValue(b) => IntValue(-b)
+        case _ => Error
+      }
+
+    case LessThan(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => BoolValue(il < ir)
+        case _ => Error
+      }
+
+    case And(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(false) => b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Or(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Implies(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          eval(r)
+        case b @ BoolValue(false) =>
+          BoolValue(true)
+        case _ => Error
+      }
+
+    case Not(l) =>
+      eval(l) match {
+        case BoolValue(b) => BoolValue(!b)
+        case _ => Error
+      }
+
+    case Eq(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir))   => BoolValue(il == ir)
+        case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir)
+        case _ => Error
+      }
+
+    case Ite(c, t, e) =>
+      eval(c) match {
+        case BoolValue(true) => eval(t)
+        case BoolValue(false) => eval(t)
+        case _ => Error
+      }
+
+    case IntLiteral(l)  => IntValue(l)
+    case BoolLiteral(b) => BoolValue(b)
+  }
+
+
+  //def desugar(e: Expr): Expr = {
+  //  choose{ (out: Expr) =>
+  //    eval(e) == eval(out) && !exists(out, f => f.isInstanceOf[Implies])
+  //  }
+  //}
+
+  def desugar(e: Expr): Expr = {
+    e match {
+      case Plus(lhs, rhs) => Plus(desugar(lhs), desugar(rhs))
+      case Minus(lhs, rhs) => Minus(desugar(lhs), desugar(rhs))
+      case LessThan(lhs, rhs) => LessThan(desugar(lhs), desugar(rhs))
+      case And(lhs, rhs) => And(desugar(lhs), desugar(rhs))
+      case Or(lhs, rhs) => Or(desugar(lhs), desugar(rhs))
+      case Implies(lhs, rhs) => //Implies(desugar(lhs), desugar(rhs))
+        Or(Not(desugar(lhs)), desugar(rhs))
+      case Eq(lhs, rhs) => Eq(desugar(lhs), desugar(rhs))
+      case Ite(c, t, e) => Ite(desugar(c), desugar(t), desugar(e))
+      case Not(e) => Not(desugar(e))
+      case UMinus(e) => UMinus(desugar(e))
+      case e => e
+    }
+  } ensuring { out =>
+    //eval(e) == eval(out) && 
+    !exists(out, f => f.isInstanceOf[Implies])
+  }
+}
diff --git a/testcases/synthesis/current/Compiler/RewriteImplies.scala b/testcases/synthesis/current/Compiler/RewriteImplies.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4b50b9cbe34043f65d1a8feeaadac929822e6c70
--- /dev/null
+++ b/testcases/synthesis/current/Compiler/RewriteImplies.scala
@@ -0,0 +1,124 @@
+import leon.lang._
+import leon.lang.synthesis._
+import leon._
+
+object Compiler {
+  abstract class Expr
+  case class Plus(lhs: Expr, rhs: Expr) extends Expr
+  case class Minus(lhs: Expr, rhs: Expr) extends Expr
+  case class UMinus(e: Expr) extends Expr
+  case class LessThan(lhs: Expr, rhs: Expr) extends Expr
+  case class And(lhs: Expr, rhs: Expr) extends Expr
+  case class Implies(lhs: Expr, rhs: Expr) extends Expr
+  case class Or(lhs: Expr, rhs: Expr) extends Expr
+  case class Not(e : Expr) extends Expr
+  case class Eq(lhs: Expr, rhs: Expr) extends Expr
+  case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr
+  case class BoolLiteral(b : Boolean) extends Expr
+  case class IntLiteral(i: BigInt) extends Expr
+
+  def exists(e: Expr, f: Expr => Boolean): Boolean = {
+    f(e) || (e match {
+      case Plus(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Minus(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case LessThan(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case And(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Or(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Implies(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Eq(lhs, rhs) => exists(lhs, f) || exists(rhs, f)
+      case Ite(c, t, e) => exists(c, f) || exists(t, f) || exists(e, f)
+      case Not(e) => exists(e, f)
+      case UMinus(e) => exists(e, f)
+      case _ => false
+    })
+  }
+
+  abstract class Value
+  case class BoolValue(b: Boolean) extends Value
+  case class IntValue(i: BigInt) extends Value
+  case object Error extends Value
+
+  def eval(e: Expr): Value = e match {
+    case Plus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il+ir)
+        case _ => Error
+      }
+
+    case Minus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il-ir)
+        case _ => Error
+      }
+
+    case UMinus(l) =>
+      eval(l) match {
+        case IntValue(b) => IntValue(-b)
+        case _ => Error
+      }
+
+    case LessThan(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => BoolValue(il < ir)
+        case _ => Error
+      }
+
+    case And(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(false) => b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Or(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Implies(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          eval(r)
+        case b @ BoolValue(false) =>
+          BoolValue(true)
+        case _ => Error
+      }
+
+    case Not(l) =>
+      eval(l) match {
+        case BoolValue(b) => BoolValue(!b)
+        case _ => Error
+      }
+
+    case Eq(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir))   => BoolValue(il == ir)
+        case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir)
+        case _ => Error
+      }
+
+    case Ite(c, t, e) =>
+      eval(c) match {
+        case BoolValue(true) => eval(t)
+        case BoolValue(false) => eval(t)
+        case _ => Error
+      }
+
+    case IntLiteral(l)  => IntValue(l)
+    case BoolLiteral(b) => BoolValue(b)
+  }
+
+
+  def desugar(in: Expr): Expr = {
+    choose{ (out: Expr) =>
+      eval(in) == eval(out) && !(out.isInstanceOf[Implies])
+    }
+  }
+}
diff --git a/testcases/synthesis/current/Compiler/RewriteMinus.scala b/testcases/synthesis/current/Compiler/RewriteMinus.scala
new file mode 100644
index 0000000000000000000000000000000000000000..de2fa4360de5fa899110b43c171e592be5282803
--- /dev/null
+++ b/testcases/synthesis/current/Compiler/RewriteMinus.scala
@@ -0,0 +1,107 @@
+import leon.lang._
+import leon.lang.synthesis._
+import leon._
+
+object Compiler {
+  abstract class Expr
+  case class Plus(lhs: Expr, rhs: Expr) extends Expr
+  case class Minus(lhs: Expr, rhs: Expr) extends Expr
+  case class UMinus(e: Expr) extends Expr
+  case class LessThan(lhs: Expr, rhs: Expr) extends Expr
+  case class And(lhs: Expr, rhs: Expr) extends Expr
+  case class Implies(lhs: Expr, rhs: Expr) extends Expr
+  case class Or(lhs: Expr, rhs: Expr) extends Expr
+  case class Not(e : Expr) extends Expr
+  case class Eq(lhs: Expr, rhs: Expr) extends Expr
+  case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr
+  case class BoolLiteral(b : Boolean) extends Expr
+  case class IntLiteral(i: BigInt) extends Expr
+
+  abstract class Value
+  case class BoolValue(b: Boolean) extends Value
+  case class IntValue(i: BigInt) extends Value
+  case object Error extends Value
+
+  def eval(e: Expr): Value = e match {
+    case Plus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il+ir)
+        case _ => Error
+      }
+
+    case Minus(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => IntValue(il-ir)
+        case _ => Error
+      }
+
+    case UMinus(l) =>
+      eval(l) match {
+        case IntValue(b) => IntValue(-b)
+        case _ => Error
+      }
+
+    case LessThan(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir)) => BoolValue(il < ir)
+        case _ => Error
+      }
+
+    case And(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(false) => b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Or(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          b
+        case b: BoolValue =>
+          eval(r)
+        case _ =>
+          Error
+      }
+
+    case Implies(l, r) =>
+      eval(l) match {
+        case b @ BoolValue(true) =>
+          eval(r)
+        case b @ BoolValue(false) =>
+          BoolValue(true)
+        case _ => Error
+      }
+
+    case Not(l) =>
+      eval(l) match {
+        case BoolValue(b) => BoolValue(!b)
+        case _ => Error
+      }
+
+    case Eq(l, r) =>
+      (eval(l), eval(r)) match {
+        case (IntValue(il), IntValue(ir))   => BoolValue(il == ir)
+        case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir)
+        case _ => Error
+      }
+
+    case Ite(c, t, e) =>
+      eval(c) match {
+        case BoolValue(true) => eval(t)
+        case BoolValue(false) => eval(t)
+        case _ => Error
+      }
+
+    case IntLiteral(l)  => IntValue(l)
+    case BoolLiteral(b) => BoolValue(b)
+  }
+
+  def rewriteMinus(in: Minus): Expr = {
+    choose{ (out: Expr) =>
+      eval(in) == eval(out) && !(out.isInstanceOf[Minus])
+    }
+  }
+}
diff --git a/testcases/synthesis/current/Diffs/Diffs.scala b/testcases/synthesis/current/Diffs/Diffs.scala
new file mode 100644
index 0000000000000000000000000000000000000000..fb0e01afb2a761260be85f6e020de73d7e32172e
--- /dev/null
+++ b/testcases/synthesis/current/Diffs/Diffs.scala
@@ -0,0 +1,16 @@
+import leon.lang._
+import leon.collection._
+import leon.lang.synthesis._
+
+object Diffs {
+
+  def diffs(l: List[BigInt]): List[BigInt] = 
+    choose((res: List[BigInt]) => 
+      res.size == l.size && undiff(res) == l
+    )
+
+  def undiff(l: List[BigInt]) = {
+    l.scanLeft(BigInt(0))(_ + _).tail
+  }
+} 
+
diff --git a/testcases/synthesis/current/HOFs/FilterNonNeg.scala b/testcases/synthesis/current/HOFs/FilterNonNeg.scala
new file mode 100644
index 0000000000000000000000000000000000000000..3d17b5d1447b4678baf9b64f15cb154ef4a887a5
--- /dev/null
+++ b/testcases/synthesis/current/HOFs/FilterNonNeg.scala
@@ -0,0 +1,26 @@
+import leon.lang._
+import leon.lang.synthesis._
+
+object FilterNonNeg {
+
+  abstract class List
+  case object Nil extends List
+  case class Cons(h: Int, t: List) extends List
+
+  def filter(l: List, f: Int => Boolean): List = {
+    l match {
+      case Cons(h, t) => if (f(h)) Cons(h, filter(t, f)) else filter(t, f)
+      case Nil => Nil
+    }
+  }
+
+  def test(in: List): List = {
+    ???[List]
+  } ensuring {
+    out => (in, out) passes {
+      case Cons(1, Cons(2, Cons(3, Cons(4, Nil))))    => Cons(1, Cons(2, Cons(3, Cons(4, Nil))))
+      case Cons(-1, Cons(-2, Cons(3, Cons(-4, Nil)))) => Cons(3, Nil)
+      case Cons(1, Cons(-2, Cons(3, Cons(-4, Nil))))  => Cons(1, Cons(3, Nil))
+    }
+  }
+}
diff --git a/testcases/synthesis/current/HOFs/MapPlus1.scala b/testcases/synthesis/current/HOFs/MapPlus1.scala
new file mode 100644
index 0000000000000000000000000000000000000000..e14451893054dcc3f3a3ff0a29fa0828fe5da9bc
--- /dev/null
+++ b/testcases/synthesis/current/HOFs/MapPlus1.scala
@@ -0,0 +1,42 @@
+import leon.lang._
+import leon.lang.synthesis._
+
+
+object MapPlus1 {
+  abstract class List
+  case object Nil extends List
+  case class Cons(h: BigInt, t: List) extends List
+
+  def size(l: List): BigInt = {
+    l match {
+      case Cons(h, t) =>  size(t) + 1
+      case Nil => BigInt(0)
+    }
+  } ensuring { res => res >= 0 }
+
+  def sum(l: List): BigInt = {
+    l match {
+      case Cons(h, t) =>  h + sum(t)
+      case Nil => BigInt(0)
+    }
+  }
+
+
+  def map(l: List, f: BigInt => BigInt): List = {
+    l match {
+      case Nil => Nil
+      case Cons(h, t) => Cons(f(h), map(t, f))
+    }
+  } ensuring { res =>
+    size(res) == size(l)
+  }
+
+
+  def test(l: List): List = {
+      ???[List]
+  } ensuring { res =>
+    (sum(res) == sum(l) + size(l)) &&
+    (size(res) == size(l))
+  }
+
+}
diff --git a/testcases/synthesis/current/List/Delete.scala b/testcases/synthesis/current/List/Delete.scala
new file mode 100644
index 0000000000000000000000000000000000000000..30716c5919256f052d0a0e741a147d30c5bc82fa
--- /dev/null
+++ b/testcases/synthesis/current/List/Delete.scala
@@ -0,0 +1,26 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object Delete {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def delete(in: List, v: BigInt) = {
+    ???[List]
+  } ensuring {
+    (out : List) =>
+      content(out) == content(in) -- Set(v)
+  }
+}
diff --git a/testcases/synthesis/current/List/Diff.scala b/testcases/synthesis/current/List/Diff.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9fb3ade9558a7db175c6056efb9bf724f487d7ca
--- /dev/null
+++ b/testcases/synthesis/current/List/Diff.scala
@@ -0,0 +1,50 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object Diff {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List) : BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def insert(in1: List, v: BigInt): List = {
+    Cons(v, in1)
+  } ensuring { content(_) == content(in1) ++ Set(v) }
+
+  def delete(in1: List, v: BigInt): List = {
+    in1 match {
+      case Cons(h,t) =>
+        if (h == v) {
+          delete(t, v)
+        } else {
+          Cons(h, delete(t, v))
+        }
+      case Nil =>
+        Nil
+    }
+  } ensuring { content(_) == content(in1) -- Set(v) }
+
+  // def diff(in1: List, in2: List): List = {
+  //   in2 match {
+  //     case Nil =>
+  //       in1
+  //     case Cons(h, t) =>
+  //       diff(delete(in1, h), t)
+  //   }
+  // } ensuring { content(_) == content(in1) -- content(in2) }
+
+  def diff(in1: List, in2: List) = choose {
+    (out : List) =>
+      content(out) == content(in1) -- content(in2)
+  }
+}
diff --git a/testcases/synthesis/current/List/IndexOfInt.scala b/testcases/synthesis/current/List/IndexOfInt.scala
new file mode 100644
index 0000000000000000000000000000000000000000..595d40cf3ca361506ab2efccc19a0fa1140d9429
--- /dev/null
+++ b/testcases/synthesis/current/List/IndexOfInt.scala
@@ -0,0 +1,67 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object IndexOf {
+  sealed abstract class List[T] {
+    def size: BigInt = {
+      this match {
+        case Nil() => BigInt(0)
+        case Cons(_, t) => BigInt(1) + t.size
+      }
+    } ensuring {
+      res => res >= 0
+    }
+
+    def content: Set[T] = this match {
+      case Nil() => Set.empty[T]
+      case Cons(i, t) => Set(i) ++ t.content
+    }
+
+    def apply(i: BigInt): T = {
+      require(i >= 0 && i < size)
+      this match {
+        case Cons(h, t) =>
+          if (i == 0) {
+            h
+          } else {
+            t.apply(i-1)
+          }
+      }
+    } ensuring { e =>
+      content contains e
+    }
+
+    def indexOfInt(e: T): BigInt = {
+      ???[BigInt]
+      
+      //this match {
+      //  case Cons(h, t) =>
+      //    val r = t.indexOfInt(e)
+
+      //    if (e == h) {
+      //      BigInt(0)
+      //    } else {
+      //      if (r < 0) {
+      //        r
+      //      } else {
+      //        r + 1
+      //      }
+      //    }
+      //  case Nil() =>
+      //    BigInt(-1)
+      //}
+      
+    } ensuring { res =>
+      if (res < 0) {
+        !(content contains e)
+      } else {
+        res < size && apply(res) == e
+      }
+    }
+  }
+
+  case class Cons[T](head: T, tail: List[T]) extends List[T]
+  case class Nil[T]() extends List[T]
+
+}
diff --git a/testcases/synthesis/current/List/IndexOfOpt.scala b/testcases/synthesis/current/List/IndexOfOpt.scala
new file mode 100644
index 0000000000000000000000000000000000000000..6738e5c23ff8764209bd43538c1e841fd894756e
--- /dev/null
+++ b/testcases/synthesis/current/List/IndexOfOpt.scala
@@ -0,0 +1,65 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object IndexOf {
+  sealed abstract class List[T] {
+    def size: BigInt = {
+      this match {
+        case Nil() => BigInt(0)
+        case Cons(_, t) => BigInt(1) + t.size
+      }
+    } ensuring {
+      res => res >= 0
+    }
+
+    def content: Set[T] = this match {
+      case Nil() => Set.empty[T]
+      case Cons(i, t) => Set(i) ++ t.content
+    }
+
+    def apply(i: BigInt): T = {
+      require(i >= 0 && i < size)
+      this match {
+        case Cons(h, t) =>
+          if (i == 0) {
+            h
+          } else {
+            t.apply(i-1)
+          }
+      }
+    } ensuring { e =>
+      content contains e
+    }
+
+    def indexOfOpt(e: T): Option[BigInt] = {
+      ???[Option[BigInt]]
+      /*
+      this match {
+        case Cons(h, t) =>
+          val r = t.indexOfOpt(e)
+
+          if (e == h) {
+            Some(BigInt(0))
+          } else {
+            r match {
+              case Some(i) => Some(i+1)
+              case None() => None[BigInt]()
+            }
+          }
+        case Nil() =>
+          None[BigInt]()
+      }
+      */
+    } ensuring { res =>
+      res match {
+        case None() => !(content contains e)
+        case Some(i) => i >= 0 && i < size && apply(i) == e
+      }
+    }
+  }
+
+  case class Cons[T](head: T, tail: List[T]) extends List[T]
+  case class Nil[T]() extends List[T]
+
+}
diff --git a/testcases/synthesis/current/List/IndexOfOpt2.scala b/testcases/synthesis/current/List/IndexOfOpt2.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ff85f7a1c42e067b2266a948027dd22445bedca5
--- /dev/null
+++ b/testcases/synthesis/current/List/IndexOfOpt2.scala
@@ -0,0 +1,67 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object IndexOf {
+  sealed abstract class List[T] {
+    def size: BigInt = {
+      this match {
+        case Nil() => BigInt(0)
+        case Cons(_, t) => BigInt(1) + t.size
+      }
+    } ensuring {
+      res => res >= 0
+    }
+
+    def content: Set[T] = this match {
+      case Nil() => Set.empty[T]
+      case Cons(i, t) => Set(i) ++ t.content
+    }
+
+    def apply(i: BigInt): T = {
+      require(i >= 0 && i < size)
+      this match {
+        case Cons(h, t) =>
+          if (i == 0) {
+            h
+          } else {
+            t.apply(i-1)
+          }
+      }
+    } ensuring { e =>
+      content contains e
+    }
+
+    def indexOfOpt(e: T, offset: BigInt): Option[BigInt] = {
+      ???[Option[BigInt]]
+      /*
+      this match {
+        case Cons(h, t) =>
+          val r = t.indexOfOpt(e)
+
+          if (e == h) {
+            Some(BigInt(0))
+          } else {
+            r match {
+              case Some(i) => Some(i+1)
+              case None() => None[BigInt]()
+            }
+          }
+        case Nil() =>
+          None[BigInt]()
+      }
+      */
+    } ensuring { res =>
+      res match {
+        case None() => !(content contains e)
+        case Some(r) =>
+          val i = r - offset;
+          i >= 0 && i < size && apply(i) == e
+      }
+    }
+  }
+
+  case class Cons[T](head: T, tail: List[T]) extends List[T]
+  case class Nil[T]() extends List[T]
+
+}
diff --git a/testcases/synthesis/current/List/Insert.scala b/testcases/synthesis/current/List/Insert.scala
new file mode 100644
index 0000000000000000000000000000000000000000..48c38f4df0098410814f3ed27038c9c36c0d6532
--- /dev/null
+++ b/testcases/synthesis/current/List/Insert.scala
@@ -0,0 +1,28 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object Insert {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List) : BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  //def insert(in1: List, v: BigInt): List = {
+  //  Cons(v, in1)
+  //} ensuring { content(_) == content(in1) ++ Set(v) }
+
+  def insert(in1: List, v: BigInt) = choose {
+    (out : List) =>
+      content(out) == content(in1) ++ Set(v)
+  }
+}
diff --git a/testcases/synthesis/current/List/Split.scala b/testcases/synthesis/current/List/Split.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f37e68264a8b5c4030fa283abc630f22ef98cd6e
--- /dev/null
+++ b/testcases/synthesis/current/List/Split.scala
@@ -0,0 +1,37 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object Complete {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List) : BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def splitSpec(list : List, res : (List,List)) : Boolean = {
+    val s1 = size(res._1)
+    val s2 = size(res._2)
+    abs(s1 - s2) <= 1 && s1 + s2 == size(list) &&
+    content(res._1) ++ content(res._2) == content(list) 
+  }
+
+  def abs(i : BigInt) : BigInt = {
+    if(i < 0) -i else i
+  } ensuring(_ >= 0)
+
+  def split(list : List) : (List,List) = {
+    choose { (res : (List,List)) => splitSpec(list, res) }
+  }
+
+}
diff --git a/testcases/synthesis/current/List/Union.scala b/testcases/synthesis/current/List/Union.scala
new file mode 100644
index 0000000000000000000000000000000000000000..d6a5fa579f5745f00e469f19ee853da15d4fece7
--- /dev/null
+++ b/testcases/synthesis/current/List/Union.scala
@@ -0,0 +1,37 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object Union {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List) : BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1)+ size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def insert(in1: List, v: BigInt): List = {
+    Cons(v, in1)
+  } ensuring { content(_) == content(in1) ++ Set(v) }
+
+  // def union(in1: List, in2: List): List = {
+  //   in1 match {
+  //     case Cons(h, t) =>
+  //       Cons(h, union(t, in2))
+  //     case Nil =>
+  //       in2
+  //   }
+  // } ensuring { content(_) == content(in1) ++ content(in2) }
+
+  def union(in1: List, in2: List) = choose {
+    (out : List) =>
+      content(out) == content(in1) ++ content(in2)
+  }
+}
diff --git a/testcases/synthesis/current/Parentheses/Par.scala b/testcases/synthesis/current/Parentheses/Par.scala
new file mode 100644
index 0000000000000000000000000000000000000000..b91213086be4792e9535efb450bca636ca907485
--- /dev/null
+++ b/testcases/synthesis/current/Parentheses/Par.scala
@@ -0,0 +1,54 @@
+import leon.lang._
+import leon.lang.synthesis._
+import leon.collection._
+
+
+object MatchPar {
+  abstract class AbsChar
+  case object OP extends AbsChar
+  case object CP extends AbsChar
+  case object NA extends AbsChar
+
+  def matchPar(l: List[AbsChar]): BigInt = {
+
+    ???[BigInt]
+    /*
+    l match {
+      case Nil() => 0
+      case Cons(h, t) =>
+        val rec = matchPar(t)
+        h match {
+          case OP => 1 + rec
+          case CP => if (rec <= 0) {
+            -1
+          } else {
+            rec - 1
+          }
+          case NA => rec
+        }
+    }*/
+  } ensuring { res =>
+    ((count(OP, l) != count(CP, l)) ==> (res != 0)) &&
+    ((l, res) passes {
+      case Nil() => 0
+      case Cons(OP, Cons(CP, Nil())) => 0
+      case Cons(CP, Cons(OP, _))     => -1
+      case Cons(OP, Cons(OP, Nil())) => 2
+      case Cons(OP, Cons(OP, Cons(CP, Cons(CP, Cons(OP, Cons(CP, Nil())))))) => 0
+    })
+  }
+
+  def count[T](a: T, l: List[T]): BigInt = {
+    l match {
+      case Cons(h, t) =>
+        if (h == a) {
+          1 + count(a, t)
+        } else {
+          count(a, t)
+        }
+      case Nil() => BigInt(0)
+    }
+  } ensuring { (res: BigInt) =>
+    res >= 0
+  }
+}
diff --git a/testcases/synthesis/current/RunLength/RunLength.scala b/testcases/synthesis/current/RunLength/RunLength.scala
new file mode 100644
index 0000000000000000000000000000000000000000..8813b97f71fe090ec6e73b75b396f0eb25f984a8
--- /dev/null
+++ b/testcases/synthesis/current/RunLength/RunLength.scala
@@ -0,0 +1,52 @@
+import leon.lang._
+import leon.lang.synthesis._
+import leon.annotation._
+import leon.collection._
+
+object RunLength {
+
+  def decode[A](l: List[(BigInt, A)]): List[A] = {
+    def fill[A](i: BigInt, a: A): List[A] = {
+      if (i > 0) a :: fill(i - 1, a)
+      else Nil[A]()
+    }
+    l match {
+      case Nil() => Nil[A]()
+      case Cons((i, x), xs) =>
+        fill(i, x) ++ decode(xs)
+    }
+  }
+
+  def legal[A](l: List[(BigInt, A)]): Boolean = l match {
+    case Cons((i, x), tl) =>
+      i > 0 && (tl match {
+        case Cons((_, y), _) => x != y
+        case _ => true
+      }) && legal(tl)
+    case _ => true
+  }
+
+  def encode[A](l: List[A]): List[(BigInt, A)] = {
+    // Solution
+    /*l match {
+      case Nil() => Nil[(BigInt, A)]()
+      case Cons(x, xs) =>
+        val rec = encode(xs)
+        rec match {
+          case Nil() =>
+            Cons( (BigInt(1), x), Nil[(BigInt,A)]())
+          case Cons( (recC, recEl), recTl) =>
+            if (x == recEl) {
+              Cons( (1+recC, x), recTl)
+            } else {
+              Cons( (BigInt(1), x), rec )
+            }
+        }
+    }*/
+    ???[List[(BigInt, A)]]
+  } ensuring {
+    (res: List[(BigInt, A)]) =>
+      legal(res) && decode(res) == l
+  }
+
+}
diff --git a/testcases/synthesis/current/SortedList/Delete.scala b/testcases/synthesis/current/SortedList/Delete.scala
new file mode 100644
index 0000000000000000000000000000000000000000..788f232d35449cff75ac27442ce7e9cb50f42391
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/Delete.scala
@@ -0,0 +1,34 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListDelete {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def delete(in: List, v: BigInt) = {
+    require(isSorted(in))
+
+    choose( (res : List) =>
+        (content(res) == content(in) -- Set(v)) && isSorted(res)
+    )
+  }
+}
diff --git a/testcases/synthesis/current/SortedList/Diff.scala b/testcases/synthesis/current/SortedList/Diff.scala
new file mode 100644
index 0000000000000000000000000000000000000000..d391b85ba60e2b405530ddb45b40d94071263725
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/Diff.scala
@@ -0,0 +1,53 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListDiff {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def delete(in1: List, v: BigInt): List = {
+    require(isSorted(in1))
+    in1 match {
+      case Cons(h,t) =>
+        if (h < v) {
+          Cons(h, delete(t, v))
+        } else if (h == v) {
+          delete(t, v)
+        } else {
+          in1
+        }
+      case Nil =>
+        Nil
+    }
+  } ensuring { res => content(res) == content(in1) -- Set(v) && isSorted(res) }
+
+
+  def diff(in1: List, in2: List) = {
+    require(isSorted(in1) && isSorted(in2))
+
+    choose {
+      (out : List) =>
+        (content(out) == content(in1) -- content(in2)) && isSorted(out)
+    }
+  }
+
+}
diff --git a/testcases/synthesis/current/SortedList/Insert.scala b/testcases/synthesis/current/SortedList/Insert.scala
new file mode 100644
index 0000000000000000000000000000000000000000..0bf80d1e99cef290e602b0da905d6966713c77b7
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/Insert.scala
@@ -0,0 +1,34 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListInsert {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def insert(in1: List, v: BigInt): List = {
+    require(isSorted(in1))
+
+    choose { (out : List) =>
+      (content(out) == content(in1) ++ Set(v)) && isSorted(out)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/SortedList/InsertAlways.scala b/testcases/synthesis/current/SortedList/InsertAlways.scala
new file mode 100644
index 0000000000000000000000000000000000000000..73e0b240d776780fab6ac8091a8f0c925c56e695
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/InsertAlways.scala
@@ -0,0 +1,34 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListInsertAlways {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def insertAlways(in1: List, v: BigInt) = {
+    require(isSorted(in1))
+
+    choose{ (out : List) =>
+      (content(out) == content(in1) ++ Set(v)) && isSorted(out) && size(out) == size(in1) + 1
+    }
+  }
+}
diff --git a/testcases/synthesis/current/SortedList/InsertionSort.scala b/testcases/synthesis/current/SortedList/InsertionSort.scala
new file mode 100644
index 0000000000000000000000000000000000000000..0752ad33fe2249de829d7180e6facaab8fb6e160
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/InsertionSort.scala
@@ -0,0 +1,49 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListInsertionSort {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def insert(in1: List, v: BigInt): List = {
+    require(isSorted(in1))
+    in1 match {
+      case Cons(h, t) =>
+        if (v < h) {
+          Cons(v, in1)
+        } else if (v == h) {
+          in1
+        } else {
+          Cons(h, insert(t, v))
+        }
+      case Nil =>
+        Cons(v, Nil)
+    }
+
+  } ensuring { res => (content(res) == content(in1) ++ Set(v)) && isSorted(res) }
+
+  def insertionSort(in1: List): List = {
+    choose { (out: List) =>
+      content(out) == content(in1) && isSorted(out)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/SortedList/MergeSort.scala b/testcases/synthesis/current/SortedList/MergeSort.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7a285c146ff249a020b6c6611fe55bf3625ecf80
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/MergeSort.scala
@@ -0,0 +1,62 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListUnion {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def split(in: List): (List, List) = {
+    in match {
+      case Cons(h1, Cons(h2, t)) =>
+        val r = split(t)
+        (Cons(h1, r._1), Cons(h2, r._2))
+      case Cons(h1, Nil) =>
+        (in, Nil)
+      case Nil =>
+        (Nil, Nil)
+    }
+  }
+
+  def merge(in1: List, in2: List): List = {
+    require(isSorted(in1) && isSorted(in2))
+    (in1, in2) match {
+      case (Cons(h1, t1), Cons(h2, t2)) =>
+        if (h1 < h2) {
+          Cons(h1, merge(t1, in2))
+        } else {
+          Cons(h2, merge(in1, t2))
+        }
+      case (l, Nil) => l
+      case (Nil, l) => l
+    }
+  } ensuring {
+    (out : List) =>
+     (content(out) == content(in1) ++ content(in2)) && isSorted(out)
+  }
+
+  def sort(in: List): List = {
+    ???[List]
+  } ensuring {
+    (out : List) =>
+     content(out) == content(in) && isSorted(out)
+  }
+}
diff --git a/testcases/synthesis/current/SortedList/MergeSortGuided.scala b/testcases/synthesis/current/SortedList/MergeSortGuided.scala
new file mode 100644
index 0000000000000000000000000000000000000000..0035eceeadbeea82295a56d06b7ff092e7df3f35
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/MergeSortGuided.scala
@@ -0,0 +1,68 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListUnion {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def split(in: List): (List, List) = {
+    in match {
+      case Cons(h1, Cons(h2, t)) =>
+        val r = split(t)
+        (Cons(h1, r._1), Cons(h2, r._2))
+      case Cons(h1, Nil) =>
+        (in, Nil)
+      case Nil =>
+        (Nil, Nil)
+    }
+  }
+
+  def merge(in1: List, in2: List): List = {
+    require(isSorted(in1) && isSorted(in2))
+    (in1, in2) match {
+      case (Cons(h1, t1), Cons(h2, t2)) =>
+        if (h1 < h2) {
+          Cons(h1, merge(t1, in2))
+        } else {
+          Cons(h2, merge(in1, t2))
+        }
+      case (l, Nil) => l
+      case (Nil, l) => l
+    }
+  } ensuring {
+    (out : List) =>
+     (content(out) == content(in1) ++ content(in2)) && isSorted(out)
+  }
+
+  def sort(in: List): List = {
+    in match {
+      case Cons(h1, Cons(h2, t)) =>
+        val s = split(in)
+        merge(sort(s._1), sort(s._2))
+      case _ =>
+        ???[List]
+    }
+  } ensuring {
+    (out : List) =>
+     content(out) == content(in) && isSorted(out)
+  }
+}
diff --git a/testcases/synthesis/current/SortedList/Union.scala b/testcases/synthesis/current/SortedList/Union.scala
new file mode 100644
index 0000000000000000000000000000000000000000..d3f11adcccc07e44d1b82c1c6aed7144cb30523c
--- /dev/null
+++ b/testcases/synthesis/current/SortedList/Union.scala
@@ -0,0 +1,51 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object SortedListUnion {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 > x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def insert(in1: List, v: BigInt): List = {
+    require(isSorted(in1))
+    in1 match {
+      case Cons(h, t) =>
+        if (v < h) {
+          Cons(v, in1)
+        } else if (v == h) {
+          in1
+        } else {
+          Cons(h, insert(t, v))
+        }
+      case Nil =>
+        Cons(v, Nil)
+    }
+
+  } ensuring { res => (content(res) == content(in1) ++ Set(v)) && isSorted(res) }
+
+  def union(in1: List, in2: List) = {
+    require(isSorted(in1) && isSorted(in2))
+    choose {
+      (out : List) =>
+       (content(out) == content(in1) ++ content(in2)) && isSorted(out)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/StrictSortedList/Delete.scala b/testcases/synthesis/current/StrictSortedList/Delete.scala
new file mode 100644
index 0000000000000000000000000000000000000000..23999d96c3577b80b00b252e0c07509f4b4b2176
--- /dev/null
+++ b/testcases/synthesis/current/StrictSortedList/Delete.scala
@@ -0,0 +1,34 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object StrictSortedListDelete {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 >= x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def delete(in: List, v: BigInt) = {
+    require(isSorted(in))
+
+    choose( (res : List) =>
+        (content(res) == content(in) -- Set(v)) && isSorted(res)
+    )
+  }
+}
diff --git a/testcases/synthesis/current/StrictSortedList/Insert.scala b/testcases/synthesis/current/StrictSortedList/Insert.scala
new file mode 100644
index 0000000000000000000000000000000000000000..65f3c01f9d7b7d8d45136196a6289088df46fa22
--- /dev/null
+++ b/testcases/synthesis/current/StrictSortedList/Insert.scala
@@ -0,0 +1,34 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object StrictSortedListInsert {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 >= x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def insert(in1: List, v: BigInt): List = {
+    require(isSorted(in1))
+
+    choose { (out : List) =>
+      (content(out) == content(in1) ++ Set(v)) && isSorted(out)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/StrictSortedList/Union.scala b/testcases/synthesis/current/StrictSortedList/Union.scala
new file mode 100644
index 0000000000000000000000000000000000000000..c10ed419d3c2cc4fefc9690efb37bc723799ef1c
--- /dev/null
+++ b/testcases/synthesis/current/StrictSortedList/Union.scala
@@ -0,0 +1,51 @@
+import leon.annotation._
+import leon.lang._
+import leon.lang.synthesis._
+
+object StrictSortedListUnion {
+  sealed abstract class List
+  case class Cons(head: BigInt, tail: List) extends List
+  case object Nil extends List
+
+  def size(l: List): BigInt = (l match {
+    case Nil => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= 0)
+
+  def content(l: List): Set[BigInt] = l match {
+    case Nil => Set.empty[BigInt]
+    case Cons(i, t) => Set(i) ++ content(t)
+  }
+
+  def isSorted(list: List): Boolean = list match {
+    case Nil => true
+    case Cons(_, Nil) => true
+    case Cons(x1, Cons(x2, _)) if(x1 >= x2) => false
+    case Cons(_, xs) => isSorted(xs)
+  }
+
+  def insert(in1: List, v: BigInt): List = {
+    require(isSorted(in1))
+    in1 match {
+      case Cons(h, t) =>
+        if (v < h) {
+          Cons(v, in1)
+        } else if (v == h) {
+          in1
+        } else {
+          Cons(h, insert(t, v))
+        }
+      case Nil =>
+        Cons(v, Nil)
+    }
+
+  } ensuring { res => (content(res) == content(in1) ++ Set(v)) && isSorted(res) }
+
+  def union(in1: List, in2: List) = {
+    require(isSorted(in1) && isSorted(in2))
+    choose {
+      (out : List) =>
+       (content(out) == content(in1) ++ content(in2)) && isSorted(out)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/UnaryNumerals/Add.scala b/testcases/synthesis/current/UnaryNumerals/Add.scala
new file mode 100644
index 0000000000000000000000000000000000000000..a34d1834fbb5cc2418ca830c5576e64d74169b4f
--- /dev/null
+++ b/testcases/synthesis/current/UnaryNumerals/Add.scala
@@ -0,0 +1,21 @@
+import leon.lang._
+import leon.lang.synthesis._
+
+object UnaryNumeralsAdd {
+  sealed abstract class Num
+  case object Z extends Num
+  case class  S(pred: Num) extends Num
+
+  def value(n: Num): BigInt = {
+    n match {
+      case Z => BigInt(0)
+      case S(p) => BigInt(1) + value(p)
+    }
+  } ensuring (_ >= 0)
+
+  def add(x: Num, y: Num): Num = {
+    choose { (r : Num) =>
+      value(r) == value(x) + value(y)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/UnaryNumerals/Distinct.scala b/testcases/synthesis/current/UnaryNumerals/Distinct.scala
new file mode 100644
index 0000000000000000000000000000000000000000..4287378d1f95225e4ff1ffae57b2d0579d72c3a5
--- /dev/null
+++ b/testcases/synthesis/current/UnaryNumerals/Distinct.scala
@@ -0,0 +1,30 @@
+import leon.lang._
+import leon.lang.synthesis._
+
+object UnaryNumeralsDistinct {
+  sealed abstract class Num
+  case object Z extends Num
+  case class  S(pred: Num) extends Num
+
+  def value(n: Num): BigInt = {
+    n match {
+      case Z => BigInt(0)
+      case S(p) => BigInt(1) + value(p)
+    }
+  } ensuring (_ >= 0)
+
+  def add(x: Num, y: Num): Num = {
+    x match {
+      case S(p) => S(add(p, y))
+      case Z => y
+    }
+  } ensuring { (r : Num) =>
+    value(r) == value(x) + value(y)
+  }
+
+  def distinct(x: Num, y: Num): Num = {
+    choose { (r : Num) =>
+      r != x && r != y
+    }
+  }
+}
diff --git a/testcases/synthesis/current/UnaryNumerals/Mult.scala b/testcases/synthesis/current/UnaryNumerals/Mult.scala
new file mode 100644
index 0000000000000000000000000000000000000000..bfa39365e8a8b35555ddc2265f40c775251b8d17
--- /dev/null
+++ b/testcases/synthesis/current/UnaryNumerals/Mult.scala
@@ -0,0 +1,30 @@
+import leon.lang._
+import leon.lang.synthesis._
+
+object UnaryNumeralsMult {
+  sealed abstract class Num
+  case object Z extends Num
+  case class  S(pred: Num) extends Num
+
+  def value(n: Num): BigInt = {
+    n match {
+      case Z => BigInt(0)
+      case S(p) => BigInt(1) + value(p)
+    }
+  } ensuring (_ >= 0)
+
+  def add(x: Num, y: Num): Num = {
+    x match {
+      case S(p) => S(add(p, y))
+      case Z => y
+    }
+  } ensuring { (r : Num) =>
+    value(r) == value(x) + value(y)
+  }
+
+  def mult(x: Num, y: Num): Num = {
+    choose { (r : Num) =>
+      value(r) == value(x) * value(y)
+    }
+  }
+}
diff --git a/testcases/synthesis/current/run.sh b/testcases/synthesis/current/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2768ce261bc4c58c5ab63475e6a44957b2305c55
--- /dev/null
+++ b/testcases/synthesis/current/run.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+function run {
+    cmd="./leon --debug=report --timeout=60 --synthesis $1"
+    echo "Running " $cmd
+    echo "------------------------------------------------------------------------------------------------------------------"
+    $cmd;
+}
+
+echo "==================================================================================================================" >> synthesis-report.txt
+# These are all the benchmarks included in my thesis
+# List
+run testcases/synthesis/current/List/Insert.scala
+run testcases/synthesis/current/List/Delete.scala
+run testcases/synthesis/current/List/Union.scala
+run testcases/synthesis/current/List/Diff.scala
+run testcases/synthesis/current/List/Split.scala
+
+# SortedList
+run testcases/synthesis/current/SortedList/Insert.scala
+run testcases/synthesis/current/SortedList/InsertAlways.scala
+run testcases/synthesis/current/SortedList/Delete.scala
+run testcases/synthesis/current/SortedList/Union.scala
+run testcases/synthesis/current/SortedList/Diff.scala
+run testcases/synthesis/current/SortedList/InsertionSort.scala
+
+# StrictSortedList
+run testcases/synthesis/current/StrictSortedList/Insert.scala
+run testcases/synthesis/current/StrictSortedList/Delete.scala
+run testcases/synthesis/current/StrictSortedList/Union.scala
+
+# UnaryNumerals
+run testcases/synthesis/current/UnaryNumerals/Add.scala
+run testcases/synthesis/current/UnaryNumerals/Distinct.scala
+run testcases/synthesis/current/UnaryNumerals/Mult.scala
+
+# BatchedQueue
+run testcases/synthesis/current/BatchedQueue/Enqueue.scala
+run testcases/synthesis/current/BatchedQueue/Dequeue.scala
+
+# AddressBook
+run testcases/synthesis/current/AddressBook/Make.scala
+run testcases/synthesis/current/AddressBook/Merge.scala
+
+# RunLength
+run testcases/synthesis/current/RunLength/RunLength.scala
+
+# Diffs
+run testcases/synthesis/current/Diffs/Diffs.scala
+
diff --git a/testcases/synthesis/etienne-thesis/AddressBook/Make.scala b/testcases/synthesis/etienne-thesis/AddressBook/Make.scala
index 1fd12466c2c6f932f776c893a66e1a290d2212ca..612effe382140cfc87bd0c12d791c4de9ddfae8e 100644
--- a/testcases/synthesis/etienne-thesis/AddressBook/Make.scala
+++ b/testcases/synthesis/etienne-thesis/AddressBook/Make.scala
@@ -49,5 +49,18 @@ object AddressBookMake {
 
   def makeAddressBook[A](as: AddressList[A]): AddressBook[A] = {
     choose( (res: AddressBook[A]) => res.content == as.content && res.invariant )
+
+ /*   as match {
+      case Nil() => AddressBook[A](Nil[A](), Nil[A]())
+      case Cons(x, xs) =>
+        val AddressBook(b, p) = makeAddressBook(xs)
+        if(x.priv) AddressBook(b, Cons(x, p))
+        else AddressBook(Cons(x, b), p)
+    }
+
+  } ensuring { 
+    res => res.content == as.content && res.invariant */
   }
+
+
 }
diff --git a/testcases/synthesis/etienne-thesis/List/Split.scala b/testcases/synthesis/etienne-thesis/List/Split.scala
index fb98204096f3e4a97b990527e588b655e8b93fac..f37e68264a8b5c4030fa283abc630f22ef98cd6e 100644
--- a/testcases/synthesis/etienne-thesis/List/Split.scala
+++ b/testcases/synthesis/etienne-thesis/List/Split.scala
@@ -30,10 +30,6 @@ object Complete {
     if(i < 0) -i else i
   } ensuring(_ >= 0)
 
-  def dispatch(es: (BigInt, BigInt), rest: (List, List)): (List, List) = {
-    (Cons(es._1, rest._1), Cons(es._2, rest._2))
-  }
-
   def split(list : List) : (List,List) = {
     choose { (res : (List,List)) => splitSpec(list, res) }
   }
diff --git a/testcases/synthesis/etienne-thesis/run.sh b/testcases/synthesis/etienne-thesis/run.sh
index 924b99cc57386f1dba92bfb97017b41a801cd8ea..3ab2ba70e48a305bc4a2ab84b644be69ff474b3d 100755
--- a/testcases/synthesis/etienne-thesis/run.sh
+++ b/testcases/synthesis/etienne-thesis/run.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 function run {
-    cmd="./leon --debug=report --timeout=30 --synthesis --cegis:maxsize=5 $1"
+    cmd="./leon --debug=report --timeout=30 --synthesis --cegis:maxsize=7 $1"
     echo "Running " $cmd
     echo "------------------------------------------------------------------------------------------------------------------"
     $cmd;
diff --git a/testcases/synthesis/future/SortedList.scala b/testcases/synthesis/future/SortedList.scala
index b71f4f67edc46804c49ba7e41c09ea054e741cec..973cd4b50ff295dec3f4d3c7d7246f07b52b3798 100644
--- a/testcases/synthesis/future/SortedList.scala
+++ b/testcases/synthesis/future/SortedList.scala
@@ -4,41 +4,44 @@ import leon.lang.synthesis._
 
 object SortedList {
   sealed abstract class List
-  case class Cons(head: Int, tail: List) extends List
+  case class Cons(head: BigInt, tail: List) extends List
   case class Nil() extends List
 
   // proved with unrolling=0
-  def size(l: List) : Int = (l match {
-    case Nil() => 0
-    case Cons(_, t) => 1 + size(t)
-  }) ensuring(res => res >= 0)
+  def size(l: List) : BigInt = (l match {
+    case Nil() => BigInt(0)
+    case Cons(_, t) => BigInt(1) + size(t)
+  }) ensuring(res => res >= BigInt(0))
 
-  //def sizeSynth(l: List): Int = choose{ (i: Int) => i >= 0 && sizeSynth(Cons(0, l)) == i + 1}
+  //def sizeSynth(l: List): BigInt = choose{ (i: BigInt) => i >= 0 && sizeSynth(Cons(0, l)) == i + 1}
 
-  def content(l: List): Set[Int] = l match {
+  def content(l: List): Set[BigInt] = l match {
     case Nil() => Set()
     case Cons(i, t) => Set(i) ++ content(t)
   }
 
   def groundSynth() = choose{ (out: List) => size(out) == 5 }
 
-  def insertSynth(in: List, v: Int) = choose{ (out: List) => content(out) == content(in) ++ Set(v) }
+  def insertSynth(in: List, v: BigInt) = choose{ (out: List) => content(out) == content(in) ++ Set(v) }
 
   def tailSynth(in: List) = choose{out: List => size(out)+1 == size(in)}
   def consSynth(in: List) = choose{out: List => size(out) == size(in)+1}
 
-  def listOfSizeSynth(i: Int) = choose{out: List => size(out) == i }
+  def listOfSizeSynth(i: BigInt) = {
+    require(i >= 0)
+    choose { out: List => size(out) == i }
+  }
 
-  def insert1(l: List, v: Int) = (
+  def insert1(l: List, v: BigInt) = (
     Cons(v, l)
   ) ensuring(res => content(res) == content(l) ++ Set(v) && size(res) >= size(l))
 
-  def insert2(l: List, v: Int): List = (l match {
+  def insert2(l: List, v: BigInt): List = (l match {
     case Nil() => Cons(v, Nil())
     case Cons(x, tail) => if (x == v) l else Cons(x, insert2(tail, v))
   }) ensuring(res => content(res) == content(l) ++ Set(v) && size(res) >= size(l))
 
-  def insert3(l: List, v: Int): List = {
+  def insert3(l: List, v: BigInt): List = {
     require(isStrictlySorted(l))
 
     l match {
@@ -54,14 +57,14 @@ object SortedList {
     }
   } ensuring(res => content(res) == content(l) ++ Set(v) && size(res) >= size(l))
 
-  def deleteSynth(in: List, v: Int) = choose{ (out: List) => !(content(out) contains v) }
+  def deleteSynth(in: List, v: BigInt) = choose{ (out: List) => !(content(out) contains v) }
 
-  def delete1(l: List, v: Int): List = (l match {
+  def delete1(l: List, v: BigInt): List = (l match {
       case Nil() => Nil()
       case Cons(x, tail) => if (x == v) delete1(tail, v) else Cons(x, delete1(tail, v))
     }) ensuring(res => !(content(res) contains v) && size(res) <= size(l))
 
-  //def delete2(l: List, v: Int): List = {
+  //def delete2(l: List, v: BigInt): List = {
   //  require(isStrictlySorted(l))
 
   //  l match {
@@ -75,19 +78,19 @@ object SortedList {
   //  }
   //} ensuring(res => !(content(res) contains v) && size(res) <= size(l))
 
-  def contains(list : List, elem : Int) : Boolean = (list match {
+  def contains(list : List, elem : BigInt) : Boolean = (list match {
     case Nil() => false
     case Cons(x, xs) => if(elem == x) true else contains(xs, elem)
   }) ensuring(res => res == content(list).contains(elem))
 
-  def deleteMagic(head: Int, tail: List, toDelete: Int): List = ({
+  def deleteMagic(head: BigInt, tail: List, toDelete: BigInt): List = ({
     //require(isStrictlySorted(Cons(head, tail)) && toDelete < head);
     require(isStrictlySorted(Cons(toDelete, Cons(head, tail))))
 
     Cons(head, tail)
   })ensuring(res => !(content(res) contains toDelete))
 
-  def delete3(l: List, v: Int): List = {
+  def delete3(l: List, v: BigInt): List = {
     require(isStrictlySorted(l))
 
     l match {
@@ -119,7 +122,7 @@ object SortedList {
     case Cons(x, xs) => lessThanAll(x, xs)
   }))
 
-  def lessThanAll(x : Int, l : List) : Boolean = (l match {
+  def lessThanAll(x : BigInt, l : List) : Boolean = (l match {
     case Nil() => true
     case Cons(y, ys) => if(x < y) lessThanAll(x, ys) else false
   }) ensuring(res => !res || !contains(l, x))
@@ -127,7 +130,7 @@ object SortedList {
   def discard(value : Boolean) = true
   
   @induct
-  def ltaLemma(x : Int, y : Int, l : List) : Boolean = {
+  def ltaLemma(x : BigInt, y : BigInt, l : List) : Boolean = {
     require(lessThanAll(y, l) && x < y)
     lessThanAll(x, Cons(y, l))
   } holds 
diff --git a/testcases/verification/list-algorithms/MergeSort.scala b/testcases/verification/list-algorithms/MergeSort.scala
index 4b494b62d40b24f5ad660fbe17ea215054509168..ed4cda282724dd60474325e58d78d53e1c13e923 100644
--- a/testcases/verification/list-algorithms/MergeSort.scala
+++ b/testcases/verification/list-algorithms/MergeSort.scala
@@ -1,68 +1,52 @@
-import leon._
-import lang._
-import annotation._
+import leon.lang._
+import synthesis._
+import leon.collection._
 
 object MergeSort {
-  sealed abstract class List
-  case class Cons(head:Int,tail:List) extends List
-  case class Nil() extends List
 
-  case class Pair(fst:List,snd:List)
-
-  def contents(l: List): Set[Int] = l match {
-    case Nil() => Set.empty
-    case Cons(x,xs) => contents(xs) ++ Set(x)
+  def isSorted(l: List[BigInt]): Boolean = l match {
+    case Cons(x, t@Cons(y, _)) => x <= y && isSorted(t)
+    case _ => true
   }
 
-  def is_sorted(l: List): Boolean = l match {
-    case Nil() => true
-    case Cons(x,xs) => xs match {
-      case Nil() => true
-      case Cons(y, ys) => x <= y && is_sorted(Cons(y, ys))
+  def merge(l1: List[BigInt], l2: List[BigInt]): List[BigInt] = {
+    require(isSorted(l1) && isSorted(l2))
+    (l1, l2) match {
+      case (Nil(), _) => l2
+      case (_, Nil()) => l1
+      case (Cons(h1,t1), Cons(h2, t2)) =>
+        if (h1 <= h2) Cons(h1, merge(t1, l2))
+        else          Cons(h2, merge(l1, t2))
     }
+  } ensuring { 
+    (res: List[BigInt]) =>
+      isSorted(res) && 
+      res.content == l1.content ++ l2.content &&
+      res.size == l1.size + l2.size
   }
 
-  def length(list:List): Int = list match {
-    case Nil() => 0
-    case Cons(x,xs) => 1 + length(xs)
-  }
-
-  def splithelper(aList:List,bList:List,n:Int): Pair =
-    if (n <= 0) Pair(aList,bList)
-    else
-    bList match {
-              case Nil() => Pair(aList,bList)
-              case Cons(x,xs) => splithelper(Cons(x,aList),xs,n-1)
+  def split(l: List[BigInt]): (List[BigInt], List[BigInt]) = {
+    l match {
+      case Cons(h1, Cons(h2, tail)) =>
+        val (rec1, rec2) = split(tail)
+        (h1 :: rec1, h2 :: rec2)
+      case _ => (l, Nil[BigInt]())
     }
+  } ensuring { (res: (List[BigInt], List[BigInt])) =>
+    val (r1, r2) = res
+    r1.size + r2.size == l.size &&
+    r1.content ++ r2.content == l.content &&
+    r1.size - r2.size <= 1 &&
+    r2.size - r1.size <= 1
+  }
 
-  def split(list:List,n:Int): Pair = splithelper(Nil(),list,n)
-
-  def merge(aList:List, bList:List):List = (bList match {
-    case Nil() => aList
-    case Cons(x,xs) =>
-         aList match {
-           case Nil() => bList
-           case Cons(y,ys) =>
-                if (y < x)
-               Cons(y,merge(ys, bList))
-            else
-           Cons(x,merge(aList, xs))
-     }
-  }) ensuring(res => contents(res) == contents(aList) ++ contents(bList))
-
-  def mergeSort(list:List):List = (list match {
-    case Nil() => list
-    case Cons(x,Nil()) => list
-    case _ =>
-         val p = split(list,length(list)/2)
-     merge(mergeSort(p.fst), mergeSort(p.snd))
-  }) ensuring(res => contents(res) == contents(list) && is_sorted(res))
-
+  def mergeSort(l: List[BigInt]): List[BigInt] = {
+    val (l1, l2) = split(l)
+    merge(mergeSort(l1), mergeSort(l2))
+  } ensuring ( res =>
+    isSorted(res) && 
+    res.content == l.content &&
+    res.size == l.size
+  )
 
-  @ignore
-  def main(args: Array[String]): Unit = {
-    val ls: List = Cons(5, Cons(2, Cons(4, Cons(5, Cons(1, Cons(8,Nil()))))))
-    println(ls)
-    println(mergeSort(ls))
-  }
 }
diff --git a/testcases/verification/xlang/BankSimpleTransactions.scala b/testcases/verification/xlang/BankSimpleTransactions.scala
new file mode 100644
index 0000000000000000000000000000000000000000..46a4d6a2be909b548e9064455f10b6c095080b90
--- /dev/null
+++ b/testcases/verification/xlang/BankSimpleTransactions.scala
@@ -0,0 +1,73 @@
+import leon.lang._
+
+object BankSimpleTransactions {
+
+  def okTransaction(): Unit = {
+    var balance: BigInt = 0
+
+    def balanceInvariant: Boolean = balance >= 0
+
+    def deposit(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0)
+      balance += x
+    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
+
+    def withdrawal(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && x <= balance)
+      balance -= x
+    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
+
+    deposit(35)
+    withdrawal(30)
+  }
+
+  def invalidTransaction(): Unit = {
+    var balance: BigInt = 0
+
+    def balanceInvariant: Boolean = balance >= 0
+
+    def deposit(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0)
+      balance += x
+    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
+
+    def withdrawal(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && x <= balance)
+      balance -= x
+    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
+
+    deposit(35)
+    withdrawal(40)
+  }
+
+
+  def internalTransfer(): Unit = {
+    var checking: BigInt = 0
+    var saving: BigInt = 0
+
+    def balance = checking + saving
+
+    def balanceInvariant: Boolean = balance >= 0
+
+    def deposit(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0)
+      checking += x
+    } ensuring(_ => checking == old(checking) + x && balanceInvariant)
+
+    def withdrawal(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && x <= checking)
+      checking -= x
+    } ensuring(_ => checking == old(checking) - x && balanceInvariant)
+
+    def checkingToSaving(x: BigInt): Unit = {
+      require(balanceInvariant && x >= 0 && checking >= x)
+      checking -= x
+      saving += x
+    } ensuring(_ => checking + saving == old(checking) + old(saving) && balanceInvariant)
+
+    deposit(50)
+    withdrawal(30)
+    checkingToSaving(10)
+  }
+
+}
diff --git a/testcases/verification/xlang/BankTransfer.scala b/testcases/verification/xlang/BankTransfer.scala
index c533b4e08a6297446aad36d7a31fd04e148ccc37..2044df06ae01907a0df26e876ae4784feab6b0ce 100644
--- a/testcases/verification/xlang/BankTransfer.scala
+++ b/testcases/verification/xlang/BankTransfer.scala
@@ -2,72 +2,39 @@ import leon.lang._
 
 object BankTransfer {
 
-  def okTransaction(): Unit = {
-    var balance: BigInt = 0
+  case class BankAccount(var checking: BigInt, var saving: BigInt) {
+    require(checking >= 0 && saving >= 0)
 
-    def balanceInvariant: Boolean = balance >= 0
-
-    def deposit(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0)
-      balance += x
-    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
-
-    def withdrawal(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && x <= balance)
-      balance -= x
-    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
-
-    deposit(35)
-    withdrawal(30)
+    def balance: BigInt = checking + saving
   }
 
-  def invalidTransaction(): Unit = {
-    var balance: BigInt = 0
+  //TODO: support for map references to mutable items
+  //case class Bank(accounts: Map[BigInt, BankAccount])
 
-    def balanceInvariant: Boolean = balance >= 0
 
-    def deposit(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0)
-      balance += x
-    } ensuring(_ => balance == old(balance) + x && balanceInvariant)
-
-    def withdrawal(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && x <= balance)
-      balance -= x
-    } ensuring(_ => balance == old(balance) - x && balanceInvariant)
-
-    deposit(35)
-    withdrawal(40)
-  }
+  def deposit(x: BigInt, account: BankAccount): Unit = {
+    require(x > 0)
+    account.checking = account.checking + x
+  } ensuring(_ => account.balance == old(account).balance + x)
 
+  def withdrawal(x: BigInt, account: BankAccount): Unit = {
+    require(x > 0 && account.checking >= x)
+    account.checking = account.checking - x
+  } ensuring(_ => account.balance == old(account).balance - x)
 
-  def internalTransfer(): Unit = {
-    var checking: BigInt = 0
-    var saving: BigInt = 0
+  def transfer(x: BigInt, a1: BankAccount, a2: BankAccount): Unit = {
+    require(x > 0 && a1.checking >= x)
+    withdrawal(x, a1)
+    deposit(x, a2)
+  } ensuring(_ => a1.balance + a2.balance == old(a1).balance + old(a2).balance &&
+                  a1.balance == old(a1).balance - x &&
+                  a2.balance == old(a2).balance + x)
 
-    def balance = checking + saving
 
-    def balanceInvariant: Boolean = balance >= 0
-
-    def deposit(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0)
-      checking += x
-    } ensuring(_ => checking == old(checking) + x && balanceInvariant)
-
-    def withdrawal(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && x <= checking)
-      checking -= x
-    } ensuring(_ => checking == old(checking) - x && balanceInvariant)
-
-    def checkingToSaving(x: BigInt): Unit = {
-      require(balanceInvariant && x >= 0 && checking >= x)
-      checking -= x
-      saving += x
-    } ensuring(_ => checking + saving == old(checking) + old(saving) && balanceInvariant)
-
-    deposit(50)
-    withdrawal(30)
-    checkingToSaving(10)
-  }
+  def save(x: BigInt, account: BankAccount): Unit = {
+    require(x > 0 && account.checking >= x)
+    account.checking = account.checking - x
+    account.saving = account.saving + x
+  } ensuring(_ => account.balance == old(account).balance)
 
 }
diff --git a/testcases/verification/xlang/FunctionCaching.scala b/testcases/verification/xlang/FunctionCaching.scala
new file mode 100644
index 0000000000000000000000000000000000000000..75c73e822831a5d7da9a209f1964d36e10298359
--- /dev/null
+++ b/testcases/verification/xlang/FunctionCaching.scala
@@ -0,0 +1,40 @@
+import leon.lang._
+import leon.collection._
+
+object FunctionCaching {
+
+  case class CachedFun[A,B](fun: (A) => B, var cached: Map[A, B], var cacheHit: Set[A]) {
+
+    def call(a: A): B = {
+      cached.get(a) match {
+        case None() =>
+          val res = fun(a)
+          cached = cached.updated(a, res)
+          res
+        case Some(res) =>
+          cacheHit = cacheHit ++ Set(a)
+          res
+      }
+    }
+
+  }
+
+  def funProperlyCached(x: BigInt, fun: (BigInt) => BigInt, trash: List[BigInt]): Boolean = {
+    val cachedFun = CachedFun[BigInt, BigInt](fun, Map(), Set())
+    val res1 = cachedFun.call(x)
+    multipleCalls(trash, cachedFun, x)
+    val res2 = cachedFun.call(x)
+    res1 == res2 && cachedFun.cacheHit.contains(x)
+  } holds
+
+  def multipleCalls(args: List[BigInt], cachedFun: CachedFun[BigInt, BigInt], x: BigInt): Unit = {
+    require(cachedFun.cached.isDefinedAt(x))
+    args match {
+      case Nil() => ()
+      case y::ys =>
+        cachedFun.call(x)
+        multipleCalls(ys, cachedFun, x)
+    }
+  } ensuring(_ => old(cachedFun).cached.get(x) == cachedFun.cached.get(x))
+
+}
diff --git a/testcases/web/verification/05_Propositional_Logic.scala b/testcases/web/verification/05_Propositional_Logic.scala
index 455cef7ec5201fd17edee71059dc38c9d7afa3d8..9f8a7c94a5d4a7bb61d6c4c3f26cd7de055ffd5f 100644
--- a/testcases/web/verification/05_Propositional_Logic.scala
+++ b/testcases/web/verification/05_Propositional_Logic.scala
@@ -1,5 +1,6 @@
 import leon.lang._
 import leon.annotation._
+import leon.proof._
 
 object PropositionalLogic {
 
@@ -74,11 +75,6 @@ object PropositionalLogic {
 
   def fv(f : Formula) = { vars(nnf(f)) }
 
-  @induct
-  def wrongCommutative(f: Formula) : Boolean = {
-    nnf(simplify(f)) == simplify(nnf(f))
-  } holds
-
   @induct
   def simplifyPreservesNNF(f: Formula) : Boolean = {
     require(isNNF(f))
@@ -96,4 +92,87 @@ object PropositionalLogic {
     require(isSimplified(f))
     simplify(f) == f
   } holds
+
+  def and(lhs: Formula, rhs: Formula): Formula = And(lhs, rhs)
+  def or(lhs: Formula, rhs: Formula): Formula = Or(lhs, rhs)
+  
+  def simplifyPreserveNNFNot(f: Formula): Boolean = {
+    (nnf(Not(simplify(f))) == nnf(Not(f))) because {
+      f match {
+        case And(lhs, rhs) => {
+          nnf(Not(simplify(f)))                                ==| trivial                     |
+          nnf(Not(And(simplify(lhs), simplify(rhs))))          ==| trivial                     |
+          or(nnf(Not(simplify(lhs))), nnf(Not(simplify(rhs)))) ==| simplifyPreserveNNFNot(lhs) |
+          or(nnf(Not(lhs)), nnf(Not(simplify(rhs))))           ==| simplifyPreserveNNFNot(rhs) |
+          or(nnf(Not(lhs)), nnf(Not(rhs)))                     ==| trivial                     |
+          nnf(Not(And(lhs, rhs)))                              ==| trivial                     |
+          nnf(Not(f))
+        } qed
+        case Or(lhs, rhs) => {
+          nnf(Not(simplify(f)))                                 ==| trivial                     |
+          nnf(Not(Or(simplify(lhs), simplify(rhs))))            ==| trivial                     |
+          and(nnf(Not(simplify(lhs))), nnf(Not(simplify(rhs)))) ==| simplifyPreserveNNFNot(lhs) |
+          and(nnf(Not(lhs)), nnf(Not(simplify(rhs))))           ==| simplifyPreserveNNFNot(rhs) |
+          and(nnf(Not(lhs)), nnf(Not(rhs)))                     ==| trivial                     |
+          nnf(Not(Or(lhs, rhs)))                                ==| trivial                     |
+          nnf(Not(f))
+        } qed
+        case Implies(lhs, rhs) => {
+          nnf(Not(simplify(f)))                                      ==| trivial                     |
+          nnf(Not(Or(Not(simplify(lhs)), simplify(rhs))))            ==| trivial                     |
+          and(nnf(Not(Not(simplify(lhs)))), nnf(Not(simplify(rhs)))) ==| trivial                     |
+          and(nnf(simplify(lhs)), nnf(Not(simplify(rhs))))           ==| simplifyPreserveNNFNot(rhs) |
+          and(nnf(simplify(lhs)), nnf(Not(rhs)))                     ==| simplifyPreserveNNF(lhs)    |
+          and(nnf(lhs), nnf(Not(rhs)))                               ==| trivial                     |
+          nnf(Not(Implies(lhs, rhs)))
+        } qed
+        case Not(g) => {
+          nnf(Not(simplify(f)))      ==| trivial                |
+          nnf(Not(Not(simplify(g)))) ==| trivial                |
+          nnf(simplify(g))           ==| simplifyPreserveNNF(g) |
+          nnf(g)                     ==| trivial                |
+          nnf(Not(Not(g)))           ==| trivial                |
+          nnf(Not(f))
+        } qed
+        case Literal(_) => trivial
+      }
+    }
+  } holds
+  
+  def simplifyPreserveNNF(f: Formula): Boolean = {
+    (nnf(simplify(f)) == nnf(f)) because {
+      f match {
+        case And(lhs, rhs) => {
+          nnf(simplify(f))                            ==| trivial                  |
+          and(nnf(simplify(lhs)), nnf(simplify(rhs))) ==| simplifyPreserveNNF(lhs) |
+          and(nnf(lhs), nnf(simplify(rhs)))           ==| simplifyPreserveNNF(rhs) |
+          and(nnf(lhs), nnf(rhs))                     ==| trivial                  |
+          nnf(f)
+        } qed
+        case Or(lhs, rhs) => {
+          nnf(simplify(f))                           ==| trivial                  |
+          or(nnf(simplify(lhs)), nnf(simplify(rhs))) ==| simplifyPreserveNNF(lhs) |
+          or(nnf(lhs), nnf(simplify(rhs)))           ==| simplifyPreserveNNF(rhs) |
+          or(nnf(lhs), nnf(rhs))                     ==| trivial                  |
+          nnf(f)
+        } qed
+        case Implies(lhs, rhs) => {
+          nnf(simplify(f))                                ==| trivial                       |
+          nnf(or(Not(simplify(lhs)), simplify(rhs)))      ==| trivial                       |
+          or(nnf(Not(simplify(lhs))), nnf(simplify(rhs))) ==| simplifyPreserveNNF(rhs)      |
+          or(nnf(Not(simplify(lhs))), nnf(rhs))           ==| trivial                       |
+          or(nnf(simplify(Not(lhs))), nnf(rhs))           ==| simplifyPreserveNNF(Not(lhs)) |
+          or(nnf(Not(lhs)), nnf(rhs))                     ==| trivial                       |
+          nnf(f)
+        } qed
+        case Not(g) => {
+          nnf(simplify(f))      ==| trivial                   |
+          nnf(Not(simplify(g))) ==| simplifyPreserveNNFNot(g) |
+          nnf(Not(g))           ==| trivial                   |
+          nnf(f)
+        } qed
+        case Literal(_) => trivial
+      }
+    }
+  } holds
 }