--- glib/glibmm.h.old	2008-08-04 23:00:39.000000000 +0400
+++ glib/glibmm.h	2009-03-11 14:16:07.000000000 +0300
@@ -61,6 +61,7 @@
 #include <glibmm/shell.h>
 #include <glibmm/signalproxy_connectionnode.h>
 #include <glibmm/signalproxy.h>
+#include <glibmm/slotscontainer.h>
 #include <glibmm/slisthandle.h>
 #include <glibmm/spawn.h>
 #include <glibmm/stringutils.h>
--- glib/src/Makefile.in.old	2009-03-11 14:04:15.000000000 +0300
+++ glib/src/Makefile.in	2009-03-11 13:24:14.000000000 +0300
@@ -213,7 +213,8 @@
 files_win32_hg = 
 files_general_hg = checksum.hg convert.hg date.hg fileutils.hg iochannel.hg keyfile.hg markup.hg \
                    module.hg optioncontext.hg optionentry.hg optiongroup.hg regex.hg \
-                   shell.hg spawn.hg thread.hg nodetree.hg unicode.hg uriutils.hg
+                   shell.hg spawn.hg thread.hg nodetree.hg unicode.hg uriutils.hg \
+                   slotscontainer.hg
 
 files_general_deprecated_hg = 
 files_all_hg = \
--- glib/src/Makefile_list_of_hg.am_fragment.old	2008-08-04 23:00:39.000000000 +0400
+++ glib/src/Makefile_list_of_hg.am_fragment	2009-03-11 13:24:04.000000000 +0300
@@ -7,7 +7,8 @@
 files_win32_hg =
 files_general_hg = checksum.hg convert.hg date.hg fileutils.hg iochannel.hg keyfile.hg markup.hg \
                    module.hg optioncontext.hg optionentry.hg optiongroup.hg regex.hg \
-                   shell.hg spawn.hg thread.hg nodetree.hg unicode.hg uriutils.hg
+                   shell.hg spawn.hg thread.hg nodetree.hg unicode.hg uriutils.hg \
+                   slotscontainer.hg
 files_general_deprecated_hg =
 
 include $(top_srcdir)/build_shared/Makefile_build_gensrc.am_fragment 
