Index: gwlib/mime.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/mime.c,v
retrieving revision 1.14
diff -u -r1.14 mime.c
--- gwlib/mime.c	14 Mar 2006 19:57:16 -0000	1.14
+++ gwlib/mime.c	29 May 2006 06:16:29 -0000
@@ -74,10 +74,11 @@
 #include "gwlib/mime.h"
 
 struct MIMEEntity {
-    List *headers;
-    List *multiparts;
-    Octstr *body;
-    struct MIMEEntity *start;   /* in case multipart/related */
+     List *headers;
+     List *multiparts;
+     Octstr *body;
+     struct MIMEEntity *start;   /* in case multipart/related */
+     struct MIMEEntity *parent; /* Pointer to the MIME container or NULL */
 };
 
 /********************************************************************
@@ -93,19 +94,27 @@
     e->multiparts = gwlist_create();
     e->body = NULL;
     e->start = NULL;
+    e->parent = NULL;
 
     return e;
 }
 
 void static mime_entity_destroy_item(void *e)
 {
-    mime_entity_destroy(e);
+     ((MIMEEntity *)e)->parent = NULL; /* So that func below will destroy it. */
+     mime_entity_destroy(e);
 }
 
+ /* Added: Never actually destroy a mime entity that has a parent,
+  * only its parent may be destroyed (which will recursively destroy children
+  */
 void mime_entity_destroy(MIMEEntity *e) 
 {
     gw_assert(e != NULL);
 
+    if (e->parent) 
+	 return;
+
     if (e->headers != NULL)
         gwlist_destroy(e->headers, octstr_destroy_item);
     if (e->multiparts != NULL)
@@ -508,9 +517,11 @@
      mime_replace_headers(copy, e->headers);
      copy->body = e->body ? octstr_duplicate(e->body) : NULL;
      
-     for (i = 0, n = gwlist_len(e->multiparts); i < n; i++)
-	  gwlist_append(copy->multiparts, 
-			mime_entity_duplicate(gwlist_get(e->multiparts, i)));
+     for (i = 0, n = gwlist_len(e->multiparts); i < n; i++) {
+	  MIMEEntity *ce = mime_entity_duplicate(gwlist_get(e->multiparts, i));   
+	  gwlist_append(copy->multiparts, ce);
+	  ce->parent = copy;
+     }
      return copy;
 }
 
@@ -536,19 +547,20 @@
 }
 
 
-/* Append  a new part to list of body parts. Copy is made
+/* Append  a new part to list of body parts. Copy is NOT made
  * Note that if it was not multipart, this action makes it so!
  */ 
 void mime_entity_add_part(MIMEEntity *e, MIMEEntity *part)
 {
      gw_assert(e != NULL);
      gw_assert(part != NULL);
-     
-     gwlist_append(e->multiparts, mime_entity_duplicate(part));
+
+     gwlist_append(e->multiparts, part);
+     part->parent = e;
 }
 
 
-/* Get part i in list of body parts. Copy is made*/ 
+/* Get part i in list of body parts. Copy is NOT made*/ 
 MIMEEntity *mime_entity_get_part(MIMEEntity *e, int i)
 {
      MIMEEntity *m;
@@ -558,7 +570,7 @@
 
      m = gwlist_get(e->multiparts, i);
      gw_assert(m);
-     return mime_entity_duplicate(m);
+     return m;
 }
 
 
@@ -575,11 +587,11 @@
      m = gwlist_get(e->multiparts, i);
      gwlist_delete(e->multiparts, i, 1);
      if (m == e->start) e->start = NULL;
-
+     m->parent = NULL;
      mime_entity_destroy(m);
 }
 
-/* Replace part i in list of body parts.  Old one will be deleted */ 
+/* Replace part i in list of body parts.  Old one will be deleted. No copy is made */ 
 void mime_entity_replace_part(MIMEEntity *e, int i, MIMEEntity *newpart)
 {
 
@@ -591,9 +603,12 @@
      
      m = gwlist_get(e->multiparts, i);
      gwlist_delete(e->multiparts, i, 1);
-     gwlist_insert(e->multiparts, i, mime_entity_duplicate(newpart));
+     gwlist_insert(e->multiparts, i, newpart);
+     newpart->parent = e;
+
      if (m == e->start) e->start = NULL;
 
+     m->parent = NULL;
      mime_entity_destroy(m);
 }
 
@@ -611,7 +626,7 @@
      e->body = octstr_duplicate(body);
 }
 
-/* Returns (copy of) the 'start' element of a multi-part entity. */
+/* Returns  the 'start' element of a multi-part entity. */
 MIMEEntity *mime_multipart_start_elem(MIMEEntity *e)
 {
      gw_assert(e != NULL);
@@ -651,7 +666,7 @@
 	       octstr_destroy(start);
      }
      
-     return (e->start) ? mime_entity_duplicate(e->start) : NULL;
+     return e->start;
 }
 
 /********************************************************************
Index: gwlib/mime.h
===================================================================
RCS file: /home/cvs/gateway/gwlib/mime.h,v
retrieving revision 1.10
diff -u -r1.10 mime.h
--- gwlib/mime.h	14 Mar 2006 19:57:16 -0000	1.10
+++ gwlib/mime.h	29 May 2006 06:16:29 -0000
@@ -104,6 +104,10 @@
 MIMEEntity *mime_entity_duplicate(MIMEEntity *e);
 
 
+/* NOTE: Most of the functions below returning or taking MIMEEntities
+ * as arguments do not make copies of their arguments
+ */
+
 /* Replace top-level MIME headers: Old ones removed completetly */
 void mime_replace_headers(MIMEEntity *e, List *headers);
 
@@ -113,22 +117,22 @@
  */
 int mime_entity_num_parts(MIMEEntity *e);
 
-/* Append  a new part to list of body parts. Copy is made*/ 
+/* Append  a new part to list of body parts. Copy is NOT made*/ 
 void mime_entity_add_part(MIMEEntity *e, MIMEEntity *part);
 
-/* Get part i in list of body parts. Copy is made*/ 
+/* Get part i in list of body parts. Copy is NOT made*/ 
 MIMEEntity *mime_entity_get_part(MIMEEntity *e, int i);
 
 /* Replace part i in list of body parts.  Old one will be deleted */ 
 void mime_entity_replace_part(MIMEEntity *e, int i, MIMEEntity *newpart);
 
-/* Remove part i in list of body parts. */ 
+/* Remove and destroy part i in list of body parts. */ 
 void mime_entity_remove_part(MIMEEntity *e, int i);
 
 /* Change body element of non-multipart entity. */
 void mime_entity_set_body(MIMEEntity *e, Octstr *body);
 
-/* Returns (copy of) the 'start' element of a multi-part entity. */
+/* Returns the 'start' element of a multi-part entity. */
 MIMEEntity *mime_multipart_start_elem(MIMEEntity *e);
 
 /*
