fully functional except argument parsing