New queueing semantics for observe events

When modifications to a collection are nested inside observe events for the same
collection, previously we would just throw an error.  Now, instead, we schedule
the new observe events for after the currently scheduled events, and make sure
they all happen before the outer modification returns.

I think this is going to be the least-unexpected behavior, even if it is a
little difficult to explain at first blush.