Almost finished, needs refactoring