anchor.diff:                          set
                       )
   
  +                // TODO: move to class-fields
                   let deadSet = HashSet()
                   let recompileSet = HashSet()
                   let relinkSet = HashSet()
  
positive.code:     inherit IAdaptiveObject
      inherit IDisposable
      
      abstract member Update : IAdaptiveObject -> AdaptiveProgramStatistics
      abstract member Run : 'i -> unit
      
      abstract member Disassemble : unit -> obj
  
      abstract member AutoDefragmentation : bool with get, set
      abstract member StartDefragmentation : unit -> Task<TimeSpan>
  
      abstract member NativeCallCount : int
      abstract member FragmentCount : int
      abstract member ProgramSizeInBytes : int64
      abstract member TotalJumpDistanceInBytes : int64
  
  [<AllowNullLiteral>]
  
negative.code:                 | _ ->
                      ()
  
          
          member x.Run (v : 'i) =
              lock x (fun () ->        
                  handler.run v
              )
  
          member x.Disassemble() =
              lock x (fun () ->        
                  let code = List()
                  let mutable current = prolog
                  while current <> epilog do
                      if current <> prolog then
                          match current.Storage with
                              | None -> code.Add [||]
                              | Some s -> code.Add(handler.disassemble s |> List.toArray)
  
                      match current.Storage, current.Next.Storage with
                          | Some l, Some r -> 
                              if not (handler.isNext l r) then
                                  failwith "bad pointers"
                          | _ -> ()
  
                      current <- current.Next
                  code.ToArray()
              )
  
          member x.Update caller = 
              // update basically runs in 4 stages:
              //  1) process input deltas adding/removing fragments
              //  2) create code for fragments which need to be recompiled.
              //     recompile can be triggered either because they're new or their 
              //     predecessor changed and compileDelta depends on the it.
              //  3) write the code for all changed fragments to their underlying 
              //     (possibly native) representation. This is obviously needed for new
              //     fragments but also for the ones where some inner-instruction changed.
              //  4) link fragments appropriately where needed. Fragments must obviously be
              //     linked whenever Next changes but also when WriteContent() returns true
              //     (which is the case when the underlying representation has been moved)
              // known issues:
              //   - whenver an instruction changes the entire fragment is re-assembled and written
              //     as a whole. The write itself may not be too bad but the assemble-step 
              //     (at least in the native implementation) might be expensive
              //   - core-implementations (like CodeFragment) provide Append/Update/Clear function which
              //     are no longer optimal for this new implementation. 
              //     a possibly better API would be (where bool indicates if the fragment was moved)
              //       Write : list<list<Instruction>> -> bool * list<Handle>
              //       Update : Handle -> list<Instruction> -> bool
              x.EvaluateIfNeeded caller AdaptiveProgramStatistics.Zero (fun v ->
                  Interlocked.Increment(version) |> ignore
  
                  // start by getting the deltas from our input-set
                  let deltas = reader.GetDelta x
  
                  // get all fragments whose inner code-representation changed. 
                  let dirtySet = 
                      lock dirtyLock (fun () ->
                          let set = dirtySet
  