ce.constructionEstimate = cost + getFixedConstructionCosts();
ce.constructionEstimate = cost + fixedConstructionCosts;
    private void doDetailedCostEstimation(CityEntry ce) {	ArrayList sites1 = new ArrayList();	ArrayList sites2 = new ArrayList();	if (ce.station1 >= 0) {	    StationModel sm = (StationModel) aiClient.getWorld().get		(KEY.STATIONS, ce.station1, aiClient.getPlayerPrincipal());	    ce.site1 = new Point(sm.getStationX(), sm.getStationY());	    sites1.add(ce.site1);	} else {	    setupStationSites(ce.city1, sites1);	}	if (ce.station2 >= 0) {	    StationModel sm = (StationModel) aiClient.getWorld().get		(KEY.STATIONS, ce.station2, aiClient.getPlayerPrincipal());	    ce.site2 = new Point(sm.getStationX(), sm.getStationY());	    sites2.add(ce.site2);	} else {	    setupStationSites(ce.city2, sites2);	}	/* choose the best combination of locations */	SupplyDemandViewer sdv = new SupplyDemandViewer(aiClient.getWorld());	CargoInfo ci = new CargoInfo();	ArrayList siteList = new ArrayList();	for (int i = 0; i < sites1.size(); i++) {	    for (int j = 0; j < sites2.size(); j++) {		Point p1 = (Point) sites1.get(i);		Point p2 = (Point) sites2.get(j);		sdv.setStationNotBuilt(sites1.size() != 1);		sdv.setLocation(p1.x, p1.y, LARGE_STATION_RADIUS);		SupplyAtStation s1 = sdv.getSupply();		DemandAtStation d1 = sdv.getDemand();		ConvertedAtStation c1 = sdv.getConversion();		sdv.setStationNotBuilt(sites2.size() != 1);		sdv.setLocation(p2.x, p2.y, LARGE_STATION_RADIUS);		SupplyAtStation s2 = sdv.getSupply();		DemandAtStation d2 = sdv.getDemand();		ConvertedAtStation c2 = sdv.getConversion();		cargoInfoFromCargoData(s1, s2, d1, d2, c1, c2, ce.distance,			REFERENCE_ENGINE_TYPE_MAX_SPEED, ci, ce);		CargoData cd = new CargoData(p1, p2, ci.annualRevenue);		siteList.add(cd);	    }	}	/* sort by ascending order of revenue */	Collections.sort(siteList);	CargoData cd;	/* attempt to plan a route between the top 10 routes */	ArrayList tmp = new ArrayList();	int sz = siteList.size();	for (int i = sz - 1; i >= sz - 10 && i >= 0; i--)	    tmp.add(siteList.remove(i));		siteList = tmp;	int nStations = siteList.size();	int currentN = 0;	while (!siteList.isEmpty()) {	    currentN++;		logger.log(Level.FINE, "examining " + currentN			+ " of " + nStations + " routes");	    cd = (CargoData) siteList.remove(siteList.size() - 1);	    RouteBuilderPathExplorerSettings s = new		RouteBuilderPathExplorerSettings(aiClient.getWorld(),			WorldConstants.get().TR_STANDARD_TRACK,			aiClient.getPlayerPrincipal(),			REFERENCE_ENGINE_TYPE_INDEX, STANDARD_LOAD);	    PathExplorer pe = new		RouteBuilderPathExplorer(aiClient.getWorld(), cd.p1.x,			cd.p1.y, CompassPoints.NORTH, s);	    PathFinder pf = new PathFinder(pe, cd.p2.x, cd.p2.y, 0,		    (int) ((cashAvailable + COMFORT_ZONE) / 100));	    LinkedList results = pf.explore();	    if (results == null) {		// no route to this destination		cd = null;		continue;	    }	    // we found a route, how much ?	    Iterator i = results.listIterator(0);	    long cost = 0;	    while (i.hasNext()) {		pe = (PathExplorer) i.next();		cost += pe.getCost();	    }	    // Costs in PathExplorers is in 100$ units	    cost *= 100;	    ce.detailedEstimate = true;	    ce.constructionEstimate = cost + getFixedConstructionCosts();	    ce.annualRevenueEstimate = cd.returnTripRevenue;	    ce.plannedRoute = results;	    /* TODO Recalculate annual maintenance and operating expense on	     * track */	    logger.log(Level.INFO, "The best route between for " + ce +		    " was found");	    return;	}    }