 
   size: 1
 
-  get:  (shift, hash, key) -> true if areEqual(key, @key)
+  get:  (shift, hash, key) -> true if equalKeys(key, @key)
 
   plus: (shift, hash, leaf) ->
     if hash == @hash

  minus: (shift, hash, key) ->
    switch @bucket.length
      when 0, 1 then null
      when 2    then Sequence.find @bucket, (v) -> not areEqual(v.key, key)
      else           new CollisionNode(hash, this.bucketWithout(key))

  toString: -> "#{@bucket.join("|")}"

  bucketWithout: (key) ->
    item for item in @bucket when not areEqual(item.key, key)


# --------------------------------------------------------------------

    catch ex
      hashCode Object::toString.call(obj)

equalKeys = (obj1, obj2) ->
  if typeof(obj1) == 'string' or typeof(obj2) == 'string'
    obj1 == obj2
  else if Sequence.accepts(obj1) and Sequence.accepts(obj2)
    not Sequence.find(Sequence.combine(obj1, obj2, equalKeys), (a) -> not a)?
  else if obj1? and typeof(obj1.equals) == "function"
    obj1.equals(obj2)
  else if obj2? and typeof(obj2.equals) == "function"
    obj2.equals(obj1)
  else
    obj1 == obj2

