Restructure into modules and add a functional test