Refactored and broke up into submodules