diff --git a/src/it/scala/inox/solvers/unrolling/AssociativeQuantifiersSuite.scala b/src/it/scala/inox/solvers/unrolling/QuantifiersSuite.scala
similarity index 75%
rename from src/it/scala/inox/solvers/unrolling/AssociativeQuantifiersSuite.scala
rename to src/it/scala/inox/solvers/unrolling/QuantifiersSuite.scala
index bb914c0536ec0418264b5d56af4479149f665673..b8f15db74140cc0888c2bb7f8e2077eedbd35b07 100644
--- a/src/it/scala/inox/solvers/unrolling/AssociativeQuantifiersSuite.scala
+++ b/src/it/scala/inox/solvers/unrolling/QuantifiersSuite.scala
@@ -4,7 +4,7 @@ package inox
 package solvers
 package unrolling
 
-class AssociativeQuantifiersSuite extends TestSuite {
+class QuantifiersSuite extends TestSuite {
   import inox.trees._
   import dsl._
 
@@ -45,10 +45,18 @@ class AssociativeQuantifiersSuite extends TestSuite {
     })
   }
 
+  val isIdempotentID = FreshIdentifier("isIdempotent")
+  val isIdempotent = mkFunDef(isIdempotentID)("A") { case Seq(aT) => (
+    Seq("f" :: ((aT, aT) =>: aT)), BooleanType, { case Seq(f) =>
+      forall("x" :: aT, "y" :: aT)((x,y) => f(x,y) === f(x,f(x,y)))
+    })
+  }
+
   val symbols = new Symbols(Map(
     isAssociativeID -> isAssociative,
     isCommutativeID -> isCommutative,
-    isRotateID      -> isRotate
+    isRotateID      -> isRotate,
+    isIdempotentID  -> isIdempotent
   ), Map.empty)
 
   test("Pair of associative ==> associative pair") { ctx => 
@@ -101,4 +109,25 @@ class AssociativeQuantifiersSuite extends TestSuite {
 
     assert(SimpleSolverAPI(SolverFactory.default(program)).solveSAT(clause).isSAT)
   }
+
+  test("Commutative + idempotent satisfiable") { ctx =>
+    val program = InoxProgram(ctx, symbols)
+
+    val f = ("f" :: ((IntegerType, IntegerType) =>: IntegerType)).toVariable
+    val clause = isCommutative(IntegerType)(f) && isIdempotent(IntegerType)(f) &&
+      !(f(E(BigInt(1)), E(BigInt(2))) ===
+        f(f(E(BigInt(2)), E(BigInt(1))), E(BigInt(3))))
+
+    assert(SimpleSolverAPI(SolverFactory.default(program)).solveSAT(clause).isSAT)
+  }
+
+  test("Unification is unsatisfiable") { ctx =>
+    val program = InoxProgram(ctx, symbols)
+
+    val aT = T("A")
+    val f = ("f" :: ((aT, aT) =>: aT)).toVariable
+    val clause = forall("x" :: aT, "y" :: aT)((x,y) => !(f(x,y) === f(y,x)))
+
+    assert(SimpleSolverAPI(SolverFactory.default(program)).solveSAT(clause).isUNSAT)
+  }
 }
