working but needs major refactoring