public void PropertyChangedTest()
        {
            DocumentDataModel model = new DocumentDataModel();

            string[] watchedProperties = new string[] { "HasUnsavedData", "HasUndoData", "HasRedoData", "DocumentRoot", "ObservableDocumentRoot" };
            Dictionary <string, object> propertyValues    = new Dictionary <string, object>();
            HashSet <string>            changedProperties = new HashSet <string>();

            PropertyChangedEventHandler propChangedHandler = delegate(object sender, PropertyChangedEventArgs e)
            {
                Assert.AreSame(model, sender);
                changedProperties.Add(e.PropertyName);
            };

            ZeroArgDelegate prepare = delegate()
            {
                // Note old property values for later comparison.
                foreach (string prop in watchedProperties)
                {
                    propertyValues[prop] = model.GetType().GetProperty(prop).GetValue(model, null);
                }
                changedProperties.Clear();
            };

            ZeroArgDelegate verify = delegate()
            {
                // Verify that properties are unchanged, or that we were notified that they changed.
                foreach (string prop in watchedProperties)
                {
                    if (changedProperties.Contains(prop))
                    {
                        continue;                                   // We were notified of a change.
                    }
                    object oldValue = propertyValues[prop];
                    object newValue = model.GetType().GetProperty(prop).GetValue(model, null);
                    Assert.AreEqual(oldValue, newValue,
                                    "Property {0} changed without notification, from '{1}' to '{2}'",
                                    prop, oldValue, newValue);
                }
                DocumentDataModelInvariant(model);
            };

            model.PropertyChanged += propChangedHandler;


            prepare();
            model.New(new Size(100, 100), new Thickness(20));
            verify();
            // New should trigger updates on both DocumentRoot properties.
            Assert.IsTrue(changedProperties.Contains("DocumentRoot"));
            Assert.IsTrue(changedProperties.Contains("ObservableDocumentRoot"));

            prepare();
            model.AddShape(new XElement("Test"));
            verify();
            // A "deep" change of the document XML must not trigger updates on DocumentRoot, but only on ObservableDocumentRoot
            Assert.IsFalse(changedProperties.Contains("DocumentRoot"));
            Assert.IsTrue(changedProperties.Contains("ObservableDocumentRoot"));

            prepare();
            model.Undo();
            verify();
            // Undo should trigger updates on both DocumentRoot properties.
            Assert.IsTrue(changedProperties.Contains("DocumentRoot"));
            Assert.IsTrue(changedProperties.Contains("ObservableDocumentRoot"));

            prepare();
            model.Redo();
            verify();
            // Redo should trigger updates on both DocumentRoot properties.
            Assert.IsTrue(changedProperties.Contains("DocumentRoot"));
            Assert.IsTrue(changedProperties.Contains("ObservableDocumentRoot"));

            prepare();
            ((XElement)model.DocumentRoot.FirstNode).Name = "Test2";
            verify();
            // A "deep" change of the document XML must not trigger updates on DocumentRoot, but only on ObservableDocumentRoot
            Assert.IsFalse(changedProperties.Contains("DocumentRoot"));
            Assert.IsTrue(changedProperties.Contains("ObservableDocumentRoot"));

            // If we remove the handler, we should not get any notifications. :-)
            model.PropertyChanged -= propChangedHandler;
            prepare();
            model.Undo();

            Assert.AreEqual(0, changedProperties.Count); // No changes that we know of.
        }