diff -ru apr-old/include/apr_memory_system.h apr-new/include/apr_memory_system.h
--- apr-old/include/apr_memory_system.h	Thu May 10 15:02:11 2001
+++ apr-new/include/apr_memory_system.h	Fri May 11 00:22:27 2001
@@ -180,7 +180,8 @@
 
 /**
  * Reset a memory system so it can be reused. 
- * This will also run all cleanup functions associated with the memory system
+ * This will also run (and unregister) all cleanup functions associated with
+ * the memory system regardless of type.
  * @warning This function will fail if there is no reset function available
  *          for the given memory system (i.e. the memory system is non-
  *          tracking).
@@ -192,9 +193,11 @@
 
 /**
  * Destroy a memory system, effectively freeing all of its memory, and itself. 
- * This will also run all cleanup functions associated with the memory system.
+ * This will also run (and unregister) all cleanup functions associated with
+ * the memory system regardless of type.
  * @caution Be carefull when using this function with a non-tracking memory
- *          system
+ *          system, make sure to free all memory first or to have a tracking
+ *          parent memory system.
  * @param memory_system The memory system to be destroyed
  * @deffunc apr_status_t apr_memory_system_destroy(apr_memory_system_t *memory_system)
  */
@@ -211,7 +214,7 @@
 
 /**
  * Release thread-safe locking required whilst this memory system was
- * being modified
+ * being modified.
  * @param memory_system The memory system to be released from thread-safety
  * @deffunc void apr_memory_system_threadsafe_unlock(apr_memory_system_t *memory_system)
  */
@@ -235,15 +238,18 @@
 
 /**
  * Register a function to be called when a memory system is reset or destroyed
+ * (or when a user call apr_memory_system_cleanup_run_type())
  * @param memory_system The memory system to register the cleanup function with
+ * @param type The type to associate with the cleanup function
  * @param data The data to pass to the cleanup function
  * @param cleanup_fn The function to call when the memory system is reset or
  *        destroyed
  * @deffunc void apr_memory_system_cleanup_register(apr_memory_system_t *memory_system,
- *		   void *data, apr_status_t (*cleanup_fn)(void *));
+ *		   apr_int32_t type, void *data, apr_status_t (*cleanup_fn)(void *));
  */
 APR_DECLARE(apr_status_t) 
 apr_memory_system_cleanup_register(apr_memory_system_t *memory_system, 
+                                   apr_int32_t type,
                                    void *data, 
                                    apr_status_t (*cleanup_fn)(void *));
 
@@ -251,13 +257,16 @@
  * Unregister a previously registered cleanup function
  * @param memory_system The memory system the cleanup function is registered
  *        with
+ * @param type The type associated with the cleanup function, pass 0 to ignore
+ *        the type
  * @param data The data associated with the cleanup function
  * @param cleanup_fn The registered cleanup function
  * @deffunc void apr_memory_system_cleanup_unregister(apr_memory_system_t *memory_system,
- *		   void *data, apr_status_t (*cleanup_fn)(void *));
+ *		   apr_int32_t type, void *data, apr_status_t (*cleanup_fn)(void *));
  */
 APR_DECLARE(apr_status_t)
 apr_memory_system_cleanup_unregister(apr_memory_system_t *memory_system,
+                                     apr_int32_t type,
                                      void *data,
                                      apr_status_t (*cleanup)(void *));
 
@@ -265,15 +274,32 @@
  * Run the specified cleanup function immediately and unregister it
  * @param memory_system The memory system the cleanup function is registered
  *        with
+ * @param type The type associated with the cleanup function, pass 0 to ignore
+ *        the type
  * @param data The data associated with the cleanup function
  * @param cleanup The registered cleanup function
  * @deffunc apr_status_t apr_memory_system_cleanup_run(apr_memory_system_t *memory_system,
- *			   void *data, apr_status_t (*cleanup)(void *));
+ *			   apr_int32_t type, void *data, apr_status_t (*cleanup)(void *));
  */
 APR_DECLARE(apr_status_t) 
 apr_memory_system_cleanup_run(apr_memory_system_t *memory_system,
+                              apr_int32_t type,
                               void *data,
                               apr_status_t (*cleanup)(void *));
