This is interesting, because when I look at the pending export in the sync engine, I see the atomic operations.
When I examine the arguments passed into the ExportEntry API call, I see a Replace at the top level, but nothing on the multi-valued attribute (member in this case).
[ExportEntry]
modificationType: Replace
changedAttributes: member
csentry: [Microsoft.MetadirectoryServices.Impl.CSEntryMAImpl] CS Role CN=ROLE-CRM-Test1
DN: CN=ROLE-CRM-Test1
ObjectClass: Microsoft.MetadirectoryServices.Impl.GenericValueCollection
ObjectType: Role
RDN: CN=ROLE-CRM-Test1
displayName [String] ROLE-CRM-Test1
member [Reference] CN=007528
CN=dev.userA
CN=dev.userB
CN=dev.userC
CN=dev.userD
CN=dev.userE
CN=dev.userF
(Wouldn't it be nice if you could just serialize the CSEntry object?)
So, I looked around on the forums, and sure enough, Markus confirms my observation:
"If members is in the list of changed attributes, the member attribute of the CSEntry contains the most recent value for this attribute.
"If you need to determine the individual change for each member, you need to calculate this. The ECMA doesn’t provide multi-valued attribute level changes."
I'd love to be proven wrong about this...