functional but needs refactoring