You're right. My solution is how you would do igt in a parseHandler (which is where I pulled my code from).
From what I can tell (looking at the API), we can't add listeners dynamically, they have to be added to the process model either when the process is modeled, or inside a parse handler.
So....you should still be able to add a TaskListener that is triggered on the "assignment" event.
This listener can still create your sub tasks using code like:
// save task Task newTask = taskService.newTask(); newTask.setParentTaskId(parentTask.getId()); newTask.setName("MySubTask"); taskService.saveTask(newTask);
Now, you should also be able to add an event listener to the process that is bound to the TASK_COMPLETE event.
The listener would get the execution id from the event and from this you should be able to create a historicTaskInstance query based on the executionId.
Once you have the task, look to see if there is a parent task, if so, set the process variable.
Something of a long way around, but it should get you there.
Be aware, events are processed asynchronously which is why you need to use a history query rather than a runtime query because you cant guarantee order.