Refactored this to make it much cleaner and more object-oriented.