Index: gtk/src/widget.hg
===================================================================
--- gtk/src/widget.hg	(revision 1131)
+++ gtk/src/widget.hg	(working copy)
@@ -640,6 +640,9 @@
   _WRAP_SIGNAL(void size_request(Requisition* requisition), "size_request")
   _WRAP_SIGNAL(void size_allocate(Allocation& allocation), "size_allocate")
 
+  virtual bool connect(Glib::ustring signal_name,
+	Glib::ustring handler_name, Glib::SlotsContainer& slots);
+
 // Changed signals -- inform widget of internal changes.
 // We rename parent_set => parent_changed 
 //  and      style_set  => style_changed 
Index: gtk/src/builder.hg
===================================================================
--- gtk/src/builder.hg	(revision 1131)
+++ gtk/src/builder.hg	(working copy)
@@ -48,6 +48,8 @@
  _IGNORE(gtk_builder_new)
 
 public:
+  _CUSTOM_DTOR
+
   /** Creates a new builder object. 
    */
   _WRAP_CREATE()
@@ -295,6 +297,19 @@
   //TODO: Custom-implement this and prevent it from being used with GTK_WIDGET-derived types?
   _WRAP_METHOD(Glib::RefPtr<Glib::Object> get_object(const Glib::ustring& name), gtk_builder_get_object, refreturn)
 
+  template <class T_Widget>
+  T_Widget *get_widget(const Glib::ustring& name)
+  {
+    // The dynamic_cast<> should never fail if get_widget_checked() succeeded.
+    T_Widget *widget = dynamic_cast<T_Widget*>
+	    (get_widget_checked(name, T_Widget::get_base_type()));
+
+    if(!widget)
+      g_critical("Gtk::Builder::get_widget(): dynamic_cast<> failed.");
+
+    return widget;
+  }
+
   /** Get a widget from the Builder file.
    * For instance:
    * @code
@@ -316,14 +331,33 @@
   template <class T_Widget> inline
   void get_widget(const Glib::ustring& name, T_Widget*& widget)
   {
-    // Initialize output parameter:
-    widget = 0;
+    widget = get_widget<T_Widget>(name);
+  }
 
-    // The dynamic_cast<> should never fail if get_widget_checked() succeeded.
-    widget = dynamic_cast<T_Widget*>(this->get_widget_checked(name, T_Widget::get_base_type()));
+  template <class T_Widget>
+  T_Widget *create_widget_derived(const Glib::ustring& name)
+  {
+     // Get the widget from the glade file.
+     typedef typename T_Widget::BaseObjectType cwidget_type;
+     cwidget_type* pCWidget = (cwidget_type*)get_cwidget(name);
 
-    if(!widget)
-      g_critical("Gtk::Builder::get_widget(): dynamic_cast<> failed.");
+     //The error was already reported by get_cwidget().
+     if(!pCWidget)
+       return NULL;
+
+     //Check whether there is already a C++ wrapper instance associated with this C instance:
+     Glib::ObjectBase* pObjectBase = ObjectBase::_get_current_wrapper((GObject*)pCWidget);
+
+     //If there is already a C++ instance, then return NULL
+     if(pObjectBase)
+       return NULL;
+
+     //Create a new C++ instance to wrap the existing C instance:
+     Glib::RefPtr<Gtk::Builder> refThis(this);
+     refThis->reference(); //take a copy.
+     T_Widget *widget = new T_Widget(pCWidget, refThis);
+     widget->reference(); //Because gtk_builder_get_object() does not give us a reference.
+     return widget;
   }
 
   /** This provides a pointer to a widget whose details are specified in the GtkBuilder file, but which is implemented
@@ -347,7 +381,7 @@
   {
      // Initialize output parameter:
      widget = 0;
-     
+
      // Get the widget from the GtkBuilder file.
      typedef typename T_Widget::BaseObjectType cwidget_type;
      cwidget_type* pCWidget = (cwidget_type*)get_cwidget(name);
@@ -374,25 +408,31 @@
      else
      {
        //Create a new C++ instance to wrap the existing C instance:
-       
-       //Set the output variable. We needed to do this because we can not template the return type.
-       Glib::RefPtr<Gtk::Builder> refThis(this);
-       refThis->reference(); //take a copy.
-       widget = new T_Widget(pCWidget, refThis);
-       widget->reference(); //Because gtk_builder_get_object() does not give us a reference.
+       widget = create_widget_derived<T_Widget>(name);
      }
   }
 
 
   //TODO:_WRAP_METHOD(GSList* get_objects(), gtk_builder_get_objects)
-  //_WRAP_METHOD(void connect_signals(gpointer       user_data), gtk_builder_connect_signals)
   //_WRAP_METHOD(void connect_signals_full(GtkBuilderConnectFunc func, gpointer       user_data), gtk_builder_connect_signals_full)
   _WRAP_METHOD(void set_translation_domain(const Glib::ustring& domain), gtk_builder_set_translation_domain)
   _WRAP_METHOD(Glib::ustring get_translation_domain() const, gtk_builder_get_translation_domain)
-  
+
   //We ignore gtk_builder_get_type_from_name() because it only seems useful when implementing GtkBuildable for widgets.
   _IGNORE(gtk_builder_get_type_from_name)
 
+  /* move this to the private header - how? */
+  struct SignalInfo {
+    Widget *widget;
+    gchar *signal_name;
+    gchar *handler_name;
+    bool connected;
+  };
+  typedef std::list<struct SignalInfo> SignalInfoList;
+  SignalInfoList siginfo;
+
+  void connect_signals(Glib::SlotsContainer& slots);
+
 protected:
   Gtk::Widget* get_widget_checked(const Glib::ustring& name, GType type);
   GtkWidget* get_cwidget(const Glib::ustring& name);
