Refactor to reuse existing code.

Port from release-2.x branch adding missing pieces.
26 files changed