diff --git a/gobject/Makefile.am b/gobject/Makefile.am
index 593498d..8ec4ee7 100644
--- a/gobject/Makefile.am
+++ b/gobject/Makefile.am
@@ -109,7 +109,9 @@ gobject_public_h_sources = \
 	gmarshal.h
 
 # GObject library header files that don't get installed
-gobject_private_h_sources = 
+gobject_private_h_sources = \
+	gtype-private.h
+
 # GObject library C sources to build the library from
 gobject_c_sources = \
 	gboxed.c		\
diff --git a/gobject/gboxed.c b/gobject/gboxed.c
index e3a6170..4425b3b 100644
--- a/gobject/gboxed.c
+++ b/gobject/gboxed.c
@@ -22,7 +22,7 @@
 #include <string.h>
 
 #include "gboxed.h"
-#include "gbsearcharray.h"
+#include "gtype-private.h"
 #include "gvalue.h"
 #include "gvaluearray.h"
 #include "gclosure.h"
@@ -46,39 +46,6 @@
  * based libraries.
  */
 
-/* --- typedefs & structures --- */
-typedef struct
-{
-  GType		 type;
-  GBoxedCopyFunc copy;
-  GBoxedFreeFunc free;
-} BoxedNode;
-
-
-/* --- prototypes --- */
-static gint	boxed_nodes_cmp		(gconstpointer	p1,
-					 gconstpointer	p2);
-
-
-/* --- variables --- */
-static GBSearchArray *boxed_bsa = NULL;
-static const GBSearchConfig boxed_bconfig = {
-  sizeof (BoxedNode),
-  boxed_nodes_cmp,
-  0,
-};
-
-
-/* --- functions --- */
-static gint
-boxed_nodes_cmp	(gconstpointer p1,
-		 gconstpointer p2)
-{
-  const BoxedNode *node1 = p1, *node2 = p2;
-
-  return G_BSEARCH_ARRAY_CMP (node1->type, node2->type);
-}
-
 static inline void              /* keep this function in sync with gvalue.c */
 value_meminit (GValue *value,
 	       GType   value_type)
@@ -129,8 +96,6 @@ g_boxed_type_init (void)
   const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, };
   GType type;
 
-  boxed_bsa = g_bsearch_array_create (&boxed_bconfig);
-
   /* G_TYPE_BOXED
    */
   type = g_type_register_fundamental (G_TYPE_BOXED, g_intern_static_string ("GBoxed"), &info, &finfo,
@@ -317,13 +282,7 @@ static void
 boxed_proxy_value_free (GValue *value)
 {
   if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
-    {
-      BoxedNode key, *node;
-
-      key.type = G_VALUE_TYPE (value);
-      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
-      node->free (value->data[0].v_pointer);
-    }
+    _g_type_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer);
 }
 
 static void
@@ -331,13 +290,7 @@ boxed_proxy_value_copy (const GValue *src_value,
 			GValue       *dest_value)
 {
   if (src_value->data[0].v_pointer)
-    {
-      BoxedNode key, *node;
-
-      key.type = G_VALUE_TYPE (src_value);
-      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
-      dest_value->data[0].v_pointer = node->copy (src_value->data[0].v_pointer);
-    }
+    dest_value->data[0].v_pointer = _g_type_boxed_copy (G_VALUE_TYPE (src_value), src_value->data[0].v_pointer);
   else
     dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
 }
@@ -354,11 +307,6 @@ boxed_proxy_collect_value (GValue      *value,
 			   GTypeCValue *collect_values,
 			   guint        collect_flags)
 {
-  BoxedNode key, *node;
-
-  key.type = G_VALUE_TYPE (value);
-  node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
-
   if (!collect_values[0].v_pointer)
     value->data[0].v_pointer = NULL;
   else
@@ -369,7 +317,7 @@ boxed_proxy_collect_value (GValue      *value,
 	  value->data[1].v_uint = G_VALUE_NOCOPY_CONTENTS;
 	}
       else
-	value->data[0].v_pointer = node->copy (collect_values[0].v_pointer);
+	value->data[0].v_pointer = _g_type_boxed_copy (G_VALUE_TYPE (value), collect_values[0].v_pointer);
     }
 
   return NULL;
