class KeysDownloader {

  public String download() throws IOException {
    synchronized (instanceStateLock) {
      // Checking and using the cache if required.
      if (hasNonExpiredDataCached()) {
        // Proactively triggering a refresh if we are close to the cache expiration.
        if (shouldProactivelyRefreshDataInBackground()) {
          refreshInBackground();
        }
        return cachedData;
      }
    }

    // Acquiring the fetch lock so we don't have multiple threads trying to fetch from the
    // server at the same time.
    synchronized (fetchDataLock) {
      // It is possible that some other thread performed the fetch already and we don't need
      // to fetch anymore, so double checking a fetch is still required.
      synchronized (instanceStateLock) {
        if (hasNonExpiredDataCached()) {
          return cachedData;
        }
      }
      // No other thread fetched, so it is up to this thread to fetch.
      return fetchAndCacheData();
    }
  }

  public  KeysDownloader(Executor backgroundExecutor, HttpTransport httpTransport, String url);

}