+Stateful::add_properties (XMLNode& owner_state)
+{
+ for (OwnedPropertyList::iterator i = _properties->begin(); i != _properties->end(); ++i) {
+ i->second->get_value (owner_state);
+ }
+}
+
+void
+Stateful::add_property (PropertyBase& s)
+{
+ _properties->add (s);
+}
+
+void
+Stateful::send_change (const PropertyChange& what_changed)
+{
+ if (what_changed.empty()) {
+ return;
+ }
+
+ {
+ Glib::Mutex::Lock lm (_lock);
+ if (_frozen) {
+ _pending_changed.add (what_changed);
+ return;
+ }
+ }
+
+ PropertyChanged (what_changed);
+}
+
+void
+Stateful::suspend_property_changes ()
+{
+ _frozen++;
+}
+
+void
+Stateful::resume_property_changes ()
+{
+ PropertyChange what_changed;
+
+ {
+ Glib::Mutex::Lock lm (_lock);
+
+ if (_frozen && --_frozen > 0) {
+ return;
+ }
+
+ if (!_pending_changed.empty()) {
+ what_changed = _pending_changed;
+ _pending_changed.clear ();
+ }
+ }
+
+ mid_thaw (what_changed);
+
+ send_change (what_changed);
+}
+
+bool
+Stateful::changed() const
+{
+ for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
+ if (i->second->changed()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+Stateful::apply_changes (const PropertyBase& prop)
+{
+ OwnedPropertyList::iterator i = _properties->find (prop.property_id());
+ if (i == _properties->end()) {
+ return false;
+ }
+
+ i->second->apply_changes (&prop);
+ return true;
+}
+
+PropertyList*
+Stateful::property_factory (const XMLNode& history_node) const
+{
+ PropertyList* prop_list = new PropertyList;
+
+ for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
+ PropertyBase* prop = i->second->clone_from_xml (history_node);
+
+ if (prop) {
+ prop_list->add (prop);
+ }
+ }
+
+ return prop_list;
+}
+
+void
+Stateful::rdiff (vector<Command*>& cmds) const
+{
+ for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
+ i->second->rdiff (cmds);
+ }
+}
+
+void
+Stateful::clear_owned_changes ()