As mentioned before, the underlying model was always correct, reflecting the changes made programmatically. What was wrong was that the index in all client IDs of the nested components was always 0. So, whenever there was a dynamic update, only the first element with this ID got updated (multiple times). Now, with all inner components having distinct client IDs, the dynamic updates are performed normally.
This solves the issue in the attached test app when modifying the model programmatically in a reordering (move) event request. However, after working on this issue, it was noticed that there hasn't never been support for programmatically modifying the model in a migrate event request. What happens right now in the test app in a migrate operation is that the model is modified programmatically, and it is updated correctly in the client, but the item that was migrated from the source list to the desitination list stays there in the destination list, even if the model was modified not to have that item. This is so, because in a dynamic update, the list items are updated individually, and not the whole list.
Since the beginning of this component, it was designed to have a significant amount of logic in the client, for efficiency purposes. So, in a migrate request, the markup of the migrated item in the client stays in the destination list, without having to update the markup from the server, because in the vast majority of use cases, a migrated item is meant to stay in the destination list and not be removed. If it's desired that a migrated item be removed programmatically in a migrate request, then the following workaround can be used:
In order to remove all items from the source list in the destination list, add the following ajax tag in the destination list:
<ace:ajax event="migrate" listener="#{bean.listener}" render="@all" onSuccess="ice.ace.jq(ice.ace.escapeClientId('<this list client ID>')).find('> ul > li').filter(function(){return this.id.indexOf('<this list client ID>') != 0;}).remove();"/>
This code (onSuccess) is executed after the response arrives to the client and before the markup is updated. What this code does is to remove all list items that don't start with the client ID of this list. If another result is desired, then it can be accomplished with some javascript code in the onSuccess attribute of the migrate ajax event.
Another possible workaround is to force a full markup update of the component on a migrate request that programmatically modifies the model. This can be accomplished by rendering a different style class name in the list component in the same listener that programmatically modifies the model. This style class can just be a number, like the current server time in milliseconds, and, of course, it doesn't have to be a style class defined in the client. This is just treated as a string for the domdiff to send a full markup update of the component.
Attached test case, showing the issue. It needs to be put under the /samples folder in the ICEfaces project.