Fix #1: Class based plugin refactor

The code has changed a bunch since the original pull request by Tim Neill
but is still largely based on that patch.