diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
index d55f225bc96fc83319f1cf0ae41f503a7c5a873d..7901e428fe605751a7162132face803f8ec9c805 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
@@ -78,6 +78,9 @@ trait SMTLIBTarget {
     case RawArrayType(from, to) =>
       r
 
+    case ft @ FunctionType(from, to) =>
+      FiniteLambda(r.default, r.elems.toSeq, ft)
+
     case _ =>
       unsupported("Unable to extract from raw array for "+tpe)
   }
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
index f781cdc480b545e3e8c3e285a95735a68b315cad..91e205c6af357074fc39beb1dc34f104e0b6e8c7 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
@@ -188,9 +188,12 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
     for (me <- smodel) me match {
       case DefineFun(s, args, kind, e) =>
         if(args.isEmpty) {
-          val id = variables.toA(s)
-          // EK: this is a little hack, we pass models for array functions as let-defs
-          model += id -> fromSMT(e, id.getType)(Map(), modelFunDefs)
+          variables.getA(s) match {
+            case Some(id) =>
+              // EK: this is a little hack, we pass models for array functions as let-defs
+              model += id -> fromSMT(e, id.getType)(Map(), modelFunDefs)
+            case _ => // function, should be handled elsewhere
+          }
         }
       case _ =>
     }
diff --git a/src/main/scala/leon/solvers/templates/LambdaManager.scala b/src/main/scala/leon/solvers/templates/LambdaManager.scala
index 7249313f16c1f171d1ef15888616ebff1108c468..d8aa9026f49cbd7b9e58db2ee42d6c80e82698fe 100644
--- a/src/main/scala/leon/solvers/templates/LambdaManager.scala
+++ b/src/main/scala/leon/solvers/templates/LambdaManager.scala
@@ -112,7 +112,7 @@ class LambdaManager[T](encoder: TemplateEncoder[T]) {
       template.contextEquality(that) match {
         case None => encoder.mkNot(equals)
         case Some(Seq()) => equals
-        case Some(seq) => encoder.mkImplies(encoder.mkAnd(seq : _*), equals)
+        case Some(seq) => encoder.mkEquals(encoder.mkAnd(seq : _*), equals)
       }
     }.toSeq
   }
