Refactor dispatch

Picking up from #387 and #388. Rebased on master now that #386 is landed.