diff --git a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
index cdbfc205c30cdf6fbc73cb7f4c15e291cbf53b93..7890d7a229da487e8ae8152ae92c7b0b066eb12e 100644
--- a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
+++ b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala
@@ -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) )
@@ -695,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/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
index 497cbb4f9ac70417744b0e6cf177797b1c322931..85e587444a41b59e38a057ac6fc8e1c6e616b8e5 100644
--- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
+++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
@@ -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)
@@ -1563,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)
@@ -1600,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
@@ -1793,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/purescala/DefOps.scala b/src/main/scala/leon/purescala/DefOps.scala
index 649c84472f2399f6530b5762326a1f3d763bc5c4..1b9d146d15765fe88b3ebf8d034ba9ac66a361a6 100644
--- a/src/main/scala/leon/purescala/DefOps.scala
+++ b/src/main/scala/leon/purescala/DefOps.scala
@@ -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 484745ae09d0f09340acaac5c83c5badd1c79762..98497afd31586ef8cff40eec4a68ef36da63162b 100644
--- a/src/main/scala/leon/purescala/Definitions.scala
+++ b/src/main/scala/leon/purescala/Definitions.scala
@@ -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]] */
diff --git a/src/main/scala/leon/purescala/MethodLifting.scala b/src/main/scala/leon/purescala/MethodLifting.scala
index 6743da68b8509e43192a825cf0a25cc6c1cdb3d2..957505f297b551ff0bab84955015de35b0a0d7e2 100644
--- a/src/main/scala/leon/purescala/MethodLifting.scala
+++ b/src/main/scala/leon/purescala/MethodLifting.scala
@@ -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 d1975779e5690b27823a9ddfd0abc7af79e0aabe..3773ebce48b3c51e056cee01f1ed059288d25bc5 100644
--- a/src/main/scala/leon/purescala/PrettyPrinter.scala
+++ b/src/main/scala/leon/purescala/PrettyPrinter.scala
@@ -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}" }
 
@@ -528,7 +530,7 @@ class PrettyPrinter(opts: PrinterOptions,
 
         if (ccd.methods.nonEmpty) {
           p"""| {
-              |  ${nary(ccd.methods, "\n\n")}
+              |  ${nary(ccd.methods, "\n\n") }
               |}"""
         }
 
diff --git a/src/main/scala/leon/purescala/Types.scala b/src/main/scala/leon/purescala/Types.scala
index 0ee936c813b942d3e55564506a200b31630f0283..b461a51c64d28a4f589f7182f4342ee58d08ddbd 100644
--- a/src/main/scala/leon/purescala/Types.scala
+++ b/src/main/scala/leon/purescala/Types.scala
@@ -98,7 +98,7 @@ object Types {
 
     assert(classDef.tparams.size == tps.size)
 
-    lazy val fields = {
+    def fields = {
       val tmap = (classDef.tparams zip tps).toMap
       if (tmap.isEmpty) {
         classDef.fields
diff --git a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
index d2717f5ef6af6eba77245ff6c7910ba8955fb1bb..34b7b35f428bff701af9a25c06258da5a43443ed 100644
--- a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
+++ b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala
@@ -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/xlang/AntiAliasingPhase.scala b/src/main/scala/leon/xlang/AntiAliasingPhase.scala
index 4d1e903fd8fc87673351e9b5a6d74929d935827b..d237c89d5089c13b4a8c6aa50e04dc7c3754e0fd 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
 
@@ -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)
       }
 
@@ -199,18 +214,26 @@ object AntiAliasingPhase extends TransformationPhase {
             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/Expressions.scala b/src/main/scala/leon/xlang/Expressions.scala
index 802fa217faa4e3803310f3c0950766b7dbdf4063..20e14ed1f0bd0badefa1ffd7c44168c4909b9b27 100644
--- a/src/main/scala/leon/xlang/Expressions.scala
+++ b/src/main/scala/leon/xlang/Expressions.scala
@@ -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
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/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/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/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/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/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))
+
+}