@@ -391,13 +339,7 @@ boxed_proxy_lcopy_value (const GValue *value,
   else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
     *boxed_p = value->data[0].v_pointer;
   else
-    {
-      BoxedNode key, *node;
-
-      key.type = G_VALUE_TYPE (value);
-      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
-      *boxed_p = node->copy (value->data[0].v_pointer);
-    }
+    *boxed_p = _g_type_boxed_copy (G_VALUE_TYPE (value), value->data[0].v_pointer);
 
   return NULL;
 }
@@ -429,7 +371,7 @@ g_boxed_type_register_static (const gchar   *name,
     "p",
     boxed_proxy_lcopy_value,
   };
-  static const GTypeInfo type_info = {
+  GTypeInfo type_info = {
     0,			/* class_size */
     NULL,		/* base_init */
     NULL,		/* base_finalize */
@@ -452,14 +394,7 @@ g_boxed_type_register_static (const gchar   *name,
 
   /* install proxy functions upon successfull registration */
   if (type)
-    {
-      BoxedNode key;
-
-      key.type = type;
-      key.copy = boxed_copy;
-      key.free = boxed_free;
-      boxed_bsa = g_bsearch_array_insert (boxed_bsa, &boxed_bconfig, &key);
-    }
+    _g_type_boxed_init (type, boxed_copy, boxed_free);
 
   return type;
 }
@@ -490,13 +425,7 @@ g_boxed_copy (GType         boxed_type,
 
   /* check if our proxying implementation is used, we can short-cut here */
   if (value_table->value_copy == boxed_proxy_value_copy)
-    {
-      BoxedNode key, *node;
-
-      key.type = boxed_type;
-      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
-      dest_boxed = node->copy ((gpointer) src_boxed);
-    }
+    dest_boxed = _g_type_boxed_copy (boxed_type, (gpointer) src_boxed);
   else
     {
       GValue src_value, dest_value;
@@ -554,13 +483,7 @@ g_boxed_free (GType    boxed_type,
 
   /* check if our proxying implementation is used, we can short-cut here */
   if (value_table->value_free == boxed_proxy_value_free)
-    {
-      BoxedNode key, *node;
-
-      key.type = boxed_type;
-      node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
-      node->free (boxed);
-    }
+    _g_type_boxed_free (boxed_type, boxed);
   else
     {
       GValue value;
@@ -611,13 +534,10 @@ g_value_dup_boxed (const GValue *value)
 
 static inline void
 value_set_boxed_internal (GValue       *value,
-			  gconstpointer const_boxed,
+			  gconstpointer boxed,
 			  gboolean      need_copy,
 			  gboolean      need_free)
 {
-  BoxedNode key, *node;
-  gpointer boxed = (gpointer) const_boxed;
-
   if (!boxed)
     {
       /* just resetting to NULL might not be desired, need to
@@ -629,27 +549,10 @@ value_set_boxed_internal (GValue       *value,
       return;
     }
 
-  key.type = G_VALUE_TYPE (value);
-  node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key);
-
-  if (node)
-    {
-      /* we proxy this type, free contents and copy right away */
-      if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
-	node->free (value->data[0].v_pointer);
-      value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS;
-      value->data[0].v_pointer = need_copy ? node->copy (boxed) : boxed;
-    }
-  else
-    {
-      /* we don't handle this type, free contents and let g_boxed_copy()
-       * figure what's required
-       */
-      if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
-	g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer);
-      value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS;
-      value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : boxed;
-    }
+  if (value->data[0].v_pointer && !(value->data[1].v_uint & G_VALUE_NOCOPY_CONTENTS))
+    g_boxed_free (G_VALUE_TYPE (value), value->data[0].v_pointer);
+  value->data[1].v_uint = need_free ? 0 : G_VALUE_NOCOPY_CONTENTS;
+  value->data[0].v_pointer = need_copy ? g_boxed_copy (G_VALUE_TYPE (value), boxed) : (gpointer) boxed;
 }
 
 /**
diff --git a/gobject/gtype-private.h b/gobject/gtype-private.h
new file mode 100644
index 0000000..664eb55
--- /dev/null
+++ b/gobject/gtype-private.h
@@ -0,0 +1,41 @@
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION)
+#error "Only <glib-object.h> can be included directly."
+#endif
+
+#ifndef __G_TYPE_PRIVATE_H__
+#define __G_TYPE_PRIVATE_H__
+
+#include "gboxed.h"
+
+G_BEGIN_DECLS
+
+/* for gboxed.c */
+gpointer        _g_type_boxed_copy      (GType          type,
+                                         gpointer       value);
+void            _g_type_boxed_free      (GType          type,
+                                         gpointer       value);
+void            _g_type_boxed_init      (GType          type,
+                                         GBoxedCopyFunc copy_func,
+                                         GBoxedFreeFunc free_func);
+
+G_END_DECLS
+
+#endif /* __G_TYPE_PRIVATE_H__ */
diff --git a/gobject/gtype.c b/gobject/gtype.c
index d582242..a782ce7 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include "gtype.h"
+#include "gtype-private.h"
 #include "gtypeplugin.h"
 #include "gvaluecollector.h"
 #include "gbsearcharray.h"
@@ -167,6 +168,7 @@
 /* --- typedefs --- */
 typedef struct _TypeNode        TypeNode;
 typedef struct _CommonData      CommonData;
+typedef struct _BoxedData       BoxedData;
 typedef struct _IFaceData       IFaceData;
 typedef struct _ClassData       ClassData;
 typedef struct _InstanceData    InstanceData;
@@ -249,6 +251,7 @@ struct _TypeNode
 #define NODE_PARENT_TYPE(node)			(node->supers[1])
 #define NODE_FUNDAMENTAL_TYPE(node)		(node->supers[node->n_supers])
 #define NODE_NAME(node)				(g_quark_to_string (node->qname))
+#define	NODE_IS_BOXED(node)			(NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_BOXED)
 #define	NODE_IS_IFACE(node)			(NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE)
 #define	CLASSED_NODE_N_IFACES(node)		((node)->_prot_n_ifaces_prerequisites)
 #define	CLASSED_NODE_IFACES_ENTRIES(node)	((node)->_prot.iface_entries)
@@ -286,6 +289,13 @@ struct _CommonData
   GTypeValueTable  *value_table;
 };
 
+struct _BoxedData
+{
+  CommonData         data;
+  GBoxedCopyFunc     copy_func;
+  GBoxedFreeFunc     free_func;
+};
+
 struct _IFaceData
 {
   CommonData         common;
@@ -331,6 +341,7 @@ struct _InstanceData
 union _TypeData
 {
   CommonData         common;
+  BoxedData          boxed;
   IFaceData          iface;
   ClassData          class;
   InstanceData       instance;
@@ -1056,6 +1067,12 @@ type_data_make_W (TypeNode              *node,
       data->iface.dflt_data = info->class_data;
       data->iface.dflt_vtable = NULL;
     }
+  else if (NODE_IS_BOXED (node))
+    {
+      data = g_malloc0 (sizeof (BoxedData) + vtable_size);
+      if (vtable_size)
+	vtable = G_STRUCT_MEMBER_P (data, sizeof (BoxedData));
+    }
   else
     {
       data = g_malloc0 (sizeof (CommonData) + vtable_size);
@@ -3966,6 +3983,34 @@ g_type_name_from_class (GTypeClass *g_class)
 }
 
 
+/* --- private api for gboxed.c --- */
+gpointer
+_g_type_boxed_copy (GType type, gpointer value)
+{
+  TypeNode *node = lookup_type_node_I (type);
+
+  return node->data->boxed.copy_func (value);
+}
+
+void
+_g_type_boxed_free (GType type, gpointer value)
+{
+  TypeNode *node = lookup_type_node_I (type);
+
+  node->data->boxed.free_func (value);
+}
+
+void
+_g_type_boxed_init (GType          type,
+                    GBoxedCopyFunc copy_func,
+                    GBoxedFreeFunc free_func)
+{
+  TypeNode *node = lookup_type_node_I (type);
+
+  node->data->boxed.copy_func = copy_func;
+  node->data->boxed.free_func = free_func;
+}
+
 /* --- initialization --- */
 /**
  * g_type_init_with_debug_flags:

