int i = 0;
    public synchronized static Route getBestRoute(Intersection from,                                                  Intersection to,                                                  float bestConvoySpeed,                                                  float worstConvoySpeed) {        Hashtable marks = new Hashtable();        boolean haveRoute = false;        float toLat;        float toLon;        LatLonPoint toLoc = to.getLocation();        toLat = toLoc.getLatitude();        toLon = toLoc.getLongitude();        LatLonPoint fromLoc = from.getLocation();        float fromLat = fromLoc.getLatitude();        float fromLon = fromLoc.getLongitude();        float timeLimitBase = GreatCircle.spherical_distance(toLat,                toLon,                fromLat,                fromLon)                / worstConvoySpeed;        float bestTime = Float.MAX_VALUE;        for (float snakeFactor = 1.0f; snakeFactor < 40f; snakeFactor *= 2f) {            //	  if (logger.isLoggable(Level.INFO))            //	    logger.info ("Snake factor " + snakeFactor);            float timeLimit = timeLimitBase * snakeFactor;            Vector toDo = new Vector();            toDo.addElement(from);            marks.clear();            marks.put(from, new NodeInfo(from, null, 0.0f, 0.0f));            while (toDo.size() > 0) {                Vector newToDo = new Vector();                for (Enumeration e = toDo.elements(); e.hasMoreElements();) {                    Intersection thisIntersection = (Intersection) e.nextElement();                    NodeInfo thisInfo = (NodeInfo) marks.get(thisIntersection);                    //  System.out.println ("examining " +                    // thisIntersection);                    for (Enumeration e2 = thisIntersection.getRoads(); e2.hasMoreElements();) {                        Road road = (Road) e2.nextElement();                        //			System.out.println (" - road " + road);                        float roadTime = road.getTraverseHours();                        float newTime = thisInfo.time + roadTime;                        if (newTime > timeLimit)                            continue;                        Intersection nextIntersection = road.getOtherIntersection(thisIntersection);                        //			System.out.println (" - next inter " +                        // nextIntersection);                        NodeInfo nextInfo = (NodeInfo) marks.get(nextIntersection);                        if (nextInfo == null) {                            LatLonPoint nextLoc = nextIntersection.getLocation();                            float crowsPathDistance = GreatCircle.spherical_distance(toLat,                                    toLon,                                    nextLoc.getLatitude(),                                    nextLoc.getLongitude());                            float crowsPathHours = crowsPathDistance                                    / bestConvoySpeed;                            nextInfo = new NodeInfo(nextIntersection, road, newTime, crowsPathHours);                            marks.put(nextIntersection, nextInfo);                            if (newTime + nextInfo.crowsPathHours > bestTime)                                continue;                            newToDo.addElement(nextIntersection);                            //    System.out.println (" - best road for "                            // + nextIntersection + " is " + road);                        } else if (nextInfo.time > newTime) {                            if (!nextInfo.intersection.equals(nextIntersection)) {                                System.err.println("huh?  lookup of "                                        + nextIntersection                                        + " gets node info with inter "                                        + nextInfo.intersection);                            }                            nextInfo.time = newTime;                            nextInfo.bestRoad = road;                            //System.out.println (" - (redo) best                            // road for " + nextIntersection + " is "                            // + road);                            if (newTime + nextInfo.crowsPathHours > bestTime)                                continue;                            newToDo.addElement(nextIntersection);                        } else {                            continue;                        }                        if (nextIntersection == to) {                            //System.err.println ("found end " + to);                            bestTime = nextInfo.time;                            haveRoute = true;                        }                    }                }                toDo = newToDo;            }            if (haveRoute)                break;        }        Vector roadVector = new Vector();        Route result = null;        if (haveRoute) {            int i = 0;            for (NodeInfo info = (NodeInfo) marks.get(to); result == null;) {                roadVector.addElement(info.bestRoad);                // System.err.println ("adding Road #" + (i++) + " - "                // + info.bestRoad);                Intersection prevIntersection = info.bestRoad.getOtherIntersection(info.intersection);                if (prevIntersection == from)                    result = new Route(roadVector, info.bestRoad.getFirstIntersection() == prevIntersection);                else                    info = (NodeInfo) marks.get(prevIntersection);            }        }        marks = null;        return result;    }