diff --git a/src/main/scala/leon/grammars/ExpressionGrammar.scala b/src/main/scala/leon/grammars/ExpressionGrammar.scala
index 186729fce32c11b956cd51912941922f3954f9f0..a1309669896a9754b0f6309f2575ed2990a1b9c4 100644
--- a/src/main/scala/leon/grammars/ExpressionGrammar.scala
+++ b/src/main/scala/leon/grammars/ExpressionGrammar.scala
@@ -18,7 +18,7 @@ abstract class ExpressionGrammar {
     * @param lab The nonterminal for which production rules will be generated
     * @note This is the cached version of [[computeProductions]]. Clients should use this method.
     */
-  def getProductions(lab: Label)(implicit ctx: LeonContext) = {
+  final def getProductions(lab: Label)(implicit ctx: LeonContext) = {
     cache.getOrElse(lab, {
       val res = applyAspects(lab, computeProductions(lab))
       cache += lab -> res
@@ -33,7 +33,7 @@ abstract class ExpressionGrammar {
     */
   def computeProductions(lab: Label)(implicit ctx: LeonContext): Seq[ProductionRule[Label, Expr]]
 
-  def applyAspects(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
+  protected def applyAspects(lab: Label, ps: Seq[ProductionRule[Label, Expr]])(implicit ctx: LeonContext) = {
     lab.aspects.foldLeft(ps) {
       case (ps, a) => a.applyTo(lab, ps)
     }
diff --git a/src/main/scala/leon/grammars/Grammars.scala b/src/main/scala/leon/grammars/Grammars.scala
index 2f60d59a48463391d9dce50add99acd19da51de1..56d63a4387460163cfcbfe8146761bff6093689e 100644
--- a/src/main/scala/leon/grammars/Grammars.scala
+++ b/src/main/scala/leon/grammars/Grammars.scala
@@ -29,5 +29,8 @@ object Grammars {
     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)
   }
+
+  def similarTo(e: Expr, base: ExpressionGrammar) = {
+  }
 }
 
diff --git a/src/main/scala/leon/grammars/SimilarTo.scala b/src/main/scala/leon/grammars/SimilarTo.scala
deleted file mode 100644
index 295f18311213ff6b93316477c09926957f777527..0000000000000000000000000000000000000000
--- a/src/main/scala/leon/grammars/SimilarTo.scala
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright 2009-2016 EPFL, Lausanne */
-
-package leon
-package grammars
-
-import purescala.Types._
-import purescala.TypeOps._
-import purescala.Extractors._
-import purescala.Definitions._
-import purescala.Expressions._
-
-import synthesis._
-
-/** A grammar that generates expressions by inserting small variations in [[e]]
- * @param e The [[Expr]] to which small variations will be inserted
- */
-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/aspects/SimilarTo.scala b/src/main/scala/leon/grammars/aspects/SimilarTo.scala
index cd27a058311f9ab6527ae3d35c414c94ef5760b6..fc500814826f8cf33f79f17f639a56069d82f43b 100644
--- a/src/main/scala/leon/grammars/aspects/SimilarTo.scala
+++ b/src/main/scala/leon/grammars/aspects/SimilarTo.scala
@@ -11,13 +11,13 @@ import purescala.Constructors._
 import purescala.Extractors._
 import utils.SeqUtils._
 
-/** Generates expressions similar to a given expression
-  * @param e The expression for which similar ones will be generated
+/** Generates expressions similar to a [[Seq]] of given expressions
+  * @param es The expressions for which similar ones will be generated
   */
-case class SimilarTo(e: Expr) extends Aspect {
+case class SimilarTo(es: Seq[Expr]) extends Aspect {
   type Prods = Seq[ProductionRule[Label, Expr]]
 
-  def asString(implicit ctx: LeonContext) = "~"+e.asString+"~"
+  def asString(implicit ctx: LeonContext) = es.mkString("~", "~", "~")
 
   def term(e: Expr, tag: Tags.Tag = Tags.Top, cost: Int = 1): ProductionRule[Label, Expr] = {
     ProductionRule(Nil, { case Seq() => e }, tag, cost)
@@ -34,7 +34,7 @@ case class SimilarTo(e: Expr) extends Aspect {
       case _ => false
     }
 
-    val similarProds: Prods = if (isSubtypeOf(e.getType, lab.getType)) {
+    val similarProds: Prods = es.filter(e => isSubtypeOf(e.getType, lab.getType)).flatMap { e =>
       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)
@@ -66,7 +66,7 @@ case class SimilarTo(e: Expr) extends Aspect {
         case Operator(as, b) if as.nonEmpty =>
           for ((a, i) <- as.zipWithIndex) yield {
             ProductionRule[Label, Expr](
-              List(Label(a.getType).withAspect(SimilarTo(a))),
+              List(Label(a.getType).withAspect(SimilarTo(Seq(a)))),
               { case Seq(e) =>
                 b(as.updated(i, e))
               },
@@ -127,8 +127,6 @@ case class SimilarTo(e: Expr) extends Aspect {
       }
 
       swaps ++ subs ++ typeVariations ++ ccVariations
-    } else {
-      Nil
     }
 
     ps ++ similarProds
diff --git a/src/main/scala/leon/grammars/aspects/TypeDepthBound.scala b/src/main/scala/leon/grammars/aspects/TypeDepthBound.scala
new file mode 100644
index 0000000000000000000000000000000000000000..177c6bfd979c39597a5c5ff94ebaa0121ba78fac
--- /dev/null
+++ b/src/main/scala/leon/grammars/aspects/TypeDepthBound.scala
@@ -0,0 +1,17 @@
+/* Copyright 2009-2016 EPFL, Lausanne */
+
+package leon
+package grammars
+package aspects
+
+import purescala.TypeOps.depth
+
+case class TypeDepthBound(bound: Int) extends PersistentAspect {
+  override def asString(implicit ctx: LeonContext): String = s"TD$bound"
+
+  override def applyTo(lab: Label, ps: Seq[Production])(implicit ctx: LeonContext) = {
+    if (depth(lab.getType) > bound) Nil
+    else super.applyTo(lab, ps)
+  }
+
+}
diff --git a/src/main/scala/leon/purescala/ExprOps.scala b/src/main/scala/leon/purescala/ExprOps.scala
index ab6a848df444a3d1d7a39550febfd8a9feac02b9..95045094272c99865089b8ebf845ce8adb9dc7a5 100644
--- a/src/main/scala/leon/purescala/ExprOps.scala
+++ b/src/main/scala/leon/purescala/ExprOps.scala
@@ -190,11 +190,6 @@ object ExprOps extends { val Deconstructor = Operator } with GenTreeOps[Expr] {
     }(expr)
   }
 
-  /** Computes the depth of the expression's tree */
-  def depth(e: Expr): Int = {
-    fold[Int]{ (_, sub) => 1 + (0 +: sub).max }(e)
-  }
-
   /** Applies the function to the I/O constraint and simplifies the resulting constraint */
   def applyAsMatches(p : Passes, f : Expr => Expr) = {
     f(p.asConstraint) match {
diff --git a/src/main/scala/leon/purescala/GenTreeOps.scala b/src/main/scala/leon/purescala/GenTreeOps.scala
index bcf6002d156a8bb854bda077e17c5375b6cfaf50..66a7829737898b2bcda91cd93c2e49f11cfb7c54 100644
--- a/src/main/scala/leon/purescala/GenTreeOps.scala
+++ b/src/main/scala/leon/purescala/GenTreeOps.scala
@@ -333,4 +333,10 @@ trait GenTreeOps[SubTree <: Tree]  {
     res
   }
 
+  /** Computes the depth of the expression's tree */
+  def depth(e: SubTree): Int = {
+    fold[Int]{ (_, sub) => 1 + (0 +: sub).max }(e)
+  }
+
+
 }
diff --git a/src/main/scala/leon/purescala/TypeOps.scala b/src/main/scala/leon/purescala/TypeOps.scala
index e0ba119b7a8299e45d32251fc794b53e3c07a4a8..34db65c8a16e2849f173be77fda04da6aa90aea9 100644
--- a/src/main/scala/leon/purescala/TypeOps.scala
+++ b/src/main/scala/leon/purescala/TypeOps.scala
@@ -14,10 +14,6 @@ object TypeOps extends GenTreeOps[TypeTree] {
 
   val Deconstructor = NAryType
 
-  def typeDepth(t: TypeTree): Int = t match {
-    case NAryType(tps, builder) => 1 + (0 +: (tps map typeDepth)).max
-  }
-
   def typeParamsOf(expr: Expr): Set[TypeParameter] = {
     ExprOps.collect(e => typeParamsOf(e.getType))(expr)
   }
diff --git a/src/main/scala/leon/synthesis/rules/CEGIS.scala b/src/main/scala/leon/synthesis/rules/CEGIS.scala
index 2ec177fc947e42b4810b4c4d16fb9407b592248d..7d15ba8f48934e6b33e966f9aed806f175a1dcba 100644
--- a/src/main/scala/leon/synthesis/rules/CEGIS.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGIS.scala
@@ -13,9 +13,7 @@ import purescala.Types.TypeTree
 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.default(sctx, p), // This limits type depth
+      grammar = Grammars.default(sctx, p),
       rootLabel = Label(_),
       optimizations = false
     )
@@ -28,9 +26,7 @@ case object NaiveCEGIS extends CEGISLike("Naive CEGIS") {
 case object CEGIS extends CEGISLike("CEGIS") {
   def getParams(sctx: SynthesisContext, p: Problem) = {
     CegisParams(
-      //grammar = TaggedGrammar(base),
-      //rootLabel = TaggedNonTerm(_, Tags.Top, 0, None),
-      grammar = NaiveCEGIS.getParams(sctx,p).grammar,
+      grammar = Grammars.default(sctx, p),
       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 cdd7d433354334eacbd77e56e9ee39895d21ace8..74bf7133daae772f51182465419dd466222b1c12 100644
--- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala
@@ -9,9 +9,9 @@ import purescala.Common._
 import purescala.Definitions._
 import purescala.Types._
 import purescala.ExprOps._
+import purescala.TypeOps.depth
 import purescala.DefOps._
 import purescala.Constructors._
-import purescala.TypeOps.typeDepth
 
 import solvers._
 import grammars._
@@ -77,8 +77,7 @@ abstract class CEGISLike(name: String) extends Rule(name) {
 
       val grammar = params.grammar
 
-      //def rootLabel = SizedNonTerm(params.rootLabel(tupleTypeWrap(p.xs.map(_.getType))), termSize)
-      def rootLabel = params.rootLabel(targetType).withAspect(Sized(termSize))
+      def rootLabel = params.rootLabel(targetType).withAspect(TypeDepthBound(depth(targetType) + 1)).withAspect(Sized(termSize))
 
       def init(): Unit = {
         updateCTree()
diff --git a/src/main/scala/leon/synthesis/rules/CEGLESS.scala b/src/main/scala/leon/synthesis/rules/CEGLESS.scala
index e29c6d2bc2ceb6a1d01d1c56f42381427be90386..c1c89f6c2935b33cae0fd0014773991c6e45bfe5 100644
--- a/src/main/scala/leon/synthesis/rules/CEGLESS.scala
+++ b/src/main/scala/leon/synthesis/rules/CEGLESS.scala
@@ -8,6 +8,7 @@ import purescala.ExprOps._
 import purescala.Types._
 import purescala.Extractors._
 import grammars._
+import grammars.aspects._
 import Witnesses._
 
 case object CEGLESS extends CEGISLike("CEGLESS") {
@@ -25,12 +26,9 @@ case object CEGLESS extends CEGISLike("CEGLESS") {
       }
     }
 
-    val guidedGrammar = Union(guides.map(SimilarTo(_, sctx, p)))
-
     CegisParams(
-      grammar = guidedGrammar,
-      //rootLabel = { (tpe: TypeTree) => NonTerminal(tpe, "G0") },
-      rootLabel = { (tpe: TypeTree) => Label(tpe) },
+      grammar = Grammars.default(sctx, p),
+      rootLabel = (tpe: TypeTree) => Label(tpe).withAspect(DepthBound(2)).withAspect(SimilarTo(guides)),
       optimizations = false,
       maxSize = Some((0 +: guides.map(depth(_) + 1)).max)
     )
diff --git a/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala b/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala
index 924e9567b04ba53c8eaf56da16bed8e6fba3cc0b..4526148dab62e3f4b7484f0d6f51d6c77c69738c 100644
--- a/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala
+++ b/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala
@@ -8,6 +8,7 @@ import purescala.Types._
 import purescala.Extractors._
 import Witnesses._
 import grammars._
+import grammars.aspects.{SimilarTo, DepthBound}
 
 case object TEGLESS extends TEGISLike("TEGLESS") {
   def getParams(sctx: SynthesisContext, p: Problem) = {
@@ -25,15 +26,9 @@ case object TEGLESS extends TEGISLike("TEGLESS") {
       }
     }
 
-    val guidedGrammar = guides.map(SimilarTo(_, sctx, p)).foldLeft[ExpressionGrammar](Empty())(_ || _)
-
     TegisParams(
-      grammar = guidedGrammar,
-      //rootLabel = { (tpe: TypeTree) => NonTerminal(tpe, "G0") }
-      rootLabel = { (tpe: TypeTree) => Label(tpe) }
+      grammar = Grammars.default(sctx, p),
+      rootLabel = { (tpe: TypeTree) => Label(tpe).withAspect(DepthBound(2)).withAspect(SimilarTo(guides)) }
     )
   }
 }
-
-
-
diff --git a/src/test/scala/leon/integration/grammars/GrammarsSuite.scala b/src/test/scala/leon/integration/grammars/SimilarToSuite.scala
similarity index 95%
rename from src/test/scala/leon/integration/grammars/GrammarsSuite.scala
rename to src/test/scala/leon/integration/grammars/SimilarToSuite.scala
index 71fc0cb55fe92f37123d7c51be9f7984b29119ab..b61d6cb942348b8b6821c0a915e8e3415ee3b987 100644
--- a/src/test/scala/leon/integration/grammars/GrammarsSuite.scala
+++ b/src/test/scala/leon/integration/grammars/SimilarToSuite.scala
@@ -138,19 +138,13 @@ class SimilarToSuite extends LeonTestSuiteWithProgram with ExpressionsDSL {
     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)))
+      val exprs = enum.iterator(Label(exp.getType).withAspect(SimilarTo(Seq(from))))
 
       //println(s"SimilarTo(${from.asString}):")
 
-      if (!(exprs.exists { e => 
-        //println(s" - ${e.asString}")
-        e == exp
-      })) {
+      if (!exprs.contains(exp)) {
         info("Productions: ")
         g.printProductions(info(_))