diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index ceda3a5..67eb122 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -94,6 +94,9 @@ pyg_destroy_notify(gpointer user_data)
     PyGILState_STATE state;
 
     state = pyg_gil_state_ensure();
+    if (IS_UNDEAD(obj)) {
+        obj = REVIVE_UNDEAD(obj);
+    }
     Py_DECREF(obj);
     pyg_gil_state_release(state);
 }
diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h
index ebf107d..b5c3339 100644
--- a/gobject/pygobject-private.h
+++ b/gobject/pygobject-private.h
@@ -8,6 +8,12 @@
 #define _INSIDE_PYGOBJECT_
 #include "pygobject.h"
 
+/* Manipulate a pointer to indicate that a PyObject is undead.  Relies on
+ * pointers being word-aligned, as most (all?) are */
+#define IS_UNDEAD(x) (GPOINTER_TO_UINT(x) & 1)
+#define MAKE_UNDEAD(x) GUINT_TO_POINTER(GPOINTER_TO_UINT(x) | 1)
+#define REVIVE_UNDEAD(x) GUINT_TO_POINTER(GPOINTER_TO_UINT(x) & ~1)
+
 /* Python 2.3 does not define Py_CLEAR */
 #ifndef Py_CLEAR
 #define Py_CLEAR(op)                \
diff --git a/gobject/pygobject.c b/gobject/pygobject.c
index 94ae09c..42303fe 100644
--- a/gobject/pygobject.c
+++ b/gobject/pygobject.c
@@ -571,11 +571,11 @@ void
 pygobject_register_wrapper(PyObject *self)
 {
     GObject *obj = ((PyGObject *)self)->obj;
+    
+    printf("register_wrapper\n");
 
     pygobject_sink(obj);
-    Py_INCREF(self);
-    g_object_set_qdata_full(obj, pygobject_wrapper_key, self,
-			    pyg_destroy_notify);
+    g_object_set_qdata(obj, pygobject_wrapper_key, self);
 }
 
 static PyObject *
@@ -777,10 +777,19 @@ pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
 	return Py_None;
     }
 
+    printf("pygobject_new\n");
+
     /* we already have a wrapper for this object -- return it. */
     self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
     if (self != NULL) {
-	Py_INCREF(self);
+        if (IS_UNDEAD(self)) {
+            g_object_ref(obj);
+            self = REVIVE_UNDEAD(self);
+            g_object_steal_qdata(obj, pygobject_wrapper_key);
+            g_object_set_qdata(obj, pygobject_wrapper_key, self);
+        } else {
+            Py_INCREF(self);
+        }
     } else {
 	/* create wrapper */
 	PyTypeObject *tp;
@@ -803,9 +812,7 @@ pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
 	self->weakreflist = NULL;
 	self->closures = NULL;
 	/* save wrapper pointer so we can access it later */
-	Py_INCREF(self);
-	g_object_set_qdata_full(obj, pygobject_wrapper_key, self,
-				pyg_destroy_notify);
+	g_object_set_qdata(obj, pygobject_wrapper_key, self);
 
 	PyObject_GC_Track((PyObject *)self);
     }
@@ -862,15 +869,23 @@ pygobject_dealloc(PyGObject *self)
 {
     GSList *tmp;
 
-    PyObject_ClearWeakRefs((PyObject *)self);
-
-    PyObject_GC_UnTrack((PyObject *)self);
-
     if (self->obj) {
-	g_object_unref(self->obj);
+        if (self->obj->ref_count > 1) {
+            Py_INCREF(self);
+            g_object_unref(self->obj);
+            g_object_set_qdata_full(self->obj, pygobject_wrapper_key,
+                                    MAKE_UNDEAD(self), pyg_destroy_notify);
+            return;
+        }
+        if (self->obj->ref_count)
+            g_object_unref(self->obj);
     }
     self->obj = NULL;
 
+    PyObject_ClearWeakRefs((PyObject *)self);
+
+    PyObject_GC_UnTrack((PyObject *)self);
+
     if (self->inst_dict) {
 	Py_DECREF(self->inst_dict);
     }
@@ -943,10 +958,6 @@ pygobject_traverse(PyGObject *self, visitproc visit, void *arg)
 	if (ret != 0) return ret;
     }
 
-    if (self->obj && self->obj->ref_count == 1)
-	ret = visit((PyObject *)self, arg);
-    if (ret != 0) return ret;
-
     return 0;
 }
 
@@ -975,11 +986,6 @@ pygobject_clear(PyGObject *self)
     if (self->closures != NULL)
 	g_warning("invalidated all closures, but self->closures != NULL !");
 
-    if (self->obj) {
-	g_object_unref(self->obj);
-    }
-    self->obj = NULL;
-
     return 0;
 }
 
