Index: gtk/gtkbuilderprivate.h
===================================================================
--- gtk/gtkbuilderprivate.h	(revision 18171)
+++ gtk/gtkbuilderprivate.h	(working copy)
@@ -91,6 +91,8 @@
   const gchar *filename;
   GSList *finalizers;
   GSList *custom_finalizers;
+  const gchar *build_root;
+  gboolean inside_build_tree;
 } ParserData;
 
 typedef GType (*GTypeGetFunc) (void);
Index: gtk/gtkbuilderparser.c
===================================================================
--- gtk/gtkbuilderparser.c	(revision 18171)
+++ gtk/gtkbuilderparser.c	(working copy)
@@ -208,6 +208,11 @@
       return;
     }
 
+  if (data->build_root != NULL && g_str_equal(object_id, data->build_root))
+    {
+      data->inside_build_tree = TRUE;
+    }
+
   object_info = g_slice_new0 (ObjectInfo);
   object_info->class_name = object_class;
   object_info->id = object_id;
@@ -301,7 +306,8 @@
 
   child_info->parent = (CommonInfo*)object_info;
 
-  object_info->object = builder_construct (data, object_info);
+  if (data->inside_build_tree)
+    object_info->object = builder_construct (data, object_info);
 }
 
 static void
@@ -527,7 +533,7 @@
   
   if (!strcmp (data->subparser->start, element_name) == 0)
     return;
-    
+
   gtk_buildable_custom_tag_end (GTK_BUILDABLE (data->subparser->object),
 				data->builder,
 				data->subparser->child,
@@ -565,10 +571,14 @@
   if (strcmp (parent_info->tag.name, "object") == 0)
     {
       ObjectInfo* object_info = (ObjectInfo*)parent_info;
-      if (!object_info->object)
-	object_info->object = _gtk_builder_construct (data->builder,
-						      object_info);
-      g_assert (object_info->object);
+
+      if (!object_info->object && data->inside_build_tree)
+        {
+          object_info->object = _gtk_builder_construct (data->builder,
+  						      object_info);
+          g_assert (object_info->object);
+        }
+
       object = object_info->object;
       child = NULL;
     }
@@ -576,13 +586,21 @@
     {
       ChildInfo* child_info = (ChildInfo*)parent_info;
       
-      _gtk_builder_add (data->builder, child_info);
+      if (data->inside_build_tree)
+        _gtk_builder_add (data->builder, child_info);
       
       object = ((ObjectInfo*)child_info->parent)->object;
       child  = child_info->object;
     }
   else
     return FALSE;
+  
+  /* We can't parse custom tags if we are building only part of the tree
+   * since we'd need to instantiate the object, so we simply state that this
+   * custom tag has been handled without actually validating it
+   */
+  if (!data->inside_build_tree)
+    return TRUE;
 
   if (!gtk_buildable_custom_tag_start (GTK_BUILDABLE (object),
 				       data->builder,
@@ -612,8 +630,7 @@
 {
   ParserData *data = (ParserData*)user_data;
 
-#ifdef GTK_ENABLE_DEBUG
-  if (gtk_debug_flags & GTK_DEBUG_BUILDER)
+  GTK_NOTE (BUILDER,
     {
       GString *tags = g_string_new ("");
       int i;
@@ -627,8 +644,15 @@
         }
       g_print ("<%s%s>\n", element_name, tags->str);
       g_string_free (tags, TRUE);
+
+      if (data->build_root != NULL)
+        {
+          g_print("%sside buildroot\n",
+                  data->inside_build_tree ? "In" : "Out");
+        }
+
     }
-#endif
+  );
 
   if (!data->last_element && strcmp (element_name, "interface") != 0)
     {
@@ -692,14 +716,21 @@
       ObjectInfo *object_info = state_pop_info (data, ObjectInfo);
       ChildInfo* child_info = state_peek_info (data, ChildInfo);
 
-      object_info->object = builder_construct (data, object_info);
+      if (data->inside_build_tree)
+        object_info->object = builder_construct (data, object_info);
 
       if (child_info)
         child_info->object = object_info->object;
 
-      if (GTK_IS_BUILDABLE (object_info->object) &&
+      if (object_info->object != NULL &&
+          GTK_IS_BUILDABLE (object_info->object) &&
           GTK_BUILDABLE_GET_IFACE (object_info->object)->parser_finished)
         data->finalizers = g_slist_prepend (data->finalizers, object_info->object);
+
+      if (data->build_root != NULL
+          && strcmp(data->build_root, object_info->id) == 0)
+        data->inside_build_tree = FALSE;
+
       free_object_info (object_info);
     }
   else if (strcmp (element_name, "property") == 0)
@@ -714,14 +745,15 @@
           object_info->properties =
             g_slist_prepend (object_info->properties, prop_info);
         }
-      else
+      else if (data->inside_build_tree)
         g_assert_not_reached ();
     }
   else if (strcmp (element_name, "child") == 0)
     {
       ChildInfo *child_info = state_pop_info (data, ChildInfo);
 
-      _gtk_builder_add (data->builder, child_info);
+      if (data->inside_build_tree)
+        _gtk_builder_add (data->builder, child_info);
 
       free_child_info (child_info);
     }
@@ -739,7 +771,7 @@
   else if (strcmp (element_name, "placeholder") == 0)
     {
     }
-  else
+  else if (data->inside_build_tree)
     {
       g_assert_not_reached ();
     }
@@ -812,6 +844,9 @@
   data->ctx = g_markup_parse_context_new (
                   &parser, G_MARKUP_TREAT_CDATA_AS_TEXT, data, NULL);
 
+  data->build_root = getenv("GTK_BUILDER_BUILD_ROOT");
+  data->inside_build_tree = data->build_root != NULL ? FALSE : TRUE;
+
   if (!g_markup_parse_context_parse (data->ctx, buffer, length, error))
     goto out;
   
