Also separates logic so that it can be tested more easily, and adds unit tests to make sure there is no regression. Fixes #1083