updated and refactured