updated with bug fixes and refactor