code: def _do_stem_grouping(self, timeperiod, stem):
          
  
          # exclude 00 from lower boundary, unless the grouping == 1
          lower_boundary = 0 if self.time_grouping == 1 else 1
          upper_boundary = self._get_stem_upper_boundary(timeperiod)
  
          for i in range(lower_boundary, upper_boundary):
              candidate = i * self.time_grouping
              if stem <= candidate <= upper_boundary:
                  return candidate
          return upper_boundary
docs: method performs *timeperiod's stem grouping*.
          :param timeperiod: timeperiod to augment
          :param stem: inclusive lower boundary for the timeperiod's corresponding token. For instance:
                  - for 2015010520 and QUALIFIER_MONTHLY, stem would be 01
                  - for 2015010520 and QUALIFIER_DAILY, stem would be 05
                  - for 2015010520 and QUALIFIER_HOURLY, stem would be 20
          :return: grouped stem. For instance:
                  - for 2015010520 and QUALIFIER_MONTHLY and time_grouping=3, stem would be 03
                  - for 2015010520 and QUALIFIER_DAILY and time_grouping=2, stem would be 06
                  - for 2015010520 and QUALIFIER_HOURLY and time_grouping=8, stem would be 23