I think I've come back around to seeing some merit in the "traditional" version. All the state is declared before the main loop. You could stop the program after any iteration of the single loop, save the explicitly declared state, and restart where you left off. The logic inside the loop can be applied to any record and state.
In the double-loop version, your place in the control flow is part of the state. If you stopped, you wouldn't know where to start up again. There's also a state variable (firstLineOfGroup) declared inside the loop.
I know why I prefer the "traditional" version: it can easily be refactored to be functional, and making the state explicit means it doesn't have to be refactored if I want to store the state externally or switch from a batch architecture to a streaming architecture. The JSP version is inherently imperative and needs to be refactored before it can be used in a different architecture. Funny how ideas like that alter your taste.