diff --git a/glib/garray.c b/glib/garray.c
index d9e7616..7d8d204 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -107,6 +107,7 @@ struct _GRealArray
   guint   elt_size;
   guint   zero_terminated : 1;
   guint   clear : 1;
+  guint   flags : 30;
   volatile gint ref_count;
 };
 
@@ -190,6 +191,7 @@ GArray* g_array_sized_new (gboolean zero_terminated,
   array->alloc           = 0;
   array->zero_terminated = (zero_terminated ? 1 : 0);
   array->clear           = (clear ? 1 : 0);
+  array->flags           = 0;
   array->elt_size        = elt_size;
   array->ref_count       = 1;
 
@@ -202,6 +204,23 @@ GArray* g_array_sized_new (gboolean zero_terminated,
   return (GArray*) array;
 }
 
+void
+g_array_set_flags (GArray *array,
+                   guint   flags)
+{
+  GRealArray *rarray = (GRealArray*) array;
+
+  rarray->flags = flags;
+}
+
+guint
+g_array_get_flags (GArray *array)
+{
+  GRealArray *rarray = (GRealArray*) array;
+
+  return rarray->flags;
+}
+
 /**
  * g_array_ref:
  * @array: A #GArray.
diff --git a/glib/garray.h b/glib/garray.h
index 6bc51f7..c06e320 100644
--- a/glib/garray.h
+++ b/glib/garray.h
@@ -103,6 +103,9 @@ void    g_array_sort              (GArray           *array,
 void    g_array_sort_with_data    (GArray           *array,
 				   GCompareDataFunc  compare_func,
 				   gpointer          user_data);
+void    g_array_set_flags         (GArray           *array,
+                                   guint             flags);
+guint   g_array_get_flags         (GArray           *array);
 
 /* Resizable pointer array.  This interface is much less complicated
  * than the above.  Add appends a pointer.  Remove fills any cleared 
diff --git a/gobject/gobject.c b/gobject/gobject.c
index ead9071..96d04a9 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -33,6 +33,158 @@
 #include "gvaluetypes.h"
 #include "gobject_trace.h"
 
+typedef struct _GDataElt GDataElt;
+struct _GDataElt {
+  GQuark          key;
+  gpointer        data;
+  GDestroyNotify  destroy;
+};
+
+static void
+datalist_init (GArray **datalist)
+{
+  *datalist = g_array_new (FALSE, FALSE, sizeof (GDataElt));
+}
+
+static void
+datalist_clear (GArray **datalist)
+{
+  GArray *a = *datalist;
+  GDataElt *data;
+  gint i;
+
+  *datalist = NULL;
+
+  data = (GDataElt *)a->data;
+  for (i = 0; i < a->len; i++)
+    {
+      if (data->data && data->destroy)
+        data->destroy (data->data);
+      data++;
+    }
+
+  g_array_free (a, TRUE);
+}
+
+static guint
+datalist_get_flags (GArray **datalist)
+{
+  return g_array_get_flags (*datalist);
+}
+
+static void
+datalist_set_flags (GArray **datalist, guint flags)
+{
+  guint old_flags;
+
+  old_flags = g_array_get_flags (*datalist);
+  g_array_set_flags (*datalist, old_flags | flags);
+}
+
+static void
+datalist_unset_flags (GArray **datalist, guint flags)
+{
+  guint old_flags;
+
+  old_flags = g_array_get_flags (*datalist);
+  g_array_set_flags (*datalist, old_flags & ~flags);
+}
+
+static gpointer
+datalist_id_remove_no_notify (GArray **datalist,
+                              GQuark   key)
+{
+  GArray *a = *datalist;
+  gpointer retval = NULL;
+  GDataElt *data;
+  gint i;
+
+  data = (GDataElt*)a->data;
+  for (i = 0; i < a->len; i++)
+    {
+      if (data[i].key == key)
+        {
+          retval = data[i].data;
+          if (i != a->len - 1)
+            data[i] = data[a->len - 1];
+          a->len -= 1;
+          break;
+        }
+    }
+  return retval;
+}
+
+static void
+datalist_id_set_data_full (GArray        **datalist,
+                           GQuark          key,
+                           gpointer        new_data,
+                           GDestroyNotify  new_destroy)
+{
+  GArray *a = *datalist;
+  GDataElt *data;
+  GDataElt old;
+  gint i;
+
+  old.data = NULL;
+
+  data = (GDataElt*)a->data;
+  for (i = 0; i < a->len; i++)
+    {
+      if (data[i].key == key)
+        {
+          old = data[i];
+          if (new_data == NULL)
+            {
+              if (i != a->len - 1)
+                data[i] = data[a->len - 1];
+              a->len -= 1;
+            }
+          else
+            {
+              data[i].data = new_data;
+              data[i].destroy = new_destroy;
+            }
+          break;
+        }
+    }
+  if (old.data == NULL)
+    {
+      GDataElt elt;
+
+      elt.key = key;
+      elt.data = new_data;
+      elt.destroy = new_destroy;
+
+      g_array_append_val (a, elt);
+    }
+  else
+    {
+      if (old.destroy)
+        old.destroy (old.data);
+    }
+}
+
+static gpointer
+datalist_id_get_data (GArray **datalist,
+                      GQuark   key)
+{
+  GArray *a = *datalist;
+  GDataElt *data;
+  gint i;
+
+  data = (GDataElt*)a->data;
+  for (i = 0; i < a->len; i++)
+    {
+      if (data[i].key == key)
+        return data[i].data;
+    }
+  return NULL;
+}
+
+
+#define datalist_id_set_data(dl,q,d) datalist_id_set_data_full((dl),(q),(d),NULL)
+#define datalist_id_remove_data(dl,q) datalist_id_set_data((dl),(q),NULL)
+
 #include "gobjectnotifyqueue.c"
 
 /**
@@ -106,7 +258,7 @@
 
 #define OBJECT_HAS_TOGGLE_REF_FLAG 0x1
 #define OBJECT_HAS_TOGGLE_REF(object) \
-    ((g_datalist_get_flags (&(object)->qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0)
+    ((datalist_get_flags (&(object)->qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0)
 #define OBJECT_FLOATING_FLAG 0x2
 
 #define CLASS_HAS_PROPS_FLAG 0x1
@@ -833,7 +985,7 @@ g_object_init (GObject		*object,
 	       GObjectClass	*class)
 {
   object->ref_count = 1;
-  g_datalist_init (&object->qdata);
+  datalist_init (&object->qdata);
 
   if (CLASS_HAS_PROPS (class))
     {
@@ -892,14 +1044,14 @@ static void
 g_object_real_dispose (GObject *object)
 {
   g_signal_handlers_destroy (object);
-  g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
-  g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
+  datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
+  datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
 }
 
 static void
 g_object_finalize (GObject *object)
 {
-  g_datalist_clear (&object->qdata);
+  datalist_clear (&object->qdata);
   
 #ifdef	G_ENABLE_DEBUG
   IF_DEBUG (OBJECTS)
@@ -2270,7 +2422,7 @@ g_object_weak_ref (GObject    *object,
   g_return_if_fail (object->ref_count >= 1);
 
   G_LOCK (weak_refs_mutex);
-  wstack = g_datalist_id_remove_no_notify (&object->qdata, quark_weak_refs);
+  wstack = datalist_id_remove_no_notify (&object->qdata, quark_weak_refs);
   if (wstack)
     {
       i = wstack->n_weak_refs++;
@@ -2285,7 +2437,7 @@ g_object_weak_ref (GObject    *object,
     }
   wstack->weak_refs[i].notify = notify;
   wstack->weak_refs[i].data = data;
-  g_datalist_id_set_data_full (&object->qdata, quark_weak_refs, wstack, weak_refs_notify);
+  datalist_id_set_data_full (&object->qdata, quark_weak_refs, wstack, weak_refs_notify);
   G_UNLOCK (weak_refs_mutex);
 }
 
@@ -2309,7 +2461,7 @@ g_object_weak_unref (GObject    *object,
   g_return_if_fail (notify != NULL);
 
   G_LOCK (weak_refs_mutex);
-  wstack = g_datalist_id_get_data (&object->qdata, quark_weak_refs);
+  wstack = datalist_id_get_data (&object->qdata, quark_weak_refs);
   if (wstack)
     {
       guint i;
@@ -2486,7 +2638,7 @@ toggle_refs_notify (GObject *object,
   ToggleRefStack tstack, *tstackptr;
 
   G_LOCK (toggle_refs_mutex);
-  tstackptr = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
+  tstackptr = datalist_id_get_data (&object->qdata, quark_toggle_refs);
   tstack = *tstackptr;
   G_UNLOCK (toggle_refs_mutex);
 
@@ -2551,7 +2703,7 @@ g_object_add_toggle_ref (GObject       *object,
   g_object_ref (object);
 
   G_LOCK (toggle_refs_mutex);
-  tstack = g_datalist_id_remove_no_notify (&object->qdata, quark_toggle_refs);
+  tstack = datalist_id_remove_no_notify (&object->qdata, quark_toggle_refs);
   if (tstack)
     {
       i = tstack->n_toggle_refs++;
@@ -2569,11 +2721,11 @@ g_object_add_toggle_ref (GObject       *object,
 
   /* Set a flag for fast lookup after adding the first toggle reference */
   if (tstack->n_toggle_refs == 1)
-    g_datalist_set_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
+    datalist_set_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
   
   tstack->toggle_refs[i].notify = notify;
   tstack->toggle_refs[i].data = data;
-  g_datalist_id_set_data_full (&object->qdata, quark_toggle_refs, tstack,
+  datalist_id_set_data_full (&object->qdata, quark_toggle_refs, tstack,
 			       (GDestroyNotify)g_free);
   G_UNLOCK (toggle_refs_mutex);
 }
@@ -2603,7 +2755,7 @@ g_object_remove_toggle_ref (GObject       *object,
   g_return_if_fail (notify != NULL);
 
   G_LOCK (toggle_refs_mutex);
-  tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
+  tstack = datalist_id_get_data (&object->qdata, quark_toggle_refs);
   if (tstack)
     {
       guint i;
@@ -2618,7 +2770,7 @@ g_object_remove_toggle_ref (GObject       *object,
 	      tstack->toggle_refs[i] = tstack->toggle_refs[tstack->n_toggle_refs];
 
 	    if (tstack->n_toggle_refs == 0)
-	      g_datalist_unset_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
+	      datalist_unset_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
 
 	    break;
 	  }
@@ -2730,9 +2882,9 @@ g_object_unref (gpointer _object)
 	}
 
       /* we are still in the process of taking away the last ref */
-      g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
+      datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
       g_signal_handlers_destroy (object);
-      g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
+      datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
       
       /* decrement the last reference */
       old_ref = g_atomic_int_exchange_and_add ((int *)&object->ref_count, -1);
@@ -2815,7 +2967,7 @@ g_object_get_qdata (GObject *object,
 {
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
   
-  return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
+  return quark ? datalist_id_get_data (&object->qdata, quark) : NULL;
 }
 
 /**
@@ -2841,7 +2993,7 @@ g_object_set_qdata (GObject *object,
   g_return_if_fail (G_IS_OBJECT (object));
   g_return_if_fail (quark > 0);
   
-  g_datalist_id_set_data (&object->qdata, quark, data);
+  datalist_id_set_data (&object->qdata, quark, data);
 }
 
 /**
@@ -2867,7 +3019,7 @@ g_object_set_qdata_full (GObject       *object,
   g_return_if_fail (G_IS_OBJECT (object));
   g_return_if_fail (quark > 0);
   
-  g_datalist_id_set_data_full (&object->qdata, quark, data,
+  datalist_id_set_data_full (&object->qdata, quark, data,
 			       data ? destroy : (GDestroyNotify) NULL);
 }
 
@@ -2921,7 +3073,7 @@ g_object_steal_qdata (GObject *object,
   g_return_val_if_fail (G_IS_OBJECT (object), NULL);
   g_return_val_if_fail (quark > 0, NULL);
   
-  return g_datalist_id_remove_no_notify (&object->qdata, quark);
+  return datalist_id_remove_no_notify (&object->qdata, quark);
 }
 
 /**
@@ -2944,7 +3096,7 @@ g_object_get_data (GObject     *object,
 
   quark = g_quark_try_string (key);
 
-  return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL;
+  return quark ? datalist_id_get_data (&object->qdata, quark) : NULL;
 }
 
 /**
@@ -2967,7 +3119,7 @@ g_object_set_data (GObject     *object,
   g_return_if_fail (G_IS_OBJECT (object));
   g_return_if_fail (key != NULL);
 
-  g_datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
+  datalist_id_set_data (&object->qdata, g_quark_from_string (key), data);
 }
 
 /**
@@ -2992,7 +3144,7 @@ g_object_set_data_full (GObject       *object,
   g_return_if_fail (G_IS_OBJECT (object));
   g_return_if_fail (key != NULL);
 
-  g_datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data,
+  datalist_id_set_data_full (&object->qdata, g_quark_from_string (key), data,
 			       data ? destroy : (GDestroyNotify) NULL);
 }
 
@@ -3017,7 +3169,7 @@ g_object_steal_data (GObject     *object,
 
   quark = g_quark_try_string (key);
 
-  return quark ? g_datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
+  return quark ? datalist_id_remove_no_notify (&object->qdata, quark) : NULL;
 }
 
 static void
@@ -3398,7 +3550,7 @@ g_object_watch_closure (GObject  *object,
 				object, (GClosureNotify) g_object_ref,
 				object, (GClosureNotify) g_object_unref);
   G_LOCK (closure_array_mutex);
-  carray = g_datalist_id_remove_no_notify (&object->qdata, quark_closure_array);
+  carray = datalist_id_remove_no_notify (&object->qdata, quark_closure_array);
   if (!carray)
     {
       carray = g_renew (CArray, NULL, 1);
@@ -3412,7 +3564,7 @@ g_object_watch_closure (GObject  *object,
       carray = g_realloc (carray, sizeof (*carray) + sizeof (carray->closures[0]) * i);
     }
   carray->closures[i] = closure;
-  g_datalist_id_set_data_full (&object->qdata, quark_closure_array, carray, destroy_closure_array);
+  datalist_id_set_data_full (&object->qdata, quark_closure_array, carray, destroy_closure_array);
   G_UNLOCK (closure_array_mutex);
 }
 
diff --git a/gobject/gobject.h b/gobject/gobject.h
index 971f365..c813b79 100644
--- a/gobject/gobject.h
+++ b/gobject/gobject.h
@@ -233,6 +233,7 @@ typedef void (*GObjectFinalizeFunc)     (GObject      *object);
  */
 typedef void (*GWeakNotify)		(gpointer      data,
 					 GObject      *where_the_object_was);
+
 /**
  * GObject:
  * 
@@ -245,7 +246,7 @@ struct  _GObject
   
   /*< private >*/
   volatile guint ref_count;
-  GData         *qdata;
+  GArray *qdata;
 };
 /**
  * GObjectClass:
diff --git a/gobject/gobjectnotifyqueue.c b/gobject/gobjectnotifyqueue.c
index 8aa1485..669596d 100644
--- a/gobject/gobjectnotifyqueue.c
+++ b/gobject/gobjectnotifyqueue.c
@@ -69,12 +69,12 @@ g_object_notify_queue_freeze (GObject		   *object,
   GObjectNotifyQueue *nqueue;
 
   G_LOCK(notify_lock);
-  nqueue = g_datalist_id_get_data (&object->qdata, context->quark_notify_queue);
+  nqueue = datalist_id_get_data (&object->qdata, context->quark_notify_queue);
   if (!nqueue)
     {
       nqueue = g_slice_new0 (GObjectNotifyQueue);
       nqueue->context = context;
-      g_datalist_id_set_data_full (&object->qdata, context->quark_notify_queue,
+      datalist_id_set_data_full (&object->qdata, context->quark_notify_queue,
 				   nqueue, g_object_notify_queue_free);
     }
 
@@ -124,7 +124,7 @@ g_object_notify_queue_thaw (GObject            *object,
     {
       pspecs[n_pspecs++] = slist->data;
     }
-  g_datalist_id_set_data (&object->qdata, context->quark_notify_queue, NULL);
+  datalist_id_set_data (&object->qdata, context->quark_notify_queue, NULL);
 
   G_UNLOCK(notify_lock);
 
@@ -185,7 +185,7 @@ static inline GObjectNotifyQueue*
 g_object_notify_queue_from_object (GObject              *object,
                                    GObjectNotifyContext *context)
 {
-  return g_datalist_id_get_data (&object->qdata, context->quark_notify_queue);
+  return datalist_id_get_data (&object->qdata, context->quark_notify_queue);
 }
 
 G_END_DECLS
