Moving some reusable code into an AbstractTask to reduce duplication and ensure that it has testing, adding a test for running an empty task stack.