anchor.diff:          fsMine.Seek(0L, SeekOrigin.Begin) |> ignore
           pb.Write(fsMine)
           fsMine.Flush()
  -
  -    let consolidateBlockList h =
  -        // TODO filter the segments by guid, ignore anything with a cursor.
  -        // if this is called at startup, so there should be no cursors yet.  still.
  -        let allBlocks = Map.fold (fun acc _ value -> value.blocks @ acc) [] h.segments
  -        let sortedBlocks = List.sortBy (fun (x:PageBlock) -> x.firstPage) allBlocks
  -        let fldr acc (t:PageBlock) =
  -            let (blk:PageBlock, pile) = acc
  -            if blk.lastPage + 1 = t.firstPage then
  -                (PageBlock(blk.firstPage, t.lastPage), pile)
  -            else
  -                (PageBlock(t.firstPage, t.lastPage), blk :: pile)
  -        let folded = List.fold fldr (List.head sortedBlocks, []) (List.tail sortedBlocks)
  -        let consolidated = (fst folded) :: (snd folded)
  -        // TODO note that the the blocks consumed by the segmentInfoList are ignored here
  -        consolidated
   
       let critSectionMerging = obj()
       // this keeps track of which segments are currently involved in a merge.
  
positive.code:                 isReleased := true
                  let next = lock critSectionInTransaction (fun () ->
                      if Queue.isEmpty waiting then
                          printfn "nobody waiting. tx done"
                          inTransaction <- false
                          None
                      else
                          printfn "queue has %d waiting.  next." (Queue.length waiting)
                          let f = Queue.head waiting
                          waiting <- Queue.tail waiting
                          printfn "giving lock to next"
                          Some f
                  )
                  match next with
                  | Some f ->
                      f()
                      printfn "done giving lock to next"
                  | None -> ()
              {
              new System.Object() with
  
negative.code:             // extra sort.  once to sort everything in order, then coalesce,
              // then sort by size descending.
  
              // TODO if the last block of the file is free, consider just
              // moving nextPage back.
  
              let newList = freeBlocks @ blocks |> consolidateBlockList
              // TODO here, inside a critical section, is an unhappy place to do a sort
              let sorted = List.sortBy (fun (x:PageBlock) -> -(x.CountPages)) newList
              freeBlocks <- sorted
          )
          #if not
          printfn "lastPage: %d" (nextPage-1)
          printfn "freeBlocks: %A" freeBlocks
          let c1 = header |> listAllBlocks |> consolidateBlockList
          printfn "usedBlocks: %A" c1
          let c2 = c1 |> invertBlockList
          printfn "inverted: %A" c2
          let c3 = List.sortBy (fun (x:PageBlock) -> -(x.CountPages)) c2
          printfn "calc: %A" c3
          printfn ""
          #endif
  
      // a stored segmentinfo for a segment is a single blob of bytes.
      // age
  