working, but needs refactoring