public ChunkCache getCacheOfBlock( Block block ) throws RefuseToPreventThrashingException {
        String chunkId = MakeChunkId(block.getChunk());
        ChunkCache cache = cachesByChunkId.get(chunkId);

        if( cache != null ){
            cachesByTime.remove(cache);
            cache.Access();
            cachesByTime.add(cache);
            ++counterCacheHits;
        }else{
            long removeCount = Math.max(5, cachesByTime.size() - maxChunks + 1);
            ChunkCache last = cachesByTime.peek();
            while (last != null && removeCount > 0 && last.getLastAccessed() + maxAge < System.currentTimeMillis()) {
                cachesByChunkId.remove(last.getChunkId());
                cachesByTime.poll();
                last.flush();
                last = cachesByTime.peek();
                --removeCount;
                ++counterChunkTimeouts;
            }
            if( cachesByTime.size() > maxChunks ){
                // WARNING: This WILL cause NaturalReinforcements to NOT be saved and thus lost.
                // TODO: Figure out why this needed to be added
                ++counterPreventedThrashing;
                throw new RefuseToPreventThrashingException();
            }
            ++counterChunkCacheLoads;
            cache = new ChunkCache( this, block.getChunk() );
            cachesByChunkId.put( cache.getChunkId(), cache );
            cachesByTime.add( cache );
        }
        return cache;
    }