Rewrote the docs for supporting cyclic garbage collection to reflect
the new way that once writes types.

Deleted the old section and sample code and added a new section
building on the Noddy example.
diff --git a/Doc/ext/cycle-gc.c b/Doc/ext/cycle-gc.c
deleted file mode 100644
index c3a0caa..0000000
--- a/Doc/ext/cycle-gc.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "Python.h"
-
-typedef struct {
-    PyObject_HEAD
-    PyObject *container;
-} MyObject;
-
-static int
-my_traverse(MyObject *self, visitproc visit, void *arg)
-{
-    if (self->container != NULL)
-        return visit(self->container, arg);
-    else
-        return 0;
-}
-
-static int
-my_clear(MyObject *self)
-{
-    Py_XDECREF(self->container);
-    self->container = NULL;
-
-    return 0;
-}
-
-static void
-my_dealloc(MyObject *self)
-{
-    PyObject_GC_UnTrack((PyObject *) self);
-    Py_XDECREF(self->container);
-    PyObject_GC_Del(self);
-}
-
-static PyTypeObject
-MyObject_Type = {
-    PyObject_HEAD_INIT(NULL)
-    0,
-    "MyObject",
-    sizeof(MyObject),
-    0,
-    (destructor)my_dealloc,     /* tp_dealloc */
-    0,                          /* tp_print */
-    0,                          /* tp_getattr */
-    0,                          /* tp_setattr */
-    0,                          /* tp_compare */
-    0,                          /* tp_repr */
-    0,                          /* tp_as_number */
-    0,                          /* tp_as_sequence */
-    0,                          /* tp_as_mapping */
-    0,                          /* tp_hash */
-    0,                          /* tp_call */
-    0,                          /* tp_str */
-    0,                          /* tp_getattro */
-    0,                          /* tp_setattro */
-    0,                          /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
-    0,                          /* tp_doc */
-    (traverseproc)my_traverse,  /* tp_traverse */
-    (inquiry)my_clear,          /* tp_clear */
-    0,                          /* tp_richcompare */
-    0,                          /* tp_weaklistoffset */
-};
-
-/* This constructor should be made accessible from Python. */
-static PyObject *
-new_object(PyObject *unused, PyObject *args)
-{
-    PyObject *container = NULL;
-    MyObject *result = NULL;
-
-    if (PyArg_ParseTuple(args, "|O:new_object", &container)) {
-        result = PyObject_GC_New(MyObject, &MyObject_Type);
-        if (result != NULL) {
-            result->container = container;
-            PyObject_GC_Track(result);
-        }
-    }
-    return (PyObject *) result;
-}
diff --git a/Doc/ext/newtypes.tex b/Doc/ext/newtypes.tex
index d834ccc..df78d54 100644
--- a/Doc/ext/newtypes.tex
+++ b/Doc/ext/newtypes.tex
@@ -670,6 +670,97 @@
 the initialization function, as we did before, and we add an extra
 definition to the \file{setup.py} file.
 
