private Rectangle getPrefetchingRegion(
      Rectangle loadedTilesBounds, BufferedVirtualSlideImage image, int resIndex) {
    Dimension tileSize = image.getTileSize(resIndex);
    Dimension tilePrefetchingRadius = getPrefetchingRadiusInTiles(tileSize);

    int tileColumns =
        (int) Math.ceil(image.getImageSize(resIndex).getWidth() / tileSize.getWidth());
    int tileRows = (int) Math.ceil(image.getImageSize(resIndex).getHeight() / tileSize.getHeight());

    int x1 = (int) Math.max(loadedTilesBounds.getX() - tilePrefetchingRadius.getWidth(), 0);
    int y1 = (int) Math.max(loadedTilesBounds.getY() - tilePrefetchingRadius.getHeight(), 0);
    int x2 =
        (int) Math.min(loadedTilesBounds.getMaxX() + tilePrefetchingRadius.getWidth(), tileColumns);
    int y2 =
        (int) Math.min(loadedTilesBounds.getMaxY() + tilePrefetchingRadius.getHeight(), tileRows);

    return new Rectangle(x1, y1, x2 - x1, y2 - y1);
  }
  @Override
  public List<Tile> getTilesToPrefetch(
      BufferedVirtualSlideImage image, Rectangle loadedImagePart, ImageIndex imageIndex) {
    Rectangle loadedTiles =
        getLoadedTilesBounds(loadedImagePart, image.getTileSize(imageIndex.getResolutionIndex()));
    Rectangle prefetchingRegion =
        getPrefetchingRegion(loadedTiles, image, imageIndex.getResolutionIndex());

    List<Tile> tilesToPrefetch = new ArrayList<Tile>();

    for (int y = prefetchingRegion.y; y < prefetchingRegion.getMaxY(); y++) {
      for (int x = prefetchingRegion.x; x < prefetchingRegion.getMaxX(); x++) {
        if (!loadedTiles.contains(x, y)) {
          tilesToPrefetch.add(new Tile(x, y, imageIndex));
        }
      }
    }

    return tilesToPrefetch;
  }