diff -Naur cyrus-imapd-2.2.6.rmquota.uncompiled/imap/ctl_cyrusdb.c cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/ctl_cyrusdb.c
--- cyrus-imapd-2.2.6.rmquota.uncompiled/imap/ctl_cyrusdb.c	2004-06-20 13:39:14.000000000 +0300
+++ cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/ctl_cyrusdb.c	2004-06-20 14:57:09.000000000 +0300
@@ -136,7 +136,7 @@
     /* if it is MBTYPE_RESERVED, unset it & call mboxlist_delete */
     if(!r && (mbtype & MBTYPE_RESERVE)) {
 	if(!r) {
-	    r = mboxlist_deletemailbox(name, 1, NULL, NULL, 0, 0, 1);
+	    r = mboxlist_deletemailbox(name, 1, NULL, NULL, 0, 0, 1, 1);
 	    if(r) {
 		/* log the error */
 		syslog(LOG_ERR,
diff -Naur cyrus-imapd-2.2.6.rmquota.uncompiled/imap/ctl_mboxlist.c cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/ctl_mboxlist.c
--- cyrus-imapd-2.2.6.rmquota.uncompiled/imap/ctl_mboxlist.c	2004-06-20 13:39:14.000000000 +0300
+++ cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/ctl_mboxlist.c	2004-06-20 14:57:09.000000000 +0300
@@ -456,7 +456,7 @@
 	    
 	    wipe_head = wipe_head->next;
 	    
-	    ret = mboxlist_deletemailbox(me->mailbox, 1, "", NULL, 0, 1, 1);
+	    ret = mboxlist_deletemailbox(me->mailbox, 1, "", NULL, 0, 1, 1, 1);
 	    if(ret) {
 		fprintf(stderr, "couldn't delete defunct mailbox %s\n",
 			me->mailbox);
diff -Naur cyrus-imapd-2.2.6.rmquota.uncompiled/imap/imapd.c cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/imapd.c
--- cyrus-imapd-2.2.6.rmquota.uncompiled/imap/imapd.c	2004-06-20 14:45:36.000000000 +0300
+++ cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/imapd.c	2004-06-20 14:57:09.000000000 +0300
@@ -3696,7 +3696,7 @@
 
     r = mboxlist_deletemailbox(name, imapd_userisadmin,
 			       imapd_userid, imapd_authstate,
-			       0, 0, 0);
+			       0, 0, 0, 1);
     
     if(r) {
 	prot_printf(imapd_out, "* NO delete %s: %s\r\n",
@@ -3715,6 +3715,12 @@
     char mailboxname[MAX_MAILBOX_NAME+1];
     char *p;
     int domainlen = 0;
+    int keepQuota = 1;
+
+    if(name && *name == '+') {
+        keepQuota = 0;
+        name++;
+    }
 
     r = (*imapd_namespace.mboxname_tointernal)(&imapd_namespace, name,
 					       imapd_userid, mailboxname);
@@ -3725,7 +3731,7 @@
 
 	r = mboxlist_deletemailbox(mailboxname, imapd_userisadmin,
 				   imapd_userid, imapd_authstate, 1,
-				   localonly, 0);
+				   localonly, 0, keepQuota);
     }
 
     /* was it a top-level user mailbox? */
@@ -6382,7 +6388,7 @@
 	/* note also that we need to remember to let proxyadmins do this */
 	r = mboxlist_deletemailbox(mailboxname,
 				   imapd_userisadmin || imapd_userisproxyadmin,
-				   imapd_userid, imapd_authstate, 0, 1, 0);
+				   imapd_userid, imapd_authstate, 0, 1, 0, 1);
 	if(r) syslog(LOG_ERR,
 		     "Could not delete local mailbox during move of %s",
 		     mailboxname);
diff -Naur cyrus-imapd-2.2.6.rmquota.uncompiled/imap/mboxlist.c cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/mboxlist.c
--- cyrus-imapd-2.2.6.rmquota.uncompiled/imap/mboxlist.c	2004-06-20 14:45:36.000000000 +0300
+++ cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/mboxlist.c	2004-06-20 14:57:09.000000000 +0300
@@ -93,6 +93,11 @@
 static int mboxlist_opensubs();
 static void mboxlist_closesubs();
 
+static int child_cb(char *name,
+                    int matchlen __attribute__((unused)),
+                    int maycreate __attribute__((unused)),
+                    void *rock);
+
 static int mboxlist_rmquota(const char *name, int matchlen, int maycreate,
 			    void *rock);
 static int mboxlist_changequota(const char *name, int matchlen, int maycreate,
@@ -893,9 +898,9 @@
  */
 int mboxlist_deletemailbox(const char *name, int isadmin, char *userid, 
 			   struct auth_state *auth_state, int checkacl,
-			   int local_only, int force)
+			   int local_only, int force, int keepQuota)
 {
-    int r;
+    int r, has_children = 0;
     char *acl;
     long access;
     struct mailbox mailbox;
@@ -907,6 +912,7 @@
     int deleteright = get_deleteright();
     const char *p;
     mupdate_handle *mupdate_h = NULL;
+    char *quotaroot = NULL;
 
     if(!isadmin && force) return IMAP_PERMISSION_DENIED;
 
@@ -1016,13 +1022,40 @@
 
     if ((r && !force) || isremote) goto done;
 
-    if (!r || force) r = mailbox_delete(&mailbox, deletequotaroot);
+    if (!r || force) {
+        /* first we have to keep the previous quota root in order to delete it */
+        if(mailbox.quota.root)
+                quotaroot = xstrdup(mailbox.quota.root);
+	r = mailbox_delete(&mailbox, deletequotaroot);
+    }
 
     /*
      * See if we have to remove mailbox's quota root
      */
-    if (!r && mailbox.quota.root != NULL) {
+    if (!r && quotaroot != NULL) {
 	/* xxx look for any other mailboxes in this quotaroot */
+        /* If we have not asked to remove the quota (default behaviour), we check 
+         * whether there are any subfolders beneeth the quota root. If there aren't
+         * any subfolders the reasonable thing is to delete the quota */
+        if(keepQuota) {
+            char pattern[MAX_MAILBOX_PATH+1];
+            strlcpy(pattern, quotaroot, sizeof(pattern));
+            if (config_virtdomains && name[strlen(name)-1] == '!') {
+                strlcat(pattern, "*", sizeof(pattern));
+            }
+            else {
+                strlcat(pattern, ".*", sizeof(pattern));
+            }
+		/* find if there are subfolders. Then we want to 
+		 * keep the existing quota */
+            mboxlist_findall(NULL, pattern, isadmin, NULL,
+                    NULL, child_cb, (void *) &has_children);
+        }
+        /* If we want to remove the quota explicitely or the quota root folder has no subfolders
+         * we execute the rmquota patch */
+        if(!keepQuota || !has_children)
+            mboxlist_unsetquota(quotaroot);
+        free(quotaroot);
     }
 
  done:
@@ -2371,9 +2404,9 @@
 	|| strchr(root, '*') || strchr(root, '%') || strchr(root, '?')) {
 	return IMAP_MAILBOX_BADNAME;
     }
+	
+    crock.tid=NULL;
     
-    crock.tid = NULL;
-
     quota.root = (char *) root;
     r = quota_read(&quota, crock.tid, 0);
     if (r == IMAP_QUOTAROOT_NONEXISTENT) {
diff -Naur cyrus-imapd-2.2.6.rmquota.uncompiled/imap/mboxlist.h cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/mboxlist.h
--- cyrus-imapd-2.2.6.rmquota.uncompiled/imap/mboxlist.h	2004-06-20 13:39:14.000000000 +0300
+++ cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/mboxlist.h	2004-06-20 14:57:09.000000000 +0300
@@ -122,7 +122,7 @@
  * the planet */
 int mboxlist_deletemailbox(const char *name, int isadmin, char *userid, 
 			   struct auth_state *auth_state, int checkacl,
-			   int local_only, int force);
+			   int local_only, int force, int keepQuota);
 
 /* Rename/move a mailbox (hierarchical) */
 int mboxlist_renamemailbox(char *oldname, char *newname, char *partition, 
diff -Naur cyrus-imapd-2.2.6.rmquota.uncompiled/imap/mupdate.c cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/mupdate.c
--- cyrus-imapd-2.2.6.rmquota.uncompiled/imap/mupdate.c	2004-06-20 13:39:14.000000000 +0300
+++ cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/mupdate.c	2004-06-20 14:57:09.000000000 +0300
@@ -2191,7 +2191,7 @@
 	    remote_boxes.head = r->next;
 	} else if (ret < 0) {
 	    /* Local without corresponding remote, delete it */
-	    mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0);
+	    mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0, 1);
 	    local_boxes.head = l->next;
 	} else /* (ret > 0) */ {
 	    /* Remote without corresponding local, insert it */
@@ -2206,7 +2206,7 @@
     if(l && !r) {
 	/* we have more deletes to do */
 	while(l) {
-	    mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0);
+	    mboxlist_deletemailbox(l->mailbox, 1, "", NULL, 0, 0, 0, 1);
 	    local_boxes.head = l->next;
 	    l = local_boxes.head;
 	}
diff -Naur cyrus-imapd-2.2.6.rmquota.uncompiled/imap/nntpd.c cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/nntpd.c
--- cyrus-imapd-2.2.6.rmquota.uncompiled/imap/nntpd.c	2004-06-20 13:39:14.000000000 +0300
+++ cyrus-imapd-2.2.6.rmquota+deletemailbox.uncompiled/imap/nntpd.c	2004-06-20 14:57:09.000000000 +0300
@@ -3236,7 +3236,7 @@
     /* XXX should we delete right away, or wait until empty? */
 
     r = mboxlist_deletemailbox(mailboxname, 0,
-			       newsmaster, newsmaster_authstate, 1, 0, 0);
+			       newsmaster, newsmaster_authstate, 1, 0, 0, 1);
 
     return r;
 }