diff --git a/src/main/scala/leon/solvers/templates/Templates.scala b/src/main/scala/leon/solvers/templates/Templates.scala
index c7e79263f807141565644ac864cafa59ad70a8b7..6c26fa8d88f856c24b710a38b936492e828fe7ad 100644
--- a/src/main/scala/leon/solvers/templates/Templates.scala
+++ b/src/main/scala/leon/solvers/templates/Templates.scala
@@ -230,7 +230,6 @@ object LambdaTemplate {
   private def structuralKey[T](lambda: Lambda, dependencies: Map[Identifier, T]): (Lambda, Map[Identifier,T]) = {
 
     def closureIds(expr: Expr): Seq[Identifier] = {
-      val vars = variablesOf(expr)
       val allVars : Seq[Identifier] = foldRight[Seq[Identifier]] {
         (expr, idSeqs) => idSeqs.foldLeft(expr match {
           case Variable(id) => Seq(id)
@@ -238,10 +237,11 @@ object LambdaTemplate {
         })((acc, seq) => acc ++ seq)
       } (expr)
 
+      val vars = variablesOf(expr)
       allVars.filter(vars(_)).distinct
     }
 
-    val grouped : Map[TypeTree, Seq[Identifier]] = closureIds(lambda).groupBy(_.getType)
+    val grouped : Map[TypeTree, Seq[Identifier]] = (lambda.args.map(_.id) ++ closureIds(lambda)).groupBy(_.getType)
     val subst : Map[Identifier, Identifier] = grouped.foldLeft(Map.empty[Identifier,Identifier]) { case (subst, (tpe, ids)) =>
       val currentVars = typedIds(tpe)
 
@@ -257,7 +257,10 @@ object LambdaTemplate {
       subst ++ (ids zip typedVars)
     }
 
-    val structuralLambda = replaceFromIDs(subst.mapValues(_.toVariable), lambda).asInstanceOf[Lambda]
+    val newArgs = lambda.args.map(vd => ValDef(subst(vd.id), vd.tpe))
+    val newBody = replaceFromIDs(subst.mapValues(_.toVariable), lambda.body)
+    val structuralLambda = Lambda(newArgs, newBody)
+
     val newDeps = dependencies.map { case (id, idT) => subst(id) -> idT }
 
     structuralLambda -> newDeps
diff --git a/src/test/resources/regression/verification/purescala/valid/FlatMap.scala b/src/test/resources/regression/verification/purescala/valid/FlatMap.scala
new file mode 100644
index 0000000000000000000000000000000000000000..56f8c47e86d835055e6c3a9ea44cb7b886e464fb
--- /dev/null
+++ b/src/test/resources/regression/verification/purescala/valid/FlatMap.scala
@@ -0,0 +1,48 @@
+import leon.lang._
+import leon.collection._
+
+object FlatMap {
+
+  def append[T](l1: List[T], l2: List[T]): List[T] = l1 match {
+    case Cons(head, tail) => Cons(head, append(tail, l2))
+    case Nil() => l2
+  }
+
+  def associative_append_lemma[T](l1: List[T], l2: List[T], l3: List[T]): Boolean = {
+    append(append(l1, l2), l3) == append(l1, append(l2, l3))
+  }
+
+  def associative_append_lemma_induct[T](l1: List[T], l2: List[T], l3: List[T]): Boolean = {
+    l1 match {
+      case Nil() => associative_append_lemma(l1, l2, l3)
+      case Cons(head, tail) => associative_append_lemma(l1, l2, l3) && associative_append_lemma_induct(tail, l2, l3)
+    }
+  }.holds
+
+  def flatMap[T,U](list: List[T], f: T => List[U]): List[U] = list match {
+    case Cons(head, tail) => append(f(head), flatMap(tail, f))
+    case Nil() => Nil()
+  }
+
+  def associative_lemma[T,U,V](list: List[T], f: T => List[U], g: U => List[V]): Boolean = {
+    flatMap(flatMap(list, f), g) == flatMap(list, (x: T) => flatMap(f(x), g))
+  }
+
+  def associative_lemma_induct[T,U,V](list: List[T], flist: List[U], glist: List[V], f: T => List[U], g: U => List[V]): Boolean = {
+    associative_lemma(list, f, g) &&
+    append(glist, flatMap(append(flist, flatMap(list, f)), g)) == append(append(glist, flatMap(flist, g)), flatMap(list, (x: T) => flatMap(f(x), g))) &&
+    (glist match {
+      case Cons(ghead, gtail) =>
+        associative_lemma_induct(list, flist, gtail, f, g)
+      case Nil() => flist match {
+        case Cons(fhead, ftail) =>
+          associative_lemma_induct(list, ftail, g(fhead), f, g)
+        case Nil() => list match {
+          case Cons(head, tail) => associative_lemma_induct(tail, f(head), Nil(), f, g)
+          case Nil() => true
+        }
+      }
+    })
+  }.holds
+
+}
diff --git a/src/test/resources/regression/verification/purescala/valid/FlatMap.scala.BAK b/src/test/resources/regression/verification/purescala/valid/FlatMap.scala.BAK
deleted file mode 100644
index fc177bd1f9e750fe2f79cf9fe910d3279ceaf299..0000000000000000000000000000000000000000
--- a/src/test/resources/regression/verification/purescala/valid/FlatMap.scala.BAK
+++ /dev/null
@@ -1,69 +0,0 @@
-import leon.lang._
-import leon.collection._
-
-object Lists5 {
-
-  def append[T](l1: List[T], l2: List[T]): List[T] = l1 match {
-    case Cons(head, tail) => Cons(head, append(tail, l2))
-    case Nil() => l2
-  }
-
-  def associative_append_lemma[T](l1: List[T], l2: List[T], l3: List[T]): Boolean = {
-    append(append(l1, l2), l3) == append(l1, append(l2, l3))
-  }
-
-  def associative_append_lemma_induct[T](l1: List[T], l2: List[T], l3: List[T]): Boolean = {
-    l1 match {
-      case Nil() => associative_append_lemma(l1, l2, l3)
-      case Cons(head, tail) => associative_append_lemma(l1, l2, l3) && associative_append_lemma_induct(tail, l2, l3)
-    }
-  }.holds
-
-  def flatMap[T,U](list: List[T], f: T => List[U]): List[U] = list match {
-    case Cons(head, tail) => append(f(head), flatMap(tail, f))
-    case Nil() => Nil()
-  }
-
-  def associative_lemma[T,U,V](list: List[T], f: T => List[U], g: U => List[V]): Boolean = {
-    flatMap(flatMap(list, f), g) == flatMap(list, (x: T) => flatMap(f(x), g))
-  }
-
-  def associative_lemma_helper[T,U,V](fprev: List[U], fcur: List[U], fgprev: List[V], fgcur: List[V], tail: List[T], f: T => List[U], g: U => List[V]): Boolean = {
-    val left = fcur match {
-      case Cons(fhead, ftail) =>
-        flatMap(append(fprev, Cons(fhead, append(ftail, flatMap(tail, f)))), g)
-      case Nil() =>
-        flatMap(append(fprev, flatMap(tail, f)), g)
-    }
-
-    val right = fgcur match {
-      case Cons(fghead, fgtail) =>
-        append(fgprev, Cons(fghead, append(fgtail, flatMap(tail, (x: T) => flatMap(f(x), g)))))
-      case Nil() =>
-        append(fgprev, flatMap(tail, (x: T) => flatMap(f(x), g)))
-    }
-        
-    left == right && (fgcur match {
-      case Cons(fghead, fgtail) => associative_lemma_helper(fprev, fcur, append(fgprev, Cons(fghead, Nil())), fgtail, tail, f, g)
-      case Nil() => fcur match {
-        case Cons(fhead, ftail) => associative_lemma_helper(append(fprev, Cons(fhead, Nil())), ftail, fgprev, fgcur, tail, f, g)
-        case Nil() => tail match {
-          case Nil() => true
-          case Cons(head, tail) => f(head) match {
-            case fl @ Cons(fh, ft) => associative_lemma_helper(Nil(), fl, Nil(), flatMap(fl, g), tail, f, g)
-            case Nil() => associative_lemma_helper(Nil(), Nil(), Nil(), Nil(), tail, f, g)
-          }
-        }
-      }
-    })
-  }
-
-  def associative_lemma_induct[T,U,V](list: List[T], f: T => List[U], g: U => List[V]): Boolean = {
-    list match {
-      case Nil() => associative_lemma(list, f, g)
-      case Cons(head, tail) =>
-        associative_lemma(list, f, g) && associative_lemma_induct(tail, f, g) && associative_lemma_helper(Nil(), Nil(), Nil(), Nil(), list, f, g)
-    }
-  }.holds
-
-}