public void cleanCleared() {
    WKey wk;
    while ((wk = (WKey) keyQ.poll()) != null) inner.remove(wk);

    WVal wv;
    while ((wv = (WVal) valQ.poll()) != null) inner.remove(wv.getWKey());
  }
 public boolean containsValue(Object val) {
   for (Iterator ii = inner.values().iterator(); ii.hasNext(); ) {
     WVal wval = (WVal) ii.next();
     if (val.equals(wval.get())) return true;
   }
   return false;
 }
 public Object remove(Object key) {
   try {
     cleanCleared();
     WVal wv = (WVal) inner.remove(holder.set(key));
     return (wv == null ? null : wv.get());
   } finally {
     holder.clear();
   }
 }
 public Object get(Object key) {
   try {
     cleanCleared();
     WVal wval = (WVal) inner.get(holder.set(key));
     return (wval == null ? null : wval.get());
   } finally {
     holder.clear();
   }
 }
 private boolean retainValues(Collection c) {
   boolean out = false;
   for (Iterator ii = inner.values().iterator(); ii.hasNext(); ) {
     WVal wv = (WVal) ii.next();
     if (!c.contains(wv.get())) {
       ii.remove();
       out = true;
     }
   }
   return out;
 }
 private boolean removeValue(Object val) {
   boolean out = false;
   for (Iterator ii = inner.values().iterator(); ii.hasNext(); ) {
     WVal wv = (WVal) ii.next();
     if (val.equals(wv.get())) {
       ii.remove();
       out = true;
     }
   }
   return out;
 }
 public Object put(Object key, Object val) {
   cleanCleared();
   WVal wout = doPut(key, val);
   if (wout != null) return wout.get();
   else return null;
 }