This needs a lot of refactoring probably