/// <summary>
 /// stores the bitmap data on disk with filename key
 /// </summary>
 /// <param name="key">
 ///            filename </param>
 /// <param name="bitmap">
 ///            tile image </param>
 private void StoreData(Job key, ITileBitmap bitmap)
 {
     try
     {
         IFile file = GetOutputFile(key);
         if (file == null)
         {
             // if the file cannot be written, silently return
             return;
         }
         using (System.IO.Stream outputStream = file.OpenAsync(FileAccess.ReadAndWrite).Result)
         {
             bitmap.Compress(outputStream);
             try
             {
                 //@lock.writeLock().@lock();
                 if (this.lruCache.Add(key.Key, file) != null)
                 {
                     LOGGER.Warn("overwriting cached entry: " + key.Key);
                 }
             }
             finally
             {
                 //@lock.writeLock().unlock();
             }
         }
     }
     catch (Exception e)
     {
         // we are catching now any exception and then disable the file cache
         // this should ensure that no exception in the storage thread will
         // ever crash the main app. If there is a runtime exception, the thread
         // will exit (via destroy).
         LOGGER.Fatal("Disabling filesystem cache", e);
         // most likely cause is that the disk is full, just disable the
         // cache otherwise
         // more and more exceptions will be thrown.
         this.Destroy();
         try
         {
             //@lock.writeLock().@lock();
             this.lruCache = new FileWorkingSetCache <string>(0);
         }
         finally
         {
             //@lock.writeLock().unlock();
         }
     }
 }
 /// <summary>
 /// Creates a new FileSystemTileCache.
 /// <para>
 /// Use the {@code persistent} argument to specify whether cache contents should be kept across instances. A
 /// persistent cache will serve any tiles it finds in {@code cacheDirectory}. Calling <seealso cref="#destroy()"/> on a
 /// persistent cache will not delete the cache directory. Conversely, a non-persistent cache will serve only tiles
 /// added to it via the <seealso cref="#put(Job, TileBitmap)"/> method, and calling <seealso cref="#destroy()"/> on a non-persistent
 /// cache will delete {@code cacheDirectory}.
 ///
 /// </para>
 /// </summary>
 /// <param name="capacity">
 ///            the maximum number of entries in this cache. </param>
 /// <param name="cacheDirectory">
 ///            the directory where cached tiles will be stored. </param>
 /// <param name="graphicFactory">
 ///            the graphicFactory implementation to use. </param>
 /// <param name="persistent">
 ///            if cache data will be kept between instances </param>
 /// <exception cref="IllegalArgumentException">
 ///             if the capacity is negative. </exception>
 /// <exception cref="IllegalArgumentException">
 ///             if the capacity is negative. </exception>
 public FileSystemTileCache(int capacity, IFolder cacheDirectory, IGraphicFactory graphicFactory, bool persistent)
 {
     this.observable = new Observable();
     this.persistent = persistent;
     this.lruCache   = new FileWorkingSetCache <string>(capacity);
     //this.@lock = new ReentrantReadWriteLock();
     if (IsValidCacheDirectory(cacheDirectory))
     {
         this.cacheDirectory = cacheDirectory;
         if (this.persistent)
         {
             // this will start a new thread to read in the cache directory.
             // there is the potential that files will be recreated because they
             // are not yet in the cache, but this will not cause any corruption.
             Task.Run(() => (new CacheDirectoryReader(this)).Run());
         }
     }
     else
     {
         this.cacheDirectory = null;
     }
     this.graphicFactory = graphicFactory;
 }