This is far from a full refactoring, but it makes the current implementation slightly easier to understand