Added more classes to further abstract out common features and make it
more flexible