refactored code, untested