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:             // extra sort.  once to sort everything in order, then coalesce,
              // then sort by size descending.
  
              let newList = freeBlocks @ blocks
              // 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
          )
          //printfn "freeBlocks: %A" freeBlocks
  
      // a stored segmentinfo for a segment is a single blob of bytes.
      // age
  
negative.code: 
      let (firstReadOfHeader,pageSize,firstAvailablePage) = readHeader()
  
      let mutable header = firstReadOfHeader
      let mutable nextPage = firstAvailablePage
      let mutable segmentsInWaiting: Map<Guid,PageBlock list> = Map.empty
  
      let consolidateBlockList blocks =
          let sortedBlocks = List.sortBy (fun (x:PageBlock) -> x.firstPage) blocks
          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)
          consolidated
  
      let invertBlockList blocks =
          let sortedBlocks = List.sortBy (fun (x:PageBlock) -> x.firstPage) blocks
          let fldr acc (t:PageBlock) =
              let (prev:PageBlock, result) = acc
              (t, PageBlock(prev.lastPage+1, t.firstPage-1) :: result)
          let folded = List.fold fldr (List.head sortedBlocks, []) (List.tail sortedBlocks)
          // if is being used to calculate free blocks, it won't find any free
          // blocks between the last used page and the end of the file
          snd folded
  
      // TODO need to build a list of all the available pages
  
      let listAllBlocks h =
          let headerBlock = PageBlock(1, HEADER_SIZE_IN_BYTES / pageSize)
          let currentBlocks = Map.fold (fun acc _ info -> info.blocks @ acc) [] h.segments
          let inWaitingBlocks = Map.fold (fun acc _ blocks -> blocks @ acc) [] segmentsInWaiting
          let segmentBlocks = headerBlock :: currentBlocks @ inWaitingBlocks
          if h.sill.firstPage > 0 then
              PageBlock(h.sill.firstPage, h.sill.lastPage) :: segmentBlocks
          else
              segmentBlocks
  
      let initialFreeBlocks = header |> listAllBlocks |> consolidateBlockList |> invertBlockList |> List.sortBy (fun (x:PageBlock) -> -(x.CountPages)) 
      //do printfn "initialFreeBlocks: %A" initialFreeBlocks
  
      let mutable freeBlocks:PageBlock list = initialFreeBlocks
  
      let critSectionNextPage = obj()
      let getBlock specificSize =
  