Rather large refactor