diff --git a/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala b/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
index 4e5bed2d032faf1933f3297bf4e5fe288d71e36d..6eca9bbb0ab26893ff1e9275463e787682e11f40 100644
--- a/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
+++ b/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
@@ -591,13 +591,20 @@ trait QuantificationTemplates { self: Templates =>
           } else {
             val substituter = mkSubstituter(map.mapValues(_.encoded))
             val msubst = map.collect { case (q, Right(m)) => q -> m }
-            val isOpt = optimizationQuorums.exists { ms =>
-              handledMatchers.containsAll(ms.map(_.substitute(substituter, msubst)))
+            val opts = optimizationQuorums.flatMap { ms =>
+              val sms = ms.map(_.substitute(substituter, msubst))
+              if (handledMatchers.containsAll(sms)) sms.toList else Nil
             }
 
-            if (isOpt) 0
-            else if (grounds(q)(bs, m.args(i))) 10
-            else 3
+            if (opts.nonEmpty) {
+              val tms = matchers.flatMap(_._2.map(_.substitute(substituter, msubst)))
+              if (opts.map(totalDepth).max >= tms.map(totalDepth).max) 0
+              else 3
+            } else if (grounds(q)(bs, m.args(i))) {
+              10
+            } else {
+              3
+            }
           }
 
           (bs, map, c + cost)
diff --git a/src/test/scala/inox/solvers/SolverPoolSuite.scala b/src/test/scala/inox/solvers/SolverPoolSuite.scala
index 12d9a1417edb47c8e2f6f4d416fb1db312323a15..452fffcc98e1dfb7f07d923086266b8a4c68f28d 100644
--- a/src/test/scala/inox/solvers/SolverPoolSuite.scala
+++ b/src/test/scala/inox/solvers/SolverPoolSuite.scala
@@ -1,85 +1,86 @@
 /* Copyright 2009-2016 EPFL, Lausanne */
-//
-//package inox
-//package solvers
-//
-//import org.scalatest._
-//
-//import inox._
-//import inox.solvers._
-//import inox.solvers.combinators._
-//
-//class SolverPoolSuite extends FunSuite {
-//  import inox.trees._
-//
-//  implicit val ctx = InoxContext.empty
-//
-//  private trait DummySolver extends Solver {
-//    val name = "Dummy"
-//    val description = "dummy"
-//
-//    def check: Option[Boolean] = None
-//    def assertCnstr(e: Expr) = {}
-//    def free() {}
-//    def reset() {}
-//    def getModel = ???
-//    def push() {}
-//    def pop() {}
-//    def interrupt() {}
-//    def recoverInterrupt() {}
-//  }
-//
-//  def sfactory(implicit ctx: InoxContext): SolverFactory { val program: InoxProgram } = {
-//    val p = InoxProgram(ctx, new Symbols(Map.empty, Map.empty))
-//    SolverFactory.create(p)("dummy", () => new DummySolver {
-//      val program: p.type = p
-//    })
-//  }
-//
-//  val poolSize = 5;
-//
-//  test(s"SolverPool has at least $poolSize solvers") {
-//
-//    val sp = SolverPoolFactory(sfactory)
-//
-//    var solvers = Set[Solver]()
-//
-//    for (i <- 1 to poolSize) {
-//      solvers += sp.getNewSolver()
-//    }
-//
-//    solvers.size === poolSize
-//  }
-//
-//  test("SolverPool reuses solvers") {
-//
-//    val sp = SolverPoolFactory(sfactory)
-//
-//    var solvers = Set[Solver]()
-//
-//    for (i <- 1 to poolSize) {
-//      val s = sp.getNewSolver()
-//      solvers += s
-//      sp.reclaim(s)
-//    }
-//
-//    for (i <- 1 to poolSize) {
-//      val s = sp.getNewSolver()
-//      assert(solvers contains s, "Solver not reused?")
-//      sp.reclaim(s)
-//    }
-//  }
-//
-//  test(s"SolverPool can grow") {
-//
-//    val sp = SolverPoolFactory(sfactory)
-//
-//    var solvers = Set[Solver]()
-//
-//    for (i <- 1 to poolSize+3) {
-//      solvers += sp.getNewSolver()
-//    }
-//
-//    solvers.size === poolSize+3
-//  }
-//}
+
+package inox
+package solvers
+
+import org.scalatest._
+
+import inox.solvers.combinators._
+
+class SolverPoolSuite extends FunSuite {
+  import inox.trees._
+  import SolverResponses._
+
+  implicit val ctx = Context.empty
+
+  private trait DummySolver extends Solver {
+    val name = "Dummy"
+    val description = "dummy"
+    val program: InoxProgram
+
+    def assertCnstr(e: Expr) = ()
+    def check(config: CheckConfiguration): config.Response[Model, Assumptions] = config.cast(Unknown)
+    def checkAssumptions(config: Configuration)(assumptions: Set[Expr]): config.Response[Model, Assumptions] = config.cast(Unknown)
+    def free() = ()
+    def reset() = ()
+    def push() = ()
+    def pop() = ()
+    def interrupt() = ()
+    def recoverInterrupt() = ()
+  }
+
+  def sfactory(implicit ctx: Context): SolverFactory { val program: InoxProgram } = {
+    val p = InoxProgram(ctx, new Symbols(Map.empty, Map.empty))
+    SolverFactory.create(p)("dummy", () => new DummySolver {
+      val program: p.type = p
+      val options = ctx.options
+    })
+  }
+
+  val poolSize = 5
+
+  test(s"SolverPool has at least $poolSize solvers") {
+
+    val sp = SolverPoolFactory(sfactory)
+
+    var solvers = Set[Solver]()
+
+    for (i <- 1 to poolSize) {
+      solvers += sp.getNewSolver()
+    }
+
+    solvers.size === poolSize
+  }
+
+  test("SolverPool reuses solvers") {
+
+    val sp = SolverPoolFactory(sfactory)
+
+    var solvers = Set[Solver]()
+
+    for (i <- 1 to poolSize) {
+      val s = sp.getNewSolver()
+      solvers += s
+      sp.reclaim(s)
+    }
+
+    for (i <- 1 to poolSize) {
+      val s = sp.getNewSolver()
+      assert(solvers contains s, "Solver not reused?")
+      sp.reclaim(s)
+    }
+  }
+
+  test(s"SolverPool can grow") {
+
+    val sp = SolverPoolFactory(sfactory)
+
+    var solvers = Set[Solver]()
+
+    for (i <- 1 to poolSize+3) {
+      solvers += sp.getNewSolver()
+    }
+
+    solvers.size === poolSize+3
+  }
+}