             v = if v is undefined then undefined else v[n]
           v
 
+  createNotifier = ->
+    list = []
+
+    (callback) ->
+      if typeof callback isnt 'function'
+        # invoke watches and cull ones that request to be removed
+        # for speed, we just rewrite the portion of the list in place every time, eliminating cleared watches
+        # @todo surely, this should be wrapped in try/catch
+        count = list.length
+        index = 0
+        compactedCount = 0
+
+        while index < count
+          listener = list[index]
+          index += 1
+
+          if listener[0]
+            # preserve the listener for next run
+            list[compactedCount] = listener
+            compactedCount += 1
+
+            listener[0]()
+
+        # truncate compacted listener list (preserving any watches that have been added during this run)
+        list.splice(compactedCount, count - compactedCount)
+
+        console.log 'watch count', list.length
+
+      else
+        listener = [ callback ]
+        list.push listener
+
+        # return a handle to be able to unwatch
+        ->
+          # delayed removal for safety
+          listener[0] = null
+
+  modelNotify = createNotifier()
+
   runTemplate = (model, viewPrototype, template, preInitMap) ->
     viewModel =
       fork: (map, subTemplate) ->

        getter = createGetter model, path
        value = getter()

        watch = ->
          # get and compare with cached values
          newValue = getter()
          if newValue isnt value
            value = newValue
            runTemplate value, viewModel, subTemplate

        watch.isCleared = false

        watchList.push watch

        runTemplate value, viewModel, subTemplate

        # return a handle to be able to unwatch
        {
          clear: ->
            # delayed removal for safety
            watch.isCleared = true
        }

      apply: (run) ->
        # fail fast on error


window.tubular = (rootModel, rootTemplate) ->
  createGetter = (model, path) ->
    if model is undefined
      # always is undefined
