Split main function.
Add some tests, remove some bugs.