+\subsection{Supporting cyclic garbage collection}
+
+Python has a cyclic-garbage collector that can identify unneeded
+objects even when their reference counts are not zero. This can happen
+when objects are involved in cycles.  For example, consider:
+
+\begin{verbatim}
+>>> l = []
+>>> l.append(l)
+>>> del l
+\end{verbatim}
+
+In this example, we create a list that contains itself. When we delete
+it, it still has a reference from itself. It's reference count doesn't
+drop to zero.  Fortunately, Python's cyclic-garbage collector will
+eventually figure out that that the list is garbage and free it.
+
+In the second version of the \class{Noddy} example, we allowed any
+kind of object to be stored in the \member{first} or \member{last}
+attributes. This means that \class{Noddy} objects can participate in
+cycles:
+
+\begin{verbatim}
+>>> import noddy2
+>>> n = noddy2.Noddy()
+>>> l = [n]
+>>> n.first = l
+\end{verbatim}
+
+This is pretty silly, but it gives us an excuse to add support for the
+cyclic-garbage collector to the \class{Noddy} example.  To support
+cyclic garbage collection, types need to fill two slots and set a
+class flag that enables these slots:
+
+\verbatiminput{noddy4.c}
+
+The traversal method provides access to subobjects that
+could participate in cycles:
+
+\begin{verbatim}
+static int
+Noddy_traverse(Noddy *self, visitproc visit, void *arg)
+{
+    if (self->first && visit(self->first, arg) < 0)
+        return -1;
+    if (self->last && visit(self->last, arg) < 0)
+        return -1;
+
+    return 0;
+}
+\end{verbatim}
+
+For each subobject that can participate in cycles, we need to call the
+\cfunction{visit} function passed to the traversal method passing the
+subobject and the extra argument passed to the traversal method.
+
+We also need to provide a method for clearing any subobjects that can
+participate in cycles.  We implement the method and reimplement the
+deallocator to use it:
+
+\begin{verbatim}
+static int 
+Noddy_clear(Noddy *self)
+{
+    Py_XDECREF(self->first);
+    self->first = NULL;
+    Py_XDECREF(self->last);
+    self->last = NULL;
+
+    return 0;
+}
+
+static void
+Noddy_dealloc(Noddy* self)
+{
+    Noddy_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+\end{verbatim}
+
+Finally, we add the \constant{Py_TPFLAGS_HAVE_GC} flag to the class flags:
+
+\begin{verbatim}
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+\end{verbatim}
+
+That's pretty much it.  If we had written custom \member{tp_alloc} or
+\member{tp_free} slots, we'd need to modify then for cyclic-garbage
+collection. Most extensions will use the versions automatically
+provided.
+
 \section{Type Methods
          \label{dnt-type-methods}}
 
@@ -1304,30 +1395,6 @@
 avoiding the exception can yield slightly better performance.  If an
 actual error occurs, it should set an exception and return \NULL.
 
-
-\subsection{Supporting the Cycle Collector
-            \label{example-cycle-support}}
-
-This example shows only enough of the implementation of an extension
-type to show how the garbage collector support needs to be added.  It
-shows the definition of the object structure, the
-\member{tp_traverse}, \member{tp_clear} and \member{tp_dealloc}
-implementations, the type structure, and a constructor --- the module
-initialization needed to export the constructor to Python is not shown
-as there are no special considerations there for the collector.  To
-make this interesting, assume that the module exposes ways for the
-\member{container} field of the object to be modified.  Note that
-since no checks are made on the type of the object used to initialize
-\member{container}, we have to assume that it may be a container.
-
-\verbatiminput{cycle-gc.c}
-
-Full details on the APIs related to the cycle detector are in
-\ulink{Supporting Cyclic Garbarge
-Collection}{../api/supporting-cycle-detection.html} in the
-\citetitle[../api/api.html]{Python/C API Reference Manual}.
-
-
 \subsection{More Suggestions}
 
 Remember that you can omit most of these functions, in which case you
diff --git a/Doc/ext/noddy4.c b/Doc/ext/noddy4.c
new file mode 100644
index 0000000..078666a
--- /dev/null
+++ b/Doc/ext/noddy4.c
@@ -0,0 +1,209 @@
+#include <Python.h>
+#include "structmember.h"
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *first;
+    PyObject *last;
+    int number;
+} Noddy;
+
+static int
+Noddy_traverse(Noddy *self, visitproc visit, void *arg)
+{
+    if (self->first && visit(self->first, arg) < 0)
+        return -1;
+    if (self->last && visit(self->last, arg) < 0)
+        return -1;
+
+    return 0;
+}
+
+static int 
+Noddy_clear(Noddy *self)
+{
+    Py_XDECREF(self->first);
+    self->first = NULL;
+    Py_XDECREF(self->last);
+    self->last = NULL;
+
+    return 0;
+}
+
+static void
+Noddy_dealloc(Noddy* self)
+{
+    Noddy_clear(self);
+    self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    Noddy *self;
+
+    self = (Noddy *)type->tp_alloc(type, 0);
+    if (self != NULL) {
+        self->first = PyString_FromString("");
+        if (self->first == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+        
+        self->last = PyString_FromString("");
+        if (self->last == NULL)
+          {
+            Py_DECREF(self);
+            return NULL;
+          }
+
+        self->number = 0;
+    }
+
+    return (PyObject *)self;
+}
+
+static int
+Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
+{
+    PyObject *first=NULL, *last=NULL;
+
+    static char *kwlist[] = {"first", "last", "number", NULL};
+
+    if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, 
+                                      &first, &last, 
+                                      &self->number))
+        return -1; 
+
+    if (first) {
+        Py_XDECREF(self->first);
+        Py_INCREF(first);
+        self->first = first;
+    }
+
+    if (last) {
+        Py_XDECREF(self->last);
+        Py_INCREF(last);
+        self->last = last;
+    }
+
+    return 0;
+}
+
+
+static PyMemberDef Noddy_members[] = {
+    {"first", T_OBJECT_EX, offsetof(Noddy, first), 0,
+     "first name"},
+    {"last", T_OBJECT_EX, offsetof(Noddy, last), 0,
+     "last name"},
+    {"number", T_INT, offsetof(Noddy, number), 0,
+     "noddy number"},
+    {NULL}  /* Sentinel */
+};
+
+static PyObject *
+Noddy_name(Noddy* self)
+{
+    static PyObject *format = NULL;
+    PyObject *args, *result;
+
+    if (format == NULL) {
+        format = PyString_FromString("%s %s");
+        if (format == NULL)
+            return NULL;
+    }
+
+    if (self->first == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "first");
+        return NULL;
+    }
+
+    if (self->last == NULL) {
+        PyErr_SetString(PyExc_AttributeError, "last");
+        return NULL;
+    }
+
+    args = Py_BuildValue("OO", self->first, self->last);
+    if (args == NULL)
+        return NULL;
+
+    result = PyString_Format(format, args);
+    Py_DECREF(args);
+    
+    return result;
+}
+
+static PyMethodDef Noddy_methods[] = {
+    {"name", (PyCFunction)Noddy_name, METH_NOARGS,
+     "Return the name, combining the first and last name"
+    },
+    {NULL}  /* Sentinel */
+};
+
+static PyTypeObject NoddyType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "noddy.Noddy",             /*tp_name*/
+    sizeof(Noddy),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)Noddy_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+    "Noddy objects",           /* tp_doc */
+    (traverseproc)Noddy_traverse,   /* tp_traverse */
+    (inquiry)Noddy_clear,           /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    Noddy_methods,             /* tp_methods */
+    Noddy_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)Noddy_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    Noddy_new,                 /* tp_new */
+};
+
+static PyMethodDef module_methods[] = {
+    {NULL}  /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initnoddy4(void) 
+{
+    PyObject* m;
+
+    if (PyType_Ready(&NoddyType) < 0)
+        return;
+
+    m = Py_InitModule3("noddy4", module_methods,
+                       "Example module that creates an extension type.");
+
+    if (m == NULL)
+      return;
+
+    Py_INCREF(&NoddyType);
+    PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
+}
diff --git a/Doc/ext/setup.py b/Doc/ext/setup.py
index 5b99cfe..1805b17 100644
--- a/Doc/ext/setup.py
+++ b/Doc/ext/setup.py
@@ -4,5 +4,6 @@
          Extension("noddy", ["noddy.c"]),
          Extension("noddy2", ["noddy2.c"]),
          Extension("noddy3", ["noddy3.c"]),
+         Extension("noddy4", ["noddy4.c"]),
          ])
 
