anchor.diff:  
                   traverseCount := !traverseCount + 1
   
  -                let outputs = 
  -                    // since we're about to access the outOfDate flag
  -                    // for this object we must acquire a lock here.
  -                    // Note that the transaction will at most hold one
  -                    // lock at a time.
  -                    lock e (fun () ->
  -                        // if the element is already outOfDate we
  -                        // do not traverse the graph further.
  -                        if e.OutOfDate then
  -                            emptyArray
  -
  +                // since we're about to access the outOfDate flag
  +                // for this object we must acquire a lock here.
  +                // Note that the transaction will at most hold one
  +                // lock at a time.
  +                Monitor.Enter e
  +                try
  +                    // if the element is already outOfDate we
  +                    // do not traverse the graph further.
  +                    if e.OutOfDate then
  +                        outputs <- emptyArray
  +
  +                    else
  +                        // if the object's level has changed since it
  +                        // was added to the queue we re-enqueue it with the new level
  +                        // Note that this may of course cause runtime overhead and
  +                        // might even change the asymptotic runtime behaviour of the entire
  +                        // system in the worst case but we opted for this approach since
  +                        // it is relatively simple to implement.
  +                        if currentLevel <> e.Level then
  +                            q.Enqueue e
  +                            outputs <- emptyArray
                           else
  -                            // if the object's level has changed since it
  -                            // was added to the queue we re-enqueue it with the new level
  -                            // Note that this may of course cause runtime overhead and
  -                            // might even change the asymptotic runtime behaviour of the entire
  -                            // system in the worst case but we opted for this approach since
  -                            // it is relatively simple to implement.
  -                            if currentLevel <> e.Level then
  +                            if causes.TryRemove(e, &myCauses.contents) then
  +                                !myCauses |> Seq.iter e.InputChanged
  +
  +                            // however if the level is consistent we may proceed
  +                            // by marking the object as outOfDate
  +                            e.OutOfDate <- true
  +
  +                            markCount := !markCount + 1
  +                
  +                            try 
  +                                // here mark and the callbacks are allowed to evaluate
  +                                // the adaptive object but must expect any call to AddOutput to 
  +                                // raise a LevelChangedException whenever a level has been changed
  +                                if e.Mark() then
  +                                    // if everything succeeded we return all current outputs
  +                                    // which will cause them to be enqueued 
  +                                    outputs <- e.Outputs.Consume()
  +
  +                                else
  +                                    // if Mark told us not to continue we're done here
  +                                    outputs <- emptyArray
  +
  +                            with LevelChangedException(obj, objLevel, distance) ->
  +                                // if the level was changed either by a callback
  +                                // or Mark we re-enqueue the object with the new level and
  +                                // mark it upToDate again (since it would otherwise not be processed again)
  +                                e.Level <- max e.Level (objLevel + distance)
  +                                e.OutOfDate <- false
  +
  +                                levelChangeCount := !levelChangeCount + 1
  +
                                   q.Enqueue e
  -                                emptyArray
  -                            else
  -                                if causes.TryRemove(e, &myCauses.contents) then
  -                                    !myCauses |> Seq.iter e.InputChanged
  -
  -                                // however if the level is consistent we may proceed
  -                                // by marking the object as outOfDate
  -                                e.OutOfDate <- true
  -
  -                                markCount := !markCount + 1
  +                                outputs <- emptyArray
                   
  -                                try 
  -                                    // here mark and the callbacks are allowed to evaluate
  -                                    // the adaptive object but must expect any call to AddOutput to 
  -                                    // raise a LevelChangedException whenever a level has been changed
  -                                    if e.Mark() then
  -                                        // if everything succeeded we return all current outputs
  -                                        // which will cause them to be enqueued 
  -                                        e.Outputs.Consume()
  -
  -                                    else
  -                                        // if Mark told us not to continue we're done here
  -                                        emptyArray
  -
  -                                with LevelChangedException(obj, objLevel, distance) ->
  -                                    // if the level was changed either by a callback
  -                                    // or Mark we re-enqueue the object with the new level and
  -                                    // mark it upToDate again (since it would otherwise not be processed again)
  -                                    e.Level <- max e.Level (objLevel + distance)
  -                                    e.OutOfDate <- false
  -
  -                                    levelChangeCount := !levelChangeCount + 1
  -
  -                                    q.Enqueue e
  -                                    emptyArray
  -                    )
  +                finally 
  +                    Monitor.Exit e
   
                   // finally we enqueue all returned outputs
                   for o in outputs do
  
positive.code: /// defines a base class for all adaptive objects implementing
  /// IAdaptiveObject.
  /// </summary>
  type AdaptiveObject() =
      static let EvaluationOverheadProbe = Symbol.Create "[Adaptive] eval"
      let id = newId()
      let mutable outOfDate = true
      let mutable level = 0
      let outputs = VolatileCollection<IAdaptiveObject>()
  
      static let time = AdaptiveObject() :> IAdaptiveObject
      
      member inline private this.evaluate (caller : IAdaptiveObject) (otherwise : Option<'a>) (f : unit -> 'a) =
          Telemetry.timed EvaluationOverheadProbe (fun () ->
              let depth = curerntEvaluationDepth.Value
              let top = isNull caller && !depth = 0 && not Transaction.HasRunning
  
  
  
negative.code:                 Monitor.Exit this
  
              if top then 
                  let time = AdaptiveObject.Time
                  Monitor.Enter time
                  if not time.Outputs.IsEmpty then
                      let outputs = time.Outputs.Consume()
  