working version, still needs improvement