public void testTransfers() throws Exception {
    TransferTable transferTable = graph.getTransferTable();

    // create dummy routes and trips
    Route fromRoute = new Route();
    fromRoute.setId(new AgencyAndId("agency", "1"));
    Trip fromTrip = new Trip();
    fromTrip.setId(new AgencyAndId("agency", "1.1"));
    fromTrip.setRoute(fromRoute);
    Route toRoute = new Route();
    toRoute.setId(new AgencyAndId("agency", "2"));
    Trip toTrip = new Trip();
    toTrip.setId(new AgencyAndId("agency", "2.1"));
    toTrip.setRoute(toRoute);
    Trip toTrip2 = new Trip();
    toTrip2.setId(new AgencyAndId("agency", "2.2"));
    toTrip2.setRoute(toRoute);

    // find stops
    Stop stopK = ((TransitStopArrive) graph.getVertex("agency_K_arrive")).getStop();
    Stop stopN = ((TransitStopDepart) graph.getVertex("agency_N_depart")).getStop();
    Stop stopM = ((TransitStopDepart) graph.getVertex("agency_M_depart")).getStop();

    assertTrue(transferTable.hasPreferredTransfers());
    assertEquals(
        StopTransfer.UNKNOWN_TRANSFER,
        transferTable.getTransferTime(stopN, stopM, fromTrip, toTrip));
    assertEquals(
        StopTransfer.FORBIDDEN_TRANSFER,
        transferTable.getTransferTime(stopK, stopM, fromTrip, toTrip));
    assertEquals(
        StopTransfer.PREFERRED_TRANSFER,
        transferTable.getTransferTime(stopN, stopK, toTrip, toTrip2));
    assertEquals(
        StopTransfer.TIMED_TRANSFER, transferTable.getTransferTime(stopN, stopK, fromTrip, toTrip));
    assertEquals(15, transferTable.getTransferTime(stopN, stopK, fromTrip, toTrip2));

    Vertex e_arrive = graph.getVertex("agency_E_arrive");
    Vertex f_depart = graph.getVertex("agency_F_depart");
    Edge edge = new TransferEdge(e_arrive, f_depart, 10000, 10000);

    long startTime = TestUtils.dateInSeconds("America/New_York", 2009, 8, 18, 0, 50, 0);
    Vertex stop_b = graph.getVertex("agency_B_depart");
    Vertex stop_g = graph.getVertex("agency_G_arrive");
    RoutingRequest options = new RoutingRequest();
    options.dateTime = startTime;
    options.setRoutingContext(graph, stop_b, stop_g);
    ShortestPathTree spt = aStar.getShortestPathTree(options);

    GraphPath path = spt.getPath(stop_g, false);
    assertNotNull(path);

    assertTrue(
        "expected to use much later trip due to min transfer time",
        path.getEndTime() - startTime > 4.5 * 60 * 60);

    /* cleanup */
    e_arrive.removeOutgoing(edge);
    f_depart.removeIncoming(edge);
  }
 public RoutingContext(
     RoutingRequest traverseOptions, Graph graph, Vertex from, Vertex to, boolean findPlaces) {
   this.opt = traverseOptions;
   this.graph = graph;
   if (findPlaces) {
     // normal mode, search for vertices based on fromPlace and toPlace
     fromVertex = graph.streetIndex.getVertexForPlace(opt.getFromPlace(), opt);
     toVertex = graph.streetIndex.getVertexForPlace(opt.getToPlace(), opt, fromVertex);
     if (opt.intermediatePlaces != null) {
       for (NamedPlace intermediate : opt.intermediatePlaces) {
         Vertex vertex = graph.streetIndex.getVertexForPlace(intermediate, opt);
         intermediateVertices.add(vertex);
       }
     }
   } else {
     // debug mode, force endpoint vertices to those specified rather than searching
     fromVertex = from;
     toVertex = to;
   }
   if (opt.getStartingTransitStopId() != null) {
     TransitIndexService tis = graph.getService(TransitIndexService.class);
     if (tis == null) {
       throw new RuntimeException(
           "Next/Previous/First/Last trip "
               + "functionality depends on the transit index. Rebuild "
               + "the graph with TransitIndexBuilder");
     }
     AgencyAndId stopId = opt.getStartingTransitStopId();
     startingStop = tis.getPreBoardEdge(stopId).getToVertex();
   }
   origin = opt.arriveBy ? toVertex : fromVertex;
   target = opt.arriveBy ? fromVertex : toVertex;
   calendarService = graph.getCalendarService();
   transferTable = graph.getTransferTable();
   timetableSnapshot = null;
   setServiceDays();
   if (opt.batch) remainingWeightHeuristic = new TrivialRemainingWeightHeuristic();
   else remainingWeightHeuristic = heuristicFactory.getInstanceForSearch(opt);
 }