reimplemented and refactored