public void changeWorkingSet(WorkingSet<String> newSet) {
    // cancel any pending jobs so that we don't waste time loading images no longer needed
    loaderPool.clearJobs();

    if (DEBUG) {
      System.out.println("RamTextureCache: changeWorkingSet:");
      for (String imageId : newSet.getPrioritizedList())
        System.out.printf("\t%s (pri %d)\n", imageId, newSet.getPriority(imageId));
    }

    synchronized (cache) // because of race with imageLoaded()
    {
      // adjust priorities of already cached items.
      // (No longer needed items get super low priority)
      cache.updatePriority(newSet);

      // switch working sets
      curSet = newSet;

      // Start loading those which we are missing
      for (String imageId : newSet.getPrioritizedList()) {
        if (!cache.contains(imageId)) {
          if (DEBUG) System.out.printf("RamTextureCache: not cached: %s\n", imageId);
          loaderPool.addJob(imageId);
        }
      }
    }
  }
  /**
   * Get the GLImage associated with the specified image-id. If the image is cached in memory this
   * call will be very fast, otherwise it will be loaded from disk and saved to cache.
   *
   * @return null if the specified image is not in the current working set
   */
  public GLImage getGLImage(String imageId) {
    synchronized (cache) {
      GLImage img = cache.get(imageId);
      if (img == null && curSet.contains(imageId)) {
        // elevate the urgency of this image
        if (DEBUG) System.out.printf("RamTextureCache: requesting immediate load of %s\n", imageId);
        urgentImageIds.add(imageId);
        loaderPool.makeTopPriority(imageId);

        long startTime = System.currentTimeMillis();

        // wait for image to arrive
        while (curSet.contains(imageId) && !cache.contains(imageId)) {
          try {
            cache.wait(10000);

            img = cache.get(imageId);

            // timed out?
            if (img == null && (System.currentTimeMillis() - startTime) >= 10000) {
              System.err.println("RamTextureCache: timed out waiting for " + imageId);
              break;
            }
          } catch (InterruptedException e) {
            // ignore
          }
        }

        urgentImageIds.remove(imageId);

        // use fallback image
        if (img == null) img = GLImage.createNullImage();
      } else if (DEBUG && img == null)
        System.out.printf("RamTextureCache: %s not in working set\n", imageId);

      return img;
    }
  }