void CompareNodeChildren(IMetadataObject original, IMetadataObject @new, IList<MetadataTreeEntryChanges> changes, Stack<string> stack, ChildPropertyInfo childProperty)
 {
     using (var enumerator = new TwoSequenceEnumerator<IMetadataObject>(
         childProperty.Accessor(original),
         childProperty.Accessor(@new)))
     {
         while (!enumerator.BothCompleted)
         {
             CompareNodeChildren(changes, stack, enumerator);
         }
     }
 }
        void CompareNodeChildren(IList<MetadataTreeEntryChanges> changes, Stack<string> stack, TwoSequenceEnumerator<IMetadataObject> enumerator)
        {
            if (enumerator.NodeIsStillThere)
            {
                stack.Push(enumerator.Left.Id.ToString());
                CompareNode(enumerator.Left, enumerator.Right, changes, stack);
                stack.Pop();

                enumerator.MoveNextLeft();
                enumerator.MoveNextRight();
                return;
            }
            else if (enumerator.NodeHasBeenAdded)
            {
                stack.Push(enumerator.Right.Id.ToString());
                var path = stack.ToDataPath();
                changes.Add(new MetadataTreeEntryChanges(path, ChangeKind.Added, @new: enumerator.Right));
                stack.Pop();
                enumerator.MoveNextRight();
                return;
            }
            else if (enumerator.NodeHasBeenRemoved)
            {
                stack.Push(enumerator.Left.Id.ToString());
                RemoveNode(enumerator.Left, changes, stack);
                stack.Pop();
                enumerator.MoveNextLeft();
                return;
            }
            throw new NotSupportedException("Unexpected child changes.");
        }