private Place[] placesPath(
    final Place init, final Place dest, boolean reports
  ) {
    if (printSearch) I.say("Searching from "+init.core+" to "+dest.core) ;
    
    final Search <Place> search = new Search <Place> (init, -1) {
      
      protected Place[] adjacent(Place spot) {
        //
        //  TODO:  Apparently, the nearCache was the problem.  It was causing
        //  dead places to stay in circulation within the agenda following
        //  their obsolescence.
        //if (spot.nearCache != null) return spot.nearCache ;
        refreshWithNeighbours(spot.caching.section) ;
        final Place near[] = spot.nearCache = new Place[spot.routes.size()] ;
        int i = 0 ; for (Route route : spot.routes) {
          near[i++] = (route.from == spot) ? route.to : route.from ;
        }
        return near ;
      }
      
      protected float cost(Place prior, Place spot) {
        for (Route r : prior.routes) {
          if (r.from == spot || r.to == spot) return r.cost ;
          ///if (r.from == spot && r.to == prior) return r.cost ;
          ///if (r.to == spot && r.from == prior) return r.cost ;
        }
        return -1 ;
      }
      
      protected boolean endSearch(Place best) {
        return best == dest ;
      }
      
      protected float estimate(Place spot) {
        return Spacing.distance(spot.core, dest.core) ;
      }
      
      protected void setEntry(Place spot, Entry flag) {
        spot.flagged = flag ;
      }
      
      protected Entry entryFor(Place spot) {
        return (Entry) spot.flagged ;
      }
    } ;
    search.verbose = reports ;
    search.doSearch() ;
    if (! search.success()) return null ;
    return search.fullPath(Place.class) ;
  }