code: public Object remove(Object key)
      {
          synchronized (_cacheL2)
          {
              if (!_cacheL1.containsKey(key) && !_cacheL2.containsKey(key))
              {
                  // nothing to remove
                  return null;
              }
  
              Object retval;
              Map newMap;
              synchronized (_cacheL1)
              {
                  // "dummy" synchronization to guarantee _cacheL1 will be assigned after fully initialized
                  // at least until JVM 1.5 where this should be guaranteed by the volatile keyword
                  newMap = HashMapUtils.merge(_cacheL1, _cacheL2);
                  retval = newMap.remove(key);
              }
  
              _cacheL1 = newMap;
              _cacheL2.clear();
              _missCount = 0;
              return retval;
          }
      }
docs: This operation is very expensive. A full copy of the Map is created