private TemporalBinList doTemporalBinning(SpatialBinCollection spatialBinMap) throws IOException {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();

    long numberOfBins = spatialBinMap.size();
    final TemporalBinner temporalBinner = new TemporalBinner(binningContext);
    final CellProcessorChain cellChain = new CellProcessorChain(binningContext);
    final TemporalBinList temporalBins = new TemporalBinList((int) numberOfBins);
    Iterable<List<SpatialBin>> spatialBinListCollection = spatialBinMap.getBinCollection();
    int binCounter = 0;
    int percentCounter = 0;
    long hundredthOfNumBins = numberOfBins / 100;
    for (List<SpatialBin> spatialBinList : spatialBinListCollection) {
      binCounter += spatialBinList.size();

      SpatialBin spatialBin = spatialBinList.get(0);
      long spatialBinIndex = spatialBin.getIndex();
      TemporalBin temporalBin = temporalBinner.processSpatialBins(spatialBinIndex, spatialBinList);

      temporalBin = temporalBinner.computeOutput(spatialBinIndex, temporalBin);
      temporalBin = cellChain.process(temporalBin);

      temporalBins.add(temporalBin);
      if (binCounter >= hundredthOfNumBins) {
        binCounter = 0;
        getLogger().info(String.format("Finished %d%% of temporal bins", ++percentCounter));
      }
    }
    stopWatch.stop();
    getLogger()
        .info(String.format("Temporal binning of %d bins done, took %s", numberOfBins, stopWatch));

    return temporalBins;
  }