[mutt] 02/11: Import neomutt 20160502 under debian/patches/neomutt

Faidon Liambotis paravoid at moszumanska.debian.org
Fri May 13 15:33:52 UTC 2016


This is an automated email from the git hooks/post-receive script.

paravoid pushed a commit to branch wip-neomutt
in repository mutt.

commit 0a32bff8c1806e066aa69643441586d231333317
Author: Faidon Liambotis <paravoid at debian.org>
Date:   Thu May 5 20:12:10 2016 +0300

    Import neomutt 20160502 under debian/patches/neomutt
    
    To be used soon.
---
 debian/patches/neomutt/01-bug-fixes.patch          |  848 +++
 debian/patches/neomutt/02-quasi-delete.patch       |  289 +
 debian/patches/neomutt/03-progress.patch           |  319 ++
 debian/patches/neomutt/04-status-color.patch       |  612 ++
 debian/patches/neomutt/05-index-color.patch        | 1119 ++++
 debian/patches/neomutt/06-nested-if.patch          |  500 ++
 debian/patches/neomutt/07-cond-date.patch          |  789 +++
 debian/patches/neomutt/08-tls-sni.patch            |  242 +
 debian/patches/neomutt/09-sidebar.patch            | 4316 +++++++++++++++
 debian/patches/neomutt/10-notmuch.patch            | 5819 ++++++++++++++++++++
 debian/patches/neomutt/11-ifdef.patch              | 1526 +++++
 debian/patches/neomutt/12-fmemopen.patch           |  366 ++
 debian/patches/neomutt/13-initials.patch           |  264 +
 debian/patches/neomutt/14-trash.patch              |  780 +++
 .../patches/neomutt/15-limit-current-thread.patch  |  322 ++
 debian/patches/neomutt/16-skip-quoted.patch        |  259 +
 debian/patches/neomutt/README.md                   |   31 +
 17 files changed, 18401 insertions(+)

diff --git a/debian/patches/neomutt/01-bug-fixes.patch b/debian/patches/neomutt/01-bug-fixes.patch
new file mode 100644
index 0000000..e3d9093
--- /dev/null
+++ b/debian/patches/neomutt/01-bug-fixes.patch
@@ -0,0 +1,848 @@
+diff -urN mutt-1.6.1/alias.c mutt-1.6.1-bug-fixes/alias.c
+--- mutt-1.6.1/alias.c	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-bug-fixes/alias.c	2016-05-02 03:02:13.041181631 +0100
+@@ -27,6 +27,7 @@
+ 
+ #include <string.h>
+ #include <ctype.h>
++#include <errno.h>
+ 
+ ADDRESS *mutt_lookup_alias (const char *s)
+ {
+@@ -379,8 +380,10 @@
+     recode_buf (buf, sizeof (buf));
+     write_safe_address (rc, buf);
+     fputc ('\n', rc);
+-    safe_fclose (&rc);
+-    mutt_message _("Alias added.");
++    if (safe_fsync_close(&rc) != 0)
++      mutt_message ("Trouble adding alias: %s.", strerror(errno));
++    else
++      mutt_message _("Alias added.");
+   }
+   else
+     mutt_perror (buf);
+diff -urN mutt-1.6.1/attach.c mutt-1.6.1-bug-fixes/attach.c
+--- mutt-1.6.1/attach.c	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-bug-fixes/attach.c	2016-05-02 03:02:13.042181647 +0100
+@@ -765,7 +765,7 @@
+       fseeko ((s.fpin = fp), m->offset, 0);
+       mutt_decode_attachment (m, &s);
+       
+-      if (fclose (s.fpout) != 0)
++      if (safe_fsync_close (&s.fpout) != 0)
+       {
+ 	mutt_perror ("fclose");
+ 	mutt_sleep (2);
+@@ -800,7 +800,10 @@
+       return (-1);
+     }
+     safe_fclose (&ofp);
+-    safe_fclose (&nfp);
++    if (safe_fsync_close (&nfp) != 0) {
++      mutt_error _("Write fault!");
++      return (-1);
++    }
+   }
+ 
+   return 0;
+@@ -814,6 +817,7 @@
+   unsigned int saved_encoding = 0;
+   BODY *saved_parts = NULL;
+   HEADER *saved_hdr = NULL;
++  int ret = 0;
+ 
+   memset (&s, 0, sizeof (s));
+   s.flags = displaying;
+@@ -871,7 +875,10 @@
+ 
+   mutt_body_handler (m, &s);
+ 
+-  safe_fclose (&s.fpout);
++  if (safe_fsync_close (&s.fpout) != 0) {
++    mutt_perror("fclose");
++    ret = -1;
++  }
+   if (fp == NULL)
+   {
+     m->length = 0;
+@@ -885,7 +892,7 @@
+     safe_fclose (&s.fpin);
+   }
+ 
+-  return (0);
++  return ret;
+ }
+ 
+ /* Ok, the difference between send and receive:
+diff -urN mutt-1.6.1/browser.c mutt-1.6.1-bug-fixes/browser.c
+--- mutt-1.6.1/browser.c	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-bug-fixes/browser.c	2016-05-02 03:02:13.146183302 +0100
+@@ -29,6 +29,7 @@
+ #include "sort.h"
+ #include "mailbox.h"
+ #include "browser.h"
++#include "mx.h"
+ #ifdef USE_IMAP
+ #include "imap.h"
+ #endif
+@@ -86,6 +87,16 @@
+   return ((BrowserSort & SORT_REVERSE) ? -r : r);
+ }
+ 
++static int browser_compare_desc (const void *a, const void *b)
++{
++  struct folder_file *pa = (struct folder_file *) a;
++  struct folder_file *pb = (struct folder_file *) b;
++
++  int r = mutt_strcoll (pa->desc, pb->desc);
++
++  return ((BrowserSort & SORT_REVERSE) ? -r : r);
++}
++
+ static int browser_compare_date (const void *a, const void *b)
+ {
+   struct folder_file *pa = (struct folder_file *) a;
+@@ -106,6 +117,26 @@
+   return ((BrowserSort & SORT_REVERSE) ? -r : r);
+ }
+ 
++static int browser_compare_count (const void *a, const void *b)
++{
++  struct folder_file *pa = (struct folder_file *) a;
++  struct folder_file *pb = (struct folder_file *) b;
++
++  int r = pa->all - pb->all;
++
++  return ((BrowserSort & SORT_REVERSE) ? -r : r);
++}
++
++static int browser_compare_count_new (const void *a, const void *b)
++{
++  struct folder_file *pa = (struct folder_file *) a;
++  struct folder_file *pb = (struct folder_file *) b;
++
++  int r = pa->new - pb->new;
++
++  return ((BrowserSort & SORT_REVERSE) ? -r : r);
++}
++
+ static void browser_sort (struct browser_state *state)
+ {
+   int (*f) (const void *, const void *);
+@@ -120,6 +151,15 @@
+     case SORT_SIZE:
+       f = browser_compare_size;
+       break;
++    case SORT_DESC:
++      f = browser_compare_desc;
++      break;
++    case SORT_COUNT:
++      f = browser_compare_count;
++      break;
++    case SORT_COUNT_NEW:
++      f = browser_compare_count_new;
++      break;
+     case SORT_SUBJECT:
+     default:
+       f = browser_compare_subject;
+@@ -260,7 +300,16 @@
+       else
+ 	mutt_format_s (dest, destlen, fmt, "");
+       break;
+-      
++
++    case 'n':
++      if (!optional) {
++	snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
++	snprintf (dest, destlen, tmp, folder->ff->all);
++      } else if (!folder->ff->all) {
++	optional = 0;
++      }
++      break;
++
+     case 'N':
+ #ifdef USE_IMAP
+       if (mx_is_imap (folder->ff->desc))
+@@ -325,7 +374,8 @@
+ }
+ 
+ static void add_folder (MUTTMENU *m, struct browser_state *state,
+-			const char *name, const struct stat *s, unsigned int new)
++			const char *name, const char *desc,
++			const struct stat *s, unsigned int new, unsigned int all)
+ {
+   if (state->entrylen == state->entrymax)
+   {
+@@ -349,8 +399,9 @@
+   }
+ 
+   (state->entry)[state->entrylen].new = new;
++  (state->entry)[state->entrylen].all = all;
+   (state->entry)[state->entrylen].name = safe_strdup (name);
+-  (state->entry)[state->entrylen].desc = safe_strdup (name);
++  (state->entry)[state->entrylen].desc = safe_strdup(desc ? desc : name);
+ #ifdef USE_IMAP
+   (state->entry)[state->entrylen].imap = 0;
+ #endif
+@@ -432,7 +483,7 @@
+     tmp = Incoming;
+     while (tmp && mutt_strcmp (buffer, tmp->path))
+       tmp = tmp->next;
+-    add_folder (menu, state, de->d_name, &s, (tmp) ? tmp->new : 0);
++    add_folder (menu, state, de->d_name, NULL, &s, (tmp) ? tmp->new : 0, 0);
+   }
+   closedir (dp);  
+   browser_sort (state);
+@@ -460,14 +511,14 @@
+     if (mx_is_imap (tmp->path))
+     {
+       imap_mailbox_state (tmp->path, &mbox);
+-      add_folder (menu, state, tmp->path, NULL, mbox.new);
++      add_folder (menu, state, tmp->path, NULL, NULL, mbox.new, mbox.messages);
+       continue;
+     }
+ #endif
+ #ifdef USE_POP
+     if (mx_is_pop (tmp->path))
+     {
+-      add_folder (menu, state, tmp->path, NULL, tmp->new);
++      add_folder (menu, state, tmp->path, NULL, NULL, tmp->new, 0);
+       continue;
+     }
+ #endif
+@@ -496,7 +547,7 @@
+     strfcpy (buffer, NONULL(tmp->path), sizeof (buffer));
+     mutt_pretty_mailbox (buffer, sizeof (buffer));
+ 
+-    add_folder (menu, state, buffer, &s, tmp->new);
++    add_folder (menu, state, buffer, NULL, &s, tmp->new, 0);
+   }
+   while ((tmp = tmp->next));
+   browser_sort (state);
+@@ -1136,9 +1187,9 @@
+ 	  int reverse = (i == OP_SORT_REVERSE);
+ 	  
+ 	  switch (mutt_multi_choice ((reverse) ?
+-	      _("Reverse sort by (d)ate, (a)lpha, si(z)e or do(n)'t sort? ") :
+-	      _("Sort by (d)ate, (a)lpha, si(z)e or do(n)'t sort? "),
+-	      _("dazn")))
++	      _("Reverse sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, ne(w) count, or do(n)'t sort? ") :
++	      _("Sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, ne(w) count, or do(n)'t sort? "),
++	      _("dazecwn")))
+ 	  {
+ 	    case -1: /* abort */
+ 	      resort = 0;
+@@ -1156,7 +1207,19 @@
+ 	      BrowserSort = SORT_SIZE;
+ 	      break;
+ 
+-            case 4: /* do(n)'t sort */
++            case 4: /* d(e)scription */
++	      BrowserSort = SORT_DESC;
++	      break;
++
++            case 5: /* (c)ount */
++	      BrowserSort = SORT_COUNT;
++	      break;
++
++            case 6: /* ne(w) count */
++	      BrowserSort = SORT_COUNT_NEW;
++	      break;
++
++            case 7: /* do(n)'t sort */
+ 	      BrowserSort = SORT_ORDER;
+ 	      resort = 0;
+ 	      break;
+diff -urN mutt-1.6.1/browser.h mutt-1.6.1-bug-fixes/browser.h
+--- mutt-1.6.1/browser.h	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-bug-fixes/browser.h	2016-05-02 03:02:13.042181647 +0100
+@@ -30,6 +30,8 @@
+   char *desc;
+ 
+   unsigned int new;
++  unsigned int all;
++
+ #ifdef USE_IMAP
+   char delim;
+   
+diff -urN mutt-1.6.1/compose.c mutt-1.6.1-bug-fixes/compose.c
+--- mutt-1.6.1/compose.c	2016-05-02 03:02:12.398171401 +0100
++++ mutt-1.6.1-bug-fixes/compose.c	2016-05-02 03:02:13.147183318 +0100
+@@ -110,7 +110,7 @@
+ 
+ static void redraw_crypt_lines (HEADER *msg)
+ {
+-  mvaddstr (HDR_CRYPT, 0, "Security: ");
++  mvprintw (HDR_CRYPT, 0, TITLE_FMT, "Security: ");
+ 
+   if ((WithCrypto & (APPLICATION_PGP | APPLICATION_SMIME)) == 0)
+   {
+@@ -150,11 +150,11 @@
+ 
+   if ((WithCrypto & APPLICATION_PGP)
+       && (msg->security & APPLICATION_PGP) && (msg->security & SIGN))
+-    printw ("%s%s", _(" sign as: "), PgpSignAs ? PgpSignAs : _("<default>"));
++    printw (TITLE_FMT "%s", _("sign as: "), PgpSignAs ? PgpSignAs : _("<default>"));
+ 
+   if ((WithCrypto & APPLICATION_SMIME)
+       && (msg->security & APPLICATION_SMIME) && (msg->security & SIGN)) {
+-      printw ("%s%s", _(" sign as: "), SmimeDefaultKey ? SmimeDefaultKey : _("<default>"));
++      printw (TITLE_FMT "%s", _("sign as: "), SmimeDefaultKey ? SmimeDefaultKey : _("<default>"));
+   }
+ 
+   if ((WithCrypto & APPLICATION_SMIME)
+@@ -175,7 +175,7 @@
+   int c;
+   char *t;
+ 
+-  mvaddstr (HDR_MIX, 0,     "     Mix: ");
++  mvprintw (HDR_MIX, 0, TITLE_FMT, "Mix: ");
+ 
+   if (!chain)
+   {
+diff -urN mutt-1.6.1/configure.ac mutt-1.6.1-bug-fixes/configure.ac
+--- mutt-1.6.1/configure.ac	2016-05-02 03:02:12.398171401 +0100
++++ mutt-1.6.1-bug-fixes/configure.ac	2016-05-02 03:02:13.147183318 +0100
+@@ -313,6 +313,7 @@
+ AC_CHECK_HEADERS(unix.h)
+ 
+ AC_CHECK_FUNCS(setrlimit getsid)
++AC_CHECK_FUNCS(fgets_unlocked fgetc_unlocked)
+ 
+ AC_MSG_CHECKING(for sig_atomic_t in signal.h)
+ AC_EGREP_HEADER(sig_atomic_t,signal.h,
+@@ -354,7 +355,7 @@
+ 
+ AC_CHECK_FUNCS(fgetpos memmove setegid srand48 strerror)
+ 
+-AC_REPLACE_FUNCS([setenv strcasecmp strdup strsep strtok_r wcscasecmp])
++AC_REPLACE_FUNCS([setenv strcasecmp strdup strndup strnlen strsep strtok_r wcscasecmp])
+ AC_REPLACE_FUNCS([strcasestr mkdtemp])
+ 
+ AC_CHECK_FUNC(getopt)
+diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-bug-fixes/curs_main.c
+--- mutt-1.6.1/curs_main.c	2016-05-02 03:02:12.400171433 +0100
++++ mutt-1.6.1-bug-fixes/curs_main.c	2016-05-02 03:02:13.149183350 +0100
+@@ -118,7 +118,9 @@
+ {
+   char *term = getenv("TERM");
+   char *tcaps;
++#ifdef HAVE_USE_EXTENDED_NAMES
+   int tcapi;
++#endif
+   char **termp;
+   char *known[] = {
+     "color-xterm",
+diff -urN mutt-1.6.1/globals.h mutt-1.6.1-bug-fixes/globals.h
+--- mutt-1.6.1/globals.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-bug-fixes/globals.h	2016-05-02 03:02:13.152183397 +0100
+@@ -192,8 +192,6 @@
+ extern unsigned char QuadOptions[];
+ #endif
+ 
+-WHERE unsigned short Counter INITVAL (0);
+-
+ WHERE short ConnectTimeout;
+ WHERE short HistSize;
+ WHERE short MenuContext;
+diff -urN mutt-1.6.1/init.c mutt-1.6.1-bug-fixes/init.c
+--- mutt-1.6.1/init.c	2016-05-02 03:02:12.405171512 +0100
++++ mutt-1.6.1-bug-fixes/init.c	2016-05-02 03:02:13.154183429 +0100
+@@ -2867,23 +2867,6 @@
+   return 0;
+ }
+ 
+-static void mutt_srandom (void)
+-{
+-  struct timeval tv;
+-  unsigned seed;
+-
+-  gettimeofday(&tv, NULL);
+-  /* POSIX.1-2008 states that seed is 'unsigned' without specifying its width.
+-   * Use as many of the lower order bits from the current time of day as the seed.
+-   * If the upper bound is truncated, that is fine.
+-   *
+-   * tv_sec is integral of type integer or float.  Cast to 'long long' before
+-   * bitshift in case it is a float.
+-   */
+-  seed = ((LONGLONG) tv.tv_sec << 20) | tv.tv_usec;
+-  srandom(seed);
+-}
+-
+ void mutt_init (int skip_sys_rc, LIST *commands)
+ {
+   struct passwd *pw;
+@@ -2902,13 +2885,9 @@
+   ReverseAlias = hash_create (1031, 1);
+   
+   mutt_menu_init ();
+-  mutt_srandom ();
+ 
+-  /* 
+-   * XXX - use something even more difficult to predict?
+-   */
+   snprintf (AttachmentMarker, sizeof (AttachmentMarker),
+-	    "\033]9;%ld\a", (long) time (NULL));
++	    "\033]9;%" PRIu64 "\a", mutt_rand64());
+   
+   /* on one of the systems I use, getcwd() does not return the same prefix
+      as is listed in the passwd file */
+diff -urN mutt-1.6.1/init.h mutt-1.6.1-bug-fixes/init.h
+--- mutt-1.6.1/init.h	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-bug-fixes/init.h	2016-05-02 03:02:13.156183461 +0100
+@@ -3046,7 +3046,10 @@
+   ** entries are sorted alphabetically.  Valid values:
+   ** .il
+   ** .dd alpha (alphabetically)
++  ** .dd count (all message count)
+   ** .dd date
++  ** .dd desc (description)
++  ** .dd new (new message count)
+   ** .dd size
+   ** .dd unsorted
+   ** .ie
+@@ -3631,7 +3634,10 @@
+ 
+ const struct mapping_t SortBrowserMethods[] = {
+   { "alpha",	SORT_SUBJECT },
++  { "count",	SORT_COUNT },
+   { "date",	SORT_DATE },
++  { "desc",	SORT_DESC },
++  { "new",	SORT_COUNT_NEW },
+   { "size",	SORT_SIZE },
+   { "unsorted",	SORT_ORDER },
+   { NULL,       0 }
+diff -urN mutt-1.6.1/lib.c mutt-1.6.1-bug-fixes/lib.c
+--- mutt-1.6.1/lib.c	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-bug-fixes/lib.c	2016-05-02 03:02:13.067182045 +0100
+@@ -219,8 +219,10 @@
+   {
+     if (fflush (*f) || fsync (fileno (*f)))
+     {
++      int save_errno = errno;
+       r = -1;
+       safe_fclose (f);
++      errno = save_errno;
+     }
+     else
+       r = safe_fclose (f);
+@@ -367,6 +369,7 @@
+     size -= chunk;
+   }
+ 
++  if (fflush(out) != 0) return -1;
+   return 0;
+ }
+ 
+@@ -381,6 +384,7 @@
+       return (-1);
+   }
+ 
++  if (fflush(fout) != 0) return -1;
+   return 0;
+ }
+ 
+diff -urN mutt-1.6.1/main.c mutt-1.6.1-bug-fixes/main.c
+--- mutt-1.6.1/main.c	2016-05-02 03:02:12.408171560 +0100
++++ mutt-1.6.1-bug-fixes/main.c	2016-05-02 03:02:13.156183461 +0100
+@@ -598,7 +598,7 @@
+ 
+   mutt_error = mutt_nocurses_error;
+   mutt_message = mutt_nocurses_error;
+-  SRAND (time (NULL));
++  (void)mutt_rand32();
+   umask (077);
+ 
+   memset (Options, 0, sizeof (Options));
+diff -urN mutt-1.6.1/mbyte.c mutt-1.6.1-bug-fixes/mbyte.c
+--- mutt-1.6.1/mbyte.c	2016-05-02 03:02:12.408171560 +0100
++++ mutt-1.6.1-bug-fixes/mbyte.c	2016-05-02 03:02:13.068182061 +0100
+@@ -107,7 +107,7 @@
+   char buf[MB_LEN_MAX+1];
+   ICONV_CONST char *ib;
+   char *ob;
+-  size_t ibl, obl, r;
++  size_t ibl, obl;
+ 
+   if (s)
+   {
+@@ -117,7 +117,7 @@
+     ib = buf;
+     ob = s;
+     obl = MB_LEN_MAX;
+-    r = iconv (cd, &ib, &ibl, &ob, &obl);
++    iconv (cd, &ib, &ibl, &ob, &obl);
+   }
+   else
+   {
+@@ -125,7 +125,7 @@
+     ibl = 1;
+     ob = buf;
+     obl = sizeof (buf);
+-    r = iconv (cd, &ib, &ibl, &ob, &obl);
++    iconv (cd, &ib, &ibl, &ob, &obl);
+   }
+   return ob - s;
+ }
+diff -urN mutt-1.6.1/mh.c mutt-1.6.1-bug-fixes/mh.c
+--- mutt-1.6.1/mh.c	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-bug-fixes/mh.c	2016-05-02 03:02:13.157183477 +0100
+@@ -304,8 +304,8 @@
+   omask = umask (mh_umask (dest));
+   FOREVER
+   {
+-    snprintf (path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%d",
+-	      dest->path, NONULL (Hostname), (int) getpid (), Counter++);
++    snprintf (path, _POSIX_PATH_MAX, "%s/.mutt-%s-%d-%" PRIu64,
++	      dest->path, NONULL (Hostname), (int) getpid (), mutt_rand64());
+     if ((fd = open (path, O_WRONLY | O_EXCL | O_CREAT, 0666)) == -1)
+     {
+       if (errno != EEXIST)
+@@ -1313,9 +1313,9 @@
+   omask = umask (mh_umask (dest));
+   FOREVER
+   {
+-    snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%lld.%u_%d.%s%s",
+-	      dest->path, subdir, (long long)time (NULL), (unsigned int)getpid (),
+-	      Counter++, NONULL (Hostname), suffix);
++    snprintf (path, _POSIX_PATH_MAX, "%s/tmp/%s.%lld.R%" PRIu64 ".%s%s",
++	      dest->path, subdir, (long long)time (NULL), mutt_rand64(),
++              NONULL (Hostname), suffix);
+ 
+     dprint (2, (debugfile, "maildir_open_new_message (): Trying %s.\n",
+ 		path));
+@@ -1399,8 +1399,8 @@
+   /* construct a new file name. */
+   FOREVER
+   {
+-    snprintf (path, _POSIX_PATH_MAX, "%s/%lld.%u_%d.%s%s", subdir,
+-	      (long long)time (NULL), (unsigned int)getpid (), Counter++,
++    snprintf (path, _POSIX_PATH_MAX, "%s/%lld.R%" PRIu64 ".%s%s", subdir,
++	      (long long)time (NULL), mutt_rand64(),
+ 	      NONULL (Hostname), suffix);
+     snprintf (full, _POSIX_PATH_MAX, "%s/%s", ctx->path, path);
+ 
+diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-bug-fixes/mutt.h
+--- mutt-1.6.1/mutt.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-bug-fixes/mutt.h	2016-05-02 03:02:13.157183477 +0100
+@@ -52,6 +52,11 @@
+ #include <limits.h>
+ #endif
+ 
++/* PATH_MAX is undefined on the hurd */
++#ifndef PATH_MAX
++#define PATH_MAX _POSIX_PATH_MAX
++#endif
++
+ #include <pwd.h>
+ #include <grp.h>
+ 
+@@ -66,6 +71,14 @@
+ # define MB_LEN_MAX 16
+ #endif
+ 
++#ifdef HAVE_FGETS_UNLOCKED
++# define fgets fgets_unlocked
++#endif
++
++#ifdef HAVE_FGETC_UNLOCKED
++# define fgetc fgetc_unlocked
++#endif
++
+ /* nifty trick I stole from ELM 2.5alpha. */
+ #ifdef MAIN_C
+ #define WHERE 
+diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-bug-fixes/muttlib.c
+--- mutt-1.6.1/muttlib.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-bug-fixes/muttlib.c	2016-05-02 03:02:13.158183493 +0100
+@@ -37,6 +37,7 @@
+ #include <string.h>
+ #include <ctype.h>
+ #include <unistd.h>
++#include <sys/syscall.h>
+ #include <stdlib.h>
+ #include <sys/wait.h>
+ #include <errno.h>
+@@ -771,12 +772,79 @@
+   mutt_free_envelope(extra);
+ }
+ 
++static FILE *frandom;
++
++void mutt_randbuf(void *out, size_t len)
++{
++  if (len > 1048576) {
++    mutt_error (_("mutt_randbuf len=%zu"), len);
++    exit(1);
++  }
++  /* XXX switch to HAVE_GETRANDOM and getrandom() in about 2017 */
++#if defined(SYS_getrandom) && defined(__linux__)
++  static int whined;
++  long ret;
++  do {
++    ret = syscall(SYS_getrandom, out, len, 0, 0, 0, 0);
++  } while ((ret == -1) && (errno == EINTR));
++  if (ret == len) return;
++  if (!whined) {
++    mutt_error (_("getrandom failed: %s"), strerror(errno));
++    mutt_sleep (1);
++    whined = 1;
++  }
++  /* let's try urandom in case user has configured selinux or something
++   * to not allow getrandom */
++#endif
++  if (frandom == NULL) {
++    frandom = fopen("/dev/urandom", "rb");
++    if (frandom == NULL) {
++      mutt_error (_("open /dev/urandom: %s"), strerror(errno));
++      exit(1);
++    }
++    setbuf(frandom, NULL);
++  }
++  if (fread(out, 1, len, frandom) != len) {
++    mutt_error (_("read /dev/urandom: %s"), strerror(errno));
++    exit(1);
++  }
++}
++
++static const unsigned char base32[] = "abcdefghijklmnopqrstuvwxyz234567";
++
++void mutt_rand_base32(void *out, size_t len)
++{
++  size_t pos;
++  uint8_t *p = out;
++
++  mutt_randbuf(p, len);
++  for (pos = 0; pos < len; pos++)
++    p[pos] = base32[p[pos] % 32];
++}
++
++uint32_t mutt_rand32(void)
++{
++  uint32_t ret;
++
++  mutt_randbuf(&ret, sizeof(ret));
++  return ret;
++}
++
++uint64_t mutt_rand64(void)
++{
++  uint64_t ret;
++
++  mutt_randbuf(&ret, sizeof(ret));
++  return ret;
++}
++
++
+ void _mutt_mktemp (char *s, size_t slen, const char *prefix, const char *suffix,
+                    const char *src, int line)
+ {
+-  size_t n = snprintf (s, slen, "%s/%s-%s-%d-%d-%ld%ld%s%s",
++  size_t n = snprintf (s, slen, "%s/%s-%s-%d-%d-%" PRIu64 "%s%s",
+       NONULL (Tempdir), NONULL (prefix), NONULL (Hostname),
+-      (int) getuid (), (int) getpid (), random (), random (),
++      (int) getuid (), (int) getpid (), mutt_rand64(),
+       suffix ? "." : "", NONULL (suffix));
+   if (n >= slen)
+     dprint (1, (debugfile, "%s:%d: ERROR: insufficient buffer space to hold temporary filename! slen=%zu but need %zu\n",
+diff -urN mutt-1.6.1/mutt_ssl.c mutt-1.6.1-bug-fixes/mutt_ssl.c
+--- mutt-1.6.1/mutt_ssl.c	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-bug-fixes/mutt_ssl.c	2016-05-02 03:02:13.158183493 +0100
+@@ -432,14 +432,6 @@
+   if (!ssl_check_certificate (conn, ssldata))
+     return -1;
+ 
+-  /* L10N:
+-     %1$s is version (e.g. "TLSv1.2")
+-     %2$s is cipher_version (e.g. "TLSv1/SSLv3")
+-     %3$s is cipher_name (e.g. "ECDHE-RSA-AES128-GCM-SHA256") */
+-  mutt_message (_("%s connection using %s (%s)"),
+-    SSL_get_version(ssldata->ssl), SSL_get_cipher_version (ssldata->ssl), SSL_get_cipher_name (ssldata->ssl));
+-  mutt_sleep (0);
+-
+   return 0;
+ }
+ 
+diff -urN mutt-1.6.1/protos.h mutt-1.6.1-bug-fixes/protos.h
+--- mutt-1.6.1/protos.h	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-bug-fixes/protos.h	2016-05-02 03:02:13.159183509 +0100
+@@ -1,5 +1,6 @@
+ /*
+  * Copyright (C) 1996-2000,2007,2010,2013 Michael R. Elkins <me at mutt.org>
++ * Copyright (C) 2013 Karel Zak <kzak at redhat.com>
+  * 
+  *     This program is free software; you can redistribute it and/or modify
+  *     it under the terms of the GNU General Public License as published by
+@@ -375,6 +376,11 @@
+ void mutt_set_header_color(CONTEXT *, HEADER *);
+ void mutt_sleep (short);
+ int mutt_save_confirm (const char  *, struct stat *);
++void mutt_randbuf(void *out, size_t len);
++#define MUTT_RANDTAG_LEN (16)
++void mutt_rand_base32(void *out, size_t len);
++uint32_t mutt_rand32(void);
++uint64_t mutt_rand64(void);
+ 
+ int mh_valid_message (const char *);
+ 
+@@ -422,16 +428,6 @@
+ #define LONGLONG long
+ #endif
+ 
+-#ifdef HAVE_SRAND48
+-#define LRAND lrand48
+-#define SRAND srand48
+-#define DRAND drand48
+-#else
+-#define LRAND rand
+-#define SRAND srand
+-#define DRAND (double)rand
+-#endif /* HAVE_SRAND48 */
+-
+ /* HP-UX, ConvexOS and UNIXware don't have this macro */
+ #ifndef S_ISLNK
+ #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK ? 1 : 0)
+@@ -565,3 +561,11 @@
+ #ifndef HAVE_MKDTEMP
+ char *mkdtemp (char *tmpl);
+ #endif
++
++#ifndef HAVE_STRNLEN
++size_t strnlen(const char *s, size_t maxlen);
++#endif
++
++#ifndef strndup
++char *strndup(const char *s, size_t n);
++#endif
+diff -urN mutt-1.6.1/sendlib.c mutt-1.6.1-bug-fixes/sendlib.c
+--- mutt-1.6.1/sendlib.c	2016-05-02 03:02:12.440172071 +0100
++++ mutt-1.6.1-bug-fixes/sendlib.c	2016-05-02 03:02:13.160183524 +0100
+@@ -73,8 +73,6 @@
+   '8', '9', '+', '/'
+ };
+ 
+-static char MsgIdPfx = 'A';
+-
+ static void transform_to_7bit (BODY *a, FILE *fpin);
+ 
+ static void encode_quoted (FGETCONV * fc, FILE *fout, int istext)
+@@ -480,18 +478,12 @@
+ 
+ #undef write_as_text_part
+ 
+-#define BOUNDARYLEN 16
+ void mutt_generate_boundary (PARAMETER **parm)
+ {
+-  char rs[BOUNDARYLEN + 1];
+-  char *p = rs;
+-  int i;
+-
+-  rs[BOUNDARYLEN] = 0;
+-  for (i=0;i<BOUNDARYLEN;i++)
+-    *p++ = B64Chars[LRAND() % sizeof (B64Chars)];
+-  *p = 0;
++  char rs[MUTT_RANDTAG_LEN + 1];
+ 
++  mutt_rand_base32(rs, sizeof(rs) - 1);
++  rs[MUTT_RANDTAG_LEN] = 0;
+   mutt_set_parameter ("boundary", rs, parm);
+ }
+ 
+@@ -2133,16 +2125,18 @@
+   time_t now;
+   struct tm *tm;
+   const char *fqdn;
++  unsigned char rndid[MUTT_RANDTAG_LEN + 1];
+ 
++  mutt_rand_base32(rndid, sizeof(rndid) - 1);
++  rndid[MUTT_RANDTAG_LEN] = 0;
+   now = time (NULL);
+   tm = gmtime (&now);
+   if(!(fqdn = mutt_fqdn(0)))
+     fqdn = NONULL(Hostname);
+ 
+-  snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.G%c%u@%s>",
++  snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.%s@%s>",
+ 	    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
+-	    tm->tm_min, tm->tm_sec, MsgIdPfx, (unsigned int)getpid (), fqdn);
+-  MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
++	    tm->tm_min, tm->tm_sec, rndid, fqdn);
+   return (safe_strdup (buf));
+ }
+ 
+@@ -2559,9 +2553,12 @@
+     mutt_copy_header (fp, h, f, ch_flags, NULL);
+     fputc ('\n', f);
+     mutt_copy_bytes (fp, f, h->content->length);
+-    safe_fclose (&f);
+     FREE (&msgid_str);
+-
++    if (safe_fclose (&f) != 0) {
++      mutt_perror(tempfile);
++      unlink(tempfile);
++      return -1;
++    }
+ #if USE_SMTP
+     if (SmtpUrl)
+       ret = mutt_smtp_send (env_from, to, NULL, NULL, tempfile,
+diff -urN mutt-1.6.1/sort.h mutt-1.6.1-bug-fixes/sort.h
+--- mutt-1.6.1/sort.h	2016-05-02 03:02:12.440172071 +0100
++++ mutt-1.6.1-bug-fixes/sort.h	2016-05-02 03:02:13.160183524 +0100
+@@ -31,6 +31,9 @@
+ #define SORT_KEYID	12
+ #define SORT_TRUST	13
+ #define SORT_SPAM	14
++#define SORT_DESC	15
++#define SORT_COUNT	16
++#define SORT_COUNT_NEW	17
+ /* dgc: Sort & SortAux are shorts, so I'm bumping these bitflags up from
+  * bits 4 & 5 to bits 8 & 9 to make room for more sort keys in the future. */
+ #define SORT_MASK	0xff
+diff -urN mutt-1.6.1/strndup.c mutt-1.6.1-bug-fixes/strndup.c
+--- mutt-1.6.1/strndup.c	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-bug-fixes/strndup.c	2016-05-02 03:02:13.105182649 +0100
+@@ -0,0 +1,19 @@
++/*
++ * Copyright (C) 2013 Karel Zak <kzak at redhat.com>
++ */
++
++#if HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include "mutt.h"
++
++char *strndup(const char *s, size_t n)
++{
++	size_t len = strnlen(s, n);
++	char *new = (char *) malloc((len + 1) * sizeof(char));
++	if (!new)
++		return NULL;
++	new[len] = '\0';
++	return (char *) memcpy(new, s, len);
++}
+diff -urN mutt-1.6.1/strnlen.c mutt-1.6.1-bug-fixes/strnlen.c
+--- mutt-1.6.1/strnlen.c	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-bug-fixes/strnlen.c	2016-05-02 03:02:13.105182649 +0100
+@@ -0,0 +1,20 @@
++/*
++ * Copyright (C) 2013 Karel Zak <kzak at redhat.com>
++ */
++
++#if HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include "mutt.h"
++
++size_t strnlen(const char *s, size_t maxlen)
++{
++        int i;
++
++        for (i = 0; i < maxlen; i++) {
++                if (s[i] == '\0')
++                        return i + 1;
++        }
++        return maxlen;
++}
diff --git a/debian/patches/neomutt/02-quasi-delete.patch b/debian/patches/neomutt/02-quasi-delete.patch
new file mode 100644
index 0000000..830676e
--- /dev/null
+++ b/debian/patches/neomutt/02-quasi-delete.patch
@@ -0,0 +1,289 @@
+diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-quasi-delete/curs_main.c
+--- mutt-1.6.1/curs_main.c	2016-05-02 03:02:12.400171433 +0100
++++ mutt-1.6.1-quasi-delete/curs_main.c	2016-05-02 03:02:13.424187725 +0100
+@@ -1150,6 +1150,20 @@
+ 	  menu->redraw = REDRAW_FULL;
+ 	break;
+ 
++      case OP_MAIN_QUASI_DELETE:
++	if (tag) {
++	  for (j = 0; j < Context->vcount; j++) {
++	    if (Context->hdrs[Context->v2r[j]]->tagged) {
++	      Context->hdrs[Context->v2r[j]]->quasi_deleted = TRUE;
++	      Context->changed = TRUE;
++	    }
++	  }
++	} else {
++	  CURHDR->quasi_deleted = TRUE;
++	  Context->changed = 1;
++	}
++	break;
++
+       case OP_MAIN_CHANGE_FOLDER:
+       case OP_MAIN_NEXT_UNREAD_MAILBOX:
+ 
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-quasi-delete/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-quasi-delete/doc/manual.xml.head	2016-05-02 03:02:13.427187773 +0100
+@@ -8081,6 +8081,126 @@
+ 
+ </sect1>
+ 
++<sect1 id="quasi-delete">
++	<title>Quasi-Delete Patch</title>
++	<subtitle>Mark emails that should be hidden, but not deleted</subtitle>
++
++	<sect2 id="quasi-delete-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Quasi-Delete</quote>, look for
++			<quote>patch-quasi-delete</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="quasi-delete-intro">
++		<title>Introduction</title>
++
++        <para>
++		The <quote>quasi-delete</quote> function marks an email that should be
++		hidden from the index, but NOT deleted.
++        </para>
++
++        <para>
++		On its own, this patch isn't very useful.  It forms a useful part of
++		the notmuch plugin.
++        </para>
++	</sect2>
++
++<!--
++	<sect2 id="quasi-delete-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="quasi-delete-functions">
++		<title>Functions</title>
++		<table id="table-quasi-delete-functions">
++			<title>Quasi-Delete Functions</title>
++			<tgroup cols="4">
++				<thead>
++					<row>
++						<entry>Menus</entry>
++						<entry>Default Key</entry>
++						<entry>Function</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>index,pager</entry>
++						<entry>(none)</entry>
++						<entry><literal><quasi-delete></literal></entry>
++						<entry>delete from mutt, don't touch on disk</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++<!--
++	<sect2 id="quasi-delete-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="quasi-delete-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="quasi-delete-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="quasi-delete-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'quasi-delete' feature.
++ 
++# The 'quasi-delete' function marks an email that should be hidden
++# from the index, but NOT deleted.</emphasis>
++bind index,pager Q quasi-delete
++ 
++<emphasis role="comment"># vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="quasi-delete-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="notmuch">notmuch patch</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="quasi-delete-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="quasi-delete-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Karel Zak <email>kzak at redhat.com</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.quasi-delete mutt-1.6.1-quasi-delete/doc/muttrc.quasi-delete
+--- mutt-1.6.1/doc/muttrc.quasi-delete	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-quasi-delete/doc/muttrc.quasi-delete	2016-05-02 03:02:13.323186118 +0100
+@@ -0,0 +1,7 @@
++# Example Mutt config file for the 'quasi-delete' feature.
++
++# The 'quasi-delete' function marks an email that should be hidden
++# from the index, but NOT deleted.
++bind index,pager Q quasi-delete
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/doc/vimrc.quasi-delete mutt-1.6.1-quasi-delete/doc/vimrc.quasi-delete
+--- mutt-1.6.1/doc/vimrc.quasi-delete	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-quasi-delete/doc/vimrc.quasi-delete	2016-05-02 03:02:13.324186134 +0100
+@@ -0,0 +1,5 @@
++" Vim syntax file for the mutt quasi-delete patch
++
++syntax match muttrcFunction     contained "\<quasi-delete\>"
++
++" vim: syntax=vim
+diff -urN mutt-1.6.1/functions.h mutt-1.6.1-quasi-delete/functions.h
+--- mutt-1.6.1/functions.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-quasi-delete/functions.h	2016-05-02 03:02:13.427187773 +0100
+@@ -167,6 +167,7 @@
+   { "mail-key",			OP_MAIL_KEY,			"\033k" },
+   { "decrypt-copy",		OP_DECRYPT_COPY,		NULL },
+   { "decrypt-save",		OP_DECRYPT_SAVE,		NULL },
++  { "quasi-delete",		OP_MAIN_QUASI_DELETE,		NULL },
+ 
+ 
+   { NULL,			0,				NULL }
+@@ -271,6 +272,7 @@
+   { "decrypt-save",    	OP_DECRYPT_SAVE,		NULL },
+ 
+   { "what-key",		OP_WHAT_KEY,		NULL },
++  { "quasi-delete",	OP_MAIN_QUASI_DELETE,		NULL },
+ 
+   { NULL,		0,				NULL }
+ };
+diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-quasi-delete/mutt.h
+--- mutt-1.6.1/mutt.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-quasi-delete/mutt.h	2016-05-02 03:02:13.433187868 +0100
+@@ -720,6 +720,7 @@
+   unsigned int flagged : 1; 		/* marked important? */
+   unsigned int tagged : 1;
+   unsigned int deleted : 1;
++  unsigned int quasi_deleted : 1;	/* deleted from mutt, but not modified on disk */
+   unsigned int changed : 1;
+   unsigned int attach_del : 1; 		/* has an attachment marked for deletion */
+   unsigned int old : 1;
+diff -urN mutt-1.6.1/mx.c mutt-1.6.1-quasi-delete/mx.c
+--- mutt-1.6.1/mx.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-quasi-delete/mx.c	2016-05-02 03:02:13.434187884 +0100
+@@ -1005,9 +1005,10 @@
+ #define this_body ctx->hdrs[j]->content
+   for (i = 0, j = 0; i < ctx->msgcount; i++)
+   {
+-    if ((committing && (!ctx->hdrs[i]->deleted || 
++    if (!ctx->hdrs[i]->quasi_deleted &&
++	((committing && (!ctx->hdrs[i]->deleted ||
+ 			(ctx->magic == M_MAILDIR && option (OPTMAILDIRTRASH)))) ||
+-	(!committing && ctx->hdrs[i]->active))
++	(!committing && ctx->hdrs[i]->active)))
+     {
+       if (i != j)
+       {
+diff -urN mutt-1.6.1/OPS mutt-1.6.1-quasi-delete/OPS
+--- mutt-1.6.1/OPS	2016-05-02 03:02:12.392171305 +0100
++++ mutt-1.6.1-quasi-delete/OPS	2016-05-02 03:02:13.417187613 +0100
+@@ -127,6 +127,7 @@
+ OP_MAIN_SET_FLAG "set a status flag on a message"
+ OP_MAIN_SYNC_FOLDER "save changes to mailbox"
+ OP_MAIN_TAG_PATTERN "tag messages matching a pattern"
++OP_MAIN_QUASI_DELETE "delete from mutt, don't touch on disk"
+ OP_MAIN_UNDELETE_PATTERN "undelete messages matching a pattern"
+ OP_MAIN_UNTAG_PATTERN "untag messages matching a pattern"
+ OP_MIDDLE_PAGE "move to the middle of the page"
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-quasi-delete/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-quasi-delete/PATCHES	2016-05-02 03:02:13.421187677 +0100
+@@ -0,0 +1 @@
++patch-quasi-delete-neo-20160502
+diff -urN mutt-1.6.1/README.quasi-delete mutt-1.6.1-quasi-delete/README.quasi-delete
+--- mutt-1.6.1/README.quasi-delete	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-quasi-delete/README.quasi-delete	2016-05-02 03:02:13.421187677 +0100
+@@ -0,0 +1,49 @@
++Quasi-Delete Patch
++==================
++
++    Mark emails that should be hidden, but not deleted
++
++Patch
++-----
++
++    To check if Mutt supports "Quasi-Delete", look for "patch-quasi-delete" in
++    the mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    The "quasi-delete" function marks an email that should be hidden from the
++    index, but NOT deleted.
++
++    On its own, this patch isn't very useful. It forms a useful part of the
++    notmuch plugin.
++
++Functions
++---------
++
++    Quasi-Delete Functions
++
++    | Menus       | Default Key | Function         | Description                           |
++    |-------------|-------------|------------------|---------------------------------------|
++    | index,pager | (none)      | '<quasi-delete>' | delete from mutt, don't touch on disk |
++
++See Also
++--------
++
++    * NeoMutt project
++    * notmuch patch
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Karel Zak <kzak at redhat.com>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/03-progress.patch b/debian/patches/neomutt/03-progress.patch
new file mode 100644
index 0000000..66720fa
--- /dev/null
+++ b/debian/patches/neomutt/03-progress.patch
@@ -0,0 +1,319 @@
+diff -urN mutt-1.6.1/color.c mutt-1.6.1-progress/color.c
+--- mutt-1.6.1/color.c	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-progress/color.c	2016-05-02 03:02:13.590190366 +0100
+@@ -93,6 +93,7 @@
+   { "bold",		MT_COLOR_BOLD },
+   { "underline",	MT_COLOR_UNDERLINE },
+   { "index",		MT_COLOR_INDEX },
++  { "progress",		MT_COLOR_PROGRESS },
+   { "prompt",		MT_COLOR_PROMPT },
+   { NULL,		0 }
+ };
+diff -urN mutt-1.6.1/curs_lib.c mutt-1.6.1-progress/curs_lib.c
+--- mutt-1.6.1/curs_lib.c	2016-05-02 03:02:12.399171417 +0100
++++ mutt-1.6.1-progress/curs_lib.c	2016-05-02 03:02:13.592190398 +0100
+@@ -411,6 +411,53 @@
+   mutt_progress_update (progress, 0, 0);
+ }
+ 
++/**
++ * message_bar - XXX
++ */
++static void
++message_bar (int percent, const char *fmt, ...)
++{
++	va_list ap;
++	char buf[STRING], buf2[STRING];
++	int w = percent * COLS / 100;
++	size_t l;
++
++	va_start (ap, fmt);
++	vsnprintf (buf, sizeof (buf), fmt, ap);
++	l = mutt_strwidth (buf);
++	va_end (ap);
++
++	mutt_format_string (buf2, sizeof (buf2), 0, COLS-2, FMT_LEFT, 0, buf, sizeof (buf), 0);
++
++	move (LINES - 1, 0);
++
++	if (l < w) {
++		SETCOLOR(MT_COLOR_PROGRESS);
++		addstr (buf2);
++		w -= l;
++		while (w--) {
++			addch (' ');
++		}
++		SETCOLOR(MT_COLOR_NORMAL);
++		clrtoeol();
++		mutt_refresh();
++	} else {
++		size_t bw;
++		char ch;
++		int off = mutt_wstr_trunc (buf2, sizeof (buf2), w, &bw);
++
++		ch = buf2[off];
++		buf2[off] = 0;
++		SETCOLOR(MT_COLOR_PROGRESS);
++		addstr (buf2);
++		buf2[off] = ch;
++		SETCOLOR(MT_COLOR_NORMAL);
++		addstr (&buf2[off]);
++		clrtoeol();
++		mutt_refresh();
++	}
++}
++
+ void mutt_progress_update (progress_t* progress, long pos, int percent)
+ {
+   char posstr[SHORT_STRING];
+@@ -461,16 +508,16 @@
+ 
+     if (progress->size > 0)
+     {
+-      mutt_message ("%s %s/%s (%d%%)", progress->msg, posstr, progress->sizestr,
+-		    percent > 0 ? percent :
+-		   	(int) (100.0 * (double) progress->pos / progress->size));
++      message_bar ((percent > 0) ? percent : (int) (100.0 * (double) progress->pos / progress->size),
++        "%s %s/%s (%d%%)", progress->msg, posstr, progress->sizestr,
++        (percent > 0) ? percent : (int) (100.0 * (double) progress->pos / progress->size));
+     }
+     else
+     {
+       if (percent > 0)
+-	mutt_message ("%s %s (%d%%)", progress->msg, posstr, percent);
++        message_bar (percent, "%s %s (%d%%)", progress->msg, posstr, percent);
+       else
+-	mutt_message ("%s %s", progress->msg, posstr);
++        mutt_message ("%s %s", progress->msg, posstr);
+     }
+   }
+ 
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-progress/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-progress/doc/manual.xml.head	2016-05-02 03:02:13.594190429 +0100
+@@ -2706,6 +2706,7 @@
+ <listitem><para>markers (the <quote>+</quote> markers at the beginning of wrapped lines in the pager)</para></listitem>
+ <listitem><para>message (informational messages)</para></listitem>
+ <listitem><para>normal</para></listitem>
++<listitem><para><link linkend="progress">progress</link> (visual progress bar)</para></listitem>
+ <listitem><para>prompt</para></listitem>
+ <listitem><para>quoted (text matching <link linkend="quote-regexp">$quote_regexp</link> in the body of a message)</para></listitem>
+ <listitem><para>quoted1, quoted2, ..., quoted<emphasis>N</emphasis> (higher levels of quoting)</para></listitem>
+@@ -8081,6 +8082,125 @@
+ 
+ </sect1>
+ 
++<sect1 id="progress">
++	<title>Progress Bar Patch</title>
++	<subtitle>Show a visual progress bar on slow operations</subtitle>
++
++	<sect2 id="progress-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Progress Bar</quote>, look for
++			<quote>patch-progress</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="progress-intro">
++		<title>Introduction</title>
++
++        <para>
++		The <quote>progress</quote> patch shows a visual progress bar on slow
++		tasks, such as indexing a large folder over the net.
++        </para>
++	</sect2>
++
++<!--
++	<sect2 id="progress-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="progress-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="progress-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="progress-colors">
++		<title>Colors</title>
++		<table id="table-progress-colors">
++			<title>Progress Colors</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Name</entry>
++						<entry>Default Color</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>progress</literal></entry>
++						<entry>default</entry>
++						<entry>Visual progress bar</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++<!--
++	<sect2 id="progress-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="progress-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'progress' patch.
++ 
++# The 'progress' patch provides clear visual feedback for
++# slow tasks, such as indexing a large folder over the net.
++ 
++# Set the color of the progress bar
++# White text on a red background</emphasis>
++color progress white red
++ 
++<emphasis role="comment"># vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="progress-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="color">Color command</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="progress-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="progress-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Rocco Rutte <email>pdmef at gmx.net</email></para></listitem>
++		<listitem><para>Vincent Lefevre <email>vincent at vinc17.org</email></para></listitem>
++		<listitem><para>Stefan Kuhn <email>wuodan at hispeed.ch</email></para></listitem>
++		<listitem><para>Karel Zak <email>kzak at redhat.com</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.progress mutt-1.6.1-progress/doc/muttrc.progress
+--- mutt-1.6.1/doc/muttrc.progress	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-progress/doc/muttrc.progress	2016-05-02 03:02:13.503188982 +0100
+@@ -0,0 +1,10 @@
++# Example Mutt config file for the 'progress' patch.
++
++# The 'progress' patch provides clear visual feedback for
++# slow tasks, such as indexing a large folder over the net.
++
++# Set the color of the progress bar
++# White text on a red background
++color progress white red
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/doc/vimrc.progress mutt-1.6.1-progress/doc/vimrc.progress
+--- mutt-1.6.1/doc/vimrc.progress	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-progress/doc/vimrc.progress	2016-05-02 03:02:13.507189045 +0100
+@@ -0,0 +1,5 @@
++" Vim syntax file for the mutt progress patch
++
++syntax keyword muttrcColorField contained progress
++
++" vim: syntax=vim
+diff -urN mutt-1.6.1/mutt_curses.h mutt-1.6.1-progress/mutt_curses.h
+--- mutt-1.6.1/mutt_curses.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-progress/mutt_curses.h	2016-05-02 03:02:13.600190525 +0100
+@@ -124,6 +124,7 @@
+   MT_COLOR_UNDERLINE,
+   MT_COLOR_INDEX,
+   MT_COLOR_PROMPT,
++  MT_COLOR_PROGRESS,
+   MT_COLOR_MAX
+ };
+ 
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-progress/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-progress/PATCHES	2016-05-02 03:02:13.589190350 +0100
+@@ -0,0 +1 @@
++patch-progress-neo-20160502
+diff -urN mutt-1.6.1/README.progress mutt-1.6.1-progress/README.progress
+--- mutt-1.6.1/README.progress	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-progress/README.progress	2016-05-02 03:02:13.589190350 +0100
+@@ -0,0 +1,49 @@
++Progress Bar Patch
++==================
++
++    Show a visual progress bar on slow operations
++
++Patch
++-----
++
++    To check if Mutt supports "Progress Bar", look for "patch-progress" in the
++    mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    The "progress" patch shows a visual progress bar on slow tasks, such as
++    indexing a large folder over the net.
++
++Colors
++------
++
++    Progress Colors
++
++    | Name       | Default Color | Description         |
++    |------------|---------------|---------------------|
++    | 'progress' | default       | Visual progress bar |
++
++See Also
++--------
++
++    * NeoMutt project
++    * Color command
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Rocco Rutte <pdmef at gmx.net>
++    * Vincent Lefevre <vincent at vinc17.org>
++    * Stefan Kuhn <wuodan at hispeed.ch>
++    * Karel Zak <kzak at redhat.com>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/04-status-color.patch b/debian/patches/neomutt/04-status-color.patch
new file mode 100644
index 0000000..209502b
--- /dev/null
+++ b/debian/patches/neomutt/04-status-color.patch
@@ -0,0 +1,612 @@
+diff -urN mutt-1.6.1/color.c mutt-1.6.1-status-color/color.c
+--- mutt-1.6.1/color.c	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-status-color/color.c	2016-05-02 03:02:13.826194121 +0100
+@@ -34,6 +34,7 @@
+ int ColorDefs[MT_COLOR_MAX];
+ COLOR_LINE *ColorHdrList = NULL;
+ COLOR_LINE *ColorBodyList = NULL;
++COLOR_LINE *ColorStatusList = NULL;
+ COLOR_LINE *ColorIndexList = NULL;
+ 
+ /* local to this file */
+@@ -495,7 +496,7 @@
+ static int 
+ add_pattern (COLOR_LINE **top, const char *s, int sensitive,
+ 	     int fg, int bg, int attr, BUFFER *err,
+-	     int is_index)
++	     int is_index, int match)
+ {
+ 
+   /* is_index used to store compiled pattern
+@@ -566,6 +567,7 @@
+     }
+     tmp->next = *top;
+     tmp->pattern = safe_strdup (s);
++    tmp->match = match;
+ #ifdef HAVE_COLOR
+     if(fg != -1 && bg != -1)
+     {
+@@ -708,7 +710,7 @@
+ 		   parser_callback_t callback, short dry_run)
+ {
+   int object = 0, attr = 0, fg = 0, bg = 0, q_level = 0;
+-  int r = 0;
++  int r = 0, match = 0;
+ 
+   if(parse_object(buf, s, &object, &q_level, err) == -1)
+     return -1;
+@@ -716,8 +718,6 @@
+   if(callback(buf, s, &fg, &bg, &attr, err) == -1)
+     return -1;
+ 
+-  /* extract a regular expression if needed */
+-  
+   if (object == MT_COLOR_HEADER || object == MT_COLOR_BODY || object == MT_COLOR_INDEX)
+   {
+     if (!MoreArgs (s))
+@@ -729,7 +729,7 @@
+     mutt_extract_token (buf, s, 0);
+   }
+    
+-  if (MoreArgs (s))
++  if (MoreArgs (s) && (object != MT_COLOR_STATUS))
+   {
+     strfcpy (err->data, _("too many arguments"), err->dsize);
+     return (-1);
+@@ -754,12 +754,37 @@
+ #endif
+   
+   if (object == MT_COLOR_HEADER)
+-    r = add_pattern (&ColorHdrList, buf->data, 0, fg, bg, attr, err,0);
++    r = add_pattern (&ColorHdrList, buf->data, 0, fg, bg, attr, err, 0, match);
+   else if (object == MT_COLOR_BODY)
+-    r = add_pattern (&ColorBodyList, buf->data, 1, fg, bg, attr, err, 0);
++    r = add_pattern (&ColorBodyList, buf->data, 1, fg, bg, attr, err, 0, match);
++  else if ((object == MT_COLOR_STATUS) && MoreArgs (s)) {
++    /* 'color status fg bg' can have upto 2 arguments:
++     * 0 arguments: sets the default status color (handled below by else part)
++     * 1 argument : colorize pattern on match
++     * 2 arguments: colorize nth submatch of pattern
++     */
++    mutt_extract_token (buf, s, 0);
++
++    if (MoreArgs (s)) {
++      BUFFER temporary;
++      memset (&temporary, 0, sizeof (BUFFER));
++      mutt_extract_token (&temporary, s, 0);
++      match = atoi (temporary.data);
++      FREE(&temporary.data);
++    }
++
++    if (MoreArgs (s)) {
++      strfcpy (err->data, _("too many arguments"), err->dsize);
++      return -1;
++    }
++
++    r = add_pattern (&ColorStatusList, buf->data, 1,
++		    fg, bg, attr, err, 0, match);
++  }
+   else if (object == MT_COLOR_INDEX)
+   {
+-    r = add_pattern (&ColorIndexList, buf->data, 1, fg, bg, attr, err, 1);
++    r = add_pattern (&ColorIndexList, buf->data, 1,
++		    fg, bg, attr, err, 1, match);
+     set_option (OPTFORCEREDRAWINDEX);
+   }
+   else if (object == MT_COLOR_QUOTED)
+diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-status-color/curs_main.c
+--- mutt-1.6.1/curs_main.c	2016-05-02 03:02:12.400171433 +0100
++++ mutt-1.6.1-status-color/curs_main.c	2016-05-02 03:02:13.828194153 +0100
+@@ -477,6 +477,112 @@
+   menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
+ }
+ 
++/**
++ * mutt_draw_statusline - XXX
++ */
++void
++mutt_draw_statusline (int cols, char *inbuf)
++{
++	int i          = 0;
++	int cnt        = 0;
++	int last_color = 0;
++	int color      = 0;
++	int offset     = 0;
++	int found      = 0;
++	int null_rx    = 0;
++	char buf[2048];
++
++	struct line_t {
++		short chunks;
++		struct syntax_t {
++			int color;
++			int first;
++			int last;
++		} *syntax;
++	} lineInfo = { 0, NULL };
++
++	mutt_format_string (buf, sizeof (buf), cols, cols, 0, ' ', inbuf, mutt_strlen (inbuf), 0);
++
++	lineInfo.syntax = safe_malloc (sizeof (struct syntax_t));
++	lineInfo.syntax[0].first = -1;
++	lineInfo.syntax[0].last  = -1;
++	lineInfo.syntax[0].color = ColorDefs[MT_COLOR_STATUS];
++	lineInfo.chunks = 1;
++
++	do {
++		found = 0;
++		null_rx = 0;
++		COLOR_LINE *color_line = ColorStatusList;
++
++		if (!buf[offset])
++			break;
++
++		while (color_line) {
++			regmatch_t pmatch[color_line->match + 1];
++
++			if (regexec (&color_line->rx, buf + offset, color_line->match + 1, pmatch, (offset ? REG_NOTBOL : 0)) == 0) {
++				if (pmatch[color_line->match].rm_eo != pmatch[color_line->match].rm_so) {
++					if (!found) {
++						if (++(lineInfo.chunks) > 1) {
++							safe_realloc (&(lineInfo.syntax), (lineInfo.chunks) * sizeof (struct syntax_t));
++						}
++					}
++					i = lineInfo.chunks - 1;
++					pmatch[color_line->match].rm_so += offset;
++					pmatch[color_line->match].rm_eo += offset;
++					if (!found ||
++						(pmatch[color_line->match].rm_so < (lineInfo.syntax)[i].first) ||
++						((pmatch[color_line->match].rm_so == (lineInfo.syntax)[i].first) &&
++						(pmatch[color_line->match].rm_eo > (lineInfo.syntax)[i].last))) {
++						(lineInfo.syntax)[i].color = color_line->pair;
++						(lineInfo.syntax)[i].first = pmatch[color_line->match].rm_so;
++						(lineInfo.syntax)[i].last = pmatch[color_line->match].rm_eo;
++					}
++					found = 1;
++					null_rx = 0;
++				} else {
++					null_rx = 1; /* empty regexp; don't add it, but keep looking */
++				}
++			}
++			color_line = color_line->next;
++		}
++
++		if (null_rx)
++			offset++; /* avoid degenerate cases */
++		else
++			offset = (lineInfo.syntax)[i].last;
++	} while (found || null_rx);
++
++	for (cnt = 0; cnt < mutt_strlen (buf); cnt++) {
++		color = lineInfo.syntax[0].color;
++		for (i = 0; i < lineInfo.chunks; i++) {
++			/* we assume the chunks are sorted */
++			if (cnt > (lineInfo.syntax)[i].last)
++				continue;
++			if (cnt < (lineInfo.syntax)[i].first)
++				break;
++			if (cnt != (lineInfo.syntax)[i].last) {
++				color = (lineInfo.syntax)[i].color;
++				break;
++			}
++			/* don't break here, as cnt might be in the next chunk as well */
++		}
++		if (color != last_color) {
++			attrset (color);
++			last_color = color;
++		}
++		/* XXX more than one char at a time? */
++		addch ((unsigned char)buf[cnt]);
++#if 0
++		waddnstr (stdscr, tgbuf, 10);
++		SETCOLOR (MT_COLOR_NORMAL);
++		waddnstr (stdscr, tgbuf + 10, -1);
++#endif
++	}
++
++	safe_free (&lineInfo.syntax);
++}
++
+ static const struct mapping_t IndexHelp[] = {
+   { N_("Quit"),  OP_QUIT },
+   { N_("Del"),   OP_DELETE },
+@@ -633,7 +739,7 @@
+ 	menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
+ 	move (option (OPTSTATUSONTOP) ? 0 : LINES-2, 0);
+ 	SETCOLOR (MT_COLOR_STATUS);
+-	mutt_paddstr (COLS, buf);
++	mutt_draw_statusline (COLS, buf);
+ 	NORMAL_COLOR;
+ 	menu->redraw &= ~REDRAW_STATUS;
+ 	if (option(OPTTSENABLED) && TSSupported)
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-status-color/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-status-color/doc/manual.xml.head	2016-05-02 03:02:13.830194184 +0100
+@@ -8081,6 +8081,209 @@
+ 
+ </sect1>
+ 
++<sect1 id="status-color">
++	<title>Status Color Patch</title>
++	<subtitle>Custom rules for theming the status bar</subtitle>
++
++	<sect2 id="status-color-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Status Color</quote>, look for
++			<quote>patch-status-color</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="status-color-intro">
++		<title>Introduction</title>
++
++        <para>
++		The <quote>status-color</quote> patch allows you to theme different
++		parts of the status bar (also when it's used by the index).
++        </para>
++
++        <para>
++		Unlike normal color commands, <literal>color status</literal> can now
++		take up to 2 extra parameters (regex, num).
++        </para>
++	</sect2>
++
++<!--
++	<sect2 id="status-color-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="status-color-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="status-color-commands">
++		<title>Commands</title>
++		<cmdsynopsis>
++			<command>color</command>
++			<arg choice="plain">
++				<option>status</option>
++			</arg>
++			<arg choice="plain">
++				<replaceable class="parameter">foreground</replaceable>
++			</arg>
++			<arg choice="plain">
++				<replaceable class="parameter">background</replaceable>
++			</arg>
++			<group choice="opt">
++				<arg choice="plain">
++					<replaceable class="parameter">regex</replaceable>
++				</arg>
++				<group choice="opt">
++					<arg choice="plain">
++						<replaceable class="parameter">num</replaceable>
++					</arg>
++				</group>
++			</group>
++		</cmdsynopsis>
++
++		<para>
++			With zero parameters, Mutt will set the default color for the entire
++			status bar.
++		</para>
++
++		<para>
++			With one parameter, Mutt will only color the parts matching the
++			regex.
++		</para>
++
++		<para>
++			With two parameters, Mutt will only color the num'th sub-match of
++			the regex.
++		</para>
++	</sect2>
++
++	<sect2 id="status-color-colors">
++		<title>Colors</title>
++
++		<table id="table-status-color-colors">
++			<title>Status Colors</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Name</entry>
++						<entry>Default Color</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>status</entry>
++						<entry><literal>reverse</literal></entry>
++						<entry>Status bar</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++<!--
++	<sect2 id="status-color-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="status-color-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'status-color' patch.
++ 
++# The 'status-color' patch allows you to theme different parts of
++# the status bar (also when it's used by the index).
++ 
++# For the examples below, set some defaults</emphasis>
++set status_format='-%r-Mutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?%?l? %l?]---(%s/%S)-%>-(%P)---'
++set index_format='%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s'
++set sort=threads
++set sort_aux=last-date-received
++ 
++<emphasis role="comment"># 'status color' can take up to 2 extra parameters
++ 
++# color status foreground background [ regex [ num ]]
++ 
++# 0 extra parameters
++# Set the default color for the entire status line</emphasis>
++color status blue white
++ 
++<emphasis role="comment"># 1 extra parameter
++# Set the color for a matching pattern
++# color status foreground background regexp
++ 
++# Highlight New, Deleted, or Flagged emails</emphasis>
++color status brightred white '(New|Del|Flag):[0-9]+'
++ 
++<emphasis role="comment"># Highlight mailbox ordering if it's different from the default
++# First, highlight anything (*/*)</emphasis>
++color status brightred default '\([^)]+/[^)]+\)'
++ 
++<emphasis role="comment"># Then override the color for one specfic case</emphasis>
++color status default   default '\(threads/last-date-received\)'
++ 
++<emphasis role="comment"># 2 extra parameters
++# Set the color for the nth submatch of a pattern
++# color status foreground background regexp num
++ 
++# Highlight the contents of the []s but not the [] themselves</emphasis>
++color status red default '\[([^]]+)\]' 1
++ 
++<emphasis role="comment"># The '1' refers to the first regex submatch, which is the inner
++# part in ()s
++ 
++# Highlight the mailbox</emphasis>
++color status brightwhite default 'Mutt: ([^ ]+)' 1
++ 
++<emphasis role="comment"># Search for 'Mutt: ' but only highlight what comes after it
++ 
++# vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="status-color-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="compile-time-features">Compile-Time Features</link></para></listitem>
++			<listitem><para><link linkend="regexp">Regular Expressions</link></para></listitem>
++			<listitem><para><link linkend="patterns">Patterns</link></para></listitem>
++			<listitem><para><link linkend="index-color">index-color patch</link></para></listitem>
++			<listitem><para><link linkend="color">Color command</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="status-color-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="status-color-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>David Sterba <email>dsterba at suse.cz</email></para></listitem>
++		<listitem><para>Thomas Glanzmann <email>thomas at glanzmann.de</email></para></listitem>
++		<listitem><para>Kirill A. Shutemov <email>kirill at shutemov.name</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.status-color mutt-1.6.1-status-color/doc/muttrc.status-color
+--- mutt-1.6.1/doc/muttrc.status-color	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-status-color/doc/muttrc.status-color	2016-05-02 03:02:13.731192609 +0100
+@@ -0,0 +1,49 @@
++# Example Mutt config file for the 'status-color' patch.
++
++# The 'status-color' patch allows you to theme different parts of
++# the status bar (also when it's used by the index).
++
++# For the examples below, set some defaults
++set status_format='-%r-Mutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?%?l? %l?]---(%s/%S)-%>-(%P)---'
++set index_format='%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s'
++set sort=threads
++set sort_aux=last-date-received
++
++# 'status color' can take up to 2 extra parameters
++
++# color status foreground background [ regex [ num ]]
++
++# 0 extra parameters
++# Set the default color for the entire status line
++color status blue white
++
++# 1 extra parameter
++# Set the color for a matching pattern
++# color status foreground background regexp
++
++# Highlight New, Deleted, or Flagged emails
++color status brightred white '(New|Del|Flag):[0-9]+'
++
++# Highlight mailbox ordering if it's different from the default
++# First, highlight anything (*/*)
++color status brightred default '\([^)]+/[^)]+\)'
++
++# Then override the color for one specfic case
++color status default   default '\(threads/last-date-received\)'
++
++# 2 extra parameters
++# Set the color for the nth submatch of a pattern
++# color status foreground background regexp num
++
++# Highlight the contents of the []s but not the [] themselves
++color status red default '\[([^]]+)\]' 1
++
++# The '1' refers to the first regex submatch, which is the inner
++# part in ()s
++
++# Highlight the mailbox
++color status brightwhite default 'Mutt: ([^ ]+)' 1
++
++# Search for 'Mutt: ' but only highlight what comes after it
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/mutt_curses.h mutt-1.6.1-status-color/mutt_curses.h
+--- mutt-1.6.1/mutt_curses.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-status-color/mutt_curses.h	2016-05-02 03:02:13.837194296 +0100
+@@ -130,6 +130,7 @@
+ typedef struct color_line
+ {
+   regex_t rx;
++  int match; /* which substringmap 0 for old behaviour */
+   char *pattern;
+   pattern_t *color_pattern; /* compiled pattern to speed up index color
+                                calculation */
+@@ -176,6 +177,7 @@
+ extern int ColorDefs[];
+ extern COLOR_LINE *ColorHdrList;
+ extern COLOR_LINE *ColorBodyList;
++extern COLOR_LINE *ColorStatusList;
+ extern COLOR_LINE *ColorIndexList;
+ 
+ void ci_init_color (void);
+diff -urN mutt-1.6.1/pager.c mutt-1.6.1-status-color/pager.c
+--- mutt-1.6.1/pager.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-status-color/pager.c	2016-05-02 03:02:13.838194312 +0100
+@@ -1804,13 +1804,13 @@
+ 	size_t l2 = sizeof (buffer);
+ 	hfi.hdr = (IsHeader (extra)) ? extra->hdr : extra->bdy->hdr;
+ 	mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
+-	mutt_paddstr (COLS, buffer);
++	mutt_draw_statusline (COLS, buffer);
+       }
+       else
+       {
+ 	char bn[STRING];
+ 	snprintf (bn, sizeof (bn), "%s (%s)", banner, pager_progress_str);
+-	mutt_paddstr (COLS, bn);
++	mutt_draw_statusline (COLS, bn);
+       }
+       NORMAL_COLOR;
+       if (option(OPTTSENABLED) && TSSupported)
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-status-color/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-status-color/PATCHES	2016-05-02 03:02:13.824194089 +0100
+@@ -0,0 +1 @@
++patch-status-color-neo-20160502
+diff -urN mutt-1.6.1/protos.h mutt-1.6.1-status-color/protos.h
+--- mutt-1.6.1/protos.h	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-status-color/protos.h	2016-05-02 03:02:13.839194328 +0100
+@@ -180,6 +180,7 @@
+ void mutt_default_save (char *, size_t, HEADER *);
+ void mutt_display_address (ENVELOPE *);
+ void mutt_display_sanitize (char *);
++void mutt_draw_statusline (int n, char *);
+ void mutt_edit_content_type (HEADER *, BODY *, FILE *);
+ void mutt_edit_file (const char *, const char *);
+ void mutt_edit_headers (const char *, const char *, HEADER *, char *, size_t);
+diff -urN mutt-1.6.1/README.status-color mutt-1.6.1-status-color/README.status-color
+--- mutt-1.6.1/README.status-color	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-status-color/README.status-color	2016-05-02 03:02:13.824194089 +0100
+@@ -0,0 +1,67 @@
++Status Color Patch
++==================
++
++    Custom rules for theming the status bar
++
++Patch
++-----
++
++    To check if Mutt supports "Status Color", look for "patch-status-color" in
++    the mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    The "status-color" patch allows you to theme different parts of the status
++    bar (also when it's used by the index).
++
++    Unlike normal color commands, 'color status' can now take up to 2 extra
++    parameters (regex, num).
++
++Commands
++--------
++
++        color status foreground background [ regex [ num ]]
++
++    With zero parameters, Mutt will set the default color for the entire status
++    bar.
++
++    With one parameter, Mutt will only color the parts matching the regex.
++
++    With two parameters, Mutt will only color the num'th sub-match of the regex.
++
++Colors
++------
++
++    Status Colors
++
++    | Name   | Default Color | Description |
++    |--------|---------------|-------------|
++    | status | 'reverse'     | Status bar  |
++
++See Also
++--------
++
++    * NeoMutt project
++    * Compile-Time Features
++    * Regular Expressions
++    * Patterns
++    * index-color patch
++    * Color command
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * David Sterba <dsterba at suse.cz>
++    * Thomas Glanzmann <thomas at glanzmann.de>
++    * Kirill A. Shutemov <kirill at shutemov.name>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/05-index-color.patch b/debian/patches/neomutt/05-index-color.patch
new file mode 100644
index 0000000..ef12e9c
--- /dev/null
+++ b/debian/patches/neomutt/05-index-color.patch
@@ -0,0 +1,1119 @@
+diff -urN mutt-1.6.1/color.c mutt-1.6.1-index-color/color.c
+--- mutt-1.6.1/color.c	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-index-color/color.c	2016-05-02 03:02:14.026197303 +0100
+@@ -35,6 +35,9 @@
+ COLOR_LINE *ColorHdrList = NULL;
+ COLOR_LINE *ColorBodyList = NULL;
+ COLOR_LINE *ColorIndexList = NULL;
++COLOR_LINE *ColorIndexAuthorList = NULL;
++COLOR_LINE *ColorIndexFlagsList = NULL;
++COLOR_LINE *ColorIndexSubjectList = NULL;
+ 
+ /* local to this file */
+ static int ColorQuoteSize;
+@@ -93,6 +96,14 @@
+   { "bold",		MT_COLOR_BOLD },
+   { "underline",	MT_COLOR_UNDERLINE },
+   { "index",		MT_COLOR_INDEX },
++  { "index_author",	MT_COLOR_INDEX_AUTHOR },
++  { "index_collapsed",	MT_COLOR_INDEX_COLLAPSED },
++  { "index_date",	MT_COLOR_INDEX_DATE },
++  { "index_flags",	MT_COLOR_INDEX_FLAGS },
++  { "index_label",	MT_COLOR_INDEX_LABEL },
++  { "index_number",	MT_COLOR_INDEX_NUMBER },
++  { "index_size",	MT_COLOR_INDEX_SIZE },
++  { "index_subject",	MT_COLOR_INDEX_SUBJECT },
+   { "prompt",		MT_COLOR_PROMPT },
+   { NULL,		0 }
+ };
+@@ -384,12 +395,52 @@
+   return _mutt_parse_uncolor(buf, s, data, err, 0);
+ }
+ 
++/**
++ * mutt_do_uncolor - XXX
++ */
++static void
++mutt_do_uncolor (BUFFER *buf, BUFFER *s, COLOR_LINE **ColorList,
++                 int *do_cache, int parse_uncolor)
++{
++	COLOR_LINE *tmp, *last = NULL;
++
++	do {
++		mutt_extract_token (buf, s, 0);
++		if (mutt_strcmp ("*", buf->data) == 0) {
++			for (tmp = *ColorList; tmp; ) {
++				if (!*do_cache) {
++					*do_cache = 1;
++				}
++				last = tmp;
++				tmp = tmp->next;
++				mutt_free_color_line (&last, parse_uncolor);
++			}
++			*ColorList = NULL;
++		} else {
++			for (last = NULL, tmp = *ColorList; tmp; last = tmp, tmp = tmp->next) {
++				if (mutt_strcmp (buf->data, tmp->pattern) == 0) {
++					if (!*do_cache) {
++						*do_cache = 1;
++					}
++					dprint (1, (debugfile,"Freeing pattern \"%s\" from ColorList\n",
++															 tmp->pattern));
++					if (last) {
++						last->next = tmp->next;
++					} else {
++						*ColorList = tmp->next;
++					}
++					mutt_free_color_line (&tmp, parse_uncolor);
++					break;
++				}
++			}
++		}
++	} while (MoreArgs (s));
++}
++
+ static int _mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data,
+ 				BUFFER *err, short parse_uncolor)
+ {
+   int object = 0, do_cache = 0;
+-  COLOR_LINE *tmp, *last = NULL;
+-  COLOR_LINE **list;
+ 
+   mutt_extract_token (buf, s, 0);
+ 
+@@ -399,13 +450,15 @@
+     return (-1);
+   }
+ 
+-  if (mutt_strncmp (buf->data, "index", 5) == 0)
+-    list = &ColorIndexList;
+-  else if (mutt_strncmp (buf->data, "body", 4) == 0)
+-    list = &ColorBodyList;
+-  else if (mutt_strncmp (buf->data, "header", 7) == 0)
+-    list = &ColorHdrList;
+-  else
++  if (object > MT_COLOR_INDEX_SUBJECT) { /* uncolor index column */
++    ColorDefs[object] = 0;
++    set_option (OPTFORCEREDRAWINDEX);
++    return 0;
++  }
++
++  if ((mutt_strncmp (buf->data, "body",   4) != 0) &&
++      (mutt_strncmp (buf->data, "header", 6) != 0) &&
++      (mutt_strncmp (buf->data, "index",  5) != 0))
+   {
+     snprintf (err->data, err->dsize,
+ 	      _("%s: command valid only for index, body, header objects"),
+@@ -442,43 +495,18 @@
+     return 0;
+   }
+ 
+-  do
+-  {
+-    mutt_extract_token (buf, s, 0);
+-    if (!mutt_strcmp ("*", buf->data))
+-    {
+-      for (tmp = *list; tmp; )
+-      {
+-        if (!do_cache)
+-	  do_cache = 1;
+-	last = tmp;
+-	tmp = tmp->next;
+-	mutt_free_color_line(&last, parse_uncolor);
+-      }
+-      *list = NULL;
+-    }
+-    else
+-    {
+-      for (last = NULL, tmp = *list; tmp; last = tmp, tmp = tmp->next)
+-      {
+-	if (!mutt_strcmp (buf->data, tmp->pattern))
+-	{
+-          if (!do_cache)
+-	    do_cache = 1;
+-	  dprint(1,(debugfile,"Freeing pattern \"%s\" from color list\n",
+-	                       tmp->pattern));
+-	  if (last)
+-	    last->next = tmp->next;
+-	  else
+-	    *list = tmp->next;
+-	  mutt_free_color_line(&tmp, parse_uncolor);
+-	  break;
+-	}
+-      }
+-    }
+-  }
+-  while (MoreArgs (s));
+-
++  if (object == MT_COLOR_BODY)
++    mutt_do_uncolor (buf, s, &ColorBodyList, &do_cache, parse_uncolor);
++  else if (object == MT_COLOR_HEADER)
++    mutt_do_uncolor (buf, s, &ColorHdrList, &do_cache, parse_uncolor);
++  else if (object == MT_COLOR_INDEX)
++    mutt_do_uncolor (buf, s, &ColorIndexList, &do_cache, parse_uncolor);
++  else if (object == MT_COLOR_INDEX_AUTHOR)
++    mutt_do_uncolor (buf, s, &ColorIndexAuthorList, &do_cache, parse_uncolor);
++  else if (object == MT_COLOR_INDEX_FLAGS)
++    mutt_do_uncolor (buf, s, &ColorIndexFlagsList, &do_cache, parse_uncolor);
++  else if (object == MT_COLOR_INDEX_SUBJECT)
++    mutt_do_uncolor (buf, s, &ColorIndexSubjectList, &do_cache, parse_uncolor);
+ 
+   if (do_cache && !option (OPTNOCURSES))
+   {
+@@ -718,12 +746,15 @@
+ 
+   /* extract a regular expression if needed */
+   
+-  if (object == MT_COLOR_HEADER || object == MT_COLOR_BODY || object == MT_COLOR_INDEX)
+-  {
+-    if (!MoreArgs (s))
+-    {
++  if ((object == MT_COLOR_BODY) ||
++      (object == MT_COLOR_HEADER) ||
++      (object == MT_COLOR_INDEX) ||
++      (object == MT_COLOR_INDEX_AUTHOR) ||
++      (object == MT_COLOR_INDEX_FLAGS) ||
++      (object == MT_COLOR_INDEX_SUBJECT)) {
++    if (!MoreArgs (s)) {
+       strfcpy (err->data, _("too few arguments"), err->dsize);
+-      return (-1);
++      return -1;
+     }
+ 
+     mutt_extract_token (buf, s, 0);
+@@ -761,6 +792,15 @@
+   {
+     r = add_pattern (&ColorIndexList, buf->data, 1, fg, bg, attr, err, 1);
+     set_option (OPTFORCEREDRAWINDEX);
++  } else if (object == MT_COLOR_INDEX_AUTHOR) {
++    r = add_pattern (&ColorIndexAuthorList, buf->data, 1, fg, bg, attr, err, 1);
++    set_option (OPTFORCEREDRAWINDEX);
++  } else if (object == MT_COLOR_INDEX_FLAGS) {
++    r = add_pattern (&ColorIndexFlagsList, buf->data, 1, fg, bg, attr, err, 1);
++    set_option (OPTFORCEREDRAWINDEX);
++  } else if (object == MT_COLOR_INDEX_SUBJECT) {
++    r = add_pattern (&ColorIndexSubjectList, buf->data, 1, fg, bg, attr, err, 1);
++    set_option (OPTFORCEREDRAWINDEX);
+   }
+   else if (object == MT_COLOR_QUOTED)
+   {
+@@ -787,7 +827,11 @@
+       ColorQuote[q_level] = fgbgattr_to_color(fg, bg, attr);
+   }
+   else
++  {
+     ColorDefs[object] = fgbgattr_to_color(fg, bg, attr);
++    if (object > MT_COLOR_INDEX_AUTHOR)
++      set_option (OPTFORCEREDRAWINDEX);
++  }
+ 
+   return (r);
+ }
+diff -urN mutt-1.6.1/curs_lib.c mutt-1.6.1-index-color/curs_lib.c
+--- mutt-1.6.1/curs_lib.c	2016-05-02 03:02:12.399171417 +0100
++++ mutt-1.6.1-index-color/curs_lib.c	2016-05-02 03:02:14.027197319 +0100
+@@ -779,6 +779,7 @@
+   size_t k, k2;
+   char scratch[MB_LEN_MAX];
+   mbstate_t mbstate1, mbstate2;
++  int escaped = 0;
+ 
+   memset(&mbstate1, 0, sizeof (mbstate1));
+   memset(&mbstate2, 0, sizeof (mbstate2));
+@@ -794,8 +795,15 @@
+       k = (k == (size_t)(-1)) ? 1 : n;
+       wc = replacement_char ();
+     }
+-    if (arboreal && wc < M_TREE_MAX)
++    if (escaped) {
++      escaped = 0;
++      w = 0;
++    } else if (arboreal && wc == M_SPECIAL_INDEX) {
++      escaped = 1;
++      w = 0;
++    } else if (arboreal && wc < M_TREE_MAX) {
+       w = 1; /* hack */
++    }
+     else
+     {
+ #ifdef HAVE_ISWBLANK
+@@ -1032,6 +1040,12 @@
+   memset (&mbstate, 0, sizeof (mbstate));
+   for (w=0; n && (k = mbrtowc (&wc, s, n, &mbstate)); s += k, n -= k)
+   {
++    if (*s == M_SPECIAL_INDEX) {
++      s += 2; /* skip the index coloring sequence */
++      k = 0;
++      continue;
++    }
++
+     if (k == (size_t)(-1) || k == (size_t)(-2))
+     {
+       k = (k == (size_t)(-1)) ? 1 : n;
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-index-color/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-index-color/doc/manual.xml.head	2016-05-02 03:02:14.030197366 +0100
+@@ -2642,7 +2642,7 @@
+ 
+ <command>color</command>
+ <arg choice="plain">
+-<option>index</option>
++<option><emphasis>index-object</emphasis></option>
+ </arg>
+ <arg choice="plain">
+ <replaceable class="parameter">foreground</replaceable>
+@@ -2657,7 +2657,7 @@
+ <command>uncolor</command>
+ <group choice="req">
+ <arg choice="plain">
+-<option>index</option>
++<option><emphasis>index-object</emphasis></option>
+ </arg>
+ <arg choice="plain">
+ <option>header</option>
+@@ -2687,8 +2687,8 @@
+ <para>
+ <emphasis>header</emphasis> and <emphasis>body</emphasis> match
+ <emphasis>regexp</emphasis> in the header/body of a message,
+-<emphasis>index</emphasis> matches <emphasis>pattern</emphasis> (see
+-<xref linkend="patterns"/>) in the message index.  Note that IMAP
++<emphasis>index-object</emphasis> can match <emphasis>pattern</emphasis>
++(see <xref linkend="patterns"/>) in the message index. Note that IMAP
+ server-side searches (=b, =B, =h) are not supported for color index
+ patterns.
+ </para>
+@@ -2702,6 +2702,14 @@
+ <listitem><para>bold (highlighting bold patterns in the body of messages)</para></listitem>
+ <listitem><para>error (error messages printed by Mutt)</para></listitem>
+ <listitem><para>hdrdefault (default color of the message header in the pager)</para></listitem>
++<listitem><para>index_author (color of the author name in the index, uses <emphasis>pattern</emphasis>)</para></listitem>
++<listitem><para>index_collapsed (the number of messages in a collapsed thread in the index)</para></listitem>
++<listitem><para>index_date (color of the date field in the index)</para></listitem>
++<listitem><para>index_flags (color of the message flags in the index)</para></listitem>
++<listitem><para>index_label (color of the message label in the index)</para></listitem>
++<listitem><para>index_number (color of the message number in the index)</para></listitem>
++<listitem><para>index_size (color of the message size and line number in the index)</para></listitem>
++<listitem><para>index_subject (color of the subject in the index, uses <emphasis>pattern</emphasis>)</para></listitem>
+ <listitem><para>indicator (arrow or bar used to indicate the current item in a menu)</para></listitem>
+ <listitem><para>markers (the <quote>+</quote> markers at the beginning of wrapped lines in the pager)</para></listitem>
+ <listitem><para>message (informational messages)</para></listitem>
+@@ -2717,6 +2725,24 @@
+ </itemizedlist>
+ 
+ <para>
++<emphasis>index-object</emphasis> can be one of the following:
++</para>
++
++<itemizedlist>
++<listitem><para>index (default highlighting of the entire index line, uses <emphasis>pattern</emphasis>)</para></listitem>
++<listitem><para>index_date (the date field)</para></listitem>
++<listitem><para>index_flags (the message flags, %S %Z, uses <emphasis>pattern</emphasis>)</para></listitem>
++<listitem><para>index_number (the message number, %C)</para></listitem>
++<listitem><para>index_collapsed (the number of messages in a collapsed thread, %M)</para></listitem>
++<listitem><para>index_author (the author name, %A %a %F %L %n, uses <emphasis>pattern</emphasis>)</para></listitem>
++<listitem><para>index_subject (the subject, %s, uses <emphasis>pattern</emphasis>)</para></listitem>
++<listitem><para>index_size (the message size, %c %l)</para></listitem>
++<listitem><para>index_label (the message label, %y %Y)</para></listitem>
++<listitem><para>index_tags (the transformed message tags, %g)</para></listitem>
++<listitem><para>index_tag (an individual message tag, %G, uses <emphasis>pattern / tag name</emphasis>)</para></listitem>
++</itemizedlist>
++
++<para>
+ <emphasis>foreground</emphasis> and <emphasis>background</emphasis> can
+ be one of the following:
+ </para>
+@@ -2833,7 +2859,7 @@
+ <command>unmono</command>
+ <group choice="req">
+ <arg choice="plain">
+-<option>index</option>
++<option><emphasis>index-object</emphasis></option>
+ </arg>
+ <arg choice="plain">
+ <option>header</option>
+@@ -8081,6 +8107,232 @@
+ 
+ </sect1>
+ 
++<sect1 id="index-color">
++	<title>Index Color Patch</title>
++	<subtitle>Custom rules for theming the email index</subtitle>
++
++	<sect2 id="index-color-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Index Color</quote>, look for
++			<quote>patch-index-color</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++			<listitem><para><link linkend="status-color">status-color patch</link></para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="index-color-intro">
++		<title>Introduction</title>
++
++        <para>
++		The <quote>index-color</quote> patch allows you to specify colors for
++		individual parts of the email index. e.g. Subject, Author, Flags.
++        </para>
++
++        <para>
++		First choose which part of the index you'd like to color.
++		Then, if needed, pick a pattern to match.
++        </para>
++
++		<para>
++		Note: The pattern does not have to refer to the object you wish to
++		color.  e.g.
++		</para>
++
++<screen>
++color index_author red default "~smutt"
++</screen>
++
++        <para>
++		The author appears red when the subject (~s) contains <quote>mutt</quote>.
++        </para>
++	</sect2>
++
++<!--
++	<sect2 id="index-color-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="index-color-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="index-color-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="index-color-colors">
++		<title>Colors</title>
++
++        <para>
++		All the colors default to <literal>default</literal>, i.e. unset.
++        </para>
++
++        <para>
++		The index objects can be themed using the <literal>color</literal> command.
++		Some objects require a pattern.
++        </para>
++
++<screen>
++color index-object foreground background
++color index-object foreground background pattern
++</screen>
++
++		<table id="table-index-color-colors">
++			<title>Index Colors</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Object</entry>
++						<entry>Pattern</entry>
++						<entry>Highlights</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>index</literal></entry>
++						<entry>yes</entry>
++						<entry>Entire index line</entry>
++					</row>
++					<row>
++						<entry><literal>index_author</literal></entry>
++						<entry>yes</entry>
++						<entry>Author name, %A %a %F %L %n</entry>
++					</row>
++					<row>
++						<entry><literal>index_collapsed</literal></entry>
++						<entry>no</entry>
++						<entry>Number of messages in a collapsed thread, %M</entry>
++					</row>
++					<row>
++						<entry><literal>index_date</literal></entry>
++						<entry>no</entry>
++						<entry>Date field</entry>
++					</row>
++					<row>
++						<entry><literal>index_flags</literal></entry>
++						<entry>yes</entry>
++						<entry>Message flags, %S %Z</entry>
++					</row>
++					<row>
++						<entry><literal>index_label</literal></entry>
++						<entry>no</entry>
++						<entry>Message label, %y %Y</entry>
++					</row>
++					<row>
++						<entry><literal>index_number</literal></entry>
++						<entry>no</entry>
++						<entry>Message number, %C</entry>
++					</row>
++					<row>
++						<entry><literal>index_size</literal></entry>
++						<entry>no</entry>
++						<entry>Message size, %c %l</entry>
++					</row>
++					<row>
++						<entry><literal>index_subject</literal></entry>
++						<entry>yes</entry>
++						<entry>Subject, %s</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++<!--
++	<sect2 id="index-color-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="index-color-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'index-color' feature.
++ 
++# Entire index line</emphasis>
++color index white black '.*'
++ 
++<emphasis role="comment"># Author name, %A %a %F %L %n
++ 
++# Give the author column a dark grey background</emphasis>
++color index_author default color234 '.*'
++ 
++<emphasis role="comment"># Highlight a particular from (~f)</emphasis>
++color index_author brightyellow color234 '~fRay Charles'
++ 
++<emphasis role="comment"># Message flags, %S %Z
++# Highlight the flags for flagged (~F) emails</emphasis>
++color index_flags default red '~F'
++ 
++<emphasis role="comment"># Subject, %s
++# Look for a particular subject (~s)</emphasis>
++color index_subject brightcyan default '~s\(closes #[0-9]+\)'
++ 
++<emphasis role="comment"># Number of messages in a collapsed thread, %M</emphasis>
++color index_collapsed default brightblue
++ 
++<emphasis role="comment"># Date field</emphasis>
++color index_date green default
++ 
++<emphasis role="comment"># Message label, %y %Y</emphasis>
++color index_label default brightgreen
++ 
++<emphasis role="comment"># Message number, %C</emphasis>
++color index_number red default
++ 
++<emphasis role="comment"># Message size, %c %l</emphasis>
++color index_size cyan default
++ 
++<emphasis role="comment"># vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="index-color-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="regexp">Regular Expressions</link></para></listitem>
++			<listitem><para><link linkend="patterns">Patterns</link></para></listitem>
++			<listitem><para><link linkend="index-format">$index_format</link></para></listitem>
++			<listitem><para><link linkend="color">Color command</link></para></listitem>
++			<listitem><para><link linkend="status-color">Status-Color patch</link></para></listitem>
++			<listitem><para><link linkend="keywords">Keywords patch</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="index-color-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="index-color-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Christian Aichinger <email>Greek0 at gmx.net</email></para></listitem>
++		<listitem><para>Christoph <quote>Myon</quote> Berg <email>myon at debian.org</email></para></listitem>
++		<listitem><para>Elimar Riesebieter <email>riesebie at lxtec.de</email></para></listitem>
++		<listitem><para>Eric Davis <email>edavis at insanum.com</email></para></listitem>
++		<listitem><para>Vladimir Marek <email>Vladimir.Marek at oracle.com</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.index-color mutt-1.6.1-index-color/doc/muttrc.index-color
+--- mutt-1.6.1/doc/muttrc.index-color	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-index-color/doc/muttrc.index-color	2016-05-02 03:02:13.937195887 +0100
+@@ -0,0 +1,37 @@
++# Example Mutt config file for the 'index-color' feature.
++
++# Entire index line
++color index white black '.*'
++
++# Author name, %A %a %F %L %n
++
++# Give the author column a dark grey background
++color index_author default color234 '.*'
++
++# Highlight a particular from (~f)
++color index_author brightyellow color234 '~fRay Charles'
++
++# Message flags, %S %Z
++# Highlight the flags for flagged (~F) emails
++color index_flags default red '~F'
++
++# Subject, %s
++# Look for a particular subject (~s)
++color index_subject brightcyan default '~s\(closes #[0-9]+\)'
++
++# Number of messages in a collapsed thread, %M
++color index_collapsed default brightblue
++
++# Date field
++color index_date green default
++
++# Message label, %y %Y
++color index_label default brightgreen
++
++# Message number, %C
++color index_number red default
++
++# Message size, %c %l
++color index_size cyan default
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/doc/vimrc.index-color mutt-1.6.1-index-color/doc/vimrc.index-color
+--- mutt-1.6.1/doc/vimrc.index-color	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-index-color/doc/vimrc.index-color	2016-05-02 03:02:13.938195903 +0100
+@@ -0,0 +1,13 @@
++" Vim syntax file for the mutt index-color patch
++
++syntax keyword muttrcColorField contained index
++syntax keyword muttrcColorField contained index_author
++syntax keyword muttrcColorField contained index_collapsed
++syntax keyword muttrcColorField contained index_date
++syntax keyword muttrcColorField contained index_flags
++syntax keyword muttrcColorField contained index_label
++syntax keyword muttrcColorField contained index_number
++syntax keyword muttrcColorField contained index_size
++syntax keyword muttrcColorField contained index_subject
++
++" vim: syntax=vim
+diff -urN mutt-1.6.1/hdrline.c mutt-1.6.1-index-color/hdrline.c
+--- mutt-1.6.1/hdrline.c	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-index-color/hdrline.c	2016-05-02 03:02:14.031197382 +0100
+@@ -103,6 +103,38 @@
+   return 0;
+ }
+ 
++/**
++ * add_index_color - XXX
++ *
++ * Takes the color to embed, the buffer to manipulate and the buffer length as
++ * arguments.
++ * Returns the number of chars written.
++ */
++static size_t
++add_index_color (char *buf, size_t buflen, format_flag flags, char color)
++{
++	int len;
++
++	/* only add color markers if we are operating on main index entries. */
++	if (!(flags & M_FORMAT_INDEX))
++		return 0;
++
++	if (color == MT_COLOR_INDEX) { /* buf might be uninitialized other cases */
++		len = mutt_strlen (buf);
++		buf += len;
++		buflen -= len;
++	}
++
++	if (buflen < 2)
++		return 0;
++
++	buf[0] = M_SPECIAL_INDEX;
++	buf[1] = color;
++	buf[2] = '\0';
++
++	return 2;
++}
++
+ static void make_from (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
+ {
+   int me;
+@@ -255,6 +287,7 @@
+ #define THREAD_NEW (threads && hdr->collapsed && hdr->num_hidden > 1 && mutt_thread_contains_unread (ctx, hdr) == 1)
+ #define THREAD_OLD (threads && hdr->collapsed && hdr->num_hidden > 1 && mutt_thread_contains_unread (ctx, hdr) == 2)
+   size_t len;
++  size_t colorlen;
+ 
+   hdr = hfi->hdr;
+   ctx = hfi->ctx;
+@@ -265,7 +298,9 @@
+     case 'A':
+       if(hdr->env->reply_to && hdr->env->reply_to->mailbox)
+       {
+-	mutt_format_s (dest, destlen, prefix, mutt_addr_for_display (hdr->env->reply_to));
++        colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_AUTHOR);
++        mutt_format_s (dest + colorlen, destlen - colorlen, prefix, mutt_addr_for_display (hdr->env->reply_to));
++        add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+ 	break;
+       }
+       /* fall through if 'A' returns nothing */
+@@ -273,7 +308,9 @@
+     case 'a':
+       if(hdr->env->from && hdr->env->from->mailbox)
+       {
+-	mutt_format_s (dest, destlen, prefix, mutt_addr_for_display (hdr->env->from));
++        colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_AUTHOR);
++        mutt_format_s (dest + colorlen, destlen - colorlen, prefix, mutt_addr_for_display (hdr->env->from));
++        add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       }
+       else
+         dest[0] = '\0';
+@@ -306,12 +343,16 @@
+       break;
+     
+     case 'c':
++      colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_SIZE);
+       mutt_pretty_size (buf2, sizeof (buf2), (long) hdr->content->length);
+-      mutt_format_s (dest, destlen, prefix, buf2);
++      mutt_format_s (dest + colorlen, destlen - colorlen, prefix, buf2);
++      add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       break;
+ 
+     case 'C':
+-      snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
++      colorlen = add_index_color (fmt, sizeof (fmt), flags, MT_COLOR_INDEX_NUMBER);
++      snprintf (fmt + colorlen, sizeof (fmt) - colorlen, "%%%sd", prefix);
++      add_index_color (fmt + colorlen, sizeof (fmt) - colorlen, flags, MT_COLOR_INDEX);
+       snprintf (dest, destlen, fmt, hdr->msgno + 1);
+       break;
+ 
+@@ -410,7 +451,10 @@
+ 	if (do_locales)
+ 	  setlocale (LC_TIME, "C");
+ 
+-	mutt_format_s (dest, destlen, prefix, buf2);
++	colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_DATE);
++	mutt_format_s (dest + colorlen, destlen - colorlen, prefix, buf2);
++	add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
++
+ 	if (len > 0 && op != 'd' && op != 'D') /* Skip ending op */
+ 	  src = cp + 1;
+       }
+@@ -440,8 +484,10 @@
+     case 'F':
+       if (!optional)
+       {
++        colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_AUTHOR);
+         make_from (hdr->env, buf2, sizeof (buf2), 0);
+-	mutt_format_s (dest, destlen, prefix, buf2);
++        mutt_format_s (dest + colorlen, destlen - colorlen, prefix, buf2);
++        add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       }
+       else if (mutt_addr_is_user (hdr->env->from))
+         optional = 0;
+@@ -467,7 +513,9 @@
+       if (!optional)
+       {
+ 	snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+-	snprintf (dest, destlen, fmt, (int) hdr->lines);
++	colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_SIZE);
++	snprintf (dest + colorlen, destlen - colorlen, fmt, (int) hdr->lines);
++	add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       }
+       else if (hdr->lines <= 0)
+         optional = 0;
+@@ -476,8 +524,10 @@
+     case 'L':
+       if (!optional)
+       {
++	colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_AUTHOR);
+ 	make_from (hdr->env, buf2, sizeof (buf2), 1);
+-	mutt_format_s (dest, destlen, prefix, buf2);
++	mutt_format_s (dest + colorlen, destlen - colorlen, prefix, buf2);
++	add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       }
+       else if (!check_for_mailing_list (hdr->env->to, NULL, NULL, 0) &&
+ 	       !check_for_mailing_list (hdr->env->cc, NULL, NULL, 0))
+@@ -497,7 +547,9 @@
+       break;
+ 
+     case 'n':
+-      mutt_format_s (dest, destlen, prefix, mutt_get_name (hdr->env->from));
++      colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_AUTHOR);
++      mutt_format_s (dest + colorlen, destlen - colorlen, prefix, mutt_get_name (hdr->env->from));
++      add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       break;
+ 
+     case 'N':
+@@ -532,10 +584,15 @@
+       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+       if (!optional)
+       {
+-	if (threads && is_index && hdr->collapsed && hdr->num_hidden > 1)
+-	  snprintf (dest, destlen, fmt, hdr->num_hidden);
+-	else if (is_index && threads)
+-	  mutt_format_s (dest, destlen, prefix, " ");
++	colorlen = add_index_color (dest, destlen, flags,
++				   MT_COLOR_INDEX_COLLAPSED);
++	if (threads && is_index && hdr->collapsed && hdr->num_hidden > 1) {
++	  snprintf (dest + colorlen, destlen - colorlen, fmt, hdr->num_hidden);
++	  add_index_color (dest, destlen - colorlen, flags, MT_COLOR_INDEX);
++	} else if (is_index && threads) {
++	  mutt_format_s (dest + colorlen, destlen - colorlen, prefix, " ");
++	  add_index_color (dest, destlen - colorlen, flags, MT_COLOR_INDEX);
++	}
+ 	else
+ 	  *dest = '\0';
+       }
+@@ -572,15 +629,20 @@
+       {
+ 	if (flags & M_FORMAT_FORCESUBJ)
+ 	{
+-	  mutt_format_s (dest, destlen, "", NONULL (hdr->env->subject));
++	  colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_SUBJECT);
++	  mutt_format_s (dest + colorlen, destlen - colorlen, "", NONULL (hdr->env->subject));
++	  add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+ 	  snprintf (buf2, sizeof (buf2), "%s%s", hdr->tree, dest);
+ 	  mutt_format_s_tree (dest, destlen, prefix, buf2);
+ 	}
+ 	else
+ 	  mutt_format_s_tree (dest, destlen, prefix, hdr->tree);
+       }
+-      else
+-	mutt_format_s (dest, destlen, prefix, NONULL (hdr->env->subject));
++      else {
++	colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_SUBJECT);
++	mutt_format_s (dest + colorlen, destlen - colorlen, prefix, NONULL (hdr->env->subject));
++	add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
++      }
+       break;
+ 
+     case 'S':
+@@ -603,8 +665,11 @@
+ 
+       /* FOO - this is probably unsafe, but we are not likely to have such
+ 	 a short string passed into this routine */
+-      *dest = ch;
+-      *(dest + 1) = 0;
++      buf2[0] = ch;
++      buf2[1] = 0;
++      colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_FLAGS);
++      mutt_format_s (dest + colorlen, destlen - colorlen, prefix, buf2);
++      add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       break;
+ 
+     case 't':
+@@ -676,7 +741,9 @@
+ 		hdr->tagged ? '*' :
+ 		(hdr->flagged ? '!' :
+ 		 (Tochars && ((i = mutt_user_is_recipient (hdr)) < mutt_strlen (Tochars)) ? Tochars[i] : ' ')));
+-      mutt_format_s (dest, destlen, prefix, buf2);
++      colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_FLAGS);
++      mutt_format_s (dest + colorlen, destlen - colorlen, prefix, buf2);
++      add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+       break;
+ 
+     case 'X':
+@@ -696,7 +763,9 @@
+        if (optional)
+ 	 optional = hdr->env->x_label ? 1 : 0;
+ 
+-       mutt_format_s (dest, destlen, prefix, NONULL (hdr->env->x_label));
++       colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_LABEL);
++       mutt_format_s (dest + colorlen, destlen - colorlen, prefix, NONULL (hdr->env->x_label));
++       add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+        break;
+  
+     case 'Y':
+@@ -722,10 +791,12 @@
+       if (optional)
+ 	optional = i;
+ 
++      colorlen = add_index_color (dest, destlen, flags, MT_COLOR_INDEX_LABEL);
+       if (i)
+-        mutt_format_s (dest, destlen, prefix, NONULL (hdr->env->x_label));
++        mutt_format_s (dest + colorlen, destlen - colorlen, prefix, NONULL (hdr->env->x_label));
+       else
+-        mutt_format_s (dest, destlen, prefix, "");
++        mutt_format_s (dest + colorlen, destlen - colorlen, prefix, "");
++      add_index_color (dest + colorlen, destlen - colorlen, flags, MT_COLOR_INDEX);
+ 
+       break;
+ 
+diff -urN mutt-1.6.1/menu.c mutt-1.6.1-index-color/menu.c
+--- mutt-1.6.1/menu.c	2016-05-02 03:02:12.408171560 +0100
++++ mutt-1.6.1-index-color/menu.c	2016-05-02 03:02:14.035197446 +0100
+@@ -27,7 +27,39 @@
+ 
+ char* SearchBuffers[MENU_MAX];
+ 
+-static void print_enriched_string (int attr, unsigned char *s, int do_color)
++/**
++ * get_color - XXX
++ */
++static int
++get_color (int index, unsigned char *s)
++{
++	COLOR_LINE *color;
++	HEADER *hdr = Context->hdrs[Context->v2r[index]];
++	int type = *s;
++
++	switch (type) {
++		case MT_COLOR_INDEX_AUTHOR:
++			color = ColorIndexAuthorList;
++			break;
++		case MT_COLOR_INDEX_FLAGS:
++			color = ColorIndexFlagsList;
++			break;
++		case MT_COLOR_INDEX_SUBJECT:
++			color = ColorIndexSubjectList;
++			break;
++		default:
++			return ColorDefs[type];
++	}
++
++	for (; color; color = color->next)
++		if (mutt_pattern_exec (color->color_pattern, M_MATCH_FULL_ADDRESS,
++		    Context, hdr))
++			return color->pair;
++
++	return 0;
++}
++
++static void print_enriched_string (int index, int attr, unsigned char *s, int do_color)
+ {
+   wchar_t wc;
+   size_t k;
+@@ -159,6 +191,22 @@
+       }
+       if (do_color) ATTRSET(attr);
+     }
++    else if (*s == M_SPECIAL_INDEX) {
++      s++;
++      if (do_color) {
++        if (*s == MT_COLOR_INDEX) {
++          attrset (attr);
++	} else {
++          if (get_color (index, s) == 0) {
++            attron (attr);
++	  } else {
++            attron (get_color (index, s));
++	  }
++        }
++      }
++      s++;
++      n -= 2;
++    }
+     else if ((k = mbrtowc (&wc, (char *)s, n, &mbstate)) > 0)
+     {
+       addnstr ((char *)s, k);
+@@ -265,7 +313,7 @@
+       else if (option(OPTARROWCURSOR))
+ 	addstr("   ");
+ 
+-      print_enriched_string (attr, (unsigned char *) buf, do_color);
++      print_enriched_string (i, attr, (unsigned char *) buf, do_color);
+     }
+     else
+     {
+@@ -300,7 +348,7 @@
+       menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
+       menu_pad_string (buf, sizeof (buf));
+       move (menu->oldcurrent + menu->offset - menu->top, 3);
+-      print_enriched_string (menu->color(menu->oldcurrent), (unsigned char *) buf, 1);
++      print_enriched_string (menu->oldcurrent, menu->color (menu->oldcurrent), (unsigned char *) buf, 1);
+     }
+ 
+     /* now draw it in the new location */
+@@ -312,14 +360,14 @@
+     /* erase the current indicator */
+     menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
+     menu_pad_string (buf, sizeof (buf));
+-    print_enriched_string (menu->color(menu->oldcurrent), (unsigned char *) buf, 1);
++    print_enriched_string (menu->oldcurrent, menu->color (menu->oldcurrent), (unsigned char *) buf, 1);
+ 
+     /* now draw the new one to reflect the change */
+     menu_make_entry (buf, sizeof (buf), menu, menu->current);
+     menu_pad_string (buf, sizeof (buf));
+     SETCOLOR(MT_COLOR_INDICATOR);
+     move(menu->current - menu->top + menu->offset, 0);
+-    print_enriched_string (menu->color(menu->current), (unsigned char *) buf, 0);
++    print_enriched_string (menu->current, menu->color (menu->current), (unsigned char *) buf, 0);
+   }
+   menu->redraw &= REDRAW_STATUS;
+   NORMAL_COLOR;
+@@ -341,10 +389,10 @@
+     ATTRSET(attr);
+     addch (' ');
+     menu_pad_string (buf, sizeof (buf));
+-    print_enriched_string (attr, (unsigned char *) buf, 1);
++    print_enriched_string (menu->current, attr, (unsigned char *) buf, 1);
+   }
+   else
+-    print_enriched_string (attr, (unsigned char *) buf, 0);
++    print_enriched_string (menu->current, attr, (unsigned char *) buf, 0);
+   menu->redraw &= REDRAW_STATUS;
+   NORMAL_COLOR;
+ }
+diff -urN mutt-1.6.1/mutt_curses.h mutt-1.6.1-index-color/mutt_curses.h
+--- mutt-1.6.1/mutt_curses.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-index-color/mutt_curses.h	2016-05-02 03:02:14.036197462 +0100
+@@ -122,8 +122,18 @@
+   MT_COLOR_SEARCH,
+   MT_COLOR_BOLD,
+   MT_COLOR_UNDERLINE,
+-  MT_COLOR_INDEX,
+   MT_COLOR_PROMPT,
++  /* please no non-MT_COLOR_INDEX objects after this point */
++  MT_COLOR_INDEX,
++  MT_COLOR_INDEX_AUTHOR,
++  MT_COLOR_INDEX_FLAGS,
++  MT_COLOR_INDEX_SUBJECT,
++  /* below here - only index coloring stuff that doesn't have a pattern */
++  MT_COLOR_INDEX_COLLAPSED,
++  MT_COLOR_INDEX_DATE,
++  MT_COLOR_INDEX_LABEL,
++  MT_COLOR_INDEX_NUMBER,
++  MT_COLOR_INDEX_SIZE,
+   MT_COLOR_MAX
+ };
+ 
+@@ -177,6 +187,9 @@
+ extern COLOR_LINE *ColorHdrList;
+ extern COLOR_LINE *ColorBodyList;
+ extern COLOR_LINE *ColorIndexList;
++extern COLOR_LINE *ColorIndexAuthorList;
++extern COLOR_LINE *ColorIndexFlagsList;
++extern COLOR_LINE *ColorIndexSubjectList;
+ 
+ void ci_init_color (void);
+ void ci_start_color (void);
+diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-index-color/mutt.h
+--- mutt-1.6.1/mutt.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-index-color/mutt.h	2016-05-02 03:02:14.036197462 +0100
+@@ -158,6 +158,8 @@
+ #define M_TREE_MISSING		13
+ #define M_TREE_MAX		14
+ 
++#define M_SPECIAL_INDEX		M_TREE_MAX
++
+ #define M_THREAD_COLLAPSE	(1<<0)
+ #define M_THREAD_UNCOLLAPSE	(1<<1)
+ #define M_THREAD_GET_HIDDEN	(1<<2)
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-index-color/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-index-color/PATCHES	2016-05-02 03:02:14.024197271 +0100
+@@ -0,0 +1 @@
++patch-index-color-neo-20160502
+diff -urN mutt-1.6.1/README.index-color mutt-1.6.1-index-color/README.index-color
+--- mutt-1.6.1/README.index-color	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-index-color/README.index-color	2016-05-02 03:02:14.024197271 +0100
+@@ -0,0 +1,82 @@
++Index Color Patch
++=================
++
++    Custom rules for theming the email index
++
++Patch
++-----
++
++    To check if Mutt supports "Index Color", look for "patch-index-color" in
++    the mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++    * status-color patch
++
++Introduction
++------------
++
++    The "index-color" patch allows you to specify colors for individual parts
++    of the email index. e.g. Subject, Author, Flags.
++
++    First choose which part of the index you'd like to color. Then, if needed,
++    pick a pattern to match.
++
++    Note: The pattern does not have to refer to the object you wish to color.
++    e.g.
++
++        color index_author red default "~smutt"
++
++    The author appears red when the subject (~s) contains "mutt".
++
++Colors
++------
++
++    All the colors default to 'default', i.e. unset.
++
++    The index objects can be themed using the 'color' command. Some objects
++    require a pattern.
++
++        color index-object foreground background
++        color index-object foreground background pattern
++
++    Index Colors
++
++    | Object            | Pattern | Highlights                                   |
++    |-------------------|---------|----------------------------------------------|
++    | 'index'           | yes     | Entire index line                            |
++    | 'index_author'    | yes     | Author name, %A %a %F %L %n                  |
++    | 'index_collapsed' | no      | Number of messages in a collapsed thread, %M |
++    | 'index_date'      | no      | Date field                                   |
++    | 'index_flags'     | yes     | Message flags, %S %Z                         |
++    | 'index_label'     | no      | Message label, %y %Y                         |
++    | 'index_number'    | no      | Message number, %C                           |
++    | 'index_size'      | no      | Message size, %c %l                          |
++    | 'index_subject'   | yes     | Subject, %s                                  |
++
++See Also
++--------
++
++    * NeoMutt project
++    * Regular Expressions
++    * Patterns
++    * $index_format
++    * Color command
++    * Status-Color patch
++    * Keywords patch
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Christian Aichinger <Greek0 at gmx.net>
++    * Christoph "Myon" Berg <myon at debian.org>
++    * Elimar Riesebieter <riesebie at lxtec.de>
++    * Eric Davis <edavis at insanum.com>
++    * Vladimir Marek <Vladimir.Marek at oracle.com>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/06-nested-if.patch b/debian/patches/neomutt/06-nested-if.patch
new file mode 100644
index 0000000..4e5e03a
--- /dev/null
+++ b/debian/patches/neomutt/06-nested-if.patch
@@ -0,0 +1,500 @@
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-nested-if/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-nested-if/doc/manual.xml.head	2016-05-02 03:02:14.216200326 +0100
+@@ -4595,6 +4595,18 @@
+ <emphasis>else_string</emphasis> will be expanded.
+ </para>
+ 
++<para>
++The conditional sequences can also be nested by using the %< and >
++operators. The %? notation can still be used but requires quoting. For example:
++</para>
++
++<screen>
++%<x?true&false>
++%<x?%<y?%<z?xyz&xy>&x>&none>
++</screen>
++
++<para>For more examples, see <xref linkend="nested-if"/></para>
++
+ </sect2>
+ 
+ <sect2 id="formatstrings-filters">
+@@ -8081,6 +8093,222 @@
+ 
+ </sect1>
+ 
++<sect1 id="nested-if">
++	<title>Nested If Patch</title>
++	<subtitle>Allow complex nested conditions in format strings</subtitle>
++
++	<sect2 id="nested-if-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Nested If</quote>, look for
++			<quote>patch-nested-if</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="nested-if-intro">
++		<title>Introduction</title>
++
++		<para>
++			Mutt's format strings can contain embedded if-then-else conditions.
++			They are of the form:
++		</para>
++
++<screen>
++%?VAR?TRUE&FALSE?
++</screen>
++
++		<para>
++			If the variable <quote>VAR</quote> has a value greater than zero,
++			print the <quote>TRUE</quote> string, otherwise print the
++			<quote>FALSE</quote> string.
++		</para>
++
++		<para>
++			e.g.  <literal>%?S?Size: %S&Empty?</literal>
++		</para>
++
++		<para>Which can be read as:</para>
++
++		<literallayout>
++		    if (%S > 0) {
++		        print "Size: %S"
++		    } else {
++		        print "Empty"
++		    }
++		</literallayout>
++
++		<para>
++			These conditions are useful, but in Mutt they cannot be nested
++			within one another.  This patch uses the notation
++			<literal>%<VAR?TRUE&FALSE></literal> and allows them to be nested.
++		</para>
++
++		<para>
++			The <literal>%<...></literal> notation was used to format the
++			current local time.  but that's not really very useful since mutt
++			has no means of refreshing the screen periodically.
++		</para>
++
++		<para>
++			A simple nested condition might be:
++			(Some whitespace has been introduced for clarity)
++		</para>
++
++		<literallayout>
++		    %<x? %<y? XY & X > & %<y? Y & NONE > >  Conditions
++		         %<y? XY & X >                      x>0
++		              XY                            x>0,y>0
++		                   X                        x>0,y=0
++		</literallayout>
++
++		<literallayout>
++		    %<x? %<y? XY & X > & %<y? Y & NONE > >  Conditions
++		                         %<y? Y & NONE >    x=0
++		                              Y             x=0,y>0
++		                                  NONE      x=0,y=0
++		</literallayout>
++
++		<para>Equivalent to:</para>
++
++		<literallayout>
++		    if (x > 0) {
++		        if (y > 0) {
++		            print 'XY'
++		        } else {
++		            print 'X'
++		        }
++		    } else {
++		        if (y > 0) {
++		            print 'Y'
++		        } else {
++		            print 'NONE'
++		        }
++		    }
++		</literallayout>
++
++		<para>Examples:</para>
++
++<screen>
++set index_format='%4C %Z %{%b %d} %-25.25n %s%> %<M?%M Msgs &%<l?%l Lines&%c Bytes>>'
++</screen>
++
++		<literallayout>
++		    if a thread is folded
++		        display the number of messages (%M)
++		    else if we know how many lines in the message
++		        display lines in message (%l)
++		    else
++		        display the size of the message in bytes (%c)
++		</literallayout>
++
++<screen>
++set index_format='%4C %Z %{%b %d} %-25.25n %<M?[%M] %s&%s%* %<l?%l&%c>>'
++</screen>
++
++		<literallayout>
++		    if a thread is folded
++		        display the number of messages (%M)
++		        display the subject (%s)
++		    else if we know how many lines in the message
++		        display lines in message (%l)
++		    else
++		        display the size of the message in bytes (%c)
++		</literallayout>
++
++	</sect2>
++
++	<sect2 id="nested-if-variables">
++		<title>Variables</title>
++		The <quote>nested-if</quote> patch doesn't have any config of its own.
++		It modifies the behavior of the format strings.
++	</sect2>
++
++<!--
++	<sect2 id="nested-if-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="nested-if-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="nested-if-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="nested-if-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="nested-if-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'nested-if' feature.
++ 
++# This patch uses the format: '%<VAR?TRUE&FALSE>' for conditional
++# format strings that can be nested.
++ 
++# Example 1
++# if a thread is folded
++#       display the number of messages (%M)
++# else if we know how many lines in the message
++#       display lines in message (%l)
++# else display the size of the message in bytes (%c)</emphasis>
++set index_format='%4C %Z %{%b %d} %-25.25n %s%> %<M?%M Msgs &%<l?%l Lines&%c Bytes>>'
++ 
++<emphasis role="comment"># Example 2
++# if a thread is folded
++#       display the number of messages (%M)
++#       display the subject (%s)
++# else if we know how many lines in the message
++#       display lines in message (%l)
++# else
++#       display the size of the message in bytes (%c)</emphasis>
++set index_format='%4C %Z %{%b %d} %-25.25n %<M?[%M] %s&%s%* %<l?%l&%c>>'
++ 
++<emphasis role="comment"># vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="nested-if-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="cond-date">cond-date patch</link></para></listitem>
++			<listitem><para><link linkend="index-format">$index_format</link></para></listitem>
++			<listitem><para><link linkend="status-format">$status_format</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="nested-if-known-bugs">
++		<title>Known Bugs</title>
++		Patch overwrites $<fmt> handler in <literal>$index_format</literal>
++	</sect2>
++
++	<sect2 id="nested-if-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>David Champion <email>dgc at uchicago.edu</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.nested-if mutt-1.6.1-nested-if/doc/muttrc.nested-if
+--- mutt-1.6.1/doc/muttrc.nested-if	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-nested-if/doc/muttrc.nested-if	2016-05-02 03:02:14.117198751 +0100
+@@ -0,0 +1,24 @@
++# Example Mutt config file for the 'nested-if' feature.
++
++# This patch uses the format: '%<VAR?TRUE&FALSE>' for conditional
++# format strings that can be nested.
++
++# Example 1
++# if a thread is folded
++#       display the number of messages (%M)
++# else if we know how many lines in the message
++#       display lines in message (%l)
++# else display the size of the message in bytes (%c)
++set index_format='%4C %Z %{%b %d} %-25.25n %s%> %<M?%M Msgs &%<l?%l Lines&%c Bytes>>'
++
++# Example 2
++# if a thread is folded
++#       display the number of messages (%M)
++#       display the subject (%s)
++# else if we know how many lines in the message
++#       display lines in message (%l)
++# else
++#       display the size of the message in bytes (%c)
++set index_format='%4C %Z %{%b %d} %-25.25n %<M?[%M] %s&%s%* %<l?%l&%c>>'
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-nested-if/muttlib.c
+--- mutt-1.6.1/muttlib.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-nested-if/muttlib.c	2016-05-02 03:02:14.226200485 +0100
+@@ -1213,6 +1213,24 @@
+ 
+       if (*src == '?')
+       {
++	/* change original %? to new %< notation */
++	/* %?x?y&z? to %<x?y&z> where y and z are nestable */
++	char *p = (char *) src;
++	*p = '<';
++	for ( ; *p && *p != '?'; p++);
++	  /* nothing */
++	if (*p == '?') {
++	  p++;
++	}
++	for ( ; *p && *p != '?'; p++);
++	  /* nothing */
++	if (*p == '?') {
++	  *p = '>';
++	}
++      }
++
++      if (*src == '<')
++      {
+ 	flags |= M_FORMAT_OPTIONAL;
+ 	src++;
+       }
+@@ -1239,6 +1257,8 @@
+ 
+       if (flags & M_FORMAT_OPTIONAL)
+       {
++	int lrbalance;
++
+         if (*src != '?')
+           break; /* bad format */
+         src++;
+@@ -1246,8 +1266,20 @@
+         /* eat the `if' part of the string */
+         cp = ifstring;
+ 	count = 0;
+-        while (count < sizeof (ifstring) && *src && *src != '?' && *src != '&')
+-	{
++	lrbalance = 1;
++        while ((lrbalance > 0) && (count < sizeof (ifstring)) && *src) {
++	  if (*src == '\\') {
++	    src++;
++	    *cp++ = *src++;
++	  } else if ((src[0] == '%') && (src[1] == '<')) {
++	    lrbalance++;
++	  } else if (src[0] == '>') {
++	    lrbalance--;
++	  }
++	  if (lrbalance == 0)
++	    break;
++	  if ((lrbalance == 1) && (src[0] == '&'))
++	    break;
+           *cp++ = *src++;
+ 	  count++;
+ 	}
+@@ -1258,9 +1290,20 @@
+ 	  src++; /* skip the & */
+ 	cp = elsestring;
+ 	count = 0;
+-	while (count < sizeof (elsestring) && *src && *src != '?')
+-	{
+-	  *cp++ = *src++;
++	while ((lrbalance > 0) && (count < sizeof (elsestring)) && *src) {
++	  if (*src == '\\') {
++	    src++;
++	    *cp++ = *src++;
++	  } else if ((src[0] == '%') && (src[1] == '<')) {
++	    lrbalance++;
++	  } else if (src[0] == '>') {
++	    lrbalance--;
++	  }
++	  if (lrbalance == 0)
++	    break;
++	  if ((lrbalance == 1) && (src[0] == '&'))
++	    break;
++          *cp++ = *src++;
+ 	  count++;
+ 	}
+ 	*cp = 0;
+@@ -1268,7 +1311,7 @@
+ 	if (!*src)
+ 	  break; /* bad format */
+ 
+-        src++; /* move past the trailing `?' */
++        src++; /* move past the trailing `>' (formerly '?') */
+       }
+ 
+       /* handle generic cases first */
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-nested-if/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-nested-if/PATCHES	2016-05-02 03:02:14.208200199 +0100
+@@ -0,0 +1 @@
++patch-nested-if-neo-20160502
+diff -urN mutt-1.6.1/README.nested-if mutt-1.6.1-nested-if/README.nested-if
+--- mutt-1.6.1/README.nested-if	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-nested-if/README.nested-if	2016-05-02 03:02:14.208200199 +0100
+@@ -0,0 +1,125 @@
++Nested If Patch
++===============
++
++    Allow complex nested conditions in format strings
++
++Patch
++-----
++
++    To check if Mutt supports "Nested If", look for "patch-nested-if" in the
++    mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    Mutt's format strings can contain embedded if-then-else conditions. They
++    are of the form:
++
++        %?VAR?TRUE&FALSE?
++
++    If the variable "VAR" has a value greater than zero, print the "TRUE"
++    string, otherwise print the "FALSE" string.
++
++    e.g. '%?S?Size: %S&Empty?'
++
++    Which can be read as:
++
++        if (%S > 0) {
++            print "Size: %S"
++        } else {
++            print "Empty"
++        }
++
++
++    These conditions are useful, but in Mutt they cannot be nested within one
++    another. This patch uses the notation '%<VAR?TRUE&FALSE>' and allows them
++    to be nested.
++
++    The '%<...>' notation was used to format the current local time. but that's
++    not really very useful since mutt has no means of refreshing the screen
++    periodically.
++
++    A simple nested condition might be: (Some whitespace has been introduced
++    for clarity)
++
++        %<x? %<y? XY & X > & %<y? Y & NONE > >  Conditions
++             %<y? XY & X >                      x>0
++                  XY                            x>0,y>0
++                       X                        x>0,y=0
++
++
++        %<x? %<y? XY & X > & %<y? Y & NONE > >  Conditions
++                             %<y? Y & NONE >    x=0
++                                  Y             x=0,y>0
++                                      NONE      x=0,y=0
++
++
++    Equivalent to:
++
++        if (x > 0) {
++            if (y > 0) {
++                print 'XY'
++            } else {
++                print 'X'
++            }
++        } else {
++            if (y > 0) {
++                print 'Y'
++            } else {
++                print 'NONE'
++            }
++        }
++
++
++    Examples:
++
++        set index_format='%4C %Z %{%b %d} %-25.25n %s%> %<M?%M Msgs &%<l?%l Lines&%c Bytes>>'
++
++        if a thread is folded
++            display the number of messages (%M)
++        else if we know how many lines in the message
++            display lines in message (%l)
++        else
++            display the size of the message in bytes (%c)
++
++
++        set index_format='%4C %Z %{%b %d} %-25.25n %<M?[%M] %s&%s%* %<l?%l&%c>>'
++
++        if a thread is folded
++            display the number of messages (%M)
++            display the subject (%s)
++        else if we know how many lines in the message
++            display lines in message (%l)
++        else
++            display the size of the message in bytes (%c)
++
++
++Variables
++---------
++
++    The nested-if patch doesn't have any config of its own. It modifies the behavior of the
++    format strings.
++
++See Also
++--------
++
++    * NeoMutt project
++    * cond-date patch
++    * $index_format
++    * $status_format
++
++Known Bugs
++----------
++
++    Patch overwrites $<fmt> handler in
++    $index_format
++
++Credits
++-------
++
++    * David Champion <dgc at uchicago.edu>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/07-cond-date.patch b/debian/patches/neomutt/07-cond-date.patch
new file mode 100644
index 0000000..fc571e1
--- /dev/null
+++ b/debian/patches/neomutt/07-cond-date.patch
@@ -0,0 +1,789 @@
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-cond-date/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-cond-date/doc/manual.xml.head	2016-05-02 03:02:14.642207104 +0100
+@@ -4701,6 +4701,27 @@
+ 
+ </sect2>
+ 
++<sect2 id="formatstrings-conditional-dates">
++<title>Conditional Dates</title>
++<para>
++This patch allows the format of dates in the index to vary based on how recent
++the message is. This is especially useful in combination with David Champion's
++patch to allow if-else sequences to be nested.
++</para>
++
++<para>
++For example, using
++<literal>%<[y?%<[d?%[%H:%M]&%[%m/%d]>&%[%y.%m]></literal>
++for the date in the <literal>$index_format</literal> will produce a display like:
++</para>
++
++<screen>
++   1   + 14.12 Grace Hall      (   13) Gulliver's Travels
++   2   + 10/02 Callum Harrison (   48) Huckleberry Finn
++   3     12:17 Rhys Lee        (   42) The Lord Of The Rings
++</screen>
++</sect2>
++
+ </sect1>
+ 
+ <sect1 id="mailto-allow">
+@@ -8081,6 +8102,413 @@
+ 
+ </sect1>
+ 
++<sect1 id="cond-date">
++	<title>Conditional Dates Patch</title>
++	<subtitle>Use rules to choose date format</subtitle>
++
++	<sect2 id="cond-date-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Conditional Dates</quote>, look for
++			<quote>patch-cond-date</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++			<listitem><para><link linkend="nested-if">nested-if patch</link></para></listitem>
++		</itemizedlist>
++
++		<para>
++			This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.
++		</para>
++	</sect2>
++
++	<sect2 id="cond-date-intro">
++		<title>Introduction</title>
++
++		<para>
++		The <quote>cond-date</quote> patch allows you to construct
++		<link linkend="index-format">$index_format</link> expressions based on the age of the email.
++		</para>
++
++		<para>
++		Mutt's default <literal>$index_format</literal> displays email dates in the
++		form: abbreviated-month day-of-month — <quote>Jan 14</quote>.
++		</para>
++
++		<para>
++		The format is configurable but only per-mailbox.  This patch allows you
++		to configure the display depending on the age of the email.
++		</para>
++
++		<table id="table-cond-date-scheme">
++			<title>Potential Formatting Scheme</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Email Sent</entry>
++						<entry>Format</entry>
++						<entry>Example</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>Today</entry>
++						<entry><literal>%H:%M</literal></entry>
++						<entry>13:23</entry>
++					</row>
++					<row>
++						<entry>This Month</entry>
++						<entry><literal>%a %d</literal></entry>
++						<entry>Thu 17</entry>
++					</row>
++					<row>
++						<entry>This Year</entry>
++						<entry><literal>%b %d</literal></entry>
++						<entry>Dec 10</entry>
++					</row>
++					<row>
++						<entry>Older than 1 Year</entry>
++						<entry><literal>%m/%y</literal></entry>
++						<entry>06/14</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++
++		<para>
++        For an explanation of the date formatting strings, see
++        <literal>strftime(3).</literal>
++		</para>
++
++		<para>
++        By carefully picking your formats, the dates can remain
++        unambiguous and compact.
++		</para>
++
++		<para>
++		Mutt's conditional format strings have the form:
++		(whitespace introduced for clarity)
++		</para>
++
++		<screen>%? TEST ? TRUE & FALSE ?</screen>
++
++		<para>
++		The examples below use the test <quote>%[</quote> — the date
++		of the message in the local timezone.  They will also work with
++		<quote>%(</quote> — the local time that the message arrived.
++		</para>
++
++		<para>
++		The date tests are of the form:
++		</para>
++
++		<screen>%[nX? TRUE & FALSE ?</screen>
++
++		<itemizedlist>
++		<listitem><para><quote>n</quote> is an optional count (defaults to 1 if missing)</para></listitem>
++		<listitem><para><quote>X</quote> is the time period</para></listitem>
++		</itemizedlist>
++
++		<table id="table-cond-date-format-codes">
++			<title>Date Formatting Codes</title>
++			<tgroup cols="2">
++				<thead>
++					<row>
++						<entry>Letter</entry>
++						<entry>Time Period</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>y</entry>
++						<entry>Years</entry>
++					</row>
++					<row>
++						<entry>m</entry>
++						<entry>Months</entry>
++					</row>
++					<row>
++						<entry>w</entry>
++						<entry>Weeks</entry>
++					</row>
++					<row>
++						<entry>d</entry>
++						<entry>Days</entry>
++					</row>
++					<row>
++						<entry>H</entry>
++						<entry>Hours</entry>
++					</row>
++					<row>
++						<entry>M</entry>
++						<entry>Minutes</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++
++		<table id="table-cond-date-example-tests">
++			<title>Example Date Tests</title>
++			<tgroup cols="2">
++				<thead>
++					<row>
++						<entry>Test</entry>
++						<entry>Meaning</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>%[y</literal></entry>
++						<entry>This year</entry>
++					</row>
++					<row>
++						<entry><literal>%[1y</literal></entry>
++						<entry>This year</entry>
++					</row>
++					<row>
++						<entry><literal>%[6m</literal></entry>
++						<entry>In the last 6 months</entry>
++					</row>
++					<row>
++						<entry><literal>%[w</literal></entry>
++						<entry>This week</entry>
++					</row>
++					<row>
++						<entry><literal>%[d</literal></entry>
++						<entry>Today</entry>
++					</row>
++					<row>
++						<entry><literal>%[4H</literal></entry>
++						<entry>In the last 4 hours</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++
++		<sect3 id="cond-date-example1">
++			<title>Example 1</title>
++
++			<para>We start with a one-condition test.</para>
++
++			<table id="table-cond-date-example1">
++				<title>Example 1</title>
++				<tgroup cols="4">
++					<thead>
++						<row>
++							<entry>Test</entry>
++							<entry>Date Range</entry>
++							<entry>Format String</entry>
++							<entry>Example</entry>
++						</row>
++					</thead>
++					<tbody>
++						<row>
++							<entry><literal>%[1m</literal></entry>
++							<entry>This month</entry>
++							<entry><literal>%[%b %d]</literal></entry>
++							<entry>Dec 10</entry>
++						</row>
++						<row>
++							<entry></entry>
++							<entry>Older</entry>
++							<entry><literal>%[%Y-%m-%d]</literal></entry>
++							<entry>2015-04-23</entry>
++						</row>
++					</tbody>
++				</tgroup>
++			</table>
++
++			<para>The $index_format string would contain:</para>
++<screen>
++%?[1m?%[%b %d]&%[%Y-%m-%d]?
++</screen>
++ 
++			<para>
++				Reparsed a little, for clarity, you can see the
++				test condition and the two format strings.
++			</para>
++
++<screen>
++%?[1m?        &           ?
++      %[%b %d] %[%Y-%m-%d]
++</screen>
++
++		</sect3>
++
++		<sect3 id="cond-date-example2">
++			<title>Example 2</title>
++
++			<para>
++			This example contains three test conditions and four date formats.
++			</para>
++
++			<table id="table-cond-date-example2">
++				<title>Example 2</title>
++				<tgroup cols="4">
++					<thead>
++						<row>
++							<entry>Test</entry>
++							<entry>Date Range</entry>
++							<entry>Format String</entry>
++							<entry>Example</entry>
++						</row>
++					</thead>
++					<tbody>
++						<row>
++							<entry><literal>%[d</literal></entry>
++							<entry>Today</entry>
++							<entry><literal>%[%H:%M ] </literal></entry>
++							<entry>12:34</entry>
++						</row>
++						<row>
++							<entry><literal>%[m</literal></entry>
++							<entry>This month</entry>
++							<entry><literal>%[%a %d]</literal></entry>
++							<entry>Thu 12</entry>
++						</row>
++						<row>
++							<entry><literal>%[y</literal></entry>
++							<entry>This year</entry>
++							<entry><literal>%[%b %d]</literal></entry>
++							<entry>Dec 10</entry>
++						</row>
++						<row>
++							<entry></entry>
++							<entry>Older</entry>
++							<entry><literal>%[%m/%y ]</literal></entry>
++							<entry>06/15</entry>
++						</row>
++					</tbody>
++				</tgroup>
++			</table>
++
++			<para>The $index_format string would contain:</para>
++ 
++<screen>
++%<[y?%<[m?%<[d?%[%H:%M ]&%[%a %d]>&%[%b %d]>&%[%m/%y ]>
++</screen>
++
++			<para>
++				Reparsed a little, for clarity, you can see the
++				test conditions and the four format strings.
++			</para>
++
++<screen>
++%<[y?                                       &%[%m/%y ]>  Older
++     %<[m?                        &%[%b %d]>             This year
++          %<[d?         &%[%a %d]>                       This month
++               %[%H:%M ]                                 Today
++</screen>
++
++			<para>
++			This a another view of the same example, with some whitespace
++			for clarity.
++			</para>
++
++<screen>
++%<[y? %<[m? %<[d? AAA & BBB > & CCC > & DDD >
++</screen>
++
++			<literallayout>
++AAA = %[%H:%M ]
++BBB = %[%a %d]
++CCC = %[%b %d]
++DDD = %[%m/%y ]
++			</literallayout>
++		</sect3>
++	</sect2>
++
++	<sect2 id="cond-date-variables">
++		<title>Variables</title>
++
++        <para>
++		The <quote>cond-date</quote> patch doesn't have any config of its own.
++		It modifies the behavior of the format strings.
++        </para>
++	</sect2>
++
++<!--
++	<sect2 id="cond-date-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="cond-date-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="cond-date-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="cond-date-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="cond-date-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'index-color' feature.
++#
++# The default index_format is:
++#       '%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s'
++#
++# We replace the date field '%{%b %d}', giving:</emphasis>
++set index_format='%4C %Z %<[y?%<[m?%<[d?%[%H:%M ]&%[%a %d]>&%[%b %d]>&%[%m/%y ]> %-15.15L (%?l?%4l&%4c?) %s'
++ 
++<emphasis role="comment"># Test  Date Range  Format String  Example
++# --------------------------------------------
++# %[d   Today       %[%H:%M ]      12:34
++# %[m   This month  %[%a %d]       Thu 12
++# %[y   This year   %[%b %d]       Dec 10
++# -     Older       %[%m/%y ]      06/15
++ 
++# vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="cond-date-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="index-format">$index_format</link></para></listitem>
++			<listitem><para><link linkend="nested-if">nested-if patch</link></para></listitem>
++			<listitem><para><literal>strftime(3)</literal></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="cond-date-known-bugs">
++		<title>Known Bugs</title>
++
++		<para>
++			Date parsing doesn't quite do what you expect.
++			<quote>1w</quote> doesn't mean the <quote>in the last 7 days</quote>, but
++			<quote><emphasis>this</emphasis> week</quote>.  This doesn't match
++			the normal Mutt behaviour: for example <literal>~d>1w</literal>
++			means emails dated in the last 7 days.
++		</para>
++
++	</sect2>
++
++	<sect2 id="cond-date-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Aaron Schrab <email>aaron at schrab.com</email></para></listitem>
++		<listitem><para>Eric Davis <email>edavis at insanum.com</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.cond-date mutt-1.6.1-cond-date/doc/muttrc.cond-date
+--- mutt-1.6.1/doc/muttrc.cond-date	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-cond-date/doc/muttrc.cond-date	2016-05-02 03:02:14.535205401 +0100
+@@ -0,0 +1,16 @@
++# Example Mutt config file for the 'index-color' feature.
++#
++# The default index_format is:
++#       '%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s'
++#
++# We replace the date field '%{%b %d}', giving:
++set index_format='%4C %Z %<[y?%<[m?%<[d?%[%H:%M ]&%[%a %d]>&%[%b %d]>&%[%m/%y ]> %-15.15L (%?l?%4l&%4c?) %s'
++
++# Test  Date Range  Format String  Example
++# --------------------------------------------
++# %[d   Today       %[%H:%M ]      12:34
++# %[m   This month  %[%a %d]       Thu 12
++# %[y   This year   %[%b %d]       Dec 10
++# -     Older       %[%m/%y ]      06/15
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/hdrline.c mutt-1.6.1-cond-date/hdrline.c
+--- mutt-1.6.1/hdrline.c	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-cond-date/hdrline.c	2016-05-02 03:02:14.643207119 +0100
+@@ -327,6 +327,98 @@
+ 	const char *cp;
+ 	struct tm *tm; 
+ 	time_t T;
++	int i = 0, invert = 0;
++
++	if (optional && ((op == '[') || (op == '('))) {
++	  char *is;
++	  T = time (NULL);
++	  tm = localtime (&T);
++	  T -= (op == '(') ? hdr->received : hdr->date_sent;
++
++	  is = (char *) prefix;
++	  if (*is == '>') {
++	    invert = 1;
++	    is++;
++	  }
++
++	  while (*is && (*is != '?')) {
++	    int t = strtol (is, &is, 10);
++	    /* semi-broken (assuming 30 days in all months) */
++	    switch (*(is++)) {
++	      case 'y':
++		if (t > 1) {
++		  t--;
++		  t *= (60 * 60 * 24 * 365);
++		}
++		t += ((tm->tm_mon  * 60 * 60 * 24 * 30) +
++		      (tm->tm_mday * 60 * 60 * 24) +
++		      (tm->tm_hour * 60 * 60) +
++		      (tm->tm_min  * 60) +
++		       tm->tm_sec);
++		break;
++
++	      case 'm':
++		if (t > 1) {
++		  t--;
++		  t *= (60 * 60 * 24 * 30);
++		}
++		t += ((tm->tm_mday * 60 * 60 * 24) +
++		      (tm->tm_hour * 60 * 60) +
++		      (tm->tm_min  * 60) +
++		      tm->tm_sec);
++		break;
++
++	      case 'w':
++		if (t > 1) {
++		  t--;
++		  t *= (60 * 60 * 24 * 7);
++		}
++		t += ((tm->tm_wday * 60 * 60 * 24) +
++		      (tm->tm_hour * 60 * 60) +
++		      (tm->tm_min  * 60) +
++		       tm->tm_sec);
++		break;
++
++	      case 'd':
++		if (t > 1) {
++		  t--;
++		  t *= (60 * 60 * 24);
++		}
++		t += ((tm->tm_hour * 60 * 60) +
++		      (tm->tm_min  * 60) +
++		       tm->tm_sec);
++		break;
++
++	      case 'H':
++		if (t > 1) {
++		  t--;
++		  t *= (60 * 60);
++		}
++		t += ((tm->tm_min * 60) +
++		       tm->tm_sec);
++		break;
++
++	      case 'M':
++		if (t > 1) {
++		  t--;
++		  t *= (60);
++		}
++		t += (tm->tm_sec);
++		break;
++
++	      default:
++		break;
++	    }
++	    i += t;
++	  }
++
++	  if (i < 0)
++	    i *= -1;
++
++	  if (((T > i) || (T < (-1*i))) ^ invert)
++	    optional = 0;
++	  break;
++	}
+ 
+ 	p = dest;
+ 
+diff -urN mutt-1.6.1/init.h mutt-1.6.1-cond-date/init.h
+--- mutt-1.6.1/init.h	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-cond-date/init.h	2016-05-02 03:02:14.646207167 +0100
+@@ -1361,6 +1361,10 @@
+   ** .dt %*X    .dd soft-fill with character ``X'' as pad
+   ** .de
+   ** .pp
++  ** Date format expressions can be constructed based on relative dates. Using
++  ** the date formatting operators along with nested conditionals, the date
++  ** format can be modified based on how old a message is.  See the section on
++  ** ``Conditional Dates'' for an explanation and examples
+   ** ``Soft-fill'' deserves some explanation: Normal right-justification
+   ** will print everything to the left of the ``%>'', displaying padding and
+   ** whatever lies to the right only if there's room. By contrast,
+diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-cond-date/muttlib.c
+--- mutt-1.6.1/muttlib.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-cond-date/muttlib.c	2016-05-02 03:02:14.649207215 +0100
+@@ -1214,7 +1214,15 @@
+       if (*src == '?')
+       {
+ 	flags |= M_FORMAT_OPTIONAL;
++	ch = *(++src); /* save the character to switch on */
+ 	src++;
++	cp = prefix;
++	count = 0;
++	while ((count < sizeof (prefix)) && (*src != '?')) {
++	  *cp++ = *src++;
++	  count++;
++	}
++	*cp = 0;
+       }
+       else
+       {
+@@ -1230,12 +1238,12 @@
+ 	  count++;
+ 	}
+ 	*cp = 0;
+-      }
+ 
+-      if (!*src)
+-	break; /* bad format */
++	if (!*src)
++	  break; /* bad format */
+ 
+-      ch = *src++; /* save the character to switch on */
++	ch = *src++; /* save the character to switch on */
++      }
+ 
+       if (flags & M_FORMAT_OPTIONAL)
+       {
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-cond-date/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-cond-date/PATCHES	2016-05-02 03:02:14.636207008 +0100
+@@ -0,0 +1 @@
++patch-cond-date-neo-20160502
+diff -urN mutt-1.6.1/README.cond-date mutt-1.6.1-cond-date/README.cond-date
+--- mutt-1.6.1/README.cond-date	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-cond-date/README.cond-date	2016-05-02 03:02:14.637207024 +0100
+@@ -0,0 +1,163 @@
++Conditional Dates Patch
++=======================
++
++    Use rules to choose date format
++
++Patch
++-----
++
++    To check if Mutt supports "Conditional Dates", look for "patch-cond-date"
++    in the mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++    * nested-if patch
++
++Introduction
++------------
++
++    The "cond-date" patch allows you to construct $index_format expressions
++    based on the age of the email.
++
++    Mutt's default '$index_format' displays email dates in the form:
++    abbreviated-month day-of-month — "Jan 14".
++
++    The format is configurable but only per-mailbox. This patch allows you to
++    configure the display depending on the age of the email.
++
++    Potential Formatting Scheme
++
++    | Email Sent        | Format  | Example |
++    |-------------------|---------|---------|
++    | Today             | '%H:%M' | 13:23   |
++    | This Month        | '%a %d' | Thu 17  |
++    | This Year         | '%b %d' | Dec 10  |
++    | Older than 1 Year | '%m/%y' | 06/14   |
++
++    For an explanation of the date formatting strings, see 'strftime(3).'
++
++    By carefully picking your formats, the dates can remain unambiguous and
++    compact.
++
++    Mutt's conditional format strings have the form: (whitespace introduced for
++    clarity)
++
++        %? TEST ? TRUE & FALSE ?
++
++    The examples below use the test "%[" — the date of the message in the local
++    timezone. They will also work with "%(" — the local time that the message
++    arrived.
++
++    The date tests are of the form:
++
++        %[nX? TRUE & FALSE ?
++
++    * "n" is an optional count (defaults to 1 if missing)
++    * "X" is the time period
++
++    Date Formatting Codes
++
++    | Letter | Time Period |
++    |--------|-------------|
++    | y      | Years       |
++    | m      | Months      |
++    | w      | Weeks       |
++    | d      | Days        |
++    | H      | Hours       |
++    | M      | Minutes     |
++
++    Date Tests
++
++    | Test   | Meaning              |
++    |--------|----------------------|
++    | '%[y'  | This year            |
++    | '%[1y' | This year            |
++    | '%[6m' | In the last 6 months |
++    | '%[w'  | This week            |
++    | '%[d'  | Today                |
++    | '%[4H' | In the last 4 hours  |
++
++### Example 1
++
++    We start with a one-condition test.
++
++    Example 1
++
++    | Test   | Date Range | Format String | Example    |
++    |--------|------------|---------------|------------|
++    | '%[1m' | This month | '%[%b %d]'    | Dec 10     |
++    |        | Older      | '%[%Y-%m-%d]' | 2015-04-23 |
++
++    The $index_format string would contain:
++
++        %?[1m?%[%b %d]&%[%Y-%m-%d]?
++
++    Reparsed a little, for clarity, you can see the test condition and the two
++    format strings.
++
++        %?[1m?        &           ?
++              %[%b %d] %[%Y-%m-%d]
++
++### Example 2
++
++    This example contains three test conditions and four date formats.
++
++    Example 2
++
++    | Test  | Date Range | Format String | Example |
++    |-------|------------|---------------|---------|
++    | '%[d' | Today      | '%[%H:%M ] '  | 12:34   |
++    | '%[m' | This month | '%[%a %d]'    | Thu 12  |
++    | '%[y' | This year  | '%[%b %d]'    | Dec 10  |
++    |       | Older      | '%[%m/%y ]'   | 06/15   |
++
++    The $index_format string would contain:
++
++        %<[y?%<[m?%<[d?%[%H:%M ]&%[%a %d]>&%[%b %d]>&%[%m/%y ]>
++
++    Reparsed a little, for clarity, you can see the test conditions and the
++    four format strings.
++
++        %<[y?                                       &%[%m/%y ]>  Older
++             %<[m?                        &%[%b %d]>             This year
++                  %<[d?         &%[%a %d]>                       This month
++                       %[%H:%M ]                                 Today
++
++    This a another view of the same example, with some whitespace for clarity.
++
++        %<[y? %<[m? %<[d? AAA & BBB > & CCC > & DDD >
++
++        AAA = %[%H:%M ]
++        BBB = %[%a %d]
++        CCC = %[%b %d]
++        DDD = %[%m/%y ]
++
++
++Variables
++---------
++
++    The "cond-date" patch doesn't have any config of its own. It modifies the
++    behavior of the format strings.
++
++See Also
++--------
++
++    * NeoMutt project
++    * $index_format
++    * nested-if patch
++    * 'strftime(3)'
++
++Known Bugs
++----------
++
++    Date parsing doesn't quite do what you expect. "1w" doesn't mean the "in
++    the last 7 days", but "*this* week". This doesn't match the normal Mutt
++    behaviour: for example '~d>1w' means emails dated in the last 7 days.
++
++Credits
++-------
++
++    * Aaron Schrab <aaron at schrab.com>
++    * Eric Davis <edavis at insanum.com>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/08-tls-sni.patch b/debian/patches/neomutt/08-tls-sni.patch
new file mode 100644
index 0000000..7af477f
--- /dev/null
+++ b/debian/patches/neomutt/08-tls-sni.patch
@@ -0,0 +1,242 @@
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-tls-sni/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-tls-sni/doc/manual.xml.head	2016-05-02 03:02:14.848210381 +0100
+@@ -8081,6 +8081,113 @@
+ 
+ </sect1>
+ 
++<sect1 id="tls-sni">
++	<title>TLS-SNI Patch</title>
++	<subtitle>Negotiate with a server for a TSL/SSL certificate</subtitle>
++
++	<sect2 id="tls-sni-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>TLS-SNI</quote>, look for
++			<quote>patch-tls-sni</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++			<listitem><para>OpenSSL</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="tls-sni-intro">
++		<title>Introduction</title>
++
++		<para>
++		The <quote>TLS-SNI</quote> patch adds support for TLS virtual hosting.
++		If your mail server doesn't support this everything will still work
++		normally.
++		</para>
++
++		<para>
++		TLS supports sending the expected server hostname during the
++		handshake, via the SNI extension.  This can be used to select a
++		server certificate to issue to the client, permitting
++		virtual-hosting without requiring multiple IP addresses.
++		</para>
++
++		<para>
++		This has been tested against Exim 4.80, which optionally logs SNI
++		and can perform vhosting.
++		</para>
++
++        <para>
++		To verify TLS SNI support by a server, you can use:
++        </para>
++
++<screen>
++openssl s_client -host <imap server> -port <port> -tls1 -servername <imap server>
++</screen>
++	</sect2>
++
++<!--
++	<sect2 id="tls-sni-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="tls-sni-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="tls-sni-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="tls-sni-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="tls-sni-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="tls-sni-muttrc">
++		<title>Muttrc</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="tls-sni-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="tls-sni-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="tls-sni-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Jeremy Katz <email>katzj at linuxpower.org</email></para></listitem>
++		<listitem><para>Phil Pennock <email>mutt-dev at spodhuis.demon.nl</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/mutt_ssl.c mutt-1.6.1-tls-sni/mutt_ssl.c
+--- mutt-1.6.1/mutt_ssl.c	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-tls-sni/mutt_ssl.c	2016-05-02 03:02:14.856210508 +0100
+@@ -401,6 +401,18 @@
+   SSL_set_mode (ssldata->ssl, SSL_MODE_AUTO_RETRY);
+ #endif
+ 
++#if (OPENSSL_VERSION_NUMBER >= 0x0090806fL) && !defined(OPENSSL_NO_TLSEXT)
++  /* TLS Virtual-hosting requires that the server present the correct
++   * certificate; to do this, the ServerNameIndication TLS extension is used.
++   * If TLS is negotiated, and OpenSSL is recent enough that it might have
++   * support, and support was enabled when OpenSSL was built, mutt supports
++   * sending the hostname we think we're connecting to, so a server can send
++   * back the correct certificate.
++   * This has been tested over SMTP against Exim 4.80.
++   * Not yet found an IMAP server which supports this. */
++  SSL_set_tlsext_host_name (ssldata->ssl, conn->account.host);
++#endif
++
+   if ((err = SSL_connect (ssldata->ssl)) != 1)
+   {
+     switch (SSL_get_error (ssldata->ssl, err))
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-tls-sni/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-tls-sni/PATCHES	2016-05-02 03:02:14.843210302 +0100
+@@ -0,0 +1 @@
++patch-tls-sni-neo-20160502
+diff -urN mutt-1.6.1/README.SSL mutt-1.6.1-tls-sni/README.SSL
+--- mutt-1.6.1/README.SSL	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-tls-sni/README.SSL	2016-05-02 03:02:14.720208345 +0100
+@@ -5,7 +5,7 @@
+ -----------
+ If you want to have SSL support in mutt, you need to install OpenSSL
+ (http://www.openssl.org) libraries and headers before compiling.
+-OpenSSL versions 0.9.3 through 0.9.6a have been tested.
++OpenSSL versions 0.9.3 through 1.0.1c have been tested.
+ 
+ For SSL support to be enabled, you need to run the ``configure''
+ script with ``--enable-imap --with-ssl[=PFX]'' parameters.  If the
+@@ -65,6 +65,12 @@
+ can also be saved so that further connections to the server are
+ automatically accepted. 
+ 
++If OpenSSL was built with support for ServerNameIndication (SNI) and TLS
++is used in the negotiation, mutt will send its idea of the server-name
++as part of the TLS negotiation.  This allows the server to select an
++appropriate certificate, in the event that one server handles multiple
++hostnames with different certificates.
++
+ If your organization has several equivalent IMAP-servers, each of them
+ should have a unique certificate which is signed with a common
+ certificate.  If you want to use all of those servers, you don't need to
+@@ -102,9 +108,15 @@
+ protocols to know.  The variables for the protocols are ssl_use_tlsv1, 
+ ssl_use_sslv2, and ssl_use_sslv3.
+ 
++To verify TLS SNI support by a server, you can use:
++    openssl s_client -host <imap server> -port <port> \
++        -tls1 -servername <imap server>
++
++
+ -- 
+ Tommi Komulainen
+ Tommi.Komulainen at iki.fi
+ 
+-Updated by Jeremy Katz
+-katzj at linuxpower.org
++Updated by:
++  Jeremy Katz <katzj at linuxpower.org>
++  Phil Pennock <mutt-dev at spodhuis.org>
+diff -urN mutt-1.6.1/README.tls-sni mutt-1.6.1-tls-sni/README.tls-sni
+--- mutt-1.6.1/README.tls-sni	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-tls-sni/README.tls-sni	2016-05-02 03:02:14.843210302 +0100
+@@ -0,0 +1,51 @@
++TLS-SNI Patch
++=============
++
++    Negotiate with a server for a TSL/SSL certificate
++
++Patch
++-----
++
++    To check if Mutt supports "TLS-SNI", look for "patch-tls-sni" in the mutt
++    version.
++
++    Dependencies
++    * mutt-1.5.24
++    * OpenSSL
++
++Introduction
++------------
++
++    The "TLS-SNI" patch adds support for TLS virtual hosting. If your mail
++    server doesn't support this everything will still work normally.
++
++    TLS supports sending the expected server hostname during the handshake, via
++    the SNI extension. This can be used to select a server certificate to issue
++    to the client, permitting virtual-hosting without requiring multiple IP
++    addresses.
++
++    This has been tested against Exim 4.80, which optionally logs SNI and can
++    perform vhosting.
++
++    To verify TLS SNI support by a server, you can use:
++
++        openssl s_client -host <imap server> -port <port> -tls1 -servername
++    <imap server>
++
++See Also
++--------
++
++    * NeoMutt project
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Jeremy Katz <katzj at linuxpower.org>
++    * Phil Pennock <mutt-dev at spodhuis.demon.nl>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/09-sidebar.patch b/debian/patches/neomutt/09-sidebar.patch
new file mode 100644
index 0000000..6371a66
--- /dev/null
+++ b/debian/patches/neomutt/09-sidebar.patch
@@ -0,0 +1,4316 @@
+diff -urN mutt-1.6.1/buffy.c mutt-1.6.1-sidebar/buffy.c
+--- mutt-1.6.1/buffy.c	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-sidebar/buffy.c	2016-05-02 03:02:15.009212943 +0100
+@@ -27,6 +27,10 @@
+ 
+ #include "mutt_curses.h"
+ 
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
++
+ #ifdef USE_IMAP
+ #include "imap.h"
+ #endif
+@@ -196,9 +200,17 @@
+ static BUFFY *buffy_new (const char *path)
+ {
+   BUFFY* buffy;
++#ifdef USE_SIDEBAR
++  char rp[PATH_MAX] = "";
++  char *r = NULL;
++#endif
+ 
+   buffy = (BUFFY *) safe_calloc (1, sizeof (BUFFY));
+   strfcpy (buffy->path, path, sizeof (buffy->path));
++#ifdef USE_SIDEBAR
++  r = realpath (path, rp);
++  strfcpy (buffy->realpath, r ? rp : path, sizeof (buffy->realpath));
++#endif
+   buffy->next = NULL;
+   buffy->magic = 0;
+ 
+@@ -215,7 +227,10 @@
+   BUFFY **tmp,*tmp1;
+   char buf[_POSIX_PATH_MAX];
+   struct stat sb;
+-  char f1[PATH_MAX], f2[PATH_MAX];
++  char f1[PATH_MAX];
++#ifndef USE_SIDEBAR
++  char f2[PATH_MAX];
++#endif
+   char *p, *q;
+ 
+   while (MoreArgs (s))
+@@ -228,6 +243,9 @@
+       for (tmp = &Incoming; *tmp;)
+       {
+         tmp1=(*tmp)->next;
++#ifdef USE_SIDEBAR
++	sb_notify_mailbox (*tmp, 0);
++#endif
+         buffy_free (tmp);
+         *tmp=tmp1;
+       }
+@@ -243,8 +261,13 @@
+     p = realpath (buf, f1);
+     for (tmp = &Incoming; *tmp; tmp = &((*tmp)->next))
+     {
++#ifdef USE_SIDEBAR
++      q = (*tmp)->realpath;
++      if (mutt_strcmp (p ? p : buf, q) == 0)
++#else
+       q = realpath ((*tmp)->path, f2);
+       if (mutt_strcmp (p ? p : buf, q ? q : (*tmp)->path) == 0)
++#endif
+       {
+ 	dprint(3,(debugfile,"mailbox '%s' already registered as '%s'\n", buf, (*tmp)->path));
+ 	break;
+@@ -256,14 +279,21 @@
+       if(*tmp)
+       {
+         tmp1=(*tmp)->next;
++#ifdef USE_SIDEBAR
++	sb_notify_mailbox (*tmp, 0);
++#endif
+         buffy_free (tmp);
+         *tmp=tmp1;
+       }
+       continue;
+     }
+ 
+-    if (!*tmp)
++    if (!*tmp) {
+       *tmp = buffy_new (buf);
++#ifdef USE_SIDEBAR
++      sb_notify_mailbox (*tmp, 1);
++#endif
++    }
+ 
+     (*tmp)->new = 0;
+     (*tmp)->notified = 1;
+@@ -306,6 +336,13 @@
+       return 0;
+   }
+ 
++#ifdef USE_SIDEBAR
++  if (option (OPTSIDEBAR) && mailbox->msg_unread > 0) {
++    mailbox->new = 1;
++    return 1;
++  }
++#endif
++
+   if ((dirp = opendir (path)) == NULL)
+   {
+     mailbox->magic = 0;
+@@ -357,6 +394,89 @@
+ 
+   return 0;
+ }
++
++#ifdef USE_SIDEBAR
++/**
++ * buffy_maildir_update_dir - Update counts for one directory
++ * @mailbox: BUFFY representing a maildir mailbox
++ * @dir:     Which directory to search
++ *
++ * Look through one directory of a maildir mailbox.  The directory could
++ * be either "new" or "cur".
++ *
++ * Count how many new, or flagged, messages there are.
++ */
++static void
++buffy_maildir_update_dir (BUFFY *mailbox, const char *dir)
++{
++	char path[_POSIX_PATH_MAX] = "";
++	DIR *dirp = NULL;
++	struct dirent *de = NULL;
++	char *p = NULL;
++	int read;
++
++	snprintf (path, sizeof (path), "%s/%s", mailbox->path, dir);
++
++	dirp = opendir (path);
++	if (!dirp) {
++		mailbox->magic = 0;
++		return;
++	}
++
++	while ((de = readdir (dirp)) != NULL) {
++		if (*de->d_name == '.')
++			continue;
++
++		/* Matches maildir_parse_flags logic */
++		read = 0;
++		mailbox->msg_count++;
++		p = strstr (de->d_name, ":2,");
++		if (p) {
++			p += 3;
++			if (strchr (p, 'S'))
++				read = 1;
++			if (strchr (p, 'F'))
++				mailbox->msg_flagged++;
++		}
++		if (!read) {
++			mailbox->msg_unread++;
++		}
++	}
++
++	closedir (dirp);
++}
++
++/**
++ * buffy_maildir_update - Update messages counts for a maildir mailbox
++ * @mailbox: BUFFY representing a maildir mailbox
++ *
++ * Open a mailbox directories and update our record of how many new, or
++ * flagged, messages there are.
++ */
++void
++buffy_maildir_update (BUFFY *mailbox)
++{
++	if (!option (OPTSIDEBAR))
++		return;
++
++	mailbox->msg_count   = 0;
++	mailbox->msg_unread  = 0;
++	mailbox->msg_flagged = 0;
++
++	buffy_maildir_update_dir (mailbox, "new");
++	if (mailbox->msg_count) {
++		mailbox->new = 1;
++	}
++	buffy_maildir_update_dir (mailbox, "cur");
++
++	mailbox->sb_last_checked = time (NULL);
++
++	/* make sure the updates are actually put on screen */
++	sb_draw();
++}
++
++#endif
++
+ /* returns 1 if mailbox has new mail */ 
+ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb)
+ {
+@@ -368,7 +488,11 @@
+   else
+     statcheck = sb->st_mtime > sb->st_atime
+       || (mailbox->newly_created && sb->st_ctime == sb->st_mtime && sb->st_ctime == sb->st_atime);
++#ifdef USE_SIDEBAR
++  if ((!option (OPTSIDEBAR) && statcheck) || (option (OPTSIDEBAR) && mailbox->msg_unread > 0))
++#else
+   if (statcheck)
++#endif
+   {
+     if (!option(OPTMAILCHECKRECENT) || sb->st_mtime > mailbox->last_visited)
+     {
+@@ -388,6 +512,40 @@
+   return rc;
+ }
+ 
++#ifdef USE_SIDEBAR
++/**
++ * buffy_mbox_update - Update messages counts for an mbox mailbox
++ * @mailbox: BUFFY representing an mbox mailbox
++ * @sb:      stat(2) infomation about the mailbox file
++ *
++ * Open a mbox file and update our record of how many new, or flagged,
++ * messages there are. If the mailbox hasn't changed since the last call,
++ * the function does nothing.
++ */
++void
++buffy_mbox_update (BUFFY *mailbox, struct stat *sb)
++{
++	CONTEXT *ctx = NULL;
++
++	if (!option (OPTSIDEBAR))
++		return;
++	if ((mailbox->sb_last_checked > sb->st_mtime) && (mailbox->msg_count != 0))
++		return; /* no check necessary */
++
++	ctx = mx_open_mailbox (mailbox->path, M_READONLY | M_QUIET | M_NOSORT | M_PEEK, NULL);
++	if (ctx) {
++		mailbox->msg_count       = ctx->msgcount;
++		mailbox->msg_unread      = ctx->unread;
++		mailbox->msg_flagged     = ctx->flagged;
++		mailbox->sb_last_checked = time (NULL);
++		mx_close_mailbox (ctx, 0);
++	}
++
++	/* make sure the updates are actually put on screen */
++	sb_draw();
++}
++#endif
++
+ int mutt_buffy_check (int force)
+ {
+   BUFFY *tmp;
+@@ -428,6 +586,9 @@
+     contex_sb.st_ino=0;
+   }
+   
++#ifdef USE_SIDEBAR
++  int should_refresh = sb_should_refresh();
++#endif
+   for (tmp = Incoming; tmp; tmp = tmp->next)
+   {
+     if (tmp->magic != M_IMAP)
+@@ -461,16 +622,30 @@
+       {
+       case M_MBOX:
+       case M_MMDF:
++#ifdef USE_SIDEBAR
++	if (should_refresh)
++	  buffy_mbox_update (tmp, &sb);
++#endif
+ 	if (buffy_mbox_hasnew (tmp, &sb) > 0)
+ 	  BuffyCount++;
+ 	break;
+ 
+       case M_MAILDIR:
++#ifdef USE_SIDEBAR
++	if (should_refresh)
++	  buffy_maildir_update (tmp);
++#endif
+ 	if (buffy_maildir_hasnew (tmp) > 0)
+ 	  BuffyCount++;
+ 	break;
+ 
+       case M_MH:
++#ifdef USE_SIDEBAR
++	if (sb_should_refresh()) {
++	  mh_buffy_update (tmp);
++	  sb_set_update_time();
++	}
++#endif
+ 	mh_buffy(tmp);
+ 	if (tmp->new)
+ 	  BuffyCount++;
+@@ -485,6 +660,10 @@
+     else if (!tmp->notified)
+       BuffyNotify++;
+   }
++#ifdef USE_SIDEBAR
++  if (should_refresh)
++	  sb_set_update_time();
++#endif
+ 
+   BuffyDoneTime = BuffyTime;
+   return (BuffyCount);
+diff -urN mutt-1.6.1/buffy.h mutt-1.6.1-sidebar/buffy.h
+--- mutt-1.6.1/buffy.h	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-sidebar/buffy.h	2016-05-02 03:02:15.010212959 +0100
+@@ -16,6 +16,9 @@
+  *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+  */
+ 
++#ifndef _BUFFY_H
++#define _BUFFY_H
++
+ /*parameter to mutt_parse_mailboxes*/
+ #define M_MAILBOXES   1
+ #define M_UNMAILBOXES 2 
+@@ -23,13 +26,28 @@
+ typedef struct buffy_t
+ {
+   char path[_POSIX_PATH_MAX];
++#ifdef USE_SIDEBAR
++  char realpath[_POSIX_PATH_MAX];
++#endif
+   off_t size;
+   struct buffy_t *next;
++#ifdef USE_SIDEBAR
++  struct buffy_t *prev;
++#endif
+   short new;			/* mailbox has new mail */
++#ifdef USE_SIDEBAR
++  int msg_count;		/* total number of messages */
++  int msg_unread;		/* number of unread messages */
++  int msg_flagged;		/* number of flagged messages */
++  short is_hidden;		/* is hidden from the sidebar */
++#endif
+   short notified;		/* user has been notified */
+   short magic;			/* mailbox type */
+   short newly_created;		/* mbox or mmdf just popped into existence */
+   time_t last_visited;		/* time of last exit from this mailbox */
++#ifdef USE_SIDEBAR
++  time_t sb_last_checked;	/* time of last buffy check from sidebar */
++#endif
+ }
+ BUFFY;
+ 
+@@ -49,3 +67,5 @@
+ void mutt_buffy_setnotified (const char *path);
+ 
+ void mh_buffy (BUFFY *);
++
++#endif /* _BUFFY_H */
+diff -urN mutt-1.6.1/color.c mutt-1.6.1-sidebar/color.c
+--- mutt-1.6.1/color.c	2016-05-02 03:02:12.397171385 +0100
++++ mutt-1.6.1-sidebar/color.c	2016-05-02 03:02:15.010212959 +0100
+@@ -94,6 +94,14 @@
+   { "underline",	MT_COLOR_UNDERLINE },
+   { "index",		MT_COLOR_INDEX },
+   { "prompt",		MT_COLOR_PROMPT },
++#ifdef USE_SIDEBAR
++  { "sidebar_divider",	MT_COLOR_DIVIDER },
++  { "sidebar_flagged",	MT_COLOR_FLAGGED },
++  { "sidebar_highlight",MT_COLOR_HIGHLIGHT },
++  { "sidebar_indicator",MT_COLOR_SB_INDICATOR },
++  { "sidebar_new",	MT_COLOR_NEW },
++  { "sidebar_spoolfile",MT_COLOR_SB_SPOOLFILE },
++#endif
+   { NULL,		0 }
+ };
+ 
+@@ -146,6 +154,9 @@
+   ColorDefs[MT_COLOR_INDICATOR] = A_REVERSE;
+   ColorDefs[MT_COLOR_SEARCH] = A_REVERSE;
+   ColorDefs[MT_COLOR_MARKERS] = A_REVERSE;
++#ifdef USE_SIDEBAR
++  ColorDefs[MT_COLOR_HIGHLIGHT] = A_UNDERLINE;
++#endif
+   /* special meaning: toggle the relevant attribute */
+   ColorDefs[MT_COLOR_BOLD] = 0;
+   ColorDefs[MT_COLOR_UNDERLINE] = 0;
+diff -urN mutt-1.6.1/compose.c mutt-1.6.1-sidebar/compose.c
+--- mutt-1.6.1/compose.c	2016-05-02 03:02:12.398171401 +0100
++++ mutt-1.6.1-sidebar/compose.c	2016-05-02 03:02:15.010212959 +0100
+@@ -32,6 +32,9 @@
+ #include "mailbox.h"
+ #include "sort.h"
+ #include "charset.h"
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
+ 
+ #ifdef MIXMASTER
+ #include "remailer.h"
+@@ -72,7 +75,7 @@
+ 
+ #define HDR_XOFFSET 10
+ #define TITLE_FMT "%10s" /* Used for Prompts, which are ASCII */
+-#define W (COLS - HDR_XOFFSET)
++#define W (COLS - HDR_XOFFSET - SidebarWidth)
+ 
+ static const char * const Prompts[] =
+ {
+@@ -110,7 +113,7 @@
+ 
+ static void redraw_crypt_lines (HEADER *msg)
+ {
+-  mvaddstr (HDR_CRYPT, 0, "Security: ");
++  mvprintw (HDR_CRYPT, SidebarWidth, TITLE_FMT, "Security: ");
+ 
+   if ((WithCrypto & (APPLICATION_PGP | APPLICATION_SMIME)) == 0)
+   {
+@@ -145,7 +148,7 @@
+       addstr (_(" (OppEnc mode)"));
+ 
+   clrtoeol ();
+-  move (HDR_CRYPTINFO, 0);
++  move (HDR_CRYPTINFO, SidebarWidth);
+   clrtoeol ();
+ 
+   if ((WithCrypto & APPLICATION_PGP)
+@@ -162,7 +165,7 @@
+       && (msg->security & ENCRYPT)
+       && SmimeCryptAlg
+       && *SmimeCryptAlg) {
+-      mvprintw (HDR_CRYPTINFO, 40, "%s%s", _("Encrypt with: "),
++      mvprintw (HDR_CRYPTINFO, SidebarWidth + 40, "%s%s", _("Encrypt with: "),
+ 		NONULL(SmimeCryptAlg));
+   }
+ }
+@@ -175,7 +178,7 @@
+   int c;
+   char *t;
+ 
+-  mvaddstr (HDR_MIX, 0,     "     Mix: ");
++  mvprintw (HDR_MIX, SidebarWidth, TITLE_FMT, "Mix: ");
+ 
+   if (!chain)
+   {
+@@ -190,7 +193,7 @@
+     if (t && t[0] == '0' && t[1] == '\0')
+       t = "<random>";
+     
+-    if (c + mutt_strlen (t) + 2 >= COLS)
++    if (c + mutt_strlen (t) + 2 >= COLS - SidebarWidth)
+       break;
+ 
+     addstr (NONULL(t));
+@@ -242,20 +245,23 @@
+ 
+   buf[0] = 0;
+   rfc822_write_address (buf, sizeof (buf), addr, 1);
+-  mvprintw (line, 0, TITLE_FMT, Prompts[line - 1]);
++  mvprintw (line, SidebarWidth, TITLE_FMT, Prompts[line - 1]);
+   mutt_paddstr (W, buf);
+ }
+ 
+ static void draw_envelope (HEADER *msg, char *fcc)
+ {
++#ifdef USE_SIDEBAR
++  sb_draw();
++#endif
+   draw_envelope_addr (HDR_FROM, msg->env->from);
+   draw_envelope_addr (HDR_TO, msg->env->to);
+   draw_envelope_addr (HDR_CC, msg->env->cc);
+   draw_envelope_addr (HDR_BCC, msg->env->bcc);
+-  mvprintw (HDR_SUBJECT, 0, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
++  mvprintw (HDR_SUBJECT, SidebarWidth, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
+   mutt_paddstr (W, NONULL (msg->env->subject));
+   draw_envelope_addr (HDR_REPLYTO, msg->env->reply_to);
+-  mvprintw (HDR_FCC, 0, TITLE_FMT, Prompts[HDR_FCC - 1]);
++  mvprintw (HDR_FCC, SidebarWidth, TITLE_FMT, Prompts[HDR_FCC - 1]);
+   mutt_paddstr (W, fcc);
+ 
+   if (WithCrypto)
+@@ -266,7 +272,7 @@
+ #endif
+ 
+   SETCOLOR (MT_COLOR_STATUS);
+-  mvaddstr (HDR_ATTACH - 1, 0, _("-- Attachments"));
++  mvaddstr (HDR_ATTACH - 1, SidebarWidth, _("-- Attachments"));
+   clrtoeol ();
+ 
+   NORMAL_COLOR;
+@@ -302,7 +308,7 @@
+   /* redraw the expanded list so the user can see the result */
+   buf[0] = 0;
+   rfc822_write_address (buf, sizeof (buf), *addr, 1);
+-  move (line, HDR_XOFFSET);
++  move (line, HDR_XOFFSET + SidebarWidth);
+   mutt_paddstr (W, buf);
+   
+   return 0;
+@@ -564,7 +570,7 @@
+ 	if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0)
+ 	{
+ 	  mutt_str_replace (&msg->env->subject, buf);
+-	  move (HDR_SUBJECT, HDR_XOFFSET);
++	  move (HDR_SUBJECT, HDR_XOFFSET + SidebarWidth);
+ 	  if (msg->env->subject)
+ 	    mutt_paddstr (W, msg->env->subject);
+ 	  else
+@@ -582,7 +588,7 @@
+ 	{
+ 	  strfcpy (fcc, buf, fcclen);
+ 	  mutt_pretty_mailbox (fcc, fcclen);
+-	  move (HDR_FCC, HDR_XOFFSET);
++	  move (HDR_FCC, HDR_XOFFSET + SidebarWidth);
+ 	  mutt_paddstr (W, fcc);
+ 	  fccSet = 1;
+ 	}
+diff -urN mutt-1.6.1/configure.ac mutt-1.6.1-sidebar/configure.ac
+--- mutt-1.6.1/configure.ac	2016-05-02 03:02:12.398171401 +0100
++++ mutt-1.6.1-sidebar/configure.ac	2016-05-02 03:02:15.011212974 +0100
+@@ -175,6 +175,15 @@
+ 	SMIMEAUX_TARGET="smime_keys"
+ fi
+ 
++AC_ARG_ENABLE(sidebar, AC_HELP_STRING([--enable-sidebar], [Enable Sidebar support]),
++[       if test x$enableval = xyes ; then
++		AC_DEFINE(USE_SIDEBAR,1,[ Define if you want support for the sidebar. ])
++		OPS="$OPS \$(srcdir)/OPS.SIDEBAR"
++		need_sidebar="yes"
++        fi
++])
++AM_CONDITIONAL(BUILD_SIDEBAR, test x$need_sidebar = xyes)
++
+ AC_ARG_WITH(mixmaster, AS_HELP_STRING([--with-mixmaster@<:@=PATH@:>@],[Include Mixmaster support]),
+   [if test "$withval" != no
+    then
+diff -urN mutt-1.6.1/copy.c mutt-1.6.1-sidebar/copy.c
+--- mutt-1.6.1/copy.c	2016-05-02 03:02:12.398171401 +0100
++++ mutt-1.6.1-sidebar/copy.c	2016-05-02 03:02:15.011212974 +0100
+@@ -288,7 +288,7 @@
+       if (flags & (CH_DECODE|CH_PREFIX))
+       {
+ 	if (mutt_write_one_header (out, 0, headers[x], 
+-				   flags & CH_PREFIX ? prefix : 0, mutt_term_width (Wrap), flags) == -1)
++				   flags & CH_PREFIX ? prefix : 0, mutt_term_width (Wrap) - SidebarWidth, flags) == -1)
+ 	{
+ 	  error = TRUE;
+ 	  break;
+diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-sidebar/curs_main.c
+--- mutt-1.6.1/curs_main.c	2016-05-02 03:02:12.400171433 +0100
++++ mutt-1.6.1-sidebar/curs_main.c	2016-05-02 03:02:15.012212990 +0100
+@@ -26,8 +26,13 @@
+ #include "mailbox.h"
+ #include "mapping.h"
+ #include "sort.h"
++#include "buffy.h"
+ #include "mx.h"
+ 
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
++
+ #ifdef USE_POP
+ #include "pop.h"
+ #endif
+@@ -595,21 +600,39 @@
+        menu->redraw |= REDRAW_STATUS;
+      if (do_buffy_notify)
+      {
+-       if (mutt_buffy_notify () && option (OPTBEEPNEW))
+- 	beep ();
++       if (mutt_buffy_notify())
++       {
++         menu->redraw |= REDRAW_STATUS;
++         if (option (OPTBEEPNEW))
++           beep();
++       }
+      }
+      else
+        do_buffy_notify = 1;
+     }
+ 
++#ifdef USE_SIDEBAR
++    if (option (OPTSIDEBAR))
++        menu->redraw |= REDRAW_SIDEBAR;
++#endif
++
+     if (op != -1)
+       mutt_curs_set (0);
+ 
+     if (menu->redraw & REDRAW_FULL)
+     {
+       menu_redraw_full (menu);
++#ifdef USE_SIDEBAR
++      sb_draw();
++#endif
+       mutt_show_error ();
+     }
++#ifdef USE_SIDEBAR
++    else if (menu->redraw & REDRAW_SIDEBAR) {
++      sb_draw();
++      menu->redraw &= ~REDRAW_SIDEBAR;
++    }
++#endif
+ 
+     if (menu->menu == MENU_MAIN)
+     {
+@@ -630,9 +653,20 @@
+ 
+       if (menu->redraw & REDRAW_STATUS)
+       {
++#ifdef USE_SIDEBAR
++        /* Temporarily lie about the sidebar width */
++	short sw = SidebarWidth;
++	SidebarWidth = 0;
++#endif
+ 	menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
++#ifdef USE_SIDEBAR
++        SidebarWidth = sw; /* Restore the sidebar width */
++#endif
+ 	move (option (OPTSTATUSONTOP) ? 0 : LINES-2, 0);
+ 	SETCOLOR (MT_COLOR_STATUS);
++#ifdef USE_SIDEBAR
++	sb_set_buffystats (Context);
++#endif
+ 	mutt_paddstr (COLS, buf);
+ 	NORMAL_COLOR;
+ 	menu->redraw &= ~REDRAW_STATUS;
+@@ -652,7 +686,7 @@
+ 	menu->oldcurrent = -1;
+ 
+       if (option (OPTARROWCURSOR))
+-	move (menu->current - menu->top + menu->offset, 2);
++	move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
+       else if (option (OPTBRAILLEFRIENDLY))
+ 	move (menu->current - menu->top + menu->offset, 0);
+       else
+@@ -1091,6 +1125,9 @@
+ 	  break;
+ 
+ 	CHECK_MSGCOUNT;
++#ifdef USE_SIDEBAR
++	CHECK_VISIBLE;
++#endif
+ 	CHECK_READONLY;
+ 	{
+ 	  int oldvcount = Context->vcount;
+@@ -1150,6 +1187,9 @@
+ 	  menu->redraw = REDRAW_FULL;
+ 	break;
+ 
++#ifdef USE_SIDEBAR
++      case OP_SIDEBAR_OPEN:
++#endif
+       case OP_MAIN_CHANGE_FOLDER:
+       case OP_MAIN_NEXT_UNREAD_MAILBOX:
+ 
+@@ -1181,6 +1221,14 @@
+ 	{
+ 	  mutt_buffy (buf, sizeof (buf));
+ 
++#ifdef USE_SIDEBAR
++	  if (op == OP_SIDEBAR_OPEN) {
++	    const char *path = sb_get_highlight();
++	    if (!path)
++	      break;
++	    strncpy (buf, path, sizeof (buf));
++	  } else
++#endif
+ 	  if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
+ 	  {
+ 	    if (menu->menu == MENU_PAGER)
+@@ -1199,6 +1247,9 @@
+ 	}
+ 
+ 	mutt_expand_path (buf, sizeof (buf));
++#ifdef USE_SIDEBAR
++	sb_set_open_buffy (buf);
++#endif
+ 	if (mx_get_magic (buf) <= 0)
+ 	{
+ 	  mutt_error (_("%s is not a mailbox."), buf);
+@@ -2310,6 +2361,21 @@
+ 	mutt_what_key();
+ 	break;
+ 
++#ifdef USE_SIDEBAR
++      case OP_SIDEBAR_NEXT:
++      case OP_SIDEBAR_NEXT_NEW:
++      case OP_SIDEBAR_PAGE_DOWN:
++      case OP_SIDEBAR_PAGE_UP:
++      case OP_SIDEBAR_PREV:
++      case OP_SIDEBAR_PREV_NEW:
++        sb_change_mailbox (op);
++        break;
++
++      case OP_SIDEBAR_TOGGLE_VISIBLE:
++	toggle_option (OPTSIDEBAR);
++	menu->redraw = REDRAW_FULL;
++	break;
++#endif
+       default:
+ 	if (menu->menu == MENU_MAIN)
+ 	  km_error_key (MENU_MAIN);
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-sidebar/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-sidebar/doc/manual.xml.head	2016-05-02 03:02:15.014213022 +0100
+@@ -405,6 +405,623 @@
+ 
+ </sect2>
+ 
++<sect2 id="intro-sidebar">
++	<title>Sidebar</title>
++	<para>
++		The Sidebar shows a list of all your mailboxes.  The list can be
++		turned on and off, it can be themed and the list style can be
++		configured.
++	</para>
++	<para>
++		This part of the manual is suitable for beginners.
++		If you already know Mutt you could skip ahead to the main
++		<link linkend="sidebar">Sidebar guide</link>.
++		If you just want to get started, you could use the sample
++		<link linkend="sidebar-muttrc">Sidebar muttrc</link>.
++	</para>
++	<para>
++		This version of Sidebar is based on Terry Chan's
++		<ulink url="http://www.lunar-linux.org/mutt-sidebar/">2015-11-11 release</ulink>.
++		It contains many
++		<emphasis role="bold"><link linkend="intro-sidebar-features">new features</link></emphasis>,
++		lots of
++		<emphasis role="bold"><link linkend="intro-sidebar-bugfixes">bugfixes</link></emphasis>
++		and a generous helping of
++		<emphasis role="bold">new documentation</emphasis> which you are already reading.
++	</para>
++	<para>
++		To check if Mutt supports <quote>Sidebar</quote>, look for the string
++		<literal>+USE_SIDEBAR</literal> in the mutt version.
++	</para>
++<screen>
++mutt -v
++</screen>
++	<para>
++		<emphasis role="bold">Let's turn on the Sidebar:</emphasis>
++	</para>
++	<screen>set sidebar_visible</screen>
++	<para>
++		You will see something like this.
++		A list of mailboxes on the left.
++		A list of emails, from the selected mailbox, on the right.
++	</para>
++<screen>
++<emphasis role="indicator">Fruit [1]     3/8</emphasis>|  1    + Jan 24  Rhys Lee         (192)  Yew
++Animals [1]   2/6|  2    + Feb 11  Grace Hall       (167)  Ilama
++Cars            4|  3      Feb 23  Aimee Scott      (450)  Nectarine
++Seas          1/7|  4    ! Feb 28  Summer Jackson   (264)  Lemon
++                 |  5      Mar 07  Callum Harrison  (464)  Raspberry
++                 |<emphasis role="indicator">  6 N  + Mar 24  Samuel Harris    (353)  Tangerine          </emphasis>
++                 |  7 N  + Sep 05  Sofia Graham     (335)  Cherry
++                 |  8 N    Sep 16  Ewan Brown       (105)  Ugli
++                 |
++                 |
++</screen>
++<para>
++	This user has four mailboxes: <quote>Fruit</quote>,
++	<quote>Cars</quote>, <quote>Animals</quote> and
++	<quote>Seas</quote>.
++</para>
++<para>
++	The current, open, mailbox is <quote>Fruit</quote>.  We can
++	also see information about the other mailboxes.  For example:
++	The <quote>Animals</quote> mailbox contains, 1 flagged email, 2
++	new emails out of a total of 6 emails.
++</para>
++	<sect3 id="intro-sidebar-navigation">
++		<title>Navigation</title>
++		<para>
++			The Sidebar adds some new <link linkend="sidebar-functions">functions</link>
++			to Mutt.
++		</para>
++		<para>
++			The user pressed the <quote>c</quote> key to
++			<literal><change-folder></literal> to the
++			<quote>Animals</quote> mailbox.  The Sidebar automatically
++			updated the indicator to match.
++		</para>
++<screen>
++Fruit [1]     3/8|  1      Jan 03  Tia Gibson       (362)  Caiman
++<emphasis role="indicator">Animals [1]   2/6</emphasis>|  2    + Jan 22  Rhys Lee         ( 48)  Dolphin
++Cars            4|  3    ! Aug 16  Ewan Brown       (333)  Hummingbird
++Seas          1/7|  4      Sep 25  Grace Hall       ( 27)  Capybara
++                 |<emphasis role="indicator">  5 N  + Nov 12  Evelyn Rogers    (453)  Tapir              </emphasis>
++                 |  6 N  + Nov 16  Callum Harrison  (498)  Hedgehog
++                 |
++                 |
++                 |
++                 |
++</screen>
++		<para>
++			Let's map some functions:
++		</para>
++<screen>
++bind index,pager \CP sidebar-prev       <emphasis role="comment"># Ctrl-Shift-P - Previous Mailbox</emphasis>
++bind index,pager \CN sidebar-next       <emphasis role="comment"># Ctrl-Shift-N - Next Mailbox</emphasis>
++bind index,pager \CO sidebar-open       <emphasis role="comment"># Ctrl-Shift-O - Open Highlighted Mailbox</emphasis>
++</screen>
++		<para>
++			Press <quote>Ctrl-Shift-N</quote> (Next mailbox) twice will
++			move the Sidebar <emphasis role="bold">highlight</emphasis> to
++			down to the <quote>Seas</quote> mailbox.
++		</para>
++<screen>
++Fruit [1]     3/8|  1      Jan 03  Tia Gibson       (362)  Caiman
++<emphasis role="indicator">Animals [1]   2/6</emphasis>|  2    + Jan 22  Rhys Lee         ( 48)  Dolphin
++Cars            4|  3    ! Aug 16  Ewan Brown       (333)  Hummingbird
++<emphasis role="highlight">Seas          1/7</emphasis>|  4      Sep 25  Grace Hall       ( 27)  Capybara
++                 |<emphasis role="indicator">  5 N  + Nov 12  Evelyn Rogers    (453)  Tapir              </emphasis>
++                 |  6 N  + Nov 16  Callum Harrison  (498)  Hedgehog
++                 |
++                 |
++                 |
++                 |
++</screen>
++		<note>
++			Functions <literal><sidebar-next></literal> and
++			<literal><sidebar-prev></literal> move the Sidebar
++			<emphasis role="bold">highlight</emphasis>.
++			They <emphasis role="bold">do not</emphasis> change the open
++			mailbox.
++		</note>
++		<para>
++			Press <quote>Ctrl-Shift-O</quote>
++			(<literal><sidebar-open></literal>)
++			to open the highlighted mailbox.
++		</para>
++<screen>
++Fruit [1]     3/8|  1    ! Mar 07  Finley Jones     (139)  Molucca Sea
++Animals [1]   2/6|  2    + Mar 24  Summer Jackson   ( 25)  Arafura Sea
++Cars            4|  3    + Feb 28  Imogen Baker     (193)  Pechora Sea
++<emphasis role="indicator">Seas          1/7</emphasis>|<emphasis role="indicator">  4 N  + Feb 23  Isla Hussain     (348)  Balearic Sea       </emphasis>
++                 |
++                 |
++                 |
++                 |
++                 |
++                 |
++</screen>
++	</sect3>
++	<sect3 id="intro-sidebar-features">
++		<title>Features</title>
++		<para>
++			The Sidebar shows a list of mailboxes in a panel.
++		<para>
++		</para>
++			Everything about the Sidebar can be configured.
++		</para>
++		<itemizedlist>
++		<title><link linkend="intro-sidebar-basics">State of the Sidebar</link></title>
++			<listitem><para>Visibility</para></listitem>
++			<listitem><para>Width</para></listitem>
++		</itemizedlist>
++		<itemizedlist>
++		<title><link linkend="intro-sidebar-limit">Which mailboxes are displayed</link></title>
++			<listitem><para>Display all</para></listitem>
++			<listitem><para>Limit to mailboxes with new mail</para></listitem>
++			<listitem><para>Whitelist mailboxes to display always</para></listitem>
++		</itemizedlist>
++		<itemizedlist>
++		<title><link linkend="sidebar-sort">The order in which mailboxes are displayed</link></title>
++		<title></title>
++			<listitem><para>Unsorted (order of mailboxes commands)</para></listitem>
++			<listitem><para>Sorted alphabetically</para></listitem>
++			<listitem><para>Sorted by number of new mails</para></listitem>
++		</itemizedlist>
++		<itemizedlist>
++		<title><link linkend="intro-sidebar-colors">Color</link></title>
++			<listitem><para>Sidebar indicators and divider</para></listitem>
++			<listitem><para>Mailboxes depending on their type</para></listitem>
++			<listitem><para>Mailboxes depending on their contents</para></listitem>
++		</itemizedlist>
++		<itemizedlist>
++		<title><link linkend="sidebar-functions">Key bindings</link></title>
++			<listitem><para>Hide/Unhide the Sidebar</para></listitem>
++			<listitem><para>Select previous/next mailbox</para></listitem>
++			<listitem><para>Select previous/next mailbox with new mail</para></listitem>
++			<listitem><para>Page up/down through a list of mailboxes</para></listitem>
++		</itemizedlist>
++		<itemizedlist>
++		<title>Misc</title>
++			<listitem><para><link linkend="intro-sidebar-format">Formatting string for mailbox</link></para></listitem>
++			<listitem><para><link linkend="sidebar-next-new-wrap">Wraparound searching</link></para></listitem>
++			<listitem><para><link linkend="intro-sidebar-abbrev">Flexible mailbox abbreviations</link></para></listitem>
++			<listitem><para>Support for Unicode mailbox names (utf-8)</para></listitem>
++		</itemizedlist>
++	</sect3>
++	<sect3 id="intro-sidebar-display">
++		<title>Display</title>
++		<para>
++			Everything about the Sidebar can be configured.
++		</para>
++		<itemizedlist>
++			<title>For a quick reference:</title>
++			<listitem><para><link linkend="sidebar-variables">Sidebar variables to set</link> </para></listitem>
++			<listitem><para><link linkend="sidebar-colors">Sidebar colors to apply</link></para></listitem>
++			<listitem><para><link linkend="sidebar-sort">Sidebar sort methods</link></para></listitem>
++		</itemizedlist>
++		<sect4 id="intro-sidebar-basics">
++			<title>Sidebar Basics</title>
++			<para>
++				The most important variable is <literal>$sidebar_visible</literal>.
++				You can set this in your <quote>muttrc</quote>, or bind a key to the
++				function <literal><sidebar-toggle-visible></literal>.
++			</para>
++<screen>
++set sidebar_visible                         <emphasis role="comment"># Make the Sidebar visible by default</emphasis>
++bind index,pager B sidebar-toggle-visible   <emphasis role="comment"># Use 'B' to switch the Sidebar on and off</emphasis>
++</screen>
++			<para>
++				Next, decide how wide you want the Sidebar to be.  25
++				characters might be enough for the mailbox name and some numbers.
++		Remember, you can hide/show the Sidebar at the press of button.
++		</para>
++		<para>
++		Finally, you might want to change the divider character.
++		By default, Sidebar draws an ASCII line between it and the Index panel
++				If your terminal supports it, you can use a Unicode line-drawing character.
++			</para>
++<screen>
++set sidebar_width = 25                  <emphasis role="comment"># Plenty of space</emphasis>
++set sidebar_divider_char = '│'          <emphasis role="comment"># Pretty line-drawing character</emphasis>
++</screen>
++		</sect4>
++		<sect4 id="intro-sidebar-format">
++			<title>Sidebar Format String</title>
++			<para>
++				<literal>$sidebar_format</literal> allows you to customize the Sidebar display.
++				For an introduction, read <link linkend="index-format">format strings</link>
++				including the section about <link linkend="formatstrings-conditionals">conditionals</link>.
++			</para>
++			<para>
++				The default value is <literal>%B%?F? [%F]?%* %?N?%N/?%S</literal>
++			</para>
++			<itemizedlist>
++				<title>Which breaks down as:</title>
++				<listitem><para><literal>%B</literal> - Mailbox name</para></listitem>
++				<listitem><para><literal>%?F? [%F]?</literal> - If flagged emails <literal>[%F]</literal>, otherwise nothing</para></listitem>
++				<listitem><para><literal>%* </literal> - Pad with spaces</para></listitem>
++				<listitem><para><literal>%?N?%N/?</literal> - If new emails <literal>%N/</literal>, otherwise nothing</para></listitem>
++				<listitem><para><literal>%S</literal> - Total number of emails</para></listitem>
++			</itemizedlist>
++			<table>
++				<title>sidebar_format</title>
++				<tgroup cols="3">
++					<thead>
++						<row>
++							<entry>Format</entry>
++							<entry>Notes</entry>
++							<entry>Description</entry>
++						</row>
++					</thead>
++					<tbody>
++						<row>
++							<entry>%B</entry>
++							<entry></entry>
++							<entry>Name of the mailbox</entry>
++						</row>
++						<row>
++							<entry>%S</entry>
++							<entry>*</entry>
++							<entry>Size of mailbox (total number of messages)</entry>
++						</row>
++						<row>
++							<entry>%N</entry>
++							<entry>*</entry>
++							<entry>Number of New messages in the mailbox</entry>
++						</row>
++						<row>
++							<entry>%F</entry>
++							<entry>*</entry>
++							<entry>Number of Flagged messages in the mailbox</entry>
++						</row>
++						<row>
++							<entry>%!</entry>
++							<entry></entry>
++							<entry>
++								<quote>!</quote>: one flagged message;
++								<quote>!!</quote>: two flagged messages;
++								<quote>n!</quote>: n flagged messages (for n > 2).
++								Otherwise prints nothing.
++							</entry>
++						</row>
++						<row>
++							<entry>%d</entry>
++							<entry>* ‡</entry>
++							<entry>Number of deleted messages</entry>
++						</row>
++						<row>
++							<entry>%L</entry>
++							<entry>* ‡</entry>
++							<entry>Number of messages after limiting</entry>
++						</row>
++						<row>
++							<entry>%t</entry>
++							<entry>* ‡</entry>
++							<entry>Number of tagged messages</entry>
++						</row>
++						<row>
++							<entry>%>X</entry>
++							<entry></entry>
++							<entry>Right justify the rest of the string and pad with <quote>X</quote></entry>
++						</row>
++						<row>
++							<entry>%|X</entry>
++							<entry></entry>
++							<entry>Pad to the end of the line with
++							<quote>X</quote></entry>
++						</row>
++						<row>
++							<entry>%*X</entry>
++							<entry></entry>
++							<entry>Soft-fill with character <quote>X</quote>as pad</entry>
++						</row>
++					</tbody>
++				</tgroup>
++			</table>
++			<para>
++			* = Can be optionally printed if nonzero
++			</para>
++			<para>
++			‡ = Only applicable to the current folder
++			</para>
++			<para>
++				Here are some examples.
++				They show the number of (F)lagged, (N)ew and (S)ize.
++			</para>
++			<table>
++				<title>sidebar_format</title>
++				<tgroup cols="2">
++					<thead>
++						<row>
++							<entry>Format</entry>
++							<entry>Example</entry>
++						</row>
++					</thead>
++					<tbody>
++						<row>
++							<entry><literal>%B%?F? [%F]?%* %?N?%N/?%S</literal></entry>
++							<entry><screen>mailbox [F]            N/S</screen></entry>
++						</row>
++						<row>
++							<entry><literal>%B%* %F:%N:%S</literal></entry>
++							<entry><screen>mailbox              F:N:S</screen></entry>
++						</row>
++						<row>
++							<entry><literal>%B %?N?(%N)?%* %S</literal></entry>
++							<entry><screen>mailbox (N)              S</screen></entry>
++						</row>
++						<row>
++							<entry><literal>%B%* ?F?%F/?%N</literal></entry>
++							<entry><screen>mailbox                F/S</screen></entry>
++						</row>
++					</tbody>
++				</tgroup>
++			</table>
++		</sect4>
++		<sect4 id="intro-sidebar-abbrev">
++			<title>Abbreviating Mailbox Names</title>
++			<para>
++				<literal>$sidebar_delim_chars</literal> tells Sidebar
++				how to split up mailbox paths.  For local directories
++				use <quote>/</quote>; for IMAP folders use <quote>.</quote>
++			</para>
++			<sect5 id="intro-sidebar-abbrev-ex1">
++				<title>Example 1</title>
++				<para>
++					This example works well if your mailboxes have unique names
++					after the last separator.
++				</para>
++				<para>
++					Add some mailboxes of diffent depths.
++				</para>
++<screen>
++set folder="~/mail"
++mailboxes =fruit/apple          =fruit/banana          =fruit/cherry
++mailboxes =water/sea/sicily     =water/sea/archipelago =water/sea/sibuyan
++mailboxes =water/ocean/atlantic =water/ocean/pacific   =water/ocean/arctic
++</screen>
++				<para>
++					Shorten the names:
++				</para>
++<screen>
++set sidebar_short_path                  <emphasis role="comment"># Shorten mailbox names</emphasis>
++set sidebar_delim_chars="/"             <emphasis role="comment"># Delete everything up to the last / character</emphasis>
++</screen>
++				<para>
++					The screenshot below shows what the Sidebar would look like
++					before and after shortening.
++				</para>
++<screen>
++|fruit/apple                            |apple
++|fruit/banana                           |banana
++|fruit/cherry                           |cherry
++|water/sea/sicily                       |sicily
++|water/sea/archipelago                  |archipelago
++|water/sea/sibuyan                      |sibuyan
++|water/ocean/atlantic                   |atlantic
++|water/ocean/pacific                    |pacific
++|water/ocean/arctic                     |arctic
++</screen>
++			</sect5>
++			<sect5 id="intro-sidebar-abbrev-ex2">
++				<title>Example 2</title>
++				<para>
++					This example works well if you have lots of mailboxes which are arranged
++					in a tree.
++				</para>
++				<para>
++					Add some mailboxes of diffent depths.
++				</para>
++<screen>
++set folder="~/mail"
++mailboxes =fruit
++mailboxes =fruit/apple =fruit/banana =fruit/cherry
++mailboxes =water
++mailboxes =water/sea
++mailboxes =water/sea/sicily =water/sea/archipelago =water/sea/sibuyan
++mailboxes =water/ocean
++mailboxes =water/ocean/atlantic =water/ocean/pacific =water/ocean/arctic
++</screen>
++				<para>
++					Shorten the names:
++				</para>
++<screen>
++set sidebar_short_path                  <emphasis role="comment"># Shorten mailbox names</emphasis>
++set sidebar_delim_chars="/"             <emphasis role="comment"># Delete everything up to the last / character</emphasis>
++set sidebar_folder_indent               <emphasis role="comment"># Indent folders whose names we've shortened</emphasis>
++set sidebar_indent_string="  "          <emphasis role="comment"># Indent with two spaces</emphasis>
++</screen>
++				<para>
++					The screenshot below shows what the Sidebar would look like
++					before and after shortening.
++				</para>
++<screen>
++|fruit                                  |fruit
++|fruit/apple                            |  apple
++|fruit/banana                           |  banana
++|fruit/cherry                           |  cherry
++|water                                  |water
++|water/sea                              |  sea
++|water/sea/sicily                       |    sicily
++|water/sea/archipelago                  |    archipelago
++|water/sea/sibuyan                      |    sibuyan
++|water/ocean                            |  ocean
++|water/ocean/atlantic                   |    atlantic
++|water/ocean/pacific                    |    pacific
++|water/ocean/arctic                     |    arctic
++</screen>
++				<para>
++					Sometimes, it will be necessary to add mailboxes, that you
++					don't use, to fill in part of the tree.	 This will trade
++					vertical space for horizonal space (but it looks good).
++				</para>
++			</sect5>
++		</sect4>
++		<sect4 id="intro-sidebar-limit">
++			<title>Limiting the Number of Mailboxes</title>
++			<para>
++				If you have a lot of mailboxes, sometimes it can be useful to hide
++				the ones you aren't using.	<literal>$sidebar_new_mail_only</literal>
++				tells Sidebar to only show mailboxes that contain new, or flagged, email.
++			</para>
++			<para>
++				If you want some mailboxes to be always visible, then use the
++				<literal>sidebar_whitelist</literal> command.  It takes a list of
++				mailboxes as parameters.
++			</para>
++<screen>
++set sidebar_new_mail_only               <emphasis role="comment"># Only mailboxes with new/flagged email</emphasis>
++sidebar_whitelist fruit fruit/apple     <emphasis role="comment"># Always display these two mailboxes</emphasis>
++</screen>
++		</sect4>
++	</sect3>
++	<sect3 id="intro-sidebar-colors">
++		<title>Colors</title>
++		<para>
++			Here is a sample color scheme:
++		</para>
++<screen>
++color sidebar_indicator default color17         <emphasis role="comment"># Dark blue background</emphasis>
++color sidebar_highlight white   color238        <emphasis role="comment"># Grey background</emphasis>
++color sidebar_spoolfile yellow  default         <emphasis role="comment"># Yellow</emphasis>
++color sidebar_new       green   default         <emphasis role="comment"># Green</emphasis>
++color sidebar_flagged   red     default         <emphasis role="comment"># Red</emphasis>
++color sidebar_divider   color8  default         <emphasis role="comment"># Dark grey</emphasis>
++</screen>
++		<para>
++			There is a priority order when coloring Sidebar mailboxes.
++			e.g.  If a mailbox has new mail it will have the
++			<literal>sidebar_new</literal> color, even if it also contains
++			flagged mails.
++		</para>
++		<table id="table-intro-sidebar-colors">
++			<title>Sidebar Color Priority</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Priority</entry>
++						<entry>Color</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>Highest</entry>
++						<entry><literal>sidebar_indicator</literal></entry>
++						<entry>Mailbox is open</entry>
++					</row>
++					<row>
++						<entry></entry>
++						<entry><literal>sidebar_highlight</literal></entry>
++						<entry>Mailbox is highlighed</entry>
++					</row>
++					<row>
++						<entry></entry>
++						<entry><literal>sidebar_spoolfile</literal></entry>
++						<entry>Mailbox is the spoolfile (receives incoming mail)</entry>
++					</row>
++					<row>
++						<entry></entry>
++						<entry><literal>sidebar_new</literal></entry>
++						<entry>Mailbox contains new mail</entry>
++					</row>
++					<row>
++						<entry></entry>
++						<entry><literal>sidebar_flagged</literal></entry>
++						<entry>Mailbox contains flagged mail</entry>
++					</row>
++					<row>
++						<entry>Lowest</entry>
++						<entry>(None)</entry>
++						<entry>Mailbox does not match above</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect3>
++	<sect3 id="intro-sidebar-bugfixes">
++		<title>Bug-fixes</title>
++		<para>
++			If you haven't used Sidebar before, you can ignore this section.
++		</para>
++		<para>
++			These bugs have been fixed since the previous Sidebar release: 2015-11-11.
++		</para>
++		<itemizedlist>
++			<listitem><para>Fix bug when starting in compose mode</para></listitem>
++			<listitem><para>Fix bug with empty sidebar_divider_char string</para></listitem>
++			<listitem><para>Fix bug with header wrapping</para></listitem>
++			<listitem><para>Correctly handle utf8 character sequences</para></listitem>
++			<listitem><para>Fix a bug in mh_buffy_update</para></listitem>
++			<listitem><para>Fix refresh -- time overflowed short</para></listitem>
++			<listitem><para>Protect against empty format strings</para></listitem>
++			<listitem><para>Limit Sidebar width to COLS</para></listitem>
++			<listitem><para>Handle unmailboxes * safely</para></listitem>
++			<listitem><para>Refresh Sidebar after timeout</para></listitem>
++		</itemizedlist>
++	</sect3>
++	<sect3 id="intro-sidebar-config-changes">
++		<title>Config Changes</title>
++		<para>
++			If you haven't used Sidebar before, you can ignore this section.
++		</para>
++		<para>
++			Some of the Sidebar config has been changed to make its meaning clearer.
++			These changes have been made since the previous Sidebar release: 2015-11-11.
++		</para>
++		<table id="table-intro-sidebar-config-changes">
++			<title>Config Changes</title>
++			<tgroup cols="2">
++				<thead>
++					<row>
++						<entry>Old Name</entry>
++						<entry>New Name</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>$sidebar_delim</literal></entry>
++						<entry><literal>$sidebar_divider_char</literal></entry>
++					</row>
++					<row>
++						<entry><literal>$sidebar_folderindent</literal></entry>
++						<entry><literal>$sidebar_folder_indent</literal></entry>
++					</row>
++					<row>
++						<entry><literal>$sidebar_indentstr</literal></entry>
++						<entry><literal>$sidebar_indent_string</literal></entry>
++					</row>
++					<row>
++						<entry><literal>$sidebar_newmail_only</literal></entry>
++						<entry><literal>$sidebar_new_mail_only</literal></entry>
++					</row>
++					<row>
++						<entry><literal>$sidebar_refresh</literal></entry>
++						<entry><literal>$sidebar_refresh_time</literal></entry>
++					</row>
++					<row>
++						<entry><literal>$sidebar_shortpath</literal></entry>
++						<entry><literal>$sidebar_short_path</literal></entry>
++					</row>
++					<row>
++						<entry><literal>$sidebar_sort</literal></entry>
++						<entry><literal>$sidebar_sort_method</literal></entry>
++					</row>
++					<row>
++						<entry><literal><sidebar-scroll-down></literal></entry>
++						<entry><literal><sidebar-page-down></literal></entry>
++					</row>
++					<row>
++						<entry><literal><sidebar-scroll-up></literal></entry>
++						<entry><literal><sidebar-page-up></literal></entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect3>
++</sect2>
++
+ <sect2 id="intro-help">
+ <title>Help</title>
+ 
+@@ -8081,6 +8698,469 @@
+ 
+ </sect1>
+ 
++<sect1 id="sidebar">
++	<title>Sidebar Patch</title>
++	<subtitle>Overview of mailboxes</subtitle>
++
++	<sect2 id="sidebar-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Sidebar</quote>, look for
++			<quote>+USE_SIDEBAR</quote> in the mutt version.
++			See: <xref linkend="compile-time-features"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="sidebar-intro">
++		<title>Introduction</title>
++
++		<para>
++			The Sidebar shows a list of all your mailboxes.  The list can be
++			turned on and off, it can be themed and the list style can be
++			configured.
++		</para>
++
++		<para>
++			This part of the manual is a reference guide.
++			If you want a simple introduction with examples see the
++			<link linkend="intro-sidebar">Sidebar Howto</link>.
++			If you just want to get started, you could use the sample
++			<link linkend="sidebar-muttrc">Sidebar muttrc</link>.
++		</para>
++
++		<para>
++			This version of Sidebar is based on Terry Chan's
++			<ulink url="http://www.lunar-linux.org/mutt-sidebar/">2015-11-11 release</ulink>.
++			It contains many
++			<emphasis role="bold"><link linkend="intro-sidebar-features">new features</link></emphasis>,
++			lots of
++			<emphasis role="bold"><link linkend="intro-sidebar-bugfixes">bugfixes</link></emphasis>.
++		</para>
++	</sect2>
++
++	<sect2 id="sidebar-variables">
++		<title>Variables</title>
++
++		<table id="table-sidebar-variables">
++			<title>Sidebar Variables</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Name</entry>
++						<entry>Type</entry>
++						<entry>Default</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>sidebar_delim_chars</literal></entry>
++						<entry>string</entry>
++						<entry><literal>/.</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_divider_char</literal></entry>
++						<entry>string</entry>
++						<entry><literal>|</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_folder_indent</literal></entry>
++						<entry>boolean</entry>
++						<entry><literal>no</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_format</literal></entry>
++						<entry>string</entry>
++						<entry><literal>%B%?F? [%F]?%* %?N?%N/?%S</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_indent_string</literal></entry>
++						<entry>string</entry>
++						<entry><literal>  </literal> (two spaces)</entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_new_mail_only</literal></entry>
++						<entry>boolean</entry>
++						<entry><literal>no</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_next_new_wrap</literal></entry>
++						<entry>boolean</entry>
++						<entry><literal>no</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_refresh_time</literal></entry>
++						<entry>number</entry>
++						<entry><literal>60</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_short_path</literal></entry>
++						<entry>boolean</entry>
++						<entry><literal>no</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_sort_method</literal></entry>
++						<entry>enum</entry>
++						<entry><literal>SORT_ORDER</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_visible</literal></entry>
++						<entry>boolean</entry>
++						<entry><literal>no</literal></entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_whitelist</literal></entry>
++						<entry>list</entry>
++						<entry>(empty)</entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_width</literal></entry>
++						<entry>number</entry>
++						<entry><literal>20</literal></entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++	<sect2 id="sidebar-functions">
++		<title>Functions</title>
++
++		<para>
++			Sidebar adds the following functions to Mutt.
++			By default, none of them are bound to keys.
++		</para>
++
++		<table id="table-sidebar-functions">
++			<title>Sidebar Functions</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Menus</entry>
++						<entry>Function</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-next></literal></entry>
++						<entry>Move the highlight to next mailbox</entry>
++					</row>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-next-new></literal></entry>
++						<entry>Move the highlight to next mailbox with new mail</entry>
++					</row>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-open></literal></entry>
++						<entry>Open highlighted mailbox</entry>
++					</row>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-page-down></literal></entry>
++						<entry>Scroll the Sidebar down 1 page</entry>
++					</row>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-page-up></literal></entry>
++						<entry>Scroll the Sidebar up 1 page</entry>
++					</row>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-prev></literal></entry>
++						<entry>Move the highlight to previous mailbox</entry>
++					</row>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-prev-new></literal></entry>
++						<entry>Move the highlight to previous mailbox with new mail</entry>
++					</row>
++					<row>
++						<entry>index,pager</entry>
++						<entry><literal><sidebar-toggle-visible></literal></entry>
++						<entry>Make the Sidebar (in)visible</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++	<sect2 id="sidebar-commands">
++		<title>Commands</title>
++		<cmdsynopsis>
++			<command>sidebar_whitelist</command>
++			<arg choice="plain">
++				<replaceable class="parameter">mailbox</replaceable>
++			</arg>
++			<arg choice="opt" rep="repeat">
++				<replaceable class="parameter">mailbox</replaceable>
++			</arg>
++		</cmdsynopsis>
++	</sect2>
++
++	<sect2 id="sidebar-colors">
++		<title>Colors</title>
++
++		<table id="table-sidebar-colors">
++			<title>Sidebar Colors</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Name</entry>
++						<entry>Default Color</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>sidebar_divider</literal></entry>
++						<entry>default</entry>
++						<entry>The dividing line between the Sidebar and the Index/Pager panels</entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_flagged</literal></entry>
++						<entry>default</entry>
++						<entry>Mailboxes containing flagged mail</entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_highlight</literal></entry>
++						<entry>underline</entry>
++						<entry>Cursor to select a mailbox</entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_indicator</literal></entry>
++						<entry>mutt <literal>indicator</literal></entry>
++						<entry>The mailbox open in the Index panel</entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_new</literal></entry>
++						<entry>default</entry>
++						<entry>Mailboxes containing new mail</entry>
++					</row>
++					<row>
++						<entry><literal>sidebar_spoolfile</literal></entry>
++						<entry>default</entry>
++						<entry>Mailbox that receives incoming mail</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++
++		If the <literal>sidebar_indicator</literal> color isn't set, then the default Mutt
++		indicator color will be used (the color used in the index panel).
++	</sect2>
++
++	<sect2 id="sidebar-sort">
++		<title>Sort</title>
++
++		<table id="table-sidebar-sort">
++			<title>Sidebar Sort</title>
++			<tgroup cols="2">
++				<thead>
++					<row>
++						<entry>Sort</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>alpha</literal></entry>
++						<entry>Alphabetically by path</entry>
++					</row>
++					<row>
++						<entry><literal>count</literal></entry>
++						<entry>Total number of messages</entry>
++					</row>
++					<row>
++						<entry><literal>flagged</literal></entry>
++						<entry>Number of flagged messages</entry>
++					</row>
++					<row>
++						<entry><literal>name</literal></entry>
++						<entry>Alphabetically by path</entry>
++					</row>
++					<row>
++						<entry><literal>new</literal></entry>
++						<entry>Number of new messages</entry>
++					</row>
++					<row>
++						<entry><literal>path</literal></entry>
++						<entry>Alphabetically by path</entry>
++					</row>
++					<row>
++						<entry><literal>unsorted</literal></entry>
++						<entry>Do not resort the paths</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++	<sect2 id="sidebar-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># This is a complete list of sidebar-related configuration.
++ 
++# --------------------------------------------------------------------------
++# VARIABLES - shown with their default values
++# --------------------------------------------------------------------------
++ 
++# Should the Sidebar be shown?</emphasis>
++set sidebar_visible = no
++ 
++<emphasis role="comment"># How wide should the Sidebar be in screen columns?
++# Note: Some characters, e.g. Chinese, take up two columns each.</emphasis>
++set sidebar_width = 20
++ 
++<emphasis role="comment"># Should the mailbox paths be abbreviated?</emphasis>
++set sidebar_short_path = no
++ 
++<emphasis role="comment"># When abbreviating mailbox path names, use any of these characters as path
++# separators.  Only the part after the last separators will be shown.
++# For file folders '/' is good.  For IMAP folders, often '.' is useful.</emphasis>
++set sidebar_delim_chars = '/.'
++ 
++<emphasis role="comment"># If the mailbox path is abbreviated, should it be indented?</emphasis>
++set sidebar_folder_indent = no
++ 
++<emphasis role="comment"># Indent mailbox paths with this string.</emphasis>
++set sidebar_indent_string = '  '
++ 
++<emphasis role="comment"># Make the Sidebar only display mailboxes that contain new, or flagged,
++# mail.</emphasis>
++set sidebar_new_mail_only = no
++ 
++<emphasis role="comment"># Any mailboxes that are whitelisted will always be visible, even if the
++# sidebar_new_mail_only option is enabled.</emphasis>
++sidebar_whitelist '/home/user/mailbox1'
++sidebar_whitelist '/home/user/mailbox2'
++ 
++<emphasis role="comment"># When searching for mailboxes containing new mail, should the search wrap
++# around when it reaches the end of the list?</emphasis>
++set sidebar_next_new_wrap = no
++ 
++<emphasis role="comment"># The character to use as the divider between the Sidebar and the other Mutt
++# panels.
++# Note: Only the first character of this string is used.</emphasis>
++set sidebar_divider_char = '|'
++ 
++<emphasis role="comment"># Display the Sidebar mailboxes using this format string.</emphasis>
++set sidebar_format = '%B%?F? [%F]?%* %?N?%N/?%S'
++ 
++<emphasis role="comment"># Sidebar will not refresh its list of mailboxes any more frequently than
++# this number of seconds.  This will help reduce disk/network traffic.</emphasis>
++set sidebar_refresh_time = 60
++ 
++<emphasis role="comment"># Sort the mailboxes in the Sidebar using this method:
++#       count    - total number of messages
++#       flagged  - number of flagged messages
++#       new      - number of new messages
++#       path     - mailbox path
++#       unsorted - do not sort the mailboxes</emphasis>
++set sidebar_sort_method = 'unsorted'
++ 
++<emphasis role="comment"># --------------------------------------------------------------------------
++# FUNCTIONS - shown with an example mapping
++# --------------------------------------------------------------------------
++ 
++# Move the highlight to the previous mailbox</emphasis>
++bind index,pager \Cp sidebar-prev
++ 
++<emphasis role="comment"># Move the highlight to the next mailbox</emphasis>
++bind index,pager \Cn sidebar-next
++ 
++<emphasis role="comment"># Open the highlighted mailbox</emphasis>
++bind index,pager \Co sidebar-open
++ 
++<emphasis role="comment"># Move the highlight to the previous page
++# This is useful if you have a LOT of mailboxes.</emphasis>
++bind index,pager <F3> sidebar-page-up
++ 
++<emphasis role="comment"># Move the highlight to the next page
++# This is useful if you have a LOT of mailboxes.</emphasis>
++bind index,pager <F4> sidebar-page-down
++ 
++<emphasis role="comment"># Move the highlight to the previous mailbox containing new, or flagged,
++# mail.</emphasis>
++bind index,pager <F5> sidebar-prev-new
++ 
++<emphasis role="comment"># Move the highlight to the next mailbox containing new, or flagged, mail.</emphasis>
++bind index,pager <F6> sidebar-next-new
++ 
++<emphasis role="comment"># Toggle the visibility of the Sidebar.</emphasis>
++bind index,pager B sidebar-toggle-visible
++ 
++<emphasis role="comment"># --------------------------------------------------------------------------
++# COLORS - some unpleasant examples are given
++# --------------------------------------------------------------------------
++# Note: All color operations are of the form:
++#       color OBJECT FOREGROUND BACKGROUND
++ 
++# Color of the current, open, mailbox
++# Note: This is a general Mutt option which colors all selected items.</emphasis>
++color indicator cyan black
++ 
++<emphasis role="comment"># Color of the highlighted, but not open, mailbox.</emphasis>
++color sidebar_highlight black color8
++ 
++<emphasis role="comment"># Color of the divider separating the Sidebar from Mutt panels</emphasis>
++color sidebar_divider color8 black
++ 
++<emphasis role="comment"># Color to give mailboxes containing flagged mail</emphasis>
++color sidebar_flagged red black
++ 
++<emphasis role="comment"># Color to give mailboxes containing new mail</emphasis>
++color sidebar_new green black
++ 
++<emphasis role="comment"># --------------------------------------------------------------------------
++ 
++# vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="sidebar-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><link linkend="regexp">Regular Expressions</link></para></listitem>
++			<listitem><para><link linkend="patterns">Patterns</link></para></listitem>
++			<listitem><para><link linkend="color">Color command</link></para></listitem>
++			<listitem><para><link linkend="notmuch">notmuch patch</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="sidebar-known-bugs">
++		<title>Known Bugs</title>
++		Unsorted isn't
++	</sect2>
++
++	<sect2 id="sidebar-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Justin Hibbits <email>jrh29 at po.cwru.edu</email></para></listitem>
++		<listitem><para>Thomer M. Gil <email>mutt at thomer.com</email></para></listitem>
++		<listitem><para>David Sterba <email>dsterba at suse.cz</email></para></listitem>
++		<listitem><para>Evgeni Golov <email>evgeni at debian.org</email></para></listitem>
++		<listitem><para>Fabian Groffen <email>grobian at gentoo.org</email></para></listitem>
++		<listitem><para>Jason DeTiberus <email>jdetiber at redhat.com</email></para></listitem>
++		<listitem><para>Stefan Assmann <email>sassmann at kpanic.de</email></para></listitem>
++		<listitem><para>Steve Kemp <email>steve at steve.org.uk</email></para></listitem>
++		<listitem><para>Terry Chan <email>tchan at lunar-linux.org</email></para></listitem>
++		<listitem><para>Tyler Earnest <email>tylere at rne.st</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+@@ -9237,6 +10317,17 @@
+ 
+ <listitem>
+ <cmdsynopsis>
++<command>sidebar_whitelist</command>
++<arg choice="plain">
++<replaceable class="parameter">item</replaceable>
++</arg>
++<arg choice="plain">
++<replaceable class="parameter">command</replaceable>
++</arg>
++</cmdsynopsis>
++</listitem>
++<listitem>
++<cmdsynopsis>
+ <command><link linkend="source">source</link></command>
+ <arg choice="plain">
+ <replaceable class="parameter">filename</replaceable>
+diff -urN mutt-1.6.1/doc/muttrc.sidebar mutt-1.6.1-sidebar/doc/muttrc.sidebar
+--- mutt-1.6.1/doc/muttrc.sidebar	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-sidebar/doc/muttrc.sidebar	2016-05-02 03:02:14.932211718 +0100
+@@ -0,0 +1,116 @@
++# This is a complete list of sidebar-related configuration.
++
++# --------------------------------------------------------------------------
++# VARIABLES - shown with their default values
++# --------------------------------------------------------------------------
++
++# Should the Sidebar be shown?
++set sidebar_visible = no
++
++# How wide should the Sidebar be in screen columns?
++# Note: Some characters, e.g. Chinese, take up two columns each.
++set sidebar_width = 20
++
++# Should the mailbox paths be abbreviated?
++set sidebar_short_path = no
++
++# When abbreviating mailbox path names, use any of these characters as path
++# separators.  Only the part after the last separators will be shown.
++# For file folders '/' is good.  For IMAP folders, often '.' is useful.
++set sidebar_delim_chars = '/.'
++
++# If the mailbox path is abbreviated, should it be indented?
++set sidebar_folder_indent = no
++
++# Indent mailbox paths with this string.
++set sidebar_indent_string = '  '
++
++# Make the Sidebar only display mailboxes that contain new, or flagged,
++# mail.
++set sidebar_new_mail_only = no
++
++# Any mailboxes that are whitelisted will always be visible, even if the
++# sidebar_new_mail_only option is enabled.
++sidebar_whitelist '/home/user/mailbox1'
++sidebar_whitelist '/home/user/mailbox2'
++
++# When searching for mailboxes containing new mail, should the search wrap
++# around when it reaches the end of the list?
++set sidebar_next_new_wrap = no
++
++# The character to use as the divider between the Sidebar and the other Mutt
++# panels.
++# Note: Only the first character of this string is used.
++set sidebar_divider_char = '|'
++
++# Display the Sidebar mailboxes using this format string.
++set sidebar_format = '%B%?F? [%F]?%* %?N?%N/?%S'
++
++# Sidebar will not refresh its list of mailboxes any more frequently than
++# this number of seconds.  This will help reduce disk/network traffic.
++set sidebar_refresh_time = 60
++
++# Sort the mailboxes in the Sidebar using this method:
++#       count    - total number of messages
++#       flagged  - number of flagged messages
++#       new      - number of new messages
++#       path     - mailbox path
++#       unsorted - do not sort the mailboxes
++set sidebar_sort_method = 'unsorted'
++
++# --------------------------------------------------------------------------
++# FUNCTIONS - shown with an example mapping
++# --------------------------------------------------------------------------
++
++# Move the highlight to the previous mailbox
++bind index,pager \Cp sidebar-prev
++
++# Move the highlight to the next mailbox
++bind index,pager \Cn sidebar-next
++
++# Open the highlighted mailbox
++bind index,pager \Co sidebar-open
++
++# Move the highlight to the previous page
++# This is useful if you have a LOT of mailboxes.
++bind index,pager <F3> sidebar-page-up
++
++# Move the highlight to the next page
++# This is useful if you have a LOT of mailboxes.
++bind index,pager <F4> sidebar-page-down
++
++# Move the highlight to the previous mailbox containing new, or flagged,
++# mail.
++bind index,pager <F5> sidebar-prev-new
++
++# Move the highlight to the next mailbox containing new, or flagged, mail.
++bind index,pager <F6> sidebar-next-new
++
++# Toggle the visibility of the Sidebar.
++bind index,pager B sidebar-toggle-visible
++
++# --------------------------------------------------------------------------
++# COLORS - some unpleasant examples are given
++# --------------------------------------------------------------------------
++# Note: All color operations are of the form:
++#       color OBJECT FOREGROUND BACKGROUND
++
++# Color of the current, open, mailbox
++# Note: This is a general Mutt option which colors all selected items.
++color indicator cyan black
++
++# Color of the highlighted, but not open, mailbox.
++color sidebar_highlight black color8
++
++# Color of the divider separating the Sidebar from Mutt panels
++color sidebar_divider color8 black
++
++# Color to give mailboxes containing flagged mail
++color sidebar_flagged red black
++
++# Color to give mailboxes containing new mail
++color sidebar_new green black
++
++# --------------------------------------------------------------------------
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/doc/vimrc.sidebar mutt-1.6.1-sidebar/doc/vimrc.sidebar
+--- mutt-1.6.1/doc/vimrc.sidebar	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-sidebar/doc/vimrc.sidebar	2016-05-02 03:02:14.933211733 +0100
+@@ -0,0 +1,35 @@
++" Vim syntax file for the mutt sidebar patch
++
++syntax keyword muttrcVarBool    skipwhite contained sidebar_folder_indent nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
++syntax keyword muttrcVarBool    skipwhite contained sidebar_new_mail_only nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
++syntax keyword muttrcVarBool    skipwhite contained sidebar_next_new_wrap nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
++syntax keyword muttrcVarBool    skipwhite contained sidebar_short_path    nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
++syntax keyword muttrcVarBool    skipwhite contained sidebar_visible       nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
++
++syntax keyword muttrcVarNum     skipwhite contained sidebar_refresh_time  nextgroup=muttrcSetNumAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
++syntax keyword muttrcVarNum     skipwhite contained sidebar_width         nextgroup=muttrcSetNumAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr
++
++syntax keyword muttrcVarStr     contained skipwhite sidebar_divider_char  nextgroup=muttrcVarEqualsIdxFmt
++syntax keyword muttrcVarStr     contained skipwhite sidebar_delim_chars   nextgroup=muttrcVarEqualsIdxFmt
++syntax keyword muttrcVarStr     contained skipwhite sidebar_format        nextgroup=muttrcVarEqualsIdxFmt
++syntax keyword muttrcVarStr     contained skipwhite sidebar_indent_string nextgroup=muttrcVarEqualsIdxFmt
++syntax keyword muttrcVarStr     contained skipwhite sidebar_sort_method   nextgroup=muttrcVarEqualsIdxFmt
++
++syntax keyword muttrcCommand    sidebar_whitelist
++
++syntax match muttrcFunction     contained "\<sidebar-next\>"
++syntax match muttrcFunction     contained "\<sidebar-next-new\>"
++syntax match muttrcFunction     contained "\<sidebar-open\>"
++syntax match muttrcFunction     contained "\<sidebar-page-down\>"
++syntax match muttrcFunction     contained "\<sidebar-page-up\>"
++syntax match muttrcFunction     contained "\<sidebar-prev\>"
++syntax match muttrcFunction     contained "\<sidebar-prev-new\>"
++syntax match muttrcFunction     contained "\<sidebar-toggle-visible\>"
++
++syntax keyword muttrcColorField contained sidebar_divider
++syntax keyword muttrcColorField contained sidebar_flagged
++syntax keyword muttrcColorField contained sidebar_highlight
++syntax keyword muttrcColorField contained sidebar_indicator
++syntax keyword muttrcColorField contained sidebar_new
++
++" vim: syntax=vim
+diff -urN mutt-1.6.1/flags.c mutt-1.6.1-sidebar/flags.c
+--- mutt-1.6.1/flags.c	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-sidebar/flags.c	2016-05-02 03:02:15.015213038 +0100
+@@ -25,6 +25,10 @@
+ #include "sort.h"
+ #include "mx.h"
+ 
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
++
+ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
+ {
+   int changed = h->changed;
+@@ -263,6 +267,9 @@
+    */
+   if (h->searched && (changed != h->changed || deleted != ctx->deleted || tagged != ctx->tagged || flagged != ctx->flagged))
+     h->searched = 0;
++#ifdef USE_SIDEBAR
++  sb_draw();
++#endif
+ }
+ 
+ void mutt_tag_set_flag (int flag, int bf)
+diff -urN mutt-1.6.1/functions.h mutt-1.6.1-sidebar/functions.h
+--- mutt-1.6.1/functions.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-sidebar/functions.h	2016-05-02 03:02:15.015213038 +0100
+@@ -168,6 +168,16 @@
+   { "decrypt-copy",		OP_DECRYPT_COPY,		NULL },
+   { "decrypt-save",		OP_DECRYPT_SAVE,		NULL },
+ 
++#ifdef USE_SIDEBAR
++  { "sidebar-next",		OP_SIDEBAR_NEXT,		NULL },
++  { "sidebar-next-new",		OP_SIDEBAR_NEXT_NEW,		NULL },
++  { "sidebar-open",		OP_SIDEBAR_OPEN,		NULL },
++  { "sidebar-page-down",	OP_SIDEBAR_PAGE_DOWN,		NULL },
++  { "sidebar-page-up",		OP_SIDEBAR_PAGE_UP,		NULL },
++  { "sidebar-prev",		OP_SIDEBAR_PREV,		NULL },
++  { "sidebar-prev-new",		OP_SIDEBAR_PREV_NEW,		NULL },
++  { "sidebar-toggle-visible",	OP_SIDEBAR_TOGGLE_VISIBLE,	NULL },
++#endif
+ 
+   { NULL,			0,				NULL }
+ };
+@@ -272,6 +282,17 @@
+ 
+   { "what-key",		OP_WHAT_KEY,		NULL },
+ 
++#ifdef USE_SIDEBAR
++  { "sidebar-next",		OP_SIDEBAR_NEXT,		NULL },
++  { "sidebar-next-new",		OP_SIDEBAR_NEXT_NEW,		NULL },
++  { "sidebar-open",		OP_SIDEBAR_OPEN,		NULL },
++  { "sidebar-page-down",	OP_SIDEBAR_PAGE_DOWN,		NULL },
++  { "sidebar-page-up",		OP_SIDEBAR_PAGE_UP,		NULL },
++  { "sidebar-prev",		OP_SIDEBAR_PREV,		NULL },
++  { "sidebar-prev-new",		OP_SIDEBAR_PREV_NEW,		NULL },
++  { "sidebar-toggle-visible",	OP_SIDEBAR_TOGGLE_VISIBLE,	NULL },
++#endif
++
+   { NULL,		0,				NULL }
+ };
+ 
+diff -urN mutt-1.6.1/globals.h mutt-1.6.1-sidebar/globals.h
+--- mutt-1.6.1/globals.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-sidebar/globals.h	2016-05-02 03:02:15.015213038 +0100
+@@ -118,6 +118,12 @@
+ WHERE char *SendCharset;
+ WHERE char *Sendmail;
+ WHERE char *Shell;
++#ifdef USE_SIDEBAR
++WHERE char *SidebarDelimChars;
++WHERE char *SidebarDividerChar;
++WHERE char *SidebarFormat;
++WHERE char *SidebarIndentString;
++#endif
+ WHERE char *Signature;
+ WHERE char *SimpleSearch;
+ #if USE_SMTP
+@@ -214,6 +220,14 @@
+ WHERE short ScoreThresholdRead;
+ WHERE short ScoreThresholdFlag;
+ 
++/* This isn't excluded from the build because it's too entwined in the code.
++ * For now. */
++WHERE short SidebarWidth;
++#ifdef USE_SIDEBAR
++WHERE short SidebarRefreshTime;
++WHERE LIST *SidebarWhitelist INITVAL(0);
++#endif
++
+ #ifdef USE_IMAP
+ WHERE short ImapKeepalive;
+ WHERE short ImapPipelineDepth;
+diff -urN mutt-1.6.1/imap/command.c mutt-1.6.1-sidebar/imap/command.c
+--- mutt-1.6.1/imap/command.c	2016-05-02 03:02:12.404171496 +0100
++++ mutt-1.6.1-sidebar/imap/command.c	2016-05-02 03:02:14.939211829 +0100
+@@ -1016,6 +1016,14 @@
+ 	     opened */
+ 	  status->uidnext = oldun;
+ 
++#ifdef USE_SIDEBAR
++	/* Make the sidebar show the correct numbers */
++	if (status->messages) {
++	  inc->msg_count  = status->messages;
++	  inc->msg_unread = status->unseen;
++	}
++#endif
++
+         FREE (&value);
+         return;
+       }
+diff -urN mutt-1.6.1/imap/imap.c mutt-1.6.1-sidebar/imap/imap.c
+--- mutt-1.6.1/imap/imap.c	2016-05-02 03:02:12.404171496 +0100
++++ mutt-1.6.1-sidebar/imap/imap.c	2016-05-02 03:02:15.016213054 +0100
+@@ -1535,7 +1535,11 @@
+ 
+     imap_munge_mbox_name (idata, munged, sizeof (munged), name);
+     snprintf (command, sizeof (command),
++#ifdef USE_SIDEBAR
++	      "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT MESSAGES)", munged);
++#else
+ 	      "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged);
++#endif
+ 
+     if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0)
+     {
+diff -urN mutt-1.6.1/init.c mutt-1.6.1-sidebar/init.c
+--- mutt-1.6.1/init.c	2016-05-02 03:02:12.405171512 +0100
++++ mutt-1.6.1-sidebar/init.c	2016-05-02 03:02:15.017213070 +0100
+@@ -2173,6 +2173,9 @@
+ 	case DT_SORT_AUX:
+ 	  map = SortAuxMethods;
+ 	  break;
++	case DT_SORT_SIDEBAR:
++	  map = SortSidebarMethods;
++	  break;
+ 	default:
+ 	  map = SortMethods;
+ 	  break;
+diff -urN mutt-1.6.1/init.h mutt-1.6.1-sidebar/init.h
+--- mutt-1.6.1/init.h	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-sidebar/init.h	2016-05-02 03:02:15.018213086 +0100
+@@ -42,11 +42,12 @@
+ #define DTYPE(x) ((x) & DT_MASK)
+ 
+ /* subtypes */
+-#define DT_SUBTYPE_MASK	0xf0
++#define DT_SUBTYPE_MASK	0xff0
+ #define DT_SORT_ALIAS	0x10
+ #define DT_SORT_BROWSER 0x20
+ #define DT_SORT_KEYS	0x40
+ #define DT_SORT_AUX	0x80
++#define DT_SORT_SIDEBAR	0x100
+ 
+ /* flags to parse_set() */
+ #define M_SET_INV	(1<<0)	/* default is to invert all vars */
+@@ -2665,6 +2666,146 @@
+   ** Command to use when spawning a subshell.  By default, the user's login
+   ** shell from \fC/etc/passwd\fP is used.
+   */
++#ifdef USE_SIDEBAR
++  { "sidebar_divider_char", DT_STR, R_BOTH, UL &SidebarDividerChar, UL "|" },
++  /*
++  ** .pp
++  ** This specifies the characters to be drawn between the sidebar (when
++  ** visible) and the other Mutt panels. ASCII and Unicode line-drawing
++  ** characters are supported.
++  */
++  { "sidebar_delim_chars", DT_STR, R_NONE, UL &SidebarDelimChars, UL "/." },
++  /*
++  ** .pp
++  ** This contains the list of characters which you would like to treat
++  ** as folder separators for displaying paths in the sidebar.
++  ** .pp
++  ** Local mail is often arranged in directories: `dir1/dir2/mailbox'.
++  ** .ts
++  ** set sidebar_delim_chars='/'
++  ** .te
++  ** IMAP mailboxes are often named: `folder1.folder2.mailbox'.
++  ** .ts
++  ** set sidebar_delim_chars='.'
++  ** .te
++  ** .pp
++  ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_folder_indent, $$sidebar_indent_string.
++  */
++  { "sidebar_folder_indent", DT_BOOL, R_BOTH, OPTSIDEBARFOLDERINDENT, 0 },
++  /*
++  ** .pp
++  ** Set this to indent mailboxes in the sidebar.
++  ** .pp
++  ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_indent_string, $$sidebar_delim_chars.
++  */
++  { "sidebar_format", DT_STR, R_NONE, UL &SidebarFormat, UL "%B%?F? [%F]?%* %?N?%N/?%S" },
++  /*
++  ** .pp
++  ** This variable allows you to customize the sidebar display. This string is
++  ** similar to $$index_format, but has its own set of \fCprintf(3)\fP-like
++  ** sequences:
++  ** .dl
++  ** .dt %B  .dd Name of the mailbox
++  ** .dt %S  .dd * Size of mailbox (total number of messages)
++  ** .dt %N  .dd * Number of New messages in the mailbox
++  ** .dt %F  .dd * Number of Flagged messages in the mailbox
++  ** .dt %!  .dd ``!'' : one flagged message;
++  **             ``!!'' : two flagged messages;
++  **             ``n!'' : n flagged messages (for n > 2).
++  **             Otherwise prints nothing.
++  ** .dt %d  .dd * @ Number of deleted messages
++  ** .dt %L  .dd * @ Number of messages after limiting
++  ** .dt %t  .dd * @ Number of tagged messages
++  ** .dt %>X .dd right justify the rest of the string and pad with ``X''
++  ** .dt %|X .dd pad to the end of the line with ``X''
++  ** .dt %*X .dd soft-fill with character ``X'' as pad
++  ** .de
++  ** .pp
++  ** * = Can be optionally printed if nonzero
++  ** @ = Only applicable to the current folder
++  */
++  { "sidebar_indent_string", DT_STR, R_BOTH, UL &SidebarIndentString, UL "  " },
++  /*
++  ** .pp
++  ** This specifies the string that is used to indent mailboxes in the sidebar.
++  ** It defaults to two spaces.
++  ** .pp
++  ** \fBSee also:\fP $$sidebar_short_path, $$sidebar_folder_indent, $$sidebar_delim_chars.
++  */
++  { "sidebar_new_mail_only", DT_BOOL, R_BOTH, OPTSIDEBARNEWMAILONLY, 0 },
++  /*
++  ** .pp
++  ** When set, the sidebar will only display mailboxes containing new, or
++  ** flagged, mail.
++  ** .pp
++  ** \fBSee also:\fP $sidebar_whitelist.
++  */
++  { "sidebar_next_new_wrap", DT_BOOL, R_BOTH, UL OPTSIDEBARNEXTNEWWRAP, 0 },
++  /*
++  ** .pp
++  ** When set, the \fC<sidebar-next-new>\fP command will not stop and the end of
++  ** the list of mailboxes, but wrap around to the beginning. The
++  ** \fC<sidebar-prev-new>\fP command is similarly affected, wrapping around to
++  ** the end of the list.
++  */
++  { "sidebar_refresh_time", DT_NUM, R_BOTH, UL &SidebarRefreshTime, 60 },
++  /*
++  ** .pp
++  ** Set sidebar_refresh_time to the minimum number of seconds between refreshes.
++  ** This will reduced network traffic.
++  ** .pp
++  ** \fBNote:\fP Set to 0 to disable refreshing.
++  */
++  { "sidebar_short_path", DT_BOOL, R_BOTH, OPTSIDEBARSHORTPATH, 0 },
++  /*
++  ** .pp
++  ** By default the sidebar will show the mailbox's path, relative to the
++  ** $$folder variable. Setting \fCsidebar_shortpath=yes\fP will shorten the
++  ** names relative to the previous name. Here's an example:
++  ** .dl
++  ** .dt \fBshortpath=no\fP .dd \fBshortpath=yes\fP .dd \fBshortpath=yes, folderindent=yes, indentstr=".."\fP
++  ** .dt \fCfruit\fP        .dd \fCfruit\fP         .dd \fCfruit\fP
++  ** .dt \fCfruit.apple\fP  .dd \fCapple\fP         .dd \fC..apple\fP
++  ** .dt \fCfruit.banana\fP .dd \fCbanana\fP        .dd \fC..banana\fP
++  ** .dt \fCfruit.cherry\fP .dd \fCcherry\fP        .dd \fC..cherry\fP
++  ** .de
++  ** .pp
++  ** \fBSee also:\fP $$sidebar_delim_chars, $$sidebar_folder_indent, $$sidebar_indent_string.
++  */
++  { "sidebar_sort_method", DT_SORT|DT_SORT_SIDEBAR, R_NONE, UL &SidebarSortMethod, SORT_ORDER },
++  /*
++  ** .pp
++  ** Specifies how to sort entries in the file browser.  By default, the
++  ** entries are sorted alphabetically.  Valid values:
++  ** .il
++  ** .dd alpha (alphabetically)
++  ** .dd count (all message count)
++  ** .dd date
++  ** .dd desc (description)
++  ** .dd new (new message count)
++  ** .dd size
++  ** .dd unsorted
++  ** .ie
++  ** .pp
++  ** You may optionally use the ``reverse-'' prefix to specify reverse sorting
++  ** order (example: ``\fCset sort_browser=reverse-date\fP'').
++  */
++  { "sidebar_visible", DT_BOOL, R_BOTH, OPTSIDEBAR, 0 },
++  /*
++  ** .pp
++  ** This specifies whether or not to show sidebar. The sidebar shows a list of
++  ** all your mailboxes.
++  ** .pp
++  ** \fBSee also:\fP $$sidebar_format, $$sidebar_width
++  */
++  { "sidebar_width", DT_NUM, R_BOTH, UL &SidebarWidth, 0 },
++  /*
++  ** .pp
++  ** This controls the width of the sidebar.  It is measured in screen columns.
++  ** For example: sidebar_width=20 could display 20 ASCII characters, or 10
++  ** Chinese characters.
++  */
++#endif
+   { "sig_dashes",	DT_BOOL, R_NONE, OPTSIGDASHES, 1 },
+   /*
+   ** .pp
+@@ -3652,6 +3793,19 @@
+   { NULL,       0 }
+ };
+ 
++const struct mapping_t SortSidebarMethods[] = {
++  { "alpha",		SORT_PATH },
++  { "count",		SORT_COUNT },
++  { "desc",		SORT_DESC },
++  { "flagged",		SORT_FLAGGED },
++  { "mailbox-order",	SORT_ORDER },
++  { "name",		SORT_PATH },
++  { "new",		SORT_COUNT_NEW },
++  { "path",		SORT_PATH },
++  { "unsorted",		SORT_ORDER },
++  { NULL,		0 }
++};
++
+ 
+ /* functions used to parse commands in a rc file */
+ 
+@@ -3741,6 +3895,9 @@
+   { "send-hook",	mutt_parse_hook,	M_SENDHOOK },
+   { "send2-hook",	mutt_parse_hook,	M_SEND2HOOK },
+   { "set",		parse_set,		0 },
++#ifdef USE_SIDEBAR
++  { "sidebar_whitelist",parse_list,		UL &SidebarWhitelist },
++#endif
+   { "source",		parse_source,		0 },
+   { "spam",		parse_spam_list,	M_SPAM },
+   { "nospam",		parse_spam_list,	M_NOSPAM },
+diff -urN mutt-1.6.1/keymap.c mutt-1.6.1-sidebar/keymap.c
+--- mutt-1.6.1/keymap.c	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-sidebar/keymap.c	2016-05-02 03:02:14.946211940 +0100
+@@ -453,6 +453,9 @@
+     }
+ #endif
+ 
++    /* update sidebar stats */
++    mutt_buffy_check(0);
++
+     timeout (i * 1000);
+     tmp = mutt_getch();
+     timeout (-1);
+diff -urN mutt-1.6.1/mailbox.h mutt-1.6.1-sidebar/mailbox.h
+--- mutt-1.6.1/mailbox.h	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-sidebar/mailbox.h	2016-05-02 03:02:15.018213086 +0100
+@@ -27,6 +27,9 @@
+ #define M_NEWFOLDER	(1<<4) /* create a new folder - same as M_APPEND, but uses
+ 				* safe_fopen() for mbox-style folders.
+ 				*/
++#ifdef USE_SIDEBAR
++#define M_PEEK		(1<<5) /* revert atime back after taking a look (if applicable) */
++#endif
+ 
+ /* mx_open_new_message() */
+ #define M_ADD_FROM	(1<<0)	/* add a From_ line */
+diff -urN mutt-1.6.1/main.c mutt-1.6.1-sidebar/main.c
+--- mutt-1.6.1/main.c	2016-05-02 03:02:12.408171560 +0100
++++ mutt-1.6.1-sidebar/main.c	2016-05-02 03:02:15.018213086 +0100
+@@ -31,6 +31,9 @@
+ #include "url.h"
+ #include "mutt_crypt.h"
+ #include "mutt_idna.h"
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
+ 
+ #ifdef USE_SASL
+ #include "mutt_sasl.h"
+@@ -485,6 +488,12 @@
+ 	"-USE_HCACHE  "
+ #endif
+ 
++#ifdef USE_SIDEBAR
++	"+USE_SIDEBAR  "
++#else
++	"-USE_SIDEBAR  "
++#endif
++
+ 	);
+ 
+ #ifdef ISPELL
+@@ -557,7 +566,11 @@
+ 
+ int main (int argc, char **argv)
+ {
++#ifdef USE_SIDEBAR
++  char folder[PATH_MAX] = "";
++#else
+   char folder[_POSIX_PATH_MAX] = "";
++#endif
+   char *subject = NULL;
+   char *includeFile = NULL;
+   char *draftFile = NULL;
+@@ -828,6 +841,9 @@
+     clear ();
+     mutt_error = mutt_curses_error;
+     mutt_message = mutt_curses_message;
++#ifdef USE_SIDEBAR
++    sb_init();
++#endif
+   }
+ 
+   /* Create the Maildir directory if it doesn't exist. */
+@@ -1184,6 +1200,15 @@
+       strfcpy (folder, NONULL(Spoolfile), sizeof (folder));
+     mutt_expand_path (folder, sizeof (folder));
+ 
++#ifdef USE_SIDEBAR
++    {
++      char tmpfolder[PATH_MAX] = "";
++      strfcpy (tmpfolder, folder, sizeof (tmpfolder));
++      if (!realpath (tmpfolder, folder))
++        strfcpy (folder, tmpfolder, sizeof (tmpfolder));
++    }
++#endif
++
+     mutt_str_replace (&CurrentFolder, folder);
+     mutt_str_replace (&LastFolder, folder);
+ 
+@@ -1206,6 +1231,9 @@
+     if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
+        || !explicit_folder)
+     {
++#ifdef USE_SIDEBAR
++      sb_set_open_buffy (folder);
++#endif
+       mutt_index_menu ();
+       if (Context)
+ 	FREE (&Context);
+diff -urN mutt-1.6.1/Makefile.am mutt-1.6.1-sidebar/Makefile.am
+--- mutt-1.6.1/Makefile.am	2016-05-02 03:02:12.392171305 +0100
++++ mutt-1.6.1-sidebar/Makefile.am	2016-05-02 03:02:15.005212879 +0100
+@@ -77,6 +77,12 @@
+ 
+ EXTRA_SCRIPTS = smime_keys
+ 
++if BUILD_SIDEBAR
++mutt_SOURCES += sidebar.c sidebar.h
++endif
++
++EXTRA_DIST += OPS.SIDEBAR
++
+ mutt_dotlock_SOURCES = mutt_dotlock.c
+ mutt_dotlock_LDADD = $(LIBOBJS)
+ mutt_dotlock_DEPENDENCIES = $(LIBOBJS)
+@@ -129,10 +135,10 @@
+ keymap_defs.h: $(OPS) $(srcdir)/gen_defs
+ 	$(srcdir)/gen_defs $(OPS) > keymap_defs.h
+ 
+-keymap_alldefs.h: $(srcdir)/OPS $(srcdir)/OPS.PGP $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME $(srcdir)/gen_defs
++keymap_alldefs.h: $(srcdir)/OPS $(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.PGP $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME $(srcdir)/gen_defs
+ 	rm -f $@
+ 	$(srcdir)/gen_defs $(srcdir)/OPS $(srcdir)/OPS.PGP \
+-		$(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME \
++		$(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME \
+ 			> keymap_alldefs.h
+ 
+ reldate.h: $(srcdir)/ChangeLog
+diff -urN mutt-1.6.1/mbox.c mutt-1.6.1-sidebar/mbox.c
+--- mutt-1.6.1/mbox.c	2016-05-02 03:02:12.408171560 +0100
++++ mutt-1.6.1-sidebar/mbox.c	2016-05-02 03:02:14.948211972 +0100
+@@ -100,6 +100,9 @@
+     mutt_perror (ctx->path);
+     return (-1);
+   }
++#ifdef USE_SIDEBAR
++  ctx->atime = sb.st_atime;
++#endif
+   ctx->mtime = sb.st_mtime;
+   ctx->size = sb.st_size;
+ 
+@@ -251,6 +254,9 @@
+ 
+   ctx->size = sb.st_size;
+   ctx->mtime = sb.st_mtime;
++#ifdef USE_SIDEBAR
++  ctx->atime = sb.st_atime;
++#endif
+ 
+ #ifdef NFS_ATTRIBUTE_HACK
+   if (sb.st_mtime > sb.st_atime)
+diff -urN mutt-1.6.1/menu.c mutt-1.6.1-sidebar/menu.c
+--- mutt-1.6.1/menu.c	2016-05-02 03:02:12.408171560 +0100
++++ mutt-1.6.1-sidebar/menu.c	2016-05-02 03:02:15.019213102 +0100
+@@ -24,6 +24,9 @@
+ #include "mutt_curses.h"
+ #include "mutt_menu.h"
+ #include "mbyte.h"
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
+ 
+ char* SearchBuffers[MENU_MAX];
+ 
+@@ -184,7 +187,7 @@
+ {
+   char *scratch = safe_strdup (s);
+   int shift = option (OPTARROWCURSOR) ? 3 : 0;
+-  int cols = COLS - shift;
++  int cols = COLS - shift - SidebarWidth;
+ 
+   mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', scratch, mutt_strlen (scratch), 1);
+   s[n - 1] = 0;
+@@ -237,6 +240,9 @@
+   int do_color;
+   int attr;
+ 
++#ifdef USE_SIDEBAR
++  sb_draw();
++#endif
+   for (i = menu->top; i < menu->top + menu->pagelen; i++)
+   {
+     if (i < menu->max)
+@@ -247,7 +253,7 @@
+       menu_pad_string (buf, sizeof (buf));
+ 
+       ATTRSET(attr);
+-      move(i - menu->top + menu->offset, 0);
++      move(i - menu->top + menu->offset, SidebarWidth);
+       do_color = 1;
+ 
+       if (i == menu->current)
+@@ -270,7 +276,11 @@
+     else
+     {
+       NORMAL_COLOR;
++#ifdef USE_SIDEBAR
++      CLEARLINE_WIN(i - menu->top + menu->offset);
++#else
+       CLEARLINE(i - menu->top + menu->offset);
++#endif
+     }
+   }
+   NORMAL_COLOR;
+@@ -287,7 +297,7 @@
+     return;
+   }
+   
+-  move (menu->oldcurrent + menu->offset - menu->top, 0);
++  move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth);
+   ATTRSET(menu->color (menu->oldcurrent));
+ 
+   if (option (OPTARROWCURSOR))
+@@ -299,13 +309,13 @@
+     {
+       menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
+       menu_pad_string (buf, sizeof (buf));
+-      move (menu->oldcurrent + menu->offset - menu->top, 3);
++      move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth + 3);
+       print_enriched_string (menu->color(menu->oldcurrent), (unsigned char *) buf, 1);
+     }
+ 
+     /* now draw it in the new location */
+     SETCOLOR(MT_COLOR_INDICATOR);
+-    mvaddstr(menu->current + menu->offset - menu->top, 0, "->");
++    mvaddstr(menu->current + menu->offset - menu->top, SidebarWidth, "->");
+   }
+   else
+   {
+@@ -318,7 +328,7 @@
+     menu_make_entry (buf, sizeof (buf), menu, menu->current);
+     menu_pad_string (buf, sizeof (buf));
+     SETCOLOR(MT_COLOR_INDICATOR);
+-    move(menu->current - menu->top + menu->offset, 0);
++    move(menu->current - menu->top + menu->offset, SidebarWidth);
+     print_enriched_string (menu->color(menu->current), (unsigned char *) buf, 0);
+   }
+   menu->redraw &= REDRAW_STATUS;
+@@ -330,7 +340,7 @@
+   char buf[LONG_STRING];
+   int attr = menu->color (menu->current);
+   
+-  move (menu->current + menu->offset - menu->top, 0);
++  move (menu->current + menu->offset - menu->top, SidebarWidth);
+   menu_make_entry (buf, sizeof (buf), menu, menu->current);
+   menu_pad_string (buf, sizeof (buf));
+ 
+@@ -873,7 +883,7 @@
+     
+     
+     if (option (OPTARROWCURSOR))
+-      move (menu->current - menu->top + menu->offset, 2);
++      move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
+     else if (option (OPTBRAILLEFRIENDLY))
+       move (menu->current - menu->top + menu->offset, 0);
+     else
+diff -urN mutt-1.6.1/mh.c mutt-1.6.1-sidebar/mh.c
+--- mutt-1.6.1/mh.c	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-sidebar/mh.c	2016-05-02 03:02:15.019213102 +0100
+@@ -295,6 +295,49 @@
+   mhs_free_sequences (&mhs);
+ }
+ 
++#ifdef USE_SIDEBAR
++/**
++ * mh_buffy_update - Update messages counts for an mh mailbox
++ * @mailbox: BUFFY representing a maildir mailbox
++ *
++ * Read through an mh mailbox and count messages.  Save the number of new,
++ * flagged messages and a timestamp for now.
++ */
++void
++mh_buffy_update (BUFFY *mailbox)
++{
++	if (!mailbox)
++		return;
++
++	if (!option (OPTSIDEBAR))
++		return;
++
++	struct mh_sequences mhs;
++	memset (&mhs, 0, sizeof (mhs));
++
++	if (mh_read_sequences (&mhs, mailbox->path) < 0)
++		return;
++
++	mailbox->msg_count   = 0;
++	mailbox->msg_unread  = 0;
++	mailbox->msg_flagged = 0;
++
++	int i;
++	for (i = 0; i <= mhs.max; i++) {
++		mailbox->msg_count++;
++	}
++	if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN) {
++		mailbox->msg_unread++;
++	}
++	if (mhs_check (&mhs, i) & MH_SEQ_FLAGGED) {
++		mailbox->msg_flagged++;
++	}
++	mhs_free_sequences (&mhs);
++	mailbox->sb_last_checked = time (NULL);
++}
++
++#endif
++
+ static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt)
+ {
+   int fd;
+diff -urN mutt-1.6.1/mutt_curses.h mutt-1.6.1-sidebar/mutt_curses.h
+--- mutt-1.6.1/mutt_curses.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-sidebar/mutt_curses.h	2016-05-02 03:02:15.019213102 +0100
+@@ -64,6 +64,9 @@
+ #undef lines
+ #endif /* lines */
+ 
++#ifdef USE_SIDEBAR
++#define CLEARLINE_WIN(x) move (x,SidebarWidth), clrtoeol()
++#endif
+ #define CLEARLINE(x) move(x,0), clrtoeol()
+ #define CENTERLINE(x,y) move(y, (COLS-strlen(x))/2), addstr(x)
+ #define BEEP() do { if (option (OPTBEEP)) beep(); } while (0)
+@@ -124,6 +127,14 @@
+   MT_COLOR_UNDERLINE,
+   MT_COLOR_INDEX,
+   MT_COLOR_PROMPT,
++#ifdef USE_SIDEBAR
++  MT_COLOR_DIVIDER,
++  MT_COLOR_FLAGGED,
++  MT_COLOR_HIGHLIGHT,
++  MT_COLOR_NEW,
++  MT_COLOR_SB_INDICATOR,
++  MT_COLOR_SB_SPOOLFILE,
++#endif
+   MT_COLOR_MAX
+ };
+ 
+diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-sidebar/mutt.h
+--- mutt-1.6.1/mutt.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-sidebar/mutt.h	2016-05-02 03:02:15.019213102 +0100
+@@ -428,6 +428,13 @@
+   OPTSAVEEMPTY,
+   OPTSAVENAME,
+   OPTSCORE,
++#ifdef USE_SIDEBAR
++  OPTSIDEBAR,
++  OPTSIDEBARFOLDERINDENT,
++  OPTSIDEBARNEWMAILONLY,
++  OPTSIDEBARNEXTNEWWRAP,
++  OPTSIDEBARSHORTPATH,
++#endif
+   OPTSIGDASHES,
+   OPTSIGONTOP,
+   OPTSORTRE,
+@@ -872,6 +879,9 @@
+ {
+   char *path;
+   FILE *fp;
++#ifdef USE_SIDEBAR
++  time_t atime;
++#endif
+   time_t mtime;
+   off_t size;
+   off_t vsize;
+@@ -906,6 +916,9 @@
+   unsigned int quiet : 1;	/* inhibit status messages? */
+   unsigned int collapsed : 1;   /* are all threads collapsed? */
+   unsigned int closing : 1;	/* mailbox is being closed */
++#ifdef USE_SIDEBAR
++  unsigned int peekonly : 1;	/* just taking a glance, revert atime */
++#endif
+ 
+   /* driver hooks */
+   void *data;			/* driver specific data */
+diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-sidebar/muttlib.c
+--- mutt-1.6.1/muttlib.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-sidebar/muttlib.c	2016-05-02 03:02:15.020213118 +0100
+@@ -1282,7 +1282,7 @@
+ 	  pl = pw = 1;
+ 
+ 	/* see if there's room to add content, else ignore */
+-	if ((col < COLS && wlen < destlen) || soft)
++	if ((col < (COLS - SidebarWidth) && (wlen < destlen)) || soft)
+ 	{
+ 	  int pad;
+ 
+@@ -1293,7 +1293,7 @@
+ 
+ 	  /* try to consume as many columns as we can, if we don't have
+ 	   * memory for that, use as much memory as possible */
+-	  pad = (COLS - col - wid) / pw;
++	  pad = (COLS - SidebarWidth - col - wid) / pw;
+ 	  if (pad > 0 && wlen + (pad * pl) + len > destlen)
+ 	    pad = ((signed)(destlen - wlen - len)) / pl;
+ 	  if (pad > 0)
+@@ -1312,13 +1312,13 @@
+ 	    /* \0-terminate dest for length computation in mutt_wstr_trunc() */
+ 	    *wptr = 0;
+ 	    /* make sure right part is at most as wide as display */
+-	    len = mutt_wstr_trunc (buf, destlen, COLS-offset, &wid);
++	    len = mutt_wstr_trunc (buf, destlen, COLS - offset - SidebarWidth, &wid);
+ 	    /* truncate left so that right part fits completely in */
+ 	    wlen = mutt_wstr_trunc (dest, destlen - len, col + pad*pw -offset, &col);
+ 	    wptr = dest + wlen;
+ 	  }
+ 	  if (len + wlen > destlen)
+-	    len = mutt_wstr_trunc (buf, destlen - wlen, COLS - col, NULL);
++	    len = mutt_wstr_trunc (buf, destlen - wlen, COLS - SidebarWidth - col, NULL);
+ 	  memcpy (wptr, buf, len);
+ 	  wptr += len;
+ 	  wlen += len;
+diff -urN mutt-1.6.1/mutt_menu.h mutt-1.6.1-sidebar/mutt_menu.h
+--- mutt-1.6.1/mutt_menu.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-sidebar/mutt_menu.h	2016-05-02 03:02:15.019213102 +0100
+@@ -34,6 +34,9 @@
+ #define REDRAW_FULL		(1<<5)
+ #define REDRAW_BODY		(1<<6)
+ #define REDRAW_SIGWINCH		(1<<7)
++#ifdef USE_SIDEBAR
++#define REDRAW_SIDEBAR		(1<<8)
++#endif
+ 
+ #define M_MODEFMT "-- Mutt: %s"
+ 
+diff -urN mutt-1.6.1/mx.c mutt-1.6.1-sidebar/mx.c
+--- mutt-1.6.1/mx.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-sidebar/mx.c	2016-05-02 03:02:15.020213118 +0100
+@@ -29,6 +29,9 @@
+ #include "copy.h"
+ #include "keymap.h"
+ #include "url.h"
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
+ 
+ #ifdef USE_IMAP
+ #include "imap.h"
+@@ -580,6 +583,7 @@
+  *		M_APPEND	open mailbox for appending
+  *		M_READONLY	open mailbox in read-only mode
+  *		M_QUIET		only print error messages
++ *		M_PEEK		revert atime where applicable
+  *	ctx	if non-null, context struct to use
+  */
+ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
+@@ -602,6 +606,10 @@
+     ctx->quiet = 1;
+   if (flags & M_READONLY)
+     ctx->readonly = 1;
++#ifdef USE_SIDEBAR
++  if (flags & M_PEEK)
++    ctx->peekonly = 1;
++#endif
+ 
+   if (flags & (M_APPEND|M_NEWFOLDER))
+   {
+@@ -705,8 +713,21 @@
+   if(!ctx) 
+     return;
+ 
++#ifdef USE_SIDEBAR
++  /* fix up the times so buffy won't get confused */
++  struct utimbuf ut;
++  if (ctx->peekonly && ctx->path && (ctx->mtime > ctx->atime)) {
++    ut.actime  = ctx->atime;
++    ut.modtime = ctx->mtime;
++    utime (ctx->path, &ut);
++  }
++#endif
++
+   /* never announce that a mailbox we've just left has new mail. #3290
+    * XXX: really belongs in mx_close_mailbox, but this is a nice hook point */
++#ifdef USE_SIDEBAR
++  if (!ctx->peekonly)
++#endif
+   mutt_buffy_setnotified(ctx->path);
+ 
+   if (ctx->mx_close)
+@@ -719,6 +740,10 @@
+   mutt_clear_threads (ctx);
+   for (i = 0; i < ctx->msgcount; i++)
+     mutt_free_header (&ctx->hdrs[i]);
++#ifdef USE_SIDEBAR
++  ctx->msgcount -= ctx->deleted;
++  sb_set_buffystats (ctx);
++#endif
+   FREE (&ctx->hdrs);
+   FREE (&ctx->v2r);
+   FREE (&ctx->path);
+@@ -812,6 +837,12 @@
+     if (!ctx->hdrs[i]->deleted && ctx->hdrs[i]->read 
+         && !(ctx->hdrs[i]->flagged && option (OPTKEEPFLAGGED)))
+       read_msgs++;
++#ifdef USE_SIDEBAR
++    if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->read)
++      ctx->unread--;
++    if (ctx->hdrs[i]->deleted && ctx->hdrs[i]->flagged)
++      ctx->flagged--;
++#endif
+   }
+ 
+   if (read_msgs && quadoption (OPT_MOVE) != M_NO)
+diff -urN mutt-1.6.1/mx.h mutt-1.6.1-sidebar/mx.h
+--- mutt-1.6.1/mx.h	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-sidebar/mx.h	2016-05-02 03:02:15.020213118 +0100
+@@ -26,6 +26,7 @@
+ #define _MX_H
+ 
+ #include "mailbox.h"
++#include "buffy.h"
+ 
+ /* supported mailbox formats */
+ enum
+@@ -57,6 +58,9 @@
+ int mh_read_dir (CONTEXT *, const char *);
+ int mh_sync_mailbox (CONTEXT *, int *);
+ int mh_check_mailbox (CONTEXT *, int *);
++#ifdef USE_SIDEBAR
++void mh_buffy_update (BUFFY *mailbox);
++#endif
+ int mh_check_empty (const char *);
+ 
+ int maildir_read_dir (CONTEXT *);
+diff -urN mutt-1.6.1/OPS.SIDEBAR mutt-1.6.1-sidebar/OPS.SIDEBAR
+--- mutt-1.6.1/OPS.SIDEBAR	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-sidebar/OPS.SIDEBAR	2016-05-02 03:02:15.005212879 +0100
+@@ -0,0 +1,8 @@
++OP_SIDEBAR_NEXT "Move the highlight to next mailbox"
++OP_SIDEBAR_NEXT_NEW "Move the highlight to next mailbox with new mail"
++OP_SIDEBAR_OPEN "Open highlighted mailbox"
++OP_SIDEBAR_PAGE_DOWN "Scroll the Sidebar down 1 page"
++OP_SIDEBAR_PAGE_UP "Scroll the Sidebar up 1 page"
++OP_SIDEBAR_PREV "Move the highlight to previous mailbox"
++OP_SIDEBAR_PREV_NEW "Move the highlight to previous mailbox with new mail"
++OP_SIDEBAR_TOGGLE_VISIBLE "Make the Sidebar (in)visible"
+diff -urN mutt-1.6.1/pager.c mutt-1.6.1-sidebar/pager.c
+--- mutt-1.6.1/pager.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-sidebar/pager.c	2016-05-02 03:02:15.021213134 +0100
+@@ -29,6 +29,9 @@
+ #include "pager.h"
+ #include "attach.h"
+ #include "mbyte.h"
++#ifdef USE_SIDEBAR
++#include "sidebar.h"
++#endif
+ 
+ #include "mutt_crypt.h"
+ 
+@@ -1096,6 +1099,9 @@
+   wchar_t wc;
+   mbstate_t mbstate;
+   int wrap_cols = mutt_term_width ((flags & M_PAGER_NOWRAP) ? 0 : Wrap);
++#ifdef USE_SIDEBAR
++  wrap_cols -= SidebarWidth;
++#endif
+ 
+   if (check_attachment_marker ((char *)buf) == 0)
+     wrap_cols = COLS;
+@@ -1491,7 +1497,7 @@
+    * a newline (grr!).
+    */
+ #ifndef USE_SLANG_CURSES
+-    if (col < COLS)
++    if (col < (COLS - SidebarWidth))
+ #endif
+       addch ('\n');
+ 
+@@ -1573,6 +1579,7 @@
+ 
+   int bodyoffset = 1;			/* offset of first line of real text */
+   int statusoffset = 0; 		/* offset for the status bar */
++  int statuswidth = COLS;
+   int helpoffset = LINES - 2;		/* offset for the help bar. */
+   int bodylen = LINES - 2 - bodyoffset; /* length of displayable area */
+ 
+@@ -1747,7 +1754,7 @@
+     if ((redraw & REDRAW_BODY) || topline != oldtopline)
+     {
+       do {
+-	move (bodyoffset, 0);
++	move (bodyoffset, SidebarWidth);
+ 	curline = oldtopline = topline;
+ 	lines = 0;
+ 	force_redraw = 0;
+@@ -1760,6 +1767,9 @@
+ 			    &QuoteList, &q_level, &force_redraw, &SearchRE) > 0)
+ 	    lines++;
+ 	  curline++;
++#ifdef USE_SIDEBAR
++	  move (lines + bodyoffset, SidebarWidth);
++#endif
+ 	}
+ 	last_offset = lineInfo[curline].offset;
+       } while (force_redraw);
+@@ -1772,6 +1782,9 @@
+ 	  addch ('~');
+ 	addch ('\n');
+ 	lines++;
++#ifdef USE_SIDEBAR
++	move (lines + bodyoffset, SidebarWidth);
++#endif
+       }
+       NORMAL_COLOR;
+ 
+@@ -1789,29 +1802,49 @@
+       hfi.ctx = Context;
+       hfi.pager_progress = pager_progress_str;
+ 
++#ifdef USE_SIDEBAR
++      statuswidth = COLS;
++      if (option (OPTSTATUSONTOP) && (PagerIndexLines > 0))
++        statuswidth -= SidebarWidth;
++#endif
++
+       if (last_pos < sb.st_size - 1)
+ 	snprintf(pager_progress_str, sizeof(pager_progress_str), OFF_T_FMT "%%", (100 * last_offset / sb.st_size));
+       else
+ 	strfcpy(pager_progress_str, (topline == 0) ? "all" : "end", sizeof(pager_progress_str));
+ 
+       /* print out the pager status bar */
+-      move (statusoffset, 0);
++      move (statusoffset, SidebarWidth);
+       SETCOLOR (MT_COLOR_STATUS);
++#ifdef USE_SIDEBAR
++      short sw = SidebarWidth;
++      if (option (OPTSTATUSONTOP) && PagerIndexLines > 0) {
++        CLEARLINE_WIN (statusoffset);
++      } else {
++        CLEARLINE (statusoffset);
++        /* Temporarily lie about the sidebar width */
++        SidebarWidth = 0;
++      }
++#endif
+ 
+       if (IsHeader (extra) || IsMsgAttach (extra))
+       {
+-	size_t l1 = COLS * MB_LEN_MAX;
++	size_t l1 = statuswidth * MB_LEN_MAX;
+ 	size_t l2 = sizeof (buffer);
+ 	hfi.hdr = (IsHeader (extra)) ? extra->hdr : extra->bdy->hdr;
+ 	mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
+-	mutt_paddstr (COLS, buffer);
++	mutt_paddstr (statuswidth, buffer);
+       }
+       else
+       {
+ 	char bn[STRING];
+ 	snprintf (bn, sizeof (bn), "%s (%s)", banner, pager_progress_str);
+-	mutt_paddstr (COLS, bn);
++	mutt_paddstr (statuswidth, bn);
+       }
++#ifdef USE_SIDEBAR
++      if (!option (OPTSTATUSONTOP) || PagerIndexLines == 0)
++        SidebarWidth = sw; /* Restore the sidebar width */
++#endif
+       NORMAL_COLOR;
+       if (option(OPTTSENABLED) && TSSupported)
+       {
+@@ -1827,16 +1860,26 @@
+       /* redraw the pager_index indicator, because the
+        * flags for this message might have changed. */
+       menu_redraw_current (index);
++#ifdef USE_SIDEBAR
++      sb_draw();
++#endif
+ 
+       /* print out the index status bar */
+       menu_status_line (buffer, sizeof (buffer), index, NONULL(Status));
+  
+-      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)), 0);
++      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)),
++          (option(OPTSTATUSONTOP) ? 0: SidebarWidth));
+       SETCOLOR (MT_COLOR_STATUS);
+-      mutt_paddstr (COLS, buffer);
++      mutt_paddstr (COLS - (option(OPTSTATUSONTOP) ? 0 : SidebarWidth), buffer);
+       NORMAL_COLOR;
+     }
+ 
++#ifdef USE_SIDEBAR
++    /* if we're not using the index, update every time */
++    if (index == 0)
++      sb_draw();
++#endif
++
+     redraw = 0;
+ 
+     if (option(OPTBRAILLEFRIENDLY)) {
+@@ -2498,8 +2541,12 @@
+ 	  ch = 0;
+ 	}
+ 
+-	if (option (OPTFORCEREDRAWPAGER))
++	if (option (OPTFORCEREDRAWPAGER)) {
+ 	  redraw = REDRAW_FULL;
++#ifdef USE_SIDEBAR
++	  sb_draw();
++#endif
++	}
+ 	unset_option (OPTFORCEREDRAWINDEX);
+ 	unset_option (OPTFORCEREDRAWPAGER);
+ 	break;
+@@ -2777,6 +2824,22 @@
+ 	mutt_what_key ();
+ 	break;
+ 
++#ifdef USE_SIDEBAR
++      case OP_SIDEBAR_NEXT:
++      case OP_SIDEBAR_NEXT_NEW:
++      case OP_SIDEBAR_PAGE_DOWN:
++      case OP_SIDEBAR_PAGE_UP:
++      case OP_SIDEBAR_PREV:
++      case OP_SIDEBAR_PREV_NEW:
++	sb_change_mailbox (ch);
++	break;
++
++      case OP_SIDEBAR_TOGGLE_VISIBLE:
++	toggle_option (OPTSIDEBAR);
++	redraw = REDRAW_FULL;
++	break;
++#endif
++
+       default:
+ 	ch = -1;
+ 	break;
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-sidebar/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-sidebar/PATCHES	2016-05-02 03:02:15.008212927 +0100
+@@ -0,0 +1 @@
++patch-sidebar-neo-20160502
+diff -urN mutt-1.6.1/README.sidebar mutt-1.6.1-sidebar/README.sidebar
+--- mutt-1.6.1/README.sidebar	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-sidebar/README.sidebar	2016-05-02 03:02:15.008212927 +0100
+@@ -0,0 +1,145 @@
++Sidebar Patch
++=============
++
++    Overview of mailboxes
++
++    NOTES:
++
++    If you haven't used the sidebar before, you might like to read the
++    Sidebar Introduction:
++
++        http://www.neomutt.org/sidebar-intro.html
++
++    If you have used an older version of the Sidebar, please note that some
++    of the configuration has changed.
++
++        http://www.neomutt.org/sidebar-intro.html#intro-sidebar-config-changes
++
++Patch
++-----
++
++    To check if Mutt supports "Sidebar", look for "+USE_SIDEBAR" in the mutt
++    version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    The Sidebar shows a list of all your mailboxes. The list can be turned on
++    and off, it can be themed and the list style can be configured.
++
++    This part of the manual is a reference guide. If you want a simple
++    introduction with examples see the Sidebar Howto. If you just want to get
++    started, you could use the sample Sidebar muttrc.
++
++    This version of Sidebar is based on Terry Chan's [2015-11-11
++    release](http://www.lunar-linux.org/mutt-sidebar/). It contains many new
++    features, lots of bugfixes.
++
++Variables
++---------
++
++    Sidebar Variables
++
++    | Name                    | Type    | Default                     |
++    |-------------------------|---------|-----------------------------|
++    | 'sidebar_delim_chars'   | string  | '/.'                        |
++    | 'sidebar_divider_char'  | string  | '|'                         |
++    | 'sidebar_folder_indent' | boolean | 'no'                        |
++    | 'sidebar_format'        | string  | '%B%?F? [%F]?%* %?N?%N/?%S' |
++    | 'sidebar_indent_string' | string  | '  ' (two spaces)           |
++    | 'sidebar_new_mail_only' | boolean | 'no'                        |
++    | 'sidebar_next_new_wrap' | boolean | 'no'                        |
++    | 'sidebar_refresh_time'  | number  | '60'                        |
++    | 'sidebar_short_path'    | boolean | 'no'                        |
++    | 'sidebar_sort_method'   | enum    | 'SORT_ORDER'                |
++    | 'sidebar_visible'       | boolean | 'no'                        |
++    | 'sidebar_whitelist'     | list    | (empty)                     |
++    | 'sidebar_width'         | number  | '20'                        |
++
++Functions
++---------
++
++    Sidebar Functions
++
++    Sidebar adds the following functions to Mutt. By default, none of them are
++    bound to keys.
++
++    | Menus       | Function                   | Description                                          |
++    |-------------|----------------------------|------------------------------------------------------|
++    | index,pager | '<sidebar-next>'           | Move the highlight to next mailbox                   |
++    | index,pager | '<sidebar-next-new>'       | Move the highlight to next mailbox with new mail     |
++    | index,pager | '<sidebar-open>'           | Open highlighted mailbox                             |
++    | index,pager | '<sidebar-page-down>'      | Scroll the Sidebar down 1 page                       |
++    | index,pager | '<sidebar-page-up>'        | Scroll the Sidebar up 1 page                         |
++    | index,pager | '<sidebar-prev>'           | Move the highlight to previous mailbox               |
++    | index,pager | '<sidebar-prev-new>'       | Move the highlight to previous mailbox with new mail |
++    | index,pager | '<sidebar-toggle-visible>' | Make the Sidebar (in)visible                         |
++
++Commands
++--------
++
++        sidebar_whitelist mailbox [ mailbox... ]
++
++Colors
++------
++
++    Sidebar Colors
++
++    | Name                | Default Color    | Description                                                      |
++    |---------------------|------------------|------------------------------------------------------------------|
++    | 'sidebar_divider'   | default          | The dividing line between the Sidebar and the Index/Pager panels |
++    | 'sidebar_flagged'   | default          | Mailboxes containing flagged mail                                |
++    | 'sidebar_highlight' | underline        | Cursor to select a mailbox                                       |
++    | 'sidebar_indicator' | mutt 'indicator' | The mailbox open in the Index panel                              |
++    | 'sidebar_new'       | default          | Mailboxes containing new mail                                    |
++    | 'sidebar_spoolfile' | default          | Mailbox that receives incoming mail                              |
++
++    If the sidebar_indicator color isn't set, then the default Mutt indicator
++    color will be used (the color used in the index panel).
++
++Sort
++----
++
++    Sidebar Sort
++
++    | Sort       | Description                |
++    |------------|----------------------------|
++    | 'alpha'    | Alphabetically by path     |
++    | 'count'    | Total number of messages   |
++    | 'flagged'  | Number of flagged messages |
++    | 'name'     | Alphabetically by path     |
++    | 'new'      | Number of new messages     |
++    | 'path'     | Alphabetically by path     |
++    | 'unsorted' | Do not resort the paths    |
++
++See Also
++--------
++
++    * Regular Expressions
++    * Patterns
++    * Color command
++    * notmuch patch
++
++Known Bugs
++----------
++
++    Unsorted isn't
++
++Credits
++-------
++
++    * Justin Hibbits <jrh29 at po.cwru.edu>
++    * Thomer M. Gil <mutt at thomer.com>
++    * David Sterba <dsterba at suse.cz>
++    * Evgeni Golov <evgeni at debian.org>
++    * Fabian Groffen <grobian at gentoo.org>
++    * Jason DeTiberus <jdetiber at redhat.com>
++    * Stefan Assmann <sassmann at kpanic.de>
++    * Steve Kemp <steve at steve.org.uk>
++    * Terry Chan <tchan at lunar-linux.org>
++    * Tyler Earnest <tylere at rne.st>
++    * Richard Russon <rich at flatcap.org>
++
+diff -urN mutt-1.6.1/sidebar.c mutt-1.6.1-sidebar/sidebar.c
+--- mutt-1.6.1/sidebar.c	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-sidebar/sidebar.c	2016-05-02 03:02:15.023213165 +0100
+@@ -0,0 +1,1069 @@
++/* Copyright (C) 2004 Justin Hibbits <jrh29 at po.cwru.edu>
++ * Copyright (C) 2004 Thomer M. Gil <mutt at thomer.com>
++ * Copyright (C) 2015-2016 Richard Russon <rich at flatcap.org>
++ *
++ *     This program is free software; you can redistribute it and/or modify
++ *     it under the terms of the GNU General Public License as published by
++ *     the Free Software Foundation; either version 2 of the License, or
++ *     (at your option) any later version.
++ *
++ *     This program is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public License
++ *     along with this program; if not, write to the Free Software
++ *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
++ */
++
++#if HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include "mutt.h"
++#include "buffy.h"
++#include "keymap.h"
++#include "mutt_curses.h"
++#include "mutt_menu.h"
++#include "sort.h"
++
++/* Previous values for some sidebar config */
++static short  OldVisible;	/* sidebar_visible */
++static short  OldWidth;		/* sidebar_width */
++static short  PreviousSort;	/* sidebar_sort_method */
++static time_t LastRefresh;	/* Time of last refresh */
++
++/* Keep track of various BUFFYs */
++static BUFFY *TopBuffy;		/* First mailbox visible in sidebar */
++static BUFFY *OpnBuffy;		/* Current (open) mailbox */
++static BUFFY *HilBuffy;		/* Highlighted mailbox */
++static BUFFY *BotBuffy;		/* Last mailbox visible in sidebar */
++static BUFFY *Outgoing;		/* Last mailbox in the linked list */
++
++/**
++ * struct sidebar_entry - Info about folders in the sidebar
++ *
++ * Used in the mutt_FormatString callback
++ */
++struct sidebar_entry {
++	char         box[SHORT_STRING];
++	BUFFY       *buffy;
++};
++
++
++/**
++ * find_next_new - Find the next folder that contains new mail
++ * @wrap: Wrap around to the beginning if the end is reached
++ *
++ * Search down the list of mail folders for one containing new mail.
++ *
++ * Returns:
++ *	BUFFY*: Success
++ *	NULL:   Failure
++ */
++static BUFFY *
++find_next_new (int wrap)
++{
++	BUFFY *b = HilBuffy;
++	if (!b)
++		return NULL;
++
++	do {
++		b = b->next;
++		if (!b && wrap) {
++			b = Incoming;
++		}
++		if (!b || (b == HilBuffy)) {
++			break;
++		}
++		if (b->msg_unread > 0) {
++			return b;
++		}
++	} while (b);
++
++	return NULL;
++}
++
++/**
++ * find_prev_new - Find the previous folder that contains new mail
++ * @wrap: Wrap around to the beginning if the end is reached
++ *
++ * Search up the list of mail folders for one containing new mail.
++ *
++ * Returns:
++ *	BUFFY*: Success
++ *	NULL:   Failure
++ */
++static BUFFY *
++find_prev_new (int wrap)
++{
++	BUFFY *b = HilBuffy;
++	if (!b)
++		return NULL;
++
++	do {
++		b = b->prev;
++		if (!b && wrap) {
++			b = Outgoing;
++		}
++		if (!b || (b == HilBuffy)) {
++			break;
++		}
++		if (b->msg_unread > 0) {
++			return b;
++		}
++	} while (b);
++
++	return NULL;
++}
++
++/**
++ * cb_format_str - Create the string to show in the sidebar
++ * @dest:        Buffer in which to save string
++ * @destlen:     Buffer length
++ * @col:         Starting column, UNUSED
++ * @op:          printf-like operator, e.g. 'B'
++ * @src:         printf-like format string
++ * @prefix:      Field formatting string, UNUSED
++ * @ifstring:    If condition is met, display this string
++ * @elsestring:  Otherwise, display this string
++ * @data:        Pointer to our sidebar_entry
++ * @flags:       Format flags, e.g. M_FORMAT_OPTIONAL
++ *
++ * cb_format_str is a callback function for mutt_FormatString.  It understands
++ * five operators. '%B' : Mailbox name, '%F' : Number of flagged messages,
++ * '%N' : Number of new messages, '%S' : Size (total number of messages),
++ * '%!' : Icon denoting number of flagged messages.
++ *
++ * Returns: src (unchanged)
++ */
++static const char *
++cb_format_str (char *dest, size_t destlen, size_t col, char op, const char *src,
++	const char *prefix, const char *ifstring, const char *elsestring,
++	unsigned long data, format_flag flags)
++{
++	struct sidebar_entry *sbe = (struct sidebar_entry *) data;
++	unsigned int optional;
++	char fmt[SHORT_STRING], buf[SHORT_STRING];
++
++	if (!sbe || !dest)
++		return src;
++
++	dest[0] = 0;	/* Just in case there's nothing to do */
++
++	BUFFY *b = sbe->buffy;
++	if (!b)
++		return src;
++
++	int c = Context && (mutt_strcmp (Context->path, b->path) == 0);
++
++	optional = flags & M_FORMAT_OPTIONAL;
++
++	switch (op) {
++		case 'B':
++			mutt_format_s (dest, destlen, prefix, sbe->box);
++			break;
++
++		case 'd':
++			if (!optional) {
++				snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
++				snprintf (dest, destlen, fmt, c ? Context->deleted : 0);
++			} else if ((c && Context->deleted == 0) || !c) {
++				optional = 0;
++			}
++			break;
++
++		case 'F':
++			if (!optional) {
++				snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
++				snprintf (dest, destlen, fmt, b->msg_flagged);
++			} else if (b->msg_flagged == 0) {
++				optional = 0;
++			}
++			break;
++
++		case 'L':
++			if (!optional) {
++				snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
++				snprintf (dest, destlen, fmt, c ? Context->vcount : b->msg_count);
++			} else if ((c && Context->vcount == b->msg_count) || !c) {
++				optional = 0;
++			}
++			break;
++
++		case 'N':
++			if (!optional) {
++				snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
++				snprintf (dest, destlen, fmt, b->msg_unread);
++			} else if (b->msg_unread == 0) {
++				optional = 0;
++			}
++			break;
++
++		case 'S':
++			if (!optional) {
++				snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
++				snprintf (dest, destlen, fmt, b->msg_count);
++			} else if (b->msg_count == 0) {
++				optional = 0;
++			}
++			break;
++
++		case 't':
++			if (!optional) {
++				snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
++				snprintf (dest, destlen, fmt, c ? Context->tagged : 0);
++			} else if ((c && Context->tagged == 0) || !c) {
++				optional = 0;
++			}
++			break;
++
++		case '!':
++			if (b->msg_flagged == 0) {
++				mutt_format_s (dest, destlen, prefix, "");
++			} else if (b->msg_flagged == 1) {
++				mutt_format_s (dest, destlen, prefix, "!");
++			} else if (b->msg_flagged == 2) {
++				mutt_format_s (dest, destlen, prefix, "!!");
++			} else {
++				snprintf (buf, sizeof (buf), "%d!", b->msg_flagged);
++				mutt_format_s (dest, destlen, prefix, buf);
++			}
++			break;
++	}
++
++	if (optional)
++		mutt_FormatString (dest, destlen, col, ifstring,   cb_format_str, (unsigned long) sbe, flags);
++	else if (flags & M_FORMAT_OPTIONAL)
++		mutt_FormatString (dest, destlen, col, elsestring, cb_format_str, (unsigned long) sbe, flags);
++
++	/* We return the format string, unchanged */
++	return src;
++}
++
++/**
++ * make_sidebar_entry - Turn mailbox data into a sidebar string
++ * @buf:     Buffer in which to save string
++ * @buflen:  Buffer length
++ * @width:   Desired width in screen cells
++ * @box:     Mailbox name
++ * @size:    Size (total number of messages)
++ * @new:     Number of new messages
++ * @flagged: Number of flagged messages
++ *
++ * Take all the relevant mailbox data and the desired screen width and then get
++ * mutt_FormatString to do the actual work. mutt_FormatString will callback to
++ * us using cb_format_str() for the sidebar specific formatting characters.
++ */
++static void
++make_sidebar_entry (char *buf, unsigned int buflen, int width, char *box,
++	BUFFY *b)
++{
++	struct sidebar_entry sbe;
++
++	if (!buf || !box || !b)
++		return;
++
++	sbe.buffy = b;
++	strncpy (sbe.box, box, sizeof (sbe.box) - 1);
++
++	int box_len = strlen (box);
++	sbe.box[box_len] = '\0';
++
++	/* Temporarily lie about the screen width */
++	int oc = COLS;
++	COLS = width + SidebarWidth;
++	mutt_FormatString (buf, buflen, 0, NONULL(SidebarFormat), cb_format_str, (unsigned long) &sbe, 0);
++	COLS = oc;
++
++	/* Force string to be exactly the right width */
++	int w = mutt_strwidth (buf);
++	int s = strlen (buf);
++	if (w < width) {
++		/* Pad with spaces */
++		memset (buf + s, ' ', width - w);
++		buf[s + width - w] = 0;
++	} else if (w > width) {
++		/* Truncate to fit */
++		int len = mutt_wstr_trunc (buf, buflen, width, NULL);
++		buf[len] = 0;
++	}
++}
++
++/**
++ * cb_qsort_buffy - qsort callback to sort BUFFYs
++ * @a: First  BUFFY to compare
++ * @b: Second BUFFY to compare
++ *
++ * Compare the paths of two BUFFYs taking the locale into account.
++ *
++ * Returns:
++ *	-1: a precedes b
++ *	 0: a and b are identical
++ *	 1: b precedes a
++ */
++static int
++cb_qsort_buffy (const void *a, const void *b)
++{
++	const BUFFY *b1 = *(const BUFFY **) a;
++	const BUFFY *b2 = *(const BUFFY **) b;
++
++	/* Special case -- move hidden BUFFYs to the end */
++	if (b1->is_hidden != b2->is_hidden) {
++		if (b1->is_hidden)
++			return 1;
++		else
++			return -1;
++	}
++
++	int result = 0;
++
++	switch ((SidebarSortMethod & SORT_MASK)) {
++		case SORT_COUNT:
++			result = (b2->msg_count - b1->msg_count);
++			break;
++		case SORT_COUNT_NEW:
++			result = (b2->msg_unread - b1->msg_unread);
++			break;
++		case SORT_FLAGGED:
++			result = (b2->msg_flagged - b1->msg_flagged);
++			break;
++		case SORT_PATH:
++			result = mutt_strcasecmp (b1->path, b2->path);
++			break;
++	}
++
++	if (SidebarSortMethod & SORT_REVERSE)
++		result = -result;
++
++	return result;
++}
++
++/**
++ * buffy_going - Prevent our pointers becoming invalid
++ * @b: BUFFY about to be deleted
++ *
++ * If we receive a delete-notification for a BUFFY, we need to change any
++ * pointers we have to reference a different BUFFY, or set them to NULL.
++ *
++ * We don't update the prev/next pointers, they'll be fixed on the next
++ * call to prepare_sidebar().
++ *
++ * Returns:
++ *	A valid alternative BUFFY, or NULL
++ */
++static BUFFY *
++buffy_going (const BUFFY *b)
++{
++	if (!b)
++		return NULL;
++
++	if (b->prev) {
++		b->prev->next = NULL;
++	}
++
++	if (b->next) {
++		b->next->prev = NULL;
++		return b->next;
++	}
++
++	return b->prev;
++}
++
++/**
++ * update_buffy_visibility - Should a BUFFY be displayed in the sidebar
++ * @arr:     array of BUFFYs
++ * @arr_len: number of BUFFYs in array
++ *
++ * For each BUFFY in the array, check whether we should display it.
++ * This is determined by several criteria.  If the BUFFY:
++ *	is the currently open mailbox
++ *	is the currently highlighted mailbox
++ *	has unread messages
++ *	has flagged messages
++ *	is whitelisted
++ */
++static void
++update_buffy_visibility (BUFFY **arr, int arr_len)
++{
++	if (!arr)
++		return;
++
++	short new_only = option (OPTSIDEBARNEWMAILONLY);
++
++	BUFFY *b;
++	int i;
++	for (i = 0; i < arr_len; i++) {
++		b = arr[i];
++
++		b->is_hidden = 0;
++
++		if (!new_only)
++			continue;
++
++		if ((b == OpnBuffy) || (b->msg_unread  > 0) ||
++		    (b == HilBuffy) || (b->msg_flagged > 0)) {
++			continue;
++		}
++
++		if (Context && (strcmp (b->path, Context->path) == 0)) {
++			/* Spool directory */
++			continue;
++		}
++
++		if (mutt_find_list (SidebarWhitelist, b->path)) {
++			/* Explicitly asked to be visible */
++			continue;
++		}
++
++		b->is_hidden = 1;
++	}
++}
++
++/**
++ * sort_buffy_array - Sort an array of BUFFY pointers
++ * @arr:     array of BUFFYs
++ * @arr_len: number of BUFFYs in array
++ *
++ * Sort an array of BUFFY pointers according to the current sort config
++ * option "sidebar_sort_method". This calls qsort to do the work which calls our
++ * callback function "cb_qsort_buffy".
++ *
++ * Once sorted, the prev/next links will be reconstructed.
++ */
++static void
++sort_buffy_array (BUFFY **arr, int arr_len)
++{
++	if (!arr)
++		return;
++
++	/* These are the only sort methods we understand */
++	short ssm = (SidebarSortMethod & SORT_MASK);
++	if ((ssm == SORT_COUNT)     ||
++	    (ssm == SORT_COUNT_NEW) ||
++	    (ssm == SORT_DESC)      ||
++	    (ssm == SORT_FLAGGED)   ||
++	    (ssm == SORT_PATH)) {
++		qsort (arr, arr_len, sizeof (*arr), cb_qsort_buffy);
++	}
++
++	int i;
++	for (i = 0; i < (arr_len - 1); i++) {
++		arr[i]->next = arr[i + 1];
++	}
++	arr[arr_len - 1]->next = NULL;
++
++	for (i = 1; i < arr_len; i++) {
++		arr[i]->prev = arr[i - 1];
++	}
++	arr[0]->prev = NULL;
++}
++
++/**
++ * prepare_sidebar - Prepare the list of BUFFYs for the sidebar display
++ * @page_size:  The number of lines on a page
++ *
++ * Before painting the sidebar, we count the BUFFYs, determine which are
++ * visible, sort them and set up our page pointers.
++ *
++ * This is a lot of work to do each refresh, but there are many things that
++ * can change outside of the sidebar that we don't hear about.
++ *
++ * Returns:
++ *	0:  No, don't draw the sidebar
++ *	1: Yes, draw the sidebar
++ */
++static int
++prepare_sidebar (int page_size)
++{
++	BUFFY *b = Incoming;
++	if (!b)
++		return 0;
++
++	int count = 0;
++	for (; b; b = b->next)
++		count++;
++
++	BUFFY **arr = safe_malloc (count * sizeof (*arr));
++	if (!arr)
++		return 0;
++
++	int i = 0;
++	for (b = Incoming; b; b = b->next, i++) {
++		arr[i] = b;
++	}
++
++	update_buffy_visibility (arr, count);
++	sort_buffy_array        (arr, count);
++
++	Incoming = arr[0];
++
++	int top_index =  0;
++	int opn_index = -1;
++	int hil_index = -1;
++	int bot_index = -1;
++
++	for (i = 0; i < count; i++) {
++		if (OpnBuffy == arr[i])
++			opn_index = i;
++		if (HilBuffy == arr[i])
++			hil_index = i;
++	}
++
++	if (!HilBuffy || (SidebarSortMethod != PreviousSort)) {
++		if (OpnBuffy) {
++			HilBuffy  = OpnBuffy;
++			hil_index = opn_index;
++		} else {
++			HilBuffy  = arr[0];
++			hil_index = 0;
++		}
++	}
++	if (TopBuffy) {
++		top_index = (hil_index / page_size) * page_size;
++	} else {
++		top_index = hil_index;
++	}
++	TopBuffy = arr[top_index];
++
++	bot_index = top_index + page_size - 1;
++	if (bot_index > (count - 1)) {
++		bot_index = count - 1;
++	}
++	BotBuffy  = arr[bot_index];
++
++	Outgoing = arr[count - 1];
++
++	PreviousSort = SidebarSortMethod;
++	free (arr);
++	return 1;
++}
++
++/**
++ * visible - Should we display the sidebar?
++ *
++ * After validating the config options "sidebar_visible" and "sidebar_width",
++ * determine whether we should should display the sidebar.
++ *
++ * When not visible, set the global SidebarWidth to 0.
++ *
++ * Returns:
++ *	Boolean
++ */
++static short
++visible (void)
++{
++	short new_visible = option (OPTSIDEBAR);
++	short new_width   = SidebarWidth;
++
++	if (OldWidth != new_width) {
++		if (new_width > 0) {
++			OldWidth = new_width;
++		}
++	}
++
++	if (OldVisible != new_visible) {
++		if (new_visible) {
++			set_option (OPTSIDEBAR);
++		} else {
++			unset_option (OPTSIDEBAR);
++		}
++		OldVisible = new_visible;
++	} else if (new_width == 0) {
++		unset_option (OPTSIDEBAR);
++		OldVisible = 0;
++	}
++
++	if (!option (OPTSIDEBAR)) {
++		SidebarWidth = 0;
++	} else if (new_width == 0) {
++		SidebarWidth = OldWidth;
++	} else {
++		SidebarWidth = new_width;
++	}
++
++	return new_visible;
++}
++
++/**
++ * draw_divider - Draw a line between the sidebar and the rest of mutt
++ * @first_row:  Screen line to start (0-based)
++ * @num_rows:   Number of rows to fill
++ *
++ * Draw a divider using characters from the config option "sidebar_divider_char".
++ * This can be an ASCII or Unicode character.  First we calculate this
++ * characters' width in screen columns, then subtract that from the config
++ * option "sidebar_width".
++ *
++ * Returns:
++ *	-1: Error: bad character, etc
++ *	0:  Error: 0 width character
++ *	n:  Success: character occupies n screen columns
++ */
++static int
++draw_divider (int first_row, int num_rows)
++{
++	/* Calculate the width of the delimiter in screen cells */
++	int delim_len = mutt_strwidth (SidebarDividerChar);
++
++	if (delim_len < 1)
++		return delim_len;
++
++	if ((SidebarWidth + delim_len) > (COLS + 1))
++		return 0;
++
++	if (delim_len > SidebarWidth)
++		return -1;
++
++	SETCOLOR(MT_COLOR_DIVIDER);
++
++	int i;
++	for (i = 0; i < num_rows; i++) {
++		move (first_row + i, SidebarWidth - delim_len);
++		addstr (NONULL(SidebarDividerChar));
++	}
++
++	return delim_len;
++}
++
++/**
++ * fill_empty_space - Wipe the remaining sidebar space
++ * @first_row:  Screen line to start (0-based)
++ * @num_rows:   Number of rows to fill
++ * @width:      Width of the sidebar (minus the divider)
++ *
++ * Write spaces over the area the sidebar isn't using.
++ */
++static void
++fill_empty_space (int first_row, int num_rows, int width)
++{
++	/* Fill the remaining rows with blank space */
++	SETCOLOR(MT_COLOR_NORMAL);
++
++	int r;
++	for (r = 0; r < num_rows; r++) {
++		int i = 0;
++		move (first_row + r, 0);
++		for (; i < width; i++)
++			addch (' ');
++	}
++}
++
++/**
++ * draw_sidebar - Write out a list of mailboxes, on the left
++ * @first_row:  Screen line to start (0-based)
++ * @num_rows:   Number of rows to fill
++ * @div_width:  Width in screen characters taken by the divider
++ *
++ * Display a list of mailboxes in a panel on the left.  What's displayed will
++ * depend on our index markers: TopBuffy, OpnBuffy, HilBuffy, BotBuffy.
++ * On the first run they'll be NULL, so we display the top of Mutt's list
++ * (Incoming).
++ *
++ * TopBuffy - first visible mailbox
++ * BotBuffy - last  visible mailbox
++ * OpnBuffy - mailbox shown in Mutt's Index Panel
++ * HilBuffy - Unselected mailbox (the paging follows this)
++ *
++ * The entries are formatted using "sidebar_format" and may be abbreviated:
++ * "sidebar_short_path", indented: "sidebar_folder_indent",
++ * "sidebar_indent_string" and sorted: "sidebar_sort_method".  Finally, they're
++ * trimmed to fit the available space.
++ */
++static void
++draw_sidebar (int first_row, int num_rows, int div_width)
++{
++	BUFFY *b = TopBuffy;
++	if (!b)
++		return;
++
++	int w = MIN(COLS, (SidebarWidth - div_width));
++	int row = 0;
++	for (b = TopBuffy; b && (row < num_rows); b = b->next) {
++		if (b->is_hidden) {
++			continue;
++		}
++
++		if (b == OpnBuffy) {
++			if ((ColorDefs[MT_COLOR_SB_INDICATOR] != 0)) {
++				SETCOLOR(MT_COLOR_SB_INDICATOR);
++			} else {
++				SETCOLOR(MT_COLOR_INDICATOR);
++			}
++		} else if (b == HilBuffy) {
++			SETCOLOR(MT_COLOR_HIGHLIGHT);
++		} else if ((ColorDefs[MT_COLOR_SB_SPOOLFILE] != 0) &&
++			(mutt_strcmp (b->path, Spoolfile) == 0)) {
++			SETCOLOR(MT_COLOR_SB_SPOOLFILE);
++		} else if (b->msg_unread > 0) {
++			SETCOLOR(MT_COLOR_NEW);
++		} else if (b->msg_flagged > 0) {
++			SETCOLOR(MT_COLOR_FLAGGED);
++		} else {
++			SETCOLOR(MT_COLOR_NORMAL);
++		}
++
++		move (first_row + row, 0);
++		if (Context && Context->path &&
++			(!strcmp (b->path, Context->path)||
++			 !strcmp (b->realpath, Context->path))) {
++			b->msg_unread  = Context->unread;
++			b->msg_count   = Context->msgcount;
++			b->msg_flagged = Context->flagged;
++		}
++
++		/* compute length of Maildir without trailing separator */
++		size_t maildirlen = strlen (Maildir);
++		if (SidebarDelimChars && strchr (SidebarDelimChars, Maildir[maildirlen - 1])) {
++			maildirlen--;
++		}
++
++		/* check whether Maildir is a prefix of the current folder's path */
++		short maildir_is_prefix = 0;
++		if ((strlen (b->path) > maildirlen) && (strncmp (Maildir, b->path, maildirlen) == 0)) {
++			maildir_is_prefix = 1;
++		}
++		/* calculate depth of current folder and generate its display name with indented spaces */
++		int sidebar_folder_depth = 0;
++		char *sidebar_folder_name;
++		int i;
++		if (option (OPTSIDEBARSHORTPATH)) {
++			/* disregard a trailing separator, so strlen() - 2 */
++			sidebar_folder_name = b->path;
++			for (i = strlen (sidebar_folder_name) - 2; i >= 0; i--) {
++				if (SidebarDelimChars &&
++						strchr (SidebarDelimChars, sidebar_folder_name[i])) {
++					sidebar_folder_name += (i + 1);
++					break;
++				}
++			}
++		} else {
++			sidebar_folder_name = b->path + maildir_is_prefix * (maildirlen + 1);
++		}
++		if (maildir_is_prefix && option (OPTSIDEBARFOLDERINDENT)) {
++			const char *tmp_folder_name;
++			int lastsep = 0;
++			tmp_folder_name = b->path + maildirlen + 1;
++			int tmplen = (int) strlen (tmp_folder_name) - 1;
++			for (i = 0; i < tmplen; i++) {
++				if (SidebarDelimChars && strchr (SidebarDelimChars, tmp_folder_name[i])) {
++					sidebar_folder_depth++;
++					lastsep = i + 1;
++				}
++			}
++			if (sidebar_folder_depth > 0) {
++				if (option (OPTSIDEBARSHORTPATH)) {
++					tmp_folder_name += lastsep;  /* basename */
++				}
++				sidebar_folder_name = malloc (strlen (tmp_folder_name) + sidebar_folder_depth*strlen (NONULL(SidebarIndentString)) + 1);
++				sidebar_folder_name[0]=0;
++				for (i=0; i < sidebar_folder_depth; i++)
++					strncat (sidebar_folder_name, NONULL(SidebarIndentString), strlen (NONULL(SidebarIndentString)));
++				strncat (sidebar_folder_name, tmp_folder_name, strlen (tmp_folder_name));
++			}
++		}
++		char str[SHORT_STRING];
++		make_sidebar_entry (str, sizeof (str), w, sidebar_folder_name, b);
++		printw ("%s", str);
++		if (sidebar_folder_depth > 0)
++			free (sidebar_folder_name);
++		row++;
++	}
++
++	fill_empty_space (first_row + row, num_rows - row, w);
++}
++
++
++/**
++ * sb_init - Set some default values for the sidebar.
++ */
++void
++sb_init (void)
++{
++	OldVisible = option (OPTSIDEBAR);
++	if (SidebarWidth > 0) {
++		OldWidth = SidebarWidth;
++	} else {
++		OldWidth = 20;
++		if (OldVisible) {
++			SidebarWidth = OldWidth;
++		}
++	}
++}
++
++/**
++ * sb_draw - Completely redraw the sidebar
++ *
++ * Completely refresh the sidebar region.  First draw the divider; then, for
++ * each BUFFY, call make_sidebar_entry; finally blank out any remaining space.
++ */
++void
++sb_draw (void)
++{
++	if (!visible())
++		return;
++
++	/* XXX - if transitioning from invisible to visible */
++	/* if (OldVisible == 0) */
++	/* 	mutt_buffy_check (1); we probably have bad or no numbers */
++
++	int first_row = 0;
++	int num_rows  = LINES - 2;
++
++	if (option (OPTHELP) || option (OPTSTATUSONTOP))
++		first_row++;
++
++	if (option (OPTHELP))
++		num_rows--;
++
++	int div_width = draw_divider (first_row, num_rows);
++	if (div_width < 0)
++		return;
++
++	if (!Incoming) {
++		int w = MIN(COLS, (SidebarWidth - div_width));
++		fill_empty_space (first_row, num_rows, w);
++		return;
++	}
++
++	if (!prepare_sidebar (num_rows))
++		return;
++
++	draw_sidebar (first_row, num_rows, div_width);
++}
++
++/**
++ * sb_should_refresh - Check if the sidebar is due to be refreshed
++ *
++ * The "sidebar_refresh_time" config option allows the user to limit the frequency
++ * with which the sidebar is refreshed.
++ *
++ * Returns:
++ *	1  Yes, refresh is due
++ *	0  No,  refresh happened recently
++ */
++int
++sb_should_refresh (void)
++{
++	if (!option (OPTSIDEBAR))
++		return 0;
++
++	if (SidebarRefreshTime == 0)
++		return 0;
++
++	time_t diff = (time (NULL) - LastRefresh);
++
++	return (diff >= SidebarRefreshTime);
++}
++
++/**
++ * sb_change_mailbox - Change the selected mailbox
++ * @op: Operation code
++ *
++ * Change the selected mailbox, e.g. "Next mailbox", "Previous Mailbox
++ * with new mail". The operations are listed OPS.SIDEBAR which is built
++ * into an enum in keymap_defs.h.
++ *
++ * If the operation is successful, HilBuffy will be set to the new mailbox.
++ * This function only *selects* the mailbox, doesn't *open* it.
++ *
++ * Allowed values are: OP_SIDEBAR_NEXT, OP_SIDEBAR_NEXT_NEW,
++ * OP_SIDEBAR_PAGE_DOWN, OP_SIDEBAR_PAGE_UP, OP_SIDEBAR_PREV,
++ * OP_SIDEBAR_PREV_NEW.
++ */
++void
++sb_change_mailbox (int op)
++{
++	BUFFY *b;
++	if (!HilBuffy)	/* It'll get reset on the next draw */
++		return;
++
++	switch (op) {
++		case OP_SIDEBAR_NEXT:
++			if (!HilBuffy->next)
++				return;
++			if (HilBuffy->next->is_hidden)
++				return;
++			HilBuffy = HilBuffy->next;
++			break;
++		case OP_SIDEBAR_NEXT_NEW:
++			b = find_next_new (option (OPTSIDEBARNEXTNEWWRAP));
++			if (!b) {
++				return;
++			} else {
++				HilBuffy = b;
++			}
++			break;
++		case OP_SIDEBAR_PAGE_DOWN:
++			HilBuffy = BotBuffy;
++			if (HilBuffy->next) {
++				HilBuffy = HilBuffy->next;
++			}
++			break;
++		case OP_SIDEBAR_PAGE_UP:
++			HilBuffy = TopBuffy;
++			if (HilBuffy != Incoming) {
++				HilBuffy = HilBuffy->prev;
++			}
++			break;
++		case OP_SIDEBAR_PREV:
++			if (!HilBuffy->prev)
++				return;
++			if (HilBuffy->prev->is_hidden)	/* Can't happen, we've sorted the hidden to the end */
++				return;
++			HilBuffy = HilBuffy->prev;
++			break;
++		case OP_SIDEBAR_PREV_NEW:
++			b = find_prev_new (option (OPTSIDEBARNEXTNEWWRAP));
++			if (!b) {
++				return;
++			} else {
++				HilBuffy = b;
++			}
++			break;
++		default:
++			return;
++	}
++
++	/* We can change folder even if the sidebar is hidden */
++	if (option (OPTSIDEBAR))
++		sb_draw();
++}
++
++/**
++ * sb_set_buffystats - Update the BUFFY's message counts from the CONTEXT
++ * @ctx:  A mailbox CONTEXT
++ *
++ * Given a mailbox CONTEXT, find a matching mailbox BUFFY and copy the message
++ * counts into it.
++ */
++void
++sb_set_buffystats (const CONTEXT *ctx)
++{
++	/* Even if the sidebar's hidden,
++	 * we should take note of the new data. */
++	BUFFY *b = Incoming;
++	if (!ctx || !b)
++		return;
++
++	for (; b; b = b->next) {
++		if (!strcmp (b->path,     ctx->path) ||
++		    !strcmp (b->realpath, ctx->path)) {
++			b->msg_unread  = ctx->unread;
++			b->msg_count   = ctx->msgcount;
++			b->msg_flagged = ctx->flagged;
++			break;
++		}
++	}
++}
++
++/**
++ * sb_get_highlight - Get the BUFFY that's highlighted in the sidebar
++ *
++ * Get the path of the mailbox that's highlighted in the sidebar.
++ *
++ * Returns:
++ *	Mailbox path
++ */
++const char *
++sb_get_highlight (void)
++{
++	if (!HilBuffy)
++		return NULL;
++
++	return HilBuffy->path;
++}
++
++/**
++ * sb_set_open_buffy - Set the OpnBuffy based on a mailbox path
++ * @path: Mailbox path
++ *
++ * Search through the list of mailboxes.  If a BUFFY has a matching path, set
++ * OpnBuffy to it.
++ */
++BUFFY *
++sb_set_open_buffy (const char *path)
++{
++	/* Even if the sidebar is hidden */
++
++	BUFFY *b = Incoming;
++
++	if (!path || !b)
++		return NULL;
++
++	OpnBuffy = NULL;
++
++	for (; b; b = b->next) {
++		if (!strcmp (b->path,     path) ||
++		    !strcmp (b->realpath, path)) {
++			OpnBuffy = b;
++			HilBuffy = b;
++			break;
++		}
++	}
++
++	return OpnBuffy;
++}
++
++/**
++ * sb_set_update_time - Note the time that the sidebar was updated
++ *
++ * Update the timestamp representing the last sidebar update.  If the user
++ * configures "sidebar_refresh_time", this will help to reduce traffic.
++ */
++void
++sb_set_update_time (void)
++{
++	/* XXX - should this be public? */
++
++	LastRefresh = time (NULL);
++}
++
++/**
++ * sb_notify_mailbox - The state of a BUFFY is about to change
++ *
++ * We receive a notification:
++ *	After a new BUFFY has been created
++ *	Before a BUFFY is deleted
++ *
++ * Before a deletion, check that our pointers won't be invalidated.
++ */
++void
++sb_notify_mailbox (BUFFY *b, int created)
++{
++	if (!b)
++		return;
++
++	/* Any new/deleted mailboxes will cause a refresh.  As long as
++	 * they're valid, our pointers will be updated in prepare_sidebar() */
++
++	if (created) {
++		if (!TopBuffy)
++			TopBuffy = b;
++		if (!HilBuffy)
++			HilBuffy = b;
++		if (!BotBuffy)
++			BotBuffy = b;
++		if (!Outgoing)
++			Outgoing = b;
++		if (!OpnBuffy && Context) {
++			/* This might happen if the user "unmailboxes *", then
++			 * "mailboxes" our current mailbox back again */
++			if (mutt_strcmp (b->path, Context->path) == 0) {
++				OpnBuffy = b;
++			}
++		}
++	} else {
++		if (TopBuffy == b)
++			TopBuffy = buffy_going (TopBuffy);
++		if (OpnBuffy == b)
++			OpnBuffy = buffy_going (OpnBuffy);
++		if (HilBuffy == b)
++			HilBuffy = buffy_going (HilBuffy);
++		if (BotBuffy == b)
++			BotBuffy = buffy_going (BotBuffy);
++		if (Outgoing == b)
++			Outgoing = buffy_going (Outgoing);
++	}
++}
+diff -urN mutt-1.6.1/sidebar.h mutt-1.6.1-sidebar/sidebar.h
+--- mutt-1.6.1/sidebar.h	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-sidebar/sidebar.h	2016-05-02 03:02:15.023213165 +0100
+@@ -0,0 +1,36 @@
++/* Copyright (C) 2004 Justin Hibbits <jrh29 at po.cwru.edu>
++ * Copyright (C) 2004 Thomer M. Gil <mutt at thomer.com>
++ * Copyright (C) 2015-2016 Richard Russon <rich at flatcap.org>
++ *
++ *     This program is free software; you can redistribute it and/or modify
++ *     it under the terms of the GNU General Public License as published by
++ *     the Free Software Foundation; either version 2 of the License, or
++ *     (at your option) any later version.
++ *
++ *     This program is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ *     You should have received a copy of the GNU General Public License
++ *     along with this program; if not, write to the Free Software
++ *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
++ */
++
++#ifndef SIDEBAR_H
++#define SIDEBAR_H
++
++#include "mutt.h"
++#include "buffy.h"
++
++void         sb_change_mailbox (int op);
++void         sb_draw (void);
++const char * sb_get_highlight (void);
++void         sb_init (void);
++void         sb_notify_mailbox (BUFFY *b, int created);
++void         sb_set_buffystats (const CONTEXT *ctx);
++BUFFY *      sb_set_open_buffy (const char *path);
++void         sb_set_update_time (void);
++int          sb_should_refresh (void);
++
++#endif /* SIDEBAR_H */
+diff -urN mutt-1.6.1/sort.h mutt-1.6.1-sidebar/sort.h
+--- mutt-1.6.1/sort.h	2016-05-02 03:02:12.440172071 +0100
++++ mutt-1.6.1-sidebar/sort.h	2016-05-02 03:02:15.023213165 +0100
+@@ -31,6 +31,12 @@
+ #define SORT_KEYID	12
+ #define SORT_TRUST	13
+ #define SORT_SPAM	14
++#define SORT_COUNT	15
++#define SORT_COUNT_NEW	16
++#define SORT_DESC	17
++#define SORT_FLAGGED	18
++#define SORT_PATH	19
++
+ /* dgc: Sort & SortAux are shorts, so I'm bumping these bitflags up from
+  * bits 4 & 5 to bits 8 & 9 to make room for more sort keys in the future. */
+ #define SORT_MASK	0xff
+@@ -50,6 +56,7 @@
+ WHERE short Sort INITVAL (SORT_DATE);
+ WHERE short SortAux INITVAL (SORT_DATE); /* auxiliary sorting method */
+ WHERE short SortAlias INITVAL (SORT_ALIAS);
++WHERE short SidebarSortMethod INITVAL (SORT_ORDER);
+ 
+ /* FIXME: This one does not belong to here */
+ WHERE short PgpSortKeys INITVAL (SORT_ADDRESS);
diff --git a/debian/patches/neomutt/10-notmuch.patch b/debian/patches/neomutt/10-notmuch.patch
new file mode 100644
index 0000000..827a381
--- /dev/null
+++ b/debian/patches/neomutt/10-notmuch.patch
@@ -0,0 +1,5819 @@
+diff -urN mutt-1.6.1-sidebar-notmuch/browser.c mutt-1.6.1-notmuch/browser.c
+--- mutt-1.6.1-sidebar-notmuch/browser.c	2016-05-02 03:02:12.695176126 +0100
++++ mutt-1.6.1-notmuch/browser.c	2016-05-02 03:02:15.119214693 +0100
+@@ -33,6 +33,9 @@
+ #ifdef USE_IMAP
+ #include "imap.h"
+ #endif
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
+ 
+ #include <stdlib.h>
+ #include <dirent.h>
+@@ -232,6 +235,12 @@
+     case 'f':
+     {
+       char *s;
++
++#ifdef USE_NOTMUCH
++      if (mx_is_notmuch(folder->ff->name))
++        s = NONULL (folder->ff->desc);
++      else
++#endif
+ #ifdef USE_IMAP
+       if (folder->ff->imap)
+ 	s = NONULL (folder->ff->desc);
+@@ -324,6 +333,18 @@
+ 	break;
+       }
+ #endif
++#ifdef USE_NOTMUCH
++      if (mx_is_notmuch (folder->ff->name))
++      {
++	if (!optional)
++	{
++	  snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
++	  snprintf (dest, destlen, tmp, folder->ff->new);
++	} else if (!folder->ff->new)
++	  optional = 0;
++	break;
++      }
++#endif
+       snprintf (tmp, sizeof (tmp), "%%%sc", fmt);
+       snprintf (dest, destlen, tmp, folder->ff->new ? 'N' : ' ');
+       break;
+@@ -490,6 +511,33 @@
+   return 0;
+ }
+ 
++#ifdef USE_NOTMUCH
++static int examine_vfolders (MUTTMENU *menu, struct browser_state *state)
++{
++  BUFFY *tmp = VirtIncoming;
++
++  if (!VirtIncoming)
++    return (-1);
++  mutt_buffy_check (0);
++
++  init_state (state, menu);
++
++  do
++  {
++    if (mx_is_notmuch (tmp->path))
++    {
++      nm_nonctx_get_count(tmp->path, &tmp->msg_count, &tmp->msg_unread);
++      add_folder (menu, state, tmp->path, tmp->desc, NULL,
++		      tmp->msg_unread, tmp->msg_count);
++      continue;
++    }
++  }
++  while ((tmp = tmp->next));
++  browser_sort (state);
++  return 0;
++}
++#endif
++
+ static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state)
+ {
+   struct stat s;
+@@ -559,6 +607,13 @@
+   return (regexec (re, ((struct folder_file *) menu->data)[n].name, 0, NULL, 0));
+ }
+ 
++#ifdef USE_NOTMUCH
++static int select_vfolder_search (MUTTMENU *menu, regex_t *re, int n)
++{
++  return (regexec (re, ((struct folder_file *) menu->data)[n].desc, 0, NULL, 0));
++}
++#endif
++
+ static void folder_entry (char *s, size_t slen, MUTTMENU *menu, int num)
+ {
+   FOLDER folder;
+@@ -570,6 +625,19 @@
+       (unsigned long) &folder, M_FORMAT_ARROWCURSOR);
+ }
+ 
++#ifdef USE_NOTMUCH
++static void vfolder_entry (char *s, size_t slen, MUTTMENU *menu, int num)
++{
++  FOLDER folder;
++
++  folder.ff = &((struct folder_file *) menu->data)[num];
++  folder.num = num;
++
++  mutt_FormatString (s, slen, 0, NONULL(VirtFolderFormat), folder_format_str,
++      (unsigned long) &folder, M_FORMAT_ARROWCURSOR);
++}
++#endif
++
+ static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
+ 		       size_t titlelen, int buffy)
+ {
+@@ -635,7 +703,7 @@
+   int buffy    = (flags & M_SEL_BUFFY)  ? 1 : 0;
+ 
+   buffy = buffy && folder;
+-  
++
+   memset (&state, 0, sizeof (struct browser_state));
+ 
+   if (!folder)
+@@ -688,13 +756,17 @@
+     }
+ #endif
+   }
+-  else 
++#ifdef USE_NOTMUCH
++  else if (!(flags & M_SEL_VFOLDER))
++#else
++  else
++#endif
+   {
+     if (!folder)
+       getcwd (LastDir, sizeof (LastDir));
+     else if (!LastDir[0])
+       strfcpy (LastDir, NONULL(Maildir), sizeof (LastDir));
+-    
++
+ #ifdef USE_IMAP
+     if (!buffy && mx_is_imap (LastDir))
+     {
+@@ -716,6 +788,12 @@
+ 
+   *f = 0;
+ 
++#ifdef USE_NOTMUCH
++  if (flags & M_SEL_VFOLDER) {
++    if (examine_vfolders (NULL, &state) == -1)
++      goto bail;
++  } else
++#endif
+   if (buffy)
+   {
+     if (examine_mailboxes (NULL, &state) == -1)
+@@ -725,17 +803,25 @@
+ #ifdef USE_IMAP
+   if (!state.imap_browse)
+ #endif
++  {
+   if (examine_directory (NULL, &state, LastDir, prefix) == -1)
+     goto bail;
+-
++  }
+   menu = mutt_new_menu (MENU_FOLDER);
+-  menu->make_entry = folder_entry;
+   menu->search = select_file_search;
+   menu->title = title;
+   menu->data = state.entry;
+   if (multiple)
+     menu->tag = file_tag;
+ 
++#ifdef USE_NOTMUCH
++  if (flags & M_SEL_VFOLDER) {
++    menu->make_entry = vfolder_entry;
++    menu->search = select_vfolder_search;
++  } else
++#endif
++    menu->make_entry = folder_entry;
++
+   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_FOLDER,
+     FolderHelp);
+ 
+@@ -884,6 +970,10 @@
+ 	else if (state.imap_browse)
+           strfcpy (f, state.entry[menu->current].name, flen);
+ #endif
++#ifdef USE_NOTMUCH
++	else if (mx_is_notmuch(state.entry[menu->current].name))
++	  strfcpy (f, state.entry[menu->current].name, flen);
++#endif
+ 	else
+ 	  mutt_concat_path (f, LastDir, state.entry[menu->current].name, flen);
+ 
+@@ -1038,7 +1128,7 @@
+         }
+         break;
+ #endif
+-      
++
+       case OP_CHANGE_DIRECTORY:
+ 
+ 	strfcpy (buf, LastDir, sizeof (buf));
+diff -urN mutt-1.6.1-sidebar-notmuch/buffy.c mutt-1.6.1-notmuch/buffy.c
+--- mutt-1.6.1-sidebar-notmuch/buffy.c	2016-05-02 03:02:12.695176126 +0100
++++ mutt-1.6.1-notmuch/buffy.c	2016-05-02 03:02:15.221216316 +0100
+@@ -35,6 +35,10 @@
+ #include "imap.h"
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #include <string.h>
+ #include <sys/stat.h>
+ #include <dirent.h>
+@@ -219,6 +223,8 @@
+ 
+ static void buffy_free (BUFFY **mailbox)
+ {
++  if (mailbox && *mailbox)
++    FREE (&(*mailbox)->desc);
+   FREE (mailbox); /* __FREE_CHECKED__ */
+ }
+ 
+@@ -377,6 +383,54 @@
+   return rc;
+ }
+ 
++#ifdef USE_NOTMUCH
++int mutt_parse_virtual_mailboxes (BUFFER *path, BUFFER *s, unsigned long data, BUFFER *err)
++{
++  BUFFY **tmp;
++  char buf[_POSIX_PATH_MAX + LONG_STRING + 32];   /* path to DB + query + URI "decoration" */
++
++  while (MoreArgs (s))
++  {
++    char *desc;
++
++    mutt_extract_token (path, s, 0);
++    if (path->data && *path->data)
++      desc = safe_strdup( path->data);
++    else
++      continue;
++
++    mutt_extract_token (path, s, 0);
++    strfcpy (buf, path->data, sizeof (buf));
++
++    /* Skip empty tokens. */
++    if(!*buf) {
++	    FREE(&desc);
++	    continue;
++    }
++
++    /* avoid duplicates */
++    for (tmp = &VirtIncoming; *tmp; tmp = &((*tmp)->next))
++    {
++      if (mutt_strcmp (buf, (*tmp)->path) == 0)
++      {
++	dprint(3,(debugfile,"vistual mailbox '%s' already registered as '%s'\n", buf, (*tmp)->path));
++	break;
++      }
++    }
++
++    if (!*tmp)
++      *tmp = buffy_new (buf);
++
++    (*tmp)->new = 0;
++    (*tmp)->notified = 1;
++    (*tmp)->newly_created = 0;
++    (*tmp)->size = 0;
++    (*tmp)->desc = desc;
++  }
++  return 0;
++}
++#endif
++
+ /* returns 1 if maildir has new mail */
+ static int buffy_maildir_hasnew (BUFFY* mailbox)
+ {
+@@ -540,51 +594,13 @@
+ }
+ #endif
+ 
+-int mutt_buffy_check (int force)
+-{
+-  BUFFY *tmp;
+-  struct stat sb;
+-  struct stat contex_sb;
+-  time_t t;
+-
+-  sb.st_size=0;
+-  contex_sb.st_dev=0;
+-  contex_sb.st_ino=0;
+ 
+-#ifdef USE_IMAP
+-  /* update postponed count as well, on force */
+-  if (force)
+-    mutt_update_num_postponed ();
+-#endif
+-
+-  /* fastest return if there are no mailboxes */
+-  if (!Incoming)
+-    return 0;
+-  t = time (NULL);
+-  if (!force && (t - BuffyTime < BuffyTimeout))
+-    return BuffyCount;
+- 
+-  BuffyTime = t;
+-  BuffyCount = 0;
+-  BuffyNotify = 0;
++static void buffy_check(BUFFY *tmp, struct stat *contex_sb)
++{
++    struct stat sb;
+ 
+-#ifdef USE_IMAP
+-  BuffyCount += imap_buffy_check (force);
+-#endif
++    sb.st_size=0;
+ 
+-  /* check device ID and serial number instead of comparing paths */
+-  if (!Context || Context->magic == M_IMAP || Context->magic == M_POP
+-      || stat (Context->path, &contex_sb) != 0)
+-  {
+-    contex_sb.st_dev=0;
+-    contex_sb.st_ino=0;
+-  }
+-  
+-#ifdef USE_SIDEBAR
+-  int should_refresh = sb_should_refresh();
+-#endif
+-  for (tmp = Incoming; tmp; tmp = tmp->next)
+-  {
+     if (tmp->magic != M_IMAP)
+     {
+       tmp->new = 0;
+@@ -593,6 +609,11 @@
+ 	tmp->magic = M_POP;
+       else
+ #endif
++#ifdef USE_NOTMUCH
++      if (mx_is_notmuch (tmp->path))
++	tmp->magic = M_NOTMUCH;
++      else
++#endif
+       if (stat (tmp->path, &sb) != 0 || (S_ISREG(sb.st_mode) && sb.st_size == 0) ||
+ 	  (!tmp->magic && (tmp->magic = mx_get_magic (tmp->path)) <= 0))
+       {
+@@ -601,23 +622,23 @@
+ 	tmp->newly_created = 1;
+ 	tmp->magic = 0;
+ 	tmp->size = 0;
+-	continue;
++	return;
+       }
+     }
+ 
+     /* check to see if the folder is the currently selected folder
+      * before polling */
+     if (!Context || !Context->path ||
+-	(( tmp->magic == M_IMAP || tmp->magic == M_POP )
++	(( tmp->magic == M_IMAP || tmp->magic == M_POP || tmp->magic == M_NOTMUCH)
+ 	    ? mutt_strcmp (tmp->path, Context->path) :
+-	      (sb.st_dev != contex_sb.st_dev || sb.st_ino != contex_sb.st_ino)))
++	      (sb.st_dev != contex_sb->st_dev || sb.st_ino != contex_sb->st_ino)))
+     {
+       switch (tmp->magic)
+       {
+       case M_MBOX:
+       case M_MMDF:
+ #ifdef USE_SIDEBAR
+-	if (should_refresh)
++	if (option(OPTSIDEBAR))
+ 	  buffy_mbox_update (tmp, &sb);
+ #endif
+ 	if (buffy_mbox_hasnew (tmp, &sb) > 0)
+@@ -626,7 +647,7 @@
+ 
+       case M_MAILDIR:
+ #ifdef USE_SIDEBAR
+-	if (should_refresh)
++	if (option(OPTSIDEBAR))
+ 	  buffy_maildir_update (tmp);
+ #endif
+ 	if (buffy_maildir_hasnew (tmp) > 0)
+@@ -635,15 +656,28 @@
+ 
+       case M_MH:
+ #ifdef USE_SIDEBAR
+-	if (sb_should_refresh()) {
++	if (option(OPTSIDEBAR))
+ 	  mh_buffy_update (tmp);
+-	  sb_set_update_time();
+-	}
+ #endif
+ 	mh_buffy(tmp);
+ 	if (tmp->new)
+ 	  BuffyCount++;
+ 	break;
++#ifdef USE_NOTMUCH
++      case M_NOTMUCH:
++	tmp->msg_count = 0;
++	tmp->msg_unread = 0;
++	tmp->msg_flagged = 0;
++	nm_nonctx_get_count(tmp->path, &tmp->msg_count, &tmp->msg_unread);
++	if (tmp->msg_unread > 0) {
++	  BuffyCount++;
++	  tmp->new = 1;
++	}
++#ifdef USE_SIDEBAR
++	sb_set_update_time();
++#endif
++	break;
++#endif
+       }
+     }
+     else if (option(OPTCHECKMBOXSIZE) && Context && Context->path)
+@@ -653,10 +687,65 @@
+       tmp->notified = 0;
+     else if (!tmp->notified)
+       BuffyNotify++;
++}
++
++int mutt_buffy_check (int force)
++{
++  BUFFY *tmp;
++  struct stat contex_sb;
++  time_t t;
++
++  contex_sb.st_dev=0;
++  contex_sb.st_ino=0;
++
++#ifdef USE_IMAP
++  /* update postponed count as well, on force */
++  if (force)
++    mutt_update_num_postponed ();
++#endif
++
++  /* fastest return if there are no mailboxes */
++#ifdef USE_NOTMUCH
++  if (!Incoming && !VirtIncoming)
++    return 0;
++#else
++  if (!Incoming)
++    return 0;
++#endif
++  t = time (NULL);
++  if (!force && (t - BuffyTime < BuffyTimeout))
++    return BuffyCount;
++
++  BuffyTime = t;
++  BuffyCount = 0;
++  BuffyNotify = 0;
++
++#ifdef USE_IMAP
++  BuffyCount += imap_buffy_check (force);
++#endif
++
++  /* check device ID and serial number instead of comparing paths */
++  if (!Context || Context->magic == M_IMAP || Context->magic == M_POP
++      || stat (Context->path, &contex_sb) != 0)
++  {
++    contex_sb.st_dev=0;
++    contex_sb.st_ino=0;
+   }
++
+ #ifdef USE_SIDEBAR
+-  if (should_refresh)
+-	  sb_set_update_time();
++  if (sb_should_refresh()) {
++    for (tmp = Incoming; tmp; tmp = tmp->next)
++      buffy_check(tmp, &contex_sb);
++    sb_set_update_time();
++  }
++#else
++  for (tmp = Incoming; tmp; tmp = tmp->next)
++    buffy_check(tmp, &contex_sb);
++#endif
++
++#ifdef USE_NOTMUCH
++  for (tmp = VirtIncoming; tmp; tmp = tmp->next)
++    buffy_check(tmp, &contex_sb);
+ #endif
+ 
+   BuffyDoneTime = BuffyTime;
+@@ -773,6 +862,35 @@
+   *s = '\0';
+ }
+ 
++#ifdef USE_NOTMUCH
++void mutt_buffy_vfolder (char *s, size_t slen)
++{
++  BUFFY *tmp;
++  int pass, found = 0;
++
++  if (mutt_buffy_check (0))
++  {
++    for (pass = 0; pass < 2; pass++) {
++      for (tmp = VirtIncoming; tmp; tmp = tmp->next)
++      {
++	if ((found || pass) && tmp->new)
++	{
++	  strfcpy (s, tmp->desc, slen);
++	  return;
++	}
++	if (mutt_strcmp (s, tmp->path) == 0)
++	  found = 1;
++      }
++    }
++
++    mutt_buffy_check (1); /* buffy was wrong - resync things */
++  }
++
++  /* no folders with new mail */
++  *s = '\0';
++}
++#endif
++
+ /* fetch buffy object for given path, if present */
+ static BUFFY* buffy_get (const char *path)
+ {
+diff -urN mutt-1.6.1-sidebar-notmuch/buffy.h mutt-1.6.1-notmuch/buffy.h
+--- mutt-1.6.1-sidebar-notmuch/buffy.h	2016-05-02 03:02:12.695176126 +0100
++++ mutt-1.6.1-notmuch/buffy.h	2016-05-02 03:02:15.221216316 +0100
+@@ -26,18 +26,17 @@
+ #ifdef USE_SIDEBAR
+   char realpath[_POSIX_PATH_MAX];
+ #endif
++  char *desc;
+   off_t size;
+   struct buffy_t *next;
+ #ifdef USE_SIDEBAR
+   struct buffy_t *prev;
+ #endif
+   short new;			/* mailbox has new mail */
+-#ifdef USE_SIDEBAR
+   int msg_count;		/* total number of messages */
+   int msg_unread;		/* number of unread messages */
+   int msg_flagged;		/* number of flagged messages */
+   short is_hidden;		/* is hidden from the sidebar */
+-#endif
+   short notified;		/* user has been notified */
+   short magic;			/* mailbox type */
+   short newly_created;		/* mbox or mmdf just popped into existence */
+@@ -51,6 +50,11 @@
+ WHERE BUFFY *Incoming INITVAL (0);
+ WHERE short BuffyTimeout INITVAL (3);
+ 
++#ifdef USE_NOTMUCH
++WHERE BUFFY *VirtIncoming INITVAL (0);
++void mutt_buffy_vfolder (char *s, size_t slen);
++#endif
++
+ extern time_t BuffyDoneTime;	/* last time we knew for sure how much mail there was */
+ 
+ BUFFY *mutt_find_mailbox (const char *path);
+diff -urN mutt-1.6.1-sidebar-notmuch/color.c mutt-1.6.1-notmuch/color.c
+--- mutt-1.6.1-sidebar-notmuch/color.c	2016-05-02 03:02:12.704176269 +0100
++++ mutt-1.6.1-notmuch/color.c	2016-05-02 03:02:15.120214709 +0100
+@@ -39,6 +39,9 @@
+ COLOR_LINE *ColorIndexAuthorList = NULL;
+ COLOR_LINE *ColorIndexFlagsList = NULL;
+ COLOR_LINE *ColorIndexSubjectList = NULL;
++#ifdef USE_NOTMUCH
++COLOR_LINE *ColorIndexTagList = NULL;
++#endif
+ 
+ /* local to this file */
+ static int ColorQuoteSize;
+@@ -106,6 +109,10 @@
+   { "index_number",	MT_COLOR_INDEX_NUMBER },
+   { "index_size",	MT_COLOR_INDEX_SIZE },
+   { "index_subject",	MT_COLOR_INDEX_SUBJECT },
++#ifdef USE_NOTMUCH
++  { "index_tag",	MT_COLOR_INDEX_TAG },
++  { "index_tags",	MT_COLOR_INDEX_TAGS },
++#endif
+   { "prompt",		MT_COLOR_PROMPT },
+ #ifdef USE_SIDEBAR
+   { "sidebar_divider",	MT_COLOR_DIVIDER },
+@@ -520,6 +527,10 @@
+     mutt_do_uncolor (buf, s, &ColorIndexFlagsList, &do_cache, parse_uncolor);
+   else if (object == MT_COLOR_INDEX_SUBJECT)
+     mutt_do_uncolor (buf, s, &ColorIndexSubjectList, &do_cache, parse_uncolor);
++#ifdef USE_NOTMUCH
++  else if (object == MT_COLOR_INDEX_TAG)
++    mutt_do_uncolor(buf, s, &ColorIndexTagList, &do_cache, parse_uncolor);
++#endif
+ 
+   if (do_cache && !option (OPTNOCURSES))
+   {
+@@ -765,7 +776,11 @@
+       (object == MT_COLOR_INDEX) ||
+       (object == MT_COLOR_INDEX_AUTHOR) ||
+       (object == MT_COLOR_INDEX_FLAGS) ||
+-      (object == MT_COLOR_INDEX_SUBJECT)) {
++      (object == MT_COLOR_INDEX_SUBJECT)
++#ifdef USE_NOTMUCH
++      || (object == MT_COLOR_INDEX_TAG)
++#endif
++      ) {
+     if (!MoreArgs (s)) {
+       strfcpy (err->data, _("too few arguments"), err->dsize);
+       return -1;
+@@ -844,6 +859,14 @@
+ 		    fg, bg, attr, err, 1, match);
+     set_option (OPTFORCEREDRAWINDEX);
+   }
++#ifdef USE_NOTMUCH
++  else if (object == MT_COLOR_INDEX_TAG)
++  {
++    r = add_pattern (&ColorIndexTagList, buf->data, 1,
++		    fg, bg, attr, err, 1, match);
++    set_option (OPTFORCEREDRAWINDEX);
++  }
++#endif
+   else if (object == MT_COLOR_QUOTED)
+   {
+     if (q_level >= ColorQuoteSize)
+diff -urN mutt-1.6.1-sidebar-notmuch/commands.c mutt-1.6.1-notmuch/commands.c
+--- mutt-1.6.1-sidebar-notmuch/commands.c	2016-05-02 03:02:12.705176285 +0100
++++ mutt-1.6.1-notmuch/commands.c	2016-05-02 03:02:15.221216316 +0100
+@@ -40,6 +40,10 @@
+ #include "imap.h"
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #include "buffy.h"
+ 
+ #include <errno.h>
+@@ -146,7 +150,9 @@
+   }
+ 
+   res = mutt_copy_message (fpout, Context, cur, cmflags,
+-       	(option (OPTWEED) ? (CH_WEED | CH_REORDER) : 0) | CH_DECODE | CH_FROM | CH_DISPLAY);
++		(option (OPTWEED) ? (CH_WEED | CH_REORDER) : 0)
++		| CH_DECODE | CH_FROM | CH_DISPLAY | CH_VIRTUAL);
++
+   if ((safe_fclose (&fpout) != 0 && errno != EPIPE) || res < 0)
+   {
+     mutt_error (_("Could not copy message"));
+@@ -846,19 +852,30 @@
+     }
+     else
+     {
++      int rc = 0;
++
++#ifdef USE_NOTMUCH
++      if (Context->magic == M_NOTMUCH)
++        nm_longrun_init(Context, TRUE);
++#endif
+       for (i = 0; i < Context->vcount; i++)
+       {
+ 	if (Context->hdrs[Context->v2r[i]]->tagged)
+ 	{
+ 	  mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], M_MESSAGEHOOK);
+-	  if (_mutt_save_message(Context->hdrs[Context->v2r[i]],
+-			     &ctx, delete, decode, decrypt) != 0)
+-          {
+-            mx_close_mailbox (&ctx, NULL);
+-            return -1;
+-          }
++	  if ((rc = _mutt_save_message(Context->hdrs[Context->v2r[i]],
++			     &ctx, delete, decode, decrypt) != 0))
++	    break;
+ 	}
+       }
++#ifdef USE_NOTMUCH
++      if (Context->magic == M_NOTMUCH)
++        nm_longrun_done(Context);
++#endif
++      if (rc != 0) {
++	mx_close_mailbox (&ctx, NULL);
++	return -1;
++      }
+     }
+ 
+     need_buffy_cleanup = (ctx.magic == M_MBOX || ctx.magic == M_MMDF);
+diff -urN mutt-1.6.1-sidebar-notmuch/compose.c mutt-1.6.1-notmuch/compose.c
+--- mutt-1.6.1-sidebar-notmuch/compose.c	2016-05-02 03:02:12.705176285 +0100
++++ mutt-1.6.1-notmuch/compose.c	2016-05-02 03:02:15.221216316 +0100
+@@ -692,7 +692,8 @@
+ 	  numfiles = 0;
+ 	  files = NULL;
+ 
+-	  if (_mutt_enter_fname (prompt, fname, sizeof (fname), &menu->redraw, 0, 1, &files, &numfiles) == -1 ||
++	  if (_mutt_enter_fname (prompt, fname, sizeof (fname),
++			&menu->redraw, 0, 1, &files, &numfiles, 0) == -1 ||
+ 	      *fname == '\0')
+ 	    break;
+ 
+@@ -1237,7 +1238,7 @@
+          if (msg->content->next)
+            msg->content = mutt_make_multipart (msg->content);
+ 
+-         if (mutt_write_fcc (fname, msg, NULL, 0, NULL) < 0)
++         if (mutt_write_fcc (fname, msg, NULL, 0, NULL, NULL) < 0)
+            msg->content = mutt_remove_multipart (msg->content);
+          else
+            mutt_message _("Message written.");
+diff -urN mutt-1.6.1-sidebar-notmuch/configure.ac mutt-1.6.1-notmuch/configure.ac
+--- mutt-1.6.1-sidebar-notmuch/configure.ac	2016-05-02 03:02:12.705176285 +0100
++++ mutt-1.6.1-notmuch/configure.ac	2016-05-02 03:02:15.222216332 +0100
+@@ -184,6 +184,31 @@
+ ])
+ AM_CONDITIONAL(BUILD_SIDEBAR, test x$need_sidebar = xyes)
+ 
++AC_ARG_ENABLE(notmuch, AC_HELP_STRING([--enable-notmuch], [Enable NOTMUCH support]),
++[       if test x$enableval = xyes ; then
++		AC_CHECK_LIB(notmuch, notmuch_database_open,,
++			AC_MSG_ERROR([Unable to find Notmuch library]))
++		AC_DEFINE(USE_NOTMUCH,1,[ Define if you want support for the notmuch. ])
++		NOTMUCH_LIBS="-lnotmuch"
++		OPS="$OPS \$(srcdir)/OPS.NOTMUCH"
++		need_notmuch="yes"
++
++		AC_MSG_CHECKING([for notmuch api version 3])
++		AC_COMPILE_IFELSE( [AC_LANG_PROGRAM(
++					[[#include <notmuch.h>]],
++					[[notmuch_database_open("/path", NOTMUCH_DATABASE_MODE_READ_ONLY, (notmuch_database_t**)NULL);]]
++					)],
++		[notmuch_api_3=yes
++			AC_DEFINE([NOTMUCH_API_3], 1, [Define to 1 if you have the notmuch api version 3.])
++			],
++		[notmuch_api_3=no]
++		)
++		AC_MSG_RESULT([$notmuch_api_3])
++        fi
++])
++AM_CONDITIONAL(BUILD_NOTMUCH, test x$need_notmuch = xyes)
++
++
+ AC_ARG_WITH(mixmaster, AS_HELP_STRING([--with-mixmaster@<:@=PATH@:>@],[Include Mixmaster support]),
+   [if test "$withval" != no
+    then
+@@ -318,7 +343,7 @@
+ AC_HEADER_STDC
+ 
+ AC_CHECK_HEADERS(stdarg.h sys/ioctl.h ioctl.h sysexits.h)
+-AC_CHECK_HEADERS(sys/time.h sys/resource.h)
++AC_CHECK_HEADERS(sys/time.h sys/resource.h sys/syscall.h)
+ AC_CHECK_HEADERS(unix.h)
+ 
+ AC_CHECK_FUNCS(setrlimit getsid)
+@@ -1075,6 +1100,7 @@
+ AC_SUBST(MUTT_LIB_OBJECTS)
+ AC_SUBST(LIBIMAP)
+ AC_SUBST(LIBIMAPDEPS)
++AC_SUBST(NOTMUCH_LIBS)
+ 
+ dnl -- iconv/gettext --
+ 
+diff -urN mutt-1.6.1-sidebar-notmuch/copy.c mutt-1.6.1-notmuch/copy.c
+--- mutt-1.6.1-sidebar-notmuch/copy.c	2016-05-02 03:02:12.705176285 +0100
++++ mutt-1.6.1-notmuch/copy.c	2016-05-02 03:02:15.125214788 +0100
+@@ -30,6 +30,10 @@
+ #include "mutt_idna.h"
+ #include "mutt_curses.h"
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #include <string.h>
+ #include <stdlib.h>
+ #include <ctype.h>
+@@ -334,6 +338,7 @@
+ 	CH_NOQFROM      ignore ">From " line
+ 	CH_UPDATE_IRT	update the In-Reply-To: header
+ 	CH_UPDATE_REFS	update the References: header
++	CH_VIRTUAL      write virtual header lines too
+ 
+    prefix
+    	string to use if CH_PREFIX is set
+@@ -347,7 +352,7 @@
+   if (h->env)
+     flags |= (h->env->irt_changed ? CH_UPDATE_IRT : 0)
+       | (h->env->refs_changed ? CH_UPDATE_REFS : 0);
+-  
++
+   if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1)
+     return -1;
+ 
+@@ -413,6 +418,15 @@
+       fprintf (out, "Lines: %d\n", h->lines);
+   }
+ 
++#ifdef USE_NOTMUCH
++  if ((flags & CH_VIRTUAL) && nm_header_get_tags(h))
++  {
++    fputs ("Tags: ", out);
++    fputs (nm_header_get_tags(h), out);
++    fputc ('\n', out);
++  }
++#endif
++
+   if ((flags & CH_NONEWLINE) == 0)
+   {
+     if (flags & CH_PREFIX)
+@@ -682,7 +696,7 @@
+ {
+   MESSAGE *msg;
+   int r;
+-  
++
+   if ((msg = mx_open_message (src, hdr->msgno)) == NULL)
+     return -1;
+   if ((r = _mutt_copy_message (fpout, msg->fp, hdr, hdr->content, flags, chflags)) == 0 
+@@ -717,7 +731,7 @@
+   fseeko (fpin, hdr->offset, 0);
+   if (fgets (buf, sizeof (buf), fpin) == NULL)
+     return -1;
+-  
++
+   if ((msg = mx_open_new_message (dest, hdr, is_from (buf, NULL, 0, NULL) ? 0 : M_ADD_FROM)) == NULL)
+     return -1;
+   if (dest->magic == M_MBOX || dest->magic == M_MMDF)
+@@ -727,6 +741,11 @@
+   if (mx_commit_message (msg, dest) != 0)
+     r = -1;
+ 
++#ifdef USE_NOTMUCH
++  if (hdr && msg->commited_path && dest->magic == M_MAILDIR && src->magic == M_NOTMUCH)
++	  nm_update_filename(src, NULL, msg->commited_path, hdr);
++#endif
++
+   mx_close_message (&msg);
+   return r;
+ }
+diff -urN mutt-1.6.1-sidebar-notmuch/copy.h mutt-1.6.1-notmuch/copy.h
+--- mutt-1.6.1-sidebar-notmuch/copy.h	2016-05-02 03:02:12.705176285 +0100
++++ mutt-1.6.1-notmuch/copy.h	2016-05-02 03:02:15.125214788 +0100
+@@ -53,6 +53,7 @@
+ #define CH_UPDATE_IRT     (1<<16) /* update In-Reply-To: */
+ #define CH_UPDATE_REFS    (1<<17) /* update References: */
+ #define CH_DISPLAY        (1<<18) /* display result to user */
++#define CH_VIRTUAL	  (1<<19) /* write virtual header lines too */
+ 
+ 
+ int mutt_copy_hdr (FILE *, FILE *, LOFF_T, LOFF_T, int, const char *);
+diff -urN mutt-1.6.1-sidebar-notmuch/curs_lib.c mutt-1.6.1-notmuch/curs_lib.c
+--- mutt-1.6.1-sidebar-notmuch/curs_lib.c	2016-05-02 03:02:12.706176301 +0100
++++ mutt-1.6.1-notmuch/curs_lib.c	2016-05-02 03:02:15.126214804 +0100
+@@ -44,6 +44,10 @@
+ #include <langinfo.h>
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ /* not possible to unget more than one char under some curses libs, and it
+  * is impossible to unget function keys in SLang, so roll our own input
+  * buffering routines.
+@@ -624,7 +628,9 @@
+   return rc;
+ }
+ 
+-int _mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, int buffy, int multiple, char ***files, int *numfiles)
++int _mutt_enter_fname (const char *prompt, char *buf, size_t blen,
++		int *redraw, int buffy, int multiple,
++		char ***files, int *numfiles, int flags)
+ {
+   event_t ch;
+ 
+@@ -647,8 +653,10 @@
+   {
+     mutt_refresh ();
+     buf[0] = 0;
+-    _mutt_select_file (buf, blen, M_SEL_FOLDER | (multiple ? M_SEL_MULTI : 0), 
+-		       files, numfiles);
++    if (!flags)
++      flags = M_SEL_FOLDER | (multiple ? M_SEL_MULTI : 0);
++
++    _mutt_select_file (buf, blen, flags, files, numfiles);
+     *redraw = REDRAW_FULL;
+   }
+   else
+@@ -662,6 +670,10 @@
+       buf[0] = 0;
+     MAYBE_REDRAW (*redraw);
+     FREE (&pc);
++#ifdef USE_NOTMUCH
++    if ((flags & M_SEL_VFOLDER) && buf[0] && strncmp(buf, "notmuch://", 10) != 0)
++      nm_description_to_path(buf, buf, blen);
++#endif
+   }
+ 
+   return 0;
+diff -urN mutt-1.6.1-sidebar-notmuch/curs_main.c mutt-1.6.1-notmuch/curs_main.c
+--- mutt-1.6.1-sidebar-notmuch/curs_main.c	2016-05-02 03:02:12.706176301 +0100
++++ mutt-1.6.1-notmuch/curs_main.c	2016-05-02 03:02:15.222216332 +0100
+@@ -41,6 +41,10 @@
+ #include "imap_private.h"
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #include "mutt_crypt.h"
+ 
+ 
+@@ -590,6 +594,70 @@
+ 	safe_free (&lineInfo.syntax);
+ }
+ 
++static int main_change_folder(MUTTMENU *menu, int op, char *buf, size_t bufsz,
++			  int *oldcount, int *index_hint)
++{
++  mutt_expand_path (buf, bufsz);
++#ifdef USE_SIDEBAR
++  sb_set_open_buffy (buf);
++#endif
++  if (mx_get_magic (buf) <= 0)
++  {
++    mutt_error (_("%s is not a mailbox."), buf);
++    return -1;
++  }
++  mutt_str_replace (&CurrentFolder, buf);
++
++  /* keepalive failure in mutt_enter_fname may kill connection. #3028 */
++  if (Context && !Context->path)
++    FREE (&Context);
++
++  if (Context)
++  {
++    int check;
++
++    mutt_str_replace (&LastFolder, Context->path);
++    *oldcount = Context ? Context->msgcount : 0;
++
++    if ((check = mx_close_mailbox (Context, index_hint)) != 0)
++    {
++      if (check == M_NEW_MAIL || check == M_REOPENED)
++        update_index (menu, Context, check, *oldcount, *index_hint);
++
++      set_option (OPTSEARCHINVALID);
++      menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
++      return 0;
++    }
++    FREE (&Context);
++  }
++
++  mutt_sleep (0);
++
++  /* Set CurrentMenu to MENU_MAIN before executing any folder
++   * hooks so that all the index menu functions are available to
++   * the exec command.
++   */
++
++  CurrentMenu = MENU_MAIN;
++  mutt_folder_hook (buf);
++
++  if ((Context = mx_open_mailbox (buf,
++		(option (OPTREADONLY) || op == OP_MAIN_CHANGE_FOLDER_READONLY) ?
++		M_READONLY : 0, NULL)) != NULL)
++  {
++    menu->current = ci_first_message ();
++  }
++  else
++    menu->current = 0;
++
++  mutt_clear_error ();
++  mutt_buffy_check(1); /* force the buffy check after we have changed the folder */
++  menu->redraw = REDRAW_FULL;
++  set_option (OPTSEARCHINVALID);
++
++  return 0;
++}
++
+ static const struct mapping_t IndexHelp[] = {
+   { N_("Quit"),  OP_QUIT },
+   { N_("Del"),   OP_DELETE },
+@@ -900,6 +968,11 @@
+       mutt_curs_set (1);	/* fallback from the pager */
+     }
+ 
++#ifdef USE_NOTMUCH
++    if (Context)
++      nm_debug_check(Context);
++#endif
++
+     switch (op)
+     {
+ 
+@@ -1309,6 +1382,131 @@
+ 	}
+ 	break;
+ 
++#ifdef USE_NOTMUCH
++      case OP_MAIN_ENTIRE_THREAD:
++      {
++	int oldcount  = Context->msgcount;
++	if (Context->magic != M_NOTMUCH) {
++	  mutt_message _("No virtual folder, aborting.");
++	  break;
++	}
++	CHECK_MSGCOUNT;
++        CHECK_VISIBLE;
++	if (nm_read_entire_thread(Context, CURHDR) < 0) {
++	   mutt_message _("Failed to read thread, aborting.");
++	   break;
++	}
++	if (oldcount < Context->msgcount) {
++		HEADER *oldcur = CURHDR;
++
++		if ((Sort & SORT_MASK) == SORT_THREADS)
++			mutt_sort_headers (Context, 0);
++		menu->current = oldcur->virtual;
++		menu->redraw = REDRAW_STATUS | REDRAW_INDEX;
++
++		if (oldcur->collapsed || Context->collapsed) {
++			menu->current = mutt_uncollapse_thread(Context, CURHDR);
++			mutt_set_virtual(Context);
++		}
++	}
++	if (menu->menu == MENU_PAGER)
++	{
++	  op = OP_DISPLAY_MESSAGE;
++	  continue;
++	}
++	break;
++      }
++
++      case OP_MAIN_MODIFY_LABELS:
++      case OP_MAIN_MODIFY_LABELS_THEN_HIDE:
++      {
++	if (Context->magic != M_NOTMUCH) {
++	  mutt_message _("No virtual folder, aborting.");
++	  break;
++	}
++	CHECK_MSGCOUNT;
++        CHECK_VISIBLE;
++	*buf = '\0';
++	if (mutt_get_field ("Add/remove labels: ", buf, sizeof (buf), M_NM_TAG) || !*buf)
++	{
++          mutt_message _("No label specified, aborting.");
++          break;
++        }
++	if (tag)
++	{
++	  char msgbuf[STRING];
++	  progress_t progress;
++	  int px;
++
++	  if (!Context->quiet) {
++	    snprintf(msgbuf, sizeof (msgbuf), _("Update labels..."));
++	    mutt_progress_init(&progress, msgbuf, M_PROGRESS_MSG,
++				   1, Context->tagged);
++	  }
++	  nm_longrun_init(Context, TRUE);
++	  for (px = 0, j = 0; j < Context->vcount; j++) {
++	    if (Context->hdrs[Context->v2r[j]]->tagged) {
++	      if (!Context->quiet)
++		mutt_progress_update(&progress, ++px, -1);
++	      nm_modify_message_tags(Context, Context->hdrs[Context->v2r[j]], buf);
++	      if (op == OP_MAIN_MODIFY_LABELS_THEN_HIDE)
++	      {
++		Context->hdrs[Context->v2r[j]]->quasi_deleted = TRUE;
++	        Context->changed = TRUE;
++	      }
++	    }
++	  }
++	  nm_longrun_done(Context);
++	  menu->redraw = REDRAW_STATUS | REDRAW_INDEX;
++	}
++	else
++	{
++	  if (nm_modify_message_tags(Context, CURHDR, buf)) {
++	    mutt_message _("Failed to modify labels, aborting.");
++	    break;
++	  }
++	  if (op == OP_MAIN_MODIFY_LABELS_THEN_HIDE)
++	  {
++	    CURHDR->quasi_deleted = TRUE;
++	    Context->changed = TRUE;
++	  }
++	  if (menu->menu == MENU_PAGER)
++	  {
++	    op = OP_DISPLAY_MESSAGE;
++	    continue;
++	  }
++	  if (option (OPTRESOLVE))
++	  {
++	    if ((menu->current = ci_next_undeleted (menu->current)) == -1)
++	    {
++	      menu->current = menu->oldcurrent;
++	      menu->redraw = REDRAW_CURRENT;
++	    }
++	    else
++	      menu->redraw = REDRAW_MOTION_RESYNCH;
++	  }
++	  else
++	    menu->redraw = REDRAW_CURRENT;
++	}
++	menu->redraw |= REDRAW_STATUS;
++	break;
++      }
++
++      case OP_MAIN_VFOLDER_FROM_QUERY:
++	buf[0] = '\0';
++        if (mutt_get_field ("Query: ", buf, sizeof (buf), M_NM_QUERY) != 0 || !buf[0])
++        {
++          mutt_message _("No query, aborting.");
++          break;
++        }
++	if (!nm_uri_from_query(Context, buf, sizeof (buf)))
++	  mutt_message _("Failed to create query, aborting.");
++	else
++	  main_change_folder(menu, op, buf, sizeof (buf), &oldcount, &index_hint);
++	break;
++
++      case OP_MAIN_CHANGE_VFOLDER:
++#endif
+ #ifdef USE_SIDEBAR
+       case OP_SIDEBAR_OPEN:
+ #endif
+@@ -1324,7 +1522,11 @@
+ 
+         if ((op == OP_MAIN_CHANGE_FOLDER_READONLY) || option (OPTREADONLY))
+           cp = _("Open mailbox in read-only mode");
+-        else
++#ifdef USE_NOTMUCH
++        else if (op == OP_MAIN_CHANGE_VFOLDER)
++	  cp = _("Open virtual folder");
++#endif
++	else
+           cp = _("Open mailbox");
+ 
+ 	buf[0] = '\0';
+@@ -1339,6 +1541,20 @@
+ 	    break;
+ 	  }
+ 	}
++#ifdef USE_NOTMUCH
++	else if (op == OP_MAIN_CHANGE_VFOLDER) {
++	  if (Context->magic == M_NOTMUCH) {
++		  strfcpy(buf, Context->path, sizeof (buf));
++		  mutt_buffy_vfolder (buf, sizeof (buf));
++	  }
++	  mutt_enter_vfolder (cp, buf, sizeof (buf), &menu->redraw, 1);
++	  if (!buf[0])
++	  {
++	    CLEARLINE (LINES-1);
++	    break;
++	  }
++	}
++#endif
+ 	else
+ 	{
+ 	  mutt_buffy (buf, sizeof (buf));
+@@ -1368,65 +1584,7 @@
+ 	  }
+ 	}
+ 
+-	mutt_expand_path (buf, sizeof (buf));
+-#ifdef USE_SIDEBAR
+-	if (sb_set_open_buffy (buf) == NULL)
+-		break;
+-#endif
+-	if (mx_get_magic (buf) <= 0)
+-	{
+-	  mutt_error (_("%s is not a mailbox."), buf);
+-	  break;
+-	}
+-	mutt_str_replace (&CurrentFolder, buf);
+-
+-	/* keepalive failure in mutt_enter_fname may kill connection. #3028 */
+-	if (Context && !Context->path)
+-	  FREE (&Context);
+-
+-        if (Context)
+-        {
+-	  int check;
+-
+-	  mutt_str_replace (&LastFolder, Context->path);
+-	  oldcount = Context ? Context->msgcount : 0;
+-
+-	  if ((check = mx_close_mailbox (Context, &index_hint)) != 0)
+-	  {
+-	    if (check == M_NEW_MAIL || check == M_REOPENED)
+-	      update_index (menu, Context, check, oldcount, index_hint);
+-
+-	    set_option (OPTSEARCHINVALID);
+-	    menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
+-	    break;
+-	  }
+-	  FREE (&Context);
+-	}
+-
+-        mutt_sleep (0);
+-
+-	/* Set CurrentMenu to MENU_MAIN before executing any folder
+-	 * hooks so that all the index menu functions are available to
+-	 * the exec command.
+-	 */
+-
+-	CurrentMenu = MENU_MAIN;
+-	mutt_folder_hook (buf);
+-
+-	if ((Context = mx_open_mailbox (buf,
+-					(option (OPTREADONLY) || op == OP_MAIN_CHANGE_FOLDER_READONLY) ?
+-					M_READONLY : 0, NULL)) != NULL)
+-	{
+-	  menu->current = ci_first_message ();
+-	}
+-	else
+-	  menu->current = 0;
+-
+-	mutt_clear_error ();
+-	mutt_buffy_check(1); /* force the buffy check after we have changed
+-			      the folder */
+-	menu->redraw = REDRAW_FULL;
+-	set_option (OPTSEARCHINVALID);
++	main_change_folder(menu, op, buf, sizeof (buf), &oldcount, &index_hint);
+ 	break;
+ 
+       case OP_DISPLAY_MESSAGE:
+@@ -2498,12 +2656,21 @@
+ 	toggle_option (OPTSIDEBAR);
+ 	menu->redraw = REDRAW_FULL;
+ 	break;
++
++      case OP_SIDEBAR_TOGGLE_VIRTUAL:
++	sb_toggle_virtual();
++	break;
+ #endif
+       default:
+ 	if (menu->menu == MENU_MAIN)
+ 	  km_error_key (MENU_MAIN);
+     }
+ 
++#ifdef USE_NOTMUCH
++    if (Context)
++      nm_debug_check(Context);
++#endif
++
+     if (menu->menu == MENU_PAGER)
+     {
+       menu->menu = MENU_MAIN;
+diff -urN mutt-1.6.1-sidebar-notmuch/doc/manual.xml.head mutt-1.6.1-notmuch/doc/manual.xml.head
+--- mutt-1.6.1-sidebar-notmuch/doc/manual.xml.head	2016-05-02 03:02:12.709176349 +0100
++++ mutt-1.6.1-notmuch/doc/manual.xml.head	2016-05-02 03:02:15.224216363 +0100
+@@ -8776,7 +8776,7 @@
+ 			<listitem><para>mutt-1.5.24</para></listitem>
+ 		</itemizedlist>
+ 
+-		<para>This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.</para>
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ 	</sect2>
+ 
+ 	<sect2 id="quasi-delete-intro">
+@@ -8859,7 +8859,7 @@
+ 		<title>See Also</title>
+ 
+ 		<itemizedlist>
+-			<listitem><para><ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ 			<listitem><para><link linkend="notmuch">notmuch patch</link></para></listitem>
+ 		</itemizedlist>
+ 	</sect2>
+@@ -8896,7 +8896,7 @@
+ 			<listitem><para>mutt-1.5.24</para></listitem>
+ 		</itemizedlist>
+ 
+-		<para>This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.</para>
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ 	</sect2>
+ 
+ 	<sect2 id="progress-intro">
+@@ -8975,7 +8975,7 @@
+ 		<title>See Also</title>
+ 
+ 		<itemizedlist>
+-			<listitem><para><ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ 			<listitem><para><link linkend="color">Color command</link></para></listitem>
+ 		</itemizedlist>
+ 	</sect2>
+@@ -9015,7 +9015,7 @@
+ 			<listitem><para>mutt-1.5.24</para></listitem>
+ 		</itemizedlist>
+ 
+-		<para>This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.</para>
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ 	</sect2>
+ 
+ 	<sect2 id="status-color-intro">
+@@ -9175,7 +9175,7 @@
+ 		<title>See Also</title>
+ 
+ 		<itemizedlist>
+-			<listitem><para><ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ 			<listitem><para><link linkend="compile-time-features">Compile-Time Features</link></para></listitem>
+ 			<listitem><para><link linkend="regexp">Regular Expressions</link></para></listitem>
+ 			<listitem><para><link linkend="patterns">Patterns</link></para></listitem>
+@@ -9219,7 +9219,7 @@
+ 			<listitem><para><link linkend="status-color">status-color patch</link></para></listitem>
+ 		</itemizedlist>
+ 
+-		<para>This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.</para>
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ 	</sect2>
+ 
+ 	<sect2 id="index-color-intro">
+@@ -9398,7 +9398,7 @@
+ 		<title>See Also</title>
+ 
+ 		<itemizedlist>
+-			<listitem><para><ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ 			<listitem><para><link linkend="regexp">Regular Expressions</link></para></listitem>
+ 			<listitem><para><link linkend="patterns">Patterns</link></para></listitem>
+ 			<listitem><para><link linkend="index-format">$index_format</link></para></listitem>
+@@ -9444,7 +9444,7 @@
+ 			<listitem><para>mutt-1.5.24</para></listitem>
+ 		</itemizedlist>
+ 
+-		<para>This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.</para>
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ 	</sect2>
+ 
+ 	<sect2 id="nested-if-intro">
+@@ -9621,7 +9621,7 @@
+ 		<title>See Also</title>
+ 
+ 		<itemizedlist>
+-			<listitem><para><ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ 			<listitem><para><link linkend="cond-date">cond-date patch</link></para></listitem>
+ 			<listitem><para><link linkend="index-format">$index_format</link></para></listitem>
+ 			<listitem><para><link linkend="status-format">$status_format</link></para></listitem>
+@@ -9662,7 +9662,7 @@
+ 		</itemizedlist>
+ 
+ 		<para>
+-			This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.
++			This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.
+ 		</para>
+ 	</sect2>
+ 
+@@ -10019,7 +10019,7 @@
+ 		<title>See Also</title>
+ 
+ 		<itemizedlist>
+-			<listitem><para><ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ 			<listitem><para><link linkend="index-format">$index_format</link></para></listitem>
+ 			<listitem><para><link linkend="nested-if">nested-if patch</link></para></listitem>
+ 			<listitem><para><literal>strftime(3)</literal></para></listitem>
+@@ -10068,7 +10068,7 @@
+ 			<listitem><para>OpenSSL</para></listitem>
+ 		</itemizedlist>
+ 
+-		<para>This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.</para>
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ 	</sect2>
+ 
+ 	<sect2 id="tls-sni-intro">
+@@ -10137,7 +10137,7 @@
+ 		<title>See Also</title>
+ 
+ 		<itemizedlist>
+-			<listitem><para><ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
+ 		</itemizedlist>
+ 	</sect2>
+ 
+@@ -10174,7 +10174,7 @@
+ 			<listitem><para>mutt-1.5.24</para></listitem>
+ 		</itemizedlist>
+ 
+-		<para>This patch is part of the <ulink url="https://github.com/neomutt/neomutt/wiki">NeoMutt Project</ulink>.</para>
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
+ 	</sect2>
+ 
+ 	<sect2 id="sidebar-intro">
+diff -urN mutt-1.6.1-sidebar-notmuch/enter.c mutt-1.6.1-notmuch/enter.c
+--- mutt-1.6.1-sidebar-notmuch/enter.c	2016-05-02 03:02:12.709176349 +0100
++++ mutt-1.6.1-notmuch/enter.c	2016-05-02 03:02:15.132214900 +0100
+@@ -630,6 +630,27 @@
+ 	      BEEP (); /* let the user know that nothing matched */
+ 	    replace_part (state, 0, buf);
+ 	  }
++#if USE_NOTMUCH
++	  else if (flags & M_NM_QUERY)
++	  {
++	    my_wcstombs (buf, buflen, state->wbuf, state->curpos);
++	    i = strlen (buf);
++	    if (!mutt_nm_query_complete(buf, buflen, i, state->tabs))
++	      BEEP ();
++
++	    replace_part (state, 0, buf);
++	  }
++	  else if (flags & M_NM_TAG)
++	  {
++	    my_wcstombs (buf, buflen, state->wbuf, state->curpos);
++	    i = strlen (buf);
++	    if (!mutt_nm_tag_complete(buf, buflen, i, state->tabs))
++	      BEEP ();
++
++	    replace_part (state, 0, buf);
++	  }
++
++#endif
+ 	  else
+ 	    goto self_insert;
+ 	  break;
+diff -urN mutt-1.6.1-sidebar-notmuch/functions.h mutt-1.6.1-notmuch/functions.h
+--- mutt-1.6.1-sidebar-notmuch/functions.h	2016-05-02 03:02:12.709176349 +0100
++++ mutt-1.6.1-notmuch/functions.h	2016-05-02 03:02:15.225216379 +0100
+@@ -177,9 +177,17 @@
+   { "sidebar-page-up",		OP_SIDEBAR_PAGE_UP,		NULL },
+   { "sidebar-prev",		OP_SIDEBAR_PREV,		NULL },
+   { "sidebar-prev-new",		OP_SIDEBAR_PREV_NEW,		NULL },
++  { "sidebar-toggle-virtual",	OP_SIDEBAR_TOGGLE_VIRTUAL,	NULL },
+   { "sidebar-toggle-visible",	OP_SIDEBAR_TOGGLE_VISIBLE,	NULL },
+ #endif
+ 
++#ifdef USE_NOTMUCH
++  { "change-vfolder",		OP_MAIN_CHANGE_VFOLDER,         "X" },
++  { "vfolder-from-query",	OP_MAIN_VFOLDER_FROM_QUERY,     "\033X" },
++  { "modify-labels",		OP_MAIN_MODIFY_LABELS,		"`" },
++  { "modify-labels-then-hide",	OP_MAIN_MODIFY_LABELS_THEN_HIDE, NULL },
++  { "entire-thread",		OP_MAIN_ENTIRE_THREAD,          "+" },
++#endif
+   { NULL,			0,				NULL }
+ };
+ 
+@@ -292,9 +300,18 @@
+   { "sidebar-page-up",		OP_SIDEBAR_PAGE_UP,		NULL },
+   { "sidebar-prev",		OP_SIDEBAR_PREV,		NULL },
+   { "sidebar-prev-new",		OP_SIDEBAR_PREV_NEW,		NULL },
++  { "sidebar-toggle-virtual",	OP_SIDEBAR_TOGGLE_VIRTUAL,	NULL },
+   { "sidebar-toggle-visible",	OP_SIDEBAR_TOGGLE_VISIBLE,	NULL },
+ #endif
+ 
++#ifdef USE_NOTMUCH
++  { "change-vfolder",		OP_MAIN_CHANGE_VFOLDER,		"X" },
++  { "vfolder-from-query",	OP_MAIN_VFOLDER_FROM_QUERY,	"\033X" },
++  { "modify-labels",		OP_MAIN_MODIFY_LABELS,		"`" },
++  { "modify-labels-then-hide",	OP_MAIN_MODIFY_LABELS_THEN_HIDE, NULL },
++  { "entire-thread",		OP_MAIN_ENTIRE_THREAD,          "+" },
++#endif
++
+   { NULL,		0,				NULL }
+ };
+ 
+diff -urN mutt-1.6.1-sidebar-notmuch/globals.h mutt-1.6.1-notmuch/globals.h
+--- mutt-1.6.1-sidebar-notmuch/globals.h	2016-05-02 03:02:12.709176349 +0100
++++ mutt-1.6.1-notmuch/globals.h	2016-05-02 03:02:15.225216379 +0100
+@@ -161,6 +161,10 @@
+ 
+ WHERE HASH *Groups;
+ WHERE HASH *ReverseAlias;
++#ifdef USE_NOTMUCH
++WHERE HASH *TagTransforms;
++WHERE HASH *TagFormats;
++#endif
+ 
+ WHERE LIST *AutoViewList INITVAL(0);
+ WHERE LIST *AlternativeOrderList INITVAL(0);
+@@ -281,6 +285,17 @@
+ WHERE char *SmimeImportCertCommand;
+ WHERE char *SmimeGetCertEmailCommand;
+ 
++#ifdef USE_NOTMUCH
++WHERE int NotmuchOpenTimeout;
++WHERE char *NotmuchDefaultUri;
++WHERE char *NotmuchExcludeTags;
++WHERE char *NotmuchUnreadTag;
++WHERE char *NotmuchHiddenTags;
++WHERE char *VirtFolderFormat;
++WHERE int NotmuchDBLimit;
++WHERE char *NotmuchQueryType;
++WHERE char *NotmuchRecordTags;
++#endif
+ 
+ 
+ 
+diff -urN mutt-1.6.1-sidebar-notmuch/hdrline.c mutt-1.6.1-notmuch/hdrline.c
+--- mutt-1.6.1-sidebar-notmuch/hdrline.c	2016-05-02 03:02:12.710176365 +0100
++++ mutt-1.6.1-notmuch/hdrline.c	2016-05-02 03:02:15.226216395 +0100
+@@ -36,6 +36,10 @@
+ #include <alloca.h>
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ int mutt_is_mail_list (ADDRESS *addr)
+ {
+   if (!mutt_match_rx_list (addr->mailbox, UnMailLists))
+@@ -243,6 +247,7 @@
+  * %E = number of messages in current thread
+  * %f = entire from line
+  * %F = like %n, unless from self
++ * %g = message labels (e.g. notmuch tags)
+  * %i = message-id
+  * %l = number of lines in the message
+  * %L = like %F, except `lists' are displayed first
+@@ -585,6 +590,19 @@
+         optional = 0;
+       break;
+ 
++#ifdef USE_NOTMUCH
++    case 'g':
++      if (!optional)
++      {
++        colorlen = add_index_color(dest, destlen, flags, MT_COLOR_INDEX_TAGS);
++        mutt_format_s (dest+colorlen, destlen-colorlen, prefix, nm_header_get_tags_transformed(hdr));
++        add_index_color(dest+colorlen, destlen-colorlen, flags, MT_COLOR_INDEX);
++      }
++      else if (!nm_header_get_tags_transformed(hdr))
++        optional = 0;
++      break;
++#endif
++
+     case 'H':
+       /* (Hormel) spam score */
+       if (optional)
+@@ -892,6 +910,48 @@
+ 
+       break;
+ 
++#ifdef USE_NOTMUCH
++    case 'G':
++    {
++      char *tag_transformed;
++      char format[3];
++      char *tag;
++
++      if (!optional)
++      {
++        format[0] = op;
++        format[1] = *src;
++        format[2] = 0;
++
++        tag = hash_find(TagFormats, format);
++        if (tag != NULL)
++        {
++            tag_transformed = nm_header_get_tag_transformed(tag, hdr);
++
++            colorlen = add_index_color(dest, destlen, flags, MT_COLOR_INDEX_TAG);
++            mutt_format_s (dest+colorlen, destlen-colorlen, prefix,
++                           (tag_transformed) ? tag_transformed : "");
++            add_index_color(dest+colorlen, destlen-colorlen, flags, MT_COLOR_INDEX);
++        }
++
++        src++;
++      }
++      else
++      {
++        format[0] = op;
++        format[1] = *prefix;
++        format[2] = 0;
++
++        tag = hash_find(TagFormats, format);
++        if (tag != NULL)
++          if (nm_header_get_tag_transformed(tag, hdr) == NULL)
++            optional = 0;
++      }
++
++      break;
++    }
++#endif
++
+     default:
+       snprintf (dest, destlen, "%%%s%c", prefix, op);
+       break;
+diff -urN mutt-1.6.1-sidebar-notmuch/init.c mutt-1.6.1-notmuch/init.c
+--- mutt-1.6.1-sidebar-notmuch/init.c	2016-05-02 03:02:12.711176381 +0100
++++ mutt-1.6.1-notmuch/init.c	2016-05-02 03:02:15.227216411 +0100
+@@ -37,7 +37,9 @@
+ #include "mutt_ssl.h"
+ #endif
+ 
+-
++#if USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
+ 
+ #include "mx.h"
+ #include "init.h"
+@@ -76,6 +78,12 @@
+ static const char* myvar_get (const char* var);
+ static void myvar_del (const char* var);
+ 
++#if USE_NOTMUCH
++/* List of tags found in last call to mutt_nm_query_complete(). */
++static char **nm_tags;
++#endif
++
++
+ static void toggle_quadoption (int opt)
+ {
+   int n = opt/4;
+@@ -2636,6 +2644,182 @@
+   return 0;
+ }
+ 
++#if USE_NOTMUCH
++
++/* Fetch a list of all notmuch tags and insert them into the completion
++ * machinery.
++ */
++static int complete_all_nm_tags (const char *pt)
++{
++  int num;
++  int tag_count_1 = 0;
++  int tag_count_2 = 0;
++
++  Num_matched = 0;
++  strfcpy (User_typed, pt, sizeof (User_typed));
++  memset (Matches, 0, Matches_listsize);
++  memset (Completed, 0, sizeof (Completed));
++
++  nm_longrun_init(Context, FALSE);
++
++  /* Work out how many tags there are. */
++  if (nm_get_all_tags(Context, NULL, &tag_count_1) || tag_count_1 == 0)
++    goto done;
++
++  /* Free the old list, if any. */
++  if (nm_tags != NULL) {
++    int i;
++    for (i = 0; nm_tags[i] != NULL; i++)
++      FREE (&nm_tags[i]);
++    FREE (&nm_tags);
++  }
++  /* Allocate a new list, with sentinel. */
++  nm_tags = safe_malloc((tag_count_1 + 1) * sizeof (char *));
++  nm_tags[tag_count_1] = NULL;
++
++  /* Get all the tags. */
++  if (nm_get_all_tags(Context, nm_tags, &tag_count_2) ||
++      tag_count_1 != tag_count_2) {
++    FREE (&nm_tags);
++    nm_tags = NULL;
++    nm_longrun_done(Context);
++    return -1;
++  }
++
++  /* Put them into the completion machinery. */
++  for (num = 0; num < tag_count_1; num++) {
++    candidate (Completed, User_typed, nm_tags[num], sizeof (Completed));
++  }
++
++  matches_ensure_morespace (Num_matched);
++  Matches[Num_matched++] = User_typed;
++
++done:
++  nm_longrun_done(Context);
++  return 0;
++}
++
++/* Return the last instance of needle in the haystack, or NULL.
++ * Like strstr(), only backwards, and for a limited haystack length.
++ */
++static const char* rstrnstr(const char* haystack,
++                            size_t haystack_length,
++                            const char* needle)
++{
++  int needle_length = strlen(needle);
++  const char* haystack_end = haystack + haystack_length - needle_length;
++  const char* p;
++
++  for (p = haystack_end; p >= haystack; --p)
++  {
++    size_t i;
++    for (i = 0; i < needle_length; ++i) {
++      if (p[i] != needle[i])
++        goto next;
++    }
++    return p;
++
++    next:;
++  }
++  return NULL;
++}
++
++/* Complete the nearest "tag:"-prefixed string previous to pos. */
++int mutt_nm_query_complete (char *buffer, size_t len, int pos, int numtabs)
++{
++  char *pt = buffer;
++  int spaces;
++
++  SKIPWS (buffer);
++  spaces = buffer - pt;
++
++  pt = (char *)rstrnstr((char *)buffer, pos, "tag:");
++  if (pt != NULL) {
++    pt += 4;
++    if (numtabs == 1) {
++      /* First TAB. Collect all the matches */
++      complete_all_nm_tags(pt);
++
++      /* All matches are stored. Longest non-ambiguous string is ""
++       * i.e. don't change 'buffer'. Fake successful return this time.
++       */
++      if (User_typed[0] == 0)
++	return 1;
++    }
++
++    if (Completed[0] == 0 && User_typed[0])
++      return 0;
++
++    /* Num_matched will _always_ be atleast 1 since the initial
++     * user-typed string is always stored */
++    if (numtabs == 1 && Num_matched == 2)
++      snprintf(Completed, sizeof(Completed),"%s", Matches[0]);
++    else if (numtabs > 1 && Num_matched > 2)
++      /* cycle thru all the matches */
++      snprintf(Completed, sizeof(Completed), "%s",
++	       Matches[(numtabs - 2) % Num_matched]);
++
++    /* return the completed query */
++    strncpy (pt, Completed, buffer + len - pt - spaces);
++  }
++  else
++    return 0;
++
++  return 1;
++}
++
++/* Complete the nearest "+" or "-" -prefixed string previous to pos. */
++int mutt_nm_tag_complete (char *buffer, size_t len, int pos, int numtabs)
++{
++  char *pt = buffer;
++  int spaces;
++  const char *first_plus = NULL;
++  const char *first_minus = NULL;
++
++  SKIPWS (buffer);
++  spaces = buffer - pt;
++
++  first_plus = rstrnstr((char *)buffer, pos, "+");
++  first_minus = rstrnstr((char *)buffer, pos, "-");
++  pt = (char *)MAX(first_plus, first_minus);
++
++  if (pt != NULL) {
++    pt++;
++
++    if (numtabs == 1)
++    {
++      /* First TAB. Collect all the matches */
++      complete_all_nm_tags(pt);
++
++      /* All matches are stored. Longest non-ambiguous string is ""
++       * i.e. don't change 'buffer'. Fake successful return this time.
++       */
++      if (User_typed[0] == 0)
++	return 1;
++    }
++
++    if (Completed[0] == 0 && User_typed[0])
++      return 0;
++
++    /* Num_matched will _always_ be atleast 1 since the initial
++     * user-typed string is always stored */
++    if (numtabs == 1 && Num_matched == 2)
++      snprintf(Completed, sizeof(Completed),"%s", Matches[0]);
++    else if (numtabs > 1 && Num_matched > 2)
++      /* cycle thru all the matches */
++      snprintf(Completed, sizeof(Completed), "%s",
++	       Matches[(numtabs - 2) % Num_matched]);
++
++    /* return the completed query */
++    strncpy (pt, Completed, buffer + len - pt - spaces);
++  }
++  else
++    return 0;
++
++  return 1;
++}
++#endif
++
+ static int var_to_string (int idx, char* val, size_t len)
+ {
+   char tmp[LONG_STRING];
+@@ -2886,7 +3070,11 @@
+ 
+   Groups = hash_create (1031, 0);
+   ReverseAlias = hash_create (1031, 1);
+-  
++#ifdef USE_NOTMUCH
++  TagTransforms = hash_create (64, 1);
++  TagFormats = hash_create (64, 0);
++#endif
++
+   mutt_menu_init ();
+ 
+   snprintf (AttachmentMarker, sizeof (AttachmentMarker),
+@@ -3170,6 +3358,11 @@
+ 
+   mutt_read_histfile ();
+ 
++#ifdef USE_NOTMUCH
++  if (option (OPTVIRTSPOOLFILE) && VirtIncoming)
++    mutt_str_replace(&Spoolfile, VirtIncoming->path);
++#endif
++
+ #if 0
+   set_option (OPTWEED); /* turn weeding on by default */
+ #endif
+@@ -3217,6 +3410,70 @@
+   return -1;
+ }
+ 
++#ifdef USE_NOTMUCH
++int parse_tag_transforms (BUFFER *b, BUFFER *s, unsigned long data, BUFFER *err)
++{
++  char *tmp;
++
++  while (MoreArgs (s))
++  {
++    char *tag, *transform;
++
++    mutt_extract_token (b, s, 0);
++    if (b->data && *b->data)
++      tag = safe_strdup (b->data);
++    else
++      continue;
++
++    mutt_extract_token (b, s, 0);
++    transform = safe_strdup (b->data);
++
++    /* avoid duplicates */
++    tmp = hash_find(TagTransforms, tag);
++    if (tmp) {
++      dprint(3,(debugfile,"tag transform '%s' already registered as '%s'\n", tag, tmp));
++      FREE(&tag);
++      FREE(&transform);
++      continue;
++    }
++
++    hash_insert(TagTransforms, tag, transform, 0);
++  }
++  return 0;
++}
++
++int parse_tag_formats (BUFFER *b, BUFFER *s, unsigned long data, BUFFER *err)
++{
++  char *tmp;
++
++  while (MoreArgs (s))
++  {
++    char *tag, *format;
++
++    mutt_extract_token (b, s, 0);
++    if (b->data && *b->data)
++      tag = safe_strdup (b->data);
++    else
++      continue;
++
++    mutt_extract_token (b, s, 0);
++    format = safe_strdup (b->data);
++
++    /* avoid duplicates */
++    tmp = hash_find(TagFormats, format);
++    if (tmp) {
++      dprint(3,(debugfile,"tag format '%s' already registered as '%s'\n", format, tmp));
++      FREE(&tag);
++      FREE(&format);
++      continue;
++    }
++
++    hash_insert(TagFormats, format, tag, 0);
++  }
++  return 0;
++}
++#endif
++
+ static void myvar_set (const char* var, const char* val)
+ {
+   myvar_t** cur;
+diff -urN mutt-1.6.1-sidebar-notmuch/init.h mutt-1.6.1-notmuch/init.h
+--- mutt-1.6.1-sidebar-notmuch/init.h	2016-05-02 03:02:12.713176413 +0100
++++ mutt-1.6.1-notmuch/init.h	2016-05-02 03:02:15.228216427 +0100
+@@ -1316,6 +1316,7 @@
+   ** .dt %E .dd number of messages in current thread
+   ** .dt %f .dd sender (address + real name), either From: or Return-Path:
+   ** .dt %F .dd author name, or recipient name if the message is from you
++  ** .dt %g .dd message labels (e.g. notmuch tags)
+   ** .dt %H .dd spam attribute(s) of this message
+   ** .dt %i .dd message-id of the current message
+   ** .dt %l .dd number of lines in the message (does not work with maildir,
+@@ -1668,6 +1669,60 @@
+    ** See also $$read_inc, $$write_inc and $$net_inc.
+    */
+ #endif
++#ifdef USE_NOTMUCH
++  { "nm_open_timeout", DT_NUM, R_NONE, UL &NotmuchOpenTimeout, 5 },
++  /*
++   ** .pp
++   ** This variable specifies the timeout for database open in seconds.
++   */
++
++  { "nm_default_uri", DT_STR, R_NONE, UL &NotmuchDefaultUri, 0 },
++  /*
++   ** .pp
++   ** This variable specifies the default Notmuch database in format
++   ** notmuch://<absolute path>.
++   */
++
++  { "nm_hidden_tags", DT_STR, R_NONE, UL &NotmuchHiddenTags, UL "unread,draft,flagged,passed,replied,attachment,signed,encrypted" },
++  /*
++   ** .pp
++   ** This variable specifies private notmuch tags which should not be printed
++   ** on screen.
++   */
++  { "nm_exclude_tags", DT_STR,  R_NONE, UL &NotmuchExcludeTags, 0 },
++  /*
++   ** .pp
++   ** The messages tagged with these tags are excluded and not loaded
++   ** from notmuch DB to mutt unless specified explicitly.
++   */
++  { "nm_unread_tag", DT_STR, R_NONE, UL &NotmuchUnreadTag, UL "unread" },
++  /*
++   ** .pp
++   ** This variable specifies notmuch tag which is used for unread messages. The
++   ** variable is used to count unread messages in DB only. All other mutt commands
++   ** use standard (e.g. maildir) flags.
++   */
++  { "nm_db_limit", DT_NUM, R_NONE, UL &NotmuchDBLimit, 0 },
++  /*
++   ** .pp
++   ** This variable specifies the default limit used in notmuch queries.
++   */
++  { "nm_query_type", DT_STR, R_NONE, UL &NotmuchQueryType, UL "messages" },
++  /*
++   ** .pp
++   ** This variable specifies the default query type (threads or messages) used in notmuch queries.
++   */
++  { "nm_record", DT_BOOL, R_NONE, OPTNOTMUCHRECORD, 0 },
++  /*
++   ** .pp
++   ** This variable specifies if the mutt record should indexed by notmuch.
++   */
++  { "nm_record_tags", DT_STR, R_NONE, UL &NotmuchRecordTags, 0 },
++  /*
++   ** .pp
++   ** This variable specifies the default tags applied to messages stored to the mutt record.
++   */
++#endif
+   { "pager",		DT_PATH, R_NONE, UL &Pager, UL "builtin" },
+   /*
+   ** .pp
+@@ -3207,14 +3262,15 @@
+   { "sort_re",		DT_BOOL, R_INDEX|R_RESORT|R_RESORT_INIT, OPTSORTRE, 1 },
+   /*
+   ** .pp
+-  ** This variable is only useful when sorting by threads with
+-  ** $$strict_threads \fIunset\fP.  In that case, it changes the heuristic
+-  ** mutt uses to thread messages by subject.  With $$sort_re \fIset\fP, mutt will
+-  ** only attach a message as the child of another message by subject if
+-  ** the subject of the child message starts with a substring matching the
+-  ** setting of $$reply_regexp.  With $$sort_re \fIunset\fP, mutt will attach
+-  ** the message whether or not this is the case, as long as the
+-  ** non-$$reply_regexp parts of both messages are identical.
++  ** This variable is only useful when sorting by mailboxes in sidebar. By default,
++  ** entries are unsorted.  Valid values:
++  ** .il
++  ** .dd count (all message count)
++  ** .dd desc  (virtual mailbox description)
++  ** .dd new (new message count)
++  ** .dd path
++  ** .dd unsorted
++  ** .ie
+   */
+   { "spam_separator",   DT_STR, R_NONE, UL &SpamSep, UL "," },
+   /*
+@@ -3657,6 +3713,31 @@
+   ** Specifies the visual editor to invoke when the ``\fC~v\fP'' command is
+   ** given in the built-in editor.
+   */
++#ifdef USE_NOTMUCH
++  { "vfolder_format",	DT_STR,	 R_INDEX, UL &VirtFolderFormat, UL " %6n(%6N) %f " },
++  /*
++  ** .pp
++  ** This variable allows you to customize the file browser display for virtual
++  ** folders to your ** personal taste.  This string is similar to $$index_format,
++  ** but has its own set of \fCprintf(3)\fP-like sequences:
++  ** .dl
++  ** .dt %f  .dd folder name (description)
++  ** .dt %n  .dd number of all messages
++  ** .dt %N  .dd number of new messages
++  ** .dt %>X .dd right justify the rest of the string and pad with character ``X''
++  ** .dt %|X .dd pad to the end of the line with character ``X''
++  ** .dt %*X .dd soft-fill with character ``X'' as pad
++  ** .de
++  ** .pp
++  ** For an explanation of ``soft-fill'', see the $$index_format documentation.
++  */
++  { "virtual_spoolfile", DT_BOOL, R_NONE, OPTVIRTSPOOLFILE, 0 },
++  /*
++  ** .pp
++  ** When \fset\fP, mutt will use the first defined virtual mailbox (see
++  ** virtual-mailboxes) as a spool file.
++  */
++#endif
+   { "wait_key",		DT_BOOL, R_NONE, OPTWAITKEY, 1 },
+   /*
+   ** .pp
+@@ -3807,6 +3888,7 @@
+ 
+ const struct mapping_t SortSidebarMethods[] = {
+   { "count",	SORT_COUNT },
++  { "desc",	SORT_DESC },
+   { "flagged",	SORT_FLAGGED },
+   { "new",	SORT_COUNT_NEW },
+   { "path",	SORT_PATH },
+@@ -3840,13 +3922,16 @@
+ static int parse_attachments (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ static int parse_unattachments (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ 
+-
+ static int parse_alternates (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ static int parse_unalternates (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ 
+ /* Parse -group arguments */
+ static int parse_group_context (group_context_t **ctx, BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err);
+ 
++#ifdef USE_NOTMUCH
++static int parse_tag_transforms (BUFFER *, BUFFER *, unsigned long, BUFFER *);
++static int parse_tag_formats (BUFFER *, BUFFER *, unsigned long, BUFFER *);
++#endif
+ 
+ struct command_t
+ {
+@@ -3887,6 +3972,11 @@
+   { "macro",		mutt_parse_macro,	0 },
+   { "mailboxes",	mutt_parse_mailboxes,	M_MAILBOXES },
+   { "unmailboxes",	mutt_parse_mailboxes,	M_UNMAILBOXES },
++#ifdef USE_NOTMUCH
++  { "virtual-mailboxes",mutt_parse_virtual_mailboxes, 0 },
++  { "tag-transforms",	parse_tag_transforms,	0 },
++  { "tag-formats",	parse_tag_formats,	0 },
++#endif
+   { "mailto_allow",	parse_list,		UL &MailtoAllow },
+   { "unmailto_allow",	parse_unlist,		UL &MailtoAllow },
+   { "message-hook",	mutt_parse_hook,	M_MESSAGEHOOK },
+diff -urN mutt-1.6.1-sidebar-notmuch/mailbox.h mutt-1.6.1-notmuch/mailbox.h
+--- mutt-1.6.1-sidebar-notmuch/mailbox.h	2016-05-02 03:02:12.713176413 +0100
++++ mutt-1.6.1-notmuch/mailbox.h	2016-05-02 03:02:15.143215075 +0100
+@@ -48,6 +48,7 @@
+ {
+   FILE *fp;	/* pointer to the message data */
+   char *path;	/* path to temp file */
++  char *commited_path; /* the final path generated by mx_commit_message() */
+   short magic;	/* type of mailbox this message belongs to */
+   short write;	/* nonzero if message is open for writing */
+   struct {
+diff -urN mutt-1.6.1-sidebar-notmuch/main.c mutt-1.6.1-notmuch/main.c
+--- mutt-1.6.1-sidebar-notmuch/main.c	2016-05-02 03:02:12.713176413 +0100
++++ mutt-1.6.1-notmuch/main.c	2016-05-02 03:02:15.228216427 +0100
+@@ -494,6 +494,12 @@
+ 	"-USE_SIDEBAR  "
+ #endif
+ 
++#if USE_NOTMUCH
++	"+NOTMUCH     "
++#else
++	"-NOTMUCH     "
++#endif
++
+ 	);
+ 
+ #ifdef ISPELL
+diff -urN mutt-1.6.1-sidebar-notmuch/Makefile.am mutt-1.6.1-notmuch/Makefile.am
+--- mutt-1.6.1-sidebar-notmuch/Makefile.am	2016-05-02 03:02:12.689176031 +0100
++++ mutt-1.6.1-notmuch/Makefile.am	2016-05-02 03:02:15.216216236 +0100
+@@ -83,6 +83,16 @@
+ 
+ EXTRA_DIST += OPS.SIDEBAR
+ 
++if BUILD_NOTMUCH
++mutt_SOURCES += mutt_notmuch.c mutt_notmuch.h
++mutt_LDADD += $(NOTMUCH_LIBS)
++endif
++
++# kz
++EXTRA_DIST += UPDATING.kz README.notmuch OPS.NOTMUCH
++
++
++
+ mutt_dotlock_SOURCES = mutt_dotlock.c
+ mutt_dotlock_LDADD = $(LIBOBJS)
+ mutt_dotlock_DEPENDENCIES = $(LIBOBJS)
+@@ -135,9 +145,9 @@
+ keymap_defs.h: $(OPS) $(srcdir)/gen_defs
+ 	$(srcdir)/gen_defs $(OPS) > keymap_defs.h
+ 
+-keymap_alldefs.h: $(srcdir)/OPS $(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.PGP $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME $(srcdir)/gen_defs
++keymap_alldefs.h: $(srcdir)/OPS $(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.NOTMUCH $(srcdir)/OPS.PGP $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME $(srcdir)/gen_defs
+ 	rm -f $@
+-	$(srcdir)/gen_defs $(srcdir)/OPS $(srcdir)/OPS.PGP \
++	$(srcdir)/gen_defs $(srcdir)/OPS $(srcdir)/OPS.NOTMUCH $(srcdir)/OPS.PGP \
+ 		$(srcdir)/OPS.SIDEBAR $(srcdir)/OPS.MIX $(srcdir)/OPS.CRYPT $(srcdir)/OPS.SMIME \
+ 			> keymap_alldefs.h
+ 
+diff -urN mutt-1.6.1-sidebar-notmuch/menu.c mutt-1.6.1-notmuch/menu.c
+--- mutt-1.6.1-sidebar-notmuch/menu.c	2016-05-02 03:02:12.713176413 +0100
++++ mutt-1.6.1-notmuch/menu.c	2016-05-02 03:02:15.144215090 +0100
+@@ -50,6 +50,17 @@
+ 		case MT_COLOR_INDEX_SUBJECT:
+ 			color = ColorIndexSubjectList;
+ 			break;
++#ifdef USE_NOTMUCH
++                case MT_COLOR_INDEX_TAG:
++                        for (color = ColorIndexTagList; color; color = color->next)
++                        {
++				const char * transform = hash_find(TagTransforms, color->pattern);
++				if (transform && (strncmp((const char *)(s+1),
++				    transform, strlen(transform)) == 0))
++					return color->pair;
++                        }
++                        return 0;
++#endif
+ 		default:
+ 			return ColorDefs[type];
+ 	}
+diff -urN mutt-1.6.1-sidebar-notmuch/mh.c mutt-1.6.1-notmuch/mh.c
+--- mutt-1.6.1-sidebar-notmuch/mh.c	2016-05-02 03:02:12.713176413 +0100
++++ mutt-1.6.1-notmuch/mh.c	2016-05-02 03:02:15.144215090 +0100
+@@ -56,6 +56,10 @@
+ #include <sys/time.h>
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #define		INS_SORT_THRESHOLD		6
+ 
+ struct maildir
+@@ -653,7 +657,7 @@
+   }
+ }
+ 
+-static void maildir_parse_flags (HEADER * h, const char *path)
++void maildir_parse_flags (HEADER * h, const char *path)
+ {
+   char *p, *q = NULL;
+ 
+@@ -736,40 +740,51 @@
+  * Actually parse a maildir message.  This may also be used to fill
+  * out a fake header structure generated by lazy maildir parsing.
+  */
+-static HEADER *maildir_parse_message (int magic, const char *fname,
++HEADER *maildir_parse_stream (int magic, FILE *f, const char *fname,
+ 				      int is_old, HEADER * _h)
+ {
+-  FILE *f;
+   HEADER *h = _h;
+   struct stat st;
+ 
+-  if ((f = fopen (fname, "r")) != NULL)
+-  {
+-    if (!h)
+-      h = mutt_new_header ();
+-    h->env = mutt_read_rfc822_header (f, h, 0, 0);
++  if (!h)
++    h = mutt_new_header ();
++  h->env = mutt_read_rfc822_header (f, h, 0, 0);
+ 
+-    fstat (fileno (f), &st);
+-    safe_fclose (&f);
++  fstat (fileno (f), &st);
+ 
+-    if (!h->received)
+-      h->received = h->date_sent;
++  if (!h->received)
++    h->received = h->date_sent;
+ 
+-    /* always update the length since we have fresh information available. */
+-    h->content->length = st.st_size - h->content->offset;
++  /* always update the length since we have fresh information available. */
++  h->content->length = st.st_size - h->content->offset;
+ 
+-    h->index = -1;
++  h->index = -1;
+ 
+-    if (magic == M_MAILDIR)
+-    {
+-      /* 
+-       * maildir stores its flags in the filename, so ignore the
+-       * flags in the header of the message 
+-       */
++  if (magic == M_MAILDIR)
++  {
++    /*
++     * maildir stores its flags in the filename, so ignore the
++     * flags in the header of the message
++     */
+ 
+-      h->old = is_old;
+-      maildir_parse_flags (h, fname);
+-    }
++    h->old = is_old;
++    maildir_parse_flags (h, fname);
++  }
++  return h;
++}
++
++/*
++ * Actually parse a maildir message.  This may also be used to fill
++ * out a fake header structure generated by lazy maildir parsing.
++ */
++HEADER *maildir_parse_message (int magic, const char *fname,
++				      int is_old, HEADER * h)
++{
++  FILE *f;
++
++  if ((f = fopen (fname, "r")) != NULL) {
++    h = maildir_parse_stream (magic, f, fname, is_old, h);
++    safe_fclose (&f);
+     return h;
+   }
+   return NULL;
+@@ -1292,7 +1307,7 @@
+   return (int)( *((const char *) a) - *((const char *) b));
+ }
+ 
+-static void maildir_flags (char *dest, size_t destlen, HEADER * hdr)
++void maildir_flags (char *dest, size_t destlen, HEADER * hdr)
+ {
+   *dest = '\0';
+ 
+@@ -1452,10 +1467,6 @@
+ 
+     if (safe_rename (msg->path, full) == 0)
+     {
+-      if (hdr)
+-	mutt_str_replace (&hdr->path, path);
+-      FREE (&msg->path);
+-
+       /*
+        * Adjust the mtime on the file to match the time at which this
+        * message was received.  Currently this is only set when copying
+@@ -1471,11 +1482,23 @@
+ 	if (utime (full, &ut))
+ 	{
+ 	  mutt_perror (_("maildir_commit_message(): unable to set time on file"));
+-	  return -1;
++	  goto post_rename_err;
+ 	}
+       }
+ 
++#ifdef USE_NOTMUCH
++      if (ctx->magic == M_NOTMUCH)
++	nm_update_filename(ctx, hdr->path, full, hdr);
++#endif
++      if (hdr)
++	mutt_str_replace (&hdr->path, path);
++      mutt_str_replace (&msg->commited_path, full);
++      FREE (&msg->path);
++
+       return 0;
++
++post_rename_err:
++      return -1;
+     }
+     else if (errno != EEXIST)
+     {
+@@ -1551,6 +1574,7 @@
+     {
+       if (hdr)
+ 	mutt_str_replace (&hdr->path, tmp);
++      mutt_str_replace (&msg->commited_path, path);
+       FREE (&msg->path);
+       break;
+     }
+@@ -1726,96 +1750,113 @@
+   return (0);
+ }
+ 
+-int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
+-{
+-  char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX];
+-  int i, j;
+-#if USE_HCACHE
+-  header_cache_t *hc = NULL;
+-#endif /* USE_HCACHE */
+-  char msgbuf[STRING];
+-  progress_t progress;
+-
+-  if (ctx->magic == M_MH)
+-    i = mh_check_mailbox (ctx, index_hint);
+-  else 
+-    i = maildir_check_mailbox (ctx, index_hint);
+-      
+-  if (i != 0)
+-    return i;
+-
+ #if USE_HCACHE
+-  if (ctx->magic == M_MAILDIR || ctx->magic == M_MH)
+-    hc = mutt_hcache_open(HeaderCache, ctx->path, NULL);
+-#endif /* USE_HCACHE */
+-
+-  if (!ctx->quiet)
+-  {
+-    snprintf (msgbuf, sizeof (msgbuf), _("Writing %s..."), ctx->path);
+-    mutt_progress_init (&progress, msgbuf, M_PROGRESS_MSG, WriteInc, ctx->msgcount);
+-  }
+-
+-  for (i = 0; i < ctx->msgcount; i++)
+-  {
+-    if (!ctx->quiet)
+-      mutt_progress_update (&progress, i, -1);
++int mh_sync_mailbox_message (CONTEXT * ctx, int msgno, header_cache_t *hc)
++#else
++int mh_sync_mailbox_message (CONTEXT * ctx, int msgno)
++#endif
++{
++    char path[_POSIX_PATH_MAX], tmp[_POSIX_PATH_MAX];
++    HEADER *h = ctx->hdrs[msgno];
+ 
+-    if (ctx->hdrs[i]->deleted
+-	&& (ctx->magic != M_MAILDIR || !option (OPTMAILDIRTRASH)))
++    if (h->deleted && (ctx->magic != M_MAILDIR || !option (OPTMAILDIRTRASH)))
+     {
+-      snprintf (path, sizeof (path), "%s/%s", ctx->path, ctx->hdrs[i]->path);
++      snprintf (path, sizeof (path), "%s/%s", ctx->path, h->path);
+       if (ctx->magic == M_MAILDIR
+ 	  || (option (OPTMHPURGE) && ctx->magic == M_MH))
+       {
+ #if USE_HCACHE
+-        if (ctx->magic == M_MAILDIR)
+-          mutt_hcache_delete (hc, ctx->hdrs[i]->path + 3, &maildir_hcache_keylen);
+-	else if (ctx->magic == M_MH)
+-	  mutt_hcache_delete (hc, ctx->hdrs[i]->path, strlen);
++	if (hc) {
++           if (ctx->magic == M_MAILDIR)
++              mutt_hcache_delete (hc, h->path + 3, &maildir_hcache_keylen);
++	   else if (ctx->magic == M_MH)
++	      mutt_hcache_delete (hc, h->path, strlen);
++	}
+ #endif /* USE_HCACHE */
+ 	unlink (path);
+       }
+       else if (ctx->magic == M_MH)
+       {
+ 	/* MH just moves files out of the way when you delete them */
+-	if (*ctx->hdrs[i]->path != ',')
++	if (*h->path != ',')
+ 	{
+-	  snprintf (tmp, sizeof (tmp), "%s/,%s", ctx->path,
+-		    ctx->hdrs[i]->path);
++	  snprintf (tmp, sizeof (tmp), "%s/,%s", ctx->path, h->path);
+ 	  unlink (tmp);
+ 	  rename (path, tmp);
+ 	}
+ 
+       }
+     }
+-    else if (ctx->hdrs[i]->changed || ctx->hdrs[i]->attach_del ||
++    else if (h->changed || h->attach_del ||
+ 	     (ctx->magic == M_MAILDIR
+-	      && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash)
+-	      && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash)))
++	      && (option (OPTMAILDIRTRASH) || h->trash)
++	      && (h->deleted != h->trash)))
+     {
+       if (ctx->magic == M_MAILDIR)
+       {
+-	if (maildir_sync_message (ctx, i) == -1)
+-	  goto err;
++	if (maildir_sync_message (ctx, msgno) == -1)
++	  return -1;
+       }
+       else
+       {
+-	if (mh_sync_message (ctx, i) == -1)
+-	  goto err;
++	if (mh_sync_message (ctx, msgno) == -1)
++	  return -1;
+       }
+     }
+ 
+ #if USE_HCACHE
+-    if (ctx->hdrs[i]->changed)
++    if (hc && h->changed)
+     {
+       if (ctx->magic == M_MAILDIR)
+-	mutt_hcache_store (hc, ctx->hdrs[i]->path + 3, ctx->hdrs[i],
+-			   0, &maildir_hcache_keylen, M_GENERATE_UIDVALIDITY);
++	mutt_hcache_store (hc, h->path + 3, h, 0, &maildir_hcache_keylen, M_GENERATE_UIDVALIDITY);
+       else if (ctx->magic == M_MH)
+-	mutt_hcache_store (hc, ctx->hdrs[i]->path, ctx->hdrs[i], 0, strlen, M_GENERATE_UIDVALIDITY);
++	mutt_hcache_store (hc, h->path, h, 0, strlen, M_GENERATE_UIDVALIDITY);
+     }
+ #endif
+ 
++    return 0;
++}
++
++int mh_sync_mailbox (CONTEXT * ctx, int *index_hint)
++{
++  int i, j;
++#if USE_HCACHE
++  header_cache_t *hc = NULL;
++#endif /* USE_HCACHE */
++  char msgbuf[STRING];
++  progress_t progress;
++
++  if (ctx->magic == M_MH)
++    i = mh_check_mailbox (ctx, index_hint);
++  else
++    i = maildir_check_mailbox (ctx, index_hint);
++
++  if (i != 0)
++    return i;
++
++#if USE_HCACHE
++  if (ctx->magic == M_MAILDIR || ctx->magic == M_MH)
++    hc = mutt_hcache_open(HeaderCache, ctx->path, NULL);
++#endif /* USE_HCACHE */
++
++  if (!ctx->quiet)
++  {
++    snprintf (msgbuf, sizeof (msgbuf), _("Writing %s..."), ctx->path);
++    mutt_progress_init (&progress, msgbuf, M_PROGRESS_MSG, WriteInc, ctx->msgcount);
++  }
++
++  for (i = 0; i < ctx->msgcount; i++)
++  {
++    if (!ctx->quiet)
++      mutt_progress_update (&progress, i, -1);
++
++#if USE_HCACHE
++    if (mh_sync_mailbox_message (ctx, i, hc) == -1)
++      goto err;
++#else
++    if (mh_sync_mailbox_message (ctx, i) == -1)
++      goto err;
++#endif
+   }
+ 
+ #if USE_HCACHE
+@@ -1894,7 +1935,7 @@
+   mutt_clear_threads (ctx);
+ }
+ 
+-static void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n)
++void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n)
+ {
+   /* save the global state here so we can reset it at the
+    * end of list block if required.
+@@ -2197,7 +2238,7 @@
+  */
+ 
+ static FILE *_maildir_open_find_message (const char *folder, const char *unique,
+-				  const char *subfolder)
++				  const char *subfolder, char **newname)
+ {
+   char dir[_POSIX_PATH_MAX];
+   char tunique[_POSIX_PATH_MAX];
+@@ -2233,11 +2274,15 @@
+ 
+   closedir (dp);
+ 
++  if (newname && fp)
++    *newname = safe_strdup(fname);
++
+   errno = oe;
+   return fp;
+ }
+ 
+-FILE *maildir_open_find_message (const char *folder, const char *msg)
++FILE *maildir_open_find_message (const char *folder, const char *msg,
++                                  char **newname)
+ {
+   char unique[_POSIX_PATH_MAX];
+   FILE *fp;
+@@ -2249,7 +2294,8 @@
+   if (
+       (fp =
+        _maildir_open_find_message (folder, unique,
+-				   new_hits > cur_hits ? "new" : "cur"))
++				   new_hits > cur_hits ? "new" : "cur",
++				   newname))
+       || errno != ENOENT)
+   {
+     if (new_hits < UINT_MAX && cur_hits < UINT_MAX)
+@@ -2263,7 +2309,8 @@
+   if (
+       (fp =
+        _maildir_open_find_message (folder, unique,
+-				   new_hits > cur_hits ? "cur" : "new"))
++				   new_hits > cur_hits ? "cur" : "new",
++				   newname))
+       || errno != ENOENT)
+   {
+     if (new_hits < UINT_MAX && cur_hits < UINT_MAX)
+diff -urN mutt-1.6.1-sidebar-notmuch/mutt_curses.h mutt-1.6.1-notmuch/mutt_curses.h
+--- mutt-1.6.1-sidebar-notmuch/mutt_curses.h	2016-05-02 03:02:12.714176428 +0100
++++ mutt-1.6.1-notmuch/mutt_curses.h	2016-05-02 03:02:15.144215090 +0100
+@@ -136,6 +136,9 @@
+   MT_COLOR_SB_SPOOLFILE,
+ #endif
+   /* please no non-MT_COLOR_INDEX objects after this point */
++#ifdef USE_NOTMUCH
++  MT_COLOR_INDEX_TAG,
++#endif
+   MT_COLOR_INDEX,
+   MT_COLOR_INDEX_AUTHOR,
+   MT_COLOR_INDEX_FLAGS,
+@@ -146,6 +149,9 @@
+   MT_COLOR_INDEX_LABEL,
+   MT_COLOR_INDEX_NUMBER,
+   MT_COLOR_INDEX_SIZE,
++#ifdef USE_NOTMUCH
++  MT_COLOR_INDEX_TAGS,
++#endif
+   MT_COLOR_MAX
+ };
+ 
+@@ -204,6 +210,9 @@
+ extern COLOR_LINE *ColorIndexAuthorList;
+ extern COLOR_LINE *ColorIndexFlagsList;
+ extern COLOR_LINE *ColorIndexSubjectList;
++#ifdef USE_NOTMUCH
++extern COLOR_LINE *ColorIndexTagList;
++#endif
+ 
+ void ci_init_color (void);
+ void ci_start_color (void);
+diff -urN mutt-1.6.1-sidebar-notmuch/mutt.h mutt-1.6.1-notmuch/mutt.h
+--- mutt-1.6.1-sidebar-notmuch/mutt.h	2016-05-02 03:02:12.714176428 +0100
++++ mutt-1.6.1-notmuch/mutt.h	2016-05-02 03:02:15.228216427 +0100
+@@ -101,6 +101,10 @@
+ #define  M_CLEAR   (1<<5) /* clear input if printable character is pressed */
+ #define  M_COMMAND (1<<6) /* do command completion */
+ #define  M_PATTERN (1<<7) /* pattern mode - only used for history classes */
++#if USE_NOTMUCH
++#define  M_NM_QUERY (1<<8) /* Notmuch query mode. */
++#define  M_NM_TAG   (1<<9) /* Notmuch tag +/- mode. */
++#endif
+ 
+ /* flags for mutt_get_token() */
+ #define M_TOKEN_EQUAL		1	/* treat '=' as a special */
+@@ -238,6 +242,9 @@
+   M_CRYPT_ENCRYPT,
+   M_PGP_KEY,
+   M_XLABEL,
++#ifdef USE_NOTMUCH
++  M_NOTMUCH_LABEL,
++#endif
+   M_MIMEATTACH,
+   
+   /* Options for Mailcap lookup */
+@@ -321,6 +328,7 @@
+ #define M_SEL_BUFFY	(1<<0)
+ #define M_SEL_MULTI	(1<<1)
+ #define M_SEL_FOLDER	(1<<2)
++#define M_SEL_VFOLDER	(1<<3)
+ 
+ /* flags for parse_spam_list */
+ #define M_SPAM          1
+@@ -543,6 +551,11 @@
+   OPTDONTHANDLEPGPKEYS,	/* (pseudo) used to extract PGP keys */
+   OPTIGNOREMACROEVENTS, /* (pseudo) don't process macro/push/exec events while set */
+ 
++#ifdef USE_NOTMUCH
++  OPTVIRTSPOOLFILE,
++  OPTNOTMUCHRECORD,
++#endif
++
+   OPTMAX
+ };
+ 
+@@ -807,8 +820,9 @@
+   int refno;			/* message number on server */
+ #endif
+ 
+-#if defined USE_POP || defined USE_IMAP
++#if defined USE_POP || defined USE_IMAP || defined USE_NOTMUCH
+   void *data;            	/* driver-specific data */
++  void (*free_cb)(struct header *); /* driver-specific data free function */
+ #endif
+   
+   char *maildir_flags;		/* unknown maildir flags */
+diff -urN mutt-1.6.1-sidebar-notmuch/muttlib.c mutt-1.6.1-notmuch/muttlib.c
+--- mutt-1.6.1-sidebar-notmuch/muttlib.c	2016-05-02 03:02:12.715176444 +0100
++++ mutt-1.6.1-notmuch/muttlib.c	2016-05-02 03:02:15.229216443 +0100
+@@ -32,12 +32,18 @@
+ #include "imap.h"
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #include "mutt_crypt.h"
+ 
+ #include <string.h>
+ #include <ctype.h>
+ #include <unistd.h>
++#ifdef HAVE_SYS_SYSCALL_H
+ #include <sys/syscall.h>
++#endif
+ #include <stdlib.h>
+ #include <sys/wait.h>
+ #include <errno.h>
+@@ -330,7 +336,9 @@
+ #ifdef MIXMASTER
+   mutt_free_list (&(*h)->chain);
+ #endif
+-#if defined USE_POP || defined USE_IMAP
++#if defined USE_POP || defined USE_IMAP || defined USE_NOTMUCH
++  if ((*h)->free_cb)
++    (*h)->free_cb(*h);
+   FREE (&(*h)->data);
+ #endif
+   FREE (h);		/* __FREE_CHECKED__ */
+@@ -441,6 +449,11 @@
+ 	  strfcpy (p, NONULL (Maildir), sizeof (p));
+ 	else
+ #endif
++#ifdef USE_NOTMUCH
++	if (mx_is_notmuch (NONULL (Maildir)))
++	  strfcpy (p, NONULL (Maildir), sizeof (p));
++	else
++#endif
+ 	if (Maildir && *Maildir && Maildir[strlen (Maildir) - 1] == '/')
+ 	  strfcpy (p, NONULL (Maildir), sizeof (p));
+ 	else
+@@ -887,6 +900,11 @@
+   }
+ #endif
+ 
++#ifdef USE_NOTMUCH
++  if (scheme == U_NOTMUCH)
++    return;
++#endif
++
+   /* if s is an url, only collapse path component */
+   if (scheme != U_UNKNOWN)
+   {
+diff -urN mutt-1.6.1-sidebar-notmuch/mutt_notmuch.c mutt-1.6.1-notmuch/mutt_notmuch.c
+--- mutt-1.6.1-sidebar-notmuch/mutt_notmuch.c	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-notmuch/mutt_notmuch.c	2016-05-02 03:02:15.145215107 +0100
+@@ -0,0 +1,1941 @@
++/*
++ * Notmuch support for mutt
++ *
++ * Copyright (C) 2011, 2012 Karel Zak <kzak at redhat.com>
++ *
++ * Notes:
++ *
++ * - notmuch uses private CONTEXT->data and private HEADER->data
++ *
++ * - all exported functions are usable within notmuch context only
++ *
++ * - all functions have to be covered by "ctx->magic == M_NOTMUCH" check
++ *   (it's implemented in get_ctxdata() and init_context() functions).
++ *
++ * - exception are nm_nonctx_* functions -- these functions use nm_default_uri
++ *   (or parse URI from another resource)
++ */
++#if HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include "mutt.h"
++#include "mx.h"
++#include "rfc2047.h"
++#include "sort.h"
++#include "mailbox.h"
++#include "copy.h"
++#include "keymap.h"
++#include "url.h"
++#include "buffy.h"
++
++#include <dirent.h>
++#include <fcntl.h>
++#include <sys/file.h>
++#include <sys/stat.h>
++#include <errno.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <string.h>
++#include <ctype.h>
++#include <utime.h>
++
++#include <notmuch.h>
++
++#include "mutt_notmuch.h"
++#include "mutt_curses.h"
++
++/* read whole-thread or matching messages only? */
++enum {
++	NM_QUERY_TYPE_MESGS = 1,	/* default */
++	NM_QUERY_TYPE_THREADS
++};
++
++/*
++ * Parsed URI arguments
++ */
++struct uri_tag {
++	char *name;
++	char *value;
++	struct uri_tag *next;
++};
++
++/*
++ * HEADER->(nm_hdrdata *)data->tag_list node
++ */
++struct nm_hdrtag
++{
++  char *tag;
++  char *transformed;
++  struct nm_hdrtag *next;
++};
++
++/*
++ * HEADER->data
++ */
++struct nm_hdrdata {
++	char *folder;
++	char *tags;
++	char *tags_transformed;
++	struct nm_hdrtag *tag_list;
++	char *oldpath;
++	char *virtual_id;
++	int magic;
++};
++
++/*
++ * CONTEXT->data
++ */
++struct nm_ctxdata {
++	notmuch_database_t *db;
++
++	char *db_filename;
++	char *db_query;
++	int db_limit;
++	int query_type;
++
++	struct uri_tag *query_items;
++
++	progress_t progress;
++	int oldmsgcount;
++	int ignmsgcount;	/* ingored messages */
++
++	unsigned int noprogress : 1,
++		     longrun : 1,
++		     trans : 1,
++		     progress_ready : 1;
++
++};
++
++static HEADER *get_mutt_header(CONTEXT *ctx, notmuch_message_t *msg);
++static notmuch_message_t *get_nm_message(notmuch_database_t *db, HEADER *hdr);
++
++static void url_free_tags(struct uri_tag *tags)
++{
++	while (tags) {
++		struct uri_tag *next = tags->next;
++		FREE(&tags->name);
++		FREE(&tags->value);
++		FREE(&tags);
++		tags = next;
++	}
++}
++
++static int url_parse_query(char *url, char **filename, struct uri_tag **tags)
++{
++	char *p = strstr(url, "://");	/* remote unsupported */
++	char *e;
++	struct uri_tag *tag, *last = NULL;
++
++	*filename = NULL;
++	*tags = NULL;
++
++	if (!p || !*(p + 3))
++		return -1;
++
++	p += 3;
++	*filename = p;
++
++	e = strchr(p, '?');
++
++	*filename = e ? e == p ? NULL : strndup(p, e - p) : safe_strdup(p);
++	if (!e)
++		return 0;
++
++	if (*filename && url_pct_decode(*filename) < 0)
++		goto err;
++	if (!e)
++		return 0;	/* only filename */
++
++	++e;	/* skip '?' */
++	p = e;
++
++	while (p && *p) {
++		tag = safe_calloc(1, sizeof(struct uri_tag));
++		if (!tag)
++			goto err;
++
++		if (!*tags)
++			last = *tags = tag;
++		else {
++			last->next = tag;
++			last = tag;
++		}
++
++		e = strchr(p, '=');
++		if (!e)
++			e = strchr(p, '&');
++		tag->name = e ? strndup(p, e - p) : safe_strdup(p);
++		if (!tag->name || url_pct_decode(tag->name) < 0)
++			goto err;
++		if (!e)
++			break;
++
++		p = e + 1;
++
++		if (*e == '&')
++			continue;
++
++		e = strchr(p, '&');
++		tag->value = e ? strndup(p, e - p) : safe_strdup(p);
++		if (!tag->value || url_pct_decode(tag->value) < 0)
++			goto err;
++		if (!e)
++			break;
++		p = e + 1;
++	}
++
++	return 0;
++err:
++	FREE(&(*filename));
++	url_free_tags(*tags);
++	return -1;
++}
++
++static void free_tag_list(struct nm_hdrtag **tag_list)
++{
++	struct nm_hdrtag *tmp;
++
++	while ((tmp = *tag_list) != NULL)
++	{
++		*tag_list = tmp->next;
++		FREE(&tmp->tag);
++		FREE(&tmp->transformed);
++		FREE(&tmp);
++	}
++
++	*tag_list = 0;
++}
++
++static void free_hdrdata(struct nm_hdrdata *data)
++{
++	if (!data)
++		return;
++
++	dprint(2, (debugfile, "nm: freeing header %p\n", data));
++	FREE(&data->folder);
++	FREE(&data->tags);
++	FREE(&data->tags_transformed);
++	free_tag_list(&data->tag_list);
++	FREE(&data->oldpath);
++	FREE(&data->virtual_id);
++	FREE(&data);
++}
++
++static void free_ctxdata(struct nm_ctxdata *data)
++{
++	if (!data)
++		return;
++
++	dprint(1, (debugfile, "nm: freeing context data %p\n", data));
++
++	if (data->db)
++#ifdef NOTMUCH_API_3
++	        notmuch_database_destroy(data->db);
++#else
++		notmuch_database_close(data->db);
++#endif
++	data->db = NULL;
++
++	FREE(&data->db_filename);
++	FREE(&data->db_query);
++	url_free_tags(data->query_items);
++	FREE(&data);
++}
++
++static struct nm_ctxdata *new_ctxdata(char *uri)
++{
++	struct nm_ctxdata *data;
++
++	if (!uri)
++		return NULL;
++
++	data = safe_calloc(1, sizeof(struct nm_ctxdata));
++	dprint(1, (debugfile, "nm: initialize context data %p\n", data));
++
++	data->db_limit = NotmuchDBLimit;
++
++	if (url_parse_query(uri, &data->db_filename, &data->query_items)) {
++		mutt_error(_("failed to parse notmuch uri: %s"), uri);
++		data->db_filename = NULL;
++		data->query_items = NULL;
++		data->query_type = 0;
++		return NULL;
++	}
++
++	return data;
++}
++
++static int deinit_context(CONTEXT *ctx)
++{
++	int i;
++
++	if (!ctx || ctx->magic != M_NOTMUCH)
++		return -1;
++
++	for (i = 0; i < ctx->msgcount; i++) {
++		HEADER *h = ctx->hdrs[i];
++
++		if (h) {
++			free_hdrdata(h->data);
++			h->data = NULL;
++		}
++	}
++
++	free_ctxdata(ctx->data);
++	ctx->data = NULL;
++	return 0;
++}
++
++static int init_context(CONTEXT *ctx)
++{
++	if (!ctx || ctx->magic != M_NOTMUCH)
++		return -1;
++
++	if (ctx->data)
++		return 0;
++
++	ctx->data = new_ctxdata(ctx->path);
++	if (!ctx->data)
++		return -1;
++
++	ctx->mx_close = deinit_context;
++	return 0;
++}
++
++char *nm_header_get_folder(HEADER *h)
++{
++	return h && h->data ? ((struct nm_hdrdata *) h->data)->folder : NULL;
++}
++
++/* returns all unhidden tags */
++char *nm_header_get_tags(HEADER *h)
++{
++	return h && h->data ? ((struct nm_hdrdata *) h->data)->tags : NULL;
++}
++
++char *nm_header_get_tags_transformed(HEADER *h)
++{
++	return h && h->data ? ((struct nm_hdrdata *) h->data)->tags_transformed : NULL;
++}
++
++char *nm_header_get_tag_transformed(char *tag, HEADER *h)
++{
++	struct nm_hdrtag *tmp;
++
++	if (!h || !h->data)
++		return NULL;
++
++	for (tmp = ((struct nm_hdrdata *) h->data)->tag_list;
++	     tmp != NULL;
++	     tmp = tmp->next)
++	{
++		if (strcmp(tag, tmp->tag) == 0)
++			return tmp->transformed;
++	}
++
++	return NULL;
++}
++
++int nm_header_get_magic(HEADER *h)
++{
++	return h && h->data ? ((struct nm_hdrdata *) h->data)->magic : 0;
++}
++
++/*
++ * Returns notmuch message Id.
++ */
++static char *nm_header_get_id(HEADER *h)
++{
++	return h && h->data ? ((struct nm_hdrdata *) h->data)->virtual_id : NULL;
++}
++
++
++char *nm_header_get_fullpath(HEADER *h, char *buf, size_t bufsz)
++{
++	snprintf(buf, bufsz, "%s/%s", nm_header_get_folder(h), h->path);
++	/*dprint(2, (debugfile, "nm: returns fullpath '%s'\n", buf));*/
++	return buf;
++}
++
++
++static struct nm_ctxdata *get_ctxdata(CONTEXT *ctx)
++{
++	if (ctx && ctx->magic == M_NOTMUCH)
++		return ctx->data;
++
++	return NULL;
++}
++
++static int string_to_guery_type(const char *str)
++{
++	if (!str)
++		str = NotmuchQueryType;		/* user's default */
++	if (!str)
++		return NM_QUERY_TYPE_MESGS;	/* hardcoded default */
++
++	if (strcmp(str, "threads") == 0)
++		return NM_QUERY_TYPE_THREADS;
++	else if (strcmp(str, "messages") == 0)
++		return NM_QUERY_TYPE_MESGS;
++
++	mutt_error (_("failed to parse notmuch query type: %s"), str);
++	return NM_QUERY_TYPE_MESGS;
++}
++
++static char *get_query_string(struct nm_ctxdata *data)
++{
++	struct uri_tag *item;
++
++	if (!data)
++		return NULL;
++	if (data->db_query)
++		return data->db_query;
++
++	for (item = data->query_items; item; item = item->next) {
++		if (!item->value || !item->name)
++			continue;
++
++		if (strcmp(item->name, "limit") == 0) {
++			if (mutt_atoi(item->value, &data->db_limit))
++				mutt_error (_("failed to parse notmuch limit: %s"), item->value);
++
++		} else if (strcmp(item->name, "type") == 0)
++			data->query_type = string_to_guery_type(item->value);
++
++		else if (strcmp(item->name, "query") == 0)
++			data->db_query = safe_strdup(item->value);
++	}
++
++	if (!data->query_type)
++		data->query_type = string_to_guery_type(NULL);
++
++	dprint(2, (debugfile, "nm: query '%s'\n", data->db_query));
++
++	return data->db_query;
++}
++
++static int get_limit(struct nm_ctxdata *data)
++{
++	return data ? data->db_limit : 0;
++}
++
++static int get_query_type(struct nm_ctxdata *data)
++{
++	return (data && data->query_type) ? data->query_type : string_to_guery_type(NULL);
++}
++
++static const char *get_db_filename(struct nm_ctxdata *data)
++{
++	char *db_filename;
++
++	if (!data)
++		return NULL;
++
++	db_filename = data->db_filename ? data->db_filename : NotmuchDefaultUri;
++	if (!db_filename)
++		db_filename = Maildir;
++	if (!db_filename)
++		return NULL;
++	if (strncmp(db_filename, "notmuch://", 10) == 0)
++		db_filename += 10;
++
++	dprint(2, (debugfile, "nm: db filename '%s'\n", db_filename));
++	return db_filename;
++}
++
++static notmuch_database_t *do_database_open(const char *filename,
++					    int writable, int verbose)
++{
++	notmuch_database_t *db = NULL;
++	unsigned int ct = 0;
++	notmuch_status_t st = NOTMUCH_STATUS_SUCCESS;
++
++	dprint(1, (debugfile, "nm: db open '%s' %s (timeout %d)\n", filename,
++			writable ? "[WRITE]" : "[READ]", NotmuchOpenTimeout));
++	do {
++#ifdef NOTMUCH_API_3
++		st = notmuch_database_open(filename,
++					writable ? NOTMUCH_DATABASE_MODE_READ_WRITE :
++					NOTMUCH_DATABASE_MODE_READ_ONLY, &db);
++#else
++		db = notmuch_database_open(filename,
++					writable ? NOTMUCH_DATABASE_MODE_READ_WRITE :
++					NOTMUCH_DATABASE_MODE_READ_ONLY);
++#endif
++		if (db || !NotmuchOpenTimeout || ct / 2 > NotmuchOpenTimeout)
++			break;
++
++		if (verbose && ct && ct % 2 == 0)
++			mutt_error(_("Waiting for notmuch DB... (%d sec)"), ct / 2);
++		usleep(500000);
++		ct++;
++	} while (1);
++
++	if (verbose) {
++		if (!db)
++			mutt_error (_("Cannot open notmuch database: %s: %s"),
++				    filename,
++				    st ? notmuch_status_to_string(st) :
++					 _("unknown reason"));
++		else if (ct > 1)
++			mutt_clear_error();
++	}
++	return db;
++}
++
++static notmuch_database_t *get_db(struct nm_ctxdata *data, int writable)
++{
++	if (!data)
++	       return NULL;
++	if (!data->db) {
++		const char *db_filename = get_db_filename(data);
++
++		if (db_filename)
++			data->db = do_database_open(db_filename, writable, TRUE);
++	}
++	return data->db;
++}
++
++static int release_db(struct nm_ctxdata *data)
++{
++	if (data && data->db) {
++		dprint(1, (debugfile, "nm: db close\n"));
++#ifdef NOTMUCH_API_3
++		notmuch_database_destroy(data->db);
++#else
++		notmuch_database_close(data->db);
++#endif
++		data->db = NULL;
++		data->longrun = 0;
++		return 0;
++	}
++
++	return -1;
++}
++
++/* returns:	< 0 = error
++ *		  1 = new transaction started
++ *		  0 = already within transaction
++ */
++static int db_trans_begin(struct nm_ctxdata *data)
++{
++	if (!data || !data->db)
++		return -1;
++
++	if (!data->trans) {
++		dprint(2, (debugfile, "nm: db trans start\n"));
++		if (notmuch_database_begin_atomic(data->db))
++			return -1;
++		data->trans = 1;
++		return 1;
++	}
++
++	return 0;
++}
++
++static int db_trans_end(struct nm_ctxdata *data)
++{
++	if (!data || !data->db)
++		return -1;
++
++	if (data->trans) {
++		dprint(2, (debugfile, "nm: db trans end\n"));
++		data->trans = 0;
++		if (notmuch_database_end_atomic(data->db))
++			return -1;
++	}
++
++	return 0;
++}
++
++void nm_longrun_init(CONTEXT *ctx, int writable)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++
++	if (data && get_db(data, writable)) {
++		data->longrun = 1;
++		dprint(2, (debugfile, "nm: long run initialized\n"));
++	}
++}
++
++void nm_longrun_done(CONTEXT *ctx)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++
++	if (data && release_db(data) == 0)
++		dprint(2, (debugfile, "nm: long run deinitialized\n"));
++}
++
++static int is_longrun(struct nm_ctxdata *data)
++{
++	return data && data->longrun;
++}
++
++void nm_debug_check(CONTEXT *ctx)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++
++	if (!data)
++		return;
++
++	if (data->db) {
++		dprint(1, (debugfile, "nm: ERROR: db is open, closing\n"));
++		release_db(data);
++	}
++}
++
++static int get_database_mtime(struct nm_ctxdata *data, time_t *mtime)
++{
++	char path[_POSIX_PATH_MAX];
++	struct stat st;
++
++	if (!data)
++	       return -1;
++
++	snprintf(path, sizeof(path), "%s/.notmuch/xapian", get_db_filename(data));
++	dprint(2, (debugfile, "nm: checking '%s' mtime\n", path));
++
++	if (stat(path, &st))
++		return -1;
++
++	if (mtime)
++		*mtime = st.st_mtime;
++
++	return 0;
++}
++
++static void apply_exclude_tags(notmuch_query_t *query)
++{
++	char *buf, *p, *end = NULL, *tag = NULL;
++
++	if (!NotmuchExcludeTags || !*NotmuchExcludeTags)
++		return;
++	buf = safe_strdup(NotmuchExcludeTags);
++
++	for (p = buf; p && *p; p++) {
++		if (!tag && isspace(*p))
++			continue;
++		if (!tag)
++			tag = p;		/* begin of the tag */
++		if (*p == ',' || *p == ' ')
++			end = p;		/* terminate the tag */
++		else if (*(p + 1) == '\0')
++			end = p + 1;		/* end of optstr */
++		if (!tag || !end)
++			continue;
++		if (tag >= end)
++			break;
++		*end = '\0';
++
++		dprint(2, (debugfile, "nm: query exclude tag '%s'\n", tag));
++		notmuch_query_add_tag_exclude(query, tag);
++		end = tag = NULL;
++	}
++	notmuch_query_set_omit_excluded(query, 1);
++	FREE(&buf);
++}
++
++static notmuch_query_t *get_query(struct nm_ctxdata *data, int writable)
++{
++	notmuch_database_t *db = NULL;
++	notmuch_query_t *q = NULL;
++	const char *str;
++
++	if (!data)
++		return NULL;
++
++	db = get_db(data, writable);
++	str = get_query_string(data);
++
++	if (!db || !str)
++		goto err;
++
++	q = notmuch_query_create(db, str);
++	if (!q)
++		goto err;
++
++	apply_exclude_tags(q);
++	notmuch_query_set_sort(q, NOTMUCH_SORT_NEWEST_FIRST);
++	dprint(2, (debugfile, "nm: query successfully initialized\n"));
++	return q;
++err:
++	if (!is_longrun(data))
++		release_db(data);
++	return NULL;
++}
++
++static void append_str_item(char **str, const char *item, int sep)
++{
++	char *p;
++	size_t sz = strlen(item);
++	size_t ssz = *str ? strlen(*str) : 0;
++
++	safe_realloc(str, ssz + (ssz && sep ? 1 : 0) + sz + 1);
++	p = *str + ssz;
++	if (sep && ssz)
++	    *p++ = sep;
++	memcpy(p, item, sz + 1);
++}
++
++static int update_header_tags(HEADER *h, notmuch_message_t *msg)
++{
++	struct nm_hdrdata *data = h->data;
++	notmuch_tags_t *tags;
++	char *tstr = NULL, *ttstr = NULL;
++	struct nm_hdrtag *tag_list = NULL, *tmp;
++
++	dprint(2, (debugfile, "nm: tags update requested (%s)\n", data->virtual_id));
++
++	for (tags = notmuch_message_get_tags(msg);
++	     tags && notmuch_tags_valid(tags);
++	     notmuch_tags_move_to_next(tags)) {
++
++		const char *t = notmuch_tags_get(tags);
++		const char *tt = NULL;
++
++		if (!t || !*t)
++			continue;
++
++		tt = hash_find(TagTransforms, t);
++		if (!tt)
++			tt = t;
++
++		/* tags list contains all tags */
++		tmp = safe_calloc(1, sizeof(*tmp));
++		tmp->tag = safe_strdup(t);
++		tmp->transformed = safe_strdup(tt);
++		tmp->next = tag_list;
++		tag_list = tmp;
++
++		/* filter out hidden tags */
++		if (NotmuchHiddenTags) {
++			char *p = strstr(NotmuchHiddenTags, t);
++			size_t xsz = p ? strlen(t) : 0;
++
++			if (p && (p == NotmuchHiddenTags
++				  || *(p - 1) == ','
++				  || *(p - 1) == ' ')
++			    && (*(p + xsz) == '\0'
++				  || *(p + xsz) == ','
++				  || *(p + xsz) == ' '))
++				continue;
++		}
++
++		/* expand the transformed tag string */
++		append_str_item(&ttstr, tt, ' ');
++
++		/* expand the un-transformed tag string */
++		append_str_item(&tstr, t, ' ');
++	}
++
++	free_tag_list(&data->tag_list);
++	data->tag_list = tag_list;
++
++	if (data->tags && tstr && strcmp(data->tags, tstr) == 0) {
++		FREE(&tstr);
++		FREE(&ttstr);
++		dprint(2, (debugfile, "nm: tags unchanged\n"));
++		return 1;
++	}
++
++	/* free old version */
++	FREE(&data->tags);
++	FREE(&data->tags_transformed);
++
++	/* new version */
++	data->tags = tstr;
++	dprint(2, (debugfile, "nm: new tags: '%s'\n", tstr));
++
++	data->tags_transformed = ttstr;
++	dprint(2, (debugfile, "nm: new tag transforms: '%s'\n", ttstr));
++
++	return 0;
++}
++
++/*
++ * set/update HEADER->path and HEADER->data->path
++ */
++static int update_message_path(HEADER *h, const char *path)
++{
++	struct nm_hdrdata *data = h->data;
++	char *p;
++
++	dprint(2, (debugfile, "nm: path update requested path=%s, (%s)\n",
++				path, data->virtual_id));
++
++	p = strrchr(path, '/');
++	if (p && p - path > 3 &&
++	    (strncmp(p - 3, "cur", 3) == 0 ||
++	     strncmp(p - 3, "new", 3) == 0 ||
++	     strncmp(p - 3, "tmp", 3) == 0)) {
++
++		data->magic = M_MAILDIR;
++
++		FREE(&h->path);
++		FREE(&data->folder);
++
++		p -= 3;				/* skip subfolder (e.g. "new") */
++		h->path = safe_strdup(p);
++
++		for (; p > path && *(p - 1) == '/'; p--);
++
++		data->folder = strndup(path, p - path);
++
++		dprint(2, (debugfile, "nm: folder='%s', file='%s'\n", data->folder, h->path));
++		return 0;
++	}
++
++	return 1;
++}
++
++static char *get_folder_from_path(const char *path)
++{
++	char *p = strrchr(path, '/');
++
++	if (p && p - path > 3 &&
++	    (strncmp(p - 3, "cur", 3) == 0 ||
++	     strncmp(p - 3, "new", 3) == 0 ||
++	     strncmp(p - 3, "tmp", 3) == 0)) {
++
++		p -= 3;
++		for (; p > path && *(p - 1) == '/'; p--);
++
++		return strndup(path, p - path);
++	}
++
++	return NULL;
++}
++
++static void deinit_header(HEADER *h)
++{
++	if (h) {
++		free_hdrdata(h->data);
++		h->data = NULL;
++	}
++}
++
++/* converts notmuch message Id to mutt message <Id> */
++static char *nm2mutt_message_id(const char *id)
++{
++	size_t sz;
++	char *mid;
++
++	if (!id)
++		return NULL;
++	sz = strlen(id) + 3;
++	mid = safe_malloc(sz);
++
++	snprintf(mid, sz, "<%s>", id);
++	return mid;
++}
++
++static int init_header(HEADER *h, const char *path, notmuch_message_t *msg)
++{
++	const char *id;
++
++	if (h->data)
++		return 0;
++
++	id = notmuch_message_get_message_id(msg);
++
++	h->data = safe_calloc(1, sizeof(struct nm_hdrdata));
++	h->free_cb = deinit_header;
++
++	/*
++	 * Notmuch ensures that message Id exists (if not notmuch Notmuch will
++	 * generate an ID), so it's more safe than use mutt HEADER->env->id
++	 */
++	((struct nm_hdrdata *) h->data)->virtual_id = safe_strdup( id );
++
++	dprint(2, (debugfile, "nm: initialize header data: [hdr=%p, data=%p] (%s)\n",
++				h, h->data, id));
++
++	if (!h->env->message_id)
++		h->env->message_id = nm2mutt_message_id( id );
++
++	if (update_message_path(h, path))
++		return -1;
++
++	update_header_tags(h, msg);
++
++	return 0;
++}
++
++/**
++static void debug_print_filenames(notmuch_message_t *msg)
++{
++	notmuch_filenames_t *ls;
++	const char *id = notmuch_message_get_message_id(msg);
++
++	for (ls = notmuch_message_get_filenames(msg);
++	     ls && notmuch_filenames_valid(ls);
++	     notmuch_filenames_move_to_next(ls)) {
++
++		dprint(2, (debugfile, "nm: %s: %s\n", id, notmuch_filenames_get(ls)));
++	}
++}
++
++static void debug_print_tags(notmuch_message_t *msg)
++{
++	notmuch_tags_t *tags;
++	const char *id = notmuch_message_get_message_id(msg);
++
++	for (tags = notmuch_message_get_tags(msg);
++	     tags && notmuch_tags_valid(tags);
++	     notmuch_tags_move_to_next(tags)) {
++
++		dprint(2, (debugfile, "nm: %s: %s\n", id, notmuch_tags_get(tags)));
++	}
++}
++***/
++
++static const char *get_message_last_filename(notmuch_message_t *msg)
++{
++	notmuch_filenames_t *ls;
++	const char *name = NULL;
++
++	for (ls = notmuch_message_get_filenames(msg);
++	     ls && notmuch_filenames_valid(ls);
++	     notmuch_filenames_move_to_next(ls)) {
++
++		name = notmuch_filenames_get(ls);
++	}
++
++	return name;
++}
++
++static void nm_progress_reset(CONTEXT *ctx)
++{
++	struct nm_ctxdata *data;
++
++	if (ctx->quiet)
++		return;
++
++	data = get_ctxdata(ctx);
++
++	memset(&data->progress, 0, sizeof(data->progress));
++	data->oldmsgcount = ctx->msgcount;
++	data->ignmsgcount = 0;
++	data->noprogress = 0;
++	data->progress_ready = 0;
++}
++
++static void nm_progress_update(CONTEXT *ctx, notmuch_query_t *q)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++
++	if (ctx->quiet || data->noprogress)
++		return;
++
++	if (!data->progress_ready && q) {
++		static char msg[STRING];
++		snprintf(msg, sizeof(msg), _("Reading messages..."));
++
++		mutt_progress_init(&data->progress, msg, M_PROGRESS_MSG,
++			ReadInc, notmuch_query_count_messages(q));
++		data->progress_ready = 1;
++	}
++
++	if (data->progress_ready)
++		mutt_progress_update(&data->progress,
++				ctx->msgcount + data->ignmsgcount
++					      - data->oldmsgcount, -1);
++}
++
++static void append_message(CONTEXT *ctx,
++			   notmuch_query_t *q,
++			   notmuch_message_t *msg,
++			   int dedup)
++{
++	char *newpath = NULL;
++	const char *path;
++	HEADER *h = NULL;
++
++	/* deduplicate */
++	if (dedup && get_mutt_header(ctx, msg)) {
++		get_ctxdata(ctx)->ignmsgcount++;
++		nm_progress_update(ctx, q);
++	        dprint(2, (debugfile, "nm: ignore id=%s, already in the context\n",
++					notmuch_message_get_message_id(msg)));
++		return;
++	}
++
++	path = get_message_last_filename(msg);
++	if (!path)
++		return;
++
++	dprint(2, (debugfile, "nm: appending message, i=%d, id=%s, path=%s\n",
++				ctx->msgcount,
++				notmuch_message_get_message_id(msg),
++				path));
++
++	if (ctx->msgcount >= ctx->hdrmax) {
++		dprint(2, (debugfile, "nm: allocate mx memory\n"));
++		mx_alloc_memory(ctx);
++	}
++	if (access(path, F_OK) == 0)
++		h = maildir_parse_message(M_MAILDIR, path, 0, NULL);
++	else {
++		/* maybe moved try find it... */
++		char *folder = get_folder_from_path(path);
++
++		if (folder) {
++			FILE *f = maildir_open_find_message(folder, path, &newpath);
++			if (f) {
++				h = maildir_parse_stream(M_MAILDIR, f, newpath, 0, NULL);
++				fclose(f);
++
++				dprint(1, (debugfile, "nm: not up-to-date: %s -> %s\n",
++							path, newpath));
++			}
++		}
++		FREE(&folder);
++	}
++
++	if (!h) {
++		dprint(1, (debugfile, "nm: failed to parse message: %s\n", path));
++		goto done;
++	}
++	if (init_header(h, newpath ? newpath : path, msg) != 0) {
++		mutt_free_header(&h);
++		dprint(1, (debugfile, "nm: failed to append header!\n"));
++		goto done;
++	}
++
++	h->active = 1;
++	h->index = ctx->msgcount;
++	ctx->size += h->content->length
++		   + h->content->offset
++		   - h->content->hdr_offset;
++	ctx->hdrs[ctx->msgcount] = h;
++	ctx->msgcount++;
++
++	if (newpath) {
++		/* remember that file has been moved -- nm_sync() will update the DB */
++		struct nm_hdrdata *hd = (struct nm_hdrdata *) h->data;
++
++		if (hd) {
++			dprint(1, (debugfile, "nm: remember obsolete path: %s\n", path));
++			hd->oldpath = safe_strdup(path);
++		}
++	}
++	nm_progress_update(ctx, q);
++done:
++	FREE(&newpath);
++}
++
++/*
++ * add all the replies to a given messages into the display.
++ * Careful, this calls itself recursively to make sure we get
++ * everything.
++ */
++static void append_replies(CONTEXT *ctx,
++			   notmuch_query_t *q,
++			   notmuch_message_t *top,
++			   int dedup)
++{
++	notmuch_messages_t *msgs;
++
++	for (msgs = notmuch_message_get_replies(top);
++	     notmuch_messages_valid(msgs);
++	     notmuch_messages_move_to_next(msgs)) {
++
++		notmuch_message_t *m = notmuch_messages_get(msgs);
++		append_message(ctx, q, m, dedup);
++		/* recurse through all the replies to this message too */
++		append_replies(ctx, q, m, dedup);
++		notmuch_message_destroy(m);
++	}
++}
++
++/*
++ * add each top level reply in the thread, and then add each
++ * reply to the top level replies
++ */
++static void append_thread(CONTEXT *ctx,
++			  notmuch_query_t *q,
++			  notmuch_thread_t *thread,
++			  int dedup)
++{
++	notmuch_messages_t *msgs;
++
++	for (msgs = notmuch_thread_get_toplevel_messages(thread);
++	     notmuch_messages_valid(msgs);
++	     notmuch_messages_move_to_next(msgs)) {
++
++		notmuch_message_t *m = notmuch_messages_get(msgs);
++		append_message(ctx, q, m, dedup);
++		append_replies(ctx, q, m, dedup);
++		notmuch_message_destroy(m);
++	}
++}
++
++static void read_mesgs_query(CONTEXT *ctx, notmuch_query_t *q, int dedup)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	int limit;
++	notmuch_messages_t *msgs;
++
++	if (!data)
++		return;
++
++	limit = get_limit(data);
++
++	for (msgs = notmuch_query_search_messages(q);
++	     notmuch_messages_valid(msgs) &&
++		(limit == 0 || ctx->msgcount < limit);
++	     notmuch_messages_move_to_next(msgs)) {
++
++		notmuch_message_t *m = notmuch_messages_get(msgs);
++		append_message(ctx, q, m, dedup);
++		notmuch_message_destroy(m);
++	}
++}
++
++static void read_threads_query(CONTEXT *ctx, notmuch_query_t *q, int dedup, int limit)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	notmuch_threads_t *threads;
++
++	if (!data)
++		return;
++
++	for (threads = notmuch_query_search_threads(q);
++	     notmuch_threads_valid(threads) &&
++		(limit == 0 || ctx->msgcount < limit);
++	     notmuch_threads_move_to_next(threads)) {
++
++		notmuch_thread_t *thread = notmuch_threads_get(threads);
++		append_thread(ctx, q, thread, dedup);
++		notmuch_thread_destroy(thread);
++	}
++}
++
++int nm_read_query(CONTEXT *ctx)
++{
++	notmuch_query_t *q;
++	struct nm_ctxdata *data;
++	int rc = -1;
++
++	if (init_context(ctx) != 0)
++		return -1;
++
++	data = get_ctxdata(ctx);
++	if (!data)
++		return -1;
++
++	dprint(1, (debugfile, "nm: reading messages...[current count=%d]\n",
++				ctx->msgcount));
++
++	nm_progress_reset(ctx);
++
++	q = get_query(data, FALSE);
++	if (q) {
++		switch(get_query_type(data)) {
++		case NM_QUERY_TYPE_MESGS:
++			read_mesgs_query(ctx, q, 0);
++			break;
++		case NM_QUERY_TYPE_THREADS:
++			read_threads_query(ctx, q, 0, get_limit(data));
++			break;
++		}
++		notmuch_query_destroy(q);
++		rc = 0;
++
++	}
++
++	if (!is_longrun(data))
++		release_db(data);
++
++	ctx->mtime = time(NULL);
++
++	mx_update_context(ctx, ctx->msgcount);
++	data->oldmsgcount = 0;
++
++	dprint(1, (debugfile, "nm: reading messages... done [rc=%d, count=%d]\n",
++				rc, ctx->msgcount));
++	return rc;
++}
++
++int nm_read_entire_thread(CONTEXT *ctx, HEADER *h)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	const char *id;
++	char *qstr = NULL;
++	notmuch_query_t *q = NULL;
++	notmuch_database_t *db = NULL;
++	notmuch_message_t *msg = NULL;
++	int rc = -1;
++
++	if (!data)
++		return -1;
++	if (!(db = get_db(data, FALSE)) || !(msg = get_nm_message(db, h)))
++		goto done;
++
++	dprint(1, (debugfile, "nm: reading entire-thread messages...[current count=%d]\n",
++				ctx->msgcount));
++
++	nm_progress_reset(ctx);
++	id = notmuch_message_get_thread_id(msg);
++	if (!id)
++		goto done;
++	append_str_item(&qstr, "thread:", 0);
++	append_str_item(&qstr, id, 0);
++
++	q = notmuch_query_create(db, qstr);
++	FREE(&qstr);
++	if (!q)
++		goto done;
++	apply_exclude_tags(q);
++	notmuch_query_set_sort(q, NOTMUCH_SORT_NEWEST_FIRST);
++
++	read_threads_query(ctx, q, 1, 0);
++	ctx->mtime = time(NULL);
++	rc = 0;
++
++	if (ctx->msgcount > data->oldmsgcount)
++		mx_update_context(ctx, ctx->msgcount - data->oldmsgcount);
++done:
++	if (q)
++		notmuch_query_destroy(q);
++	if (!is_longrun(data))
++		release_db(data);
++
++	if (ctx->msgcount == data->oldmsgcount)
++		mutt_message _("No more messages in the thread.");
++
++	data->oldmsgcount = 0;
++	dprint(1, (debugfile, "nm: reading entire-thread messages... done [rc=%d, count=%d]\n",
++				rc, ctx->msgcount));
++	return rc;
++}
++
++char *nm_uri_from_query(CONTEXT *ctx, char *buf, size_t bufsz)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	char uri[_POSIX_PATH_MAX + LONG_STRING + 32];	/* path to DB + query + URI "decoration" */
++
++	if (data)
++		snprintf(uri, sizeof(uri), "notmuch://%s?query=%s",
++			 get_db_filename(data), buf);
++	else if (NotmuchDefaultUri)
++		snprintf(uri, sizeof(uri), "%s?query=%s", NotmuchDefaultUri, buf);
++	else if (Maildir)
++		snprintf(uri, sizeof(uri), "notmuch://%s?query=%s", Maildir, buf);
++	else
++		return NULL;
++
++	strncpy(buf, uri, bufsz);
++	buf[bufsz - 1] = '\0';
++
++	dprint(1, (debugfile, "nm: uri from query '%s'\n", buf));
++	return buf;
++}
++
++/*
++ * returns message from notmuch database
++ */
++static notmuch_message_t *get_nm_message(notmuch_database_t *db, HEADER *hdr)
++{
++	notmuch_message_t *msg = NULL;
++	char *id = nm_header_get_id(hdr);
++
++	dprint(2, (debugfile, "nm: find message (%s)\n", id));
++
++	if (id && db)
++		notmuch_database_find_message(db, id, &msg);
++
++	return msg;
++}
++
++static int update_tags(notmuch_message_t *msg, const char *tags)
++{
++	char *tag = NULL, *end = NULL, *p;
++	char *buf = safe_strdup(tags);
++
++	if (!buf)
++		return -1;
++
++	notmuch_message_freeze(msg);
++
++	for (p = buf; p && *p; p++) {
++		if (!tag && isspace(*p))
++			continue;
++		if (!tag)
++			tag = p;		/* begin of the tag */
++		if (*p == ',' || *p == ' ')
++			end = p;		/* terminate the tag */
++		else if (*(p + 1) == '\0')
++			end = p + 1;		/* end of optstr */
++		if (!tag || !end)
++			continue;
++		if (tag >= end)
++			break;
++
++		*end = '\0';
++
++		if (*tag == '-') {
++			dprint(1, (debugfile, "nm: remove tag: '%s'\n", tag + 1));
++			notmuch_message_remove_tag(msg, tag + 1);
++		} else {
++			dprint(1, (debugfile, "nm: add tag: '%s'\n", *tag == '+' ? tag + 1 : tag));
++			notmuch_message_add_tag(msg, *tag == '+' ? tag + 1 : tag);
++		}
++		end = tag = NULL;
++	}
++
++	notmuch_message_thaw(msg);
++	FREE(&buf);
++	return 0;
++}
++
++int nm_modify_message_tags(CONTEXT *ctx, HEADER *hdr, char *buf)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	notmuch_database_t *db = NULL;
++	notmuch_message_t *msg = NULL;
++	int rc = -1;
++
++	if (!buf || !*buf || !data)
++		return -1;
++
++	if (!(db = get_db(data, TRUE)) || !(msg = get_nm_message(db, hdr)))
++		goto done;
++
++	dprint(1, (debugfile, "nm: tags modify: '%s'\n", buf));
++
++	update_tags(msg, buf);
++	update_header_tags(hdr, msg);
++	mutt_set_header_color(ctx, hdr);
++
++	rc = 0;
++	hdr->changed = TRUE;
++done:
++	if (!is_longrun(data))
++		release_db(data);
++	if (hdr->changed)
++		ctx->mtime = time(NULL);
++	dprint(1, (debugfile, "nm: tags modify done [rc=%d]\n", rc));
++	return rc;
++}
++
++static int rename_maildir_filename(const char *old, char *newpath, size_t newsz, HEADER *h)
++{
++	char filename[_POSIX_PATH_MAX];
++	char suffix[_POSIX_PATH_MAX];
++	char folder[_POSIX_PATH_MAX];
++	char *p;
++
++	strfcpy(folder, old, sizeof(folder));
++	p = strrchr(folder, '/');
++	if (p)
++		*p = '\0';
++
++	p++;
++	strfcpy(filename, p, sizeof(filename));
++
++	/* remove (new,cur,...) from folder path */
++	p = strrchr(folder, '/');
++	if (p)
++		*p = '\0';
++
++	/* remove old flags from filename */
++	if ((p = strchr(filename, ':')))
++		*p = '\0';
++
++	/* compose new flags */
++	maildir_flags(suffix, sizeof(suffix), h);
++
++	snprintf(newpath, newsz, "%s/%s/%s%s",
++			folder,
++			(h->read || h->old) ? "cur" : "new",
++			filename,
++			suffix);
++
++	if (strcmp(old, newpath) == 0)
++		return 1;
++
++	if (rename(old, newpath) != 0) {
++		dprint(1, (debugfile, "nm: rename(2) failed %s -> %s\n", old, newpath));
++		return -1;
++	}
++
++	return 0;
++}
++
++static int remove_filename(struct nm_ctxdata *data, const char *path)
++{
++	notmuch_status_t st;
++	notmuch_filenames_t *ls;
++	notmuch_message_t *msg = NULL;
++	notmuch_database_t *db = get_db(data, TRUE);
++	int trans;
++
++	dprint(2, (debugfile, "nm: remove filename '%s'\n", path));
++
++	if (!db)
++		return -1;
++	st = notmuch_database_find_message_by_filename(db, path, &msg);
++	if (st || !msg)
++		return -1;
++	trans = db_trans_begin(data);
++	if (trans < 0)
++		return -1;
++
++	/*
++	 * note that unlink() is probably unnecessary here, it's already removed
++	 * by mh_sync_mailbox_message(), but for sure...
++	 */
++	st = notmuch_database_remove_message(db, path);
++	switch (st) {
++	case NOTMUCH_STATUS_SUCCESS:
++		dprint(2, (debugfile, "nm: remove success, call unlink\n"));
++		unlink(path);
++		break;
++	case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
++		dprint(2, (debugfile, "nm: remove succes (duplicate), call unlink\n"));
++		unlink(path);
++		for (ls = notmuch_message_get_filenames(msg);
++		     ls && notmuch_filenames_valid(ls);
++		     notmuch_filenames_move_to_next(ls)) {
++
++			path = notmuch_filenames_get(ls);
++
++			dprint(2, (debugfile, "nm: remove duplicate: '%s'\n", path));
++			unlink(path);
++			notmuch_database_remove_message(db, path);
++		}
++		break;
++	default:
++		dprint(1, (debugfile, "nm: failed to remove '%s' [st=%d]\n", path, (int) st));
++		break;
++	}
++
++	notmuch_message_destroy(msg);
++	if (trans)
++		db_trans_end(data);
++	return 0;
++}
++
++static int rename_filename(struct nm_ctxdata *data,
++			const char *old, const char *new, HEADER *h)
++{
++	int rc = -1;
++	notmuch_status_t st;
++	notmuch_filenames_t *ls;
++	notmuch_message_t *msg;
++	notmuch_database_t *db = get_db(data, TRUE);
++	int trans;
++
++	if (!db || !new || !old || access(new, F_OK) != 0)
++		return -1;
++
++	dprint(1, (debugfile, "nm: rename filename, %s -> %s\n", old, new));
++	trans = db_trans_begin(data);
++	if (trans < 0)
++		return -1;
++
++	dprint(2, (debugfile, "nm: rename: add '%s'\n", new));
++	st = notmuch_database_add_message(db, new, &msg);
++
++	if (st != NOTMUCH_STATUS_SUCCESS &&
++	    st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {
++		dprint(1, (debugfile, "nm: failed to add '%s' [st=%d]\n", new, (int) st));
++		goto done;
++	}
++
++	dprint(2, (debugfile, "nm: rename: rem '%s'\n", old));
++	st = notmuch_database_remove_message(db, old);
++	switch (st) {
++	case NOTMUCH_STATUS_SUCCESS:
++		break;
++	case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
++		dprint(2, (debugfile, "nm: rename: syncing duplicate filename\n"));
++		notmuch_message_destroy(msg);
++		msg = NULL;
++		notmuch_database_find_message_by_filename(db, new, &msg);
++
++		for (ls = notmuch_message_get_filenames(msg);
++		     msg && ls && notmuch_filenames_valid(ls);
++		     notmuch_filenames_move_to_next(ls)) {
++
++			const char *path = notmuch_filenames_get(ls);
++			char newpath[_POSIX_PATH_MAX];
++
++			if (strcmp(new, path) == 0)
++				continue;
++
++			dprint(2, (debugfile, "nm: rename: syncing duplicate: %s\n", path));
++
++			if (rename_maildir_filename(path, newpath, sizeof(newpath), h) == 0) {
++				dprint(2, (debugfile, "nm: rename dup %s -> %s\n", path, newpath));
++				notmuch_database_remove_message(db, path);
++				notmuch_database_add_message(db, newpath, NULL);
++			}
++		}
++		notmuch_message_destroy(msg);
++		msg = NULL;
++		notmuch_database_find_message_by_filename(db, new, &msg);
++		st = NOTMUCH_STATUS_SUCCESS;
++		break;
++	default:
++		dprint(1, (debugfile, "nm: failed to remove '%s' [st=%d]\n",
++					old, (int) st));
++		break;
++	}
++
++	if (st == NOTMUCH_STATUS_SUCCESS && h && msg) {
++		notmuch_message_maildir_flags_to_tags(msg);
++		update_header_tags(h, msg);
++		update_tags(msg, nm_header_get_tags(h));
++	}
++
++	rc = 0;
++done:
++	if (msg)
++		notmuch_message_destroy(msg);
++	if (trans)
++		db_trans_end(data);
++	return rc;
++}
++
++int nm_update_filename(CONTEXT *ctx, const char *old, const char *new, HEADER *h)
++{
++	char buf[PATH_MAX];
++	int rc;
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++
++	if (!data || !new)
++		return -1;
++
++	if (!old && h && h->data) {
++		nm_header_get_fullpath(h, buf, sizeof(buf));
++		old = buf;
++	}
++
++	rc = rename_filename(data, old, new, h);
++
++	if (!is_longrun(data))
++		release_db(data);
++	ctx->mtime = time(NULL);
++	return rc;
++}
++
++int nm_sync(CONTEXT *ctx, int *index_hint)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	int i, rc = 0;
++	char msgbuf[STRING];
++	progress_t progress;
++	char *uri = ctx->path;
++	int changed = 0;
++
++	if (!data)
++		return -1;
++
++	dprint(1, (debugfile, "nm: sync start ...\n"));
++
++	if (!ctx->quiet) {
++		/* all is in this function so we don't use data->progress here */
++		snprintf(msgbuf, sizeof (msgbuf), _("Writing %s..."), ctx->path);
++		mutt_progress_init(&progress, msgbuf, M_PROGRESS_MSG,
++				   WriteInc, ctx->msgcount);
++	}
++
++	for (i = 0; i < ctx->msgcount; i++) {
++		char old[_POSIX_PATH_MAX], new[_POSIX_PATH_MAX];
++		HEADER *h = ctx->hdrs[i];
++		struct nm_hdrdata *hd = h->data;
++
++		if (!ctx->quiet)
++			mutt_progress_update(&progress, i, -1);
++
++		*old = *new = '\0';
++
++		if (hd->oldpath) {
++			strncpy(old, hd->oldpath, sizeof(old));
++			old[sizeof(old) - 1] = '\0';
++			dprint(2, (debugfile, "nm: fixing obsolete path '%s'\n", old));
++		} else
++			nm_header_get_fullpath(h, old, sizeof(old));
++
++		ctx->path = hd->folder;
++		ctx->magic = hd->magic;
++#if USE_HCACHE
++		rc = mh_sync_mailbox_message(ctx, i, NULL);
++#else
++		rc = mh_sync_mailbox_message(ctx, i);
++#endif
++		ctx->path = uri;
++		ctx->magic = M_NOTMUCH;
++
++		if (rc)
++			break;
++
++		if (!h->deleted)
++			nm_header_get_fullpath(h, new, sizeof(new));
++
++		if (h->deleted || strcmp(old, new) != 0) {
++			if (h->deleted && remove_filename(data, old) == 0)
++				changed = 1;
++			else if (*new && *old && rename_filename(data, old, new, h) == 0)
++				changed = 1;
++		}
++
++		FREE(&hd->oldpath);
++	}
++
++	ctx->path = uri;
++	ctx->magic = M_NOTMUCH;
++
++	if (!is_longrun(data))
++		release_db(data);
++	if (changed)
++		ctx->mtime = time(NULL);
++
++	dprint(1, (debugfile, "nm: .... sync done [rc=%d]\n", rc));
++	return rc;
++}
++
++static unsigned count_query(notmuch_database_t *db, const char *qstr)
++{
++	unsigned res = 0;
++	notmuch_query_t *q = notmuch_query_create(db, qstr);
++
++	if (q) {
++		apply_exclude_tags(q);
++		res = notmuch_query_count_messages(q);
++		notmuch_query_destroy(q);
++		dprint(1, (debugfile, "nm: count '%s', result=%d\n", qstr, res));
++	}
++	return res;
++}
++
++int nm_nonctx_get_count(char *path, int *all, int *new)
++{
++	struct uri_tag *query_items = NULL, *item;
++	char *db_filename = NULL, *db_query = NULL;
++	notmuch_database_t *db = NULL;
++	int rc = -1, dflt = 0;
++
++	dprint(1, (debugfile, "nm: count\n"));
++
++	if (url_parse_query(path, &db_filename, &query_items)) {
++		mutt_error(_("failed to parse notmuch uri: %s"), path);
++		goto done;
++	}
++	if (!query_items)
++		goto done;
++
++	for (item = query_items; item; item = item->next) {
++		if (item->value && strcmp(item->name, "query") == 0) {
++			db_query = item->value;
++			break;
++		}
++	}
++
++	if (!db_query)
++		goto done;
++
++	if (!db_filename) {
++		if (NotmuchDefaultUri) {
++			if (strncmp(NotmuchDefaultUri, "notmuch://", 10) == 0)
++				db_filename = NotmuchDefaultUri + 10;
++			else
++				db_filename = NotmuchDefaultUri;
++		} else if (Maildir)
++			db_filename = Maildir;
++		dflt = 1;
++	}
++
++	/* don't be verbose about connection, as we're called from
++	 * sidebar/buffy very often */
++	db = do_database_open(db_filename, FALSE, FALSE);
++	if (!db)
++		goto done;
++
++	/* all emails */
++	if (all)
++		*all = count_query(db, db_query);
++
++	/* new messages */
++	if (new) {
++		char *qstr;
++
++		safe_asprintf(&qstr, "( %s ) tag:%s",
++				db_query, NotmuchUnreadTag);
++		*new = count_query(db, qstr);
++		FREE(&qstr);
++	}
++
++	rc = 0;
++done:
++	if (db) {
++#ifdef NOTMUCH_API_3
++		notmuch_database_destroy(db);
++#else
++		notmuch_database_close(db);
++#endif
++		dprint(1, (debugfile, "nm: count close DB\n"));
++	}
++	if (!dflt)
++		FREE(&db_filename);
++	url_free_tags(query_items);
++
++	dprint(1, (debugfile, "nm: count done [rc=%d]\n", rc));
++	return rc;
++}
++
++char *nm_get_description(CONTEXT *ctx)
++{
++	BUFFY *p;
++
++	for (p = VirtIncoming; p; p = p->next)
++		if (p->path && p->desc && strcmp(p->path, ctx->path) == 0)
++			return p->desc;
++
++	return NULL;
++}
++
++int nm_description_to_path(const char *desc, char *buf, size_t bufsz)
++{
++	BUFFY *p;
++
++	if (!desc || !buf || !bufsz)
++		return -EINVAL;
++
++	for (p = VirtIncoming; p; p = p->next)
++		if (p->path && p->desc && strcmp(desc, p->desc) == 0) {
++			strncpy(buf, p->path, bufsz);
++			buf[bufsz - 1] = '\0';
++			return 0;
++		}
++
++	return -1;
++}
++
++/*
++ * returns header from mutt context
++ */
++static HEADER *get_mutt_header(CONTEXT *ctx, notmuch_message_t *msg)
++{
++	char *mid;
++	const char *id;
++	HEADER *h;
++
++	if (!ctx || !msg)
++		return NULL;
++
++	id = notmuch_message_get_message_id(msg);
++	if (!id)
++		return NULL;
++
++	dprint(2, (debugfile, "nm: mutt header, id='%s'\n", id));
++
++	if (!ctx->id_hash) {
++		dprint(2, (debugfile, "nm: init hash\n"));
++		ctx->id_hash = mutt_make_id_hash(ctx);
++		if (!ctx->id_hash)
++			return NULL;
++	}
++
++	mid = nm2mutt_message_id( id );
++	dprint(2, (debugfile, "nm: mutt id='%s'\n", mid));
++
++	h = hash_find(ctx->id_hash, mid);
++	FREE(&mid);
++	return h;
++}
++
++int nm_check_database(CONTEXT *ctx, int *index_hint)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	time_t mtime = 0;
++	notmuch_query_t *q;
++	notmuch_messages_t *msgs;
++	int i, limit, occult = 0, new_flags = 0;
++
++	if (!data || get_database_mtime(data, &mtime) != 0)
++		return -1;
++
++	if (ctx->mtime >= mtime) {
++		dprint(2, (debugfile, "nm: check unnecessary (db=%d ctx=%d)\n", mtime, ctx->mtime));
++		return 0;
++	}
++
++	dprint(1, (debugfile, "nm: checking (db=%d ctx=%d)\n", mtime, ctx->mtime));
++
++	q = get_query(data, FALSE);
++	if (!q)
++		goto done;
++
++	dprint(1, (debugfile, "nm: start checking (count=%d)\n", ctx->msgcount));
++	data->oldmsgcount = ctx->msgcount;
++	data->noprogress = 1;
++
++	for (i = 0; i < ctx->msgcount; i++)
++		ctx->hdrs[i]->active = 0;
++
++	limit = get_limit(data);
++
++	for (i = 0, msgs = notmuch_query_search_messages(q);
++	     notmuch_messages_valid(msgs) && (limit == 0 || i < limit);
++	     notmuch_messages_move_to_next(msgs), i++) {
++
++		char old[_POSIX_PATH_MAX];
++		const char *new;
++
++		notmuch_message_t *m = notmuch_messages_get(msgs);
++		HEADER *h = get_mutt_header(ctx, m);
++
++		if (!h) {
++			/* new email */
++			append_message(ctx, NULL, m, 0);
++			notmuch_message_destroy(m);
++			continue;
++		}
++
++		/* message already exists, merge flags */
++		h->active = 1;
++
++		/* check to see if the message has moved to a different
++		 * subdirectory.  If so, update the associated filename.
++		 */
++		new = get_message_last_filename(m);
++		nm_header_get_fullpath(h, old, sizeof(old));
++
++		if (mutt_strcmp(old, new) != 0)
++			update_message_path(h, new);
++
++		if (!h->changed) {
++			/* if the user hasn't modified the flags on
++			 * this message, update the flags we just
++			 * detected.
++			 */
++			HEADER tmp;
++			memset(&tmp, 0, sizeof(tmp));
++			maildir_parse_flags(&tmp, new);
++			maildir_update_flags(ctx, h, &tmp);
++		}
++
++		if (update_header_tags(h, m) == 0)
++			new_flags++;
++
++		notmuch_message_destroy(m);
++	}
++
++	for (i = 0; i < ctx->msgcount; i++) {
++		if (ctx->hdrs[i]->active == 0) {
++			occult = 1;
++			break;
++		}
++	}
++
++	if (ctx->msgcount > data->oldmsgcount)
++		mx_update_context(ctx, ctx->msgcount - data->oldmsgcount);
++done:
++	if (q)
++		notmuch_query_destroy(q);
++
++	if (!is_longrun(data))
++		release_db(data);
++
++	ctx->mtime = time(NULL);
++
++	dprint(1, (debugfile, "nm: ... check done [count=%d, new_flags=%d, occult=%d]\n",
++				ctx->msgcount, new_flags, occult));
++
++	return occult ? M_REOPENED :
++	       ctx->msgcount > data->oldmsgcount ? M_NEW_MAIL :
++	       new_flags ? M_FLAGS : 0;
++}
++
++int nm_record_message(CONTEXT *ctx, char *path, HEADER *h)
++{
++	notmuch_database_t *db;
++	notmuch_status_t st;
++	notmuch_message_t *msg = NULL;
++	int rc = -1, trans;
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++
++	if (!path || !data || access(path, F_OK) != 0)
++		return 0;
++	db = get_db(data, TRUE);
++	if (!db)
++		return -1;
++
++	dprint(1, (debugfile, "nm: record message: %s\n", path));
++	trans = db_trans_begin(data);
++	if (trans < 0)
++		goto done;
++
++	st = notmuch_database_add_message(db, path, &msg);
++
++	if (st != NOTMUCH_STATUS_SUCCESS &&
++	    st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {
++		dprint(1, (debugfile, "nm: failed to add '%s' [st=%d]\n", path, (int) st));
++		goto done;
++	}
++
++	if (st == NOTMUCH_STATUS_SUCCESS && msg) {
++		notmuch_message_maildir_flags_to_tags(msg);
++		if (h)
++			update_tags(msg, nm_header_get_tags(h));
++		if (NotmuchRecordTags)
++			update_tags(msg, NotmuchRecordTags);
++	}
++
++	rc = 0;
++done:
++	if (msg)
++		notmuch_message_destroy(msg);
++	if (trans == 1)
++		db_trans_end(data);
++	if (!is_longrun(data))
++		release_db(data);
++	return rc;
++}
++
++/*
++ * Fill a list with all notmuch tags.
++ *
++ * If tag_list is NULL, just count the tags.
++ */
++int nm_get_all_tags(CONTEXT *ctx, char **tag_list, int *tag_count)
++{
++	struct nm_ctxdata *data = get_ctxdata(ctx);
++	notmuch_database_t *db = NULL;
++	notmuch_tags_t *tags = NULL;
++	int rc = -1;
++
++	if (!data)
++		return -1;
++
++	if (!(db = get_db(data, FALSE)) ||
++			!(tags = notmuch_database_get_all_tags(db)))
++		goto done;
++
++	*tag_count = 0;
++	dprint(1, (debugfile, "nm: get all tags\n"));
++
++	while (notmuch_tags_valid(tags)) {
++		if (tag_list != NULL) {
++			tag_list[*tag_count] = safe_strdup(notmuch_tags_get(tags));
++		}
++		(*tag_count)++;
++		notmuch_tags_move_to_next(tags);
++	}
++
++	rc = 0;
++done:
++	if (tags)
++		notmuch_tags_destroy(tags);
++
++	if (!is_longrun(data))
++		release_db(data);
++
++	dprint(1, (debugfile, "nm: get all tags done [rc=%d tag_count=%u]\n", rc,
++						 *tag_count));
++	return rc;
++}
+diff -urN mutt-1.6.1-sidebar-notmuch/mutt_notmuch.h mutt-1.6.1-notmuch/mutt_notmuch.h
+--- mutt-1.6.1-sidebar-notmuch/mutt_notmuch.h	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-notmuch/mutt_notmuch.h	2016-05-02 03:02:15.145215107 +0100
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (C) 2011 Karel Zak <kzak at redhat.com>
++ */
++#ifndef _MUTT_NOTMUCH_H_
++#define _MUTT_NOTMUCH_H_ 1
++
++int nm_read_query(CONTEXT *ctx);
++int nm_read_entire_thread(CONTEXT *ctx, HEADER *h);
++
++int nm_sync(CONTEXT * ctx, int *index_hint);
++int nm_check_database(CONTEXT * ctx, int *index_hint);
++char *nm_header_get_folder(HEADER *h);
++int nm_header_get_magic(HEADER *h);
++char *nm_header_get_fullpath(HEADER *h, char *buf, size_t bufsz);
++int nm_update_filename(CONTEXT *ctx, const char *o, const char *n, HEADER *h);
++char *nm_uri_from_query(CONTEXT *ctx, char *buf, size_t bufsz);
++int nm_modify_message_tags(CONTEXT *ctx, HEADER *hdr, char *tags);
++
++void nm_longrun_init(CONTEXT *cxt, int writable);
++void nm_longrun_done(CONTEXT *cxt);
++
++char *nm_get_description(CONTEXT *ctx);
++int nm_description_to_path(const char *desc, char *buf, size_t bufsz);
++
++int nm_record_message(CONTEXT *ctx, char *path, HEADER *h);
++
++void nm_debug_check(CONTEXT *ctx);
++int nm_get_all_tags(CONTEXT *ctx, char **tag_list, int *tag_count);
++
++/*
++ * functions usable outside notmuch CONTEXT
++ */
++int nm_nonctx_get_count(char *path, int *all, int *new);
++
++char *nm_header_get_tag_transformed(char *tag, HEADER *h);
++char *nm_header_get_tags_transformed(HEADER *h);
++char *nm_header_get_tags(HEADER *h);
++
++#endif /* _MUTT_NOTMUCH_H_ */
+diff -urN mutt-1.6.1-sidebar-notmuch/mx.c mutt-1.6.1-notmuch/mx.c
+--- mutt-1.6.1-sidebar-notmuch/mx.c	2016-05-02 03:02:12.715176444 +0100
++++ mutt-1.6.1-notmuch/mx.c	2016-05-02 03:02:15.229216443 +0100
+@@ -41,6 +41,10 @@
+ #include "pop.h"
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #include "buffy.h"
+ 
+ #ifdef USE_DOTLOCK
+@@ -60,6 +64,10 @@
+ #include <ctype.h>
+ #include <utime.h>
+ 
++#if USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ 
+ #define mutt_is_spool(s)  (mutt_strcmp (Spoolfile, s) == 0)
+ 
+@@ -346,6 +354,24 @@
+ }
+ #endif
+ 
++#ifdef USE_NOTMUCH
++
++int mx_is_notmuch(const char *p)
++{
++  url_scheme_t scheme;
++
++  if (!p)
++    return 0;
++
++  scheme = url_check_scheme (p);
++  if (scheme == U_NOTMUCH)
++    return 1;
++
++  return 0;
++}
++
++#endif
++
+ int mx_get_magic (const char *path)
+ {
+   struct stat st;
+@@ -363,6 +389,11 @@
+     return M_POP;
+ #endif /* USE_POP */
+ 
++#ifdef USE_NOTMUCH
++  if (mx_is_notmuch(path))
++    return M_NOTMUCH;
++#endif
++
+   if (stat (path, &st) == -1)
+   {
+     dprint (1, (debugfile, "mx_get_magic(): unable to stat %s: %s (errno %d).\n",
+@@ -676,6 +707,12 @@
+       break;
+ #endif /* USE_POP */
+ 
++#ifdef USE_NOTMUCH
++    case M_NOTMUCH:
++      rc = nm_read_query (ctx);
++      break;
++#endif /* USE_IMAP */
++
+     default:
+       rc = -1;
+       break;
+@@ -789,6 +826,13 @@
+       rc = pop_sync_mailbox (ctx, index_hint);
+       break;
+ #endif /* USE_POP */
++
++#ifdef USE_NOTMUCH
++    case M_NOTMUCH:
++      rc = nm_sync (ctx, index_hint);
++      break;
++#endif /* USE_NOTMUCH */
++
+   }
+ 
+ #if 0
+@@ -1381,6 +1425,11 @@
+       case M_POP:
+ 	return (pop_check_mailbox (ctx, index_hint));
+ #endif /* USE_POP */
++
++#ifdef USE_NOTMUCH
++      case M_NOTMUCH:
++	return nm_check_database(ctx, index_hint);
++#endif
+     }
+   }
+ 
+@@ -1392,7 +1441,7 @@
+ MESSAGE *mx_open_message (CONTEXT *ctx, int msgno)
+ {
+   MESSAGE *msg;
+-  
++
+   msg = safe_calloc (1, sizeof (MESSAGE));
+   switch (msg->magic = ctx->magic)
+   {
+@@ -1403,15 +1452,24 @@
+ 
+     case M_MH:
+     case M_MAILDIR:
++#ifdef USE_NOTMUCH
++    case M_NOTMUCH:
++#endif
+     {
+       HEADER *cur = ctx->hdrs[msgno];
+       char path[_POSIX_PATH_MAX];
+-      
+-      snprintf (path, sizeof (path), "%s/%s", ctx->path, cur->path);
+-      
++      char *folder = ctx->path;
++#ifdef USE_NOTMUCH
++      if (ctx->magic == M_NOTMUCH) {
++	msg->magic = nm_header_get_magic(cur);
++	folder = nm_header_get_folder(cur);
++      }
++#endif
++      snprintf (path, sizeof (path), "%s/%s", folder, cur->path);
++
+       if ((msg->fp = fopen (path, "r")) == NULL && errno == ENOENT &&
+-	  ctx->magic == M_MAILDIR)
+-	msg->fp = maildir_open_find_message (ctx->path, cur->path);
++	  (ctx->magic == M_MAILDIR || ctx->magic == M_NOTMUCH))
++	msg->fp = maildir_open_find_message (folder, cur->path, NULL);
+       
+       if (msg->fp == NULL)
+       {
+@@ -1486,13 +1544,17 @@
+       break;
+     }
+ #endif
+-    
++
+     case M_MAILDIR:
+     {
+       r = maildir_commit_message (ctx, msg, NULL);
+       break;
+     }
+-    
++
++    case M_NOTMUCH:
++      mutt_perror _("Can't write to virtual folder.");
++      break;
++
+     case M_MH:
+     {
+       r = mh_commit_message (ctx, msg, NULL);
+@@ -1506,7 +1568,7 @@
+     mutt_perror _("Can't write message");
+     r = -1;
+   }
+- 
++
+   return r;
+ }
+ 
+@@ -1516,14 +1578,18 @@
+   int r = 0;
+ 
+   if ((*msg)->magic == M_MH || (*msg)->magic == M_MAILDIR
+-      || (*msg)->magic == M_IMAP || (*msg)->magic == M_POP)
++      || (*msg)->magic == M_IMAP || (*msg)->magic == M_POP
++      || (*msg)->magic == M_NOTMUCH)
+   {
+     r = safe_fclose (&(*msg)->fp);
+   }
+   else
+     (*msg)->fp = NULL;
+ 
+-  if ((*msg)->path)
++  dprint (2, (debugfile, "mx_close_message (): close: path=%s, commited=%s\n",
++	(*msg)->path, (*msg)->commited_path));
++
++  if ((*msg)->path && (*msg)->magic != M_NOTMUCH)
+   {
+     dprint (1, (debugfile, "mx_close_message (): unlinking %s\n",
+ 		(*msg)->path));
+@@ -1531,6 +1597,7 @@
+     FREE (&(*msg)->path);
+   }
+ 
++  FREE (&(*msg)->commited_path);
+   FREE (msg);		/* __FREE_CHECKED__ */
+   return (r);
+ }
+diff -urN mutt-1.6.1-sidebar-notmuch/mx.h mutt-1.6.1-notmuch/mx.h
+--- mutt-1.6.1-sidebar-notmuch/mx.h	2016-05-02 03:02:12.715176444 +0100
++++ mutt-1.6.1-notmuch/mx.h	2016-05-02 03:02:15.229216443 +0100
+@@ -35,6 +35,7 @@
+   M_MH,
+   M_MAILDIR,
+   M_IMAP,
++  M_NOTMUCH,
+   M_POP
+ };
+ 
+@@ -67,13 +68,30 @@
+ int maildir_check_mailbox (CONTEXT *, int *);
+ int maildir_check_empty (const char *);
+ 
++HEADER *maildir_parse_message (int magic, const char *fname, int is_old, HEADER * _h);
++HEADER *maildir_parse_stream (int magic, FILE *f, const char *fname, int is_old, HEADER * _h);
++void maildir_parse_flags (HEADER * h, const char *path);
++void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n);
++void maildir_flags(char *dest, size_t destlen, HEADER * hdr);
++
++#if USE_HCACHE
++#include <hcache.h>
++int mh_sync_mailbox_message (CONTEXT * ctx, int msgno, header_cache_t *hc);
++#else
++int mh_sync_mailbox_message (CONTEXT * ctx, int msgno);
++#endif
++
++#ifdef USE_NOTMUCH
++int mx_is_notmuch(const char *p);
++#endif
++
+ int maildir_commit_message (CONTEXT *, MESSAGE *, HEADER *);
+ int mh_commit_message (CONTEXT *, MESSAGE *, HEADER *);
+ 
+ int maildir_open_new_message (MESSAGE *, CONTEXT *, HEADER *);
+ int mh_open_new_message (MESSAGE *, CONTEXT *, HEADER *);
+ 
+-FILE *maildir_open_find_message (const char *, const char *);
++FILE *maildir_open_find_message (const char *, const char *, char **);
+ 
+ int mbox_strict_cmp_headers (const HEADER *, const HEADER *);
+ int mutt_reopen_mailbox (CONTEXT *, int *);
+diff -urN mutt-1.6.1-sidebar-notmuch/OPS.NOTMUCH mutt-1.6.1-notmuch/OPS.NOTMUCH
+--- mutt-1.6.1-sidebar-notmuch/OPS.NOTMUCH	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-notmuch/OPS.NOTMUCH	2016-05-02 03:02:15.112214581 +0100
+@@ -0,0 +1,5 @@
++OP_MAIN_CHANGE_VFOLDER "open a different virtual folder"
++OP_MAIN_VFOLDER_FROM_QUERY "generate virtual folder from query"
++OP_MAIN_MODIFY_LABELS "modify (notmuch) tags"
++OP_MAIN_MODIFY_LABELS_THEN_HIDE "modify labeld and then hide message"
++OP_MAIN_ENTIRE_THREAD "read entire thread of the current message"
+diff -urN mutt-1.6.1-sidebar-notmuch/OPS.SIDEBAR mutt-1.6.1-notmuch/OPS.SIDEBAR
+--- mutt-1.6.1-sidebar-notmuch/OPS.SIDEBAR	2016-05-02 03:02:12.689176031 +0100
++++ mutt-1.6.1-notmuch/OPS.SIDEBAR	2016-05-02 03:02:15.113214597 +0100
+@@ -5,4 +5,5 @@
+ OP_SIDEBAR_PAGE_UP "Scroll the Sidebar up 1 page"
+ OP_SIDEBAR_PREV "Move the highlight to previous mailbox"
+ OP_SIDEBAR_PREV_NEW "Move the highlight to previous mailbox with new mail"
++OP_SIDEBAR_TOGGLE_VIRTUAL "toggle between mailboxes and virtual mailboxes"
+ OP_SIDEBAR_TOGGLE_VISIBLE "Make the Sidebar (in)visible"
+diff -urN mutt-1.6.1-sidebar-notmuch/pattern.c mutt-1.6.1-notmuch/pattern.c
+--- mutt-1.6.1-sidebar-notmuch/pattern.c	2016-05-02 03:02:12.716176460 +0100
++++ mutt-1.6.1-notmuch/pattern.c	2016-05-02 03:02:15.230216459 +0100
+@@ -42,6 +42,10 @@
+ #include "imap/imap.h"
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ static int eat_regexp (pattern_t *pat, BUFFER *, BUFFER *);
+ static int eat_date (pattern_t *pat, BUFFER *, BUFFER *);
+ static int eat_range (pattern_t *pat, BUFFER *, BUFFER *);
+@@ -95,6 +99,9 @@
+   { 'x', M_REFERENCE,		0,		eat_regexp },
+   { 'X', M_MIMEATTACH,		0,		eat_range },
+   { 'y', M_XLABEL,		0,		eat_regexp },
++#ifdef USE_NOTMUCH
++  { 'Y', M_NOTMUCH_LABEL,	0,		eat_regexp },
++#endif
+   { 'z', M_SIZE,		0,		eat_range },
+   { '=', M_DUPLICATED,		0,		NULL },
+   { '$', M_UNREFERENCED,	0,		NULL },
+@@ -1210,6 +1217,13 @@
+      return (pat->not ^ ((h->security & APPLICATION_PGP) && (h->security & PGPKEY)));
+     case M_XLABEL:
+       return (pat->not ^ (h->env->x_label && patmatch (pat, h->env->x_label) == 0));
++#ifdef USE_NOTMUCH
++    case M_NOTMUCH_LABEL:
++      {
++      char *tags = nm_header_get_tags(h);
++      return (pat->not ^ (tags && patmatch (pat, tags) == 0));
++      }
++#endif
+     case M_HORMEL:
+       return (pat->not ^ (h->env->spam && h->env->spam->data && patmatch (pat, h->env->spam->data) == 0));
+     case M_DUPLICATED:
+diff -urN mutt-1.6.1-sidebar-notmuch/protos.h mutt-1.6.1-notmuch/protos.h
+--- mutt-1.6.1-sidebar-notmuch/protos.h	2016-05-02 03:02:12.732176715 +0100
++++ mutt-1.6.1-notmuch/protos.h	2016-05-02 03:02:15.248216745 +0100
+@@ -80,6 +80,9 @@
+ void mutt_delete_parameter (const char *attribute, PARAMETER **p);
+ void mutt_set_parameter (const char *, const char *, PARAMETER **);
+ 
++#ifdef USE_NOTMUCH
++int mutt_parse_virtual_mailboxes (BUFFER *path, BUFFER *s, unsigned long data, BUFFER *err);
++#endif
+ 
+ FILE *mutt_open_read (const char *, pid_t *);
+ 
+@@ -286,6 +289,10 @@
+ int mutt_check_traditional_pgp (HEADER *, int *);
+ int mutt_command_complete (char *, size_t, int, int);
+ int mutt_var_value_complete (char *, size_t, int);
++#if USE_NOTMUCH
++int mutt_nm_query_complete (char *buffer, size_t len, int pos, int numtabs);
++int mutt_nm_tag_complete (char *buffer, size_t len, int pos, int numtabs);
++#endif
+ int mutt_complete (char *, size_t);
+ int mutt_compose_attachment (BODY *a);
+ int mutt_copy_body (FILE *, BODY **, BODY *);
+@@ -301,8 +308,10 @@
+ int mutt_parent_message (CONTEXT *, HEADER *);
+ int mutt_prepare_template(FILE*, CONTEXT *, HEADER *, HEADER *, short);
+ int mutt_resend_message (FILE *, CONTEXT *, HEADER *);
+-#define mutt_enter_fname(A,B,C,D,E) _mutt_enter_fname(A,B,C,D,E,0,NULL,NULL)
+-int _mutt_enter_fname (const char *, char *, size_t, int *, int, int, char ***, int *);
++#define mutt_enter_fname(A,B,C,D,E) _mutt_enter_fname(A,B,C,D,E,0,NULL,NULL,0)
++#define mutt_enter_vfolder(A,B,C,D,E) _mutt_enter_fname(A,B,C,D,E,0,NULL,NULL,M_SEL_VFOLDER)
++
++int _mutt_enter_fname (const char *, char *, size_t, int *, int, int, char ***, int *, int);
+ int  mutt_enter_string (char *buf, size_t buflen, int y, int x, int flags);
+ int _mutt_enter_string (char *, size_t, int, int, int, int, char ***, int *, ENTER_STATE *);
+ #define mutt_get_field(A,B,C,D) _mutt_get_field(A,B,C,D,0,NULL,NULL)
+@@ -367,7 +376,7 @@
+ void mutt_update_num_postponed (void);
+ int mutt_wait_filter (pid_t);
+ int mutt_which_case (const char *);
+-int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, char *);
++int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, char *, char **);
+ int mutt_write_mime_body (BODY *, FILE *);
+ int mutt_write_mime_header (BODY *, FILE *);
+ int mutt_write_one_header (FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, int flags);
+diff -urN mutt-1.6.1-sidebar-notmuch/README.notmuch mutt-1.6.1-notmuch/README.notmuch
+--- mutt-1.6.1-sidebar-notmuch/README.notmuch	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-notmuch/README.notmuch	2016-05-02 03:02:15.117214661 +0100
+@@ -0,0 +1,402 @@
++notmuch support for mutt
++------------------------
++
++ * notmuch is e-mail fulltext indexing and tagging engine; see
++   http://notmuchmail.org/ for more information.
++
++ * home page (wiki) and git:
++
++   https://github.com/karelzak/mutt-kz
++
++   Note that the master branch is rebased to be up to date with mutt upstream. Use
++   stable/v<version> branches for downstream packaging.
++
++ * mailing list:
++
++   https://admin.fedoraproject.org/mailman/listinfo/mutt-kz
++
++ * requirements:
++
++   notmuch >= 0.9
++
++ * compile:
++
++  $ git clone git://github.com/karelzak/mutt-kz.git
++  $ cd mutt-kz
++  $ ./prepare
++  $ ./configure --enable-notmuch [--enable-debug]
++  $ make
++
++ * Folders URI
++
++   notmuch://[<path>][?<item>=<name>[& ...]]
++
++   The <path> is an absolute path to the directory where the notmuch database
++   is found as returned by 'notmuch config get database.path' command. Note that
++   the <path> should NOT include .notmuch directory name.
++
++   If the "<path>" is not defined then $nm_default_uri or $folder is used,
++   for example:
++
++	set nm_default_uri = "notmuch:///home/foo/maildir"
++	virtual-mailboxes "My INBOX" "notmuch://?query=tag:inbox"
++
++   Items:
++
++      query=<string>
++
++	 See SEARCH SYNTAX in notmuch man page. Don't forget to use "and" and
++         "or" operators in your queries.
++
++      Note that proper URI should not contain blank space and all "bad" chars
++      should be encoded, for example
++
++	 "tag:AAA and tag:BBB" --encoding-> tag:AAA%20and%20tag:BBB
++
++      but mutt config file parser is smart enough to accept space in quoted
++      strings. It means that you can use
++
++         "notmuch:///foo?query=tag:AAA and tag:BBB"
++
++      in your config files to keep things readable.
++
++      See http://xapian.org/docs/queryparser.html for more details about Xapian
++      queries.
++
++
++      limit=<number>
++
++         Restricts number of messages/threads in the result. The default limit
++         is nm_db_limit.
++
++      type=<threads|messages>
++
++         Reads all matching messages or whole-threads. The default is 'messages'
++         or nm_query_type.
++
++
++ * commands:
++
++   change-vfolder:
++      - switch to another virtual folder, a new folder maybe be specified by
++        vfolder description (see virtual-mailboxes) or URI
++      - the default is next vfolder with unread messages
++      - default key: X
++
++   vfolder-from-query:
++      - generate new virtual folder from notmuch search query
++      - default key: <Esc>X
++      - note: TAB completion of 'tag:' names is available
++
++   modify-labels:
++      - add or remove notmuch tags; [+]<tag> to add, -<tag> to remove
++      - default key: `
++      - note: TAB completion of tag names is available
++      - example: "+AAA +BBB -CCC"
++
++   modify-labels-then-hide:
++      - same as <modify-labels> but message is marked by <quasi-delete>
++      - not mapped to any key
++      - note: TAB completion of tag names is available
++      - example (add "archive" notmuch tag and remove message from screen):
++
++       macro index A "<modify-labels-then-hide>+archive -inbox\n<sync-mailbox>"
++       macro index I "<modify-labels-then-hide>-inbox\n<sync-mailbox>"
++
++   quasi-delete:
++      - delete message from mutt (usually after <sync-mailbox> function), but
++        don't touch message on disk
++
++   entire-thread:
++      - add to the current list of the messages all messages that belongs to the same thread
++        as the current message. This command is useful when you have a new email in your INBOX
++        and you want to see the rest of the archived thread.
++      - default key: +
++
++ * Pattern modifiers:
++
++   Many of Mutt's commands allow you to specify a pattern to match (limit,
++   tag-pattern, delete-pattern, color, etc.). The following notmuch specific
++   mutt pattern modifiers are available:
++
++   - '~Y EXPR': Messages which contain EXPR in the list of labels.
++     Example:
++        # Color red all messages labeled as 'spam'.
++        color index    red      default        "~Y '\W?spam\W?'"
++
++ * muttrc:
++
++   Note that you can use notmuch specific mutt config file, see -F <config> in
++   mutt docs.
++
++
++   virtual-mailboxes <description> <uri> [ ...]
++
++      This command specifies one or more virtual folder. The folders are
++      accessible by command 'X'. It's possible to use the virtual mailbox
++      description as a sort key (e.g set sort_sidebar=desc)
++
++      example:
++
++      virtual-mailboxes "Linux Kernel" "notmuch:///whereis/db?query=tag:lkml&limit=1000" \
++                        "Filesystems"  "notmuch:///whereis/db?query=tag:fs" \
++                        "Music"        "notmuch:///another/db?query=tag:hard and tag:heavy"
++
++      The folder description is used for status line, folders browser, sidebar
++      and <change-vfolder> command (this command also accepts vfolder URI). The
++      folder-hook regex uses the URI.
++
++   virtual_spoolfile = <boolean>
++
++      When set, mutt will use the first virtual mailbox (see virtual-mailboxes)
++      as a spoolfile.
++
++      When set together with sidebar, mutt will use list of virtual folders in
++      the sidebar. It's possible to toggle between virtual and normal folders by
++      sidebar-toggle command.
++
++   tag-transforms <tag> <transform> [ ...]
++
++      This command specifies text transforms to be shown instead of the actual
++      tag names with '%g' in the index and pager formats. Note that Unicode
++      symbols can be used for transforms.
++
++      example:
++
++      tag-transforms "inbox"   "i"   \
++                     "unread"  "u"   \
++                     "replied" "↻ "  \
++                     "sent"    "➥ "  \
++                     "todo"    "T"   \
++                     "deleted" "DEL" \
++                     "invites" "CAL"
++
++   tag-formats <tag> <format sequence> [ ...]
++
++      Specify index formatting sequences for individual tags for direct
++      placement in the $index_format. The formats must start with 'G' and
++      the entire sequence is case sensitive.
++
++      example:
++
++      tag-formats "inbox"   "GI" \
++                  "unread"  "GU" \
++                  "replied" "GR" \
++                  "sent"    "GS" \
++                  "todo"    "Gt" \
++                  "deleted" "GD" \
++                  "invites" "Gi"
++
++      Now instead of using '%g' in your $index_format, which lists all tags
++      in a non-deterministic order, you can something like the following which puts
++      a transformed tag name in a specific spot on the index line:
++
++      set index_format='4C %S %[%y.%m.%d] %-18.18n %?GU?%GU& ? %?GR?%GR& ? %?GI?%GI& ? %s'
++
++      The %G formatting sequence may display all tags including tags hidden by
++      nm_hidden_tags.
++
++   nm_record = <boolean>
++
++      Add messages stored to the mutt record (see $record in the mutt docs)
++      also to notmuch DB. If you reply to an email then the new email inherits
++      tags from the original email.
++
++   nm_record_tags = <comma delimited list>
++
++      Tags that should be removed or added to the to the messages stored in the mutt record.
++
++      example:
++
++      set record = "~/sent-mails"
++      set nm_record = yes
++      set nm_record_tags = "-inbox,archive,me"
++
++   nm_open_timeout = <seconds>
++
++      This option specifies timeout for Notmuch database. Default is 5 seconds.
++
++   nm_default_uri = <uri>
++
++      This variable specifies the default Notmuch database in format
++      notmuch://<absolute path>, the URI is used for notmuch queries (ESC+X) when the
++      current folder is not based on notmuch. If the default URI is not specified
++      then mutt will try to use $folder variable (see mutt manual for more details).
++
++   nm_hidden_tags = <comma delimited list>
++
++      This variable specifies private notmuch tags which should not be printed
++      on screen (index, pager).
++
++      Default is "unread,draft,flagged,passed,replied,attachment".
++
++   nm_exclude_tags = <comma delimited list>
++
++      The messages tagged with these tags are excluded and not loaded
++      from notmuch DB to mutt unless specified explicitly.
++
++      Not set by default.
++
++   nm_unread_tag = <name>
++
++      This variable specifies notmuch tag which is used for unread messages. The
++      variable is used to count unread messages in DB only. All other mutt
++      commands use standard (e.g. maildir) flags.
++
++      Default is "unread".
++
++   nm_db_limit = <num>
++
++     This variable specifies notmuch query limit.
++
++     Default is unlimited.
++
++   nm_query_type = <threads|messages>
++
++     This variable specifies notmuch query type, supported types: 'threads' and
++     'messages'.
++
++     Default is 'messages'.
++
++   vfolder_format = <string>
++
++      This variable allows you to customize the file browser display for virtual
++      folders to your personal taste.  This string is similar to $index_format,
++      but has its own set of printf(3)-like sequences:
++
++	%f   folder name (description)
++	%n   number of all messages
++	%N   number of new messages
++	%>X  right justify the rest of the string and pad with character ``X''
++	%|X  pad to the end of the line with character ``X''
++	%*X  soft-fill with character ``X'' as pad
++
++      Default is "%6n(%6N) %f ".
++
++   index_format and pager_format
++
++        %g   notmuch tags (labels)
++        %Gx  specific notmuch tag defined by tag-formats (see above)
++
++        for example:
++
++        tag-formats "inbox" "GI"
++        set index_format = "%4C %Z %?GI?%GI? ?  %[%d/%b]  %-16.15F %s %> %?g?(%g)?"
++        set pager_format = "-%Z- %C/%m: %-20.20n   %s%*  -- %?g?(%g)? - (%P)"
++
++
++* .muttrc example:
++
++	set record="~/Mail/Maildir/sent-mail"
++	set nm_record = yes
++	set nm_record_tags ="-inbox me archive"
++
++	set nm_default_uri="notmuch:///home/kzak/Mail/Maildir"
++	set virtual_spoolfile	= yes
++	set sort_browser        = unsorted
++
++	# normal folders
++	set mbox_type=Maildir
++	set folder="~/Mail/Maildir"
++	mailboxes =rh =fedora =misc
++
++	set sidebar_width	 = 35
++	set sidebar_visible	 = yes
++	set sidebar_sort_method  = unsorted
++	set sidebar_divider_char = │
++
++	color sidebar_new yellow default
++	color progress default magenta
++
++	bind index <left> sidebar-prev
++	bind index <right> sidebar-next
++	bind index <space> sidebar-open
++	bind index <Esc>S sidebar-toggle-virtual
++
++	set index_format="%4C %Z %?GI?%GI& ? %[%d/%b]  %-16.15F %?M?(%3M)&     ? %s %> %?g?%g?"
++
++        # virtual folders
++	virtual-mailboxes \
++	   "INBOX"                "notmuch://?query=tag:inbox and NOT tag:archive" \
++	   "Util-linux"           "notmuch://?query=tag:ul and NOT tag:archive" \
++	   "Bugs"                 "notmuch://?query=tag:bug NOT tag:archive" \
++	   "RH"                   "notmuch://?query=tag:rh and NOT tag:archive" \
++	   "Fedora"               "notmuch://?query=tag:fed and NOT tag:archive" \
++	   "Linux"                "notmuch://?query=tag:lk and NOT tag:archive" \
++	   "NFS"                  "notmuch://?query=tag:nfs and NOT tag:archive" \
++	   "Filesystems"          "notmuch://?query=tag:fs and NOT tag:archive" \
++	   "Security"             "notmuch://?query=tag:sec" \
++	   "Partitioning"         "notmuch://?query=tag:part" \
++	   "GNU"                  "notmuch://?query=tag:gnu" \
++	   "udev"                 "notmuch://?query=tag:udev" \
++	   "initrd"               "notmuch://?query=tag:initrd" \
++	   "Linux CZ"             "notmuch://?query=tag:cz" \
++	   "Notmuch"              "notmuch://?query=tag:nm" \
++	   "Procps"               "notmuch://?query=tag:proc" \
++	\
++	   " Util-linux  [archive]" "notmuch://?query=tag:ul and tag:archive" \
++	   " Bugs        [archive]" "notmuch://?query=tag:bug and tag:archive" \
++	   " RH          [archive]" "notmuch://?query=tag:rh and tag:archive" \
++	   " Fedora      [archive]" "notmuch://?query=tag:fed and tag:archive" \
++	   " Linux       [archive]" "notmuch://?query=tag:lk and tag:archive" \
++	   " Filesystems [archive]" "notmuch://?query=tag:fs and tag:archive" \
++
++	# move message to archive
++	macro index A "<modify-labels-then-hide>+archive -inbox\n<sync-mailbox>"
++
++	# remove message from inbox
++	macro index I "<modify-labels-then-hide>-inbox\n<sync-mailbox>"
++
++	# mark emails for git-am
++	# (e.g. "git am -i -3 $(notmuch search --output=files tag:PATCH)"
++	#
++	macro index P "<modify-labels>PATCH\n"
++	macro index <Esc>P "<modify-labels>-PATCH\n"
++
++
++* .procmailrc example:
++
++	NOINBOX="-r inbox"
++
++	### Add 'kw' (keyword) tag to all interesting e-mails and make the emails
++	### visible in inbox.
++	:0
++	* ^Subject:.*(mount|umount|libmount|losetup|util-linux|blkid|hwclock|mkswap|fdisk|parted|partition|gpt|topology)
++	{
++		TAGS="-t kw"
++		NOINBOX=""
++	}
++
++	### Deliver emails to maildirs by notmuch-deliver
++	### from notmuch contrib/
++	###
++	###    notmuch-deliver -t <tags> [-t ...] <maildir>
++
++	:0:notmuch.lock
++	* ^List-Id:.*linux.linux.cz
++	| notmuch-deliver $NOINBOX -t cz $TAGS linux.cz
++
++	:0:notmuch.lock
++	* ^X-Mailing-List:.*util-linux at vger.kernel.org
++	| notmuch-deliver -t ul $TAGS util-linux
++
++	:0:notmuch.lock
++	* ^List-Id:.*parted-devel.lists.alioth.debian.org
++	| notmuch-deliver $NOINBOX -t part $TAGS parted
++
++	### [...cut to make the example short...] ###
++
++	### All unmatched mails
++	:0:notmuch.lock
++	* ^From
++	| notmuch-deliver $TAGS misc
++
++	### fallback if notmuch does not work
++	:0:
++	* ^From
++	Mail/Maildir/misc/
++
++
++* another example:
++
++  http://notmuchmail.org/mutttips/
+diff -urN mutt-1.6.1-sidebar-notmuch/send.c mutt-1.6.1-notmuch/send.c
+--- mutt-1.6.1-sidebar-notmuch/send.c	2016-05-02 03:02:12.733176731 +0100
++++ mutt-1.6.1-notmuch/send.c	2016-05-02 03:02:15.248216745 +0100
+@@ -48,6 +48,9 @@
+ #include "remailer.h"
+ #endif
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
+ 
+ static void append_signature (FILE *f)
+ {
+@@ -1164,6 +1167,7 @@
+   char *smime_default_key = NULL;
+   char *tag = NULL, *err = NULL;
+   char *ctype;
++  char *finalpath = NULL;
+ 
+   int rv = -1;
+   
+@@ -1646,7 +1650,9 @@
+       mutt_prepare_envelope (msg->env, 0);
+       mutt_env_to_intl (msg->env, NULL, NULL);	/* Handle bad IDNAs the next time. */
+ 
+-      if (!Postponed || mutt_write_fcc (NONULL (Postponed), msg, (cur && (flags & SENDREPLY)) ? cur->env->message_id : NULL, 1, fcc) < 0)
++      if (!Postponed || mutt_write_fcc (NONULL (Postponed), msg,
++	                    (cur && (flags & SENDREPLY)) ?
++			             cur->env->message_id : NULL, 1, fcc, NULL) < 0)
+       {
+ 	msg->content = mutt_remove_multipart (msg->content);
+ 	decode_descriptions (msg->content);
+@@ -1829,7 +1835,7 @@
+        * message was first postponed.
+        */
+       msg->received = time (NULL);
+-      if (mutt_write_fcc (fcc, msg, NULL, 0, NULL) == -1)
++      if (mutt_write_fcc (fcc, msg, NULL, 0, NULL, &finalpath) == -1)
+       {
+ 	/*
+ 	 * Error writing FCC, we should abort sending.
+@@ -1890,6 +1896,7 @@
+       msg->content = mutt_remove_multipart (msg->content);
+       decode_descriptions (msg->content);
+       mutt_unprepare_envelope (msg->env);
++      FREE(&finalpath);
+       goto main_loop;
+     }
+     else
+@@ -1898,8 +1905,13 @@
+       goto cleanup;
+     }
+   }
+-  else if (!option (OPTNOCURSES) && ! (flags & SENDMAILX))
++  else if (!option (OPTNOCURSES) && ! (flags & SENDMAILX)) {
+     mutt_message (i == 0 ? _("Mail sent.") : _("Sending in background."));
++#ifdef USE_NOTMUCH
++    if (option(OPTNOTMUCHRECORD))
++      nm_record_message(ctx, finalpath, cur);
++#endif
++  }
+ 
+   if (WithCrypto && (msg->security & ENCRYPT))
+     FREE (&pgpkeylist);
+@@ -1944,7 +1956,8 @@
+   safe_fclose (&tempfp);
+   if (! (flags & SENDNOFREEHEADER))
+     mutt_free_header (&msg);
+-  
++
++  FREE(&finalpath);
+   return rv;
+ }
+ 
+diff -urN mutt-1.6.1-sidebar-notmuch/sendlib.c mutt-1.6.1-notmuch/sendlib.c
+--- mutt-1.6.1-sidebar-notmuch/sendlib.c	2016-05-02 03:02:12.733176731 +0100
++++ mutt-1.6.1-notmuch/sendlib.c	2016-05-02 03:02:15.178215632 +0100
+@@ -2684,7 +2684,8 @@
+   }
+ }
+ 
+-int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, char *fcc)
++int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid,
++		    int post, char *fcc, char **finalpath)
+ {
+   CONTEXT f;
+   MESSAGE *msg;
+@@ -2873,6 +2874,8 @@
+ 
+   if (mx_commit_message (msg, &f) != 0)
+     r = -1;
++  else if (finalpath)
++    *finalpath = safe_strdup(msg->commited_path);
+   mx_close_message (&msg);
+   mx_close_mailbox (&f, NULL);
+ 
+diff -urN mutt-1.6.1-sidebar-notmuch/sidebar.c mutt-1.6.1-notmuch/sidebar.c
+--- mutt-1.6.1-sidebar-notmuch/sidebar.c	2016-05-02 03:02:12.733176731 +0100
++++ mutt-1.6.1-notmuch/sidebar.c	2016-05-02 03:02:15.248216745 +0100
+@@ -26,6 +26,7 @@
+ #include "keymap.h"
+ #include "mutt_curses.h"
+ #include "mutt_menu.h"
++#include "mx.h"
+ #include "sort.h"
+ 
+ /* Previous values for some sidebar config */
+@@ -51,6 +52,38 @@
+ 	BUFFY       *buffy;
+ };
+ 
++enum {
++	SB_SRC_NONE = 0,
++	SB_SRC_VIRT,
++	SB_SRC_INCOMING
++};
++static int sidebar_source = SB_SRC_NONE;
++
++static BUFFY *
++get_incoming (void)
++{
++	switch (sidebar_source) {
++	case SB_SRC_NONE:
++		sidebar_source = SB_SRC_INCOMING;
++
++#ifdef USE_NOTMUCH
++		if (option (OPTVIRTSPOOLFILE) && VirtIncoming) {
++			sidebar_source = SB_SRC_VIRT;
++			return VirtIncoming;
++		}
++		break;
++	case SB_SRC_VIRT:
++		if (VirtIncoming) {
++			return VirtIncoming;
++		}
++		break;
++#endif
++	case SB_SRC_INCOMING:
++		break;
++	}
++
++	return Incoming;	/* default */
++}
+ 
+ /**
+  * find_next_new - Find the next folder that contains new mail
+@@ -73,7 +106,7 @@
+ 	do {
+ 		b = b->next;
+ 		if (!b && wrap) {
+-			b = Incoming;
++			b = get_incoming();
+ 		}
+ 		if (!b || (b == HilBuffy)) {
+ 			break;
+@@ -330,6 +363,9 @@
+ 		case SORT_COUNT_NEW:
+ 			result = (b2->msg_unread - b1->msg_unread);
+ 			break;
++		case SORT_DESC:
++			result = mutt_strcmp (b1->desc, b2->desc);
++			break;
+ 		case SORT_FLAGGED:
+ 			result = (b2->msg_flagged - b1->msg_flagged);
+ 			break;
+@@ -472,7 +508,7 @@
+ static int
+ prepare_sidebar (int page_size)
+ {
+-	BUFFY *b = Incoming;
++	BUFFY *b = get_incoming();
+ 	if (!b)
+ 		return 0;
+ 
+@@ -488,14 +524,15 @@
+ 		return 0;
+ 
+ 	int i = 0;
+-	for (b = Incoming; b; b = b->next, i++) {
++	for (b = get_incoming(); b; b = b->next, i++) {
+ 		arr[i] = b;
+ 	}
+ 
+ 	update_buffy_visibility (arr, count);
+ 	sort_buffy_array        (arr, count);
+ 
+-	Incoming = arr[0];
++	if (sidebar_source == SB_SRC_INCOMING)
++		Incoming = arr[0];
+ 
+ 	int top_index =  0;
+ 	int opn_index = -1;
+@@ -778,6 +815,11 @@
+ 				strncat (sidebar_folder_name, tmp_folder_name, strlen (tmp_folder_name));
+ 			}
+ 		}
++#ifdef USE_NOTMUCH
++		else if (b->magic == M_NOTMUCH) {
++			sidebar_folder_name = b->desc;
++		}
++#endif
+ 		char str[SHORT_STRING];
+ 		make_sidebar_entry (str, sizeof (str), w, sidebar_folder_name, b);
+ 		printw ("%s", str);
+@@ -836,7 +878,7 @@
+ 	if (div_width < 0)
+ 		return;
+ 
+-	if (!Incoming) {
++	if (!get_incoming()) {
+ 		int w = MIN(COLS, (SidebarWidth - div_width));
+ 		fill_empty_space (first_row, num_rows, w);
+ 		return;
+@@ -921,7 +963,7 @@
+ 			break;
+ 		case OP_SIDEBAR_PAGE_UP:
+ 			HilBuffy = TopBuffy;
+-			if (HilBuffy != Incoming) {
++			if (HilBuffy != get_incoming()) {
+ 				HilBuffy = HilBuffy->prev;
+ 			}
+ 			break;
+@@ -958,7 +1000,7 @@
+ {
+ 	/* Even if the sidebar's hidden,
+ 	 * we should take note of the new data. */
+-	BUFFY *b = Incoming;
++	BUFFY *b = get_incoming();
+ 	if (!ctx || !b)
+ 		return;
+ 
+@@ -1005,7 +1047,7 @@
+ {
+ 	/* Even if the sidebar is hidden */
+ 
+-	BUFFY *b = Incoming;
++	BUFFY *b = get_incoming();
+ 
+ 	if (!path || !b)
+ 		return NULL;
+@@ -1078,3 +1120,29 @@
+ 			Outgoing = buffy_going (Outgoing);
+ 	}
+ }
++
++/**
++ * sb_toggle_virtual - Switch between regular and virtual folders
++ */
++void
++sb_toggle_virtual (void)
++{
++	if (sidebar_source == -1)
++		get_incoming();
++
++#ifdef USE_NOTMUCH
++	if ((sidebar_source == SB_SRC_INCOMING) && VirtIncoming)
++		sidebar_source = SB_SRC_VIRT;
++	else
++#endif
++		sidebar_source = SB_SRC_INCOMING;
++
++	TopBuffy = NULL;
++	OpnBuffy = NULL;
++	HilBuffy = NULL;
++	BotBuffy = NULL;
++	Outgoing = NULL;
++
++	sb_draw();
++}
++
+diff -urN mutt-1.6.1-sidebar-notmuch/sidebar.h mutt-1.6.1-notmuch/sidebar.h
+--- mutt-1.6.1-sidebar-notmuch/sidebar.h	2016-05-02 03:02:12.733176731 +0100
++++ mutt-1.6.1-notmuch/sidebar.h	2016-05-02 03:02:15.248216745 +0100
+@@ -32,5 +32,6 @@
+ BUFFY *      sb_set_open_buffy (const char *path);
+ void         sb_set_update_time (void);
+ int          sb_should_refresh (void);
++void         sb_toggle_virtual (void);
+ 
+ #endif /* SIDEBAR_H */
+diff -urN mutt-1.6.1-sidebar-notmuch/status.c mutt-1.6.1-notmuch/status.c
+--- mutt-1.6.1-sidebar-notmuch/status.c	2016-05-02 03:02:12.733176731 +0100
++++ mutt-1.6.1-notmuch/status.c	2016-05-02 03:02:15.179215647 +0100
+@@ -27,6 +27,10 @@
+ #include "mapping.h"
+ #include "mx.h"
+ 
++#ifdef USE_NOTMUCH
++#include "mutt_notmuch.h"
++#endif
++
+ #include <string.h>
+ #include <ctype.h>
+ #include <unistd.h>
+@@ -95,7 +99,14 @@
+       break;
+ 
+     case 'f':
+-      snprintf (fmt, sizeof(fmt), "%%%ss", prefix);
++    {
++#ifdef USE_NOTMUCH
++      char *p;
++      if (Context && Context->magic == M_NOTMUCH &&
++                   (p = nm_get_description(Context)))
++	  strfcpy(tmp, p, sizeof (tmp));
++      else
++#endif
+       if (Context && Context->path)
+       {
+ 	strfcpy (tmp, Context->path, sizeof (tmp));
+@@ -103,9 +114,11 @@
+       }
+       else
+ 	strfcpy (tmp, _("(no mailbox)"), sizeof (tmp));
++
++      snprintf (fmt, sizeof(fmt), "%%%ss", prefix);
+       snprintf (buf, buflen, fmt, tmp);
+       break;
+-
++    }
+     case 'F':
+       if (!optional)
+       {
+diff -urN mutt-1.6.1-sidebar-notmuch/UPDATING.kz mutt-1.6.1-notmuch/UPDATING.kz
+--- mutt-1.6.1-sidebar-notmuch/UPDATING.kz	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-notmuch/UPDATING.kz	2016-05-02 03:02:15.118214677 +0100
+@@ -0,0 +1,68 @@
++1.6.0.1:
++
+++ rebase to mutt upstream 1.6.0
+++ update to the new sidebar implementation. Note that all .muttrc options 
++  are prefixed by "sidebar_" now.
++
+++ rebase is based on neomutt project (see https://github.com/neomutt) where are
++  maintained all non-upstream mutt changes, so it's easy to merge another
++  features like "trash", "ifdef", ... to mutt-kz.
++
+++ the stable mutt-kz releases and tags are maintained in stable/v<version> branches, 
++  the master branch is going to be *rebased*. This development model help us to be 
++  up to date with mutt upstream.
++
++
++1.5.23.1:
++
+++ integrated color status patch (original from Thomas Glanzmann)
++  https://thomas.glanzmann.de//mutt/#cstatus
+++ integrated TLS Server Name Indication support patch (original from Phil Pennock)
+++ improved sidebar functionality to optinaly show only folders with new emails
++  (sidebar-new, sitebar-next, ...)
++
+++ fix notmuch DB usage
+++ use unlocked libc IO in improve performance
+++ security bug fix from original mutt
++
+++ sync with the original mutt upstream
+++ add sidebar_whitelist option
+++ oppenc & pgp upstream sync and improvements
++
++
++1.5.22.1:
++
+++ use git and github rather than hg to maintain source code
++
+++ virtual folders based on notmuch queries
+++ merge sidebar patch
+++ merge index-color patch
++
+++ <change-vfolder> command
+++ <vfolder-from-query> command
+++ <modify-labels> command to set/unset notmuch tags
+++ <modify-labels-then-hide> command to set/unset notmuch tags and hide email
++  from the current view
+++ <quasi-delete> command to delete message from mutt, but don't touch message
++  on the disk
+++ <entire-thread> command to add to the current list of the messages all
++  messages that belongs to the same thread as the current message
+++ ~Y EXPR  pattern modifier for notmuch labels for limit, tag-pattern,
++  delete-pattern, color etc.
+++ virtual-mailboxes <desc> <uri> [...]  to specify list of the virtual mailboxes
+++ virtual_spoolfile = <boolean> to use the first virtual mailbox as a spoolfile
+++ tag-transforms <tag> <transform> to transform tag name to another name
+++ tag-formats <tag> <format sequence> [ ...] to define tag specific formatting
++  sequence for $index_format
+++ nm_record = <boolean> to add sent emails (mutt record) to notmuch DB
+++ nm_record_tags = <comma delimited list> to specify tags for nm_record
+++ nm_open_timeout = <seconds> to specify timeout for notmuch database
+++ nm_default_uri = <uri>  the default URI to connect notmuch
+++ nm_hidden_tags = <comma delimited list> to make some tags invisible for mutt user
+++ nm_exclude_tags = <comma delimited list> - messages tagged with these tags
++  are excluded and not loaded from notmuch DB to mutt unless specified explicitly
+++ nm_unread_tag = <name> to specify unread messages
+++ nm_db_limit = <num> to specify notmuch query limit
+++ nm_query_type = <threads|messages> to specify what to load from DB
+++ vfolder_format = <string> to specify vfolders brower entry format
+++ %g and %Gx index_format and pager_format formatting sequences
+diff -urN mutt-1.6.1-sidebar-notmuch/url.c mutt-1.6.1-notmuch/url.c
+--- mutt-1.6.1-sidebar-notmuch/url.c	2016-05-02 03:02:12.733176731 +0100
++++ mutt-1.6.1-notmuch/url.c	2016-05-02 03:02:15.180215663 +0100
+@@ -40,12 +40,15 @@
+   { "pop",  	U_POP },
+   { "pops", 	U_POPS },
+   { "mailto",	U_MAILTO },
++#ifdef USE_NOTMUCH
++  { "notmuch",  U_NOTMUCH },
++#endif
+   { "smtp",     U_SMTP },
+   { "smtps",    U_SMTPS },
+   { NULL,	U_UNKNOWN }
+ };
+ 
+-static int url_pct_decode (char *s)
++int url_pct_decode (char *s)
+ {
+   char *d;
+ 
+diff -urN mutt-1.6.1-sidebar-notmuch/url.h mutt-1.6.1-notmuch/url.h
+--- mutt-1.6.1-sidebar-notmuch/url.h	2016-05-02 03:02:12.733176731 +0100
++++ mutt-1.6.1-notmuch/url.h	2016-05-02 03:02:15.180215663 +0100
+@@ -11,6 +11,9 @@
+   U_SMTP,
+   U_SMTPS,
+   U_MAILTO,
++#ifdef USE_NOTMUCH
++  U_NOTMUCH,
++#endif
+   U_UNKNOWN
+ }
+ url_scheme_t;
+@@ -34,5 +37,6 @@
+ int url_parse_ciss (ciss_url_t *ciss, char *src);
+ int url_ciss_tostring (ciss_url_t* ciss, char* dest, size_t len, int flags);
+ int url_parse_mailto (ENVELOPE *e, char **body, const char *src);
++int url_pct_decode (char *s);
+ 
+ #endif
diff --git a/debian/patches/neomutt/11-ifdef.patch b/debian/patches/neomutt/11-ifdef.patch
new file mode 100644
index 0000000..8f9bcfb
--- /dev/null
+++ b/debian/patches/neomutt/11-ifdef.patch
@@ -0,0 +1,1526 @@
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-ifdef/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-ifdef/doc/manual.xml.head	2016-05-02 03:02:15.448219927 +0100
+@@ -8081,6 +8081,167 @@
+ 
+ </sect1>
+ 
++<sect1 id="ifdef">
++	<title>Ifdef Patch</title>
++	<subtitle>Conditional config options</subtitle>
++
++	<sect2 id="ifdef-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>ifdef</quote>, look for
++			<quote>patch-ifdef</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="ifdef-intro">
++		<title>Introduction</title>
++
++		<para>
++			The <quote>ifdef</quote> patch introduces three new commands to
++			Mutt and allow you to share one config file between versions of Mutt
++			that may have different features compiled in.
++		</para>
++
++<screen>
++ifdef  symbol config-command [args...]  <emphasis role="comment"># If a symbol is defined</emphasis>
++ifndef symbol config-command [args...]  <emphasis role="comment"># If a symbol is not defined</emphasis>
++finish                                  <emphasis role="comment"># Finish reading the current file</emphasis>
++</screen>
++
++		<para>
++			Here a symbol can be a <link linkend="variables">$variable</link>,
++			<link linkend="functions"><function></link>,
++			<link linkend="commands">command</link> or compile-time symbol, such
++			as <quote>USE_IMAP</quote>.
++		</para>
++
++        <para>
++            <literal>finish</literal> is particularly useful when combined with
++            <literal>ifndef</literal>. e.g.
++        </para>
++
++<screen>
++<emphasis role="comment"># Sidebar config file</emphasis>
++ifndef USE_SIDEBAR finish
++</screen>
++
++	</sect2>
++
++<!--
++	<sect2 id="ifdef-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="ifdef-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="ifdef-commands">
++		<title>Commands</title>
++		<cmdsynopsis>
++			<command>ifdef</command>
++			<arg choice="plain">
++				<replaceable class="parameter">symbol</replaceable>
++			</arg>
++			<arg choice="plain">
++				<replaceable class="parameter">"config-command [args]"</replaceable>
++			</arg>
++			<command>ifndef</command>
++			<arg choice="plain">
++				<replaceable class="parameter">symbol</replaceable>
++			</arg>
++			<arg choice="plain">
++				<replaceable class="parameter">"config-command [args]"</replaceable>
++			</arg>
++			<command>finish</command>
++		</cmdsynopsis>
++	</sect2>
++
++<!--
++	<sect2 id="ifdef-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="ifdef-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="ifdef-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'ifdef' feature.
++ 
++# This feature introduces three useful commands which allow you to share
++# one config file between versions of Mutt that may have different
++# features compiled in.
++ 
++#	ifdef  symbol config-command [args...]
++#	ifndef symbol config-command [args...]
++#	finish                                
++ 
++# The 'ifdef' command tests whether Mutt understands the name of
++# a variable, function, command or compile-time symbol.
++# If it does, then it executes a config command.
++ 
++# The 'ifndef' command tests whether a symbol does NOT exist.
++ 
++# The 'finish' command tells Mutt to stop reading current config file.
++ 
++# If the 'trash' variable exists, set it.</emphasis>
++ifdef trash 'set trash=~/Mail/trash'
++ 
++<emphasis role="comment"># If the 'tag-pattern' function exists, bind a key to it.</emphasis>
++ifdef tag-pattern 'bind index <F6> tag-pattern'
++ 
++<emphasis role="comment"># If the 'imap-fetch-mail' command exists, read my IMAP config.</emphasis>
++ifdef imap-fetch-mail 'source ~/.mutt/imap.rc'
++ 
++<emphasis role="comment"># If the compile-time symbol 'USE_SIDEBAR' does not exist, then
++# stop reading the current config file.</emphasis>
++ifndef USE_SIDEBAR finish
++ 
++<emphasis role="comment"># vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="ifdef-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="ifdef-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="ifdef-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Cedric Duval <email>cedricduval at free.fr</email></para></listitem>
++		<listitem><para>Matteo F. Vescovi <email>mfvescovi at gmail.com</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+@@ -8872,6 +9033,18 @@
+ </cmdsynopsis>
+ </listitem>
+ 
++<listitem>
++<cmdsynopsis>
++<command>ifdef</command>
++<arg choice="plain">
++<replaceable class="parameter">item</replaceable>
++</arg>
++<arg choice="plain">
++<replaceable class="parameter">"config-command [args]"</replaceable>
++</arg>
++</cmdsynopsis>
++</listitem>
++
+ <listitem>
+ <cmdsynopsis>
+ <command><link linkend="ignore">ignore</link></command>
+diff -urN mutt-1.6.1/doc/muttrc.ifdef mutt-1.6.1-ifdef/doc/muttrc.ifdef
+--- mutt-1.6.1/doc/muttrc.ifdef	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-ifdef/doc/muttrc.ifdef	2016-05-02 03:02:15.358218495 +0100
+@@ -0,0 +1,32 @@
++# Example Mutt config file for the 'ifdef' feature.
++
++# This feature introduces three useful commands which allow you to share
++# one config file between versions of Mutt that may have different
++# features compiled in.
++
++#	ifdef  symbol config-command [args...]
++#	ifndef symbol config-command [args...]
++#	finish                                
++
++# The 'ifdef' command tests whether Mutt understands the name of
++# a variable, function, command or compile-time symbol.
++# If it does, then it executes a config command.
++
++# The 'ifndef' command tests whether a symbol does NOT exist.
++
++# The 'finish' command tells Mutt to stop reading current config file.
++
++# If the 'trash' variable exists, set it.
++ifdef trash 'set trash=~/Mail/trash'
++
++# If the 'tag-pattern' function exists, bind a key to it.
++ifdef tag-pattern 'bind index <F6> tag-pattern'
++
++# If the 'imap-fetch-mail' command exists, read my IMAP config.
++ifdef imap-fetch-mail 'source ~/.mutt/imap.rc'
++
++# If the compile-time symbol 'USE_SIDEBAR' does not exist, then
++# stop reading the current config file.
++ifndef USE_SIDEBAR finish
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/doc/vimrc.ifdef mutt-1.6.1-ifdef/doc/vimrc.ifdef
+--- mutt-1.6.1/doc/vimrc.ifdef	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-ifdef/doc/vimrc.ifdef	2016-05-02 03:02:15.359218511 +0100
+@@ -0,0 +1,7 @@
++" Vim syntax file for the mutt ifdef patch
++
++syntax keyword muttrcCommand    ifdef
++syntax keyword muttrcCommand    ifndef
++syntax keyword muttrcCommand    finish
++
++" vim: syntax=vim
+diff -urN mutt-1.6.1/hook.c mutt-1.6.1-ifdef/hook.c
+--- mutt-1.6.1/hook.c	2016-05-02 03:02:12.404171496 +0100
++++ mutt-1.6.1-ifdef/hook.c	2016-05-02 03:02:15.362218559 +0100
+@@ -362,7 +362,7 @@
+ 
+     if (hook->type & type)
+       if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not)
+-	if (mutt_parse_rc_line (hook->command, &token, &err) != 0)
++	if (mutt_parse_rc_line (hook->command, &token, &err) == -1)
+ 	{
+ 	  FREE (&token.data);
+ 	  mutt_error ("%s", err.data);
+diff -urN mutt-1.6.1/init.c mutt-1.6.1-ifdef/init.c
+--- mutt-1.6.1/init.c	2016-05-02 03:02:12.405171512 +0100
++++ mutt-1.6.1-ifdef/init.c	2016-05-02 03:02:15.451219975 +0100
+@@ -32,6 +32,7 @@
+ #include "mutt_crypt.h"
+ #include "mutt_idna.h"
+ #include "group.h"
++#include "version.h"
+ 
+ #if defined(USE_SSL)
+ #include "mutt_ssl.h"
+@@ -601,6 +602,113 @@
+   }
+ }
+ 
++/**
++ * finish_source - 'finish' command: stop processing current config file
++ * @tmp:  Temporary space shared by all command handlers
++ * @s:    Current line of the config file
++ * @data: data field from init.h:struct command_t
++ * @err:  Buffer for any error message
++ *
++ * If the 'finish' command is found, we should stop reading the current file.
++ *
++ * Returns:
++ *	 1 Stop processing the current file
++ *	-1 Failed
++ */
++static int finish_source (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
++{
++	if (MoreArgs (s)) {
++		snprintf (err->data, err->dsize, _("finish: too many arguments"));
++		return -1;
++	}
++
++	return 1;
++}
++
++/**
++ * parse_ifdef - 'ifdef' command: conditional config
++ * @tmp:  Temporary space shared by all command handlers
++ * @s:    Current line of the config file
++ * @data: data field from init.h:struct command_t
++ * @err:  Buffer for any error message
++ *
++ * The 'ifdef' command allows conditional elements in the config file.
++ * If a given variable, function, command or compile-time symbol exists, then
++ * read the rest of the line of config commands.
++ * e.g.
++ *	ifdef USE_SIDEBAR source ~/.mutt/sidebar.rc
++ *
++ * If (data == 1) then it means use the 'ifndef' (if-not-defined) command.
++ * e.g.
++ *	ifndef USE_IMAP finish
++ *
++ * Returns:
++ *	 0 Success
++ *	-1 Failed
++ */
++static int parse_ifdef (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
++{
++	int i, j, res = 0;
++	BUFFER token;
++
++	memset (&token, 0, sizeof (token));
++	mutt_extract_token (tmp, s, 0);
++
++	/* is the item defined as a variable? */
++	res = (mutt_option_index (tmp->data) != -1);
++
++	/* is the item a compiled-in feature? */
++	if (!res) {
++		res = feature_enabled (tmp->data);
++	}
++
++	/* or a function? */
++	if (!res) {
++		for (i = 0; !res && (i < MENU_MAX); i++) {
++			const struct binding_t *b = km_get_table (Menus[i].value);
++			if (!b)
++				continue;
++
++			for (j = 0; b[j].name; j++) {
++				if (mutt_strcmp (tmp->data, b[j].name) == 0) {
++					res = 1;
++					break;
++				}
++			}
++		}
++	}
++
++	/* or a command? */
++	if (!res) {
++		for (i = 0; Commands[i].name; i++) {
++			if (mutt_strcmp (tmp->data, Commands[i].name) == 0) {
++				res = 1;
++				break;
++			}
++		}
++	}
++
++	if (!MoreArgs (s)) {
++		snprintf (err->data, err->dsize, _("%s: too few arguments"),
++			(data ? "ifndef" : "ifdef"));
++		return -1;
++	}
++	mutt_extract_token (tmp, s, M_TOKEN_SPACE);
++
++        /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
++	if ((res && (data == 0)) || (!res && (data == 1))) {
++                int rc = mutt_parse_rc_line (tmp->data, &token, err);
++		if (rc == -1) {
++			mutt_error ("Error: %s", err->data);
++			FREE(&token.data);
++			return -1;
++		}
++		FREE(&token.data);
++                return rc;
++	}
++	return 0;
++}
++
+ static int parse_unignore (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
+ {
+   do
+@@ -2238,7 +2346,7 @@
+ static int source_rc (const char *rcfile, BUFFER *err)
+ {
+   FILE *f;
+-  int line = 0, rc = 0, conv = 0;
++  int line = 0, rc = 0, conv = 0, line_rc;
+   BUFFER token;
+   char *linebuf = NULL;
+   char *currentline = NULL;
+@@ -2267,17 +2375,17 @@
+     else 
+       currentline=linebuf;
+ 
+-    if (mutt_parse_rc_line (currentline, &token, err) == -1)
+-    {
++    line_rc = mutt_parse_rc_line (currentline, &token, err);
++    if (line_rc == -1) {
+       mutt_error (_("Error in %s, line %d: %s"), rcfile, line, err->data);
+       if (--rc < -MAXERRS) 
+       {
+         if (conv) FREE(&currentline);
+         break;
+       }
+-    }
+-    else
+-    {
++    } else if (line_rc == 1) {
++      break;	/* Found "finish" command */
++    } else {
+       if (rc < 0)
+         rc = -1;
+     }
+@@ -2332,7 +2440,7 @@
+    err		where to write error messages */
+ int mutt_parse_rc_line (/* const */ char *line, BUFFER *token, BUFFER *err)
+ {
+-  int i, r = -1;
++  int i, r = 0;
+   BUFFER expn;
+ 
+   if (!line || !*line)
+@@ -2359,22 +2467,24 @@
+     {
+       if (!mutt_strcmp (token->data, Commands[i].name))
+       {
+-	if (Commands[i].func (token, &expn, Commands[i].data, err) != 0)
+-	  goto finish;
+-        break;
++        r = Commands[i].func (token, &expn, Commands[i].data, err);
++        if (r != 0) {   /* -1 Error, +1 Finish */
++          goto finish;  /* Propagate return code */
++        }
++        break;          /* Continue with next command */
+       }
+     }
+     if (!Commands[i].name)
+     {
+       snprintf (err->data, err->dsize, _("%s: unknown command"), NONULL (token->data));
+-      goto finish;
++      r = -1;
++      break;            /* Ignore the rest of the line */
+     }
+   }
+-  r = 0;
+ finish:
+   if (expn.destroy)
+     FREE (&expn.data);
+-  return (r);
++  return r;
+ }
+ 
+ 
+@@ -2852,7 +2962,7 @@
+   mutt_buffer_init (&token);
+   for (; p; p = p->next)
+   {
+-    if (mutt_parse_rc_line (p->data, &token, &err) != 0)
++    if (mutt_parse_rc_line (p->data, &token, &err) == -1)
+     {
+       fprintf (stderr, _("Error in command line: %s\n"), err.data);
+       FREE (&token.data);
+diff -urN mutt-1.6.1/init.h mutt-1.6.1-ifdef/init.h
+--- mutt-1.6.1/init.h	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-ifdef/init.h	2016-05-02 03:02:15.453220007 +0100
+@@ -3665,6 +3665,8 @@
+ static int parse_unlists (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ static int parse_alias (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ static int parse_unalias (BUFFER *, BUFFER *, unsigned long, BUFFER *);
++static int finish_source (BUFFER *, BUFFER *, unsigned long, BUFFER *);
++static int parse_ifdef (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ static int parse_ignore (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ static int parse_unignore (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+ static int parse_source (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+@@ -3715,6 +3717,9 @@
+   { "group",		parse_group,		M_GROUP },
+   { "ungroup",		parse_group,		M_UNGROUP },
+   { "hdr_order",	parse_list,		UL &HeaderOrderList },
++  { "ifdef",		parse_ifdef,		0 },
++  { "ifndef",		parse_ifdef,		1 },
++  { "finish",		finish_source,		0 },
+ #ifdef HAVE_ICONV
+   { "iconv-hook",	mutt_parse_hook,	M_ICONVHOOK },
+ #endif
+diff -urN mutt-1.6.1/main.c mutt-1.6.1-ifdef/main.c
+--- mutt-1.6.1/main.c	2016-05-02 03:02:12.408171560 +0100
++++ mutt-1.6.1-ifdef/main.c	2016-05-02 03:02:15.454220023 +0100
+@@ -31,6 +31,7 @@
+ #include "url.h"
+ #include "mutt_crypt.h"
+ #include "mutt_idna.h"
++#include "version.h"
+ 
+ #ifdef USE_SASL
+ #include "mutt_sasl.h"
+@@ -62,46 +63,6 @@
+ #include <idn/stringprep.h>
+ #endif
+ 
+-static const char *ReachingUs = N_("\
+-To contact the developers, please mail to <mutt-dev at mutt.org>.\n\
+-To report a bug, please visit http://bugs.mutt.org/.\n");
+-
+-static const char *Notice = N_("\
+-Copyright (C) 1996-2016 Michael R. Elkins and others.\n\
+-Mutt comes with ABSOLUTELY NO WARRANTY; for details type `mutt -vv'.\n\
+-Mutt is free software, and you are welcome to redistribute it\n\
+-under certain conditions; type `mutt -vv' for details.\n");
+-
+-static const char *Copyright = N_("\
+-Copyright (C) 1996-2014 Michael R. Elkins <me at mutt.org>\n\
+-Copyright (C) 1996-2002 Brandon Long <blong at fiction.net>\n\
+-Copyright (C) 1997-2009 Thomas Roessler <roessler at does-not-exist.org>\n\
+-Copyright (C) 1998-2005 Werner Koch <wk at isil.d.shuttle.de>\n\
+-Copyright (C) 1999-2014 Brendan Cully <brendan at kublai.com>\n\
+-Copyright (C) 1999-2002 Tommi Komulainen <Tommi.Komulainen at iki.fi>\n\
+-Copyright (C) 2000-2004 Edmund Grimley Evans <edmundo at rano.org>\n\
+-Copyright (C) 2006-2009 Rocco Rutte <pdmef at gmx.net>\n\
+-Copyright (C) 2014-2015 Kevin J. McCarthy <kevin at 8t8.us>\n\
+-\n\
+-Many others not mentioned here contributed code, fixes,\n\
+-and suggestions.\n");
+-
+-static const char *Licence = N_("\
+-    This program is free software; you can redistribute it and/or modify\n\
+-    it under the terms of the GNU General Public License as published by\n\
+-    the Free Software Foundation; either version 2 of the License, or\n\
+-    (at your option) any later version.\n\
+-\n\
+-    This program is distributed in the hope that it will be useful,\n\
+-    but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
+-    GNU General Public License for more details.\n");
+-static const char *Obtaining = N_("\
+-    You should have received a copy of the GNU General Public License\n\
+-    along with this program; if not, write to the Free Software\n\
+-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n\
+-");
+-
+ void mutt_exit (int code)
+ {
+   mutt_endwin (NULL);
+@@ -158,359 +119,6 @@
+   exit (0);
+ }
+ 
+-extern const char cc_version[];
+-extern const char cc_cflags[];
+-extern const char configure_options[];
+-
+-static char *
+-rstrip_in_place(char *s)
+-{
+-  char *p;
+-
+-  p = &s[strlen(s)];
+-  if (p == s)
+-    return s;
+-  p--;
+-  while (p >= s && (*p == '\n' || *p == '\r'))
+-    *p-- = '\0';
+-  return s;
+-}
+-
+-static void show_version (void)
+-{
+-  struct utsname uts;
+-
+-  puts (mutt_make_version());
+-  puts (_(Notice));
+-
+-  uname (&uts);
+-
+-#ifdef _AIX
+-  printf ("System: %s %s.%s", uts.sysname, uts.version, uts.release);
+-#elif defined (SCO)
+-  printf ("System: SCO %s", uts.release);
+-#else
+-  printf ("System: %s %s", uts.sysname, uts.release);
+-#endif
+-
+-  printf (" (%s)", uts.machine);
+-
+-#ifdef NCURSES_VERSION
+-  printf ("\nncurses: %s (compiled with %s)", curses_version(), NCURSES_VERSION);
+-#elif defined(USE_SLANG_CURSES)
+-  printf ("\nslang: %d", SLANG_VERSION);
+-#endif
+-
+-#ifdef _LIBICONV_VERSION
+-  printf ("\nlibiconv: %d.%d", _LIBICONV_VERSION >> 8,
+-	  _LIBICONV_VERSION & 0xff);
+-#endif
+-
+-#ifdef HAVE_LIBIDN
+-  printf ("\nlibidn: %s (compiled with %s)", stringprep_check_version (NULL), 
+-	  STRINGPREP_VERSION);
+-#endif
+-
+-#ifdef USE_HCACHE
+-  printf ("\nhcache backend: %s", mutt_hcache_backend ());
+-#endif
+-
+-  puts ("\n\nCompiler:");
+-  rstrip_in_place((char *)cc_version);
+-  puts (cc_version);
+-
+-  rstrip_in_place((char *)configure_options);
+-  printf ("\nConfigure options: %s\n", configure_options);
+-
+-  rstrip_in_place((char *)cc_cflags);
+-  printf ("\nCompilation CFLAGS: %s\n", cc_cflags);
+-
+-  puts (_("\nCompile options:"));
+-
+-#ifdef DOMAIN
+-  printf ("DOMAIN=\"%s\"\n", DOMAIN);
+-#else
+-  puts ("-DOMAIN");
+-#endif
+-
+-#ifdef DEBUG
+-  puts ("+DEBUG");
+-#else
+-  puts ("-DEBUG");
+-#endif
+-  
+-
+-  
+-  puts (
+-
+-#ifdef HOMESPOOL
+-	"+HOMESPOOL  "
+-#else
+-	"-HOMESPOOL  "
+-#endif
+-
+-#ifdef USE_SETGID
+-	"+USE_SETGID  "
+-#else
+-	"-USE_SETGID  "
+-#endif
+-
+-#ifdef USE_DOTLOCK
+-	"+USE_DOTLOCK  "
+-#else
+-	"-USE_DOTLOCK  "
+-#endif
+-
+-#ifdef DL_STANDALONE
+-	"+DL_STANDALONE  "
+-#else
+-	"-DL_STANDALONE  "
+-#endif
+-
+-#ifdef USE_FCNTL
+-	"+USE_FCNTL  "
+-#else
+-	"-USE_FCNTL  "
+-#endif
+-
+-#ifdef USE_FLOCK
+-	"+USE_FLOCK   "
+-#else
+-	"-USE_FLOCK   "
+-#endif
+-    );
+-  puts (
+-#ifdef USE_POP
+-	"+USE_POP  "
+-#else
+-	"-USE_POP  "
+-#endif
+-
+-#ifdef USE_IMAP
+-        "+USE_IMAP  "
+-#else
+-        "-USE_IMAP  "
+-#endif
+-
+-#ifdef USE_SMTP
+-	"+USE_SMTP  "
+-#else
+-	"-USE_SMTP  "
+-#endif
+-	"\n"
+-	
+-#ifdef USE_SSL_OPENSSL
+-	"+USE_SSL_OPENSSL  "
+-#else
+-	"-USE_SSL_OPENSSL  "
+-#endif
+-
+-#ifdef USE_SSL_GNUTLS
+-	"+USE_SSL_GNUTLS  "
+-#else
+-	"-USE_SSL_GNUTLS  "
+-#endif
+-
+-#ifdef USE_SASL
+-	"+USE_SASL  "
+-#else
+-	"-USE_SASL  "
+-#endif
+-#ifdef USE_GSS
+-	"+USE_GSS  "
+-#else
+-	"-USE_GSS  "
+-#endif
+-
+-#if HAVE_GETADDRINFO
+-	"+HAVE_GETADDRINFO  "
+-#else
+-	"-HAVE_GETADDRINFO  "
+-#endif
+-        );
+-  	
+-  puts (
+-#ifdef HAVE_REGCOMP
+-	"+HAVE_REGCOMP  "
+-#else
+-	"-HAVE_REGCOMP  "
+-#endif
+-
+-#ifdef USE_GNU_REGEX
+-	"+USE_GNU_REGEX  "
+-#else
+-	"-USE_GNU_REGEX  "
+-#endif
+-
+-	"\n"
+-	
+-#ifdef HAVE_COLOR
+-	"+HAVE_COLOR  "
+-#else
+-	"-HAVE_COLOR  "
+-#endif
+-	
+-#ifdef HAVE_START_COLOR
+-	"+HAVE_START_COLOR  "
+-#else
+-	"-HAVE_START_COLOR  "
+-#endif
+-	
+-#ifdef HAVE_TYPEAHEAD
+-	"+HAVE_TYPEAHEAD  "
+-#else
+-	"-HAVE_TYPEAHEAD  "
+-#endif
+-	
+-#ifdef HAVE_BKGDSET
+-	"+HAVE_BKGDSET  "
+-#else
+-	"-HAVE_BKGDSET  "
+-#endif
+-
+-	"\n"
+-	
+-#ifdef HAVE_CURS_SET
+-	"+HAVE_CURS_SET  "
+-#else
+-	"-HAVE_CURS_SET  "
+-#endif
+-	
+-#ifdef HAVE_META
+-	"+HAVE_META  "
+-#else
+-	"-HAVE_META  "
+-#endif
+-	
+-#ifdef HAVE_RESIZETERM
+-	"+HAVE_RESIZETERM  "
+-#else
+-	"-HAVE_RESIZETERM  "
+-#endif
+-        );	
+-  
+-  puts (
+-#ifdef CRYPT_BACKEND_CLASSIC_PGP
+-        "+CRYPT_BACKEND_CLASSIC_PGP  "
+-#else
+-        "-CRYPT_BACKEND_CLASSIC_PGP  "
+-#endif
+-#ifdef CRYPT_BACKEND_CLASSIC_SMIME
+-        "+CRYPT_BACKEND_CLASSIC_SMIME  "
+-#else
+-        "-CRYPT_BACKEND_CLASSIC_SMIME  "
+-#endif
+-#ifdef CRYPT_BACKEND_GPGME
+-        "+CRYPT_BACKEND_GPGME  "
+-#else
+-        "-CRYPT_BACKEND_GPGME  "
+-#endif
+-        );
+-  
+-  puts (
+-#ifdef EXACT_ADDRESS
+-	"+EXACT_ADDRESS  "
+-#else
+-	"-EXACT_ADDRESS  "
+-#endif
+-
+-#ifdef SUN_ATTACHMENT
+-	"+SUN_ATTACHMENT  "
+-#else
+-	"-SUN_ATTACHMENT  "
+-#endif
+-
+-	"\n"
+-	
+-#ifdef ENABLE_NLS
+-	"+ENABLE_NLS  "
+-#else
+-	"-ENABLE_NLS  "
+-#endif
+-
+-#ifdef LOCALES_HACK
+-	"+LOCALES_HACK  "
+-#else
+-	"-LOCALES_HACK  "
+-#endif
+-	      
+-#ifdef HAVE_WC_FUNCS
+-	"+HAVE_WC_FUNCS  "
+-#else
+-	"-HAVE_WC_FUNCS  "
+-#endif
+-	
+-#ifdef HAVE_LANGINFO_CODESET
+-	"+HAVE_LANGINFO_CODESET  "
+-#else
+-	"-HAVE_LANGINFO_CODESET  "
+-#endif
+-
+-	
+-#ifdef HAVE_LANGINFO_YESEXPR
+- 	"+HAVE_LANGINFO_YESEXPR  "
+-#else
+- 	"-HAVE_LANGINFO_YESEXPR  "
+-#endif
+-	
+-	"\n"
+-
+-#if HAVE_ICONV
+-	"+HAVE_ICONV  "
+-#else
+-	"-HAVE_ICONV  "
+-#endif
+-
+-#if ICONV_NONTRANS
+-	"+ICONV_NONTRANS  "
+-#else
+-	"-ICONV_NONTRANS  "
+-#endif
+-
+-#if HAVE_LIBIDN
+-	"+HAVE_LIBIDN  "
+-#else
+-	"-HAVE_LIBIDN  "
+-#endif
+-	
+-#if HAVE_GETSID
+-	"+HAVE_GETSID  "
+-#else
+-	"-HAVE_GETSID  "
+-#endif
+-
+-#if USE_HCACHE
+-	"+USE_HCACHE  "
+-#else
+-	"-USE_HCACHE  "
+-#endif
+-
+-	);
+-
+-#ifdef ISPELL
+-  printf ("ISPELL=\"%s\"\n", ISPELL);
+-#else
+-  puts ("-ISPELL");
+-#endif
+-
+-  printf ("SENDMAIL=\"%s\"\n", SENDMAIL);
+-  printf ("MAILPATH=\"%s\"\n", MAILPATH);
+-  printf ("PKGDATADIR=\"%s\"\n", PKGDATADIR);
+-  printf ("SYSCONFDIR=\"%s\"\n", SYSCONFDIR);
+-  printf ("EXECSHELL=\"%s\"\n", EXECSHELL);
+-#ifdef MIXMASTER
+-  printf ("MIXMASTER=\"%s\"\n", MIXMASTER);
+-#else
+-  puts ("-MIXMASTER");
+-#endif
+-
+-  puts(_(ReachingUs));
+-
+-  mutt_print_patchlist();
+-  
+-  exit (0);
+-}
+-
+ static void start_curses (void)
+ {
+   km_init (); /* must come before mutt_init */
+@@ -752,14 +360,10 @@
+     case 0:
+       break;
+     case 1:
+-      show_version ();
+-      break;
++      print_version();
++      exit (0);
+     default:
+-      puts (mutt_make_version ());
+-      puts (_(Copyright));
+-      puts (_(Licence));
+-      puts (_(Obtaining));
+-      puts (_(ReachingUs));
++      print_copyright();
+       exit (0);
+   }
+ 
+diff -urN mutt-1.6.1/Makefile.am mutt-1.6.1-ifdef/Makefile.am
+--- mutt-1.6.1/Makefile.am	2016-05-02 03:02:12.392171305 +0100
++++ mutt-1.6.1-ifdef/Makefile.am	2016-05-02 03:02:15.439219784 +0100
+@@ -34,7 +34,7 @@
+ 	score.c send.c sendlib.c signal.c sort.c \
+ 	status.c system.c thread.c charset.c history.c lib.c \
+ 	muttlib.c editmsg.c mbyte.c \
+-	url.c ascii.c crypt-mod.c crypt-mod.h safe_asprintf.c
++	url.c ascii.c crypt-mod.c crypt-mod.h safe_asprintf.c version.c
+ 
+ nodist_mutt_SOURCES = $(BUILT_SOURCES)
+ 
+@@ -73,7 +73,7 @@
+ 	muttbug pgppacket.h depcomp ascii.h BEWARE PATCHES patchlist.sh \
+ 	ChangeLog mkchangelog.sh mutt_idna.h \
+ 	snprintf.c regex.c crypt-gpgme.h hcachever.sh.in sys_socket.h \
+-	txt2c.c txt2c.sh version.sh check_sec.sh
++	txt2c.c txt2c.sh version.sh check_sec.sh version.h
+ 
+ EXTRA_SCRIPTS = smime_keys
+ 
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-ifdef/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-ifdef/PATCHES	2016-05-02 03:02:15.443219848 +0100
+@@ -0,0 +1 @@
++patch-ifdef-neo-20160502
+diff -urN mutt-1.6.1/README.ifdef mutt-1.6.1-ifdef/README.ifdef
+--- mutt-1.6.1/README.ifdef	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-ifdef/README.ifdef	2016-05-02 03:02:15.443219848 +0100
+@@ -0,0 +1,57 @@
++Ifdef Patch
++===========
++
++    Conditional config options
++
++Patch
++-----
++
++    To check if Mutt supports "ifdef", look for "patch-ifdef" in the mutt
++    version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    The "ifdef" patch introduces three new commands to Mutt and allow you to
++    share one config file between versions of Mutt that may have different
++    features compiled in.
++
++        ifdef  symbol config-command [args...]  # If a symbol is defined
++        ifndef symbol config-command [args...]  # If a symbol is not defined
++        finish                                  # Finish reading the current file
++
++    Here a symbol can be a $variable, <function>, command or compile-time
++    symbol, such as "USE_IMAP".
++
++    'finish' is particularly useful when combined with 'ifndef'. e.g.
++
++        # Sidebar config file
++        ifndef USE_SIDEBAR finish
++
++Commands
++--------
++
++        ifdef  symbol "config-command [args]"
++        ifndef symbol "config-command [args]"
++        finish
++
++See Also
++--------
++
++    * NeoMutt project
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Cedric Duval <cedricduval at free.fr>
++    * Matteo F. Vescovi <mfvescovi at gmail.com>
++    * Richard Russon <rich at flatcap.org>
++
+diff -urN mutt-1.6.1/version.c mutt-1.6.1-ifdef/version.c
+--- mutt-1.6.1/version.c	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-ifdef/version.c	2016-05-02 03:02:15.459220102 +0100
+@@ -0,0 +1,492 @@
++/**
++ * Copyright (C) 1996-2007 Michael R. Elkins <me at mutt.org>
++ * Copyright (C) 1999-2007 Thomas Roessler <roessler at does-not-exist.org>
++ * Copyright (C) 2016 Richard Russon
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#if HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <stdio.h>
++#include <string.h>
++#include <sys/utsname.h>
++
++#ifdef HAVE_STRINGPREP_H
++#include <stringprep.h>
++#elif defined (HAVE_IDN_STRINGPREP_H)
++#include <idn/stringprep.h>
++#endif
++#ifdef USE_SLANG_CURSES
++#include "slang.h"
++#endif
++
++#include "lib.h"
++
++// #include "protos.h"
++const char * mutt_make_version (void);
++void mutt_print_patchlist (void);
++
++// #include "hcache.h"
++const char * mutt_hcache_backend (void);
++
++const int SCREEN_WIDTH = 80;
++
++extern const char cc_version[];
++extern const char cc_cflags[];
++extern const char configure_options[];
++
++static const char *Copyright = N_(
++	"Copyright (C) 1996-2014 Michael R. Elkins <me at mutt.org>\n"
++	"Copyright (C) 1996-2002 Brandon Long <blong at fiction.net>\n"
++	"Copyright (C) 1997-2009 Thomas Roessler <roessler at does-not-exist.org>\n"
++	"Copyright (C) 1998-2005 Werner Koch <wk at isil.d.shuttle.de>\n"
++	"Copyright (C) 1999-2014 Brendan Cully <brendan at kublai.com>\n"
++	"Copyright (C) 1999-2002 Tommi Komulainen <Tommi.Komulainen at iki.fi>\n"
++	"Copyright (C) 2000-2004 Edmund Grimley Evans <edmundo at rano.org>\n"
++	"Copyright (C) 2006-2009 Rocco Rutte <pdmef at gmx.net>\n"
++	"Copyright (C) 2014-2015 Kevin J. McCarthy <kevin at 8t8.us>\n"
++	"\n"
++	"Many others not mentioned here contributed code, fixes,\n"
++	"and suggestions.\n"
++);
++
++static const char *License = N_(
++	"    This program is free software; you can redistribute it and/or modify\n"
++	"    it under the terms of the GNU General Public License as published by\n"
++	"    the Free Software Foundation; either version 2 of the License, or\n"
++	"    (at your option) any later version.\n"
++	"\n"
++	"    This program is distributed in the hope that it will be useful,\n"
++	"    but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
++	"    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
++	"    GNU General Public License for more details.\n"
++);
++
++static const char *Obtaining = N_(
++	"    You should have received a copy of the GNU General Public License\n"
++	"    along with this program; if not, write to the Free Software\n"
++	"    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n"
++);
++
++static const char *ReachingUs = N_(
++	"To contact the developers, please mail to <mutt-dev at mutt.org>.\n"
++	"To report a bug, please visit http://bugs.mutt.org/.\n"
++);
++
++static const char *Notice = N_(
++	"Copyright (C) 1996-2016 Michael R. Elkins and others.\n"
++	"Mutt comes with ABSOLUTELY NO WARRANTY; for details type `mutt -vv'.\n"
++	"Mutt is free software, and you are welcome to redistribute it\n"
++	"under certain conditions; type `mutt -vv' for details.\n"
++);
++
++struct compile_options {
++	const char *name;
++	int enabled;
++};
++
++static struct compile_options comp_opts[] = {
++#ifdef CRYPT_BACKEND_CLASSIC_PGP
++	{ "CRYPT_BACKEND_CLASSIC_PGP", 1 },
++#else
++	{ "CRYPT_BACKEND_CLASSIC_PGP", 0 },
++#endif
++#ifdef CRYPT_BACKEND_CLASSIC_SMIME
++	{ "CRYPT_BACKEND_CLASSIC_SMIME", 1 },
++#else
++	{ "CRYPT_BACKEND_CLASSIC_SMIME", 0 },
++#endif
++#ifdef CRYPT_BACKEND_GPGME
++	{ "CRYPT_BACKEND_GPGME", 1 },
++#else
++	{ "CRYPT_BACKEND_GPGME", 0 },
++#endif
++#ifdef DEBUG
++	{ "DEBUG", 1 },
++#else
++	{ "DEBUG", 0 },
++#endif
++#ifdef DL_STANDALONE
++	{ "DL_STANDALONE", 1 },
++#else
++	{ "DL_STANDALONE", 0 },
++#endif
++#ifdef ENABLE_NLS
++	{ "ENABLE_NLS", 1 },
++#else
++	{ "ENABLE_NLS", 0 },
++#endif
++#ifdef EXACT_ADDRESS
++	{ "EXACT_ADDRESS", 1 },
++#else
++	{ "EXACT_ADDRESS", 0 },
++#endif
++#ifdef HOMESPOOL
++	{ "HOMESPOOL", 1 },
++#else
++	{ "HOMESPOOL", 0 },
++#endif
++#ifdef LOCALES_HACK
++	{ "LOCALES_HACK", 1 },
++#else
++	{ "LOCALES_HACK", 0 },
++#endif
++#ifdef SUN_ATTACHMENT
++	{ "SUN_ATTACHMENT", 1 },
++#else
++	{ "SUN_ATTACHMENT", 0 },
++#endif
++#ifdef HAVE_BKGDSET
++	{ "HAVE_BKGDSET", 1 },
++#else
++	{ "HAVE_BKGDSET", 0 },
++#endif
++#ifdef HAVE_COLOR
++	{ "HAVE_COLOR", 1 },
++#else
++	{ "HAVE_COLOR", 0 },
++#endif
++#ifdef HAVE_CURS_SET
++	{ "HAVE_CURS_SET", 1 },
++#else
++	{ "HAVE_CURS_SET", 0 },
++#endif
++#ifdef HAVE_GETADDRINFO
++	{ "HAVE_GETADDRINFO", 1 },
++#else
++	{ "HAVE_GETADDRINFO", 0 },
++#endif
++#ifdef HAVE_GETSID
++	{ "HAVE_GETSID", 1 },
++#else
++	{ "HAVE_GETSID", 0 },
++#endif
++#ifdef HAVE_ICONV
++	{ "HAVE_ICONV", 1 },
++#else
++	{ "HAVE_ICONV", 0 },
++#endif
++#ifdef HAVE_LANGINFO_CODESET
++	{ "HAVE_LANGINFO_CODESET", 1 },
++#else
++	{ "HAVE_LANGINFO_CODESET", 0 },
++#endif
++#ifdef HAVE_LANGINFO_YESEXPR
++	{ "HAVE_LANGINFO_YESEXPR", 1 },
++#else
++	{ "HAVE_LANGINFO_YESEXPR", 0 },
++#endif
++#ifdef HAVE_LIBIDN
++	{ "HAVE_LIBIDN", 1 },
++#else
++	{ "HAVE_LIBIDN", 0 },
++#endif
++#ifdef HAVE_META
++	{ "HAVE_META", 1 },
++#else
++	{ "HAVE_META", 0 },
++#endif
++#ifdef HAVE_REGCOMP
++	{ "HAVE_REGCOMP", 1 },
++#else
++	{ "HAVE_REGCOMP", 0 },
++#endif
++#ifdef HAVE_RESIZETERM
++	{ "HAVE_RESIZETERM", 1 },
++#else
++	{ "HAVE_RESIZETERM", 0 },
++#endif
++#ifdef HAVE_START_COLOR
++	{ "HAVE_START_COLOR", 1 },
++#else
++	{ "HAVE_START_COLOR", 0 },
++#endif
++#ifdef HAVE_TYPEAHEAD
++	{ "HAVE_TYPEAHEAD", 1 },
++#else
++	{ "HAVE_TYPEAHEAD", 0 },
++#endif
++#ifdef HAVE_WC_FUNCS
++	{ "HAVE_WC_FUNCS", 1 },
++#else
++	{ "HAVE_WC_FUNCS", 0 },
++#endif
++#ifdef ICONV_NONTRANS
++	{ "ICONV_NONTRANS", 1 },
++#else
++	{ "ICONV_NONTRANS", 0 },
++#endif
++#ifdef USE_DOTLOCK
++	{ "USE_DOTLOCK", 1 },
++#else
++	{ "USE_DOTLOCK", 0 },
++#endif
++#ifdef USE_FCNTL
++	{ "USE_FCNTL", 1 },
++#else
++	{ "USE_FCNTL", 0 },
++#endif
++#ifdef USE_FLOCK
++	{ "USE_FLOCK", 1 },
++#else
++	{ "USE_FLOCK", 0 },
++#endif
++#ifdef USE_GNU_REGEX
++	{ "USE_GNU_REGEX", 1 },
++#else
++	{ "USE_GNU_REGEX", 0 },
++#endif
++#ifdef USE_GSS
++	{ "USE_GSS", 1 },
++#else
++	{ "USE_GSS", 0 },
++#endif
++#ifdef USE_HCACHE
++	{ "USE_HCACHE", 1 },
++#else
++	{ "USE_HCACHE", 0 },
++#endif
++#ifdef USE_IMAP
++	{ "USE_IMAP", 1 },
++#else
++	{ "USE_IMAP", 0 },
++#endif
++#ifdef USE_POP
++	{ "USE_POP", 1 },
++#else
++	{ "USE_POP", 0 },
++#endif
++#ifdef USE_SASL
++	{ "USE_SASL", 1 },
++#else
++	{ "USE_SASL", 0 },
++#endif
++#ifdef USE_SETGID
++	{ "USE_SETGID", 1 },
++#else
++	{ "USE_SETGID", 0 },
++#endif
++#ifdef USE_SMTP
++	{ "USE_SMTP", 1 },
++#else
++	{ "USE_SMTP", 0 },
++#endif
++#ifdef USE_SSL_GNUTLS
++	{ "USE_SSL_GNUTLS", 1 },
++#else
++	{ "USE_SSL_GNUTLS", 0 },
++#endif
++#ifdef USE_SSL_OPENSSL
++	{ "USE_SSL_OPENSSL", 1 },
++#else
++	{ "USE_SSL_OPENSSL", 0 },
++#endif
++	{ NULL, 0 }
++};
++
++/**
++ * print_compile_options - Print a list of enabled/disabled features
++ *
++ * The configure script lets uses enable/disable features.
++ * This shows the Mutt user which features are/aren't available.
++ *
++ * The output is of the form: "+ENABLED_FEATURE -DISABLED_FEATURE" and is
++ * wrapped to SCREEN_WIDTH characters.
++ */
++static void
++print_compile_options (void)
++{
++	int i;
++	char c;
++	int len;
++	int used = 0;
++
++	for (i = 0; comp_opts[i].name; i++) {
++		len = strlen (comp_opts[i].name) + 2;	/* +/- and a space */
++		if ((used + len) > SCREEN_WIDTH) {
++			used = 0;
++			puts ("");
++		}
++		used += len;
++		c = comp_opts[i].enabled ? '+' : '-';
++		printf ("%c%s ", c, comp_opts[i].name);
++	}
++	puts ("");
++}
++
++/**
++ * rstrip_in_place - Strip a trailing carriage return
++ * @s:  String to be modified
++ *
++ * The string has its last carriage return set to NUL.
++ * Returns:
++ *	The modified string
++ */
++static char *
++rstrip_in_place (char *s)
++{
++	if (!s)
++		return NULL;
++
++	char *p;
++
++	p = &s[strlen (s)];
++	if (p == s)
++		return s;
++	p--;
++	while ((p >= s) && ((*p == '\n') || (*p == '\r')))
++		*p-- = '\0';
++	return s;
++}
++
++/**
++ * print_version - Print system and compile info
++ *
++ * Print information about the current system Mutt is running on.
++ * Also print a list of all the compile-time information.
++ */
++void
++print_version (void)
++{
++	struct utsname uts;
++
++	puts (mutt_make_version());
++	puts (_(Notice));
++
++	uname (&uts);
++
++#ifdef _AIX
++	printf ("System: %s %s.%s", uts.sysname, uts.version, uts.release);
++#elif defined (SCO)
++	printf ("System: SCO %s", uts.release);
++#else
++	printf ("System: %s %s", uts.sysname, uts.release);
++#endif
++
++	printf (" (%s)", uts.machine);
++
++#ifdef NCURSES_VERSION
++	printf ("\nncurses: %s (compiled with %s)", curses_version(), NCURSES_VERSION);
++#elif defined (USE_SLANG_CURSES)
++	printf ("\nslang: %d", SLANG_VERSION);
++#endif
++
++#ifdef _LIBICONV_VERSION
++	printf ("\nlibiconv: %d.%d", _LIBICONV_VERSION >> 8,
++		_LIBICONV_VERSION & 0xff);
++#endif
++
++#ifdef HAVE_LIBIDN
++	printf ("\nlibidn: %s (compiled with %s)", stringprep_check_version (NULL),
++		STRINGPREP_VERSION);
++#endif
++
++#ifdef USE_HCACHE
++	printf ("\nhcache backend: %s", mutt_hcache_backend());
++#endif
++
++	puts ("\n\nCompiler:");
++	rstrip_in_place ((char *) cc_version);
++	puts (cc_version);
++
++	rstrip_in_place ((char *) configure_options);
++	printf ("\nConfigure options: %s\n", configure_options);
++
++	rstrip_in_place ((char *) cc_cflags);
++	printf ("\nCompilation CFLAGS: %s\n", cc_cflags);
++
++	puts (_("\nCompile options:"));
++	print_compile_options();
++
++#ifdef DOMAIN
++	printf ("DOMAIN=\"%s\"\n", DOMAIN);
++#else
++	puts ("-DOMAIN");
++#endif
++
++#ifdef MIXMASTER
++	printf ("MIXMASTER=\"%s\"\n", MIXMASTER);
++#else
++	puts ("-MIXMASTER");
++#endif
++
++#ifdef ISPELL
++	printf ("ISPELL=\"%s\"\n", ISPELL);
++#else
++	puts ("-ISPELL");
++#endif
++
++	printf ("SENDMAIL=\"%s\"\n", SENDMAIL);
++	printf ("MAILPATH=\"%s\"\n", MAILPATH);
++	printf ("PKGDATADIR=\"%s\"\n", PKGDATADIR);
++	printf ("SYSCONFDIR=\"%s\"\n", SYSCONFDIR);
++	printf ("EXECSHELL=\"%s\"\n", EXECSHELL);
++
++	puts (_(ReachingUs));
++
++	mutt_print_patchlist();
++}
++
++/**
++ * print_copyright - Print copyright message
++ *
++ * Print the authors' copyright messages, the GPL license and some contact
++ * information for the Mutt project.
++ */
++void
++print_copyright (void)
++{
++      puts (mutt_make_version());
++      puts (_(Copyright));
++      puts (_(License));
++      puts (_(Obtaining));
++      puts (_(ReachingUs));
++}
++
++/**
++ * feature_enabled - Test is a compile-time feature is enabled
++ * @name:  Compile-time symbol of the feature
++ *
++ * Many of the larger features of mutt can be disabled at compile time.
++ * They define a symbol and use #ifdef's around their code.
++ * The symbols are mirrored in "struct compile_options comp_opts[]" in this
++ * file.
++ *
++ * This function checks if one of these symbols is present in the code.
++ *
++ * These symbols are also seen in the output of "mutt -v".
++ *
++ * Returns:
++ *	1: Feature enables
++ *	0: Feature not enabled, or not compiled in
++ */
++int
++feature_enabled (const char *name)
++{
++	if (!name)
++		return 0;
++
++	int i;
++	for (i = 0; comp_opts[i].name; i++) {
++		if (mutt_strcmp (name, comp_opts[i].name) == 0) {
++			return 1;
++		}
++	}
++	return 0;
++}
++
+diff -urN mutt-1.6.1/version.h mutt-1.6.1-ifdef/version.h
+--- mutt-1.6.1/version.h	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-ifdef/version.h	2016-05-02 03:02:15.408219291 +0100
+@@ -0,0 +1,26 @@
++/**
++ * Copyright (C) 2016 Richard Russon
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
++ */
++
++#ifndef _VERSION_H_
++#define _VERSION_H_
++
++void print_version (void);
++void print_copyright (void);
++int feature_enabled (const char *name);
++
++#endif /* _VERSION_H_ */
diff --git a/debian/patches/neomutt/12-fmemopen.patch b/debian/patches/neomutt/12-fmemopen.patch
new file mode 100644
index 0000000..f6a8960
--- /dev/null
+++ b/debian/patches/neomutt/12-fmemopen.patch
@@ -0,0 +1,366 @@
+diff -urN mutt-1.6.1/configure.ac mutt-1.6.1-fmemopen/configure.ac
+--- mutt-1.6.1/configure.ac	2016-05-02 03:02:12.398171401 +0100
++++ mutt-1.6.1-fmemopen/configure.ac	2016-05-02 03:02:15.615222584 +0100
+@@ -1308,6 +1308,8 @@
+   AC_DEFINE(HAVE_LANGINFO_YESEXPR,1,[ Define if you have <langinfo.h> and nl_langinfo(YESEXPR). ])
+ fi
+ 
++AC_CHECK_FUNCS(fmemopen open_memstream)
++
+ dnl Documentation tools
+ have_openjade="no"
+ AC_PATH_PROG([OSPCAT], [ospcat], [none])
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-fmemopen/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-fmemopen/doc/manual.xml.head	2016-05-02 03:02:15.618222632 +0100
+@@ -8081,6 +8081,109 @@
+ 
+ </sect1>
+ 
++<sect1 id="fmemopen">
++	<title>Fmemopen Patch</title>
++	<subtitle>Replace some temporary files with memory buffers</subtitle>
++
++	<sect2 id="fmemopen-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>fmemopen</quote>, look for
++			<quote>patch-fmemopen</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++			<listitem><para><literal>open_memstream()</literal>, <literal>fmemopen()</literal> from glibc</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="fmemopen-intro">
++		<title>Introduction</title>
++
++        <para>
++		The <quote>fmemopen</quote> patch speeds up some searches.
++        </para>
++
++        <para>
++		This patch changes a few places where Mutt creates temporary files.
++		It replaces them with in-memory buffers.  This should improve the
++		performance when searching the header or body using the
++		<link linkend="thorough-search">$thorough_search</link> option.
++        </para>
++
++        <para>
++		There are no user-configurable parts.
++        </para>
++
++        <para>
++		This patch depends on <literal>open_memstream()</literal> and
++		<literal>fmemopen()</literal>.  They are provided by glibc.  Without
++		them, Mutt will simply create temporary files.
++        </para>
++	</sect2>
++
++<!--
++	<sect2 id="fmemopen-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="fmemopen-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="fmemopen-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="fmemopen-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="fmemopen-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="fmemopen-muttrc">
++		<title>Muttrc</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="fmemopen-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="compile-time-features">Compile-Time Features</link></para></listitem>
++			<listitem><para><literal>fmemopen(3)</literal></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="fmemopen-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="fmemopen-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Julius Plenz <email>plenz at cis.fu-berlin.de</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/handler.c mutt-1.6.1-fmemopen/handler.c
+--- mutt-1.6.1/handler.c	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-fmemopen/handler.c	2016-05-02 03:02:15.531221248 +0100
+@@ -1595,7 +1595,9 @@
+   int origType;
+   char *savePrefix = NULL;
+   FILE *fp = NULL;
++#ifndef HAVE_FMEMOPEN
+   char tempfile[_POSIX_PATH_MAX];
++#endif
+   size_t tmplength = 0;
+   LOFF_T tmpoffset = 0;
+   int decode = 0;
+@@ -1603,6 +1605,11 @@
+ 
+   fseeko (s->fpin, b->offset, 0);
+ 
++#ifdef HAVE_FMEMOPEN
++  char *temp;
++  size_t tempsize;
++#endif
++
+   /* see if we need to decode this part before processing it */
+   if (b->encoding == ENCBASE64 || b->encoding == ENCQUOTEDPRINTABLE ||
+       b->encoding == ENCUUENCODED || plaintext ||
+@@ -1618,6 +1625,14 @@
+     {
+       /* decode to a tempfile, saving the original destination */
+       fp = s->fpout;
++#ifdef HAVE_FMEMOPEN
++     s->fpout = open_memstream (&temp, &tempsize);
++     if (!s->fpout) {
++       mutt_error _("Unable to open memory stream!");
++       dprint (1, (debugfile, "Can't open memory stream.\n"));
++       return -1;
++     }
++#else
+       mutt_mktemp (tempfile, sizeof (tempfile));
+       if ((s->fpout = safe_fopen (tempfile, "w")) == NULL)
+       {
+@@ -1625,6 +1640,7 @@
+         dprint (1, (debugfile, "Can't open %s.\n", tempfile));
+         return -1;
+       }
++#endif
+       /* decoding the attachment changes the size and offset, so save a copy
+         * of the "real" values now, and restore them after processing
+         */
+@@ -1653,9 +1669,20 @@
+       /* restore final destination and substitute the tempfile for input */
+       s->fpout = fp;
+       fp = s->fpin;
++#ifdef HAVE_FMEMOPEN
++      if (tempsize) {
++        s->fpin = fmemopen (temp, tempsize, "r");
++      } else { /* fmemopen cannot handle zero-length buffers */
++        s->fpin = safe_fopen ("/dev/null", "r");
++      }
++      if (!s->fpin) {
++        mutt_perror ("failed to re-open memstream!");
++        return -1;
++      }
++#else
+       s->fpin = fopen (tempfile, "r");
+       unlink (tempfile);
+-
++#endif
+       /* restore the prefix */
+       s->prefix = savePrefix;
+     }
+@@ -1680,6 +1707,10 @@
+ 
+       /* restore the original source stream */
+       safe_fclose (&s->fpin);
++#ifdef HAVE_FMEMOPEN
++      if (tempsize)
++        FREE(&temp);
++#endif
+       s->fpin = fp;
+     }
+   }
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-fmemopen/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-fmemopen/PATCHES	2016-05-02 03:02:15.612222536 +0100
+@@ -0,0 +1 @@
++patch-fmemopen-neo-20160502
+diff -urN mutt-1.6.1/pattern.c mutt-1.6.1-fmemopen/pattern.c
+--- mutt-1.6.1/pattern.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-fmemopen/pattern.c	2016-05-02 03:02:15.627222775 +0100
+@@ -144,16 +144,21 @@
+ static int
+ msg_search (CONTEXT *ctx, pattern_t* pat, int msgno)
+ {
+-  char tempfile[_POSIX_PATH_MAX];
+   MESSAGE *msg = NULL;
+   STATE s;
+-  struct stat st;
+   FILE *fp = NULL;
+   long lng = 0;
+   int match = 0;
+   HEADER *h = ctx->hdrs[msgno];
+   char *buf;
+   size_t blen;
++#ifdef HAVE_FMEMOPEN
++  char *temp;
++  size_t tempsize;
++#else
++  char tempfile[_POSIX_PATH_MAX];
++  struct stat st;
++#endif
+ 
+   if ((msg = mx_open_message (ctx, msgno)) != NULL)
+   {
+@@ -163,12 +168,20 @@
+       memset (&s, 0, sizeof (s));
+       s.fpin = msg->fp;
+       s.flags = M_CHARCONV;
++#ifdef HAVE_FMEMOPEN
++      s.fpout = open_memstream (&temp, &tempsize);
++      if (!s.fpout) {
++	mutt_perror ("Error opening memstream");
++	return 0;
++      }
++#else
+       mutt_mktemp (tempfile, sizeof (tempfile));
+       if ((s.fpout = safe_fopen (tempfile, "w+")) == NULL)
+       {
+ 	mutt_perror (tempfile);
+ 	return (0);
+       }
++#endif
+ 
+       if (pat->op != M_BODY)
+ 	mutt_copy_header (msg->fp, h, s.fpout, CH_FROM | CH_DECODE, NULL);
+@@ -184,7 +197,11 @@
+ 	  if (s.fpout)
+ 	  {
+ 	    safe_fclose (&s.fpout);
++#ifdef HAVE_FMEMOPEN
++            FREE(&temp);
++#else
+ 	    unlink (tempfile);
++#endif
+ 	  }
+ 	  return (0);
+ 	}
+@@ -193,11 +210,30 @@
+ 	mutt_body_handler (h->content, &s);
+       }
+ 
++#ifdef HAVE_FMEMOPEN
++      fclose (s.fpout);
++      lng = tempsize;
++
++      if (tempsize) {
++        fp = fmemopen (temp, tempsize, "r");
++        if (!fp) {
++          mutt_perror ("Error re-opening memstream");
++          return 0;
++        }
++      } else { /* fmemopen cannot handle empty buffers */
++        fp = safe_fopen ("/dev/null", "r");
++        if (!fp) {
++          mutt_perror ("Error opening /dev/null");
++          return 0;
++        }
++      }
++#else
+       fp = s.fpout;
+       fflush (fp);
+       fseek (fp, 0, 0);
+       fstat (fileno (fp), &st);
+       lng = (long) st.st_size;
++#endif
+     }
+     else
+     {
+@@ -244,7 +280,12 @@
+     if (option (OPTTHOROUGHSRC))
+     {
+       safe_fclose (&fp);
++#ifdef HAVE_FMEMOPEN
++      if (tempsize)
++        FREE(&temp);
++#else
+       unlink (tempfile);
++#endif
+     }
+   }
+ 
+diff -urN mutt-1.6.1/README.fmemopen mutt-1.6.1-fmemopen/README.fmemopen
+--- mutt-1.6.1/README.fmemopen	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-fmemopen/README.fmemopen	2016-05-02 03:02:15.613222553 +0100
+@@ -0,0 +1,47 @@
++Fmemopen Patch
++==============
++
++    Replace some temporary files with memory buffers
++
++Patch
++-----
++
++    To check if Mutt supports "fmemopen", look for "patch-fmemopen" in the mutt
++    version.
++
++    Dependencies
++    * mutt-1.5.24
++    * 'open_memstream()', 'fmemopen()' from glibc
++
++Introduction
++------------
++
++    The "fmemopen" patch speeds up some searches.
++
++    This patch changes a few places where Mutt creates temporary files. It
++    replaces them with in-memory buffers. This should improve the performance
++    when searching the header or body using the $thorough_search option.
++
++    There are no user-configurable parts.
++
++    This patch depends on 'open_memstream()' and 'fmemopen()'. They are
++    provided by glibc. Without them, Mutt will simply create temporary files.
++
++See Also
++--------
++
++    * NeoMutt project
++    * Compile-Time Features
++    * 'fmemopen(3)'
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Julius Plenz <plenz at cis.fu-berlin.de>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/13-initials.patch b/debian/patches/neomutt/13-initials.patch
new file mode 100644
index 0000000..9f1b6e6
--- /dev/null
+++ b/debian/patches/neomutt/13-initials.patch
@@ -0,0 +1,264 @@
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-initials/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-initials/doc/manual.xml.head	2016-05-02 03:02:15.789225353 +0100
+@@ -8081,6 +8081,132 @@
+ 
+ </sect1>
+ 
++<sect1 id="initials">
++	<title>Initials Expando Patch</title>
++	<subtitle>Expando for author's initials</subtitle>
++
++	<sect2 id="initials-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Initials</quote>, look for
++			<quote>patch-initials</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="initials-intro">
++		<title>Introduction</title>
++
++        <para>
++		The <quote>initials</quote> patch adds an expando (%I) for an author's
++		initials.
++        </para>
++
++		<para>
++		The index panel displays a list of emails.  Its layout is controlled by
++		the <link linkend="index-format">$index_format</link> variable.  Using
++		this expando saves space in the index panel.  This can be useful if you
++		are regularly working with a small set of people.
++		</para>
++	</sect2>
++
++	<sect2 id="initials-variables">
++		<title>Variables</title>
++
++        <para>
++        This patch has no config of its own.  It adds an expando which can be
++		used in the <link linkend="index-format">$index_format</link> variable.
++        </para>
++	</sect2>
++
++<!--
++	<sect2 id="initials-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="initials-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="initials-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="initials-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="initials-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'initials' patch.
++ 
++# The 'initials' patch has no config of its own.
++# It adds an expando for an author's initials,
++# which can be used in the 'index_format' variable.
++ 
++# The default 'index_format' is:</emphasis>
++set index_format='%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s'
++ 
++<emphasis role="comment"># Where %L represents the author/recipient
++ 
++# This might look like:
++#       1   + Nov 17 David Bowie   Changesbowie    ( 689)
++#       2   ! Nov 17 Stevie Nicks  Rumours         ( 555)
++#       3   + Nov 16 Jimi Hendrix  Voodoo Child    ( 263)
++#       4   + Nov 16 Debbie Harry  Parallel Lines  ( 540)
++ 
++# Using the %I expando:</emphasis>
++set index_format='%4C %Z %{%b %d} %I (%?l?%4l&%4c?) %s'
++ 
++<emphasis role="comment"># This might look like:
++#       1   + Nov 17 DB Changesbowie    ( 689)
++#       2   ! Nov 17 SN Rumours         ( 555)
++#       3   + Nov 16 JH Voodoo Child    ( 263)
++#       4   + Nov 16 DH Parallel Lines  ( 540)
++ 
++# vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="initials-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="index-format">$index_format</link></para></listitem>
++			<listitem><para><link linkend="index-color">index-color patch</link></para></listitem>
++			<listitem><para><link linkend="folder-hook">folder-hook</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="initials-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="initials-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Vsevolod Volkov <email>vvv at mutt.org.ua</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.initials mutt-1.6.1-initials/doc/muttrc.initials
+--- mutt-1.6.1/doc/muttrc.initials	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-initials/doc/muttrc.initials	2016-05-02 03:02:15.698223905 +0100
+@@ -0,0 +1,27 @@
++# Example Mutt config file for the 'initials' patch.
++
++# The 'initials' patch has no config of its own.
++# It adds an expando for an author's initials,
++# which can be used in the 'index_format' variable.
++
++# The default 'index_format' is:
++set index_format='%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s'
++
++# Where %L represents the author/recipient
++
++# This might look like:
++#       1   + Nov 17 David Bowie   Changesbowie    ( 689)
++#       2   ! Nov 17 Stevie Nicks  Rumours         ( 555)
++#       3   + Nov 16 Jimi Hendrix  Voodoo Child    ( 263)
++#       4   + Nov 16 Debbie Harry  Parallel Lines  ( 540)
++
++# Using the %I expando:
++set index_format='%4C %Z %{%b %d} %I (%?l?%4l&%4c?) %s'
++
++# This might look like:
++#       1   + Nov 17 DB Changesbowie    ( 689)
++#       2   ! Nov 17 SN Rumours         ( 555)
++#       3   + Nov 16 JH Voodoo Child    ( 263)
++#       4   + Nov 16 DH Parallel Lines  ( 540)
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/hdrline.c mutt-1.6.1-initials/hdrline.c
+--- mutt-1.6.1/hdrline.c	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-initials/hdrline.c	2016-05-02 03:02:15.791225385 +0100
+@@ -212,6 +212,7 @@
+  * %f = entire from line
+  * %F = like %n, unless from self
+  * %i = message-id
++ * %I = initials of author
+  * %l = number of lines in the message
+  * %L = like %F, except `lists' are displayed first
+  * %m = number of messages in the mailbox
+@@ -463,6 +464,28 @@
+       mutt_format_s (dest, destlen, prefix, hdr->env->message_id ? hdr->env->message_id : "<no.id>");
+       break;
+ 
++    case 'I':
++      {
++	int iflag = FALSE;
++	int j = 0;
++
++	for (i = 0; hdr->env->from && hdr->env->from->personal &&
++		    hdr->env->from->personal[i] && (j < (SHORT_STRING - 1)); i++) {
++	  if (isalpha ((int) hdr->env->from->personal[i])) {
++	    if (!iflag) {
++	      buf2[j++] = hdr->env->from->personal[i];
++	      iflag = TRUE;
++	    }
++	  } else {
++	    iflag = FALSE;
++	  }
++	}
++
++	buf2[j] = '\0';
++      }
++      mutt_format_s (dest, destlen, prefix, buf2);
++      break;
++
+     case 'l':
+       if (!optional)
+       {
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-initials/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-initials/PATCHES	2016-05-02 03:02:15.783225257 +0100
+@@ -0,0 +1 @@
++patch-initials-neo-20160502
+diff -urN mutt-1.6.1/README.initials mutt-1.6.1-initials/README.initials
+--- mutt-1.6.1/README.initials	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-initials/README.initials	2016-05-02 03:02:15.784225273 +0100
+@@ -0,0 +1,48 @@
++Initials Expando Patch
++======================
++
++    Expando for author's initials
++
++Patch
++-----
++
++    To check if Mutt supports "Initials", look for "patch-initials" in the mutt
++    version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    The "initials" patch adds an expando (%I) for an author's initials.
++
++    The index panel displays a list of emails. Its layout is controlled by the
++    $index_format variable. Using this expando saves space in the index panel.
++    This can be useful if you are regularly working with a small set of people.
++
++Variables
++---------
++
++    This patch has no config of its own. It adds an expando which can be used
++    in the $index_format variable.
++
++See Also
++--------
++
++    * NeoMutt project
++    * $index_format
++    * index-color patch
++    * folder-hook
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Vsevolod Volkov <vvv at mutt.org.ua>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/14-trash.patch b/debian/patches/neomutt/14-trash.patch
new file mode 100644
index 0000000..4b25200
--- /dev/null
+++ b/debian/patches/neomutt/14-trash.patch
@@ -0,0 +1,780 @@
+diff -urN mutt-1.6.1/commands.c mutt-1.6.1-trash/commands.c
+--- mutt-1.6.1/commands.c	2016-05-02 03:02:12.398171401 +0100
++++ mutt-1.6.1-trash/commands.c	2016-05-02 03:02:15.950227914 +0100
+@@ -720,6 +720,7 @@
+     if (option (OPTDELETEUNTAG))
+       mutt_set_flag (Context, h, M_TAG, 0);
+   }
++  mutt_set_flag (Context, h, M_APPENDED, 1);
+   
+   return 0;
+ }
+diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-trash/curs_main.c
+--- mutt-1.6.1/curs_main.c	2016-05-02 03:02:12.400171433 +0100
++++ mutt-1.6.1-trash/curs_main.c	2016-05-02 03:02:15.953227962 +0100
+@@ -1919,6 +1919,7 @@
+ 	MAYBE_REDRAW (menu->redraw);
+ 	break;
+ 
++      case OP_PURGE_MESSAGE:
+       case OP_DELETE:
+ 
+ 	CHECK_MSGCOUNT;
+@@ -1930,6 +1931,7 @@
+ 	if (tag)
+ 	{
+ 	  mutt_tag_set_flag (M_DELETE, 1);
++	  mutt_tag_set_flag (M_PURGED, (op != OP_PURGE_MESSAGE) ? 0 : 1);
+ 	  if (option (OPTDELETEUNTAG))
+ 	    mutt_tag_set_flag (M_TAG, 0);
+ 	  menu->redraw = REDRAW_INDEX;
+@@ -1937,6 +1939,8 @@
+ 	else
+ 	{
+ 	  mutt_set_flag (Context, CURHDR, M_DELETE, 1);
++	  mutt_set_flag (Context, CURHDR, M_PURGED,
++			 (op != OP_PURGE_MESSAGE) ? 0 : 1);
+ 	  if (option (OPTDELETEUNTAG))
+ 	    mutt_set_flag (Context, CURHDR, M_TAG, 0);
+ 	  if (option (OPTRESOLVE))
+@@ -2242,11 +2246,13 @@
+ 	if (tag)
+ 	{
+ 	  mutt_tag_set_flag (M_DELETE, 0);
++	  mutt_tag_set_flag (M_PURGED, 0);
+ 	  menu->redraw = REDRAW_INDEX;
+ 	}
+ 	else
+ 	{
+ 	  mutt_set_flag (Context, CURHDR, M_DELETE, 0);
++	  mutt_set_flag (Context, CURHDR, M_PURGED, 0);
+ 	  if (option (OPTRESOLVE) && menu->current < Context->vcount - 1)
+ 	  {
+ 	    menu->current++;
+@@ -2268,9 +2274,11 @@
+ 	CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
+ 
+ 	rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0,
+-				   op == OP_UNDELETE_THREAD ? 0 : 1);
++				   op == OP_UNDELETE_THREAD ? 0 : 1)
++	  + mutt_thread_set_flag (CURHDR, M_PURGED, 0,
++				  (op == OP_UNDELETE_THREAD) ? 0 : 1);
+ 
+-	if (rc != -1)
++	if (rc > -1)
+ 	{
+ 	  if (option (OPTRESOLVE))
+ 	  {
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-trash/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-trash/doc/manual.xml.head	2016-05-02 03:02:15.955227994 +0100
+@@ -8081,6 +8081,175 @@
+ 
+ </sect1>
+ 
++<sect1 id="trash-folder">
++	<title>Trash Folder Patch</title>
++	<subtitle>Automatically move "deleted" emails to a trash bin</subtitle>
++
++	<sect2 id="trash-folder-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>Trash Folder</quote>, look for
++			<quote>patch-trash</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		If IMAP is enabled, this patch will use it
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++			<listitem><para>IMAP support</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="trash-folder-intro">
++		<title>Introduction</title>
++
++		<para>
++		In Mutt, when you <quote>delete</quote> an email it is first marked
++		deleted.  The email isn't really gone until
++		<link linkend="index-map"><sync-mailbox></link> is called.
++		This happens when the user leaves the folder, or the function is called
++		manually.
++		</para>
++
++		<para>
++		After <literal><sync-mailbox></literal> has been called the email is gone forever.
++		</para>
++
++		<para>
++		The <link linkend="trash">$trash</link> variable defines a folder in
++		which to keep old emails.  As before, first you mark emails for
++		deletion.  When <sync-mailbox> is called the emails are moved to
++		the trash folder.
++		</para>
++
++		<para>
++		The <literal>$trash</literal> path can be either a full directory,
++		or be relative to the <link linkend="folder">$folder</link>
++		variable, like the <literal>mailboxes</literal> command.
++		</para>
++
++		<note>
++		Emails deleted from the trash folder are gone forever.
++		</note>
++	</sect2>
++
++	<sect2 id="trash-folder-variables">
++		<title>Variables</title>
++		<table id="table-trash-variables">
++			<title>Trash Variables</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Name</entry>
++						<entry>Type</entry>
++						<entry>Default</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>trash</entry>
++						<entry>string</entry>
++						<entry>(none)</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++	<sect2 id="trash-folder-functions">
++		<title>Functions</title>
++		<table id="table-trash-functions">
++			<title>Trash Functions</title>
++			<tgroup cols="4">
++				<thead>
++					<row>
++						<entry>Menus</entry>
++						<entry>Default Key</entry>
++						<entry>Function</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>index,pager</entry>
++						<entry>(none)</entry>
++						<entry><literal><purge-message></literal></entry>
++						<entry>really delete the current entry, bypassing the trash folder</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++<!--
++	<sect2 id="trash-folder-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="trash-folder-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="trash-folder-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="trash-folder-muttrc">
++		<title>Muttrc</title>
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'trash' feature.
++ 
++# This feature defines a new 'trash' folder.
++# When mail is deleted it will be moved to this folder.
++ 
++# Folder in which to put deleted emails</emphasis>
++set trash='+Trash'
++set trash='/home/flatcap/Mail/Trash'
++ 
++<emphasis role="comment"># The default delete key 'd' will move an email to the 'trash' folder
++# Bind 'D' to REALLY delete an email</emphasis>
++bind index D purge-message
++ 
++<emphasis role="comment"># Note: Deleting emails from the 'trash' folder will REALLY delete them.
++ 
++# vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="trash-folder-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++			<listitem><para><link linkend="folder-hook">folder-hook</link></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="trash-folder-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="trash-folder-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>Cedric Duval <email>cedricduval at free.fr</email></para></listitem>
++		<listitem><para>Benjamin Kuperman <email>kuperman at acm.org</email></para></listitem>
++		<listitem><para>Paul Miller <email>paul at voltar.org</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.trash mutt-1.6.1-trash/doc/muttrc.trash
+--- mutt-1.6.1/doc/muttrc.trash	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-trash/doc/muttrc.trash	2016-05-02 03:02:15.862226514 +0100
+@@ -0,0 +1,16 @@
++# Example Mutt config file for the 'trash' feature.
++
++# This feature defines a new 'trash' folder.
++# When mail is deleted it will be moved to this folder.
++
++# Folder in which to put deleted emails
++set trash='+Trash'
++set trash='/home/flatcap/Mail/Trash'
++
++# The default delete key 'd' will move an email to the 'trash' folder
++# Bind 'D' to REALLY delete an email
++bind index D purge-message
++
++# Note: Deleting emails from the 'trash' folder will REALLY delete them.
++
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/doc/vimrc.trash mutt-1.6.1-trash/doc/vimrc.trash
+--- mutt-1.6.1/doc/vimrc.trash	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-trash/doc/vimrc.trash	2016-05-02 03:02:15.863226530 +0100
+@@ -0,0 +1,7 @@
++" Vim syntax file for the mutt trash patch
++
++syntax keyword muttrcVarStr     contained skipwhite trash                 nextgroup=muttrcVarEqualsIdxFmt
++
++syntax match muttrcFunction     contained "\<purge-message\>"
++
++" vim: syntax=vim
+diff -urN mutt-1.6.1/flags.c mutt-1.6.1-trash/flags.c
+--- mutt-1.6.1/flags.c	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-trash/flags.c	2016-05-02 03:02:15.956228010 +0100
+@@ -65,7 +65,13 @@
+       {
+ 	h->deleted = 0;
+         update = 1;
+-	if (upd_ctx) ctx->deleted--;
++        if (upd_ctx) {
++          ctx->deleted--;
++          if (h->appended) {
++            ctx->appended--;
++	  }
++        }
++        h->appended = 0; /* when undeleting, also reset the appended flag */
+ #ifdef USE_IMAP
+         /* see my comment above */
+ 	if (ctx->magic == M_IMAP) 
+@@ -87,6 +93,27 @@
+       }
+       break;
+ 
++    case M_APPENDED:
++      if (bf) {
++        if (!h->appended) {
++          h->appended = 1;
++          if (upd_ctx) {
++            ctx->appended++;
++          }
++        }
++      }
++      break;
++
++    case M_PURGED:
++      if (bf) {
++        if (!h->purged) {
++          h->purged = 1;
++        }
++      } else if (h->purged) {
++        h->purged = 0;
++      }
++      break;
++
+     case M_NEW:
+ 
+       if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
+diff -urN mutt-1.6.1/functions.h mutt-1.6.1-trash/functions.h
+--- mutt-1.6.1/functions.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-trash/functions.h	2016-05-02 03:02:15.956228010 +0100
+@@ -121,6 +121,7 @@
+   { "toggle-write",		OP_TOGGLE_WRITE,		"%" },
+   { "next-thread",		OP_MAIN_NEXT_THREAD,		"\016" },
+   { "next-subthread",		OP_MAIN_NEXT_SUBTHREAD,		"\033n" },
++  { "purge-message",		OP_PURGE_MESSAGE,		NULL },
+   { "query",			OP_QUERY,			"Q" },
+   { "quit",			OP_QUIT,			"q" },
+   { "reply",			OP_REPLY,			"r" },
+@@ -213,6 +214,7 @@
+   { "print-message",	OP_PRINT,			"p" },
+   { "previous-thread",	OP_MAIN_PREV_THREAD,		"\020" },
+   { "previous-subthread",OP_MAIN_PREV_SUBTHREAD,	"\033p" },
++  { "purge-message",	OP_PURGE_MESSAGE,		NULL },
+   { "quit",		OP_QUIT,			"Q" },
+   { "exit",		OP_EXIT,			"q" },
+   { "reply",		OP_REPLY,			"r" },
+diff -urN mutt-1.6.1/globals.h mutt-1.6.1-trash/globals.h
+--- mutt-1.6.1/globals.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-trash/globals.h	2016-05-02 03:02:15.956228010 +0100
+@@ -141,6 +141,7 @@
+ WHERE char *Status;
+ WHERE char *Tempdir;
+ WHERE char *Tochars;
++WHERE char *TrashPath;
+ WHERE char *TSStatusFormat;
+ WHERE char *TSIconFormat;
+ WHERE short TSSupported;
+diff -urN mutt-1.6.1/imap/imap.c mutt-1.6.1-trash/imap/imap.c
+--- mutt-1.6.1/imap/imap.c	2016-05-02 03:02:12.404171496 +0100
++++ mutt-1.6.1-trash/imap/imap.c	2016-05-02 03:02:15.957228026 +0100
+@@ -888,6 +888,12 @@
+           if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
+             match = invert ^ hdrs[n]->deleted;
+ 	  break;
++        case M_EXPIRED: /* imap_fast_trash version of M_DELETED */
++	  if (hdrs[n]->purged)
++	    break;
++          if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
++            match = invert ^ (hdrs[n]->deleted && !hdrs[n]->appended);
++	  break;
+         case M_FLAG:
+           if (hdrs[n]->flagged != HEADER_DATA(hdrs[n])->flagged)
+             match = invert ^ hdrs[n]->flagged;
+@@ -2038,3 +2044,53 @@
+ 
+   return -1;
+ }
++
++/**
++ * imap_fast_trash - XXX
++ */
++int
++imap_fast_trash (void)
++{
++	if ((Context->magic == M_IMAP) && mx_is_imap (TrashPath)) {
++		IMAP_MBOX mx;
++		IMAP_DATA *idata = (IMAP_DATA *) Context->data;
++		char mbox[LONG_STRING];
++		char mmbox[LONG_STRING];
++		int rc;
++		dprint (1, (debugfile, "[itf] trashcan seems to be on imap.\n"));
++
++		if (imap_parse_path (TrashPath, &mx) == 0) {
++			if (mutt_account_match (&(idata->conn->account), &(mx.account))) {
++				dprint (1, (debugfile, "[itf] trashcan seems to be on the same account.\n"));
++
++				imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
++				if (!*mbox)
++					strfcpy (mbox, "INBOX", sizeof (mbox));
++				imap_munge_mbox_name (idata, mmbox, sizeof (mmbox), mbox);
++
++				rc = imap_exec_msgset (idata, "UID COPY", mmbox, M_EXPIRED, 0, 0);
++				if (rc == 0) {
++					dprint (1, (debugfile, "imap_copy_messages: No messages del-tagged\n"));
++					rc = -1;
++					goto old_way;
++				} else if (rc < 0) {
++					dprint (1, (debugfile, "could not queue copy\n"));
++					goto old_way;
++				} else {
++					mutt_message (_("Copying %d messages to %s..."), rc, mbox);
++					return 0;
++				}
++			} else {
++				dprint (1, (debugfile, "[itf] trashcan seems to be on a different account.\n"));
++			}
++old_way:
++			FREE(&mx.mbox); /* we probably only need to free this when the parse works */
++		} else {
++			dprint (1, (debugfile, "[itf] failed to parse TrashPath.\n"));
++		}
++
++		dprint (1, (debugfile, "[itf] giving up and trying old fasioned way.\n"));
++	}
++
++	return 1;
++}
+diff -urN mutt-1.6.1/imap/imap.h mutt-1.6.1-trash/imap/imap.h
+--- mutt-1.6.1/imap/imap.h	2016-05-02 03:02:12.404171496 +0100
++++ mutt-1.6.1-trash/imap/imap.h	2016-05-02 03:02:15.867226594 +0100
+@@ -72,4 +72,7 @@
+ 
+ int imap_account_match (const ACCOUNT* a1, const ACCOUNT* a2);
+ 
++/* trash */
++int imap_fast_trash (void);
++
+ #endif
+diff -urN mutt-1.6.1/imap/message.c mutt-1.6.1-trash/imap/message.c
+--- mutt-1.6.1/imap/message.c	2016-05-02 03:02:12.405171512 +0100
++++ mutt-1.6.1-trash/imap/message.c	2016-05-02 03:02:15.867226594 +0100
+@@ -886,6 +886,7 @@
+         if (ctx->hdrs[n]->tagged)
+         {
+           mutt_set_flag (ctx, ctx->hdrs[n], M_DELETE, 1);
++          mutt_set_flag (ctx, ctx->hdrs[n], M_APPENDED, 1);
+           if (option (OPTDELETEUNTAG))
+             mutt_set_flag (ctx, ctx->hdrs[n], M_TAG, 0);
+         }
+@@ -893,6 +894,7 @@
+     else
+     {
+       mutt_set_flag (ctx, h, M_DELETE, 1);
++      mutt_set_flag (ctx, h, M_APPENDED, 1);
+       if (option (OPTDELETEUNTAG))
+         mutt_set_flag (ctx, h, M_TAG, 0);
+     }
+diff -urN mutt-1.6.1/init.h mutt-1.6.1-trash/init.h
+--- mutt-1.6.1/init.h	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-trash/init.h	2016-05-02 03:02:15.960228073 +0100
+@@ -3419,6 +3419,16 @@
+   ** provided that ``$$ts_enabled'' has been set. This string is identical in
+   ** formatting to the one used by ``$$status_format''.
+   */
++  { "trash",            DT_PATH, R_NONE, UL &TrashPath, 0 },
++  /*
++  ** .pp
++  ** If set, this variable specifies the path of the trash folder where the
++  ** mails marked for deletion will be moved, instead of being irremediably
++  ** purged.
++  ** .pp
++  ** NOTE: When you delete a message in the trash folder, it is really
++  ** deleted, so that you have a way to clean the trash.
++  */
+ #ifdef USE_SOCKET
+   { "tunnel",            DT_STR, R_NONE, UL &Tunnel, UL 0 },
+   /*
+diff -urN mutt-1.6.1/mutt.h mutt-1.6.1-trash/mutt.h
+--- mutt-1.6.1/mutt.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-trash/mutt.h	2016-05-02 03:02:15.961228089 +0100
+@@ -182,6 +182,8 @@
+   M_DELETE,
+   M_UNDELETE,
+   M_DELETED,
++  M_APPENDED,
++  M_PURGED,
+   M_FLAG,
+   M_TAG,
+   M_UNTAG,
+@@ -719,6 +721,8 @@
+   unsigned int mime : 1;    		/* has a MIME-Version header? */
+   unsigned int flagged : 1; 		/* marked important? */
+   unsigned int tagged : 1;
++  unsigned int appended : 1;		/* has been saved */
++  unsigned int purged : 1;   /* bypassing the trash folder */
+   unsigned int deleted : 1;
+   unsigned int changed : 1;
+   unsigned int attach_del : 1; 		/* has an attachment marked for deletion */
+@@ -891,6 +895,7 @@
+   int new;			/* how many new messages? */
+   int unread;			/* how many unread messages? */
+   int deleted;			/* how many deleted messages */
++  int appended;                 /* how many saved messages? */
+   int flagged;			/* how many flagged messages */
+   int msgnotreadyet;		/* which msg "new" in pager, -1 if none */
+ 
+diff -urN mutt-1.6.1/muttlib.c mutt-1.6.1-trash/muttlib.c
+--- mutt-1.6.1/muttlib.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-trash/muttlib.c	2016-05-02 03:02:15.962228105 +0100
+@@ -1511,7 +1511,9 @@
+ 
+   if (magic > 0 && !mx_access (s, W_OK))
+   {
+-    if (option (OPTCONFIRMAPPEND))
++    if (option (OPTCONFIRMAPPEND) &&
++       (!TrashPath || (mutt_strcmp (s, TrashPath) != 0)))
++       /* if we're appending to the trash, there's no point in asking */
+     {
+       snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s);
+       if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
+diff -urN mutt-1.6.1/mx.c mutt-1.6.1-trash/mx.c
+--- mutt-1.6.1/mx.c	2016-05-02 03:02:12.410171592 +0100
++++ mutt-1.6.1-trash/mx.c	2016-05-02 03:02:15.962228105 +0100
+@@ -776,6 +776,62 @@
+   return rc;
+ }
+ 
++/**
++ * trash_append - XXX
++ *
++ * move deleted mails to the trash folder
++ */
++static int trash_append (CONTEXT *ctx)
++{
++	CONTEXT *ctx_trash;
++	int i = 0;
++	struct stat st, stc;
++
++	if (!TrashPath || !ctx->deleted ||
++	   ((ctx->magic == M_MAILDIR) && option (OPTMAILDIRTRASH))) {
++		return 0;
++	}
++
++	for (; i < ctx->msgcount && (!ctx->hdrs[i]->deleted || ctx->hdrs[i]->appended); i++);
++		/* nothing */
++
++	if (i == ctx->msgcount)
++		return 0; /* nothing to be done */
++
++	if (mutt_save_confirm (TrashPath, &st) != 0) {
++		mutt_error _("message(s) not deleted");
++		return -1;
++	}
++
++	if (lstat (ctx->path, &stc) == 0 && stc.st_ino == st.st_ino
++	    && stc.st_dev == st.st_dev && stc.st_rdev == st.st_rdev) {
++		return 0;  /* we are in the trash folder: simple sync */
++	}
++
++#ifdef USE_IMAP
++	if (!imap_fast_trash())
++		return 0;
++#endif
++
++	if ((ctx_trash = mx_open_mailbox (TrashPath, M_APPEND, NULL)) != NULL) {
++		for (i = 0 ; i < ctx->msgcount ; i++) {
++			if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->appended
++			    && !ctx->hdrs[i]->purged
++			    && mutt_append_message (ctx_trash, ctx, ctx->hdrs[i], 0, 0) == -1) {
++				mx_close_mailbox (ctx_trash, NULL);
++				return -1;
++			}
++		}
++
++		mx_close_mailbox (ctx_trash, NULL);
++	} else {
++		mutt_error _("Can't open trash folder");
++		return -1;
++	}
++
++	return 0;
++}
++
+ /* save changes and close mailbox */
+ int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
+ {
+@@ -912,6 +968,7 @@
+ 	  if (mutt_append_message (&f, ctx, ctx->hdrs[i], 0, CH_UPDATE_LEN) == 0)
+ 	  {
+ 	    mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, 1);
++	    mutt_set_flag (ctx, ctx->hdrs[i], M_APPENDED, 1);
+ 	  }
+ 	  else
+ 	  {
+@@ -936,6 +993,14 @@
+     return 0;
+   }
+   
++  /* copy mails to the trash before expunging */
++  if (purge && ctx->deleted && mutt_strcmp (ctx->path, TrashPath)) {
++    if (trash_append (ctx) != 0) {
++      ctx->closing = 0;
++      return -1;
++    }
++  }
++
+ #ifdef USE_IMAP
+   /* allow IMAP to preserve the deleted flag across sessions */
+   if (ctx->magic == M_IMAP)
+@@ -1140,6 +1205,12 @@
+   msgcount = ctx->msgcount;
+   deleted = ctx->deleted;
+ 
++  if (purge && ctx->deleted && mutt_strcmp (ctx->path, TrashPath)) {
++    if (trash_append (ctx) == -1) {
++      return -1;
++    }
++  }
++
+ #ifdef USE_IMAP
+   if (ctx->magic == M_IMAP)
+     rc = imap_sync_mailbox (ctx, purge, index_hint);
+diff -urN mutt-1.6.1/OPS mutt-1.6.1-trash/OPS
+--- mutt-1.6.1/OPS	2016-05-02 03:02:12.392171305 +0100
++++ mutt-1.6.1-trash/OPS	2016-05-02 03:02:15.945227835 +0100
+@@ -142,6 +142,7 @@
+ OP_PREV_LINE "scroll up one line"
+ OP_PREV_PAGE "move to the previous page"
+ OP_PRINT "print the current entry"
++OP_PURGE_MESSAGE "really delete the current entry, bypassing the trash folder"
+ OP_QUERY "query external program for addresses"
+ OP_QUERY_APPEND "append new query results to current results"
+ OP_QUIT "save changes to mailbox and quit"
+diff -urN mutt-1.6.1/pager.c mutt-1.6.1-trash/pager.c
+--- mutt-1.6.1/pager.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-trash/pager.c	2016-05-02 03:02:15.963228121 +0100
+@@ -2351,6 +2351,7 @@
+ 	MAYBE_REDRAW (redraw);
+ 	break;
+ 
++      case OP_PURGE_MESSAGE:
+       case OP_DELETE:
+ 	CHECK_MODE(IsHeader (extra));
+ 	CHECK_READONLY;
+@@ -2358,6 +2359,8 @@
+ 	CHECK_ACL(M_ACL_DELETE, _("Cannot delete message"));
+ 
+ 	mutt_set_flag (Context, extra->hdr, M_DELETE, 1);
++	mutt_set_flag (Context, extra->hdr, M_PURGED,
++		       ch != OP_PURGE_MESSAGE ? 0 : 1);
+         if (option (OPTDELETEUNTAG))
+ 	  mutt_set_flag (Context, extra->hdr, M_TAG, 0);
+ 	redraw = REDRAW_STATUS | REDRAW_INDEX;
+@@ -2688,6 +2691,7 @@
+ 	CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message"));
+ 
+ 	mutt_set_flag (Context, extra->hdr, M_DELETE, 0);
++	mutt_set_flag (Context, extra->hdr, M_PURGED, 0);
+ 	redraw = REDRAW_STATUS | REDRAW_INDEX;
+ 	if (option (OPTRESOLVE))
+ 	{
+@@ -2704,9 +2708,11 @@
+ 	CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
+ 
+ 	r = mutt_thread_set_flag (extra->hdr, M_DELETE, 0,
++				  ch == OP_UNDELETE_THREAD ? 0 : 1)
++	  + mutt_thread_set_flag (extra->hdr, M_PURGED, 0,
+ 				  ch == OP_UNDELETE_THREAD ? 0 : 1);
+ 
+-	if (r != -1)
++	if (r > -1)
+ 	{
+ 	  if (option (OPTRESOLVE))
+ 	  {
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-trash/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-trash/PATCHES	2016-05-02 03:02:15.949227898 +0100
+@@ -0,0 +1 @@
++patch-trash-neo-20160502
+diff -urN mutt-1.6.1/pattern.c mutt-1.6.1-trash/pattern.c
+--- mutt-1.6.1/pattern.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-trash/pattern.c	2016-05-02 03:02:15.963228121 +0100
+@@ -1367,8 +1367,9 @@
+       {
+ 	switch (op)
+ 	{
+-	  case M_DELETE:
+ 	  case M_UNDELETE:
++	    mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_PURGED, 0);
++	  case M_DELETE:
+ 	    mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_DELETE, 
+ 			  (op == M_DELETE));
+ 	    break;
+diff -urN mutt-1.6.1/postpone.c mutt-1.6.1-trash/postpone.c
+--- mutt-1.6.1/postpone.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-trash/postpone.c	2016-05-02 03:02:15.905227198 +0100
+@@ -277,6 +277,9 @@
+   /* finished with this message, so delete it. */
+   mutt_set_flag (PostContext, h, M_DELETE, 1);
+ 
++  /* and consider it saved, so that it won't be moved to the trash folder */
++  mutt_set_flag (PostContext, h, M_APPENDED, 1);
++
+   /* update the count for the status display */
+   PostCount = PostContext->msgcount - PostContext->deleted;
+ 
+diff -urN mutt-1.6.1/README.trash mutt-1.6.1-trash/README.trash
+--- mutt-1.6.1/README.trash	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-trash/README.trash	2016-05-02 03:02:15.949227898 +0100
+@@ -0,0 +1,74 @@
++Trash Folder Patch
++==================
++
++    Automatically move "deleted" emails to a trash bin
++
++Patch
++-----
++
++    To check if Mutt supports "Trash Folder", look for "patch-trash" in the
++    mutt version.
++
++    If IMAP is enabled, this patch will use it
++
++    Dependencies
++    * mutt-1.5.24
++    * IMAP support
++
++Introduction
++------------
++
++    In Mutt, when you "delete" an email it is first marked deleted. The email
++    isn't really gone until <sync-mailbox> is called. This happens when the
++    user leaves the folder, or the function is called manually.
++
++    After '<sync-mailbox>' has been called the email is gone forever.
++
++    The $trash variable defines a folder in which to keep old emails. As
++    before, first you mark emails for deletion. When <sync-mailbox> is called
++    the emails are moved to the trash folder.
++
++    The '$trash' path can be either a full directory, or be relative to the
++    $folder variable, like the 'mailboxes' command.
++
++    > Note
++    >
++    > Emails deleted from the trash folder are gone forever.
++
++Variables
++---------
++
++    Trash Variables
++
++    | Name  | Type   | Default |
++    |-------|--------|---------|
++    | trash | string | (none)  |
++
++Functions
++---------
++
++    Trash Functions
++
++    | Menus       | Default Key | Function          | Description                                                 |
++    |-------------|-------------|-------------------|-------------------------------------------------------------|
++    | index,pager | (none)      | '<purge-message>' | really delete the current entry, bypassing the trash folder |
++
++See Also
++--------
++
++    * NeoMutt project
++    * folder-hook
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * Cedric Duval <cedricduval at free.fr>
++    * Benjamin Kuperman <kuperman at acm.org>
++    * Paul Miller <paul at voltar.org>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/15-limit-current-thread.patch b/debian/patches/neomutt/15-limit-current-thread.patch
new file mode 100644
index 0000000..22c23dd
--- /dev/null
+++ b/debian/patches/neomutt/15-limit-current-thread.patch
@@ -0,0 +1,322 @@
+diff -urN mutt-1.6.1/curs_main.c mutt-1.6.1-limit-current-thread/curs_main.c
+--- mutt-1.6.1/curs_main.c	2016-05-02 03:02:12.400171433 +0100
++++ mutt-1.6.1-limit-current-thread/curs_main.c	2016-05-02 03:02:16.152231128 +0100
+@@ -904,12 +904,14 @@
+ 	}
+         break;
+ 
++      case OP_LIMIT_CURRENT_THREAD:
+       case OP_MAIN_LIMIT:
+ 
+ 	CHECK_IN_MAILBOX;
+ 	menu->oldcurrent = (Context->vcount && menu->current >= 0 && menu->current < Context->vcount) ?
+ 		CURHDR->index : -1;
+-	if (mutt_pattern_func (M_LIMIT, _("Limit to messages matching: ")) == 0)
++	if (((op == OP_LIMIT_CURRENT_THREAD) && mutt_limit_current_thread(CURHDR))
++	    || ((op == OP_MAIN_LIMIT) && (mutt_pattern_func (M_LIMIT, _("Limit to messages matching: ")) == 0)))
+ 	{
+ 	  if (menu->oldcurrent >= 0)
+ 	  {
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-limit-current-thread/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-limit-current-thread/doc/manual.xml.head	2016-05-02 03:02:16.154231160 +0100
+@@ -8081,6 +8081,125 @@
+ 
+ </sect1>
+ 
++<sect1 id="limit-current-thread">
++	<title>Limit-Current-Thread Patch</title>
++	<subtitle>Focus on one Email Thread</subtitle>
++
++	<sect2 id="limit-current-thread-patch">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>limit-current-thread</quote>, look for
++			<quote>patch-limit-current-thread</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="limit-current-thread-intro">
++		<title>Introduction</title>
++
++		<para>
++			This patch adds a new way of using the
++			<link linkend="tuning-search">Limit Command</link>.
++                        The <literal><limit-current-thread></literal>
++                        function restricts the view to just the current thread.
++                        Setting the limit (the <literal>l</literal> key) to
++                        <quote>all</quote> will restore the full email list.
++		</para>
++
++	</sect2>
++
++<!--
++	<sect2 id="limit-current-thread-variables">
++		<title>Variables</title>
++		<para>None</para>
++	</sect2>
++-->
++	<sect2 id="limit-current-thread-functions">
++		<title>Functions</title>
++
++		<table id="table-limit-current-thread-functions">
++			<title>Limit-Current-Thread Functions</title>
++			<tgroup cols="4">
++				<thead>
++					<row>
++						<entry>Menus</entry>
++						<entry>Default Key</entry>
++						<entry>Function</entry>
++						<entry>Description</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry>index</entry>
++                                                <entry><literal><Esc> L</literal></entry>
++						<entry><literal><limit-current-thread></literal></entry>
++						<entry>Limit view to current thread</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++
++	</sect2>
++<!--
++	<sect2 id="limit-current-thread-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="limit-current-thread-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="limit-current-thread-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="limit-current-thread-muttrc">
++		<title>Muttrc</title>
++
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'limit-current-thread' patch.
++ 
++# Limit view to current thread</emphasis>
++bind index <esc>L limit-current-thread
++ 
++<emphasis role="comment"># vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="limit-current-thread-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="limit-current-thread-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="limit-current-thread-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>David Sterba <email>dsterba at suse.cz</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.limit-current-thread mutt-1.6.1-limit-current-thread/doc/muttrc.limit-current-thread
+--- mutt-1.6.1/doc/muttrc.limit-current-thread	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-limit-current-thread/doc/muttrc.limit-current-thread	2016-05-02 03:02:16.041229362 +0100
+@@ -0,0 +1,6 @@
++# Example Mutt config file for the 'limit-current-thread' patch.
++ 
++# Limit view to current thread
++bind index <esc>L limit-current-thread
++ 
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/functions.h mutt-1.6.1-limit-current-thread/functions.h
+--- mutt-1.6.1/functions.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-limit-current-thread/functions.h	2016-05-02 03:02:16.154231160 +0100
+@@ -114,6 +114,7 @@
+   { "next-undeleted",		OP_MAIN_NEXT_UNDELETED,		"j" },
+   { "previous-undeleted",	OP_MAIN_PREV_UNDELETED,		"k" },
+   { "limit",			OP_MAIN_LIMIT,			"l" },
++  { "limit-current-thread",	OP_LIMIT_CURRENT_THREAD,	"\033L" },
+   { "link-threads",		OP_MAIN_LINK_THREADS,		"&" },
+   { "list-reply",		OP_LIST_REPLY,			"L" },
+   { "mail",			OP_MAIL,			"m" },
+diff -urN mutt-1.6.1/mutt_menu.h mutt-1.6.1-limit-current-thread/mutt_menu.h
+--- mutt-1.6.1/mutt_menu.h	2016-05-02 03:02:12.409171576 +0100
++++ mutt-1.6.1-limit-current-thread/mutt_menu.h	2016-05-02 03:02:16.160231255 +0100
+@@ -115,4 +115,6 @@
+ void index_make_entry (char *, size_t, struct menu_t *, int);
+ int index_color (int);
+ 
++int mutt_limit_current_thread (HEADER *h);
++
+ #endif /* _MUTT_MENU_H_ */
+diff -urN mutt-1.6.1/OPS mutt-1.6.1-limit-current-thread/OPS
+--- mutt-1.6.1/OPS	2016-05-02 03:02:12.392171305 +0100
++++ mutt-1.6.1-limit-current-thread/OPS	2016-05-02 03:02:16.143230985 +0100
+@@ -176,6 +176,7 @@
+ OP_VIEW_ATTACH "view attachment using mailcap entry if necessary"
+ OP_VIEW_ATTACHMENTS "show MIME attachments"
+ OP_WHAT_KEY "display the keycode for a key press"
++OP_LIMIT_CURRENT_THREAD "limit view to current thread"
+ OP_MAIN_SHOW_LIMIT "show currently active limit pattern"
+ OP_MAIN_COLLAPSE_THREAD "collapse/uncollapse current thread"
+ OP_MAIN_COLLAPSE_ALL "collapse/uncollapse all threads"
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-limit-current-thread/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-limit-current-thread/PATCHES	2016-05-02 03:02:16.148231065 +0100
+@@ -0,0 +1 @@
++patch-limit-current-thread-neo-20160502
+diff -urN mutt-1.6.1/pattern.c mutt-1.6.1-limit-current-thread/pattern.c
+--- mutt-1.6.1/pattern.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-limit-current-thread/pattern.c	2016-05-02 03:02:16.162231287 +0100
+@@ -1294,6 +1294,74 @@
+   }
+ }
+ 
++/**
++ * top_of_thread - Find the first email in the current thread
++ * @h: Header of current email
++ *
++ * Returns:
++ *	THREAD*: success, email found
++ *	NULL:    on error
++ */
++static THREAD *
++top_of_thread (HEADER *h)
++{
++	THREAD *t;
++
++	if (!h)
++		return NULL;
++
++	t = h->thread;
++
++	while (t && t->parent)
++		t = t->parent;
++
++	return t;
++}
++
++/**
++ * mutt_limit_current_thread - Limit the email view to the current thread
++ * @h: Header of current email
++ *
++ * Returns:
++ *	1: Success
++ *	0: Failure
++ */
++int
++mutt_limit_current_thread (HEADER *h)
++{
++	int i;
++	THREAD *me;
++
++	if (!h)
++		return 0;
++
++	me = top_of_thread (h);
++	if (!me)
++		return 0;
++
++	Context->vcount    = 0;
++	Context->vsize     = 0;
++	Context->collapsed = 0;
++
++	for (i = 0; i < Context->msgcount; i++) {
++		Context->hdrs[i]->virtual    = -1;
++		Context->hdrs[i]->limited    = 0;
++		Context->hdrs[i]->collapsed  = 0;
++		Context->hdrs[i]->num_hidden = 0;
++
++		if (top_of_thread (Context->hdrs[i]) == me) {
++			BODY *body = Context->hdrs[i]->content;
++
++			Context->hdrs[i]->virtual = Context->vcount;
++			Context->hdrs[i]->limited = 1;
++			Context->v2r[Context->vcount] = i;
++			Context->vcount++;
++			Context->vsize += (body->length + body->offset - body->hdr_offset);
++		}
++	}
++	return 1;
++}
++
+ int mutt_pattern_func (int op, char *prompt)
+ {
+   pattern_t *pat;
+diff -urN mutt-1.6.1/README.limit-current-thread mutt-1.6.1-limit-current-thread/README.limit-current-thread
+--- mutt-1.6.1/README.limit-current-thread	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-limit-current-thread/README.limit-current-thread	2016-05-02 03:02:16.148231065 +0100
+@@ -0,0 +1,45 @@
++Limit-Current-Thread Patch
++==========================
++
++    Focus on one Email Thread
++
++Patch
++-----
++
++    To check if Mutt supports "limit-current-thread", look for
++    "patch-limit-current-thread" in the mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    This patch adds a new way of using the Limit Command. The
++    '<limit-current-thread>' function restricts the view to just the current
++    thread.
++    Setting the limit (the 'l' key) to "all" will restore the full email list.
++
++Functions
++---------
++
++    | Menus | Default Key | Function                 | Description                  |
++    |-------|-------------|--------------------------|------------------------------|
++    | index | '<Esc> L'   | '<limit-current-thread>' | Limit view to current thread |
++
++See Also
++--------
++
++    * NeoMutt project
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * David Sterba <dsterba at suse.cz>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/16-skip-quoted.patch b/debian/patches/neomutt/16-skip-quoted.patch
new file mode 100644
index 0000000..2bbe346
--- /dev/null
+++ b/debian/patches/neomutt/16-skip-quoted.patch
@@ -0,0 +1,259 @@
+diff -urN mutt-1.6.1/doc/manual.xml.head mutt-1.6.1-skip-quoted/doc/manual.xml.head
+--- mutt-1.6.1/doc/manual.xml.head	2016-05-02 03:02:12.402171465 +0100
++++ mutt-1.6.1-skip-quoted/doc/manual.xml.head	2016-05-02 03:02:16.766240897 +0100
+@@ -8081,6 +8081,127 @@
+ 
+ </sect1>
+ 
++<sect1 id="skip-quoted-patch">
++	<title>Skip-Quoted Patch</title>
++	<subtitle>Leave some context visible</subtitle>
++
++	<sect2 id="skip-quoted-patch2">
++		<title>Patch</title>
++
++		<para>
++			To check if Mutt supports <quote>skip-quoted</quote>, look for
++			<quote>patch-skip-quoted</quote> in the mutt version.
++			See: <xref linkend="mutt-patches"/>.
++		</para>
++
++		<itemizedlist>
++			<title>Dependencies:</title>
++			<listitem><para>mutt-1.5.24</para></listitem>
++		</itemizedlist>
++
++		<para>This patch is part of the <ulink url="http://www.neomutt.org/">NeoMutt Project</ulink>.</para>
++	</sect2>
++
++	<sect2 id="skip-quoted-intro">
++		<title>Introduction</title>
++
++		<para>
++			When viewing an email, the
++			<literal><skip-to-quoted></literal> function (by default the
++			<literal>S</literal> key) will scroll past any quoted text.
++			Sometimes, a little context is useful.
++		</para>
++
++		<para>
++			By setting the <literal>$skip_quoted_offset</literal> variable, you
++			can select how much of the quoted text is left visible.
++		</para>
++	</sect2>
++
++	<sect2 id="skip-quoted-variables">
++		<title>Variables</title>
++		<table id="table-skip-quoted-variables">
++			<title>Skip-Quoted Variables</title>
++			<tgroup cols="3">
++				<thead>
++					<row>
++						<entry>Name</entry>
++						<entry>Type</entry>
++						<entry>Default</entry>
++					</row>
++				</thead>
++				<tbody>
++					<row>
++						<entry><literal>skip_quoted_offset</literal></entry>
++						<entry>number</entry>
++						<entry>0</entry>
++					</row>
++				</tbody>
++			</tgroup>
++		</table>
++	</sect2>
++
++<!--
++	<sect2 id="skip-quoted-functions">
++		<title>Functions</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="skip-quoted-commands">
++		<title>Commands</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="skip-quoted-colors">
++		<title>Colors</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="skip-quoted-sort">
++		<title>Sort</title>
++		<para>None</para>
++	</sect2>
++-->
++
++	<sect2 id="skip-quoted-muttrc">
++		<title>Muttrc</title>
++
++<screen>
++<emphasis role="comment"># Example Mutt config file for the 'skip-quoted' patch.
++ 
++# The 'S' (skip-quoted) command scrolls the pager past the quoted text (usually
++# indented with '> '.  Setting 'skip_quoted_offset' leaves some lines of quoted
++# text on screen for context.
++ 
++# Show three quoted lines before the reply</emphasis>
++set skip_quoted_offset = 3
++ 
++<emphasis role="comment"># vim: syntax=muttrc</emphasis>
++</screen>
++	</sect2>
++
++	<sect2 id="skip-quoted-see-also">
++		<title>See Also</title>
++
++		<itemizedlist>
++			<listitem><para><ulink url="http://www.neomutt.org/">NeoMutt Project</ulink></para></listitem>
++		</itemizedlist>
++	</sect2>
++
++	<sect2 id="skip-quoted-known-bugs">
++		<title>Known Bugs</title>
++		<para>None</para>
++	</sect2>
++
++	<sect2 id="skip-quoted-credits">
++		<title>Credits</title>
++		<itemizedlist>
++		<listitem><para>David Sterba <email>dsterba at suse.cz</email></para></listitem>
++		<listitem><para>Richard Russon <email>rich at flatcap.org</email></para></listitem>
++		</itemizedlist>
++	</sect2>
++</sect1>
++
+ </chapter>
+ 
+ <chapter id="security">
+diff -urN mutt-1.6.1/doc/muttrc.skip-quoted mutt-1.6.1-skip-quoted/doc/muttrc.skip-quoted
+--- mutt-1.6.1/doc/muttrc.skip-quoted	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-skip-quoted/doc/muttrc.skip-quoted	2016-05-02 03:02:16.663239258 +0100
+@@ -0,0 +1,10 @@
++# Example Mutt config file for the 'skip-quoted' patch.
++ 
++# The 'S' (skip-quoted) command scrolls the pager past the quoted text (usually
++# indented with '> '.  Setting 'skip_quoted_offset' leaves some lines of quoted
++# text on screen for context.
++ 
++# Show three quoted lines before the reply
++set skip_quoted_offset = 3
++ 
++# vim: syntax=muttrc
+diff -urN mutt-1.6.1/globals.h mutt-1.6.1-skip-quoted/globals.h
+--- mutt-1.6.1/globals.h	2016-05-02 03:02:12.403171480 +0100
++++ mutt-1.6.1-skip-quoted/globals.h	2016-05-02 03:02:16.767240913 +0100
+@@ -204,6 +204,7 @@
+ WHERE short SaveHist;
+ WHERE short SendmailWait;
+ WHERE short SleepTime INITVAL (1);
++WHERE short SkipQuotedOffset;
+ WHERE short TimeInc;
+ WHERE short Timeout;
+ WHERE short Wrap;
+diff -urN mutt-1.6.1/init.h mutt-1.6.1-skip-quoted/init.h
+--- mutt-1.6.1/init.h	2016-05-02 03:02:12.407171544 +0100
++++ mutt-1.6.1-skip-quoted/init.h	2016-05-02 03:02:16.771240977 +0100
+@@ -2703,6 +2703,12 @@
+   ** replacing ``%s'' with the supplied string.
+   ** For the default value, ``joe'' would be expanded to: ``~f joe | ~s joe''.
+   */
++  { "skip_quoted_offset", DT_NUM, R_NONE, UL &SkipQuotedOffset, 0 },
++  /*
++  ** .pp
++  ** Lines of quoted text that are displayed before the unquoted text after
++  ** 'skip to quoted' command (S)
++  */
+   { "sleep_time",	DT_NUM, R_NONE, UL &SleepTime, 1 },
+   /*
+   ** .pp
+diff -urN mutt-1.6.1/pager.c mutt-1.6.1-skip-quoted/pager.c
+--- mutt-1.6.1/pager.c	2016-05-02 03:02:12.411171608 +0100
++++ mutt-1.6.1-skip-quoted/pager.c	2016-05-02 03:02:16.775241040 +0100
+@@ -2249,11 +2249,11 @@
+ 	  int dretval = 0;
+ 	  int new_topline = topline;
+ 
+-	  while ((new_topline < lastLine ||
++	  while (((new_topline + SkipQuotedOffset) < lastLine ||
+ 		  (0 == (dretval = display_line (fp, &last_pos, &lineInfo,
+ 			 new_topline, &lastLine, &maxLine, M_TYPES | (flags & M_PAGER_NOWRAP),
+ 			 &QuoteList, &q_level, &force_redraw, &SearchRE))))
+-		 && lineInfo[new_topline].type != MT_COLOR_QUOTED)
++		 && lineInfo[new_topline + SkipQuotedOffset].type != MT_COLOR_QUOTED)
+ 	    new_topline++;
+ 
+ 	  if (dretval < 0)
+@@ -2262,11 +2262,11 @@
+ 	    break;
+ 	  }
+ 
+-	  while ((new_topline < lastLine ||
++	  while (((new_topline + SkipQuotedOffset) < lastLine ||
+ 		  (0 == (dretval = display_line (fp, &last_pos, &lineInfo,
+ 			 new_topline, &lastLine, &maxLine, M_TYPES | (flags & M_PAGER_NOWRAP),
+ 			 &QuoteList, &q_level, &force_redraw, &SearchRE))))
+-		 && lineInfo[new_topline].type == MT_COLOR_QUOTED)
++		 && lineInfo[new_topline + SkipQuotedOffset].type == MT_COLOR_QUOTED)
+ 	    new_topline++;
+ 
+ 	  if (dretval < 0)
+diff -urN mutt-1.6.1/PATCHES mutt-1.6.1-skip-quoted/PATCHES
+--- mutt-1.6.1/PATCHES	2016-05-02 03:02:12.396171369 +0100
++++ mutt-1.6.1-skip-quoted/PATCHES	2016-05-02 03:02:16.761240817 +0100
+@@ -0,0 +1 @@
++patch-skip-quoted-neo-20160502
+diff -urN mutt-1.6.1/README.skip-quoted mutt-1.6.1-skip-quoted/README.skip-quoted
+--- mutt-1.6.1/README.skip-quoted	1970-01-01 01:00:00.000000000 +0100
++++ mutt-1.6.1-skip-quoted/README.skip-quoted	2016-05-02 03:02:16.761240817 +0100
+@@ -0,0 +1,47 @@
++Skip-Quoted Patch
++=================
++
++    Leave some context visible
++
++Patch
++-----
++
++    To check if Mutt supports "Skip-Quoted", look for "patch-skip-quoted" in
++    the mutt version.
++
++    Dependencies
++    * mutt-1.5.24
++
++Introduction
++------------
++
++    When viewing an email, the '<skip-to-quoted>' function (by default the 'S'
++    key) will scroll past any quoted text. Sometimes, a little context is
++    useful.
++
++    By setting the '$skip_quoted_offset' variable, you can select how much of
++    the quoted text is left visible.
++
++Variables
++---------
++
++    | Name                 | Type   | Default |
++    |----------------------|--------|---------|
++    | 'skip_quoted_offset' | number | 0       |
++
++See Also
++--------
++
++    * NeoMutt project
++
++Known Bugs
++----------
++
++    None
++
++Credits
++-------
++
++    * David Sterba <dsterba at suse.cz>
++    * Richard Russon <rich at flatcap.org>
++
diff --git a/debian/patches/neomutt/README.md b/debian/patches/neomutt/README.md
new file mode 100644
index 0000000..6bcd592
--- /dev/null
+++ b/debian/patches/neomutt/README.md
@@ -0,0 +1,31 @@
+# 2016-05-02 - Release for Mutt-1.6.1
+
+Many thanks to new NeoMutt contributors: Yoshiki Vázquez Baeza and Santiago Torres.
+
+This release sees many bug-fixes in Mutt, some more NeoMutt bug fixes and a
+couple of improvements to the Sidebar.
+
+Thank you to all the people who reported problems.
+
+## Fixes and Improvements
+
+- Build for Notmuch works if Sidebar is disabled
+- Sidebar functions work even if the Sidebar is hidden
+- sidebar-next-new, etc, only find **new** mail, as documented
+- Notmuch supports **very** long queries
+
+## Under Development
+
+Yoshiki and Santiago are working on a 'new-mail' command which is executed when
+new mail arrives.  It should be ready, soon.
+
+These patches apply to Mutt-1.6.1
+
+Patches: https://github.com/neomutt/neomutt/releases/download/neomutt-20160502/neomutt-patches-20160502.tar.gz
+Source:  https://github.com/neomutt/neomutt/archive/neomutt-20160502.tar.gz
+Release: https://github.com/neomutt/neomutt/tree/neomutt-20160502
+Website: http://www.neomutt.org/
+
+Rich Russon (FlatCap)
+rich at flatcap.org
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mutt/mutt.git



More information about the pkg-mutt-commits mailing list