diff --git a/src/main/scala/leon/ArrayTransformation.scala b/src/main/scala/leon/ArrayTransformation.scala
index 735462cd4acecaad24139b444b7f9e7f98fbbda0..7d0d94458291b71381d8719a25e13751ca3cdd9f 100644
--- a/src/main/scala/leon/ArrayTransformation.scala
+++ b/src/main/scala/leon/ArrayTransformation.scala
@@ -21,7 +21,6 @@ object ArrayTransformation extends Pass {
     pgm
   }
 
-
   private var id2FreshId = Map[Identifier, Identifier]()
 
   def transform(expr: Expr): Expr = expr match {
@@ -61,6 +60,10 @@ object ArrayTransformation extends Pass {
       ).setType(ra.getType)
       res
     }
+    case ArrayClone(a) => {
+      val ra = transform(a)
+      ra
+    }
     case Let(i, v, b) => {
       v.getType match {
         case ArrayType(_) => {
diff --git a/src/main/scala/leon/plugin/CodeExtraction.scala b/src/main/scala/leon/plugin/CodeExtraction.scala
index 2b3187e1ae116fe01c79f2d408d1682287549dca..a05dd1f289ed4829ef0f29a49f31635f23bf5c1a 100644
--- a/src/main/scala/leon/plugin/CodeExtraction.scala
+++ b/src/main/scala/leon/plugin/CodeExtraction.scala
@@ -249,6 +249,7 @@ trait CodeExtraction extends Extractors {
       val newParams = params.map(p => {
         val ptpe = st2ps(p.tpt.tpe)
         val newID = FreshIdentifier(p.name.toString).setType(ptpe)
+        owners += (Variable(newID) -> None)
         varSubsts(p.symbol) = (() => Variable(newID))
         VarDecl(newID, ptpe)
       })
@@ -259,6 +260,8 @@ trait CodeExtraction extends Extractors {
       var realBody = body
       var reqCont: Option[Expr] = None
       var ensCont: Option[Expr] = None
+      
+      currentFunDef = funDef
 
       realBody match {
         case ExEnsuredExpression(body2, resSym, contract) => {
@@ -289,15 +292,23 @@ trait CodeExtraction extends Extractors {
         case e: ImpureCodeEncounteredException => None
       }
 
+      bodyAttempt.foreach(e => 
+        if(e.getType.isInstanceOf[ArrayType]) {
+          //println(owners)
+          //println(getOwner(e))
+          getOwner(e) match {
+            case Some(Some(fd)) if fd == funDef =>
+            case None =>
+            case _ => unit.error(realBody.pos, "Function cannot return an array that is not locally defined")
+          }
+        })
       reqCont.map(e => 
         if(containsLetDef(e)) {
           unit.error(realBody.pos, "Function precondtion should not contain nested function definition")
-          throw ImpureCodeEncounteredException(realBody)
         })
       ensCont.map(e => 
         if(containsLetDef(e)) {
           unit.error(realBody.pos, "Function postcondition should not contain nested function definition")
-          throw ImpureCodeEncounteredException(realBody)
         })
       funDef.body = bodyAttempt
       funDef.precondition = reqCont
@@ -341,7 +352,10 @@ trait CodeExtraction extends Extractors {
 
 
   private var currentFunDef: FunDef = null
-  private var owners: Map[Expr, Option[FunDef]] = Map()
+
+  //This is a bit missleading, if an expr is not mapped then it has no owner, if it is mapped to None it means
+  //that it can have any owner
+  private var owners: Map[Expr, Option[FunDef]] = Map() 
 
   /** Forces conversion from scalac AST to purescala AST, throws an Exception
    * if impossible. If not in 'silent mode', non-pure AST nodes are reported as
@@ -408,6 +422,7 @@ trait CodeExtraction extends Extractors {
       val newParams = params.map(p => {
         val ptpe =  scalaType2PureScala(unit, silent) (p.tpt.tpe)
         val newID = FreshIdentifier(p.name.toString).setType(ptpe)
+        owners += (Variable(newID) -> None)
         varSubsts(p.symbol) = (() => Variable(newID))
         VarDecl(newID, ptpe)
       })
@@ -451,20 +466,21 @@ trait CodeExtraction extends Extractors {
       }
 
       bodyAttempt.foreach(e => 
-        if(e.getType.isInstanceOf[ArrayType] && owners.get(e).getOrElse(null) != funDef) {
-          unit.error(realBody.pos, "Function cannot return an array that is not locally defined")
-          throw ImpureCodeEncounteredException(realBody)
+        if(e.getType.isInstanceOf[ArrayType]) {
+          getOwner(e) match {
+            case Some(Some(fd)) if fd == funDef =>
+            case None =>
+            case _ => unit.error(realBody.pos, "Function cannot return an array that is not locally defined")
+          }
         })
 
       reqCont.foreach(e => 
         if(containsLetDef(e)) {
           unit.error(realBody.pos, "Function precondtion should not contain nested function definition")
-          throw ImpureCodeEncounteredException(realBody)
         })
       ensCont.foreach(e => 
         if(containsLetDef(e)) {
           unit.error(realBody.pos, "Function postcondition should not contain nested function definition")
-          throw ImpureCodeEncounteredException(realBody)
         })
       funDef.body = bodyAttempt
       funDef.precondition = reqCont
@@ -500,6 +516,16 @@ trait CodeExtraction extends Extractors {
           val binderTpe = scalaType2PureScala(unit, silent)(tpt.tpe)
           val newID = FreshIdentifier(vs.name.toString).setType(binderTpe)
           val valTree = rec(bdy)
+          handleRest = false
+          if(valTree.getType.isInstanceOf[ArrayType]) {
+            getOwner(valTree) match {
+              case None =>
+                owners += (Variable(newID) -> Some(currentFunDef))
+              case Some(_) =>
+                unit.error(nextExpr.pos, "Cannot alias array")
+                throw ImpureCodeEncounteredException(nextExpr)
+            }
+          }
           val restTree = rest match {
             case Some(rst) => {
               varSubsts(vs) = (() => Variable(newID))
@@ -509,7 +535,6 @@ trait CodeExtraction extends Extractors {
             }
             case None => UnitLiteral
           }
-          handleRest = false
           val res = Let(newID, valTree, restTree)
           res
         }
@@ -517,9 +542,11 @@ trait CodeExtraction extends Extractors {
           val funDef = extractFunSig(n, p, t).setPosInfo(dd.pos.line, dd.pos.column)
           defsToDefs += (dd.symbol -> funDef)
           val oldMutableVarSubst = mutableVarSubsts.toMap //take an immutable snapshot of the map
+          val oldCurrentFunDef = currentFunDef
           mutableVarSubsts.clear //reseting the visible mutable vars, we do not handle mutable variable closure in nested functions
           val funDefWithBody = extractFunDef(funDef, b)
           mutableVarSubsts ++= oldMutableVarSubst
+          currentFunDef = oldCurrentFunDef
           val restTree = rest match {
             case Some(rst) => rec(rst)
             case None => UnitLiteral
@@ -530,15 +557,25 @@ trait CodeExtraction extends Extractors {
         }
         case ExVarDef(vs, tpt, bdy) => {
           val binderTpe = scalaType2PureScala(unit, silent)(tpt.tpe)
-          binderTpe match {
-            case ArrayType(_) => 
-              unit.error(tree.pos, "Cannot declare array variables, only val are alllowed")
-              throw ImpureCodeEncounteredException(tree)
-            case _ =>
-          }
+          //binderTpe match {
+          //  case ArrayType(_) => 
+          //    unit.error(tree.pos, "Cannot declare array variables, only val are alllowed")
+          //    throw ImpureCodeEncounteredException(tree)
+          //  case _ =>
+          //}
           val newID = FreshIdentifier(vs.name.toString).setType(binderTpe)
           val valTree = rec(bdy)
           mutableVarSubsts += (vs -> (() => Variable(newID)))
+          handleRest = false
+          if(valTree.getType.isInstanceOf[ArrayType]) {
+            getOwner(valTree) match {
+              case None =>
+                owners += (Variable(newID) -> Some(currentFunDef))
+              case Some(_) =>
+                unit.error(nextExpr.pos, "Cannot alias array")
+                throw ImpureCodeEncounteredException(nextExpr)
+            }
+          }
           val restTree = rest match {
             case Some(rst) => {
               varSubsts(vs) = (() => Variable(newID))
@@ -548,7 +585,6 @@ trait CodeExtraction extends Extractors {
             }
             case None => UnitLiteral
           }
-          handleRest = false
           val res = LetVar(newID, valTree, restTree)
           res
         }
@@ -557,6 +593,14 @@ trait CodeExtraction extends Extractors {
           case Some(fun) => {
             val Variable(id) = fun()
             val rhsTree = rec(rhs)
+            if(rhsTree.getType.isInstanceOf[ArrayType]) {
+              getOwner(rhsTree) match {
+                case None =>
+                case Some(_) =>
+                  unit.error(nextExpr.pos, "Cannot alias array")
+                  throw ImpureCodeEncounteredException(nextExpr)
+              }
+            }
             Assignment(id, rhsTree)
           }
           case None => {
@@ -830,6 +874,16 @@ trait CodeExtraction extends Extractors {
               throw ImpureCodeEncounteredException(tree)
             }
           }
+          getOwner(lhsRec) match {
+            case Some(Some(fd)) if fd != currentFunDef => 
+              unit.error(nextExpr.pos, "cannot update an array that is not defined locally")
+              throw ImpureCodeEncounteredException(nextExpr)
+            case Some(None) =>
+              unit.error(nextExpr.pos, "cannot update an array that is not defined locally")
+              throw ImpureCodeEncounteredException(nextExpr)
+            case Some(_) =>
+            case None => sys.error("This array: " + lhsRec + " should have had an owner")
+          }
           val indexRec = rec(index)
           val newValueRec = rec(newValue)
           ArrayUpdate(lhsRec, indexRec, newValueRec).setPosInfo(update.pos.line, update.pos.column)
@@ -838,6 +892,10 @@ trait CodeExtraction extends Extractors {
           val rt = rec(t)
           ArrayLength(rt)
         }
+        case ExArrayClone(t) => {
+          val rt = rec(t)
+          ArrayClone(rt)
+        }
         case ExArrayFill(baseType, length, defaultValue) => {
           val underlying = scalaType2PureScala(unit, silent)(baseType.tpe)
           val lengthRec = rec(length)
@@ -941,17 +999,20 @@ trait CodeExtraction extends Extractors {
         }
       }
 
-      if(handleRest) {
+      val res = if(handleRest) {
         rest match {
           case Some(rst) => {
             val recRst = rec(rst)
-            PBlock(Seq(psExpr), recRst).setType(recRst.getType)
+            val block = PBlock(Seq(psExpr), recRst).setType(recRst.getType)
+            block
           }
           case None => psExpr
         }
       } else {
         psExpr
       }
+
+      res
     }
     rec(tree)
   }
@@ -994,4 +1055,27 @@ trait CodeExtraction extends Extractors {
   def mkPosString(pos: scala.tools.nsc.util.Position) : String = {
     pos.line + "," + pos.column
   }
+
+  def getReturnedExpr(expr: Expr): Seq[Expr] = expr match {
+    case Let(_, _, rest) => getReturnedExpr(rest)
+    case LetVar(_, _, rest) => getReturnedExpr(rest)
+    case PBlock(_, rest) => getReturnedExpr(rest)
+    case IfExpr(_, then, elze) => getReturnedExpr(then) ++ getReturnedExpr(elze)
+    case _ => Seq(expr)
+  }
+
+  def getOwner(exprs: Seq[Expr]): Option[Option[FunDef]] = {
+    val exprOwners: Seq[Option[Option[FunDef]]] = exprs.map(owners.get(_))
+    if(exprOwners.exists(_ == None))
+      None
+    else if(exprOwners.exists(_ == Some(None)))
+      Some(None)
+    else if(exprOwners.exists(o1 => exprOwners.exists(o2 => o1 != o2)))
+      Some(None)
+    else
+      exprOwners(0)
+  }
+
+  def getOwner(expr: Expr): Option[Option[FunDef]] = getOwner(getReturnedExpr(expr))
+
 }
diff --git a/src/main/scala/leon/plugin/Extractors.scala b/src/main/scala/leon/plugin/Extractors.scala
index 13b6392edbaf0e61d0182c27e327610d76d64edc..b45fef576bbc8d06a87f9289f4be5822ec884fa5 100644
--- a/src/main/scala/leon/plugin/Extractors.scala
+++ b/src/main/scala/leon/plugin/Extractors.scala
@@ -672,6 +672,13 @@ trait Extractors {
       }
     }
 
+    object ExArrayClone {
+      def unapply(tree: Apply): Option[Tree] = {println(tree); tree match {
+        case Apply(Select(t, n), List()) if (n.toString == "clone") => Some(t)
+        case _ => None
+      }}
+    }
+
 
     object ExArrayFill {
       def unapply(tree: Apply): Option[(Tree, Tree, Tree)] = tree match {
diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala
index f03c624af8acddea63ad6c68f993446ffb3cda92..21a9393b142b177d49ba985988512c5dbe885c5f 100644
--- a/src/main/scala/leon/purescala/PrettyPrinter.scala
+++ b/src/main/scala/leon/purescala/PrettyPrinter.scala
@@ -253,6 +253,10 @@ object PrettyPrinter {
       pp(a, sb, lvl)
       sb.append(".length")
     }
+    case ArrayClone(a) => {
+      pp(a, sb, lvl)
+      sb.append(".clone")
+    }
     case fill@ArrayFill(size, v) => {
       sb.append("Array.fill(")
       pp(size, sb, lvl)
diff --git a/src/main/scala/leon/purescala/Trees.scala b/src/main/scala/leon/purescala/Trees.scala
index 1c015cfe6e1127a178746786d2fe7678c6b30c4d..aff4f7c5560ebf7a6b70989e11d3291b9a41dc5e 100644
--- a/src/main/scala/leon/purescala/Trees.scala
+++ b/src/main/scala/leon/purescala/Trees.scala
@@ -399,6 +399,10 @@ object Trees {
     val fixedType = Int32Type
   }
   case class FiniteArray(exprs: Seq[Expr]) extends Expr
+  case class ArrayClone(array: Expr) extends Expr {
+    if(array.getType != Untyped)
+      setType(array.getType)
+  }
 
   /* List operations */
   case class NilList(baseType: TypeTree) extends Expr with Terminal
@@ -433,6 +437,7 @@ object Trees {
       case Assignment(id, e) => Some((e, Assignment(id, _)))
       case TupleSelect(t, i) => Some((t, TupleSelect(_, i)))
       case ArrayLength(a) => Some((a, ArrayLength))
+      case ArrayClone(a) => Some((a, ArrayClone))
       case ArrayMake(t) => Some((t, ArrayMake))
       case e@Epsilon(t) => Some((t, (expr: Expr) => Epsilon(expr).setType(e.getType).setPosInfo(e)))
       case _ => None
@@ -837,6 +842,7 @@ object Trees {
       case LetDef(_, _) => false
       case ArrayUpdate(_, _, _) => false
       case ArrayMake(_) => false
+      case ArrayClone(_) => false
       case Epsilon(_) => false
       case _ => true
     }
@@ -849,6 +855,7 @@ object Trees {
       case LetDef(_, _) => false
       case ArrayUpdate(_, _, _) => false
       case ArrayMake(_) => false
+      case ArrayClone(_) => false
       case Epsilon(_) => false
       case _ => b
     }
diff --git a/testcases/BubbleSort.scala b/testcases/BubbleSort.scala
index 8e85143ac10414572114f6a24c09e194853af8de..3551ebf16416f68bd932adc512177edc6f2611d8 100644
--- a/testcases/BubbleSort.scala
+++ b/testcases/BubbleSort.scala
@@ -8,7 +8,7 @@ object BubbleSort {
     require(a.length >= 1)
     var i = a.length - 1
     var j = 0
-    val sa = a
+    val sa = a.clone
     (while(i > 0) {
       j = 0
       (while(j < i) {
diff --git a/testcases/regression/error/Array10.scala b/testcases/regression/error/Array10.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9973626b83a01c7a8a944bcf808274d7989b3a66
--- /dev/null
+++ b/testcases/regression/error/Array10.scala
@@ -0,0 +1,12 @@
+object Array10 {
+
+  def foo(): Int = {
+    val a = Array.fill(5)(0)
+    def rec(): Array[Int] = {
+      a
+    }
+    val b = rec()
+    b(0)
+  }
+
+}
diff --git a/testcases/regression/error/Array2.scala b/testcases/regression/error/Array2.scala
index 8ae7054ca20927b87d6032810f5e4fed87e4ba86..9154460c37237761b6c8f2d0ecb0b34fb3ec0bf6 100644
--- a/testcases/regression/error/Array2.scala
+++ b/testcases/regression/error/Array2.scala
@@ -1,8 +1,9 @@
 object Array2 {
 
   def foo(): Int = {
-    var a = Array.fill(5)(5)
-    0
+    val a = Array.fill(5)(5)
+    val b = a
+    b(3)
   }
 
 }
diff --git a/testcases/regression/error/Array3.scala b/testcases/regression/error/Array3.scala
index 451dd9db06873a8dc9c88a4d5c8285c5ab063a73..a2c2fbd6ddfde2b3cca2dcc08fb61a79f0ae471c 100644
--- a/testcases/regression/error/Array3.scala
+++ b/testcases/regression/error/Array3.scala
@@ -4,7 +4,8 @@ object Array3 {
     val a = Array.fill(5)(5)
     if(a.length > 2)
       a(1) = 2
-    else 0
+    else 
+      0
     0
   }
 
diff --git a/testcases/regression/error/Array4.scala b/testcases/regression/error/Array4.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5ab0115af5e8737c6baab851822643490e79334f
--- /dev/null
+++ b/testcases/regression/error/Array4.scala
@@ -0,0 +1,8 @@
+object Array4 {
+
+  def foo(a: Array[Int]): Int = {
+    val b = a
+    b(3)
+  }
+
+}
diff --git a/testcases/regression/error/Array5.scala b/testcases/regression/error/Array5.scala
new file mode 100644
index 0000000000000000000000000000000000000000..005d3d389dd1e748d139283a6fbdcb93aa8d525c
--- /dev/null
+++ b/testcases/regression/error/Array5.scala
@@ -0,0 +1,10 @@
+object Array5 {
+
+  def foo(a: Array[Int]): Int = {
+    a(2) = 4
+    a(2)
+  }
+
+}
+
+// vim: set ts=4 sw=4 et:
diff --git a/testcases/regression/error/Array6.scala b/testcases/regression/error/Array6.scala
new file mode 100644
index 0000000000000000000000000000000000000000..15c87a08554c7e9563cbad9b47a881376e45a4c5
--- /dev/null
+++ b/testcases/regression/error/Array6.scala
@@ -0,0 +1,10 @@
+
+object Array6 {
+
+  def foo(): Int = {
+    val a = Array.fill(5)(5)
+    var b = a
+    b(0)
+  }
+
+}
diff --git a/testcases/regression/error/Array7.scala b/testcases/regression/error/Array7.scala
new file mode 100644
index 0000000000000000000000000000000000000000..abb83e1c0bd931bf1d41a132fef6fb74ea25318b
--- /dev/null
+++ b/testcases/regression/error/Array7.scala
@@ -0,0 +1,9 @@
+object Array7 {
+
+  def foo(): Int = {
+    val a = Array.fill(5)(5)
+    var b = a
+    b(0)
+  }
+
+}
diff --git a/testcases/regression/error/Array8.scala b/testcases/regression/error/Array8.scala
new file mode 100644
index 0000000000000000000000000000000000000000..89af32efdb89273ecf6b275b5a8f2f787bb73a1f
--- /dev/null
+++ b/testcases/regression/error/Array8.scala
@@ -0,0 +1,7 @@
+object Array8 {
+
+  def foo(a: Array[Int]): Array[Int] = {
+    a
+  }
+
+}
diff --git a/testcases/regression/error/Array9.scala b/testcases/regression/error/Array9.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5dc9d3aea24f7c38b8a374659058c9d0ca7fb336
--- /dev/null
+++ b/testcases/regression/error/Array9.scala
@@ -0,0 +1,11 @@
+object Array9 {
+
+  def foo(a: Array[Int]): Int = {
+    def rec(): Array[Int] = {
+      a
+    }
+    val b = rec()
+    b(0)
+  }
+
+}
diff --git a/testcases/regression/valid/Array10.scala b/testcases/regression/valid/Array10.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ebb60ad6e0ba7556c55c74e1b1b624e6c34b4311
--- /dev/null
+++ b/testcases/regression/valid/Array10.scala
@@ -0,0 +1,9 @@
+object Array10 {
+
+  def foo(a: Array[Int]): Int = {
+    require(a.length > 0)
+    val b = a.clone
+    b(0)
+  } ensuring(res => res == a(0))
+
+}
diff --git a/testcases/regression/valid/Array9.scala b/testcases/regression/valid/Array9.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f49333236abfaf63caa278405a89670b1c9c115d
--- /dev/null
+++ b/testcases/regression/valid/Array9.scala
@@ -0,0 +1,15 @@
+object Array9 {
+
+  def foo(i: Int): Array[Int] = {
+    require(i > 0)
+    val a = Array.fill(i)(0)
+    a
+  } ensuring(res => res.length == i)
+
+  def bar(i: Int): Int = {
+    require(i > 0)
+    val b = foo(i)
+    b(0)
+  }
+
+}