diff --git a/Doc/ext/test.py b/Doc/ext/test.py
index 5e09e7c..10549d6 100644
--- a/Doc/ext/test.py
+++ b/Doc/ext/test.py
@@ -106,6 +106,99 @@
 TypeError: an integer is required
 >>> del n1
 >>> del n2
+
+Noddy 4
+
+>>> import noddy4
+>>> n1 = noddy4.Noddy('jim', 'fulton', 42)
+>>> n1.first
+'jim'
+>>> n1.last
+'fulton'
+>>> n1.number
+42
+>>> n1.name()
+'jim fulton'
+>>> n1.first = 'will'
+>>> n1.name()
+'will fulton'
+>>> n1.last = 'tell'
+>>> n1.name()
+'will tell'
+>>> del n1.first
+>>> n1.name()
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n1.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n1.first = 'drew'
+>>> n1.first
+'drew'
+>>> del n1.number
+Traceback (most recent call last):
+...
+TypeError: can't delete numeric/char attribute
+>>> n1.number=2
+>>> n1.number
+2
+>>> n1.first = 42
+>>> n1.name()
+'42 tell'
+>>> n2 = noddy4.Noddy()
+>>> n2 = noddy4.Noddy()
+>>> n2 = noddy4.Noddy()
+>>> n2 = noddy4.Noddy()
+>>> n2.name()
+' '
+>>> n2.first
+''
+>>> n2.last
+''
+>>> del n2.first
+>>> n2.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n2.first
+Traceback (most recent call last):
+...
+AttributeError: first
+>>> n2.name()
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+AttributeError: first
+>>> n2.number
+0
+>>> n3 = noddy4.Noddy('jim', 'fulton', 'waaa')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+TypeError: an integer is required
+
+
+Test cyclic gc(?)
+
+>>> import gc
+>>> gc.disable()
+
+>>> x = []
+>>> l = [x]
+>>> n2.first = l
+>>> n2.first
+[[]]
+>>> l.append(n2)
+>>> del l
+>>> del n1
+>>> del n2
+>>> sys.getrefcount(x)
+3
+>>> ignore = gc.collect()
+>>> sys.getrefcount(x)
+2
+
+>>> gc.enable()
 """
 
 import os