diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
index 9ec20b64184f8298431b2fe540e8158d70c39ae3..0ffca50ba25cd39956aeeefe16c114e1498dfdbb 100644
--- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
+++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala
@@ -672,7 +672,7 @@ trait CodeExtraction extends ASTExtractors {
           outOfSubsetError(tree, "Don't know what to do with this. Not purescala?");
       }
 
-      new LeonModuleDef(FreshIdentifier(nameStr), newDefs)
+      LeonModuleDef(FreshIdentifier(nameStr), newDefs, nameStr contains "$standalone")
     }
 
 
@@ -728,7 +728,7 @@ trait CodeExtraction extends ASTExtractors {
         NoTree(funDef.returnType)
       }
 
-      funDef.fullBody = finalBody;
+      funDef.fullBody = finalBody 
 
       // Post-extraction sanity checks
 
@@ -751,12 +751,12 @@ trait CodeExtraction extends ASTExtractors {
 
     private def extractPattern(p: Tree, binder: Option[Identifier] = None)(implicit dctx: DefContext): (Pattern, DefContext) = p match {
       case b @ Bind(name, t @ Typed(pat, tpt)) =>
-        val newID = FreshIdentifier(name.toString).setType(extractType(tpt)).setPos(b.pos)
+        val newID = FreshIdentifier(name.toString).setType(extractType(tpt)).setPos(b.pos).setOwner(currentFunDef)
         val pctx = dctx.withNewVar(b.symbol -> (() => Variable(newID)))
         extractPattern(t, Some(newID))(pctx)
 
       case b @ Bind(name, pat) =>
-        val newID = FreshIdentifier(name.toString).setType(extractType(b)).setPos(b.pos)
+        val newID = FreshIdentifier(name.toString).setType(extractType(b)).setPos(b.pos).setOwner(currentFunDef)
         val pctx = dctx.withNewVar(b.symbol -> (() => Variable(newID)))
         extractPattern(pat, Some(newID))(pctx)
 
@@ -839,7 +839,7 @@ trait CodeExtraction extends ASTExtractors {
 
       val res = current match {
         case ExEnsuredExpression(body, resVd, contract) =>
-          val resId = FreshIdentifier(resVd.symbol.name.toString).setType(extractType(current)).setPos(resVd.pos)
+          val resId = FreshIdentifier(resVd.symbol.name.toString).setType(extractType(current)).setPos(resVd.pos).setOwner(currentFunDef)
           val post = extractTree(contract)(dctx.withNewVar(resVd.symbol -> (() => Variable(resId))))
 
           val b = try {
@@ -852,7 +852,7 @@ trait CodeExtraction extends ASTExtractors {
           Ensuring(b, resId, post)
 
         case t @ ExHoldsExpression(body) =>
-          val resId = FreshIdentifier("holds").setType(BooleanType).setPos(current.pos)
+          val resId = FreshIdentifier("holds").setType(BooleanType).setPos(current.pos).setOwner(currentFunDef)
           val post = Variable(resId).setPos(current.pos)
 
           val b = try {
@@ -918,7 +918,7 @@ trait CodeExtraction extends ASTExtractors {
 
         case ExValDef(vs, tpt, bdy) =>
           val binderTpe = extractType(tpt)
-          val newID = FreshIdentifier(vs.name.toString).setType(binderTpe)
+          val newID = FreshIdentifier(vs.name.toString).setType(binderTpe).setOwner(currentFunDef)
           val valTree = extractTree(bdy)
 
           if(valTree.getType.isInstanceOf[ArrayType]) {
@@ -953,7 +953,7 @@ trait CodeExtraction extends ASTExtractors {
 
           val oldCurrentFunDef = currentFunDef
 
-          val funDefWithBody = extractFunBody(fd, params, b)(newDctx.copy(mutableVars = Map()))
+          val funDefWithBody = extractFunBody(fd, params, b)(newDctx.copy(mutableVars = Map())).setOwner(oldCurrentFunDef)
 
           currentFunDef = oldCurrentFunDef
 
@@ -970,7 +970,7 @@ trait CodeExtraction extends ASTExtractors {
 
         case ExVarDef(vs, tpt, bdy) => {
           val binderTpe = extractType(tpt)
-          val newID = FreshIdentifier(vs.name.toString).setType(binderTpe)
+          val newID = FreshIdentifier(vs.name.toString).setType(binderTpe).setOwner(currentFunDef)
           val valTree = extractTree(bdy)
 
           if(valTree.getType.isInstanceOf[ArrayType]) {
@@ -1094,7 +1094,7 @@ trait CodeExtraction extends ASTExtractors {
           val newOracles = oracles map { case (tpt, sym) =>
             val aTpe  = extractType(tpt)
             val oTpe  = oracleType(ops.pos, aTpe)
-            val newID = FreshIdentifier(sym.name.toString).setType(oTpe)
+            val newID = FreshIdentifier(sym.name.toString).setType(oTpe).setOwner(currentFunDef)
             owners += (newID -> None)
             newID
           }
@@ -1112,7 +1112,7 @@ trait CodeExtraction extends ASTExtractors {
         case chs @ ExChooseExpression(args, body) =>
           val vars = args map { case (tpt, sym) =>
             val aTpe  = extractType(tpt)
-            val newID = FreshIdentifier(sym.name.toString).setType(aTpe)
+            val newID = FreshIdentifier(sym.name.toString).setType(aTpe).setOwner(currentFunDef)
             owners += (newID -> None)
             newID
           }
diff --git a/src/main/scala/leon/purescala/Common.scala b/src/main/scala/leon/purescala/Common.scala
index 28b197b474440807b78d55f997bf69ff93603608..dd1a6de02e35913f3a2ab11365c49eef3f2597c1 100644
--- a/src/main/scala/leon/purescala/Common.scala
+++ b/src/main/scala/leon/purescala/Common.scala
@@ -4,6 +4,7 @@ package leon
 package purescala
 
 import utils._
+import Definitions.Definition
 
 object Common {
   import Trees.Variable
@@ -54,6 +55,16 @@ object Common {
     def toVariable : Variable = Variable(this)
 
     def freshen: Identifier = FreshIdentifier(name, alwaysShowUniqueID).copiedFrom(this)
+    
+    var owner : Option[Definition] = None
+    
+    def setOwner(df : Definition) : Identifier = { this.owner = Some(df); this }
+    
+    def ownerChain : List[Identifier] = owner match { 
+      case None => List(this)
+      case Some(ow) => ow.id :: ow.id.ownerChain
+    }
+
   }
 
   private object UniqueCounter {
diff --git a/src/main/scala/leon/purescala/Definitions.scala b/src/main/scala/leon/purescala/Definitions.scala
index 1932cfd6de3d39889b46c6e47b89ede74425d395..582ebba3c9f17ab4fc615de76bd0e0f6366fa974 100644
--- a/src/main/scala/leon/purescala/Definitions.scala
+++ b/src/main/scala/leon/purescala/Definitions.scala
@@ -14,8 +14,14 @@ object Definitions {
   import TypeTreeOps._
 
   sealed abstract class Definition extends Tree {
+    
     val id: Identifier
-    var enclosing : Option[Definition] = None // The definition/scope enclosing this definition
+    
+    def owner = id.owner
+    def setOwner(owner : Definition) : this.type = { id.owner = Some(owner); this }
+    
+    var origOwner : Option[Definition] = None // The definition/scope enclosing this definition
+    
     def subDefinitions : Seq[Definition]      // The enclosed scopes/definitions by this definition
     override def hashCode : Int = id.hashCode
     override def equals(that : Any) : Boolean = that match {
@@ -25,12 +31,15 @@ object Definitions {
     override def copiedFrom(o : Tree) : this.type = {
       super.copiedFrom(o)
       o match {
-        case df : Definition => enclosing = df.enclosing
-        case _ => // FIXME should this ever happen?
+        case df : Definition if df.owner.isDefined => this.setOwner(df.owner.get) 
+        case _ => this // FIXME should this ever happen?
       }
-      this
+      
     }
 
+    // TODO: this seems quite elegant, but make sure it works
+    def setSubDefOwners() = for (df <- subDefinitions) df.setOwner(this)
+    
   }
 
   /** A ValDef declares a new identifier to be of a certain type. */
@@ -47,12 +56,13 @@ object Definitions {
     }
 
     def toVariable : Variable = Variable(id).setType(tpe)
+    setSubDefOwners()
   }
 
   /** A wrapper for a program. For now a program is simply a single object. The
    * name is meaningless and we just use the package name as id. */
   case class Program(id: Identifier, units: List[UnitDef]) extends Definition {
-    enclosing = None
+    origOwner = None
     def subDefinitions = units
     
     def definedFunctions    = units.flatMap(_.definedFunctions)
@@ -79,6 +89,7 @@ object Definitions {
       out.write(ScalaPrinter(this))
       out.close
     }
+    setSubDefOwners()
   }
 
   object Program {
@@ -91,9 +102,11 @@ object Definitions {
   case class TypeParameterDef(tp: TypeParameter) extends Definition {
     def subDefinitions = Seq()
     val id = tp.id
+    setSubDefOwners()
   }
 
   
+    
   object UnitDef { 
     def apply(id : Identifier, modules : Seq[ModuleDef]) : UnitDef = UnitDef(id,modules, true)
   }
@@ -124,13 +137,15 @@ object Definitions {
       out.write(ScalaPrinter(this))
       out.close
     }
+    
+    setSubDefOwners()
   }
   
    
   
   /** Objects work as containers for class definitions, functions (def's) and
    * val's. */
-  case class ModuleDef(id: Identifier, defs : Seq[Definition]) extends Definition {
+  case class ModuleDef(id: Identifier, defs : Seq[Definition], isSynthetic : Boolean = false) extends Definition {
     
     def subDefinitions = defs
     
@@ -156,6 +171,7 @@ object Definitions {
       case other => other // FIXME: huh?
     }})
     
+    setSubDefOwners()
 
   }
 
@@ -164,7 +180,7 @@ object Definitions {
   sealed trait ClassDef extends Definition {
     self =>
 
-    def subDefinitions = methods
+    def subDefinitions = fields ++ methods ++ tparams 
       
     val id: Identifier
     val tparams: Seq[TypeParameterDef]
@@ -185,6 +201,7 @@ object Definitions {
 
     def registerMethod(fd: FunDef) = {
       _methods = _methods ::: List(fd)
+      fd.setOwner(this)
     }
 
     def clearMethods() {
@@ -228,6 +245,7 @@ object Definitions {
     lazy val definedFunctions : Seq[FunDef] = methods
     lazy val definedClasses = Seq(this)
     lazy val classHierarchyRoots = if (this.hasParent) Seq(this) else Nil
+    
   }
 
   /** Abstract classes. */
@@ -240,7 +258,7 @@ object Definitions {
     val isCaseObject = false
     
     lazy val singleCaseClasses : Seq[CaseClassDef] = Nil
-    
+    setSubDefOwners()
   }
 
   /** Case classes/objects. */
@@ -249,12 +267,13 @@ object Definitions {
                           val parent: Option[AbstractClassType],
                           val isCaseObject: Boolean) extends ClassDef {
 
-    var _fields = Seq[ValDef]()
+    private var _fields = Seq[ValDef]()
 
     def fields = _fields
 
     def setFields(fields: Seq[ValDef]) {
       _fields = fields
+      _fields foreach { _.setOwner(this)}
     }
 
 
@@ -270,7 +289,7 @@ object Definitions {
     }
     
     lazy val singleCaseClasses : Seq[CaseClassDef] = if (hasParent) Nil else Seq(this)
-
+    setSubDefOwners()
   }
 
  
@@ -300,26 +319,31 @@ object Definitions {
     val defType : DefType
   ) extends Definition {
     
-    var fullBody: Expr = NoTree(returnType)
+    private var fullBody_ : Expr = NoTree(returnType)
+    def fullBody = fullBody_
+    def fullBody_= (e : Expr) {
+      fullBody_ = e
+      nestedFuns map {_.setOwner(this)}
+    }
 
     def body: Option[Expr] = withoutSpec(fullBody)
-    def body_=(b: Option[Expr]) = fullBody = withBody(fullBody, b)
+    def body_=(b: Option[Expr]) = {
+      fullBody = withBody(fullBody, b)
+    }
 
     def precondition = preconditionOf(fullBody)
     def precondition_=(oe: Option[Expr]) = {
-      fullBody = withPrecondition(fullBody, oe)
+      fullBody = withPrecondition(fullBody, oe) 
     }
 
     def postcondition = postconditionOf(fullBody)
     def postcondition_=(op: Option[(Identifier, Expr)]) = {
-      fullBody = withPostcondition(fullBody, op)
+      fullBody = withPostcondition(fullBody, op) 
     }
 
-    def subDefinitions = Seq()
-
-    // Metadata kept here after transformations
-    var parent: Option[FunDef] = None
-    var orig: Option[FunDef] = None
+    def nestedFuns = directlyNestedFunDefs(fullBody)
+    
+    def subDefinitions = params ++ tparams ++ nestedFuns.toList
 
     def duplicate: FunDef = {
       val fd = new FunDef(id, tparams, returnType, params, defType)
@@ -328,10 +352,10 @@ object Definitions {
     }
     
     def copyContentFrom(from : FunDef) {
-      this.fullBody       = from.fullBody
-      this.parent         = from.parent
-      this.orig           = from.orig
-      this.enclosing      = from.enclosing
+      this.fullBody  = from.fullBody 
+      //this.parent   = from.parent
+      //this.orig    = from.orig
+      this.origOwner = from.origOwner
       this.addAnnotation(from.annotations.toSeq : _*)
     }
 
@@ -367,6 +391,7 @@ object Definitions {
       TypedFunDef(this, Nil)
     }
 
+    setSubDefOwners()
     // Deprecated, old API
     @deprecated("Use .body instead", "2.3")
     def implementation : Option[Expr] = body
diff --git a/src/main/scala/leon/purescala/FunctionClosure.scala b/src/main/scala/leon/purescala/FunctionClosure.scala
index 5151f2b708a1448922370697f96f452107c14eaf..225070f6f834f99a8bd357f28108aa8b3e892216 100644
--- a/src/main/scala/leon/purescala/FunctionClosure.scala
+++ b/src/main/scala/leon/purescala/FunctionClosure.scala
@@ -62,9 +62,9 @@ object FunctionClosure extends TransformationPhase {
       val newFunDef = new FunDef(newFunId, fd.tparams, fd.returnType, newValDefs, fd.defType).copiedFrom(fd)
       topLevelFuns += newFunDef
       newFunDef.addAnnotation(fd.annotations.toSeq:_*) //TODO: this is still some dangerous side effects
-      newFunDef.parent = Some(parent)
-      fd.parent        = Some(parent)
-      newFunDef.orig   = Some(fd)
+      newFunDef.setOwner(parent)
+      fd       .setOwner(parent)
+      newFunDef.origOwner   = Some(fd)
 
       def introduceLets(expr: Expr, fd2FreshFd: Map[FunDef, (FunDef, Seq[Variable])]): Expr = {
         val (newExpr, _) = enclosingLets.foldLeft((expr, Map[Identifier, Identifier]()))((acc, p) => {
diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala
index 7338b58107e1f4c9e9ae0981f33c09c5d6365ae4..c661714b84193325daf86d48947ec05009590101 100644
--- a/src/main/scala/leon/purescala/PrettyPrinter.scala
+++ b/src/main/scala/leon/purescala/PrettyPrinter.scala
@@ -372,16 +372,17 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe
 
 
       // Definitions
-      case Program(id, units) =>
-        p"""${nary(units, "\n\n")}"""        
 
+      case Program(id, units) =>
+        p"""${nary(units, "\n\n")}"""
+        
       case UnitDef(id,modules,isBasic) =>
         if (isBasic) {
           p"""|package $id {
               |  ${nary(modules,"\n\n")}
               |}"""
         }
-      case ModuleDef(id, defs) =>
+      case ModuleDef(id, defs, _) =>
         p"""|object $id {
             |  ${nary(defs, "\n\n")}
             |}"""
diff --git a/src/main/scala/leon/purescala/RestoreMethods.scala b/src/main/scala/leon/purescala/RestoreMethods.scala
index 0a808649884927dada2f31a1f14ea8957ea335ae..0b44f5d55eebfe1ae5b4bec7e162adbda9df2d2b 100644
--- a/src/main/scala/leon/purescala/RestoreMethods.scala
+++ b/src/main/scala/leon/purescala/RestoreMethods.scala
@@ -21,7 +21,7 @@ object RestoreMethods extends TransformationPhase {
     var fd2Md = Map[FunDef, FunDef]()
     var whoseMethods = Map[ClassDef, Seq[FunDef]]()
     
-    for ( (Some(cd : ClassDef), funDefs) <- p.definedFunctions.groupBy(_.enclosing).toSeq ) {
+    for ( (Some(cd : ClassDef), funDefs) <- p.definedFunctions.groupBy(_.origOwner).toSeq ) {
       whoseMethods += cd -> funDefs
       for (fn <- funDefs) {
         val theName = try {
diff --git a/src/main/scala/leon/purescala/TreeOps.scala b/src/main/scala/leon/purescala/TreeOps.scala
index 67cec4c0e39105361c8fa84358a1c012f1a44a97..2277f606037279c0091681c61f39922e20c680ed 100644
--- a/src/main/scala/leon/purescala/TreeOps.scala
+++ b/src/main/scala/leon/purescala/TreeOps.scala
@@ -368,7 +368,15 @@ object TreeOps {
       case _ => Set()
     }(expr)
   }
-
+  
+  /** Returns functions in directly nested LetDefs */
+  def directlyNestedFunDefs(e: Expr): Set[FunDef] = {
+    foldRight[Set[FunDef]]{ 
+      case (LetDef(fd,bd), _) => Set(fd)
+      case (_, subs) => subs.foldLeft(Set[FunDef]())(_ ++ _) 
+    }(e)
+  }
+  
   def negate(expr: Expr) : Expr = (expr match {
     case Let(i,b,e) => Let(i,b,negate(e))
     case Not(e) => e
diff --git a/src/main/scala/leon/utils/ScopingPhase.scala b/src/main/scala/leon/utils/ScopingPhase.scala
index deb2e8a13689eef50d1993295c10f512938c2e47..839f53855bf50e5db10ac3a43ebdf9f8eb597342 100644
--- a/src/main/scala/leon/utils/ScopingPhase.scala
+++ b/src/main/scala/leon/utils/ScopingPhase.scala
@@ -15,7 +15,7 @@ object ScopingPhase extends UnitPhase[Program] {
   }
 
   private def insertScopingInformation(df : Definition , parent : Option[Definition]) {
-    df.enclosing = parent
+    df.origOwner = parent
     for (sub <- df.subDefinitions){
       insertScopingInformation(sub, Some(df))
     }
diff --git a/src/main/scala/leon/xlang/XlangAnalysisPhase.scala b/src/main/scala/leon/xlang/XlangAnalysisPhase.scala
index 3d236b1b4810570fc11e494722a71c025f8633d3..3ec56711560a4a2e3750a729410950bccd292fbf 100644
--- a/src/main/scala/leon/xlang/XlangAnalysisPhase.scala
+++ b/src/main/scala/leon/xlang/XlangAnalysisPhase.scala
@@ -21,14 +21,15 @@ object XlangAnalysisPhase extends LeonPhase[Program, VerificationReport] {
     val (pgm3, wasLoop) = ImperativeCodeElimination.run(ctx)(pgm2)
     val pgm4 = purescala.FunctionClosure.run(ctx)(pgm3)
 
-    def functionWasLoop(fd: FunDef): Boolean = fd.orig match {
-      case None => false //meaning, this was a top level function
-      case Some(nested) => wasLoop.contains(nested) //could have been a LetDef originally
+    def functionWasLoop(fd: FunDef): Boolean = fd.origOwner match {
+      case Some(nested : FunDef) => // was a nested function
+        wasLoop.contains(nested)
+      case _ => false //meaning, this was a top level function
     }
 
     var subFunctionsOf = Map[FunDef, Set[FunDef]]().withDefaultValue(Set())
-    pgm4.definedFunctions.foreach { fd => fd.parent match {
-      case Some(p) =>
+    pgm4.definedFunctions.foreach { fd => fd.owner match {
+      case Some(p : FunDef) =>
         subFunctionsOf += p -> (subFunctionsOf(p) + fd)
       case _ =>
     }}
@@ -72,7 +73,7 @@ object XlangAnalysisPhase extends LeonPhase[Program, VerificationReport] {
       if(functionWasLoop(funDef)) {
         val freshVc = new VerificationCondition(
           vc.condition, 
-          funDef.parent.getOrElse(funDef), 
+          funDef.owner match { case Some(fd : FunDef) => fd; case _ => funDef }, 
           if(vc.kind == VCPostcondition) VCInvariantPost else if(vc.kind == VCPrecondition) VCInvariantInd else vc.kind,
           vc.tactic,
           vc.info).setPos(funDef)