diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 9aafaad..3909f45 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -60,6 +60,7 @@ struct _GtkBuilderPrivate
 {
   gchar *domain;
   GHashTable *objects;
+  GHashTable *symbols;
   GSList *delayed_properties;
   GSList *signals;
   gchar *filename;
@@ -109,6 +110,8 @@ gtk_builder_init (GtkBuilder *builder)
   builder->priv->domain = NULL;
   builder->priv->objects = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   g_free, g_object_unref);
+  builder->priv->symbols = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                  g_free, NULL);
 }
 
 
@@ -125,6 +128,7 @@ gtk_builder_finalize (GObject *object)
   g_free (priv->filename);
   
   g_hash_table_destroy (priv->objects);
+  g_hash_table_destroy (priv->symbols);
 
   g_slist_foreach (priv->signals, (GFunc) _free_signal_info, NULL);
   g_slist_free (priv->signals);
@@ -955,6 +959,16 @@ typedef struct {
   gpointer data;
 } connect_args;
 
+
+void         
+gtk_builder_expose_symbol (GtkBuilder    *builder,
+	        	   const gchar   *symbol_name,
+			   gpointer       user_data)
+{
+  g_hash_table_insert (builder->priv->symbols, g_strdup (symbol_name), user_data);
+}
+
+
 static void
 gtk_builder_connect_signals_default (GtkBuilder    *builder,
 				     GObject       *object,
@@ -979,6 +993,26 @@ gtk_builder_connect_signals_default (GtkBuilder    *builder,
     g_signal_connect_data (object, signal_name, func, args->data, NULL, flags);
 }
 
+static void
+gtk_builder_connect_signals_data (GtkBuilder    *builder,
+				     GObject       *object,
+				     const gchar   *signal_name,
+				     const gchar   *handler_name,
+				     GConnectFlags  flags,
+				     gpointer       user_data)
+{
+  GCallback func;
+  connect_args *args = (connect_args*)user_data;
+  
+  if (!g_module_symbol (args->module, handler_name, (gpointer)&func))
+    {
+      g_warning ("Could not find signal handler '%s'", handler_name);
+      return;
+    }
+
+  g_signal_connect_data (object, signal_name, func, args->data, NULL, flags);
+}
+
 
 /**
  * gtk_builder_connect_signals:
@@ -1064,6 +1098,7 @@ gtk_builder_connect_signals_full (GtkBuilder            *builder,
   GSList *l;
   GObject *object;
   GObject *connect_object;
+  void *connect_data;
   
   g_return_if_fail (GTK_IS_BUILDER (builder));
   g_return_if_fail (func != NULL);
@@ -1084,19 +1119,37 @@ gtk_builder_connect_signals_full (GtkBuilder            *builder,
       g_assert (object != NULL);
 
       connect_object = NULL;
+      connect_data = NULL;
       
       if (signal->connect_object_name)
 	{
-	  connect_object = g_hash_table_lookup (builder->priv->objects,
-						signal->connect_object_name);
-	  if (!connect_object)
-	      g_warning ("Could not lookup object %s on signal %s of object %s",
-			 signal->connect_object_name, signal->name,
-			 signal->object_name);
-	}
-						  
-      func (builder, object, signal->name, signal->handler, 
-	    connect_object, signal->flags, user_data);
+          if (signal->external)
+            {
+               connect_data = g_hash_table_lookup (builder->priv->symbols,
+		  		                   signal->connect_object_name);
+               if (!connect_data)
+                 {
+                   g_warning ("External %s source not exposed!\n", signal->connect_object_name);
+                 } else {
+                   connect_args *args = (connect_args *)user_data;
+                   args->data = connect_data;
+                   gtk_builder_connect_signals_data (builder, object, signal->name, signal->handler, 
+                                      	             signal->flags, args);
+                 }
+            } else {
+              connect_object = g_hash_table_lookup (builder->priv->objects,
+						    signal->connect_object_name);
+              if (!connect_object)
+                g_warning ("Could not lookup object %s on signal %s of object %s.",
+  			            signal->connect_object_name, signal->name,
+			            signal->object_name);
+            }
+        }						  
+      if (connect_data == NULL)
+        {
+          func (builder, object, signal->name, signal->handler, 
+              	connect_object, signal->flags, user_data);
+        }
     }
 
   g_slist_foreach (builder->priv->signals, (GFunc)_free_signal_info, NULL);
diff --git a/gtk/gtkbuilder.h b/gtk/gtkbuilder.h
index 0f9224e..a9020ac 100644
--- a/gtk/gtkbuilder.h
+++ b/gtk/gtkbuilder.h
@@ -113,6 +113,9 @@ guint        gtk_builder_add_objects_from_string (GtkBuilder    *builder,
 GObject*     gtk_builder_get_object              (GtkBuilder    *builder,
                                                   const gchar   *name);
 GSList*      gtk_builder_get_objects             (GtkBuilder    *builder);
+void         gtk_builder_expose_symbol           (GtkBuilder    *builder,
+						  const gchar   *name,
+						  gpointer       user_data);
 void         gtk_builder_connect_signals         (GtkBuilder    *builder,
 						  gpointer       user_data);
 void         gtk_builder_connect_signals_full    (GtkBuilder    *builder,
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index b4f6855..bf54a5b 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -556,6 +556,7 @@ parse_signal (ParserData   *data,
   gboolean after = FALSE;
   gboolean swapped = FALSE;
   gboolean swapped_set = FALSE;
+  gboolean external = FALSE;
   ObjectInfo *object_info;
   int i;
 
@@ -583,6 +584,11 @@ parse_signal (ParserData   *data,
 	    return;
 	  swapped_set = TRUE;
 	}
+      else if (strcmp (names[i], "external") == 0)
+	{
+	  if (!_gtk_builder_boolean_from_string (values[i], &external, error))
+	    return;
+	}
       else if (strcmp (names[i], "object") == 0)
         object = g_strdup (values[i]);
       else if (strcmp (names[i], "last_modification_time") == 0)
@@ -617,6 +623,7 @@ parse_signal (ParserData   *data,
     info->flags |= G_CONNECT_AFTER;
   if (swapped)
     info->flags |= G_CONNECT_SWAPPED;
+  info->external = external;
   info->connect_object_name = object;
   state_push (data, info);
 
diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h
index e633a28..0033584 100644
--- a/gtk/gtkbuilderprivate.h
+++ b/gtk/gtkbuilderprivate.h
@@ -66,6 +66,7 @@ typedef struct {
   gchar *object_name;
   gchar *name;
   gchar *handler;
+  gboolean external;
   GConnectFlags flags;
   gchar *connect_object_name;
 } SignalInfo;
