       variable: (name, value) ->
         viewModel[name] = value
         viewModelNotify()
-
-      bind: (path, subTemplate) ->
-        if typeof path isnt 'string'
-          bindIndex path, subTemplate
-        else if path[0] is '@'
-          bindVariable path.substring(1), subTemplate
-        else
-          bindPath path.split('.'), subTemplate
 
       apply: (path) ->
         target = null


  modelNotify = createNotifier()

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

    clear = notify ->
      # get and compare with cached values
      newValue = getter()
      if newValue isnt value
        value = newValue
        runTemplate value, {}, createNotifier(), viewInstance, subTemplate

    runTemplate value, {}, createNotifier(), viewInstance, subTemplate

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

  runTemplate = (model, viewModel, viewModelNotify, viewPrototype, template, preInitMap) ->
    bindVariable = (name, subTemplate) ->
      bindOnChange (-> viewModel[name]), viewModelNotify, viewInstance, subTemplate

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

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

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

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

    {
      bind: (path, subTemplate) ->
        if typeof path isnt 'string'
          bindIndex this, path, subTemplate
        else if path[0] is '@'
          bindVariable this, path.substring(1), subTemplate
        else
          bindPath this, path.split('.'), subTemplate

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