BIG refactor into classes with specs

@kevinreedy @shanesveller