Relatively complete version, still need to test run and debug