lots and lots of changes, so much for splitting it up into smaller commits :D