final code (pretty much)