         method.call(target)
 
         modelNotify()
+    }
+
+  # @todo mask a top-level property and also keep track of which scope notifier it is
+  # @todo this works exactly like before, except the bound model is not "this", but a named property, to allow access to previous scopes
+  # @todo this fits the idea of a model still - it's now a view-model, groomed by the template glue code for convenience
+  # @todo an alternative could be to track "parent" scope name - but this just fits programmer mindset better and is more convenient and closer to the template conventions
+  runTemplate = (viewPrototype, preInitMap, template) ->
+    viewInstance =
+      fork: (map, subTemplate) ->
+        # create clean sub-view model and initialize it with given values
+        runTemplate viewInstance, map, subTemplate
 
     if preInitMap
       viewInstance[n] = v for n, v of preInitMap
 
     viewInstance.__proto__ = viewPrototype
 
-    template.call(viewInstance, model)
+    template.call(viewInstance)
 
     undefined # prevent stray output
 
-  runTemplate rootModel, {}, createNotifier(), Object.prototype, rootTemplate
+  runTemplate Object.prototype, createViewScope(rootModel), rootTemplate

          createGetter (-> v = parentGetter(); if typeof v isnt 'object' then undefined else v[element]), index + 1

      getter = createGetter (-> model), 0
      bindOnChange getter, modelNotify, viewInstance, subTemplate

    viewInstance =
      fork: (map, subTemplate) ->
        # create clean sub-view model and initialize it with given values
        runTemplate model, viewModel, viewModelNotify, viewInstance, subTemplate, map

      get: () ->
        # @todo type-check for primitives for true immutability


  modelNotify = createNotifier()

  createViewScope = (model) ->
    viewModel = {}
    viewModelNotify = createNotifier()

    bindOnChange = (viewInstance, getter, notify, subTemplate) ->
      value = getter()

      clear = notify ->
        # get and compare with cached values
        newValue = getter()
        if newValue isnt value
          value = newValue
          viewInstance.fork createViewScope(value), subTemplate

      viewInstance.fork createViewScope(value), subTemplate

      # return a handle to be able to unwatch
      { clear: clear }

    bindVariable = (viewInstance, name, subTemplate) ->
      bindOnChange viewInstance, (-> viewModel[name]), viewModelNotify, subTemplate

    bindIndex = (viewInstance, index, subTemplate) ->
      getter = if typeof model is 'object' then (-> model[index]) else (-> undefined)
      bindOnChange viewInstance, getter, modelNotify, subTemplate

    bindPath = (viewInstance, pathElementList, subTemplate) ->
      # recursive getter that freezes actual path elements inside the closures
      createGetter = (parentGetter, index) ->
        if index >= pathElementList.length
