Perhaps an abstract method could be added to `AsyncTaskHandle` to provide a list of messages, although that may not be appropriate for that interface.

The whole contents of this method are about mapping a task to a DTO - the ultimate solution might be a hierarchy of mappers, so that the parts that differ between different task types can be handled differently, while sharing most of the mapping logic.