         f.apply(@, args)
     result.$isNonreactive = true
     result
-  
+
   onInvalidate: (f) ->
     if not Tracker.active
       throw new Error("Tracker.onInvalidate requires a currentComputation")
-      
+
     Tracker.currentComputation.onInvalidate(f)
-    
+
   afterFlush: (f) ->
     afterFlushCallbacks.push(f)
 


_.extend Tracker,
  currentComputationVar: new Meteor.EnvironmentVariable()
  
  flush: ->
    if not queue.safeToRunTask()
      throw new Error("Can't call Tracker.flush while flushing, or inside Tracker.autorun")
    
    queue.drain()
      
  _postRun: ->
    while (queue._taskHandles.length == 0) and (afterFlushCallbacks.length > 0)
      f = afterFlushCallbacks.shift()

      @firstRun = false
      if errored
        @stop()

  onInvalidate: (f) ->
    if typeof f != "function"
      throw new Error("onInvalidate requires a function")

    f = Tracker._makeNonreactive(Meteor.bindEnvironment(f, null, @))

    if @invalidated
      f()
    else
      @_onInvalidateCallbacks.push(f)

  invalidate: ->
    if not @invalidated
      if not @_recomputing and not @stopped
        queue.queueTask =>
          @._recompute()
          Tracker._postRun()

      @invalidated = true

      for callback in @_onInvalidateCallbacks
        callback()
      @_onInvalidateCallbacks = []

  stop: ->
    if not @stopped
      @stopped = true
      @invalidate()

  _compute: ->
    @invalidated = false
    @._func(@)

  _recompute: ->
    @_recomputing = true
    while @invalidated and not @stopped
