Towards a better undo
Here is my growing theory: current versions of 'undo' functionality generally aren't all that good. Having any undo is a lot better than none, and having multi-level undo is a lot better than only a single level of it (to the point where it's hard for me to consider single level undo as 'undo' any more), but this is a long way from being really useful.
(The problem with single-level undo are hopefully obvious: it's only useful if you immediately realize your mistake. In practice this is unlikely to be the case, especially if the user is an expert with your program who is thus not constantly checking their work.)
The problem with multi-level undo for me is that it doesn't really do what I want to do. If I am going back more than a little bit, I generally don't want to actually reverse my changes; instead, what I want is to go back to look at an old version and maybe cherry-pick some things that I like from it. At the extreme, I want to branch my work in order to experiment with several alternatives. This is especially common with code, where I can often wind up doing experimental rewrites of routines or interfaces or the like (and sometimes the rewrites don't work out and I revert them).
Partly I think that this is an issue of bad interfaces; even with a 'redo', action by action undo makes moving back and forth significantly awkward, for example. I would probably be better served by an interface that has a time based slider (or just an older/newer slider in general). The ability to set marker points and jump back to them would be nice, too, as would the ability to see an old version and the current version at once (to make for easy cherry-picking and the like).
(You need a slider because I am only somewhat more likely to remember how many minutes ago the program looked right as I am to remember how many operations ago that was. A slider gives you a way to directly and rapidly manipulate things to zero in on where you want to be.)