private Place[] grabPlacesFor(Caching caching, final Section section) {
    ///I.say("Grabbing new places at: "+section.area) ;
    //
    //  We scan through every tile in this section, and grab any contiguous
    //  areas of unblocked tiles.  (These must be flagged just after
    //  acquisition, so that we know to skip over them.)
    final Batch <Tile[]> allUnder = new Batch <Tile[]> () ;
    for (Coord c : Visit.grid(section.area)) {
      final Tile t = world.tileAt(c.x, c.y) ;
      if (t.flaggedWith() != null || t.blocked()) continue ;
      final TileSpread spread = new TileSpread(t) {
        protected boolean canAccess(Tile t) {
          return section.area.contains(t.x, t.y) && ! t.blocked() ;
        }
        protected boolean canPlaceAt(Tile t) { return false ; }
      } ;
      spread.doSearch() ;
      final Tile under[] = spread.allSearched(Tile.class) ;
      for (Tile u : under) u.flagWith(allUnder) ;
      allUnder.add(under) ;
    }
    //
    //  Having obtained each block of tiles, we create corresponding Place
    //  objects, and assign them a core-
    final Place places[] = new Place[allUnder.size()] ;
    int i = 0 ; for (Tile[] under : allUnder) {
      final Place place = places[i++] = new Place() ;
      place.under = under ;
      place.core = findCore(under) ;
      place.caching = caching ;
      if (verbose) I.say(under.length+" tiles grabbed...") ;
      for (Tile u : under) {
        tilePlaces[u.x][u.y] = place ;
        u.flagWith(null) ;
      }
    }
    return places ;
  }