+
+/**
+ * Run the registered cleanup functions of type 'type' and unregister them
+ * @param memory_system The memory system the cleanup functions are registered
+ *        with
+ * @param type The type cleanup functions to run and unregister, pass 0 to ignore
+ *        the type and run and unregister all cleanup functions
+ * @param cleanup The registered cleanup function
+ * @deffunc apr_status_t apr_memory_system_cleanup_run_type(apr_memory_system_t *memory_system,
+ *			   apr_int32_t type);
+ */
+APR_DECLARE(apr_status_t) 
+apr_memory_system_cleanup_run_type(apr_memory_system_t *memory_system,
+                                   apr_int32_t type);
 
 /**
  * Create a standard malloc/realloc/free memory system
Only in apr-new/include/arch/unix: apr_private.h.in
diff -ru apr-old/memory/unix/apr_memory_system.c apr-new/memory/unix/apr_memory_system.c
--- apr-old/memory/unix/apr_memory_system.c	Thu May 10 15:02:11 2001
+++ apr-new/memory/unix/apr_memory_system.c	Fri May 11 00:04:56 2001
@@ -74,6 +74,7 @@
 struct apr_memory_system_cleanup
 {
     struct apr_memory_system_cleanup *next;
+    apr_int32_t type;
     void *data;
     apr_status_t (*cleanup_fn)(void *);
 };
@@ -188,6 +189,11 @@
         memory_system->child_memory_system = NULL;
     }
 
+    /* Some more paranoia */
+    memory_system->reset_fn = NULL;
+    memory_system->pre_destroy_fn = NULL;
+    memory_system->destroy_fn = NULL;
+
     return memory_system;
 }
 
@@ -445,15 +451,15 @@
 
   /* 1 - If we have a self destruct, use it */
   if (memory_system->destroy_fn != NULL)
-      memory_system->destroy_fn(memory_system);
+      return memory_system->destroy_fn(memory_system);
 
   /* 2 - If we don't have a parent, free using ourselves */
-  else if (memory_system->parent_memory_system == NULL)
-      memory_system->free_fn(memory_system, memory_system);
+  if (memory_system->parent_memory_system == NULL)
+      return memory_system->free_fn(memory_system, memory_system);
 
   /* 3 - If we do have a parent and it has a free function, use it */
-  else if (memory_system->parent_memory_system->free_fn != NULL)
-      apr_memory_system_free(memory_system->parent_memory_system, memory_system);
+  if (memory_system->parent_memory_system->free_fn != NULL)
+      return apr_memory_system_free(memory_system->parent_memory_system, memory_system);
 
   /* 4 - Assume we are the child of a tracking memory system, and do nothing */
 #ifdef APR_MEMORY_SYSTEM_DEBUG