@@ -410,4 +450,3 @@
 };
 
 } // namespace Gtk
-
Index: gtk/src/button.ccg
===================================================================
--- gtk/src/button.ccg	(revision 1131)
+++ gtk/src/button.ccg	(working copy)
@@ -37,5 +37,26 @@
   _CONSTRUCT("use_stock", 1, "label", stock_id.get_c_str())
 {}
 
+bool Button::connect(Glib::ustring signal_name,
+	Glib::ustring handler_name, Glib::SlotsContainer& slots)
+{
+#define CONNECT_SIG(sig, sig_name, handler_name) \
+  do { \
+    if (sig_name == __STRING(sig)) { \
+      return slots.connect(signal_##sig(), handler_name); \
+    } \
+  } while (0)
+#define DO_CONNECT(sig) CONNECT_SIG(sig, signal_name, handler_name)
+
+  DO_CONNECT(clicked);
+  DO_CONNECT(released);
+  DO_CONNECT(clicked);
+  DO_CONNECT(enter);
+  DO_CONNECT(leave);
+  DO_CONNECT(activate);
+
+  return false;
+}
+
 } // namespace Gtk
 
Index: gtk/src/button.hg
===================================================================
--- gtk/src/button.hg	(revision 1131)
+++ gtk/src/button.hg	(working copy)
@@ -79,6 +79,9 @@
   _WRAP_METHOD(void enter(), gtk_button_enter)
   _WRAP_METHOD(void leave(), gtk_button_leave)
 
+  bool connect(Glib::ustring signal_name,
+	Glib::ustring handler_name, Glib::SlotsContainer& slots);
+
   _WRAP_METHOD(void set_relief(ReliefStyle newstyle), gtk_button_set_relief)
   _WRAP_METHOD(ReliefStyle get_relief() const, gtk_button_get_relief)
 
Index: gtk/src/widget.ccg
===================================================================
--- gtk/src/widget.ccg	(revision 1131)
+++ gtk/src/widget.ccg	(working copy)
@@ -576,6 +576,11 @@
   return Glib::wrap((GdkPixmapObject*)(gtk_widget_get_snapshot(const_cast<GtkWidget*>(gobj()), NULL)));
 }
 
+bool Widget::connect(Glib::ustring signal_name,
+	Glib::ustring handler_name, Glib::SlotsContainer& slots)
+{
+  return false;
+}
 
 } // namespace Gtk
 
Index: gtk/src/builder.ccg
===================================================================
--- gtk/src/builder.ccg	(revision 1131)
+++ gtk/src/builder.ccg	(working copy)
@@ -291,7 +291,46 @@
 }
 
 
+static void connect_signals_private(GtkBuilder *builder,
+	GObject *object, const gchar *signal_name, const gchar *handler_name,
+	GObject *connect_object, GConnectFlags flags, gpointer user_data)
+{
+  Gtk::Builder::SignalInfoList *list =
+	(Gtk::Builder::SignalInfoList *)user_data;
+  /* gtk_builder_connect_signals_full() destroys all the signal-related
+   * data, so we need to g_strdup() the strings. */
+  list->push_back((struct Gtk::Builder::SignalInfo){
+	Glib::wrap(GTK_WIDGET(object)),
+	g_strdup(signal_name), g_strdup(handler_name), false });
+}
 
+void Builder::connect_signals(Glib::SlotsContainer& slots)
+{
+  if (siginfo.empty())
+    gtk_builder_connect_signals_full(gobj(),
+	connect_signals_private, &siginfo);
+  for (SignalInfoList::iterator it = siginfo.begin();
+	it != siginfo.end(); it++) {
+    if (!slots.have_slot(it->handler_name))
+      continue;
+    if (it->connected)
+      continue;
+    it->connected = it->widget->connect(it->signal_name,
+	    it->handler_name, slots);
+    if (!it->connected)
+      g_warning("Cannot connect signal %s to %s\n",
+    	it->signal_name, it->handler_name);
+  }
+}
 
+Builder::~Builder(void)
+{
+  for (SignalInfoList::iterator it = siginfo.begin();
+	it != siginfo.end(); it++) {
+    g_free(it->signal_name);
+    g_free(it->handler_name);
+  }
+}
+
 } // namespace Gtk
 
