Split implementation

For maintainability and readability, I've split the code
into multiple files, all in the same package (main)