tests pass, needs refactoring