refactored to be tail recursive