anchor.diff:  
           let mutable isDisposed = false
           let mutable refCount = 1
  -        
  +        let mutable changedInputs = []
  +
  +        override x.InputChanged (i : IAdaptiveObject) =
  +            if desc.trackChangedInputs then
  +                Interlocked.Change(&changedInputs, fun l -> i::l) |> ignore
  +                       
   
           //member x.Dependencies = desc.dependencies
           member x.UpdateCPU(caller : IAdaptiveObject) = 
               Telemetry.timed updateCPUProbe (fun () ->
  +                let changed = 
  +                    if desc.trackChangedInputs then Interlocked.Exchange(&changedInputs, [])
  +                    else []
                   //desc.dependencies |> List.iter (fun a -> a.GetValue(x) |> ignore)
  -                desc.updateCPU()
  +                desc.updateCPU changed
               )
   
           member x.UpdateGPU(caller) = 
  
positive.code:     exception ResourceManagerException of string
  
      type internal ChangeableResourceDescription<'a> = 
          { dependencies : list<IMod>; 
            updateCPU : unit -> unit; 
            updateGPU : unit -> unit; 
            destroy : unit -> unit; 
            resource : IMod<'a>;
  
negative.code:                     let handle = ctx.CreateVertexArrayObject(bindings |> List.map (fun (i,r) -> i, r.GetValue(self)))
                      let attributes = bindings |> List.map snd |> List.map (fun b -> b :> IMod)
  
                      { trackChangedInputs = true
                        dependencies = attributes
                        updateCPU = fun _ -> ()
                        updateGPU = fun () -> ctx.Update(handle,bindings |> List.map (fun (i,r) -> i, r.GetValue(self)))
                        destroy = fun () -> ctx.Delete(handle)
                        resource = Mod.constant handle
  