private void seedTiles(StorageBroker storageBroker, TileRange tr, final WMSLayer tl)
      throws Exception {
    final String layerName = tl.getName();
    // define the meta tile size to 1,1 so we hit all the tiles
    final TileRangeIterator trIter = new TileRangeIterator(tr, tl.getMetaTilingFactors());

    long[] gridLoc = trIter.nextMetaGridLocation(new long[3]);

    while (gridLoc != null) {
      Map<String, String> fullParameters = tr.getParameters();

      final ConveyorTile tile =
          new ConveyorTile(
              storageBroker,
              layerName,
              tr.getGridSetId(),
              gridLoc,
              tr.getMimeType(),
              fullParameters,
              null,
              null);
      tile.setTileLayer(tl);

      tl.seedTile(tile, false);

      gridLoc = trIter.nextMetaGridLocation(gridLoc);
    }
  }
  private List<ConveyorTile> getTiles(StorageBroker storageBroker, TileRange tr, final WMSLayer tl)
      throws Exception {
    final String layerName = tl.getName();
    // define the meta tile size to 1,1 so we hit all the tiles
    final TileRangeIterator trIter = new TileRangeIterator(tr, new int[] {1, 1});

    long[] gridLoc = trIter.nextMetaGridLocation(new long[3]);

    // six concurrent requests max
    ExecutorService requests = Executors.newFixedThreadPool(6);
    ExecutorCompletionService completer = new ExecutorCompletionService(requests);

    List<Future<ConveyorTile>> futures = new ArrayList<Future<ConveyorTile>>();
    while (gridLoc != null) {
      Map<String, String> fullParameters = tr.getParameters();

      final ConveyorTile tile =
          new ConveyorTile(
              storageBroker,
              layerName,
              tr.getGridSetId(),
              gridLoc,
              tr.getMimeType(),
              fullParameters,
              null,
              null);
      futures.add(
          completer.submit(
              new Callable<ConveyorTile>() {

                public ConveyorTile call() throws Exception {
                  try {
                    return tl.getTile(tile);
                  } catch (OutsideCoverageException oce) {
                    return null;
                  }
                }
              }));

      gridLoc = trIter.nextMetaGridLocation(gridLoc);
    }

    // these assertions could be externalized
    List<ConveyorTile> results = new ArrayList<ConveyorTile>();
    for (int i = 0; i < futures.size(); i++) {
      ConveyorTile get = futures.get(i).get();
      if (get != null) {
        results.add(get);
      }
    }

    requests.shutdown();

    return results;
  }