i think there are combinations here where you call `self.reset()` and others where you don't and the logic is quite complex... wouldn't calling reset at the end of it all work? or having here some aux functions that make the logic clearer? (i'm worried that changing a line before or after might introduce bugs)