public TransitLine createSingleTransitLine(Id<Vehicle> driverId) {
    // initialize
    TransitLine line =
        this.tS.getFactory().createTransitLine(Id.create(driverId, TransitLine.class));
    TransitStopFacility startStop = getRandomTransitStop();
    TransitStopFacility endStop = getRandomTransitStop();

    TransitRoute transitRoute_H =
        createRoute(Id.create(driverId + "_H", TransitRoute.class), startStop, endStop);
    TransitRoute transitRoute_R =
        createRoute(Id.create(driverId + "_R", TransitRoute.class), endStop, startStop);

    // register route
    line.addRoute(transitRoute_H);
    line.addRoute(transitRoute_R);

    // add departures
    int n = 0;
    for (double j = 0.0; j < 24 * 3600; ) {
      Departure departure = this.tS.getFactory().createDeparture(Id.create(n, Departure.class), j);
      departure.setVehicleId(driverId);
      transitRoute_H.addDeparture(departure);
      j += transitRoute_H.getStop(endStop).getDepartureOffset() + 5 * 60;
      n++;

      departure = this.tS.getFactory().createDeparture(Id.create(n, Departure.class), j);
      departure.setVehicleId(driverId);
      transitRoute_R.addDeparture(departure);
      j += transitRoute_R.getStop(startStop).getDepartureOffset() + 5 * 60;
      n++;
    }

    return line;
  }
  private void convertRoute(final BRoute route) {
    Map<Id<TransitRoute>, TransitRoute> transitRoutes = new HashMap<>();

    for (BFahrt fahrt : route.fahrten) {
      TransitRoute tRoute = transitRoutes.get(getTransitRouteId(route, fahrt.fahrzeitprofil));
      if (tRoute == null) {
        tRoute = convertFahrzeitprofil(route, fahrt.fahrzeitprofil);
        transitRoutes.put(tRoute.getId(), tRoute);
        this.currentTransitLine.addRoute(tRoute);
      }
      tRoute.addDeparture(
          this.builder.createDeparture(
              Id.create(this.departureCounter++, Departure.class), fahrt.departureTime));
    }
  }
  public void testTransitRouteCopy() {
    Config config = super.loadConfig(null);
    config.scenario().setUseTransit(true);
    config.scenario().setUseVehicles(true);
    ScenarioImpl scenario = (ScenarioImpl) ScenarioUtils.createScenario(config);

    Id<Node> nodeId1 = Id.create("1", Node.class);
    Id<Node> nodeId2 = Id.create("2", Node.class);
    Id<Node> nodeId3 = Id.create("3", Node.class);
    Id<Link> linkId1 = Id.create("1", Link.class);
    Id<Link> linkId2 = Id.create("2", Link.class);

    // build network
    Network network = scenario.getNetwork();
    NetworkFactory nBuilder = network.getFactory();
    Node node1 = nBuilder.createNode(nodeId1, scenario.createCoord(0, 0));
    Node node2 = nBuilder.createNode(nodeId2, scenario.createCoord(1000, 0));
    Node node3 = nBuilder.createNode(nodeId3, scenario.createCoord(2000, 0));
    network.addNode(node1);
    network.addNode(node2);
    network.addNode(node3);
    Link link1 = nBuilder.createLink(linkId1, node1, node2);
    Link link2 = nBuilder.createLink(linkId2, node2, node3);
    network.addLink(link1);
    network.addLink(link2);

    // build schedule
    TransitSchedule schedule = scenario.getTransitSchedule();
    TransitScheduleFactory sBuilder = schedule.getFactory();

    TransitStopFacility stopF1 =
        sBuilder.createTransitStopFacility(
            Id.create("1", TransitStopFacility.class), scenario.createCoord(1000.0, 0), false);
    TransitStopFacility stopF2 =
        sBuilder.createTransitStopFacility(
            Id.create("2", TransitStopFacility.class), scenario.createCoord(2000.0, 0), false);
    stopF1.setLinkId(link1.getId());
    stopF2.setLinkId(link2.getId());
    schedule.addStopFacility(stopF1);
    schedule.addStopFacility(stopF2);

    TransitLine tLine1 = sBuilder.createTransitLine(Id.create("1", TransitLine.class));

    TransitRouteStop stop1 = sBuilder.createTransitRouteStop(stopF1, 0, 0);
    TransitRouteStop stop2 = sBuilder.createTransitRouteStop(stopF2, 100, 100);
    ArrayList<TransitRouteStop> stops = new ArrayList<TransitRouteStop>();
    stops.add(stop1);
    stops.add(stop2);

    NetworkRoute netRoute = new LinkNetworkRouteImpl(link1.getId(), link2.getId());
    netRoute.setLinkIds(link1.getId(), Collections.<Id<Link>>emptyList(), link2.getId());
    TransitRoute tRoute1 =
        sBuilder.createTransitRoute(Id.create("1", TransitRoute.class), netRoute, stops, "bus");

    tRoute1.addDeparture(sBuilder.createDeparture(Id.create("1", Departure.class), 7.0 * 3600));
    tLine1.addRoute(tRoute1);
    schedule.addTransitLine(tLine1);

    // build vehicles
    new CreateVehiclesForSchedule(schedule, scenario.getVehicles()).run();

    // build population
    Population population = scenario.getPopulation();
    PopulationFactory pBuilder = population.getFactory();
    Person person1 = pBuilder.createPerson(Id.create("1", Person.class));
    Plan plan = pBuilder.createPlan();
    Activity homeAct = pBuilder.createActivityFromLinkId("h", linkId1);
    homeAct.setEndTime(7.0 * 3600);
    plan.addActivity(homeAct);
    Leg leg = pBuilder.createLeg(TransportMode.pt);
    ExperimentalTransitRoute tRoute = new ExperimentalTransitRoute(stopF1, tLine1, tRoute1, stopF2);
    leg.setRoute(tRoute);
    plan.addLeg(leg);
    plan.addActivity(pBuilder.createActivityFromLinkId("w", linkId2));
    person1.addPlan(plan);
    population.addPerson(person1);

    // prepare config
    config.controler().setFirstIteration(0);
    config.controler().setLastIteration(1);

    ActivityParams params = new ActivityParams("h");
    params.setTypicalDuration(16.0 * 3600);
    config.planCalcScore().addActivityParams(params);
    params = new ActivityParams("w");
    params.setTypicalDuration(8.0 * 3600);
    config.planCalcScore().addActivityParams(params);

    StrategySettings tam = new StrategySettings(Id.create(1, StrategySettings.class));
    tam.setStrategyName("TimeAllocationMutator");
    tam.setWeight(1.0);
    config.strategy().addStrategySettings(tam);

    // run
    Controler controler = new Controler(scenario);
    controler.getConfig().controler().setWriteEventsInterval(0);
    controler.setCreateGraphs(false);
    controler.run();

    // checks
    assertEquals(1, population.getPersons().size());
    assertEquals(2, person1.getPlans().size());
    assertEquals(
        ExperimentalTransitRoute.class,
        ((Leg) person1.getPlans().get(0).getPlanElements().get(1)).getRoute().getClass());
    assertEquals(
        ExperimentalTransitRoute.class,
        ((Leg) person1.getPlans().get(1).getPlanElements().get(1)).getRoute().getClass());
  }
  private final void convertSchedules(
      OTTDataContainer dataContainer, ObjectAttributes trainTypes, boolean isPerformance) {
    TransitScheduleFactory scheduleFactory = scenario.getTransitSchedule().getFactory();
    VehiclesFactory vehiclesFactory = ((ScenarioImpl) scenario).getVehicles().getFactory();

    VehicleType vehicleType =
        vehiclesFactory.createVehicleType(new IdImpl(WagonSimConstants.DEFAULT_VEHICLE_TYPE));
    VehicleCapacity vehicleCapacity = vehiclesFactory.createVehicleCapacity();
    // we do not use this capacity. Therefore it should infinite, otherwise this capacity may exceed
    // before ``our'' capacities are exceeded // dr, oct'13
    vehicleCapacity.setSeats(999999);
    vehicleCapacity.setStandingRoom(999999);
    // we defined the vehicle-enter/leave-time is implicit included in transfer-times which
    // are defined in the transitrouterconfig (for handling see
    // WagonSimTripRouterFactoryImpl#WagonSimRouterWrapper)
    // dr, oct'13
    vehicleType.setAccessTime(0);
    vehicleType.setEgressTime(0);
    vehicleType.setCapacity(vehicleCapacity);
    ((ScenarioImpl) scenario).getVehicles().addVehicleType(vehicleType);

    Date startDate = extractStartDate(dataContainer, isPerformance);
    System.out.println("startDate=" + startDate.toString());

    for (Locomotive locomotive : dataContainer.locomotives.values()) {

      Departure departure = null;
      List<TransitRouteStop> transitRouteStops = new ArrayList<TransitRouteStop>();
      for (StationData stationData : locomotive.trips.values()) {

        TransitStopFacility stopFacility =
            scenario.getTransitSchedule().getFacilities().get(stationData.stationId);
        if (stopFacility == null) {
          throw new RuntimeException(
              "locomotive id="
                  + locomotive.id
                  + ": station id="
                  + stationData.stationId
                  + " not found. Bailing out.");
        }

        double arrivalDelay = Double.NaN;
        double departureDelay = Double.NaN;
        if (departure == null) {
          double lineDepartureOffset =
              (stationData.departure.getTime() - startDate.getTime()) / 1000.0;
          if (!isPerformance) {
            lineDepartureOffset -= stationData.delayDeparture;
          }
          departure = scheduleFactory.createDeparture(locomotive.id, lineDepartureOffset);
          arrivalDelay = 0.0;
        } else {
          arrivalDelay =
              (stationData.arrival.getTime() - startDate.getTime()) / 1000.0
                  - departure.getDepartureTime();
          if (!isPerformance) {
            arrivalDelay -= stationData.delayArrival;
          }
        }
        departureDelay =
            (stationData.departure.getTime() - startDate.getTime()) / 1000.0
                - departure.getDepartureTime();
        if (!isPerformance) {
          departureDelay -= stationData.delayDeparture;
        }

        if (departureDelay < arrivalDelay) {
          throw new RuntimeException(
              "locomotive id="
                  + locomotive.id
                  + ": arrival="
                  + stationData.arrival.toString()
                  + " does not fit with departure="
                  + stationData.departure.toString()
                  + ". ("
                  + departureDelay
                  + "<"
                  + arrivalDelay
                  + ") Bailing out.");
        }

        TransitRouteStop stop =
            scheduleFactory.createTransitRouteStop(stopFacility, arrivalDelay, departureDelay);
        stop.setAwaitDepartureTime(true);
        transitRouteStops.add(stop);
      }

      if (transitRouteStops.size() > 1) {

        // check if train type is given
        if (trainTypes.getAttribute(locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED)
            == null) {
          throw new RuntimeException(
              "locomotive id="
                  + locomotive.id
                  + ": type="
                  + locomotive.type
                  + " is not defined by the train type table. Bailing out.");
        }

        TransitLine line = scheduleFactory.createTransitLine(locomotive.id);
        scenario.getTransitSchedule().addTransitLine(line);
        TransitRoute route =
            scheduleFactory.createTransitRoute(
                line.getId(), null, transitRouteStops, TransportMode.pt);
        line.addRoute(route);

        Vehicle vehicle = vehiclesFactory.createVehicle(route.getId(), vehicleType);
        ((ScenarioImpl) scenario).getVehicles().addVehicle(vehicle);
        departure.setVehicleId(vehicle.getId());
        route.addDeparture(departure);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(), WagonSimConstants.TRAIN_TYPE, locomotive.type);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_SPEED,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_WEIGHT,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_WEIGHT));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_LENGTH,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_LENGTH));

        // the next day
        vehicle = vehiclesFactory.createVehicle(new IdImpl(route.getId() + ".1"), vehicleType);
        ((ScenarioImpl) scenario).getVehicles().addVehicle(vehicle);
        departure =
            scheduleFactory.createDeparture(
                vehicle.getId(), departure.getDepartureTime() + 24 * 3600);
        departure.setVehicleId(vehicle.getId());
        route.addDeparture(departure);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(), WagonSimConstants.TRAIN_TYPE, locomotive.type);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_SPEED,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_WEIGHT,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_WEIGHT));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_LENGTH,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_LENGTH));

        // the day after the next day
        vehicle = vehiclesFactory.createVehicle(new IdImpl(route.getId() + ".2"), vehicleType);
        ((ScenarioImpl) scenario).getVehicles().addVehicle(vehicle);
        departure =
            scheduleFactory.createDeparture(
                vehicle.getId(), departure.getDepartureTime() + 24 * 3600);
        departure.setVehicleId(vehicle.getId());
        route.addDeparture(departure);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(), WagonSimConstants.TRAIN_TYPE, locomotive.type);
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_SPEED,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_SPEED));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_WEIGHT,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_WEIGHT));
        this.vehicleAttributes.putAttribute(
            vehicle.getId().toString(),
            WagonSimConstants.TRAIN_MAX_LENGTH,
            (Double)
                trainTypes.getAttribute(
                    locomotive.type.toString(), WagonSimConstants.TRAIN_MAX_LENGTH));
      } else if (transitRouteStops.size() == 1) {
        System.out.println(
            "locomotive id="
                + locomotive.id
                + ": only one station given. Therefore, no transitLine created.");
      } else {
        System.out.println(
            "locomotive id="
                + locomotive.id
                + ": no station is given. Therefore, no transitLine created.");
      }
    }
  }