working version; refactored and needs more;