Lots of refactoring, hope it's better now :(