working but need refactoring and tests