remomo, you got it exactly right... :)
onion layers is a nice metaphor for stack (it really is :D), but still, WRAP / UNWRAP is a stack...
mikedee, if plugin1 plugin2 plugin3 are loaded in that order, and you want to unload plugin1, you have to first first unload plugin 3 and plugin 2 (in that order), or else the stack will get wrong (yes, it is a stack, and yes, core will actually unload plugin 3 and plugin 2 if it wants to unload plugin 1). after that, you of course load plugin 2 and plugin 3 again, so they aren't really "unloaded".
this was actually kind of a problem with group, when the user unlaoded any other plugin (not just group), all the groups informations was lost. we fixed that by storing the groups in xprops.
TBH, i don't like the way WRAP / UNWRAP works.
the main limitations are not being able to UWNRAP a plugin from the middle of the list (because reloading plugin 3 and plugin 2 are indeed quite redundant if you want to unload plugin 1), and not being able to recall the whole stack again.
the second point was again kind of a problem for us in group. when we move a grouped window, we want other windows to be moved, but we can't call moveWindow normally because not all plugins (or more specifically, plugins that are loaded after group) won't get the move notifies.
we fixed that by queuing the moves, and doing all th actual moves in preparePaintScreen - not the nicest solution if you ask me.
the original reason drawWindow was made and called by paintWindow was the second point (switcher wasn't able to draw decorations because it couldn't call the whole stack chain, so david decided to put decorations code in a different stack). TBH, sometimes separating between drawWindow and paintWindow is nice, but i'm not sure this was the best fix for the switcher + decorations problem.
in beryl we started to reimplement UNWRAP / WRAP by using linked lists to fix those 2 points, but unfortunately we never finished that patch and it was dropped... :\