Well, in the end you have to keep a record of previous states. I've seen lots of ways of doing it, but I like something similar to VariantRecords myself. Basically, a header record and then records for each "Message" type. The header contains an ID for the message type. When I write the message I record its type, when I read it, I read the message type back in and pass it out (thus allowing me to add messages quite quickly).

Also, I use a stack of N (an array) to record my undo actions. Simply record the Max top item (incase you want redo), and a stack pointer at the current state. Walk the stack either way to perform the actions (undo or redo). This is nice, as I can write the undo stack into the data file for use when the user re-loads the actual data file. Of course, you can strip the info to shrink the data file size.

Anyways, there is my answer