Good call.  I took care of the first two items, but I had already removed the completer mapping and decided to keep the completer state in the listener closure instead in the original push.  Thinking about this, it may have been the wrong decision.  Originally, I wanted to avoid the extra memory and instance clutter that mapping completers caused, but in retrospect, I think that using closures to keep the state uses equal or greater memory, won't use as efficient an algorithm as a map to look up the completer, and will basically use n² cpu (n = number of stacked service calls).  Service calls shouldn't be stacking up too badly, but it's still a consideration.

I hadn't done the same for ping / pongs because they aren't normal ServiceActionEvents.  I guess I'll switch everything back to using a map after thinking about the above.  Thoughts?