private OneWayCarsharingRDWithParkingStation findClosestAvailableParkingSpace(Link link) {

    // find the closest available car in the quad tree(?) reserve it (make it unavailable)
    // if no cars within certain radius return null

    double distanceSearch =
        Double.parseDouble(
            scenario
                .getConfig()
                .getModule("OneWayCarsharing")
                .getParams()
                .get("searchDistanceOneWayCarsharing"));

    Collection<OneWayCarsharingRDWithParkingStation> location =
        this.carSharingVehicles
            .getOneWayVehicles()
            .getQuadTree()
            .getDisk(link.getCoord().getX(), link.getCoord().getY(), distanceSearch);
    if (location.isEmpty()) return null;

    OneWayCarsharingRDWithParkingStation closest = null;
    for (OneWayCarsharingRDWithParkingStation station : location) {
      if (CoordUtils.calcEuclideanDistance(link.getCoord(), station.getLink().getCoord())
              < distanceSearch
          && station.getNumberOfAvailableParkingSpaces() > 0) {
        closest = station;
        distanceSearch =
            CoordUtils.calcEuclideanDistance(link.getCoord(), station.getLink().getCoord());
      }
    }

    // owvehiclesLocation.removeVehicle(closest.getLink());
    return closest;
  }
  private void initializeOneWayCarsharingStartWalkLeg(Leg leg, double now) {

    this.state = MobsimAgent.State.LEG;
    Route route = leg.getRoute();
    OneWayCarsharingRDWithParkingStation station =
        findClosestAvailableOWCar(route.getStartLinkId());

    if (station == null) {
      this.state = MobsimAgent.State.ABORT;
      this.simulation
          .getEventsManager()
          .processEvent(new NoVehicleCarSharingEvent(now, route.getStartLinkId(), "ow"));

      return;
    }
    startStationOW = station;
    owVehId = station.getIDs().get(0);
    this.carSharingVehicles.getOneWayVehicles().removeVehicle(station, owVehId);

    initializeCSWalkLeg(
        "walk_ow_sb",
        now,
        scenario.getNetwork().getLinks().get(route.getStartLinkId()),
        startStationOW.getLink());
  }
  private void initializeOneWayCarsharingCarLeg(Link l, double now) {
    this.state = MobsimAgent.State.LEG;

    PlanElement pe = this.getCurrentPlanElement();

    Leg leg = (Leg) pe;
    Network network = scenario.getNetwork();
    endStationOW =
        findClosestAvailableParkingSpace(network.getLinks().get(leg.getRoute().getEndLinkId()));

    if (endStationOW == null) {

      this.state = MobsimAgent.State.ABORT;
      this.simulation
          .getEventsManager()
          .processEvent(new NoParkingSpaceEvent(now, leg.getRoute().getEndLinkId(), "ow"));

      return;
    } else {
      startStationOW.freeParkingSpot();
      endStationOW.reserveParkingSpot();

      Link destinationLink = endStationOW.getLink();
      // create route for the car part of the onewaycarsharing trip
      initializeCSVehicleLeg("onewaycarsharing", now, l, destinationLink);
    }
  }
  private void initializeOneWayCarsharingEndWalkLeg(Leg leg, double now) {

    this.state = MobsimAgent.State.LEG;
    Route route = leg.getRoute();

    initializeCSWalkLeg(
        "walk_ow_sb",
        now,
        endStationOW.getLink(),
        scenario.getNetwork().getLinks().get(route.getEndLinkId()));
  }
  private void advancePlan(double now) {
    this.currentPlanElementIndex++;

    // check if plan has run dry:
    if (this.currentPlanElementIndex >= this.getPlanElements().size()) {
      log.error(
          "plan of agent with id = "
              + this.getId()
              + " has run empty.  Setting agent state to ABORT\n"
              + "          (but continuing the mobsim).  This used to be an exception ...");
      this.state = MobsimAgent.State.ABORT;
      return;
    }

    PlanElement pe = this.getCurrentPlanElement();
    if (pe instanceof Activity) {
      Activity act = (Activity) pe;
      initializeActivity(act);
    } else if (pe instanceof Leg) {
      Leg leg = (Leg) pe;
      // start of added stuff

      String mode = leg.getMode();

      PlanElement previousPlanElement =
          this.plan.getPlanElements().get(this.plan.getPlanElements().indexOf(pe) - 1);
      PlanElement nextPlanElement =
          this.plan.getPlanElements().get(this.plan.getPlanElements().indexOf(pe) + 1);

      switch (mode) {
        case "walk_rb":
          if (nextPlanElement instanceof Leg) {

            initializeTwoWayCarsharingStartWalkLeg(leg, now);
          } else if (previousPlanElement instanceof Leg) {

            initializeTwoWayCarsharingEndWalkLeg(leg, now);
          }
          break;

        case "twowaycarsharing":
          if (previousPlanElement instanceof Activity && nextPlanElement instanceof Activity)
            initializeTwoWayCSMidleCarLeg(startLinkTW, now);
          else if (previousPlanElement instanceof Leg && !(nextPlanElement instanceof Leg))
            initializeTwoWayCarsharingCarLeg(startLinkTW, now);
          else if (previousPlanElement instanceof Leg && (nextPlanElement instanceof Leg))
            initializeTwoWayCarsharingEmptyCarLeg(startLinkTW, now);
          else if (nextPlanElement instanceof Leg)
            initializeTwoWayCarsharingEndCarLeg(startLinkTW, now);
          else log.error("This should never happen");
          break;

        case "walk_ff":
          initializeFreeFLoatingWalkLeg(leg, now);
          break;

        case "freefloating":
          initializeFreeFLoatingCarLeg(startLinkFF, now);
          break;

        case "walk_ow_sb":
          if (nextPlanElement instanceof Leg) {

            initializeOneWayCarsharingStartWalkLeg(leg, now);
          } else if (previousPlanElement instanceof Leg) {

            initializeOneWayCarsharingEndWalkLeg(leg, now);
          }
          break;

        case "onewaycarsharing":
          initializeOneWayCarsharingCarLeg(startStationOW.getLink(), now);
          break;
        default:
          initializeLeg(leg);
          break;
      }

    } else {
      throw new RuntimeException("Unknown PlanElement of type: " + pe.getClass().getName());
    }
  }