Split up giant handleNextEvent method in SimpleClient

By breaking it into request, response, and event it's
much easier to follow and modify.
Make withSbt test util synchronously block until the client closes

This reduces potential side effects where one test affects another.
Fix execution event tracker sending two ExecutionWaiting for same execution

Also add an exception when two ExecutionWaiting are processed, which
would make the tests fail if we regressed this again.
Track execution state in SimpleClient and zero it on disconnect

The idea here is that a user of SbtClient can rely on all
execution/task starts getting a corresponding completion event,
rather than having to track disconnection themselves as a
special case.