anchor.diff:                          set
                       )
   
  +                // TODO: move to class-fields
                   let deadSet = HashSet()
                   let recompileSet = HashSet()
                   let relinkSet = HashSet()
  
positive.code:                 let mutable added = 0
                  let mutable removed = 0
              
                  let prologNext = 
                      prolog.Next.Storage
  
                  let epilogPrev = 
                      epilog.Prev.Storage
  
  
                  let createBetween (prev : Option<Fragment<'i, 'a, 'instruction, 'fragment>>) (v : 'a) (next : Option<Fragment<'i, 'a, 'instruction, 'fragment>>)  =
                      //let code = desc.compileDelta (Option.map DynamicFragment.tag prev) v (Option.map DynamicFragment.tag next)
                      let fragment = new Fragment<'i, 'a, 'instruction, 'fragment>(handler, v)
  
                      let l = 
                          match prev with 
                              | Some l -> l 
                              | None -> prolog
  
                      let r = 
                          match next with 
                              | Some r -> 
                                  if handler.compileNeedsPrev then recompileSet.Add r |> ignore
                                  r 
                              | None -> epilog
                      
                      relinkSet.Add l |> ignore
                      relinkSet.Add fragment |> ignore
  
                      r.Prev <- fragment
                      fragment.Prev <- l
                      fragment.Next <- r
                      l.Next <- fragment
  
                      fragment
  
                  deltaProcessWatch.Restart()
                  for d in deltas do
                      match d with
                          | Add (k,v) ->
                              added <- added + 1
  
                              let l,s,r = SortedDictionary.neighbourhood k fragments
  
                              let next =
                                  match r with
                                      | Some(_,r) -> r.First
                                      | None -> None
  
                              let prev =
                                  match l with
                                      | Some(_,l) -> l.Last
                                      | None -> None
  
                              let fragment = 
                                  match s with
                                      | Some self ->
                                          let created =
                                              self.AddWithPrev (fun p -> createBetween p v next) 
  
                                          match created with
                                              | Some f -> f
                                              | None -> failwithf "duplicated key: %A" k
  
                                      | None ->
                                          let frag = createBetween prev v next
                                          let set = StableSet()
                                          set.Add frag |> ignore
                                          fragments.[k] <- set
                                          frag
  
                              cache.[(k,v)] <- fragment
                              recompileSet.Add fragment |> ignore
  
                          | Rem (k,v) ->
                          
                              match fragments.TryGetValue k with
                                  | (true, set) ->
                                      match cache.TryRemove ((k,v)) with
                                          | (true, fragment) ->
  
                                              if set.Remove fragment then
                                                  removed <- removed + 1 
                                                  fragment.Next.Prev <- fragment.Prev
                                                  fragment.Prev.Next <- fragment.Next
  
                                                  relinkSet.Add fragment.Prev |> ignore
                                                  if handler.compileNeedsPrev && fragment.Next <> epilog then
                                                      recompileSet.Add fragment.Next |> ignore
  
                                                  fragment.Dispose()
                                                  deadSet.Add fragment |> ignore
  
                                                  if set.Count = 0 then
                                                      fragments.Remove k |> ignore
  
                                              ()
                                          | _ ->
                                              failwithf "could not find Fragment for: %A" k
                                  | _ -> 
                                      failwithf "could not find container for: %A" k
                  deltaProcessWatch.Stop()
  
                  dirtySet.ExceptWith deadSet
                  recompileSet.ExceptWith deadSet
                  relinkSet.ExceptWith deadSet
  
                  compileWatch.Restart()
                  for r in recompileSet do
                      if r.Recompile x then
                          relinkSet.Add r |> ignore
                          dirtySet.Add r |> ignore
  
                  compileWatch.Stop()
  
  
  
                  writeWatch.Restart()
                  for d in dirtySet do
                      if d.WriteContent x then
                          relinkSet.Add d.Prev |> ignore
  
  
                  relinkSet.UnionWith(fragments |> Seq.collect (fun (KeyValue(_,v)) -> v))
  
                  for d in relinkSet do
                      d.LinkNext x
  
  //                prolog.LinkNext x
  //                epilog.LinkPrev x
                  writeWatch.Stop()
  
                  if autoDefragmentation = 1 && relinkSet.Count > 0 && !handler.jumpDistance > 0 then
                      handler.startDefragmentation (x :> obj) version |> ignore
  
                  AdaptiveProgramStatistics (
                      DeltaProcessTime = deltaProcessWatch.Elapsed,
                      CompileTime = compileWatch.Elapsed,
  
negative.code:     inherit IAdaptiveObject
      inherit IDisposable
      
      /// updates the program representation if needed and returns some statistics
      abstract member Update : IAdaptiveObject -> AdaptiveProgramStatistics
  
      /// runs the program with the given input argument
      /// NOTE: that no updates are performed here
      abstract member Run : 'i -> unit
      
      /// disassembles the underlying program and returns
      /// an implementation specific representation
      abstract member Disassemble : unit -> obj
  
      /// gets or sets a flag indicating whether or not the program should automatically
      /// be defragmented whenever the jump-distance is non-zero
      abstract member AutoDefragmentation : bool with get, set
  
      /// explicitly starts a defragmentation task if needed
      abstract member StartDefragmentation : unit -> Task<TimeSpan>
  
      /// gets the number of native calls currently performed by the program
      abstract member NativeCallCount : int
  
      /// gets the number of elements currently contained in the program
      abstract member FragmentCount : int
  
      /// gets a total size for the underlying program data
      abstract member ProgramSizeInBytes : int64
  
      /// gets a total jump distance for the underlying program (if applicable)
      abstract member TotalJumpDistanceInBytes : int64
  
  [<AllowNullLiteral>]
  