public synchronized <U extends T> U put(U obj) {
        if (obj == null) {
            return null;
        }

        Entry<T>[] entries = mEntries;
        int hash = hashCode(obj);
        int index = (hash & 0x7fffffff) % entries.length;
        for (Entry<T> e = entries[index], prev = null; e != null; e = e.mNext) {
            T iobj = e.get();
            if (iobj == null) {
                // Clean up after a cleared Reference.
                if (prev == null) {
                    entries[index] = e.mNext;
                } else {
                    prev.mNext = e.mNext;
                }
                mSize--;
            } else if (e.mHash == hash && obj.getClass() == iobj.getClass() && equals(obj, iobj)) {
                // Found canonical instance.
                return (U) iobj;
            } else {
                prev = e;
            }
        }

        if (mSize >= mThreshold) {
            cleanup();
            if (mSize >= mThreshold) {
                rehash();
                entries = mEntries;
                index = (hash & 0x7fffffff) % entries.length;
            }
        }

        entries[index] = new Entry<T>(this, obj, hash, entries[index]);
        mSize++;
        return obj;
    }