finished and working but may need refactoring