anchor.diff:                      (BitmapIndexedNode(ref null, NodeHelpers.bitpos(hashCollisionKey, shift), [| null; this |]) :> INode)
                           .assoc(shift, hashKey, key, value, addedLeaf)
   
  +            member this.assoc(thread1, shift, hashKey, key, value, addedLeaf) : INode = 
  +                if hashCollisionKey = hashKey then
  +                    let idx = this.findIndex(key)
  +                    if idx <> -1 then
  +                        if array.[idx + 1] = value then this :> INode else this.editAndSet(thread1, idx+1, value) :> INode
  +                    else
  +                        if array.Length > 2*count then
  +                            addedLeaf.Value <- addedLeaf :> obj
  +                            let editable = this.editAndSet(thread1, 2*count, key, 2*count+1, value)
  +                            editable.count <- editable.count + 1
  +                            editable :> INode
  +                        else
  +                            let newArray = Array.create (array.Length + 2) null
  +                            System.Array.Copy(array, 0, newArray, 0, array.Length)
  +                            newArray.[array.Length] <- key
  +                            newArray.[array.Length + 1] <- value
  +                            addedLeaf.Value <- addedLeaf :> obj
  +                            this.ensureEditable(thread1, count + 1, newArray) :> INode
  +                else
  +                    // nest it in a bitmap node
  +                    (BitmapIndexedNode(thread1, NodeHelpers.bitpos(hashCollisionKey, shift), [| null; this; null; null |]) :> INode)
  +                        .assoc(thread1, shift, hashKey, key, value, addedLeaf);
  +
               member this.find(shift, hash, key) =
  -                let idx = findIndex(key)
  +                let idx = this.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)
  +                let idx = this.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)
  +                let idx = this.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)
  +                HashCollisionNode(ref null, hashKey, count - 1, NodeHelpers.removePair(array, idx/2)) :> INode
  +
  +            member this.without(thread, shift, hashKey, key, removedLeaf) =
  +                let idx = this.findIndex(key)
  +                if idx = -1 then this :> INode else
  +                removedLeaf.Value <- removedLeaf :> obj
  +                if count = 1 then Unchecked.defaultof<INode> else
  +                let editable = this.ensureEditable(thread)
  +                editable.array.[idx] <- editable.array.[2*count-2]
  +                editable.array.[idx+1] <- editable.array.[2*count-1]
  +                editable.array.[2*count-2] <- null
  +                editable.array.[2*count-1] <- null;
  +                editable.count <- editable.count - 1
  +                editable :> INode
  +
  +and private ArrayNode(thread,count,array:INode[]) =
  +    member val array = array with get, set
  +    member val count = count with get, set
                       
       with
  +
  +        member this.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)
  +
  +        member this.ensureEditable(thread1) =
  +            if !thread = !thread then this else
  +            ArrayNode(thread1, count, Array.copy array) 
  +
  +
  +        member this.editAndSet(thread1, i, n) =
  +            let editable = this.ensureEditable(thread1)
  +            editable.array.[i] <- n
  +            editable
  +
           interface INode with
  +
  +            member this.SetThread t = thread := t
  +
               member this.assoc(shift, hashKey, key, value, addedLeaf) : INode = 
                   let idx = NodeHelpers.mask(hashKey, shift)
                   let node = array.[idx]
  
positive.code:         System.Array.Copy(array, 2*(i+1), newArray, 2*i, newArray.Length - 2*i)
          newArray
  
      static member createNode( shift, key1, val1, key2hash, key2, val2) =
          let key1hash = hash(key1)
  
          if key1hash = key2hash then HashCollisionNode(ref null, key1hash, 2, [|key1; val1; key2; val2|]) :> INode else 
          
          let addedLeaf = Box(null)
          let edit = ref null
          (BitmapIndexedNode() :> INode)
              .assoc(shift, key1hash, key1, val1, addedLeaf) // edit
              .assoc(shift, key2hash, key2, val2, addedLeaf) // edit
  
  and HashCollisionNode(thread,hashCollisionKey,count,array:obj[]) =
      let findIndex key =
          let i = ref 0
          while (!i < 2*count) && (key <> array.[!i]) do
              i := !i + 2
          if !i < 2*count then !i else -1
          
      with
      
          interface INode with
              member this.assoc(shift, hashKey, key, value, addedLeaf) : INode = 
                  if hashKey = hashCollisionKey then
                      let idx = findIndex(key)
                      if idx <> -1 then
                          if array.[idx + 1] = value then this :> INode else
                          HashCollisionNode(ref null, hashKey, count, NodeHelpers.cloneAndSet(array, idx + 1, value)) :> INode
  
