anchor.diff:                      | Some value -> value :?> 'S
                       | _ -> failwithf "Key %A is not found in the map." key
   
  +    member this.persistent() : PersistentHashMap<'T,'S> =
  +        root.SetThread null
  +        PersistentHashMap(count, root, hasNull, nullValue)
  +
  +and PersistentHashMap<[<EqualityConditionalOn>]'T, 'S when 'T : equality and 'S : equality> (count,root:INode,hasNull, nullValue:'S) =
  +    
  +    static member Empty() : PersistentHashMap<'T, 'S> = PersistentHashMap(0, Unchecked.defaultof<INode>, false, Unchecked.defaultof<'S>)
  +    member this.Length : int = count
  +
  +    member this.ContainsKey (key:'T) =
  +        if key = Unchecked.defaultof<'T> then hasNull else
  +        if root = Unchecked.defaultof<INode> then false else
  +        root.find(0, hash(key), key) <> null
  +
  +    member this.Add(key:'T, value:'S) =
  +        if key = Unchecked.defaultof<'T> then
  +            if hasNull && value = nullValue then this else
  +            let count = if hasNull then count else count + 1
  +            PersistentHashMap<'T, 'S>(count, root, true, value)
  +        else 
  +            let addedLeaf = Box(null)
  +            let newroot =
  +                (if root = Unchecked.defaultof<INode> then BitmapIndexedNode() :> INode else root)
  +                    .assoc(0, hash(key), key, value, addedLeaf) 
  +
  +            if newroot = root then this else
  +            let count = if addedLeaf.Value = null then count else count + 1
  +            PersistentHashMap(count, newroot, hasNull, nullValue)
  +
  +    member this.Remove(key:'T) =
  +        if key = Unchecked.defaultof<'T> then
  +            if hasNull then PersistentHashMap(count - 1, root, false, Unchecked.defaultof<'S>) else this
  +        else 
  +            if root = Unchecked.defaultof<INode> then this else
  +            let newroot = root.without(0, hash(key), key)
  +            if newroot = root then this else
  +            PersistentHashMap(count - 1, newroot, hasNull, nullValue)
  +
  +    member this.Item 
  +        with get key = 
  +            if key = Unchecked.defaultof<'T> then 
  +                if hasNull then nullValue else failwith "Key null is not found in the map."
  +            else
  +                if root = Unchecked.defaultof<INode> then
  +                    failwithf "Key %A is not found in the map." key 
  +                else 
  +                    match root.tryFind(0, hash(key), key) with
  +                    | Some value -> value :?> 'S
  +                    | _ -> failwithf "Key %A is not found in the map." key
  +
   [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
   module PersistentHashMap = 
       ///O(1), returns an empty PersistentHashMap
  
positive.code:                     (BitmapIndexedNode(ref null, NodeHelpers.bitpos(hashCollisionKey, shift), [| null; this |]) :> INode)
                          .assoc(shift, hashKey, key, value, addedLeaf)
  
              member this.find(shift, hash, key) =
                  let idx = findIndex(key)
                  if idx < 0 then null else
                  if key = array.[idx] then array.[idx+1] else null
  
              member this.tryFind(shift, hash, key) =
                  let idx = findIndex(key)
                  if idx < 0 then None else
                  if key = array.[idx] then Some array.[idx+1] else None
  
              member this.without(shift, hashKey, key) =
                  let idx = findIndex(key)
                  if idx = -1 then this :> INode else
                  if count = 1 then Unchecked.defaultof<INode> else
                  HashCollisionNode(ref null, hashKey, count - 1, NodeHelpers.removePair(array, idx/2)) :> INode 
  
  and ArrayNode(thread,count,array:INode[]) =
      let pack(thred, idx) =
          let newArray = Array.create (2*(count - 1)) null
          let mutable j = 1
          let mutable bitmap = 0
          for i in 0 .. idx - 1 do
              if array.[i] <> Unchecked.defaultof<INode> then
                  newArray.[j] <- array.[i] :> obj
                  bitmap <- bitmap ||| (1 <<< i)
                  j <- j + 2
              
          for i in idx + 1 .. array.Length - 1 do
              if array.[i] <> Unchecked.defaultof<INode> then
                  newArray.[j] <- array.[i] :> obj
                  bitmap <- bitmap ||| (1 <<< i)
                  j <- j + 2
  
          BitmapIndexedNode(thread, bitmap, newArray)
                      
      with
          interface INode with
              member this.assoc(shift, hashKey, key, value, addedLeaf) : INode = 
                  let idx = NodeHelpers.mask(hashKey, shift)
                  let node = array.[idx]
  
negative.code:                 else
                      let n = node.assoc(shift + 5, hashKey, key, value, addedLeaf)
                      if n = node then this :> INode else
                      ArrayNode(ref null, count, NodeHelpers.cloneAndSet(array, idx, n)) :> INode
  
              member this.assoc(thread1, shift, hashKey, key, value, addedLeaf) : INode = 
                  let idx = NodeHelpers.mask(hashKey, shift)
                  let node = array.[idx]
                  if node = Unchecked.defaultof<INode> then
                      let editable = this.editAndSet(thread1, idx, (BitmapIndexedNode() :> INode).assoc(thread1, shift + 5, hashKey, key, value, addedLeaf))
                      editable.count <- editable.count + 1
                      editable :> INode                      
                  else
                      let n = node.assoc(thread1, shift + 5, hashKey, key, value, addedLeaf);
                      if n = node then this :> INode else this.editAndSet(thread1, idx, n) :> INode
  
              member this.find(shift, hash, key) =
                  let idx = NodeHelpers.mask(hash, shift)
  