Refactored to use inheritance and separate logic where possible.
Addressed comments.
Change-Id: I9e62414cd83121575bdf99a3b47466a7585bedb6
Former-commit-id: dbba727f3d [formerly dbba727f3d [formerly 6e015b3f61c20635077d6e8271e9b763e5a32fe1]]
Former-commit-id: 17196b5dcd
Former-commit-id: 8b279966d1