Very large refactor, not complete