@@ -507,6 +513,7 @@
 
 APR_DECLARE(apr_status_t)
 apr_memory_system_cleanup_register(apr_memory_system_t *memory_system,
+                                   apr_int32_t type,
                                    void *data,
                                    apr_status_t (*cleanup_fn)(void *))
 {
@@ -525,6 +532,7 @@
     if (cleanup == NULL)
         return APR_ENOMEM;
 
+    cleanup->type = type;
     cleanup->data = data;
     cleanup->cleanup_fn = cleanup_fn;
     cleanup->next = memory_system->cleanups;
@@ -535,6 +543,7 @@
 
 APR_DECLARE(apr_status_t)
 apr_memory_system_cleanup_unregister(apr_memory_system_t *memory_system,
+                                     apr_int32_t type,
                                      void *data,
                                      apr_status_t (*cleanup_fn)(void *))
 {
@@ -548,7 +557,9 @@
     cleanup_ref = &memory_system->cleanups;
     while (cleanup)
     {
-        if (cleanup->data == data && cleanup->cleanup_fn == cleanup_fn)
+        if ((type == 0 || cleanup->type == type) && 
+            cleanup->data == data &&
+            cleanup->cleanup_fn == cleanup_fn)
         {
             *cleanup_ref = cleanup->next;
 
@@ -569,10 +580,45 @@
 }
 
 APR_DECLARE(apr_status_t)
-apr_memory_system_cleanup_run(apr_memory_system_t *memory_system, 
+apr_memory_system_cleanup_run(apr_memory_system_t *memory_system,
+                              apr_int32_t type, 
 			      void *data, 
 			      apr_status_t (*cleanup_fn)(void *))
 {
-    apr_memory_system_cleanup_unregister(memory_system, data, cleanup_fn);
+    apr_memory_system_cleanup_unregister(memory_system, type, data, cleanup_fn);
     return cleanup_fn(data);
+}
+
+APR_DECLARE(apr_status_t)
+apr_memory_system_cleanup_run_type(apr_memory_system_t *memory_system,
+                                   apr_int32_t type)
+{
+    struct apr_memory_system_cleanup *cleanup;
+    struct apr_memory_system_cleanup **cleanup_ref;
+
+    assert(memory_system != NULL);
+    assert(memory_system->accounting_memory_system != NULL);
+
+    cleanup = memory_system->cleanups;
+    cleanup_ref = &memory_system->cleanups;
+    memory_system = memory_system->accounting_memory_system;
+    while (cleanup)
+    {
+        if (type == 0 || cleanup->type == type)
+        {
+            *cleanup_ref = cleanup->next;
+
+            if (memory_system->free_fn != NULL)
+                apr_memory_system_free(memory_system, cleanup);
+
+            cleanup = *cleanup_ref;
+        }
+        else
+        {
+            cleanup_ref = &cleanup->next;
+            cleanup = cleanup->next;
+        }
+    }
+
+    return APR_SUCCESS;
 }
diff -ru apr-old/memory/unix/apr_tracking_memory_system.c apr-new/memory/unix/apr_tracking_memory_system.c
--- apr-old/memory/unix/apr_tracking_memory_system.c	Fri May 11 00:29:49 2001
+++ apr-new/memory/unix/apr_tracking_memory_system.c	Fri May 11 00:13:40 2001
@@ -182,22 +182,28 @@
         node = tracking_memory_system->nodes;
         *(node->ref) = node->next;
         if (node->next != NULL)
-          node->next->ref = node->ref;
+            node->next->ref = node->ref;
+
         if ((rv = apr_memory_system_free(memory_system->parent_memory_system,
                                          node)) != APR_SUCCESS)
             return rv;
     }
+
     return APR_SUCCESS;
 }
 
 static
-void
+apr_status_t
 apr_tracking_memory_system_destroy(apr_memory_system_t *memory_system)
 {
-  assert (memory_system != NULL);
+    apr_status_t rv;
+
+    assert (memory_system != NULL);
+
+    if ((rv = apr_tracking_memory_system_reset(memory_system)) != APR_SUCCESS)
+        return rv;
 
-  apr_tracking_memory_system_reset(memory_system);
-  apr_memory_system_free(memory_system->parent_memory_system, memory_system);
+    return apr_memory_system_free(memory_system->parent_memory_system, memory_system);
 }
 
 APR_DECLARE(apr_status_t)
@@ -217,7 +223,7 @@
 
   *memory_system = NULL;
   if (new_memory_system == NULL)
-    return APR_ENOMEM;
+      return APR_ENOMEM;
 
   new_memory_system->malloc_fn = apr_tracking_memory_system_malloc;
   new_memory_system->realloc_fn = apr_tracking_memory_system_realloc;