--- /dev/null	2009-03-11 11:50:45.993007025 +0300
+++ glib/src/slotscontainer.ccg	2009-03-11 13:49:04.000000000 +0300
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+namespace Glib
+{
+
+SlotsContainer::~SlotsContainer(void)
+{
+  for (std::map<ustring, sigc::slot_base*>::iterator it =
+	slot_map.begin(); it != slot_map.end(); it++) {
+    delete it->second;
+  }
+  slot_map.clear();
+}
+
+} // namespace Glib
--- /dev/null	2009-03-11 11:50:45.993007025 +0300
+++ glib/src/slotscontainer.hg	2009-03-11 13:48:55.000000000 +0300
@@ -0,0 +1,93 @@
+/* Copyright (C) 2002 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+_DEFS(glibmm,glib)
+
+#include <glibmm/exception.h>
+#include <glibmm/error.h>
+#include <glibmm/ustring.h>
+#include <map>
+#include <sigc++/slot.h>
+
+namespace Glib
+{
+
+class NoSlotException : public Exception
+{
+public:
+  NoSlotException(const ustring& name) { str = name; }
+  virtual ~NoSlotException(void) throw() {}
+  virtual ustring what() const
+  {
+    return str;
+  }
+
+protected:
+  ustring str;
+};
+
+class SlotsContainer
+{
+public:
+
+  virtual ~SlotsContainer(void);
+
+  template <class T_class>
+  T_class get_slot(const ustring name)
+  {
+    if (slot_map.empty())
+	__init_slots();
+    std::map<ustring, sigc::slot_base*>::iterator it =
+	    slot_map.find(name);
+    if (it == slot_map.end())
+	throw NoSlotException(name);
+    T_class *sl = dynamic_cast<T_class*>(it->second);
+    if (!sl)
+	throw Error(g_quark_from_static_string("wrong_handler_type"), -1,
+		"Wrong handler type");
+    return *sl;
+  }
+
+  template <class T_sig>
+  void connect(T_sig sig, const ustring& name)
+  {
+    sig.connect(get_slot<typename T_sig::SlotType>(name));
+  }
+
+  template <typename T_ret, class T_class>
+  void register_slot(const ustring& name,
+	T_ret(T_class::*handler)(void))
+  {
+    T_class *self = dynamic_cast<T_class*>(this);
+    g_assert(self);
+    slot_map[name] = new sigc::slot<T_ret>(sigc::mem_fun(*self, handler));
+  }
+  template <typename T_ret, class T_class, typename T_arg>
+  void register_slot(const ustring& name,
+	T_ret(T_class::*handler)(T_arg))
+  {
+    T_class *self = dynamic_cast<T_class*>(this);
+    g_assert(self);
+    slot_map[name] = new sigc::slot<T_ret, T_arg>(sigc::mem_fun(*self, handler));
+  }
+
+protected:
+  virtual void __init_slots(void) = 0;
+  std::map<ustring, sigc::slot_base*> slot_map;
+};
+
+} // namespace Glib
--- glib/glibmm/Makefile.am.old	2008-08-04 23:00:39.000000000 +0400
+++ glib/glibmm/Makefile.am	2009-03-11 14:19:44.000000000 +0300
@@ -36,6 +36,7 @@
   random.cc \
   signalproxy.cc \
   signalproxy_connectionnode.cc  \
+  slotscontainer.cc \
   streamiochannel.cc \
   stringutils.cc \
   threadpool.cc \
@@ -82,6 +83,7 @@
   refptr.h \
   sarray.h \
   signalproxy_connectionnode.h  \
+  slotscontainer.h \
   slisthandle.h \
   streamiochannel.h \
   stringutils.h \
--- glib/glibmm/Makefile.in.old	2009-03-11 14:16:19.000000000 +0300
+++ glib/glibmm/Makefile.in	2009-03-11 14:20:00.000000000 +0300
@@ -94,7 +94,7 @@
 	exception.lo exceptionhandler.lo init.lo interface.lo main.lo \
 	miscutils.lo object.lo objectbase.lo pattern.lo property.lo \
 	propertyproxy.lo propertyproxy_base.lo quark.lo random.lo \
-	signalproxy.lo signalproxy_connectionnode.lo \
+	signalproxy.lo signalproxy_connectionnode.lo slotscontainer.lo \
 	streamiochannel.lo stringutils.lo threadpool.lo timer.lo \
 	timeval.lo ustring.lo utility.lo value.lo value_custom.lo \
 	wrap.lo value_basictypes.lo
@@ -276,10 +276,10 @@
 	init.cc interface.cc main.cc miscutils.cc object.cc \
 	objectbase.cc pattern.cc property.cc propertyproxy.cc \
 	propertyproxy_base.cc quark.cc random.cc signalproxy.cc \
-	signalproxy_connectionnode.cc streamiochannel.cc \
-	stringutils.cc threadpool.cc timer.cc timeval.cc ustring.cc \
-	utility.cc value.cc value_custom.cc wrap.cc \
-	value_basictypes.cc
+	signalproxy_connectionnode.cc slotscontainer.cc \
+	streamiochannel.cc stringutils.cc threadpool.cc timer.cc \
+	timeval.cc ustring.cc utility.cc value.cc value_custom.cc \
+	wrap.cc value_basictypes.cc
 sublib_files_extra_posix_h = 
 sublib_files_extra_win32_h = 
 sublib_files_extra_general_h = arrayhandle.h class.h \
@@ -289,10 +289,10 @@
 	listhandle.h main.h miscutils.h object.h objectbase.h \
 	pattern.h priorities.h property.h propertyproxy.h \
 	propertyproxy_base.h quark.h random.h refptr.h sarray.h \
-	signalproxy_connectionnode.h slisthandle.h streamiochannel.h \
-	stringutils.h threadpool.h timer.h timeval.h ustring.h \
-	utility.h value.h value_custom.h wrap.h signalproxy.h \
-	value_basictypes.h
+	signalproxy_connectionnode.h slotscontainer.h slisthandle.h \
+	streamiochannel.h stringutils.h threadpool.h timer.h timeval.h \
+	ustring.h utility.h value.h value_custom.h wrap.h \
+	signalproxy.h value_basictypes.h
 files_posix_hg = 
 files_win32_hg = 
 files_general_hg = checksum.hg convert.hg date.hg fileutils.hg iochannel.hg keyfile.hg markup.hg \
--- /dev/null	2009-03-11 11:50:45.993007025 +0300
+++ glib/glibmm/private/slotscontainer_p.h	2009-03-11 13:35:46.000000000 +0300
@@ -0,0 +1,8 @@
+// -*- c++ -*-
+// Generated by gtkmmproc -- DO NOT MODIFY!
+#ifndef _GLIBMM_SLOTSCONTAINER_P_H
+#define _GLIBMM_SLOTSCONTAINER_P_H
+
+
+#endif /* _GLIBMM_SLOTSCONTAINER_P_H */
+
--- /dev/null	2009-03-11 11:50:45.993007025 +0300
+++ glib/glibmm/slotscontainer.cc	2009-03-11 13:49:11.000000000 +0300
@@ -0,0 +1,42 @@
+// Generated by gtkmmproc -- DO NOT MODIFY!
+
+
+#include <glibmm/slotscontainer.h>
+#include <glibmm/private/slotscontainer_p.h>
+
+/* Copyright (C) 2002 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+namespace Glib
+{
+
+SlotsContainer::~SlotsContainer(void)
+{
+  for (std::map<ustring, sigc::slot_base*>::iterator it =
+	slot_map.begin(); it != slot_map.end(); it++) {
+    delete it->second;
+  }
+  slot_map.clear();
+}
+
+} // namespace Glib
+
+namespace
+{
+} // anonymous namespace
+
+
--- /dev/null	2009-03-11 11:50:45.993007025 +0300
+++ glib/glibmm/slotscontainer.h	2009-03-11 13:49:11.000000000 +0300
@@ -0,0 +1,102 @@
+// -*- c++ -*-
+// Generated by gtkmmproc -- DO NOT MODIFY!
+#ifndef _GLIBMM_SLOTSCONTAINER_H
+#define _GLIBMM_SLOTSCONTAINER_H
+
+
+/* Copyright (C) 2002 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <glibmm/exception.h>
+#include <glibmm/error.h>
+#include <glibmm/ustring.h>
+#include <map>
+#include <sigc++/slot.h>
+
+namespace Glib
+{
+
+class NoSlotException : public Exception
+{
+public:
+  NoSlotException(const ustring& name) { str = name; }
+  virtual ~NoSlotException(void) throw() {}
+  virtual ustring what() const
+  {
+    return str;
+  }
+
+protected:
+  ustring str;
+};
+
+class SlotsContainer
+{
+public:
+
+  virtual ~SlotsContainer(void);
+
+  template <class T_class>
+  T_class get_slot(const ustring name)
+  {
+    if (slot_map.empty())
+	__init_slots();
+    std::map<ustring, sigc::slot_base*>::iterator it =
+	    slot_map.find(name);
+    if (it == slot_map.end())
+	throw NoSlotException(name);
+    T_class *sl = dynamic_cast<T_class*>(it->second);
+    if (!sl)
+	throw Error(g_quark_from_static_string("wrong_handler_type"), -1,
+		"Wrong handler type");
+    return *sl;
+  }
+
+  template <class T_sig>
+  void connect(T_sig sig, const ustring& name)
+  {
+    sig.connect(get_slot<typename T_sig::SlotType>(name));
+  }
+
+  template <typename T_ret, class T_class>
+  void register_slot(const ustring& name,
+	T_ret(T_class::*handler)(void))
+  {
+    T_class *self = dynamic_cast<T_class*>(this);
+    g_assert(self);
+    slot_map[name] = new sigc::slot<T_ret>(sigc::mem_fun(*self, handler));
+  }
+  template <typename T_ret, class T_class, typename T_arg>
+  void register_slot(const ustring& name,
+	T_ret(T_class::*handler)(T_arg))
+  {
+    T_class *self = dynamic_cast<T_class*>(this);
+    g_assert(self);
+    slot_map[name] = new sigc::slot<T_ret, T_arg>(sigc::mem_fun(*self, handler));
+  }
+
+protected:
+  virtual void __init_slots(void) = 0;
+  std::map<ustring, sigc::slot_base*> slot_map;
+};
+
+} // namespace Glib
+
+
+#endif /* _GLIBMM_SLOTSCONTAINER_H */
+
