Split things up to make them cleaner. Added many more tests.