/**
   * Associate the given object with the given key in this <tt>IdentityWeakHashMap</tt>, replacing
   * any existing mapping.
   *
   * @param key key to map to given object.
   * @param obj object to be associated with key.
   * @return the previous object for key or <tt>null</tt> if this <tt>IdentityWeakHashMap</tt> did
   *     not have one.
   * @throws <tt>NullPointerException</tt> if obj is null</tt>.
   */
  public V put(K key, V obj) {
    if (obj == null || key == null) {
      throw new IllegalArgumentException(
          ExceptionLocalization.buildMessage("null_not_supported_identityweakhashmap"));
    }
    cleanUp();
    WeakEntry[] copyOfEntries = entries;
    int hash = System.identityHashCode(key);
    int index = (hash & 0x7FFFFFFF) % copyOfEntries.length;
    for (WeakEntry e = copyOfEntries[index]; e != null; e = e.next) {
      if (e.key.get() == key) {
        EntryReference<V> old = e.value;
        if (key == obj) {
          e.value = e.key;
        } else {
          e.value = new HardEntryReference<V>(obj);
        }
        return old.get();
      }
    }

    modCount++;
    if (count >= threshold) {
      rehash();
      copyOfEntries = entries;
      index = (hash & 0x7FFFFFFF) % copyOfEntries.length;
    }
    WeakEntry<K, V> e = new WeakEntry<K, V>(hash, key, obj, copyOfEntries[index], referenceQueue);
    copyOfEntries[index] = e;
    count++;
    return null;
  }
  protected boolean removeEntry(WeakEntry o, boolean userModification) {

    WeakEntry[] copyOfEntries = entries;
    int index = (o.hash & 0x7FFFFFFF) % copyOfEntries.length;
    for (WeakEntry e = copyOfEntries[index], prev = null; e != null; prev = e, e = e.next) {
      if (e == o) {
        // if this method was called as a result of a user action,
        // increment the modification count
        // this method is also called by our cleanup code and
        // that code should not cause a concurrent modification
        // exception
        if (userModification) {
          modCount++;
        }
        if (prev != null) {
          prev.next = e.next;
        } else {
          copyOfEntries[index] = e.next;
        }
        count--;
        e.value = null;
        e.next = null;
        return true;
      }
    }
    return false;
  }