@Override
  public void handleEvent(ActivityEndEvent event) {
    try {
      if (isTransitScenario) {
        if (transitDriverIds.contains(event.getPersonId())) return;
      }
      TravellerChain chain = chains.get(event.getPersonId());
      locations.put(event.getPersonId(), network.getLinks().get(event.getLinkId()).getCoord());
      if (chain == null) {
        chain = new TravellerChain();
        chains.put(event.getPersonId(), chain);
        Activity act = chain.addActivity();
        act.setCoord(network.getLinks().get(event.getLinkId()).getCoord());
        act.setEndTime(event.getTime());
        act.setFacility(event.getFacilityId());
        act.setStartTime(0.0);
        act.setType(event.getActType());

      } else if (!event.getActType().equals(PtConstants.TRANSIT_ACTIVITY_TYPE)) {
        Activity act = chain.getActs().getLast();
        act.setEndTime(event.getTime());
      }
    } catch (Exception e) {
      System.err.println(e.getStackTrace());
      System.err.println(event.toString());
    }
  }
  @Override
  public void handleEvent(ActivityStartEvent event) {
    try {
      if (isTransitScenario) {
        if (transitDriverIds.contains(event.getPersonId())) return;
      }
      TravellerChain chain = chains.get(event.getPersonId());
      boolean beforeInPT = chain.isInPT();
      if (event.getActType().equals(PtConstants.TRANSIT_ACTIVITY_TYPE)) {
        chain.setInPT(true);

      } else {
        chain.setInPT(false);
        chain.traveling = false;
        Activity act = chain.addActivity();
        act.setCoord(network.getLinks().get(event.getLinkId()).getCoord());
        act.setFacility(event.getFacilityId());
        act.setStartTime(event.getTime());
        act.setType(event.getActType());
        // end the preceding journey
        Journey journey = chain.getJourneys().getLast();
        journey.setDest(act.getCoord());
        journey.setEndTime(event.getTime());
        journey.setToAct(act);
        if (beforeInPT) journey.getWalks().getLast().setEgressWalk(true);
      }
    } catch (Exception e) {
      System.err.println(e.getStackTrace());
      System.err.println(event.toString());
      ;
    }
  }
  public void writeSimulationResultsToTabSeparated(String path, String appendage)
      throws IOException {
    String actTableName;
    String journeyTableName;
    String transferTableName;
    String tripTableName;
    if (appendage.matches("[a-zA-Z0-9]*[_]*")) {
      actTableName = appendage + "matsim_activities.txt";
      journeyTableName = appendage + "matsim_journeys.txt";
      transferTableName = appendage + "matsim_transfers.txt";
      tripTableName = appendage + "matsim_trips.txt";
    } else {
      if (appendage.matches("[a-zA-Z0-9]*")) appendage = "_" + appendage;
      actTableName = "matsim_activities" + appendage + ".txt";
      journeyTableName = "matsim_journeys" + appendage + ".txt";
      transferTableName = "matsim_transfers" + appendage + ".txt";
      tripTableName = "matsim_trips" + appendage + ".txt";
    }
    BufferedWriter activityWriter = IOUtils.getBufferedWriter(path + "/" + actTableName);

    activityWriter.write(
        "activity_id\tperson_id\tfacility_id\ttype\t"
            + "start_time\tend_time\tx\ty\tsample_selector\n");

    BufferedWriter journeyWriter = IOUtils.getBufferedWriter(path + "/" + journeyTableName);
    journeyWriter.write(
        "journey_id\tperson_id\tstart_time\t"
            + "end_time\tdistance\tmain_mode\tfrom_act\tto_act\t"
            + "in_vehicle_distance\tin_vehicle_time\t"
            + "access_walk_distance\taccess_walk_time\taccess_wait_time\t"
            + "first_boarding_stop\tegress_walk_distance\t"
            + "egress_walk_time\tlast_alighting_stop\t"
            + "transfer_walk_distance\ttransfer_walk_time\t"
            + "transfer_wait_time\tsample_selector\n");

    BufferedWriter tripWriter = IOUtils.getBufferedWriter(path + "/" + tripTableName);
    tripWriter.write(
        "trip_id\tjourney_id\tstart_time\tend_time\t"
            + "distance\tmode\tline\troute\tboarding_stop\t"
            + "alighting_stop\tsample_selector\n");

    BufferedWriter transferWriter = IOUtils.getBufferedWriter(path + "/" + transferTableName);
    transferWriter.write(
        "transfer_id\tjourney_id\tstart_time\t"
            + "end_time\tfrom_trip\tto_trip\twalk_distance\t"
            + "walk_time\twait_time\tsample_selector\n");

    // read a static field that increments with every inheriting object constructed
    Counter counter = new Counter("Output lines written: ");
    for (Entry<Id, TravellerChain> entry : chains.entrySet()) {
      String pax_id = entry.getKey().toString();
      TravellerChain chain = entry.getValue();
      for (Activity act : chain.getActs()) {
        try {
          activityWriter.write(
              String.format(
                  "%d\t%s\t%s\t%s\t%d\t%d\t%f\t%f\t%f\n",
                  act.getElementId(),
                  pax_id,
                  act.getFacility(),
                  act.getType(),
                  (int) act.getStartTime(),
                  (int) act.getEndTime(),
                  act.getCoord().getX(),
                  act.getCoord().getY(),
                  MatsimRandom.getRandom().nextDouble()));
        } catch (Exception e) {
          System.out.println("Couldn't print activity chain!");
        }
      }
      for (Journey journey : chain.getJourneys()) {
        try {
          journeyWriter.write(
              String.format(
                  "%d\t%s\t%d\t%d\t%.3f\t%s\t%d\t%d\t%.3f\t%d\t%.3f\t%d\t%d\t%s\t%.3f\t%d\t%s\t%.3f\t%d\t%d\t%f\n",
                  journey.getElementId(),
                  pax_id,
                  (int) journey.getStartTime(),
                  (int) journey.getEndTime(),
                  journey.getDistance(),
                  journey.getMainMode(),
                  journey.getFromAct().getElementId(),
                  journey.getToAct().getElementId(),
                  journey.getInVehDistance(),
                  (int) journey.getInVehTime(),
                  journey.getAccessWalkDistance(),
                  (int) journey.getAccessWalkTime(),
                  (int) journey.getAccessWaitTime(),
                  journey.getFirstBoardingStop(),
                  journey.getEgressWalkDistance(),
                  (int) journey.getEgressWalkTime(),
                  journey.getLastAlightingStop(),
                  journey.getTransferWalkDistance(),
                  (int) journey.getTransferWalkTime(),
                  (int) journey.getTransferWaitTime(),
                  MatsimRandom.getRandom().nextDouble()));
          counter.incCounter();

          if (!(journey.isCarJourney() || journey.isTeleportJourney())) {
            for (Trip trip : journey.getTrips()) {
              tripWriter.write(
                  String.format(
                      "%d\t%d\t%d\t%d\t%.3f\t%s\t%s\t%s\t%s\t%s\t%f\n",
                      trip.getElementId(),
                      journey.getElementId(),
                      (int) trip.getStartTime(),
                      (int) trip.getEndTime(),
                      trip.getDistance(),
                      trip.getMode(),
                      trip.getLine(),
                      trip.getRoute(),
                      trip.getBoardingStop(),
                      trip.getAlightingStop(),
                      MatsimRandom.getRandom().nextDouble()));
              counter.incCounter();
            }
            for (Transfer transfer : journey.getTransfers()) {
              transferWriter.write(
                  String.format(
                      "%d\t%d\t%d\t%d\t%d\t%d\t%.3f\t%d\t%d\t%f\n",
                      transfer.getElementId(),
                      journey.getElementId(),
                      (int) transfer.getStartTime(),
                      (int) transfer.getEndTime(),
                      transfer.getFromTrip().getElementId(),
                      transfer.getToTrip().getElementId(),
                      transfer.getWalkDistance(),
                      (int) transfer.getWalkTime(),
                      (int) transfer.getWaitTime(),
                      MatsimRandom.getRandom().nextDouble()));

              counter.incCounter();
            }
          } else {
            for (Trip trip : journey.getTrips()) {

              tripWriter.write(
                  String.format(
                      "%d\t%d\t%d\t%d\t%.3f\t%s\t%s\t%s\t%s\t%s\t%f\n",
                      trip.getElementId(),
                      journey.getElementId(),
                      (int) trip.getStartTime(),
                      (int) trip.getEndTime(),
                      journey.isTeleportJourney() ? 0.000 : trip.getDistance(),
                      trip.getMode(),
                      "",
                      "",
                      "",
                      "",
                      MatsimRandom.getRandom().nextDouble()));

              counter.incCounter();
            }
          }
        } catch (NullPointerException e) {
          setStuck(getStuck() + 1);
        }
      }
    }

    activityWriter.close();
    journeyWriter.close();
    tripWriter.close();
    transferWriter.close();
    counter.printCounter();
  }