Refactor protocol API to support both synchronous and asynchronous protocols.
Merge branch 'master' into synchronous-protocol