ActionRunner conforms to his own Cancel API
ExecuteAction takes Action interface, not runner
ExecuteAction delegates Cancel to its Action
ExecuteAction delegates Cleanup to its Action
ActionRunner.Cleanup is a no-op

It actually doesn't make sense for it to clean up its actions. That will be
automatically done either when it's Performed or Canceled.