a) ->traverseNode() now operates on a clone of the node, otherwise the original node will be modified too
b) before nodes were passed to the following visitor unchanged, even though they were already changed in the tree
Instead manually implement IteratorAggregate and define the required magic methods. The reasoning behind this is:
a) Extending ArrayObject is always risky, because a lot of magic which is known to be buggy is involved
b) This allows to lateron change the implementation for the nodes altogether, for example it could be changed to using real public fields instead of a $subNodes array.