If you replace "whitespace handling" with "replacing every occurrence of the letter 'A' with 'B'", a similar idea, you can see what I'm getting at--the fo:block should be able to clean itself up (if there is such a property defined for the fo mandating that cleanup) prior to presenting itself to layout, so layout needn't be concerned with the "whitespace handling". The earlier this is done, preferably in flow.Block, the less work (and fewer instantiations) for FOText object and TextLayoutManager.
Handling space normalization before the text gets into layout might save some work if the layout uses backtracking. Nevertheless, Text can come from inline FOs as well, and the normalization process is sensitive to properties on inlines, e.g. in <fo:block>A <fo:wrapper text-decoration="underline"> B</fo:wrapper> </fo:block) *both* spaces between A and B remain (the current implementation is non-conformant in this respect).
IIRC flow.Block is parsed into multiple FOText items, each of which get fed into the TextLayoutManager. I'm not certain that "line breaks" are actually being created during layout; rather, during parsing, I suspect the BPD is just incremented and the next line is rendered.
The inline layout managers create line break possiblities if they think a line is full, rather similar to the maintenance branch code. The break possibility bubles up to the nearest block layout manager, which stores it, updates the BPD and goes ongetting further break possiblities from the child LMs.