gt:                 for (String mode : modes) {
context: package beam.analysis.plots;
  
  import beam.agentsim.events.ModeChoiceEvent;
  import beam.agentsim.events.ReplanningEvent;
  import beam.sim.config.BeamConfig;
  import com.google.common.collect.Lists;
  import org.apache.commons.collections4.ListUtils;
  import org.jfree.chart.JFreeChart;
  import org.jfree.data.category.CategoryDataset;
  import org.jfree.data.category.DefaultCategoryDataset;
  import org.jfree.data.general.DatasetUtilities;
  import org.matsim.api.core.v01.events.Event;
  import org.matsim.core.controler.OutputDirectoryHierarchy;
  import org.matsim.core.controler.events.IterationEndsEvent;
  import org.matsim.core.utils.collections.Tuple;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.*;
  import java.util.*;
  import java.util.stream.Collectors;
  
  import static beam.sim.metrics.Metrics.ShortLevel;
  
  
  public class RealizedModeAnalysis extends BaseModeAnalysis {
  
      private static final String graphTitle = "Realized Mode Histogram";
      private static final String referenceGraphTitle = "Reference Realized Mode Histogram";
      private static final String replanningGraphTitle = "Replanning Event Count";
      private static final String rootReplanningGraphTitle = "ReplanningEvent Count";
      private static final String yAxisTitleForReplanning = "count";
      private static final String xAxisTitle = "Hour";
      private static final String yAxisTitle = "# mode chosen";
      static final String fileName = "realizedMode";
  
      private Map<Integer, Map<String, Double>> hourModeFrequency = new HashMap<>();
      private Map<String, Stack<ModeHour>> hourPerson = new HashMap<>();
      private Map<Integer, Map<String, Double>> realizedModeChoiceInIteration = new HashMap<>();
      private Map<Integer, Integer> affectedModeCount = new HashMap<>();
      private Map<Integer, Integer> rootAffectedModeCount = new HashMap<>();
      private Set<String> iterationTypeSet = new HashSet<>();
      private Set<String> cumulativeMode = new TreeSet<>();
      private Map<String, Map<Integer, Map<String, Integer>>> personHourModeCount = new HashMap<>();
      private Map<String, Double> benchMarkData;
      private Set<String> cumulativeReferenceMode = new TreeSet<>();
      private Map<String,List<String>> personReplanningChain = new HashMap<>();
      private Map<String, Integer> replanningReasonCount = new HashMap<>();
      private Map<Integer, Map<String, Integer>> replanningReasonCountPerIter = new HashMap<>();
      //This map will always hold value as 0 or 1
      private Map<String, Integer> personIdList = new HashMap<>();
  
      private final boolean writeGraph;
      private final StatsComputation<Tuple<Map<Integer, Map<String, Double>>, Set<String>>, double[][]> statComputation;
  
      public RealizedModeAnalysis(StatsComputation<Tuple<Map<Integer, Map<String, Double>>, Set<String>>, double[][]> statComputation, boolean writeGraph, BeamConfig beamConfig) {
          String benchMarkFileLocation = beamConfig.beam().calibration().mode().benchmarkFilePath();
          this.statComputation = statComputation;
          this.writeGraph = writeGraph;
          benchMarkData = benchMarkCSVLoader(benchMarkFileLocation);
      }
  
      public static class RealizedModesStatsComputation implements StatsComputation<Tuple<Map<Integer, Map<String, Double>>, Set<String>>, double[][]> {
  
          @Override
          public double[][] compute(Tuple<Map<Integer, Map<String, Double>>, Set<String>> stat) {
              List<Integer> hoursList = GraphsStatsAgentSimEventsListener.getSortedIntegerList(stat.getFirst().keySet());
              List<String> modesChosenList = GraphsStatsAgentSimEventsListener.getSortedStringList(stat.getSecond());
              if (0 == hoursList.size())
                  return null;
              int maxHour = hoursList.get(hoursList.size() - 1);
              double[][] dataset = new double[stat.getSecond().size()][maxHour + 1];
              for (int i = 0; i < modesChosenList.size(); i++) {
                  String modeChosen = modesChosenList.get(i);
                  dataset[i] = getHoursDataPerOccurrenceAgainstMode(modeChosen, maxHour, stat.getFirst());
              }
              return dataset;
          }
  
          private double[] getHoursDataPerOccurrenceAgainstMode(String modeChosen, int maxHour, Map<Integer, Map<String, Double>> stat) {
              double[] modeOccurrencePerHour = new double[maxHour + 1];
              for (int hour = 0; hour <= maxHour; hour++) {
                  Map<String, Double> hourData = stat.get(hour);
                  if (hourData != null) {
                      modeOccurrencePerHour[hour] = hourData.get(modeChosen) == null ? 0 : hourData.get(modeChosen);
                  } else {
                      modeOccurrencePerHour[hour] = 0;
                  }
              }
              return modeOccurrencePerHour;
          }
      }
  
      @Override
      public void processStats(Event event) {
          if (event instanceof ReplanningEvent || event.getEventType().equalsIgnoreCase(ReplanningEvent.EVENT_TYPE) ||
                  event instanceof ModeChoiceEvent || event.getEventType().equalsIgnoreCase(ModeChoiceEvent.EVENT_TYPE))
              processRealizedMode(event);
      }
  
      @Override
      public void createGraph(IterationEndsEvent event) throws IOException {
  
          Map<String, String> tags = new HashMap<>();
          tags.put("stats-type", "aggregated-mode-choice");
  
          updatePersonCount();
  
          hourModeFrequency.values().stream().filter(Objects::nonNull).flatMap(x -> x.entrySet().stream())
                  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a + b))
                  .forEach((mode, count) -> countOccurrenceJava(mode, count.longValue(), ShortLevel(), tags));
  
          updateRealizedModeChoiceInIteration(event.getIteration());
          CategoryDataset modesFrequencyDataset = buildModesFrequencyDatasetForGraph();
          if (modesFrequencyDataset != null && writeGraph) {
              String graphImageFile = GraphsStatsAgentSimEventsListener.CONTROLLER_IO.getIterationFilename(event.getIteration(), fileName + ".png");
              createGraphInRootDirectory(modesFrequencyDataset, graphTitle, graphImageFile, xAxisTitle, yAxisTitle, getModesChosen());
          }
          OutputDirectoryHierarchy outputDirectoryHierarchy = event.getServices().getControlerIO();
  
          String fileName;
          CategoryDataset dataset = buildRealizedModeChoiceDatasetForGraph();
          if (dataset != null && writeGraph) {
              fileName = outputDirectoryHierarchy.getOutputFilename("realizedModeChoice.png");
              createGraphInRootDirectory(dataset, graphTitle, fileName, "Iteration", "# mode choosen", cumulativeMode);
          }
  
          CategoryDataset referenceDataset = buildRealizedModeChoiceReferenceDatasetForGraph();
          if (referenceDataset != null && writeGraph) {
              fileName = outputDirectoryHierarchy.getOutputFilename("referenceRealizedModeChoice.png");
              cumulativeReferenceMode.addAll(benchMarkData.keySet());
              createGraphInRootDirectory(referenceDataset, referenceGraphTitle, fileName, "Iteration", "# mode choosen(Percent)", cumulativeReferenceMode);
          }
  
          Map<String, Integer> modeCount = calculateModeCount();
          writeToReplaningChainCSV(event, modeCount);
          
          writeToRootCSV(GraphsStatsAgentSimEventsListener.CONTROLLER_IO.getOutputFilename("realizedModeChoice.csv"), realizedModeChoiceInIteration, cumulativeMode);
          writeToCSV(event);
          writeToReferenceCSV();
  
          DefaultCategoryDataset replanningModeCountDataset = replanningCountModeChoiceDataset();
          createReplanningCountModeChoiceGraph(replanningModeCountDataset, event.getIteration());
          writeToReplanningCSV(event);
  
          rootAffectedModeCount.put(event.getIteration(), affectedModeCount.values().stream().reduce(Integer::sum).orElse(0));
          fileName = outputDirectoryHierarchy.getOutputFilename("replanningCountModeChoice.png");
          writeToRootReplanningCountModeChoice(fileName);
  
          writeReplanningReasonCountCSV(event.getIteration());
  
          replanningReasonCountPerIter.put(event.getIteration(),replanningReasonCount.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
          writeReplanningReasonCountRootCSV();
      }
  
      @Override
      public void resetStats() {
          hourModeFrequency.clear();
          personIdList.clear();
          hourPerson.clear();
          personIdList.clear();
          personHourModeCount.clear();
          affectedModeCount.clear();
          personReplanningChain.clear();
          replanningReasonCount.clear();
      }
  
      private void writeToRootReplanningCountModeChoice(String fileName) throws IOException {
          CategoryDataset dataset = rootReplanningCountModeChoiceDataset();
          createRootReplaningModeChoiceCountGraph(dataset, fileName);
      }
  
      // The modeChoice events for same person as of replanning event will be excluded in the form of CRC, CRCRC, CRCRCRC so on.
      private void processRealizedMode(Event event) {
          int hour = GraphsStatsAgentSimEventsListener.getEventHour(event.getTime());
          Map<String, Double> hourData = hourModeFrequency.get(hour);
          if (event instanceof ModeChoiceEvent) {
              ModeChoiceEvent mce = (ModeChoiceEvent) event;
              String mode = mce.mode;
              String personId = mce.getPersonId().toString();
              Map<String, String> tags = new HashMap<>();
              tags.put("stats-type", "mode-choice");
              tags.put("hour", "" + (hour + 1));
  
              countOccurrenceJava(mode, 1, ShortLevel(), tags);
              personReplanningChain.merge(personId , Lists.newArrayList(mode), ListUtils::union);
              if (personIdList.containsKey(personId) && personIdList.get(personId) == 1) {
                  personIdList.put(personId, 0);
                  setHourPersonMode(hour, personId, mode, true);
                  return;
              }
  
              if (personIdList.remove(personId) != null) {
                  updateHourMode(personId);
                  personHourModeCount.remove(personId);
              }
              if (hourData == null) {
                  hourData = new HashMap<>();
              }
  
              hourData.merge(mode, 1.0, Double::sum);
              hourModeFrequency.put(hour, hourData);
              ModeHour modeHour = new ModeHour(mode, hour);
              Stack<ModeHour> modeHours = hourPerson.get(personId);
              if (modeHours == null) {
                  modeHours = new Stack<>();
              }
              modeHours.push(modeHour);
              hourPerson.put(personId, modeHours);
              setHourPersonMode(hour, personId, mode, false);
          }
  
          if (event instanceof ReplanningEvent) {
              ReplanningEvent re = (ReplanningEvent) event;
              String person = re.getPersonId().toString();
  
              personReplanningChain.merge(person , Lists.newArrayList(re.getEventType()), ListUtils::union);
              Stack<ModeHour> modeHours = hourPerson.get(person);
              affectedModeCount.merge(hour, 1, Integer::sum);
              replanningReasonCount.merge(re.getReason(), 1, Integer::sum);
  
              if (personIdList.containsKey(person) && personIdList.get(person) == 0) {
                  personIdList.put(person, 1);
                  return;
              }
  
              if (modeHours != null && modeHours.size() > 0
                      && !personIdList.containsKey(person)) {
  
                  personIdList.put(person, 1);
  
                  ModeHour modeHour = modeHours.pop();
                  hourPerson.put(person, modeHours);
  
                  hourData = hourModeFrequency.get(modeHour.getHour());
                  hourData.merge(modeHour.getMode(), -1.0, Double::sum);
                  hourModeFrequency.put(modeHour.getHour(), hourData);
              }
          }
      }
  
      // adding proportionate of replanning to mode choice
      public void updateHourMode(String personId) {
          Map<Integer, Map<String, Integer>> hourModeCount = personHourModeCount.get(personId);
          if (hourModeCount != null) {
              double countSum = hourModeCount.values().stream().map(Map::values).mapToInt(i -> i.stream().mapToInt(Integer::intValue).sum()).sum();
  
              Set<String> modes = new HashSet<>();
              hourModeCount.values().stream().map(Map::keySet).forEach(modes::addAll);
              Set<Integer> hours = hourModeCount.keySet();
              double sum = modes.size();
              if (countSum >= 2 && sum == 1) {
                  Optional<Integer> optionalHour = hours.stream().findFirst();
                  if (optionalHour.isPresent()) {
                      int hour = optionalHour.get();
                      Map<String, Double> oldHourData = hourModeFrequency.get(hour);
                      if (oldHourData == null) {
                          oldHourData = new HashMap<>();
                      }
                      Optional<String> optionalMode = modes.stream().findFirst();
                      if (optionalMode.isPresent()) {
                          oldHourData.merge(optionalMode.get(), 1.0, Double::sum);
                          hourModeFrequency.put(hour, oldHourData);
                      }
                  }
  
              } else if (countSum >= 2 && sum > 1) {
  