negative.code:                         System.Array.Copy(array, 2*idx, newArray, 2*(idx+1), 2*(n-idx))
                          BitmapIndexedNode(ref null, bitmap ||| bit, newArray) :> INode
  
  
              member this.assoc(thread1, shift, hashKey, key, value, addedLeaf) = 
                  let bit = NodeHelpers.bitpos(hashKey, shift)
                  let idx = NodeHelpers.index(bitmap,bit)
                  if (bitmap &&& bit) <> 0 then
                      let keyOrNull = array.[2*idx]
                      let valOrNode = array.[2*idx+1]
                      if keyOrNull = null then
                          let n = (valOrNode :?> INode).assoc(thread1, shift + 5, hashKey, key, value, addedLeaf)
                          if n = (valOrNode :?> INode) then this :> INode else this.editAndSet(thread1, 2*idx+1, n) :> INode
                      else
                          if key = keyOrNull then
                              if value = valOrNode then this :> INode else this.editAndSet(thread1, 2*idx+1, value) :> INode
                          else
                              addedLeaf.Value <- addedLeaf :> obj
                              this.editAndSet(thread1, 2*idx, null, 2*idx+1, 
                                              NodeHelpers.createNode(thread1, shift + 5, keyOrNull, valOrNode, hashKey, key, value)) :> INode
                  else
                      let n = NodeHelpers.NumberOfSetBits(bitmap)
                      if n*2 < array.Length then
                          addedLeaf.Value <- addedLeaf :> obj
                          let editable = this.ensureEditable(thread1)
                          System.Array.Copy(editable.array, 2*idx, editable.array, 2*(idx+1), 2*(n-idx))
                          editable.array.[2*idx] <- key
                          editable.array.[2*idx+1] <- value
                          editable.bitmap <- editable.bitmap ||| bit
                          editable :> INode
                      else
                          if n >= 16 then
                              let nodes = Array.create 32 Unchecked.defaultof<INode>
                              let jdx = NodeHelpers.mask(hashKey, shift)
                              nodes.[jdx] <- (BitmapIndexedNode() :> INode).assoc(thread1, shift + 5, hashKey, key, value, addedLeaf)
                              let mutable j = 0
                              for i in 0..31 do
                                  if ((bitmap >>> i) &&& 1) <> 0 then
                                      if array.[j] = null then
                                          nodes.[i] <- array.[j+1] :?> INode
                                      else
                                          nodes.[i] <- (BitmapIndexedNode() :> INode).assoc(thread1, shift + 5, hash(array.[j]), array.[j], array.[j+1], addedLeaf)
                                      j <- j + 2;
                                   
                              ArrayNode(thread1, n + 1, nodes) :> INode
                          else
                              let newArray = Array.create (2*(n+4)) null
                              System.Array.Copy(array, 0, newArray, 0, 2*idx)
                              newArray.[2*idx] <- key
                              addedLeaf.Value <- addedLeaf :> obj
                              newArray.[2*idx+1] <- value
                              System.Array.Copy(array, 2*idx, newArray, 2*(idx+1), 2*(n-idx))
                              let editable = this.ensureEditable(thread1)
                              editable.array <- newArray
                              editable.bitmap <- bitmap ||| bit
                              editable :> INode
                          
  
              member this.without(shift, hashKey, key) =
                  let bit = NodeHelpers.bitpos(hashKey, shift)
                  if (bitmap &&& bit) = 0 then this :> INode else
  