needs refactoring but works