commit 47db8fc58175f1404a24b7dd4ce73fd95e83f018
parent 178c5e4636f5d2168423f2d51115a615609e4952
Author: Jaromil <jaromil@dyne.org>
Date:   Tue,  6 Jan 2015 19:13:12 +0100
removed mairix from codebase
Diffstat:
79 files changed, 0 insertions(+), 36263 deletions(-)
diff --git a/src/fetchdate.c b/src/fetchdate.c
@@ -1,152 +0,0 @@
-/* Jaro Mail
- *
- *  (C) Copyright 2012 Denis Roio <jaromil@dyne.org>
- *      
- * This is just a simple use of Mairix API to extract formatted dates
- *
- * This source code is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Public License as published 
- * by the Free Software Foundation; either version 3 of the License,
- * or (at your option) any later version.
- *
- * This source code 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.
- * Please refer to the GNU Public License for more details.
- *
- * You should have received a copy of the GNU Public License along with
- * this source code; if not, write to:
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdio.h>
-#include <mairix.h>
-
-#define TEST 1
-
-int verbose = 0;
-int do_hardlinks = 0;
-int do_movefiles = 0;
-char dateformat[256];
-
-void out_of_mem(char *file, int line, size_t size);
-void report_error(const char *str, const char *filename);
-void emit_int(int x);
-
-static struct rfc822 *parsed;
-
-int main (int argc, char **argv) {
-  if( argc < 2 ) {
-    printf("usage: fetchdate filename strftime_format\n");
-    printf("see man strftime(5) for format options");
-    exit(1);
-  }
-
-  if(argc>2)
-    snprintf(dateformat, 255, "%s", argv[2]);
-  else // default date format
-    strcpy(dateformat, "%a, %d %b %Y");
-
-  //  printf("Parsing email: %s\n",argv[1]);
-  parsed = make_rfc822(argv[1]);
-
-  if (parsed) {
-    char datebuf[64];
-    struct tm *thetm;
-#ifdef TEST
-    if (parsed->hdrs.to)      printf("  To:         %s\n", parsed->hdrs.to);
-    if (parsed->hdrs.cc)      printf("  Cc:         %s\n", parsed->hdrs.cc);
-    if (parsed->hdrs.from)    printf("  From:       %s\n", parsed->hdrs.from);
-    if (parsed->hdrs.subject) printf("  Subject:    %s\n", parsed->hdrs.subject);
-    if (parsed->hdrs.message_id)
-      printf("  Message-ID: %s\n", parsed->hdrs.message_id);
-    thetm = gmtime(&parsed->hdrs.date);
-    strftime(datebuf, sizeof(datebuf), dateformat, thetm);
-    printf("  Date:        %s\n", datebuf);
-#else
-    thetm = gmtime(&parsed->hdrs.date);
-    strftime(datebuf, sizeof(datebuf), dateformat, thetm);
-
-    /* needed by timecloud:
-
-   [["YYYY-MM-DD",[["TAG1","WEIGHT1"],
-                   ["TAG2","WEIGHT2"],
-                   ...
-                  ]
-    ],
-    ["YYYY-MM-DD",[....]]
-   ]
-
-    */      
-
-    printf("%s\n",datebuf);
-    
-#endif
-    free_rfc822(parsed);
-  }
-
-  exit(0);
-}
-
-void out_of_mem(char *file, int line, size_t size)/*{{{*/
-{
-  /* Hairy coding ahead - can't use any [s]printf, itoa etc because
-   * those might try to use the heap! */
-
-  int filelen;
-  char *p;
-
-  static char msg1[] = "Out of memory (at ";
-  static char msg2[] = " bytes)\n";
-  /* Perhaps even strlen is unsafe in this situation? */
-  p = file;
-  while (*p) p++;
-  filelen = p - file;
-  write(2, msg1, sizeof(msg1));
-  write(2, file, filelen);
-  write(2, ":", 1);
-  emit_int(line);
-  write(2, ", ", 2);
-  emit_int(size);
-  write(2, msg2, sizeof(msg2));
-  exit(2);
-}
-/*}}}*/
-void report_error(const char *str, const char *filename)/*{{{*/
-{
-  if (filename) {
-    int len = strlen(str) + strlen(filename) + 4;
-    char *t;
-    t = new_array(char, len);
-    sprintf(t, "%s '%s'", str, filename);
-    perror(t);
-    free(t);
-  } else {
-    perror(str);
-  }
-}
-void emit_int(int x)/*{{{*/
-{
-  char buf1[20], buf2[20];
-  char *p, *q;
-  int neg=0;
-  p = buf1;
-  *p = '0'; /* In case x is zero */
-  if (x < 0) {
-    neg = 1;
-    x = -x;
-  }
-  while (x) {
-    *p++ = '0' + (x % 10);
-    x /= 10;
-  }
-  p--;
-  q = buf2;
-  if (neg) *q++ = '-';
-  while (p >= buf1) {
-    *q++ = *p--;
-  }
-  write(2, buf2, q-buf2);
-  return;
-}
diff --git a/src/mairix.h b/src/mairix.h
@@ -1,403 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 MAIRIX_H
-#define MAIRIX_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "memmac.h"
-
-struct msgpath {/*{{{*/
-  /* The 'selector' for this union is the corresponding entry of type 'enum
-   * message_type' */
-  union {
-    struct {
-      char *path;
-      size_t size;  /* size of the message in bytes */
-      time_t mtime; /* mtime of message file on disc */
-    } mpf; /* message per file */
-    struct {
-      int file_index; /* index into table of mbox files */
-      int msg_index;  /* index of message within the file */
-    } mbox; /* for messages in mbox format folders */
-  } src;
-
-  /* Now fields that are common to both types of message. */
-  time_t date;  /* representation of Date: header in message */
-  int tid;      /* thread-id */
-
-  /* Message flags. */
-  unsigned int seen:1;
-  unsigned int replied:1;
-  unsigned int flagged:1;
-    
-  /* + other stuff eventually */
-};
-/*}}}*/
-
-enum message_type {/*{{{*/
-  MTY_DEAD,     /* msg no longer exists, i.e. don't report in searches,
-                   prune it on a '-p' run. */
-  MTY_FILE,     /* msg <-> file in 1-1 correspondence e.g. maildir, MH */
-  MTY_MBOX      /* multiple msgs per file : MBOX format file */
-};
-/*}}}*/
-struct msgpath_array {/*{{{*/
-  enum message_type *type;
-  struct msgpath *paths;
-  int n;
-  int max;
-};
-/*}}}*/
-
-struct matches {/*{{{*/
-  unsigned char *msginfo;
-  int n; /* bytes in use */
-  int max; /* bytes allocated */
-  unsigned long highest;
-};
-/*}}}*/
-struct token {/*{{{*/
-  char *text;
-  unsigned long hashval;
-  /* to store delta-compressed info of which msgpaths match the token */
-  struct matches match0;
-};
-/*}}}*/
-struct token2 {/*{{{*/
-  char *text;
-  unsigned long hashval;
-  /* to store delta-compressed info of which msgpaths match the token */
-  struct matches match0;
-  struct matches match1;
-};
-/*}}}*/
-struct toktable {/*{{{*/
-  struct token **tokens;
-  int n; /* # in use */
-  int size; /* # allocated */
-  unsigned int mask; /* for masking down hash values */
-  int hwm; /* number to have before expanding */
-};
-/*}}}*/
-struct toktable2 {/*{{{*/
-  struct token2 **tokens;
-  int n; /* # in use */
-  int size; /* # allocated */
-  unsigned int mask; /* for masking down hash values */
-  int hwm; /* number to have before expanding */
-};
-/*}}}*/
-
-enum content_type {/*{{{*/
-  CT_TEXT_PLAIN,
-  CT_TEXT_HTML,
-  CT_TEXT_OTHER,
-  CT_MESSAGE_RFC822,
-  CT_OTHER
-};
-/*}}}*/
-struct rfc822;
-struct attachment {/*{{{*/
-  struct attachment *next;
-  struct attachment *prev;
-  enum content_type ct;
-  char *filename;
-  union attachment_body {
-    struct normal_attachment_body {
-      int len;
-      char *bytes;
-    } normal;
-    struct rfc822 *rfc822;
-  } data;
-};
-/*}}}*/
-struct headers {/*{{{*/
-  char *to;
-  char *cc;
-  char *from;
-  char *subject;
-
-  /* The following are needed to support threading */
-  char *message_id;
-  char *in_reply_to;
-  char *references;
-
-  struct {
-    unsigned int seen:1;
-    unsigned int replied:1;
-    unsigned int flagged:1;
-  } flags;
-
-  time_t date;
-};
-/*}}}*/
-struct rfc822 {/*{{{*/
-  struct headers hdrs;
-  struct attachment atts;
-};
-/*}}}*/
-
-typedef char checksum_t[16];
-
-struct message_list {/*{{{*/
-  struct message_list *next;
-  off_t start;
-  size_t len;
-};
-/*}}}*/
-struct mbox {/*{{{*/
-  /* If path==NULL, this indicates that the mbox is dead, i.e. no longer
-   * exists. */
-  char *path;
-  /* As read in from database (i.e. current last time mairix scan was run.) */
-  time_t file_mtime;
-  size_t file_size;
-  /* As found in the filesystem now. */
-  time_t current_mtime;
-  size_t current_size;
-  /* After reconciling a loaded database with what's on the disc, this entry
-     stores how many of the msgs that used to be there last time are still
-     present at the head of the file.  Thus, all messages beyond that are
-     treated as dead, and scanning starts at that point to find 'new' messages
-     (whch may actually be old ones that have moved, but they're treated as
-     new.) */
-  int n_old_msgs_valid;
-
-  /* Hold list of new messages and their number.  Number is temporary -
-   * eventually just list walking in case >=2 have to be reattached. */
-  struct message_list *new_msgs;
-  int n_new_msgs;
-
-  int n_so_far; /* Used during database load. */
-
-  int n_msgs;   /* Number of entries in 'start' and 'len' */
-  int max_msgs; /* Allocated size of 'start' and 'len' */
-  /* File offset to the start of each message (first line of real header, not to mbox 'From ' line) */
-  off_t *start;
-  /* Length of each message */
-  size_t *len;
-  /* Checksums on whole messages. */
-  checksum_t *check_all;
-
-};
-/*}}}*/
-struct database {/*{{{*/
-  /* Used to hold an entire mapping between an array of filenames, each
-     containing a single message, and the sets of tokens that occur in various
-     parts of those messages */
-
-  enum message_type *type;
-  struct msgpath *msgs; /* Paths to messages */
-  int n_msgs; /* Number in use */
-  int max_msgs; /* Space allocated */
-
-  struct mbox *mboxen;
-  int n_mboxen; /* number in use. */
-  int max_mboxen; /* space allocated */
-
-  /* Seed for hashing in the token tables.  Randomly created for
-   * each new database - avoid DoS attacks through carefully
-   * crafted messages. */
-  unsigned int hash_key;
-
-  /* Token tables */
-  struct toktable *to;
-  struct toktable *cc;
-  struct toktable *from;
-  struct toktable *subject;
-  struct toktable *body;
-  struct toktable *attachment_name;
-
-  /* Encoding chain 0 stores all msgids appearing in the following message headers:
-   * Message-Id, In-Reply-To, References.  Used for thread reconciliation.
-   * Encoding chain 1 stores just the Message-Id.  Used for search by message ID.
-  */
-  struct toktable2 *msg_ids;
-};
-/*}}}*/
-
-enum folder_type {/*{{{*/
-  FT_MAILDIR,
-  FT_MH,
-  FT_MBOX,
-  FT_RAW,
-  FT_EXCERPT
-};
-/*}}}*/
-
-struct string_list {/*{{{*/
-  struct string_list *next;
-  struct string_list *prev;
-  char *data;
-};
-/*}}}*/
-
-struct msg_src {
-  enum {MS_FILE, MS_MBOX} type;
-  char *filename;
-  off_t start;
-  size_t len;
-};
-
-/* Outcomes of checking a filename/dirname to see whether to keep on looking
- * at filenames within this dir. */
-enum traverse_check {
-  TRAV_PROCESS, /* Continue looking at this entry */
-  TRAV_IGNORE,  /* Ignore just this dir entry */
-  TRAV_FINISH   /* Ignore this dir entry and don't bother looking at the rest of the directory */
-};
-
-struct traverse_methods {
-  int (*filter)(const char *, const struct stat *);
-  enum traverse_check (*scrutinize)(int, const char *);
-};
-
-extern struct traverse_methods maildir_traverse_methods;
-extern struct traverse_methods mh_traverse_methods;
-extern struct traverse_methods mbox_traverse_methods;
-
-extern int verbose; /* cmd line -v switch */
-extern int do_hardlinks; /* cmd line -H switch */
-extern int do_movefiles; /* cmd line -M switch */
-
-/* Lame fix for systems where NAME_MAX isn't defined after including the above
- * set of .h files (Solaris, FreeBSD so far).  Probably grossly oversized but
- * it'll do. */
-
-#if !defined(NAME_MAX)
-#define NAME_MAX 4096
-#endif
-
-/* In glob.c */
-struct globber;
-struct globber_array;
-
-struct globber *make_globber(const char *wildstring);
-void free_globber(struct globber *old);
-int is_glob_match(struct globber *g, const char *s);
-struct globber_array *colon_sep_string_to_globber_array(const char *in);
-int is_globber_array_match(struct globber_array *ga, const char *s);
-void free_globber_array(struct globber_array *in);
-
-/* In hash.c */
-unsigned int hashfn( unsigned char *k, unsigned int length, unsigned int initval);
-
-/* In dirscan.c */
-struct msgpath_array *new_msgpath_array(void);
-int valid_mh_filename_p(const char *x);
-void free_msgpath_array(struct msgpath_array *x);
-void string_list_to_array(struct string_list *list, int *n, char ***arr);
-void split_on_colons(const char *str, int *n, char ***arr);
-void build_message_list(char *folder_base, char *folders, enum folder_type ft,
-    struct msgpath_array *msgs, struct globber_array *omit_globs);
-
-/* In rfc822.c */
-struct rfc822 *make_rfc822(char *filename);
-void free_rfc822(struct rfc822 *msg);
-enum data_to_rfc822_error {
-  DTR8_OK,
-  DTR8_MISSING_END, /* missing endpoint marker. */
-  DTR8_MULTIPART_SANS_BOUNDARY, /* multipart with no boundary string defined */
-  DTR8_BAD_HEADERS, /* corrupt headers */
-  DTR8_BAD_ATTACHMENT /* corrupt attachment (e.g. no body part) */
-};
-struct rfc822 *data_to_rfc822(struct msg_src *src, char *data, int length, enum data_to_rfc822_error *error);
-void create_ro_mapping(const char *filename, unsigned char **data, int *len);
-void free_ro_mapping(unsigned char *data, int len);
-char *format_msg_src(struct msg_src *src);
-
-/* In tok.c */
-struct toktable *new_toktable(void);
-struct toktable2 *new_toktable2(void);
-void free_token(struct token *x);
-void free_token2(struct token2 *x);
-void free_toktable(struct toktable *x);
-void free_toktable2(struct toktable2 *x);
-void add_token_in_file(int file_index, unsigned int hash_key, char *tok_text, struct toktable *table);
-void check_and_enlarge_encoding(struct matches *m);
-void insert_index_on_encoding(struct matches *m, int idx);
-void add_token2_in_file(int file_index, unsigned int hash_key, char *tok_text, struct toktable2 *table, int add_to_chain1);
-
-/* In db.c */
-#define CREATE_RANDOM_DATABASE_HASH 0
-struct database *new_database(unsigned int hash_key);
-struct database *new_database_from_file(char *db_filename, int do_integrity_checks);
-void free_database(struct database *db);
-void maybe_grow_message_arrays(struct database *db);
-void tokenise_message(int file_index, struct database *db, struct rfc822 *msg);
-int update_database(struct database *db, struct msgpath *sorted_paths, int n_paths, int do_fast_index);
-void check_database_integrity(struct database *db);
-int cull_dead_messages(struct database *db, int do_integrity_checks);
-
-/* In mbox.c */
-void build_mbox_lists(struct database *db, const char *folder_base,
-    const char *mboxen_paths, struct globber_array *omit_globs);
-int add_mbox_messages(struct database *db);
-void compute_checksum(const char *data, size_t len, checksum_t *csum);
-void cull_dead_mboxen(struct database *db);
-unsigned int encode_mbox_indices(unsigned int mb, unsigned int msg);
-void decode_mbox_indices(unsigned int index, unsigned int *mb, unsigned int *msg);
-int verify_mbox_size_constraints(struct database *db);
-void glob_and_expand_paths(const char *folder_base, char **paths_in, int n_in, char ***paths_out, int *n_out, const struct traverse_methods *methods, struct globber_array *omit_globs);
-
-/* In glob.c */
-struct globber;
-
-struct globber *make_globber(const char *wildstring);
-void free_globber(struct globber *old);
-int is_glob_match(struct globber *g, const char *s);
-
-/* In writer.c */
-void write_database(struct database *db, char *filename, int do_integrity_checks);
-
-/* In search.c */
-int search_top(int do_threads, int do_augment, char *database_path, char *complete_mfolder, char **argv, enum folder_type ft, int verbose);
-
-/* In stats.c */
-void get_db_stats(struct database *db);
-
-/* In dates.c */
-int scan_date_string(char *in, time_t *start, int *has_start, time_t *end, int *has_end);
-
-/* In dumper.c */
-void dump_database(char *filename);
-
-/* In strexpand.c */
-char *expand_string(const char *p);
-
-/* In dotlock.c */
-void lock_database(char *path, int forced_unlock);
-void unlock_database(void);
-void unlock_and_exit(int code);
-
-/* In mairix.c */
-void report_error(const char *str, const char *filename);
-
-#endif /* MAIRIX_H */
diff --git a/src/mairix/ACKNOWLEDGEMENTS b/src/mairix/ACKNOWLEDGEMENTS
@@ -1,60 +0,0 @@
-These people have contributed useful patches, ideas and suggestions:
-
-Anand Kumria
-André Costa
-Andreas Amann
-Andre Costa
-Aredridel
-Balázs Szabó
-Bardur Arantsson
-Benj. Mako Hill
-Chris Mason
-Christoph Dworzak
-Christopher Rosado
-Chung-chieh Shan
-Claus Alboege
-Corrin Lakeland
-Dan Egnor
-Daniel Jacobowitz
-Dirk Huebner
-Ed Blackman
-Emil Sit
-Felipe Gustavo de Almeida
-Ico Doornekamp
-Jaime Velasco Juan
-James Leifer
-Jerry Jorgenson
-Joerg Desch
-Johannes Schindelin
-Johannes Weißl
-John Arthur Kane
-John Keener
-Jonathan Kamens
-Josh Purinton
-Karsten Petersen
-Kevin Rosenberg
-Mark Hills
-Martin Danielsson
-Matthias Teege
-Mikael Ylikoski
-Mika Fischer
-Oliver Braun
-Paramjit Oberoi
-Paul Fox
-Peter Chines
-Peter Jeremy
-Robert Hofer
-Roberto Boati
-Samuel Tardieu
-Sanjoy Mahajan
-Satyaki Das
-Steven Lumos
-Tim Harder
-Tom Doherty
-Vincent Lefevre
-Vladimir V. Kisil
-Will Yardley
-Wolfgang Weisselberg
-
-I apologise to any contributors who have been omitted from this list!
-
diff --git a/src/mairix/COPYING b/src/mairix/COPYING
@@ -1,339 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/src/mairix/INSTALL b/src/mairix/INSTALL
@@ -1,22 +0,0 @@
-Installation of mairix goes as follows:
-
-./configure
-make
-make install
-
-You need to be root to run the final step unless you're installing under your
-own home directory somewhere.
-
-However, you might want to tune the options further.  The configure script
-shares its common options with the usual autoconf-generated scripts, even
-though it's not autoconf-generated itself.  For example, a fuller build could
-use
-
-CC=gcc CFLAGS="-O2 -Wall" ./configure \
-    --prefix=/opt/mairix \
-    --infodir=/usr/share/info
-make
-make install
-
-The final step is to create a ~/.mairixrc file.  An example is included in the
-file dotmairixrc.eg.  Just copy that to ~/.mairixrc and edit it.
diff --git a/src/mairix/Makefile.in b/src/mairix/Makefile.in
@@ -1,114 +0,0 @@
-#########################################################################
-#
-# mairix - message index builder and finder for maildir folders.
-#
-# Copyright (C) Richard P. Curnow  2002-2004,2006
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-# 
-# 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.
-#
-# =======================================================================
-
-#########################################################################
-# Edit the following variables as required
-CC=@cc@
-CFLAGS=@cflags@ @defs@
-CPPFLAGS=@CPPFLAGS@
-LDFLAGS=@LDFLAGS@
-LIBS=@LIBS@
-
-#######################################################################
-# If you're generating a package, you may want to use
-# 	make DESTDIR=temporary_dir install
-# to get the software installed to a directory where you can create
-# a tdl.tar.gz from it
-DESTDIR=
-
-#######################################################################
-
-prefix=$(DESTDIR)@prefix@
-bindir=$(DESTDIR)@bindir@
-mandir=$(DESTDIR)@mandir@
-man1dir=$(mandir)/man1
-man5dir=$(mandir)/man5
-infodir=$(DESTDIR)@infodir@
-docdir=$(DESTDIR)@docdir@
-
-#########################################################################
-# Things below this point shouldn't need to be edited.
-
-OBJ = mairix.o db.o rfc822.o tok.o hash.o dirscan.o writer.o \
-      reader.o search.o stats.o dates.o datescan.o mbox.o md5.o \
-  	  fromcheck.o glob.o dumper.o expandstr.o dotlock.o \
-			nvp.o nvpscan.o
-
-all : mairix
-
-mairix : $(OBJ)
-	$(CC) -o mairix $(CFLAGS) $(LDFLAGS) $(OBJ) $(LIBS)
-
-%.o : %.c memmac.h mairix.h reader.h Makefile
-	$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
-
-datescan.c datescan.h : datescan.nfa ./dfasyn/dfasyn
-	./dfasyn/dfasyn -o datescan.c -ho datescan.h -r datescan.report -u datescan.nfa
-
-fromcheck.c fromcheck.h : fromcheck.nfa ./dfasyn/dfasyn
-	./dfasyn/dfasyn -o fromcheck.c -ho fromcheck.h -r fromcheck.report -u fromcheck.nfa
-
-nvpscan.c nvpscan.h : nvp.nfa ./dfasyn/dfasyn
-	./dfasyn/dfasyn -o nvpscan.c -ho nvpscan.h -r nvpscan.report -u nvp.nfa
-
-dates.o : datescan.h
-mbox.o : fromcheck.h
-nvp.o : nvpscan.h
-
-version.h:
-	./mkversion
-
-./dfasyn/dfasyn:
-	if [ -d dfasyn ]; then cd dfasyn ; $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" ; else echo "No dfasyn subdirectory?" ; exit 1 ; fi
-
-clean:
-	-rm -f *~ *.o mairix *.s core
-	-rm -f mairix.cp mairix.fn mairix.aux mairix.log mairix.ky mairix.pg mairix.toc mairix.tp mairix.vr
-	-rm -f fromcheck.[ch] datescan.[ch]
-	-rm -f nvpscan.[ch]
-	if [ -d dfasyn ]; then cd dfasyn ; $(MAKE) clean ; fi
-	if [ -d test ]; then cd test ; $(MAKE) clean ; fi
-
-distclean: clean
-	if [ -d test ]; then cd test ; $(MAKE) distclean ; fi
-	-rm -f Makefile config.log
-
-install:
-	[ -d $(prefix) ] || mkdir -p $(prefix)
-	[ -d $(bindir) ] || mkdir -p $(bindir)
-	[ -d $(mandir) ] || mkdir -p $(mandir)
-	[ -d $(man1dir) ] || mkdir -p $(man1dir)
-	[ -d $(man5dir) ] || mkdir -p $(man5dir)
-	cp -f mairix $(bindir)
-	chmod 555 $(bindir)/mairix
-	cp -f mairix.1 $(man1dir)
-	chmod 444 $(man1dir)/mairix.1
-	cp -f mairixrc.5 $(man5dir)
-	chmod 444 $(man5dir)/mairixrc.5
-
-check: mairix
-	if [ -d test ]; then cd test ; $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" check ; else echo "No test subdirectory?" ; exit 1 ; fi
-
-.PHONY : all install clean distclean check
-
-mairix.o : version.h
-
-
diff --git a/src/mairix/NEWS b/src/mairix/NEWS
@@ -1,317 +0,0 @@
-NEW IN VERSION 0.23
-===================
-* Allow '=' in message-id search for RFC2822 conformance
-* Add the option -H to force hardlinks
-* Skip .gitignore files
-* Do not interpret special characters [~,/=^] in Message-ID queries
-* Fix faultly mbox message separators
-* Improve reporting of unparsed MIME headers & remove code duplication
-* Allow empty sections in MIME headers
-* Add support for uuencoded attachments
-* Improve the parsing of MIME boundaries
-* Fix SEGV if mbox shrinks
-* Add test suite
-* Fix building in parallel
-
-NEW IN VERSION 0.22
-===================
-
-* Skip symlinks when using mbox (R A Lichtensteiger)
-* Update copyright year info throughout
-* Update ACKNOWLEDGEMENTS and copyright headers where more credit was due
-* Update FSF address in file headers
-* Update COPYING to latest gpl-2.0.txt
-* Improve error message if home directory cannot be determined
-* Honour HOME environment variable (Andreas Amann)
-* MIME types are allowed to have "+" characters in them. (Jonathan Kamens)
-* Fix deficiencies in the parsing of mbox From lines (Jonathan Kamens)
-* Include the existing -x flag in the help message (Mark Hills)
-* Fix documentation nits (Tom Doherty)
-* Remove spurious message when the mtime of a message file has changed
-* Do not export functions already exported through a callback structure. (Samuel Tardieu)
-* Fix two manpages buglets. (Samuel Tardieu)
-* When freeing a struct nvp, do not forget to free the struct nvp_entry. (Samuel Tardieu)
-* Do not leak memory if duplicate fields are present. (Samuel Tardieu)
-* Initialize the date header with a known value. (Samuel Tardieu)
-* Merge two conflicting solutions for bad MIME encoding
-* Fix segfault when last char is not a newline (Mika Fischer)
-* fix for MIME-related crash (Paramjit Oberoi)
-* Add support claws-mail (Anand Kumria)
-* Add MH sub-type support for ezmlm-archives (Claus Alboege)
-* Detect a trailing -f or -o with no following argument
-* Allow lines starting "From" to occur part-way through the header.o
-* Display message-ID in search -x mode
-* Remove execute permission from source files
-* Handle mbox from separators where email address is in angle brackets
-* Fix a bug in rfc822.c: Some headers weren't correctly parsed. (Jaime Velasco Juan)
-
-NEW IN VERSION 0.21
-===================
-
-* Fix make clean target in dfasyn/ (Benj. Mako Hill)
-* Limit number of messages that are examined when an end boundary is missing in
-  an mbox (Chung-chieh Shan)
-* Avoid examining . and .. when traversing MH folder hierarchy (Steven Lumos)
-* Fix various bugs in the name/value parser
-* Add some RFC2231 support to the name/value parser (continuations)
-* Fix indexing when existing database only contains 1 message
-
-NEW IN VERSION 0.20
-===================
-
-* Cache uncompressed mbox data (Chris Mason, further work by me)
-* Fix gaps in date ranges for search
-* Unlock database if mairix is interrupted (Paul Fox)
-* Add fast index option (-F)
-* Fix conditional compilation errors for compressed mbox
-* Reimplement MIME header parsing
-* Add capability to search on names of attachments
-* Add capability to search on state of message flags
-* Create maildir-format mfolder filenames correctly with regard to flags
-* Various bug fixes (Oliver Braun, Matthias Teege)
-
-
-NEW IN VERSION 0.19
-===================
-* mairix.spec fixes (André Costa)
-* bug fix: freeing of message structures (Karsten Petersen)
-* Add new -x (--excerpt-output) option, an alternative mode for searching.
-  This displays the key headers from the matching messages on stdout.
-* Add notes about the mairix-users mailing list and the SourceForge page to
-  README.
-* Fix configuration + compilation to allow building with gzip support but
-  without bzlib support.
-* Rename internal functions like zopen() to avoid name conflicts on MacOS X.
-  (Vincent Lefevre)
-* Remove a spurious ; in bison input file (Vincent Lefevre)
-* Improve output given in various error conditions (based on patch by Karsten
-  Petersen)
-
-NEW IN VERSION 0.18
-===================
-
-* Support bzip2'd mbox folders
-* Fix bugs in parsing mbox folders containing unquoted 'From ' lines inside
-  MIME body parts
-* Fix bug in parsing content-type data containing quotes with whitespace
-  before
-* Clone the message flags (when both the source folder and mfolder are both
-  of maildir type)
-* New manpages mairix.1 and mairixrc.5 are included, and the old texinfo-based
-  documentation is deprecated into the old_docs/ directory.
-* Upgrade scanners to new version of dfasyn
-* Support Mew's MH folder subtype
-
-
-NEW IN VERSION 0.17.1
-=====================
-
-* Fix detection of MH folder subtype used by nnml (Gnus)
-* Fix filename format generated in the /cur/ directory for maildir mfolders.
-* Syntax fix in configure script
-
-NEW IN VERSION 0.17
-===================
-
-* Support gzipped mbox folders (any file matched by a mbox= line in the config
-  file is considered as a gzipped mbox if its name ends in .gz)
-* Rework directory traversal for the '...' construct to speed up indexing and
-  the check that mfolder isn't going to overwrite a real folder when searching.
-* Check whether database exists before attempting to do searching.
-* Matched new maildir messages go in /new/ subdirectory of maildir mfolder.
-* Fix lots of compiler warnings generated by gcc4.x
-* Don't create and immediately scrub database entries for empty mbox folders.
-* Fix usage() info for bare word in searching
-* Allow '.' on the ends of numeric filenames in MH folders (to work
-  with Evolution)
-* Update .PHONY target so that 'make install' etc are more reliable.
-* Add X-source-folder header to indicate the original folder of a match found
-  in an mbox.
-* Migration to git for revision control.
-
-NEW IN VERSION 0.16.1
-=====================
-
-* Remove the lockfile if the program terminates for any reason.
-
-NEW IN VERSION 0.16
-===================
-
-* Home directory (~) and environment variable ($foo / ${foo}) expansion in the
-  .mairixrc file
-* Add -Q flag to skip database integrity checks during indexing (equivalently
-  the nochecks option in .mairixrc file).  This speeds up indexing but loses
-  some robustness.
-* Add ^ word prefix to require substring search to be left-anchored
-* Split 'make clean' into separate clean and clean_docs
-* Improve some error messages
-* Add online help entries for -o and -d
-* Don't write out the database if there are no changes found during indexing.
-* Fix stale information about the 'and' and 'or' delimiters in the online help.
-* Add the capability to omit particular folders from indexing (omit keyword in
-  .mairixrc file.)  This allows broad wildcards to be used with selected
-  folders removed from the wildcard which is much more convenient in many
-  set-ups.
-* Avoid writing matches to any folder on the list of folders to be indexed
-  (affects both mfolder option and argument of -o command line switch.)  This
-  prevents disasterous loss of messages in the event of trying to overwrite an
-  wanted folder with the matches.
-* Implement dot-locking on the database file to prevent corruption due to
-  concurrent updates.  Add --unlock file to forcibly remove a stray lockfile.
-* Display message path in warning messages from rfc822 parsing.
-
-NEW IN VERSION 0.15
-===================
-
-* Migrate to GNU Arch for hosting the development archive
-* In mbox parsing, handle return path in 'From ' line only being a local part
-  (reported by several people)
-* Don't output number of matched messages in raw mode (to make output more
-  useful to scripts etc) (Samuel Tardieu)
-* Fix vfolder->mfolder in dotmairixrc.eg (reported by several people)
-* Handle spaces in multipart message boundary strings (Chung-chieh Shan)
-* Be more tolerant of bad multipart message boundary separators (Chung-chieh
-  Shan)
-* Add rudimentary database dump command (-d/--dump)
-* Fix bug in handling of per-database hash key
-* Improve standards-compliance of maildir output file names (Jeff King)
-* Remove most compiler warnings
-
-NEW IN VERSION 0.14.1
-=====================
-
-* Bug fix : splitting of messages in mboxes was too strict regarding whitespace
-
-NEW IN VERSION 0.14
-===================
-
-* Fix error in path (p:) searching for messages in mboxes.
-* Improve usage() function
-
-NEW IN VERSION 0.13
-===================
-
-* Fixes to support the mbox format used by Mozilla mail
-* When creating vfolder directories for maildir/mh, remove existing
-  non-directory at the same path, if present.  When creating mbox vfolder file,
-  complain if there's already a directory at the same path and exit.
-* Switch from the term "virtual folder" to "match folder"
-* Fix bug in path matches (p:) containing upper-case letters - previously they
-  matched on corresponding all lower-case paths.
-
-NEW IN VERSION 0.12
-===================
-
-! Change in database file format - existing databases need to be destroyed and
-  recreated.
-
-* Indexing of mbox folders in addition to the existing maildir & MH support
-* Output to mbox format vfolder
-* Return exit status 1 if no messages are matched in search mode, and exit
-  status 2 for all error conditions.
-* Allow wildcards to be used in specifying maildir and mh folder paths.
-* Searching on messages having a particular Message-ID (m:msgid expression in
-  search mode).
-* When indexing whole email addresses, '+' is now considered a valid character.
-* Use ',' instead of '+' in search expressions, and '/' instead of ','.  This
-  is to allow '+' to be used inside email addresses that are being searched
-  for.  The '/' character is traditionally associated with meaning 'or', so it
-  made more sense to move ',' to mean 'and'.  (Unfortunately, there were very
-  few metacharacters left which don't have some special meaning to shells, and
-  I wanted to avoid the need to quote or escape the search expressions.)
-* Bug fix checking return status of mmap.
-* Handle ">From " at the start of the message headers
-* Handle mis-formatted encoding strings "7 bit" and "8 bit"
-* Make every database use a random seed for the token hash function (to prevent
-  denial of service attacks against mairix through carefully crafted messages.)
-* Rename some options in the mairixrc file, to put the folder formats on an
-  equal footing.
-* Properly handle the case where a maildir vfolder exists but one or more of
-  the new,tmp,cur subdirectories is missing.
-* Add configure script (not autoconf-based)
-
-NEW IN VERSION 0.11
-===================
-
-* Detect failed malloc (out of memory) conditions properly and report it.
-* Improved date specification syntax for d: option
-* Allow vfolder to be an absolute path or relative to current directory,
-  instead of just relative to base directory.
-
-NEW IN VERSION 0.10
-===================
-
-* Add 'raw' mode for searching.
-* When purging, only print the pass[12] message in verbose mode
-* Add an ACKNOWLEDGEMENTS file.
-* Hack to handle missing NAME_MAX on various non-Linux systems
-* Improve mairix.spec file for RPM building
-* Change default value for prefix in Makefile to make it more standard.
-
-NEW IN VERSION 0.9
-==================
-
-* Fix problem with auditing headers if a uucp/mbox-style "from " header is
-  present at the start.
-* Allow \: sequence in folder names to specify a :
-
-NEW IN VERSION 0.8
-==================
-
-* Fix bug : mairix used to crash if a message had corrupted RFC822 header lines
-
-NEW IN VERSION 0.7
-==================
-
-* Fix bug : mairix likely to crash if a non-existant folder is listed in the
-  conf file.
-* Allow multiple folders and mh_folders lines in the conf file for people who
-  have many separate folders.
-* Print an extra 'comfort' message in verbose mode before starting to scan the
-  directory tree.
-
-NEW IN VERSION 0.6
-==================
-
-* When an unrecognized encoding is found, ignore the body part instead of
-  aborting the run.
-
-NEW IN VERSION 0.5
-==================
-
-* When -a option is used for search, avoid symlinking the same message twice if
-  it matches more than one query.
-* Fixes to rpm spec file.
-* Fix handling of = in base64-encoded attachments.
-* Support non POSIX locales.
-* Support rfc2047 encoding in headers.
-* Create vfolder if it doesn't already exist.
-* Allow searching on complete email addresses as well as individual words in
-  to, cc and from fields.
-* New -o option to allow vfolder name to be given on the command line.
-
-NEW IN VERSION 0.4
-==================
-
-* Support for MH folders
-* Create database with mode 0600 instead of 0644 (better security).
-* Add Makefile target to install whichever forms of the documentation have been
-  built.
-
-NEW IN VERSION 0.3
-==================
-
-* Various bug fixes
-
-NEW IN VERSION 0.2
-==================
-
-* Substrings of message paths can be used as search expressions (p:substring
-  option)
-* = now used instead of / as the delimiter for number of errors in an
-  approximate match (to help with path search)
-* Bug fix when using -t mode for search with unpurged dead messages still in
-  the database.
-
-==================
-# vim:comments-=mb\:*:comments+=fb\:*
diff --git a/src/mairix/README b/src/mairix/README
@@ -1,63 +0,0 @@
-mairix is a program for indexing and searching email messages stored in
-Maildir, MH or mbox folders.
-
-* Indexing is fast.  It runs incrementally on new messages - any particular
-  message only gets scanned once in the lifetime of the index file.
-
-* The search mode populates a "virtual" folder with symlinks(*) which
-  point to the real messages.  This folder can be opened as usual in your mail
-  program.
-
-* The search mode is very fast.
-
-* Indexing and searching works on the basis of words.  The index file tabulates
-  which words occur in which parts (particular headers + body) of which
-  messages.
-
-The program is a very useful complement to mail programs like mutt
-(http://www.mutt.org/, which supports Maildir, MH and mbox folders) and
-Sylpheed (which supports MH folders).
-
-[(*) where the input or output folder is an mbox, a copy of the message is made
-instead of symlinking.]
-
-See also the mairix.txt file.
-
-*********************************************************************
- Copyright (C) Richard P. Curnow  2002-2004
- 
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License as
- published by the Free Software Foundation.
- 
- 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.
- 
-*********************************************************************
-
-Suggestions, bug reports, experiences, praise, complaints etc to the author
-please, at <rc@rc0.org.uk>
-
-Since July 2006, there is a mairix-users mailing list.  To subscribe or to view
-the archives, visit
-
-   https://lists.sourceforge.net/lists/listinfo/mairix-users 
-
-The main website for mairix is
-
-   http://www.rc0.org.uk/mairix
-
-The SourceForge project page is
-
-   http://www.sf.net/projects/mairix
-
-ACKNOWLEDGEMENTS
-================
-
-See the ACKNOWLEDGEMENTS file
diff --git a/src/mairix/configure b/src/mairix/configure
@@ -1,337 +0,0 @@
-#!/bin/sh
-#########################################################################
-#
-# mairix - message index builder and finder for maildir folders.
-#
-# Copyright (C) Richard P. Curnow  2003,2004,2005
-# Copyright (C) Paramjit Oberoi 2005
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-# 
-# 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 [ -f config.log ]; then rm -f config.log ; fi
-exec 5>config.log
-
-MYCC=${CC:-gcc}
-MYCFLAGS=${CFLAGS:--O2 -Wall}
-MYCPPFLAGS=${CPPFLAGS:-}
-MYLDFLAGS=${LDFLAGS:-}
-
-# =======================================================================
-# Functions
-
-#{{{ cleanup
-cleanup () {
-  if [ -f docheck.c ]; then rm -f docheck.c ; fi
-  if [ -f docheck.o ]; then rm -f docheck.o ; fi
-  if [ -f docheck   ]; then rm -f docheck   ; fi
-  rm -rf docheck.c docheck.o docheck
-}
-#}}}
-
-#{{{ test_cc : basic compiler sanity check
-test_cc () {
-  printf "Testing whether your compiler \"$MYCC $MYCFLAGS\" works : "
-  cat >docheck.c <<EOF;
-#include <stdio.h>
-int main (int argc, char **argv)
-{
-  return 0;
-}
-EOF
-  ${MYCC} ${MYCFLAGS} -o docheck docheck.c 1>&5 2>&5
-  if [ $? -eq 0 ]
-  then
-    printf "it works\n"
-  else
-    printf "it doesn't work\n"
-    printf "Failed program was\n" 1>&5
-    cat docheck.c 1>&5
-    rm -f docheck.c docheck
-    exit 1
-  fi
-  cleanup
-}
-#}}}
-
-#{{{ test_for_stdint_h
-test_for_stdint_h () {
-  cat >docheck.c <<EOF;
-#include <stdint.h>
-int main(int argc, char **argv) {
-  return 0;
-}
-EOF
-
-  ${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
-  if [ $? -eq 0 ]
-  then
-    result=0
-  else
-    result=1
-  fi
-
-  rm -f docheck.c docheck.o
-  echo $result
-}
-#}}}
-#{{{ test_for_inttypes_h
-test_for_inttypes_h () {
-  cat >docheck.c <<EOF;
-#include <inttypes.h>
-int main(int argc, char **argv) {
-  return 0;
-}
-EOF
-
-  ${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
-  if [ $? -eq 0 ]
-  then
-    result=0
-  else
-    result=1
-  fi
-
-  rm -f docheck.c docheck.o
-  echo $result
-}
-#}}}
-#{{{ test_for_zlib
-test_for_zlib () {
-  cat > docheck.c <<EOF;
-#include <zlib.h>
-int main () {
-  const char *foo;
-  foo = zlibVersion();
-  return 0;
-}
-EOF
-  echo "Test program is" 1>&5
-  cat docheck.c 1>&5
-  ${MYCC} ${MYCPPFLAGS} ${MYCFLAGS} ${MYLDFLAGS} -o docheck docheck.c -lz 1>&5 2>&1
-  if [ $? -eq 0 ]
-  then
-    result=0
-  else
-    result=1
-  fi
-  rm -f docheck.c docheck
-  echo $result
-}
-#}}}
-#{{{ test_for_bzlib
-test_for_bzlib () {
-  cat > docheck.c <<EOF;
-#include <bzlib.h>
-int main () {
-  const char *foo;
-  foo = BZ2_bzlibVersion();
-  return 0;
-}
-EOF
-  echo "Test program is" 1>&5
-  cat docheck.c 1>&5
-  ${MYCC} ${MYCPPFLAGS} ${MYCFLAGS} ${MYLDFLAGS} -o docheck docheck.c -lbz2 1>&5 2>&1
-  if [ $? -eq 0 ]
-  then
-    result=0
-  else
-    result=1
-  fi
-  rm -f docheck.c docheck
-  echo $result
-}
-#}}}
-#{{{ usage
-usage () {
-  cat <<EOF;
-\`configure' configures tdl to adapt to many kinds of systems.
-
-Usage: ./configure [OPTION]...
-
-Defaults for the options are specified in brackets.
-
-Configuration:
-  -h, --help              display this help and exit
-
-Installation directories:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-                          [/usr/local]
-
-By default, \`make install' will install all the files in
-\`/usr/local/bin', \`/usr/local/lib' etc.  You can specify
-an installation prefix other than \`/usr/local' using \`--prefix',
-for instance \`--prefix=$HOME'.
-
-Fine tuning of the installation directories:
-  --bindir=DIR           user executables [EPREFIX/bin]
-  --infodir=DIR          info documentation [PREFIX/info]
-  --mandir=DIR           man documentation [PREFIX/man]
-  --docdir=DIR           other documentation [PREFIX/doc/mairix-\$version]
-
-Other options:
-  --enable-gzip-mbox     attempt to support gzipped mboxes (requires zlib)
-  --disable-gzip-mbox    don't attempt to support gzipped mboxes
-  --enable-bzip-mbox     attempt to support bzip2ed mboxes (requires bzlib)
-  --disable-bzip-mbox    don't attempt to support bzip2ed mboxes
-
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  CPPFLAGS    Extra C preprocessor flags, e.g. -I<include dir> if you
-              have header files in a nonstandard directory <include dir>
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-
-Use these variables to override the choices made by \`configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to <rc@rc0.org.uk>.
-EOF
-}
-#}}}
-# =======================================================================
-
-# Defaults for variables
-PREFIX=/usr/local
-
-use_readline=yes
-bad_options=no
-use_gzip_mbox=yes
-use_bzip_mbox=yes
-
-# Parse options to configure
-for option
-do
-	case "$option" in
-
-  --prefix=* | --install-prefix=* )
-    PREFIX=`echo $option | sed -e 's/[^=]*=//;'`
-    ;;
-  --bindir=* )
-    BINDIR=`echo $option | sed -e 's/[^=]*=//;'`
-    ;;
-  --mandir=* )
-    MANDIR=`echo $option | sed -e 's/[^=]*=//;'`
-    ;;
-  --infodir=* )
-    INFODIR=`echo $option | sed -e 's/[^=]*=//;'`
-    ;;
-  --docdir=* )
-    DOCDIR=`echo $option | sed -e 's/[^=]*=//;'`
-    ;;
-  --enable-gzip-mbox )
-    use_gzip_mbox=yes
-    ;;
-  --disable-gzip-mbox )
-    use_gzip_mbox=no
-    ;;
-  --enable-bzip-mbox )
-    use_bzip_mbox=yes
-    ;;
-  --disable-bzip-mbox )
-    use_bzip_mbox=no
-    ;;
-  -h | --help )
-    usage
-    exit 1
-    ;;
-  * )
-    printf "Unrecognized option : $option\n"
-    bad_options=yes
-    ;;
-  esac
-done
-
-if [ ${bad_options} = yes ]; then
-  exit 1
-fi
-
-DEFS=""
-test_cc
-
-printf "Checking for <stdint.h> : "
-if [ `test_for_stdint_h` -eq 0 ]; then
-  printf "Yes\n"
-  DEFS="${DEFS} -DHAS_STDINT_H"
-else
-  printf "No\n"
-fi
-
-printf "Checking for <inttypes.h> : "
-if [ `test_for_inttypes_h` -eq 0 ]; then
-  printf "Yes\n"
-  DEFS="${DEFS} -DHAS_INTTYPES_H"
-else
-  printf "No\n"
-fi
-
-if [ $use_gzip_mbox = "yes" ]; then
-  printf "Checking for zlib : "
-  if [ `test_for_zlib` -eq 0 ]; then
-    printf "Yes\n";
-    DEFS="${DEFS} -DUSE_GZIP_MBOX"
-    LIBS="-lz"
-  else
-    printf "No (disabled gzipped mbox support)\n";
-  fi
-fi
-
-if [ $use_bzip_mbox = "yes" ]; then
-  printf "Checking for bzlib : "
-  if [ `test_for_bzlib` -eq 0 ]; then
-    printf "Yes\n";
-    DEFS="${DEFS} -DUSE_BZIP_MBOX"
-    LIBS="${LIBS} -lbz2"
-  else
-    printf "No (disabled bzip2ed mbox support)\n";
-  fi
-fi
-
-#{{{ Determine version number of the program.
-if [ -f version.txt ]; then
-	revision=`cat version.txt`
-else
-	revision="DEVELOPMENT"
-fi
-
-#}}}
-if [ "x" = "x${BINDIR}" ]; then BINDIR=${PREFIX}/bin ; fi
-if [ "x" = "x${MANDIR}" ]; then MANDIR=${PREFIX}/man ; fi
-if [ "x" = "x${INFODIR}" ]; then INFODIR=${PREFIX}/info ; fi
-if [ "x" = "x${DOCDIR}" ]; then DOCDIR=${PREFIX}/doc/mairix-${revision} ; fi
-
-echo "Generating Makefile"
-
-rm -f Makefile
-sed -e "s%@cc@%${MYCC}%; \
-        s%@defs@%${DEFS}%; \
-        s%@cflags@%${MYCFLAGS}%; \
-        s%@prefix@%${PREFIX}%; \
-        s%@bindir@%${BINDIR}%; \
-        s%@mandir@%${MANDIR}%; \
-        s%@infodir@%${INFODIR}%; \
-        s%@docdir@%${DOCDIR}%; \
-        s%@LIBS@%${LIBS}%; \
-        s%@CPPFLAGS@%${MYCPPFLAGS}%; \
-        s%@LDFLAGS@%${MYLDFLAGS}%; \
-       " < Makefile.in > Makefile
-
-# Avoid editing Makefile instead of Makefile.in
-chmod ugo-w Makefile
-
-# =======================================================================
-# vim:et:sw=2:ht=2:sts=2:fdm=marker:cms=#%s
-
diff --git a/src/mairix/dates.c b/src/mairix/dates.c
@@ -1,404 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002-2004,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <ctype.h>
-#include <assert.h>
-#include "mairix.h"
-#include "dates.h"
-#include "datescan.h"
-
-static enum DATESCAN_TYPE discover_type(char *first, char *last)/*{{{*/
-{
-  int current_state = 0;
-  int token;
-  char *p;
-  p = first;
-  while (p < last) {
-    token = datescan_char2tok[(int)*(unsigned char*)p];
-    current_state = datescan_next_state(current_state, token);
-    if (current_state < 0) break;
-    p++;
-  }
-
-  if (current_state < 0) {
-    return DS_FAILURE;
-  } else {
-    return datescan_attr[current_state];
-  }
-}
-/*}}}*/
-static int match_month(char *p)/*{{{*/
-{
-  if (!strncasecmp(p, "jan", 3)) return 1;
-  if (!strncasecmp(p, "feb", 3)) return 2;
-  if (!strncasecmp(p, "mar", 3)) return 3;
-  if (!strncasecmp(p, "apr", 3)) return 4;
-  if (!strncasecmp(p, "may", 3)) return 5;
-  if (!strncasecmp(p, "jun", 3)) return 6;
-  if (!strncasecmp(p, "jul", 3)) return 7;
-  if (!strncasecmp(p, "aug", 3)) return 8;
-  if (!strncasecmp(p, "sep", 3)) return 9;
-  if (!strncasecmp(p, "oct", 3)) return 10;
-  if (!strncasecmp(p, "nov", 3)) return 11;
-  if (!strncasecmp(p, "dec", 3)) return 12;
-  return 0;
-}
-/*}}}*/
-static int year_fix(int y)/*{{{*/
-{
-  if (y>100) {
-    return y-1900;
-  } else if (y < 70) {
-    /* 2000-2069 */
-    return y+100;
-  } else {
-    /* 1970-1999 */
-    return y;
-  }
-}
-/*}}}*/
-static int last_day(int mon, int y) {/*{{{*/
-  /* mon in [0,11], y=year-1900 */
-
-  static unsigned char days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
-  if (mon != 1) {
-    return days[mon];
-  } else {
-    /* Because 2000 was a leap year, we don't have to bother about the %100
-     * rule, at least not in this range of dates. */
-    if ((y % 4) == 0) {
-      return 29;
-    } else {
-      return 28;
-    }
-  }
-}
-/*}}}*/
-static void set_day(struct tm *x, int y)/*{{{*/
-{
-  if (y > x->tm_mday) {
-    /* Shorthand for that day in previous month */
-    if (x->tm_mon == 0) {
-      x->tm_mon = 11;
-      --x->tm_year;
-    } else {
-      --x->tm_mon;
-    }
-  }
-  x->tm_mday = y; /* Always */
-}
-/*}}}*/
-static int is_later_dm(struct tm *x, int m, int d)/*{{{*/
-{
-  int m1 = m-1;
-  return ((x->tm_mon < m1) || ((x->tm_mon == m1) && (x->tm_mday < d)));
-}
-/*}}}*/
-static int scan_date_expr(char *first, char *last, struct tm *start, struct tm *end)/*{{{*/
-{
-  enum DATESCAN_TYPE type;
-  time_t now;
-
-  time(&now);
-  type = discover_type(first, last);
-
-  if (type == DS_SCALED) {/*{{{*/
-    int v;
-    char *p;
-    time_t then;
-
-    p = first;
-    v = 0;
-    while (isdigit(*p)) {
-      v = (v*10) + (*p - '0');
-      p++;
-    }
-    switch(*p) {
-      case 'd': v *= 86400; break;
-      case 'w': v *= 7*86400; break;
-      case 'm': v *= 30*86400; break;
-      case 'y': v *= 365*86400; break;
-      default:
-        fprintf(stderr, "Unrecognized relative date scaling '%c'\n", *p);
-        return -1;
-    }
-    then = now - v;
-    if (start) {
-      *start = *localtime(&then);
-    }
-    if (end) {
-      *end = *localtime(&then);
-    }/*}}}*/
-  } else if (type == DS_FAILURE) {
-    fputs("Cannot parse date expression [", stderr);
-    fwrite(first, sizeof(char), last-first, stderr);
-    fputs("]\n", stderr);
-    return -1;
-  } else {
-    /* something else */
-    int v1, v3;
-    int m2;   /* decoded month */
-    char *p;
-
-    v1 = v3 = m2 = 0;
-    p = first;
-    while (p < last && isdigit(*p)) {
-      v1 = (v1*10) + (*p - '0');
-      p++;
-    }
-    if (p < last) {
-      m2 = match_month(p);
-      p += 3;
-      if (m2 == 0) {
-        return -1; /* failure */
-      }
-
-    }
-    while (p < last && isdigit(*p)) {
-      v3 = (v3*10) + (*p - '0');
-      p++;
-    }
-    assert(p==last); /* should be true in all cases. */
-
-    switch (type) {
-      case DS_D:/*{{{*/
-        if (start) set_day(start, v1);
-        if (end) set_day(end, v1);
-        break;
-/*}}}*/
-      case DS_Y:/*{{{*/
-        if (start) {
-          start->tm_mday = 1;
-          start->tm_mon  = 0; /* january */
-          start->tm_year = year_fix(v1);
-        }
-        if (end) {
-          end->tm_mday = 31;
-          end->tm_mon  = 11;
-          end->tm_year = year_fix(v1);
-        }
-        break;
-/*}}}*/
-      case DS_YYMMDD:/*{{{*/
-        if (start) {
-          start->tm_mday = v1 % 100;
-          start->tm_mon  = ((v1 / 100) % 100) - 1;
-          start->tm_year = year_fix(v1/10000);
-        }
-        if (end) {
-          end->tm_mday = v1 % 100;
-          end->tm_mon  = ((v1 / 100) % 100) - 1;
-          end->tm_year = year_fix(v1/10000);
-        }
-        break;
-/*}}}*/
-      case DS_M:/*{{{*/
-        if (start) {
-          if (m2-1 > start->tm_mon) --start->tm_year; /* shorthand for previous year */
-          start->tm_mon = m2-1;
-          start->tm_mday = 1;
-        }
-        if (end) {
-          if (m2-1 > end->tm_mon) --end->tm_year; /* shorthand for previous year */
-          end->tm_mon = m2-1;
-          end->tm_mday = last_day(m2-1, end->tm_year);
-        }
-        break;
-/*}}}*/
-      case DS_DM:/*{{{*/
-        if (start) {
-          if (is_later_dm(start, m2, v1)) --start->tm_year; /* shorthand for previous year. */
-          start->tm_mon = m2-1;
-          start->tm_mday = v1;
-        }
-        if (end) {
-          if (is_later_dm(end, m2, v1)) --end->tm_year; /* shorthand for previous year. */
-          end->tm_mon = m2-1;
-          end->tm_mday = v1;
-        }
-        break;
-/*}}}*/
-      case DS_MD:/*{{{*/
-        if (start) {
-          if (is_later_dm(start, m2, v3)) --start->tm_year; /* shorthand for previous year. */
-          start->tm_mon = m2-1;
-          start->tm_mday = v3;
-        }
-        if (end) {
-          if (is_later_dm(end, m2, v3)) --end->tm_year; /* shorthand for previous year. */
-          end->tm_mon = m2-1;
-          end->tm_mday = v3;
-        }
-        break;
-/*}}}*/
-      case DS_DMY:/*{{{*/
-        if (start) {
-          start->tm_mon = m2-1;
-          start->tm_mday = v1;
-          start->tm_year = year_fix(v3);
-        }
-        if (end) {
-          end->tm_mon = m2-1;
-          end->tm_mday = v1;
-          end->tm_year = year_fix(v3);
-        }
-        break;
-/*}}}*/
-      case DS_YMD:/*{{{*/
-        if (start) {
-          start->tm_mon = m2-1;
-          start->tm_mday = v3;
-          start->tm_year = year_fix(v1);
-        }
-        if (end) {
-          end->tm_mon = m2-1;
-          end->tm_mday = v3;
-          end->tm_year = year_fix(v1);
-        }
-        break;
-/*}}}*/
-      case DS_MY:/*{{{*/
-        if (start) {
-          start->tm_year = year_fix(v3);
-          start->tm_mon  = m2 - 1;
-          start->tm_mday = 1;
-        }
-        if (end) {
-          end->tm_year = year_fix(v3);
-          end->tm_mon  = m2 - 1;
-          end->tm_mday = last_day(end->tm_mon, end->tm_year);
-        }
-        break;
-/*}}}*/
-      case DS_YM:/*{{{*/
-        if (start) {
-          start->tm_year = year_fix(v1);
-          start->tm_mon  = m2 - 1;
-          start->tm_mday = 1;
-        }
-        if (end) {
-          end->tm_year = year_fix(v1);
-          end->tm_mon  = m2 - 1;
-          end->tm_mday = last_day(end->tm_mon, end->tm_year);
-        }
-        break;/*}}}*/
-      case DS_FAILURE:
-        return -1;
-        break;
-
-      case DS_SCALED:
-        assert(0);
-        break;
-
-    }
-  }
-  return 0;
-}
-/*}}}*/
-
-int scan_date_string(char *in, time_t *start, int *has_start, time_t *end, int *has_end)/*{{{*/
-{
-  char *hyphen;
-  time_t now;
-  struct tm start_tm, end_tm;
-  char *nullchar;
-  int status;
-
-  *has_start = *has_end = 0;
-
-  nullchar = in;
-  while (*nullchar) nullchar++;
-
-  time(&now);
-  start_tm = end_tm = *localtime(&now);
-  start_tm.tm_hour = 0;
-  start_tm.tm_min = 0;
-  start_tm.tm_sec = 0;
-  end_tm.tm_hour = 23;
-  end_tm.tm_min = 59;
-  end_tm.tm_sec = 59;
-
-  hyphen = strchr(in, '-');
-  if (!hyphen) {
-    /* Start and end are the same. */
-    *has_start = *has_end = 1;
-    status = scan_date_expr(in, nullchar, &start_tm, &end_tm);
-    if (status) return status;
-    *start = mktime(&start_tm);
-    *end = mktime(&end_tm);
-    return 0;
-  } else {
-    if (hyphen+1 < nullchar) {
-      *has_end = 1;
-      status = scan_date_expr(hyphen+1, nullchar, NULL, &end_tm);
-      if (status) return status;
-      *end = mktime(&end_tm);
-      start_tm = end_tm;
-    }
-    if (hyphen > in) {
-      *has_start = 1;
-      status = scan_date_expr(in, hyphen, &start_tm, NULL);
-      if (status) return status;
-      *start = mktime(&start_tm);
-    }
-  }
-  return 0;
-}
-/*}}}*/
-
-#ifdef TEST
-static void check(char *in)/*{{{*/
-{
-  struct tm start, end;
-  int result;
-  result = scan_date_string(in, &start, &end);
-  if (result) printf("Conversion for <%s> failed\n", in);
-  else {
-    char buf1[128], buf2[128];
-    strftime(buf1, 128, "%d-%b-%Y", &start);
-    strftime(buf2, 128, "%d-%b-%Y", &end);
-    printf("Computed range for <%s> : %s - %s\n", in, buf1, buf2);
-  }
-
-}
-/*}}}*/
-int main (int argc, char **argv)/*{{{*/
-{
-
-  check("2w-1w");
-  check("4m-1w");
-  check("2002-2003");
-  check("may2002-2003");
-  check("2002may-2003");
-  check("feb98-15may99");
-  check("feb98-15may1999");
-  check("2feb98-1y");
-  check("02feb98-1y");
-  check("970617-20010618");
-
-  return 0;
-}
-/*}}}*/
-#endif
diff --git a/src/mairix/dates.h b/src/mairix/dates.h
@@ -1,45 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002-2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 DATES_H
-#define DATES_H
-
-enum DATESCAN_TYPE {
-  DS_FAILURE,
-  DS_D,
-  DS_Y,
-  DS_YYMMDD,
-  DS_SCALED,
-  DS_M,
-  DS_DM,
-  DS_MD,
-  DS_YM,
-  DS_MY,
-  DS_YMD,
-  DS_DMY,
-};
-
-extern int datescan_next_state(int current_state, int next_token);
-extern enum DATESCAN_TYPE datescan_exitval[];
-
-
-#endif /* DATES_H */
diff --git a/src/mairix/datescan.nfa b/src/mairix/datescan.nfa
@@ -1,112 +0,0 @@
-#########################################################################
-#
-# mairix - message index builder and finder for maildir folders.
-#
-# Copyright (C) Richard P. Curnow  2002-2004,2006
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# 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.
-#
-# =======================================================================
-
-# NFA description for parsing dates
-
-# Stuff to pass through verbatim
-%{
-#include "dates.h"
-%}
-
-Abbrev A = [a-zA-Z]
-
-BLOCK day {
-    State in
-        [12] ; [0-9] -> out
-        [3] ; [01]  -> out
-}
-
-# Match 2 digit year
-BLOCK year {
-    State in
-        [04-9] ; [0-9]  -> out
-        [3] ; [2-9] -> out
-}
-
-BLOCK month {
-    State in
-        A ; A ; A -> out
-}
-
-BLOCK scaled {
-    State in
-        [0-9] -> in, after_value
-
-    State after_value
-        A -> out
-}
-
-BLOCK ccyy {
-    State in
-        [1-9] ; [0-9] ; [0-9] ; [0-9] -> out
-}
-
-BLOCK main {
-    State in
-        [1-9] = DS_D
-        <day:in->out> = DS_D
-        <year:in->out> = DS_Y
-        <ccyy:in->out> = DS_Y
-        [0-9] ; [0-9] ; [0-9] ; [0-9] ; [0-9] ; [0-9] = DS_YYMMDD
-        [0-9] ; [0-9] ; [0-9] ; [0-9] ;
-            [0-9] ; [0-9] ; [0-9] ; [0-9] = DS_YYMMDD
-        <scaled:in->out> = DS_SCALED
-        <month:in->out> = DS_M
-        [1-9] ; <month:in->out> = DS_DM
-        <day:in->out> ; <month:in->out> = DS_DM
-        <month:in->out> ; [1-9] = DS_MD
-        <month:in->out> ; <day:in->out> = DS_MD
-        <year:in->out> ; <month:in->out> = DS_YM
-        <month:in->out> ; <year:in->out> = DS_MY
-        <ccyy:in->out> ; <month:in->out> = DS_YM
-        <month:in->out> ; <ccyy:in->out> = DS_MY
-
-        <year:in->out> ; <month:in->out> ; [1-9] = DS_YMD
-        <year:in->out> ; <month:in->out> ; <day:in->out> = DS_YMD
-        [1-9] ; <month:in->out> ; <year:in->out> = DS_DMY
-        <day:in->out> ; <month:in->out> ; <year:in->out> = DS_DMY
-
-        <ccyy:in->out> ; <month:in->out> ; [1-9] = DS_YMD
-        <ccyy:in->out> ; <month:in->out> ; <day:in->out> = DS_YMD
-        [1-9] ; <month:in->out> ; <ccyy:in->out> = DS_DMY
-        <day:in->out> ; <month:in->out> ; <ccyy:in->out> = DS_DMY
-}
-
-ATTR DS_D
-ATTR DS_Y
-ATTR DS_YYMMDD
-ATTR DS_SCALED
-ATTR DS_M
-ATTR DS_DM
-ATTR DS_MD
-ATTR DS_YM
-ATTR DS_MY
-ATTR DS_YMD
-ATTR DS_DMY
-
-DEFATTR DS_FAILURE
-
-TYPE "enum DATESCAN_TYPE"
-PREFIX datescan
-
-
-# vim:ft=txt:et:sw=4:sts=4:ht=4
-
diff --git a/src/mairix/datescan.report b/src/mairix/datescan.report
@@ -1,3303 +0,0 @@
-NFA state 0 = in
-  [(epsilon)] -> day#37.in
-   1:[1] -> #55
-   4:[4-9] -> #55
-   3:[3] -> #55
-   2:[2] -> #55
-  [(epsilon)] -> ccyy#32.in
-  [(epsilon)] -> ccyy#30.in
-  [(epsilon)] -> day#27.in
-   1:[1] -> #43
-   4:[4-9] -> #43
-   3:[3] -> #43
-   2:[2] -> #43
-  [(epsilon)] -> year#22.in
-  [(epsilon)] -> year#20.in
-  [(epsilon)] -> month#18.in
-  [(epsilon)] -> ccyy#16.in
-  [(epsilon)] -> month#14.in
-  [(epsilon)] -> year#12.in
-  [(epsilon)] -> month#10.in
-  [(epsilon)] -> month#9.in
-  [(epsilon)] -> day#7.in
-   1:[1] -> #21
-   4:[4-9] -> #21
-   3:[3] -> #21
-   2:[2] -> #21
-  [(epsilon)] -> month#5.in
-  [(epsilon)] -> scaled#4.in
-   0:[0] -> #11
-   4:[4-9] -> #11
-   3:[3] -> #11
-   2:[2] -> #11
-   1:[1] -> #11
-   0:[0] -> #5
-   4:[4-9] -> #5
-   3:[3] -> #5
-   2:[2] -> #5
-   1:[1] -> #5
-  [(epsilon)] -> ccyy#3.in
-  [(epsilon)] -> year#2.in
-  [(epsilon)] -> day#1.in
-   1:[1] -> #1
-   4:[4-9] -> #1
-   3:[3] -> #1
-   2:[2] -> #1
-  Epsilon closure :
-    (self)
-    day#1.in
-    year#2.in
-    ccyy#3.in
-    scaled#4.in
-    month#5.in
-    day#7.in
-    month#9.in
-    month#10.in
-    year#12.in
-    month#14.in
-    ccyy#16.in
-    month#18.in
-    year#20.in
-    year#22.in
-    day#27.in
-    ccyy#30.in
-    ccyy#32.in
-    day#37.in
-
-NFA state 1 = #1
-  Tags : DS_D
-  Epsilon closure :
-    (self)
-
-NFA state 2 = #2
-  Tags : DS_D
-  Epsilon closure :
-    (self)
-
-NFA state 3 = day#1.in
-   1:[1] -> day#1.#1
-   2:[2] -> day#1.#1
-   3:[3] -> day#1.#2
-  Epsilon closure :
-    (self)
-
-NFA state 4 = day#1.#1
-   0:[0] -> day#1.out
-   4:[4-9] -> day#1.out
-   3:[3] -> day#1.out
-   2:[2] -> day#1.out
-   1:[1] -> day#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 5 = day#1.#2
-   0:[0] -> day#1.out
-   1:[1] -> day#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 6 = day#1.out
-  [(epsilon)] -> #2
-  Epsilon closure :
-    (self)
-    #2
-
-NFA state 7 = #3
-  Tags : DS_Y
-  Epsilon closure :
-    (self)
-
-NFA state 8 = year#2.in
-   0:[0] -> year#2.#1
-   4:[4-9] -> year#2.#1
-   3:[3] -> year#2.#2
-  Epsilon closure :
-    (self)
-
-NFA state 9 = year#2.#1
-   0:[0] -> year#2.out
-   4:[4-9] -> year#2.out
-   3:[3] -> year#2.out
-   2:[2] -> year#2.out
-   1:[1] -> year#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 10 = year#2.#2
-   2:[2] -> year#2.out
-   4:[4-9] -> year#2.out
-   3:[3] -> year#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 11 = year#2.out
-  [(epsilon)] -> #3
-  Epsilon closure :
-    (self)
-    #3
-
-NFA state 12 = #4
-  Tags : DS_Y
-  Epsilon closure :
-    (self)
-
-NFA state 13 = ccyy#3.in
-   1:[1] -> ccyy#3.#1
-   4:[4-9] -> ccyy#3.#1
-   3:[3] -> ccyy#3.#1
-   2:[2] -> ccyy#3.#1
-  Epsilon closure :
-    (self)
-
-NFA state 14 = ccyy#3.#1
-   0:[0] -> ccyy#3.#2
-   4:[4-9] -> ccyy#3.#2
-   3:[3] -> ccyy#3.#2
-   2:[2] -> ccyy#3.#2
-   1:[1] -> ccyy#3.#2
-  Epsilon closure :
-    (self)
-
-NFA state 15 = ccyy#3.#2
-   0:[0] -> ccyy#3.#3
-   4:[4-9] -> ccyy#3.#3
-   3:[3] -> ccyy#3.#3
-   2:[2] -> ccyy#3.#3
-   1:[1] -> ccyy#3.#3
-  Epsilon closure :
-    (self)
-
-NFA state 16 = ccyy#3.#3
-   0:[0] -> ccyy#3.out
-   4:[4-9] -> ccyy#3.out
-   3:[3] -> ccyy#3.out
-   2:[2] -> ccyy#3.out
-   1:[1] -> ccyy#3.out
-  Epsilon closure :
-    (self)
-
-NFA state 17 = ccyy#3.out
-  [(epsilon)] -> #4
-  Epsilon closure :
-    (self)
-    #4
-
-NFA state 18 = #5
-   0:[0] -> #6
-   4:[4-9] -> #6
-   3:[3] -> #6
-   2:[2] -> #6
-   1:[1] -> #6
-  Epsilon closure :
-    (self)
-
-NFA state 19 = #6
-   0:[0] -> #7
-   4:[4-9] -> #7
-   3:[3] -> #7
-   2:[2] -> #7
-   1:[1] -> #7
-  Epsilon closure :
-    (self)
-
-NFA state 20 = #7
-   0:[0] -> #8
-   4:[4-9] -> #8
-   3:[3] -> #8
-   2:[2] -> #8
-   1:[1] -> #8
-  Epsilon closure :
-    (self)
-
-NFA state 21 = #8
-   0:[0] -> #9
-   4:[4-9] -> #9
-   3:[3] -> #9
-   2:[2] -> #9
-   1:[1] -> #9
-  Epsilon closure :
-    (self)
-
-NFA state 22 = #9
-   0:[0] -> #10
-   4:[4-9] -> #10
-   3:[3] -> #10
-   2:[2] -> #10
-   1:[1] -> #10
-  Epsilon closure :
-    (self)
-
-NFA state 23 = #10
-  Tags : DS_YYMMDD
-  Epsilon closure :
-    (self)
-
-NFA state 24 = #11
-   0:[0] -> #12
-   4:[4-9] -> #12
-   3:[3] -> #12
-   2:[2] -> #12
-   1:[1] -> #12
-  Epsilon closure :
-    (self)
-
-NFA state 25 = #12
-   0:[0] -> #13
-   4:[4-9] -> #13
-   3:[3] -> #13
-   2:[2] -> #13
-   1:[1] -> #13
-  Epsilon closure :
-    (self)
-
-NFA state 26 = #13
-   0:[0] -> #14
-   4:[4-9] -> #14
-   3:[3] -> #14
-   2:[2] -> #14
-   1:[1] -> #14
-  Epsilon closure :
-    (self)
-
-NFA state 27 = #14
-   0:[0] -> #15
-   4:[4-9] -> #15
-   3:[3] -> #15
-   2:[2] -> #15
-   1:[1] -> #15
-  Epsilon closure :
-    (self)
-
-NFA state 28 = #15
-   0:[0] -> #16
-   4:[4-9] -> #16
-   3:[3] -> #16
-   2:[2] -> #16
-   1:[1] -> #16
-  Epsilon closure :
-    (self)
-
-NFA state 29 = #16
-   0:[0] -> #17
-   4:[4-9] -> #17
-   3:[3] -> #17
-   2:[2] -> #17
-   1:[1] -> #17
-  Epsilon closure :
-    (self)
-
-NFA state 30 = #17
-   0:[0] -> #18
-   4:[4-9] -> #18
-   3:[3] -> #18
-   2:[2] -> #18
-   1:[1] -> #18
-  Epsilon closure :
-    (self)
-
-NFA state 31 = #18
-  Tags : DS_YYMMDD
-  Epsilon closure :
-    (self)
-
-NFA state 32 = #19
-  Tags : DS_SCALED
-  Epsilon closure :
-    (self)
-
-NFA state 33 = scaled#4.in
-   0:[0] -> scaled#4.in
-   4:[4-9] -> scaled#4.in
-   3:[3] -> scaled#4.in
-   2:[2] -> scaled#4.in
-   1:[1] -> scaled#4.in
-   0:[0] -> scaled#4.after_value
-   4:[4-9] -> scaled#4.after_value
-   3:[3] -> scaled#4.after_value
-   2:[2] -> scaled#4.after_value
-   1:[1] -> scaled#4.after_value
-  Epsilon closure :
-    (self)
-
-NFA state 34 = scaled#4.after_value
-   5:[A-Za-z] -> scaled#4.out
-  Epsilon closure :
-    (self)
-
-NFA state 35 = scaled#4.out
-  [(epsilon)] -> #19
-  Epsilon closure :
-    (self)
-    #19
-
-NFA state 36 = #20
-  Tags : DS_M
-  Epsilon closure :
-    (self)
-
-NFA state 37 = month#5.in
-   5:[A-Za-z] -> month#5.#1
-  Epsilon closure :
-    (self)
-
-NFA state 38 = month#5.#1
-   5:[A-Za-z] -> month#5.#2
-  Epsilon closure :
-    (self)
-
-NFA state 39 = month#5.#2
-   5:[A-Za-z] -> month#5.out
-  Epsilon closure :
-    (self)
-
-NFA state 40 = month#5.out
-  [(epsilon)] -> #20
-  Epsilon closure :
-    (self)
-    #20
-
-NFA state 41 = #21
-  [(epsilon)] -> month#6.in
-  Epsilon closure :
-    (self)
-    month#6.in
-
-NFA state 42 = #22
-  Tags : DS_DM
-  Epsilon closure :
-    (self)
-
-NFA state 43 = month#6.in
-   5:[A-Za-z] -> month#6.#1
-  Epsilon closure :
-    (self)
-
-NFA state 44 = month#6.#1
-   5:[A-Za-z] -> month#6.#2
-  Epsilon closure :
-    (self)
-
-NFA state 45 = month#6.#2
-   5:[A-Za-z] -> month#6.out
-  Epsilon closure :
-    (self)
-
-NFA state 46 = month#6.out
-  [(epsilon)] -> #22
-  Epsilon closure :
-    (self)
-    #22
-
-NFA state 47 = #23
-  [(epsilon)] -> month#8.in
-  Epsilon closure :
-    (self)
-    month#8.in
-
-NFA state 48 = day#7.in
-   1:[1] -> day#7.#1
-   2:[2] -> day#7.#1
-   3:[3] -> day#7.#2
-  Epsilon closure :
-    (self)
-
-NFA state 49 = day#7.#1
-   0:[0] -> day#7.out
-   4:[4-9] -> day#7.out
-   3:[3] -> day#7.out
-   2:[2] -> day#7.out
-   1:[1] -> day#7.out
-  Epsilon closure :
-    (self)
-
-NFA state 50 = day#7.#2
-   0:[0] -> day#7.out
-   1:[1] -> day#7.out
-  Epsilon closure :
-    (self)
-
-NFA state 51 = day#7.out
-  [(epsilon)] -> #23
-  Epsilon closure :
-    (self)
-    #23
-    month#8.in
-
-NFA state 52 = #24
-  Tags : DS_DM
-  Epsilon closure :
-    (self)
-
-NFA state 53 = month#8.in
-   5:[A-Za-z] -> month#8.#1
-  Epsilon closure :
-    (self)
-
-NFA state 54 = month#8.#1
-   5:[A-Za-z] -> month#8.#2
-  Epsilon closure :
-    (self)
-
-NFA state 55 = month#8.#2
-   5:[A-Za-z] -> month#8.out
-  Epsilon closure :
-    (self)
-
-NFA state 56 = month#8.out
-  [(epsilon)] -> #24
-  Epsilon closure :
-    (self)
-    #24
-
-NFA state 57 = #25
-   1:[1] -> #26
-   4:[4-9] -> #26
-   3:[3] -> #26
-   2:[2] -> #26
-  Epsilon closure :
-    (self)
-
-NFA state 58 = month#9.in
-   5:[A-Za-z] -> month#9.#1
-  Epsilon closure :
-    (self)
-
-NFA state 59 = month#9.#1
-   5:[A-Za-z] -> month#9.#2
-  Epsilon closure :
-    (self)
-
-NFA state 60 = month#9.#2
-   5:[A-Za-z] -> month#9.out
-  Epsilon closure :
-    (self)
-
-NFA state 61 = month#9.out
-  [(epsilon)] -> #25
-  Epsilon closure :
-    (self)
-    #25
-
-NFA state 62 = #26
-  Tags : DS_MD
-  Epsilon closure :
-    (self)
-
-NFA state 63 = #27
-  [(epsilon)] -> day#11.in
-  Epsilon closure :
-    (self)
-    day#11.in
-
-NFA state 64 = month#10.in
-   5:[A-Za-z] -> month#10.#1
-  Epsilon closure :
-    (self)
-
-NFA state 65 = month#10.#1
-   5:[A-Za-z] -> month#10.#2
-  Epsilon closure :
-    (self)
-
-NFA state 66 = month#10.#2
-   5:[A-Za-z] -> month#10.out
-  Epsilon closure :
-    (self)
-
-NFA state 67 = month#10.out
-  [(epsilon)] -> #27
-  Epsilon closure :
-    (self)
-    #27
-    day#11.in
-
-NFA state 68 = #28
-  Tags : DS_MD
-  Epsilon closure :
-    (self)
-
-NFA state 69 = day#11.in
-   1:[1] -> day#11.#1
-   2:[2] -> day#11.#1
-   3:[3] -> day#11.#2
-  Epsilon closure :
-    (self)
-
-NFA state 70 = day#11.#1
-   0:[0] -> day#11.out
-   4:[4-9] -> day#11.out
-   3:[3] -> day#11.out
-   2:[2] -> day#11.out
-   1:[1] -> day#11.out
-  Epsilon closure :
-    (self)
-
-NFA state 71 = day#11.#2
-   0:[0] -> day#11.out
-   1:[1] -> day#11.out
-  Epsilon closure :
-    (self)
-
-NFA state 72 = day#11.out
-  [(epsilon)] -> #28
-  Epsilon closure :
-    (self)
-    #28
-
-NFA state 73 = #29
-  [(epsilon)] -> month#13.in
-  Epsilon closure :
-    (self)
-    month#13.in
-
-NFA state 74 = year#12.in
-   0:[0] -> year#12.#1
-   4:[4-9] -> year#12.#1
-   3:[3] -> year#12.#2
-  Epsilon closure :
-    (self)
-
-NFA state 75 = year#12.#1
-   0:[0] -> year#12.out
-   4:[4-9] -> year#12.out
-   3:[3] -> year#12.out
-   2:[2] -> year#12.out
-   1:[1] -> year#12.out
-  Epsilon closure :
-    (self)
-
-NFA state 76 = year#12.#2
-   2:[2] -> year#12.out
-   4:[4-9] -> year#12.out
-   3:[3] -> year#12.out
-  Epsilon closure :
-    (self)
-
-NFA state 77 = year#12.out
-  [(epsilon)] -> #29
-  Epsilon closure :
-    (self)
-    #29
-    month#13.in
-
-NFA state 78 = #30
-  Tags : DS_YM
-  Epsilon closure :
-    (self)
-
-NFA state 79 = month#13.in
-   5:[A-Za-z] -> month#13.#1
-  Epsilon closure :
-    (self)
-
-NFA state 80 = month#13.#1
-   5:[A-Za-z] -> month#13.#2
-  Epsilon closure :
-    (self)
-
-NFA state 81 = month#13.#2
-   5:[A-Za-z] -> month#13.out
-  Epsilon closure :
-    (self)
-
-NFA state 82 = month#13.out
-  [(epsilon)] -> #30
-  Epsilon closure :
-    (self)
-    #30
-
-NFA state 83 = #31
-  [(epsilon)] -> year#15.in
-  Epsilon closure :
-    (self)
-    year#15.in
-
-NFA state 84 = month#14.in
-   5:[A-Za-z] -> month#14.#1
-  Epsilon closure :
-    (self)
-
-NFA state 85 = month#14.#1
-   5:[A-Za-z] -> month#14.#2
-  Epsilon closure :
-    (self)
-
-NFA state 86 = month#14.#2
-   5:[A-Za-z] -> month#14.out
-  Epsilon closure :
-    (self)
-
-NFA state 87 = month#14.out
-  [(epsilon)] -> #31
-  Epsilon closure :
-    (self)
-    #31
-    year#15.in
-
-NFA state 88 = #32
-  Tags : DS_MY
-  Epsilon closure :
-    (self)
-
-NFA state 89 = year#15.in
-   0:[0] -> year#15.#1
-   4:[4-9] -> year#15.#1
-   3:[3] -> year#15.#2
-  Epsilon closure :
-    (self)
-
-NFA state 90 = year#15.#1
-   0:[0] -> year#15.out
-   4:[4-9] -> year#15.out
-   3:[3] -> year#15.out
-   2:[2] -> year#15.out
-   1:[1] -> year#15.out
-  Epsilon closure :
-    (self)
-
-NFA state 91 = year#15.#2
-   2:[2] -> year#15.out
-   4:[4-9] -> year#15.out
-   3:[3] -> year#15.out
-  Epsilon closure :
-    (self)
-
-NFA state 92 = year#15.out
-  [(epsilon)] -> #32
-  Epsilon closure :
-    (self)
-    #32
-
-NFA state 93 = #33
-  [(epsilon)] -> month#17.in
-  Epsilon closure :
-    (self)
-    month#17.in
-
-NFA state 94 = ccyy#16.in
-   1:[1] -> ccyy#16.#1
-   4:[4-9] -> ccyy#16.#1
-   3:[3] -> ccyy#16.#1
-   2:[2] -> ccyy#16.#1
-  Epsilon closure :
-    (self)
-
-NFA state 95 = ccyy#16.#1
-   0:[0] -> ccyy#16.#2
-   4:[4-9] -> ccyy#16.#2
-   3:[3] -> ccyy#16.#2
-   2:[2] -> ccyy#16.#2
-   1:[1] -> ccyy#16.#2
-  Epsilon closure :
-    (self)
-
-NFA state 96 = ccyy#16.#2
-   0:[0] -> ccyy#16.#3
-   4:[4-9] -> ccyy#16.#3
-   3:[3] -> ccyy#16.#3
-   2:[2] -> ccyy#16.#3
-   1:[1] -> ccyy#16.#3
-  Epsilon closure :
-    (self)
-
-NFA state 97 = ccyy#16.#3
-   0:[0] -> ccyy#16.out
-   4:[4-9] -> ccyy#16.out
-   3:[3] -> ccyy#16.out
-   2:[2] -> ccyy#16.out
-   1:[1] -> ccyy#16.out
-  Epsilon closure :
-    (self)
-
-NFA state 98 = ccyy#16.out
-  [(epsilon)] -> #33
-  Epsilon closure :
-    (self)
-    #33
-    month#17.in
-
-NFA state 99 = #34
-  Tags : DS_YM
-  Epsilon closure :
-    (self)
-
-NFA state 100 = month#17.in
-   5:[A-Za-z] -> month#17.#1
-  Epsilon closure :
-    (self)
-
-NFA state 101 = month#17.#1
-   5:[A-Za-z] -> month#17.#2
-  Epsilon closure :
-    (self)
-
-NFA state 102 = month#17.#2
-   5:[A-Za-z] -> month#17.out
-  Epsilon closure :
-    (self)
-
-NFA state 103 = month#17.out
-  [(epsilon)] -> #34
-  Epsilon closure :
-    (self)
-    #34
-
-NFA state 104 = #35
-  [(epsilon)] -> ccyy#19.in
-  Epsilon closure :
-    (self)
-    ccyy#19.in
-
-NFA state 105 = month#18.in
-   5:[A-Za-z] -> month#18.#1
-  Epsilon closure :
-    (self)
-
-NFA state 106 = month#18.#1
-   5:[A-Za-z] -> month#18.#2
-  Epsilon closure :
-    (self)
-
-NFA state 107 = month#18.#2
-   5:[A-Za-z] -> month#18.out
-  Epsilon closure :
-    (self)
-
-NFA state 108 = month#18.out
-  [(epsilon)] -> #35
-  Epsilon closure :
-    (self)
-    #35
-    ccyy#19.in
-
-NFA state 109 = #36
-  Tags : DS_MY
-  Epsilon closure :
-    (self)
-
-NFA state 110 = ccyy#19.in
-   1:[1] -> ccyy#19.#1
-   4:[4-9] -> ccyy#19.#1
-   3:[3] -> ccyy#19.#1
-   2:[2] -> ccyy#19.#1
-  Epsilon closure :
-    (self)
-
-NFA state 111 = ccyy#19.#1
-   0:[0] -> ccyy#19.#2
-   4:[4-9] -> ccyy#19.#2
-   3:[3] -> ccyy#19.#2
-   2:[2] -> ccyy#19.#2
-   1:[1] -> ccyy#19.#2
-  Epsilon closure :
-    (self)
-
-NFA state 112 = ccyy#19.#2
-   0:[0] -> ccyy#19.#3
-   4:[4-9] -> ccyy#19.#3
-   3:[3] -> ccyy#19.#3
-   2:[2] -> ccyy#19.#3
-   1:[1] -> ccyy#19.#3
-  Epsilon closure :
-    (self)
-
-NFA state 113 = ccyy#19.#3
-   0:[0] -> ccyy#19.out
-   4:[4-9] -> ccyy#19.out
-   3:[3] -> ccyy#19.out
-   2:[2] -> ccyy#19.out
-   1:[1] -> ccyy#19.out
-  Epsilon closure :
-    (self)
-
-NFA state 114 = ccyy#19.out
-  [(epsilon)] -> #36
-  Epsilon closure :
-    (self)
-    #36
-
-NFA state 115 = #37
-  [(epsilon)] -> month#21.in
-  Epsilon closure :
-    (self)
-    month#21.in
-
-NFA state 116 = year#20.in
-   0:[0] -> year#20.#1
-   4:[4-9] -> year#20.#1
-   3:[3] -> year#20.#2
-  Epsilon closure :
-    (self)
-
-NFA state 117 = year#20.#1
-   0:[0] -> year#20.out
-   4:[4-9] -> year#20.out
-   3:[3] -> year#20.out
-   2:[2] -> year#20.out
-   1:[1] -> year#20.out
-  Epsilon closure :
-    (self)
-
-NFA state 118 = year#20.#2
-   2:[2] -> year#20.out
-   4:[4-9] -> year#20.out
-   3:[3] -> year#20.out
-  Epsilon closure :
-    (self)
-
-NFA state 119 = year#20.out
-  [(epsilon)] -> #37
-  Epsilon closure :
-    (self)
-    #37
-    month#21.in
-
-NFA state 120 = #38
-   1:[1] -> #39
-   4:[4-9] -> #39
-   3:[3] -> #39
-   2:[2] -> #39
-  Epsilon closure :
-    (self)
-
-NFA state 121 = month#21.in
-   5:[A-Za-z] -> month#21.#1
-  Epsilon closure :
-    (self)
-
-NFA state 122 = month#21.#1
-   5:[A-Za-z] -> month#21.#2
-  Epsilon closure :
-    (self)
-
-NFA state 123 = month#21.#2
-   5:[A-Za-z] -> month#21.out
-  Epsilon closure :
-    (self)
-
-NFA state 124 = month#21.out
-  [(epsilon)] -> #38
-  Epsilon closure :
-    (self)
-    #38
-
-NFA state 125 = #39
-  Tags : DS_YMD
-  Epsilon closure :
-    (self)
-
-NFA state 126 = #40
-  [(epsilon)] -> month#23.in
-  Epsilon closure :
-    (self)
-    month#23.in
-
-NFA state 127 = year#22.in
-   0:[0] -> year#22.#1
-   4:[4-9] -> year#22.#1
-   3:[3] -> year#22.#2
-  Epsilon closure :
-    (self)
-
-NFA state 128 = year#22.#1
-   0:[0] -> year#22.out
-   4:[4-9] -> year#22.out
-   3:[3] -> year#22.out
-   2:[2] -> year#22.out
-   1:[1] -> year#22.out
-  Epsilon closure :
-    (self)
-
-NFA state 129 = year#22.#2
-   2:[2] -> year#22.out
-   4:[4-9] -> year#22.out
-   3:[3] -> year#22.out
-  Epsilon closure :
-    (self)
-
-NFA state 130 = year#22.out
-  [(epsilon)] -> #40
-  Epsilon closure :
-    (self)
-    #40
-    month#23.in
-
-NFA state 131 = #41
-  [(epsilon)] -> day#24.in
-  Epsilon closure :
-    (self)
-    day#24.in
-
-NFA state 132 = month#23.in
-   5:[A-Za-z] -> month#23.#1
-  Epsilon closure :
-    (self)
-
-NFA state 133 = month#23.#1
-   5:[A-Za-z] -> month#23.#2
-  Epsilon closure :
-    (self)
-
-NFA state 134 = month#23.#2
-   5:[A-Za-z] -> month#23.out
-  Epsilon closure :
-    (self)
-
-NFA state 135 = month#23.out
-  [(epsilon)] -> #41
-  Epsilon closure :
-    (self)
-    #41
-    day#24.in
-
-NFA state 136 = #42
-  Tags : DS_YMD
-  Epsilon closure :
-    (self)
-
-NFA state 137 = day#24.in
-   1:[1] -> day#24.#1
-   2:[2] -> day#24.#1
-   3:[3] -> day#24.#2
-  Epsilon closure :
-    (self)
-
-NFA state 138 = day#24.#1
-   0:[0] -> day#24.out
-   4:[4-9] -> day#24.out
-   3:[3] -> day#24.out
-   2:[2] -> day#24.out
-   1:[1] -> day#24.out
-  Epsilon closure :
-    (self)
-
-NFA state 139 = day#24.#2
-   0:[0] -> day#24.out
-   1:[1] -> day#24.out
-  Epsilon closure :
-    (self)
-
-NFA state 140 = day#24.out
-  [(epsilon)] -> #42
-  Epsilon closure :
-    (self)
-    #42
-
-NFA state 141 = #43
-  [(epsilon)] -> month#25.in
-  Epsilon closure :
-    (self)
-    month#25.in
-
-NFA state 142 = #44
-  [(epsilon)] -> year#26.in
-  Epsilon closure :
-    (self)
-    year#26.in
-
-NFA state 143 = month#25.in
-   5:[A-Za-z] -> month#25.#1
-  Epsilon closure :
-    (self)
-
-NFA state 144 = month#25.#1
-   5:[A-Za-z] -> month#25.#2
-  Epsilon closure :
-    (self)
-
-NFA state 145 = month#25.#2
-   5:[A-Za-z] -> month#25.out
-  Epsilon closure :
-    (self)
-
-NFA state 146 = month#25.out
-  [(epsilon)] -> #44
-  Epsilon closure :
-    (self)
-    #44
-    year#26.in
-
-NFA state 147 = #45
-  Tags : DS_DMY
-  Epsilon closure :
-    (self)
-
-NFA state 148 = year#26.in
-   0:[0] -> year#26.#1
-   4:[4-9] -> year#26.#1
-   3:[3] -> year#26.#2
-  Epsilon closure :
-    (self)
-
-NFA state 149 = year#26.#1
-   0:[0] -> year#26.out
-   4:[4-9] -> year#26.out
-   3:[3] -> year#26.out
-   2:[2] -> year#26.out
-   1:[1] -> year#26.out
-  Epsilon closure :
-    (self)
-
-NFA state 150 = year#26.#2
-   2:[2] -> year#26.out
-   4:[4-9] -> year#26.out
-   3:[3] -> year#26.out
-  Epsilon closure :
-    (self)
-
-NFA state 151 = year#26.out
-  [(epsilon)] -> #45
-  Epsilon closure :
-    (self)
-    #45
-
-NFA state 152 = #46
-  [(epsilon)] -> month#28.in
-  Epsilon closure :
-    (self)
-    month#28.in
-
-NFA state 153 = day#27.in
-   1:[1] -> day#27.#1
-   2:[2] -> day#27.#1
-   3:[3] -> day#27.#2
-  Epsilon closure :
-    (self)
-
-NFA state 154 = day#27.#1
-   0:[0] -> day#27.out
-   4:[4-9] -> day#27.out
-   3:[3] -> day#27.out
-   2:[2] -> day#27.out
-   1:[1] -> day#27.out
-  Epsilon closure :
-    (self)
-
-NFA state 155 = day#27.#2
-   0:[0] -> day#27.out
-   1:[1] -> day#27.out
-  Epsilon closure :
-    (self)
-
-NFA state 156 = day#27.out
-  [(epsilon)] -> #46
-  Epsilon closure :
-    (self)
-    #46
-    month#28.in
-
-NFA state 157 = #47
-  [(epsilon)] -> year#29.in
-  Epsilon closure :
-    (self)
-    year#29.in
-
-NFA state 158 = month#28.in
-   5:[A-Za-z] -> month#28.#1
-  Epsilon closure :
-    (self)
-
-NFA state 159 = month#28.#1
-   5:[A-Za-z] -> month#28.#2
-  Epsilon closure :
-    (self)
-
-NFA state 160 = month#28.#2
-   5:[A-Za-z] -> month#28.out
-  Epsilon closure :
-    (self)
-
-NFA state 161 = month#28.out
-  [(epsilon)] -> #47
-  Epsilon closure :
-    (self)
-    #47
-    year#29.in
-
-NFA state 162 = #48
-  Tags : DS_DMY
-  Epsilon closure :
-    (self)
-
-NFA state 163 = year#29.in
-   0:[0] -> year#29.#1
-   4:[4-9] -> year#29.#1
-   3:[3] -> year#29.#2
-  Epsilon closure :
-    (self)
-
-NFA state 164 = year#29.#1
-   0:[0] -> year#29.out
-   4:[4-9] -> year#29.out
-   3:[3] -> year#29.out
-   2:[2] -> year#29.out
-   1:[1] -> year#29.out
-  Epsilon closure :
-    (self)
-
-NFA state 165 = year#29.#2
-   2:[2] -> year#29.out
-   4:[4-9] -> year#29.out
-   3:[3] -> year#29.out
-  Epsilon closure :
-    (self)
-
-NFA state 166 = year#29.out
-  [(epsilon)] -> #48
-  Epsilon closure :
-    (self)
-    #48
-
-NFA state 167 = #49
-  [(epsilon)] -> month#31.in
-  Epsilon closure :
-    (self)
-    month#31.in
-
-NFA state 168 = ccyy#30.in
-   1:[1] -> ccyy#30.#1
-   4:[4-9] -> ccyy#30.#1
-   3:[3] -> ccyy#30.#1
-   2:[2] -> ccyy#30.#1
-  Epsilon closure :
-    (self)
-
-NFA state 169 = ccyy#30.#1
-   0:[0] -> ccyy#30.#2
-   4:[4-9] -> ccyy#30.#2
-   3:[3] -> ccyy#30.#2
-   2:[2] -> ccyy#30.#2
-   1:[1] -> ccyy#30.#2
-  Epsilon closure :
-    (self)
-
-NFA state 170 = ccyy#30.#2
-   0:[0] -> ccyy#30.#3
-   4:[4-9] -> ccyy#30.#3
-   3:[3] -> ccyy#30.#3
-   2:[2] -> ccyy#30.#3
-   1:[1] -> ccyy#30.#3
-  Epsilon closure :
-    (self)
-
-NFA state 171 = ccyy#30.#3
-   0:[0] -> ccyy#30.out
-   4:[4-9] -> ccyy#30.out
-   3:[3] -> ccyy#30.out
-   2:[2] -> ccyy#30.out
-   1:[1] -> ccyy#30.out
-  Epsilon closure :
-    (self)
-
-NFA state 172 = ccyy#30.out
-  [(epsilon)] -> #49
-  Epsilon closure :
-    (self)
-    #49
-    month#31.in
-
-NFA state 173 = #50
-   1:[1] -> #51
-   4:[4-9] -> #51
-   3:[3] -> #51
-   2:[2] -> #51
-  Epsilon closure :
-    (self)
-
-NFA state 174 = month#31.in
-   5:[A-Za-z] -> month#31.#1
-  Epsilon closure :
-    (self)
-
-NFA state 175 = month#31.#1
-   5:[A-Za-z] -> month#31.#2
-  Epsilon closure :
-    (self)
-
-NFA state 176 = month#31.#2
-   5:[A-Za-z] -> month#31.out
-  Epsilon closure :
-    (self)
-
-NFA state 177 = month#31.out
-  [(epsilon)] -> #50
-  Epsilon closure :
-    (self)
-    #50
-
-NFA state 178 = #51
-  Tags : DS_YMD
-  Epsilon closure :
-    (self)
-
-NFA state 179 = #52
-  [(epsilon)] -> month#33.in
-  Epsilon closure :
-    (self)
-    month#33.in
-
-NFA state 180 = ccyy#32.in
-   1:[1] -> ccyy#32.#1
-   4:[4-9] -> ccyy#32.#1
-   3:[3] -> ccyy#32.#1
-   2:[2] -> ccyy#32.#1
-  Epsilon closure :
-    (self)
-
-NFA state 181 = ccyy#32.#1
-   0:[0] -> ccyy#32.#2
-   4:[4-9] -> ccyy#32.#2
-   3:[3] -> ccyy#32.#2
-   2:[2] -> ccyy#32.#2
-   1:[1] -> ccyy#32.#2
-  Epsilon closure :
-    (self)
-
-NFA state 182 = ccyy#32.#2
-   0:[0] -> ccyy#32.#3
-   4:[4-9] -> ccyy#32.#3
-   3:[3] -> ccyy#32.#3
-   2:[2] -> ccyy#32.#3
-   1:[1] -> ccyy#32.#3
-  Epsilon closure :
-    (self)
-
-NFA state 183 = ccyy#32.#3
-   0:[0] -> ccyy#32.out
-   4:[4-9] -> ccyy#32.out
-   3:[3] -> ccyy#32.out
-   2:[2] -> ccyy#32.out
-   1:[1] -> ccyy#32.out
-  Epsilon closure :
-    (self)
-
-NFA state 184 = ccyy#32.out
-  [(epsilon)] -> #52
-  Epsilon closure :
-    (self)
-    #52
-    month#33.in
-
-NFA state 185 = #53
-  [(epsilon)] -> day#34.in
-  Epsilon closure :
-    (self)
-    day#34.in
-
-NFA state 186 = month#33.in
-   5:[A-Za-z] -> month#33.#1
-  Epsilon closure :
-    (self)
-
-NFA state 187 = month#33.#1
-   5:[A-Za-z] -> month#33.#2
-  Epsilon closure :
-    (self)
-
-NFA state 188 = month#33.#2
-   5:[A-Za-z] -> month#33.out
-  Epsilon closure :
-    (self)
-
-NFA state 189 = month#33.out
-  [(epsilon)] -> #53
-  Epsilon closure :
-    (self)
-    #53
-    day#34.in
-
-NFA state 190 = #54
-  Tags : DS_YMD
-  Epsilon closure :
-    (self)
-
-NFA state 191 = day#34.in
-   1:[1] -> day#34.#1
-   2:[2] -> day#34.#1
-   3:[3] -> day#34.#2
-  Epsilon closure :
-    (self)
-
-NFA state 192 = day#34.#1
-   0:[0] -> day#34.out
-   4:[4-9] -> day#34.out
-   3:[3] -> day#34.out
-   2:[2] -> day#34.out
-   1:[1] -> day#34.out
-  Epsilon closure :
-    (self)
-
-NFA state 193 = day#34.#2
-   0:[0] -> day#34.out
-   1:[1] -> day#34.out
-  Epsilon closure :
-    (self)
-
-NFA state 194 = day#34.out
-  [(epsilon)] -> #54
-  Epsilon closure :
-    (self)
-    #54
-
-NFA state 195 = #55
-  [(epsilon)] -> month#35.in
-  Epsilon closure :
-    (self)
-    month#35.in
-
-NFA state 196 = #56
-  [(epsilon)] -> ccyy#36.in
-  Epsilon closure :
-    (self)
-    ccyy#36.in
-
-NFA state 197 = month#35.in
-   5:[A-Za-z] -> month#35.#1
-  Epsilon closure :
-    (self)
-
-NFA state 198 = month#35.#1
-   5:[A-Za-z] -> month#35.#2
-  Epsilon closure :
-    (self)
-
-NFA state 199 = month#35.#2
-   5:[A-Za-z] -> month#35.out
-  Epsilon closure :
-    (self)
-
-NFA state 200 = month#35.out
-  [(epsilon)] -> #56
-  Epsilon closure :
-    (self)
-    #56
-    ccyy#36.in
-
-NFA state 201 = #57
-  Tags : DS_DMY
-  Epsilon closure :
-    (self)
-
-NFA state 202 = ccyy#36.in
-   1:[1] -> ccyy#36.#1
-   4:[4-9] -> ccyy#36.#1
-   3:[3] -> ccyy#36.#1
-   2:[2] -> ccyy#36.#1
-  Epsilon closure :
-    (self)
-
-NFA state 203 = ccyy#36.#1
-   0:[0] -> ccyy#36.#2
-   4:[4-9] -> ccyy#36.#2
-   3:[3] -> ccyy#36.#2
-   2:[2] -> ccyy#36.#2
-   1:[1] -> ccyy#36.#2
-  Epsilon closure :
-    (self)
-
-NFA state 204 = ccyy#36.#2
-   0:[0] -> ccyy#36.#3
-   4:[4-9] -> ccyy#36.#3
-   3:[3] -> ccyy#36.#3
-   2:[2] -> ccyy#36.#3
-   1:[1] -> ccyy#36.#3
-  Epsilon closure :
-    (self)
-
-NFA state 205 = ccyy#36.#3
-   0:[0] -> ccyy#36.out
-   4:[4-9] -> ccyy#36.out
-   3:[3] -> ccyy#36.out
-   2:[2] -> ccyy#36.out
-   1:[1] -> ccyy#36.out
-  Epsilon closure :
-    (self)
-
-NFA state 206 = ccyy#36.out
-  [(epsilon)] -> #57
-  Epsilon closure :
-    (self)
-    #57
-
-NFA state 207 = #58
-  [(epsilon)] -> month#38.in
-  Epsilon closure :
-    (self)
-    month#38.in
-
-NFA state 208 = day#37.in
-   1:[1] -> day#37.#1
-   2:[2] -> day#37.#1
-   3:[3] -> day#37.#2
-  Epsilon closure :
-    (self)
-
-NFA state 209 = day#37.#1
-   0:[0] -> day#37.out
-   4:[4-9] -> day#37.out
-   3:[3] -> day#37.out
-   2:[2] -> day#37.out
-   1:[1] -> day#37.out
-  Epsilon closure :
-    (self)
-
-NFA state 210 = day#37.#2
-   0:[0] -> day#37.out
-   1:[1] -> day#37.out
-  Epsilon closure :
-    (self)
-
-NFA state 211 = day#37.out
-  [(epsilon)] -> #58
-  Epsilon closure :
-    (self)
-    #58
-    month#38.in
-
-NFA state 212 = #59
-  [(epsilon)] -> ccyy#39.in
-  Epsilon closure :
-    (self)
-    ccyy#39.in
-
-NFA state 213 = month#38.in
-   5:[A-Za-z] -> month#38.#1
-  Epsilon closure :
-    (self)
-
-NFA state 214 = month#38.#1
-   5:[A-Za-z] -> month#38.#2
-  Epsilon closure :
-    (self)
-
-NFA state 215 = month#38.#2
-   5:[A-Za-z] -> month#38.out
-  Epsilon closure :
-    (self)
-
-NFA state 216 = month#38.out
-  [(epsilon)] -> #59
-  Epsilon closure :
-    (self)
-    #59
-    ccyy#39.in
-
-NFA state 217 = #60
-  Tags : DS_DMY
-  Epsilon closure :
-    (self)
-
-NFA state 218 = ccyy#39.in
-   1:[1] -> ccyy#39.#1
-   4:[4-9] -> ccyy#39.#1
-   3:[3] -> ccyy#39.#1
-   2:[2] -> ccyy#39.#1
-  Epsilon closure :
-    (self)
-
-NFA state 219 = ccyy#39.#1
-   0:[0] -> ccyy#39.#2
-   4:[4-9] -> ccyy#39.#2
-   3:[3] -> ccyy#39.#2
-   2:[2] -> ccyy#39.#2
-   1:[1] -> ccyy#39.#2
-  Epsilon closure :
-    (self)
-
-NFA state 220 = ccyy#39.#2
-   0:[0] -> ccyy#39.#3
-   4:[4-9] -> ccyy#39.#3
-   3:[3] -> ccyy#39.#3
-   2:[2] -> ccyy#39.#3
-   1:[1] -> ccyy#39.#3
-  Epsilon closure :
-    (self)
-
-NFA state 221 = ccyy#39.#3
-   0:[0] -> ccyy#39.out
-   4:[4-9] -> ccyy#39.out
-   3:[3] -> ccyy#39.out
-   2:[2] -> ccyy#39.out
-   1:[1] -> ccyy#39.out
-  Epsilon closure :
-    (self)
-
-NFA state 222 = ccyy#39.out
-  [(epsilon)] -> #60
-  Epsilon closure :
-    (self)
-    #60
-
---------------------------------
-DFA structure before compression
---------------------------------
-DFA state 0
-  NFA states :
-    in
-    day#1.in
-    year#2.in
-    ccyy#3.in
-    scaled#4.in
-    month#5.in
-    day#7.in
-    month#9.in
-    month#10.in
-    year#12.in
-    month#14.in
-    ccyy#16.in
-    month#18.in
-    year#20.in
-    year#22.in
-    day#27.in
-    ccyy#30.in
-    ccyy#32.in
-    day#37.in
-
-  Forward route :
-   (START)->(HERE)
-  Transitions :
-    0:[0] -> 1
-    1:[1] -> 2
-    2:[2] -> 2
-    3:[3] -> 3
-    4:[4-9] -> 4
-    5:[A-Za-z] -> 5
-
-DFA state 1
-  NFA states :
-    year#2.#1
-    #5
-    #11
-    scaled#4.in
-    scaled#4.after_value
-    year#12.#1
-    year#20.#1
-    year#22.#1
-
-  Forward route : (from state 0)
-   (START)->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 6
-    1:[1] -> 6
-    2:[2] -> 6
-    3:[3] -> 6
-    4:[4-9] -> 6
-    5:[A-Za-z] -> 7
-
-DFA state 2
-  NFA states :
-    #1
-    day#1.#1
-    ccyy#3.#1
-    #5
-    #11
-    scaled#4.in
-    scaled#4.after_value
-    #21
-    month#6.in
-    day#7.#1
-    ccyy#16.#1
-    #43
-    month#25.in
-    day#27.#1
-    ccyy#30.#1
-    ccyy#32.#1
-    #55
-    month#35.in
-    day#37.#1
-
-  Forward route : (from state 0)
-   (START)->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 8
-    1:[1] -> 8
-    2:[2] -> 8
-    3:[3] -> 8
-    4:[4-9] -> 8
-    5:[A-Za-z] -> 9
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 3
-  NFA states :
-    #1
-    day#1.#2
-    year#2.#2
-    ccyy#3.#1
-    #5
-    #11
-    scaled#4.in
-    scaled#4.after_value
-    #21
-    month#6.in
-    day#7.#2
-    year#12.#2
-    ccyy#16.#1
-    year#20.#2
-    year#22.#2
-    #43
-    month#25.in
-    day#27.#2
-    ccyy#30.#1
-    ccyy#32.#1
-    #55
-    month#35.in
-    day#37.#2
-
-  Forward route : (from state 0)
-   (START)->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 8
-    1:[1] -> 8
-    2:[2] -> 10
-    3:[3] -> 10
-    4:[4-9] -> 10
-    5:[A-Za-z] -> 9
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 4
-  NFA states :
-    #1
-    year#2.#1
-    ccyy#3.#1
-    #5
-    #11
-    scaled#4.in
-    scaled#4.after_value
-    #21
-    month#6.in
-    year#12.#1
-    ccyy#16.#1
-    year#20.#1
-    year#22.#1
-    #43
-    month#25.in
-    ccyy#30.#1
-    ccyy#32.#1
-    #55
-    month#35.in
-
-  Forward route : (from state 0)
-   (START)->4:[4-9]->(HERE)
-  Transitions :
-    0:[0] -> 10
-    1:[1] -> 10
-    2:[2] -> 10
-    3:[3] -> 10
-    4:[4-9] -> 10
-    5:[A-Za-z] -> 9
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 5
-  NFA states :
-    month#5.#1
-    month#9.#1
-    month#10.#1
-    month#14.#1
-    month#18.#1
-
-  Forward route : (from state 0)
-   (START)->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 11
-
-DFA state 6
-  NFA states :
-    #3
-    year#2.out
-    #6
-    #12
-    scaled#4.in
-    scaled#4.after_value
-    #29
-    year#12.out
-    month#13.in
-    #37
-    year#20.out
-    month#21.in
-    #40
-    year#22.out
-    month#23.in
-
-  Forward route : (from state 1)
-   (START)->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 12
-    1:[1] -> 12
-    2:[2] -> 12
-    3:[3] -> 12
-    4:[4-9] -> 12
-    5:[A-Za-z] -> 13
-  NFA exit tags applying :
-    DS_Y
-  Attributes for <(DEFAULT)> : DS_Y
-
-DFA state 7
-  NFA states :
-    #19
-    scaled#4.out
-
-  Forward route : (from state 1)
-   (START)->0:[0]->5:[A-Za-z]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 8
-  NFA states :
-    #2
-    day#1.out
-    ccyy#3.#2
-    #6
-    #12
-    scaled#4.in
-    scaled#4.after_value
-    #23
-    day#7.out
-    month#8.in
-    ccyy#16.#2
-    #46
-    day#27.out
-    month#28.in
-    ccyy#30.#2
-    ccyy#32.#2
-    #58
-    day#37.out
-    month#38.in
-
-  Forward route : (from state 2)
-   (START)->1:[1]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 14
-    1:[1] -> 14
-    2:[2] -> 14
-    3:[3] -> 14
-    4:[4-9] -> 14
-    5:[A-Za-z] -> 15
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 9
-  NFA states :
-    #19
-    scaled#4.out
-    month#6.#1
-    month#25.#1
-    month#35.#1
-
-  Forward route : (from state 2)
-   (START)->1:[1]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 16
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 10
-  NFA states :
-    #3
-    year#2.out
-    ccyy#3.#2
-    #6
-    #12
-    scaled#4.in
-    scaled#4.after_value
-    #29
-    year#12.out
-    month#13.in
-    ccyy#16.#2
-    #37
-    year#20.out
-    month#21.in
-    #40
-    year#22.out
-    month#23.in
-    ccyy#30.#2
-    ccyy#32.#2
-
-  Forward route : (from state 3)
-   (START)->3:[3]->2:[2]->(HERE)
-  Transitions :
-    0:[0] -> 14
-    1:[1] -> 14
-    2:[2] -> 14
-    3:[3] -> 14
-    4:[4-9] -> 14
-    5:[A-Za-z] -> 13
-  NFA exit tags applying :
-    DS_Y
-  Attributes for <(DEFAULT)> : DS_Y
-
-DFA state 11
-  NFA states :
-    month#5.#2
-    month#9.#2
-    month#10.#2
-    month#14.#2
-    month#18.#2
-
-  Forward route : (from state 5)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 17
-
-DFA state 12
-  NFA states :
-    #7
-    #13
-    scaled#4.in
-    scaled#4.after_value
-
-  Forward route : (from state 6)
-   (START)->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 18
-    1:[1] -> 18
-    2:[2] -> 18
-    3:[3] -> 18
-    4:[4-9] -> 18
-    5:[A-Za-z] -> 7
-
-DFA state 13
-  NFA states :
-    #19
-    scaled#4.out
-    month#13.#1
-    month#21.#1
-    month#23.#1
-
-  Forward route : (from state 6)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 19
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 14
-  NFA states :
-    ccyy#3.#3
-    #7
-    #13
-    scaled#4.in
-    scaled#4.after_value
-    ccyy#16.#3
-    ccyy#30.#3
-    ccyy#32.#3
-
-  Forward route : (from state 8)
-   (START)->1:[1]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 20
-    1:[1] -> 20
-    2:[2] -> 20
-    3:[3] -> 20
-    4:[4-9] -> 20
-    5:[A-Za-z] -> 7
-
-DFA state 15
-  NFA states :
-    #19
-    scaled#4.out
-    month#8.#1
-    month#28.#1
-    month#38.#1
-
-  Forward route : (from state 8)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 21
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 16
-  NFA states :
-    month#6.#2
-    month#25.#2
-    month#35.#2
-
-  Forward route : (from state 9)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 22
-
-DFA state 17
-  NFA states :
-    #20
-    month#5.out
-    #25
-    month#9.out
-    #27
-    month#10.out
-    day#11.in
-    #31
-    month#14.out
-    year#15.in
-    #35
-    month#18.out
-    ccyy#19.in
-
-  Forward route : (from state 11)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    0:[0] -> 23
-    1:[1] -> 24
-    2:[2] -> 24
-    3:[3] -> 25
-    4:[4-9] -> 26
-  NFA exit tags applying :
-    DS_M
-  Attributes for <(DEFAULT)> : DS_M
-
-DFA state 18
-  NFA states :
-    #8
-    #14
-    scaled#4.in
-    scaled#4.after_value
-
-  Forward route : (from state 12)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 27
-    1:[1] -> 27
-    2:[2] -> 27
-    3:[3] -> 27
-    4:[4-9] -> 27
-    5:[A-Za-z] -> 7
-
-DFA state 19
-  NFA states :
-    month#13.#2
-    month#21.#2
-    month#23.#2
-
-  Forward route : (from state 13)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 28
-
-DFA state 20
-  NFA states :
-    #4
-    ccyy#3.out
-    #8
-    #14
-    scaled#4.in
-    scaled#4.after_value
-    #33
-    ccyy#16.out
-    month#17.in
-    #49
-    ccyy#30.out
-    month#31.in
-    #52
-    ccyy#32.out
-    month#33.in
-
-  Forward route : (from state 14)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 27
-    1:[1] -> 27
-    2:[2] -> 27
-    3:[3] -> 27
-    4:[4-9] -> 27
-    5:[A-Za-z] -> 29
-  NFA exit tags applying :
-    DS_Y
-  Attributes for <(DEFAULT)> : DS_Y
-
-DFA state 21
-  NFA states :
-    month#8.#2
-    month#28.#2
-    month#38.#2
-
-  Forward route : (from state 15)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 30
-
-DFA state 22
-  NFA states :
-    #22
-    month#6.out
-    #44
-    month#25.out
-    year#26.in
-    #56
-    month#35.out
-    ccyy#36.in
-
-  Forward route : (from state 16)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    0:[0] -> 31
-    1:[1] -> 32
-    2:[2] -> 32
-    3:[3] -> 33
-    4:[4-9] -> 34
-  NFA exit tags applying :
-    DS_DM
-  Attributes for <(DEFAULT)> : DS_DM
-
-DFA state 23
-  NFA states :
-    year#15.#1
-
-  Forward route : (from state 17)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 35
-    1:[1] -> 35
-    2:[2] -> 35
-    3:[3] -> 35
-    4:[4-9] -> 35
-
-DFA state 24
-  NFA states :
-    #26
-    day#11.#1
-    ccyy#19.#1
-
-  Forward route : (from state 17)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 36
-    1:[1] -> 36
-    2:[2] -> 36
-    3:[3] -> 36
-    4:[4-9] -> 36
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 25
-  NFA states :
-    #26
-    day#11.#2
-    year#15.#2
-    ccyy#19.#1
-
-  Forward route : (from state 17)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 36
-    1:[1] -> 36
-    2:[2] -> 37
-    3:[3] -> 37
-    4:[4-9] -> 37
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 26
-  NFA states :
-    #26
-    year#15.#1
-    ccyy#19.#1
-
-  Forward route : (from state 17)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-    0:[0] -> 37
-    1:[1] -> 37
-    2:[2] -> 37
-    3:[3] -> 37
-    4:[4-9] -> 37
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 27
-  NFA states :
-    #9
-    #15
-    scaled#4.in
-    scaled#4.after_value
-
-  Forward route : (from state 18)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 38
-    1:[1] -> 38
-    2:[2] -> 38
-    3:[3] -> 38
-    4:[4-9] -> 38
-    5:[A-Za-z] -> 7
-
-DFA state 28
-  NFA states :
-    #30
-    month#13.out
-    #38
-    month#21.out
-    #41
-    month#23.out
-    day#24.in
-
-  Forward route : (from state 19)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    1:[1] -> 39
-    2:[2] -> 39
-    3:[3] -> 40
-    4:[4-9] -> 41
-  NFA exit tags applying :
-    DS_YM
-  Attributes for <(DEFAULT)> : DS_YM
-
-DFA state 29
-  NFA states :
-    #19
-    scaled#4.out
-    month#17.#1
-    month#31.#1
-    month#33.#1
-
-  Forward route : (from state 20)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 42
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 30
-  NFA states :
-    #24
-    month#8.out
-    #47
-    month#28.out
-    year#29.in
-    #59
-    month#38.out
-    ccyy#39.in
-
-  Forward route : (from state 21)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    0:[0] -> 43
-    1:[1] -> 44
-    2:[2] -> 44
-    3:[3] -> 45
-    4:[4-9] -> 46
-  NFA exit tags applying :
-    DS_DM
-  Attributes for <(DEFAULT)> : DS_DM
-
-DFA state 31
-  NFA states :
-    year#26.#1
-
-  Forward route : (from state 22)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 47
-    1:[1] -> 47
-    2:[2] -> 47
-    3:[3] -> 47
-    4:[4-9] -> 47
-
-DFA state 32
-  NFA states :
-    ccyy#36.#1
-
-  Forward route : (from state 22)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 48
-    1:[1] -> 48
-    2:[2] -> 48
-    3:[3] -> 48
-    4:[4-9] -> 48
-
-DFA state 33
-  NFA states :
-    year#26.#2
-    ccyy#36.#1
-
-  Forward route : (from state 22)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 48
-    1:[1] -> 48
-    2:[2] -> 49
-    3:[3] -> 49
-    4:[4-9] -> 49
-
-DFA state 34
-  NFA states :
-    year#26.#1
-    ccyy#36.#1
-
-  Forward route : (from state 22)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-    0:[0] -> 49
-    1:[1] -> 49
-    2:[2] -> 49
-    3:[3] -> 49
-    4:[4-9] -> 49
-
-DFA state 35
-  NFA states :
-    #32
-    year#15.out
-
-  Forward route : (from state 23)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_MY
-  Attributes for <(DEFAULT)> : DS_MY
-
-DFA state 36
-  NFA states :
-    #28
-    day#11.out
-    ccyy#19.#2
-
-  Forward route : (from state 24)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 50
-    1:[1] -> 50
-    2:[2] -> 50
-    3:[3] -> 50
-    4:[4-9] -> 50
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 37
-  NFA states :
-    #32
-    year#15.out
-    ccyy#19.#2
-
-  Forward route : (from state 25)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->2:[2]->(HERE)
-  Transitions :
-    0:[0] -> 50
-    1:[1] -> 50
-    2:[2] -> 50
-    3:[3] -> 50
-    4:[4-9] -> 50
-  NFA exit tags applying :
-    DS_MY
-  Attributes for <(DEFAULT)> : DS_MY
-
-DFA state 38
-  NFA states :
-    #10
-    #16
-    scaled#4.in
-    scaled#4.after_value
-
-  Forward route : (from state 27)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 51
-    1:[1] -> 51
-    2:[2] -> 51
-    3:[3] -> 51
-    4:[4-9] -> 51
-    5:[A-Za-z] -> 7
-  NFA exit tags applying :
-    DS_YYMMDD
-  Attributes for <(DEFAULT)> : DS_YYMMDD
-
-DFA state 39
-  NFA states :
-    #39
-    day#24.#1
-
-  Forward route : (from state 28)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 52
-    1:[1] -> 52
-    2:[2] -> 52
-    3:[3] -> 52
-    4:[4-9] -> 52
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 40
-  NFA states :
-    #39
-    day#24.#2
-
-  Forward route : (from state 28)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 52
-    1:[1] -> 52
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 41
-  NFA states :
-    #39
-
-  Forward route : (from state 28)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 42
-  NFA states :
-    month#17.#2
-    month#31.#2
-    month#33.#2
-
-  Forward route : (from state 29)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 53
-
-DFA state 43
-  NFA states :
-    year#29.#1
-
-  Forward route : (from state 30)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 54
-    1:[1] -> 54
-    2:[2] -> 54
-    3:[3] -> 54
-    4:[4-9] -> 54
-
-DFA state 44
-  NFA states :
-    ccyy#39.#1
-
-  Forward route : (from state 30)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 55
-    1:[1] -> 55
-    2:[2] -> 55
-    3:[3] -> 55
-    4:[4-9] -> 55
-
-DFA state 45
-  NFA states :
-    year#29.#2
-    ccyy#39.#1
-
-  Forward route : (from state 30)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 55
-    1:[1] -> 55
-    2:[2] -> 56
-    3:[3] -> 56
-    4:[4-9] -> 56
-
-DFA state 46
-  NFA states :
-    year#29.#1
-    ccyy#39.#1
-
-  Forward route : (from state 30)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-    0:[0] -> 56
-    1:[1] -> 56
-    2:[2] -> 56
-    3:[3] -> 56
-    4:[4-9] -> 56
-
-DFA state 47
-  NFA states :
-    #45
-    year#26.out
-
-  Forward route : (from state 31)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-DFA state 48
-  NFA states :
-    ccyy#36.#2
-
-  Forward route : (from state 32)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 57
-    1:[1] -> 57
-    2:[2] -> 57
-    3:[3] -> 57
-    4:[4-9] -> 57
-
-DFA state 49
-  NFA states :
-    #45
-    year#26.out
-    ccyy#36.#2
-
-  Forward route : (from state 33)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->2:[2]->(HERE)
-  Transitions :
-    0:[0] -> 57
-    1:[1] -> 57
-    2:[2] -> 57
-    3:[3] -> 57
-    4:[4-9] -> 57
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-DFA state 50
-  NFA states :
-    ccyy#19.#3
-
-  Forward route : (from state 36)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 58
-    1:[1] -> 58
-    2:[2] -> 58
-    3:[3] -> 58
-    4:[4-9] -> 58
-
-DFA state 51
-  NFA states :
-    #17
-    scaled#4.in
-    scaled#4.after_value
-
-  Forward route : (from state 38)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 59
-    1:[1] -> 59
-    2:[2] -> 59
-    3:[3] -> 59
-    4:[4-9] -> 59
-    5:[A-Za-z] -> 7
-
-DFA state 52
-  NFA states :
-    #42
-    day#24.out
-
-  Forward route : (from state 39)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 53
-  NFA states :
-    #34
-    month#17.out
-    #50
-    month#31.out
-    #53
-    month#33.out
-    day#34.in
-
-  Forward route : (from state 42)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    1:[1] -> 60
-    2:[2] -> 60
-    3:[3] -> 61
-    4:[4-9] -> 62
-  NFA exit tags applying :
-    DS_YM
-  Attributes for <(DEFAULT)> : DS_YM
-
-DFA state 54
-  NFA states :
-    #48
-    year#29.out
-
-  Forward route : (from state 43)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-DFA state 55
-  NFA states :
-    ccyy#39.#2
-
-  Forward route : (from state 44)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 63
-    1:[1] -> 63
-    2:[2] -> 63
-    3:[3] -> 63
-    4:[4-9] -> 63
-
-DFA state 56
-  NFA states :
-    #48
-    year#29.out
-    ccyy#39.#2
-
-  Forward route : (from state 45)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->2:[2]->(HERE)
-  Transitions :
-    0:[0] -> 63
-    1:[1] -> 63
-    2:[2] -> 63
-    3:[3] -> 63
-    4:[4-9] -> 63
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-DFA state 57
-  NFA states :
-    ccyy#36.#3
-
-  Forward route : (from state 48)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 64
-    1:[1] -> 64
-    2:[2] -> 64
-    3:[3] -> 64
-    4:[4-9] -> 64
-
-DFA state 58
-  NFA states :
-    #36
-    ccyy#19.out
-
-  Forward route : (from state 50)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_MY
-  Attributes for <(DEFAULT)> : DS_MY
-
-DFA state 59
-  NFA states :
-    #18
-    scaled#4.in
-    scaled#4.after_value
-
-  Forward route : (from state 51)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 65
-    1:[1] -> 65
-    2:[2] -> 65
-    3:[3] -> 65
-    4:[4-9] -> 65
-    5:[A-Za-z] -> 7
-  NFA exit tags applying :
-    DS_YYMMDD
-  Attributes for <(DEFAULT)> : DS_YYMMDD
-
-DFA state 60
-  NFA states :
-    #51
-    day#34.#1
-
-  Forward route : (from state 53)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 66
-    1:[1] -> 66
-    2:[2] -> 66
-    3:[3] -> 66
-    4:[4-9] -> 66
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 61
-  NFA states :
-    #51
-    day#34.#2
-
-  Forward route : (from state 53)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 66
-    1:[1] -> 66
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 62
-  NFA states :
-    #51
-
-  Forward route : (from state 53)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 63
-  NFA states :
-    ccyy#39.#3
-
-  Forward route : (from state 55)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 67
-    1:[1] -> 67
-    2:[2] -> 67
-    3:[3] -> 67
-    4:[4-9] -> 67
-
-DFA state 64
-  NFA states :
-    #57
-    ccyy#36.out
-
-  Forward route : (from state 57)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-DFA state 65
-  NFA states :
-    scaled#4.in
-    scaled#4.after_value
-
-  Forward route : (from state 59)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 65
-    1:[1] -> 65
-    2:[2] -> 65
-    3:[3] -> 65
-    4:[4-9] -> 65
-    5:[A-Za-z] -> 7
-
-DFA state 66
-  NFA states :
-    #54
-    day#34.out
-
-  Forward route : (from state 60)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 67
-  NFA states :
-    #60
-    ccyy#39.out
-
-  Forward route : (from state 63)
-   (START)->1:[1]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-
-Entry states in DFA:
-Entry <(ONLY ENTRY)> : 0
-Searching for dead states...
-(no dead states found)
-
------------------------------
------- COMPRESSING DFA ------
------------------------------
-Old DFA state 0 becomes 0
-Old DFA state 1 becomes 1
-Old DFA state 2 becomes 2
-Old DFA state 3 becomes 3
-Old DFA state 4 becomes 4
-Old DFA state 5 becomes 5
-Old DFA state 6 becomes 6
-Old DFA state 7 becomes 7
-Old DFA state 8 becomes 8
-Old DFA state 9 becomes 9
-Old DFA state 10 becomes 10
-Old DFA state 11 becomes 11
-Old DFA state 12 becomes 12
-Old DFA state 13 becomes 13
-Old DFA state 14 becomes 14
-Old DFA state 15 becomes 9 (formerly 9)
-Old DFA state 16 becomes 15
-Old DFA state 17 becomes 16
-Old DFA state 18 becomes 17
-Old DFA state 19 becomes 18
-Old DFA state 20 becomes 19
-Old DFA state 21 becomes 15 (formerly 16)
-Old DFA state 22 becomes 20
-Old DFA state 23 becomes 21
-Old DFA state 24 becomes 22
-Old DFA state 25 becomes 23
-Old DFA state 26 becomes 24
-Old DFA state 27 becomes 25
-Old DFA state 28 becomes 26
-Old DFA state 29 becomes 13 (formerly 13)
-Old DFA state 30 becomes 20 (formerly 22)
-Old DFA state 31 becomes 27
-Old DFA state 32 becomes 28
-Old DFA state 33 becomes 29
-Old DFA state 34 becomes 30
-Old DFA state 35 becomes 31
-Old DFA state 36 becomes 32
-Old DFA state 37 becomes 33
-Old DFA state 38 becomes 34
-Old DFA state 39 becomes 35
-Old DFA state 40 becomes 36
-Old DFA state 41 becomes 37
-Old DFA state 42 becomes 18 (formerly 19)
-Old DFA state 43 becomes 27 (formerly 31)
-Old DFA state 44 becomes 28 (formerly 32)
-Old DFA state 45 becomes 29 (formerly 33)
-Old DFA state 46 becomes 30 (formerly 34)
-Old DFA state 47 becomes 38
-Old DFA state 48 becomes 39
-Old DFA state 49 becomes 40
-Old DFA state 50 becomes 21 (formerly 23)
-Old DFA state 51 becomes 41
-Old DFA state 52 becomes 37 (formerly 41)
-Old DFA state 53 becomes 26 (formerly 28)
-Old DFA state 54 becomes 38 (formerly 47)
-Old DFA state 55 becomes 39 (formerly 48)
-Old DFA state 56 becomes 40 (formerly 49)
-Old DFA state 57 becomes 27 (formerly 31)
-Old DFA state 58 becomes 31 (formerly 35)
-Old DFA state 59 becomes 42
-Old DFA state 60 becomes 35 (formerly 39)
-Old DFA state 61 becomes 36 (formerly 40)
-Old DFA state 62 becomes 37 (formerly 41)
-Old DFA state 63 becomes 27 (formerly 31)
-Old DFA state 64 becomes 38 (formerly 47)
-Old DFA state 65 becomes 43
-Old DFA state 66 becomes 37 (formerly 41)
-Old DFA state 67 becomes 38 (formerly 47)
-Entry <(ONLY ENTRY)>, formerly state 0, now state 0
--------------------------------
-DFA structure after compression
--------------------------------
-DFA state 0
-  Forward route :
-   (START)->(HERE)
-  Transitions :
-    0:[0] -> 1
-    1:[1] -> 2
-    2:[2] -> 2
-    3:[3] -> 3
-    4:[4-9] -> 4
-    5:[A-Za-z] -> 5
-
-DFA state 1
-  Forward route : (from state 0)
-   (START)->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 6
-    1:[1] -> 6
-    2:[2] -> 6
-    3:[3] -> 6
-    4:[4-9] -> 6
-    5:[A-Za-z] -> 7
-
-DFA state 2
-  Forward route : (from state 0)
-   (START)->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 8
-    1:[1] -> 8
-    2:[2] -> 8
-    3:[3] -> 8
-    4:[4-9] -> 8
-    5:[A-Za-z] -> 9
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 3
-  Forward route : (from state 0)
-   (START)->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 8
-    1:[1] -> 8
-    2:[2] -> 10
-    3:[3] -> 10
-    4:[4-9] -> 10
-    5:[A-Za-z] -> 9
-  Use state 2 as basis (3 fixups)
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 4
-  Forward route : (from state 0)
-   (START)->4:[4-9]->(HERE)
-  Transitions :
-    0:[0] -> 10
-    1:[1] -> 10
-    2:[2] -> 10
-    3:[3] -> 10
-    4:[4-9] -> 10
-    5:[A-Za-z] -> 9
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 5
-  Forward route : (from state 0)
-   (START)->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 11
-
-DFA state 6
-  Forward route : (from state 1)
-   (START)->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 12
-    1:[1] -> 12
-    2:[2] -> 12
-    3:[3] -> 12
-    4:[4-9] -> 12
-    5:[A-Za-z] -> 13
-  NFA exit tags applying :
-    DS_Y
-  Attributes for <(DEFAULT)> : DS_Y
-
-DFA state 7
-  Forward route : (from state 1)
-   (START)->0:[0]->5:[A-Za-z]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 8
-  Forward route : (from state 2)
-   (START)->1:[1]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 14
-    1:[1] -> 14
-    2:[2] -> 14
-    3:[3] -> 14
-    4:[4-9] -> 14
-    5:[A-Za-z] -> 9
-  NFA exit tags applying :
-    DS_D
-  Attributes for <(DEFAULT)> : DS_D
-
-DFA state 9
-  Forward route : (from state 2)
-   (START)->1:[1]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 15
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 10
-  Forward route : (from state 3)
-   (START)->3:[3]->2:[2]->(HERE)
-  Transitions :
-    0:[0] -> 14
-    1:[1] -> 14
-    2:[2] -> 14
-    3:[3] -> 14
-    4:[4-9] -> 14
-    5:[A-Za-z] -> 13
-  Use state 8 as basis (1 fixups)
-  NFA exit tags applying :
-    DS_Y
-  Attributes for <(DEFAULT)> : DS_Y
-
-DFA state 11
-  Forward route : (from state 5)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 16
-
-DFA state 12
-  Forward route : (from state 6)
-   (START)->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 17
-    1:[1] -> 17
-    2:[2] -> 17
-    3:[3] -> 17
-    4:[4-9] -> 17
-    5:[A-Za-z] -> 7
-
-DFA state 13
-  Forward route : (from state 6)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 18
-  NFA exit tags applying :
-    DS_SCALED
-  Attributes for <(DEFAULT)> : DS_SCALED
-
-DFA state 14
-  Forward route : (from state 8)
-   (START)->1:[1]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 19
-    1:[1] -> 19
-    2:[2] -> 19
-    3:[3] -> 19
-    4:[4-9] -> 19
-    5:[A-Za-z] -> 7
-
-DFA state 15
-  Forward route : (from state 9)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 20
-
-DFA state 16
-  Forward route : (from state 11)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    0:[0] -> 21
-    1:[1] -> 22
-    2:[2] -> 22
-    3:[3] -> 23
-    4:[4-9] -> 24
-  NFA exit tags applying :
-    DS_M
-  Attributes for <(DEFAULT)> : DS_M
-
-DFA state 17
-  Forward route : (from state 12)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 25
-    1:[1] -> 25
-    2:[2] -> 25
-    3:[3] -> 25
-    4:[4-9] -> 25
-    5:[A-Za-z] -> 7
-
-DFA state 18
-  Forward route : (from state 13)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    5:[A-Za-z] -> 26
-
-DFA state 19
-  Forward route : (from state 14)
-   (START)->1:[1]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 25
-    1:[1] -> 25
-    2:[2] -> 25
-    3:[3] -> 25
-    4:[4-9] -> 25
-    5:[A-Za-z] -> 13
-  Use state 17 as basis (1 fixups)
-  NFA exit tags applying :
-    DS_Y
-  Attributes for <(DEFAULT)> : DS_Y
-
-DFA state 20
-  Forward route : (from state 15)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    0:[0] -> 27
-    1:[1] -> 28
-    2:[2] -> 28
-    3:[3] -> 29
-    4:[4-9] -> 30
-  NFA exit tags applying :
-    DS_DM
-  Attributes for <(DEFAULT)> : DS_DM
-
-DFA state 21
-  Forward route : (from state 16)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 31
-    1:[1] -> 31
-    2:[2] -> 31
-    3:[3] -> 31
-    4:[4-9] -> 31
-
-DFA state 22
-  Forward route : (from state 16)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 32
-    1:[1] -> 32
-    2:[2] -> 32
-    3:[3] -> 32
-    4:[4-9] -> 32
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 23
-  Forward route : (from state 16)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 32
-    1:[1] -> 32
-    2:[2] -> 33
-    3:[3] -> 33
-    4:[4-9] -> 33
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 24
-  Forward route : (from state 16)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-    0:[0] -> 33
-    1:[1] -> 33
-    2:[2] -> 33
-    3:[3] -> 33
-    4:[4-9] -> 33
-  Use state 23 as basis (2 fixups)
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 25
-  Forward route : (from state 17)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 34
-    1:[1] -> 34
-    2:[2] -> 34
-    3:[3] -> 34
-    4:[4-9] -> 34
-    5:[A-Za-z] -> 7
-
-DFA state 26
-  Forward route : (from state 18)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->(HERE)
-  Transitions :
-    1:[1] -> 35
-    2:[2] -> 35
-    3:[3] -> 36
-    4:[4-9] -> 37
-  NFA exit tags applying :
-    DS_YM
-  Attributes for <(DEFAULT)> : DS_YM
-
-DFA state 27
-  Forward route : (from state 20)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 38
-    1:[1] -> 38
-    2:[2] -> 38
-    3:[3] -> 38
-    4:[4-9] -> 38
-
-DFA state 28
-  Forward route : (from state 20)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 39
-    1:[1] -> 39
-    2:[2] -> 39
-    3:[3] -> 39
-    4:[4-9] -> 39
-
-DFA state 29
-  Forward route : (from state 20)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 39
-    1:[1] -> 39
-    2:[2] -> 40
-    3:[3] -> 40
-    4:[4-9] -> 40
-
-DFA state 30
-  Forward route : (from state 20)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-    0:[0] -> 40
-    1:[1] -> 40
-    2:[2] -> 40
-    3:[3] -> 40
-    4:[4-9] -> 40
-  Use state 29 as basis (2 fixups)
-
-DFA state 31
-  Forward route : (from state 21)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_MY
-  Attributes for <(DEFAULT)> : DS_MY
-
-DFA state 32
-  Forward route : (from state 22)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 21
-    1:[1] -> 21
-    2:[2] -> 21
-    3:[3] -> 21
-    4:[4-9] -> 21
-  NFA exit tags applying :
-    DS_MD
-  Attributes for <(DEFAULT)> : DS_MD
-
-DFA state 33
-  Forward route : (from state 23)
-   (START)->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->2:[2]->(HERE)
-  Transitions :
-    0:[0] -> 21
-    1:[1] -> 21
-    2:[2] -> 21
-    3:[3] -> 21
-    4:[4-9] -> 21
-  Use state 32 as basis (0 fixups)
-  NFA exit tags applying :
-    DS_MY
-  Attributes for <(DEFAULT)> : DS_MY
-
-DFA state 34
-  Forward route : (from state 25)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 41
-    1:[1] -> 41
-    2:[2] -> 41
-    3:[3] -> 41
-    4:[4-9] -> 41
-    5:[A-Za-z] -> 7
-  NFA exit tags applying :
-    DS_YYMMDD
-  Attributes for <(DEFAULT)> : DS_YYMMDD
-
-DFA state 35
-  Forward route : (from state 26)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->(HERE)
-  Transitions :
-    0:[0] -> 37
-    1:[1] -> 37
-    2:[2] -> 37
-    3:[3] -> 37
-    4:[4-9] -> 37
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 36
-  Forward route : (from state 26)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->(HERE)
-  Transitions :
-    0:[0] -> 37
-    1:[1] -> 37
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 37
-  Forward route : (from state 26)
-   (START)->0:[0]->0:[0]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->4:[4-9]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_YMD
-  Attributes for <(DEFAULT)> : DS_YMD
-
-DFA state 38
-  Forward route : (from state 27)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->0:[0]->0:[0]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-DFA state 39
-  Forward route : (from state 28)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->1:[1]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 27
-    1:[1] -> 27
-    2:[2] -> 27
-    3:[3] -> 27
-    4:[4-9] -> 27
-
-DFA state 40
-  Forward route : (from state 29)
-   (START)->1:[1]->5:[A-Za-z]->5:[A-Za-z]->5:[A-Za-z]->3:[3]->2:[2]->(HERE)
-  Transitions :
-    0:[0] -> 27
-    1:[1] -> 27
-    2:[2] -> 27
-    3:[3] -> 27
-    4:[4-9] -> 27
-  Use state 39 as basis (0 fixups)
-  NFA exit tags applying :
-    DS_DMY
-  Attributes for <(DEFAULT)> : DS_DMY
-
-DFA state 41
-  Forward route : (from state 34)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 42
-    1:[1] -> 42
-    2:[2] -> 42
-    3:[3] -> 42
-    4:[4-9] -> 42
-    5:[A-Za-z] -> 7
-
-DFA state 42
-  Forward route : (from state 41)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 43
-    1:[1] -> 43
-    2:[2] -> 43
-    3:[3] -> 43
-    4:[4-9] -> 43
-    5:[A-Za-z] -> 7
-  NFA exit tags applying :
-    DS_YYMMDD
-  Attributes for <(DEFAULT)> : DS_YYMMDD
-
-DFA state 43
-  Forward route : (from state 42)
-   (START)->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->0:[0]->(HERE)
-  Transitions :
-    0:[0] -> 43
-    1:[1] -> 43
-    2:[2] -> 43
-    3:[3] -> 43
-    4:[4-9] -> 43
-    5:[A-Za-z] -> 7
-  Use state 42 as basis (0 fixups)
-
-
-Entry states in DFA:
-Entry <(ONLY ENTRY)> : 0
diff --git a/src/mairix/db.c b/src/mairix/db.c
@@ -1,1297 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006,2007,2009
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Handle complete database */
-
-#include "mairix.h"
-#include "reader.h"
-#include <ctype.h>
-#include <assert.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-struct sortable_token {/*{{{*/
-  char *text;
-  int index;
-};
-/*}}}*/
-static int compare_sortable_tokens(const void *a, const void *b)/*{{{*/
-{
-  const struct sortable_token *aa = (const struct sortable_token *) a;
-  const struct sortable_token *bb = (const struct sortable_token *) b;
-  int foo;
-  foo = strcmp(aa->text, bb->text);
-  if (foo) {
-    return foo;
-  } else {
-    if (aa->index < bb->index) return -1;
-    else if (aa->index > bb->index) return +1;
-    else return 0;
-  }
-}
-/*}}}*/
-static void check_toktable_enc_integrity(int n_msgs, struct toktable *table)/*{{{*/
-{
-  /* FIXME : Check reachability of tokens that are displaced from their natural
-   * hash bucket (if deletions have occurred during purge). */
-
-  int idx, incr;
-  int i, k;
-  unsigned char *j, *last_char;
-  int broken_chains = 0;
-  struct sortable_token *sort_list;
-  int any_duplicates;
-
-  for (i=0; i<table->size; i++) {
-    struct token *tok = table->tokens[i];
-    if (tok) {
-      idx = 0;
-      incr = 0;
-      last_char = tok->match0.msginfo + tok->match0.n;
-      for (j = tok->match0.msginfo; j < last_char; ) {
-        incr = read_increment(&j);
-        idx += incr;
-      }
-      if (idx != tok->match0.highest) {
-        fprintf(stderr, "broken encoding chain for token <%s>, highest=%ld\n", tok->text, tok->match0.highest);
-        fflush(stderr);
-        broken_chains = 1;
-      }
-      if (idx >= n_msgs) {
-        fprintf(stderr, "end of chain higher than number of message paths (%d) for token <%s>\n", n_msgs, tok->text);
-        fflush(stderr);
-        broken_chains = 1;
-      }
-    }
-  }
-
-  assert(!broken_chains);
-
-  /* Check there are no duplicated tokens in the table. */
-  sort_list = new_array(struct sortable_token, table->n);
-  k = 0;
-  for (i=0; i<table->size; i++) {
-    struct token *tok = table->tokens[i];
-    if (tok) {
-      sort_list[k].text = new_string(tok->text);
-      sort_list[k].index = i;
-      k++;
-    }
-  }
-  assert(k == table->n);
-
-  qsort(sort_list, table->n, sizeof(struct sortable_token), compare_sortable_tokens);
-  /* Check for uniqueness of neighbouring token texts */
-  any_duplicates = 0;
-  for (i=0; i<(table->n - 1); i++) {
-    if (!strcmp(sort_list[i].text, sort_list[i+1].text)) {
-      fprintf(stderr, "Token table contains duplicated token %s at indices %d and %d\n",
-               sort_list[i].text, sort_list[i].index, sort_list[i+1].index);
-      any_duplicates = 1;
-    }
-  }
-
-  /* release */
-  for (i=0; i<table->n; i++) {
-    free(sort_list[i].text);
-  }
-  free(sort_list);
-
-  if (any_duplicates) {
-    fprintf(stderr, "Token table contained duplicate entries, aborting\n");
-    assert(0);
-  }
-}
-/*}}}*/
-static int compare_strings(const void *a, const void *b)/*{{{*/
-{
-  const char **aa = (const char **) a;
-  const char **bb = (const char **) b;
-  return strcmp(*aa, *bb);
-}
-/*}}}*/
-static void check_message_path_integrity(struct database *db)/*{{{*/
-{
-  /* TODO : for now only checks integrity of non-mbox paths. */
-  /* Check there are no duplicates */
-  int i;
-  int n;
-  int has_duplicate = 0;
-
-  char **paths;
-  paths = new_array(char *, db->n_msgs);
-  for (i=0, n=0; i<db->n_msgs; i++) {
-    switch (db->type[i]) {
-      case MTY_DEAD:
-      case MTY_MBOX:
-        break;
-      case MTY_FILE:
-        paths[n++] = db->msgs[i].src.mpf.path;
-        break;
-    }
-  }
-
-  qsort(paths, n, sizeof(char *), compare_strings);
-
-  for (i=1; i<n; i++) {
-    if (!strcmp(paths[i-1], paths[i])) {
-      fprintf(stderr, "Path <%s> repeated\n", paths[i]);
-      has_duplicate = 1;
-    }
-  }
-
-  fflush(stderr);
-  assert(!has_duplicate);
-
-  free(paths);
-  return;
-}
-/*}}}*/
-void check_database_integrity(struct database *db)/*{{{*/
-{
-  if (verbose) fprintf(stderr, "Checking message path integrity\n");
-  check_message_path_integrity(db);
-
-  /* Just check encoding chains for now */
-  if (verbose) fprintf(stderr, "Checking to\n");
-  check_toktable_enc_integrity(db->n_msgs, db->to);
-  if (verbose) fprintf(stderr, "Checking cc\n");
-  check_toktable_enc_integrity(db->n_msgs, db->cc);
-  if (verbose) fprintf(stderr, "Checking from\n");
-  check_toktable_enc_integrity(db->n_msgs, db->from);
-  if (verbose) fprintf(stderr, "Checking subject\n");
-  check_toktable_enc_integrity(db->n_msgs, db->subject);
-  if (verbose) fprintf(stderr, "Checking body\n");
-  check_toktable_enc_integrity(db->n_msgs, db->body);
-  if (verbose) fprintf(stderr, "Checking attachment_name\n");
-  check_toktable_enc_integrity(db->n_msgs, db->attachment_name);
-}
-/*}}}*/
-struct database *new_database(unsigned int hash_key)/*{{{*/
-{
-  struct database *result = new(struct database);
-  struct timeval tv;
-  pid_t  pid;
-
-  result->to = new_toktable();
-  result->cc = new_toktable();
-  result->from = new_toktable();
-  result->subject = new_toktable();
-  result->body = new_toktable();
-  result->attachment_name = new_toktable();
-
-  result->msg_ids = new_toktable2();
-
-  if ( hash_key == CREATE_RANDOM_DATABASE_HASH )
-    {
-      gettimeofday(&tv, NULL);
-      pid = getpid();
-      hash_key = tv.tv_sec ^ (pid ^ (tv.tv_usec << 15));
-    }
-  result->hash_key = hash_key;
-
-  result->msgs = NULL;
-  result->type = NULL;
-  result->n_msgs = 0;
-  result->max_msgs = 0;
-
-  result->mboxen = NULL;
-  result->n_mboxen = 0;
-  result->max_mboxen = 0;
-
-  return result;
-}
-/*}}}*/
-void free_database(struct database *db)/*{{{*/
-{
-  int i;
-
-  free_toktable(db->to);
-  free_toktable(db->cc);
-  free_toktable(db->from);
-  free_toktable(db->subject);
-  free_toktable(db->body);
-  free_toktable(db->attachment_name);
-  free_toktable2(db->msg_ids);
-
-  if (db->msgs) {
-    for (i=0; i<db->n_msgs; i++) {
-      switch (db->type[i]) {
-        case MTY_DEAD:
-          break;
-        case MTY_MBOX:
-          break;
-        case MTY_FILE:
-          assert(db->msgs[i].src.mpf.path);
-          free(db->msgs[i].src.mpf.path);
-          break;
-      }
-    }
-    free(db->msgs);
-    free(db->type);
-  }
-
-  free(db);
-}
-/*}}}*/
-
-static int get_max (int a, int b) {/*{{{*/
-  return (a > b) ? a : b;
-}
-/*}}}*/
-static void import_toktable(char *data, unsigned int hash_key, int n_msgs, struct toktable_db *in, struct toktable *out)/*{{{*/
-{
-  int n, size, i;
-
-  n = in->n;
-  size = 1;
-  while (size < n) size <<= 1;
-  size <<= 1; /* safe hash table size */
-
-  out->size = size;
-  out->mask = size - 1;
-  out->n = n;
-  out->tokens = new_array(struct token *, size);
-  memset(out->tokens, 0, size * sizeof(struct token *));
-  out->hwm = (n + size) >> 1;
-
-  for (i=0; i<n; i++) {
-    unsigned int hash, index;
-    char *text;
-    unsigned char *enc;
-    int enc_len;
-    struct token *nt;
-    int enc_hi;
-    int idx, incr;
-    unsigned char *j;
-
-    /* Recover enc_len and enc_hi from the data */
-    enc = (unsigned char *) data + in->enc_offsets[i];
-    idx = 0;
-    for (j = enc; *j != 0xff; ) {
-      incr = read_increment(&j);
-      idx += incr;
-    }
-    enc_len = j - enc;
-    enc_hi = idx;
-
-    text = data + in->tok_offsets[i];
-    hash = hashfn((unsigned char *) text, strlen(text), hash_key);
-
-    nt = new(struct token);
-    nt->hashval = hash;
-    nt->text = new_string(text);
-    /* Allow a bit of headroom for adding more entries later */
-    nt->match0.max = get_max(16, enc_len + (enc_len >> 1));
-    nt->match0.n = enc_len;
-    nt->match0.highest = enc_hi;
-    assert(nt->match0.highest < n_msgs);
-    nt->match0.msginfo = new_array(unsigned char, nt->match0.max);
-    memcpy(nt->match0.msginfo, enc, nt->match0.n);
-
-    index = hash & out->mask;
-    while (out->tokens[index]) {
-      /* Audit to look for corrupt database with multiple entries for the same
-       * string. */
-      if (!strcmp(nt->text, out->tokens[index]->text)) {
-        fprintf(stderr, "\n!!! Corrupt token table found in database, token <%s> duplicated, aborting\n",
-            nt->text);
-        fprintf(stderr, "  Delete the database file and rebuild from scratch as a workaround\n");
-        /* No point going on - need to find out why the database got corrupted
-         * in the 1st place.  Workaround for user - rebuild database from
-         * scratch by deleting it then rerunning. */
-        unlock_and_exit(1);
-      }
-      ++index;
-      index &= out->mask;
-    }
-
-    out->tokens[index] = nt;
-  }
-}
-/*}}}*/
-static void import_toktable2(char *data, unsigned int hash_key, int n_msgs, struct toktable2_db *in, struct toktable2 *out)/*{{{*/
-{
-  int n, size, i;
-
-  n = in->n;
-  size = 1;
-  while (size < n) size <<= 1;
-  size <<= 1; /* safe hash table size */
-
-  out->size = size;
-  out->mask = size - 1;
-  out->n = n;
-  out->tokens = new_array(struct token2 *, size);
-  memset(out->tokens, 0, size * sizeof(struct token *));
-  out->hwm = (n + size) >> 1;
-
-  for (i=0; i<n; i++) {
-    unsigned int hash, index;
-    char *text;
-    struct token2 *nt;
-    unsigned char *enc0, *enc1;
-    int enc0_len, enc1_len;
-    int enc0_hi, enc1_hi;
-    int idx, incr;
-    unsigned char *j;
-
-/*{{{ do enc0*/
-    enc0 = (unsigned char *) data + in->enc0_offsets[i];
-    idx = 0;
-    for (j = enc0; *j != 0xff; ) {
-      incr = read_increment(&j);
-      idx += incr;
-    }
-    enc0_len = j - enc0;
-    enc0_hi = idx;
-/*}}}*/
-/*{{{ do enc1*/
-    enc1 = (unsigned char *) data + in->enc1_offsets[i];
-    idx = 0;
-    for (j = enc1; *j != 0xff; ) {
-      incr = read_increment(&j);
-      idx += incr;
-    }
-    enc1_len = j - enc1;
-    enc1_hi = idx;
-/*}}}*/
-
-    text = data + in->tok_offsets[i];
-    hash = hashfn((unsigned char *) text, strlen(text), hash_key);
-
-    nt = new(struct token2);
-    nt->hashval = hash;
-    nt->text = new_string(text);
-    /* Allow a bit of headroom for adding more entries later */
-    /*{{{ set up match0 chain */
-    nt->match0.max = get_max(16, enc0_len + (enc0_len >> 1));
-    nt->match0.n = enc0_len;
-    nt->match0.highest = enc0_hi;
-    assert(nt->match0.highest < n_msgs);
-    nt->match0.msginfo = new_array(unsigned char, nt->match0.max);
-    memcpy(nt->match0.msginfo, enc0, nt->match0.n);
-    /*}}}*/
-    /*{{{ set up match1 chain */
-    nt->match1.max = get_max(16, enc1_len + (enc1_len >> 1));
-    nt->match1.n = enc1_len;
-    nt->match1.highest = enc1_hi;
-    assert(nt->match1.highest < n_msgs);
-    nt->match1.msginfo = new_array(unsigned char, nt->match1.max);
-    memcpy(nt->match1.msginfo, enc1, nt->match1.n);
-    /*}}}*/
-
-    index = hash & out->mask;
-    while (out->tokens[index]) {
-      ++index;
-      index &= out->mask;
-    }
-
-    out->tokens[index] = nt;
-  }
-}
-/*}}}*/
-struct database *new_database_from_file(char *db_filename, int do_integrity_checks)/*{{{*/
-{
-  /* Read existing database from file for doing incremental update */
-  struct database *result;
-  struct read_db *input;
-  int i, n, N;
-
-  result = new_database( CREATE_RANDOM_DATABASE_HASH );
-  input = open_db(db_filename);
-  if (!input) {
-    /* Nothing to initialise */
-    if (verbose) printf("Database file was empty, creating a new database\n");
-    return result;
-  }
-
-  /* Build pathname information */
-  n = result->n_msgs = input->n_msgs;
-  result->max_msgs = input->n_msgs; /* let it be extended as-and-when */
-  result->msgs = new_array(struct msgpath, n);
-  result->type = new_array(enum message_type, n);
-
-  result->hash_key = input->hash_key;
-
-  /* Set up mbox structures */
-  N = result->n_mboxen = result->max_mboxen = input->n_mboxen;
-  result->mboxen = N ? (new_array(struct mbox, N)) : NULL;
-  for (i=0; i<N; i++) {
-    int nn;
-    if (input->mbox_paths_table[i]) {
-      result->mboxen[i].path = new_string(input->data + input->mbox_paths_table[i]);
-    } else {
-      /* mbox is dead. */
-      result->mboxen[i].path = NULL;
-    }
-    result->mboxen[i].file_mtime = input->mbox_mtime_table[i];
-    result->mboxen[i].file_size  = input->mbox_size_table[i];
-    nn = result->mboxen[i].n_msgs = input->mbox_entries_table[i];
-    result->mboxen[i].max_msgs = nn;
-    result->mboxen[i].start = new_array(off_t, nn);
-    result->mboxen[i].len   = new_array(size_t, nn);
-    result->mboxen[i].check_all = new_array(checksum_t, nn);
-    /* Copy the entire checksum table in one go. */
-    memcpy(result->mboxen[i].check_all,
-           input->data + input->mbox_checksum_table[i],
-           nn * sizeof(checksum_t));
-    result->mboxen[i].n_so_far = 0;
-  }
-
-  for (i=0; i<n; i++) {
-    switch (rd_msg_type(input, i)) {
-      case DB_MSG_DEAD:
-        result->type[i] = MTY_DEAD;
-        break;
-      case DB_MSG_FILE:
-        result->type[i] = MTY_FILE;
-        result->msgs[i].src.mpf.path = new_string(input->data + input->path_offsets[i]);
-        result->msgs[i].src.mpf.mtime = input->mtime_table[i];
-        result->msgs[i].src.mpf.size  = input->size_table[i];
-        break;
-      case DB_MSG_MBOX:
-        {
-          unsigned int mbi, msgi;
-          int n;
-          struct mbox *mb;
-          result->type[i] = MTY_MBOX;
-          decode_mbox_indices(input->path_offsets[i], &mbi, &msgi);
-          result->msgs[i].src.mbox.file_index = mbi;
-          mb = &result->mboxen[mbi];
-          assert(mb->n_so_far == msgi);
-          n = mb->n_so_far;
-          result->msgs[i].src.mbox.msg_index = n;
-          mb->start[n] = input->mtime_table[i];
-          mb->len[n] = input->size_table[i];
-          ++mb->n_so_far;
-        }
-
-        break;
-    }
-    result->msgs[i].seen    = (input->msg_type_and_flags[i] & FLAG_SEEN)    ? 1:0;
-    result->msgs[i].replied = (input->msg_type_and_flags[i] & FLAG_REPLIED) ? 1:0;
-    result->msgs[i].flagged = (input->msg_type_and_flags[i] & FLAG_FLAGGED) ? 1:0;
-    result->msgs[i].date  = input->date_table[i];
-    result->msgs[i].tid   = input->tid_table[i];
-  }
-
-  import_toktable(input->data, input->hash_key, result->n_msgs, &input->to, result->to);
-  import_toktable(input->data, input->hash_key, result->n_msgs, &input->cc, result->cc);
-  import_toktable(input->data, input->hash_key, result->n_msgs, &input->from, result->from);
-  import_toktable(input->data, input->hash_key, result->n_msgs, &input->subject, result->subject);
-  import_toktable(input->data, input->hash_key, result->n_msgs, &input->body, result->body);
-  import_toktable(input->data, input->hash_key, result->n_msgs, &input->attachment_name, result->attachment_name);
-  import_toktable2(input->data, input->hash_key, result->n_msgs, &input->msg_ids, result->msg_ids);
-
-  close_db(input);
-
-  if (do_integrity_checks) {
-    check_database_integrity(result);
-  }
-
-  return result;
-}
-/*}}}*/
-
-static void add_angled_terms(int file_index, unsigned int hash_key, struct toktable2 *table, int add_to_chain1, char *s)/*{{{*/
-{
-  char *left, *right;
-
-  if (s) {
-    left = strchr(s, '<');
-    while (left) {
-      right = strchr(left, '>');
-      if (right) {
-        *right = '\0';
-        add_token2_in_file(file_index, hash_key, left+1, table, add_to_chain1);
-        *right = '>'; /* restore */
-      } else {
-        break;
-      }
-      left = strchr(right, '<');
-    }
-  }
-}
-/*}}}*/
-
-/* Macro for what characters can make up token strings.
-
-   The following characters have special meanings:
-   0x2b +
-   0x2d -
-   0x2e .
-   0x40 @
-   0x5f _
-
-   since they can occur within email addresses and message IDs when considered
-   as a whole rather than as individual words.  Underscore (0x5f) is considered
-   a word-character always too.
-
-   */
-static unsigned char special_table[256] = {
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00-0f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10-1f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 0, /* 20-2f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30-3f */
-  2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-4f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, /* 50-5f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-6f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70-7f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-9f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0-af */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0-bf */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0-cf */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0-df */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0-ef */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* f0-ff */
-};
-
-#if 0
-#define CHAR_VALID(x,mask) (isalnum((unsigned char) x) || (special_table[(unsigned int)(unsigned char) x] & mask))
-#endif
-static inline int char_valid_p(char x, unsigned int mask)/*{{{*/
-{
-  unsigned char xx = (unsigned char) x;
-  if (isalnum(xx)) return 1;
-  else if (special_table[(unsigned int) xx] & mask) return 1;
-  else return 0;
-}
-/*}}}*/
-static void tokenise_string(int file_index, unsigned int hash_key, struct toktable *table, char *data, int match_mask)/*{{{*/
-{
-  char *ss, *es, old_es;
-  ss = data;
-  for (;;) {
-    while (*ss && !char_valid_p(*ss,match_mask)) ss++;
-    if (!*ss) break;
-    es = ss + 1;
-    while (*es && char_valid_p(*es,match_mask)) es++;
-
-    /* deal with token [ss,es) */
-    old_es = *es;
-    *es = '\0';
-    /* FIXME: Ought to do this by passing start and length - clean up later */
-    add_token_in_file(file_index, hash_key, ss, table);
-    *es = old_es;
-
-    if (!*es) break;
-    ss = es;
-  }
-}
-/*}}}*/
-static void tokenise_html_string(int file_index, unsigned int hash_key, struct toktable *table, char *data)/*{{{*/
-{
-  char *ss, *es, old_es;
-
-  /* FIXME : Probably want to rewrite this as an explicit FSM */
-
-  ss = data;
-  for (;;) {
-    /* Assume < and > are never valid token characters ! */
-    while (*ss && !char_valid_p(*ss, 1)) {
-      if (*ss++ == '<') {
-        /* Skip over HTML tag */
-        while (*ss && (*ss != '>')) ss++;
-      }
-    }
-    if (!*ss) break;
-
-    es = ss + 1;
-    while (*es && char_valid_p(*es, 1)) es++;
-
-    /* deal with token [ss,es) */
-    old_es = *es;
-    *es = '\0';
-    /* FIXME: Ought to do this by passing start and length - clean up later */
-    add_token_in_file(file_index, hash_key, ss, table);
-    *es = old_es;
-
-    if (!*es) break;
-    ss = es;
-  }
-}
-/*}}}*/
-void tokenise_message(int file_index, struct database *db, struct rfc822 *msg)/*{{{*/
-{
-  struct attachment *a;
-
-  /* Match on whole addresses in these headers as well as the individual words */
-  if (msg->hdrs.to) {
-    tokenise_string(file_index, db->hash_key, db->to, msg->hdrs.to, 1);
-    tokenise_string(file_index, db->hash_key, db->to, msg->hdrs.to, 2);
-  }
-  if (msg->hdrs.cc) {
-    tokenise_string(file_index, db->hash_key, db->cc, msg->hdrs.cc, 1);
-    tokenise_string(file_index, db->hash_key, db->cc, msg->hdrs.cc, 2);
-  }
-  if (msg->hdrs.from) {
-    tokenise_string(file_index, db->hash_key, db->from, msg->hdrs.from, 1);
-    tokenise_string(file_index, db->hash_key, db->from, msg->hdrs.from, 2);
-  }
-  if (msg->hdrs.subject) tokenise_string(file_index, db->hash_key, db->subject, msg->hdrs.subject, 1);
-
-  for (a=msg->atts.next; a!=&msg->atts; a=a->next) {
-    switch (a->ct) {
-      case CT_TEXT_PLAIN:
-        tokenise_string(file_index, db->hash_key, db->body, a->data.normal.bytes, 1);
-        break;
-      case CT_TEXT_HTML:
-        tokenise_html_string(file_index, db->hash_key, db->body, a->data.normal.bytes);
-        break;
-      case CT_MESSAGE_RFC822:
-        /* Just recurse for now - maybe we should have separate token tables
-         * for tokens occurring in embedded messages? */
-
-        if (a->data.rfc822) {
-          tokenise_message(file_index, db, a->data.rfc822);
-        }
-        break;
-      default:
-        /* Don't do anything - unknown text format or some nasty binary stuff.
-         * In future, we could have all kinds of 'plug-ins' here, e.g.
-         * something that can parse PDF to get the basic text strings out of
-         * the pages? */
-        break;
-    }
-
-    if (a->filename) {
-      add_token_in_file(file_index, db->hash_key, a->filename, db->attachment_name);
-    }
-
-  }
-
-  /* Deal with threading information */
-  add_angled_terms(file_index, db->hash_key, db->msg_ids, 1, msg->hdrs.message_id);
-  add_angled_terms(file_index, db->hash_key, db->msg_ids, 0, msg->hdrs.in_reply_to);
-  add_angled_terms(file_index, db->hash_key, db->msg_ids, 0, msg->hdrs.references);
-}
-/*}}}*/
-
-static void scan_maildir_flags(struct msgpath *m)/*{{{*/
-{
-  const char *p, *start;
-  start = m->src.mpf.path;
-  m->seen = 0;
-  m->replied = 0;
-  m->flagged = 0;
-  for (p=start; *p; p++) {}
-  for (p--; (p >= start) && ((*p) != ':'); p--) {}
-  if (p >= start) {
-    if (!strncmp(p, ":2,", 3)) {
-      p += 3;
-      while (*p) {
-        switch (*p) {
-          case 'F': m->flagged = 1; break;
-          case 'R': m->replied = 1; break;
-          case 'S': m->seen = 1; break;
-          default: break;
-        }
-        p++;
-      }
-    }
-  }
-}
-/*}}}*/
-static void scan_new_messages(struct database *db, int start_at)/*{{{*/
-{
-  int i;
-  for (i=start_at; i<db->n_msgs; i++) {
-    struct rfc822 *msg = NULL;
-    int len = strlen(db->msgs[i].src.mpf.path);
-
-    if (len > 10 && !strcmp(db->msgs[i].src.mpf.path + len - 11, "/.gitignore"))
-      continue;
-
-    switch (db->type[i]) {
-      case MTY_DEAD:
-        assert(0);
-        break;
-      case MTY_MBOX:
-        assert(0); /* Should never get here - mbox messages are scanned elsewhere. */
-        break;
-      case MTY_FILE:
-        if (verbose) fprintf(stderr, "Scanning <%s>\n", db->msgs[i].src.mpf.path);
-        msg = make_rfc822(db->msgs[i].src.mpf.path);
-        break;
-    }
-    if(msg)
-    {
-      db->msgs[i].date = msg->hdrs.date;
-      scan_maildir_flags(&db->msgs[i]);
-      tokenise_message(i, db, msg);
-      free_rfc822(msg);
-    }
-    else
-      fprintf(stderr, "Skipping %s (could not parse message)\n", db->msgs[i].src.mpf.path);
-  }
-}
-/*}}}*/
-
-static inline void set_bit(unsigned long *x, int n)/*{{{*/
-{
-  int set;
-  unsigned long mask;
-  set = (n >> 5);
-  mask = (1UL << (n & 31));
-  x[set] |= mask;
-}
-/*}}}*/
-static inline int isset_bit(unsigned long *x, int n)/*{{{*/
-{
-  int set;
-  unsigned long mask;
-  set = (n >> 5);
-  mask = (1UL << (n & 31));
-  return (x[set] & mask) ? 1 : 0;
-}
-/*}}}*/
-static int find_base(int *table, int index) {/*{{{*/
-  int a = index;
-
-  /* TODO : make this compress the path lengths down to the base entry */
-  while (table[a] != a) {
-    a = table[a];
-  }
-  return a;
-}
-/*}}}*/
-static void find_threading(struct database *db)/*{{{*/
-{
-
-  /* ix is a table mapping path array index to the lowest path array index that
-   * is known to share at least one message ID in its hdrs somewhere (i.e. they
-   * must be in the same thread) */
-  int *ix;
-
-  int i, m, np, nm, sm;
-  int next_tid;
-
-  np = db->n_msgs;
-  nm = db->msg_ids->n;
-  sm = db->msg_ids->size;
-
-  ix = new_array(int, np);
-  for (i=0; i<np; i++) {
-    ix[i] = i; /* default - every message in a thread of its own */
-  }
-
-  for (m=0; m<sm; m++) {
-    struct token2 *tok = db->msg_ids->tokens[m];
-    if (tok) {
-      unsigned char *j = tok->match0.msginfo;
-      unsigned char *last_char = j + tok->match0.n;
-      int cur = 0, incr, first=1;
-      int new_base=-1, old_base;
-      while (j < last_char) {
-        incr = read_increment(&j);
-        cur += incr;
-        if (first) {
-          new_base = find_base(ix, cur);
-          first = 0;
-        } else {
-          old_base = find_base(ix, cur);
-          if (old_base < new_base) {
-            ix[new_base] = old_base;
-            new_base = old_base;
-          } else if (old_base > new_base) {
-            assert(new_base != -1);
-            ix[old_base] = new_base;
-          }
-        }
-      }
-    }
-  }
-
-  /* Now make each entry point directly to its base */
-  for (i=0; i<np; i++) {
-    if (ix[i] != i) {
-      /* Sure to work as we're going up from the bottom */
-      ix[i] = ix[ix[i]];
-    }
-  }
-
-  /* Now allocate contiguous thread group numbers */
-  next_tid = 0;
-  for (i=0; i<np; i++) {
-    if (ix[i] == i) {
-      db->msgs[i].tid = next_tid++;
-    } else {
-      db->msgs[i].tid = db->msgs[ix[i]].tid;
-    }
-  }
-
-  free(ix);
-  return;
-}
-/*}}}*/
-static int lookup_msgpath(struct msgpath *sorted_paths, int n_msgs, char *key)/*{{{*/
-{
-  /* Implement bisection search */
- int l, h, m, r;
- l = 0, h = n_msgs;
- m = -1;
- while (h > l) {
-   m = (h + l) >> 1;
-   /* Should only get called on 'file' type messages - TBC */
-   r = strcmp(sorted_paths[m].src.mpf.path, key);
-   if (r == 0) break;
-   if (l == m) return -1;
-   if (r > 0) h = m;
-   else       l = m;
- }
- return m;
-}
-/*}}}*/
-void maybe_grow_message_arrays(struct database *db)/*{{{*/
-{
-  if (db->n_msgs == db->max_msgs) {
-    if (db->max_msgs <= 128) {
-      db->max_msgs = 256;
-    } else {
-      db->max_msgs += (db->max_msgs >> 1);
-    }
-    db->msgs  = grow_array(struct msgpath,    db->max_msgs, db->msgs);
-    db->type  = grow_array(enum message_type, db->max_msgs, db->type);
-  }
-}
-/*}}}*/
-static void add_msg_path(struct database *db, char *path, time_t mtime, size_t message_size)/*{{{*/
-{
-  maybe_grow_message_arrays(db);
-  db->type[db->n_msgs] = MTY_FILE;
-  db->msgs[db->n_msgs].src.mpf.path = new_string(path);
-  db->msgs[db->n_msgs].src.mpf.mtime = mtime;
-  db->msgs[db->n_msgs].src.mpf.size = message_size;
-  ++db->n_msgs;
-}
-/*}}}*/
-
-static int do_stat(struct msgpath *mp)/*{{{*/
-{
-  struct stat sb;
-  int status;
-  status = stat(mp->src.mpf.path, &sb);
-  if ((status < 0) ||
-      !S_ISREG(sb.st_mode)) {
-    return 0;
-  } else {
-    mp->src.mpf.mtime = sb.st_mtime;
-    mp->src.mpf.size = sb.st_size;
-    return 1;
-  }
-}
-/*}}}*/
-int update_database(struct database *db, struct msgpath *sorted_paths, int n_msgs, int do_fast_index)/*{{{*/
-{
-  /* The incoming list must be sorted into order, to make binary searching
-   * possible.  We search for each existing path in the incoming sorted array.
-   * If the date differs, or the file no longer exist, the existing database
-   * entry for that file is nulled.  (These are only recovered if the database
-   * is actively compressed.)  If the date differed, a new entry for the file
-   * is put at the end of the list.  Similarly, any new file goes at the end.
-   * These new entries are all rescanned to find tokens and add them to the
-   * database. */
-
-  char *file_in_db, *file_in_new_list;
-  int matched_index;
-  int i, new_entries_start_at;
-  int any_new, n_newly_pruned, n_already_dead;
-  int status;
-
-  file_in_db = new_array(char, n_msgs);
-  file_in_new_list = new_array(char, db->n_msgs);
-  bzero(file_in_db, n_msgs);
-  bzero(file_in_new_list, db->n_msgs);
-
-  n_already_dead = 0;
-  n_newly_pruned = 0;
-
-  for (i=0; i<db->n_msgs; i++) {
-    switch (db->type[i]) {
-      case MTY_FILE:
-        matched_index = lookup_msgpath(sorted_paths, n_msgs, db->msgs[i].src.mpf.path);
-        if (matched_index >= 0) {
-          if (do_fast_index) {
-            /* Assume the presence of a matching path is good enough without
-             * even bothering to stat the file that's there now. */
-            file_in_db[matched_index] = 1;
-            file_in_new_list[i] = 1;
-          } else {
-            status = do_stat(sorted_paths + matched_index);
-            if (status) {
-              if (sorted_paths[matched_index].src.mpf.mtime == db->msgs[i].src.mpf.mtime) {
-                /* Treat stale files as though the path has changed. */
-                file_in_db[matched_index] = 1;
-                file_in_new_list[i] = 1;
-              }
-            } else {
-              /* This path will get treated as dead, and be re-stated below.
-               * When that stat fails, the path won't get added to the db. */
-            }
-          }
-        }
-        break;
-      case MTY_MBOX:
-        /* Nothing to do on this pass. */
-        break;
-      case MTY_DEAD:
-        break;
-    }
-  }
-
-  /* Add new entries to database */
-  new_entries_start_at = db->n_msgs;
-
-  for (i=0; i<db->n_msgs; i++) {
-    /* Weed dead entries */
-    switch (db->type[i]) {
-      case MTY_FILE:
-        if (!file_in_new_list[i]) {
-          free(db->msgs[i].src.mpf.path);
-          db->msgs[i].src.mpf.path = NULL;
-          db->type[i] = MTY_DEAD;
-          ++n_newly_pruned;
-        }
-        break;
-      case MTY_MBOX:
-        {
-          int msg_index, file_index, number_valid;
-          int mbox_valid;
-          msg_index = db->msgs[i].src.mbox.msg_index;
-          file_index = db->msgs[i].src.mbox.file_index;
-          assert (file_index < db->n_mboxen);
-          mbox_valid = (db->mboxen[file_index].path) ? 1 : 0;
-          number_valid = db->mboxen[file_index].n_old_msgs_valid;
-          if (!mbox_valid || (msg_index >= number_valid)) {
-            db->type[i] = MTY_DEAD;
-            ++n_newly_pruned;
-          }
-        }
-        break;
-      case MTY_DEAD:
-        /* already dead */
-        ++n_already_dead;
-        break;
-    }
-  }
-
-  if (verbose) {
-    fprintf(stderr, "%d newly dead messages, %d messages now dead in total\n", n_newly_pruned, n_newly_pruned+n_already_dead);
-  }
-
-  any_new = 0;
-  for (i=0; i<n_msgs; i++) {
-    if (!file_in_db[i]) {
-      int status;
-      any_new = 1;
-      /* The 'sorted_paths' array is only used for file-per-message folders. */
-      status = do_stat(sorted_paths + i);
-      if (status) {
-        /* We only add files that could be successfully stat()'d as regular
-         * files. */
-        add_msg_path(db, sorted_paths[i].src.mpf.path, sorted_paths[i].src.mpf.mtime, sorted_paths[i].src.mpf.size);
-      } else {
-        fprintf(stderr, "Cannot add '%s' to database; stat() failed\n", sorted_paths[i].src.mpf.path);
-      }
-    }
-  }
-
-  if (any_new) {
-    scan_new_messages(db, new_entries_start_at);
-  }
-
-  /* Add newly found mbox messages. */
-  any_new |= add_mbox_messages(db);
-
-  if (any_new) {
-    find_threading(db);
-  } else {
-    if (verbose) fprintf(stderr, "No new messages found\n");
-  }
-
-  free(file_in_db);
-  free(file_in_new_list);
-
-  return any_new || (n_newly_pruned > 0);
-}
-/*}}}*/
-static void recode_encoding(struct matches *m, int *new_idx)/*{{{*/
-{
-  unsigned char *new_enc, *old_enc;
-  unsigned char *j, *last_char;
-  int incr, idx, n_idx;
-
-  old_enc = m->msginfo;
-  j = old_enc;
-  last_char = old_enc + m->n;
-
-  new_enc = new_array(unsigned char, m->max); /* Probably not bigger than this. */
-  m->n = 0;
-  m->highest = 0;
-  m->msginfo = new_enc;
-  idx = 0;
-
-  while (j < last_char) {
-    incr = read_increment(&j);
-    idx += incr;
-    n_idx = new_idx[idx];
-    if (n_idx >= 0) {
-      check_and_enlarge_encoding(m);
-      insert_index_on_encoding(m, n_idx);
-    }
-  }
-  free(old_enc);
-}
-/*}}}*/
-static void recode_toktable(struct toktable *tbl, int *new_idx)/*{{{*/
-{
-  /* Re-encode the vectors according to the new path indices */
-  int i;
-  int any_dead = 0;
-  int any_moved, pass;
-
-  for (i=0; i<tbl->size; i++) {
-    struct token *tok = tbl->tokens[i];
-    if (tok) {
-      recode_encoding(&tok->match0, new_idx);
-      if (tok->match0.n == 0) {
-        /* Delete this token.  Gotcha - there may be tokens further on in the
-         * array that didn't get their natural hash bucket due to collisions.
-         * Need to shuffle such tokens up to guarantee that the buckets between
-         * the natural one and the one where they are now are all occupied, to
-         * prevent their lookups failing. */
-
-#if 0
-        fprintf(stderr, "Token <%s> (bucket %d) no longer has files containing it, deleting\n", tok->text, i);
-#endif
-        free_token(tok);
-        tbl->tokens[i] = NULL;
-        --tbl->n; /* Maintain number in use counter */
-        any_dead = 1;
-      }
-
-    }
-  }
-
-
-  if (any_dead) {
-    /* Now close gaps.  This has to be done in a second pass, otherwise we get a
-     * problem with moving entries that need deleting back before the current
-       scan point. */
-
-    pass = 1;
-    for (;;) {
-      int i;
-
-      if (verbose) {
-        fprintf(stderr, "Pass %d\n", pass);
-      }
-
-      any_moved = 0;
-
-      for (i=0; i<tbl->size; i++) {
-        if (tbl->tokens[i]) {
-          int nat_bucket_i;
-          nat_bucket_i = tbl->tokens[i]->hashval & tbl->mask;
-          if (nat_bucket_i != i) {
-            /* Find earliest bucket that we could move i to */
-            int j = nat_bucket_i;
-            while (j != i) {
-              if (!tbl->tokens[j]) {
-                /* put it here */
-#if 0
-                fprintf(stderr, "Moved <%s> from bucket %d to %d (natural bucket %d)\n", tbl->tokens[i]->text, i, j, nat_bucket_i);
-#endif
-                tbl->tokens[j] = tbl->tokens[i];
-                tbl->tokens[i] = NULL;
-                any_moved = 1;
-                break;
-              } else {
-                j++;
-                j &= tbl->mask;
-              }
-            }
-            if (tbl->tokens[i]) {
-#if 0
-              fprintf(stderr, "NOT moved <%s> from bucket %d (natural bucket %d)\n", tbl->tokens[i]->text, i, nat_bucket_i);
-#endif
-            }
-          }
-        }
-      }
-
-      if (!any_moved) break;
-      pass++;
-    }
-  }
-}
-/*}}}*/
-static void recode_toktable2(struct toktable2 *tbl, int *new_idx)/*{{{*/
-{
-  /* Re-encode the vectors according to the new path indices */
-  int i;
-  int any_dead = 0;
-  int any_moved, pass;
-
-  for (i=0; i<tbl->size; i++) {
-    struct token2 *tok = tbl->tokens[i];
-    if (tok) {
-      recode_encoding(&tok->match0, new_idx);
-      recode_encoding(&tok->match1, new_idx);
-      if ((tok->match0.n == 0) && (tok->match1.n == 0)) {
-        /* Delete this token.  Gotcha - there may be tokens further on in the
-         * array that didn't get their natural hash bucket due to collisions.
-         * Need to shuffle such tokens up to guarantee that the buckets between
-         * the natural one and the one where they are now are all occupied, to
-         * prevent their lookups failing. */
-
-#if 0
-        fprintf(stderr, "Token <%s> (bucket %d) no longer has files containing it, deleting\n", tok->text, i);
-#endif
-        free_token2(tok);
-        tbl->tokens[i] = NULL;
-        --tbl->n; /* Maintain number in use counter */
-        any_dead = 1;
-      }
-    }
-  }
-
-  if (any_dead) {
-    /* Now close gaps.  This has to be done in a second pass, otherwise we get a
-     * problem with moving entries that need deleting back before the current
-       scan point. */
-
-    pass = 1;
-    for (;;) {
-      int i;
-
-      if (verbose) {
-        fprintf(stderr, "Pass %d\n", pass);
-      }
-
-      any_moved = 0;
-
-      for (i=0; i<tbl->size; i++) {
-        if (tbl->tokens[i]) {
-          int nat_bucket_i;
-          nat_bucket_i = tbl->tokens[i]->hashval & tbl->mask;
-          if (nat_bucket_i != i) {
-            /* Find earliest bucket that we could move i to */
-            int j = nat_bucket_i;
-            while (j != i) {
-              if (!tbl->tokens[j]) {
-                /* put it here */
-#if 0
-                fprintf(stderr, "Moved <%s> from bucket %d to %d (natural bucket %d)\n", tbl->tokens[i]->text, i, j, nat_bucket_i);
-#endif
-                tbl->tokens[j] = tbl->tokens[i];
-                tbl->tokens[i] = NULL;
-                any_moved = 1;
-                break;
-              } else {
-                j++;
-                j &= tbl->mask;
-              }
-            }
-            if (tbl->tokens[i]) {
-#if 0
-              fprintf(stderr, "NOT moved <%s> from bucket %d (natural bucket %d)\n", tbl->tokens[i]->text, i, nat_bucket_i);
-#endif
-            }
-          }
-        }
-      }
-
-      if (!any_moved) break;
-      pass++;
-    }
-  }
-}
-/*}}}*/
-int cull_dead_messages(struct database *db, int do_integrity_checks)/*{{{*/
-{
-  /* Return true if any culled */
-
-  int *new_idx, i, j, n_old;
-  int any_culled = 0;
-
-  /* Check db is OK before we start on this. (Check afterwards is done in the
-   * writer.c code.) */
-  if (do_integrity_checks) {
-    check_database_integrity(db);
-  }
-
-  if (verbose) {
-    fprintf(stderr, "Culling dead messages\n");
-  }
-
-  n_old = db->n_msgs;
-
-  new_idx = new_array(int, n_old);
-  for (i=0, j=0; i<n_old; i++) {
-    switch (db->type[i]) {
-      case MTY_FILE:
-      case MTY_MBOX:
-        new_idx[i] = j++;
-        break;
-      case MTY_DEAD:
-        new_idx[i] = -1;
-        any_culled = 1;
-        break;
-    }
-  }
-
-  recode_toktable(db->to, new_idx);
-  recode_toktable(db->cc, new_idx);
-  recode_toktable(db->from, new_idx);
-  recode_toktable(db->subject, new_idx);
-  recode_toktable(db->body, new_idx);
-  recode_toktable(db->attachment_name, new_idx);
-  recode_toktable2(db->msg_ids, new_idx);
-
-  /* And crunch down the filename table */
-  for (i=0, j=0; i<n_old; i++) {
-    switch (db->type[i]) {
-      case MTY_DEAD:
-        break;
-      case MTY_FILE:
-      case MTY_MBOX:
-        if (i > j) {
-          db->msgs[j] = db->msgs[i];
-          db->type[j]  = db->type[i];
-        }
-        j++;
-        break;
-    }
-  }
-  db->n_msgs = j;
-
-  free(new_idx);
-
-  /* .. and cull dead mboxen */
-  cull_dead_mboxen(db);
-
-  return any_culled;
-}
-/*}}}*/
diff --git a/src/mairix/dfasyn/COPYING b/src/mairix/dfasyn/COPYING
@@ -1,339 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/src/mairix/dfasyn/INSTALL b/src/mairix/dfasyn/INSTALL
@@ -1,19 +0,0 @@
-There is no real configure mechanism (yet).
-
-To build the program
-
-    make
-
-To install the program (perhaps as root)
-
-    make prefix=/usr/local install
-
-or as yourself you might do
-
-    make prefix=$HOME install
-
-or if your distribution puts manpages in /usr/share/man, you might do
-
-    make prefix=/usr/local mandir=/usr/share/man install
-
-# vim:et:sw=4
diff --git a/src/mairix/dfasyn/Makefile b/src/mairix/dfasyn/Makefile
@@ -1,62 +0,0 @@
-# Makefile for NFA->DFA conversion utility
-#
-# Copyright (C) Richard P. Curnow  2000-2001,2003,2005,2006,2007
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-# 
-# 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.
-#
-
-CC=gcc
-#CFLAGS=-g -Wall
-#CFLAGS=-O2 -pg
-CFLAGS=-Wall
-prefix?=/usr/local
-bindir=$(prefix)/bin
-mandir?=$(prefix)/man
-man1dir=$(mandir)/man1
-man5dir=$(mandir)/man5
-
-OBJ = dfasyn.o parse.o scan.o \
-	tokens.o abbrevs.o charclass.o \
-	stimulus.o \
-	blocks.o states.o \
-	n2d.o expr.o evaluator.o \
-	tabcompr.o compdfa.o
-
-all : dfasyn
-
-install : all
-	[ -d $(bindir) ] || mkdir -p $(bindir)
-	[ -d $(man1dir) ] || mkdir -p $(man1dir)
-	[ -d $(man5dir) ] || mkdir -p $(man5dir)
-	cp dfasyn $(bindir)
-	cp dfasyn.1 $(man1dir)
-	cp dfasyn.5 $(man5dir)
-
-dfasyn : $(OBJ)
-	$(CC) $(CFLAGS) -o dfasyn $(OBJ)
-
-parse.c parse.h : parse.y
-	bison -v -d -o parse.c parse.y
-
-parse.o : parse.c dfasyn.h
-
-scan.c : scan.l
-	flex -t -s scan.l > scan.c
-
-scan.o : scan.c parse.h dfasyn.h
-
-$(OBJ) : dfasyn.h
-
-clean:
-	rm -f dfasyn *.o scan.c parse.c parse.h parse.output
-
diff --git a/src/mairix/dfasyn/NEWS b/src/mairix/dfasyn/NEWS
@@ -1,5 +0,0 @@
-New in version 0.2
-==================
-
-* Added README and NEWS files
-
diff --git a/src/mairix/dfasyn/README b/src/mairix/dfasyn/README
@@ -1,8 +0,0 @@
-dfasyn is a tool for constructing state machines.  The input language allows a
-lot of generality.  For example, it allows repeated elements to be specified
-where the items have constraints between the end of one and the start of the
-next.   (I could not find a way to define such an automaton in the lex/flex
-input language, which prompted the writing of the tool.)  Currently, you must
-do a fair amount of work yourself to build a parser around the resulting state
-machine.
-
diff --git a/src/mairix/dfasyn/abbrevs.c b/src/mairix/dfasyn/abbrevs.c
@@ -1,67 +0,0 @@
-/***************************************
-  Handle state-related stuff
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2000-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-
-static struct Abbrev *abbrevtable=NULL;
-static int nabbrevs = 0;
-static int maxabbrevs = 0;
-
-static void grow_abbrevs(void)/*{{{*/
-{
-  maxabbrevs += 32;
-  abbrevtable = resize_array(struct Abbrev, abbrevtable, maxabbrevs);
-}
-/*}}}*/
-struct Abbrev * create_abbrev(const char *name, struct StimulusList *stimuli)/*{{{*/
-{
-  struct Abbrev *result;
-  if (nabbrevs == maxabbrevs) {
-    grow_abbrevs();
-  }
-  result = abbrevtable + (nabbrevs++);
-  result->lhs = new_string(name);
-  result->stimuli = stimuli;
-  return result;
-}
-/*}}}*/
-struct Abbrev * lookup_abbrev(char *name)/*{{{*/
-{
-  int found = -1;
-  int i;
-  struct Abbrev *result = NULL;
-  /* Scan table in reverse order.  If a name has been redefined,
-     make sure the most recent definition is picked up. */
-  for (i=nabbrevs-1; i>=0; i--) {
-    if (!strcmp(abbrevtable[i].lhs, name)) {
-      found = i;
-      result = abbrevtable + found;
-      break;
-    }
-  }
-
-  return result;
-}
-/*}}}*/
-
diff --git a/src/mairix/dfasyn/blocks.c b/src/mairix/dfasyn/blocks.c
@@ -1,168 +0,0 @@
-/***************************************
-  Handle blocks
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2000-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-
-
-static Block **blocks = NULL;
-static int nblocks = 0;
-static int maxblocks = 0;
-
-/* ================================================================= */
-
-static void grow_blocks(void)/*{{{*/
-{
-  maxblocks += 32;
-  blocks = resize_array(Block*, blocks, maxblocks);
-}
-/*}}}*/
-static Block * create_block(char *name)/*{{{*/
-{
-  Block *result;
-  int i;
-
-  if (nblocks == maxblocks) {
-    grow_blocks();
-  }
-
-#if 0
-  /* Not especially useful to show this */
-  if (verbose) {
-    fprintf(stderr, " %s", name);
-  }
-#endif
-
-  result = blocks[nblocks++] = new(Block);
-  result->name = new_string(name);
-  for (i=0; i<HASH_BUCKETS; i++) {
-    result->state_hash[i].states = NULL;
-    result->state_hash[i].nstates = 0;
-    result->state_hash[i].maxstates = 0;
-  }
-  result->states = NULL;
-  result->nstates = result->maxstates = 0;
-  result->eclo = NULL;
-
-  result->subcount = 1;
-  result->subblockcount = 1;
-  return result;
-}
-/*}}}*/
-Block * lookup_block(char *name, int create)/*{{{*/
-{
-  Block *found = NULL;
-  int i;
-  for (i=0; i<nblocks; i++) {
-    if (!strcmp(blocks[i]->name, name)) {
-      found = blocks[i];
-      break;
-    }
-  }
-
-  switch (create) {
-    case USE_OLD_MUST_EXIST:
-      if (!found) {
-        fprintf(stderr, "Could not find block '%s' to instantiate\n", name);
-        exit(1);
-      }
-      break;
-    case CREATE_MUST_NOT_EXIST:
-      if (found) {
-        fprintf(stderr, "Already have a block called '%s', cannot redefine\n", name);
-        exit(1);
-      } else {
-        found = create_block(name);
-      }
-      break;
-    case CREATE_OR_USE_OLD:
-      if (!found) {
-        found = create_block(name);
-      }
-      break;
-  }
-
-  return found;
-}
-/*}}}*/
-/* ================================================================= */
-void instantiate_block(Block *curblock, char *block_name, char *instance_name)/*{{{*/
-{
-  Block *master = lookup_block(block_name, USE_OLD_MUST_EXIST);
-  char namebuf[1024];
-  int i;
-  for (i=0; i<master->nstates; i++) {
-    State *s = master->states[i];
-    State *new_state;
-    TransList *tl;
-    Stringlist *sl, *ex;
-
-    strcpy(namebuf, instance_name);
-    strcat(namebuf, ".");
-    strcat(namebuf, s->name);
-
-    /* In perverse circumstances, we might already have a state called this */
-    new_state = lookup_state(curblock, namebuf, CREATE_OR_USE_OLD);
-
-    for (tl=s->transitions; tl; tl=tl->next) {
-      TransList *new_tl = new(TransList);
-      new_tl->type = tl->type;
-      /* Might cause some dangling ref problem later... */
-      new_tl->x = tl->x;
-      strcpy(namebuf, instance_name);
-      strcat(namebuf, ".");
-      strcat(namebuf, tl->ds_name);
-      new_tl->ds_name = new_string(namebuf);
-      new_tl->ds_ref = NULL;
-      new_tl->next = new_state->transitions;
-      new_state->transitions = new_tl;
-    }
-
-    /*{{{  Copy state tags */
-    ex = NULL;
-    for (sl=s->tags; sl; sl=sl->next) {
-      Stringlist *new_sl = new(Stringlist);
-      new_sl->string = sl->string;
-      new_sl->next = ex;
-      ex = new_sl;
-    }
-    new_state->tags = ex;
-    /*}}}*/
-
-    /* **DON'T** COPY ENTRIES : these are deliberately dropped if they occur
-     * in a block that gets instantiated elsewhere. */
-
-  }
-}
-/*}}}*/
-/* ================================================================= */
-InlineBlock *create_inline_block(char *type, char *in, char *out)/*{{{*/
-{
-  InlineBlock *result;
-  result = new(InlineBlock);
-  result->type = new_string(type);
-  result->in = new_string(in);
-  result->out = new_string(out);
-  return result;
-}
-/*}}}*/
diff --git a/src/mairix/dfasyn/charclass.c b/src/mairix/dfasyn/charclass.c
@@ -1,364 +0,0 @@
-/***************************************
-  Handle character classes
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-#include <ctype.h>
-
-struct cc_list {
-  struct cc_list *next;
-  CharClass *cc;
-};
-
-static struct cc_list *cc_list = NULL;
-static short mapping[256];
-
-int n_charclasses;
-static char *strings[256];
-
-static void set_bit(unsigned long *bitmap, int entry)/*{{{*/
-{
-  int i, j, mask;
-  i = (entry >> 5);
-  j = entry & 31;
-  mask = 1<<j;
-  bitmap[i] |= mask;
-}
-/*}}}*/
-static void clear_bit(unsigned long *bitmap, int entry)/*{{{*/
-{
-  int i, j, mask;
-  i = (entry >> 5);
-  j = entry & 31;
-  mask = 1<<j;
-  bitmap[i] &= ~mask;
-}
-/*}}}*/
-int cc_test_bit(const unsigned long *bitmap, int entry)/*{{{*/
-{
-  int i, j, mask;
-  i = (entry >> 5);
-  j = entry & 31;
-  mask = 1<<j;
-  return (bitmap[i] & mask) ? 1 : 0;
-}
-/*}}}*/
-CharClass *new_charclass(void)/*{{{*/
-{
-  CharClass *result = new(CharClass);
-  result->is_used = 0;
-  memset(result->char_bitmap, 0, sizeof(result->char_bitmap));
-  memset(result->group_bitmap, 0, sizeof(result->group_bitmap));
-  return result;
-}
-/*}}}*/
-void free_charclass(CharClass *what)/*{{{*/
-{
-  free(what);
-}
-/*}}}*/
-void add_charclass_to_list(CharClass *cc)/*{{{*/
-{
-  /* Add the cc to the master list for later processing. */
-  struct cc_list *elt = new(struct cc_list);
-  elt->next = cc_list;
-  elt->cc = cc;
-  cc_list = elt;
-}
-/*}}}*/
-void add_singleton_to_charclass(CharClass *towhat, char thechar)/*{{{*/
-{
-  int x;
-  x = (int)(unsigned char) thechar;
-  set_bit(towhat->char_bitmap, x);
-}
-/*}}}*/
-void add_range_to_charclass(CharClass *towhat, char start, char end)/*{{{*/
-{
-  int sx, ex, t;
-  sx = (int)(unsigned char) start;
-  ex = (int)(unsigned char) end;
-  if (sx > ex) {
-    t = sx, sx = ex, ex = t;
-  }
-  for (t=sx; t<=ex; t++) {
-    set_bit(towhat->char_bitmap, t);
-  }
-}
-/*}}}*/
-void invert_charclass(CharClass *what)/*{{{*/
-{
-  int i;
-  for (i=0; i<ULONGS_PER_CC; i++) {
-    what->char_bitmap[i] ^= 0xffffffffUL;
-  }
-}
-/*}}}*/
-void diff_charclasses(CharClass *left, CharClass *right)/*{{{*/
-{
-  /* Compute set difference */
-  int i;
-  for (i=0; i<ULONGS_PER_CC; i++) {
-    left->char_bitmap[i] &= ~(right->char_bitmap[i]);
-  }
-}
-/*}}}*/
-
-static char *emit_char (char *p, int i)/*{{{*/
-{
-  if (i == '\\') {
-    *p++ = '\\';
-    *p++ = '\\';
-  } else if (isprint(i) && (i != '-')) {
-    *p++ = i;
-  } else if (i == '\n') {
-    *p++ = '\\';
-    *p++ = 'n';
-  } else if (i == '\r') {
-    *p++ = '\\';
-    *p++ = 'r';
-  } else if (i == '\f') {
-    *p++ = '\\';
-    *p++ = 'f';
-  } else if (i == '\t') {
-    *p++ = '\\';
-    *p++ = 't';
-  } else {
-    p += sprintf(p, "\\%03o", i);
-  }
-  return p;
-}
-/*}}}*/
-static void generate_string(int idx, const unsigned long *x)/*{{{*/
-{
-  int i, j;
-  char buffer[4096];
-  char *p;
-
-  p = buffer;
-  *p++ = '[';
-  /* Force '-' to be shown at the start. */
-  i = 0;
-  do {
-    while ((i < 256) && !cc_test_bit(x,i)) i++;
-    if (i>=256) break;
-
-    j = i + 1;
-    while ((j < 256) && cc_test_bit(x,j)) j++;
-    j--;
-
-    p = emit_char(p, i);
-    if (j == (i + 1)) {
-      p = emit_char(p, j);
-    } else if (j > (i + 1)) {
-      *p++ = '-';
-      p = emit_char(p, j);
-    }
-
-    i = j + 1;
-  } while (i < 256);
-  *p++ = ']';
-  *p = 0;
-  strings[idx] = new_string(buffer);
-  return;
-}
-/*}}}*/
-static void combine(unsigned long *into, const unsigned long *with)/*{{{*/
-{
-  int i;
-  for (i=0; i<ULONGS_PER_CC; i++)  into[i] |= with[i];
-}
-/*}}}*/
-static void set_all(unsigned long *x)/*{{{*/
-{
-  int i;
-  for (i=0; i<ULONGS_PER_CC; i++) x[i] = 0xffffffffUL;
-}
-/*}}}*/
-static void clear_all(unsigned long *x)/*{{{*/
-{
-  int i;
-  for (i=0; i<ULONGS_PER_CC; i++) x[i] = 0x0UL;
-}
-/*}}}*/
-static int find_lowest_bit_set(const unsigned long *x)/*{{{*/
-{
-  int i;
-  for (i=0; i<ULONGS_PER_CC; i++) {
-    if (x[i]) {
-      int pos = 0;
-      unsigned long val = x[i];
-      if (!(val & 0xffff)) pos += 16, val >>= 16;
-      if (!(val & 0x00ff)) pos +=  8, val >>=  8;
-      if (!(val & 0x000f)) pos +=  4, val >>=  4;
-      if (!(val & 0x0003)) pos +=  2, val >>=  2;
-      if (!(val & 0x0001)) pos +=  1;
-      return (i << 5) + pos;
-    }
-  }
-  return -1;
-}
-/*}}}*/
-
-static void mark_used_in_block(const Block *b)/*{{{*/
-{
-  int i;
-
-  for (i=0; i<b->nstates; i++) {
-    const State *s = b->states[i];
-    const TransList *tl;
-    for (tl=s->transitions; tl; tl=tl->next) {
-      switch (tl->type) {
-        case TT_CHARCLASS:
-          tl->x.char_class->is_used = 1;
-          break;
-        default:
-          break;
-      }
-    }
-  }
-}
-/*}}}*/
-static void reduce_list(void)/*{{{*/
-{
-  struct cc_list *ccl, *next_ccl;
-  ccl = cc_list;
-  cc_list = NULL;
-  while (ccl) {
-    next_ccl = ccl->next;
-    if (ccl->cc->is_used) {
-      ccl->next = cc_list;
-      cc_list = ccl;
-    } else {
-      free(ccl->cc);
-      free(ccl);
-    }
-    ccl = next_ccl;
-  }
-}
-/*}}}*/
-void split_charclasses(const Block *b)/*{{{*/
-{
-  unsigned long cc_union[ULONGS_PER_CC];
-  struct cc_list *elt;
-  int i;
-  int any_left;
-
-  mark_used_in_block(b);
-  reduce_list();
-
-  n_charclasses = 0;
-
-  if (!cc_list) {
-    if (verbose) fprintf(stderr, "No charclasses used\n");
-    return;
-  }
-
-  /* Form union */
-  clear_all(cc_union);
-  for (elt=cc_list; elt; elt=elt->next) {
-    combine(cc_union, elt->cc->char_bitmap);
-  }
-
-  for (i=0; i<256; i++) mapping[i] = -1;
-
-  do {
-    int first_char;
-    int i;
-    unsigned long pos[ULONGS_PER_CC], neg[ULONGS_PER_CC];
-    first_char = find_lowest_bit_set(cc_union);
-    set_all(pos);
-    clear_all(neg);
-    for (elt=cc_list; elt; elt=elt->next) {
-      if (cc_test_bit(elt->cc->char_bitmap, first_char)) {
-        for (i=0; i<ULONGS_PER_CC; i++) pos[i] &= elt->cc->char_bitmap[i];
-      } else {
-        for (i=0; i<ULONGS_PER_CC; i++) neg[i] |= elt->cc->char_bitmap[i];
-      }
-    }
-
-    for (i=0; i<ULONGS_PER_CC; i++) {
-      pos[i] &= ~neg[i];
-    }
-
-    generate_string(n_charclasses, pos);
-
-    for (i=0; i<256; i++) {
-      if (cc_test_bit(pos, i)) {
-        mapping[i] = n_charclasses;
-        clear_bit(cc_union, i);
-      }
-    }
-
-    n_charclasses++;
-    any_left = 0;
-    for (i=0; i<ULONGS_PER_CC; i++) {
-      if (cc_union[i]) {
-        any_left = 1;
-        break;
-      }
-    }
-  } while (any_left);
-
-  /* Build group bitmaps */
-  for (elt=cc_list; elt; elt=elt->next) {
-    for (i=0; i<256; i++) {
-      if (cc_test_bit(elt->cc->char_bitmap, i)) {
-        set_bit(elt->cc->group_bitmap, mapping[i]);
-      }
-    }
-  }
-
-  fprintf(stderr, "Got %d character classes\n", n_charclasses);
-
-  return;
-}
-/*}}}*/
-void print_charclass_mapping(FILE *out, FILE *header_out, const char *prefix_under)/*{{{*/
-{
-  int i;
-  if (!cc_list) return;
-  fprintf(out, "short %schar2tok[256] = {", prefix_under);
-  for (i=0; i<256; i++) {
-    if (i > 0) fputs(", ", out);
-    if ((i & 15) == 0) fputs("\n  ", out);
-    if (mapping[i] >= 0) {
-      fprintf(out, "%3d", mapping[i] + ntokens);
-    } else {
-      fprintf(out, "%3d", mapping[i]);
-    }
-  }
-  fputs("\n};\n", out);
-  if (header_out) {
-    fprintf(header_out, "extern short %schar2tok[256];\n",
-        prefix_under);
-  }
-  return;
-}
-/*}}}*/
-void print_charclass(FILE *out, int idx)/*{{{*/
-{
-  fprintf(out, "%d:%s", idx, strings[idx]);
-}
-/*}}}*/
-
diff --git a/src/mairix/dfasyn/compdfa.c b/src/mairix/dfasyn/compdfa.c
@@ -1,479 +0,0 @@
-/***************************************
-  Routines for compressing the DFA by commoning-up equivalent states
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/*
-  The input to this stage is the 'raw' DFA build from the NFA by the subset
-  construction.  Depending on the style of the NFA, there may be large chunks
-  of the DFA that have equivalent functionality, in terms of resulting in the
-  same attributes for the same sequence of input tokens, but which are reached
-  by different prefixes.  The idea of this stage is to common up such regions,
-  to reduce the size of the DFA and hence the table sizes that are generated.
-
-  Conceptually, the basis of the algorithm is to assign the DFA states to
-  equivalence classes.  If there are N different tags-combinations, there are
-  initially N+1 classes.  All states that can exit with a particular value are
-  placed in a class together, and all non-accepting states are placed together.
-  Now, a pass is made over all pairs of states.  Two states remain equivalent
-  if for each token, their outbound transitions go to states in the same class.
-  If the states do not stay equivalent, the class they were in is split
-  accordingly.  This is repeated again and again until no more bisections
-  occur.
-
-  The algorithm actually used is to assign an ordering to the states based on
-  their current class and outbound transitions.  The states are then sorted.
-  This allows all checking to be done on near-neighbours in the sequence
-  generated by the sort, which brings the execution time down to something
-  finite.
-
-  */
-
-#include "dfasyn.h"
-
-static int last_eq_class; /* Next class to assign */
-static int Nt; /* Number of tokens; has to be made static to be visible to comparison fn. */
-
-/* To give 'general_compre' visibility of the current equiv. classes of the
-   destination states */
-static DFANode **local_dfas;
-
-static void calculate_signatures(DFANode **seq, DFANode **dfas, int ndfas)/*{{{*/
-/**** Determine state signatures based on transitions and current classes. ****/
-{
-  unsigned long sig;
-  int i, t;
-
-  for (i=0; i<ndfas; i++) {
-    DFANode *s = seq[i];
-    sig = 0UL;
-    for (t=0; t<Nt; t++) {
-      int di = s->map[t];
-      if (di >= 0) {
-        DFANode *d = dfas[di];
-        int deq_class = d->eq_class;
-
-        sig = increment(sig, deq_class & 0xf); /* 16 bit pairs in sig */
-      }
-    }
-
-    s->signature = sig;
-  }
-}
-/*}}}*/
-static int general_compare(const void *a, const void *b)/*{{{*/
-/************************* Do full compare on states *************************/
-{
-  Castderef (a, const DFANode *, aa);
-  Castderef (b, const DFANode *, bb);
-
-  if (aa->eq_class < bb->eq_class) {
-    return -1;
-  } else if (aa->eq_class > bb->eq_class) {
-    return +1;
-  } else if (aa->signature < bb->signature) {
-    return -1;
-  } else if (aa->signature > bb->signature) {
-    return +1;
-  } else {
-    /* The hard way... */
-    int i;
-    for (i=0; i<Nt; i++) {
-      int am = aa->map[i];
-      int bm = bb->map[i];
-
-      /* Map transition destinations to the current equivalence class of the
-         destination state (otherwise compressor is very pessimistic). */
-      am = (am>=0) ? local_dfas[am]->eq_class: -1;
-      bm = (bm>=0) ? local_dfas[bm]->eq_class: -1;
-
-      if      (am < bm) return -1;
-      else if (am > bm) return +1;
-    }
-
-  }
-
-  /* If you get here, the states are still equivalent */
-  return 0;
-
-}
-/*}}}*/
-static int split_classes(DFANode **seq, DFANode **dfas, int ndfas)/*{{{*/
-/*********************** Do one pass of class splitting ***********************/
-{
-  int i;
-  int had_to_split = 0;
-
-  calculate_signatures(seq, dfas, ndfas);
-  qsort(seq, ndfas, sizeof(DFANode *), general_compare);
-
-  seq[0]->new_eq_class = seq[0]->eq_class;
-
-  for (i=1; i<ndfas; i++) {
-    seq[i]->new_eq_class = seq[i]->eq_class;
-
-    if (seq[i]->eq_class == seq[i-1]->eq_class) {
-      /* May need to split, otherwise states were previously separated anyway
-         */
-
-      if (general_compare(seq+i, seq+i-1) != 0) {
-        /* Different transition pattern, split existing equivalent class */
-        had_to_split = 1;
-        seq[i]->new_eq_class = ++last_eq_class;
-        if (verbose) fprintf(stderr, "Found %d equivalence classes\r", last_eq_class+1);
-      } else {
-        /* This works even if seq[i-1] was assigned a new class due to
-           splitting from seq[i-2] etc. */
-        seq[i]->new_eq_class = seq[i-1]->new_eq_class;
-      }
-    }
-  }
-
-  /* Set classes to new class values. */
-  for (i=0; i<ndfas; i++) {
-    seq[i]->eq_class = seq[i]->new_eq_class;
-  }
-
-  return had_to_split;
-
-}
-/*}}}*/
-static int initial_compare(const void *a, const void *b)/*{{{*/
-/************************** Sort based on tags **************************/
-{
-  Castderef (a, const DFANode *, aa);
-  Castderef (b, const DFANode *, bb);
-  int status;
-  int i;
-
-  for (i=0; i<n_evaluators; i++) {
-
-    const char *ar = aa->attrs[i], *br = bb->attrs[i];
-    if (!ar) ar = get_defattr(i);
-    if (!br) br = get_defattr(i);
-
-    /* Sort so that states with identical attributes appear together. */
-    if (!ar && br) {
-      return -1;
-    } else if (ar && !br) {
-      return +1;
-    } else {
-      if (ar && br) {
-        status = strcmp(ar, br);
-        if      (status < 0) return -1;
-        else if (status > 0) return +1;
-      }
-
-      /* So neither had an attribute at all, or both did and they were equal.
-       * i.e. need to look at attributes further up the vectors */
-    }
-  }
-
-  /* Got here => both states were identical in terms of their attribute sets */
-  return 0;
-}
-/*}}}*/
-static void assign_initial_classes(DFANode **seq, int ndfas)/*{{{*/
-/******************* Determine initial equivalence classes. *******************/
-{
-  int i;
-  qsort(seq, ndfas, sizeof(DFANode *), initial_compare);
-
-  last_eq_class = 0;
-
-  seq[0]->eq_class = last_eq_class;
-
-  for (i=1; i<ndfas; i++) {
-    if (initial_compare(seq+i-1, seq+i) != 0) {
-      /* Not same as previous entry, assign a new class */
-      seq[i]->eq_class = ++last_eq_class;
-    } else {
-      /* Same class as last entry */
-      seq[i]->eq_class = last_eq_class;
-    }
-  }
-}
-/*}}}*/
-/*{{{ compress_states() */
-static void compress_states(struct DFA *dfa, int n_dfa_entries, struct DFAEntry *dfa_entries)
-/***** Compress the DFA so there is precisely one state in each eq. class *****/
-{
-  int *reps;
-  int i, j, t;
-  int neqc;
-  int new_index;
-
-  if (verbose) fprintf(stderr, "%d DFA states before compression\n", dfa->n);
-
-  if (report) {
-    fprintf(report,
-        "\n-----------------------------\n"
-        "------ COMPRESSING DFA ------\n"
-        "-----------------------------\n");
-  }
-
-  neqc = 1 + last_eq_class;
-
-  /* Array containing which state is the representative of each eq. class.
-     Keep the state which had the lowest array index. */
-  reps = new_array(int, neqc);
-
-  for (i=0; i<neqc; i++) reps[i] = -1; /* undefined */
-
-  /* Go through DFA states to find the representative of each class. */
-  for (i=0; i<dfa->n; i++) {
-    int eqc = dfa->s[i]->eq_class;
-    if (reps[eqc] < 0) {
-      reps[eqc] = i;
-      dfa->s[i]->is_rep = 1;
-    } else {
-      dfa->s[i]->is_rep = 0;
-    }
-  }
-
-  /* Go through DFA states and assign new indices. */
-  for (i=0, new_index=0; i<dfa->n; i++) {
-    if (dfa->s[i]->is_dead) {
-      dfa->s[i]->new_index = -1;
-      if (report) fprintf(report, "Old DFA state %d becomes -1 (dead state)\n", i);
-    } else if (dfa->s[i]->is_rep) {
-      dfa->s[i]->new_index = new_index++;
-      if (report) fprintf(report, "Old DFA state %d becomes %d\n", i, dfa->s[i]->new_index);
-    } else {
-      int eqc = dfa->s[i]->eq_class;
-      int rep = reps[eqc];
-
-      /* This assignment works because the representative for the class
-         must have been done earlier in the loop. */
-      dfa->s[i]->new_index = dfa->s[rep]->new_index;
-
-      if (report) fprintf(report, "Old DFA state %d becomes %d (formerly %d)\n", i, dfa->s[i]->new_index, rep);
-    }
-  }
-
-  /* Go through all transitions and fix them up. */
-  for (i=0; i<dfa->n; i++) {
-    DFANode *s = dfa->s[i];
-    for (t=0; t<Nt; t++) {
-      int dest = s->map[t];
-      if (dest >= 0) {
-        s->map[t] = dfa->s[dest]->new_index;
-      }
-    }
-  }
-
-  /* Go through the entries and fix their states */
-  for (i=0; i<n_dfa_entries; i++) {
-    int ni = dfa->s[dfa_entries[i].state_number]->new_index;
-    if (report) {
-      fprintf(report, "Entry <%s>, formerly state %d, now state %d\n",
-          dfa_entries[i].entry_name,
-          dfa_entries[i].state_number, ni);
-    }
-    dfa_entries[i].state_number = dfa->s[dfa_entries[i].state_number]->new_index;
-  }
-
-  /* Fix from_state */
-  for (i=0; i<dfa->n; i++) {
-    int old_from_state, new_from_state;
-    /* If we're not going to preserve the state, move along */
-    if (!dfa->s[i]->is_rep) continue;
-    old_from_state = dfa->s[i]->from_state;
-    /* Any entry state ..., move along */
-    if (old_from_state < 0) continue;
-    new_from_state = dfa->s[reps[dfa->s[old_from_state]->eq_class]]->new_index;
-    dfa->s[i]->from_state = new_from_state;
-  }
-
-  /* Go through and crunch the entries in the DFA array, fixing up the indices */
-  for (i=j=0; i<dfa->n; i++) {
-    if (!dfa->s[i]->is_dead && dfa->s[i]->is_rep) {
-      dfa->s[j] = dfa->s[i];
-      dfa->s[j]->index = dfa->s[j]->new_index;
-      j++;
-    }
-  }
-
-  free(reps);
-  dfa->n = new_index; /* ignore dead states which are completely pruned. */
-  if (verbose) fprintf(stderr, "%d DFA states after compression", dfa->n);
-}
-/*}}}*/
-static void discard_nfa_bitmaps(struct DFA *dfa)/*{{{*/
-/********** Discard the (now inaccurate) NFA bitmaps from the states **********/
-{
-  int i;
-  for (i=0; i<dfa->n; i++) {
-    free(dfa->s[i]->nfas);
-    dfa->s[i]->nfas = NULL;
-  }
-  return;
-}
-/*}}}*/
-static void print_classes(DFANode **dfas, int ndfas)/*{{{*/
-{
-  int i;
-#if 1
-  /* Comment out to print this stuff for debug */
-  return;
-#endif
-  if (!report) return;
-  fprintf(report, "Equivalence classes are :\n");
-  for (i=0; i<ndfas; i++) {
-    fprintf(report, "State %d class %d\n", i, dfas[i]->eq_class);
-  }
-  fprintf(report, "\n");
-  return;
-}
-/*}}}*/
-static int has_any_nondefault_attribute(const DFANode *x)/*{{{*/
-{
-  int result = 0;
-  int i;
-  for (i=0; i<n_evaluators; i++) {
-    if (x->attrs[i]) {
-      char *defattr;
-      defattr = get_defattr(i);
-      if (defattr && strcmp(defattr, x->attrs[i])) {
-        result = 1;
-        break;
-      }
-    }
-  }
-  return result;
-}
-/*}}}*/
-static void find_dead_states(DFANode **dfas, int ndfas, int ntokens)/*{{{*/
-{
-  /* Find any state that has no transitions out of it and no attribute.
-   * If you get there, you're guaranteed to be stuck.
-   * Then, repeatedly look for states which are such that all transitions from
-   * them lead to dead states.  Mark these dead too.
-   * Then, go through all the dead states and remove their transitions.
-   * This will force them all into a single class later. */
-
-  int did_any;
-  int i, j;
-  /* Eventually, consider looking for results that are non-default. */
-  char *leads_to_result;
-  int total_found = 0;
-
-  leads_to_result = new_array(char, ndfas);
-  memset(leads_to_result, 0, ndfas);
-
-  if (report) {
-    fprintf(report, "Searching for dead states...\n");
-  }
-
-  do {
-    did_any = 0;
-    for (i=0; i<ndfas; i++) {
-      if (leads_to_result[i] == 0) {
-        if (has_any_nondefault_attribute(dfas[i])) {
-          leads_to_result[i] = 1;
-          did_any = 1;
-          continue;
-        }
-
-        for (j=0; j<ntokens; j++) {
-          int next_state = dfas[i]->map[j];
-          if ((next_state >= 0) && leads_to_result[next_state]) {
-            leads_to_result[i] = 1;
-            did_any = 1;
-            goto do_next_dfa_state;
-          }
-        }
-      }
-do_next_dfa_state:
-      (void) 0;
-    }
-  } while (did_any);
-
-
-  /* Now prune any transition to states that have no path to a result. */
-  for (i=0; i<ndfas; i++) {
-    if (leads_to_result[i] == 0) {
-      total_found++;
-      if (report) {
-        fprintf(report, "DFA state %d is dead\n", i);
-      }
-      dfas[i]->from_state = -1;
-      dfas[i]->via_token = -1;
-      dfas[i]->is_dead = 1;
-    } else {
-      dfas[i]->is_dead = 0;
-    }
-
-    for (j=0; j<ntokens; j++) {
-      int next_state = dfas[i]->map[j];
-      if (leads_to_result[next_state] == 0) {
-        dfas[i]->map[j] = -1;
-      }
-    }
-  }
-
-  free(leads_to_result);
-
-  if (!total_found && report) {
-    fprintf(report, "(no dead states found)\n");
-  }
-}
-/*}}}*/
-/*{{{ compress_dfa() */
-void compress_dfa(struct DFA *dfa, int ntokens,
-    int n_dfa_entries, struct DFAEntry *dfa_entries)
-{
-  DFANode **seq; /* Storage for node sequence */
-  int i;
-  int had_to_split;
-
-  /* Safety net */
-  if (dfa->n <= 0) return;
-
-  local_dfas = dfa->s;
-  Nt = ntokens;
-
-  seq = new_array(DFANode *, dfa->n);
-  for (i=0; i<dfa->n; i++) {
-    seq[i] = dfa->s[i];
-  }
-
-  find_dead_states(dfa->s, dfa->n, ntokens);
-
-  assign_initial_classes(seq, dfa->n);
-
-  do {
-    print_classes(dfa->s, dfa->n);
-    had_to_split = split_classes(seq, dfa->s, dfa->n);
-  } while (had_to_split);
-
-  print_classes(dfa->s, dfa->n);
-
-  compress_states(dfa, n_dfa_entries, dfa_entries);
-  discard_nfa_bitmaps(dfa);
-
-  free(seq);
-  return;
-
-}
-/*}}}*/
-
diff --git a/src/mairix/dfasyn/configure b/src/mairix/dfasyn/configure
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-egrep -v '^#' INSTALL
-
diff --git a/src/mairix/dfasyn/dfasyn.1 b/src/mairix/dfasyn/dfasyn.1
@@ -1,154 +0,0 @@
-.TH DFASYN 1 ""
-.SH NAME
-dfasyn \- generate deterministic finite automata
-.SH SYNOPSYS
-.B dfasyn
-[
-.BR \-o | \-\-output
-.I C-filename
-] [
-.BR \-ho | \-\-header-output
-.I H-filename
-] [
-.BR \-r | \-\-report
-.I report-filename
-] [
-.BR \-p | \-\-prefix
-.I prefix
-] [
-.BR \-u | \-\-uncompressed-tables
-] [
-.BR \-ud | \-\-uncompressed-dfa
-] [
-.BR \-I | \-\-inline-function
-] [
-.BR \-v | \-\-verbose
-] [
-.BR \-h | \-\-help
-]
-.I input-file
-
-.SH DESCRIPTION
-.B dfasyn
-generates a deterministic finite automaton (DFA) from a description file.
-
-.SH OPTIONS
-.SS Options controlling output files
-.TP
-.BI "-o " C-filename
-.br
-.ns
-.TP
-.BI "--output " C-filename
-.br
-Specify the name of the file to which the C program text will be written.
-If this option is not present, the C program text will be written to stdout.
-
-.TP
-.BI "-ho " H-filename
-.br
-.ns
-.TP
-.BI "--header-output " H-filename
-.br
-Specify the name of the file to which the header information will be written.
-
-.TP
-.BI "-r " report-filename
-.br
-.ns
-.TP
-.BI "--report " report-filename
-.br
-Specify the name of the file to which the report on the generated automaton
-will be written.  If this option is not present, no report will be written.
-
-.TP
-.I input-file
-.br
-This is the name of the file containing the definition of the automaton.  Refer
-to
-.BR dfasyn (5)
-for more information about the format of this file.
-
-.SS Options controlling the generated automaton
-.TP
-.BI "-p " prefix
-.br
-.ns
-.TP
-.BI "--prefix " prefix
-.br
-Specify the prefix to be prepended onto each symbol that
-.B dfasyn
-generates in the output file.  This allows multiple automata to be linked into
-the same final program without namespace clashes.
-
-The string prepended is actually
-.I prefix
-followed by an underscore ('_').
-
-.TP
-.BR -u ", " --uncompressed-tables
-.br
-Do not compress the transition tables.  By default,
-.B dfasyn
-emits the transition tables compressed, and it emits a next-state function that
-uses a bisection algorithm to search the tables.  By contrast, uncompressed
-tables use a simple array indexing algorithm in the next-state algorithm.
-However, the generated tables will be much larger, especially if there is a
-large set of input symbols and the transitions in the automaton are relatively
-sparse.  This option therefore represents a speed versus space trade-off in the
-generated DFA.
-
-.TP
-.BR -ud ", " --uncompressed-dfa
-.br
-Do not compress the generated DFA.  By default,
-.B dfasyn
-compresses the DFA to combine common states into a single state in the final
-DFA and to remove unreachable states.  This option suppresses the compression.
-Giving this option can only be to the detriment of the final DFA, in terms of
-the array sizes of its tables.  However, the option is useful for debugging
-.B dfasyn
-and will also reduce the run time of
-.B dfasyn
-since a potentially complex processing step can be omitted.
-
-.TP
-.BR -I ", " --inline-function
-.br
-This causes the next-state function to emitted as an inline function in the header output.
-Specifying this option without
-.B -ho
-is non-sensical and
-.B dfasyn
-will complain in that situation.
-
-Normally,
-.B dfasyn
-will emit the next_state function in the C program text output.  This will
-incur a function call overhead for each input symbol when the DFA is used at
-run-time.  If this is significant to the final application, the
-.B -I
-option may be useful to allow the next-state function to be inlined.
-
-.SS General options
-
-.TP
-.BR -v ", " --verbose
-.br
-Make the output more verbose; provide more comfort messages whilst
-.B dfasyn
-is running.
-
-.TP
-.BR -h ", " --help
-.br
-Show usage summary and exit
-
-.SH "SEE ALSO"
-.BR dfasyn (5),
-.BR bison (1),
-.BR flex (1)
-
diff --git a/src/mairix/dfasyn/dfasyn.5 b/src/mairix/dfasyn/dfasyn.5
@@ -1,650 +0,0 @@
-.TH DFASYN 5 ""
-.SH NAME
-dfasyn
-.SH SYNOPSYS
-This page describes the format of the
-.I input-file
-for the
-.B dfasyn
-deterministic finite automaton generator.
-.SH DESCRIPTION
-.SS Overview
-Reserved words may be given in all-lowercase, all-uppercase, initial capitals,
-or 'WikiWord' format (e.g.
-.B endblock
-may be given as
-.BR endblock ", " Endblock ", " EndBlock " or " ENDBLOCK .
-
-.SS Block declaration
-A
-.B block
-declaration is used to group together a set of state declarations.  Blocks are
-useful if there are blocks of states and their interconnections that occur more
-than once in the NFA.  In this case it is useful to declare a block, allowing
-that block to be instantiated more than once elsewhere in the input file.
-
-Since state declarations are only allowed inside blocks, there must be at least
-one block declaration in any useful input file.
-
-The syntax of a block declaration is
-.RS
-.B block
-.I block-name
-{
-.br
-.RS 2
-[
-.I instance-declarations
-]
-.br
-[
-.I state-declarations
-]
-.RE
-.br
-}
-.RE
-
-.SS State declarations
-A
-.B state
-declaration gives rise to a state in the input NFA.
-
-The syntax of a state declaration is
-.RS
-.B state
-.I state-name
-[
-.B entry
-.I entry-name
-]
-.br
-.RS 2
-[
-.I transitions
-]
-.RE
-.RE
-
-States are implicitly terminated by the beginning of another type of construct.
-
-.B entry
-.I entry-name
-(if present) defines the name of an entry point into the scanner.  In the
-resulting C-code, a symbol called
-.I entry-name
-will be declared.  Its value will be the DFA state number of the state
-containing just this NFA state (plus its epsilon closure.)  This allows for
-multiple scanners to be generated from the same input file.  For example, if
-one scanner is the same as another but with some extra text that must match at
-the beginning, two different
-.B entry
-states can be declared to represent this.
-.B dfasyn
-will be able to common-up all of the common part of the DFA's transition
-tables.
-
-If there are no
-.B entry
-directives anywhere in the input file,
-.B dfasyn
-defaults to the last mentioned state in the last block being the entry state.
-
-.I transitions
-is a whitespace-separated sequence of zero or more transitions.  These define which
-of the automaton's input symbols cause a transition from this state to which other
-states.
-
-The same state may be declared more than once inside its block.  In this case,
-the transitions given in the second declaration will be merged with those given
-in the first, as though all the transitions had been given in the first place.
-
-.SS Instance declarations
-A block may be instantiated inside another block.  This is useful if there is a
-block of states with their transitions that occurs in more than once place
-within the NFA.
-
-The syntax for an instance declaration is
-
-.RS
-.I instance-name
-:
-.I block-name
-.RE
-
-where
-.I instance-name
-is the name of the new instance, and
-.I block-name
-is the name of the block that is being instantiated.  This block
-.B must
-have been declared earlier in the input file.  For one thing, this prevents
-mutually recursive definitions.
-
-When such an instance has been created, the states inside it may be referred to
-within the enclosing block by prefixing their names with the
-.I instance-name
-followed by a period.
-
-.SS Transitions
-A state-to-state transition is specified as follows.
-
-.RS
-.I transition
-->
-.I destinations
-.RE
-
-.I destinations
-is a comma-separated list of one or more fully-qualified state names.  These
-are the states to which the NFA moves if the
-.I transition
-is matched next in the input.  The destination state names are allowed to be
-forward-references; just the name is stored during parsing, and a second pass
-later is used to resolve all the names.  There is no need for a named
-destination to actually be declared with another state definition; a state just
-comes into being if it is named at all.
-
-A
-.I transition
-defines the inputs that are required to cause the scanner to move
-from one state to another.  A
-.I transition
-is a semicolon-separated list of one or more
-.I stimuli.
-(If there is only one stimulus, no semicolon is required.) The transition
-matches as a whole if the stimuli are matched individually in sequential order
-from left to right.
-
-.SS Transitions to a tag
-Where a transition leads to a tagged exit state, the following syntax is used:
-
-.RS
-.I transition
-=
-.I tags
-.RE
-
-where
-.I tags
-is a comma-separated list of one or more tag names.  Thus a construction like
-
-.RS
-state foo XXX = TAG1
-.RE
-
-indicates that matching the token XXX leads to a state in which TAG1 applies.
-
-.SS Stimuli
-A
-.B stimulus 
-is a pipe-separated list of alternatives.  Each alternative may be one of the following:
-.IP "*" 7
-the name of a token
-.IP "*" 7
-a character class
-.IP "*" 7
-the name of an abbreviation
-.IP "*" 7
-an empty string (which gives rise to an
-.B epsilon transition
-)
-.IP "*" 7
-an inline block instance
-
-.SS Input symbols
-Input symbols can be defined in two ways.  The first is to use ASCII characters
-directly.  The second is to define a set of
-.I tokens
-and use a front-end module to generate these based on the actual input.  You
-can actually mix both types of input symbol.  For example, you might wish to
-use ASCII characters mostly, but detect \(dqend-of-file\(dq as an explicit symbol.
-
-.SS ASCII input and character classes.
-
-Single ASCII characters can be given in double-quotes.  Sets of ASCII
-characters can be given in square brackets, similar to shell globbing.
-Character classes can be negated and differenced.
-
-.IP [a] 12
-The character "a".
-.IP [abe-h] 12
-Any of the characters "a", "b", "e", "f", "g", "h".
-.IP ~[abc] 12
-Any of the 253 characters excluding "a", "b" and "c"; a negated character class.
-.IP [^abc] 12
-Ditto - another way of expressing a negated character class.
-.IP [a-z]~[c] 12
-Equivalent to [abd-z].
-
-.PP
-The following special cases are available within the square brackets:
-
-.IP \(rs- 8
-A hyphen.  Normally the hyphen is used as a range separator.  To get a literal
-hyphen, it must be escaped by a back-slash.
-.IP \(rs] 8
-A closing square bracket.  The escaping is required to prevent it being handled
-as the end of the character class.
-.IP \(rs\(rs 8
-A literal backslash.
-.IP \(rs^ 8
-A literal "^".
-.IP \(rsn 8
-The same character as "\(rsn" in C.
-.IP \(rsr 8
-The same character as "\(rsr" in C.
-.IP \(rsf 8
-The same character as "\(rsf" in C.
-.IP \(rst 8
-The same character as "\(rst" in C.
-.IP ^A 8
-Generate a control character, in this case ASCII character 1.  Defined for ^@
-through to ^Z.
-.IP \(rsxa9 8
-The ASCII character with hex value 0xa9.  Upper or lower case hex may be used.
-.IP \(rs234
-The ASCII character with octal value 0234.
-
-.SS Tokens
-To define non-ASCII inputs, at least one
-.B tokens
-directive must be used.  The syntax is
-.PP
-.B tokens
-.I list-of-tokens
-.PP
-where
-.I list-of-tokens
-is a space-separated list of token names.  Each token name is a string that
-will be acceptable as a C macro name when prefixed by the current prefix string
-plus an underscore.
-
-If more than one
-.B tokens
-line appears in the input file, the 2nd and subsequent lines are treated as
-though their entries were concatenated with the 1st line.
-
-.SS Abbreviations
-An
-.B abbreviation
-provides a convenient way to define a shorthand name for a frequently used
-.B stimulus.
-
-The syntax is
-
-.RS
-.B abbrev
-.I abbrev-name
-=
-.I stimulus
-.RE
-
-For example:
-
-.RS
-abbrev FOO = [aeiouAEIOU] | A_TOKEN | <xyzzy:in->out>
-.RE
-
-.SS Inline block instances
-A
-.B stimulus
-may take the form of a block instance.  This is a convenient shorthand when a
-complex sequence of input tokens needs to be matched as part of a transition.
-
-The syntax of an inline block instance is
-.RS
-.RI < block_name : entry_state "->" exit_state >
-.RE
-
-As an example, given a block
-.B double_a
-defined like this
-.RS
-block double_a
-  state in A -> out
-.br
-endblock
-.RE
-
-the following construction
-.RS
-block x
-  state foo <double_a:in->out> ; B ; <double_a:in->out> -> bar
-.br
-endblock
-.RE
-
-is equivalent to
-.RS
-block x
-  aa1 : double_a
-  aa2 : double_a
-  state foo -> aa1.in
-  state aa1.out
-    B -> aa2.in
-  state aa2.out -> bar
-.br
-endblock
-.RE
-
-Note that in the second example, where explicit instances have been created,
-they must have unique names.  In the first case,
-.B dfasyn
-will create the two anonymous instances automatically and handle all the
-plumbing to connect up the in and out states.  Note there is no requirement for
-the states to be named 'in' and 'out'; that is merely a convention.  An
-instanced block may have multiple inputs, with different inputs being used in
-different instantiations of the block, for example.
-
-.SS Tags and attributes
-.B Tags
-are associated with the NFA states in the input.  An NFA state may have an
-arbitrary number of tags associated with it, through what amounts to a list of
-strings.
-.B Attributes
-are attached to the DFA states in the output.  In the generated C-file, the
-attributes are expressed in terms of an array which is indexed by the DFA state
-number and whose elements are the attribute values applying to the states.
-
-Once the DFA has been generated,
-.B dfasyn
-knows the NFA states that apply in each DFA state.  From this, the tags
-associated with a DFA state are given by the union of all the tags appylying in
-all the NFA states that apply in that DFA state.
-
-The input file defines how a set of tags applying in a DFA state is to be
-reduced to a single attribute value.  A boolean expression language is provided
-for this purpose.
-
-Although the default is to generate a single attribute table,
-.B dfasyn
-can generate arbitrarily many tables if required.  This is achieved by using
-.B attribute groups.
-The NFA tag namespace is shared across all such groups.  The group syntax is as
-follows:
-
-.RS
-.B group
-.I groupname
-.B {
-.I declaration
-[
-.RI ", " declaration 
-\ ...
-]
-.B }
-.RE
-
-where each
-.I declaration
-is one of the following:
-
-.RS
-.B attr
-.I attribute-name
-[
-.RI ", " attribute-name
-\ ... ]
-.br
-.B attr
-.I attribute-name
-.B :
-.I expression
-.br
-.B early
-.B attr
-.I attribute-name
-[
-.RI ", " attribute-name
-\ ... ]
-.br
-.B early
-.B attr
-.I attribute-name
-.B :
-.I expression
-.RE
-
-In the form with no expression, each
-.I attribute-name
-has an implicit expression consisting of just the tag with the same name as
-itself.
-
-.I expression
-is defined in the section
-.B Expressions
-later.  The short form
-
-.RS
-.B attr
-foo
-.RE
-
-is short for 
-.RS
-.B attr
-foo
-.B :
-foo
-.RE
-
-i.e. it allows an attribute to be defined which has the same name as a tag and
-which is active in the cases where precisely that tag is active.
-
-If an attribute is prefixed by
-.BR early ,
-it means that the C-code you provide to drive the DFA is going to stop scanning
-once this state attribute is detected.  For example, this would apply if you
-were coding a "shortest match" scanner.
-.B dfasyn
-will prune all the transitions away from any DFA state having such an
-attribute.  This may lead to greater opportunities for
-.B dfasyn
-to compress the DFA.
-
-A default attribute must be declared.  This is used to fill all the entries in
-the attribute array for DFA states that end up with no explicit attribute
-defined.  (It is also used in determining where the DFA may be optimised to
-remove "dead states".)  The syntax is
-
-.RS
-.B defattr
-.I default-attribute-string
-.RE
-
-Finally, the C-type of the attribute must be declared.  This becomes the base
-type of the array indexed by the DFA state number.  The syntax is
-
-.RS
-.B type
-.I attribute-type-name
-.RE
-
-It is illegal for more than one attribute in a particular attribute group to be
-active in a DFA state.  If this situation occurs, it indicates that the
-expression logic for that group is defective.
-
-.SS Expressions
-An
-.I expression
-defines an attribute in terms of a boolean relationship between one more more
-tags.  An
-.I expression
-may be any one of the following:
-
-.RS
-.IR expression " & " expression
-.br
-.IR expression " | " expression
-.br
-.IR expression " ^ " expression
-.br
-.IR expression " ? " expression " : " expression
-.br
-.RI ( expression )
-.br
-.RI "~" expression
-.br
-.RI "!" expression
-.br
-.I tag-name
-.RE
-
-Note that
-.RI "~" expression
-and
-.RI "!" expression
-both mean the negation of expression.
-
-The operator precedence is what would be expected for a C-programmer.
-
-.SH Prefix specification
-The
-.B prefix
-used in the generated C-file can optionally be set in the input file using the following syntax:
-
-.RS
-.B prefix
-.I prefix-string
-.RE
-
-where
-.IR prefix-string _
-(i.e. the specific string followed by an underscore) will occur at the start of
-each symbol name in the generated C-file.
-
-If the prefix has been set via the command line using
-.BR -p ,
-the
-.B prefix
-line in the input file will be ignored and a warning given.
-
-.SH "THE GENERATED C-FILE"
-The generated file exports the following symbols that can be used by the calling program:
-
-.TP
-.B short
-.IB prefix_ char2tok
-[256];
-.br
-If character classes have been used, this table maps from ASCII values to the
-internal tokens numbers used by the generated DFA.  This array will be defined
-in the generated C-file.  If a header file is being generated, it will be
-declared in there also.
-
-.TP
-.B #define
-.IB prefix_ TOKEN
-.I numeric_value
-.br
-If a
-.b tokens
-directive has been used, each such token will be assigned a number.  These
-assignments are emitted by
-.b dfasyn
-as a series of #define lines.  Each token name from the input file will have the
-.I prefix
-and an underscore prepended to form the name of the symbol in the #define.
-If a header file is being generated
-.RB ( -ho ),
-these definitions are placed in the header file.  Otherwise, they are placed in
-the main output C-file.
-
-.TP 7
-.B int
-.IB prefix_ next_state
-(int current_state, int next_state);
-.br
-This is the prototype for the next state function which the calling program must invoke.
-
-If no 
-.B -I
-option has been used, this function will be defined in the generated C-file.
-If a header file is being generated, it will be prototyped in there also.
-
-If
-.B -I
-has been used, the function will be defined in the header file.
-
-.TP
-.B int
-.IB prefix _ entry-name
-.br
-If the
-.B entrystruct
-directive has not been used, this format is used to define the DFA state
-numbers for the defined entry points.  The calling program uses these values to
-set the
-.I current_state
-at the start of the scanning process, depending on which entry point is being
-used.
-
-If there is more than one entry, there will be more than one such line.
-
-
-.TP
-.B struct
-.I entrystruct-type
-{ ... }
-.I entrystruct-var
-.br
-If the
-.B entrystruct
-directive has been used, the DFA state numbers for the entry points are
-declared as elements of a struct.  The struct member names are identical to the
-entry names used in the
-.B dfasyn
-input file.  The declaration of the struct variable containing the state
-numbers will be in the generated C-file.  If a header file is being generated
-.RB ( -ho ),
-the definition of the struct type will be in there.  Otherwise, it will be in
-the C-file also.
-
-.TP 12
-.I attr-type
-.IB prefix_ attr
-.RI [ #DFA-states ]
-.br
-This defines the attributes for each of the DFA states in the default attribute
-group.  If no
-.B type
-.I attr-type
-declaration was in the input file, the default of
-.B short
-will be used.
-
-If other attribute groups are defined, there will be a similar array for each one:
-
-.TP 18
-.I group-attr-type
-.I prefix_group-name
-.RI [ #DFA-states ]
-.br
-For the attribute group declared with 
-.B group
-.I group-name
-in the input file, this defines the attribute of each of the DFA states in that
-group.
-
-.SH TEXT PASSTHROUGH
-To pass a block of literal text through to the output file without
-interpretation, enclose it in %{ ... %} like this:
-
-.RS
-%{
-.br
-#include "foo.h"
-.br
-%}
-.RE
-
-The opening and closing patterns must be on lines on their own (trailing
-whitespace is allowed).
-
-
-.SH "SEE ALSO"
-.BR dfasyn (1)
-
-
-
diff --git a/src/mairix/dfasyn/dfasyn.c b/src/mairix/dfasyn/dfasyn.c
@@ -1,690 +0,0 @@
-/***************************************
-  Main program for NFA to DFA table builder program.
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2000-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-
-FILE *report = NULL;
-FILE *output = NULL;
-FILE *header_output = NULL;
-
-/* If non-null this gets prepended onto the names of the all the entities that
- * are generated in the output file. */
-char *prefix = NULL;
-
-extern int yyparse(void);
-
-/* ================================================================= */
-static char *entrystruct = NULL;
-static char *entryvar = NULL;
-
-void define_entrystruct(const char *s, const char *v)/*{{{*/
-{
-  if (!entrystruct) {
-    entrystruct = new_string(s);
-    entryvar = new_string(v);
-  } else {
-    fprintf(stderr, "Can't redefine entrystruct with <%s>\n", s);
-    exit(1);
-  }
-}
-/*}}}*/
-/* ================================================================= */
-static void print_token_table(void)/*{{{*/
-{
-  FILE *dest;
-  int i;
-  extern char *prefix;
-
-  dest = header_output ? header_output : output;
-  /* Not sure how it makes sense to write this to the C file : maybe if you're going
-   * to include the C file into a bigger one it's reasonable?  Anyway, the intention
-   * is that you're more likely to use this for real if you're writing a header file. */
-
-  for (i=0; i<ntokens; i++) {
-    fprintf(dest, "#define %s_%s %d\n",
-        prefix ? prefix : "TOK_",
-        toktable[i], i);
-  }
-}
-/*}}}*/
-static void print_attr_tables(struct DFA *dfa, const char *prefix_under)/*{{{*/
-{
-  int i, tab;
-
-  for (tab=0; tab<n_evaluators; tab++) {
-    char *defattr = get_defattr(tab);
-    char *attrname = get_attr_name(tab);
-    if (!attrname) attrname = "attr";
-    fprintf(output, "%s %s%s[] = {\n", get_attr_type(tab), prefix_under, attrname);
-    for (i=0; i<dfa->n; i++) {
-      char *attr = dfa->s[i]->attrs[tab];
-      fprintf(output, "  %s", attr ? attr : defattr);
-      fputc ((i<(dfa->n - 1)) ? ',' : ' ', output);
-      fprintf(output, " /* State %d */\n", i);
-    }
-    fprintf(output, "};\n\n");
-    if (header_output) {
-      fprintf(header_output, "extern %s %s%s[];\n", get_attr_type(tab), prefix_under, attrname);
-    }
-  }
-}
-/*}}}*/
-static void check_default_attrs(void)/*{{{*/
-{
-  int tab;
-  int fail = 0;
-
-  for (tab=0; tab<n_evaluators; tab++) {
-    char *defattr = get_defattr(tab);
-    char *attrname = get_attr_name(tab);
-    attrname = attrname ? attrname : "(DEFAULT)";
-    if (!defattr) {
-      fprintf(stderr, "ERROR: No defattr definition for %s\n", attrname);
-      fail = 1;
-    }
-  }
-  if (fail) {
-    exit(1);
-  }
-}
-/*}}}*/
-static void write_next_state_function_uncompressed(int Nt, int do_inline, const char *prefix_under)/*{{{*/
-{
-  FILE *dest;
-
-  dest = do_inline ? header_output : output;
-
-  fprintf(dest, "%sint %snext_state(int current_state, int next_token) {\n",
-      do_inline ? "static inline " : "",
-      prefix_under);
-  fprintf(dest, "  if (next_token < 0 || next_token >= %d) return -1;\n", Nt);
-  fprintf(dest, "  return %strans[%d*current_state + next_token];\n",
-      prefix_under, Nt);
-  fprintf(dest, "}\n");
-  if (!do_inline && header_output) {
-    fprintf(header_output, "extern int %snext_state(int current_state, int next_token);\n",
-        prefix_under);
-  }
-}
-/*}}}*/
-static void print_uncompressed_tables(struct DFA *dfa, int do_inline, const char *prefix_under)/*{{{*/
-/* Print out the state/transition table uncompressed, i.e. every
-   token has an array entry in every state.  This is fast to access
-   but quite wasteful on memory with many states and many tokens. */
-{
-  int Nt = ntokens + n_charclasses;
-  int n, i, j;
-
-  n = 0;
-  fprintf(output, "%sshort %strans[] = {",
-      do_inline ? "" : "static ",
-      prefix_under);
-
-  if (do_inline) {
-    fprintf(header_output, "extern short %strans[];\n",
-        prefix_under);
-  }
-
-  for (i=0; i<dfa->n; i++) {
-    for (j=0; j<Nt; j++) {
-      if (n>0) fputc (',', output);
-      if (n%8 == 0) {
-        fprintf(output, "\n  ");
-      } else {
-        fputc(' ', output);
-      }
-      n++;
-      fprintf(output, "%4d", dfa->s[i]->map[j]);
-    }
-  }
-
-  fprintf(output, "\n};\n\n");
-
-  write_next_state_function_uncompressed(Nt, do_inline, prefix_under);
-
-}
-/*}}}*/
-static int check_include_char(struct DFA *dfa, int this_state, int token)/*{{{*/
-{
-  if (dfa->s[this_state]->defstate >= 0) {
-    return (dfa->s[this_state]->map[token] !=
-            dfa->s[dfa->s[this_state]->defstate]->map[token]);
-  } else {
-    return (dfa->s[this_state]->map[token] >= 0);
-  }
-}
-/*}}}*/
-static void write_next_state_function_compressed(int do_inline, const char *prefix_under)/*{{{*/
-/* Write the next_state function for traversing compressed tables into the
-   output file. */
-{
-  FILE *dest;
-  dest = do_inline ? header_output : output;
-
-  fprintf(dest, "%sint %snext_state(int current_state, int next_token) {\n",
-      do_inline ? "static inline " : "",
-      prefix_under);
-  fprintf(dest, "  int h, l, m, xm;\n");
-  fprintf(dest, "  while (current_state >= 0) {\n");
-  fprintf(dest, "    l = %sbase[current_state], h = %sbase[current_state+1];\n", prefix_under, prefix_under);
-  fprintf(dest, "    while (h > l) {\n");
-  fprintf(dest, "      m = (h + l) >> 1; xm = %stoken[m];\n", prefix_under);
-  fprintf(dest, "      if (xm == next_token) goto done;\n");
-  fprintf(dest, "      if (m == l) break;\n");
-  fprintf(dest, "      if (xm > next_token) h = m;\n");
-  fprintf(dest, "      else                 l = m;\n");
-  fprintf(dest, "    }\n");
-  fprintf(dest, "    current_state = %sdefstate[current_state];\n", prefix_under);
-  fprintf(dest, "  }\n");
-  fprintf(dest, "  return -1;\n");
-  fprintf(dest, "  done:\n");
-  fprintf(dest, "  return %snextstate[m];\n", prefix_under);
-  fprintf(dest, "}\n");
-  if (!do_inline && header_output) {
-    fprintf(header_output, "extern int %snext_state(int current_state, int next_token);\n",
-        prefix_under);
-  }
-
-}
-/*}}}*/
-static void print_compressed_tables(struct DFA *dfa, int do_inline, const char *prefix_under)/*{{{*/
-/* Print state/transition table in compressed form.  This is more
-   economical on storage, but requires a bisection search to find
-   the next state for a given current state & token */
-{
-  int *basetab = new_array(int, dfa->n + 1);
-  int Nt = ntokens + n_charclasses;
-  int n, i, j;
-
-  n = 0;
-  fprintf(output, "%sunsigned char %stoken[] = {",
-      do_inline ? "" : "static ",
-      prefix_under);
-  for (i=0; i<dfa->n; i++) {
-    for (j=0; j<Nt; j++) {
-      if (check_include_char(dfa, i, j)) {
-        if (n>0) fputc (',', output);
-        if (n%8 == 0) {
-          fprintf(output, "\n  ");
-        } else {
-          fputc(' ', output);
-        }
-        n++;
-        fprintf(output, "%3d", j);
-      }
-    }
-  }
-  fprintf(output, "\n};\n\n");
-
-  n = 0;
-  fprintf(output, "%sshort %snextstate[] = {",
-      do_inline ? "" : "static ",
-      prefix_under);
-  for (i=0; i<dfa->n; i++) {
-    basetab[i] = n;
-    for (j=0; j<Nt; j++) {
-      if (check_include_char(dfa, i, j)) {
-        if (n>0) fputc (',', output);
-        if (n%8 == 0) {
-          fprintf(output, "\n  ");
-        } else {
-          fputc(' ', output);
-        }
-        n++;
-        fprintf(output, "%5d", dfa->s[i]->map[j]);
-      }
-    }
-  }
-  fprintf(output, "\n};\n\n");
-  basetab[dfa->n] = n;
-
-  n = 0;
-  fprintf(output, "%sunsigned short %sbase[] = {",
-      do_inline ? "" : "static ",
-      prefix_under);
-  for (i=0; i<=dfa->n; i++) {
-    if (n>0) fputc (',', output);
-    if (n%8 == 0) {
-      fprintf(output, "\n  ");
-    } else {
-      fputc(' ', output);
-    }
-    n++;
-    fprintf(output, "%5d", basetab[i]);
-  }
-  fprintf(output, "\n};\n\n");
-
-  n = 0;
-  fprintf(output, "%sshort %sdefstate[] = {",
-      do_inline ? "" : "static ",
-      prefix_under);
-  for (i=0; i<dfa->n; i++) {
-    if (n>0) fputc (',', output);
-    if (n%8 == 0) {
-      fprintf(output, "\n  ");
-    } else {
-      fputc(' ', output);
-    }
-    n++;
-    fprintf(output, "%5d", dfa->s[i]->defstate);
-  }
-  fprintf(output, "\n};\n\n");
-
-  if (do_inline) {
-    fprintf(header_output, "extern unsigned char %stoken[];\n", prefix_under);
-    fprintf(header_output, "extern short %snextstate[];\n", prefix_under);
-    fprintf(header_output, "extern unsigned short %sbase[];\n", prefix_under);
-    fprintf(header_output, "extern short %sdefstate[];\n", prefix_under);
-  }
-  free(basetab);
-
-  write_next_state_function_compressed(do_inline, prefix_under);
-}
-/*}}}*/
-static void print_entries_table(const char *prefix_under)/*{{{*/
-{
-  int i;
-  if (entrystruct) {
-    int first;
-    /* If we write the struct defn to the header file, we ought not to emit the
-     * full struct defn again in the main output.  This is tricky unless we can
-     * guarantee the header will get included, though. */
-    fprintf(output, "struct %s {\n", entrystruct);
-    if (header_output) {
-      fprintf(header_output, "extern struct %s {\n", entrystruct);
-    }
-    for (i=0; i<n_dfa_entries; i++) {
-      fprintf(output, "  int %s;\n", dfa_entries[i].entry_name);
-      if (header_output) {
-        fprintf(header_output, "  int %s;\n", dfa_entries[i].entry_name);
-      }
-    }
-    fprintf(output, "} %s = {\n", entryvar);
-    if (header_output) {
-      fprintf(header_output, "} %s;\n", entryvar);
-    }
-    for (i=0, first=1; i<n_dfa_entries; i++, first=0) {
-      if (!first) {
-        fputs(",\n", output);
-      }
-      fprintf(output, "  %d", dfa_entries[i].state_number);
-    }
-    fputs("\n};\n", output);
-  } else {
-    for (i=0; i<n_dfa_entries; i++) {
-      fprintf(output, "int %s%s = %d;\n",
-          prefix_under,
-          dfa_entries[i].entry_name, dfa_entries[i].state_number);
-      if (header_output) {
-        fprintf(header_output, "extern int %s%s;\n",
-            prefix_under,
-            dfa_entries[i].entry_name);
-      }
-    }
-  }
-}
-/*}}}*/
-/* ================================================================= */
-static void deal_with_multiple_entries(Block **blk, struct DFA **dfa)/*{{{*/
-{
-  /* Get the list of blocks that are to be combined to form a union of all their states. */
-  struct Entrylist *e;
-  int Ne;
-  Block **blocks;
-  Block *jumbo;
-  int bi, Nb, Ns, si, ei;
-
-  for (Ne=0, e=entries; e; e=e->next) Ne++;
-  if (report) {
-    fprintf(report, "Processing %d separate entry points\n", Ne);
-  }
-  blocks = new_array(Block*, Ne);
-  for (Nb=0, e=entries; e; e=e->next) {
-    int matched = 0;
-    for (bi=0; bi<Nb; bi++) {
-      if (e->state->parent == blocks[bi]) {
-        matched = 1;
-        break;
-      }
-    }
-    if (!matched) {
-      blocks[Nb++] = e->state->parent;
-    }
-  }
-  for (Ns=0, bi=0; bi<Nb; bi++) {
-    Ns += blocks[bi]->nstates;
-  }
-
-  if (report) {
-    fprintf(report, "Entries in %d blocks, total of %d states\n",
-        Nb, Ns);
-  }
-
-  jumbo = new(Block);
-  jumbo->name = "(UNION OF MULTIPLE BLOCKS)";
-  jumbo->nstates = jumbo->maxstates = Ns;
-  jumbo->states = new_array(State *, Ns);
-  jumbo->eclo = NULL;
-
-  for (bi=0, si=0; bi<Nb; bi++) {
-    int ns = blocks[bi]->nstates;
-    int i;
-    int block_name_len;
-    memcpy(jumbo->states + si, blocks[bi]->states, sizeof(State *) * ns);
-    block_name_len = strlen(blocks[bi]->name);
-    for (i=0; i<ns; i++) {
-      int len;
-      char *new_name;
-      State *s = jumbo->states[si + i];
-      len = block_name_len + strlen(s->name) + 2;
-      new_name = new_array(char, len);
-      strcpy(new_name, blocks[bi]->name);
-      strcat(new_name, ".");
-      strcat(new_name, s->name);
-      free(s->name);
-      s->name = new_name;
-    }
-    si += ns;
-  }
-
-  /* Reindex all the states */
-  for (si=0; si<Ns; si++) {
-    jumbo->states[si]->index = si;
-  }
-
-  split_charclasses(jumbo);
-  expand_charclass_transitions(jumbo);
-
-  if (verbose) fprintf(stderr, "Computing epsilon closure...\n");
-  generate_epsilon_closure(jumbo);
-  print_nfa(jumbo);
-  build_transmap(jumbo);
-
-  if (verbose) fprintf(stderr, "Building DFA...\n");
-  n_dfa_entries = Ne;
-  dfa_entries = new_array(struct DFAEntry, Ne);
-  for (e=entries, ei=0; e; e=e->next, ei++) {
-    dfa_entries[ei].entry_name = new_string(e->entry_name);
-    dfa_entries[ei].state_number = e->state->index;
-  }
-  *dfa = build_dfa(jumbo);
-  *blk = jumbo;
-
-}
-/*}}}*/
-/* ================================================================= */
-static void usage(void)/*{{{*/
-{
-  fprintf(stderr,
-    "dfasyn, Copyright (C) 2001-2003,2005,2006 Richard P. Curnow\n"
-    "\n"
-    "dfasyn comes with ABSOLUTELY NO WARRANTY.\n"
-    "This is free software, and you are welcome to redistribute it\n"
-    "under certain conditions; see the GNU General Public License for details.\n"
-    "\n"
-    "Usage: dfasyn [OPTION]... FILE\n"
-    "Read state-machine description from FILE and generate a deterministic automaton.\n"
-    "Write results to stdout unless options dictate otherwise.\n"
-    "\n"
-    "Output files:\n"
-    "  -o,  --output FILE          Define the name of the output file (e.g. foobar.c)\n"
-    "  -ho, --header-output FILE   Define the name of the header output file (e.g. foobar.h)\n"
-    "  -r,  --report FILE          Define the name where the full generator report goes (e.g. foobar.report)\n"
-    "\n"
-    "Generated automaton:\n"
-    "  -p,  --prefix PREFIX        Specify a prefix for the variables and functions in the generated file(s)\n"
-    "  -u,  --uncompressed-tables  Don't compress the generated transition tables\n"
-    "  -ud, --uncompressed-dfa     Don't common-up identical states in the DFA\n"
-    "  -I,  --inline-function      Make the next_state function inline (requires -ho)\n"
-    "\n"
-    "General:\n"
-    "  -v,  --verbose              Be verbose\n"
-    "  -h,  --help                 Display this help message\n"
-    );
-
-}
-/*}}}*/
-/* ================================================================= */
-int main (int argc, char **argv)/*{{{*/
-{
-  int result;
-
-  Block *main_block;
-  char *input_name = NULL;
-  char *output_name = NULL;
-  char *header_output_name = NULL;
-  char *report_name = NULL;
-  int uncompressed_tables = 0;
-  int uncompressed_dfa = 0; /* Useful for debug */
-  int do_inline = 0;
-  extern char *prefix;
-  char *prefix_under;
-  FILE *input = NULL;
-  struct DFA *dfa;
-
-  verbose = 0;
-  report = NULL;
-
-  /*{{{ Parse cmd line arguments */
-  while (++argv, --argc) {
-    if (!strcmp(*argv, "-h") || !strcmp(*argv, "--help")) {
-      usage();
-      exit(0);
-    } else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) {
-      verbose = 1;
-    } else if (!strcmp(*argv, "-o") || !strcmp(*argv, "--output")) {
-      ++argv, --argc;
-      output_name = *argv;
-    } else if (!strcmp(*argv, "-ho") || !strcmp(*argv, "--header-output")) {
-      ++argv, --argc;
-      header_output_name = *argv;
-    } else if (!strcmp(*argv, "-r") || !strcmp(*argv, "--report")) {
-      ++argv, --argc;
-      report_name = *argv;
-    } else if (!strcmp(*argv, "-u") || !strcmp(*argv, "--uncompressed-tables")) {
-      uncompressed_tables = 1;
-    } else if (!strcmp(*argv, "-ud") || !strcmp(*argv, "--uncompressed-dfa")) {
-      uncompressed_dfa = 1;
-    } else if (!strcmp(*argv, "-I") || !strcmp(*argv, "--inline-function")) {
-      do_inline = 1;
-    } else if (!strcmp(*argv, "-p") || !strcmp(*argv, "--prefix")) {
-      ++argv, --argc;
-      prefix = *argv;
-    } else if ((*argv)[0] == '-') {
-      fprintf(stderr, "Unrecognized command line option %s\n", *argv);
-    } else {
-      input_name = *argv;
-    }
-  }
-  /*}}}*/
-
-  if (do_inline && !header_output_name) {/*{{{*/
-    fprintf(stderr,
-        "--------------------------------------------------------------\n"
-        "It doesn't make sense to try inlining if you're not generating\n"
-        "a separate header file.\n"
-        "Not inlining the transition function.\n"
-        "--------------------------------------------------------------\n"
-        );
-    do_inline = 0;
-  }
-/*}}}*/
-  if (input_name) {/*{{{*/
-    input = fopen(input_name, "r");
-    if (!input) {
-      fprintf(stderr, "Can't open %s for input, exiting\n", input_name);
-      exit(1);
-    }
-  } else {
-    input = stdin;
-  }
-  /*}}}*/
-  if (output_name) {/*{{{*/
-    output = fopen(output_name, "w");
-    if (!output) {
-      fprintf(stderr, "Can't open %s for writing, exiting\n", output_name);
-      exit(1);
-    }
-  } else {
-    output = stdout;
-  }
-/*}}}*/
-  if (header_output_name) {/*{{{*/
-    header_output = fopen(header_output_name, "w");
-    if (!header_output) {
-      fprintf(stderr, "Can't open %s for writing, exiting\n", header_output_name);
-      exit(1);
-    }
-  }
-  /* otherwise the header stuff just goes to the same fd as the main output. */
-
-/*}}}*/
-  if (report_name) {/*{{{*/
-    report = fopen(report_name, "w");
-    if (!report) {
-      fprintf(stderr, "Can't open %s for writing, no report will be created\n", report_name);
-    }
-  }
-/*}}}*/
-
-  if (verbose) {
-    fprintf(stderr, "General-purpose automaton builder\n");
-    fprintf(stderr, "Copyright (C) Richard P. Curnow  2000-2003,2005,2006\n");
-  }
-
-  eval_initialise();
-
-  if (verbose) fprintf(stderr, "Parsing input...");
-  yyin = input;
-
-  /* Set yyout.  This means that if anything leaks from the scanner, or appears
-     in a %{ .. %} block, it goes to the right place. */
-  yyout = output;
-
-  result = yyparse();
-  if (result > 0) exit(1);
-  if (verbose) fprintf(stderr, "\n");
-
-  make_evaluator_array();
-  check_default_attrs();
-
-  if (!entries) {
-    /* Support legacy method : the last state to be current in the input file
-     * is the entry state of the NFA */
-    State *start_state;
-    start_state = get_curstate();
-    main_block = start_state->parent;
-    split_charclasses(main_block);
-    expand_charclass_transitions(main_block);
-    if (verbose) fprintf(stderr, "Computing epsilon closure...\n");
-    generate_epsilon_closure(main_block);
-    print_nfa(main_block);
-    build_transmap(main_block);
-
-    if (verbose) fprintf(stderr, "Building DFA...\n");
-    {
-      struct DFAEntry entry[1];
-      n_dfa_entries = 1;
-      dfa_entries = entry;
-      entry[0].entry_name = "(ONLY ENTRY)";
-      entry[0].state_number = start_state->index;
-      dfa = build_dfa(main_block);
-    }
-  } else {
-    /* Allow generation of multiple entry states, so you can use the same input file when
-     * you need several automata that have a lot of logic in common. */
-    deal_with_multiple_entries(&main_block, &dfa);
-  }
-  if (report) {
-    fprintf(report, "--------------------------------\n"
-                    "DFA structure before compression\n"
-                    "--------------------------------\n");
-  }
-  print_dfa(dfa);
-
-  if (had_ambiguous_result) {
-    fprintf(stderr, "No output written, there were ambiguous attribute values for accepting states\n");
-    exit(2);
-  }
-
-  if (!uncompressed_dfa) {
-    if (verbose) fprintf(stderr, "\nCompressing DFA...\n");
-    compress_dfa(dfa, ntokens + n_charclasses, n_dfa_entries, dfa_entries);
-  }
-
-  if (verbose) fprintf(stderr, "\nCompressing transition tables...\n");
-  compress_transition_table(dfa, ntokens + n_charclasses);
-
-  if (report) {
-    fprintf(report, "-------------------------------\n"
-                    "DFA structure after compression\n"
-                    "-------------------------------\n");
-  }
-  if (verbose) fprintf(stderr, "Writing outputs...\n");
-  print_dfa(dfa);
-
-  if (prefix) {
-    prefix_under = new_array(char, 2 + strlen(prefix));
-    strcpy(prefix_under, prefix);
-    strcat(prefix_under, "_");
-  } else {
-    prefix_under = "";
-  }
-
-  if (header_output) {
-    fprintf(header_output, "#ifndef %sHEADER_H\n", prefix_under);
-    fprintf(header_output, "#define %sHEADER_H\n", prefix_under);
-  }
-
-  print_token_table();
-  print_charclass_mapping(output, header_output, prefix_under);
-  print_attr_tables(dfa, prefix_under);
-
-  if (uncompressed_tables) {
-    print_uncompressed_tables(dfa, do_inline, prefix_under);
-  } else {
-    print_compressed_tables(dfa, do_inline, prefix_under);
-  }
-
-  if (entries) {
-    /* Emit entry table */
-    print_entries_table(prefix_under);
-  } else {
-    /* Legacy behaviour - DFA state 0 is implicitly the single entry state. */
-  }
-
-  if (report) {
-    fclose(report);
-    report = NULL;
-  }
-
-  report_unused_tags();
-
-  if (header_output) {
-    fprintf(header_output, "#endif\n");
-  }
-
-  return result;
-}
-/*}}}*/
diff --git a/src/mairix/dfasyn/dfasyn.h b/src/mairix/dfasyn/dfasyn.h
@@ -1,365 +0,0 @@
-/***************************************
-  Header file for NFA->DFA conversion utility.
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 N2D_H
-#define N2D_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define new(T) ((T *) malloc(sizeof(T)))
-#define new_array(T,N) ((T *) malloc((N) * sizeof(T)))
-#define resize_array(T,arr,newN) ((T *) ((arr) ? realloc(arr,(newN)*sizeof(T)) : malloc((newN)*sizeof(T))))
-#define new_string(s) strcpy((char *)malloc((strlen(s)+1)*sizeof(char)),s)
-
-/* For typecasting, especially useful for declarations of local ptrs to args
-   of a qsort comparison fn */
-#define Castdecl(x, T, nx) T nx = (T) x
-
-#define Castderef(x, T, nx) T nx = *(T*) x
-
-/* Globally visible options to control reporting */
-extern FILE *report;
-extern FILE *report;
-extern FILE *output;
-extern FILE *header_output;
-
-/* Bison interface. */
-extern FILE *yyin;
-extern FILE *yyout;
-
-extern int verbose;
-
-extern char *prefix;
-
-/* Temporary - this will be done better when the charclass stuff is
- * added. */
-extern char **toktable;
-extern int ntokens;
-
-extern int n_charclasses;
-
-extern int had_ambiguous_result;
-
-extern int n_dfa_entries;
-extern struct DFAEntry *dfa_entries;
-
-struct State;
-struct Block;
-struct StimulusList;
-
-struct Abbrev {/*{{{*/
-  char *lhs; /* Defined name */
-  struct StimulusList *stimuli;
-#if 0
-  char **rhs; /* Token/define */
-  int nrhs;
-  int maxrhs;
-#endif
-};
-/*}}}*/
-
-typedef enum StimulusType {/*{{{*/
-  T_EPSILON,
-  T_TOKEN,
-  T_ABBREV,
-  T_INLINEBLOCK,
-  T_CHARCLASS
-} StimulusType;
-/*}}}*/
-typedef struct InlineBlock {/*{{{*/
-  char *type; /* Block type */
-  char *in;   /* Name of input node */
-  char *out;  /* Name of output node */
-} InlineBlock;
-/*}}}*/
-
-#define ULONGS_PER_CC 8
-
-typedef struct CharClass {/*{{{*/
-  int is_used;
-  unsigned long char_bitmap[ULONGS_PER_CC];
-  unsigned long group_bitmap[ULONGS_PER_CC];
-} CharClass;
-/*}}}*/
-typedef struct Stimulus {/*{{{*/
-  StimulusType type;
-  union {
-    /* TODO : token should eventually become a struct ref ? */
-    int token;
-    struct Abbrev *abbrev;
-    /* placeholders */
-    InlineBlock *inline_block;
-    CharClass *char_class;
-  } x;
-} Stimulus;
-/*}}}*/
-typedef struct StimulusList {/*{{{*/
-  struct StimulusList *next;
-  Stimulus *stimulus;
-} StimulusList;
-/*}}}*/
-typedef enum TransType {/*{{{*/
-  TT_EPSILON,
-  TT_TOKEN,
-  TT_CHARCLASS
-} TransType;
-/*}}}*/
-typedef struct TransList {/*{{{*/
-  struct TransList *next;
-  TransType type;
-  union {
-    int token;
-    CharClass *char_class;
-  } x;
-  char *ds_name;
-  struct State *ds_ref;
-} TransList;
-/*}}}*/
-typedef struct Stringlist {/*{{{*/
-  struct Stringlist *next;
-  char *string;
-} Stringlist;
-/*}}}*/
-
-#if 0
-typedef struct InlineBlockList {/*{{{*/
-  struct InlineBlockList *next;
-  InlineBlock *ib;
-} InlineBlockList;
-/*}}}*/
-#endif
-
-typedef struct State {/*{{{*/
-  char *name;
-  int index; /* Array index in containing block */
-  struct Block *parent;
-  TransList *transitions;
-  Stringlist *tags;
-  Stringlist *entries;
-
-  /* Pointers to the nodes in the 'transitions' list, sorted into canonical order */
-  TransList **ordered_trans;
-  int n_transitions;
-
-  unsigned char removed; /* Flag indicating state has been pruned by compression stage */
-} State;
-/*}}}*/
-typedef struct S_Stateset {/*{{{*/
-  State **states;
-  int nstates;
-  int maxstates;
-} Stateset;
-/*}}}*/
-#define HASH_BUCKETS 64
-#define HASH_MASK (HASH_BUCKETS-1)
-
-typedef struct Block {/*{{{*/
-  char *name;
-
-  /* The master table of states within this block.  This has to be in a flat
-     array because we have to work with respect to state indices when doing the
-     2D bitmap stuff for the subset construction. */
-  State **states;
-  int nstates;
-  int maxstates;
-
-  /* epsilon closure for this block (treating it as a top-level block.) */
-  unsigned long **eclo;
-
-  /* Hash table for getting rapid access to a state within the block, given
-     its name */
-  Stateset state_hash[HASH_BUCKETS];
-
-  int subcount; /* Number for generating substates */
-  int subblockcount; /* Number for generating inline subblocks */
-} Block;
-/*}}}*/
-struct Entrylist {/*{{{*/
-  struct Entrylist *next;
-  char *entry_name;
-  State *state;
-};
-/*}}}*/
-extern struct Entrylist *entries;
-
-typedef struct DFANode {/*{{{*/
-  unsigned long *nfas;
-  unsigned long signature; /* All the longwords in the nfas array xor'ed together */
-  int index; /* Entry's own index in the array */
-  int *map; /* index by token code */
-  int from_state; /* the state which provided the first transition to this one (leading to its creation) */
-  int via_token; /* the token through which we got to this state the first time. */
-  Stringlist *nfa_exit_sl; /* NFA exit values */
-  Stringlist *nfa_attr_sl; /* NFA exit values */
-  char **attrs;       /* Attributes, computed by boolean expressions defined in input text */
-  int has_early_exit; /* If !=0, the scanner is expected to exit immediately this DFA state is entered.
-                       It means that no out-bound transitions have to be created. */
-
-  /* Fields calculated in compdfa.c */
-
-  /* The equivalence class the state is in. */
-  int eq_class;
-
-  /* Temp. storage for the new eq. class within a single pass of the splitting alg. */
-  int new_eq_class;
-
-  /* Signature field from above is also re-used. */
-
-  int is_rep; /* Set if state is chosen as the representative of its equivalence class. */
-  int is_dead; /* Set if the state has no path to a non-default result */
-  int new_index; /* New index assigned to the state. */
-
-  /* Fields calculated in tabcompr.c */
-
-  unsigned long transition_sig;
-
-  /* Default state, i.e. the one that supplies transitions for tokens not
-     explicitly listed for this one. */
-  int defstate;
-
-  /* Number of transitions that this state has different to those in the
-     default state. */
-  int best_diff;
-
-} DFANode;
-/*}}}*/
-struct DFAEntry {/*{{{*/
-  char *entry_name;
-  /* Initially the NFA number, overwritten with DFA number by build_dfa */
-  int state_number;
-};
-/*}}}*/
-struct DFA {/*{{{*/
-  DFANode **s; /* states */
-  int n;
-  int max;
-
-  /* the original block that the DFA comes from. */
-  Block *b;
-};
-/*}}}*/
-
-void yyerror(const char *s);
-extern int yylex(void);
-
-/* Constants for 'create' args */
-#define USE_OLD_MUST_EXIST 0
-#define CREATE_MUST_NOT_EXIST 1
-#define CREATE_OR_USE_OLD 2
-
-State *get_curstate(void);
-
-struct Abbrev;
-extern struct Abbrev * create_abbrev(const char *name, struct StimulusList *stimuli);
-
-int lookup_token(char *name, int create);
-Block *lookup_block(char *name, int create);
-State *lookup_state(Block *in_block, char *name, int create);
-void add_entry_to_state(State *curstate, const char *entry);
-void define_entrystruct(const char *s, const char *v);
-Stringlist * add_string_to_list(Stringlist *existing, const char *token);
-void add_transitions(Block *curblock, State *curstate, StimulusList *stimuli, char *destination);
-State * add_transitions_to_internal(Block *curblock, State *addtostate, StimulusList *stimuli);
-void add_tags(State *curstate, Stringlist *sl);
-InlineBlock *create_inline_block(char *type, char *in, char *out);
-void instantiate_block(Block *curblock, char *block_name, char *instance_name);
-void fixup_state_refs(Block *b);
-void expand_charclass_transitions(Block *b);
-
-void compress_nfa(Block *b);
-
-extern void generate_epsilon_closure(Block *b);
-extern void print_nfa(Block *b);
-extern void build_transmap(Block *b);
-extern struct DFA *build_dfa(Block *b);
-extern void print_dfa(struct DFA *dfa);
-
-/* In expr.c */
-typedef struct Expr Expr;
-
-Expr * new_not_expr(Expr *c);
-Expr * new_and_expr(Expr *c1, Expr *c2);
-Expr * new_or_expr(Expr *c1, Expr *c2);
-Expr * new_xor_expr(Expr *c1, Expr *c2);
-Expr * new_cond_expr(Expr *c1, Expr *c2, Expr *c3);
-Expr * new_tag_expr(char *tag_name);
-extern int eval(Expr *e);
-void define_tag(char *name, Expr *e);
-void clear_tag_values(void);
-void report_unused_tags(void);
-
-/* In evaluator.c */
-typedef struct evaluator Evaluator;
-extern int n_evaluators;
-extern Evaluator *default_evaluator;
-extern Evaluator *start_evaluator(const char *name);
-void define_attr(Evaluator *x, char *string, Expr *e, int early);
-void define_defattr(Evaluator *x, char *string);
-void set_tag_value(char *tag_name);
-int evaluate_attrs(char ***, int *);
-int evaluator_is_used(Evaluator *x);
-void define_defattr(Evaluator *x, char *text);
-void define_type(Evaluator *x, char *text);
-char* get_defattr(int i);
-char* get_attr_type(int i);
-char* get_attr_name(int i);
-void make_evaluator_array(void);
-void emit_dfa_attr_report(char **results, FILE *out);
-void eval_initialise(void);
-
-void compress_transition_table(struct DFA *dfa, int ntokens);
-unsigned long increment(unsigned long x, int field);
-unsigned long count_bits_set(unsigned long x);
-
-/* in abbrevs.c */
-struct Abbrev * lookup_abbrev(char *name);
-
-/* in stimulus.c */
-extern Stimulus *stimulus_from_epsilon(void);
-extern Stimulus *stimulus_from_string(char *str);
-extern Stimulus *stimulus_from_inline_block(InlineBlock *block);
-extern Stimulus *stimulus_from_char_class(CharClass *char_class);
-extern StimulusList *append_stimulus_to_list(StimulusList *existing, Stimulus *stim);
-
-/* in charclass.c */
-extern int cc_test_bit(const unsigned long *bitmap, int entry);
-extern CharClass *new_charclass(void);
-extern void free_charclass(CharClass *what);
-extern void add_charclass_to_list(CharClass *cc);
-extern void add_singleton_to_charclass(CharClass *towhat, char thechar);
-extern void add_range_to_charclass(CharClass *towhat, char star, char end);
-extern void invert_charclass(CharClass *what);
-extern void diff_charclasses(CharClass *left, CharClass *right);
-extern void split_charclasses(const Block *b);
-extern void print_charclass_mapping(FILE *out, FILE *header_out, const char *prefix_under);
-extern void print_charclass(FILE *out, int idx);
-
-/* Return new number of DFA states */
-extern void compress_dfa(struct DFA *dfa, int ntokens,
-    int n_dfa_entries, struct DFAEntry *dfa_entries);
-
-#endif /* N2D_H */
-
diff --git a/src/mairix/dfasyn/dfasyn.texi b/src/mairix/dfasyn/dfasyn.texi
@@ -1,85 +0,0 @@
-@setfilename dfasyn.info
-@settitle User guide for the dfasyn DFA construction utility
-
-@titlepage
-@title dfasyn user guide
-@subtitle This manual describes how to use dfasyn.
-@author Richard P. Curnow
-@page
-@end titlepage
-
-@c{{{ Top node
-@node Top
-@top
-@menu
-* Introduction:: The introduction
-* Input file format:: A reference for the input file
-* Concept Index:: Index of concepts
-@end menu
-@c}}}
-@c{{{ ch:Introduction
-@node Introduction
-@chapter Introduction
-
-@menu
-* Uses for dfasyn:: The types of problem to which dfasyn is well-suited
-@end menu
-
-@node Uses for dfasyn
-@section Uses for dfasyn
-dfasyn is particularly suited to the following types of scanning problem, both of
-which exceed flex's capabilities
-
-@itemize @bullet
-@item When the pattern describing a token cannot be written as a regular
-expression.  For example, there may be iteration but with constraints between
-the end of one iteration and the start of the next.
-@item When more than 1 rule matches in a flex input file, flex chooses between
-them based on
-
-  @itemize -
-  @item Longest match first
-  @item Earliest rule in the file if more than 1 match of the same length exists
-  @end itemize
-
-dfasyn allows for a more general method of resolving multiple matches.
-Conceptually, it works out which rules match, giving a true/false status for
-each rule.  The input file defines an arbitrarily complex set of boolean
-expressions to reduce the multiple matches down to one unique one.  (If more than
-one of the boolean expressions evaluates true, this is an error.)
-
-@item When a customised method is required to construct the input tokens that
-pass to the scanner.  For example, if the tokens are the characters in a string
-(rather than coming from a file), or if some special logic has to be used to
-generate the tokens from the input character stream.
-  
-@item If you want to add actions to the scanning loop, e.g. to remember special
-locations within the word being scanned.
-  
-@end itemize
-
-@node Non-uses for dfasyn
-@section Cases where flex might be better
-
-In general, flex is easier and more convenient to use.  Where it is applicable
-to your problem, there are no obvious benefits to using dfasyn.
-
-@node Why written
-@section Why was dfasyn written?
-@c}}}
-
-@c{{{ ch:Input file format
-@node Input file format
-@chapter Input file format
-This section describes the format of the input file.
-
-@c}}}
-
-
-@node Concept Index
-@unnumbered Concept Index
-@printindex cp
-@bye
-
-@c vim:syntax=OFF:fdm=marker:fdc=4:cms=@c%s
-
diff --git a/src/mairix/dfasyn/evaluator.c b/src/mairix/dfasyn/evaluator.c
@@ -1,248 +0,0 @@
-/***************************************
-  Routines for merging and prioritising exit tags and attribute tags
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Handle boolean expressions used to determine the final scanner result from
-   the set of NFA accepting states that are simultaneously active at the end of
-   the scan.  */
-
-#include "dfasyn.h"
-
-struct Attr {
-  char *attr; /* The string to write to the output file */
-  /* The boolean expression that defines whether the attribute is active */
-  Expr *e;
-  /* If != 0, assume the state machine that the program's output is embedded in
-     will exit immediately if this result occurs.  This may allow lots of
-     states to be culled from the DFA. */
-  int early;
-};
-
-typedef struct Attr Attr;
-struct evaluator {
-  Attr *attrs;
-  int is_used; /* Set if any input rules reference this evaluator */
-  int n_attrs;
-  int max_attrs;
-  char *name;
-  char *defattr;
-  char *attr_type;
-};
-
-Evaluator *default_evaluator;
-
-struct evaluator_list {
-  struct evaluator_list *next;
-  Evaluator *evaluator;
-};
-
-static struct evaluator_list *evaluator_list = NULL;
-
-/* Array pointer */
-static struct evaluator **evaluators = NULL;
-int n_evaluators = 0;
-
-Evaluator* start_evaluator(const char *name)/*{{{*/
-{
-  Evaluator *x = NULL;
-  struct evaluator_list *el;
-  for (el=evaluator_list; el; el=el->next) {
-    /* name is null for the default (anonymous) attribute group */
-    const char *een = el->evaluator->name;
-    if ((!een && !name) ||
-        (een && name && !strcmp(een, name))) {
-      x = el->evaluator;
-      break;
-    }
-  }
-  if (!x) {
-    struct evaluator_list *nel;
-    x = new(struct evaluator);
-    x->attrs = NULL;
-    x->is_used = 0;
-    x->n_attrs = x->max_attrs = 0;
-    x->name = name ? new_string(name) : NULL;
-    x->defattr = NULL;
-    x->attr_type = NULL;
-    nel = new(struct evaluator_list);
-    nel->next = evaluator_list;
-    nel->evaluator = x;
-    evaluator_list = nel;
-  }
-  return x;
-}
-/*}}}*/
-void destroy_evaluator(Evaluator *x)/*{{{*/
-{
-  /* Just leak memory for now, no need to clean up. */
-  return;
-}
-/*}}}*/
-void define_defattr(Evaluator *x, char *text)/*{{{*/
-{
-  x = x ? x : default_evaluator;
-  x->defattr = new_string(text);
-  x->is_used = 1;
-}
-/*}}}*/
-void define_type(Evaluator *x, char *text)/*{{{*/
-{
-  x = x ? x : default_evaluator;
-  x->attr_type = new_string(text);
-  x->is_used = 1;
-}
-/*}}}*/
-char* get_defattr(int i)/*{{{*/
-{
-  Evaluator *x = evaluators[i];
-  return x->defattr;
-}
-/*}}}*/
-char* get_attr_type(int i)/*{{{*/
-{
-  Evaluator *x = evaluators[i];
-  return x->attr_type ? x->attr_type : "short";
-}
-/*}}}*/
-char* get_attr_name(int i)/*{{{*/
-{
-  Evaluator *x = evaluators[i];
-  return x->name ? x->name : NULL;
-}
-/*}}}*/
-static void grow_attrs(Evaluator *x)/*{{{*/
-{
-  if (x->n_attrs == x->max_attrs) {
-    x->max_attrs += 32;
-    x->attrs = resize_array(Attr, x->attrs, x->max_attrs);
-  }
-}
-/*}}}*/
-
-void define_attr(Evaluator *x, char *string, Expr *e, int early)/*{{{*/
-/*++++++++++++++++++++
-  Add a attr defn.  If the expr is null, it means build a single expr corr.
-  to the value of the tag with the same name as the attr string.
-  ++++++++++++++++++++*/
-{
-  Attr *r;
-
-  x = x ? x : default_evaluator;
-
-  x->is_used = 1;
-  grow_attrs(x);
-  r = &(x->attrs[x->n_attrs++]);
-  r->attr = new_string(string);
-  r->early = early;
-  if (e) {
-    r->e = e;
-  } else {
-    Expr *ne;
-    ne = new_tag_expr(string);
-    r->e = ne;
-  }
-
-  return;
-}
-/*}}}*/
-
-void make_evaluator_array(void)/*{{{*/
-{
-  int n;
-  struct evaluator_list *el;
-  for (el=evaluator_list, n=0; el; el=el->next, n++) ;
-  evaluators = new_array(struct evaluator *, n);
-  n_evaluators = n;
-  for (el=evaluator_list, n=0; el; el=el->next, n++) {
-    evaluators[n] = el->evaluator;
-  }
-}
-/*}}}*/
-int evaluate_attrs(char ***attrs, int *attr_early)/*{{{*/
-/*++++++++++++++++++++
-  Evaluate the attr which holds given the tags that are set
-  ++++++++++++++++++++*/
-{
-  int i, j;
-  int status;
-
-  if (attr_early) *attr_early = 0;
-  status = 1;
-
-  *attrs = new_array(char *, n_evaluators);
-
-  for (j=0; j<n_evaluators; j++) {
-    char **attr;
-    struct evaluator *x;
-    int any_attrs_so_far = 0;
-    int matched = -1;
-
-    attr = &(*attrs)[j];
-    x = evaluators[j];
-
-    for (i=0; i<x->n_attrs; i++) {
-      if (eval(x->attrs[i].e)) {
-        if (matched >= 0) {
-          *attr = NULL;
-          status = 0;
-          break;
-        } else {
-          any_attrs_so_far = 1;
-          matched = i;
-        }
-      }
-    }
-    if (matched < 0) {
-      *attr = NULL;
-    } else {
-      *attr = x->attrs[matched].attr;
-      if (attr_early) *attr_early |= x->attrs[matched].early;
-    }
-  }
-
-  return status;
-}
-/*}}}*/
-int evaluator_is_used(Evaluator *x)/*{{{*/
-{
-  return x->is_used;
-}
-/*}}}*/
-void emit_dfa_attr_report(char **attrs, FILE *out)/*{{{*/
-{
-  int i;
-  for (i=0; i<n_evaluators; i++) {
-    if (attrs[i]) {
-      const char *name = evaluators[i]->name;
-      fprintf(out, "  Attributes for <%s> : %s\n",
-          name ? name : "(DEFAULT)", attrs[i]);
-    }
-  }
-}
-/*}}}*/
-/* Initialisation */
-void eval_initialise(void)/*{{{*/
-{
-  default_evaluator = start_evaluator(NULL);
-}
-/*}}}*/
diff --git a/src/mairix/dfasyn/expr.c b/src/mairix/dfasyn/expr.c
@@ -1,243 +0,0 @@
-/***************************************
-  Routines for merging and prioritising exit tags and attribute tags
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Handle boolean expressions used to determine the final scanner result from
-   the set of NFA accepting states that are simultaneously active at the end of
-   the scan.  */
-
-#include "dfasyn.h"
-
-enum ExprType {
-  E_AND, E_OR, E_XOR, E_COND, E_NOT, E_TAG
-};
-
-struct Tag;
-
-struct Expr {
-  enum ExprType type;
-  union {
-    struct { struct Expr *c1, *c2; } and;
-    struct { struct Expr *c1, *c2; } or;
-    struct { struct Expr *c1, *c2; } xor;
-    struct { struct Expr *c1, *c2, *c3; } cond;
-    struct { struct Expr *c1; } not;
-    struct { char *name; struct Tag *s; } tag;
-  } data;
-};
-
-struct Tag {
-  char *name;
-  int is_expr;
-  union {
-    Expr *e;
-    int val;
-  } data;
-  int is_used;
-};
-
-struct TagList {
-  struct TagList *next;
-  struct Tag *tag;
-};
-
-typedef struct Tag Tag;
-typedef struct TagList TagList;
-
-static TagList *tags = NULL;
-
-Expr * new_not_expr(Expr *c)/*{{{*/
-{
-  Expr *r = new(Expr);
-  r->type = E_NOT;
-  r->data.not.c1 = c;
-  return r;
-}
-/*}}}*/
-Expr * new_and_expr(Expr *c1, Expr *c2)/*{{{*/
-{
-  Expr *r = new(Expr);
-  r->type = E_AND;
-  r->data.and.c1 = c1;
-  r->data.and.c2 = c2;
-  return r;
-}
-/*}}}*/
-Expr * new_or_expr(Expr *c1, Expr *c2)/*{{{*/
-{
-  Expr *r = new(Expr);
-  r->type = E_OR;
-  r->data.or.c1 = c1;
-  r->data.or.c2 = c2;
-  return r;
-}
-/*}}}*/
-Expr * new_xor_expr(Expr *c1, Expr *c2)/*{{{*/
-{
-  Expr *r = new(Expr);
-  r->type = E_XOR;
-  r->data.xor.c1 = c1;
-  r->data.xor.c2 = c2;
-  return r;
-}
-/*}}}*/
-Expr * new_cond_expr(Expr *c1, Expr *c2, Expr *c3)/*{{{*/
-{
-  Expr *r = new(Expr);
-  r->type = E_COND;
-  r->data.cond.c1 = c1;
-  r->data.cond.c2 = c2;
-  r->data.cond.c3 = c3;
-  return r;
-}
-/*}}}*/
-
-Expr * new_tag_expr(char *tag_name)/*{{{*/
-/* Return expr for tag name if it already exist, else create.  Don't bind to
-   actual tag instance yet.  At the stage of parsing where this function is
-   used, we don't know yet which tag table the tag has to exist in.  */
-{
-  Expr *r;
-
-  r = new(Expr);
-  r->type = E_TAG;
-  r->data.tag.name = new_string(tag_name);
-  r->data.tag.s = NULL; /* Force binding at first use */
-  return r;
-}
-/*}}}*/
-static void add_new_tag(Tag *s)/*{{{*/
-{
-  TagList *nsl = new(TagList);
-  nsl->tag = s;
-  nsl->next = tags;
-  tags = nsl;
-}
-  /*}}}*/
-static Tag *  find_tag_or_create(char *tag_name)/*{{{*/
-{
-  Tag *s;
-  TagList *sl;
-  for (sl=tags; sl; sl=sl->next) {
-    s = sl->tag;
-    if (!strcmp(s->name, tag_name)) {
-      return s;
-    }
-  }
-
-  s = new(Tag);
-  add_new_tag(s);
-  s->is_expr = 0; /* Until proven otherwise */
-  s->data.val = 0; /* Force initial value to be well-defined */
-  s->name = new_string(tag_name);
-  s->is_used = 0;
-  return s;
-}
-/*}}}*/
-void define_tag(char *name, Expr *e)/*{{{*/
-/*++++++++++++++++++++
-  Define an entry in the tag table.
-  ++++++++++++++++++++*/
-{
-  Tag *s;
-  s = find_tag_or_create(name);
-  s->data.e = e;
-  s->is_expr = 1;
-  return;
-}
-/*}}}*/
-
-void clear_tag_values(void)/*{{{*/
-{
-  TagList *sl;
-  for (sl=tags; sl; sl=sl->next) {
-    Tag *s = sl->tag;
-    if (0 == s->is_expr) {
-      s->data.val = 0;
-    }
-  }
-}
-/*}}}*/
-void set_tag_value(char *tag_name)/*{{{*/
-{
-  Tag *s;
-
-  s = find_tag_or_create(tag_name);
-  if (s->is_expr) {
-    fprintf(stderr, "Cannot set value for tag '%s', it is defined by an expression\n", s->name);
-    exit(2);
-  } else {
-    s->data.val = 1;
-  }
-}
-/*}}}*/
-int eval(Expr *e)/*{{{*/
-/*++++++++++++++++++++
-  Evaluate the value of an expr
-  ++++++++++++++++++++*/
-{
-  switch (e->type) {
-    case E_AND:
-      return eval(e->data.and.c1) && eval(e->data.and.c2);
-    case E_OR:
-      return eval(e->data.or.c1) || eval(e->data.or.c2);
-    case E_XOR:
-      return eval(e->data.xor.c1) ^ eval(e->data.xor.c2);
-    case E_COND:
-      return eval(e->data.cond.c1) ? eval(e->data.cond.c2) : eval(e->data.cond.c3);
-    case E_NOT:
-      return !eval(e->data.not.c1);
-    case E_TAG:
-      {
-        Tag *s = e->data.tag.s;
-        int result;
-        if (!s) {
-          /* Not bound yet */
-          e->data.tag.s = s = find_tag_or_create(e->data.tag.name);
-        }
-        if (s->is_expr) {
-          result = eval(s->data.e);
-        } else {
-          result = s->data.val;
-        }
-        s->is_used = 1;
-        return result;
-      }
-    default:
-      fprintf(stderr, "Interal error : Can't get here!\n");
-      exit(2);
-  }
-}
-/*}}}*/
-void report_unused_tags(void)/*{{{*/
-{
-  Tag *s;
-  TagList *sl;
-  for (sl=tags; sl; sl=sl->next) {
-    s = sl->tag;
-    if (!s->is_used) {
-      fprintf(stderr, "Warning: tag <%s> not referenced by any attribute expression\n", s->name);
-    }
-  }
-}
-/*}}}*/
diff --git a/src/mairix/dfasyn/n2d.c b/src/mairix/dfasyn/n2d.c
@@ -1,696 +0,0 @@
-/***************************************
-  Convert NFA to DFA
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2000-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* {{{ General comments
-  Convert a nondeterminstic finite automaton (NFA) into a deterministic finite
-  automaton (DFA).
-
-  The NFA is defined in terms of a set of states, with transitions between the
-  states.  The transitions may occur on any one of a set of symbols (specified
-  with | characters between the options), or may be 'epsilon' transitions, i.e.
-  occurring without consumption of any input.  A state may have multiple
-  transitions for the same input symbol (hence 'nondeterministic').  The final
-  state encountered within the final block defined in the input file is taken
-  to be the start state of the whole NFA.  A state may be entered more than
-  once in the file; the transitions in the multiple definitions are combined to
-  give the complete transition set.  A state may have 1 or more tags assigned
-  (with =); this is the return value of the automaton if the end of string is
-  encountered when in that state.
-  }}} */
-
-#include <ctype.h>
-#include "dfasyn.h"
-#include <assert.h>
-
-/* Globally visible options to control reporting */
-int verbose;
-
-struct Entrylist *entries = NULL;
-
-/* ================================================================= */
-static inline int round_up(const int x) {/*{{{*/
-  return (x+31)>>5;
-}
-/*}}}*/
-static inline void set_bit(unsigned long *x, int n)/*{{{*/
-{
-  int r = n>>5;
-  unsigned long m = 1UL<<(n&31);
-  x[r] |= m;
-}
-/*}}}*/
-static inline int is_set(unsigned long *x, int n)/*{{{*/
-{
-  int r = n>>5;
-  unsigned long m = 1UL<<(n&31);
-  return !!(x[r] & m);
-}
-/*}}}*/
-/* ================================================================= */
-static void transitively_close_eclo(unsigned long **eclo, int N)/*{{{*/
-{
-  int from;
-  unsigned long *from_row;
-  unsigned long *todo, this_todo;
-  int Nru;
-  int i, i32, j, k, merge_idx;
-  int j_limit;
-  int any_changes;
-
-  Nru = round_up(N);
-  todo = new_array(unsigned long, Nru);
-
-  for (from=0; from<N; from++) {
-    from_row = eclo[from];
-    for (i=0; i<Nru; i++) {
-      todo[i] = from_row[i];
-    }
-    any_changes = 1;
-    while (any_changes) {
-      any_changes = 0;
-      for (i=0; i<Nru; i++) { /* loop over words in bitvector */
-        i32 = i<<5;
-        this_todo = todo[i];
-        todo[i] = 0UL; /* reset to avoid oo-loop */
-        if (!this_todo) continue; /* none to do in this block */
-        j_limit = N - i32;
-        if (j_limit > 32) j_limit = 32;
-
-        for (j=0; j<j_limit;) { /* loop over bits in this word */
-          if (this_todo & 1) {
-            /* Merge in */
-            merge_idx = i32 + j;
-            for (k=0; k<Nru; k++) {
-              unsigned long to_merge = eclo[merge_idx][k];
-              unsigned long orig = from_row[k];
-              unsigned long diffs = to_merge & (~orig);
-              from_row[k] |= to_merge;
-              if (diffs) any_changes = 1;
-              todo[k] |= diffs;
-            }
-          }
-          this_todo >>= 1;
-          if (!this_todo) break; /* Workload reduction at end */
-          j++;
-        }
-      }
-    }
-  }
-}
-/*}}}*/
-void generate_epsilon_closure(Block *b)/*{{{*/
-{
-  int i, j, N;
-
-  N = b->nstates;
-  b->eclo = new_array(unsigned long*, N);
-  for (i=0; i<N; i++) {
-    b->eclo[i] = new_array(unsigned long, round_up(N));
-    for (j=0; j<round_up(N); j++) {
-      b->eclo[i][j] = 0;
-    }
-  }
-
-  /* Determine initial immediate transitions */
-  for (i=0; i<N; i++) {
-    State *s = b->states[i];
-    TransList *tl;
-    int from_state = s->index;
-    set_bit(b->eclo[from_state], from_state); /* Always reflexive */
-
-    for (tl=s->transitions; tl; tl=tl->next) {
-      switch (tl->type) {
-        case TT_EPSILON:
-          {
-            int to_state = tl->ds_ref->index;
-            set_bit(b->eclo[from_state], to_state);
-          }
-          break;
-        case TT_TOKEN:
-          /* smoke out old method of indicating an epsilon trans */
-          assert(tl->x.token >= 0);
-          break;
-        default:
-          assert(0);
-          break;
-      }
-    }
-  }
-
-  transitively_close_eclo(b->eclo, N);
-
-}
-/*}}}*/
-void print_nfa(Block *b)/*{{{*/
-{
-  int i, j, N;
-  N = b->nstates;
-
-  if (!report) return;
-
-  for (i=0; i<N; i++) {
-    State *s = b->states[i];
-    TransList *tl;
-    Stringlist *sl;
-    fprintf(report, "NFA state %d = %s", i, s->name);
-    if (s->entries) {
-      int first = 1;
-      Stringlist *e = s->entries;
-      fputs(" [Entries: ", report);
-      while (e) {
-        if (!first) {
-          fputc(',', report);
-        }
-        first = 0;
-        fputs(e->string, report);
-        e = e->next;
-      }
-      fputc(']', report);
-    }
-    fputc('\n', report);
-    for (tl=s->transitions; tl; tl=tl->next) {
-      switch (tl->type) {
-        case TT_EPSILON:
-          fprintf(report, "  [(epsilon)] -> ");
-          break;
-        case TT_TOKEN:
-          assert(tl->x.token >= 0);
-          if (tl->x.token >= ntokens) {
-            fprintf(report, "   ");
-            print_charclass(report, tl->x.token - ntokens);
-            fprintf(report, " -> ");
-          } else {
-            fprintf(report, "  %s -> ", toktable[tl->x.token]);
-          }
-          break;
-        default:
-          assert(0);
-          break;
-      }
-      fprintf(report, "%s\n", tl->ds_name);
-    }
-    if (s->tags) {
-      int first = 1;
-      fprintf(report, "  Tags : ");
-      for (sl=s->tags; sl; sl=sl->next) {
-        fprintf(report, "%s%s",
-                first ? "" : "|",
-                sl->string);
-      }
-      fprintf(report, "\n");
-    }
-    fprintf(report, "  Epsilon closure :\n    (self)\n");
-    for (j=0; j<N; j++) {
-      if (i!=j && is_set(b->eclo[i], j)) {
-        fprintf(report, "    %s\n", b->states[j]->name);
-      }
-    }
-
-    fprintf(report, "\n");
-  }
-
-}
-/*}}}*/
-/* ================================================================= */
-
-/* Indexed [from_state][token][to_state], flag set if there is
-   a transition from from_state to to_state, via token then zero or more
-   epsilon transitions */
-
-static unsigned long ***transmap;
-
-/* Index [from_nfa_state][token], flag set if there is a transition
-   to any destination nfa state for that token. */
-static unsigned long **anytrans;
-
-/* ================================================================= */
-void build_transmap(Block *b)/*{{{*/
-{
-  int N = b->nstates;
-  int Nt = ntokens + n_charclasses;
-  int i, j, k, m, dest;
-
-  transmap = new_array(unsigned long **, N);
-  anytrans = new_array(unsigned long *, N);
-  for (i=0; i<N; i++) {
-    transmap[i] = new_array(unsigned long *, Nt);
-    anytrans[i] = new_array(unsigned long, round_up(Nt));
-    for (j=0; j<round_up(Nt); j++) {
-      anytrans[i][j] = 0UL;
-    }
-    for (j=0; j<Nt; j++) {
-      transmap[i][j] = new_array(unsigned long, round_up(N));
-      for (k=0; k<round_up(N); k++) {
-        transmap[i][j][k] = 0UL;
-      }
-    }
-  }
-
-  for (i=0; i<N; i++) {
-    State *s = b->states[i];
-    TransList *tl;
-    for (tl=s->transitions; tl; tl=tl->next) {
-      switch (tl->type) {
-        case TT_EPSILON:
-          break;
-        case TT_TOKEN:
-          {
-            assert(tl->x.token >= 0);
-            dest = tl->ds_ref->index;
-            for (m=0; m<round_up(N); m++) {
-              unsigned long x = b->eclo[dest][m];
-              transmap[i][tl->x.token][m] |= x;
-              if (!!x) set_bit(anytrans[i], tl->x.token);
-            }
-          }
-          break;
-        default:
-          assert(0);
-          break;
-      }
-    }
-  }
-}
-/*}}}*/
-/* ================================================================= */
-
-int had_ambiguous_result = 0;
-
-/* ================================================================= */
-
-/* Implement an array of linked lists to access DFA states directly.  The
- * hashes are given by folding the signatures down to single bytes. */
-
-struct DFAList {
-  struct DFAList *next;
-  DFANode *dfa;
-};
-
-#define DFA_HASHSIZE 256
-static struct DFAList *dfa_hashtable[DFA_HASHSIZE];
-
-/* ================================================================= */
-
-int n_dfa_entries;
-struct DFAEntry *dfa_entries = NULL;
-
-/* ================================================================= */
-static void grow_dfa(struct DFA *dfa)/*{{{*/
-{
-  dfa->max += 32;
-  dfa->s = resize_array(DFANode*, dfa->s, dfa->max);
-}
-/*}}}*/
-static unsigned long fold_signature(unsigned long sig)/*{{{*/
-{
-  unsigned long folded;
-  folded = sig ^ (sig >> 16);
-  folded ^= (folded >> 8);
-  folded &= 0xff;
-  return folded;
-}
-/*}}}*/
-/* ================================================================= */
-static int find_dfa(unsigned long *nfas, int N)/*{{{*/
-/* Simple linear search.  Use 'signatures' to get rapid rejection
-   of any DFA state that can't possibly match */
-{
-  int j;
-  unsigned long signature = 0UL;
-  unsigned long folded_signature;
-  struct DFAList *dfal;
-
-  for (j=0; j<round_up(N); j++) {
-    signature ^= nfas[j];
-  }
-  folded_signature = fold_signature(signature);
-
-  for(dfal=dfa_hashtable[folded_signature]; dfal; dfal = dfal->next) {
-    DFANode *dfa = dfal->dfa;
-    int matched;
-
-    if (signature != dfa->signature) continue;
-
-    matched=1;
-
-    for (j=0; j<round_up(N); j++) {
-      if (nfas[j] != dfa->nfas[j]) {
-        matched = 0;
-        break;
-      }
-    }
-    if (matched) {
-      return dfa->index;
-    }
-  }
-  return -1;
-}
-/*}}}*/
-
-/*{{{ add_dfa() */
-static int add_dfa(Block *b, struct DFA *dfa, unsigned long *nfas, int N, int Nt, int from_state, int via_token)
-{
-  int j;
-  int result = dfa->n;
-  int this_result_unambiguous;
-
-  Stringlist *ex;
-  unsigned long signature = 0UL, folded_signature;
-  struct DFAList *dfal;
-
-  if (verbose) {
-    fprintf(stderr, "Adding DFA state %d\r", dfa->n);
-    fflush(stderr);
-  }
-
-  if (dfa->max == dfa->n) {
-    grow_dfa(dfa);
-  }
-
-  dfa->s[dfa->n] = new(DFANode);
-  dfa->s[dfa->n]->nfas = new_array(unsigned long, round_up(N));
-  dfa->s[dfa->n]->map = new_array(int, Nt);
-  for (j=0; j<Nt; j++) dfa->s[dfa->n]->map[j] = -1;
-  dfa->s[dfa->n]->index = dfa->n;
-  dfa->s[dfa->n]->defstate = -1;
-
-  dfa->s[dfa->n]->from_state = from_state;
-  dfa->s[dfa->n]->via_token = via_token;
-
-  for (j=0; j<round_up(N); j++) {
-    unsigned long x = nfas[j];
-    signature ^= x;
-    dfa->s[dfa->n]->nfas[j] = x;
-  }
-  dfa->s[dfa->n]->signature = signature;
-
-  folded_signature = fold_signature(signature);
-  dfal = new(struct DFAList);
-  dfal->dfa = dfa->s[dfa->n];
-  dfal->next = dfa_hashtable[folded_signature];
-  dfa_hashtable[folded_signature] = dfal;
-
-  /* {{{ Boolean reductions to get attributes */
-  ex = NULL;
-  clear_tag_values();
-  for (j=0; j<N; j++) {
-    if (is_set(dfa->s[dfa->n]->nfas, j)) {
-      Stringlist *sl;
-      State *s = b->states[j];
-      for (sl = s->tags; sl; sl = sl->next) {
-        Stringlist *new_sl;
-        new_sl = new(Stringlist);
-        new_sl->string = sl->string;
-        new_sl->next = ex;
-        ex = new_sl;
-
-        set_tag_value(sl->string);
-      }
-    }
-  }
-
-  dfa->s[dfa->n]->nfa_exit_sl = ex;
-
-  this_result_unambiguous =
-    evaluate_attrs(&dfa->s[dfa->n]->attrs, &dfa->s[dfa->n]->has_early_exit);
-
-  if (!this_result_unambiguous) {
-    Stringlist *sl;
-    fprintf(stderr, "WARNING : Ambiguous exit state abandoned for DFA state %d\n", dfa->n);
-    fprintf(stderr, "NFA exit tags applying in this stage :\n");
-    for (sl = ex; sl; sl = sl->next) {
-      fprintf(stderr, "  %s\n", sl->string);
-    }
-    had_ambiguous_result = 1;
-  }
-  /*}}}*/
-
-  ++dfa->n;
-  return result;
-}
-/*}}}*/
-static void clear_nfas(unsigned long *nfas, int N)/*{{{*/
-{
-  int i;
-  for (i=0; i<round_up(N); i++) {
-    nfas[i] = 0;
-  }
-}
-/*}}}*/
-struct DFA *build_dfa(Block *b)/*{{{*/
-{
-  unsigned long **nfas;
-  int i;
-  int j;
-  int N, Nt;
-  int next_to_do;
-  int *found_any;
-  int rup_N;
-  struct DFA *dfa;
-
-  dfa = new(struct DFA);
-  dfa->n = 0;
-  dfa->max = 0;
-  dfa->s = NULL;
-  dfa->b = b;
-
-  for (i=0; i<DFA_HASHSIZE; i++) dfa_hashtable[i] = NULL;
-
-  N = b->nstates;
-  rup_N = round_up(N);
-  Nt = ntokens + n_charclasses;
-
-  nfas = new_array(unsigned long *, Nt);
-  for (i=0; i<Nt; i++) {
-    nfas[i] = new_array(unsigned long, round_up(N));
-  }
-
-  /* Add initial states */
-  for (j=0; j<n_dfa_entries; j++) {
-    int idx;
-    clear_nfas(nfas[0], N);
-    for (i=0; i<round_up(N); i++) {
-      nfas[0][i] |= b->eclo[dfa_entries[j].state_number][i];
-    }
-    /* Must handle the case where >=2 of the start states are actually identical;
-     * nothing in the input language prevents this. */
-    idx = find_dfa(nfas[0], N);
-    if (idx < 0) {
-      idx = dfa->n;
-      add_dfa(b, dfa, nfas[0], N, Nt, -1, -1);
-    }
-    dfa_entries[j].state_number = idx;
-  }
-
-  next_to_do = 0;
-  found_any = new_array(int, Nt);
-
-  /* Now the heart of the program : the subset construction to turn the NFA
-     into a DFA.  This is a major performance hog in the program, so there are
-     lots of tricks to speed this up (particularly, hoisting intermediate
-     pointer computations out of the loop to assert the fact that there is no
-     aliasing between the arrays.) */
-
-  while (next_to_do < dfa->n) {
-
-    int t; /* token index */
-    int j0, j0_5, j1, j, mask, k;
-    int idx;
-    unsigned long *current_nfas;
-    unsigned long block_bitmap;
-
-    /* If the next DFA state has the result_early flag set, it means that the scanner will
-     * always exit straight away when that state is reached, so there's no need to compute
-     * any transitions out of it. */
-
-    if (dfa->s[next_to_do]->has_early_exit) {
-      next_to_do++;
-      continue;
-    }
-
-    for (j=0; j<Nt; j++) {
-      clear_nfas(nfas[j], N);
-      found_any[j] = 0;
-    }
-
-    current_nfas = dfa->s[next_to_do]->nfas;
-    for (j0=0; j0<rup_N; j0++) { /* Loop over NFA states which may be in this DFA state */
-      block_bitmap = current_nfas[j0];
-      if (!block_bitmap) continue;
-      j0_5 = j0 << 5;
-      for (mask=1UL, j1=0; j1<32; mask<<=1, j1++) {
-        j = j0_5 + j1;
-        if (block_bitmap & mask) { /* Is NFA state in DFA */
-          unsigned long **transmap_j = transmap[j];
-          unsigned long *anytrans_j = anytrans[j];
-          for (t=0; t<Nt; t++) { /* Loop over transition symbols */
-            unsigned long *transmap_t;
-            unsigned long *nfas_t;
-            unsigned long found_any_t;
-            if (!is_set(anytrans_j, t)) continue;
-            transmap_t = transmap_j[t];
-            nfas_t = nfas[t];
-            found_any_t = found_any[t];
-            for (k=0; k<rup_N; k++) { /* Loop over destination NFA states */
-              unsigned long x;
-              x = transmap_t[k];
-              nfas_t[k] |= x;
-              found_any_t |= !!x;
-            }
-            found_any[t] = found_any_t;
-          }
-        }
-      }
-    }
-
-    for (t=0; t<Nt; t++) {
-      if (found_any[t]) {
-        idx = find_dfa(nfas[t], N);
-        if (idx < 0) {
-          idx = add_dfa(b, dfa, nfas[t], N, Nt, next_to_do, t);
-        }
-      } else {
-        idx = -1;
-      }
-      dfa->s[next_to_do]->map[t] = idx;
-    }
-
-    next_to_do++;
-  }
-
-  free(found_any);
-  for (i=0; i<Nt; i++) free(nfas[i]);
-  free(nfas);
-  return dfa;
-}
-/*}}}*/
-/* ================================================================= */
-static void display_route(struct DFA *dfa, int idx, FILE *out)/*{{{*/
-{
-  int from_state, via_token;
-  from_state = dfa->s[idx]->from_state;
-  if (from_state >= 0) {
-    display_route(dfa, from_state, out);
-    fputs("->", out);
-  }
-
-  via_token = dfa->s[idx]->via_token;
-  if (via_token >= ntokens) {
-    print_charclass(out, via_token - ntokens);
-  } else if (via_token >= 0) {
-    fprintf(out, "%s", toktable[via_token]);
-  }
-}
-/*}}}*/
-void print_dfa(struct DFA *dfa)/*{{{*/
-{
-  int N = dfa->b->nstates;
-  int Nt = ntokens + n_charclasses;
-
-  int i, j0, j0_5, j1, t;
-  unsigned long mask;
-  unsigned long current_nfas;
-  int rup_N = round_up(N);
-  int from_state, this_state;
-
-  if (!report) return;
-
-  for (i=0; i<dfa->n; i++) {
-    fprintf(report, "DFA state %d\n", i);
-    if (dfa->s[i]->nfas) {
-      fprintf(report, "  NFA states :\n");
-      for (j0=0; j0<rup_N; j0++) {
-        current_nfas = dfa->s[i]->nfas[j0];
-        if (!current_nfas) continue;
-        j0_5 = j0<<5;
-        for (j1=0, mask=1UL; j1<32; mask<<=1, j1++) {
-          if (current_nfas & mask) {
-            fprintf(report, "    %s\n", dfa->b->states[j0_5 + j1]->name);
-          }
-        }
-      }
-      fprintf(report, "\n");
-    }
-    fprintf(report, "  Forward route :");
-    this_state = i;
-    from_state = dfa->s[i]->from_state;
-    if (from_state >= 0) {
-      fprintf(report, " (from state %d)", from_state);
-    }
-    fputs("\n   (START)", report);
-    display_route(dfa, i, report);
-    fputs("->(HERE)", report);
-    fprintf(report, "\n");
-
-    fprintf(report, "  Transitions :\n");
-    for (t=0; t<Nt; t++) {
-      int dest = dfa->s[i]->map[t];
-      if (dest >= 0) {
-        if (t >= ntokens) {
-          fprintf(report, "    ");
-          print_charclass(report, t - ntokens);
-          fprintf(report, " -> %d\n", dest);
-        } else {
-          fprintf(report, "    %s -> %d\n", toktable[t], dest);
-        }
-      }
-    }
-    if (dfa->s[i]->defstate >= 0) {
-      fprintf(report, "  Use state %d as basis (%d fixups)\n",
-              dfa->s[i]->defstate, dfa->s[i]->best_diff);
-    }
-    if (dfa->s[i]->nfa_exit_sl) {
-      Stringlist *sl;
-      fprintf(report, "  NFA exit tags applying :\n");
-      for (sl=dfa->s[i]->nfa_exit_sl; sl; sl = sl->next) {
-        fprintf(report, "    %s\n", sl->string);
-      }
-    }
-
-    emit_dfa_attr_report(dfa->s[i]->attrs, report);
-    fprintf(report, "\n");
-  }
-  fprintf(report, "\nEntry states in DFA:\n");
-  for (i=0; i<n_dfa_entries; i++) {
-    fprintf(report, "Entry <%s> : %d\n",
-        dfa_entries[i].entry_name,
-        dfa_entries[i].state_number);
-  }
-
-}
-/*}}}*/
-/* ================================================================= */
-void yyerror (const char *s)/*{{{*/
-{
-  extern int lineno;
-  fprintf(stderr, "%s at line %d\n", s, lineno);
-}
-/*}}}*/
-int yywrap(void) /*{{{*/
-{
-  return -1;
-}
-/*}}}*/
-/* ================================================================= */
-
diff --git a/src/mairix/dfasyn/n2d.h b/src/mairix/dfasyn/n2d.h
@@ -1,226 +0,0 @@
-/***************************************
-  $Header: /cvs/src/dfasyn/n2d.h,v 1.2 2003/03/02 23:42:11 richard Exp $
-
-  Header file for NFA->DFA conversion utility.
-  ***************************************/
-
-/* 
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- * 
- * 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 N2D_H
-#define N2D_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define new(T) ((T *) malloc(sizeof(T)))
-#define new_array(T,N) ((T *) malloc((N) * sizeof(T)))
-#define resize_array(T,arr,newN) ((T *) ((arr) ? realloc(arr,(newN)*sizeof(T)) : malloc((newN)*sizeof(T))))
-#define new_string(s) strcpy((char *)malloc((strlen(s)+1)*sizeof(char)),s)
-
-/* For typecasting, especially useful for declarations of local ptrs to args
-   of a qsort comparison fn */
-#define Castdecl(x, T, nx) T nx = (T) x
-
-#define Castderef(x, T, nx) T nx = *(T*) x
-
-/* Globally visible options to control reporting */
-extern FILE *report;
-extern int verbose;
-
-struct State;
-struct Block;
-
-typedef struct Translist {
-  struct Translist *next;
-  int token;
-  char *ds_name;
-  struct State *ds_ref;
-} Translist;
-
-typedef struct Stringlist {
-  struct Stringlist *next;
-  char *string;
-} Stringlist;
-
-typedef struct InlineBlock {
-  char *type; /* Block type */
-  char *in;   /* Name of input node */
-  char *out;  /* Name of output node */
-} InlineBlock;
-
-typedef struct InlineBlockList {
-  struct InlineBlockList *next;
-  InlineBlock *ib;
-} InlineBlockList;
-  
-typedef struct State {
-  char *name;
-  int index; /* Array index in containing block */
-  struct Block *parent;
-  Translist *transitions;
-  Stringlist *exitvals;
-  Stringlist *attributes;
-
-  /* Pointers to the nodes in the 'transitions' list, sorted into canonical order */
-  Translist **ordered_trans;
-  int n_transitions;
-
-  unsigned char removed; /* Flag indicating state has been pruned by compression stage */
-} State;
-
-typedef struct S_Stateset {
-  State **states;
-  int nstates;
-  int maxstates;
-} Stateset;
-
-#define HASH_BUCKETS 64
-#define HASH_MASK (HASH_BUCKETS-1)
-
-typedef struct Block {
-  char *name;
-
-  /* The master table of states within this block.  This has to be in a flat
-     array because we have to work with respect to state indices when doing the
-     2D bitmap stuff for the subset construction. */
-  State **states;
-  int nstates;
-  int maxstates;
-  
-  /* Hash table for getting rapid access to a state within the block, given
-     its name */
-  Stateset state_hash[HASH_BUCKETS];
-  
-  int subcount; /* Number for generating substates */
-  int subblockcount; /* Number for generating inline subblocks */
-} Block;
-
-typedef struct {
-  unsigned long *nfas;
-  unsigned long signature; /* All the longwords in the nfas array xor'ed together */
-  int index; /* Entry's own index in the array */
-  int *map; /* index by token code */
-  int from_state; /* the state which provided the first transition to this one (leading to its creation) */
-  int via_token; /* the token through which we got to this state the first time. */
-  Stringlist *nfa_exit_sl; /* NFA exit values */
-  Stringlist *nfa_attr_sl; /* NFA exit values */
-  char *result;    /* Result token, computed by boolean expressions defined in input text */
-  int result_early; /* If !=0, the scanner is expected to exit immediately this DFA state is entered.
-                       It means that no out-bound transitions have to be created. */
-  char *attribute; /* Attribute token, computed by boolean expressions defined in input text */
-
-  /* Fields calculated in compdfa.c */
-  
-  /* The equivalence class the state is in. */
-  int eq_class;
-
-  /* Temp. storage for the new eq. class within a single pass of the splitting alg. */
-  int new_eq_class; 
-
-  /* Signature field from above is also re-used. */
-
-  int is_rep; /* Set if state is chosen as the representative of its equivalence class. */
-  int new_index; /* New index assigned to the state. */
-
-  /* Fields calculated in tabcompr.c */
-  
-  unsigned long transition_sig;
-
-  /* Default state, i.e. the one that supplies transitions for tokens not
-     explicitly listed for this one. */
-  int defstate; 
-
-  /* Number of transitions that this state has different to those in the
-     default state. */
-  int best_diff; 
-
-} DFANode;
-
-
-void yyerror(const char *s);
-extern int yylex(void);
-
-/* Constants for 'create' args */  
-#define USE_OLD_MUST_EXIST 0
-#define CREATE_MUST_NOT_EXIST 1
-#define CREATE_OR_USE_OLD 2
-
-State *get_curstate(void);
-
-struct Abbrev;
-extern struct Abbrev * create_abbrev(char *name);
-extern void add_tok_to_abbrev(struct Abbrev *abbrev, char *tok);
-
-int lookup_token(char *name, int create);
-Block *lookup_block(char *name, int create);
-State *lookup_state(Block *in_block, char *name, int create);
-Stringlist * add_token(Stringlist *existing, char *token);
-void add_transitions(State *curstate, Stringlist *tokens, char *destination);
-State * add_transitions_to_internal(Block *curblock, State *addtostate, Stringlist *tokens);
-void add_exit_value(State *curstate, char *value);
-void set_state_attribute(State *curstate, char *name);
-InlineBlock *create_inline_block(char *type, char *in, char *out);
-InlineBlockList *add_inline_block(InlineBlockList *existing, InlineBlock *nib);
-State * add_inline_block_transitions(Block *curblock, State *addtostate, InlineBlockList *ibl);
-void instantiate_block(Block *curblock, char *block_name, char *instance_name);
-void fixup_state_refs(Block *b);
-
-void compress_nfa(Block *b);
-
-/* In expr.c */
-typedef struct Expr Expr;
-
-typedef struct evaluator Evaluator;
-extern Evaluator *exit_evaluator;
-extern Evaluator *attr_evaluator;
-
-Expr * new_wild_expr(void);
-Expr * new_not_expr(Expr *c);
-Expr * new_and_expr(Expr *c1, Expr *c2);
-Expr * new_or_expr(Expr *c1, Expr *c2);
-Expr * new_xor_expr(Expr *c1, Expr *c2);
-Expr * new_cond_expr(Expr *c1, Expr *c2, Expr *c3);
-Expr * new_sym_expr(char *sym_name);
-
-void define_symbol(Evaluator *x, char *name, Expr *e);
-void define_result(Evaluator *x, char *string, Expr *e, int early);
-void define_symresult(Evaluator *x, char *string, Expr *e, int early);
-void define_defresult(Evaluator *x, char *string);
-void clear_symbol_values(Evaluator *x);
-void set_symbol_value(Evaluator *x, char *sym_name);
-int evaluate_result(Evaluator *x, char **, int *);
-int evaluator_is_used(Evaluator *x);
-void define_defresult(Evaluator *x, char *text);
-void define_type(Evaluator *x, char *text);
-char* get_defresult(Evaluator *x);
-char* get_result_type(Evaluator *x);
-void eval_initialise(void);
-
-void compress_transition_table(DFANode **dfas, int ndfas, int ntokens);
-unsigned long increment(unsigned long x, int field);
-unsigned long count_bits_set(unsigned long x);
-
-/* Return new number of DFA states */
-int compress_dfa(DFANode **dfas, int ndfas, int ntokens);
-
-#endif /* N2D_H */
-
diff --git a/src/mairix/dfasyn/parse.y b/src/mairix/dfasyn/parse.y
@@ -1,262 +0,0 @@
-/**********************************************************************
-  Grammar definition for input files defining an NFA
- *********************************************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-%{
-#include "dfasyn.h"
-
-static Block *curblock = NULL; /* Current block being built */
-static State *curstate = NULL; /* Current state being worked on */
-static State *addtostate = NULL; /* Current state (incl ext) to which transitions are added */
-static StimulusList *curtranslist = NULL; /* Final option set of stimuli prior to ARROW */
-static CharClass *curcharclass = NULL;
-static Evaluator *current_evaluator = NULL;
-
-State *get_curstate(void) { return curstate; }
-
-%}
-
-%union {
-    char c;
-    char *s;
-    int i;
-    Stringlist *sl;
-    Stimulus *st;
-    StimulusList *stl;
-    InlineBlock *ib;
-    CharClass *cc;
-    Expr *e;
-}
-
-%token STRING STATE TOKENS PREFIX ARROW BLOCK ENDBLOCK COLON EQUAL SEMICOLON COMMA
-%token ABBREV DEFINE
-%type<s> STRING
-%type<st> stimulus
-%type<sl> tag_seq
-%type<stl> stimulus_seq
-%type<stl> transition_seq
-%type<e> expr
-%type<ib> inline_block
-%type<c> CHAR
-%type<cc> char_class simple_char_class negated_char_class char_class_diff
-
-%token ATTR TAG
-%token DEFATTR
-%token EARLY
-%token TYPE
-%token ENTRY
-%token ENTRYSTRUCT
-%token GROUP
-%token LBRACE RBRACE
-
-%token LSQUARE RSQUARE
-%token LSQUARE_CARET
-%token CHAR HYPHEN
-
-%right QUERY COLON
-%left PIPE
-%left XOR
-%left AND
-%left NOT
-%left LPAREN RPAREN
-%left LANGLE RANGLE
-
-%%
-
-all : decl_seq ;
-
-decl_seq : /* empty */ | decl_seq decl ;
-
-decl : block_decl
-     | tokens_decl | abbrev_decl
-     | attr_decl | group_decl | tag_decl
-     | prefix_decl | entrystruct_decl ;
-
-/* Don't invalidate curstate at the end, this is the means of working out the
-   starting state of the NFA */
-block_decl : block1 block2 { fixup_state_refs(curblock); curblock = NULL; } ;
-
-block1 : BLOCK STRING LBRACE { curblock = lookup_block($2, CREATE_MUST_NOT_EXIST); addtostate = curstate = NULL; } ;
-
-block2 : instance_decl_seq state_decl_seq RBRACE ;
-
-prefix_decl : PREFIX STRING
-              { if (!prefix) {
-                  prefix = $2;
-                } else {
-                  fprintf(stderr, "\n\nWarning: prefix declaration ignored; already set on the command line\n");
-                }
-              };
-
-tokens_decl : TOKENS token_seq ;
-
-abbrev_decl : ABBREV STRING EQUAL stimulus_seq
-              { create_abbrev($2, $4); }
-            ;
-
-token_seq : token_seq token | token ;
-
-token : STRING { (void) lookup_token($1, CREATE_MUST_NOT_EXIST); } ;
-
-instance_decl_seq : /* empty */ | instance_decl_seq instance_decl ;
-
-state_decl_seq : /* empty */ | state_decl_seq state_decl ;
-
-state_decl : STATE STRING { addtostate = curstate = lookup_state(curblock, $2, CREATE_OR_USE_OLD); }
-             sdecl_seq
-           | STATE STRING ENTRY STRING { addtostate = curstate = lookup_state(curblock, $2, CREATE_OR_USE_OLD);
-	                                       add_entry_to_state(curstate, $4); }
-             sdecl_seq
-           ;
-
-sdecl_seq : /* empty */ | sdecl_seq sdecl ;
-
-sdecl : transition_decl ;
-
-instance_decl : STRING COLON STRING { instantiate_block(curblock, $3 /* master_block_name */, $1 /* instance_name */ ); } ;
-
-transition_decl : transition_seq ARROW { curtranslist = $1; } destination_seq { addtostate = curstate; }
-                | transition_seq EQUAL tag_seq { addtostate = add_transitions_to_internal(curblock, addtostate, $1);
-                                                    add_tags(addtostate, $3);
-                                                    addtostate = curstate; }
-                ;
-
-destination_seq : STRING                       { add_transitions(curblock, addtostate, curtranslist, $1); }
-                | destination_seq COMMA STRING { add_transitions(curblock, addtostate, curtranslist, $3); }
-                ;
-
-transition_seq : stimulus_seq { $$ = $1; }
-               | transition_seq SEMICOLON stimulus_seq
-                 {
-                   addtostate = add_transitions_to_internal(curblock, addtostate, $1);
-                   $$ = $3;
-                 }
-               ;
-
-tag_seq : STRING { $$ = add_string_to_list(NULL, $1); }
-        | tag_seq COMMA STRING { $$ = add_string_to_list($1, $3); }
-        ;
-
-stimulus_seq : stimulus
-               { $$ = append_stimulus_to_list(NULL, $1); }
-             | stimulus_seq PIPE stimulus
-               { $$ = append_stimulus_to_list($1, $3); }
-             ;
-
-/* A 'thing' that will make the DFA move from one state to another */
-stimulus : STRING
-           { $$ = stimulus_from_string($1); }
-         | inline_block
-           { $$ = stimulus_from_inline_block($1); }
-         | char_class
-           { add_charclass_to_list($1); /* freeze it into the list. */
-             $$ = stimulus_from_char_class($1); }
-         | /* empty */
-           { $$ = stimulus_from_epsilon(); }
-         ;
-
-inline_block : LANGLE STRING COLON STRING ARROW STRING RANGLE
-               { $$ = create_inline_block($2, $4, $6); }
-             ;
-
-char_class : simple_char_class
-           | negated_char_class
-           | char_class_diff
-           ;
-
-negated_char_class : NOT simple_char_class
-                     { invert_charclass($2); $$ = $2; }
-                   ;
-
-char_class_diff : simple_char_class NOT simple_char_class
-                  { diff_charclasses($1, $3);
-                    free_charclass($3);
-                    $$ = $1;
-                  }
-                ;
-
-simple_char_class : LSQUARE { curcharclass = new_charclass(); }
-                    cc_body
-                    RSQUARE { $$ = curcharclass;
-                              curcharclass = NULL; }
-                  | LSQUARE_CARET { curcharclass = new_charclass(); }
-                    cc_body
-                    RSQUARE { $$ = curcharclass;
-                              invert_charclass($$);
-                              curcharclass = NULL; }
-                  ;
-
-cc_body : CHAR { add_singleton_to_charclass(curcharclass, $1); }
-        | CHAR HYPHEN CHAR { add_range_to_charclass(curcharclass, $1, $3); }
-        | cc_body CHAR { add_singleton_to_charclass(curcharclass, $2); }
-        | cc_body CHAR HYPHEN CHAR { add_range_to_charclass(curcharclass, $2, $4); }
-        ;
-
-attr_decl : ATTR simple_attr_seq
-          | ATTR STRING COLON expr       {    define_attr(current_evaluator, $2, $4, 0); }
-          | EARLY ATTR early_attr_seq
-          | EARLY ATTR STRING COLON expr {    define_attr(current_evaluator, $3, $5, 1); }
-          | DEFATTR STRING               { define_defattr(current_evaluator, $2); }
-          | TYPE STRING                  {    define_type(current_evaluator, $2); }
-          ;
-
-simple_attr_seq : STRING
-                  { define_attr(current_evaluator, $1, NULL, 0); }
-                | simple_attr_seq COMMA STRING
-                  { define_attr(current_evaluator, $3, NULL, 0); }
-                ;
-
-early_attr_seq : STRING
-                  { define_attr(current_evaluator, $1, NULL, 1); }
-                | early_attr_seq COMMA STRING
-                  { define_attr(current_evaluator, $3, NULL, 1); }
-                ;
-
-group_decl : GROUP STRING LBRACE { current_evaluator = start_evaluator($2); }
-             attr_decl_seq
-             RBRACE { current_evaluator = NULL; }
-           ;
-
-attr_decl_seq : /* empty */
-                | attr_decl_seq attr_decl
-                ;
-
-tag_decl : TAG STRING EQUAL expr { define_tag($2, $4); }
-         ;
-
-entrystruct_decl :
-              ENTRYSTRUCT STRING STRING   { define_entrystruct($2, $3); }
-            ;
-
-expr : NOT expr { $$ = new_not_expr($2); }
-     | expr AND expr { $$ = new_and_expr($1, $3); }
-     | expr PIPE /* OR */ expr { $$ = new_or_expr($1, $3); }
-     | expr XOR expr { $$ = new_xor_expr($1, $3); }
-     | expr QUERY expr COLON expr { $$ = new_cond_expr($1, $3, $5); }
-     | LPAREN expr RPAREN { $$ = $2; }
-     | STRING { $$ = new_tag_expr($1); }
-     ;
-
-/* vim:et
-*/
-
diff --git a/src/mairix/dfasyn/scan.l b/src/mairix/dfasyn/scan.l
@@ -1,111 +0,0 @@
-/**********************************************************************
-  Lexical analyser definition for input files defining an NFA
- *********************************************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-%{
-#include "dfasyn.h"
-#include "parse.h"
-
-/* yyunput() not used - define this to avoid compiler warnings */
-#define YY_NO_UNPUT
-
-int lineno = 1;
-%}
-
-%x PASSTHRU
-%x STR
-%x CHARCLASS
-
-%%
-
-STATE|State|state           { return STATE; }
-ABBREV|Abbrev|abbrev        { return ABBREV; }
-DEFINE|Define|define        { return DEFINE; }
-TOKENS|Tokens|tokens        { return TOKENS; }
-PREFIX|Prefix|prefix        { return PREFIX; }
-BLOCK|Block|block           { return BLOCK; }
-TYPE|Type|type              { return TYPE; }
-ENTRY|Entry|entry           { return ENTRY; }
-ENTRYSTRUCT                 { return ENTRYSTRUCT; }
-EntryStruct                 { return ENTRYSTRUCT; }
-Entrystruct                 { return ENTRYSTRUCT; }
-entrystruct                 { return ENTRYSTRUCT; }
-ATTR|Attr|attr              { return ATTR; }
-EARLY|Early|early           { return EARLY; }
-DEFATTR|DefAttr             { return DEFATTR; }
-Defattr|defattr             { return DEFATTR; }
-TAG|Tag|tag                 { return TAG; }
-GROUP|Group|group           { return GROUP; }
-[A-Za-z0-9_.]+              { yylval.s = new_string(yytext); return STRING; }
-\#.*$                       { /* strip comments */ }
-\-\>                        { return ARROW; }
-=                           { return EQUAL; }
-\|                          { return PIPE; /* OR */ }
-\&                          { return AND; }
-\~                          { return NOT; }
-\!                          { return NOT; }
-\^                          { return XOR; }
-\?                          { return QUERY; }
-\:                          { return COLON; }
-\;                          { return SEMICOLON; }
-\(                          { return LPAREN; }
-\)                          { return RPAREN; }
-\{                          { return LBRACE; }
-\}                          { return RBRACE; }
-\<                          { return LANGLE; }
-\>                          { return RANGLE; }
-\[                          { BEGIN CHARCLASS; return LSQUARE; }
-\[\^                        { BEGIN CHARCLASS; return LSQUARE_CARET; }
-\,                          { return COMMA; }
-\n                          { lineno++; }
-[ \t]+                      { /* ignore */ }
-^\%\{[ \t]*\n               { BEGIN PASSTHRU; }
-\"                          { BEGIN STR; }
-.                           { printf("Unmatched input <%s> at line %d\n", yytext, lineno); exit (1); }
-
-<PASSTHRU>^\%\}[ \t]*\n     { BEGIN INITIAL; }
-<PASSTHRU>\n                { fputs(yytext, yyout); lineno++; }
-<PASSTHRU>.+                { fputs(yytext, yyout); }
-
-<STR>\"                     { BEGIN INITIAL; }
-<STR>[^"]*                  { yylval.s = new_string(yytext); return STRING; }
-
-<CHARCLASS>\]               { BEGIN INITIAL; return RSQUARE; }
-<CHARCLASS>\-               { return HYPHEN; }
-<CHARCLASS>\\-              { yylval.c = '-'; return CHAR; }
-<CHARCLASS>\\]              { yylval.c = ']'; return CHAR; }
-<CHARCLASS>\\^              { yylval.c = '^'; return CHAR; }
-<CHARCLASS>\\n              { yylval.c = '\n'; return CHAR; }
-<CHARCLASS>\\r              { yylval.c = '\r'; return CHAR; }
-<CHARCLASS>\\f              { yylval.c = '\f'; return CHAR; }
-<CHARCLASS>\\t              { yylval.c = '\t'; return CHAR; }
-<CHARCLASS>\\\\             { yylval.c = '\\'; return CHAR; }
-<CHARCLASS>\^[@A-Z]         { yylval.c = yytext[1] - '@'; return CHAR; }
-<CHARCLASS>\\x[0-9a-fA-F][0-9a-fA-F] { unsigned int foo; sscanf(yytext+2,"%x",&foo); yylval.c = (char) foo; return CHAR; }
-<CHARCLASS>\\[0-7][0-7][0-7] { unsigned int foo; sscanf(yytext+1,"%o",&foo); yylval.c = (char) foo; return CHAR; }
-<CHARCLASS>.                { yylval.c = yytext[0]; return CHAR; }
-
-%{
-/* vim:et
-*/
-%}
diff --git a/src/mairix/dfasyn/states.c b/src/mairix/dfasyn/states.c
@@ -1,303 +0,0 @@
-/***************************************
-  Handle state-related stuff
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2000-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-
-static void maybe_grow_states(Block *b, int hash)/*{{{*/
-{
-  Stateset *ss = b->state_hash + hash;
-  if (ss->nstates == ss->maxstates) {
-    ss->maxstates += 8;
-    ss->states = resize_array(State*, ss->states, ss->maxstates);
-  }
-  if (b->nstates == b->maxstates) {
-    b->maxstates += 32;
-    b->states = resize_array(State*, b->states, b->maxstates);
-  }
-
-}
-/*}}}*/
-static unsigned long hashfn(const char *s)/*{{{*/
-{
-  unsigned long y = 0UL, v, w, x, k;
-  const char *t = s;
-  while (1) {
-    k = (unsigned long) *(unsigned char *)(t++);
-    if (!k) break;
-    v = ~y;
-    w = y<<13;
-    x = v>>6;
-    y = w ^ x;
-    y += k;
-  }
-  y ^= (y>>13);
-  y &= HASH_MASK;
-  return y;
-}
-/*}}}*/
-static State * create_state(Block *b, char *name)/*{{{*/
-{
-  State *result;
-  int hash;
-  Stateset *ss;
-  hash = hashfn(name);
-  maybe_grow_states(b, hash);
-  ss = b->state_hash + hash;
-  result = b->states[b->nstates++] = ss->states[ss->nstates++] = new(State);
-  result->name = new_string(name);
-  result->parent = b;
-  result->index = b->nstates - 1;
-  result->transitions = NULL;
-  result->tags = NULL;
-  result->entries = NULL;
-  result->ordered_trans = NULL;
-  result->n_transitions = 0;
-  result->removed = 0;
-  return result;
-}
-/*}}}*/
-State * lookup_state(Block *b, char *name, int create)/*{{{*/
-{
-  State *found = NULL;
-  int i;
-  int hash;
-  Stateset *ss;
-
-  hash = hashfn(name);
-  ss = b->state_hash + hash;
-
-  for (i=0; i<ss->nstates; i++) {
-    if (!strcmp(ss->states[i]->name, name)) {
-      found = ss->states[i];
-      break;
-    }
-  }
-
-  switch (create) {
-    case USE_OLD_MUST_EXIST:
-      if (!found) {
-        fprintf(stderr, "Could not find a state '%s' in block '%s' to transition to\n", name, b->name);
-        exit(1);
-      }
-      break;
-    case CREATE_MUST_NOT_EXIST:
-      if (found) {
-        fprintf(stderr, "Warning : already have a state '%s' in block '%s'\n", name, b->name);
-      } else {
-        found = create_state(b, name);
-      }
-      break;
-    case CREATE_OR_USE_OLD:
-      if (!found) {
-        found = create_state(b, name);
-      }
-      break;
-  }
-
-  return found;
-}
-/*}}}*/
-void add_entry_to_state(State *curstate, const char *entry_tag)/*{{{*/
-{
-  struct Entrylist *new_entries = new(struct Entrylist);
-  new_entries->entry_name = new_string(entry_tag);
-  new_entries->state = curstate;
-  new_entries->next = entries;
-  entries = new_entries;
-  curstate->entries = add_string_to_list(curstate->entries, entry_tag);
-}
-/*}}}*/
-/* ================================================================= */
-static void add_transition(Block *curblock, State *curstate, Stimulus *stimulus, char *destination);
-/* ================================================================= */
-Stringlist * add_string_to_list(Stringlist *existing, const char *token)/*{{{*/
-{
-  Stringlist *result = new(Stringlist);
-  if (token) {
-    result->string = new_string(token);
-  } else {
-    result->string = NULL;
-  }
-  result->next = existing;
-  return result;
-}
-/*}}}*/
-static TransList *new_translist(struct TransList *existing, char *destination)/*{{{*/
-{
-  TransList *result;
-  result = new(TransList);
-  result->next = existing;
-  result->ds_name = new_string(destination);
-  return result;
-}
-/*}}}*/
-static void add_epsilon_transition(State *curstate, char *destination)/*{{{*/
-{
-  TransList *tl = new_translist(curstate->transitions, destination);
-  tl->type = TT_EPSILON;
-  curstate->transitions = tl;
-}
-/*}}}*/
-static void add_token_transition(State *curstate, int token, char *destination)/*{{{*/
-{
-  TransList *tl = new_translist(curstate->transitions, destination);
-  tl->type = TT_TOKEN;
-  tl->x.token = token;
-  curstate->transitions = tl;
-}
-/*}}}*/
-static void add_abbrev_transition(Block *curblock, State *curstate, struct Abbrev *abbrev, char *destination)/*{{{*/
-{
-  StimulusList *stimuli;
-  for (stimuli = abbrev->stimuli; stimuli; stimuli = stimuli->next) {
-    add_transition(curblock, curstate, stimuli->stimulus, destination);
-  }
-}
-/*}}}*/
-static void add_inline_block_transition(Block *curblock, State *curstate, InlineBlock *ib, char *destination)/*{{{*/
-{
-  char block_name[1024];
-  char input_name[1024];
-  char output_name[1024];
-  State *output_state;
-
-  sprintf(block_name, "%s#%d", ib->type, curblock->subblockcount++);
-  instantiate_block(curblock, ib->type, block_name);
-  sprintf(input_name, "%s.%s", block_name, ib->in);
-  sprintf(output_name, "%s.%s", block_name, ib->out);
-  output_state = lookup_state(curblock, output_name, CREATE_OR_USE_OLD);
-  add_epsilon_transition(curstate, input_name);
-  add_epsilon_transition(output_state, destination);
-}
-/*}}}*/
-static void add_char_class_transition(State *curstate, CharClass *cc, char *destination)/*{{{*/
-{
-  TransList *tl = new_translist(curstate->transitions, destination);
-  tl->type = TT_CHARCLASS;
-  tl->x.char_class = cc;
-  curstate->transitions = tl;
-}
-/*}}}*/
-static void add_transition(Block *curblock, State *curstate, Stimulus *stimulus, char *destination)/*{{{*/
-/* Add a single transition to the state.  Allow definitions to be
-   recursive */
-{
-  switch (stimulus->type) {
-    case T_EPSILON:
-      add_epsilon_transition(curstate, destination);
-      break;
-    case T_TOKEN:
-      add_token_transition(curstate, stimulus->x.token, destination);
-      break;
-    case T_ABBREV:
-      add_abbrev_transition(curblock, curstate, stimulus->x.abbrev, destination);
-      break;
-    case T_INLINEBLOCK:
-      add_inline_block_transition(curblock, curstate, stimulus->x.inline_block, destination);
-      break;
-    case T_CHARCLASS:
-      add_char_class_transition(curstate, stimulus->x.char_class, destination);
-      break;
-  }
-
-}
-/*}}}*/
-void add_transitions(Block *curblock, State *curstate, StimulusList *stimuli, char *destination)/*{{{*/
-{
-  StimulusList *sl;
-  for (sl=stimuli; sl; sl=sl->next) {
-    add_transition(curblock, curstate, sl->stimulus, destination);
-  }
-}
-/*}}}*/
-State * add_transitions_to_internal(Block *curblock, State *addtostate, StimulusList *stimuli)/*{{{*/
-{
-  char buffer[1024];
-  State *result;
-  sprintf(buffer, "#%d", curblock->subcount++);
-  result = lookup_state(curblock, buffer, CREATE_MUST_NOT_EXIST);
-  add_transitions(curblock, addtostate, stimuli, result->name);
-  return result;
-}
-/*}}}*/
-void add_tags(State *curstate, Stringlist *sl)/*{{{*/
-{
-  if (curstate->tags) {
-    /* If we already have some, stick them on the end of the new list */
-    Stringlist *xsl = sl;
-    while (xsl->next) xsl = xsl->next;
-    xsl->next = curstate->tags;
-  }
-  curstate->tags = sl;
-}
-/*}}}*/
-/* ================================================================= */
-void fixup_state_refs(Block *b)/*{{{*/
-{
-  int i;
-  for (i=0; i<b->nstates; i++) {
-    State *s = b->states[i];
-    TransList *tl;
-    for (tl=s->transitions; tl; tl=tl->next) {
-      tl->ds_ref = lookup_state(b, tl->ds_name, CREATE_OR_USE_OLD);
-    }
-  }
-}
-/*}}}*/
-/* ================================================================= */
-void expand_charclass_transitions(Block *b)/*{{{*/
-{
-  int i;
-  for (i=0; i<b->nstates; i++) {
-    State *s = b->states[i];
-    TransList *tl;
-    for (tl=s->transitions; tl; tl=tl->next) {
-      if (tl->type == TT_CHARCLASS) {
-        int i, first;
-        CharClass *cc = tl->x.char_class;
-        first = 1;
-        for (i=0; i<256; i++) {
-          /* Insert separate transitions for each subclass of the charclass */
-          if (cc_test_bit(cc->group_bitmap, i)) {
-            if (first) {
-              tl->type = TT_TOKEN;
-              tl->x.token = ntokens + i;
-            } else {
-              TransList *ntl = new(TransList);
-              ntl->next = tl->next;
-              ntl->ds_name = new_string(tl->ds_name);
-              ntl->ds_ref = tl->ds_ref;
-              ntl->type = TT_TOKEN;
-              ntl->x.token = ntokens + i;
-              tl->next = ntl;
-            }
-            first = 0;
-          }
-        }
-      }
-    }
-  }
-}
-/*}}}*/
-/* ================================================================= */
diff --git a/src/mairix/dfasyn/stimulus.c b/src/mairix/dfasyn/stimulus.c
@@ -1,87 +0,0 @@
-/***************************************
-  Handle stimulus-related stuff
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-
-Stimulus *stimulus_from_epsilon(void)/*{{{*/
-{
-  Stimulus *result;
-  result = new(Stimulus);
-  result->type = T_EPSILON;
-  return result;
-}
-/*}}}*/
-Stimulus *stimulus_from_string(char *str)/*{{{*/
-{
-  struct Abbrev *abbrev;
-  Stimulus *result;
-
-  result = new(Stimulus);
-
-  /* See if an abbrev exists with the name */
-  abbrev = lookup_abbrev(str);
-
-  if (abbrev) {
-    result->type = T_ABBREV;
-    result->x.abbrev = abbrev;
-  } else {
-    /* Token */
-    int token;
-    token = lookup_token(str, USE_OLD_MUST_EXIST);
-    /* lookup_token will have bombed if it wasn't found. */
-    result->type = T_TOKEN;
-    result->x.token = token;
-  }
-
-  return result;
-
-}
-/*}}}*/
-Stimulus *stimulus_from_inline_block(InlineBlock *block)/*{{{*/
-{
-  Stimulus *result;
-  result = new(Stimulus);
-  result->type = T_INLINEBLOCK;
-  result->x.inline_block = block;
-  return result;
-}
-/*}}}*/
-Stimulus *stimulus_from_char_class(CharClass *char_class)/*{{{*/
-{
-  Stimulus *result;
-  result = new(Stimulus);
-  result->type = T_CHARCLASS;
-  result->x.char_class = char_class;
-  return result;
-}
-/*}}}*/
-StimulusList *append_stimulus_to_list(StimulusList *existing, Stimulus *stim)/*{{{*/
-{
-  StimulusList *result;
-  result = new(StimulusList);
-  result->next = existing;
-  result->stimulus = stim;
-  return result;
-}
-/*}}}*/
diff --git a/src/mairix/dfasyn/tabcompr.c b/src/mairix/dfasyn/tabcompr.c
@@ -1,181 +0,0 @@
-/***************************************
-  Routines to compress the DFA transition tables, by identifying where two DFA
-  states have a lot of transitions the same.
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2001-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-
-/* ================================================================= */
-/* Treat 'x' as a set of 16 bit pairs, with field (0..15) specifying
-   which.  Increment the field'th bit pair as a gray code, in the
-   pattern 00->01->11->10->00 */
-
-unsigned long increment(unsigned long x, int field)
-{
-  int f2 = field + field;
-  static unsigned char transxor[4] = {1, 2, 2, 1};
-  unsigned long g = x >> f2;
-  unsigned long h = transxor[g&3];
-  return x ^ (h<<f2);
-}
-
-/* ================================================================= */
-/* Calculate the number of bits set in an unsigned long. */
-
-unsigned long count_bits_set(unsigned long x)
-{
-  unsigned long y = x;
-  unsigned long c;
-  c = 0x55555555UL;
-  y = ((y>>1) & c) + (y & c);
-  c = 0x33333333UL;
-  y = ((y>>2) & c) + (y & c);
-  y = (y>>4) + y;
-  c = 0x0f0f0f0fUL;
-  y &= c;
-  y = (y>>8) + y;
-  y = (y>>16) + y;
-  return y & 0x1f;
-}
-
-/* ================================================================= */
-/* Compute 'signatures' of the transitions out of a particular state.
-   The signature is given by considering the destination state numbers mod 16,
-   and counting how many transitions there are in each resulting equivalence
-   class.  The number is encoded using the gray code implied by the increment
-   fn. */
-
-static void
-compute_transition_sigs(struct DFA *dfa, int ntokens)
-{
-  int i, j;
-  for (i=0; i<dfa->n; i++) {
-    unsigned long ts = 0UL; /* transition signature */
-    for (j=0; j<ntokens; j++) {
-      unsigned long dest = dfa->s[i]->map[j];
-      dest &= 0xf; /* 16 bit pairs in 'ts' */
-      ts = increment(ts, dest);
-    }
-    dfa->s[i]->transition_sig = ts;
-  }
-}
-
-
-/* ================================================================= */
-
-#define REQUIRED_BENEFIT 2
-
-static void
-find_default_states(struct DFA *dfa, int ntokens)
-{
-  int i, j, t;
-  int best_index;
-  int best_diff;
-  int trans_count; /* Number of transitions in working state */
-  unsigned long tsi;
-
-  for (i=0; i<dfa->n; i++) {
-    trans_count = 0;
-    for (t=0; t<ntokens; t++) {
-      if (dfa->s[i]->map[t] >= 0) trans_count++;
-    }
-
-    dfa->s[i]->defstate = -1; /* not defaulted */
-    best_index = -1;
-    best_diff = ntokens + 1; /* Worse than any computed value */
-    tsi = dfa->s[i]->transition_sig;
-    for (j=0; j<i; j++) {
-      unsigned long tsj;
-      unsigned long sigdiff;
-      int diffsize;
-
-      if (dfa->s[j]->defstate >= 0) continue; /* Avoid chains of defstates */
-      tsj = dfa->s[j]->transition_sig;
-
-      /* This is the heart of the technique : if we xor two vectors of bit
-         pairs encoded with the gray code above, and count the number of bits
-         set in the result, we get the sum of absolute differences of the bit
-         pairs.   The number of outgoing transitions that differ between the
-         states must be _at_least_ this value.  It may in fact be much greater
-         (i.e. we may get 'false matches').  However, this algorithm is a quick
-         way of filtering most of the useless potential default states out. */
-
-      sigdiff = tsi ^ tsj;
-      diffsize = count_bits_set(sigdiff);
-      if (diffsize >= best_diff) continue;
-      if (diffsize >= trans_count) continue; /* Else pointless! */
-
-      /* Otherwise, do an exact check (i.e. see how much false matching we
-         suffered). */
-      diffsize = 0;
-      for (t=0; t<ntokens; t++) {
-        if (dfa->s[i]->map[t] != dfa->s[j]->map[t]) {
-          diffsize++;
-        }
-      }
-
-      if (((best_index < 0) || (diffsize < best_diff))
-          &&
-          (diffsize < (trans_count - REQUIRED_BENEFIT))) {
-        best_index = j;
-        best_diff = diffsize;
-      }
-    }
-
-    dfa->s[i]->defstate = best_index;
-    dfa->s[i]->best_diff = best_diff;
-  }
-}
-
-/* ================================================================= */
-
-void
-compress_transition_table(struct DFA *dfa, int ntokens)
-{
-  compute_transition_sigs(dfa, ntokens);
-  find_default_states(dfa, ntokens);
-}
-
-/* ================================================================= */
-
-#ifdef TEST
-int main () {
-  unsigned long x = 0;
-  unsigned long x1, x2, x3, x4;
-  x1 = increment(x,  2);
-  x2 = increment(x1, 2);
-  x3 = increment(x2, 2);
-  x4 = increment(x3, 2);
-  printf("%d %d %d %d %d\n", x, x1, x2, x3, x4);
-
-  printf("1=%d\n", count_bits_set(0x00000001));
-  printf("2=%d\n", count_bits_set(0x00000003));
-  printf("3=%d\n", count_bits_set(0x00000007));
-  printf("4=%d\n", count_bits_set(0x0000000f));
-  printf("4=%d\n", count_bits_set(0xf0000000));
-
-  return 0;
-}
-#endif
-
-
diff --git a/src/mairix/dfasyn/tokens.c b/src/mairix/dfasyn/tokens.c
@@ -1,85 +0,0 @@
-/***************************************
-  Handle token-related stuff
-  ***************************************/
-
-/*
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2000-2003,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "dfasyn.h"
-
-char **toktable=NULL;
-int ntokens = 0;
-static int maxtokens = 0;
-/* ================================================================= */
-static void grow_tokens(void)/*{{{*/
-{
-  maxtokens += 32;
-  toktable = resize_array(char *, toktable, maxtokens);
-}
-/*}}}*/
-static int create_token(char *name)/*{{{*/
-{
-  int result;
-  if (ntokens == maxtokens) {
-    grow_tokens();
-  }
-  result = ntokens++;
-  toktable[result] = new_string(name);
-  return result;
-}
-/*}}}*/
-int lookup_token(char *name, int create)/*{{{*/
-{
-  int found = -1;
-  int i;
-  for (i=0; i<ntokens; i++) {
-    if (!strcmp(toktable[i], name)) {
-      found = i;
-      break;
-    }
-  }
-
-  switch (create) {
-    case USE_OLD_MUST_EXIST:
-      if (found < 0) {
-        fprintf(stderr, "Token '%s' was never declared\n", name);
-        exit(1);
-      }
-      break;
-    case CREATE_MUST_NOT_EXIST:
-      if (found >= 0) {
-        fprintf(stderr, "Token '%s' already declared\n", name);
-        exit(1);
-      } else {
-        found = create_token(name);
-      }
-      break;
-    case CREATE_OR_USE_OLD:
-      if (found < 0) {
-        found = create_token(name);
-      }
-      break;
-  }
-
-  return found;
-}
-/*}}}*/
-
-
diff --git a/src/mairix/dirscan.c b/src/mairix/dirscan.c
@@ -1,420 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006,2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Traverse a directory tree and find maildirs, then list files in them. */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <assert.h>
-#include "mairix.h"
-
-struct msgpath_array *new_msgpath_array(void)/*{{{*/
-{
-  struct msgpath_array *result;
-  result = new(struct msgpath_array);
-  result->paths = NULL;
-  result->type = NULL;
-  result->n = 0;
-  result->max = 0;
-  return result;
-}
-/*}}}*/
-void free_msgpath_array(struct msgpath_array *x)/*{{{*/
-{
-  int i;
-  if (x->paths) {
-    for (i=0; i<x->n; i++) {
-      switch (x->type[i]) {
-        case MTY_FILE:
-          free(x->paths[i].src.mpf.path);
-          break;
-        case MTY_MBOX:
-          break;
-        case MTY_DEAD:
-          break;
-      }
-    }
-    free(x->type);
-    free(x->paths);
-  }
-  free(x);
-}
-/*}}}*/
-static void add_file_to_list(char *x, struct msgpath_array *arr) {/*{{{*/
-  char *y = new_string(x);
-  if (arr->n == arr->max) {
-    arr->max += 1024;
-    arr->paths = grow_array(struct msgpath,    arr->max, arr->paths);
-    arr->type  = grow_array(enum message_type, arr->max, arr->type);
-  }
-  arr->type[arr->n] = MTY_FILE;
-  arr->paths[arr->n].src.mpf.path = y;
-  ++arr->n;
-  return;
-}
-/*}}}*/
-static void get_maildir_message_paths(char *folder, struct msgpath_array *arr)/*{{{*/
-{
-  char *subdir, *fname;
-  int i;
-  static char *subdirs[] = {"new", "cur"};
-  DIR *d;
-  struct dirent *de;
-  int folder_len = strlen(folder);
-
-  /* FIXME : just store mdir-rooted paths in array and have common prefix elsewhere. */
-
-  subdir = new_array(char, folder_len + 6);
-  fname = new_array(char, folder_len + 8 + NAME_MAX);
-  for (i=0; i<2; i++) {
-    strcpy(subdir, folder);
-    strcat(subdir, "/");
-    strcat(subdir, subdirs[i]);
-    d = opendir(subdir);
-    if (d) {
-      while ((de = readdir(d))) {
-        /* TODO : Perhaps we ought to do some validation on the path here?
-           i.e. check that the filename looks valid for a maildir message. */
-        if (!strcmp(de->d_name, ".") ||
-            !strcmp(de->d_name, "..")) {
-          continue;
-        }
-        strcpy(fname, subdir);
-        strcat(fname, "/");
-        strcat(fname, de->d_name);
-        add_file_to_list(fname, arr);
-      }
-      closedir(d);
-    }
-  }
-  free(subdir);
-  free(fname);
-  return;
-}
-/*}}}*/
-int valid_mh_filename_p(const char *x)/*{{{*/
-{
-  const char *p;
-
-  if (!*x) return 0; /* Must not be empty */
-  p = x;
-  while (*p) {
-    if (!isdigit(*p)) {
-      /* Handle MH folders generated by Evolution, which have '.' on the ends
-       * of the numerical filenames for the messages. */
-      if ((p[0] == '.') && (p[1] == 0)) return 1;
-      else return 0;
-    }
-    p++;
-  }
-  return 1;
-}
-/*}}}*/
-static void get_mh_message_paths(char *folder, struct msgpath_array *arr)/*{{{*/
-{
-  char *fname;
-  DIR *d;
-  struct dirent *de;
-  int folder_len = strlen(folder);
-
-  fname = new_array(char, folder_len + 8 + NAME_MAX);
-  d = opendir(folder);
-  if (d) {
-    while ((de = readdir(d))) {
-      if (!strcmp(de->d_name, ".") ||
-          !strcmp(de->d_name, "..")) {
-        continue;
-      }
-      strcpy(fname, folder);
-      strcat(fname, "/");
-      strcat(fname, de->d_name);
-      if (valid_mh_filename_p(de->d_name)) {
-        add_file_to_list(fname, arr);
-      }
-    }
-    closedir(d);
-  }
-  free(fname);
-  return;
-}
-/*}}}*/
-static int child_stat(const char *base, const char *child, struct stat *sb)/*{{{*/
-{
-  int result = 0;
-  char *scratch;
-  int len;
-
-  len = strlen(base) + strlen(child) + 2;
-  scratch = new_array(char, len);
-
-  strcpy(scratch, base);
-  strcat(scratch, "/");
-  strcat(scratch, child);
-
-  result = stat(scratch, sb);
-  free(scratch);
-  return result;
-}
-/*}}}*/
-static int has_child_file(const char *base, const char *child)/*{{{*/
-{
-  int result = 0;
-  int status;
-  struct stat sb;
-
-  status = child_stat(base, child, &sb);
-  if ((status >= 0) && S_ISREG(sb.st_mode)) {
-    result = 1;
-  }
-
-  return result;
-}
-/*}}}*/
-static int has_child_dir(const char *base, const char *child)/*{{{*/
-{
-  int result = 0;
-  int status;
-  struct stat sb;
-
-  status = child_stat(base, child, &sb);
-  if ((status >= 0) && S_ISDIR(sb.st_mode)) {
-    result = 1;
-  }
-
-  return result;
-}
-/*}}}*/
-static enum traverse_check scrutinize_maildir_entry(int parent_is_maildir, const char *de_name)/*{{{*/
-{
-  if (parent_is_maildir) {
-    /* Process any subdirectory that's not part of this maildir itself. */
-    if (!strcmp(de_name, "new") ||
-        !strcmp(de_name, "cur") ||
-        !strcmp(de_name, "tmp")) {
-      return TRAV_IGNORE;
-    } else {
-      return TRAV_PROCESS;
-    }
-  } else {
-    return TRAV_PROCESS;
-  }
-}
-/*}}}*/
-static int filter_is_maildir(const char *path, const struct stat *sb)/*{{{*/
-{
-  if (S_ISDIR(sb->st_mode)) {
-    if (has_child_dir(path, "new") &&
-        has_child_dir(path, "tmp") &&
-        has_child_dir(path, "cur")) {
-      return 1;
-    }
-  }
-  return 0;
-}
-/*}}}*/
-struct traverse_methods maildir_traverse_methods = {/*{{{*/
-  .filter = filter_is_maildir,
-  .scrutinize = scrutinize_maildir_entry
-};
-/*}}}*/
-static enum traverse_check scrutinize_mh_entry(int parent_is_mh, const char *de_name)/*{{{*/
-{
-  /* Have to allow sub-folders within a folder until we think of a better
-   * solution.  */
-  if (valid_mh_filename_p(de_name)) {
-    return TRAV_IGNORE;
-  } else {
-    return TRAV_PROCESS;
-  }
-}
-/*}}}*/
-static int filter_is_mh(const char *path, const struct stat *sb)/*{{{*/
-{
-  int result = 0;
-  if (S_ISDIR(sb->st_mode)) {
-    /* TODO : find a way of making this more scalable?  e.g. if a folder of a
-     * particular subtype is found once, try that subtype first later, since
-     * the user presumably uses a consistent MH-subtype (i.e. a single MUA). */
-    if (has_child_file(path, ".xmhcache") ||
-        has_child_file(path, ".mh_sequences") ||
-        /* Sylpheed */
-        has_child_file(path, ".sylpheed_cache") ||
-        has_child_file(path, ".sylpheed_mark") ||
-        /* claws-mail */
-        has_child_file(path, ".claws_cache") ||
-        has_child_file(path, ".claws_mark") ||
-        /* NNML (Gnus) */
-        has_child_file(path, ".marks") ||
-        has_child_file(path, ".overview") ||
-        /* Evolution */
-        has_child_file(path, "cmeta") ||
-        has_child_file(path, "summary") ||
-        /* Mew */
-        has_child_file(path, ".mew-summary") ||
-        /* ezmlm/archive */
-        has_child_file(path, "index")
-        ) {
-      result = 1;
-    }
-  }
-  return result;
-}
-/*}}}*/
-struct traverse_methods mh_traverse_methods = {/*{{{*/
-  .filter = filter_is_mh,
-  .scrutinize = scrutinize_mh_entry
-};
-/*}}}*/
-#if 0
-static void scan_directory(char *folder_base, char *this_folder, enum folder_type ft, struct msgpath_array *arr)/*{{{*/
-{
-  DIR *d;
-  struct dirent *de;
-  struct stat sb;
-  char *fname, *sname;
-  char *name;
-  int folder_base_len = strlen(folder_base);
-  int this_folder_len = strlen(this_folder);
-
-  name = new_array(char, folder_base_len + this_folder_len + 2);
-  strcpy(name, folder_base);
-  strcat(name, "/");
-  strcat(name, this_folder);
-
-  switch (ft) {
-    case FT_MAILDIR:
-      if (looks_like_maildir(folder_base, this_folder)) {
-        get_maildir_message_paths(folder_base, this_folder, arr);
-      }
-      break;
-    case FT_MH:
-      get_mh_message_paths(folder_base, this_folder, arr);
-      break;
-    default:
-      break;
-  }
-
-  fname = new_array(char, strlen(name) + 2 + NAME_MAX);
-  sname = new_array(char, this_folder_len + 2 + NAME_MAX);
-
-  d = opendir(name);
-  if (d) {
-    while ((de = readdir(d))) {
-      if (!strcmp(de->d_name, ".") ||
-          !strcmp(de->d_name, "..")) {
-        continue;
-      }
-
-      strcpy(fname, name);
-      strcat(fname, "/");
-      strcat(fname, de->d_name);
-
-      strcpy(sname, this_folder);
-      strcat(sname, "/");
-      strcat(sname, de->d_name);
-
-      if (stat(fname, &sb) >= 0) {
-        if (S_ISDIR(sb.st_mode)) {
-          scan_directory(folder_base, sname, ft, arr);
-        }
-      }
-    }
-    closedir(d);
-  }
-
-  free(fname);
-  free(sname);
-  free(name);
-  return;
-}
-/*}}}*/
-#endif
-static int message_compare(const void *a, const void *b)/*{{{*/
-{
-  /* FIXME : Is this a sensible way to do this with mbox messages in the picture? */
-  struct msgpath *aa = (struct msgpath *) a;
-  struct msgpath *bb = (struct msgpath *) b;
-  /* This should only get called on 'file' type messages - TBC! */
-  return strcmp(aa->src.mpf.path, bb->src.mpf.path);
-}
-/*}}}*/
-static void sort_message_list(struct msgpath_array *arr)/*{{{*/
-{
-  qsort(arr->paths, arr->n, sizeof(struct msgpath), message_compare);
-}
-/*}}}*/
-/*{{{ void build_message_list */
-void build_message_list(char *folder_base, char *folders, enum folder_type ft,
-    struct msgpath_array *msgs,
-    struct globber_array *omit_globs)
-{
-  char **raw_paths, **paths;
-  int n_raw_paths, n_paths, i;
-
-  split_on_colons(folders, &n_raw_paths, &raw_paths);
-  switch (ft) {
-    case FT_MAILDIR:
-      glob_and_expand_paths(folder_base, raw_paths, n_raw_paths, &paths, &n_paths, &maildir_traverse_methods, omit_globs);
-      for (i=0; i<n_paths; i++) {
-        get_maildir_message_paths(paths[i], msgs);
-      }
-      break;
-    case FT_MH:
-      glob_and_expand_paths(folder_base, raw_paths, n_raw_paths, &paths, &n_paths, &mh_traverse_methods, omit_globs);
-      for (i=0; i<n_paths; i++) {
-        get_mh_message_paths(paths[i], msgs);
-      }
-      break;
-    default:
-      assert(0);
-      break;
-  }
-
-  if (paths) free(paths);
-
-  sort_message_list(msgs);
-  return;
-}
-/*}}}*/
-
-#ifdef TEST
-int main (int argc, char **argv)
-{
-  int i;
-  struct msgpath_array *arr;
-
-  arr = build_message_list(".");
-
-  for (i=0; i<arr->n; i++) {
-    printf("%08lx %s\n", arr->paths[i].mtime, arr->paths[i].path);
-  }
-
-  free_msgpath_array(arr);
-
-  return 0;
-}
-#endif
-
-
diff --git a/src/mairix/dotlock.c b/src/mairix/dotlock.c
@@ -1,116 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "mairix.h"
-#include <sys/utsname.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <unistd.h>
-
-static char *lock_file_name = NULL;
-
-/* This locking code was originally written for tdl */
-
-void lock_database(char *path, int forced_unlock)/*{{{*/
-{
-  struct utsname uu;
-  struct passwd *pw;
-  int pid;
-  int len;
-  char *tname;
-  struct stat sb;
-  FILE *out;
-
-  if (uname(&uu) < 0) {
-    perror("uname");
-    exit(1);
-  }
-  pw = getpwuid(getuid());
-  if (!pw) {
-    perror("getpwuid");
-    exit(1);
-  }
-  pid = getpid();
-  len = 1 + strlen(path) + 5;
-  lock_file_name = new_array(char, len);
-  sprintf(lock_file_name, "%s.lock", path);
-
-  if (forced_unlock) {
-    unlock_database();
-    forced_unlock = 0;
-  }
-
-  len += strlen(uu.nodename);
-  /* add on max width of pid field (allow up to 32 bit pid_t) + 2 '.' chars */
-  len += (10 + 2);
-  tname = new_array(char, len);
-  sprintf(tname, "%s.%d.%s", lock_file_name, pid, uu.nodename);
-  out = fopen(tname, "w");
-  if (!out) {
-    fprintf(stderr, "Cannot open lock file %s for writing\n", tname);
-    exit(1);
-  }
-  fprintf(out, "%d,%s,%s\n", pid, uu.nodename, pw->pw_name);
-  fclose(out);
-
-  if (link(tname, lock_file_name) < 0) {
-    /* check if link count==2 */
-    if (stat(tname, &sb) < 0) {
-      fprintf(stderr, "Could not stat the lock file\n");
-      unlink(tname);
-      exit(1);
-    } else {
-      if (sb.st_nlink != 2) {
-        FILE *in;
-        in = fopen(lock_file_name, "r");
-        if (in) {
-          char line[2048];
-          fgets(line, sizeof(line), in);
-          line[strlen(line)-1] = 0; /* strip trailing newline */
-          fprintf(stderr, "Database %s appears to be locked by (pid,node,user)=(%s)\n", path, line);
-          unlink(tname);
-          exit(1);
-        }
-      } else {
-        /* lock succeeded apparently */
-      }
-    }
-  } else {
-    /* lock succeeded apparently */
-  }
-  unlink(tname);
-  free(tname);
-  return;
-}
-/*}}}*/
-void unlock_database(void)/*{{{*/
-{
-  if (lock_file_name) unlink(lock_file_name);
-  return;
-}
-/*}}}*/
-void unlock_and_exit(int code)/*{{{*/
-{
-  unlock_database();
-  exit(code);
-}
-/*}}}*/
diff --git a/src/mairix/dotmairixrc.eg b/src/mairix/dotmairixrc.eg
@@ -1,41 +0,0 @@
-#######################################################################
-#
-# Example ~/.mairixrc file
-#
-# Any line starting with # is a comment.
-#
-#######################################################################
-# Set this to the directory where your maildir folders live
-base=/home/richard/mail
-
-#######################################################################
-# You need to define at least one of maildir, mh and mbox. You probably don't
-# need to define all three!  You can use >1 line for any of these.
-
-# Set this to a list of maildir folders within 'base'.  3 dots at the end means
-# there are sub-folders within this folder.
-maildir=inbox:archive...
-maildir=lists...
-
-# Set this to a list of MH folders within 'base'.  3 dots at the end means
-# there are sub-folders within this folder.
-mh=mh_archive...
-
-# Set this to a list of mbox folders within 'base'.
-mbox=mboxen/folder1:mboxen/folder2:mboxen/foobar
-
-#######################################################################
-# Set this to the folder within 'base' where you want the search mode
-# to write its output.
-mfolder=mfolder
-
-# Set this if you want the format of mfolder to be mh or mbox (the default is
-# maildir).
-#
-# mformat=mh
-# mformat=mbox
-
-#######################################################################
-# Set this to the path where the index database file will be kept
-database=/home/richard/mail/mairix_database
-
diff --git a/src/mairix/dumper.c b/src/mairix/dumper.c
@@ -1,151 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2004, 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Database dumper */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <sys/mman.h>
-
-#include "mairix.h"
-#include "reader.h"
-#include "memmac.h"
-
-static void dump_token_chain(struct read_db *db, unsigned int n, unsigned int *tok_offsets, unsigned int *enc_offsets)
-{
-  int i, j, incr;
-  int on_line;
-  unsigned char *foo;
-  printf("%d entries\n", n);
-  for (i=0; i<n; i++) {
-    printf("Word %d : <%s>\n", i, db->data + tok_offsets[i]);
-    foo = (unsigned char *) db->data + enc_offsets[i];
-    j = 0;
-    on_line = 0;
-    printf("  ");
-    while (*foo != 0xff) {
-      if (on_line > 15) {
-        printf("\n");
-        on_line = 0;
-      }
-      incr = read_increment(&foo);
-      j += incr;
-      printf("%d ", j);
-      on_line++;
-    }
-    printf("\n");
-  }
-}
-
-static void dump_toktable(struct read_db *db, struct toktable_db *tbl, const char *title)
-{
-  printf("Contents of <%s> table\n", title);
-  dump_token_chain( db, tbl->n, tbl->tok_offsets, tbl->enc_offsets);
-}
-
-static void dump_toktable2(struct read_db *db, struct toktable2_db *tbl, const char *title)
-{
-  unsigned int n;
-  n = tbl->n;
-  printf("Contents of <%s> table\n", title);
-  printf("Chain 0\n");
-  dump_token_chain( db, n, tbl->tok_offsets, tbl->enc0_offsets);
-  printf("Chain 1\n");
-  dump_token_chain( db, n, tbl->tok_offsets, tbl->enc1_offsets);
-}
-
-void dump_database(char *filename)
-{
-  struct read_db *db;
-  int i;
-
-  db = open_db(filename);
-
-  printf("Dump of %s\n", filename);
-  printf("%d messages\n", db->n_msgs);
-  for (i=0; i<db->n_msgs; i++) {
-    printf("%6d: ", i);
-    switch (rd_msg_type(db, i)) {
-      case DB_MSG_DEAD:
-        printf("DEAD");
-        break;
-      case DB_MSG_FILE:
-        printf("FILE %s, size=%d, tid=%d",
-               db->data + db->path_offsets[i], db->size_table[i], db->tid_table[i]);
-        break;
-      case DB_MSG_MBOX:
-        {
-          unsigned int mbix, msgix;
-          decode_mbox_indices(db->path_offsets[i], &mbix, &msgix);
-
-          printf("MBOX %d, msg %d, offset=%d, size=%d, tid=%d",
-                 mbix, msgix, db->mtime_table[i], db->size_table[i], db->tid_table[i]);
-        }
-        break;
-    }
-    if (db->msg_type_and_flags[i] & FLAG_SEEN) printf(" seen");
-    if (db->msg_type_and_flags[i] & FLAG_REPLIED) printf(" replied");
-    if (db->msg_type_and_flags[i] & FLAG_FLAGGED) printf(" flagged");
-    printf("\n");
-  }
-  printf("\n");
-  if (db->n_mboxen > 0) {
-    printf("\nMBOX INFORMATION\n");
-    printf("%d mboxen\n", db->n_mboxen);
-    for (i=0; i<db->n_mboxen; i++) {
-      if (db->mbox_paths_table[i]) {
-        printf("%4d: %d msgs in %s\n", i, db->mbox_entries_table[i], db->data + db->mbox_paths_table[i]);
-      } else {
-        printf("%4d: dead\n", i);
-      }
-    }
-    printf("\n");
-  }
-
-  printf("Hash key %08x\n\n", db->hash_key);
-  printf("--------------------------------\n");
-  dump_toktable(db, &db->to, "To");
-  printf("--------------------------------\n");
-  dump_toktable(db, &db->cc, "Cc");
-  printf("--------------------------------\n");
-  dump_toktable(db, &db->from, "From");
-  printf("--------------------------------\n");
-  dump_toktable(db, &db->subject, "Subject");
-  printf("--------------------------------\n");
-  dump_toktable(db, &db->body, "Body");
-  printf("--------------------------------\n");
-  dump_toktable(db, &db->attachment_name, "Attachment names");
-  printf("--------------------------------\n");
-  dump_toktable2(db, &db->msg_ids, "Message Ids");
-  printf("--------------------------------\n");
-
-  close_db(db);
-  return;
-}
-
diff --git a/src/mairix/expandstr.c b/src/mairix/expandstr.c
@@ -1,196 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2004
- * Copyright (C) Andreas Amann 2010
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "mairix.h"
-#include <stdlib.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <unistd.h>
-
-static int isenv(unsigned char x)/*{{{*/
-{
-  /* Return true if x is valid as part of an environment variable name. */
-  if (isalnum(x))
-    return 1;
-  else if (x == '_')
-    return 1;
-  else
-    return 0;
-}
-/*}}}*/
-static int home_dir_len(void)/*{{{*/
-{
-  struct passwd *foo;
-  char *lookup;
-  lookup = getenv("HOME");
-  if (lookup) {
-    return strlen(lookup);
-  }
-  foo = getpwuid(getuid());
-  return strlen(foo->pw_dir);
-}
-/*}}}*/
-static char *env_lookup(const char *p, const char *q)/*{{{*/
-{
-  char *var;
-  char *lookup, *result;
-  char *s;
-  var = new_array(char, (q-p)+1);
-  for (s=var; p<q; p++, s++) {
-    *s = *p;
-  }
-  *s = 0;
-  lookup = getenv(var);
-  if (lookup) {
-    result = new_string(lookup);
-  } else {
-    result = NULL;
-  }
-  free(var);
-  return result;
-}
-/*}}}*/
-static int env_lookup_len(const char *p, const char *q) {/*{{{*/
-  char *foo;
-  int len;
-  foo = env_lookup(p, q);
-  if (!foo) len = 0;
-  else {
-    len = strlen(foo);
-    free(foo);
-  }
-  return len;
-}
-/*}}}*/
-static int compute_length(const char *p)/*{{{*/
-{
-  const char *q;
-  int first;
-  int len;
-  first = 1;
-  len = 0;
-  while (*p) {
-    if (first && (*p == '~') && (p[1] == '/')) {
-      /* Make no attempt to expand ~other_user form */
-      len += home_dir_len();
-      p++;
-    } else if ((*p == '$') && (p[1] == '{')) {
-      p += 2;
-      q = p;
-      while (*q && (*q != '}')) q++;
-      len += env_lookup_len(p, q);
-      p = *q ? (q + 1) : q;
-    } else if (*p == '$') {
-      p++;
-      q = p;
-      while (*q && isenv(*(unsigned char*)q)) q++;
-      len += env_lookup_len(p, q);
-      p = q;
-    } else {
-      len++;
-      p++;
-    }
-    first = 0;
-  }
-  return len;
-}
-/*}}}*/
-static char *append_home_dir(char *to)/*{{{*/
-{
-  struct passwd *foo;
-  int len;
-  char *lookup;
-  lookup = getenv("HOME");
-  if (lookup) {
-    len = strlen(lookup);
-    strcpy(to, lookup);
-  } else {
-    foo = getpwuid(getuid());
-    len = strlen(foo->pw_dir);
-    strcpy(to, foo->pw_dir);
-  }
-  return to + len;
-}
-/*}}}*/
-static char *append_env(char *to, const char *p, const char *q)/*{{{*/
-{
-  char *foo;
-  int len;
-  foo = env_lookup(p, q);
-  if (foo) {
-    len = strlen(foo);
-    strcpy(to, foo);
-    free(foo);
-  } else {
-    len = 0;
-  }
-  return (to + len);
-}
-/*}}}*/
-static void do_expand(const char *p, char *result)/*{{{*/
-{
-  const char *q;
-  int first;
-  first = 1;
-  while (*p) {
-    if (first && (*p == '~') && (p[1] == '/')) {
-      result = append_home_dir(result);
-      p++;
-    } else if ((*p == '$') && (p[1] == '{')) {
-      p += 2;
-      q = p;
-      while (*q && (*q != '}')) q++;
-      result = append_env(result, p, q);
-      p = *q ? (q + 1) : q;
-    } else if (*p == '$') {
-      p++;
-      q = p;
-      while (*q && isenv(*(unsigned char*)q)) q++;
-      result = append_env(result, p, q);
-      p = q;
-    } else {
-      *result++ = *p++;
-    }
-    first = 0;
-  }
-  *result = 0;
-}
-/*}}}*/
-char *expand_string(const char *p)/*{{{*/
-{
-  /* Return a copy of p, but with
-
-     ~ expanded to the user's home directory
-     $env expanded to the value of that environment variable
-  */
-
-  int len;
-  char *result;
-
-  len = compute_length(p);
-  result = new_array(char, len+1);
-  do_expand(p, result);
-  return result;
-}
-/*}}}*/
diff --git a/src/mairix/from.h b/src/mairix/from.h
@@ -1,32 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002-2004,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 _FROM_H
-#define _FROM_H
-
-enum fromcheck_result {
-  FROMCHECK_PASS,
-  FROMCHECK_FAIL
-};
-
-#endif
-
diff --git a/src/mairix/fromcheck.nfa b/src/mairix/fromcheck.nfa
@@ -1,218 +0,0 @@
-#########################################################################
-#
-# mairix - message index builder and finder for maildir folders.
-#
-# Copyright (C) Richard P. Curnow  2002-2004,2006
-# Copyright (C) Jonathan Kamens 2010
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# 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.
-#
-# =======================================================================
-
-%{
-#include "from.h"
-%}
-
-
-# Define tokens
-# CR : \n
-# DIGIT : [0-9]
-# AT : @
-# COLON : :
-# WHITE : ' ', \t
-# LOWER : [a-z]
-# UPPER : [A-Z]
-# PLUSMINUS : [+-]
-# OTHER_EMAIL : other stuff valid in the LHS of an address
-# DOMAIN : stuff valid in the RHS of an address
-
-Abbrev LF = [\n]
-Abbrev CR = [\r]
-Abbrev DIGIT = [0-9]
-Abbrev PERIOD = [.]
-Abbrev AT = [@]
-Abbrev LOWER = [a-z]
-Abbrev UPPER = [A-Z]
-Abbrev COLON = [:]
-Abbrev WHITE = [ \t]
-Abbrev PLUSMINUS = [+\-]
-# Explained clearly at
-# http://en.wikipedia.org/wiki/E-mail_address#RFC_specification
-Abbrev OTHER_EMAIL = [.!#$%&'*/=?^_`{|}~]
-Abbrev LT = [<]
-Abbrev GT = [>]
-Abbrev EMAIL = LOWER | UPPER | DIGIT | PLUSMINUS | OTHER_EMAIL
-Abbrev OTHER_DOMAIN = [\-_.]
-Abbrev DOMAIN = LOWER | UPPER | DIGIT | OTHER_DOMAIN
-Abbrev DQUOTE = ["]
-Abbrev OTHER_QUOTED = [@:<>]
-Abbrev LEFTSQUARE = [[]
-Abbrev RIGHTSQUARE = [\]]
-
-BLOCK email {
-    STATE in
-        EMAIL -> in, before_at
-        DQUOTE -> quoted_before_at
-        AT -> domain_route
-
-    STATE domain_route
-        DOMAIN -> domain_route
-        COLON -> in
-
-    STATE quoted_before_at
-        EMAIL | WHITE | OTHER_QUOTED -> quoted_before_at
-        DQUOTE -> before_at
-
-    STATE before_at
-        EMAIL -> before_at
-        DQUOTE -> quoted_before_at
-        # Local part only : >=1 characters will suffice, which we've already
-        # matched.
-        -> out
-        AT -> start_of_domain
-
-    STATE start_of_domain
-        LEFTSQUARE -> dotted_quad
-        DOMAIN -> after_at
-
-    STATE dotted_quad
-        DIGIT | PERIOD -> dotted_quad
-        RIGHTSQUARE -> out
-
-    STATE after_at
-        DOMAIN -> after_at, out
-
-}
-
-BLOCK angled_email {
-    STATE in
-        LT -> in_angles
-
-    STATE in_angles
-        <email:in->out> -> before_gt
-
-    STATE before_gt
-        GT -> out
-}
-
-BLOCK zone {
-    # Make this pretty lenient
-    STATE in
-        UPPER -> zone2
-        UPPER -> out
-        PLUSMINUS -> zone2
-
-    STATE zone2
-        UPPER | LOWER -> zone2, out
-        DIGIT         -> zone2, out
-}
-
-BLOCK date {
-    STATE in
-        WHITE -> in, before_weekday
-
-    STATE before_weekday
-        UPPER ; LOWER ; LOWER ; WHITE -> after_weekday
-
-    STATE after_weekday
-        WHITE -> after_weekday
-        UPPER ; LOWER ; LOWER ; WHITE -> after_month
-
-    STATE after_month
-        WHITE -> after_month
-        DIGIT ; WHITE -> after_day
-        DIGIT ; DIGIT ; WHITE -> after_day
-
-    STATE after_day
-        WHITE -> after_day
-        # Accept HH:MM:SS
-        DIGIT ; DIGIT ; COLON ; DIGIT ; DIGIT ; COLON ; DIGIT ; DIGIT ; WHITE -> after_time
-        # Accept HH:MM
-        DIGIT ; DIGIT ; COLON ; DIGIT ; DIGIT ; WHITE -> after_time
-
-    # Allow either 1 or 2 words of timezone
-    STATE after_time
-        WHITE -> after_time
-        -> after_timezone
-        <zone:in->out> ; WHITE -> after_timezone
-        <zone:in->out> ; WHITE -> after_timezone_1
-
-        # It appears that Pine puts the timezone after the year
-        DIGIT ; DIGIT ; DIGIT ; DIGIT -> after_year_before_zone
-
-    STATE after_year_before_zone
-        WHITE -> after_year_before_zone
-        <zone:in->out> -> after_timezone_after_year
-        <zone:in->out> ; WHITE -> after_timezone_after_year_1
-
-    STATE after_timezone_after_year_1
-        WHITE -> after_timezone_after_year_1
-        <zone:in->out> -> after_timezone_after_year
-
-    STATE after_timezone_after_year
-        WHITE -> after_timezone_after_year
-        -> out
-
-    STATE after_timezone_1
-        WHITE -> after_timezone_1
-        <zone:in->out> ; WHITE -> after_timezone
-
-    STATE after_timezone
-        WHITE -> after_timezone
-        DIGIT ; DIGIT ; DIGIT ; DIGIT -> after_year
-
-    STATE after_year
-        WHITE -> after_year
-        -> out
-
-}
-
-# Assume the earlier code has identified the '\nFrom ' sequence,
-# and the validator starts scanning from the character beyond the space
-
-BLOCK main {
-
-    STATE in
-        # Real return address.
-        WHITE -> in
-        <email:in->out> -> before_date
-        <angled_email:in->out> -> before_date
-
-        # Cope with Mozilla mbox folder format which just uses a '-' as
-        # the return address field.
-        PLUSMINUS       -> before_date
-
-        # Empty return address
-                        -> before_date
-
-    STATE before_date
-        <date:in->out> ; LF = FROMCHECK_PASS
-
-        # Cope with mozilla mbox format
-        <date:in->out> ; CR ; LF = FROMCHECK_PASS
-
-    # Mention this state last : the last mentioned state in the last defined
-    # block becomes the entry state of the scanner.
-
-    STATE in
-
-}
-
-ATTR FROMCHECK_PASS
-ATTR FROMCHECK_FAIL
-DEFATTR FROMCHECK_FAIL
-PREFIX fromcheck
-TYPE "enum fromcheck_result"
-
-# vim:ft=txt:et:sw=4:sts=4:ht=4
diff --git a/src/mairix/fromcheck.report b/src/mairix/fromcheck.report
@@ -1,3222 +0,0 @@
-NFA state 0 = in
-  [(epsilon)] -> before_date
-   5:[+] -> before_date
-   6:[\055] -> before_date
-  [(epsilon)] -> angled_email#2.in
-  [(epsilon)] -> email#1.in
-   0:[\t ] -> in
-  Epsilon closure :
-    (self)
-    email#1.in
-    angled_email#2.in
-    before_date
-    date#3.in
-    date#4.in
-
-NFA state 1 = email#1.in
-   3:[!#-'*/=?^`{-~] -> email#1.in
-   16:[_] -> email#1.in
-   7:[.] -> email#1.in
-   5:[+] -> email#1.in
-   6:[\055] -> email#1.in
-   8:[0-9] -> email#1.in
-   13:[A-Z] -> email#1.in
-   17:[a-z] -> email#1.in
-   3:[!#-'*/=?^`{-~] -> email#1.before_at
-   16:[_] -> email#1.before_at
-   7:[.] -> email#1.before_at
-   5:[+] -> email#1.before_at
-   6:[\055] -> email#1.before_at
-   8:[0-9] -> email#1.before_at
-   13:[A-Z] -> email#1.before_at
-   17:[a-z] -> email#1.before_at
-   4:["] -> email#1.quoted_before_at
-   12:[@] -> email#1.domain_route
-  Epsilon closure :
-    (self)
-
-NFA state 2 = email#1.domain_route
-   6:[\055] -> email#1.domain_route
-   16:[_] -> email#1.domain_route
-   7:[.] -> email#1.domain_route
-   8:[0-9] -> email#1.domain_route
-   13:[A-Z] -> email#1.domain_route
-   17:[a-z] -> email#1.domain_route
-   9:[:] -> email#1.in
-  Epsilon closure :
-    (self)
-
-NFA state 3 = email#1.quoted_before_at
-   9:[:] -> email#1.quoted_before_at
-   12:[@] -> email#1.quoted_before_at
-   11:[>] -> email#1.quoted_before_at
-   10:[<] -> email#1.quoted_before_at
-   0:[\t ] -> email#1.quoted_before_at
-   3:[!#-'*/=?^`{-~] -> email#1.quoted_before_at
-   16:[_] -> email#1.quoted_before_at
-   7:[.] -> email#1.quoted_before_at
-   5:[+] -> email#1.quoted_before_at
-   6:[\055] -> email#1.quoted_before_at
-   8:[0-9] -> email#1.quoted_before_at
-   13:[A-Z] -> email#1.quoted_before_at
-   17:[a-z] -> email#1.quoted_before_at
-   4:["] -> email#1.before_at
-  Epsilon closure :
-    (self)
-
-NFA state 4 = email#1.before_at
-   3:[!#-'*/=?^`{-~] -> email#1.before_at
-   16:[_] -> email#1.before_at
-   7:[.] -> email#1.before_at
-   5:[+] -> email#1.before_at
-   6:[\055] -> email#1.before_at
-   8:[0-9] -> email#1.before_at
-   13:[A-Z] -> email#1.before_at
-   17:[a-z] -> email#1.before_at
-   4:["] -> email#1.quoted_before_at
-  [(epsilon)] -> email#1.out
-   12:[@] -> email#1.start_of_domain
-  Epsilon closure :
-    (self)
-    email#1.out
-    before_date
-    date#3.in
-    date#4.in
-
-NFA state 5 = email#1.start_of_domain
-   14:[[] -> email#1.dotted_quad
-   6:[\055] -> email#1.after_at
-   16:[_] -> email#1.after_at
-   7:[.] -> email#1.after_at
-   8:[0-9] -> email#1.after_at
-   13:[A-Z] -> email#1.after_at
-   17:[a-z] -> email#1.after_at
-  Epsilon closure :
-    (self)
-
-NFA state 6 = email#1.dotted_quad
-   7:[.] -> email#1.dotted_quad
-   8:[0-9] -> email#1.dotted_quad
-   15:[]] -> email#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 7 = email#1.after_at
-   6:[\055] -> email#1.after_at
-   16:[_] -> email#1.after_at
-   7:[.] -> email#1.after_at
-   8:[0-9] -> email#1.after_at
-   13:[A-Z] -> email#1.after_at
-   17:[a-z] -> email#1.after_at
-   6:[\055] -> email#1.out
-   16:[_] -> email#1.out
-   7:[.] -> email#1.out
-   8:[0-9] -> email#1.out
-   13:[A-Z] -> email#1.out
-   17:[a-z] -> email#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 8 = email#1.out
-  [(epsilon)] -> before_date
-  Epsilon closure :
-    (self)
-    before_date
-    date#3.in
-    date#4.in
-
-NFA state 9 = angled_email#2.in
-   10:[<] -> angled_email#2.in_angles
-  Epsilon closure :
-    (self)
-
-NFA state 10 = angled_email#2.in_angles
-  [(epsilon)] -> angled_email#2.email#1.in
-  Epsilon closure :
-    (self)
-    angled_email#2.email#1.in
-
-NFA state 11 = angled_email#2.email#1.in
-   12:[@] -> angled_email#2.email#1.domain_route
-   4:["] -> angled_email#2.email#1.quoted_before_at
-   17:[a-z] -> angled_email#2.email#1.before_at
-   13:[A-Z] -> angled_email#2.email#1.before_at
-   8:[0-9] -> angled_email#2.email#1.before_at
-   5:[+] -> angled_email#2.email#1.before_at
-   6:[\055] -> angled_email#2.email#1.before_at
-   3:[!#-'*/=?^`{-~] -> angled_email#2.email#1.before_at
-   16:[_] -> angled_email#2.email#1.before_at
-   7:[.] -> angled_email#2.email#1.before_at
-   17:[a-z] -> angled_email#2.email#1.in
-   13:[A-Z] -> angled_email#2.email#1.in
-   8:[0-9] -> angled_email#2.email#1.in
-   5:[+] -> angled_email#2.email#1.in
-   6:[\055] -> angled_email#2.email#1.in
-   3:[!#-'*/=?^`{-~] -> angled_email#2.email#1.in
-   16:[_] -> angled_email#2.email#1.in
-   7:[.] -> angled_email#2.email#1.in
-  Epsilon closure :
-    (self)
-
-NFA state 12 = angled_email#2.email#1.domain_route
-   9:[:] -> angled_email#2.email#1.in
-   17:[a-z] -> angled_email#2.email#1.domain_route
-   13:[A-Z] -> angled_email#2.email#1.domain_route
-   8:[0-9] -> angled_email#2.email#1.domain_route
-   6:[\055] -> angled_email#2.email#1.domain_route
-   16:[_] -> angled_email#2.email#1.domain_route
-   7:[.] -> angled_email#2.email#1.domain_route
-  Epsilon closure :
-    (self)
-
-NFA state 13 = angled_email#2.email#1.quoted_before_at
-   4:["] -> angled_email#2.email#1.before_at
-   17:[a-z] -> angled_email#2.email#1.quoted_before_at
-   13:[A-Z] -> angled_email#2.email#1.quoted_before_at
-   8:[0-9] -> angled_email#2.email#1.quoted_before_at
-   5:[+] -> angled_email#2.email#1.quoted_before_at
-   6:[\055] -> angled_email#2.email#1.quoted_before_at
-   3:[!#-'*/=?^`{-~] -> angled_email#2.email#1.quoted_before_at
-   16:[_] -> angled_email#2.email#1.quoted_before_at
-   7:[.] -> angled_email#2.email#1.quoted_before_at
-   0:[\t ] -> angled_email#2.email#1.quoted_before_at
-   9:[:] -> angled_email#2.email#1.quoted_before_at
-   12:[@] -> angled_email#2.email#1.quoted_before_at
-   11:[>] -> angled_email#2.email#1.quoted_before_at
-   10:[<] -> angled_email#2.email#1.quoted_before_at
-  Epsilon closure :
-    (self)
-
-NFA state 14 = angled_email#2.email#1.before_at
-   12:[@] -> angled_email#2.email#1.start_of_domain
-  [(epsilon)] -> angled_email#2.email#1.out
-   4:["] -> angled_email#2.email#1.quoted_before_at
-   17:[a-z] -> angled_email#2.email#1.before_at
-   13:[A-Z] -> angled_email#2.email#1.before_at
-   8:[0-9] -> angled_email#2.email#1.before_at
-   5:[+] -> angled_email#2.email#1.before_at
-   6:[\055] -> angled_email#2.email#1.before_at
-   3:[!#-'*/=?^`{-~] -> angled_email#2.email#1.before_at
-   16:[_] -> angled_email#2.email#1.before_at
-   7:[.] -> angled_email#2.email#1.before_at
-  Epsilon closure :
-    (self)
-    angled_email#2.email#1.out
-    angled_email#2.before_gt
-
-NFA state 15 = angled_email#2.email#1.start_of_domain
-   17:[a-z] -> angled_email#2.email#1.after_at
-   13:[A-Z] -> angled_email#2.email#1.after_at
-   8:[0-9] -> angled_email#2.email#1.after_at
-   6:[\055] -> angled_email#2.email#1.after_at
-   16:[_] -> angled_email#2.email#1.after_at
-   7:[.] -> angled_email#2.email#1.after_at
-   14:[[] -> angled_email#2.email#1.dotted_quad
-  Epsilon closure :
-    (self)
-
-NFA state 16 = angled_email#2.email#1.dotted_quad
-   15:[]] -> angled_email#2.email#1.out
-   8:[0-9] -> angled_email#2.email#1.dotted_quad
-   7:[.] -> angled_email#2.email#1.dotted_quad
-  Epsilon closure :
-    (self)
-
-NFA state 17 = angled_email#2.email#1.after_at
-   17:[a-z] -> angled_email#2.email#1.out
-   13:[A-Z] -> angled_email#2.email#1.out
-   8:[0-9] -> angled_email#2.email#1.out
-   6:[\055] -> angled_email#2.email#1.out
-   16:[_] -> angled_email#2.email#1.out
-   7:[.] -> angled_email#2.email#1.out
-   17:[a-z] -> angled_email#2.email#1.after_at
-   13:[A-Z] -> angled_email#2.email#1.after_at
-   8:[0-9] -> angled_email#2.email#1.after_at
-   6:[\055] -> angled_email#2.email#1.after_at
-   16:[_] -> angled_email#2.email#1.after_at
-   7:[.] -> angled_email#2.email#1.after_at
-  Epsilon closure :
-    (self)
-
-NFA state 18 = angled_email#2.email#1.out
-  [(epsilon)] -> angled_email#2.before_gt
-  Epsilon closure :
-    (self)
-    angled_email#2.before_gt
-
-NFA state 19 = angled_email#2.before_gt
-   11:[>] -> angled_email#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 20 = angled_email#2.out
-  [(epsilon)] -> before_date
-  Epsilon closure :
-    (self)
-    before_date
-    date#3.in
-    date#4.in
-
-NFA state 21 = before_date
-  [(epsilon)] -> date#4.in
-  [(epsilon)] -> date#3.in
-  Epsilon closure :
-    (self)
-    date#3.in
-    date#4.in
-
-NFA state 22 = #1
-   1:[\n] -> #2
-  Epsilon closure :
-    (self)
-
-NFA state 23 = date#3.in
-   0:[\t ] -> date#3.in
-   0:[\t ] -> date#3.before_weekday
-  Epsilon closure :
-    (self)
-
-NFA state 24 = date#3.before_weekday
-   13:[A-Z] -> date#3.#1
-  Epsilon closure :
-    (self)
-
-NFA state 25 = date#3.#1
-   17:[a-z] -> date#3.#2
-  Epsilon closure :
-    (self)
-
-NFA state 26 = date#3.#2
-   17:[a-z] -> date#3.#3
-  Epsilon closure :
-    (self)
-
-NFA state 27 = date#3.#3
-   0:[\t ] -> date#3.after_weekday
-  Epsilon closure :
-    (self)
-
-NFA state 28 = date#3.after_weekday
-   0:[\t ] -> date#3.after_weekday
-   13:[A-Z] -> date#3.#4
-  Epsilon closure :
-    (self)
-
-NFA state 29 = date#3.#4
-   17:[a-z] -> date#3.#5
-  Epsilon closure :
-    (self)
-
-NFA state 30 = date#3.#5
-   17:[a-z] -> date#3.#6
-  Epsilon closure :
-    (self)
-
-NFA state 31 = date#3.#6
-   0:[\t ] -> date#3.after_month
-  Epsilon closure :
-    (self)
-
-NFA state 32 = date#3.after_month
-   0:[\t ] -> date#3.after_month
-   8:[0-9] -> date#3.#7
-   8:[0-9] -> date#3.#8
-  Epsilon closure :
-    (self)
-
-NFA state 33 = date#3.#7
-   0:[\t ] -> date#3.after_day
-  Epsilon closure :
-    (self)
-
-NFA state 34 = date#3.#8
-   8:[0-9] -> date#3.#9
-  Epsilon closure :
-    (self)
-
-NFA state 35 = date#3.#9
-   0:[\t ] -> date#3.after_day
-  Epsilon closure :
-    (self)
-
-NFA state 36 = date#3.after_day
-   0:[\t ] -> date#3.after_day
-   8:[0-9] -> date#3.#10
-   8:[0-9] -> date#3.#18
-  Epsilon closure :
-    (self)
-
-NFA state 37 = date#3.#10
-   8:[0-9] -> date#3.#11
-  Epsilon closure :
-    (self)
-
-NFA state 38 = date#3.#11
-   9:[:] -> date#3.#12
-  Epsilon closure :
-    (self)
-
-NFA state 39 = date#3.#12
-   8:[0-9] -> date#3.#13
-  Epsilon closure :
-    (self)
-
-NFA state 40 = date#3.#13
-   8:[0-9] -> date#3.#14
-  Epsilon closure :
-    (self)
-
-NFA state 41 = date#3.#14
-   9:[:] -> date#3.#15
-  Epsilon closure :
-    (self)
-
-NFA state 42 = date#3.#15
-   8:[0-9] -> date#3.#16
-  Epsilon closure :
-    (self)
-
-NFA state 43 = date#3.#16
-   8:[0-9] -> date#3.#17
-  Epsilon closure :
-    (self)
-
-NFA state 44 = date#3.#17
-   0:[\t ] -> date#3.after_time
-  Epsilon closure :
-    (self)
-
-NFA state 45 = date#3.#18
-   8:[0-9] -> date#3.#19
-  Epsilon closure :
-    (self)
-
-NFA state 46 = date#3.#19
-   9:[:] -> date#3.#20
-  Epsilon closure :
-    (self)
-
-NFA state 47 = date#3.#20
-   8:[0-9] -> date#3.#21
-  Epsilon closure :
-    (self)
-
-NFA state 48 = date#3.#21
-   8:[0-9] -> date#3.#22
-  Epsilon closure :
-    (self)
-
-NFA state 49 = date#3.#22
-   0:[\t ] -> date#3.after_time
-  Epsilon closure :
-    (self)
-
-NFA state 50 = date#3.after_time
-   0:[\t ] -> date#3.after_time
-  [(epsilon)] -> date#3.after_timezone
-  [(epsilon)] -> date#3.zone#1.in
-  [(epsilon)] -> date#3.zone#2.in
-   8:[0-9] -> date#3.#25
-  Epsilon closure :
-    (self)
-    date#3.zone#1.in
-    date#3.zone#2.in
-    date#3.after_timezone
-
-NFA state 51 = date#3.#23
-   0:[\t ] -> date#3.after_timezone
-  Epsilon closure :
-    (self)
-
-NFA state 52 = date#3.zone#1.in
-   5:[+] -> date#3.zone#1.zone2
-   6:[\055] -> date#3.zone#1.zone2
-   13:[A-Z] -> date#3.zone#1.out
-   13:[A-Z] -> date#3.zone#1.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 53 = date#3.zone#1.zone2
-   8:[0-9] -> date#3.zone#1.out
-   8:[0-9] -> date#3.zone#1.zone2
-   13:[A-Z] -> date#3.zone#1.out
-   17:[a-z] -> date#3.zone#1.out
-   13:[A-Z] -> date#3.zone#1.zone2
-   17:[a-z] -> date#3.zone#1.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 54 = date#3.zone#1.out
-  [(epsilon)] -> date#3.#23
-  Epsilon closure :
-    (self)
-    date#3.#23
-
-NFA state 55 = date#3.#24
-   0:[\t ] -> date#3.after_timezone_1
-  Epsilon closure :
-    (self)
-
-NFA state 56 = date#3.zone#2.in
-   5:[+] -> date#3.zone#2.zone2
-   6:[\055] -> date#3.zone#2.zone2
-   13:[A-Z] -> date#3.zone#2.out
-   13:[A-Z] -> date#3.zone#2.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 57 = date#3.zone#2.zone2
-   8:[0-9] -> date#3.zone#2.out
-   8:[0-9] -> date#3.zone#2.zone2
-   13:[A-Z] -> date#3.zone#2.out
-   17:[a-z] -> date#3.zone#2.out
-   13:[A-Z] -> date#3.zone#2.zone2
-   17:[a-z] -> date#3.zone#2.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 58 = date#3.zone#2.out
-  [(epsilon)] -> date#3.#24
-  Epsilon closure :
-    (self)
-    date#3.#24
-
-NFA state 59 = date#3.#25
-   8:[0-9] -> date#3.#26
-  Epsilon closure :
-    (self)
-
-NFA state 60 = date#3.#26
-   8:[0-9] -> date#3.#27
-  Epsilon closure :
-    (self)
-
-NFA state 61 = date#3.#27
-   8:[0-9] -> date#3.after_year_before_zone
-  Epsilon closure :
-    (self)
-
-NFA state 62 = date#3.after_year_before_zone
-   0:[\t ] -> date#3.after_year_before_zone
-  [(epsilon)] -> date#3.zone#3.in
-  [(epsilon)] -> date#3.zone#4.in
-  Epsilon closure :
-    (self)
-    date#3.zone#3.in
-    date#3.zone#4.in
-
-NFA state 63 = date#3.zone#3.in
-   5:[+] -> date#3.zone#3.zone2
-   6:[\055] -> date#3.zone#3.zone2
-   13:[A-Z] -> date#3.zone#3.out
-   13:[A-Z] -> date#3.zone#3.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 64 = date#3.zone#3.zone2
-   8:[0-9] -> date#3.zone#3.out
-   8:[0-9] -> date#3.zone#3.zone2
-   13:[A-Z] -> date#3.zone#3.out
-   17:[a-z] -> date#3.zone#3.out
-   13:[A-Z] -> date#3.zone#3.zone2
-   17:[a-z] -> date#3.zone#3.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 65 = date#3.zone#3.out
-  [(epsilon)] -> date#3.after_timezone_after_year
-  Epsilon closure :
-    (self)
-    #1
-    date#3.after_timezone_after_year
-    date#3.out
-
-NFA state 66 = date#3.#28
-   0:[\t ] -> date#3.after_timezone_after_year_1
-  Epsilon closure :
-    (self)
-
-NFA state 67 = date#3.zone#4.in
-   5:[+] -> date#3.zone#4.zone2
-   6:[\055] -> date#3.zone#4.zone2
-   13:[A-Z] -> date#3.zone#4.out
-   13:[A-Z] -> date#3.zone#4.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 68 = date#3.zone#4.zone2
-   8:[0-9] -> date#3.zone#4.out
-   8:[0-9] -> date#3.zone#4.zone2
-   13:[A-Z] -> date#3.zone#4.out
-   17:[a-z] -> date#3.zone#4.out
-   13:[A-Z] -> date#3.zone#4.zone2
-   17:[a-z] -> date#3.zone#4.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 69 = date#3.zone#4.out
-  [(epsilon)] -> date#3.#28
-  Epsilon closure :
-    (self)
-    date#3.#28
-
-NFA state 70 = date#3.after_timezone_after_year_1
-   0:[\t ] -> date#3.after_timezone_after_year_1
-  [(epsilon)] -> date#3.zone#5.in
-  Epsilon closure :
-    (self)
-    date#3.zone#5.in
-
-NFA state 71 = date#3.zone#5.in
-   5:[+] -> date#3.zone#5.zone2
-   6:[\055] -> date#3.zone#5.zone2
-   13:[A-Z] -> date#3.zone#5.out
-   13:[A-Z] -> date#3.zone#5.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 72 = date#3.zone#5.zone2
-   8:[0-9] -> date#3.zone#5.out
-   8:[0-9] -> date#3.zone#5.zone2
-   13:[A-Z] -> date#3.zone#5.out
-   17:[a-z] -> date#3.zone#5.out
-   13:[A-Z] -> date#3.zone#5.zone2
-   17:[a-z] -> date#3.zone#5.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 73 = date#3.zone#5.out
-  [(epsilon)] -> date#3.after_timezone_after_year
-  Epsilon closure :
-    (self)
-    #1
-    date#3.after_timezone_after_year
-    date#3.out
-
-NFA state 74 = date#3.after_timezone_after_year
-   0:[\t ] -> date#3.after_timezone_after_year
-  [(epsilon)] -> date#3.out
-  Epsilon closure :
-    (self)
-    #1
-    date#3.out
-
-NFA state 75 = date#3.after_timezone_1
-   0:[\t ] -> date#3.after_timezone_1
-  [(epsilon)] -> date#3.zone#6.in
-  Epsilon closure :
-    (self)
-    date#3.zone#6.in
-
-NFA state 76 = date#3.#29
-   0:[\t ] -> date#3.after_timezone
-  Epsilon closure :
-    (self)
-
-NFA state 77 = date#3.zone#6.in
-   5:[+] -> date#3.zone#6.zone2
-   6:[\055] -> date#3.zone#6.zone2
-   13:[A-Z] -> date#3.zone#6.out
-   13:[A-Z] -> date#3.zone#6.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 78 = date#3.zone#6.zone2
-   8:[0-9] -> date#3.zone#6.out
-   8:[0-9] -> date#3.zone#6.zone2
-   13:[A-Z] -> date#3.zone#6.out
-   17:[a-z] -> date#3.zone#6.out
-   13:[A-Z] -> date#3.zone#6.zone2
-   17:[a-z] -> date#3.zone#6.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 79 = date#3.zone#6.out
-  [(epsilon)] -> date#3.#29
-  Epsilon closure :
-    (self)
-    date#3.#29
-
-NFA state 80 = date#3.after_timezone
-   0:[\t ] -> date#3.after_timezone
-   8:[0-9] -> date#3.#30
-  Epsilon closure :
-    (self)
-
-NFA state 81 = date#3.#30
-   8:[0-9] -> date#3.#31
-  Epsilon closure :
-    (self)
-
-NFA state 82 = date#3.#31
-   8:[0-9] -> date#3.#32
-  Epsilon closure :
-    (self)
-
-NFA state 83 = date#3.#32
-   8:[0-9] -> date#3.after_year
-  Epsilon closure :
-    (self)
-
-NFA state 84 = date#3.after_year
-   0:[\t ] -> date#3.after_year
-  [(epsilon)] -> date#3.out
-  Epsilon closure :
-    (self)
-    #1
-    date#3.out
-
-NFA state 85 = date#3.out
-  [(epsilon)] -> #1
-  Epsilon closure :
-    (self)
-    #1
-
-NFA state 86 = #2
-  Tags : FROMCHECK_PASS
-  Epsilon closure :
-    (self)
-
-NFA state 87 = #3
-   2:[\r] -> #4
-  Epsilon closure :
-    (self)
-
-NFA state 88 = date#4.in
-   0:[\t ] -> date#4.in
-   0:[\t ] -> date#4.before_weekday
-  Epsilon closure :
-    (self)
-
-NFA state 89 = date#4.before_weekday
-   13:[A-Z] -> date#4.#1
-  Epsilon closure :
-    (self)
-
-NFA state 90 = date#4.#1
-   17:[a-z] -> date#4.#2
-  Epsilon closure :
-    (self)
-
-NFA state 91 = date#4.#2
-   17:[a-z] -> date#4.#3
-  Epsilon closure :
-    (self)
-
-NFA state 92 = date#4.#3
-   0:[\t ] -> date#4.after_weekday
-  Epsilon closure :
-    (self)
-
-NFA state 93 = date#4.after_weekday
-   0:[\t ] -> date#4.after_weekday
-   13:[A-Z] -> date#4.#4
-  Epsilon closure :
-    (self)
-
-NFA state 94 = date#4.#4
-   17:[a-z] -> date#4.#5
-  Epsilon closure :
-    (self)
-
-NFA state 95 = date#4.#5
-   17:[a-z] -> date#4.#6
-  Epsilon closure :
-    (self)
-
-NFA state 96 = date#4.#6
-   0:[\t ] -> date#4.after_month
-  Epsilon closure :
-    (self)
-
-NFA state 97 = date#4.after_month
-   0:[\t ] -> date#4.after_month
-   8:[0-9] -> date#4.#7
-   8:[0-9] -> date#4.#8
-  Epsilon closure :
-    (self)
-
-NFA state 98 = date#4.#7
-   0:[\t ] -> date#4.after_day
-  Epsilon closure :
-    (self)
-
-NFA state 99 = date#4.#8
-   8:[0-9] -> date#4.#9
-  Epsilon closure :
-    (self)
-
-NFA state 100 = date#4.#9
-   0:[\t ] -> date#4.after_day
-  Epsilon closure :
-    (self)
-
-NFA state 101 = date#4.after_day
-   0:[\t ] -> date#4.after_day
-   8:[0-9] -> date#4.#10
-   8:[0-9] -> date#4.#18
-  Epsilon closure :
-    (self)
-
-NFA state 102 = date#4.#10
-   8:[0-9] -> date#4.#11
-  Epsilon closure :
-    (self)
-
-NFA state 103 = date#4.#11
-   9:[:] -> date#4.#12
-  Epsilon closure :
-    (self)
-
-NFA state 104 = date#4.#12
-   8:[0-9] -> date#4.#13
-  Epsilon closure :
-    (self)
-
-NFA state 105 = date#4.#13
-   8:[0-9] -> date#4.#14
-  Epsilon closure :
-    (self)
-
-NFA state 106 = date#4.#14
-   9:[:] -> date#4.#15
-  Epsilon closure :
-    (self)
-
-NFA state 107 = date#4.#15
-   8:[0-9] -> date#4.#16
-  Epsilon closure :
-    (self)
-
-NFA state 108 = date#4.#16
-   8:[0-9] -> date#4.#17
-  Epsilon closure :
-    (self)
-
-NFA state 109 = date#4.#17
-   0:[\t ] -> date#4.after_time
-  Epsilon closure :
-    (self)
-
-NFA state 110 = date#4.#18
-   8:[0-9] -> date#4.#19
-  Epsilon closure :
-    (self)
-
-NFA state 111 = date#4.#19
-   9:[:] -> date#4.#20
-  Epsilon closure :
-    (self)
-
-NFA state 112 = date#4.#20
-   8:[0-9] -> date#4.#21
-  Epsilon closure :
-    (self)
-
-NFA state 113 = date#4.#21
-   8:[0-9] -> date#4.#22
-  Epsilon closure :
-    (self)
-
-NFA state 114 = date#4.#22
-   0:[\t ] -> date#4.after_time
-  Epsilon closure :
-    (self)
-
-NFA state 115 = date#4.after_time
-   0:[\t ] -> date#4.after_time
-  [(epsilon)] -> date#4.after_timezone
-  [(epsilon)] -> date#4.zone#1.in
-  [(epsilon)] -> date#4.zone#2.in
-   8:[0-9] -> date#4.#25
-  Epsilon closure :
-    (self)
-    date#4.zone#1.in
-    date#4.zone#2.in
-    date#4.after_timezone
-
-NFA state 116 = date#4.#23
-   0:[\t ] -> date#4.after_timezone
-  Epsilon closure :
-    (self)
-
-NFA state 117 = date#4.zone#1.in
-   5:[+] -> date#4.zone#1.zone2
-   6:[\055] -> date#4.zone#1.zone2
-   13:[A-Z] -> date#4.zone#1.out
-   13:[A-Z] -> date#4.zone#1.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 118 = date#4.zone#1.zone2
-   8:[0-9] -> date#4.zone#1.out
-   8:[0-9] -> date#4.zone#1.zone2
-   13:[A-Z] -> date#4.zone#1.out
-   17:[a-z] -> date#4.zone#1.out
-   13:[A-Z] -> date#4.zone#1.zone2
-   17:[a-z] -> date#4.zone#1.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 119 = date#4.zone#1.out
-  [(epsilon)] -> date#4.#23
-  Epsilon closure :
-    (self)
-    date#4.#23
-
-NFA state 120 = date#4.#24
-   0:[\t ] -> date#4.after_timezone_1
-  Epsilon closure :
-    (self)
-
-NFA state 121 = date#4.zone#2.in
-   5:[+] -> date#4.zone#2.zone2
-   6:[\055] -> date#4.zone#2.zone2
-   13:[A-Z] -> date#4.zone#2.out
-   13:[A-Z] -> date#4.zone#2.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 122 = date#4.zone#2.zone2
-   8:[0-9] -> date#4.zone#2.out
-   8:[0-9] -> date#4.zone#2.zone2
-   13:[A-Z] -> date#4.zone#2.out
-   17:[a-z] -> date#4.zone#2.out
-   13:[A-Z] -> date#4.zone#2.zone2
-   17:[a-z] -> date#4.zone#2.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 123 = date#4.zone#2.out
-  [(epsilon)] -> date#4.#24
-  Epsilon closure :
-    (self)
-    date#4.#24
-
-NFA state 124 = date#4.#25
-   8:[0-9] -> date#4.#26
-  Epsilon closure :
-    (self)
-
-NFA state 125 = date#4.#26
-   8:[0-9] -> date#4.#27
-  Epsilon closure :
-    (self)
-
-NFA state 126 = date#4.#27
-   8:[0-9] -> date#4.after_year_before_zone
-  Epsilon closure :
-    (self)
-
-NFA state 127 = date#4.after_year_before_zone
-   0:[\t ] -> date#4.after_year_before_zone
-  [(epsilon)] -> date#4.zone#3.in
-  [(epsilon)] -> date#4.zone#4.in
-  Epsilon closure :
-    (self)
-    date#4.zone#3.in
-    date#4.zone#4.in
-
-NFA state 128 = date#4.zone#3.in
-   5:[+] -> date#4.zone#3.zone2
-   6:[\055] -> date#4.zone#3.zone2
-   13:[A-Z] -> date#4.zone#3.out
-   13:[A-Z] -> date#4.zone#3.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 129 = date#4.zone#3.zone2
-   8:[0-9] -> date#4.zone#3.out
-   8:[0-9] -> date#4.zone#3.zone2
-   13:[A-Z] -> date#4.zone#3.out
-   17:[a-z] -> date#4.zone#3.out
-   13:[A-Z] -> date#4.zone#3.zone2
-   17:[a-z] -> date#4.zone#3.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 130 = date#4.zone#3.out
-  [(epsilon)] -> date#4.after_timezone_after_year
-  Epsilon closure :
-    (self)
-    #3
-    date#4.after_timezone_after_year
-    date#4.out
-
-NFA state 131 = date#4.#28
-   0:[\t ] -> date#4.after_timezone_after_year_1
-  Epsilon closure :
-    (self)
-
-NFA state 132 = date#4.zone#4.in
-   5:[+] -> date#4.zone#4.zone2
-   6:[\055] -> date#4.zone#4.zone2
-   13:[A-Z] -> date#4.zone#4.out
-   13:[A-Z] -> date#4.zone#4.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 133 = date#4.zone#4.zone2
-   8:[0-9] -> date#4.zone#4.out
-   8:[0-9] -> date#4.zone#4.zone2
-   13:[A-Z] -> date#4.zone#4.out
-   17:[a-z] -> date#4.zone#4.out
-   13:[A-Z] -> date#4.zone#4.zone2
-   17:[a-z] -> date#4.zone#4.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 134 = date#4.zone#4.out
-  [(epsilon)] -> date#4.#28
-  Epsilon closure :
-    (self)
-    date#4.#28
-
-NFA state 135 = date#4.after_timezone_after_year_1
-   0:[\t ] -> date#4.after_timezone_after_year_1
-  [(epsilon)] -> date#4.zone#5.in
-  Epsilon closure :
-    (self)
-    date#4.zone#5.in
-
-NFA state 136 = date#4.zone#5.in
-   5:[+] -> date#4.zone#5.zone2
-   6:[\055] -> date#4.zone#5.zone2
-   13:[A-Z] -> date#4.zone#5.out
-   13:[A-Z] -> date#4.zone#5.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 137 = date#4.zone#5.zone2
-   8:[0-9] -> date#4.zone#5.out
-   8:[0-9] -> date#4.zone#5.zone2
-   13:[A-Z] -> date#4.zone#5.out
-   17:[a-z] -> date#4.zone#5.out
-   13:[A-Z] -> date#4.zone#5.zone2
-   17:[a-z] -> date#4.zone#5.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 138 = date#4.zone#5.out
-  [(epsilon)] -> date#4.after_timezone_after_year
-  Epsilon closure :
-    (self)
-    #3
-    date#4.after_timezone_after_year
-    date#4.out
-
-NFA state 139 = date#4.after_timezone_after_year
-   0:[\t ] -> date#4.after_timezone_after_year
-  [(epsilon)] -> date#4.out
-  Epsilon closure :
-    (self)
-    #3
-    date#4.out
-
-NFA state 140 = date#4.after_timezone_1
-   0:[\t ] -> date#4.after_timezone_1
-  [(epsilon)] -> date#4.zone#6.in
-  Epsilon closure :
-    (self)
-    date#4.zone#6.in
-
-NFA state 141 = date#4.#29
-   0:[\t ] -> date#4.after_timezone
-  Epsilon closure :
-    (self)
-
-NFA state 142 = date#4.zone#6.in
-   5:[+] -> date#4.zone#6.zone2
-   6:[\055] -> date#4.zone#6.zone2
-   13:[A-Z] -> date#4.zone#6.out
-   13:[A-Z] -> date#4.zone#6.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 143 = date#4.zone#6.zone2
-   8:[0-9] -> date#4.zone#6.out
-   8:[0-9] -> date#4.zone#6.zone2
-   13:[A-Z] -> date#4.zone#6.out
-   17:[a-z] -> date#4.zone#6.out
-   13:[A-Z] -> date#4.zone#6.zone2
-   17:[a-z] -> date#4.zone#6.zone2
-  Epsilon closure :
-    (self)
-
-NFA state 144 = date#4.zone#6.out
-  [(epsilon)] -> date#4.#29
-  Epsilon closure :
-    (self)
-    date#4.#29
-
-NFA state 145 = date#4.after_timezone
-   0:[\t ] -> date#4.after_timezone
-   8:[0-9] -> date#4.#30
-  Epsilon closure :
-    (self)
-
-NFA state 146 = date#4.#30
-   8:[0-9] -> date#4.#31
-  Epsilon closure :
-    (self)
-
-NFA state 147 = date#4.#31
-   8:[0-9] -> date#4.#32
-  Epsilon closure :
-    (self)
-
-NFA state 148 = date#4.#32
-   8:[0-9] -> date#4.after_year
-  Epsilon closure :
-    (self)
-
-NFA state 149 = date#4.after_year
-   0:[\t ] -> date#4.after_year
-  [(epsilon)] -> date#4.out
-  Epsilon closure :
-    (self)
-    #3
-    date#4.out
-
-NFA state 150 = date#4.out
-  [(epsilon)] -> #3
-  Epsilon closure :
-    (self)
-    #3
-
-NFA state 151 = #4
-   1:[\n] -> #5
-  Epsilon closure :
-    (self)
-
-NFA state 152 = #5
-  Tags : FROMCHECK_PASS
-  Epsilon closure :
-    (self)
-
---------------------------------
-DFA structure before compression
---------------------------------
-DFA state 0
-  NFA states :
-    in
-    email#1.in
-    angled_email#2.in
-    before_date
-    date#3.in
-    date#4.in
-
-  Forward route :
-   (START)->(HERE)
-  Transitions :
-    0:[\t ] -> 1
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    10:[<] -> 4
-    12:[@] -> 5
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-
-DFA state 1
-  NFA states :
-    in
-    email#1.in
-    angled_email#2.in
-    before_date
-    date#3.in
-    date#3.before_weekday
-    date#4.in
-    date#4.before_weekday
-
-  Forward route : (from state 0)
-   (START)->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 1
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    10:[<] -> 4
-    12:[@] -> 5
-    13:[A-Z] -> 6
-    16:[_] -> 2
-    17:[a-z] -> 2
-
-DFA state 2
-  NFA states :
-    email#1.in
-    email#1.before_at
-    email#1.out
-    before_date
-    date#3.in
-    date#4.in
-
-  Forward route : (from state 0)
-   (START)->3:[!#-'*/=?^`{-~]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-
-DFA state 3
-  NFA states :
-    email#1.quoted_before_at
-
-  Forward route : (from state 0)
-   (START)->4:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 3
-    3:[!#-'*/=?^`{-~] -> 3
-    4:["] -> 9
-    5:[+] -> 3
-    6:[\055] -> 3
-    7:[.] -> 3
-    8:[0-9] -> 3
-    9:[:] -> 3
-    10:[<] -> 3
-    11:[>] -> 3
-    12:[@] -> 3
-    13:[A-Z] -> 3
-    16:[_] -> 3
-    17:[a-z] -> 3
-
-DFA state 4
-  NFA states :
-    angled_email#2.in_angles
-    angled_email#2.email#1.in
-
-  Forward route : (from state 0)
-   (START)->10:[<]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 10
-    4:["] -> 11
-    5:[+] -> 10
-    6:[\055] -> 10
-    7:[.] -> 10
-    8:[0-9] -> 10
-    12:[@] -> 12
-    13:[A-Z] -> 10
-    16:[_] -> 10
-    17:[a-z] -> 10
-
-DFA state 5
-  NFA states :
-    email#1.domain_route
-
-  Forward route : (from state 0)
-   (START)->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 5
-    7:[.] -> 5
-    8:[0-9] -> 5
-    9:[:] -> 13
-    13:[A-Z] -> 5
-    16:[_] -> 5
-    17:[a-z] -> 5
-
-DFA state 6
-  NFA states :
-    email#1.in
-    email#1.before_at
-    email#1.out
-    before_date
-    date#3.in
-    date#3.#1
-    date#4.in
-    date#4.#1
-
-  Forward route : (from state 1)
-   (START)->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 14
-
-DFA state 7
-  NFA states :
-    date#3.in
-    date#3.before_weekday
-    date#4.in
-    date#4.before_weekday
-
-  Forward route : (from state 2)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    13:[A-Z] -> 15
-
-DFA state 8
-  NFA states :
-    email#1.domain_route
-    email#1.start_of_domain
-
-  Forward route : (from state 2)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 16
-    7:[.] -> 16
-    8:[0-9] -> 16
-    9:[:] -> 13
-    13:[A-Z] -> 16
-    14:[[] -> 17
-    16:[_] -> 16
-    17:[a-z] -> 16
-
-DFA state 9
-  NFA states :
-    email#1.before_at
-    email#1.out
-    before_date
-    date#3.in
-    date#4.in
-
-  Forward route : (from state 3)
-   (START)->4:["]->4:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 9
-    4:["] -> 3
-    5:[+] -> 9
-    6:[\055] -> 9
-    7:[.] -> 9
-    8:[0-9] -> 9
-    12:[@] -> 18
-    13:[A-Z] -> 9
-    16:[_] -> 9
-    17:[a-z] -> 9
-
-DFA state 10
-  NFA states :
-    angled_email#2.email#1.in
-    angled_email#2.email#1.before_at
-    angled_email#2.email#1.out
-    angled_email#2.before_gt
-
-  Forward route : (from state 4)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 10
-    4:["] -> 11
-    5:[+] -> 10
-    6:[\055] -> 10
-    7:[.] -> 10
-    8:[0-9] -> 10
-    11:[>] -> 19
-    12:[@] -> 20
-    13:[A-Z] -> 10
-    16:[_] -> 10
-    17:[a-z] -> 10
-
-DFA state 11
-  NFA states :
-    angled_email#2.email#1.quoted_before_at
-
-  Forward route : (from state 4)
-   (START)->10:[<]->4:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 11
-    3:[!#-'*/=?^`{-~] -> 11
-    4:["] -> 21
-    5:[+] -> 11
-    6:[\055] -> 11
-    7:[.] -> 11
-    8:[0-9] -> 11
-    9:[:] -> 11
-    10:[<] -> 11
-    11:[>] -> 11
-    12:[@] -> 11
-    13:[A-Z] -> 11
-    16:[_] -> 11
-    17:[a-z] -> 11
-
-DFA state 12
-  NFA states :
-    angled_email#2.email#1.domain_route
-
-  Forward route : (from state 4)
-   (START)->10:[<]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 12
-    7:[.] -> 12
-    8:[0-9] -> 12
-    9:[:] -> 22
-    13:[A-Z] -> 12
-    16:[_] -> 12
-    17:[a-z] -> 12
-
-DFA state 13
-  NFA states :
-    email#1.in
-
-  Forward route : (from state 5)
-   (START)->12:[@]->9:[:]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 5
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-
-DFA state 14
-  NFA states :
-    email#1.in
-    email#1.before_at
-    email#1.out
-    before_date
-    date#3.in
-    date#3.#2
-    date#4.in
-    date#4.#2
-
-  Forward route : (from state 6)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 23
-
-DFA state 15
-  NFA states :
-    date#3.#1
-    date#4.#1
-
-  Forward route : (from state 7)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    17:[a-z] -> 24
-
-DFA state 16
-  NFA states :
-    email#1.domain_route
-    email#1.after_at
-
-  Forward route : (from state 8)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 25
-    7:[.] -> 25
-    8:[0-9] -> 25
-    9:[:] -> 13
-    13:[A-Z] -> 25
-    16:[_] -> 25
-    17:[a-z] -> 25
-
-DFA state 17
-  NFA states :
-    email#1.dotted_quad
-
-  Forward route : (from state 8)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->14:[[]->(HERE)
-  Transitions :
-    7:[.] -> 17
-    8:[0-9] -> 17
-    15:[]] -> 26
-
-DFA state 18
-  NFA states :
-    email#1.start_of_domain
-
-  Forward route : (from state 9)
-   (START)->4:["]->4:["]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 27
-    7:[.] -> 27
-    8:[0-9] -> 27
-    13:[A-Z] -> 27
-    14:[[] -> 17
-    16:[_] -> 27
-    17:[a-z] -> 27
-
-DFA state 19
-  NFA states :
-    angled_email#2.out
-    before_date
-    date#3.in
-    date#4.in
-
-  Forward route : (from state 10)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->11:[>]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-
-DFA state 20
-  NFA states :
-    angled_email#2.email#1.domain_route
-    angled_email#2.email#1.start_of_domain
-
-  Forward route : (from state 10)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 28
-    7:[.] -> 28
-    8:[0-9] -> 28
-    9:[:] -> 22
-    13:[A-Z] -> 28
-    14:[[] -> 29
-    16:[_] -> 28
-    17:[a-z] -> 28
-
-DFA state 21
-  NFA states :
-    angled_email#2.email#1.before_at
-    angled_email#2.email#1.out
-    angled_email#2.before_gt
-
-  Forward route : (from state 11)
-   (START)->10:[<]->4:["]->4:["]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 21
-    4:["] -> 11
-    5:[+] -> 21
-    6:[\055] -> 21
-    7:[.] -> 21
-    8:[0-9] -> 21
-    11:[>] -> 19
-    12:[@] -> 30
-    13:[A-Z] -> 21
-    16:[_] -> 21
-    17:[a-z] -> 21
-
-DFA state 22
-  NFA states :
-    angled_email#2.email#1.in
-
-  Forward route : (from state 12)
-   (START)->10:[<]->12:[@]->9:[:]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 10
-    4:["] -> 11
-    5:[+] -> 10
-    6:[\055] -> 10
-    7:[.] -> 10
-    8:[0-9] -> 10
-    12:[@] -> 12
-    13:[A-Z] -> 10
-    16:[_] -> 10
-    17:[a-z] -> 10
-
-DFA state 23
-  NFA states :
-    email#1.in
-    email#1.before_at
-    email#1.out
-    before_date
-    date#3.in
-    date#3.#3
-    date#4.in
-    date#4.#3
-
-  Forward route : (from state 14)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 31
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-
-DFA state 24
-  NFA states :
-    date#3.#2
-    date#4.#2
-
-  Forward route : (from state 15)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    17:[a-z] -> 32
-
-DFA state 25
-  NFA states :
-    email#1.domain_route
-    email#1.after_at
-    email#1.out
-    before_date
-    date#3.in
-    date#4.in
-
-  Forward route : (from state 16)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    6:[\055] -> 25
-    7:[.] -> 25
-    8:[0-9] -> 25
-    9:[:] -> 13
-    13:[A-Z] -> 25
-    16:[_] -> 25
-    17:[a-z] -> 25
-
-DFA state 26
-  NFA states :
-    email#1.out
-    before_date
-    date#3.in
-    date#4.in
-
-  Forward route : (from state 17)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->14:[[]->15:[]]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-
-DFA state 27
-  NFA states :
-    email#1.after_at
-
-  Forward route : (from state 18)
-   (START)->4:["]->4:["]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 33
-    7:[.] -> 33
-    8:[0-9] -> 33
-    13:[A-Z] -> 33
-    16:[_] -> 33
-    17:[a-z] -> 33
-
-DFA state 28
-  NFA states :
-    angled_email#2.email#1.domain_route
-    angled_email#2.email#1.after_at
-
-  Forward route : (from state 20)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 34
-    7:[.] -> 34
-    8:[0-9] -> 34
-    9:[:] -> 22
-    13:[A-Z] -> 34
-    16:[_] -> 34
-    17:[a-z] -> 34
-
-DFA state 29
-  NFA states :
-    angled_email#2.email#1.dotted_quad
-
-  Forward route : (from state 20)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->14:[[]->(HERE)
-  Transitions :
-    7:[.] -> 29
-    8:[0-9] -> 29
-    15:[]] -> 35
-
-DFA state 30
-  NFA states :
-    angled_email#2.email#1.start_of_domain
-
-  Forward route : (from state 21)
-   (START)->10:[<]->4:["]->4:["]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 36
-    7:[.] -> 36
-    8:[0-9] -> 36
-    13:[A-Z] -> 36
-    14:[[] -> 29
-    16:[_] -> 36
-    17:[a-z] -> 36
-
-DFA state 31
-  NFA states :
-    date#3.in
-    date#3.before_weekday
-    date#3.after_weekday
-    date#4.in
-    date#4.before_weekday
-    date#4.after_weekday
-
-  Forward route : (from state 23)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 31
-    13:[A-Z] -> 37
-
-DFA state 32
-  NFA states :
-    date#3.#3
-    date#4.#3
-
-  Forward route : (from state 24)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 38
-
-DFA state 33
-  NFA states :
-    email#1.after_at
-    email#1.out
-    before_date
-    date#3.in
-    date#4.in
-
-  Forward route : (from state 27)
-   (START)->4:["]->4:["]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    6:[\055] -> 33
-    7:[.] -> 33
-    8:[0-9] -> 33
-    13:[A-Z] -> 33
-    16:[_] -> 33
-    17:[a-z] -> 33
-
-DFA state 34
-  NFA states :
-    angled_email#2.email#1.domain_route
-    angled_email#2.email#1.after_at
-    angled_email#2.email#1.out
-    angled_email#2.before_gt
-
-  Forward route : (from state 28)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 34
-    7:[.] -> 34
-    8:[0-9] -> 34
-    9:[:] -> 22
-    11:[>] -> 19
-    13:[A-Z] -> 34
-    16:[_] -> 34
-    17:[a-z] -> 34
-
-DFA state 35
-  NFA states :
-    angled_email#2.email#1.out
-    angled_email#2.before_gt
-
-  Forward route : (from state 29)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->14:[[]->15:[]]->(HERE)
-  Transitions :
-    11:[>] -> 19
-
-DFA state 36
-  NFA states :
-    angled_email#2.email#1.after_at
-
-  Forward route : (from state 30)
-   (START)->10:[<]->4:["]->4:["]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 39
-    7:[.] -> 39
-    8:[0-9] -> 39
-    13:[A-Z] -> 39
-    16:[_] -> 39
-    17:[a-z] -> 39
-
-DFA state 37
-  NFA states :
-    date#3.#1
-    date#3.#4
-    date#4.#1
-    date#4.#4
-
-  Forward route : (from state 31)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    17:[a-z] -> 40
-
-DFA state 38
-  NFA states :
-    date#3.after_weekday
-    date#4.after_weekday
-
-  Forward route : (from state 32)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 38
-    13:[A-Z] -> 41
-
-DFA state 39
-  NFA states :
-    angled_email#2.email#1.after_at
-    angled_email#2.email#1.out
-    angled_email#2.before_gt
-
-  Forward route : (from state 36)
-   (START)->10:[<]->4:["]->4:["]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 39
-    7:[.] -> 39
-    8:[0-9] -> 39
-    11:[>] -> 19
-    13:[A-Z] -> 39
-    16:[_] -> 39
-    17:[a-z] -> 39
-
-DFA state 40
-  NFA states :
-    date#3.#2
-    date#3.#5
-    date#4.#2
-    date#4.#5
-
-  Forward route : (from state 37)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    17:[a-z] -> 42
-
-DFA state 41
-  NFA states :
-    date#3.#4
-    date#4.#4
-
-  Forward route : (from state 38)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    17:[a-z] -> 43
-
-DFA state 42
-  NFA states :
-    date#3.#3
-    date#3.#6
-    date#4.#3
-    date#4.#6
-
-  Forward route : (from state 40)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 44
-
-DFA state 43
-  NFA states :
-    date#3.#5
-    date#4.#5
-
-  Forward route : (from state 41)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    17:[a-z] -> 45
-
-DFA state 44
-  NFA states :
-    date#3.after_weekday
-    date#3.after_month
-    date#4.after_weekday
-    date#4.after_month
-
-  Forward route : (from state 42)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 44
-    8:[0-9] -> 46
-    13:[A-Z] -> 41
-
-DFA state 45
-  NFA states :
-    date#3.#6
-    date#4.#6
-
-  Forward route : (from state 43)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 47
-
-DFA state 46
-  NFA states :
-    date#3.#7
-    date#3.#8
-    date#4.#7
-    date#4.#8
-
-  Forward route : (from state 44)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 48
-    8:[0-9] -> 49
-
-DFA state 47
-  NFA states :
-    date#3.after_month
-    date#4.after_month
-
-  Forward route : (from state 45)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 47
-    8:[0-9] -> 46
-
-DFA state 48
-  NFA states :
-    date#3.after_day
-    date#4.after_day
-
-  Forward route : (from state 46)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 48
-    8:[0-9] -> 50
-
-DFA state 49
-  NFA states :
-    date#3.#9
-    date#4.#9
-
-  Forward route : (from state 46)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 48
-
-DFA state 50
-  NFA states :
-    date#3.#10
-    date#3.#18
-    date#4.#10
-    date#4.#18
-
-  Forward route : (from state 48)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 51
-
-DFA state 51
-  NFA states :
-    date#3.#11
-    date#3.#19
-    date#4.#11
-    date#4.#19
-
-  Forward route : (from state 50)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    9:[:] -> 52
-
-DFA state 52
-  NFA states :
-    date#3.#12
-    date#3.#20
-    date#4.#12
-    date#4.#20
-
-  Forward route : (from state 51)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->(HERE)
-  Transitions :
-    8:[0-9] -> 53
-
-DFA state 53
-  NFA states :
-    date#3.#13
-    date#3.#21
-    date#4.#13
-    date#4.#21
-
-  Forward route : (from state 52)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 54
-
-DFA state 54
-  NFA states :
-    date#3.#14
-    date#3.#22
-    date#4.#14
-    date#4.#22
-
-  Forward route : (from state 53)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 55
-    9:[:] -> 56
-
-DFA state 55
-  NFA states :
-    date#3.after_time
-    date#3.zone#1.in
-    date#3.zone#2.in
-    date#3.after_timezone
-    date#4.after_time
-    date#4.zone#1.in
-    date#4.zone#2.in
-    date#4.after_timezone
-
-  Forward route : (from state 54)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 55
-    5:[+] -> 57
-    6:[\055] -> 57
-    8:[0-9] -> 58
-    13:[A-Z] -> 59
-
-DFA state 56
-  NFA states :
-    date#3.#15
-    date#4.#15
-
-  Forward route : (from state 54)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->9:[:]->(HERE)
-  Transitions :
-    8:[0-9] -> 60
-
-DFA state 57
-  NFA states :
-    date#3.zone#1.zone2
-    date#3.zone#2.zone2
-    date#4.zone#1.zone2
-    date#4.zone#2.zone2
-
-  Forward route : (from state 55)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 59
-    13:[A-Z] -> 59
-    17:[a-z] -> 59
-
-DFA state 58
-  NFA states :
-    date#3.#25
-    date#3.#30
-    date#4.#25
-    date#4.#30
-
-  Forward route : (from state 55)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 61
-
-DFA state 59
-  NFA states :
-    date#3.#23
-    date#3.zone#1.zone2
-    date#3.zone#1.out
-    date#3.#24
-    date#3.zone#2.zone2
-    date#3.zone#2.out
-    date#4.#23
-    date#4.zone#1.zone2
-    date#4.zone#1.out
-    date#4.#24
-    date#4.zone#2.zone2
-    date#4.zone#2.out
-
-  Forward route : (from state 55)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 62
-    8:[0-9] -> 59
-    13:[A-Z] -> 59
-    17:[a-z] -> 59
-
-DFA state 60
-  NFA states :
-    date#3.#16
-    date#4.#16
-
-  Forward route : (from state 56)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 63
-
-DFA state 61
-  NFA states :
-    date#3.#26
-    date#3.#31
-    date#4.#26
-    date#4.#31
-
-  Forward route : (from state 58)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 64
-
-DFA state 62
-  NFA states :
-    date#3.after_timezone_1
-    date#3.zone#6.in
-    date#3.after_timezone
-    date#4.after_timezone_1
-    date#4.zone#6.in
-    date#4.after_timezone
-
-  Forward route : (from state 59)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 62
-    5:[+] -> 65
-    6:[\055] -> 65
-    8:[0-9] -> 66
-    13:[A-Z] -> 67
-
-DFA state 63
-  NFA states :
-    date#3.#17
-    date#4.#17
-
-  Forward route : (from state 60)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 55
-
-DFA state 64
-  NFA states :
-    date#3.#27
-    date#3.#32
-    date#4.#27
-    date#4.#32
-
-  Forward route : (from state 61)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 68
-
-DFA state 65
-  NFA states :
-    date#3.zone#6.zone2
-    date#4.zone#6.zone2
-
-  Forward route : (from state 62)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 67
-    13:[A-Z] -> 67
-    17:[a-z] -> 67
-
-DFA state 66
-  NFA states :
-    date#3.#30
-    date#4.#30
-
-  Forward route : (from state 62)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 69
-
-DFA state 67
-  NFA states :
-    date#3.#29
-    date#3.zone#6.zone2
-    date#3.zone#6.out
-    date#4.#29
-    date#4.zone#6.zone2
-    date#4.zone#6.out
-
-  Forward route : (from state 62)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 70
-    8:[0-9] -> 67
-    13:[A-Z] -> 67
-    17:[a-z] -> 67
-
-DFA state 68
-  NFA states :
-    #1
-    date#3.after_year_before_zone
-    date#3.zone#3.in
-    date#3.zone#4.in
-    date#3.after_year
-    date#3.out
-    #3
-    date#4.after_year_before_zone
-    date#4.zone#3.in
-    date#4.zone#4.in
-    date#4.after_year
-    date#4.out
-
-  Forward route : (from state 64)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 68
-    1:[\n] -> 71
-    2:[\r] -> 72
-    5:[+] -> 73
-    6:[\055] -> 73
-    13:[A-Z] -> 74
-
-DFA state 69
-  NFA states :
-    date#3.#31
-    date#4.#31
-
-  Forward route : (from state 66)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 75
-
-DFA state 70
-  NFA states :
-    date#3.after_timezone
-    date#4.after_timezone
-
-  Forward route : (from state 67)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->13:[A-Z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 70
-    8:[0-9] -> 66
-
-DFA state 71
-  NFA states :
-    #2
-
-  Forward route : (from state 68)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->1:[\n]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    FROMCHECK_PASS
-  Attributes for <(DEFAULT)> : FROMCHECK_PASS
-
-DFA state 72
-  NFA states :
-    #4
-
-  Forward route : (from state 68)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->2:[\r]->(HERE)
-  Transitions :
-    1:[\n] -> 76
-
-DFA state 73
-  NFA states :
-    date#3.zone#3.zone2
-    date#3.zone#4.zone2
-    date#4.zone#3.zone2
-    date#4.zone#4.zone2
-
-  Forward route : (from state 68)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 74
-    13:[A-Z] -> 74
-    17:[a-z] -> 74
-
-DFA state 74
-  NFA states :
-    #1
-    date#3.zone#3.zone2
-    date#3.zone#3.out
-    date#3.#28
-    date#3.zone#4.zone2
-    date#3.zone#4.out
-    date#3.after_timezone_after_year
-    date#3.out
-    #3
-    date#4.zone#3.zone2
-    date#4.zone#3.out
-    date#4.#28
-    date#4.zone#4.zone2
-    date#4.zone#4.out
-    date#4.after_timezone_after_year
-    date#4.out
-
-  Forward route : (from state 68)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 77
-    1:[\n] -> 71
-    2:[\r] -> 72
-    8:[0-9] -> 74
-    13:[A-Z] -> 74
-    17:[a-z] -> 74
-
-DFA state 75
-  NFA states :
-    date#3.#32
-    date#4.#32
-
-  Forward route : (from state 69)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 78
-
-DFA state 76
-  NFA states :
-    #5
-
-  Forward route : (from state 72)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->2:[\r]->1:[\n]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    FROMCHECK_PASS
-  Attributes for <(DEFAULT)> : FROMCHECK_PASS
-
-DFA state 77
-  NFA states :
-    #1
-    date#3.after_timezone_after_year_1
-    date#3.zone#5.in
-    date#3.after_timezone_after_year
-    date#3.out
-    #3
-    date#4.after_timezone_after_year_1
-    date#4.zone#5.in
-    date#4.after_timezone_after_year
-    date#4.out
-
-  Forward route : (from state 74)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 77
-    1:[\n] -> 71
-    2:[\r] -> 72
-    5:[+] -> 79
-    6:[\055] -> 79
-    13:[A-Z] -> 80
-
-DFA state 78
-  NFA states :
-    #1
-    date#3.after_year
-    date#3.out
-    #3
-    date#4.after_year
-    date#4.out
-
-  Forward route : (from state 75)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 78
-    1:[\n] -> 71
-    2:[\r] -> 72
-
-DFA state 79
-  NFA states :
-    date#3.zone#5.zone2
-    date#4.zone#5.zone2
-
-  Forward route : (from state 77)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->0:[\t ]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 80
-    13:[A-Z] -> 80
-    17:[a-z] -> 80
-
-DFA state 80
-  NFA states :
-    #1
-    date#3.zone#5.zone2
-    date#3.zone#5.out
-    date#3.after_timezone_after_year
-    date#3.out
-    #3
-    date#4.zone#5.zone2
-    date#4.zone#5.out
-    date#4.after_timezone_after_year
-    date#4.out
-
-  Forward route : (from state 77)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 81
-    1:[\n] -> 71
-    2:[\r] -> 72
-    8:[0-9] -> 80
-    13:[A-Z] -> 80
-    17:[a-z] -> 80
-
-DFA state 81
-  NFA states :
-    #1
-    date#3.after_timezone_after_year
-    date#3.out
-    #3
-    date#4.after_timezone_after_year
-    date#4.out
-
-  Forward route : (from state 80)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->0:[\t ]->13:[A-Z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 81
-    1:[\n] -> 71
-    2:[\r] -> 72
-
-
-Entry states in DFA:
-Entry <(ONLY ENTRY)> : 0
-Searching for dead states...
-(no dead states found)
-
------------------------------
------- COMPRESSING DFA ------
------------------------------
-Old DFA state 0 becomes 0
-Old DFA state 1 becomes 1
-Old DFA state 2 becomes 2
-Old DFA state 3 becomes 3
-Old DFA state 4 becomes 4
-Old DFA state 5 becomes 5
-Old DFA state 6 becomes 6
-Old DFA state 7 becomes 7
-Old DFA state 8 becomes 8
-Old DFA state 9 becomes 9
-Old DFA state 10 becomes 10
-Old DFA state 11 becomes 11
-Old DFA state 12 becomes 12
-Old DFA state 13 becomes 13
-Old DFA state 14 becomes 14
-Old DFA state 15 becomes 15
-Old DFA state 16 becomes 16
-Old DFA state 17 becomes 17
-Old DFA state 18 becomes 18
-Old DFA state 19 becomes 19
-Old DFA state 20 becomes 20
-Old DFA state 21 becomes 21
-Old DFA state 22 becomes 4 (formerly 4)
-Old DFA state 23 becomes 22
-Old DFA state 24 becomes 23
-Old DFA state 25 becomes 24
-Old DFA state 26 becomes 19 (formerly 19)
-Old DFA state 27 becomes 25
-Old DFA state 28 becomes 26
-Old DFA state 29 becomes 27
-Old DFA state 30 becomes 28
-Old DFA state 31 becomes 29
-Old DFA state 32 becomes 30
-Old DFA state 33 becomes 31
-Old DFA state 34 becomes 32
-Old DFA state 35 becomes 33
-Old DFA state 36 becomes 34
-Old DFA state 37 becomes 35
-Old DFA state 38 becomes 36
-Old DFA state 39 becomes 37
-Old DFA state 40 becomes 38
-Old DFA state 41 becomes 39
-Old DFA state 42 becomes 40
-Old DFA state 43 becomes 41
-Old DFA state 44 becomes 42
-Old DFA state 45 becomes 43
-Old DFA state 46 becomes 44
-Old DFA state 47 becomes 45
-Old DFA state 48 becomes 46
-Old DFA state 49 becomes 47
-Old DFA state 50 becomes 48
-Old DFA state 51 becomes 49
-Old DFA state 52 becomes 50
-Old DFA state 53 becomes 51
-Old DFA state 54 becomes 52
-Old DFA state 55 becomes 53
-Old DFA state 56 becomes 54
-Old DFA state 57 becomes 55
-Old DFA state 58 becomes 56
-Old DFA state 59 becomes 57
-Old DFA state 60 becomes 58
-Old DFA state 61 becomes 59
-Old DFA state 62 becomes 60
-Old DFA state 63 becomes 61
-Old DFA state 64 becomes 62
-Old DFA state 65 becomes 63
-Old DFA state 66 becomes 64
-Old DFA state 67 becomes 65
-Old DFA state 68 becomes 66
-Old DFA state 69 becomes 67
-Old DFA state 70 becomes 68
-Old DFA state 71 becomes 69
-Old DFA state 72 becomes 70
-Old DFA state 73 becomes 71
-Old DFA state 74 becomes 72
-Old DFA state 75 becomes 73
-Old DFA state 76 becomes 69 (formerly 71)
-Old DFA state 77 becomes 74
-Old DFA state 78 becomes 75
-Old DFA state 79 becomes 76
-Old DFA state 80 becomes 77
-Old DFA state 81 becomes 75 (formerly 78)
-Entry <(ONLY ENTRY)>, formerly state 0, now state 0
--------------------------------
-DFA structure after compression
--------------------------------
-DFA state 0
-  Forward route :
-   (START)->(HERE)
-  Transitions :
-    0:[\t ] -> 1
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    10:[<] -> 4
-    12:[@] -> 5
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-
-DFA state 1
-  Forward route : (from state 0)
-   (START)->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 1
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    10:[<] -> 4
-    12:[@] -> 5
-    13:[A-Z] -> 6
-    16:[_] -> 2
-    17:[a-z] -> 2
-  Use state 0 as basis (1 fixups)
-
-DFA state 2
-  Forward route : (from state 0)
-   (START)->3:[!#-'*/=?^`{-~]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-  Use state 0 as basis (3 fixups)
-
-DFA state 3
-  Forward route : (from state 0)
-   (START)->4:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 3
-    3:[!#-'*/=?^`{-~] -> 3
-    4:["] -> 9
-    5:[+] -> 3
-    6:[\055] -> 3
-    7:[.] -> 3
-    8:[0-9] -> 3
-    9:[:] -> 3
-    10:[<] -> 3
-    11:[>] -> 3
-    12:[@] -> 3
-    13:[A-Z] -> 3
-    16:[_] -> 3
-    17:[a-z] -> 3
-
-DFA state 4
-  Forward route : (from state 0)
-   (START)->10:[<]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 10
-    4:["] -> 11
-    5:[+] -> 10
-    6:[\055] -> 10
-    7:[.] -> 10
-    8:[0-9] -> 10
-    12:[@] -> 12
-    13:[A-Z] -> 10
-    16:[_] -> 10
-    17:[a-z] -> 10
-
-DFA state 5
-  Forward route : (from state 0)
-   (START)->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 5
-    7:[.] -> 5
-    8:[0-9] -> 5
-    9:[:] -> 13
-    13:[A-Z] -> 5
-    16:[_] -> 5
-    17:[a-z] -> 5
-
-DFA state 6
-  Forward route : (from state 1)
-   (START)->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 14
-  Use state 0 as basis (4 fixups)
-
-DFA state 7
-  Forward route : (from state 2)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    13:[A-Z] -> 15
-
-DFA state 8
-  Forward route : (from state 2)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 16
-    7:[.] -> 16
-    8:[0-9] -> 16
-    9:[:] -> 13
-    13:[A-Z] -> 16
-    14:[[] -> 17
-    16:[_] -> 16
-    17:[a-z] -> 16
-
-DFA state 9
-  Forward route : (from state 3)
-   (START)->4:["]->4:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 9
-    4:["] -> 3
-    5:[+] -> 9
-    6:[\055] -> 9
-    7:[.] -> 9
-    8:[0-9] -> 9
-    12:[@] -> 18
-    13:[A-Z] -> 9
-    16:[_] -> 9
-    17:[a-z] -> 9
-
-DFA state 10
-  Forward route : (from state 4)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 10
-    4:["] -> 11
-    5:[+] -> 10
-    6:[\055] -> 10
-    7:[.] -> 10
-    8:[0-9] -> 10
-    11:[>] -> 19
-    12:[@] -> 20
-    13:[A-Z] -> 10
-    16:[_] -> 10
-    17:[a-z] -> 10
-  Use state 4 as basis (2 fixups)
-
-DFA state 11
-  Forward route : (from state 4)
-   (START)->10:[<]->4:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 11
-    3:[!#-'*/=?^`{-~] -> 11
-    4:["] -> 21
-    5:[+] -> 11
-    6:[\055] -> 11
-    7:[.] -> 11
-    8:[0-9] -> 11
-    9:[:] -> 11
-    10:[<] -> 11
-    11:[>] -> 11
-    12:[@] -> 11
-    13:[A-Z] -> 11
-    16:[_] -> 11
-    17:[a-z] -> 11
-
-DFA state 12
-  Forward route : (from state 4)
-   (START)->10:[<]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 12
-    7:[.] -> 12
-    8:[0-9] -> 12
-    9:[:] -> 4
-    13:[A-Z] -> 12
-    16:[_] -> 12
-    17:[a-z] -> 12
-
-DFA state 13
-  Forward route : (from state 5)
-   (START)->12:[@]->9:[:]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 5
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-  Use state 0 as basis (2 fixups)
-
-DFA state 14
-  Forward route : (from state 6)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 22
-  Use state 0 as basis (4 fixups)
-
-DFA state 15
-  Forward route : (from state 7)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    17:[a-z] -> 23
-
-DFA state 16
-  Forward route : (from state 8)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 24
-    7:[.] -> 24
-    8:[0-9] -> 24
-    9:[:] -> 13
-    13:[A-Z] -> 24
-    16:[_] -> 24
-    17:[a-z] -> 24
-
-DFA state 17
-  Forward route : (from state 8)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->14:[[]->(HERE)
-  Transitions :
-    7:[.] -> 17
-    8:[0-9] -> 17
-    15:[]] -> 19
-
-DFA state 18
-  Forward route : (from state 9)
-   (START)->4:["]->4:["]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 25
-    7:[.] -> 25
-    8:[0-9] -> 25
-    13:[A-Z] -> 25
-    14:[[] -> 17
-    16:[_] -> 25
-    17:[a-z] -> 25
-
-DFA state 19
-  Forward route : (from state 10)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->11:[>]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-
-DFA state 20
-  Forward route : (from state 10)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 26
-    7:[.] -> 26
-    8:[0-9] -> 26
-    9:[:] -> 4
-    13:[A-Z] -> 26
-    14:[[] -> 27
-    16:[_] -> 26
-    17:[a-z] -> 26
-
-DFA state 21
-  Forward route : (from state 11)
-   (START)->10:[<]->4:["]->4:["]->(HERE)
-  Transitions :
-    3:[!#-'*/=?^`{-~] -> 21
-    4:["] -> 11
-    5:[+] -> 21
-    6:[\055] -> 21
-    7:[.] -> 21
-    8:[0-9] -> 21
-    11:[>] -> 19
-    12:[@] -> 28
-    13:[A-Z] -> 21
-    16:[_] -> 21
-    17:[a-z] -> 21
-
-DFA state 22
-  Forward route : (from state 14)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 29
-    3:[!#-'*/=?^`{-~] -> 2
-    4:["] -> 3
-    5:[+] -> 2
-    6:[\055] -> 2
-    7:[.] -> 2
-    8:[0-9] -> 2
-    12:[@] -> 8
-    13:[A-Z] -> 2
-    16:[_] -> 2
-    17:[a-z] -> 2
-  Use state 0 as basis (3 fixups)
-
-DFA state 23
-  Forward route : (from state 15)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    17:[a-z] -> 30
-
-DFA state 24
-  Forward route : (from state 16)
-   (START)->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    6:[\055] -> 24
-    7:[.] -> 24
-    8:[0-9] -> 24
-    9:[:] -> 13
-    13:[A-Z] -> 24
-    16:[_] -> 24
-    17:[a-z] -> 24
-  Use state 16 as basis (1 fixups)
-
-DFA state 25
-  Forward route : (from state 18)
-   (START)->4:["]->4:["]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 31
-    7:[.] -> 31
-    8:[0-9] -> 31
-    13:[A-Z] -> 31
-    16:[_] -> 31
-    17:[a-z] -> 31
-
-DFA state 26
-  Forward route : (from state 20)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 32
-    7:[.] -> 32
-    8:[0-9] -> 32
-    9:[:] -> 4
-    13:[A-Z] -> 32
-    16:[_] -> 32
-    17:[a-z] -> 32
-
-DFA state 27
-  Forward route : (from state 20)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->14:[[]->(HERE)
-  Transitions :
-    7:[.] -> 27
-    8:[0-9] -> 27
-    15:[]] -> 33
-
-DFA state 28
-  Forward route : (from state 21)
-   (START)->10:[<]->4:["]->4:["]->12:[@]->(HERE)
-  Transitions :
-    6:[\055] -> 34
-    7:[.] -> 34
-    8:[0-9] -> 34
-    13:[A-Z] -> 34
-    14:[[] -> 27
-    16:[_] -> 34
-    17:[a-z] -> 34
-
-DFA state 29
-  Forward route : (from state 22)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 29
-    13:[A-Z] -> 35
-
-DFA state 30
-  Forward route : (from state 23)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 36
-
-DFA state 31
-  Forward route : (from state 25)
-   (START)->4:["]->4:["]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    0:[\t ] -> 7
-    6:[\055] -> 31
-    7:[.] -> 31
-    8:[0-9] -> 31
-    13:[A-Z] -> 31
-    16:[_] -> 31
-    17:[a-z] -> 31
-  Use state 25 as basis (1 fixups)
-
-DFA state 32
-  Forward route : (from state 26)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 32
-    7:[.] -> 32
-    8:[0-9] -> 32
-    9:[:] -> 4
-    11:[>] -> 19
-    13:[A-Z] -> 32
-    16:[_] -> 32
-    17:[a-z] -> 32
-  Use state 26 as basis (1 fixups)
-
-DFA state 33
-  Forward route : (from state 27)
-   (START)->10:[<]->3:[!#-'*/=?^`{-~]->12:[@]->14:[[]->15:[]]->(HERE)
-  Transitions :
-    11:[>] -> 19
-
-DFA state 34
-  Forward route : (from state 28)
-   (START)->10:[<]->4:["]->4:["]->12:[@]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 37
-    7:[.] -> 37
-    8:[0-9] -> 37
-    13:[A-Z] -> 37
-    16:[_] -> 37
-    17:[a-z] -> 37
-
-DFA state 35
-  Forward route : (from state 29)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    17:[a-z] -> 38
-
-DFA state 36
-  Forward route : (from state 30)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 36
-    13:[A-Z] -> 39
-
-DFA state 37
-  Forward route : (from state 34)
-   (START)->10:[<]->4:["]->4:["]->12:[@]->6:[\055]->6:[\055]->(HERE)
-  Transitions :
-    6:[\055] -> 37
-    7:[.] -> 37
-    8:[0-9] -> 37
-    11:[>] -> 19
-    13:[A-Z] -> 37
-    16:[_] -> 37
-    17:[a-z] -> 37
-  Use state 34 as basis (1 fixups)
-
-DFA state 38
-  Forward route : (from state 35)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    17:[a-z] -> 40
-
-DFA state 39
-  Forward route : (from state 36)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    17:[a-z] -> 41
-
-DFA state 40
-  Forward route : (from state 38)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 42
-
-DFA state 41
-  Forward route : (from state 39)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->(HERE)
-  Transitions :
-    17:[a-z] -> 43
-
-DFA state 42
-  Forward route : (from state 40)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 42
-    8:[0-9] -> 44
-    13:[A-Z] -> 39
-
-DFA state 43
-  Forward route : (from state 41)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->(HERE)
-  Transitions :
-    0:[\t ] -> 45
-
-DFA state 44
-  Forward route : (from state 42)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 46
-    8:[0-9] -> 47
-
-DFA state 45
-  Forward route : (from state 43)
-   (START)->3:[!#-'*/=?^`{-~]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 45
-    8:[0-9] -> 44
-
-DFA state 46
-  Forward route : (from state 44)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 46
-    8:[0-9] -> 48
-
-DFA state 47
-  Forward route : (from state 44)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 46
-
-DFA state 48
-  Forward route : (from state 46)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 49
-
-DFA state 49
-  Forward route : (from state 48)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    9:[:] -> 50
-
-DFA state 50
-  Forward route : (from state 49)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->(HERE)
-  Transitions :
-    8:[0-9] -> 51
-
-DFA state 51
-  Forward route : (from state 50)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 52
-
-DFA state 52
-  Forward route : (from state 51)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 53
-    9:[:] -> 54
-
-DFA state 53
-  Forward route : (from state 52)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 53
-    5:[+] -> 55
-    6:[\055] -> 55
-    8:[0-9] -> 56
-    13:[A-Z] -> 57
-
-DFA state 54
-  Forward route : (from state 52)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->9:[:]->(HERE)
-  Transitions :
-    8:[0-9] -> 58
-
-DFA state 55
-  Forward route : (from state 53)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 57
-    13:[A-Z] -> 57
-    17:[a-z] -> 57
-
-DFA state 56
-  Forward route : (from state 53)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 59
-
-DFA state 57
-  Forward route : (from state 53)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 60
-    8:[0-9] -> 57
-    13:[A-Z] -> 57
-    17:[a-z] -> 57
-  Use state 55 as basis (1 fixups)
-
-DFA state 58
-  Forward route : (from state 54)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 61
-
-DFA state 59
-  Forward route : (from state 56)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 62
-
-DFA state 60
-  Forward route : (from state 57)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 60
-    5:[+] -> 63
-    6:[\055] -> 63
-    8:[0-9] -> 64
-    13:[A-Z] -> 65
-
-DFA state 61
-  Forward route : (from state 58)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 53
-
-DFA state 62
-  Forward route : (from state 59)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 66
-
-DFA state 63
-  Forward route : (from state 60)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 65
-    13:[A-Z] -> 65
-    17:[a-z] -> 65
-
-DFA state 64
-  Forward route : (from state 60)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 67
-
-DFA state 65
-  Forward route : (from state 60)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 68
-    8:[0-9] -> 65
-    13:[A-Z] -> 65
-    17:[a-z] -> 65
-  Use state 63 as basis (1 fixups)
-
-DFA state 66
-  Forward route : (from state 62)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 66
-    1:[\n] -> 69
-    2:[\r] -> 70
-    5:[+] -> 71
-    6:[\055] -> 71
-    13:[A-Z] -> 72
-
-DFA state 67
-  Forward route : (from state 64)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 73
-
-DFA state 68
-  Forward route : (from state 65)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->13:[A-Z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 68
-    8:[0-9] -> 64
-
-DFA state 69
-  Forward route : (from state 66)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->1:[\n]->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    FROMCHECK_PASS
-  Attributes for <(DEFAULT)> : FROMCHECK_PASS
-
-DFA state 70
-  Forward route : (from state 66)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->2:[\r]->(HERE)
-  Transitions :
-    1:[\n] -> 69
-
-DFA state 71
-  Forward route : (from state 66)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 72
-    13:[A-Z] -> 72
-    17:[a-z] -> 72
-
-DFA state 72
-  Forward route : (from state 66)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 74
-    1:[\n] -> 69
-    2:[\r] -> 70
-    8:[0-9] -> 72
-    13:[A-Z] -> 72
-    17:[a-z] -> 72
-  Use state 71 as basis (3 fixups)
-
-DFA state 73
-  Forward route : (from state 67)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    8:[0-9] -> 75
-
-DFA state 74
-  Forward route : (from state 72)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 74
-    1:[\n] -> 69
-    2:[\r] -> 70
-    5:[+] -> 76
-    6:[\055] -> 76
-    13:[A-Z] -> 77
-
-DFA state 75
-  Forward route : (from state 73)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->13:[A-Z]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 75
-    1:[\n] -> 69
-    2:[\r] -> 70
-
-DFA state 76
-  Forward route : (from state 74)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->0:[\t ]->5:[+]->(HERE)
-  Transitions :
-    8:[0-9] -> 77
-    13:[A-Z] -> 77
-    17:[a-z] -> 77
-
-DFA state 77
-  Forward route : (from state 74)
-   (START)->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->13:[A-Z]->17:[a-z]->17:[a-z]->0:[\t ]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->9:[:]->8:[0-9]->8:[0-9]->0:[\t ]->8:[0-9]->8:[0-9]->8:[0-9]->8:[0-9]->13:[A-Z]->0:[\t ]->13:[A-Z]->(HERE)
-  Transitions :
-    0:[\t ] -> 75
-    1:[\n] -> 69
-    2:[\r] -> 70
-    8:[0-9] -> 77
-    13:[A-Z] -> 77
-    17:[a-z] -> 77
-  Use state 75 as basis (3 fixups)
-
-
-Entry states in DFA:
-Entry <(ONLY ENTRY)> : 0
diff --git a/src/mairix/glob.c b/src/mairix/glob.c
@@ -1,393 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2003,2004,2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <ctype.h>
-#include "mairix.h"
-
-
-struct globber {
-  unsigned int pat[256];
-  unsigned int starpat;
-  unsigned int twostarpat;
-  unsigned int hit;
-};
-
-struct globber_array {
-  int n;
-  struct globber **globs;
-};
-
-static const char *parse_charclass(const char *in, struct globber *result, unsigned int mask)/*{{{*/
-{
-  int first = 1;
-  int prev = -1;
-  in++; /* Advance over '[' */
-  while (*in) {
-    if (*in == ']') {
-      if (first) {
-        result->pat[(int)']'] |= mask;
-      } else {
-        return in;
-      }
-    } else if (*in == '-') {
-      /* Maybe range */
-      if ((prev < 0) || !in[1] || (in[1]==']')) {
-        /* - at either end of string (or right after an earlier range) means
-         * normal - */
-        result->pat['-'] |= mask;
-      } else {
-        int next = in[1];
-        int hi, lo;
-        int i;
-        /* Cope with range being inverted */
-        if (prev < next) {
-          lo = prev, hi = next;
-        } else {
-          lo = next, hi = prev;
-        }
-        for (i=lo; i<=hi; i++) {
-          int index = 0xff & i;
-          result->pat[index] |= mask;
-        }
-        /* require 1 extra increment */
-        in++;
-        prev = -1; /* Avoid junk like [a-e-z] */
-      }
-    } else {
-      int index = 0xff & (int)*in;
-      result->pat[index] |= mask;
-    }
-    prev = *in;
-    first = 0;
-    in++;
-  }
-  return in;
-}
-/*}}}*/
-
-struct globber *make_globber(const char *wildstring)/*{{{*/
-{
-  struct globber *result;
-  int n, i;
-  const char *p;
-  char c;
-  int index;
-  unsigned int mask;
-
-  result = new(struct globber);
-  memset(&result->pat, 0x00, 256*sizeof(unsigned int));
-  memset(&result->starpat, 0x00, sizeof(unsigned int));
-  memset(&result->twostarpat, 0x00, sizeof(unsigned int));
-  mask = 0x1;
-
-  n = 0;
-  for (p=wildstring; *p; p++) {
-    mask = 1<<n;
-    c = *p;
-    switch (c) {
-      case '*':/*{{{*/
-        if (p[1] == '*') {
-          result->twostarpat |= mask;
-          p++;
-        } else {
-          /* Match zero or more of anything */
-          result->starpat |= mask;
-        }
-        break;
-/*}}}*/
-      case '[':/*{{{*/
-        p = parse_charclass(p, result, mask);
-        n++;
-        break;
-/*}}}*/
-      case '?':/*{{{*/
-        for (i=0; i<256; i++) {
-          result->pat[i] |= mask;
-        }
-        n++;
-        break;
-/*}}}*/
-      default:/*{{{*/
-        index = 0xff & (int)c;
-        result->pat[index] |= mask;
-        n++;
-        break;
-/*}}}*/
-    }
-  }
-
-  result->hit = (1<<n);
-  return result;
-
-}
-/*}}}*/
-void free_globber(struct globber *old)/*{{{*/
-{
-  free(old);
-}
-/*}}}*/
-
-#define DODEBUG 0
-
-int is_glob_match(struct globber *g, const char *s)/*{{{*/
-{
-  unsigned int reg;
-  unsigned int stars;
-  unsigned int twostars;
-  unsigned int stars2;
-  int index;
-
-  reg = 0x1;
-  while (*s) {
-    index = 0xff & (int) *s;
-#if DODEBUG
-    printf("*s=%c index=%02x old_reg=%08lx pat=%08lx //",
-           *s, index, reg, g->pat[index]);
-#endif
-    stars = (reg & g->starpat);
-    twostars = (reg & g->twostarpat);
-    if (index != '/') {
-      stars2 = stars | twostars;
-    } else {
-      stars2 = twostars;
-    }
-    reg &= g->pat[index];
-    reg <<= 1;
-    reg |= stars2;
-#if DODEBUG
-    printf(" new_reg=%08lx ", reg);
-    printf("starpat=%08lx stars=%08lx stars2=%08lx\n", g->starpat, stars, stars2);
-#endif
-    s++;
-  }
-
-#if DODEBUG
-  printf("reg=%08lx hit=%08lx\n", reg, g->hit);
-#endif
-  reg &= g->hit;
-  if (reg) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-/*}}}*/
-
-struct globber_array *colon_sep_string_to_globber_array(const char *in)/*{{{*/
-{
-  char **strings;
-  int n_strings;
-  int i;
-  struct globber_array *result;
-
-  split_on_colons(in, &n_strings, &strings);
-  result = new(struct globber_array);
-  result->n = n_strings;
-  result->globs = new_array(struct globber *, n_strings);
-  for (i=0; i<n_strings; i++) {
-    result->globs[i] = make_globber(strings[i]);
-    free(strings[i]);
-  }
-  free(strings);
-  return result;
-}
-/*}}}*/
-int is_globber_array_match(struct globber_array *ga, const char *s)/*{{{*/
-{
-  int i;
-  if (!ga) return 0;
-  for (i=0; i<ga->n; i++) {
-    if (is_glob_match(ga->globs[i], s)) return 1;
-  }
-  return 0;
-}
-/*}}}*/
-void free_globber_array(struct globber_array *in)/*{{{*/
-{
-  int i;
-  for (i=0; i<in->n; i++) {
-    free_globber(in->globs[i]);
-  }
-  free(in);
-}
-/*}}}*/
-
-static char *copy_folder_name(const char *start, const char *end)/*{{{*/
-{
-  /* 'start' points to start of string to copy.
-     Any '\:' sequence is replaced by ':' .
-     Otherwise \ is treated normally.
-     'end' can be 1 beyond the end of the string to copy.  Otherwise it can be
-     null, meaning treat 'start' as the start of a normal null-terminated
-     string. */
-  char *p;
-  const char *q;
-  int len;
-  char *result;
-  if (end) {
-    len = end - start;
-  } else {
-    len = strlen(start);
-  }
-  result = new_array(char, len + 1);
-  for (p=result, q=start;
-       end ? (q < end) : *q;
-       q++) {
-    if ((q[0] == '\\') && (q[1] == ':')) {
-      /* Escaped colon : drop the backslash */
-    } else {
-      *p++ = *q;
-    }
-  }
-  *p = '\0';
-  return result;
-}
-/*}}}*/
-void string_list_to_array(struct string_list *list, int *n, char ***arr)/*{{{*/
-{
-  int N, i;
-  struct string_list *a, *next_a;
-  char **result;
-  for (N=0, a=list->next; a!=list; a=a->next, N++) ;
-
-  result = new_array(char *, N);
-  for (i=0, a=list->next; i<N; a=next_a, i++) {
-    result[i] = a->data;
-    next_a = a->next;
-    free(a);
-  }
-
-  *n = N;
-  *arr = result;
-}
-/*}}}*/
-void split_on_colons(const char *str, int *n, char ***arr)/*{{{*/
-{
-  struct string_list list, *new_cell;
-  const char *left_to_do;
-
-  list.next = list.prev = &list;
-  left_to_do = str;
-  do {
-    char *colon;
-    char *xx;
-
-    colon = strchr(left_to_do, ':');
-    /* Allow backslash-escaped colons in filenames */
-    if (colon && (colon > left_to_do) && (colon[-1]=='\\')) {
-      int is_escaped;
-      do {
-        colon = strchr(colon + 1, ':');
-        is_escaped = (colon && (colon[-1] == '\\'));
-      } while (colon && is_escaped);
-    }
-    /* 'colon' now points to the first non-escaped colon or is null if there
-       were no more such colons in the rest of the line. */
-
-    xx = copy_folder_name(left_to_do, colon);
-    if (colon) {
-      left_to_do = colon + 1;
-    } else {
-      while (*left_to_do) ++left_to_do;
-    }
-
-    new_cell = new(struct string_list);
-    new_cell->data = xx;
-    new_cell->next = &list;
-    new_cell->prev = list.prev;
-    list.prev->next = new_cell;
-    list.prev = new_cell;
-  } while (*left_to_do);
-
-  string_list_to_array(&list, n, arr);
-
-}
-/*}}}*/
-
-#if defined (TEST)
-void run1(char *ref, char *s, int expected)/*{{{*/
-{
-  struct globber *g;
-  int result;
-  g = make_globber(ref);
-  result = is_glob_match(g, s);
-
-  printf("ref=%s, str=%s, %s  %s\n", ref, s, result ? "MATCHED" : "not matched", (expected==result) ? "" : "??????");
-  free_globber(g);
-}
-/*}}}*/
-int main (int argc, char **argv)/*{{{*/
-{
-
-  run1("ab?de", "abdde", 1);
-  run1("ab?de", "abcde", 1);
-  run1("ab?de", "Abcde", 0);
-  run1("ab?de", "abcd", 0);
-  run1("ab?de", "abc", 0);
-  run1("ab[cd]de", "abdde", 1);
-  run1("ab[cd]de", "abbde", 0);
-  run1("ab[cd]de", "abcde", 1);
-  run1("ab*de", "ade", 0);
-  run1("ab*de", "abde", 1);
-  run1("ab*de", "abcde", 1);
-  run1("ab*de", "abccde", 1);
-  run1("ab*de", "abccdfde", 1);
-  run1("ab*de", "abccdedf", 0);
-  run1("ab[b-d]de", "abade",0);
-  run1("ab[b-d]de", "abcDe",0);
-  run1("ab[b-d]de", "abcde",1);
-  run1("ab[b-d]de", "abdde",1);
-  run1("ab[b-d]de", "abEde", 0);
-  run1("[a-z][0-9A-F][]a-f-]", "yE]", 1);
-  run1("[a-z][0-9A-F][]a-f-]", "uE[", 0);
-  run1("[a-z][0-9A-F][]a-f-]", "vG-", 0);
-  run1("[a-z][0-9A-F][]a-f-]", "w8-", 1);
-  run1("*", "a", 1);
-  run1("*", "", 1);
-  run1("a*", "a", 1);
-  run1("a*", "aa", 1);
-  run1("a*", "aaA", 1);
-  run1("*a", "aaa", 1);
-  run1("*a", "a", 1);
-  run1("x*abc", "xabdxabc", 1);
-  run1("*", "", 1);
-  run1("a*", "", 0);
-  run1("*a", "", 0);
-  run1("a", "", 0);
-
-  run1("*abc*", "x/abc/y", 0);
-  run1("**abc**", "x/abc/y", 1);
-  run1("x/*/abc**", "x/z/abc/y", 1);
-  run1("x/*/abc**", "x/z/w/abc/y", 0);
-  run1("x/*/abc**", "x/zz/w/abc/y", 0);
-  run1("x/*/abc**", "x/z/ww/abc/y", 0);
-  run1("x/**/abc**", "x/z/w/abc/y", 1);
-  run1("x/**/abc**", "x/zz/w/abc/y", 1);
-
-  return 0;
-}
-/*}}}*/
-#endif
-
diff --git a/src/mairix/hash.c b/src/mairix/hash.c
@@ -1,143 +0,0 @@
-/* Hash function */
-
-#include "mairix.h"
-
-/*
---------------------------------------------------------------------
-lookup2.c, by Bob Jenkins, December 1996, Public Domain.
-hash(), hash2(), hash3, and mix() are externally useful functions.
-Routines to test the hash are included if SELF_TEST is defined.
-You can use this free for any purpose.  It has no warranty.
---------------------------------------------------------------------
-*/
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-#define hashsize(n) ((unsigned int)1<<(n))
-#define hashmask(n) (hashsize(n)-1)
-
-/*
---------------------------------------------------------------------
-mix -- mix 3 32-bit values reversibly.
-For every delta with one or two bit set, and the deltas of all three
-  high bits or all three low bits, whether the original value of a,b,c
-  is almost all zero or is uniformly distributed,
-* If mix() is run forward or backward, at least 32 bits in a,b,c
-  have at least 1/4 probability of changing.
-* If mix() is run forward, every bit of c will change between 1/3 and
-  2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
-mix() was built out of 36 single-cycle latency instructions in a
-  structure that could supported 2x parallelism, like so:
-      a -= b;
-      a -= c; x = (c>>13);
-      b -= c; a ^= x;
-      b -= a; x = (a<<8);
-      c -= a; b ^= x;
-      c -= b; x = (b>>13);
-      ...
-  Unfortunately, superscalar Pentiums and Sparcs can't take advantage
-  of that parallelism.  They've also turned some of those single-cycle
-  latency instructions into multi-cycle latency instructions.  Still,
-  this is the fastest good hash I could find.  There were about 2^^68
-  to choose from.  I only looked at a billion or so.
---------------------------------------------------------------------
-*/
-#define mix(a,b,c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<<8); \
-  c -= a; c -= b; c ^= (b>>13); \
-  a -= b; a -= c; a ^= (c>>12);  \
-  b -= c; b -= a; b ^= (a<<16); \
-  c -= a; c -= b; c ^= (b>>5); \
-  a -= b; a -= c; a ^= (c>>3);  \
-  b -= c; b -= a; b ^= (a<<10); \
-  c -= a; c -= b; c ^= (b>>15); \
-}
-
-/* same, but slower, works on systems that might have 8 byte ub4's */
-#define mix2(a,b,c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<< 8); \
-  c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
-  a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
-  b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
-  c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
-  a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
-  b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
-  c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
-}
-
-/*
---------------------------------------------------------------------
-hash() -- hash a variable-length key into a 32-bit value
-  k     : the key (the unaligned variable-length array of bytes)
-  len   : the length of the key, counting by bytes
-  level : can be any 4-byte value
-Returns a 32-bit value.  Every bit of the key affects every bit of
-the return value.  Every 1-bit and 2-bit delta achieves avalanche.
-About 36+6len instructions.
-
-The best hash table sizes are powers of 2.  There is no need to do
-mod a prime (mod is sooo slow!).  If you need less than 32 bits,
-use a bitmask.  For example, if you need only 10 bits, do
-  h = (h & hashmask(10));
-In which case, the hash table should have hashsize(10) elements.
-
-If you are hashing n strings (ub1 **)k, do it like this:
-  for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
-
-By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use this
-code any way you wish, private, educational, or commercial.  It's free.
-
-See http://burlteburtle.net/bob/hash/evahash.html
-Use for hash table lookup, or anything where one collision in 2^32 is
-acceptable.  Do NOT use for cryptographic purposes.
---------------------------------------------------------------------
-*/
-
-unsigned int hashfn( unsigned char *k, unsigned int length, unsigned int initval)
-{
-   register unsigned int a,b,c,len;
-
-   /* Set up the internal state */
-   len = length;
-   a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
-   c = initval;           /* the previous hash value */
-
-   /*---------------------------------------- handle most of the key */
-   while (len >= 12)
-   {
-      a += (k[0] +((unsigned int)k[1]<<8) +((unsigned int)k[2]<<16) +((unsigned int)k[3]<<24));
-      b += (k[4] +((unsigned int)k[5]<<8) +((unsigned int)k[6]<<16) +((unsigned int)k[7]<<24));
-      c += (k[8] +((unsigned int)k[9]<<8) +((unsigned int)k[10]<<16)+((unsigned int)k[11]<<24));
-      mix(a,b,c);
-      k += 12; len -= 12;
-   }
-
-   /*------------------------------------- handle the last 11 bytes */
-   c += length;
-   switch(len)              /* all the case statements fall through */
-   {
-   case 11: c+=((unsigned int)k[10]<<24);
-   case 10: c+=((unsigned int)k[9]<<16);
-   case 9 : c+=((unsigned int)k[8]<<8);
-      /* the first byte of c is reserved for the length */
-   case 8 : b+=((unsigned int)k[7]<<24);
-   case 7 : b+=((unsigned int)k[6]<<16);
-   case 6 : b+=((unsigned int)k[5]<<8);
-   case 5 : b+=k[4];
-   case 4 : a+=((unsigned int)k[3]<<24);
-   case 3 : a+=((unsigned int)k[2]<<16);
-   case 2 : a+=((unsigned int)k[1]<<8);
-   case 1 : a+=k[0];
-     /* case 0: nothing left to add */
-   }
-   mix(a,b,c);
-   /*-------------------------------------------- report the result */
-   return c;
-}
-
-
diff --git a/src/mairix/mairix.1 b/src/mairix/mairix.1
@@ -1,673 +0,0 @@
-.TH MAIRIX 1 "January 2006"
-.de Sx
-.PP
-.ne \\$1
-.nf
-.na
-.RS 7
-..
-.de Ex
-.RE 
-.fi
-.ad
-.PP
-..
-.de Sy
-.PP
-.ne \\$1
-.nf
-.na
-.RS 12
-..
-.de Ey
-.RE 
-.fi
-.ad
-.IP "" 7
-..
-.SH NAME
-mairix \- index and search mail folders
-.SH SYNOPSIS
-.SS Indexing
-.B mairix
-[
-.BR \-v | \-\-verbose
-] [
-.BR \-p | \-\-purge
-] [
-.BR \-f | \-\-rcfile
-.I mairixrc
-] [
-.BR \-F | \-\-fast-index
-] [
-.BR \-\-force-hash-key-new-database
-.I hash
-]
-
-.SS Searching
-.B mairix
-[
-.BR \-v | \-\-verbose
-] [
-.BR \-f | \-\-rcfile
-.I mairixrc
-] [
-.BR \-r | \-\-raw-output
-] [
-.BR \-x | \-\-excerpt-output
-] [
-.BR \-H | \-\-force-hardlinks
-] [
-.BR \-o | \-\-mfolder
-.I mfolder
-] [
-.BR \-a | \-\-augment
-] [
-.BR \-t | \-\-threads
-]
-.I search-patterns
-
-.SS Other
-.B mairix
-[
-.BR \-h | \-\-help
-]
-
-.B mairix
-[
-.BR \-V | \-\-version
-]
-
-.B mairix
-[
-.BR \-d | \-\-dump
-]
-
-.SH DESCRIPTION
-.I mairix
-indexes and searches a collection of email messages.  The folders containing
-the messages for indexing are defined in the configuration file.  The indexing
-stage produces a database file.  The database file provides rapid access to
-details of the indexed messages during searching operations.  A search normally
-produces a folder (so-called
-.BR mfolder )
-containing the matched messages.  However, a raw mode
-.RB ( \-r )
-exists which just lists the matched messages instead.
-.PP
-It can operate with the following folder types
-.IP *
-maildir
-.IP *
-MH (compatible with the MH folder formats used by xmh, sylpheed, claws-mail, nnml (Gnus) and evolution)
-.IP *
-mbox (including mboxes that have been compressed with gzip or bzip2)
-.PP
-If maildir or MH source folders are used, and a search outputs its matches to
-an mfolder in maildir or MH format, symbolic links are used to reference the
-original messages inside the mfolder.  However, if mbox folders are involved,
-copies of messages are made instead.
-
-.SH OPTIONS
-
-.B mairix
-decides whether indexing or searching is required by looking for the presence of any
-.I search-patterns
-on the command line.
-
-.SS Special modes
-.TP
-.B -h, --help
-.br
-Show usage summary and exit
-
-.TP
-.B -V, --version
-Show program version and exit
-
-.TP
-.B -d
-.br
-Dump the database's contents in human-readable form to stdout.
-
-.SS General options
-.TP
-.BI "-f " mairixrc
-.br
-.ns
-.TP
-.BI "--rcfile " mairixrc
-.br
-Specify an alternative configuration file to use.  The default configuration file is
-.IR ~/.mairixrc .
-
-.TP
-.B -v, --verbose
-.br
-Make the output more verbose
-
-.TP
-.B -Q, --no-integrity-checks
-.br
-Normally
-.I mairix
-will do some internal integrity tests on the database.  The
-.B -Q
-option removes these checks, making
-.I mairix
-run faster, but it will be less likely to detect internal problems if any bugs creep in.
-
-The
-.I nochecks
-directive in the rc file has the same effect.
-
-.TP
-.B \-\-unlock
-.br
-.I mairix
-locks its database file during any indexing or searching operation to prevent
-multiple indexing runs interfering with each other, or an indexing run
-interfering with search runs.  The
-.B --unlock
-option removes the lockfile before doing the requested indexing or searching
-operation.  This is a convenient way of cleaning up a stale lockfile if an
-earlier run crashed for some reason or was aborted.
-
-.SS Indexing options
-
-.TP
-.B -p, --purge
-.br
-Cause stale (dead) messages to be purged from the database during an indexing
-run.  (Normally, stale messages are left in the database because of the
-additional cost of compacting away the storage that they take up.)
-
-.TP
-.B -F, --fast-index
-.br
-When processing maildir and MH folders,
-.I mairix
-normally compares the mtime and size of each message against the values stored
-in the database.  If they have changed, the message will be rescanned.  This
-check requires each message file to be stat'ed.  For large numbers of messages
-in these folder types, this can be a sizeable overhead.
-
-This option tells
-.I mairix
-to assume that when a message currently on-disc has a name matching one already
-in the database, it should assume the message is unchanged.
-
-A later indexing run without using this option will fix up any rescans that
-were missed due to its use.
-
-.TP
-.BI "--force-hash-key-new-database " hash
-.br
-This option should only be used for debugging.
-.br
-If a new database is created,
-.I hash
-is used as hash key, instead of a random hash.
-
-.SS Search options
-.TP
-.B -a, --augment
-.br
-Append newly matches messages to the current mfolder instead of creating the
-mfolder from scratch.
-
-.TP
-.B -t, --threads
-.br
-As well as returning the matched messages, also return every message in the
-same thread as one of the real matches.
-
-.TP
-.B -r, --raw-output
-.br
-Instead of creating an mfolder containing the matched messages, just show their
-paths on stdout.
-
-.TP
-.B -x, --excerpt-output
-.br
-Instead of creating an mfolder containing the matched messages, display an
-excerpt from their headers on stdout.  The excerpt shows To, Cc, From, Subject
-and Date.
-
-.TP
-.B -H, --force-hardlinks
-.br
-Instead of creating symbolic links, force the use of hardlinks.  This helps
-mailers such as alpine to realize that there are new mails in the search
-folder.
-
-.TP
-.BI "-o " mfolder
-.br
-.ns
-.TP
-.BI "--mfolder " mfolder
-.br
-Specify a temporary alternative path for the mfolder to use, overriding the
-.I mfolder
-directive in the rc file.
-
-.B mairix
-will refuse to output search results into any folder that appears to be amongst
-those that are indexed.  This is to prevent accidental deletion of emails.
-
-.SS Search patterns
-.TP
-.BI t: word
-.br
-Match
-.I word
-in the To: header.
-
-.TP
-.BI c: word
-.br
-Match
-.I word
-in the Cc: header.
-
-.TP
-.BI f: word
-.br
-Match
-.I word
-in the From: header.
-
-.TP
-.BI s: word
-.br
-Match
-.I word
-in the Subject: header.
-
-.TP
-.BI m: word
-.br
-Match
-.I word
-in the Message-ID: header.
-
-.TP
-.BI b: word
-.br
-Match
-.I word
-in the message body.
-
-.B Message body
-is taken to mean any body part of type text/plain or text/html.  For text/html,
-text within meta tags is ignored.  In particular, the URLs inside <A
-HREF="..."> tags are not currently indexed.  Non-text attachments are ignored.
-If there's an attachment of type message/rfc822, this is parsed and the match
-is performed on this sub-message too.  If a hit occurs, the enclosing message
-is treated as having a hit.
-
-.TP
-.BI d: "[start-datespec]" - "[end-datespec]"
-.br
-Match messages with Date: headers lying in the specific range.
-
-.TP
-.BI z: "[low-size]" - "[high-size]"
-.br
-Match messages whose size lies in the specified range.  If the
-.I low-size
-argument is omitted it defaults to zero.  If the
-.I high-size
-argument is omitted it defaults to infinite size.
-
-For example, to match messages between 10kilobytes and 20kilobytes in size, the
-following search term can be used:
-.Sy 1
-mairix z:10k-20k
-.Ey
-
-The suffix 'k' on a number means multiply by 1024, and the suffix 'M' on a
-number means multiply by 1024*1024.
-
-.TP
-.BI n: word
-.br
-Match
-.I word
-occurring as the name of an attachment in the message.  Since attachment names
-are usually long, this option would usually be used in the substring form.  So
-.Sy 1
-mairix n:mairix=
-.Ey
-
-would match all messages which have attachments whose names contain the
-substring
-.IR mairix .
-
-The attachment name is determined from the name=xxx or filename=xxx qualifiers
-on the Content-Type: and Content-Disposition: headers respectively.
-
-.TP
-.BI F: flags
-.br
-Match messages with particular flag settings.  The available flags are 's'
-meaning seen, 'r' meaning replied, and 'f' meaning flagged.  The flags are
-case-insensitive.  A flag letter may be prefixed by a '-' to negate its sense.  Thus
-
-.Sy 1
-mairix F:-s d:1w-
-.Ey
-
-would match any unread message less than a week old, and
-
-.Sy 1
-mairix F:f-r d:-1m
-.Ey
-
-would match any flagged message older than a month which you haven't replied to yet.
-
-Note that the flag characters and their meanings agree with those used as the
-suffix letters on message filenames in maildir folders.
-
-.SS Searching for a match amongst more than one part of a message
-.PP
-Multiple body parts may be grouped together, if a match in any of them is
-sought.  Common examples follow.
-
-.TP
-.BI tc: word
-.br
-Match
-.I word
-in either the To: or Cc: headers (or both).
-
-.TP
-.BI bs: word
-.br
-Match
-.I word
-in either the Subject: header or the message body (or both).
-
-.PP
-The
-.B a:
-search pattern is an abbreviation for
-.BR tcf: ;
-i.e. match the word in the To:, Cc: or From: headers.  ("a" stands for
-"address" in this case.)
-
-.SS Match words
-The
-.I word
-argument to the search strings can take various forms.
-
-.TP
-.I ~word
-.br
-Match messages
-.B not
-containing the word.
-
-.TP
-.I word1,word2
-.br
-This matches if both the words are matched in the specified message part.
-
-.TP
-.I word1/word2
-.br
-This matches if either of the words are matched in the specified message part.
-
-.TP
-.I substring=
-.br
-Match any word containing
-.I substring
-as a substring
-
-.TP
-.I substring=N
-.br
-Match any word containing
-.IR substring ,
-allowing up to
-.I N
-errors in the match.  For example, if
-.I N
-is 1, a single error is allowed, where an error can be
-.IP *
-a missing letter
-.IP *
-an extra letter
-.IP *
-a different letter.
-
-.TP
-.I ^substring=
-.br
-Match any word containing
-.I substring
-as a substring, with the requirement that
-.I substring
-occurs at the beginning of the matched word.
-
-.SS Precedence matters
-
-The binding order of the constructions is:
-
-.IP "1." 
-Individual command line arguments define separate conditions which are AND-ed
-together
-
-.IP "2."
-Within a single argument, the letters before the colon define which message
-parts the expression applies to.  If there is no colon, the expression applies
-to all the headers listed earlier and the body.
-
-.IP "3."
-After the colon, commas delineate separate disjuncts, which are
-OR-ed together.
-
-.IP "4."
-Each disjunct may contain separate conjuncts, which are separated
-by plus signs.  These conditions are AND-ed together.
-
-.IP "5."
-Each conjunct may start with a tilde to negate it, and may be
-followed by a slash to indicate a substring match, optionally
-followed by an integer to define the maximum number of errors
-allowed.
-
-.SS Date specification
-.PP
-This section describes the syntax used for specifying dates when
-searching using the `d:' option.
-
-Dates are specified as a range.  The start and end of the range can both be
-specified.  Alternatively, if the start is omitted, it is treated as being the
-beginning of time.  If the end is omitted, it is treated as the current time.
-
-There are 4 basic formats:
-.TP
-.BI d: start-end
-.br
-Specify both start and end explicitly
-.TP
-.BI d: start-
-Specify start, end is the current time
-.TP
-.BI d: -end
-Specify end, start is 'a long time ago' (i.e. early enough to include any
-message).
-.TP
-.BI d: period
-Specify start and end implicitly, as the start and end of the
-period given.
-
-.PP
-The start and end can be specified either absolute or relative.  A relative
-endpoint is given as a number followed by a single letter defining the scaling:
-
-.TS
-box tab(&);
-lb | lb | lb | lb.
-letter & short for & example & meaning
-=
-.T&
-l | l | l | l.
-d & days   & 3d & 3 days
-w & weeks  & 2w & 2 weeks (14 days)
-m & months & 5m & 5 months (150 days)
-y & years  & 4y & 4 years (4*365 days)
-.TE
-
-.PP
-Months are always treated as 30 days, and years as 365 days, for
-this purpose.
-
-Absolute times can be specified in many forms.  Some forms have different
-meanings when they define a start date from that when they define an end date.
-Where a single expression specifies both the start and end (i.e. where the
-argument to d: doesn't contain a `-'), it will usually have different
-interpretations in the two cases.
-
-In the examples below, suppose the current date is Sunday May 18th,
-2003 (when I started to write this material.)
-
-.TS
-box tab(&);
-l | l | l | l.
-Example & Start date & End date & Notes
-=
-d:20030301\-20030425 & March 1st, 2003 & 25th April, 2003
-d:030301\-030425 & March 1st, 2003 & April 25th, 2003 & century assumed
-d:mar1\-apr25    & March 1st, 2003 & April 25th, 2003
-d:Mar1\-Apr25    & March 1st, 2003 & April 25th, 2003 & case insensitive
-d:MAR1\-APR25    & March 1st, 2003 & April 25th, 2003 & case insensitive
-d:1mar\-25apr    & March 1st, 2003 & April 25th, 2003 & date and month in either order
-d:2002          & January 1st, 2002 & December 31st, 2002 & whole year
-d:mar           & March 1st, 2003 & March 31st, 2003 & most recent March
-d:oct           & October 1st, 2002 & October 31st, 2002 & most recent October
-d:21oct\-mar     & October 21st, 2002 & March 31st, 2003 & start before end
-d:21apr\-mar     & April 21st, 2002 & March 31st, 2003 & start before end
-d:21apr\-        & April 21st, 2003 & May 18th, 2003 & end omitted
-d:\-21apr        & January 1st, 1900 & April 21st, 2003 & start omitted
-d:6w\-2w         & April 6th, 2003 & May 4th, 2003 & both dates relative
-d:21apr\-1w      & April 21st, 2003 & May 11th, 2003 & one date relative
-d:21apr\-2y      & April 21st, 2001 & May 11th, 2001 & start before end
-d:99\-11         & January 1st, 1999 & May 11th, 2003 &T{
-2 digits are a day of the month if possible, otherwise a year
-T}
-d:99oct\-1oct    & October 1st, 1999 & October 1st, 2002 &T{
-end before now, single digit is a day of the month
-T}
-d:99oct\-01oct   & October 1st, 1999 & October 31st, 2001 &T{
-2 digits starting with zero treated as a year
-T}
-d:oct99\-oct1    & October 1st, 1999 & October 1st, 2002 &T{
-day and month in either order
-T}
-d:oct99\-oct01   & October 1st, 1999 & October 31st, 2001 &T{
-year and month in either order
-T}
-.TE
-
-.PP
-The principles in the table work as follows.
-.IP \(bu
-When the expression defines a period of more than a day (i.e. if a month or
-year is specified), the earliest day in the period is taken when the start date
-is defined, and the last day in the period if the end of the range is being
-defined.
-.IP \(bu
-The end date is always taken to be on or before the current date.
-.IP \(bu
-The start date is always taken to be on or before the end date.
-
-.SH "SETTING UP THE MATCH FOLDER"
-
-If the match folder does not exist when running in search mode, it is
-automatically created.  For 'mformat=maildir' (the default), this
-should be all you need to do.  If you use 'mformat=mh', you may have to
-run some commands before your mailer will recognize the folder.  e.g.
-for mutt, you could do
-.Sx 2
-mkdir -p /home/richard/Mail/mfolder
-touch /home/richard/Mail/mfolder/.mh_sequences
-.Ex
-which seems to work.  Alternatively, within mutt, you could set MBOX_TYPE to
-'mh' and save a message to '+mfolder' to have mutt set up the structure for you
-in advance.
-
-If you use Sylpheed, the best way seems to be to create the new folder from
-within Sylpheed before letting mairix write into it.
-
-.SH EXAMPLES
-.PP
-Suppose my email address is <richard@doesnt.exist>.
-
-Either of the following will match all messages newer than 3 months from me
-with the word 'chrony' in the subject line:
-.Sx 2
-mairix d:3m- f:richard+doesnt+exist s:chrony
-mairix d:3m- f:richard@doesnt.exist s:chrony
-.Ex
-Suppose I don't mind a few spurious matches on the address, I want a wider date
-range, and I suspect that some messages I replied to might have had the subject
-keyword spelt wrongly (let's allow up to 2 errors):
-.Sx 1
-mairix d:6m- f:richard s:chrony=2
-.Ex
-
-.SH NOTES
-.PP
-.B mairix
-works exclusively in terms of
-.IR words .
-The index that's built
-in indexing mode contains a table of which words occur in which
-messages.  Hence, the search capability is based on finding messages
-that contain particular words.
-.B mairix
-defines a word as any string of alphanumeric characters + underscore.  Any
-whitespace, punctuation, hyphens etc are treated as word boundaries.
-
-.B mairix
-has special handling for the To:, Cc: and From: headers.
-Besides the normal word scan, these headers are scanned a second time,
-where the characters '@', '-' and '.' are also treated as word
-characters.  This allows most (if not all) email addresses to appear in
-the database as single words.  So if you have a mail from
-wibble@foobar.zzz, it will match on both these searches
-
-.Sx 2
-mairix f:foobar
-mairix f:wibble@foobar.zzz
-.Ex
-It should be clear by now that the searching cannot be used to find messages
-matching general regular expressions.  This has never been much of a
-limitation.  Most searches are for particular keywords that were in the
-messages, or details of the recipients, or the approximate date.
-
-It's also worth pointing out that there is no 'locality' information
-stored, so you can't search for messages that have one words 'close' to
-some other word.  For every message and every word, there is a simple
-yes/no condition stored - whether the message contains the word in a
-particular header or in the body.  So far this has proved to be
-adequate.
-.B mairix
-has a similar feel to using an Internet search engine.
-
-.SH FILES
-.I ~/.mairixrc
-
-.SH AUTHOR
-Copyright (C) 2002-2006 Richard P. Curnow <rc@rc0.org.uk>
-.SH "SEE ALSO"
-mairixrc(5)
-.SH BUGS
-.PP
-We need a plugin scheme to allow more types of attachment to be scanned and indexed.
-
diff --git a/src/mairix/mairix.c b/src/mairix/mairix.c
@@ -1,778 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006,2007,2008
- * Copyright (C) Sanjoy Mahajan 2005
- * - mfolder validation code
- * Copyright (C) James Cameron 2005
- * Copyright (C) Paul Fox 2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "mairix.h"
-#include "version.h"
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <locale.h>
-#include <signal.h>
-
-#ifdef TEST_OOM
-int total_bytes=0;
-#endif
-
-int verbose = 0;
-int do_hardlinks = 0;
-int do_movefiles = 0;
-
-static char *folder_base = NULL;
-static char *maildir_folders = NULL;
-static char *mh_folders = NULL;
-static char *mboxen = NULL;
-static char *mfolder = NULL;
-static char *omit = NULL;
-static char *database_path = NULL;
-static enum folder_type output_folder_type = FT_MAILDIR;
-static int skip_integrity_checks = 0;
-
-enum filetype {
-  M_NONE, M_FILE, M_DIR, M_OTHER
-};
-
-static enum filetype classify_file(char *name)/*{{{*/
-{
-  struct stat sb;
-  if (stat(name, &sb) < 0) {
-    return M_NONE;
-  }
-  if (S_ISREG(sb.st_mode)) {
-    return M_FILE;
-  } else if (S_ISDIR(sb.st_mode)) {
-    return M_DIR;
-  } else {
-    return M_OTHER;
-  }
-}
-/*}}}*/
-/*{{{ member of*/
-/* returns 1 iff COMPLETE_MFOLDER (i.e. the match folder with
-   folder_base prepended if needed) matches one of the FOLDERS after
-   expanding the wildcards and recursion. Used to make sure that the
-   match folder will not overwrite a valuable mail file or
-   directory.  */
-int member_of (const char *complete_mfolder,
-    const char *folder_base,
-    const char *folders,
-    enum folder_type ft,
-    struct globber_array *omit_globs) {
-  char **raw_paths, **paths;
-  int n_raw_paths, n_paths, i;
-
-  if (!folders)
-    return 0;
-  split_on_colons(folders, &n_raw_paths, &raw_paths);
-  switch (ft) {
-    case FT_MAILDIR:
-      glob_and_expand_paths(folder_base, raw_paths, n_raw_paths, &paths, &n_paths, &maildir_traverse_methods, omit_globs);
-      break;
-    case FT_MH:
-      glob_and_expand_paths(folder_base, raw_paths, n_raw_paths, &paths, &n_paths, &mh_traverse_methods, omit_globs);
-      break;
-    case FT_MBOX:
-      glob_and_expand_paths(folder_base, raw_paths, n_raw_paths, &paths, &n_paths, &mbox_traverse_methods, omit_globs);
-      break;
-    case FT_RAW: /* cannot happen but to keep compiler happy */
-    case FT_EXCERPT:
-      break;
-  }
-  for (i=0; i<n_paths; i++) {
-    struct stat mfolder_sb, src_folder_sb; /* for checking inode numbers */
-
-    /* if the complete path names are the same, definitely a match */
-    if (strcmp (complete_mfolder, paths[i]) == 0)
-      return 1;
-    /* also a match if they point to the same file or directory but
-       via different routes (e.g. absolute path for one but path with
-       ../.. for the other), so check inode numbers */
-    /* if cannot even get stat() info, probably not wrecking any mail
-       files or dirs, so continue, i.e. skip inode check. */
-    if (stat (complete_mfolder, &mfolder_sb) != 0 ||
-        stat (paths[i], &src_folder_sb) != 0)
-      continue;
-    if (mfolder_sb.st_ino == src_folder_sb.st_ino)
-      return 1;
-  }
-  return 0;
-}
-/*}}}*/
-static char *copy_value(char *text)/*{{{*/
-{
-  char *p;
-  char *result;
-  for (p = text; *p && (*p != '='); p++) ;
-  if (!*p) return NULL;
-  p++;
-  result = expand_string(p);
-  return result;
-}
-/*}}}*/
-static void add_folders(char **folders, char *extra_folders)/*{{{*/
-{
-  /* note : extra_pointers is stale after this routine exits. */
-
-  if (!*folders) {
-    *folders = extra_folders;
-  } else {
-    char *old_folders = *folders;
-    char *new_folders;
-    int old_len, extra_len;
-    old_len = strlen(old_folders);
-    extra_len = strlen(extra_folders);
-    new_folders = new_array(char, old_len + extra_len + 2);
-    strcpy(new_folders, old_folders);
-    strcpy(new_folders + old_len, ":");
-    strcpy(new_folders + old_len + 1, extra_folders);
-    *folders = new_folders;
-    free(old_folders);
-  }
-}
-/*}}}*/
-static void parse_output_folder(char *p)/*{{{*/
-{
-  char *temp;
-  temp = copy_value(p);
-  if (!strncasecmp(temp, "mh", 2)) {
-    output_folder_type = FT_MH;
-  } else if (!strncasecmp(temp, "maildir", 7)) {
-    output_folder_type = FT_MAILDIR;
-  } else if (!strncasecmp(temp, "raw", 3)) {
-    output_folder_type = FT_RAW;
-  } else if (!strncasecmp(temp, "excerpt", 3)) {
-    output_folder_type = FT_EXCERPT;
-  } else if (!strncasecmp(temp, "mbox", 4)) {
-    output_folder_type = FT_MBOX;
-  }
-  else {
-    fprintf(stderr, "Unrecognized mformat <%s>\n", temp);
-  }
-  free(temp);
-}
-/*}}}*/
-static void parse_rc_file(char *name)/*{{{*/
-{
-  FILE *in;
-  char line[4096], *p;
-  int len, lineno;
-  int all_blank;
-  int used_default_name = 0;
-
-  if (!name) {
-    /* open default file */
-    struct passwd *pw;
-    char *home;
-    home = getenv("HOME");
-    if (!home) {
-      pw = getpwuid(getuid());
-      if (!pw) {
-        fprintf(stderr, "Cannot determine home directory\n");
-        exit(2);
-      }
-      home = pw->pw_dir;
-    }
-    name = new_array(char, strlen(home) + 12);
-    strcpy(name, home);
-    strcat(name, "/.mairixrc");
-    used_default_name = 1;
-  }
-
-  in = fopen(name, "r");
-  if (!in) {
-    fprintf(stderr, "Cannot open %s, exiting\n", name);
-    exit(2);
-  }
-
-  lineno = 0;
-  while(fgets(line, sizeof(line), in)) {
-    lineno++;
-    len = strlen(line);
-    if (len > sizeof(line) - 4) {
-      fprintf(stderr, "Line %d in %s too long, exiting\n", lineno, name);
-      exit(2);
-    }
-
-    if (line[len-1] == '\n') {
-      line[len-1] = '\0';
-    }
-
-    /* Strip trailing comments. */
-    for (p=line; *p && !strchr("#!;%", *p); p++) ;
-    if (*p) *p = '\0';
-
-    /* Discard blank lines */
-    all_blank = 1;
-    for (p=line; *p; p++) {
-      if (!isspace(*(unsigned char *)p)) {
-        all_blank = 0;
-        break;
-      }
-    }
-
-    if (all_blank) continue;
-
-    /* Now a real line to parse */
-    if (!strncasecmp(p, "base", 4)) folder_base = copy_value(p);
-    else if (!strncasecmp(p, "folders", 7)) {
-      fprintf(stderr, "'folders=' option in rc file is depracated, use 'maildir='\n");
-      add_folders(&maildir_folders, copy_value(p));
-    }
-    else if (!strncasecmp(p, "maildir=", 8)) add_folders(&maildir_folders, copy_value(p));
-    else if (!strncasecmp(p, "mh_folders=", 11)) {
-      fprintf(stderr, "'mh_folders=' option in rc file is depracated, use 'mh='\n");
-      add_folders(&mh_folders, copy_value(p));
-    }
-    else if (!strncasecmp(p, "mh=", 3)) add_folders(&mh_folders, copy_value(p));
-    else if (!strncasecmp(p, "mbox=", 5)) add_folders(&mboxen, copy_value(p));
-    else if (!strncasecmp(p, "omit=", 5)) add_folders(&omit, copy_value(p));
-
-    else if (!strncasecmp(p, "mformat=", 8)) {
-      parse_output_folder(p);
-    }
-    else if (!strncasecmp(p, "mfolder=", 8)) mfolder = copy_value(p);
-    else if (!strncasecmp(p, "database=", 9)) database_path = copy_value(p);
-    else if (!strncasecmp(p, "nochecks", 8)) skip_integrity_checks = 1;
-    else {
-      if (verbose) {
-        fprintf(stderr, "Unrecognized option at line %d in %s\n", lineno, name);
-      }
-    }
-  }
-
-  fclose(in);
-
-  if (used_default_name) free(name);
-}
-/*}}}*/
-static int compare_strings(const void *a, const void *b)/*{{{*/
-{
-  const char **aa = (const char **) a;
-  const char **bb = (const char **) b;
-  return strcmp(*aa, *bb);
-}
-/*}}}*/
-static int check_message_list_for_duplicates(struct msgpath_array *msgs)/*{{{*/
-{
-  /* Caveat : only examines the file-per-message case */
-  char **sorted_paths;
-  int i, n, nn;
-  int result;
-
-  n = msgs->n;
-  sorted_paths = new_array(char *, n);
-  for (i=0, nn=0; i<n; i++) {
-    switch (msgs->type[i]) {
-      case MTY_MBOX:
-        break;
-      case MTY_DEAD:
-        assert(0);
-        break;
-      case MTY_FILE:
-        sorted_paths[nn++] = msgs->paths[i].src.mpf.path;
-        break;
-    }
-  }
-  qsort(sorted_paths, nn, sizeof(char *), compare_strings);
-
-  result = 0;
-  for (i=1; i<nn; i++) {
-    if (!strcmp(sorted_paths[i-1], sorted_paths[i])) {
-      result = 1;
-      break;
-    }
-  }
-
-  free(sorted_paths);
-  return result;
-}
-/*}}}*/
-
-static void emit_int(int x)/*{{{*/
-{
-  char buf1[20], buf2[20];
-  char *p, *q;
-  int neg=0;
-  p = buf1;
-  *p = '0'; /* In case x is zero */
-  if (x < 0) {
-    neg = 1;
-    x = -x;
-  }
-  while (x) {
-    *p++ = '0' + (x % 10);
-    x /= 10;
-  }
-  p--;
-  q = buf2;
-  if (neg) *q++ = '-';
-  while (p >= buf1) {
-    *q++ = *p--;
-  }
-  write(2, buf2, q-buf2);
-  return;
-}
-/*}}}*/
-void out_of_mem(char *file, int line, size_t size)/*{{{*/
-{
-  /* Hairy coding ahead - can't use any [s]printf, itoa etc because
-   * those might try to use the heap! */
-
-  int filelen;
-  char *p;
-
-  static char msg1[] = "Out of memory (at ";
-  static char msg2[] = " bytes)\n";
-  /* Perhaps even strlen is unsafe in this situation? */
-  p = file;
-  while (*p) p++;
-  filelen = p - file;
-  write(2, msg1, sizeof(msg1));
-  write(2, file, filelen);
-  write(2, ":", 1);
-  emit_int(line);
-  write(2, ", ", 2);
-  emit_int(size);
-  write(2, msg2, sizeof(msg2));
-  exit(2);
-}
-/*}}}*/
-void report_error(const char *str, const char *filename)/*{{{*/
-{
-  if (filename) {
-    int len = strlen(str) + strlen(filename) + 4;
-    char *t;
-    t = new_array(char, len);
-    sprintf(t, "%s '%s'", str, filename);
-    perror(t);
-    free(t);
-  } else {
-    perror(str);
-  }
-}
-/*}}}*/
-static void print_copyright(void)/*{{{*/
-{
-  fprintf(stderr,
-          "mairix %s, Copyright (C) 2002-2010 Richard P. Curnow\n"
-          "mairix comes with ABSOLUTELY NO WARRANTY.\n"
-          "This is free software, and you are welcome to redistribute it\n"
-          "under certain conditions; see the GNU General Public License for details.\n\n",
-          PROGRAM_VERSION);
-}
-/*}}}*/
-static void print_version(void)/*{{{*/
-{
-  fprintf(stdout,
-          "mairix %s\n",
-          PROGRAM_VERSION);
-}
-/*}}}*/
-static void handlesig(int signo)/*{{{*/
-{
-  unlock_and_exit(7);
-}
-/*}}}*/
-static void usage(void)/*{{{*/
-{
-  print_copyright();
-
-  printf("mairix [-h]                                    : Show help\n"
-         "mairix [-f <rcfile>] [-v] [-p] [-F]            : Build index\n"
-         "mairix [-f <rcfile>] [-a] [-t] expr1 ... exprN : Run search\n"
-         "mairix [-f <rcfile>] -d                        : Dump database to stdout\n"
-         "-h           : show this help\n"
-         "-f <rcfile>  : use alternative rc file (default ~/.mairixrc)\n"
-         "-V           : show version\n"
-         "-v           : be verbose\n"
-         "-p           : purge messages that no longer exist\n"
-         "-F           : fast scan for maildir and MH folders (no mtime or size checks)\n"
-         "-a           : add new matches to match folder (default : clear it first)\n"
-         "-x           : display excerpt of message headers (default : use match folder)\n" 
-         "-t           : include all messages in same threads as matching messages\n"
-         "-o <mfolder> : override setting of mfolder from mairixrc file\n"
-         "-r           : force raw output regardless of mformat setting in mairixrc file\n"
-         "-H           : force hard links rather than symbolic ones\n"
-	 "-M           : force moving files between maildirs, deleting originals\n"
-         "expr_i       : search expression (all expr's AND'ed together):\n"
-         "    word          : match word in message body and major headers\n"
-         "    t:word        : match word in To: header\n"
-         "    c:word        : match word in Cc: header\n"
-         "    f:word        : match word in From: header\n"
-         "    a:word        : match word in To:, Cc: or From: headers (address)\n"
-         "    s:word        : match word in Subject: header\n"
-         "    b:word        : match word in message body\n"
-         "    m:word        : match word in Message-ID: header\n"
-         "    n:word        : match name of attachment within message\n"
-         "    F:flags       : match on message flags (s=seen,r=replied,f=flagged,-=negate)\n"
-         "    p:substring   : match substring of path\n"
-         "    d:start-end   : match date range\n"
-         "    z:low-high    : match messages in size range\n"
-         "    bs:word       : match word in Subject: header or body (or any other group of prefixes)\n"
-         "    s:word1,word2 : match both words in Subject:\n"
-         "    s:word1/word2 : match either word or both words in Subject:\n"
-         "    s:~word       : match messages not containing word in Subject:\n"
-         "    s:substring=  : match substring in any word in Subject:\n"
-         "    s:^substring= : match left-anchored substring in any word in Subject:\n"
-         "    s:substring=2 : match substring with <=2 errors in any word in Subject:\n"
-         "\n"
-         "    (See documentation for more examples)\n"
-         );
-}
-    /*}}}*/
-/* Notes on folder management: {{{
-
-   Assumption is that the user wants to keep the 'mfolder' directories under a
-   common root with the real maildir folders.  This allows a common value for
-   mutt's 'folder' variable => the '+' and '=' prefixes work better.  This
-   means the indexer here can't just scan down all subdirectories of a single
-   ancestor, because it'll pick up its own mfolders.  So, use environment
-   variables to tailor the folders.
-
-   MAIRIX_FOLDER_BASE is the common parent directory of the folders (aka
-   mutt's 'folder' variable)
-
-   MAIRIX_MAILDIR_FOLDERS, MAIRIX_MH_FOLDERS, MAIRIX_MBOXEN are
-   colon-separated lists of folders to index, with '...' after a
-   component meaning any maildir underneath it.
-
-   MAIRIX_MFOLDER is the folder to put the match data.
-
-   For example, if
-   MAIRIX_FOLDER_BASE = "/home/foobar/mail"
-   MAIRIX_FOLDERS = "inbox:lists...:action:archive..."
-   MAIRIX_MFOLDER = "mf"
-
-   then /home/foobar/mail/mf/{new,cur,tmp} contain the output of the search.
-   }}} */
-
-int main (int argc, char **argv)/*{{{*/
-{
-  struct msgpath_array *msgs;
-  struct database *db = NULL;
-
-  char *arg_rc_file_path = NULL;
-  char *arg_mfolder = NULL;
-  char *e;
-  int do_augment = 0;
-  int do_threads = 0;
-  int do_search = 0;
-  int do_purge = 0;
-  int any_updates = 0;
-  int any_purges = 0;
-  int do_help = 0;
-  int do_raw_output = 0;
-  int do_excerpt_output = 0;
-  int do_dump = 0;
-  int do_integrity_checks = 1;
-  int do_forced_unlock = 0;
-  int do_fast_index = 0;
-
-  unsigned int forced_hash_key = CREATE_RANDOM_DATABASE_HASH;
-
-  struct globber_array *omit_globs;
-
-  int result;
-
-  setlocale(LC_CTYPE, "");
-
-  while (++argv, --argc) {
-    if (!*argv) {
-      break;
-    } else if (!strcmp(*argv, "-f") || !strcmp(*argv, "--rcfile")) {
-      ++argv, --argc;
-      if (!argc) {
-        fprintf(stderr, "No filename given after -f argument\n");
-        exit(1);
-      }
-      arg_rc_file_path = *argv;
-    } else if (!strcmp(*argv, "-t") || !strcmp(*argv, "--threads")) {
-      do_search = 1;
-      do_threads = 1;
-    } else if (!strcmp(*argv, "-a") || !strcmp(*argv, "--augment")) {
-      do_search = 1;
-      do_augment = 1;
-    } else if (!strcmp(*argv, "-o") || !strcmp(*argv, "--mfolder")) {
-      ++argv, --argc;
-      if (!argc) {
-        fprintf(stderr, "No folder name given after -o argument\n");
-        exit(1);
-      }
-      arg_mfolder = *argv;
-    } else if (!strcmp(*argv, "-p") || !strcmp(*argv, "--purge")) {
-      do_purge = 1;
-    } else if (!strcmp(*argv, "-d") || !strcmp(*argv, "--dump")) {
-      do_dump = 1;
-    } else if (!strcmp(*argv, "-r") || !strcmp(*argv, "--raw-output")) {
-      do_raw_output = 1;
-    } else if (!strcmp(*argv, "-x") || !strcmp(*argv, "--excerpt-output")) {
-      do_excerpt_output = 1;
-    } else if (!strcmp(*argv, "-H") || !strcmp(*argv, "--force-hardlinks")) {
-      do_hardlinks = 1;
-    } else if (!strcmp(*argv, "-M") || !strcmp(*argv, "--force-move")) {
-      do_movefiles = 1;
-    } else if (!strcmp(*argv, "-Q") || !strcmp(*argv, "--no-integrity-checks")) {
-      do_integrity_checks = 0;
-    } else if (!strcmp(*argv, "--unlock")) {
-      do_forced_unlock = 1;
-    } else if (!strcmp(*argv, "-F") ||
-               !strcmp(*argv, "--fast-index")) {
-      do_fast_index = 1;
-    } else if (!strcmp(*argv, "--force-hash-key-new-database")) {
-      ++argv, --argc;
-      if (!argc) {
-        fprintf(stderr, "No hash key given after --force-hash-key-new-database\n");
-        exit(1);
-      }
-      if ( 1 != sscanf(*argv, "%u", &forced_hash_key) )
-	{
-        fprintf(stderr, "Hash key given after --force-hash-key-new-database could not be parsed\n");
-        exit(1);
-	}
-    } else if (!strcmp(*argv, "-v") || !strcmp(*argv, "--verbose")) {
-      verbose = 1;
-    } else if (!strcmp(*argv, "-V") || !strcmp(*argv, "--version")) {
-      print_version();
-      exit(0);
-    } else if (!strcmp(*argv, "-h") ||
-               !strcmp(*argv, "--help")) {
-      do_help = 1;
-    } else if ((*argv)[0] == '-') {
-      fprintf(stderr, "Unrecognized option %s\n", *argv);
-    } else if (!strcmp(*argv, "--")) {
-      /* End of args */
-      break;
-    } else {
-      /* standard args start */
-      break;
-    }
-  }
-
-  if (do_help) {
-    usage();
-    exit(0);
-  }
-
-  if (verbose) {
-    print_copyright();
-  }
-
-  if (*argv) {
-    /* There are still args to process */
-    do_search = 1;
-  }
-
-  parse_rc_file(arg_rc_file_path);
-
-  if (getenv("MAIRIX_FOLDER_BASE")) {
-    folder_base = getenv("MAIRIX_FOLDER_BASE");
-  }
-
-  if (getenv("MAIRIX_MAILDIR_FOLDERS")) {
-    maildir_folders = getenv("MAIRIX_MAIDIR_FOLDERS");
-  }
-
-  if (getenv("MAIRIX_MH_FOLDERS")) {
-    mh_folders = getenv("MAIRIX_MH_FOLDERS");
-  }
-
-  if ((e = getenv("MAIRIX_MBOXEN"))) {
-    mboxen = e;
-  }
-
-  if (getenv("MAIRIX_MFOLDER")) {
-    mfolder = getenv("MAIRIX_MFOLDER");
-  }
-
-  if (getenv("MAIRIX_DATABASE")) {
-    database_path = getenv("MAIRIX_DATABASE");
-  }
-
-  if (arg_mfolder) {
-    mfolder = arg_mfolder;
-  }
-
-  if (skip_integrity_checks) {
-    do_integrity_checks = 0;
-  }
-
-  if (!folder_base) {
-    fprintf(stderr, "No folder_base/MAIRIX_FOLDER_BASE set\n");
-    exit(2);
-  }
-
-  if (!database_path) {
-    fprintf(stderr, "No database/MAIRIX_DATABASE set\n");
-    exit(2);
-  }
-
-  if (do_raw_output) {
-    output_folder_type = FT_RAW;
-  } else if (do_excerpt_output) {
-    output_folder_type = FT_EXCERPT;
-  }
-
-  if (omit) {
-    omit_globs = colon_sep_string_to_globber_array(omit);
-  } else {
-    omit_globs = NULL;
-  }
-
-  /* Lock database.
-   * Prevent concurrent updates due to parallel indexing (e.g. due to stuck
-   * cron jobs).
-   * Prevent concurrent searching and indexing. */
-
-  signal(SIGHUP, handlesig);
-  signal(SIGINT, handlesig);
-  signal(SIGQUIT, handlesig);
-
-  lock_database(database_path, do_forced_unlock);
-
-  if (do_dump) {
-    dump_database(database_path);
-    result = 0;
-
-  } else if (do_search) {
-    int len;
-    char *complete_mfolder;
-    enum filetype ftype;
-
-    if (!mfolder) {
-      switch (output_folder_type) {
-        case FT_RAW:
-        case FT_EXCERPT:
-          break;
-        default:
-          fprintf(stderr, "No mfolder/MAIRIX_MFOLDER set\n");
-          unlock_and_exit(2);
-      }
-      mfolder = new_string("");
-    }
-
-    /* complete_mfolder is needed by search_top() and member_of() so
-       compute it once here rather than in search_top() as well */
-    if ((mfolder[0] == '/') ||
-        ((mfolder[0] == '.') && (mfolder[1] == '/'))) {
-      complete_mfolder = new_string(mfolder);
-    } else {
-      len = strlen(folder_base) + strlen(mfolder) + 2;
-      complete_mfolder = new_array(char, len);
-      strcpy(complete_mfolder, folder_base);
-      strcat(complete_mfolder, "/");
-      strcat(complete_mfolder, mfolder);
-    }
-    /* check whether mfolder output would destroy a mail folder or mbox */
-    switch (output_folder_type) {
-      case FT_RAW:
-      case FT_EXCERPT:
-        break;
-      default:
-        if ((member_of(complete_mfolder,folder_base, maildir_folders, FT_MAILDIR, omit_globs)||
-             member_of (complete_mfolder, folder_base, mh_folders, FT_MH, omit_globs) ||
-             member_of (complete_mfolder, folder_base, mboxen, FT_MBOX, omit_globs))) {
-          fprintf (stderr,
-              "You asked search results to go to the folder '%s'.\n"
-              "That folder appears to be one of the indexed mail folders!\n"
-              "For your own good, I refuse to output search results to an indexed mail folder.\n",
-              mfolder);
-          unlock_and_exit(3);
-        }
-    }
-
-    ftype = classify_file(database_path);
-    if (ftype != M_FILE) {
-      fprintf(stderr, "No database file '%s' is present.\nYou need to do an indexing run first.\n",
-          database_path);
-      unlock_and_exit(3);
-    }
-    result = search_top(do_threads, do_augment, database_path, complete_mfolder, argv, output_folder_type, verbose);
-
-  } else {
-    enum filetype ftype;
-
-    if (!maildir_folders && !mh_folders && !mboxen) {
-      fprintf(stderr, "No [mh_]folders/mboxen/MAIRIX_[MH_]FOLDERS set\n");
-      unlock_and_exit(2);
-    }
-
-    if (verbose) printf("Finding all currently existing messages...\n");
-    msgs = new_msgpath_array();
-    if (maildir_folders) {
-      build_message_list(folder_base, maildir_folders, FT_MAILDIR, msgs, omit_globs);
-    }
-    if (mh_folders) {
-      build_message_list(folder_base, mh_folders, FT_MH, msgs, omit_globs);
-    }
-
-    /* The next call sorts the msgs array as part of looking for duplicates. */
-    if (check_message_list_for_duplicates(msgs)) {
-      fprintf(stderr, "Message list contains duplicates - check your 'folders' setting\n");
-      unlock_and_exit(2);
-    }
-
-    /* Try to open existing database */
-    ftype = classify_file(database_path);
-    if (ftype == M_FILE) {
-      if (verbose) printf("Reading existing database...\n");
-      db = new_database_from_file(database_path, do_integrity_checks);
-      if (verbose) printf("Loaded %d existing messages\n", db->n_msgs);
-    } else if (ftype == M_NONE) {
-      if (verbose) printf("Starting new database\n");
-      db = new_database( forced_hash_key );
-    } else {
-      fprintf(stderr, "database path %s is not a file; you can't put the database there\n", database_path);
-      unlock_and_exit(2);
-    }
-
-    build_mbox_lists(db, folder_base, mboxen, omit_globs);
-
-    any_updates = update_database(db, msgs->paths, msgs->n, do_fast_index);
-    if (do_purge) {
-      any_purges = cull_dead_messages(db, do_integrity_checks);
-    }
-    if (any_updates || any_purges) {
-      /* For now write it every time.  This is obviously the most reliable method. */
-      write_database(db, database_path, do_integrity_checks);
-    }
-
-#if 0
-    get_db_stats(db);
-#endif
-
-    free_database(db);
-    free_msgpath_array(msgs);
-
-    result = 0;
-  }
-
-  unlock_database();
-
-  return result;
-}
-/*}}}*/
diff --git a/src/mairix/mairix.h b/src/mairix/mairix.h
@@ -1,403 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 MAIRIX_H
-#define MAIRIX_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "memmac.h"
-
-struct msgpath {/*{{{*/
-  /* The 'selector' for this union is the corresponding entry of type 'enum
-   * message_type' */
-  union {
-    struct {
-      char *path;
-      size_t size;  /* size of the message in bytes */
-      time_t mtime; /* mtime of message file on disc */
-    } mpf; /* message per file */
-    struct {
-      int file_index; /* index into table of mbox files */
-      int msg_index;  /* index of message within the file */
-    } mbox; /* for messages in mbox format folders */
-  } src;
-
-  /* Now fields that are common to both types of message. */
-  time_t date;  /* representation of Date: header in message */
-  int tid;      /* thread-id */
-
-  /* Message flags. */
-  unsigned int seen:1;
-  unsigned int replied:1;
-  unsigned int flagged:1;
-    
-  /* + other stuff eventually */
-};
-/*}}}*/
-
-enum message_type {/*{{{*/
-  MTY_DEAD,     /* msg no longer exists, i.e. don't report in searches,
-                   prune it on a '-p' run. */
-  MTY_FILE,     /* msg <-> file in 1-1 correspondence e.g. maildir, MH */
-  MTY_MBOX      /* multiple msgs per file : MBOX format file */
-};
-/*}}}*/
-struct msgpath_array {/*{{{*/
-  enum message_type *type;
-  struct msgpath *paths;
-  int n;
-  int max;
-};
-/*}}}*/
-
-struct matches {/*{{{*/
-  unsigned char *msginfo;
-  int n; /* bytes in use */
-  int max; /* bytes allocated */
-  unsigned long highest;
-};
-/*}}}*/
-struct token {/*{{{*/
-  char *text;
-  unsigned long hashval;
-  /* to store delta-compressed info of which msgpaths match the token */
-  struct matches match0;
-};
-/*}}}*/
-struct token2 {/*{{{*/
-  char *text;
-  unsigned long hashval;
-  /* to store delta-compressed info of which msgpaths match the token */
-  struct matches match0;
-  struct matches match1;
-};
-/*}}}*/
-struct toktable {/*{{{*/
-  struct token **tokens;
-  int n; /* # in use */
-  int size; /* # allocated */
-  unsigned int mask; /* for masking down hash values */
-  int hwm; /* number to have before expanding */
-};
-/*}}}*/
-struct toktable2 {/*{{{*/
-  struct token2 **tokens;
-  int n; /* # in use */
-  int size; /* # allocated */
-  unsigned int mask; /* for masking down hash values */
-  int hwm; /* number to have before expanding */
-};
-/*}}}*/
-
-enum content_type {/*{{{*/
-  CT_TEXT_PLAIN,
-  CT_TEXT_HTML,
-  CT_TEXT_OTHER,
-  CT_MESSAGE_RFC822,
-  CT_OTHER
-};
-/*}}}*/
-struct rfc822;
-struct attachment {/*{{{*/
-  struct attachment *next;
-  struct attachment *prev;
-  enum content_type ct;
-  char *filename;
-  union attachment_body {
-    struct normal_attachment_body {
-      int len;
-      char *bytes;
-    } normal;
-    struct rfc822 *rfc822;
-  } data;
-};
-/*}}}*/
-struct headers {/*{{{*/
-  char *to;
-  char *cc;
-  char *from;
-  char *subject;
-
-  /* The following are needed to support threading */
-  char *message_id;
-  char *in_reply_to;
-  char *references;
-
-  struct {
-    unsigned int seen:1;
-    unsigned int replied:1;
-    unsigned int flagged:1;
-  } flags;
-
-  time_t date;
-};
-/*}}}*/
-struct rfc822 {/*{{{*/
-  struct headers hdrs;
-  struct attachment atts;
-};
-/*}}}*/
-
-typedef char checksum_t[16];
-
-struct message_list {/*{{{*/
-  struct message_list *next;
-  off_t start;
-  size_t len;
-};
-/*}}}*/
-struct mbox {/*{{{*/
-  /* If path==NULL, this indicates that the mbox is dead, i.e. no longer
-   * exists. */
-  char *path;
-  /* As read in from database (i.e. current last time mairix scan was run.) */
-  time_t file_mtime;
-  size_t file_size;
-  /* As found in the filesystem now. */
-  time_t current_mtime;
-  size_t current_size;
-  /* After reconciling a loaded database with what's on the disc, this entry
-     stores how many of the msgs that used to be there last time are still
-     present at the head of the file.  Thus, all messages beyond that are
-     treated as dead, and scanning starts at that point to find 'new' messages
-     (whch may actually be old ones that have moved, but they're treated as
-     new.) */
-  int n_old_msgs_valid;
-
-  /* Hold list of new messages and their number.  Number is temporary -
-   * eventually just list walking in case >=2 have to be reattached. */
-  struct message_list *new_msgs;
-  int n_new_msgs;
-
-  int n_so_far; /* Used during database load. */
-
-  int n_msgs;   /* Number of entries in 'start' and 'len' */
-  int max_msgs; /* Allocated size of 'start' and 'len' */
-  /* File offset to the start of each message (first line of real header, not to mbox 'From ' line) */
-  off_t *start;
-  /* Length of each message */
-  size_t *len;
-  /* Checksums on whole messages. */
-  checksum_t *check_all;
-
-};
-/*}}}*/
-struct database {/*{{{*/
-  /* Used to hold an entire mapping between an array of filenames, each
-     containing a single message, and the sets of tokens that occur in various
-     parts of those messages */
-
-  enum message_type *type;
-  struct msgpath *msgs; /* Paths to messages */
-  int n_msgs; /* Number in use */
-  int max_msgs; /* Space allocated */
-
-  struct mbox *mboxen;
-  int n_mboxen; /* number in use. */
-  int max_mboxen; /* space allocated */
-
-  /* Seed for hashing in the token tables.  Randomly created for
-   * each new database - avoid DoS attacks through carefully
-   * crafted messages. */
-  unsigned int hash_key;
-
-  /* Token tables */
-  struct toktable *to;
-  struct toktable *cc;
-  struct toktable *from;
-  struct toktable *subject;
-  struct toktable *body;
-  struct toktable *attachment_name;
-
-  /* Encoding chain 0 stores all msgids appearing in the following message headers:
-   * Message-Id, In-Reply-To, References.  Used for thread reconciliation.
-   * Encoding chain 1 stores just the Message-Id.  Used for search by message ID.
-  */
-  struct toktable2 *msg_ids;
-};
-/*}}}*/
-
-enum folder_type {/*{{{*/
-  FT_MAILDIR,
-  FT_MH,
-  FT_MBOX,
-  FT_RAW,
-  FT_EXCERPT
-};
-/*}}}*/
-
-struct string_list {/*{{{*/
-  struct string_list *next;
-  struct string_list *prev;
-  char *data;
-};
-/*}}}*/
-
-struct msg_src {
-  enum {MS_FILE, MS_MBOX} type;
-  char *filename;
-  off_t start;
-  size_t len;
-};
-
-/* Outcomes of checking a filename/dirname to see whether to keep on looking
- * at filenames within this dir. */
-enum traverse_check {
-  TRAV_PROCESS, /* Continue looking at this entry */
-  TRAV_IGNORE,  /* Ignore just this dir entry */
-  TRAV_FINISH   /* Ignore this dir entry and don't bother looking at the rest of the directory */
-};
-
-struct traverse_methods {
-  int (*filter)(const char *, const struct stat *);
-  enum traverse_check (*scrutinize)(int, const char *);
-};
-
-extern struct traverse_methods maildir_traverse_methods;
-extern struct traverse_methods mh_traverse_methods;
-extern struct traverse_methods mbox_traverse_methods;
-
-extern int verbose; /* cmd line -v switch */
-extern int do_hardlinks; /* cmd line -H switch */
-extern int do_movefiles; /* cmd line -M switch */
-
-/* Lame fix for systems where NAME_MAX isn't defined after including the above
- * set of .h files (Solaris, FreeBSD so far).  Probably grossly oversized but
- * it'll do. */
-
-#if !defined(NAME_MAX)
-#define NAME_MAX 4096
-#endif
-
-/* In glob.c */
-struct globber;
-struct globber_array;
-
-struct globber *make_globber(const char *wildstring);
-void free_globber(struct globber *old);
-int is_glob_match(struct globber *g, const char *s);
-struct globber_array *colon_sep_string_to_globber_array(const char *in);
-int is_globber_array_match(struct globber_array *ga, const char *s);
-void free_globber_array(struct globber_array *in);
-
-/* In hash.c */
-unsigned int hashfn( unsigned char *k, unsigned int length, unsigned int initval);
-
-/* In dirscan.c */
-struct msgpath_array *new_msgpath_array(void);
-int valid_mh_filename_p(const char *x);
-void free_msgpath_array(struct msgpath_array *x);
-void string_list_to_array(struct string_list *list, int *n, char ***arr);
-void split_on_colons(const char *str, int *n, char ***arr);
-void build_message_list(char *folder_base, char *folders, enum folder_type ft,
-    struct msgpath_array *msgs, struct globber_array *omit_globs);
-
-/* In rfc822.c */
-struct rfc822 *make_rfc822(char *filename);
-void free_rfc822(struct rfc822 *msg);
-enum data_to_rfc822_error {
-  DTR8_OK,
-  DTR8_MISSING_END, /* missing endpoint marker. */
-  DTR8_MULTIPART_SANS_BOUNDARY, /* multipart with no boundary string defined */
-  DTR8_BAD_HEADERS, /* corrupt headers */
-  DTR8_BAD_ATTACHMENT /* corrupt attachment (e.g. no body part) */
-};
-struct rfc822 *data_to_rfc822(struct msg_src *src, char *data, int length, enum data_to_rfc822_error *error);
-void create_ro_mapping(const char *filename, unsigned char **data, int *len);
-void free_ro_mapping(unsigned char *data, int len);
-char *format_msg_src(struct msg_src *src);
-
-/* In tok.c */
-struct toktable *new_toktable(void);
-struct toktable2 *new_toktable2(void);
-void free_token(struct token *x);
-void free_token2(struct token2 *x);
-void free_toktable(struct toktable *x);
-void free_toktable2(struct toktable2 *x);
-void add_token_in_file(int file_index, unsigned int hash_key, char *tok_text, struct toktable *table);
-void check_and_enlarge_encoding(struct matches *m);
-void insert_index_on_encoding(struct matches *m, int idx);
-void add_token2_in_file(int file_index, unsigned int hash_key, char *tok_text, struct toktable2 *table, int add_to_chain1);
-
-/* In db.c */
-#define CREATE_RANDOM_DATABASE_HASH 0
-struct database *new_database(unsigned int hash_key);
-struct database *new_database_from_file(char *db_filename, int do_integrity_checks);
-void free_database(struct database *db);
-void maybe_grow_message_arrays(struct database *db);
-void tokenise_message(int file_index, struct database *db, struct rfc822 *msg);
-int update_database(struct database *db, struct msgpath *sorted_paths, int n_paths, int do_fast_index);
-void check_database_integrity(struct database *db);
-int cull_dead_messages(struct database *db, int do_integrity_checks);
-
-/* In mbox.c */
-void build_mbox_lists(struct database *db, const char *folder_base,
-    const char *mboxen_paths, struct globber_array *omit_globs);
-int add_mbox_messages(struct database *db);
-void compute_checksum(const char *data, size_t len, checksum_t *csum);
-void cull_dead_mboxen(struct database *db);
-unsigned int encode_mbox_indices(unsigned int mb, unsigned int msg);
-void decode_mbox_indices(unsigned int index, unsigned int *mb, unsigned int *msg);
-int verify_mbox_size_constraints(struct database *db);
-void glob_and_expand_paths(const char *folder_base, char **paths_in, int n_in, char ***paths_out, int *n_out, const struct traverse_methods *methods, struct globber_array *omit_globs);
-
-/* In glob.c */
-struct globber;
-
-struct globber *make_globber(const char *wildstring);
-void free_globber(struct globber *old);
-int is_glob_match(struct globber *g, const char *s);
-
-/* In writer.c */
-void write_database(struct database *db, char *filename, int do_integrity_checks);
-
-/* In search.c */
-int search_top(int do_threads, int do_augment, char *database_path, char *complete_mfolder, char **argv, enum folder_type ft, int verbose);
-
-/* In stats.c */
-void get_db_stats(struct database *db);
-
-/* In dates.c */
-int scan_date_string(char *in, time_t *start, int *has_start, time_t *end, int *has_end);
-
-/* In dumper.c */
-void dump_database(char *filename);
-
-/* In strexpand.c */
-char *expand_string(const char *p);
-
-/* In dotlock.c */
-void lock_database(char *path, int forced_unlock);
-void unlock_database(void);
-void unlock_and_exit(int code);
-
-/* In mairix.c */
-void report_error(const char *str, const char *filename);
-
-#endif /* MAIRIX_H */
diff --git a/src/mairix/mairix.spec b/src/mairix/mairix.spec
@@ -1,45 +0,0 @@
-Name:		mairix
-Summary:	A maildir indexer and searcher
-Version:	0.23
-Release:	1
-Source:		%{name}-%{version}.tar.gz
-License:	GPL
-Group:		Application/Internet
-Packager:	Richard P. Curnow
-BuildRoot:	%{_tmppath}/%{name}-%{version}-root-%(id -u -n)
-Requires:	info
-URL:		http://www.rc0.org.uk/mairix
-
-%description
-mairix is a tool for indexing email messages stored in maildir format folders
-and performing fast searches on the resulting index.  The output is a new
-maildir folder containing symbolic links to the matched messages.
-
-%prep
-%setup -q
-
-%build
-CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-cd $RPM_BUILD_DIR/mairix-%{version}
-make install DESTDIR=$RPM_BUILD_ROOT mandir=$RPM_BUILD_ROOT/%{_mandir}
-cp README dotmairixrc.eg ..
-
-%files
-%{_bindir}/mairix
-%doc README
-%doc dotmairixrc.eg
-%doc %{_mandir}/man1/mairix.1.gz
-%doc %{_mandir}/man5/mairixrc.5.gz
-
-%changelog
-* Fri Mar 24 2006 Andre Costa <blueser@gmail.com> - 0.18
-- Updated to version 0.18
-- Included URL on header
-- removed references to 'mairix.txt', 'mairix.html' and 'mairix.info'
-- .info files have been deprecated
-- removed useless 'post' section
-- makefile's "mandir" is pointing to /usr/man instead of /usr/share/man
diff --git a/src/mairix/mairixrc.5 b/src/mairix/mairixrc.5
@@ -1,405 +0,0 @@
-.TH MAIRIXRC 5 "January 2006"
-.de Sx
-.PP
-.ne \\$1
-.nf
-.na
-.RS 12
-..
-.de Ex
-.RE 
-.fi
-.ad
-.IP "" 7
-..
-.SH NAME
-mairixrc \- configuration file for mairix(1)
-.SH SYNOPSIS
-$HOME/.mairixrc
-.SH DESCRIPTION
-.PP
-The
-.I mairixrc
-file tells
-.B mairix
-where your mail folders are located.  It also tells
-.B mairix
-where the results of searches are to be written.
-
-.B mairix
-searches for this file at
-.I $HOME/.mairixrc
-unless the
-.B -f
-option is used.
-
-The directives
-.BR base ,
-.BR mfolder ,
-and
-.B database
-must always appear in the file.  There must also be some folder definitions
-(using the
-.BR maildir ,
-.BR mh ,
-or
-.BR mbox )
-directives.
-
-.SS Comments
-Any line starting with a '#' character is treated as a comment.
-
-.SS Directives
-.TP
-.BI base= base-directory
-.br
-This defines the path to the common parent directory of all your
-maildir folders.
-
-If the path is relative, it is treated as relative to the location of the
-.I mairixrc
-file.
-
-.TP
-.BI maildir= list-of-folder-specifications
-This is a colon-separated list of the Maildir folders (relative to
-`base') that you want indexed.  Any entry that ends `...' is
-recursively scanned to find any Maildir folders underneath it.
-
-More than one line starting with `maildir' can be included.  In
-this case, mairix joins the lines together with colons as though a
-single list of folders had been given on a single very long line.
-
-Each colon-separated entry may be a wildcard.  See the discussion
-under mbox (below) for the wildcard syntax.  For example
-.Sx 1
-maildir=zzz/foo*...
-.Ex
-will match maildir folders like these (relative to the 
-.IR base-directory )
-.Sx 4
-zzz/foobar/xyz
-zzz/fooquux
-zzz/foo
-zzz/fooabc/u/v/w
-.Ex
-
-and
-.Sx 1
-maildir=zzz/foo[abc]*
-.Ex
-will match maildir folders like these (relative to the folder_base)
-.Sx 4
-zzz/fooa
-zzz/fooaaaxyz
-zzz/foobcd
-zzz/fooccccccc
-.Ex
-If a folder name contains a colon, you can write this by using the
-sequence '\\:' to escape the colon.  Otherwise, the backslash
-character is treated normally.  (If the folder name actually
-contains the sequence '\\:', you're out of luck.)
-
-.TP
-.BI mh= list-of-folder-specifications
-.br
-This is a colon-separated list of the MH folders (relative to
-`base') that you want indexed.  Any entry that ends '...' is
-recursively scanned to find any MH folders underneath it.
-
-More than one line starting with 'mh' can be included.  In this
-case, mairix joins the lines together with colons as though a
-single list of folders had been given on a single very long line.
-
-Each colon-separated entry may be a wildcard, see the discussion
-under maildir (above) and mbox (below) for the syntax and
-semantics of specifying wildcards.
-
-.b mairix
-recognizes the types of MH folders created by the following email applications:
-.RS 7
-.IP "*"
-xmh
-.IP "*"
-sylpheed
-.IP "*"
-claws-mail
-.IP "*"
-evolution
-.IP "*"
-NNML
-.IP "*"
-Mew
-.RE
-
-.TP
-.BI mbox= list-of-folder-specifications
-.br
-This is a colon-separated list of the mbox folders (relative to
-`base') that you want indexed.
-
-Each colon-separated item in the list can be suffixed by '...'.
-If the item matches a regular file, that file is treated as a mbox
-folder and the '...' suffix is ignored.  If the item matches a
-directory, a recursive scan of everything inside that directory is
-made, and all regular files are initially considered as mbox
-folders.  (Any directories found in this scan are themselves
-scanned, since the scan is recursive.)
-
-Each colon-separated item may contain wildcard operators, but only
-in its final path component.  The wildcard operators currently
-supported are
-
-.TP
-*
-.br
-Match zero or more characters (each character matched is
-arbitrary)
-
-.TP
-?
-.br
-Match exactly one arbitrary character
-
-.TP
-[abcs-z]
-.br
-Character class : match a single character from the set a, b,
-c, s, t, u, v, w, x, y and z.
-
-To include a literal ']' in the class, place it immediately
-after the opening '['.  To include a literal '-' in the
-class, place it immediately before the closing ']'.
-
-If these metacharacters are included in non-final path components,
-they have no special meaning.
-
-Here are some examples
-
-.TP
-mbox=foo/bar*
-.br
-matches 'foo/bar', 'foo/bar1', 'foo/barrrr' etc
-
-.TP
-mbox=foo*/bar*
-.br
-matches 'foo*/bar', 'foo*/bar1', 'foo*/barrrr' etc
-
-.TP
-mbox=foo/*
-.br
-matches 'foo/bar', 'foo/bar1', 'foo/barrrr', 'foo/foo',
-\'foo/x' etc
-
-.TP
-mbox=foo...
-.br
-matches any regular file in the tree rooted at 'foo'
-
-.TP
-mbox=foo/*...
-.br
-same as before
-
-.TP
-mbox=foo/[a-z]*...
-.br
-matches 'foo/a', 'foo/aardvark/xxx', 'foo/zzz/foobar',
-\'foo/w/x/y/zzz', but not 'foo/A/foobar'
-
-Regular files that are mbox folder candidates are examined
-internally.  Only files containing standard mbox 'From ' separator
-lines will be scanned for messages.
-
-If a regular file has a name ending in '.gz', and gzip support is
-compiled into the 
-.B mairix
-binary, the file will be treated as a gzipped mbox.
-
-If a regular file has a name ending in '.bz2', and bzip support is
-compiled into the
-.B mairix
-binary, the file will be treated as a bzip2'd mbox.
-
-More than one line starting with 'mbox' can be included.  In this
-case, 
-.B mairix
-joins the lines together with colons as though a
-single list of folders had been given on a single very long line.
-
-.B mairix
-performs no locking of mbox folders when it is accessing
-them.  If a mail delivery program is modifying the mbox at the
-same time, it is likely that one or messages in the mbox will
-never get indexed by 
-.B mairix
-(until the database is removed and recreated from scratch, anyway.)  The
-assumption is that
-.B mairix
-will be used to index archive folders rather than incoming ones, so this is
-unlikely to be much of a problem in reality.
-
-.B mairix
-can support a maximum of 65536 separate mboxes, and a
-maximum of 65536 messages within any one mbox.
-
-.TP
-.BI omit= list-of-glob-patterns
-This is a colon-separated list of glob patterns for folders to be omitted from
-the indexing.  This allows wide wildcards and recursive elements to be used
-in the 
-.BR maildir , mh ", and" mbox
-directives, with the
-.B omit
-option used to selectively remove unwanted folders from the folder
-lists.
-
-Within the glob patterns, a single '*' matches any
-sequence of characters other than '/'.  However '**' matches any
-sequence of characters including '/'.  This allows glob patterns
-to be constructed which have a wildcard for just one directory
-component, or for any number of directory components.
-
-The _omit_ option can be specified as many times as required so
-that the list of patterns doesn't all have to fit on one line.
-
-As an example,
-.Sx 2
-mbox=bulk...
-omit=bulk/spam*
-.Ex
-will index all mbox folders at any level under the 'bulk'
-subdirectory of the base folder, except for those folders whose
-names start 'bulk/spam', e.g. 'bulk/spam', 'bulk/spam2005' etc.
-
-In constrast,
-.Sx 2
-mbox=bulk...
-omit=bulk/spam**
-.Ex
-will index all mbox folders at any level under the 'bulk'
-subdirectory of the base folder, except for those folders whose
-names start 'bulk/spam', e.g. 'bulk/spam', 'bulk/spam2005',
-\'bulk/spam/2005', 'bulk/spam/2005/jan' etc.
-
-.TP
-.B nochecks
-This takes no arguments.  If a line starting with
-.B nochecks is
-present, it is the equivalent of specifying the 
-.B -Q
-flag to every indexing run.
-
-.TP
-.BI mfolder= match-folder-name
-This defines the name of the folder (within the directory
-specified by 
-.BR base )
-into which the search mode writes its output.  (If the 
-.B mformat
-used is 'raw' or 'excerpt', then this setting is not used and may be omitted.)
-
-The
-.B mfolder
-setting may be over-ridden for a particular search by using the
-.B -o
-option to
-.BR mairix .
-
-.B mairix
-will refuse to output search results to a folder that appears to be amongst
-those that are indexed.  This is to prevent accidental deletion of emails.
-
-If the first character of the mfolder value is '/' or '.', it is
-taken as a pathname in its own right.  This allows you to specify
-absolute paths and paths relative to the current directory where
-the mfolder should be written.  Otherwise, the value of mfolder is
-appended to the value of base, in the same way as for the source
-folders.
-
-.TP
-.BI mformat= format
-This defines the type of folder used for the match folder where
-the search results go.  There are four valid settings for
-.IR format ,
-namely 'maildir', 'mh', 'mbox', 'raw' or 'excerpt'.  If the 'raw' setting is
-used then
-.B mairix
-will just print out the path names of the files that match and no match folder
-will be created.  If the 'excerpt' setting is used,
-.B mairix
-will also print out the To:, Cc:, From:, Subject: and Date: headers of the
-matching messages.  'maildir' is the default if this option is not
-defined.  The setting is case-insensitive.
-
-.TP
-.BI database= path-to-database
-.br
-This defines the path where
-.BR mairix 's
-index database is kept.  You can keep this file anywhere you like.
-
-Currently,
-.B mairix
-will place a single database file at the location indicated by
-.IR path-to-database .
-However, a future version of
-.B mairix
-may instead place a directory containing several files at this location.
-
-.I path-to-database
-should be an absolute pathname (starting with '/').  If a relative pathname is
-used, it will be interpreted relative to the current directory at the time
-.B mairix
-is run,
-.RB ( not
-relative to the location of the 
-.I mairixrc
-file or anything like that.)
-
-.SS Expansions
-
-The part of each line in '.mairixrc' following the equals sign can
-contain the following types of expansion:
-
-.TP
-.B Home directory expansion
-If the sequence '~/' appears at the start of the text after the
-equals sign, it is expanded to the user's home directory.  Example:
-.Sx 1
-database=~/Mail/mairix_database
-.Ex
-.TP
-.B Environment expansion
-If a '$' is followed by a sequence of alpha-numeric characters (or
-\'_'), the whole string is replaced by looking up the corresponding
-environment variable.  Similarly, if '$' is followed by an open
-brace ('{'), everything up to the next close brace is looked up as
-an environment variable and the result replaces the entire
-sequence.
-
-Suppose in the shell we do
-.Sx 1
-export FOO=bar
-.Ex
-and the '.mairixrc' file contains
-.Sx 2
-maildir=xxx/$FOO
-mbox=yyy/a${FOO}b
-.Ex
-this is equivalent to
-.Sx 2
-maildir=xxx/bar
-mbox=yyy/abarb
-.Ex
-If the specified environment variable is not set, the replacement
-is the empty string.
-
-.SH NOTES
-.PP
-An alternative path to the configuration file may be given with the
-.B \-f
-option to mairix(1).
-
-
diff --git a/src/mairix/mbox.c b/src/mairix/mbox.c
@@ -1,1060 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2003,2004,2005,2006,2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <dirent.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include "mairix.h"
-#include "from.h"
-#include "fromcheck.h"
-#include "md5.h"
-
-struct extant_mbox {/*{{{*/
-  char *full_path;
-  time_t mtime;
-  size_t size;
-  int db_index;
-  /* + stuff to store positions etc of individual messages. */
-};
-/*}}}*/
-static int compare_extant_mboxen(const void *a, const void *b)/*{{{*/
-{
-  const struct extant_mbox *aa = (const struct extant_mbox *) a;
-  const struct extant_mbox *bb = (const struct extant_mbox *) b;
-  return strcmp(aa->full_path, bb->full_path);
-}
-/*}}}*/
-static int lookup_extant_mbox(struct extant_mbox *sorted_mboxen, int n_extant, char *key)/*{{{*/
-{
-  /* Implement bisection search */
- int l, h, m, r;
- l = 0, h = n_extant;
- m = -1;
- while (h > l) {
-   m = (h + l) >> 1;
-   /* Should only get called on 'file' type messages - TBC */
-   r = strcmp(sorted_mboxen[m].full_path, key);
-   if (r == 0) break;
-   if (l == m) return -1;
-   if (r > 0) h = m;
-   else       l = m;
- }
- return m;
-}
-/*}}}*/
-static void append_new_mboxen_to_db(struct database *db, struct extant_mbox *extant_mboxen, int n_extant)/*{{{*/
-{
-  int N, n_reqd;
-  int i, j;
-
-  for (i=N=0; i<n_extant; i++) {
-    if (extant_mboxen[i].db_index < 0) N++;
-  }
-
-  n_reqd = db->n_mboxen + N;
-  if (n_reqd > db->max_mboxen) {
-    db->max_mboxen = n_reqd;
-    db->mboxen = grow_array(struct mbox, n_reqd, db->mboxen);
-  }
-  /* Init new entries. */
-  for (j=0, i=db->n_mboxen; j<n_extant; j++) {
-    if (extant_mboxen[j].db_index < 0) {
-      db->mboxen[i].path = new_string(extant_mboxen[j].full_path);
-      db->mboxen[i].current_mtime = extant_mboxen[j].mtime;
-      db->mboxen[i].current_size = extant_mboxen[j].size;
-      db->mboxen[i].file_mtime = 0;
-      db->mboxen[i].file_size = 0;
-      db->mboxen[i].n_msgs = 0;
-      db->mboxen[i].n_old_msgs_valid = 0;
-      db->mboxen[i].max_msgs = 0;
-      db->mboxen[i].start = NULL;
-      db->mboxen[i].len = NULL;
-      db->mboxen[i].check_all = NULL;
-      i++;
-    }
-  }
-
-  db->n_mboxen = n_reqd;
-}
-/*}}}*/
-void compute_checksum(const char *data, size_t len, checksum_t *csum)/*{{{*/
-{
-  MD5_CTX md5;
-  MD5Init(&md5);
-  MD5Update(&md5, (unsigned char *) data, len);
-  MD5Final(&md5);
-  memcpy(csum, md5.digest, sizeof(md5.digest));
-  return;
-}
-/*}}}*/
-static int message_is_intact(struct mbox *mb, int idx, char *va, size_t len)/*{{{*/
-{
-  /* TODO : later, look at whether to optimise this in some way, e.g. by doing
-     an initial check on just the first 1k of a message, this will detect
-     failures much faster at the cost of extra storage. */
-
-  if (mb->start[idx] + mb->len[idx] > len) {
-    /* Message overruns the end of the file - can't possibly be intact. */
-    return 0;
-  } else {
-    checksum_t csum;
-    compute_checksum(va + mb->start[idx], mb->len[idx], &csum);
-    if (!memcmp(mb->check_all[idx], &csum, sizeof(checksum_t))) {
-      return 1;
-    } else {
-      return 0;
-    }
-  }
-  return 0;
-}
-/*}}}*/
-static int find_number_intact(struct mbox *mb, char *va, size_t len)/*{{{*/
-{
-  /* Pick up the common obvious case first - where new messages have been appended to the
-     end of the mbox */
-  if (mb->n_msgs == 0) {
-    return 0;
-  } else if (message_is_intact(mb, mb->n_msgs - 1, va, len)) {
-    return mb->n_msgs; /* The lot */
-  } else if (!message_is_intact(mb, 0, va, len)) {
-    return 0; /* None of them. */
-  } else {
-    /* Looks like a deletion has occurred earlier in the file => binary chop
-       search to find the last message that's still valid.  Assume that
-       everything below a valid message is still valid itself (possibly
-       dangerous assumption, time will tell.) */
-
-    int l, m, h;
-    l = 0;
-    h = mb->n_msgs;
-    /* Loop invariant : always, mesasage[l] is intact, message[h] isn't. */
-    while (l < h) {
-      m = (h + l) >> 1;
-      if (m==l) break;
-      if (message_is_intact(mb, m, va, len)) {
-        l = m;
-      } else {
-        h = m;
-      }
-    }
-    /* By loop invariant, message[l] is the highest valid one. */
-    return (l + 1);
-  }
-}
-/*}}}*/
-
-
-static int fromtab_inited = 0;
-static signed char fromtab[256];
-
-static void init_fromtab(void)/*{{{*/
-{
-  memset(fromtab, 0xff, 256);
-  fromtab[(int)(unsigned char)'\n'] = ~(1<<0);
-  fromtab[(int)(unsigned char)'F']  = ~(1<<1);
-  fromtab[(int)(unsigned char)'r']  = ~(1<<2);
-  fromtab[(int)(unsigned char)'o']  = ~(1<<3);
-  fromtab[(int)(unsigned char)'m']  = ~(1<<4);
-  fromtab[(int)(unsigned char)' ']  = ~(1<<5);
-}
-/*}}}*/
-
-/* REAL CHECKING : need to see if the line looks like this:
- * From [ <return-path> ] <weekday> <month> <day> <time> [ <timezone> ] <year>
-   (from the mutt sources).
- * where timezone can be two words rather than one sometimes. */
-
-#undef DEBUG_DFA
-
-static int looks_like_from_separator(off_t n, char *va, size_t len, int verbose)/*{{{*/
-{
-  char p;
-  int current_state = 0;
-  int result = 0;
-
-  n++; /* look beyond the space. */
-
-  while (n < len) {
-    p = va[n++];
-    if (verbose) {
-      printf("current_state=%d, p=%02x (%1c) ", current_state, (int)(unsigned char)p, ((p>=32)&&(p<=126))?p:'.');
-    }
-    current_state = fromcheck_next_state(current_state, (int)fromcheck_char2tok[(int)(unsigned char)p]);
-    if (verbose) {
-      printf("next_state=%d\n", current_state);
-    }
-    if (current_state < 0) {
-      /* not matched */
-      break;
-    }
-    if (fromcheck_attr[current_state] == FROMCHECK_PASS) {
-      result = 1; /* matched good separator */
-      break;
-    }
-  }
-
-  /* If we hit the end of the file, it doesn't look like a real 'From' line. */
-#ifdef DEBUG_DFA
-  unlock_and_exit(0);
-#endif
-  return result;
-}
-/*}}}*/
-
-static off_t find_next_from(off_t n, char *va, size_t len)/*{{{*/
-{
-  unsigned char c;
-  unsigned long hit;
-  unsigned long reg;
-  unsigned long mask;
-
-  if (!n) {
-    if ((len >= 5) && !strncmp(va, "From ", 5)) {
-      return 0;
-    }
-  }
-
-scan_again:
-
-  reg = (unsigned long) -1;
-  hit = ~(1<<5);
-  while (n < len) {
-    c = va[n];
-    mask = (unsigned long)(signed long) fromtab[(int)c];
-    reg = (reg << 1) | mask;
-    if (~(reg|hit)) {
-      if (looks_like_from_separator(n, va, len, 0)) {
-        return (n-4);
-      } else {
-#if 0
-        int nn;
-        printf("Rejecting from line at %d\n", n);
-        nn = n;
-        printf(" >> ");
-        while (nn < len) {
-          unsigned char c = va[nn++];
-          putchar(c);
-          if (c=='\n') break;
-        }
-        looks_like_from_separator(n, va, len, 1);
-#endif
-        goto scan_again;
-      }
-    }
-    n++;
-  }
-  return -1;
-}
-/*}}}*/
-static off_t start_of_next_line(off_t n, char *va, size_t len)/*{{{*/
-{
-  unsigned char c;
-  /* We are always starting from 'From ' so we can advance before testing */
-  do {
-    c = va[n];
-    n++;
-  }
-  while ((n < len) && (c != '\n'));
-  if (n == len) {
-    return -1;
-  } else {
-    return n;
-  }
-}
-/*}}}*/
-
-
-static struct message_list *build_new_message_list(struct mbox *mb, char *va, size_t len, int *n_messages)/*{{{*/
-{
-  struct message_list *result, *here, *next;
-  off_t start_from, start_pos, end_from;
-  int old_percent = -100;
-  int N;
-
-#define PERCENT_GRAN 2
-
-  *n_messages = 0;
-
-  result = here = NULL;
-  N = mb->n_old_msgs_valid;
-  if (N == 0) {
-    start_from = 0;
-  } else {
-    /* Must point to the \n at the end of the preceding message, otherwise the
-       'From ' at the start of the first message in the section to be rescanned
-       won't get detected and that message won't get indexed. */
-    start_from = mb->start[N - 1] + mb->len[N - 1] - 1;
-  }
-
-  if (!fromtab_inited) {
-    init_fromtab();
-    fromtab_inited = 1;
-  }
-
-  /* Locate next 'From ' at the start of a line */
-  start_from = find_next_from(start_from, va, len);
-  while (start_from != -1) {
-    start_pos = start_of_next_line(start_from, va, len);
-    if (start_pos == -1) {
-      /* Something is awry. */
-      goto done;
-    }
-    if (verbose) {
-      int percent;
-      percent = (int)(0.5 + 100.0 * (double) start_pos / (double) len);
-      if (percent > (old_percent+PERCENT_GRAN)) {
-        printf("Scanning mbox %s : %3d%% done\r", mb->path, percent);
-        fflush(stdout);
-        old_percent = percent;
-      }
-    }
-
-    end_from = find_next_from(start_pos, va, len);
-    next = new(struct message_list);
-    next->next = NULL;
-    next->start = start_pos;
-    if (end_from == -1) {
-      /* message runs through to end of file. */
-      next->len = len - start_pos;
-    } else {
-      next->len = end_from - start_pos;
-    }
-    if (!result) {
-      result = here = next;
-    } else {
-      here->next = next;
-      here = next;
-    }
-    ++*n_messages;
-    start_from = end_from;
-  }
-
-done:
-  if (verbose) {
-    printf("Scanning mbox %s : 100%% done\n", mb->path);
-    fflush(stdout);
-  }
-  return result;
-
-}
-/*}}}*/
-static void rescan_mbox(struct mbox *mb, char *va, size_t len)/*{{{*/
-{
-  /* We get here if it's determined that
-   * 1. the mbox file still exists
-   * 2. the mtime or size has changed, i.e. it's been modified in some way
-        since the last mairix run.
-  */
-
-  /* Find the last message in the box that appears to be intact. */
-  mb->n_old_msgs_valid = find_number_intact(mb, va, len);
-  mb->new_msgs = build_new_message_list(mb, va, len, &mb->n_new_msgs);
-}
-/*}}}*/
-static void deaden_mbox(struct mbox *mb)/*{{{*/
-{
-  mb->n_old_msgs_valid = 0;
-  mb->n_msgs = 0;
-
-  free(mb->path);
-  mb->path = NULL;
-
-  if (mb->max_msgs > 0) {
-    free(mb->start);
-    free(mb->len);
-    free(mb->check_all);
-    mb->max_msgs = 0;
-  }
-}
-/*}}}*/
-static void marry_up_mboxen(struct database *db, struct extant_mbox *extant_mboxen, int n_extant)/*{{{*/
-{
-  int *old_to_new_idx;
-  int i;
-
-  for (i=0; i<n_extant; i++) extant_mboxen[i].db_index = -1;
-
-  old_to_new_idx = NULL;
-  if (db->n_mboxen > 0) {
-    old_to_new_idx = new_array(int, db->n_mboxen);
-    for (i=0; i<db->n_mboxen; i++) old_to_new_idx[i] = -1;
-
-    for (i=0; i<db->n_mboxen; i++) {
-      if (db->mboxen[i].path) {
-        int idx;
-        idx = lookup_extant_mbox(extant_mboxen, n_extant, db->mboxen[i].path);
-        if (idx >= 0) {
-          struct mbox *mb = &db->mboxen[i];
-          old_to_new_idx[i] = idx;
-          extant_mboxen[idx].db_index = i;
-          mb->current_mtime = extant_mboxen[idx].mtime;
-          mb->current_size  = extant_mboxen[idx].size;
-        }
-      }
-    }
-  }
-
-  for (i=0; i<db->n_mboxen; i++) {
-    if (old_to_new_idx[i] < 0) {
-      /* old mbox is no more. */
-      deaden_mbox(&db->mboxen[i]);
-    }
-  }
-
-  /* Append entries for newly discovered mboxen */
-  append_new_mboxen_to_db(db, extant_mboxen, n_extant);
-
-  /* From here on, everything we need is in the db */
-  if (old_to_new_idx)
-    free(old_to_new_idx);
-
-}
-/*}}}*/
-static void check_duplicates(struct extant_mbox *extant_mboxen, int n_extant)/*{{{*/
-{
-  /* Note, list is sorted at this point */
-  int i;
-  int any_dupl = 0;
-  for (i=0; i<n_extant-1; i++) {
-    if (!strcmp(extant_mboxen[i].full_path, extant_mboxen[i+1].full_path)) {
-      printf("mbox %s is listed twice in the mairixrc file\n", extant_mboxen[i].full_path);
-      any_dupl = 1;
-    }
-  }
-  if (any_dupl) {
-    printf("Exiting, the mairixrc file needs fixing\n");
-    unlock_and_exit(1);
-  }
-}
-/*}}}*/
-static char *find_last_slash(char *in)/*{{{*/
-{
-  char *p = in;
-  char *result = NULL;
-  while (*p) {
-    if (*p == '/') result = p;
-    p++;
-  }
-  return result;
-}
-/*}}}*/
-static int append_shallow(char *path, int base_len, struct stat *sb, struct string_list *list, /*{{{*/
-                  const struct traverse_methods *methods,
-                  struct globber_array *omit_globs)
-{
-  int result = 0;
-  if ((methods->filter)(path, sb)) {
-    if (!is_globber_array_match(omit_globs, path + base_len)) {
-      struct string_list *nn = new(struct string_list);
-      nn->data = new_string(path);
-      nn->next = list;
-      nn->prev = list->prev;
-      list->prev->next = nn;
-      list->prev = nn;
-      result = 1;
-    }
-  }
-  return result;
-}
-/*}}}*/
-static int append_deep(char *path, int base_len, struct stat *sb, struct string_list *list, /*{{{*/
-                        const struct traverse_methods *methods,
-                        struct globber_array *omit_globs)
-{
-  /* path is dir : read its contents, call append_shallow or self accordingly. */
-  /* path is file : call append_shallow. */
-  struct stat sb2;
-  char *xpath;
-  DIR *d;
-  struct dirent *de;
-  int appended_any = 0;
-  int this_file_matched;
-
-  this_file_matched = append_shallow(path, base_len, sb, list, methods, omit_globs);
-  appended_any |= this_file_matched;
-
-  if (S_ISDIR(sb->st_mode)) {
-    xpath = new_array(char, strlen(path) + 2 + NAME_MAX);
-    d = opendir(path);
-    if (d) {
-      while ((de = readdir(d))) {
-        enum traverse_check status;
-        if (!strcmp(de->d_name, ".")) continue;
-        if (!strcmp(de->d_name, "..")) continue;
-        strcpy(xpath, path);
-        strcat(xpath, "/");
-        strcat(xpath, de->d_name);
-        if (!is_globber_array_match(omit_globs, xpath+base_len)) {
-          /* Filter out omissions at this point, e.g. to avoid wasting time on
-           * a recursive expansion of a tree that's going to get pruned in at
-           * the deepest level anyway. */
-          status = (methods->scrutinize)(this_file_matched, de->d_name);
-#if 0
-          /* debugging */
-          fprintf(stderr, "scrutinize for %s in %s returned %s\n",
-              de->d_name,
-              path,
-              (status == TRAV_FINISH) ? "FINISH" :
-              (status == TRAV_IGNORE) ? "IGNORE" : "PROCESS");
-#endif
-          switch (status) {
-            case TRAV_FINISH:
-              goto done_this_dir;
-            case TRAV_IGNORE:
-              goto next_path;
-            case TRAV_PROCESS:
-              if (stat(xpath, &sb2) >= 0) {
-                if (S_ISREG(sb2.st_mode)) {
-                  appended_any |= append_shallow(xpath, base_len, &sb2, list, methods, omit_globs);
-                } else if (S_ISDIR(sb2.st_mode)) {
-                  appended_any |= append_deep(xpath, base_len, &sb2, list, methods, omit_globs);
-                }
-              }
-              break;
-          }
-        }
-next_path:
-        (void) 0;
-      }
-done_this_dir:
-      closedir(d);
-    }
-    free(xpath);
-  }
-  return appended_any;
-}
-/*}}}*/
-static void handle_wild(char *path, int base_len, char *last_comp, struct string_list *list,/*{{{*/
-                        int (*append)(char *, int, struct stat *, struct string_list *,
-                              const struct traverse_methods *, struct globber_array *),
-                        const struct traverse_methods *methods,
-                        struct globber_array *omit_globs)
-{
-  /* last_comp is the character within 'path' where the wildcard stuff starts. */
-  struct globber *gg;
-  char *temp_path, *xpath;
-  DIR *d;
-  struct dirent *de;
-  int had_matches;
-
-  gg = make_globber(last_comp);
-
-  /* Null-terminate parent directory, i.e. null the character where the trailing / is */
-  if (last_comp > path) {
-    int len = last_comp - path;
-    temp_path = new_array(char, len);
-    memcpy(temp_path, path, len-1);
-    temp_path[len-1] = '\0';
-    xpath = new_array(char, len + 2 + NAME_MAX);
-  } else {
-    temp_path = new_string(".");
-    xpath = new_array(char, 3 + NAME_MAX);
-  }
-
-  d = opendir(temp_path);
-  had_matches = 0;
-  if (d) {
-    while ((de = readdir(d))) {
-      if (!strcmp(de->d_name, ".")) continue;
-      if (!strcmp(de->d_name, "..")) continue;
-      if (is_glob_match(gg, de->d_name)) {
-        struct stat xsb;
-        strcpy(xpath, temp_path);
-        strcat(xpath, "/");
-        strcat(xpath, de->d_name);
-        if (!is_globber_array_match(omit_globs, xpath+base_len)) {
-          /* Filter out omissions at this point, e.g. to avoid wasting time on
-           * a recursive expansion of a tree that's going to get pruned in full
-           * later anyway. */
-          had_matches = 1;
-          if (stat(xpath, &xsb) >= 0) {
-            (*append)(xpath, base_len, &xsb, list, methods, omit_globs);
-          }
-        }
-      }
-    }
-    closedir(d);
-    if (!had_matches) {
-      fprintf(stderr, "WARNING: Wildcard \"%s\" matched nothing in %s\n", last_comp, temp_path);
-    }
-  } else {
-    fprintf(stderr, "WARNING: Folder path %s does not exist\n", temp_path);
-  }
-
-
-  free(temp_path);
-  free(xpath);
-  free(gg);
-}
-/*}}}*/
-static void handle_single(char *path, int base_len, struct string_list *list,/*{{{*/
-                          int (*append)(char *, int, struct stat *, struct string_list *,
-                                const struct traverse_methods *, struct globber_array *),
-                          const struct traverse_methods *methods,
-                          struct globber_array *omit_globs)
-{
-  struct stat sb;
-  if (stat(path, &sb) >= 0) {
-    (*append)(path, base_len, &sb, list, methods, omit_globs);
-  } else {
-    fprintf(stderr, "WARNING: Folder path %s does not exist\n", path);
-  }
-}
-/*}}}*/
-static int filter_is_file(const char *x, const struct stat *sb)/*{{{*/
-{
-  if (S_ISREG(sb->st_mode))
-    return 1;
-  else
-    return 0;
-}
-/*}}}*/
-enum traverse_check scrutinize_mbox_entry(int parent_is_mbox, const char *de_name)/*{{{*/
-{
-  /* We have to keep looking at everything in this case. */
-  return TRAV_PROCESS;
-}
-/*}}}*/
-struct traverse_methods mbox_traverse_methods = {/*{{{*/
-  .filter = filter_is_file,
-  .scrutinize = scrutinize_mbox_entry
-};
-/*}}}*/
-static int is_wild(const char *x)/*{{{*/
-{
-  const char *p;
-  p = x;
-  while (*p) {
-    switch (*p) {
-      case '[':
-      case '*':
-      case '?':
-        return 1;
-    }
-    p++;
-  }
-  return 0;
-}
-/*}}}*/
-/*{{{ handle_one_path() */
-static void handle_one_path(const char *folder_base,
-    const char *path,
-    struct string_list *list,
-    const struct traverse_methods *methods,
-    struct globber_array *omit_globs)
-{
-  /* Valid syntaxen ([.]=optional):
-   * [xxx/]foo : single path
-   * [xxx/]foo... : if foo is a file, as before; if a directory, every ordinary file under it
-   * [xxx/]wild : any single path matching the wildcard
-   * [xxx/]wild... : consider each match of the wildcard by the rule 2 lines above
-
-   * <wild> contains any of these shell-like metacharacters
-   * * : any string of 1 or more arbitrary characters
-   * ? : any 1 arbitrary character
-   * [a-z] : character class
-   * [^a-z] : negated character class.
-
-  */
-  int folder_base_len = strlen(folder_base);
-  char *full_path;
-  int is_abs;
-  int len;
-  char *last_slash;
-  char *last_comp;
-  int base_len;
-
-  is_abs = (path[0] == '/') ? 1 : 0;
-  if (is_abs) {
-    full_path = new_string(path);
-    base_len = 0;
-  } else {
-    full_path = new_array(char, folder_base_len + strlen(path) + 2);
-    strcpy(full_path, folder_base);
-    strcat(full_path, "/");
-    strcat(full_path, path);
-    base_len = strlen(folder_base) + 1;
-  }
-  len = strlen(full_path);
-  last_slash = find_last_slash(full_path);
-  last_comp = last_slash ? (last_slash + 1) : full_path;
-  if ((len >= 4) && !strcmp(full_path + (len - 3), "...")) {
-    full_path[len - 3] = '\0';
-    if (is_wild(last_comp)) {
-      handle_wild(full_path, base_len, last_comp, list, append_deep, methods, omit_globs);
-    } else {
-      handle_single(full_path, base_len, list, append_deep, methods, omit_globs);
-    }
-  } else {
-    if (is_wild(last_comp)) {
-      handle_wild(full_path, base_len, last_comp, list, append_shallow, methods, omit_globs);
-    } else {
-      handle_single(full_path, base_len, list, append_shallow, methods, omit_globs);
-    }
-  }
-  free(full_path);
-}
-/*}}}*/
-/*{{{ glob_and_expand_paths() */
-void glob_and_expand_paths(const char *folder_base,
-    char **paths_in, int n_in,
-    char ***paths_out, int *n_out,
-    const struct traverse_methods *methods,
-    struct globber_array *omit_globs)
-{
-  struct string_list list;
-  int i;
-
-  /* Clear it. */
-  list.next = list.prev = &list;
-
-  for (i=0; i<n_in; i++) {
-    char *path = paths_in[i];
-    handle_one_path(folder_base, path, &list, methods, omit_globs);
-  }
-
-  string_list_to_array(&list, n_out, paths_out);
-}
-/*}}}*/
-
-void build_mbox_lists(struct database *db, const char *folder_base, /*{{{*/
-    const char *mboxen_paths, struct globber_array *omit_globs)
-{
-  char **raw_paths, **paths;
-  int n_raw_paths, i;
-  int n_paths;
-  struct stat sb;
-
-  int n_extant;
-  struct extant_mbox *extant_mboxen;
-
-  n_extant = 0;
-
-  if (mboxen_paths) {
-    split_on_colons(mboxen_paths, &n_raw_paths, &raw_paths);
-    glob_and_expand_paths(folder_base, raw_paths, n_raw_paths, &paths, &n_paths, &mbox_traverse_methods, omit_globs);
-    extant_mboxen = new_array(struct extant_mbox, n_paths);
-  } else {
-    n_paths = 0;
-    paths = NULL;
-    extant_mboxen = NULL;
-  }
-
-  /* Assume maximal size array. TODO : new strategy when globbing is included.
-   * */
-
-  /* TODO TODO ::: Build a sorted list of the paths and check that there aren't
-     any duplicates!! */
-
-  for (i=0; i<n_paths; i++) {
-    char *path = paths[i];
-    if (lstat(path, &sb) < 0) {
-      /* can't stat */
-    } else {
-      if (S_ISLNK(sb.st_mode)) {
-        /* Skip mbox if symlink */
-        if (verbose) {
-          printf("%s is a link - skipping\n", path);
-        }
-      } else {
-        extant_mboxen[n_extant].full_path = new_string(path);
-        extant_mboxen[n_extant].mtime = sb.st_mtime;
-        extant_mboxen[n_extant].size = sb.st_size;
-        n_extant++;
-      }
-    }
-    free(paths[i]);
-  }
-  if (paths) {
-    free(paths);
-    paths=NULL;
-  }
-
-  /* Reconcile list against that in the db. : sort, match etc. */
-  if (n_extant) {
-    qsort(extant_mboxen, n_extant, sizeof(struct extant_mbox), compare_extant_mboxen);
-  }
-
-  check_duplicates(extant_mboxen, n_extant);
-
-  marry_up_mboxen(db, extant_mboxen, n_extant);
-
-  /* Now look for new/modified mboxen, find how many of the old messages are
-   * still valid and scan the remainder. */
-
-  for (i=0; i<db->n_mboxen; i++) {
-    struct mbox *mb = &db->mboxen[i];
-    mb->new_msgs = NULL;
-    if (mb->path) {
-      if ((mb->current_mtime == mb->file_mtime) &&
-          (mb->current_size  == mb->file_size)) {
-        mb->n_old_msgs_valid = mb->n_msgs;
-      } else {
-        unsigned char *va;
-        int len;
-        create_ro_mapping(mb->path, &va, &len);
-        if (va) {
-          rescan_mbox(mb, (char *) va, len);
-          free_ro_mapping(va, len);
-        } else if (!len) {
-          mb->n_old_msgs_valid = mb->n_msgs = 0;
-        } else {
-          /* Treat as dead mbox */
-          deaden_mbox(mb);
-        }
-      }
-    }
-  }
-
-  /* At the end of this, we want the db->mboxen table to contain up to date info about
-   * the mboxen, together with how much of the old info was still current. */
-}
-/*}}}*/
-
-static struct msg_src *setup_msg_src(char *filename, off_t start, size_t len)/*{{{*/
-{
-  static struct msg_src result;
-  result.type = MS_MBOX;
-  result.filename = filename;
-  result.start = start;
-  result.len = len;
-  return &result;
-}
-/*}}}*/
-int add_mbox_messages(struct database *db)/*{{{*/
-{
-  int i, j;
-  int any_new = 0;
-  int N;
-  unsigned char *va;
-  int valen;
-  enum data_to_rfc822_error error;
-
-  for (i=0; i<db->n_mboxen; i++) {
-    struct mbox *mb = &db->mboxen[i];
-    struct message_list *here, *next;
-
-    if (mb->new_msgs) {
-      /* Upper bound : we may need to coalesce 2 or more messages if false
-       * matches on From lines have occurred inside MIME encoded body parts. */
-      N = mb->n_old_msgs_valid + mb->n_new_msgs;
-      if (N > mb->max_msgs) {
-        mb->max_msgs = N;
-        mb->start = grow_array(off_t, N, mb->start);
-        mb->len = grow_array(size_t, N, mb->len);
-        mb->check_all = grow_array(checksum_t, N, mb->check_all);
-      }
-
-      va = NULL; /* lazy mmap */
-      for (j=mb->n_old_msgs_valid, here=mb->new_msgs; here; j++, here=next) {
-        int n;
-        int trials = 0;
-        off_t start;
-        size_t len;
-        struct rfc822 *r8;
-        struct msg_src *msg_src;
-        struct message_list *last, *xx, *xn;
-
-        next = here->next;
-
-        if (!va) {
-          create_ro_mapping(mb->path, &va, &valen);
-        }
-        if (!va) {
-          fprintf(stderr, "Couldn't create mapping of file %s\n", mb->path);
-          unlock_and_exit(1);
-        }
-
-
-        /* Try to parse the next 'From' -to- 'From' chunk as an rfc822 message.
-         * If we get an unterminated MIME encoding, coalesce the next chunk
-         * onto the current one and try again.  Keep going until it works, or
-         * we run out of chunks.  If we run out, back up to just using the
-         * first chunk and assume it is broken.
-         *
-         * This is to deal with cases such as having a text/plain attachment
-         * that is actually an mbox file in its own right, i.e. will have
-         * embedded '^From ' lines in it.
-         *
-         * 'last' is the last chunk currently in the putative message. */
-        last = here;
-        do {
-          len = last->start + last->len - here->start;
-          msg_src = setup_msg_src(mb->path, here->start, len);
-          r8 = data_to_rfc822(msg_src, (char *) va + here->start, len, &error);
-          if (error == DTR8_MISSING_END) {
-            if (r8) free_rfc822(r8);
-            r8 = NULL;
-            last = last->next; /* Try with another chunk on the end */
-            ++trials;
-          } else {
-            /* Treat as success */
-            next = last->next;
-            break;
-          }
-        } while (last && trials < 100);
-
-        if (last && trials < 100) {
-          start = mb->start[j] = here->start;
-          mb->len[j] = len;
-          compute_checksum((char *) va + here->start, len, &mb->check_all[j]);
-        } else {
-          /* Faulty message or last message in the file */
-          start = mb->start[j] = here->start;
-          len = mb->len[j] = here->len;
-          compute_checksum((char *) va + here->start, len, &mb->check_all[j]);
-          msg_src = setup_msg_src(mb->path, start, len);
-          r8 = data_to_rfc822(msg_src, (char *) va + start, len, &error);
-          if (error == DTR8_MISSING_END) {
-            fprintf(stderr, "Can't find end boundary in multipart message %s\n",
-                format_msg_src(msg_src));
-          }
-        }
-
-        /* Release all the list entries in the range [here,next) (inclusive) */
-        for (xx=here; xx!=next; xx=xn) {
-          xn = xx->next;
-          free(xx);
-        }
-
-        /* Only do this once a valid rfc822 structure has been obtained. */
-        maybe_grow_message_arrays(db);
-        n = db->n_msgs;
-        db->type[n] = MTY_MBOX;
-        db->msgs[n].src.mbox.file_index = i;
-        db->msgs[n].src.mbox.msg_index = j;
-
-        if (r8) {
-          if (verbose) {
-            printf("Scanning %s[%d] at [%d,%d)\n", mb->path, j, (int)start, (int)(start + len));
-          }
-          db->msgs[n].date = r8->hdrs.date;
-          db->msgs[n].seen = r8->hdrs.flags.seen;
-          db->msgs[n].replied = r8->hdrs.flags.replied;
-          db->msgs[n].flagged = r8->hdrs.flags.flagged;
-          tokenise_message(n, db, r8);
-          free_rfc822(r8);
-        } else {
-          printf("Message in %s at [%d,%d) is misformatted\n", mb->path, (int)start, (int)(start + len));
-        }
-
-        ++db->n_msgs;
-        any_new = 1;
-      }
-      mb->n_msgs = j;
-      if (va) {
-        free_ro_mapping(va, valen);
-      }
-    }
-  }
-  return any_new;
-}
-/*}}}*/
-
-/* OTHER */
-void cull_dead_mboxen(struct database *db)/*{{{*/
-{
-  int n_alive, i, j, n;
-  int *old_to_new;
-  struct mbox *newtab;
-
-  n = db->n_mboxen;
-  for (i=0, n_alive=0; i<n; i++) {
-    if (db->mboxen[i].path) n_alive++;
-  }
-
-  /* Simple case - no dead mboxen */
-  if (n_alive == n) return;
-
-  newtab = new_array(struct mbox, n_alive);
-  old_to_new = new_array(int, n);
-  for (i=0, j=0; i<n; i++) {
-    if (db->mboxen[i].path) {
-      old_to_new[i] = j;
-      newtab[j] = db->mboxen[i];
-      printf("Copying mbox[%d] to [%d], path=%s\n", i, j, db->mboxen[i].path);
-      j++;
-    } else {
-      printf("Pruning old mbox[%d], dead\n", i);
-      old_to_new[i] = -1;
-    }
-  }
-
-  /* Renumber file indices in messages */
-  n = db->n_msgs;
-  for (i=0; i<n; i++) {
-    if (db->type[i] == MTY_MBOX) {
-      int old_idx = db->msgs[i].src.mbox.file_index;
-      assert(old_to_new[old_idx] != -1);
-      db->msgs[i].src.mbox.file_index = old_to_new[old_idx];
-    }
-  }
-
-  /* Fix up pointers */
-  db->n_mboxen = db->max_mboxen = n_alive;
-  free(db->mboxen);
-  db->mboxen = newtab;
-  free(old_to_new);
-  return;
-}
-/*}}}*/
-
-unsigned int encode_mbox_indices(unsigned int mb, unsigned int msg)/*{{{*/
-{
-  unsigned int result;
-  result = ((mb & 0xffff) << 16) | (msg & 0xffff);
-  return result;
-}
-/*}}}*/
-void decode_mbox_indices(unsigned int index, unsigned int *mb, unsigned int *msg)/*{{{*/
-{
-  *mb = (index >> 16) & 0xffff;
-  *msg = (index & 0xffff);
-}
-/*}}}*/
-int verify_mbox_size_constraints(struct database *db)/*{{{*/
-{
-  int i;
-  int fail;
-  if (db->n_mboxen > 65536) {
-    fprintf(stderr, "Too many mboxes (max 65536, you have %d)\n", db->n_mboxen);
-    return 0;
-  }
-  fail = 0;
-  for (i=0; i<db->n_mboxen; i++) {
-    if (db->mboxen[i].n_msgs > 65536) {
-      fprintf(stderr, "Too many messages in mbox %s (max 65536, you have %d)\n",
-              db->mboxen[i].path, db->mboxen[i].n_msgs);
-      fail = 1;
-    }
-  }
-  if (fail) return 0;
-  else      return 1;
-}
-/*}}}*/
-
diff --git a/src/mairix/md5.c b/src/mairix/md5.c
@@ -1,322 +0,0 @@
-/*
- ***********************************************************************
- ** md5.c -- the source code for MD5 routines                         **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                   **
- ** Revised (for MD5): RLR 4/27/91                                    **
- **   -- G modified to have y&~z instead of y&z                       **
- **   -- FF, GG, HH modified to add in last register done             **
- **   -- Access pattern: round 2 works mod 5, round 3 works mod 3     **
- **   -- distinct additive constant for each step                     **
- **   -- round 4 added, working mod 7                                 **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-
-#include "md5.h"
-
-/*
- ***********************************************************************
- **  Message-digest routines:                                         **
- **  To form the message digest for a message M                       **
- **    (1) Initialize a context buffer mdContext using MD5Init        **
- **    (2) Call MD5Update on mdContext and M                          **
- **    (3) Call MD5Final on mdContext                                 **
- **  The message digest is now in mdContext->digest[0...15]           **
- ***********************************************************************
- */
-
-/* forward declaration */
-static void Transform (UINT4 *, UINT4 *);
-
-#ifdef	__STDC__
-static const
-#else
-static
-#endif
-unsigned char PADDING[64] = {
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* F, G, H and I are basic MD5 functions */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits */
-#if	defined(FAST_MD5) && defined(__GNUC__) && defined(mc68000)
-/*
- * If we're on a 68000 based CPU and using a GNU C compiler with
- * inline assembly code, we can speed this up a bit.
- */
-inline UINT4 ROTATE_LEFT(UINT4 x, int n)
-{
-    asm("roll %2,%0" : "=d" (x) : "0" (x), "Ir" (n));
-    return x;
-}
-#else
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-#endif
-
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s, ac) \
-  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define GG(a, b, c, d, x, s, ac) \
-  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define HH(a, b, c, d, x, s, ac) \
-  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-#define II(a, b, c, d, x, s, ac) \
-  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
-   (a) = ROTATE_LEFT ((a), (s)); \
-   (a) += (b); \
-  }
-
-/* The routine MD5Init initializes the message-digest context
-   mdContext. All fields are set to zero.
- */
-void MD5Init (mdContext)
-MD5_CTX *mdContext;
-{
-  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
-
-  /* Load magic initialization constants.
-   */
-  mdContext->buf[0] = (UINT4)0x67452301;
-  mdContext->buf[1] = (UINT4)0xefcdab89;
-  mdContext->buf[2] = (UINT4)0x98badcfe;
-  mdContext->buf[3] = (UINT4)0x10325476;
-}
-
-/* The routine MD5Update updates the message-digest context to
-   account for the presence of each of the characters inBuf[0..inLen-1]
-   in the message whose digest is being computed.
- */
-void MD5Update (mdContext, inBuf, inLen)
-MD5_CTX *mdContext;
-unsigned const char *inBuf;
-unsigned int inLen;
-{
-  UINT4 in[16];
-  int mdi;
-  unsigned int i, ii;
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* update number of bits */
-  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
-    mdContext->i[1]++;
-  mdContext->i[0] += ((UINT4)inLen << 3);
-  mdContext->i[1] += ((UINT4)inLen >> 29);
-
-  while (inLen--) {
-    /* add new character to buffer, increment mdi */
-    mdContext->in[mdi++] = *inBuf++;
-
-    /* transform if necessary */
-    if (mdi == 0x40) {
-      for (i = 0, ii = 0; i < 16; i++, ii += 4)
-        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-                (((UINT4)mdContext->in[ii+2]) << 16) |
-                (((UINT4)mdContext->in[ii+1]) << 8) |
-                ((UINT4)mdContext->in[ii]);
-      Transform (mdContext->buf, in);
-      mdi = 0;
-    }
-  }
-}
-
-/* The routine MD5Final terminates the message-digest computation and
-   ends with the desired message digest in mdContext->digest[0...15].
- */
-
-void MD5Final (mdContext)
-MD5_CTX *mdContext;
-{
-  UINT4 in[16];
-  int mdi;
-  unsigned int i, ii;
-  unsigned int padLen;
-
-  /* save number of bits */
-  in[14] = mdContext->i[0];
-  in[15] = mdContext->i[1];
-
-  /* compute number of bytes mod 64 */
-  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
-  /* pad out to 56 mod 64 */
-  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
-  MD5Update (mdContext, PADDING, padLen);
-
-  /* append length in bits and transform */
-  for (i = 0, ii = 0; i < 14; i++, ii += 4)
-    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
-            (((UINT4)mdContext->in[ii+2]) << 16) |
-            (((UINT4)mdContext->in[ii+1]) << 8) |
-            ((UINT4)mdContext->in[ii]);
-  Transform (mdContext->buf, in);
-
-  /* store buffer in digest */
-  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
-    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
-    mdContext->digest[ii+1] =
-      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
-    mdContext->digest[ii+2] =
-      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
-    mdContext->digest[ii+3] =
-      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
-  }
-}
-
-/* Basic MD5 step. Transforms buf based on in.
- */
-static void Transform (buf, in)
-UINT4 *buf;
-UINT4 *in;
-{
-  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-
-  /* Round 1 */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-
-  FF ( a, b, c, d, in[ 0], S11, 0xd76aa478); /* 1 */
-  FF ( d, a, b, c, in[ 1], S12, 0xe8c7b756); /* 2 */
-  FF ( c, d, a, b, in[ 2], S13, 0x242070db); /* 3 */
-  FF ( b, c, d, a, in[ 3], S14, 0xc1bdceee); /* 4 */
-  FF ( a, b, c, d, in[ 4], S11, 0xf57c0faf); /* 5 */
-  FF ( d, a, b, c, in[ 5], S12, 0x4787c62a); /* 6 */
-  FF ( c, d, a, b, in[ 6], S13, 0xa8304613); /* 7 */
-  FF ( b, c, d, a, in[ 7], S14, 0xfd469501); /* 8 */
-  FF ( a, b, c, d, in[ 8], S11, 0x698098d8); /* 9 */
-  FF ( d, a, b, c, in[ 9], S12, 0x8b44f7af); /* 10 */
-  FF ( c, d, a, b, in[10], S13, 0xffff5bb1); /* 11 */
-  FF ( b, c, d, a, in[11], S14, 0x895cd7be); /* 12 */
-  FF ( a, b, c, d, in[12], S11, 0x6b901122); /* 13 */
-  FF ( d, a, b, c, in[13], S12, 0xfd987193); /* 14 */
-  FF ( c, d, a, b, in[14], S13, 0xa679438e); /* 15 */
-  FF ( b, c, d, a, in[15], S14, 0x49b40821); /* 16 */
-
-  /* Round 2 */
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-  GG ( a, b, c, d, in[ 1], S21, 0xf61e2562); /* 17 */
-  GG ( d, a, b, c, in[ 6], S22, 0xc040b340); /* 18 */
-  GG ( c, d, a, b, in[11], S23, 0x265e5a51); /* 19 */
-  GG ( b, c, d, a, in[ 0], S24, 0xe9b6c7aa); /* 20 */
-  GG ( a, b, c, d, in[ 5], S21, 0xd62f105d); /* 21 */
-  GG ( d, a, b, c, in[10], S22,  0x2441453); /* 22 */
-  GG ( c, d, a, b, in[15], S23, 0xd8a1e681); /* 23 */
-  GG ( b, c, d, a, in[ 4], S24, 0xe7d3fbc8); /* 24 */
-  GG ( a, b, c, d, in[ 9], S21, 0x21e1cde6); /* 25 */
-  GG ( d, a, b, c, in[14], S22, 0xc33707d6); /* 26 */
-  GG ( c, d, a, b, in[ 3], S23, 0xf4d50d87); /* 27 */
-  GG ( b, c, d, a, in[ 8], S24, 0x455a14ed); /* 28 */
-  GG ( a, b, c, d, in[13], S21, 0xa9e3e905); /* 29 */
-  GG ( d, a, b, c, in[ 2], S22, 0xfcefa3f8); /* 30 */
-  GG ( c, d, a, b, in[ 7], S23, 0x676f02d9); /* 31 */
-  GG ( b, c, d, a, in[12], S24, 0x8d2a4c8a); /* 32 */
-
-  /* Round 3 */
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-  HH ( a, b, c, d, in[ 5], S31, 0xfffa3942); /* 33 */
-  HH ( d, a, b, c, in[ 8], S32, 0x8771f681); /* 34 */
-  HH ( c, d, a, b, in[11], S33, 0x6d9d6122); /* 35 */
-  HH ( b, c, d, a, in[14], S34, 0xfde5380c); /* 36 */
-  HH ( a, b, c, d, in[ 1], S31, 0xa4beea44); /* 37 */
-  HH ( d, a, b, c, in[ 4], S32, 0x4bdecfa9); /* 38 */
-  HH ( c, d, a, b, in[ 7], S33, 0xf6bb4b60); /* 39 */
-  HH ( b, c, d, a, in[10], S34, 0xbebfbc70); /* 40 */
-  HH ( a, b, c, d, in[13], S31, 0x289b7ec6); /* 41 */
-  HH ( d, a, b, c, in[ 0], S32, 0xeaa127fa); /* 42 */
-  HH ( c, d, a, b, in[ 3], S33, 0xd4ef3085); /* 43 */
-  HH ( b, c, d, a, in[ 6], S34,  0x4881d05); /* 44 */
-  HH ( a, b, c, d, in[ 9], S31, 0xd9d4d039); /* 45 */
-  HH ( d, a, b, c, in[12], S32, 0xe6db99e5); /* 46 */
-  HH ( c, d, a, b, in[15], S33, 0x1fa27cf8); /* 47 */
-  HH ( b, c, d, a, in[ 2], S34, 0xc4ac5665); /* 48 */
-
-  /* Round 4 */
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-  II ( a, b, c, d, in[ 0], S41, 0xf4292244); /* 49 */
-  II ( d, a, b, c, in[ 7], S42, 0x432aff97); /* 50 */
-  II ( c, d, a, b, in[14], S43, 0xab9423a7); /* 51 */
-  II ( b, c, d, a, in[ 5], S44, 0xfc93a039); /* 52 */
-  II ( a, b, c, d, in[12], S41, 0x655b59c3); /* 53 */
-  II ( d, a, b, c, in[ 3], S42, 0x8f0ccc92); /* 54 */
-  II ( c, d, a, b, in[10], S43, 0xffeff47d); /* 55 */
-  II ( b, c, d, a, in[ 1], S44, 0x85845dd1); /* 56 */
-  II ( a, b, c, d, in[ 8], S41, 0x6fa87e4f); /* 57 */
-  II ( d, a, b, c, in[15], S42, 0xfe2ce6e0); /* 58 */
-  II ( c, d, a, b, in[ 6], S43, 0xa3014314); /* 59 */
-  II ( b, c, d, a, in[13], S44, 0x4e0811a1); /* 60 */
-  II ( a, b, c, d, in[ 4], S41, 0xf7537e82); /* 61 */
-  II ( d, a, b, c, in[11], S42, 0xbd3af235); /* 62 */
-  II ( c, d, a, b, in[ 2], S43, 0x2ad7d2bb); /* 63 */
-  II ( b, c, d, a, in[ 9], S44, 0xeb86d391); /* 64 */
-
-  buf[0] += a;
-  buf[1] += b;
-  buf[2] += c;
-  buf[3] += d;
-}
-
-/*
- ***********************************************************************
- ** End of md5.c                                                      **
- ******************************** (cut) ********************************
- */
diff --git a/src/mairix/md5.h b/src/mairix/md5.h
@@ -1,62 +0,0 @@
-/*
- ***********************************************************************
- ** md5.h -- header file for implementation of MD5                    **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
- ** Created: 2/17/90 RLR                                              **
- ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version               **
- ** Revised (for MD5): RLR 4/27/91                                    **
- ***********************************************************************
- */
-
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
- **                                                                   **
- ** License to copy and use this software is granted provided that    **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
- ** Digest Algorithm" in all material mentioning or referencing this  **
- ** software or this function.                                        **
- **                                                                   **
- ** License is also granted to make and use derivative works          **
- ** provided that such works are identified as "derived from the RSA  **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
- ** material mentioning or referencing the derived work.              **
- **                                                                   **
- ** RSA Data Security, Inc. makes no representations concerning       **
- ** either the merchantability of this software or the suitability    **
- ** of this software for any particular purpose.  It is provided "as  **
- ** is" without express or implied warranty of any kind.              **
- **                                                                   **
- ** These notices must be retained in any copies of any part of this  **
- ** documentation and/or software.                                    **
- ***********************************************************************
- */
-
-#ifdef HAS_STDINT_H
-#include <stdint.h>
-#elif defined(HAS_INTTYPES_H)
-#include <inttypes.h>
-#else
-#error "No <stdint.h> or <inttypes.h>"
-#endif
-
-/* typedef a 32-bit type */
-typedef uint32_t UINT4;
-
-/* Data structure for MD5 (Message-Digest) computation */
-typedef struct {
-  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
-  UINT4 buf[4];                                    /* scratch buffer */
-  unsigned char in[64];                              /* input buffer */
-  unsigned char digest[16];     /* actual digest after MD5Final call */
-} MD5_CTX;
-
-void MD5Init (MD5_CTX *mdContext);
-void MD5Update (MD5_CTX *, unsigned const char *, unsigned int);
-void MD5Final (MD5_CTX *);
-
-/*
- ***********************************************************************
- ** End of md5.h                                                      **
- ******************************** (cut) ********************************
- */
diff --git a/src/mairix/memmac.h b/src/mairix/memmac.h
@@ -1,72 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002-2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 MEMMAC_H
-#define MEMMAC_H
-
-/*{{{ Safe alloc helpers (GCC extensions) */
-extern void out_of_mem(char *file, int line, size_t size);
-
-#undef TEST_OOM
-
-#ifdef TEST_OOM
-extern int total_bytes;
-#endif
-
-static __inline__ void* safe_malloc(char *file, int line, size_t s)/*{{{*/
-{
-  void *x = malloc(s);
-#ifdef TEST_OOM
-  total_bytes += s;
-  if (total_bytes > 131072) x = NULL;
-#endif
-  if (!x) out_of_mem(file, line, s);
-  return x;
-}
-/*}}}*/
-static __inline__ void* safe_realloc(char *file, int line, void *old_ptr, size_t s)/*{{{*/
-{
-  void *x = realloc(old_ptr, s);
-  if (!x) out_of_mem(file, line, s);
-  return x;
-}
-/*}}}*/
-#ifndef TEST
-#define Malloc(s) safe_malloc(__FILE__, __LINE__, s)
-#define Realloc(xx,s) safe_realloc(__FILE__, __LINE__,xx,s)
-#else
-#define Malloc(s) malloc(s)
-#define Realloc(xx,s) realloc(xx,s)
-#endif
-/*}}}*/
-
-/*{{{  Memory macros*/
-#define new_string(s) strcpy((char *) Malloc(1+strlen(s)), (s))
-#define extend_string(x,s) (strcat(Realloc(x, (strlen(x)+strlen(s)+1)), s))
-#define new(T) (T *) Malloc(sizeof(T))
-#define new_array(T, n) (T *) Malloc(sizeof(T) * (n))
-#define grow_array(T, n, oldX) (T *) ((oldX) ? Realloc(oldX, (sizeof(T) * (n))) : Malloc(sizeof(T) * (n)))
-#define EMPTY(x) {&(x), &(x)}
-/*}}}*/
-
-#endif /* MEMMAC_H */
diff --git a/src/mairix/mkversion b/src/mairix/mkversion
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-rm -f version.h
-echo "#ifndef VERSION_H" > version.h
-echo "#define VERSION_H 1" >> version.h
-
-if [ -f version.txt ]; then
-	ver=`cat version.txt`
-	echo "#define PROGRAM_VERSION \"$ver\"" >> version.h
-else
-	echo "#define PROGRAM_VERSION \"DEVELOPMENT\"" >> version.h
-fi
-
-echo "#endif /* VERSION_H */" >> version.h
-
diff --git a/src/mairix/nvp.c b/src/mairix/nvp.c
@@ -1,416 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2006,2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#ifdef VERBOSE_TEST
-#define TEST 1
-#endif
-
-/* Parse name/value pairs from mail headers into a lookup table. */
-#include <stdio.h>
-#include <ctype.h>
-#include "mairix.h"
-#include "nvptypes.h"
-#include "nvpscan.h"
-#include "nvp.h"
-
-enum nvp_type {/*{{{*/
-  NVP_NAME,
-  NVP_MAJORMINOR,
-  NVP_NAMEVALUE
-};
-/*}}}*/
-struct nvp_entry {/*{{{*/
-  struct nvp_entry *next;
-  struct nvp_entry *prev;
-  enum nvp_type type;
-  char *lhs;
-  char *rhs;
-};
-/*}}}*/
-struct nvp {/*{{{*/
-  struct nvp_entry *first, *last;
-};
-/*}}}*/
-static void append(struct nvp *nvp, struct nvp_entry *ne)/*{{{*/
-{
-  ne->next = NULL;
-  ne->prev = nvp->last;
-  if (nvp->last) nvp->last->next = ne;
-  else nvp->first = ne;
-  nvp->last = ne;
-}
-/*}}}*/
-static void append_name(struct nvp *nvp, char *name)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = new(struct nvp_entry);
-  ne->type = NVP_NAME;
-  ne->lhs = new_string(name);
-  append(nvp, ne);
-}
-/*}}}*/
-static void append_majorminor(struct nvp *nvp, char *major, char *minor)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = new(struct nvp_entry);
-  ne->type = NVP_MAJORMINOR;
-  ne->lhs = new_string(major);
-  ne->rhs = new_string(minor);
-  append(nvp, ne);
-
-}
-/*}}}*/
-static void append_namevalue(struct nvp *nvp, char *name, char *value)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = new(struct nvp_entry);
-  ne->type = NVP_NAMEVALUE;
-  ne->lhs = new_string(name);
-  ne->rhs = new_string(value);
-  append(nvp, ne);
-}
-/*}}}*/
-static void combine_namevalue(struct nvp *nvp, char *name, char *value)/*{{{*/
-{
-  struct nvp_entry *n;
-  for (n=nvp->first; n; n=n->next) {
-    if (n->type == NVP_NAMEVALUE) {
-      if (!strcmp(n->lhs, name)) {
-        char *new_rhs;
-        new_rhs = new_array(char, strlen(n->rhs) + strlen(value) + 1);
-        strcpy(new_rhs, n->rhs);
-        strcat(new_rhs, value);
-        free(n->rhs);
-        n->rhs = new_rhs;
-        return;
-      }
-    }
-  }
-  /* No match : it's the first one */
-  append_namevalue(nvp, name, value);
-}
-/*}}}*/
-static void release_nvp(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *e, *ne;
-  for (e=nvp->first; e; e=ne) {
-    ne = e->next;
-    switch (e->type) {
-      case NVP_NAME:
-        free(e->lhs);
-        break;
-      case NVP_MAJORMINOR:
-      case NVP_NAMEVALUE:
-        free(e->lhs);
-        free(e->rhs);
-        break;
-    }
-    free(e);
-  }
-  free(nvp);
-}
-/*}}}*/
-struct nvp *make_nvp(struct msg_src *src, char *s, const char *pfx)/*{{{*/
-{
-  int current_state;
-  unsigned int tok;
-  char *q;
-  unsigned char qq;
-  char name[256];
-  char minor[256];
-  char value[256];
-  enum nvp_action last_action, current_action;
-  struct nvp *result;
-  size_t pfxlen;
-  char *nn, *mm, *vv;
-
-  pfxlen = strlen(pfx);
-  if (strncasecmp(pfx, s, pfxlen))
-    return NULL;
-  s += pfxlen;
-
-  result = new(struct nvp);
-  result->first = result->last = NULL;
-
-  current_state = nvp_in;
-
-  q = s;
-  nn = name;
-  mm = minor;
-  vv = value;
-  last_action = GOT_NOTHING;
-  do {
-    qq = *(unsigned char *) q;
-    if (qq) {
-      tok = nvp_char2tok[qq];
-    } else {
-      tok = nvp_EOS;
-    }
-    current_state = nvp_next_state(current_state, tok);
-#ifdef VERBOSE_TEST
-    fprintf(stderr, "Char %02x (%c) tok=%d new_current_state=%d\n",
-        qq, ((qq>=32) && (qq<=126)) ? qq : '.',
-        tok, current_state);
-#endif
-
-    if (current_state < 0) {
-#ifdef TEST
-      fprintf(stderr, "'%s' could not be parsed\n", s);
-#else
-      fprintf(stderr, "Header '%s%s' in %s could not be parsed\n",
-          pfx, s, format_msg_src(src));
-#endif
-      release_nvp(result);
-      return NULL;
-    }
-
-    switch (nvp_copier[current_state]) {
-      case COPY_TO_NAME:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "  COPY_TO_NAME\n");
-#endif
-        *nn++ = *q;
-        break;
-      case COPY_TO_MINOR:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "  COPY_TO_MINOR\n");
-#endif
-        *mm++ = *q;
-        break;
-      case COPY_TO_VALUE:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "  COPY_TO_VALUE\n");
-#endif
-        *vv++ = *q;
-        break;
-      case COPY_NOWHERE:
-        break;
-    }
-
-    current_action = nvp_action[current_state];
-    switch (current_action) {
-      case GOT_NAME:
-      case GOT_NAME_TRAILING_SPACE:
-      case GOT_MAJORMINOR:
-      case GOT_NAMEVALUE:
-      case GOT_NAMEVALUE_CONT:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "   Setting last action to %d\n", current_action);
-#endif
-        last_action = current_action;
-        break;
-      case GOT_TERMINATOR:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "   Hit terminator; last_action=%d\n", last_action);
-#endif
-        switch (last_action) {
-          case GOT_NAME:
-            *nn = 0;
-            append_name(result, name);
-            break;
-          case GOT_NAME_TRAILING_SPACE:
-            while (isspace(*--nn)) {}
-            *++nn = 0;
-            append_name(result, name);
-            break;
-          case GOT_MAJORMINOR:
-            *nn = 0;
-            *mm = 0;
-            append_majorminor(result, name, minor);
-            break;
-          case GOT_NAMEVALUE:
-            *nn = 0;
-            *vv = 0;
-            append_namevalue(result, name, value);
-            break;
-          case GOT_NAMEVALUE_CONT:
-            *nn = 0;
-            *vv = 0;
-            combine_namevalue(result, name, value);
-            break;
-          default:
-            break;
-        }
-        nn = name;
-        mm = minor;
-        vv = value;
-        break;
-      case GOT_NOTHING:
-        break;
-    }
-
-    q++;
-  } while (tok != nvp_EOS);
-
-  return result;
-}
-/*}}}*/
-void free_nvp(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne, *nne;
-  for (ne = nvp->first; ne; ne=nne) {
-    nne = ne->next;
-    switch (ne->type) {
-      case NVP_NAME:
-        free(ne->lhs);
-        break;
-      case NVP_MAJORMINOR:
-      case NVP_NAMEVALUE:
-        free(ne->lhs);
-        free(ne->rhs);
-        break;
-    }
-    free(ne);
-  }
-  free(nvp);
-}
-/*}}}*/
-const char *nvp_lookup(struct nvp *nvp, const char *name)/*{{{*/
-{
-  struct nvp_entry *ne;
-  for (ne = nvp->first; ne; ne=ne->next) {
-    if (ne->type == NVP_NAMEVALUE) {
-      if (!strcmp(ne->lhs, name)) {
-        return ne->rhs;
-      }
-    }
-  }
-  return NULL;
-}
-/*}}}*/
-const char *nvp_lookupcase(struct nvp *nvp, const char *name)/*{{{*/
-{
-  struct nvp_entry *ne;
-  for (ne = nvp->first; ne; ne=ne->next) {
-    if (ne->type == NVP_NAMEVALUE) {
-      if (!strcasecmp(ne->lhs, name)) {
-        return ne->rhs;
-      }
-    }
-  }
-  return NULL;
-}
-/*}}}*/
-
-void nvp_dump(struct nvp *nvp, FILE *out)/*{{{*/
-{
-  struct nvp_entry *ne;
-  fprintf(out, "----\n");
-  for (ne = nvp->first; ne; ne=ne->next) {
-    switch (ne->type) {
-      case NVP_NAME:
-        fprintf(out, "NAME: %s\n", ne->lhs);
-        break;
-      case NVP_MAJORMINOR:
-        fprintf(out, "MAJORMINOR: %s/%s\n", ne->lhs, ne->rhs);
-        break;
-      case NVP_NAMEVALUE:
-        fprintf(out, "NAMEVALUE: %s=%s\n", ne->lhs, ne->rhs);
-        break;
-    }
-  }
-}
-/*}}}*/
-
-/* In these cases, we only look at the first entry */
-const char *nvp_major(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = nvp->first;
-  if (ne) {
-    if (ne->type == NVP_MAJORMINOR) {
-      return ne->lhs;
-    } else {
-      return NULL;
-    }
-  } else {
-    return NULL;
-  }
-}
-/*}}}*/
-const char *nvp_minor(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = nvp->first;
-  if (ne) {
-    if (ne->type == NVP_MAJORMINOR) {
-      return ne->rhs;
-    } else {
-      return NULL;
-    }
-  } else {
-    return NULL;
-  }
-}
-/*}}}*/
-const char *nvp_first(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = nvp->first;
-  if (ne) {
-    if (ne->type == NVP_NAME) {
-      return ne->lhs;
-    } else {
-      return NULL;
-    }
-  } else {
-    return NULL;
-  }
-}
-/*}}}*/
-
-#ifdef TEST
-
-static void do_test(char *s)
-{
-  struct nvp *n;
-  n = make_nvp(NULL, s, "");
-  if (n) {
-    nvp_dump(n, stderr);
-    free_nvp(n);
-  }
-}
-
-
-int main (int argc, char **argv) {
-  struct nvp *n;
-#if 0
-  do_test("attachment; filename=\"foo.c\"; prot=ro");
-  do_test("attachment; filename= \"foo bar.c\" ;prot=ro");
-  do_test("attachment ; filename= \"foo bar.c\" ;prot= ro");
-  do_test("attachment ; filename= \"foo bar.c\" ;prot= ro");
-  do_test("attachment ; filename= \"foo ;  bar.c\" ;prot= ro");
-  do_test("attachment ; x*0=\"hi \"; x*1=\"there\"");
-#endif
-
-  do_test("application/vnd.ms-excel;       name=\"thequiz.xls\"");
-#if 0
-  do_test("inline; filename*0=\"aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj\t kkkkllll\"");
-  do_test(" text/plain ; name= \"foo bar.c\" ;prot= ro/rw; read/write; read= foo bar");
-#endif
-  return 0;
-}
-#endif
-
-
-
-
diff --git a/src/mairix/nvp.h b/src/mairix/nvp.h
@@ -1,38 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2006,2010
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 NVP_H
-#define NVP_H
-
-struct nvp;
-struct msg_src;
-extern struct nvp *make_nvp(struct msg_src *, char *, const char *);
-extern void free_nvp(struct nvp *);
-extern void nvp_dump(struct nvp *nvp, FILE *out);
-extern const char *nvp_major(struct nvp *n);
-extern const char *nvp_minor(struct nvp *n);
-extern const char *nvp_first(struct nvp *n);
-extern const char *nvp_lookup(struct nvp *n, const char *name);
-extern const char *nvp_lookupcase(struct nvp *n, const char *name);
-
-#endif
-
diff --git a/src/mairix/nvp.nfa b/src/mairix/nvp.nfa
@@ -1,197 +0,0 @@
-#########################################################################
-#
-# mairix - message index builder and finder for maildir folders.
-#
-# Copyright (C) Richard P. Curnow  2006,2007
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# 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.
-#
-# =======================================================================
-
-Tokens EOS
-Abbrev VALUE = [\041-~]~[\\";]
-Abbrev QVALUE = VALUE | [\011\040;] | <escape:in->out>
-Abbrev NAME1 = [0-9a-zA-Z_\-]
-Abbrev MINOR = NAME1 | [\.\-+]
-Abbrev OWS = <optwhite:in->out>
-
-%{
-#include "nvptypes.h"
-%}
-
-Block escape {
-    State in
-        [\\] ; [\\] -> out
-        [\\] ; ["]  -> out
-}
-
-Block optwhite {
-    State in
-        -> out
-        # I have seen headers with ^M in them...
-        [ \t\r] -> in
-}
-
-Block name {
-    # This needs to cope with embedded spaces, e.g. for mailers that write '7
-    # bit' instead of '7bit'
-    State in
-        NAME1 -> name1
-
-    State name1
-        = COPY_TO_NAME
-        = GOT_NAME
-        NAME1 -> name1
-        [ \t] -> name2
-        -> out
-
-    State name2
-        = COPY_TO_NAME
-        = GOT_NAME_TRAILING_SPACE
-        [ \t] -> name2
-        NAME1 -> name1
-        -> out
-
-    State out
-}
-
-Block value {
-    State in
-        VALUE -> v1
-    State v1
-        = COPY_TO_VALUE
-        -> out
-        VALUE -> v1
-}
-
-Block qvalue {
-    State in
-        ["] -> qv0
-
-    State qv0
-        QVALUE -> qv1
-
-    State qv1
-        = COPY_TO_VALUE
-        QVALUE -> qv1
-        -> qv2
-
-    State qv2
-        ["] -> out
-}
-
-Block digits {
-    State in
-        [0-9] -> out
-        [0-9] -> in
-}
-
-Block namevalue {
-    State in
-        OWS ; <name:in->out> ; OWS ; [=] -> rhs_normal
-        OWS ; <name:in->out> ; [*] ; <digits:in->out> ; OWS ; [=] -> rhs_continue
-
-    State rhs_normal
-        OWS ; <qvalue:in->out> ; OWS -> out_normal
-        OWS ; <value:in->out> ; OWS -> out_normal
-        OWS ; ; EOS -> out_normal
-
-    State rhs_continue
-        OWS ; <qvalue:in->out> ; OWS -> out_continue
-        OWS ; <value:in->out> ; OWS -> out_continue
-
-    State out_normal = GOT_NAMEVALUE
-        -> out
-    State out_continue = GOT_NAMEVALUE_CONT
-        -> out
-}
-
-Block major {
-    State in
-        NAME1 -> name1
-
-    State name1
-        NAME1 -> name1
-        -> out
-}
-
-Block minor {
-    State in
-        MINOR -> minor1
-
-    State minor1
-        = COPY_TO_MINOR
-        MINOR -> minor1
-        -> out
-}
-
-Block majorminor {
-    State in
-        <major:in->out> -> foo
-
-    State foo
-        [/] -> bar
-
-    State bar
-        <minor:in->out> -> out
-
-    State out = GOT_MAJORMINOR
-}
-
-Block component {
-    State in
-        <namevalue:in->out> -> out
-        <name:in->out> -> out
-        <majorminor:in->out> -> out
-}
-
-Block main {
-    State in Entry in
-        OWS ; <component:in->out> ; OWS ; EOS -> out2
-        OWS ; <component:in->out> ; OWS ; [;] ; OWS ; EOS -> out2
-        OWS ; <component:in->out> ; OWS ; [;] -> in2
-        
-    State in2
-        = GOT_TERMINATOR
-        -> in
-
-    State out2
-        = GOT_TERMINATOR
-        -> out
-}
-
-Defattr 0
-Prefix nvp
-
-Group action {
-    Attr GOT_NAMEVALUE
-    Attr GOT_NAMEVALUE_CONT
-    Attr GOT_NAME
-    Attr GOT_NAME_TRAILING_SPACE
-    Attr GOT_MAJORMINOR
-    Attr GOT_TERMINATOR
-    Defattr GOT_NOTHING
-    Type "enum nvp_action"
-}
-
-Group copier {
-    Attr COPY_TO_NAME
-    Attr COPY_TO_MINOR
-    Attr COPY_TO_VALUE
-    Defattr COPY_NOWHERE
-    Type "enum nvp_copier"
-}
-
-# vim:et:sts=4:sw=4:ht=8
-
diff --git a/src/mairix/nvpscan.report b/src/mairix/nvpscan.report
@@ -1,6352 +0,0 @@
-Processing 1 separate entry points
-Entries in 1 blocks, total of 415 states
-NFA state 0 = main.in [Entries: in]
-  [(epsilon)] -> optwhite#8.in
-  [(epsilon)] -> optwhite#4.in
-  [(epsilon)] -> optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.#1
-    main.optwhite#1.in
-    main.optwhite#1.out
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-    main.#4
-    main.optwhite#4.in
-    main.optwhite#4.out
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-    main.#9
-    main.optwhite#8.in
-    main.optwhite#8.out
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-NFA state 1 = main.#1
-  [(epsilon)] -> component#2.in
-  Epsilon closure :
-    (self)
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-
-NFA state 2 = main.optwhite#1.in
-  [(epsilon)] -> optwhite#1.out
-   0:[\t ] -> optwhite#1.in
-   1:[\r] -> optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.#1
-    main.optwhite#1.out
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-
-NFA state 3 = main.optwhite#1.out
-  [(epsilon)] -> #1
-  Epsilon closure :
-    (self)
-    main.#1
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-
-NFA state 4 = main.#2
-  [(epsilon)] -> optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 5 = main.component#2.in
-  [(epsilon)] -> component#2.namevalue#1.in
-  [(epsilon)] -> component#2.name#2.in
-  [(epsilon)] -> component#2.majorminor#3.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-
-NFA state 6 = main.component#2.namevalue#1.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#4.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-
-NFA state 7 = main.component#2.namevalue#1.#1
-  [(epsilon)] -> component#2.namevalue#1.name#2.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.name#2.in
-
-NFA state 8 = main.component#2.namevalue#1.optwhite#1.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#1.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#1.in
-   1:[\r] -> component#2.namevalue#1.optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-
-NFA state 9 = main.component#2.namevalue#1.optwhite#1.out
-  [(epsilon)] -> component#2.namevalue#1.#1
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.name#2.in
-
-NFA state 10 = main.component#2.namevalue#1.#2
-  [(epsilon)] -> component#2.namevalue#1.optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-
-NFA state 11 = main.component#2.namevalue#1.name#2.in
-   6:[\055] -> component#2.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#2.namevalue#1.name#2.name1
-   8:[0-9] -> component#2.namevalue#1.name#2.name1
-  Epsilon closure :
-    (self)
-
-NFA state 12 = main.component#2.namevalue#1.name#2.name1
-  [(epsilon)] -> component#2.namevalue#1.name#2.#1
-  [(epsilon)] -> component#2.namevalue#1.name#2.#2
-   6:[\055] -> component#2.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#2.namevalue#1.name#2.name1
-   8:[0-9] -> component#2.namevalue#1.name#2.name1
-   0:[\t ] -> component#2.namevalue#1.name#2.name2
-  [(epsilon)] -> component#2.namevalue#1.name#2.out
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#2
-    main.component#2.namevalue#1.name#2.#1
-    main.component#2.namevalue#1.name#2.#2
-    main.component#2.namevalue#1.name#2.out
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-
-NFA state 13 = main.component#2.namevalue#1.name#2.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 14 = main.component#2.namevalue#1.name#2.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 15 = main.component#2.namevalue#1.name#2.name2
-  [(epsilon)] -> component#2.namevalue#1.name#2.#3
-  [(epsilon)] -> component#2.namevalue#1.name#2.#4
-   0:[\t ] -> component#2.namevalue#1.name#2.name2
-   6:[\055] -> component#2.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#2.namevalue#1.name#2.name1
-   8:[0-9] -> component#2.namevalue#1.name#2.name1
-  [(epsilon)] -> component#2.namevalue#1.name#2.out
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#2
-    main.component#2.namevalue#1.name#2.#3
-    main.component#2.namevalue#1.name#2.#4
-    main.component#2.namevalue#1.name#2.out
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-
-NFA state 16 = main.component#2.namevalue#1.name#2.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 17 = main.component#2.namevalue#1.name#2.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 18 = main.component#2.namevalue#1.name#2.out
-  [(epsilon)] -> component#2.namevalue#1.#2
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#2
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-
-NFA state 19 = main.component#2.namevalue#1.#3
-   10:[=] -> component#2.namevalue#1.rhs_normal
-  Epsilon closure :
-    (self)
-
-NFA state 20 = main.component#2.namevalue#1.optwhite#3.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#3.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#3.in
-   1:[\r] -> component#2.namevalue#1.optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.out
-
-NFA state 21 = main.component#2.namevalue#1.optwhite#3.out
-  [(epsilon)] -> component#2.namevalue#1.#3
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#3
-
-NFA state 22 = main.component#2.namevalue#1.#4
-  [(epsilon)] -> component#2.namevalue#1.name#5.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.name#5.in
-
-NFA state 23 = main.component#2.namevalue#1.optwhite#4.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#4.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#4.in
-   1:[\r] -> component#2.namevalue#1.optwhite#4.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-
-NFA state 24 = main.component#2.namevalue#1.optwhite#4.out
-  [(epsilon)] -> component#2.namevalue#1.#4
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.name#5.in
-
-NFA state 25 = main.component#2.namevalue#1.#5
-   4:[*] -> component#2.namevalue#1.#6
-  Epsilon closure :
-    (self)
-
-NFA state 26 = main.component#2.namevalue#1.name#5.in
-   6:[\055] -> component#2.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#2.namevalue#1.name#5.name1
-   8:[0-9] -> component#2.namevalue#1.name#5.name1
-  Epsilon closure :
-    (self)
-
-NFA state 27 = main.component#2.namevalue#1.name#5.name1
-  [(epsilon)] -> component#2.namevalue#1.name#5.#1
-  [(epsilon)] -> component#2.namevalue#1.name#5.#2
-   6:[\055] -> component#2.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#2.namevalue#1.name#5.name1
-   8:[0-9] -> component#2.namevalue#1.name#5.name1
-   0:[\t ] -> component#2.namevalue#1.name#5.name2
-  [(epsilon)] -> component#2.namevalue#1.name#5.out
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#5
-    main.component#2.namevalue#1.name#5.#1
-    main.component#2.namevalue#1.name#5.#2
-    main.component#2.namevalue#1.name#5.out
-
-NFA state 28 = main.component#2.namevalue#1.name#5.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 29 = main.component#2.namevalue#1.name#5.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 30 = main.component#2.namevalue#1.name#5.name2
-  [(epsilon)] -> component#2.namevalue#1.name#5.#3
-  [(epsilon)] -> component#2.namevalue#1.name#5.#4
-   0:[\t ] -> component#2.namevalue#1.name#5.name2
-   6:[\055] -> component#2.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#2.namevalue#1.name#5.name1
-   8:[0-9] -> component#2.namevalue#1.name#5.name1
-  [(epsilon)] -> component#2.namevalue#1.name#5.out
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#5
-    main.component#2.namevalue#1.name#5.#3
-    main.component#2.namevalue#1.name#5.#4
-    main.component#2.namevalue#1.name#5.out
-
-NFA state 31 = main.component#2.namevalue#1.name#5.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 32 = main.component#2.namevalue#1.name#5.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 33 = main.component#2.namevalue#1.name#5.out
-  [(epsilon)] -> component#2.namevalue#1.#5
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#5
-
-NFA state 34 = main.component#2.namevalue#1.#6
-  [(epsilon)] -> component#2.namevalue#1.digits#6.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.digits#6.in
-
-NFA state 35 = main.component#2.namevalue#1.#7
-  [(epsilon)] -> component#2.namevalue#1.optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#8
-    main.component#2.namevalue#1.optwhite#7.in
-    main.component#2.namevalue#1.optwhite#7.out
-
-NFA state 36 = main.component#2.namevalue#1.digits#6.in
-   8:[0-9] -> component#2.namevalue#1.digits#6.out
-   8:[0-9] -> component#2.namevalue#1.digits#6.in
-  Epsilon closure :
-    (self)
-
-NFA state 37 = main.component#2.namevalue#1.digits#6.out
-  [(epsilon)] -> component#2.namevalue#1.#7
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#7
-    main.component#2.namevalue#1.#8
-    main.component#2.namevalue#1.optwhite#7.in
-    main.component#2.namevalue#1.optwhite#7.out
-
-NFA state 38 = main.component#2.namevalue#1.#8
-   10:[=] -> component#2.namevalue#1.rhs_continue
-  Epsilon closure :
-    (self)
-
-NFA state 39 = main.component#2.namevalue#1.optwhite#7.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#7.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#7.in
-   1:[\r] -> component#2.namevalue#1.optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#8
-    main.component#2.namevalue#1.optwhite#7.out
-
-NFA state 40 = main.component#2.namevalue#1.optwhite#7.out
-  [(epsilon)] -> component#2.namevalue#1.#8
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#8
-
-NFA state 41 = main.component#2.namevalue#1.rhs_normal
-  [(epsilon)] -> component#2.namevalue#1.optwhite#14.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#11.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#8.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#9
-    main.component#2.namevalue#1.optwhite#8.in
-    main.component#2.namevalue#1.optwhite#8.out
-    main.component#2.namevalue#1.qvalue#9.in
-    main.component#2.namevalue#1.#11
-    main.component#2.namevalue#1.optwhite#11.in
-    main.component#2.namevalue#1.optwhite#11.out
-    main.component#2.namevalue#1.value#12.in
-    main.component#2.namevalue#1.#13
-    main.component#2.namevalue#1.optwhite#14.in
-    main.component#2.namevalue#1.optwhite#14.out
-    main.component#2.namevalue#1.#14
-
-NFA state 42 = main.component#2.namevalue#1.#9
-  [(epsilon)] -> component#2.namevalue#1.qvalue#9.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#9.in
-
-NFA state 43 = main.component#2.namevalue#1.optwhite#8.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#8.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#8.in
-   1:[\r] -> component#2.namevalue#1.optwhite#8.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#9
-    main.component#2.namevalue#1.optwhite#8.out
-    main.component#2.namevalue#1.qvalue#9.in
-
-NFA state 44 = main.component#2.namevalue#1.optwhite#8.out
-  [(epsilon)] -> component#2.namevalue#1.#9
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#9
-    main.component#2.namevalue#1.qvalue#9.in
-
-NFA state 45 = main.component#2.namevalue#1.#10
-  [(epsilon)] -> component#2.namevalue#1.optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#10.in
-    main.component#2.namevalue#1.optwhite#10.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 46 = main.component#2.namevalue#1.qvalue#9.in
-   3:["] -> component#2.namevalue#1.qvalue#9.qv0
-  Epsilon closure :
-    (self)
-
-NFA state 47 = main.component#2.namevalue#1.qvalue#9.qv0
-  [(epsilon)] -> component#2.namevalue#1.qvalue#9.escape#1.in
-   0:[\t ] -> component#2.namevalue#1.qvalue#9.qv1
-   9:[;] -> component#2.namevalue#1.qvalue#9.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.qvalue#9.qv1
-   11:[A-Z_a-z] -> component#2.namevalue#1.qvalue#9.qv1
-   10:[=] -> component#2.namevalue#1.qvalue#9.qv1
-   8:[0-9] -> component#2.namevalue#1.qvalue#9.qv1
-   7:[/] -> component#2.namevalue#1.qvalue#9.qv1
-   6:[\055] -> component#2.namevalue#1.qvalue#9.qv1
-   5:[+.] -> component#2.namevalue#1.qvalue#9.qv1
-   4:[*] -> component#2.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#9.escape#1.in
-
-NFA state 48 = main.component#2.namevalue#1.qvalue#9.escape#1.in
-   12:[\\] -> component#2.namevalue#1.qvalue#9.escape#1.#2
-   12:[\\] -> component#2.namevalue#1.qvalue#9.escape#1.#1
-  Epsilon closure :
-    (self)
-
-NFA state 49 = main.component#2.namevalue#1.qvalue#9.escape#1.#1
-   12:[\\] -> component#2.namevalue#1.qvalue#9.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 50 = main.component#2.namevalue#1.qvalue#9.escape#1.#2
-   3:["] -> component#2.namevalue#1.qvalue#9.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 51 = main.component#2.namevalue#1.qvalue#9.escape#1.out
-  [(epsilon)] -> component#2.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#9.qv1
-    main.component#2.namevalue#1.qvalue#9.#1
-    main.component#2.namevalue#1.qvalue#9.escape#2.in
-    main.component#2.namevalue#1.qvalue#9.qv2
-
-NFA state 52 = main.component#2.namevalue#1.qvalue#9.qv1
-  [(epsilon)] -> component#2.namevalue#1.qvalue#9.#1
-  [(epsilon)] -> component#2.namevalue#1.qvalue#9.escape#2.in
-   0:[\t ] -> component#2.namevalue#1.qvalue#9.qv1
-   9:[;] -> component#2.namevalue#1.qvalue#9.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.qvalue#9.qv1
-   11:[A-Z_a-z] -> component#2.namevalue#1.qvalue#9.qv1
-   10:[=] -> component#2.namevalue#1.qvalue#9.qv1
-   8:[0-9] -> component#2.namevalue#1.qvalue#9.qv1
-   7:[/] -> component#2.namevalue#1.qvalue#9.qv1
-   6:[\055] -> component#2.namevalue#1.qvalue#9.qv1
-   5:[+.] -> component#2.namevalue#1.qvalue#9.qv1
-   4:[*] -> component#2.namevalue#1.qvalue#9.qv1
-  [(epsilon)] -> component#2.namevalue#1.qvalue#9.qv2
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#9.#1
-    main.component#2.namevalue#1.qvalue#9.escape#2.in
-    main.component#2.namevalue#1.qvalue#9.qv2
-
-NFA state 53 = main.component#2.namevalue#1.qvalue#9.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 54 = main.component#2.namevalue#1.qvalue#9.escape#2.in
-   12:[\\] -> component#2.namevalue#1.qvalue#9.escape#2.#2
-   12:[\\] -> component#2.namevalue#1.qvalue#9.escape#2.#1
-  Epsilon closure :
-    (self)
-
-NFA state 55 = main.component#2.namevalue#1.qvalue#9.escape#2.#1
-   12:[\\] -> component#2.namevalue#1.qvalue#9.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 56 = main.component#2.namevalue#1.qvalue#9.escape#2.#2
-   3:["] -> component#2.namevalue#1.qvalue#9.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 57 = main.component#2.namevalue#1.qvalue#9.escape#2.out
-  [(epsilon)] -> component#2.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#9.qv1
-    main.component#2.namevalue#1.qvalue#9.#1
-    main.component#2.namevalue#1.qvalue#9.escape#2.in
-    main.component#2.namevalue#1.qvalue#9.qv2
-
-NFA state 58 = main.component#2.namevalue#1.qvalue#9.qv2
-   3:["] -> component#2.namevalue#1.qvalue#9.out
-  Epsilon closure :
-    (self)
-
-NFA state 59 = main.component#2.namevalue#1.qvalue#9.out
-  [(epsilon)] -> component#2.namevalue#1.#10
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#10
-    main.component#2.namevalue#1.optwhite#10.in
-    main.component#2.namevalue#1.optwhite#10.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 60 = main.component#2.namevalue#1.optwhite#10.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#10.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#10.in
-   1:[\r] -> component#2.namevalue#1.optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#10.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 61 = main.component#2.namevalue#1.optwhite#10.out
-  [(epsilon)] -> component#2.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 62 = main.component#2.namevalue#1.#11
-  [(epsilon)] -> component#2.namevalue#1.value#12.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.value#12.in
-
-NFA state 63 = main.component#2.namevalue#1.optwhite#11.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#11.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#11.in
-   1:[\r] -> component#2.namevalue#1.optwhite#11.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#11
-    main.component#2.namevalue#1.optwhite#11.out
-    main.component#2.namevalue#1.value#12.in
-
-NFA state 64 = main.component#2.namevalue#1.optwhite#11.out
-  [(epsilon)] -> component#2.namevalue#1.#11
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#11
-    main.component#2.namevalue#1.value#12.in
-
-NFA state 65 = main.component#2.namevalue#1.#12
-  [(epsilon)] -> component#2.namevalue#1.optwhite#13.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#13.in
-    main.component#2.namevalue#1.optwhite#13.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 66 = main.component#2.namevalue#1.value#12.in
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.value#12.v1
-   11:[A-Z_a-z] -> component#2.namevalue#1.value#12.v1
-   10:[=] -> component#2.namevalue#1.value#12.v1
-   8:[0-9] -> component#2.namevalue#1.value#12.v1
-   7:[/] -> component#2.namevalue#1.value#12.v1
-   6:[\055] -> component#2.namevalue#1.value#12.v1
-   5:[+.] -> component#2.namevalue#1.value#12.v1
-   4:[*] -> component#2.namevalue#1.value#12.v1
-  Epsilon closure :
-    (self)
-
-NFA state 67 = main.component#2.namevalue#1.value#12.v1
-  [(epsilon)] -> component#2.namevalue#1.value#12.#1
-  [(epsilon)] -> component#2.namevalue#1.value#12.out
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.value#12.v1
-   11:[A-Z_a-z] -> component#2.namevalue#1.value#12.v1
-   10:[=] -> component#2.namevalue#1.value#12.v1
-   8:[0-9] -> component#2.namevalue#1.value#12.v1
-   7:[/] -> component#2.namevalue#1.value#12.v1
-   6:[\055] -> component#2.namevalue#1.value#12.v1
-   5:[+.] -> component#2.namevalue#1.value#12.v1
-   4:[*] -> component#2.namevalue#1.value#12.v1
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#12
-    main.component#2.namevalue#1.value#12.#1
-    main.component#2.namevalue#1.value#12.out
-    main.component#2.namevalue#1.optwhite#13.in
-    main.component#2.namevalue#1.optwhite#13.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 68 = main.component#2.namevalue#1.value#12.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 69 = main.component#2.namevalue#1.value#12.out
-  [(epsilon)] -> component#2.namevalue#1.#12
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#12
-    main.component#2.namevalue#1.optwhite#13.in
-    main.component#2.namevalue#1.optwhite#13.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 70 = main.component#2.namevalue#1.optwhite#13.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#13.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#13.in
-   1:[\r] -> component#2.namevalue#1.optwhite#13.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#13.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 71 = main.component#2.namevalue#1.optwhite#13.out
-  [(epsilon)] -> component#2.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 72 = main.component#2.namevalue#1.#13
-  [(epsilon)] -> component#2.namevalue#1.#14
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#14
-
-NFA state 73 = main.component#2.namevalue#1.optwhite#14.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#14.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#14.in
-   1:[\r] -> component#2.namevalue#1.optwhite#14.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#13
-    main.component#2.namevalue#1.optwhite#14.out
-    main.component#2.namevalue#1.#14
-
-NFA state 74 = main.component#2.namevalue#1.optwhite#14.out
-  [(epsilon)] -> component#2.namevalue#1.#13
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#13
-    main.component#2.namevalue#1.#14
-
-NFA state 75 = main.component#2.namevalue#1.#14
-  EOS -> component#2.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-
-NFA state 76 = main.component#2.namevalue#1.rhs_continue
-  [(epsilon)] -> component#2.namevalue#1.optwhite#18.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#15.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#15
-    main.component#2.namevalue#1.optwhite#15.in
-    main.component#2.namevalue#1.optwhite#15.out
-    main.component#2.namevalue#1.qvalue#16.in
-    main.component#2.namevalue#1.#17
-    main.component#2.namevalue#1.optwhite#18.in
-    main.component#2.namevalue#1.optwhite#18.out
-    main.component#2.namevalue#1.value#19.in
-
-NFA state 77 = main.component#2.namevalue#1.#15
-  [(epsilon)] -> component#2.namevalue#1.qvalue#16.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#16.in
-
-NFA state 78 = main.component#2.namevalue#1.optwhite#15.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#15.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#15.in
-   1:[\r] -> component#2.namevalue#1.optwhite#15.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#15
-    main.component#2.namevalue#1.optwhite#15.out
-    main.component#2.namevalue#1.qvalue#16.in
-
-NFA state 79 = main.component#2.namevalue#1.optwhite#15.out
-  [(epsilon)] -> component#2.namevalue#1.#15
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#15
-    main.component#2.namevalue#1.qvalue#16.in
-
-NFA state 80 = main.component#2.namevalue#1.#16
-  [(epsilon)] -> component#2.namevalue#1.optwhite#17.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#17.in
-    main.component#2.namevalue#1.optwhite#17.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 81 = main.component#2.namevalue#1.qvalue#16.in
-   3:["] -> component#2.namevalue#1.qvalue#16.qv0
-  Epsilon closure :
-    (self)
-
-NFA state 82 = main.component#2.namevalue#1.qvalue#16.qv0
-  [(epsilon)] -> component#2.namevalue#1.qvalue#16.escape#1.in
-   0:[\t ] -> component#2.namevalue#1.qvalue#16.qv1
-   9:[;] -> component#2.namevalue#1.qvalue#16.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.qvalue#16.qv1
-   11:[A-Z_a-z] -> component#2.namevalue#1.qvalue#16.qv1
-   10:[=] -> component#2.namevalue#1.qvalue#16.qv1
-   8:[0-9] -> component#2.namevalue#1.qvalue#16.qv1
-   7:[/] -> component#2.namevalue#1.qvalue#16.qv1
-   6:[\055] -> component#2.namevalue#1.qvalue#16.qv1
-   5:[+.] -> component#2.namevalue#1.qvalue#16.qv1
-   4:[*] -> component#2.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#16.escape#1.in
-
-NFA state 83 = main.component#2.namevalue#1.qvalue#16.escape#1.in
-   12:[\\] -> component#2.namevalue#1.qvalue#16.escape#1.#2
-   12:[\\] -> component#2.namevalue#1.qvalue#16.escape#1.#1
-  Epsilon closure :
-    (self)
-
-NFA state 84 = main.component#2.namevalue#1.qvalue#16.escape#1.#1
-   12:[\\] -> component#2.namevalue#1.qvalue#16.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 85 = main.component#2.namevalue#1.qvalue#16.escape#1.#2
-   3:["] -> component#2.namevalue#1.qvalue#16.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 86 = main.component#2.namevalue#1.qvalue#16.escape#1.out
-  [(epsilon)] -> component#2.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#16.qv1
-    main.component#2.namevalue#1.qvalue#16.#1
-    main.component#2.namevalue#1.qvalue#16.escape#2.in
-    main.component#2.namevalue#1.qvalue#16.qv2
-
-NFA state 87 = main.component#2.namevalue#1.qvalue#16.qv1
-  [(epsilon)] -> component#2.namevalue#1.qvalue#16.#1
-  [(epsilon)] -> component#2.namevalue#1.qvalue#16.escape#2.in
-   0:[\t ] -> component#2.namevalue#1.qvalue#16.qv1
-   9:[;] -> component#2.namevalue#1.qvalue#16.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.qvalue#16.qv1
-   11:[A-Z_a-z] -> component#2.namevalue#1.qvalue#16.qv1
-   10:[=] -> component#2.namevalue#1.qvalue#16.qv1
-   8:[0-9] -> component#2.namevalue#1.qvalue#16.qv1
-   7:[/] -> component#2.namevalue#1.qvalue#16.qv1
-   6:[\055] -> component#2.namevalue#1.qvalue#16.qv1
-   5:[+.] -> component#2.namevalue#1.qvalue#16.qv1
-   4:[*] -> component#2.namevalue#1.qvalue#16.qv1
-  [(epsilon)] -> component#2.namevalue#1.qvalue#16.qv2
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#16.#1
-    main.component#2.namevalue#1.qvalue#16.escape#2.in
-    main.component#2.namevalue#1.qvalue#16.qv2
-
-NFA state 88 = main.component#2.namevalue#1.qvalue#16.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 89 = main.component#2.namevalue#1.qvalue#16.escape#2.in
-   12:[\\] -> component#2.namevalue#1.qvalue#16.escape#2.#2
-   12:[\\] -> component#2.namevalue#1.qvalue#16.escape#2.#1
-  Epsilon closure :
-    (self)
-
-NFA state 90 = main.component#2.namevalue#1.qvalue#16.escape#2.#1
-   12:[\\] -> component#2.namevalue#1.qvalue#16.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 91 = main.component#2.namevalue#1.qvalue#16.escape#2.#2
-   3:["] -> component#2.namevalue#1.qvalue#16.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 92 = main.component#2.namevalue#1.qvalue#16.escape#2.out
-  [(epsilon)] -> component#2.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.qvalue#16.qv1
-    main.component#2.namevalue#1.qvalue#16.#1
-    main.component#2.namevalue#1.qvalue#16.escape#2.in
-    main.component#2.namevalue#1.qvalue#16.qv2
-
-NFA state 93 = main.component#2.namevalue#1.qvalue#16.qv2
-   3:["] -> component#2.namevalue#1.qvalue#16.out
-  Epsilon closure :
-    (self)
-
-NFA state 94 = main.component#2.namevalue#1.qvalue#16.out
-  [(epsilon)] -> component#2.namevalue#1.#16
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#16
-    main.component#2.namevalue#1.optwhite#17.in
-    main.component#2.namevalue#1.optwhite#17.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 95 = main.component#2.namevalue#1.optwhite#17.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#17.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#17.in
-   1:[\r] -> component#2.namevalue#1.optwhite#17.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#17.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 96 = main.component#2.namevalue#1.optwhite#17.out
-  [(epsilon)] -> component#2.namevalue#1.out_continue
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 97 = main.component#2.namevalue#1.#17
-  [(epsilon)] -> component#2.namevalue#1.value#19.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.value#19.in
-
-NFA state 98 = main.component#2.namevalue#1.optwhite#18.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#18.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#18.in
-   1:[\r] -> component#2.namevalue#1.optwhite#18.in
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#17
-    main.component#2.namevalue#1.optwhite#18.out
-    main.component#2.namevalue#1.value#19.in
-
-NFA state 99 = main.component#2.namevalue#1.optwhite#18.out
-  [(epsilon)] -> component#2.namevalue#1.#17
-  Epsilon closure :
-    (self)
-    main.component#2.namevalue#1.#17
-    main.component#2.namevalue#1.value#19.in
-
-NFA state 100 = main.component#2.namevalue#1.#18
-  [(epsilon)] -> component#2.namevalue#1.optwhite#20.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#20.in
-    main.component#2.namevalue#1.optwhite#20.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 101 = main.component#2.namevalue#1.value#19.in
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.value#19.v1
-   11:[A-Z_a-z] -> component#2.namevalue#1.value#19.v1
-   10:[=] -> component#2.namevalue#1.value#19.v1
-   8:[0-9] -> component#2.namevalue#1.value#19.v1
-   7:[/] -> component#2.namevalue#1.value#19.v1
-   6:[\055] -> component#2.namevalue#1.value#19.v1
-   5:[+.] -> component#2.namevalue#1.value#19.v1
-   4:[*] -> component#2.namevalue#1.value#19.v1
-  Epsilon closure :
-    (self)
-
-NFA state 102 = main.component#2.namevalue#1.value#19.v1
-  [(epsilon)] -> component#2.namevalue#1.value#19.#1
-  [(epsilon)] -> component#2.namevalue#1.value#19.out
-   2:[!#-),:<>-@[]^`{-~] -> component#2.namevalue#1.value#19.v1
-   11:[A-Z_a-z] -> component#2.namevalue#1.value#19.v1
-   10:[=] -> component#2.namevalue#1.value#19.v1
-   8:[0-9] -> component#2.namevalue#1.value#19.v1
-   7:[/] -> component#2.namevalue#1.value#19.v1
-   6:[\055] -> component#2.namevalue#1.value#19.v1
-   5:[+.] -> component#2.namevalue#1.value#19.v1
-   4:[*] -> component#2.namevalue#1.value#19.v1
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#18
-    main.component#2.namevalue#1.value#19.#1
-    main.component#2.namevalue#1.value#19.out
-    main.component#2.namevalue#1.optwhite#20.in
-    main.component#2.namevalue#1.optwhite#20.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 103 = main.component#2.namevalue#1.value#19.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 104 = main.component#2.namevalue#1.value#19.out
-  [(epsilon)] -> component#2.namevalue#1.#18
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#18
-    main.component#2.namevalue#1.optwhite#20.in
-    main.component#2.namevalue#1.optwhite#20.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 105 = main.component#2.namevalue#1.optwhite#20.in
-  [(epsilon)] -> component#2.namevalue#1.optwhite#20.out
-   0:[\t ] -> component#2.namevalue#1.optwhite#20.in
-   1:[\r] -> component#2.namevalue#1.optwhite#20.in
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.optwhite#20.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 106 = main.component#2.namevalue#1.optwhite#20.out
-  [(epsilon)] -> component#2.namevalue#1.out_continue
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 107 = main.component#2.namevalue#1.out_normal
-  [(epsilon)] -> component#2.namevalue#1.out
-  [(epsilon)] -> component#2.namevalue#1.#19
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 108 = main.component#2.namevalue#1.#19
-  Tags : GOT_NAMEVALUE
-  Epsilon closure :
-    (self)
-
-NFA state 109 = main.component#2.namevalue#1.out_continue
-  [(epsilon)] -> component#2.namevalue#1.out
-  [(epsilon)] -> component#2.namevalue#1.#20
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 110 = main.component#2.namevalue#1.#20
-  Tags : GOT_NAMEVALUE_CONT
-  Epsilon closure :
-    (self)
-
-NFA state 111 = main.component#2.namevalue#1.out
-  [(epsilon)] -> component#2.out
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 112 = main.component#2.name#2.in
-   6:[\055] -> component#2.name#2.name1
-   11:[A-Z_a-z] -> component#2.name#2.name1
-   8:[0-9] -> component#2.name#2.name1
-  Epsilon closure :
-    (self)
-
-NFA state 113 = main.component#2.name#2.name1
-  [(epsilon)] -> component#2.name#2.out
-   0:[\t ] -> component#2.name#2.name2
-   6:[\055] -> component#2.name#2.name1
-   11:[A-Z_a-z] -> component#2.name#2.name1
-   8:[0-9] -> component#2.name#2.name1
-  [(epsilon)] -> component#2.name#2.#2
-  [(epsilon)] -> component#2.name#2.#1
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.name#2.#1
-    main.component#2.name#2.#2
-    main.component#2.name#2.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 114 = main.component#2.name#2.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 115 = main.component#2.name#2.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 116 = main.component#2.name#2.name2
-  [(epsilon)] -> component#2.name#2.out
-   6:[\055] -> component#2.name#2.name1
-   11:[A-Z_a-z] -> component#2.name#2.name1
-   8:[0-9] -> component#2.name#2.name1
-   0:[\t ] -> component#2.name#2.name2
-  [(epsilon)] -> component#2.name#2.#4
-  [(epsilon)] -> component#2.name#2.#3
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.name#2.#3
-    main.component#2.name#2.#4
-    main.component#2.name#2.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 117 = main.component#2.name#2.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 118 = main.component#2.name#2.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 119 = main.component#2.name#2.out
-  [(epsilon)] -> component#2.out
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 120 = main.component#2.majorminor#3.in
-  [(epsilon)] -> component#2.majorminor#3.major#1.in
-  Epsilon closure :
-    (self)
-    main.component#2.majorminor#3.major#1.in
-
-NFA state 121 = main.component#2.majorminor#3.major#1.in
-   6:[\055] -> component#2.majorminor#3.major#1.name1
-   11:[A-Z_a-z] -> component#2.majorminor#3.major#1.name1
-   8:[0-9] -> component#2.majorminor#3.major#1.name1
-  Epsilon closure :
-    (self)
-
-NFA state 122 = main.component#2.majorminor#3.major#1.name1
-   6:[\055] -> component#2.majorminor#3.major#1.name1
-   11:[A-Z_a-z] -> component#2.majorminor#3.major#1.name1
-   8:[0-9] -> component#2.majorminor#3.major#1.name1
-  [(epsilon)] -> component#2.majorminor#3.major#1.out
-  Epsilon closure :
-    (self)
-    main.component#2.majorminor#3.major#1.out
-    main.component#2.majorminor#3.foo
-
-NFA state 123 = main.component#2.majorminor#3.major#1.out
-  [(epsilon)] -> component#2.majorminor#3.foo
-  Epsilon closure :
-    (self)
-    main.component#2.majorminor#3.foo
-
-NFA state 124 = main.component#2.majorminor#3.foo
-   7:[/] -> component#2.majorminor#3.bar
-  Epsilon closure :
-    (self)
-
-NFA state 125 = main.component#2.majorminor#3.bar
-  [(epsilon)] -> component#2.majorminor#3.minor#2.in
-  Epsilon closure :
-    (self)
-    main.component#2.majorminor#3.minor#2.in
-
-NFA state 126 = main.component#2.majorminor#3.minor#2.in
-   5:[+.] -> component#2.majorminor#3.minor#2.minor1
-   12:[\\] -> component#2.majorminor#3.minor#2.minor1
-   6:[\055] -> component#2.majorminor#3.minor#2.minor1
-   6:[\055] -> component#2.majorminor#3.minor#2.minor1
-   11:[A-Z_a-z] -> component#2.majorminor#3.minor#2.minor1
-   8:[0-9] -> component#2.majorminor#3.minor#2.minor1
-  Epsilon closure :
-    (self)
-
-NFA state 127 = main.component#2.majorminor#3.minor#2.minor1
-  [(epsilon)] -> component#2.majorminor#3.minor#2.#1
-   5:[+.] -> component#2.majorminor#3.minor#2.minor1
-   12:[\\] -> component#2.majorminor#3.minor#2.minor1
-   6:[\055] -> component#2.majorminor#3.minor#2.minor1
-   6:[\055] -> component#2.majorminor#3.minor#2.minor1
-   11:[A-Z_a-z] -> component#2.majorminor#3.minor#2.minor1
-   8:[0-9] -> component#2.majorminor#3.minor#2.minor1
-  [(epsilon)] -> component#2.majorminor#3.minor#2.out
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.majorminor#3.minor#2.#1
-    main.component#2.majorminor#3.minor#2.out
-    main.component#2.majorminor#3.out
-    main.component#2.majorminor#3.#1
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 128 = main.component#2.majorminor#3.minor#2.#1
-  Tags : COPY_TO_MINOR
-  Epsilon closure :
-    (self)
-
-NFA state 129 = main.component#2.majorminor#3.minor#2.out
-  [(epsilon)] -> component#2.majorminor#3.out
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.majorminor#3.out
-    main.component#2.majorminor#3.#1
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 130 = main.component#2.majorminor#3.out
-  [(epsilon)] -> component#2.majorminor#3.#1
-  [(epsilon)] -> component#2.out
-  Epsilon closure :
-    (self)
-    main.#2
-    main.component#2.majorminor#3.#1
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 131 = main.component#2.majorminor#3.#1
-  Tags : GOT_MAJORMINOR
-  Epsilon closure :
-    (self)
-
-NFA state 132 = main.component#2.out
-  [(epsilon)] -> #2
-  Epsilon closure :
-    (self)
-    main.#2
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-
-NFA state 133 = main.#3
-  EOS -> out2
-  Epsilon closure :
-    (self)
-
-NFA state 134 = main.optwhite#3.in
-  [(epsilon)] -> optwhite#3.out
-   0:[\t ] -> optwhite#3.in
-   1:[\r] -> optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.#3
-    main.optwhite#3.out
-
-NFA state 135 = main.optwhite#3.out
-  [(epsilon)] -> #3
-  Epsilon closure :
-    (self)
-    main.#3
-
-NFA state 136 = main.#4
-  [(epsilon)] -> component#5.in
-  Epsilon closure :
-    (self)
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-
-NFA state 137 = main.optwhite#4.in
-  [(epsilon)] -> optwhite#4.out
-   0:[\t ] -> optwhite#4.in
-   1:[\r] -> optwhite#4.in
-  Epsilon closure :
-    (self)
-    main.#4
-    main.optwhite#4.out
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-
-NFA state 138 = main.optwhite#4.out
-  [(epsilon)] -> #4
-  Epsilon closure :
-    (self)
-    main.#4
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-
-NFA state 139 = main.#5
-  [(epsilon)] -> optwhite#6.in
-  Epsilon closure :
-    (self)
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 140 = main.component#5.in
-  [(epsilon)] -> component#5.namevalue#1.in
-  [(epsilon)] -> component#5.name#2.in
-  [(epsilon)] -> component#5.majorminor#3.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-
-NFA state 141 = main.component#5.namevalue#1.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#4.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-
-NFA state 142 = main.component#5.namevalue#1.#1
-  [(epsilon)] -> component#5.namevalue#1.name#2.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.name#2.in
-
-NFA state 143 = main.component#5.namevalue#1.optwhite#1.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#1.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#1.in
-   1:[\r] -> component#5.namevalue#1.optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-
-NFA state 144 = main.component#5.namevalue#1.optwhite#1.out
-  [(epsilon)] -> component#5.namevalue#1.#1
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.name#2.in
-
-NFA state 145 = main.component#5.namevalue#1.#2
-  [(epsilon)] -> component#5.namevalue#1.optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-
-NFA state 146 = main.component#5.namevalue#1.name#2.in
-   6:[\055] -> component#5.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#5.namevalue#1.name#2.name1
-   8:[0-9] -> component#5.namevalue#1.name#2.name1
-  Epsilon closure :
-    (self)
-
-NFA state 147 = main.component#5.namevalue#1.name#2.name1
-  [(epsilon)] -> component#5.namevalue#1.name#2.#1
-  [(epsilon)] -> component#5.namevalue#1.name#2.#2
-   6:[\055] -> component#5.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#5.namevalue#1.name#2.name1
-   8:[0-9] -> component#5.namevalue#1.name#2.name1
-   0:[\t ] -> component#5.namevalue#1.name#2.name2
-  [(epsilon)] -> component#5.namevalue#1.name#2.out
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#2
-    main.component#5.namevalue#1.name#2.#1
-    main.component#5.namevalue#1.name#2.#2
-    main.component#5.namevalue#1.name#2.out
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-
-NFA state 148 = main.component#5.namevalue#1.name#2.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 149 = main.component#5.namevalue#1.name#2.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 150 = main.component#5.namevalue#1.name#2.name2
-  [(epsilon)] -> component#5.namevalue#1.name#2.#3
-  [(epsilon)] -> component#5.namevalue#1.name#2.#4
-   0:[\t ] -> component#5.namevalue#1.name#2.name2
-   6:[\055] -> component#5.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#5.namevalue#1.name#2.name1
-   8:[0-9] -> component#5.namevalue#1.name#2.name1
-  [(epsilon)] -> component#5.namevalue#1.name#2.out
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#2
-    main.component#5.namevalue#1.name#2.#3
-    main.component#5.namevalue#1.name#2.#4
-    main.component#5.namevalue#1.name#2.out
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-
-NFA state 151 = main.component#5.namevalue#1.name#2.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 152 = main.component#5.namevalue#1.name#2.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 153 = main.component#5.namevalue#1.name#2.out
-  [(epsilon)] -> component#5.namevalue#1.#2
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#2
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-
-NFA state 154 = main.component#5.namevalue#1.#3
-   10:[=] -> component#5.namevalue#1.rhs_normal
-  Epsilon closure :
-    (self)
-
-NFA state 155 = main.component#5.namevalue#1.optwhite#3.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#3.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#3.in
-   1:[\r] -> component#5.namevalue#1.optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.out
-
-NFA state 156 = main.component#5.namevalue#1.optwhite#3.out
-  [(epsilon)] -> component#5.namevalue#1.#3
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#3
-
-NFA state 157 = main.component#5.namevalue#1.#4
-  [(epsilon)] -> component#5.namevalue#1.name#5.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.name#5.in
-
-NFA state 158 = main.component#5.namevalue#1.optwhite#4.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#4.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#4.in
-   1:[\r] -> component#5.namevalue#1.optwhite#4.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-
-NFA state 159 = main.component#5.namevalue#1.optwhite#4.out
-  [(epsilon)] -> component#5.namevalue#1.#4
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.name#5.in
-
-NFA state 160 = main.component#5.namevalue#1.#5
-   4:[*] -> component#5.namevalue#1.#6
-  Epsilon closure :
-    (self)
-
-NFA state 161 = main.component#5.namevalue#1.name#5.in
-   6:[\055] -> component#5.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#5.namevalue#1.name#5.name1
-   8:[0-9] -> component#5.namevalue#1.name#5.name1
-  Epsilon closure :
-    (self)
-
-NFA state 162 = main.component#5.namevalue#1.name#5.name1
-  [(epsilon)] -> component#5.namevalue#1.name#5.#1
-  [(epsilon)] -> component#5.namevalue#1.name#5.#2
-   6:[\055] -> component#5.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#5.namevalue#1.name#5.name1
-   8:[0-9] -> component#5.namevalue#1.name#5.name1
-   0:[\t ] -> component#5.namevalue#1.name#5.name2
-  [(epsilon)] -> component#5.namevalue#1.name#5.out
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#5
-    main.component#5.namevalue#1.name#5.#1
-    main.component#5.namevalue#1.name#5.#2
-    main.component#5.namevalue#1.name#5.out
-
-NFA state 163 = main.component#5.namevalue#1.name#5.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 164 = main.component#5.namevalue#1.name#5.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 165 = main.component#5.namevalue#1.name#5.name2
-  [(epsilon)] -> component#5.namevalue#1.name#5.#3
-  [(epsilon)] -> component#5.namevalue#1.name#5.#4
-   0:[\t ] -> component#5.namevalue#1.name#5.name2
-   6:[\055] -> component#5.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#5.namevalue#1.name#5.name1
-   8:[0-9] -> component#5.namevalue#1.name#5.name1
-  [(epsilon)] -> component#5.namevalue#1.name#5.out
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#5
-    main.component#5.namevalue#1.name#5.#3
-    main.component#5.namevalue#1.name#5.#4
-    main.component#5.namevalue#1.name#5.out
-
-NFA state 166 = main.component#5.namevalue#1.name#5.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 167 = main.component#5.namevalue#1.name#5.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 168 = main.component#5.namevalue#1.name#5.out
-  [(epsilon)] -> component#5.namevalue#1.#5
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#5
-
-NFA state 169 = main.component#5.namevalue#1.#6
-  [(epsilon)] -> component#5.namevalue#1.digits#6.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.digits#6.in
-
-NFA state 170 = main.component#5.namevalue#1.#7
-  [(epsilon)] -> component#5.namevalue#1.optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#8
-    main.component#5.namevalue#1.optwhite#7.in
-    main.component#5.namevalue#1.optwhite#7.out
-
-NFA state 171 = main.component#5.namevalue#1.digits#6.in
-   8:[0-9] -> component#5.namevalue#1.digits#6.out
-   8:[0-9] -> component#5.namevalue#1.digits#6.in
-  Epsilon closure :
-    (self)
-
-NFA state 172 = main.component#5.namevalue#1.digits#6.out
-  [(epsilon)] -> component#5.namevalue#1.#7
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#7
-    main.component#5.namevalue#1.#8
-    main.component#5.namevalue#1.optwhite#7.in
-    main.component#5.namevalue#1.optwhite#7.out
-
-NFA state 173 = main.component#5.namevalue#1.#8
-   10:[=] -> component#5.namevalue#1.rhs_continue
-  Epsilon closure :
-    (self)
-
-NFA state 174 = main.component#5.namevalue#1.optwhite#7.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#7.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#7.in
-   1:[\r] -> component#5.namevalue#1.optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#8
-    main.component#5.namevalue#1.optwhite#7.out
-
-NFA state 175 = main.component#5.namevalue#1.optwhite#7.out
-  [(epsilon)] -> component#5.namevalue#1.#8
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#8
-
-NFA state 176 = main.component#5.namevalue#1.rhs_normal
-  [(epsilon)] -> component#5.namevalue#1.optwhite#14.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#11.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#8.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#9
-    main.component#5.namevalue#1.optwhite#8.in
-    main.component#5.namevalue#1.optwhite#8.out
-    main.component#5.namevalue#1.qvalue#9.in
-    main.component#5.namevalue#1.#11
-    main.component#5.namevalue#1.optwhite#11.in
-    main.component#5.namevalue#1.optwhite#11.out
-    main.component#5.namevalue#1.value#12.in
-    main.component#5.namevalue#1.#13
-    main.component#5.namevalue#1.optwhite#14.in
-    main.component#5.namevalue#1.optwhite#14.out
-    main.component#5.namevalue#1.#14
-
-NFA state 177 = main.component#5.namevalue#1.#9
-  [(epsilon)] -> component#5.namevalue#1.qvalue#9.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#9.in
-
-NFA state 178 = main.component#5.namevalue#1.optwhite#8.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#8.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#8.in
-   1:[\r] -> component#5.namevalue#1.optwhite#8.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#9
-    main.component#5.namevalue#1.optwhite#8.out
-    main.component#5.namevalue#1.qvalue#9.in
-
-NFA state 179 = main.component#5.namevalue#1.optwhite#8.out
-  [(epsilon)] -> component#5.namevalue#1.#9
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#9
-    main.component#5.namevalue#1.qvalue#9.in
-
-NFA state 180 = main.component#5.namevalue#1.#10
-  [(epsilon)] -> component#5.namevalue#1.optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#10.in
-    main.component#5.namevalue#1.optwhite#10.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 181 = main.component#5.namevalue#1.qvalue#9.in
-   3:["] -> component#5.namevalue#1.qvalue#9.qv0
-  Epsilon closure :
-    (self)
-
-NFA state 182 = main.component#5.namevalue#1.qvalue#9.qv0
-  [(epsilon)] -> component#5.namevalue#1.qvalue#9.escape#1.in
-   0:[\t ] -> component#5.namevalue#1.qvalue#9.qv1
-   9:[;] -> component#5.namevalue#1.qvalue#9.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.qvalue#9.qv1
-   11:[A-Z_a-z] -> component#5.namevalue#1.qvalue#9.qv1
-   10:[=] -> component#5.namevalue#1.qvalue#9.qv1
-   8:[0-9] -> component#5.namevalue#1.qvalue#9.qv1
-   7:[/] -> component#5.namevalue#1.qvalue#9.qv1
-   6:[\055] -> component#5.namevalue#1.qvalue#9.qv1
-   5:[+.] -> component#5.namevalue#1.qvalue#9.qv1
-   4:[*] -> component#5.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#9.escape#1.in
-
-NFA state 183 = main.component#5.namevalue#1.qvalue#9.escape#1.in
-   12:[\\] -> component#5.namevalue#1.qvalue#9.escape#1.#2
-   12:[\\] -> component#5.namevalue#1.qvalue#9.escape#1.#1
-  Epsilon closure :
-    (self)
-
-NFA state 184 = main.component#5.namevalue#1.qvalue#9.escape#1.#1
-   12:[\\] -> component#5.namevalue#1.qvalue#9.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 185 = main.component#5.namevalue#1.qvalue#9.escape#1.#2
-   3:["] -> component#5.namevalue#1.qvalue#9.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 186 = main.component#5.namevalue#1.qvalue#9.escape#1.out
-  [(epsilon)] -> component#5.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#9.qv1
-    main.component#5.namevalue#1.qvalue#9.#1
-    main.component#5.namevalue#1.qvalue#9.escape#2.in
-    main.component#5.namevalue#1.qvalue#9.qv2
-
-NFA state 187 = main.component#5.namevalue#1.qvalue#9.qv1
-  [(epsilon)] -> component#5.namevalue#1.qvalue#9.#1
-  [(epsilon)] -> component#5.namevalue#1.qvalue#9.escape#2.in
-   0:[\t ] -> component#5.namevalue#1.qvalue#9.qv1
-   9:[;] -> component#5.namevalue#1.qvalue#9.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.qvalue#9.qv1
-   11:[A-Z_a-z] -> component#5.namevalue#1.qvalue#9.qv1
-   10:[=] -> component#5.namevalue#1.qvalue#9.qv1
-   8:[0-9] -> component#5.namevalue#1.qvalue#9.qv1
-   7:[/] -> component#5.namevalue#1.qvalue#9.qv1
-   6:[\055] -> component#5.namevalue#1.qvalue#9.qv1
-   5:[+.] -> component#5.namevalue#1.qvalue#9.qv1
-   4:[*] -> component#5.namevalue#1.qvalue#9.qv1
-  [(epsilon)] -> component#5.namevalue#1.qvalue#9.qv2
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#9.#1
-    main.component#5.namevalue#1.qvalue#9.escape#2.in
-    main.component#5.namevalue#1.qvalue#9.qv2
-
-NFA state 188 = main.component#5.namevalue#1.qvalue#9.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 189 = main.component#5.namevalue#1.qvalue#9.escape#2.in
-   12:[\\] -> component#5.namevalue#1.qvalue#9.escape#2.#2
-   12:[\\] -> component#5.namevalue#1.qvalue#9.escape#2.#1
-  Epsilon closure :
-    (self)
-
-NFA state 190 = main.component#5.namevalue#1.qvalue#9.escape#2.#1
-   12:[\\] -> component#5.namevalue#1.qvalue#9.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 191 = main.component#5.namevalue#1.qvalue#9.escape#2.#2
-   3:["] -> component#5.namevalue#1.qvalue#9.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 192 = main.component#5.namevalue#1.qvalue#9.escape#2.out
-  [(epsilon)] -> component#5.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#9.qv1
-    main.component#5.namevalue#1.qvalue#9.#1
-    main.component#5.namevalue#1.qvalue#9.escape#2.in
-    main.component#5.namevalue#1.qvalue#9.qv2
-
-NFA state 193 = main.component#5.namevalue#1.qvalue#9.qv2
-   3:["] -> component#5.namevalue#1.qvalue#9.out
-  Epsilon closure :
-    (self)
-
-NFA state 194 = main.component#5.namevalue#1.qvalue#9.out
-  [(epsilon)] -> component#5.namevalue#1.#10
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#10
-    main.component#5.namevalue#1.optwhite#10.in
-    main.component#5.namevalue#1.optwhite#10.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 195 = main.component#5.namevalue#1.optwhite#10.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#10.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#10.in
-   1:[\r] -> component#5.namevalue#1.optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#10.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 196 = main.component#5.namevalue#1.optwhite#10.out
-  [(epsilon)] -> component#5.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 197 = main.component#5.namevalue#1.#11
-  [(epsilon)] -> component#5.namevalue#1.value#12.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.value#12.in
-
-NFA state 198 = main.component#5.namevalue#1.optwhite#11.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#11.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#11.in
-   1:[\r] -> component#5.namevalue#1.optwhite#11.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#11
-    main.component#5.namevalue#1.optwhite#11.out
-    main.component#5.namevalue#1.value#12.in
-
-NFA state 199 = main.component#5.namevalue#1.optwhite#11.out
-  [(epsilon)] -> component#5.namevalue#1.#11
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#11
-    main.component#5.namevalue#1.value#12.in
-
-NFA state 200 = main.component#5.namevalue#1.#12
-  [(epsilon)] -> component#5.namevalue#1.optwhite#13.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#13.in
-    main.component#5.namevalue#1.optwhite#13.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 201 = main.component#5.namevalue#1.value#12.in
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.value#12.v1
-   11:[A-Z_a-z] -> component#5.namevalue#1.value#12.v1
-   10:[=] -> component#5.namevalue#1.value#12.v1
-   8:[0-9] -> component#5.namevalue#1.value#12.v1
-   7:[/] -> component#5.namevalue#1.value#12.v1
-   6:[\055] -> component#5.namevalue#1.value#12.v1
-   5:[+.] -> component#5.namevalue#1.value#12.v1
-   4:[*] -> component#5.namevalue#1.value#12.v1
-  Epsilon closure :
-    (self)
-
-NFA state 202 = main.component#5.namevalue#1.value#12.v1
-  [(epsilon)] -> component#5.namevalue#1.value#12.#1
-  [(epsilon)] -> component#5.namevalue#1.value#12.out
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.value#12.v1
-   11:[A-Z_a-z] -> component#5.namevalue#1.value#12.v1
-   10:[=] -> component#5.namevalue#1.value#12.v1
-   8:[0-9] -> component#5.namevalue#1.value#12.v1
-   7:[/] -> component#5.namevalue#1.value#12.v1
-   6:[\055] -> component#5.namevalue#1.value#12.v1
-   5:[+.] -> component#5.namevalue#1.value#12.v1
-   4:[*] -> component#5.namevalue#1.value#12.v1
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#12
-    main.component#5.namevalue#1.value#12.#1
-    main.component#5.namevalue#1.value#12.out
-    main.component#5.namevalue#1.optwhite#13.in
-    main.component#5.namevalue#1.optwhite#13.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 203 = main.component#5.namevalue#1.value#12.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 204 = main.component#5.namevalue#1.value#12.out
-  [(epsilon)] -> component#5.namevalue#1.#12
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#12
-    main.component#5.namevalue#1.optwhite#13.in
-    main.component#5.namevalue#1.optwhite#13.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 205 = main.component#5.namevalue#1.optwhite#13.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#13.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#13.in
-   1:[\r] -> component#5.namevalue#1.optwhite#13.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#13.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 206 = main.component#5.namevalue#1.optwhite#13.out
-  [(epsilon)] -> component#5.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 207 = main.component#5.namevalue#1.#13
-  [(epsilon)] -> component#5.namevalue#1.#14
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#14
-
-NFA state 208 = main.component#5.namevalue#1.optwhite#14.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#14.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#14.in
-   1:[\r] -> component#5.namevalue#1.optwhite#14.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#13
-    main.component#5.namevalue#1.optwhite#14.out
-    main.component#5.namevalue#1.#14
-
-NFA state 209 = main.component#5.namevalue#1.optwhite#14.out
-  [(epsilon)] -> component#5.namevalue#1.#13
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#13
-    main.component#5.namevalue#1.#14
-
-NFA state 210 = main.component#5.namevalue#1.#14
-  EOS -> component#5.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-
-NFA state 211 = main.component#5.namevalue#1.rhs_continue
-  [(epsilon)] -> component#5.namevalue#1.optwhite#18.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#15.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#15
-    main.component#5.namevalue#1.optwhite#15.in
-    main.component#5.namevalue#1.optwhite#15.out
-    main.component#5.namevalue#1.qvalue#16.in
-    main.component#5.namevalue#1.#17
-    main.component#5.namevalue#1.optwhite#18.in
-    main.component#5.namevalue#1.optwhite#18.out
-    main.component#5.namevalue#1.value#19.in
-
-NFA state 212 = main.component#5.namevalue#1.#15
-  [(epsilon)] -> component#5.namevalue#1.qvalue#16.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#16.in
-
-NFA state 213 = main.component#5.namevalue#1.optwhite#15.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#15.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#15.in
-   1:[\r] -> component#5.namevalue#1.optwhite#15.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#15
-    main.component#5.namevalue#1.optwhite#15.out
-    main.component#5.namevalue#1.qvalue#16.in
-
-NFA state 214 = main.component#5.namevalue#1.optwhite#15.out
-  [(epsilon)] -> component#5.namevalue#1.#15
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#15
-    main.component#5.namevalue#1.qvalue#16.in
-
-NFA state 215 = main.component#5.namevalue#1.#16
-  [(epsilon)] -> component#5.namevalue#1.optwhite#17.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#17.in
-    main.component#5.namevalue#1.optwhite#17.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 216 = main.component#5.namevalue#1.qvalue#16.in
-   3:["] -> component#5.namevalue#1.qvalue#16.qv0
-  Epsilon closure :
-    (self)
-
-NFA state 217 = main.component#5.namevalue#1.qvalue#16.qv0
-  [(epsilon)] -> component#5.namevalue#1.qvalue#16.escape#1.in
-   0:[\t ] -> component#5.namevalue#1.qvalue#16.qv1
-   9:[;] -> component#5.namevalue#1.qvalue#16.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.qvalue#16.qv1
-   11:[A-Z_a-z] -> component#5.namevalue#1.qvalue#16.qv1
-   10:[=] -> component#5.namevalue#1.qvalue#16.qv1
-   8:[0-9] -> component#5.namevalue#1.qvalue#16.qv1
-   7:[/] -> component#5.namevalue#1.qvalue#16.qv1
-   6:[\055] -> component#5.namevalue#1.qvalue#16.qv1
-   5:[+.] -> component#5.namevalue#1.qvalue#16.qv1
-   4:[*] -> component#5.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#16.escape#1.in
-
-NFA state 218 = main.component#5.namevalue#1.qvalue#16.escape#1.in
-   12:[\\] -> component#5.namevalue#1.qvalue#16.escape#1.#2
-   12:[\\] -> component#5.namevalue#1.qvalue#16.escape#1.#1
-  Epsilon closure :
-    (self)
-
-NFA state 219 = main.component#5.namevalue#1.qvalue#16.escape#1.#1
-   12:[\\] -> component#5.namevalue#1.qvalue#16.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 220 = main.component#5.namevalue#1.qvalue#16.escape#1.#2
-   3:["] -> component#5.namevalue#1.qvalue#16.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 221 = main.component#5.namevalue#1.qvalue#16.escape#1.out
-  [(epsilon)] -> component#5.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#16.qv1
-    main.component#5.namevalue#1.qvalue#16.#1
-    main.component#5.namevalue#1.qvalue#16.escape#2.in
-    main.component#5.namevalue#1.qvalue#16.qv2
-
-NFA state 222 = main.component#5.namevalue#1.qvalue#16.qv1
-  [(epsilon)] -> component#5.namevalue#1.qvalue#16.#1
-  [(epsilon)] -> component#5.namevalue#1.qvalue#16.escape#2.in
-   0:[\t ] -> component#5.namevalue#1.qvalue#16.qv1
-   9:[;] -> component#5.namevalue#1.qvalue#16.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.qvalue#16.qv1
-   11:[A-Z_a-z] -> component#5.namevalue#1.qvalue#16.qv1
-   10:[=] -> component#5.namevalue#1.qvalue#16.qv1
-   8:[0-9] -> component#5.namevalue#1.qvalue#16.qv1
-   7:[/] -> component#5.namevalue#1.qvalue#16.qv1
-   6:[\055] -> component#5.namevalue#1.qvalue#16.qv1
-   5:[+.] -> component#5.namevalue#1.qvalue#16.qv1
-   4:[*] -> component#5.namevalue#1.qvalue#16.qv1
-  [(epsilon)] -> component#5.namevalue#1.qvalue#16.qv2
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#16.#1
-    main.component#5.namevalue#1.qvalue#16.escape#2.in
-    main.component#5.namevalue#1.qvalue#16.qv2
-
-NFA state 223 = main.component#5.namevalue#1.qvalue#16.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 224 = main.component#5.namevalue#1.qvalue#16.escape#2.in
-   12:[\\] -> component#5.namevalue#1.qvalue#16.escape#2.#2
-   12:[\\] -> component#5.namevalue#1.qvalue#16.escape#2.#1
-  Epsilon closure :
-    (self)
-
-NFA state 225 = main.component#5.namevalue#1.qvalue#16.escape#2.#1
-   12:[\\] -> component#5.namevalue#1.qvalue#16.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 226 = main.component#5.namevalue#1.qvalue#16.escape#2.#2
-   3:["] -> component#5.namevalue#1.qvalue#16.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 227 = main.component#5.namevalue#1.qvalue#16.escape#2.out
-  [(epsilon)] -> component#5.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.qvalue#16.qv1
-    main.component#5.namevalue#1.qvalue#16.#1
-    main.component#5.namevalue#1.qvalue#16.escape#2.in
-    main.component#5.namevalue#1.qvalue#16.qv2
-
-NFA state 228 = main.component#5.namevalue#1.qvalue#16.qv2
-   3:["] -> component#5.namevalue#1.qvalue#16.out
-  Epsilon closure :
-    (self)
-
-NFA state 229 = main.component#5.namevalue#1.qvalue#16.out
-  [(epsilon)] -> component#5.namevalue#1.#16
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#16
-    main.component#5.namevalue#1.optwhite#17.in
-    main.component#5.namevalue#1.optwhite#17.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 230 = main.component#5.namevalue#1.optwhite#17.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#17.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#17.in
-   1:[\r] -> component#5.namevalue#1.optwhite#17.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#17.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 231 = main.component#5.namevalue#1.optwhite#17.out
-  [(epsilon)] -> component#5.namevalue#1.out_continue
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 232 = main.component#5.namevalue#1.#17
-  [(epsilon)] -> component#5.namevalue#1.value#19.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.value#19.in
-
-NFA state 233 = main.component#5.namevalue#1.optwhite#18.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#18.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#18.in
-   1:[\r] -> component#5.namevalue#1.optwhite#18.in
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#17
-    main.component#5.namevalue#1.optwhite#18.out
-    main.component#5.namevalue#1.value#19.in
-
-NFA state 234 = main.component#5.namevalue#1.optwhite#18.out
-  [(epsilon)] -> component#5.namevalue#1.#17
-  Epsilon closure :
-    (self)
-    main.component#5.namevalue#1.#17
-    main.component#5.namevalue#1.value#19.in
-
-NFA state 235 = main.component#5.namevalue#1.#18
-  [(epsilon)] -> component#5.namevalue#1.optwhite#20.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#20.in
-    main.component#5.namevalue#1.optwhite#20.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 236 = main.component#5.namevalue#1.value#19.in
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.value#19.v1
-   11:[A-Z_a-z] -> component#5.namevalue#1.value#19.v1
-   10:[=] -> component#5.namevalue#1.value#19.v1
-   8:[0-9] -> component#5.namevalue#1.value#19.v1
-   7:[/] -> component#5.namevalue#1.value#19.v1
-   6:[\055] -> component#5.namevalue#1.value#19.v1
-   5:[+.] -> component#5.namevalue#1.value#19.v1
-   4:[*] -> component#5.namevalue#1.value#19.v1
-  Epsilon closure :
-    (self)
-
-NFA state 237 = main.component#5.namevalue#1.value#19.v1
-  [(epsilon)] -> component#5.namevalue#1.value#19.#1
-  [(epsilon)] -> component#5.namevalue#1.value#19.out
-   2:[!#-),:<>-@[]^`{-~] -> component#5.namevalue#1.value#19.v1
-   11:[A-Z_a-z] -> component#5.namevalue#1.value#19.v1
-   10:[=] -> component#5.namevalue#1.value#19.v1
-   8:[0-9] -> component#5.namevalue#1.value#19.v1
-   7:[/] -> component#5.namevalue#1.value#19.v1
-   6:[\055] -> component#5.namevalue#1.value#19.v1
-   5:[+.] -> component#5.namevalue#1.value#19.v1
-   4:[*] -> component#5.namevalue#1.value#19.v1
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#18
-    main.component#5.namevalue#1.value#19.#1
-    main.component#5.namevalue#1.value#19.out
-    main.component#5.namevalue#1.optwhite#20.in
-    main.component#5.namevalue#1.optwhite#20.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 238 = main.component#5.namevalue#1.value#19.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 239 = main.component#5.namevalue#1.value#19.out
-  [(epsilon)] -> component#5.namevalue#1.#18
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#18
-    main.component#5.namevalue#1.optwhite#20.in
-    main.component#5.namevalue#1.optwhite#20.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 240 = main.component#5.namevalue#1.optwhite#20.in
-  [(epsilon)] -> component#5.namevalue#1.optwhite#20.out
-   0:[\t ] -> component#5.namevalue#1.optwhite#20.in
-   1:[\r] -> component#5.namevalue#1.optwhite#20.in
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.optwhite#20.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 241 = main.component#5.namevalue#1.optwhite#20.out
-  [(epsilon)] -> component#5.namevalue#1.out_continue
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 242 = main.component#5.namevalue#1.out_normal
-  [(epsilon)] -> component#5.namevalue#1.out
-  [(epsilon)] -> component#5.namevalue#1.#19
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 243 = main.component#5.namevalue#1.#19
-  Tags : GOT_NAMEVALUE
-  Epsilon closure :
-    (self)
-
-NFA state 244 = main.component#5.namevalue#1.out_continue
-  [(epsilon)] -> component#5.namevalue#1.out
-  [(epsilon)] -> component#5.namevalue#1.#20
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 245 = main.component#5.namevalue#1.#20
-  Tags : GOT_NAMEVALUE_CONT
-  Epsilon closure :
-    (self)
-
-NFA state 246 = main.component#5.namevalue#1.out
-  [(epsilon)] -> component#5.out
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 247 = main.component#5.name#2.in
-   6:[\055] -> component#5.name#2.name1
-   11:[A-Z_a-z] -> component#5.name#2.name1
-   8:[0-9] -> component#5.name#2.name1
-  Epsilon closure :
-    (self)
-
-NFA state 248 = main.component#5.name#2.name1
-  [(epsilon)] -> component#5.name#2.out
-   0:[\t ] -> component#5.name#2.name2
-   6:[\055] -> component#5.name#2.name1
-   11:[A-Z_a-z] -> component#5.name#2.name1
-   8:[0-9] -> component#5.name#2.name1
-  [(epsilon)] -> component#5.name#2.#2
-  [(epsilon)] -> component#5.name#2.#1
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.name#2.#1
-    main.component#5.name#2.#2
-    main.component#5.name#2.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 249 = main.component#5.name#2.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 250 = main.component#5.name#2.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 251 = main.component#5.name#2.name2
-  [(epsilon)] -> component#5.name#2.out
-   6:[\055] -> component#5.name#2.name1
-   11:[A-Z_a-z] -> component#5.name#2.name1
-   8:[0-9] -> component#5.name#2.name1
-   0:[\t ] -> component#5.name#2.name2
-  [(epsilon)] -> component#5.name#2.#4
-  [(epsilon)] -> component#5.name#2.#3
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.name#2.#3
-    main.component#5.name#2.#4
-    main.component#5.name#2.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 252 = main.component#5.name#2.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 253 = main.component#5.name#2.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 254 = main.component#5.name#2.out
-  [(epsilon)] -> component#5.out
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 255 = main.component#5.majorminor#3.in
-  [(epsilon)] -> component#5.majorminor#3.major#1.in
-  Epsilon closure :
-    (self)
-    main.component#5.majorminor#3.major#1.in
-
-NFA state 256 = main.component#5.majorminor#3.major#1.in
-   6:[\055] -> component#5.majorminor#3.major#1.name1
-   11:[A-Z_a-z] -> component#5.majorminor#3.major#1.name1
-   8:[0-9] -> component#5.majorminor#3.major#1.name1
-  Epsilon closure :
-    (self)
-
-NFA state 257 = main.component#5.majorminor#3.major#1.name1
-   6:[\055] -> component#5.majorminor#3.major#1.name1
-   11:[A-Z_a-z] -> component#5.majorminor#3.major#1.name1
-   8:[0-9] -> component#5.majorminor#3.major#1.name1
-  [(epsilon)] -> component#5.majorminor#3.major#1.out
-  Epsilon closure :
-    (self)
-    main.component#5.majorminor#3.major#1.out
-    main.component#5.majorminor#3.foo
-
-NFA state 258 = main.component#5.majorminor#3.major#1.out
-  [(epsilon)] -> component#5.majorminor#3.foo
-  Epsilon closure :
-    (self)
-    main.component#5.majorminor#3.foo
-
-NFA state 259 = main.component#5.majorminor#3.foo
-   7:[/] -> component#5.majorminor#3.bar
-  Epsilon closure :
-    (self)
-
-NFA state 260 = main.component#5.majorminor#3.bar
-  [(epsilon)] -> component#5.majorminor#3.minor#2.in
-  Epsilon closure :
-    (self)
-    main.component#5.majorminor#3.minor#2.in
-
-NFA state 261 = main.component#5.majorminor#3.minor#2.in
-   5:[+.] -> component#5.majorminor#3.minor#2.minor1
-   12:[\\] -> component#5.majorminor#3.minor#2.minor1
-   6:[\055] -> component#5.majorminor#3.minor#2.minor1
-   6:[\055] -> component#5.majorminor#3.minor#2.minor1
-   11:[A-Z_a-z] -> component#5.majorminor#3.minor#2.minor1
-   8:[0-9] -> component#5.majorminor#3.minor#2.minor1
-  Epsilon closure :
-    (self)
-
-NFA state 262 = main.component#5.majorminor#3.minor#2.minor1
-  [(epsilon)] -> component#5.majorminor#3.minor#2.#1
-   5:[+.] -> component#5.majorminor#3.minor#2.minor1
-   12:[\\] -> component#5.majorminor#3.minor#2.minor1
-   6:[\055] -> component#5.majorminor#3.minor#2.minor1
-   6:[\055] -> component#5.majorminor#3.minor#2.minor1
-   11:[A-Z_a-z] -> component#5.majorminor#3.minor#2.minor1
-   8:[0-9] -> component#5.majorminor#3.minor#2.minor1
-  [(epsilon)] -> component#5.majorminor#3.minor#2.out
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.majorminor#3.minor#2.#1
-    main.component#5.majorminor#3.minor#2.out
-    main.component#5.majorminor#3.out
-    main.component#5.majorminor#3.#1
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 263 = main.component#5.majorminor#3.minor#2.#1
-  Tags : COPY_TO_MINOR
-  Epsilon closure :
-    (self)
-
-NFA state 264 = main.component#5.majorminor#3.minor#2.out
-  [(epsilon)] -> component#5.majorminor#3.out
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.majorminor#3.out
-    main.component#5.majorminor#3.#1
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 265 = main.component#5.majorminor#3.out
-  [(epsilon)] -> component#5.majorminor#3.#1
-  [(epsilon)] -> component#5.out
-  Epsilon closure :
-    (self)
-    main.#5
-    main.component#5.majorminor#3.#1
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 266 = main.component#5.majorminor#3.#1
-  Tags : GOT_MAJORMINOR
-  Epsilon closure :
-    (self)
-
-NFA state 267 = main.component#5.out
-  [(epsilon)] -> #5
-  Epsilon closure :
-    (self)
-    main.#5
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-
-NFA state 268 = main.#6
-   9:[;] -> #7
-  Epsilon closure :
-    (self)
-
-NFA state 269 = main.optwhite#6.in
-  [(epsilon)] -> optwhite#6.out
-   0:[\t ] -> optwhite#6.in
-   1:[\r] -> optwhite#6.in
-  Epsilon closure :
-    (self)
-    main.#6
-    main.optwhite#6.out
-
-NFA state 270 = main.optwhite#6.out
-  [(epsilon)] -> #6
-  Epsilon closure :
-    (self)
-    main.#6
-
-NFA state 271 = main.#7
-  [(epsilon)] -> optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.#8
-    main.optwhite#7.in
-    main.optwhite#7.out
-
-NFA state 272 = main.#8
-  EOS -> out2
-  Epsilon closure :
-    (self)
-
-NFA state 273 = main.optwhite#7.in
-  [(epsilon)] -> optwhite#7.out
-   0:[\t ] -> optwhite#7.in
-   1:[\r] -> optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.#8
-    main.optwhite#7.out
-
-NFA state 274 = main.optwhite#7.out
-  [(epsilon)] -> #8
-  Epsilon closure :
-    (self)
-    main.#8
-
-NFA state 275 = main.#9
-  [(epsilon)] -> component#9.in
-  Epsilon closure :
-    (self)
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-NFA state 276 = main.optwhite#8.in
-  [(epsilon)] -> optwhite#8.out
-   0:[\t ] -> optwhite#8.in
-   1:[\r] -> optwhite#8.in
-  Epsilon closure :
-    (self)
-    main.#9
-    main.optwhite#8.out
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-NFA state 277 = main.optwhite#8.out
-  [(epsilon)] -> #9
-  Epsilon closure :
-    (self)
-    main.#9
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-NFA state 278 = main.#10
-  [(epsilon)] -> optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 279 = main.component#9.in
-  [(epsilon)] -> component#9.namevalue#1.in
-  [(epsilon)] -> component#9.name#2.in
-  [(epsilon)] -> component#9.majorminor#3.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-NFA state 280 = main.component#9.namevalue#1.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#4.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-
-NFA state 281 = main.component#9.namevalue#1.#1
-  [(epsilon)] -> component#9.namevalue#1.name#2.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.name#2.in
-
-NFA state 282 = main.component#9.namevalue#1.optwhite#1.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#1.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#1.in
-   1:[\r] -> component#9.namevalue#1.optwhite#1.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-
-NFA state 283 = main.component#9.namevalue#1.optwhite#1.out
-  [(epsilon)] -> component#9.namevalue#1.#1
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.name#2.in
-
-NFA state 284 = main.component#9.namevalue#1.#2
-  [(epsilon)] -> component#9.namevalue#1.optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-
-NFA state 285 = main.component#9.namevalue#1.name#2.in
-   6:[\055] -> component#9.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#9.namevalue#1.name#2.name1
-   8:[0-9] -> component#9.namevalue#1.name#2.name1
-  Epsilon closure :
-    (self)
-
-NFA state 286 = main.component#9.namevalue#1.name#2.name1
-  [(epsilon)] -> component#9.namevalue#1.name#2.#1
-  [(epsilon)] -> component#9.namevalue#1.name#2.#2
-   6:[\055] -> component#9.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#9.namevalue#1.name#2.name1
-   8:[0-9] -> component#9.namevalue#1.name#2.name1
-   0:[\t ] -> component#9.namevalue#1.name#2.name2
-  [(epsilon)] -> component#9.namevalue#1.name#2.out
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#2
-    main.component#9.namevalue#1.name#2.#1
-    main.component#9.namevalue#1.name#2.#2
-    main.component#9.namevalue#1.name#2.out
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-
-NFA state 287 = main.component#9.namevalue#1.name#2.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 288 = main.component#9.namevalue#1.name#2.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 289 = main.component#9.namevalue#1.name#2.name2
-  [(epsilon)] -> component#9.namevalue#1.name#2.#3
-  [(epsilon)] -> component#9.namevalue#1.name#2.#4
-   0:[\t ] -> component#9.namevalue#1.name#2.name2
-   6:[\055] -> component#9.namevalue#1.name#2.name1
-   11:[A-Z_a-z] -> component#9.namevalue#1.name#2.name1
-   8:[0-9] -> component#9.namevalue#1.name#2.name1
-  [(epsilon)] -> component#9.namevalue#1.name#2.out
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#2
-    main.component#9.namevalue#1.name#2.#3
-    main.component#9.namevalue#1.name#2.#4
-    main.component#9.namevalue#1.name#2.out
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-
-NFA state 290 = main.component#9.namevalue#1.name#2.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 291 = main.component#9.namevalue#1.name#2.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 292 = main.component#9.namevalue#1.name#2.out
-  [(epsilon)] -> component#9.namevalue#1.#2
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#2
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-
-NFA state 293 = main.component#9.namevalue#1.#3
-   10:[=] -> component#9.namevalue#1.rhs_normal
-  Epsilon closure :
-    (self)
-
-NFA state 294 = main.component#9.namevalue#1.optwhite#3.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#3.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#3.in
-   1:[\r] -> component#9.namevalue#1.optwhite#3.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.out
-
-NFA state 295 = main.component#9.namevalue#1.optwhite#3.out
-  [(epsilon)] -> component#9.namevalue#1.#3
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#3
-
-NFA state 296 = main.component#9.namevalue#1.#4
-  [(epsilon)] -> component#9.namevalue#1.name#5.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.name#5.in
-
-NFA state 297 = main.component#9.namevalue#1.optwhite#4.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#4.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#4.in
-   1:[\r] -> component#9.namevalue#1.optwhite#4.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-
-NFA state 298 = main.component#9.namevalue#1.optwhite#4.out
-  [(epsilon)] -> component#9.namevalue#1.#4
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.name#5.in
-
-NFA state 299 = main.component#9.namevalue#1.#5
-   4:[*] -> component#9.namevalue#1.#6
-  Epsilon closure :
-    (self)
-
-NFA state 300 = main.component#9.namevalue#1.name#5.in
-   6:[\055] -> component#9.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#9.namevalue#1.name#5.name1
-   8:[0-9] -> component#9.namevalue#1.name#5.name1
-  Epsilon closure :
-    (self)
-
-NFA state 301 = main.component#9.namevalue#1.name#5.name1
-  [(epsilon)] -> component#9.namevalue#1.name#5.#1
-  [(epsilon)] -> component#9.namevalue#1.name#5.#2
-   6:[\055] -> component#9.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#9.namevalue#1.name#5.name1
-   8:[0-9] -> component#9.namevalue#1.name#5.name1
-   0:[\t ] -> component#9.namevalue#1.name#5.name2
-  [(epsilon)] -> component#9.namevalue#1.name#5.out
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#5
-    main.component#9.namevalue#1.name#5.#1
-    main.component#9.namevalue#1.name#5.#2
-    main.component#9.namevalue#1.name#5.out
-
-NFA state 302 = main.component#9.namevalue#1.name#5.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 303 = main.component#9.namevalue#1.name#5.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 304 = main.component#9.namevalue#1.name#5.name2
-  [(epsilon)] -> component#9.namevalue#1.name#5.#3
-  [(epsilon)] -> component#9.namevalue#1.name#5.#4
-   0:[\t ] -> component#9.namevalue#1.name#5.name2
-   6:[\055] -> component#9.namevalue#1.name#5.name1
-   11:[A-Z_a-z] -> component#9.namevalue#1.name#5.name1
-   8:[0-9] -> component#9.namevalue#1.name#5.name1
-  [(epsilon)] -> component#9.namevalue#1.name#5.out
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#5
-    main.component#9.namevalue#1.name#5.#3
-    main.component#9.namevalue#1.name#5.#4
-    main.component#9.namevalue#1.name#5.out
-
-NFA state 305 = main.component#9.namevalue#1.name#5.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 306 = main.component#9.namevalue#1.name#5.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 307 = main.component#9.namevalue#1.name#5.out
-  [(epsilon)] -> component#9.namevalue#1.#5
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#5
-
-NFA state 308 = main.component#9.namevalue#1.#6
-  [(epsilon)] -> component#9.namevalue#1.digits#6.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.digits#6.in
-
-NFA state 309 = main.component#9.namevalue#1.#7
-  [(epsilon)] -> component#9.namevalue#1.optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#8
-    main.component#9.namevalue#1.optwhite#7.in
-    main.component#9.namevalue#1.optwhite#7.out
-
-NFA state 310 = main.component#9.namevalue#1.digits#6.in
-   8:[0-9] -> component#9.namevalue#1.digits#6.out
-   8:[0-9] -> component#9.namevalue#1.digits#6.in
-  Epsilon closure :
-    (self)
-
-NFA state 311 = main.component#9.namevalue#1.digits#6.out
-  [(epsilon)] -> component#9.namevalue#1.#7
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#7
-    main.component#9.namevalue#1.#8
-    main.component#9.namevalue#1.optwhite#7.in
-    main.component#9.namevalue#1.optwhite#7.out
-
-NFA state 312 = main.component#9.namevalue#1.#8
-   10:[=] -> component#9.namevalue#1.rhs_continue
-  Epsilon closure :
-    (self)
-
-NFA state 313 = main.component#9.namevalue#1.optwhite#7.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#7.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#7.in
-   1:[\r] -> component#9.namevalue#1.optwhite#7.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#8
-    main.component#9.namevalue#1.optwhite#7.out
-
-NFA state 314 = main.component#9.namevalue#1.optwhite#7.out
-  [(epsilon)] -> component#9.namevalue#1.#8
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#8
-
-NFA state 315 = main.component#9.namevalue#1.rhs_normal
-  [(epsilon)] -> component#9.namevalue#1.optwhite#14.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#11.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#8.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#9
-    main.component#9.namevalue#1.optwhite#8.in
-    main.component#9.namevalue#1.optwhite#8.out
-    main.component#9.namevalue#1.qvalue#9.in
-    main.component#9.namevalue#1.#11
-    main.component#9.namevalue#1.optwhite#11.in
-    main.component#9.namevalue#1.optwhite#11.out
-    main.component#9.namevalue#1.value#12.in
-    main.component#9.namevalue#1.#13
-    main.component#9.namevalue#1.optwhite#14.in
-    main.component#9.namevalue#1.optwhite#14.out
-    main.component#9.namevalue#1.#14
-
-NFA state 316 = main.component#9.namevalue#1.#9
-  [(epsilon)] -> component#9.namevalue#1.qvalue#9.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#9.in
-
-NFA state 317 = main.component#9.namevalue#1.optwhite#8.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#8.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#8.in
-   1:[\r] -> component#9.namevalue#1.optwhite#8.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#9
-    main.component#9.namevalue#1.optwhite#8.out
-    main.component#9.namevalue#1.qvalue#9.in
-
-NFA state 318 = main.component#9.namevalue#1.optwhite#8.out
-  [(epsilon)] -> component#9.namevalue#1.#9
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#9
-    main.component#9.namevalue#1.qvalue#9.in
-
-NFA state 319 = main.component#9.namevalue#1.#10
-  [(epsilon)] -> component#9.namevalue#1.optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#10.in
-    main.component#9.namevalue#1.optwhite#10.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 320 = main.component#9.namevalue#1.qvalue#9.in
-   3:["] -> component#9.namevalue#1.qvalue#9.qv0
-  Epsilon closure :
-    (self)
-
-NFA state 321 = main.component#9.namevalue#1.qvalue#9.qv0
-  [(epsilon)] -> component#9.namevalue#1.qvalue#9.escape#1.in
-   0:[\t ] -> component#9.namevalue#1.qvalue#9.qv1
-   9:[;] -> component#9.namevalue#1.qvalue#9.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.qvalue#9.qv1
-   11:[A-Z_a-z] -> component#9.namevalue#1.qvalue#9.qv1
-   10:[=] -> component#9.namevalue#1.qvalue#9.qv1
-   8:[0-9] -> component#9.namevalue#1.qvalue#9.qv1
-   7:[/] -> component#9.namevalue#1.qvalue#9.qv1
-   6:[\055] -> component#9.namevalue#1.qvalue#9.qv1
-   5:[+.] -> component#9.namevalue#1.qvalue#9.qv1
-   4:[*] -> component#9.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#9.escape#1.in
-
-NFA state 322 = main.component#9.namevalue#1.qvalue#9.escape#1.in
-   12:[\\] -> component#9.namevalue#1.qvalue#9.escape#1.#2
-   12:[\\] -> component#9.namevalue#1.qvalue#9.escape#1.#1
-  Epsilon closure :
-    (self)
-
-NFA state 323 = main.component#9.namevalue#1.qvalue#9.escape#1.#1
-   12:[\\] -> component#9.namevalue#1.qvalue#9.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 324 = main.component#9.namevalue#1.qvalue#9.escape#1.#2
-   3:["] -> component#9.namevalue#1.qvalue#9.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 325 = main.component#9.namevalue#1.qvalue#9.escape#1.out
-  [(epsilon)] -> component#9.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#9.qv1
-    main.component#9.namevalue#1.qvalue#9.#1
-    main.component#9.namevalue#1.qvalue#9.escape#2.in
-    main.component#9.namevalue#1.qvalue#9.qv2
-
-NFA state 326 = main.component#9.namevalue#1.qvalue#9.qv1
-  [(epsilon)] -> component#9.namevalue#1.qvalue#9.#1
-  [(epsilon)] -> component#9.namevalue#1.qvalue#9.escape#2.in
-   0:[\t ] -> component#9.namevalue#1.qvalue#9.qv1
-   9:[;] -> component#9.namevalue#1.qvalue#9.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.qvalue#9.qv1
-   11:[A-Z_a-z] -> component#9.namevalue#1.qvalue#9.qv1
-   10:[=] -> component#9.namevalue#1.qvalue#9.qv1
-   8:[0-9] -> component#9.namevalue#1.qvalue#9.qv1
-   7:[/] -> component#9.namevalue#1.qvalue#9.qv1
-   6:[\055] -> component#9.namevalue#1.qvalue#9.qv1
-   5:[+.] -> component#9.namevalue#1.qvalue#9.qv1
-   4:[*] -> component#9.namevalue#1.qvalue#9.qv1
-  [(epsilon)] -> component#9.namevalue#1.qvalue#9.qv2
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#9.#1
-    main.component#9.namevalue#1.qvalue#9.escape#2.in
-    main.component#9.namevalue#1.qvalue#9.qv2
-
-NFA state 327 = main.component#9.namevalue#1.qvalue#9.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 328 = main.component#9.namevalue#1.qvalue#9.escape#2.in
-   12:[\\] -> component#9.namevalue#1.qvalue#9.escape#2.#2
-   12:[\\] -> component#9.namevalue#1.qvalue#9.escape#2.#1
-  Epsilon closure :
-    (self)
-
-NFA state 329 = main.component#9.namevalue#1.qvalue#9.escape#2.#1
-   12:[\\] -> component#9.namevalue#1.qvalue#9.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 330 = main.component#9.namevalue#1.qvalue#9.escape#2.#2
-   3:["] -> component#9.namevalue#1.qvalue#9.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 331 = main.component#9.namevalue#1.qvalue#9.escape#2.out
-  [(epsilon)] -> component#9.namevalue#1.qvalue#9.qv1
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#9.qv1
-    main.component#9.namevalue#1.qvalue#9.#1
-    main.component#9.namevalue#1.qvalue#9.escape#2.in
-    main.component#9.namevalue#1.qvalue#9.qv2
-
-NFA state 332 = main.component#9.namevalue#1.qvalue#9.qv2
-   3:["] -> component#9.namevalue#1.qvalue#9.out
-  Epsilon closure :
-    (self)
-
-NFA state 333 = main.component#9.namevalue#1.qvalue#9.out
-  [(epsilon)] -> component#9.namevalue#1.#10
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#10
-    main.component#9.namevalue#1.optwhite#10.in
-    main.component#9.namevalue#1.optwhite#10.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 334 = main.component#9.namevalue#1.optwhite#10.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#10.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#10.in
-   1:[\r] -> component#9.namevalue#1.optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#10.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 335 = main.component#9.namevalue#1.optwhite#10.out
-  [(epsilon)] -> component#9.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 336 = main.component#9.namevalue#1.#11
-  [(epsilon)] -> component#9.namevalue#1.value#12.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.value#12.in
-
-NFA state 337 = main.component#9.namevalue#1.optwhite#11.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#11.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#11.in
-   1:[\r] -> component#9.namevalue#1.optwhite#11.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#11
-    main.component#9.namevalue#1.optwhite#11.out
-    main.component#9.namevalue#1.value#12.in
-
-NFA state 338 = main.component#9.namevalue#1.optwhite#11.out
-  [(epsilon)] -> component#9.namevalue#1.#11
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#11
-    main.component#9.namevalue#1.value#12.in
-
-NFA state 339 = main.component#9.namevalue#1.#12
-  [(epsilon)] -> component#9.namevalue#1.optwhite#13.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#13.in
-    main.component#9.namevalue#1.optwhite#13.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 340 = main.component#9.namevalue#1.value#12.in
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.value#12.v1
-   11:[A-Z_a-z] -> component#9.namevalue#1.value#12.v1
-   10:[=] -> component#9.namevalue#1.value#12.v1
-   8:[0-9] -> component#9.namevalue#1.value#12.v1
-   7:[/] -> component#9.namevalue#1.value#12.v1
-   6:[\055] -> component#9.namevalue#1.value#12.v1
-   5:[+.] -> component#9.namevalue#1.value#12.v1
-   4:[*] -> component#9.namevalue#1.value#12.v1
-  Epsilon closure :
-    (self)
-
-NFA state 341 = main.component#9.namevalue#1.value#12.v1
-  [(epsilon)] -> component#9.namevalue#1.value#12.#1
-  [(epsilon)] -> component#9.namevalue#1.value#12.out
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.value#12.v1
-   11:[A-Z_a-z] -> component#9.namevalue#1.value#12.v1
-   10:[=] -> component#9.namevalue#1.value#12.v1
-   8:[0-9] -> component#9.namevalue#1.value#12.v1
-   7:[/] -> component#9.namevalue#1.value#12.v1
-   6:[\055] -> component#9.namevalue#1.value#12.v1
-   5:[+.] -> component#9.namevalue#1.value#12.v1
-   4:[*] -> component#9.namevalue#1.value#12.v1
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#12
-    main.component#9.namevalue#1.value#12.#1
-    main.component#9.namevalue#1.value#12.out
-    main.component#9.namevalue#1.optwhite#13.in
-    main.component#9.namevalue#1.optwhite#13.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 342 = main.component#9.namevalue#1.value#12.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 343 = main.component#9.namevalue#1.value#12.out
-  [(epsilon)] -> component#9.namevalue#1.#12
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#12
-    main.component#9.namevalue#1.optwhite#13.in
-    main.component#9.namevalue#1.optwhite#13.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 344 = main.component#9.namevalue#1.optwhite#13.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#13.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#13.in
-   1:[\r] -> component#9.namevalue#1.optwhite#13.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#13.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 345 = main.component#9.namevalue#1.optwhite#13.out
-  [(epsilon)] -> component#9.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 346 = main.component#9.namevalue#1.#13
-  [(epsilon)] -> component#9.namevalue#1.#14
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#14
-
-NFA state 347 = main.component#9.namevalue#1.optwhite#14.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#14.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#14.in
-   1:[\r] -> component#9.namevalue#1.optwhite#14.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#13
-    main.component#9.namevalue#1.optwhite#14.out
-    main.component#9.namevalue#1.#14
-
-NFA state 348 = main.component#9.namevalue#1.optwhite#14.out
-  [(epsilon)] -> component#9.namevalue#1.#13
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#13
-    main.component#9.namevalue#1.#14
-
-NFA state 349 = main.component#9.namevalue#1.#14
-  EOS -> component#9.namevalue#1.out_normal
-  Epsilon closure :
-    (self)
-
-NFA state 350 = main.component#9.namevalue#1.rhs_continue
-  [(epsilon)] -> component#9.namevalue#1.optwhite#18.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#15.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#15
-    main.component#9.namevalue#1.optwhite#15.in
-    main.component#9.namevalue#1.optwhite#15.out
-    main.component#9.namevalue#1.qvalue#16.in
-    main.component#9.namevalue#1.#17
-    main.component#9.namevalue#1.optwhite#18.in
-    main.component#9.namevalue#1.optwhite#18.out
-    main.component#9.namevalue#1.value#19.in
-
-NFA state 351 = main.component#9.namevalue#1.#15
-  [(epsilon)] -> component#9.namevalue#1.qvalue#16.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#16.in
-
-NFA state 352 = main.component#9.namevalue#1.optwhite#15.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#15.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#15.in
-   1:[\r] -> component#9.namevalue#1.optwhite#15.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#15
-    main.component#9.namevalue#1.optwhite#15.out
-    main.component#9.namevalue#1.qvalue#16.in
-
-NFA state 353 = main.component#9.namevalue#1.optwhite#15.out
-  [(epsilon)] -> component#9.namevalue#1.#15
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#15
-    main.component#9.namevalue#1.qvalue#16.in
-
-NFA state 354 = main.component#9.namevalue#1.#16
-  [(epsilon)] -> component#9.namevalue#1.optwhite#17.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#17.in
-    main.component#9.namevalue#1.optwhite#17.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 355 = main.component#9.namevalue#1.qvalue#16.in
-   3:["] -> component#9.namevalue#1.qvalue#16.qv0
-  Epsilon closure :
-    (self)
-
-NFA state 356 = main.component#9.namevalue#1.qvalue#16.qv0
-  [(epsilon)] -> component#9.namevalue#1.qvalue#16.escape#1.in
-   0:[\t ] -> component#9.namevalue#1.qvalue#16.qv1
-   9:[;] -> component#9.namevalue#1.qvalue#16.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.qvalue#16.qv1
-   11:[A-Z_a-z] -> component#9.namevalue#1.qvalue#16.qv1
-   10:[=] -> component#9.namevalue#1.qvalue#16.qv1
-   8:[0-9] -> component#9.namevalue#1.qvalue#16.qv1
-   7:[/] -> component#9.namevalue#1.qvalue#16.qv1
-   6:[\055] -> component#9.namevalue#1.qvalue#16.qv1
-   5:[+.] -> component#9.namevalue#1.qvalue#16.qv1
-   4:[*] -> component#9.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#16.escape#1.in
-
-NFA state 357 = main.component#9.namevalue#1.qvalue#16.escape#1.in
-   12:[\\] -> component#9.namevalue#1.qvalue#16.escape#1.#2
-   12:[\\] -> component#9.namevalue#1.qvalue#16.escape#1.#1
-  Epsilon closure :
-    (self)
-
-NFA state 358 = main.component#9.namevalue#1.qvalue#16.escape#1.#1
-   12:[\\] -> component#9.namevalue#1.qvalue#16.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 359 = main.component#9.namevalue#1.qvalue#16.escape#1.#2
-   3:["] -> component#9.namevalue#1.qvalue#16.escape#1.out
-  Epsilon closure :
-    (self)
-
-NFA state 360 = main.component#9.namevalue#1.qvalue#16.escape#1.out
-  [(epsilon)] -> component#9.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#16.qv1
-    main.component#9.namevalue#1.qvalue#16.#1
-    main.component#9.namevalue#1.qvalue#16.escape#2.in
-    main.component#9.namevalue#1.qvalue#16.qv2
-
-NFA state 361 = main.component#9.namevalue#1.qvalue#16.qv1
-  [(epsilon)] -> component#9.namevalue#1.qvalue#16.#1
-  [(epsilon)] -> component#9.namevalue#1.qvalue#16.escape#2.in
-   0:[\t ] -> component#9.namevalue#1.qvalue#16.qv1
-   9:[;] -> component#9.namevalue#1.qvalue#16.qv1
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.qvalue#16.qv1
-   11:[A-Z_a-z] -> component#9.namevalue#1.qvalue#16.qv1
-   10:[=] -> component#9.namevalue#1.qvalue#16.qv1
-   8:[0-9] -> component#9.namevalue#1.qvalue#16.qv1
-   7:[/] -> component#9.namevalue#1.qvalue#16.qv1
-   6:[\055] -> component#9.namevalue#1.qvalue#16.qv1
-   5:[+.] -> component#9.namevalue#1.qvalue#16.qv1
-   4:[*] -> component#9.namevalue#1.qvalue#16.qv1
-  [(epsilon)] -> component#9.namevalue#1.qvalue#16.qv2
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#16.#1
-    main.component#9.namevalue#1.qvalue#16.escape#2.in
-    main.component#9.namevalue#1.qvalue#16.qv2
-
-NFA state 362 = main.component#9.namevalue#1.qvalue#16.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 363 = main.component#9.namevalue#1.qvalue#16.escape#2.in
-   12:[\\] -> component#9.namevalue#1.qvalue#16.escape#2.#2
-   12:[\\] -> component#9.namevalue#1.qvalue#16.escape#2.#1
-  Epsilon closure :
-    (self)
-
-NFA state 364 = main.component#9.namevalue#1.qvalue#16.escape#2.#1
-   12:[\\] -> component#9.namevalue#1.qvalue#16.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 365 = main.component#9.namevalue#1.qvalue#16.escape#2.#2
-   3:["] -> component#9.namevalue#1.qvalue#16.escape#2.out
-  Epsilon closure :
-    (self)
-
-NFA state 366 = main.component#9.namevalue#1.qvalue#16.escape#2.out
-  [(epsilon)] -> component#9.namevalue#1.qvalue#16.qv1
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.qvalue#16.qv1
-    main.component#9.namevalue#1.qvalue#16.#1
-    main.component#9.namevalue#1.qvalue#16.escape#2.in
-    main.component#9.namevalue#1.qvalue#16.qv2
-
-NFA state 367 = main.component#9.namevalue#1.qvalue#16.qv2
-   3:["] -> component#9.namevalue#1.qvalue#16.out
-  Epsilon closure :
-    (self)
-
-NFA state 368 = main.component#9.namevalue#1.qvalue#16.out
-  [(epsilon)] -> component#9.namevalue#1.#16
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#16
-    main.component#9.namevalue#1.optwhite#17.in
-    main.component#9.namevalue#1.optwhite#17.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 369 = main.component#9.namevalue#1.optwhite#17.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#17.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#17.in
-   1:[\r] -> component#9.namevalue#1.optwhite#17.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#17.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 370 = main.component#9.namevalue#1.optwhite#17.out
-  [(epsilon)] -> component#9.namevalue#1.out_continue
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 371 = main.component#9.namevalue#1.#17
-  [(epsilon)] -> component#9.namevalue#1.value#19.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.value#19.in
-
-NFA state 372 = main.component#9.namevalue#1.optwhite#18.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#18.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#18.in
-   1:[\r] -> component#9.namevalue#1.optwhite#18.in
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#17
-    main.component#9.namevalue#1.optwhite#18.out
-    main.component#9.namevalue#1.value#19.in
-
-NFA state 373 = main.component#9.namevalue#1.optwhite#18.out
-  [(epsilon)] -> component#9.namevalue#1.#17
-  Epsilon closure :
-    (self)
-    main.component#9.namevalue#1.#17
-    main.component#9.namevalue#1.value#19.in
-
-NFA state 374 = main.component#9.namevalue#1.#18
-  [(epsilon)] -> component#9.namevalue#1.optwhite#20.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#20.in
-    main.component#9.namevalue#1.optwhite#20.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 375 = main.component#9.namevalue#1.value#19.in
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.value#19.v1
-   11:[A-Z_a-z] -> component#9.namevalue#1.value#19.v1
-   10:[=] -> component#9.namevalue#1.value#19.v1
-   8:[0-9] -> component#9.namevalue#1.value#19.v1
-   7:[/] -> component#9.namevalue#1.value#19.v1
-   6:[\055] -> component#9.namevalue#1.value#19.v1
-   5:[+.] -> component#9.namevalue#1.value#19.v1
-   4:[*] -> component#9.namevalue#1.value#19.v1
-  Epsilon closure :
-    (self)
-
-NFA state 376 = main.component#9.namevalue#1.value#19.v1
-  [(epsilon)] -> component#9.namevalue#1.value#19.#1
-  [(epsilon)] -> component#9.namevalue#1.value#19.out
-   2:[!#-),:<>-@[]^`{-~] -> component#9.namevalue#1.value#19.v1
-   11:[A-Z_a-z] -> component#9.namevalue#1.value#19.v1
-   10:[=] -> component#9.namevalue#1.value#19.v1
-   8:[0-9] -> component#9.namevalue#1.value#19.v1
-   7:[/] -> component#9.namevalue#1.value#19.v1
-   6:[\055] -> component#9.namevalue#1.value#19.v1
-   5:[+.] -> component#9.namevalue#1.value#19.v1
-   4:[*] -> component#9.namevalue#1.value#19.v1
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#18
-    main.component#9.namevalue#1.value#19.#1
-    main.component#9.namevalue#1.value#19.out
-    main.component#9.namevalue#1.optwhite#20.in
-    main.component#9.namevalue#1.optwhite#20.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 377 = main.component#9.namevalue#1.value#19.#1
-  Tags : COPY_TO_VALUE
-  Epsilon closure :
-    (self)
-
-NFA state 378 = main.component#9.namevalue#1.value#19.out
-  [(epsilon)] -> component#9.namevalue#1.#18
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#18
-    main.component#9.namevalue#1.optwhite#20.in
-    main.component#9.namevalue#1.optwhite#20.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 379 = main.component#9.namevalue#1.optwhite#20.in
-  [(epsilon)] -> component#9.namevalue#1.optwhite#20.out
-   0:[\t ] -> component#9.namevalue#1.optwhite#20.in
-   1:[\r] -> component#9.namevalue#1.optwhite#20.in
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.optwhite#20.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 380 = main.component#9.namevalue#1.optwhite#20.out
-  [(epsilon)] -> component#9.namevalue#1.out_continue
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 381 = main.component#9.namevalue#1.out_normal
-  [(epsilon)] -> component#9.namevalue#1.out
-  [(epsilon)] -> component#9.namevalue#1.#19
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 382 = main.component#9.namevalue#1.#19
-  Tags : GOT_NAMEVALUE
-  Epsilon closure :
-    (self)
-
-NFA state 383 = main.component#9.namevalue#1.out_continue
-  [(epsilon)] -> component#9.namevalue#1.out
-  [(epsilon)] -> component#9.namevalue#1.#20
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 384 = main.component#9.namevalue#1.#20
-  Tags : GOT_NAMEVALUE_CONT
-  Epsilon closure :
-    (self)
-
-NFA state 385 = main.component#9.namevalue#1.out
-  [(epsilon)] -> component#9.out
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 386 = main.component#9.name#2.in
-   6:[\055] -> component#9.name#2.name1
-   11:[A-Z_a-z] -> component#9.name#2.name1
-   8:[0-9] -> component#9.name#2.name1
-  Epsilon closure :
-    (self)
-
-NFA state 387 = main.component#9.name#2.name1
-  [(epsilon)] -> component#9.name#2.out
-   0:[\t ] -> component#9.name#2.name2
-   6:[\055] -> component#9.name#2.name1
-   11:[A-Z_a-z] -> component#9.name#2.name1
-   8:[0-9] -> component#9.name#2.name1
-  [(epsilon)] -> component#9.name#2.#2
-  [(epsilon)] -> component#9.name#2.#1
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.name#2.#1
-    main.component#9.name#2.#2
-    main.component#9.name#2.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 388 = main.component#9.name#2.#1
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 389 = main.component#9.name#2.#2
-  Tags : GOT_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 390 = main.component#9.name#2.name2
-  [(epsilon)] -> component#9.name#2.out
-   6:[\055] -> component#9.name#2.name1
-   11:[A-Z_a-z] -> component#9.name#2.name1
-   8:[0-9] -> component#9.name#2.name1
-   0:[\t ] -> component#9.name#2.name2
-  [(epsilon)] -> component#9.name#2.#4
-  [(epsilon)] -> component#9.name#2.#3
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.name#2.#3
-    main.component#9.name#2.#4
-    main.component#9.name#2.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 391 = main.component#9.name#2.#3
-  Tags : COPY_TO_NAME
-  Epsilon closure :
-    (self)
-
-NFA state 392 = main.component#9.name#2.#4
-  Tags : GOT_NAME_TRAILING_SPACE
-  Epsilon closure :
-    (self)
-
-NFA state 393 = main.component#9.name#2.out
-  [(epsilon)] -> component#9.out
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 394 = main.component#9.majorminor#3.in
-  [(epsilon)] -> component#9.majorminor#3.major#1.in
-  Epsilon closure :
-    (self)
-    main.component#9.majorminor#3.major#1.in
-
-NFA state 395 = main.component#9.majorminor#3.major#1.in
-   6:[\055] -> component#9.majorminor#3.major#1.name1
-   11:[A-Z_a-z] -> component#9.majorminor#3.major#1.name1
-   8:[0-9] -> component#9.majorminor#3.major#1.name1
-  Epsilon closure :
-    (self)
-
-NFA state 396 = main.component#9.majorminor#3.major#1.name1
-   6:[\055] -> component#9.majorminor#3.major#1.name1
-   11:[A-Z_a-z] -> component#9.majorminor#3.major#1.name1
-   8:[0-9] -> component#9.majorminor#3.major#1.name1
-  [(epsilon)] -> component#9.majorminor#3.major#1.out
-  Epsilon closure :
-    (self)
-    main.component#9.majorminor#3.major#1.out
-    main.component#9.majorminor#3.foo
-
-NFA state 397 = main.component#9.majorminor#3.major#1.out
-  [(epsilon)] -> component#9.majorminor#3.foo
-  Epsilon closure :
-    (self)
-    main.component#9.majorminor#3.foo
-
-NFA state 398 = main.component#9.majorminor#3.foo
-   7:[/] -> component#9.majorminor#3.bar
-  Epsilon closure :
-    (self)
-
-NFA state 399 = main.component#9.majorminor#3.bar
-  [(epsilon)] -> component#9.majorminor#3.minor#2.in
-  Epsilon closure :
-    (self)
-    main.component#9.majorminor#3.minor#2.in
-
-NFA state 400 = main.component#9.majorminor#3.minor#2.in
-   5:[+.] -> component#9.majorminor#3.minor#2.minor1
-   12:[\\] -> component#9.majorminor#3.minor#2.minor1
-   6:[\055] -> component#9.majorminor#3.minor#2.minor1
-   6:[\055] -> component#9.majorminor#3.minor#2.minor1
-   11:[A-Z_a-z] -> component#9.majorminor#3.minor#2.minor1
-   8:[0-9] -> component#9.majorminor#3.minor#2.minor1
-  Epsilon closure :
-    (self)
-
-NFA state 401 = main.component#9.majorminor#3.minor#2.minor1
-  [(epsilon)] -> component#9.majorminor#3.minor#2.#1
-   5:[+.] -> component#9.majorminor#3.minor#2.minor1
-   12:[\\] -> component#9.majorminor#3.minor#2.minor1
-   6:[\055] -> component#9.majorminor#3.minor#2.minor1
-   6:[\055] -> component#9.majorminor#3.minor#2.minor1
-   11:[A-Z_a-z] -> component#9.majorminor#3.minor#2.minor1
-   8:[0-9] -> component#9.majorminor#3.minor#2.minor1
-  [(epsilon)] -> component#9.majorminor#3.minor#2.out
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.majorminor#3.minor#2.#1
-    main.component#9.majorminor#3.minor#2.out
-    main.component#9.majorminor#3.out
-    main.component#9.majorminor#3.#1
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 402 = main.component#9.majorminor#3.minor#2.#1
-  Tags : COPY_TO_MINOR
-  Epsilon closure :
-    (self)
-
-NFA state 403 = main.component#9.majorminor#3.minor#2.out
-  [(epsilon)] -> component#9.majorminor#3.out
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.majorminor#3.out
-    main.component#9.majorminor#3.#1
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 404 = main.component#9.majorminor#3.out
-  [(epsilon)] -> component#9.majorminor#3.#1
-  [(epsilon)] -> component#9.out
-  Epsilon closure :
-    (self)
-    main.#10
-    main.component#9.majorminor#3.#1
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 405 = main.component#9.majorminor#3.#1
-  Tags : GOT_MAJORMINOR
-  Epsilon closure :
-    (self)
-
-NFA state 406 = main.component#9.out
-  [(epsilon)] -> #10
-  Epsilon closure :
-    (self)
-    main.#10
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-NFA state 407 = main.#11
-   9:[;] -> in2
-  Epsilon closure :
-    (self)
-
-NFA state 408 = main.optwhite#10.in
-  [(epsilon)] -> optwhite#10.out
-   0:[\t ] -> optwhite#10.in
-   1:[\r] -> optwhite#10.in
-  Epsilon closure :
-    (self)
-    main.#11
-    main.optwhite#10.out
-
-NFA state 409 = main.optwhite#10.out
-  [(epsilon)] -> #11
-  Epsilon closure :
-    (self)
-    main.#11
-
-NFA state 410 = main.in2
-  [(epsilon)] -> in
-  [(epsilon)] -> #12
-  Epsilon closure :
-    (self)
-    main.in
-    main.#1
-    main.optwhite#1.in
-    main.optwhite#1.out
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-    main.#4
-    main.optwhite#4.in
-    main.optwhite#4.out
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-    main.#9
-    main.optwhite#8.in
-    main.optwhite#8.out
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-    main.#12
-
-NFA state 411 = main.#12
-  Tags : GOT_TERMINATOR
-  Epsilon closure :
-    (self)
-
-NFA state 412 = main.out2
-  [(epsilon)] -> out
-  [(epsilon)] -> #13
-  Epsilon closure :
-    (self)
-    main.#13
-    main.out
-
-NFA state 413 = main.#13
-  Tags : GOT_TERMINATOR
-  Epsilon closure :
-    (self)
-
-NFA state 414 = main.out
-  Epsilon closure :
-    (self)
-
---------------------------------
-DFA structure before compression
---------------------------------
-DFA state 0
-  NFA states :
-    main.in
-    main.#1
-    main.optwhite#1.in
-    main.optwhite#1.out
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-    main.#4
-    main.optwhite#4.in
-    main.optwhite#4.out
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-    main.#9
-    main.optwhite#8.in
-    main.optwhite#8.out
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-  Forward route :
-   (START)->(HERE)
-  Transitions :
-    0:[\t ] -> 1
-    1:[\r] -> 1
-    6:[\055] -> 2
-    8:[0-9] -> 2
-    11:[A-Z_a-z] -> 2
-
-DFA state 1
-  NFA states :
-    main.#1
-    main.optwhite#1.in
-    main.optwhite#1.out
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-    main.#4
-    main.optwhite#4.in
-    main.optwhite#4.out
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-    main.#9
-    main.optwhite#8.in
-    main.optwhite#8.out
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-  Forward route : (from state 0)
-   (START)->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 1
-    1:[\r] -> 1
-    6:[\055] -> 2
-    8:[0-9] -> 2
-    11:[A-Z_a-z] -> 2
-
-DFA state 2
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.#2
-    main.component#2.namevalue#1.name#2.name1
-    main.component#2.namevalue#1.name#2.#1
-    main.component#2.namevalue#1.name#2.#2
-    main.component#2.namevalue#1.name#2.out
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-    main.component#2.namevalue#1.#5
-    main.component#2.namevalue#1.name#5.name1
-    main.component#2.namevalue#1.name#5.#1
-    main.component#2.namevalue#1.name#5.#2
-    main.component#2.namevalue#1.name#5.out
-    main.component#2.name#2.name1
-    main.component#2.name#2.#1
-    main.component#2.name#2.#2
-    main.component#2.name#2.out
-    main.component#2.majorminor#3.major#1.name1
-    main.component#2.majorminor#3.major#1.out
-    main.component#2.majorminor#3.foo
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.#2
-    main.component#5.namevalue#1.name#2.name1
-    main.component#5.namevalue#1.name#2.#1
-    main.component#5.namevalue#1.name#2.#2
-    main.component#5.namevalue#1.name#2.out
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-    main.component#5.namevalue#1.#5
-    main.component#5.namevalue#1.name#5.name1
-    main.component#5.namevalue#1.name#5.#1
-    main.component#5.namevalue#1.name#5.#2
-    main.component#5.namevalue#1.name#5.out
-    main.component#5.name#2.name1
-    main.component#5.name#2.#1
-    main.component#5.name#2.#2
-    main.component#5.name#2.out
-    main.component#5.majorminor#3.major#1.name1
-    main.component#5.majorminor#3.major#1.out
-    main.component#5.majorminor#3.foo
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.#2
-    main.component#9.namevalue#1.name#2.name1
-    main.component#9.namevalue#1.name#2.#1
-    main.component#9.namevalue#1.name#2.#2
-    main.component#9.namevalue#1.name#2.out
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-    main.component#9.namevalue#1.#5
-    main.component#9.namevalue#1.name#5.name1
-    main.component#9.namevalue#1.name#5.#1
-    main.component#9.namevalue#1.name#5.#2
-    main.component#9.namevalue#1.name#5.out
-    main.component#9.name#2.name1
-    main.component#9.name#2.#1
-    main.component#9.name#2.#2
-    main.component#9.name#2.out
-    main.component#9.majorminor#3.major#1.name1
-    main.component#9.majorminor#3.major#1.out
-    main.component#9.majorminor#3.foo
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 0)
-   (START)->6:[\055]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 4
-    1:[\r] -> 5
-    4:[*] -> 6
-    6:[\055] -> 2
-    7:[/] -> 7
-    8:[0-9] -> 2
-    9:[;] -> 8
-    10:[=] -> 9
-    11:[A-Z_a-z] -> 2
-  NFA exit tags applying :
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-  Attributes for <copier> : COPY_TO_NAME
-  Attributes for <action> : GOT_NAME
-
-DFA state 3
-  NFA states :
-    main.out2
-    main.#13
-    main.out
-
-  Forward route : (from state 2)
-   (START)->6:[\055]->EOS->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    GOT_TERMINATOR
-  Attributes for <action> : GOT_TERMINATOR
-
-DFA state 4
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.#2
-    main.component#2.namevalue#1.name#2.name2
-    main.component#2.namevalue#1.name#2.#3
-    main.component#2.namevalue#1.name#2.#4
-    main.component#2.namevalue#1.name#2.out
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-    main.component#2.namevalue#1.#5
-    main.component#2.namevalue#1.name#5.name2
-    main.component#2.namevalue#1.name#5.#3
-    main.component#2.namevalue#1.name#5.#4
-    main.component#2.namevalue#1.name#5.out
-    main.component#2.name#2.name2
-    main.component#2.name#2.#3
-    main.component#2.name#2.#4
-    main.component#2.name#2.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.#2
-    main.component#5.namevalue#1.name#2.name2
-    main.component#5.namevalue#1.name#2.#3
-    main.component#5.namevalue#1.name#2.#4
-    main.component#5.namevalue#1.name#2.out
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-    main.component#5.namevalue#1.#5
-    main.component#5.namevalue#1.name#5.name2
-    main.component#5.namevalue#1.name#5.#3
-    main.component#5.namevalue#1.name#5.#4
-    main.component#5.namevalue#1.name#5.out
-    main.component#5.name#2.name2
-    main.component#5.name#2.#3
-    main.component#5.name#2.#4
-    main.component#5.name#2.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.#2
-    main.component#9.namevalue#1.name#2.name2
-    main.component#9.namevalue#1.name#2.#3
-    main.component#9.namevalue#1.name#2.#4
-    main.component#9.namevalue#1.name#2.out
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-    main.component#9.namevalue#1.#5
-    main.component#9.namevalue#1.name#5.name2
-    main.component#9.namevalue#1.name#5.#3
-    main.component#9.namevalue#1.name#5.#4
-    main.component#9.namevalue#1.name#5.out
-    main.component#9.name#2.name2
-    main.component#9.name#2.#3
-    main.component#9.name#2.#4
-    main.component#9.name#2.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 2)
-   (START)->6:[\055]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 4
-    1:[\r] -> 5
-    4:[*] -> 6
-    6:[\055] -> 10
-    8:[0-9] -> 10
-    9:[;] -> 8
-    10:[=] -> 9
-    11:[A-Z_a-z] -> 10
-  NFA exit tags applying :
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-  Attributes for <copier> : COPY_TO_NAME
-  Attributes for <action> : GOT_NAME_TRAILING_SPACE
-
-DFA state 5
-  NFA states :
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 2)
-   (START)->6:[\055]->1:[\r]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 5
-    1:[\r] -> 5
-    9:[;] -> 8
-    10:[=] -> 9
-
-DFA state 6
-  NFA states :
-    main.component#2.namevalue#1.#6
-    main.component#2.namevalue#1.digits#6.in
-    main.component#5.namevalue#1.#6
-    main.component#5.namevalue#1.digits#6.in
-    main.component#9.namevalue#1.#6
-    main.component#9.namevalue#1.digits#6.in
-
-  Forward route : (from state 2)
-   (START)->6:[\055]->4:[*]->(HERE)
-  Transitions :
-    8:[0-9] -> 11
-
-DFA state 7
-  NFA states :
-    main.component#2.majorminor#3.bar
-    main.component#2.majorminor#3.minor#2.in
-    main.component#5.majorminor#3.bar
-    main.component#5.majorminor#3.minor#2.in
-    main.component#9.majorminor#3.bar
-    main.component#9.majorminor#3.minor#2.in
-
-  Forward route : (from state 2)
-   (START)->6:[\055]->7:[/]->(HERE)
-  Transitions :
-    5:[+.] -> 12
-    6:[\055] -> 12
-    8:[0-9] -> 12
-    11:[A-Z_a-z] -> 12
-    12:[\\] -> 12
-
-DFA state 8
-  NFA states :
-    main.in
-    main.#1
-    main.optwhite#1.in
-    main.optwhite#1.out
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-    main.#4
-    main.optwhite#4.in
-    main.optwhite#4.out
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-    main.#7
-    main.#8
-    main.optwhite#7.in
-    main.optwhite#7.out
-    main.#9
-    main.optwhite#8.in
-    main.optwhite#8.out
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-    main.in2
-    main.#12
-
-  Forward route : (from state 2)
-   (START)->6:[\055]->9:[;]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 13
-    1:[\r] -> 13
-    6:[\055] -> 2
-    8:[0-9] -> 2
-    11:[A-Z_a-z] -> 2
-  NFA exit tags applying :
-    GOT_TERMINATOR
-  Attributes for <action> : GOT_TERMINATOR
-
-DFA state 9
-  NFA states :
-    main.component#2.namevalue#1.rhs_normal
-    main.component#2.namevalue#1.#9
-    main.component#2.namevalue#1.optwhite#8.in
-    main.component#2.namevalue#1.optwhite#8.out
-    main.component#2.namevalue#1.qvalue#9.in
-    main.component#2.namevalue#1.#11
-    main.component#2.namevalue#1.optwhite#11.in
-    main.component#2.namevalue#1.optwhite#11.out
-    main.component#2.namevalue#1.value#12.in
-    main.component#2.namevalue#1.#13
-    main.component#2.namevalue#1.optwhite#14.in
-    main.component#2.namevalue#1.optwhite#14.out
-    main.component#2.namevalue#1.#14
-    main.component#5.namevalue#1.rhs_normal
-    main.component#5.namevalue#1.#9
-    main.component#5.namevalue#1.optwhite#8.in
-    main.component#5.namevalue#1.optwhite#8.out
-    main.component#5.namevalue#1.qvalue#9.in
-    main.component#5.namevalue#1.#11
-    main.component#5.namevalue#1.optwhite#11.in
-    main.component#5.namevalue#1.optwhite#11.out
-    main.component#5.namevalue#1.value#12.in
-    main.component#5.namevalue#1.#13
-    main.component#5.namevalue#1.optwhite#14.in
-    main.component#5.namevalue#1.optwhite#14.out
-    main.component#5.namevalue#1.#14
-    main.component#9.namevalue#1.rhs_normal
-    main.component#9.namevalue#1.#9
-    main.component#9.namevalue#1.optwhite#8.in
-    main.component#9.namevalue#1.optwhite#8.out
-    main.component#9.namevalue#1.qvalue#9.in
-    main.component#9.namevalue#1.#11
-    main.component#9.namevalue#1.optwhite#11.in
-    main.component#9.namevalue#1.optwhite#11.out
-    main.component#9.namevalue#1.value#12.in
-    main.component#9.namevalue#1.#13
-    main.component#9.namevalue#1.optwhite#14.in
-    main.component#9.namevalue#1.optwhite#14.out
-    main.component#9.namevalue#1.#14
-
-  Forward route : (from state 2)
-   (START)->6:[\055]->10:[=]->(HERE)
-  Transitions :
-    EOS -> 14
-    0:[\t ] -> 15
-    1:[\r] -> 15
-    2:[!#-),:<>-@[]^`{-~] -> 16
-    3:["] -> 17
-    4:[*] -> 16
-    5:[+.] -> 16
-    6:[\055] -> 16
-    7:[/] -> 16
-    8:[0-9] -> 16
-    10:[=] -> 16
-    11:[A-Z_a-z] -> 16
-
-DFA state 10
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.#2
-    main.component#2.namevalue#1.name#2.name1
-    main.component#2.namevalue#1.name#2.#1
-    main.component#2.namevalue#1.name#2.#2
-    main.component#2.namevalue#1.name#2.out
-    main.component#2.namevalue#1.#3
-    main.component#2.namevalue#1.optwhite#3.in
-    main.component#2.namevalue#1.optwhite#3.out
-    main.component#2.namevalue#1.#5
-    main.component#2.namevalue#1.name#5.name1
-    main.component#2.namevalue#1.name#5.#1
-    main.component#2.namevalue#1.name#5.#2
-    main.component#2.namevalue#1.name#5.out
-    main.component#2.name#2.name1
-    main.component#2.name#2.#1
-    main.component#2.name#2.#2
-    main.component#2.name#2.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.#2
-    main.component#5.namevalue#1.name#2.name1
-    main.component#5.namevalue#1.name#2.#1
-    main.component#5.namevalue#1.name#2.#2
-    main.component#5.namevalue#1.name#2.out
-    main.component#5.namevalue#1.#3
-    main.component#5.namevalue#1.optwhite#3.in
-    main.component#5.namevalue#1.optwhite#3.out
-    main.component#5.namevalue#1.#5
-    main.component#5.namevalue#1.name#5.name1
-    main.component#5.namevalue#1.name#5.#1
-    main.component#5.namevalue#1.name#5.#2
-    main.component#5.namevalue#1.name#5.out
-    main.component#5.name#2.name1
-    main.component#5.name#2.#1
-    main.component#5.name#2.#2
-    main.component#5.name#2.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.#2
-    main.component#9.namevalue#1.name#2.name1
-    main.component#9.namevalue#1.name#2.#1
-    main.component#9.namevalue#1.name#2.#2
-    main.component#9.namevalue#1.name#2.out
-    main.component#9.namevalue#1.#3
-    main.component#9.namevalue#1.optwhite#3.in
-    main.component#9.namevalue#1.optwhite#3.out
-    main.component#9.namevalue#1.#5
-    main.component#9.namevalue#1.name#5.name1
-    main.component#9.namevalue#1.name#5.#1
-    main.component#9.namevalue#1.name#5.#2
-    main.component#9.namevalue#1.name#5.out
-    main.component#9.name#2.name1
-    main.component#9.name#2.#1
-    main.component#9.name#2.#2
-    main.component#9.name#2.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 4)
-   (START)->6:[\055]->0:[\t ]->6:[\055]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 4
-    1:[\r] -> 5
-    4:[*] -> 6
-    6:[\055] -> 10
-    8:[0-9] -> 10
-    9:[;] -> 8
-    10:[=] -> 9
-    11:[A-Z_a-z] -> 10
-  NFA exit tags applying :
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-  Attributes for <copier> : COPY_TO_NAME
-  Attributes for <action> : GOT_NAME
-
-DFA state 11
-  NFA states :
-    main.component#2.namevalue#1.#7
-    main.component#2.namevalue#1.digits#6.in
-    main.component#2.namevalue#1.digits#6.out
-    main.component#2.namevalue#1.#8
-    main.component#2.namevalue#1.optwhite#7.in
-    main.component#2.namevalue#1.optwhite#7.out
-    main.component#5.namevalue#1.#7
-    main.component#5.namevalue#1.digits#6.in
-    main.component#5.namevalue#1.digits#6.out
-    main.component#5.namevalue#1.#8
-    main.component#5.namevalue#1.optwhite#7.in
-    main.component#5.namevalue#1.optwhite#7.out
-    main.component#9.namevalue#1.#7
-    main.component#9.namevalue#1.digits#6.in
-    main.component#9.namevalue#1.digits#6.out
-    main.component#9.namevalue#1.#8
-    main.component#9.namevalue#1.optwhite#7.in
-    main.component#9.namevalue#1.optwhite#7.out
-
-  Forward route : (from state 6)
-   (START)->6:[\055]->4:[*]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 18
-    1:[\r] -> 18
-    8:[0-9] -> 11
-    10:[=] -> 19
-
-DFA state 12
-  NFA states :
-    main.#2
-    main.component#2.majorminor#3.minor#2.minor1
-    main.component#2.majorminor#3.minor#2.#1
-    main.component#2.majorminor#3.minor#2.out
-    main.component#2.majorminor#3.out
-    main.component#2.majorminor#3.#1
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.majorminor#3.minor#2.minor1
-    main.component#5.majorminor#3.minor#2.#1
-    main.component#5.majorminor#3.minor#2.out
-    main.component#5.majorminor#3.out
-    main.component#5.majorminor#3.#1
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.majorminor#3.minor#2.minor1
-    main.component#9.majorminor#3.minor#2.#1
-    main.component#9.majorminor#3.minor#2.out
-    main.component#9.majorminor#3.out
-    main.component#9.majorminor#3.#1
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 7)
-   (START)->6:[\055]->7:[/]->5:[+.]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 20
-    1:[\r] -> 20
-    5:[+.] -> 12
-    6:[\055] -> 12
-    8:[0-9] -> 12
-    9:[;] -> 8
-    11:[A-Z_a-z] -> 12
-    12:[\\] -> 12
-  NFA exit tags applying :
-    GOT_MAJORMINOR
-    COPY_TO_MINOR
-    GOT_MAJORMINOR
-    COPY_TO_MINOR
-    GOT_MAJORMINOR
-    COPY_TO_MINOR
-  Attributes for <copier> : COPY_TO_MINOR
-  Attributes for <action> : GOT_MAJORMINOR
-
-DFA state 13
-  NFA states :
-    main.#1
-    main.optwhite#1.in
-    main.optwhite#1.out
-    main.component#2.in
-    main.component#2.namevalue#1.in
-    main.component#2.namevalue#1.#1
-    main.component#2.namevalue#1.optwhite#1.in
-    main.component#2.namevalue#1.optwhite#1.out
-    main.component#2.namevalue#1.name#2.in
-    main.component#2.namevalue#1.#4
-    main.component#2.namevalue#1.optwhite#4.in
-    main.component#2.namevalue#1.optwhite#4.out
-    main.component#2.namevalue#1.name#5.in
-    main.component#2.name#2.in
-    main.component#2.majorminor#3.in
-    main.component#2.majorminor#3.major#1.in
-    main.#4
-    main.optwhite#4.in
-    main.optwhite#4.out
-    main.component#5.in
-    main.component#5.namevalue#1.in
-    main.component#5.namevalue#1.#1
-    main.component#5.namevalue#1.optwhite#1.in
-    main.component#5.namevalue#1.optwhite#1.out
-    main.component#5.namevalue#1.name#2.in
-    main.component#5.namevalue#1.#4
-    main.component#5.namevalue#1.optwhite#4.in
-    main.component#5.namevalue#1.optwhite#4.out
-    main.component#5.namevalue#1.name#5.in
-    main.component#5.name#2.in
-    main.component#5.majorminor#3.in
-    main.component#5.majorminor#3.major#1.in
-    main.#8
-    main.optwhite#7.in
-    main.optwhite#7.out
-    main.#9
-    main.optwhite#8.in
-    main.optwhite#8.out
-    main.component#9.in
-    main.component#9.namevalue#1.in
-    main.component#9.namevalue#1.#1
-    main.component#9.namevalue#1.optwhite#1.in
-    main.component#9.namevalue#1.optwhite#1.out
-    main.component#9.namevalue#1.name#2.in
-    main.component#9.namevalue#1.#4
-    main.component#9.namevalue#1.optwhite#4.in
-    main.component#9.namevalue#1.optwhite#4.out
-    main.component#9.namevalue#1.name#5.in
-    main.component#9.name#2.in
-    main.component#9.majorminor#3.in
-    main.component#9.majorminor#3.major#1.in
-
-  Forward route : (from state 8)
-   (START)->6:[\055]->9:[;]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 13
-    1:[\r] -> 13
-    6:[\055] -> 2
-    8:[0-9] -> 2
-    11:[A-Z_a-z] -> 2
-
-DFA state 14
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 9)
-   (START)->6:[\055]->10:[=]->EOS->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 20
-    1:[\r] -> 20
-    9:[;] -> 8
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 15
-  NFA states :
-    main.component#2.namevalue#1.#9
-    main.component#2.namevalue#1.optwhite#8.in
-    main.component#2.namevalue#1.optwhite#8.out
-    main.component#2.namevalue#1.qvalue#9.in
-    main.component#2.namevalue#1.#11
-    main.component#2.namevalue#1.optwhite#11.in
-    main.component#2.namevalue#1.optwhite#11.out
-    main.component#2.namevalue#1.value#12.in
-    main.component#2.namevalue#1.#13
-    main.component#2.namevalue#1.optwhite#14.in
-    main.component#2.namevalue#1.optwhite#14.out
-    main.component#2.namevalue#1.#14
-    main.component#5.namevalue#1.#9
-    main.component#5.namevalue#1.optwhite#8.in
-    main.component#5.namevalue#1.optwhite#8.out
-    main.component#5.namevalue#1.qvalue#9.in
-    main.component#5.namevalue#1.#11
-    main.component#5.namevalue#1.optwhite#11.in
-    main.component#5.namevalue#1.optwhite#11.out
-    main.component#5.namevalue#1.value#12.in
-    main.component#5.namevalue#1.#13
-    main.component#5.namevalue#1.optwhite#14.in
-    main.component#5.namevalue#1.optwhite#14.out
-    main.component#5.namevalue#1.#14
-    main.component#9.namevalue#1.#9
-    main.component#9.namevalue#1.optwhite#8.in
-    main.component#9.namevalue#1.optwhite#8.out
-    main.component#9.namevalue#1.qvalue#9.in
-    main.component#9.namevalue#1.#11
-    main.component#9.namevalue#1.optwhite#11.in
-    main.component#9.namevalue#1.optwhite#11.out
-    main.component#9.namevalue#1.value#12.in
-    main.component#9.namevalue#1.#13
-    main.component#9.namevalue#1.optwhite#14.in
-    main.component#9.namevalue#1.optwhite#14.out
-    main.component#9.namevalue#1.#14
-
-  Forward route : (from state 9)
-   (START)->6:[\055]->10:[=]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 14
-    0:[\t ] -> 15
-    1:[\r] -> 15
-    2:[!#-),:<>-@[]^`{-~] -> 16
-    3:["] -> 17
-    4:[*] -> 16
-    5:[+.] -> 16
-    6:[\055] -> 16
-    7:[/] -> 16
-    8:[0-9] -> 16
-    10:[=] -> 16
-    11:[A-Z_a-z] -> 16
-
-DFA state 16
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.#12
-    main.component#2.namevalue#1.value#12.v1
-    main.component#2.namevalue#1.value#12.#1
-    main.component#2.namevalue#1.value#12.out
-    main.component#2.namevalue#1.optwhite#13.in
-    main.component#2.namevalue#1.optwhite#13.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.#12
-    main.component#5.namevalue#1.value#12.v1
-    main.component#5.namevalue#1.value#12.#1
-    main.component#5.namevalue#1.value#12.out
-    main.component#5.namevalue#1.optwhite#13.in
-    main.component#5.namevalue#1.optwhite#13.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.#12
-    main.component#9.namevalue#1.value#12.v1
-    main.component#9.namevalue#1.value#12.#1
-    main.component#9.namevalue#1.value#12.out
-    main.component#9.namevalue#1.optwhite#13.in
-    main.component#9.namevalue#1.optwhite#13.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 9)
-   (START)->6:[\055]->10:[=]->2:[!#-),:<>-@[]^`{-~]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 21
-    1:[\r] -> 21
-    2:[!#-),:<>-@[]^`{-~] -> 16
-    4:[*] -> 16
-    5:[+.] -> 16
-    6:[\055] -> 16
-    7:[/] -> 16
-    8:[0-9] -> 16
-    9:[;] -> 8
-    10:[=] -> 16
-    11:[A-Z_a-z] -> 16
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    COPY_TO_VALUE
-    GOT_NAMEVALUE
-    COPY_TO_VALUE
-    GOT_NAMEVALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 17
-  NFA states :
-    main.component#2.namevalue#1.qvalue#9.qv0
-    main.component#2.namevalue#1.qvalue#9.escape#1.in
-    main.component#5.namevalue#1.qvalue#9.qv0
-    main.component#5.namevalue#1.qvalue#9.escape#1.in
-    main.component#9.namevalue#1.qvalue#9.qv0
-    main.component#9.namevalue#1.qvalue#9.escape#1.in
-
-  Forward route : (from state 9)
-   (START)->6:[\055]->10:[=]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 22
-    2:[!#-),:<>-@[]^`{-~] -> 22
-    4:[*] -> 22
-    5:[+.] -> 22
-    6:[\055] -> 22
-    7:[/] -> 22
-    8:[0-9] -> 22
-    9:[;] -> 22
-    10:[=] -> 22
-    11:[A-Z_a-z] -> 22
-    12:[\\] -> 23
-
-DFA state 18
-  NFA states :
-    main.component#2.namevalue#1.#8
-    main.component#2.namevalue#1.optwhite#7.in
-    main.component#2.namevalue#1.optwhite#7.out
-    main.component#5.namevalue#1.#8
-    main.component#5.namevalue#1.optwhite#7.in
-    main.component#5.namevalue#1.optwhite#7.out
-    main.component#9.namevalue#1.#8
-    main.component#9.namevalue#1.optwhite#7.in
-    main.component#9.namevalue#1.optwhite#7.out
-
-  Forward route : (from state 11)
-   (START)->6:[\055]->4:[*]->8:[0-9]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 18
-    1:[\r] -> 18
-    10:[=] -> 19
-
-DFA state 19
-  NFA states :
-    main.component#2.namevalue#1.rhs_continue
-    main.component#2.namevalue#1.#15
-    main.component#2.namevalue#1.optwhite#15.in
-    main.component#2.namevalue#1.optwhite#15.out
-    main.component#2.namevalue#1.qvalue#16.in
-    main.component#2.namevalue#1.#17
-    main.component#2.namevalue#1.optwhite#18.in
-    main.component#2.namevalue#1.optwhite#18.out
-    main.component#2.namevalue#1.value#19.in
-    main.component#5.namevalue#1.rhs_continue
-    main.component#5.namevalue#1.#15
-    main.component#5.namevalue#1.optwhite#15.in
-    main.component#5.namevalue#1.optwhite#15.out
-    main.component#5.namevalue#1.qvalue#16.in
-    main.component#5.namevalue#1.#17
-    main.component#5.namevalue#1.optwhite#18.in
-    main.component#5.namevalue#1.optwhite#18.out
-    main.component#5.namevalue#1.value#19.in
-    main.component#9.namevalue#1.rhs_continue
-    main.component#9.namevalue#1.#15
-    main.component#9.namevalue#1.optwhite#15.in
-    main.component#9.namevalue#1.optwhite#15.out
-    main.component#9.namevalue#1.qvalue#16.in
-    main.component#9.namevalue#1.#17
-    main.component#9.namevalue#1.optwhite#18.in
-    main.component#9.namevalue#1.optwhite#18.out
-    main.component#9.namevalue#1.value#19.in
-
-  Forward route : (from state 11)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->(HERE)
-  Transitions :
-    0:[\t ] -> 24
-    1:[\r] -> 24
-    2:[!#-),:<>-@[]^`{-~] -> 25
-    3:["] -> 26
-    4:[*] -> 25
-    5:[+.] -> 25
-    6:[\055] -> 25
-    7:[/] -> 25
-    8:[0-9] -> 25
-    10:[=] -> 25
-    11:[A-Z_a-z] -> 25
-
-DFA state 20
-  NFA states :
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 12)
-   (START)->6:[\055]->7:[/]->5:[+.]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 20
-    1:[\r] -> 20
-    9:[;] -> 8
-
-DFA state 21
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.optwhite#13.in
-    main.component#2.namevalue#1.optwhite#13.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.optwhite#13.in
-    main.component#5.namevalue#1.optwhite#13.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.optwhite#13.in
-    main.component#9.namevalue#1.optwhite#13.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 16)
-   (START)->6:[\055]->10:[=]->2:[!#-),:<>-@[]^`{-~]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 21
-    1:[\r] -> 21
-    9:[;] -> 8
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 22
-  NFA states :
-    main.component#2.namevalue#1.qvalue#9.qv1
-    main.component#2.namevalue#1.qvalue#9.#1
-    main.component#2.namevalue#1.qvalue#9.escape#2.in
-    main.component#2.namevalue#1.qvalue#9.qv2
-    main.component#5.namevalue#1.qvalue#9.qv1
-    main.component#5.namevalue#1.qvalue#9.#1
-    main.component#5.namevalue#1.qvalue#9.escape#2.in
-    main.component#5.namevalue#1.qvalue#9.qv2
-    main.component#9.namevalue#1.qvalue#9.qv1
-    main.component#9.namevalue#1.qvalue#9.#1
-    main.component#9.namevalue#1.qvalue#9.escape#2.in
-    main.component#9.namevalue#1.qvalue#9.qv2
-
-  Forward route : (from state 17)
-   (START)->6:[\055]->10:[=]->3:["]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 22
-    2:[!#-),:<>-@[]^`{-~] -> 22
-    3:["] -> 27
-    4:[*] -> 22
-    5:[+.] -> 22
-    6:[\055] -> 22
-    7:[/] -> 22
-    8:[0-9] -> 22
-    9:[;] -> 22
-    10:[=] -> 22
-    11:[A-Z_a-z] -> 22
-    12:[\\] -> 28
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-DFA state 23
-  NFA states :
-    main.component#2.namevalue#1.qvalue#9.escape#1.#1
-    main.component#2.namevalue#1.qvalue#9.escape#1.#2
-    main.component#5.namevalue#1.qvalue#9.escape#1.#1
-    main.component#5.namevalue#1.qvalue#9.escape#1.#2
-    main.component#9.namevalue#1.qvalue#9.escape#1.#1
-    main.component#9.namevalue#1.qvalue#9.escape#1.#2
-
-  Forward route : (from state 17)
-   (START)->6:[\055]->10:[=]->3:["]->12:[\\]->(HERE)
-  Transitions :
-    3:["] -> 29
-    12:[\\] -> 29
-
-DFA state 24
-  NFA states :
-    main.component#2.namevalue#1.#15
-    main.component#2.namevalue#1.optwhite#15.in
-    main.component#2.namevalue#1.optwhite#15.out
-    main.component#2.namevalue#1.qvalue#16.in
-    main.component#2.namevalue#1.#17
-    main.component#2.namevalue#1.optwhite#18.in
-    main.component#2.namevalue#1.optwhite#18.out
-    main.component#2.namevalue#1.value#19.in
-    main.component#5.namevalue#1.#15
-    main.component#5.namevalue#1.optwhite#15.in
-    main.component#5.namevalue#1.optwhite#15.out
-    main.component#5.namevalue#1.qvalue#16.in
-    main.component#5.namevalue#1.#17
-    main.component#5.namevalue#1.optwhite#18.in
-    main.component#5.namevalue#1.optwhite#18.out
-    main.component#5.namevalue#1.value#19.in
-    main.component#9.namevalue#1.#15
-    main.component#9.namevalue#1.optwhite#15.in
-    main.component#9.namevalue#1.optwhite#15.out
-    main.component#9.namevalue#1.qvalue#16.in
-    main.component#9.namevalue#1.#17
-    main.component#9.namevalue#1.optwhite#18.in
-    main.component#9.namevalue#1.optwhite#18.out
-    main.component#9.namevalue#1.value#19.in
-
-  Forward route : (from state 19)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 24
-    1:[\r] -> 24
-    2:[!#-),:<>-@[]^`{-~] -> 25
-    3:["] -> 26
-    4:[*] -> 25
-    5:[+.] -> 25
-    6:[\055] -> 25
-    7:[/] -> 25
-    8:[0-9] -> 25
-    10:[=] -> 25
-    11:[A-Z_a-z] -> 25
-
-DFA state 25
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.#18
-    main.component#2.namevalue#1.value#19.v1
-    main.component#2.namevalue#1.value#19.#1
-    main.component#2.namevalue#1.value#19.out
-    main.component#2.namevalue#1.optwhite#20.in
-    main.component#2.namevalue#1.optwhite#20.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.#18
-    main.component#5.namevalue#1.value#19.v1
-    main.component#5.namevalue#1.value#19.#1
-    main.component#5.namevalue#1.value#19.out
-    main.component#5.namevalue#1.optwhite#20.in
-    main.component#5.namevalue#1.optwhite#20.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.#18
-    main.component#9.namevalue#1.value#19.v1
-    main.component#9.namevalue#1.value#19.#1
-    main.component#9.namevalue#1.value#19.out
-    main.component#9.namevalue#1.optwhite#20.in
-    main.component#9.namevalue#1.optwhite#20.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 19)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->2:[!#-),:<>-@[]^`{-~]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 30
-    1:[\r] -> 30
-    2:[!#-),:<>-@[]^`{-~] -> 25
-    4:[*] -> 25
-    5:[+.] -> 25
-    6:[\055] -> 25
-    7:[/] -> 25
-    8:[0-9] -> 25
-    9:[;] -> 8
-    10:[=] -> 25
-    11:[A-Z_a-z] -> 25
-  NFA exit tags applying :
-    GOT_NAMEVALUE_CONT
-    COPY_TO_VALUE
-    GOT_NAMEVALUE_CONT
-    COPY_TO_VALUE
-    GOT_NAMEVALUE_CONT
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-  Attributes for <action> : GOT_NAMEVALUE_CONT
-
-DFA state 26
-  NFA states :
-    main.component#2.namevalue#1.qvalue#16.qv0
-    main.component#2.namevalue#1.qvalue#16.escape#1.in
-    main.component#5.namevalue#1.qvalue#16.qv0
-    main.component#5.namevalue#1.qvalue#16.escape#1.in
-    main.component#9.namevalue#1.qvalue#16.qv0
-    main.component#9.namevalue#1.qvalue#16.escape#1.in
-
-  Forward route : (from state 19)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 31
-    2:[!#-),:<>-@[]^`{-~] -> 31
-    4:[*] -> 31
-    5:[+.] -> 31
-    6:[\055] -> 31
-    7:[/] -> 31
-    8:[0-9] -> 31
-    9:[;] -> 31
-    10:[=] -> 31
-    11:[A-Z_a-z] -> 31
-    12:[\\] -> 32
-
-DFA state 27
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.#10
-    main.component#2.namevalue#1.qvalue#9.out
-    main.component#2.namevalue#1.optwhite#10.in
-    main.component#2.namevalue#1.optwhite#10.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.#10
-    main.component#5.namevalue#1.qvalue#9.out
-    main.component#5.namevalue#1.optwhite#10.in
-    main.component#5.namevalue#1.optwhite#10.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.#10
-    main.component#9.namevalue#1.qvalue#9.out
-    main.component#9.namevalue#1.optwhite#10.in
-    main.component#9.namevalue#1.optwhite#10.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 22)
-   (START)->6:[\055]->10:[=]->3:["]->0:[\t ]->3:["]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 33
-    1:[\r] -> 33
-    9:[;] -> 8
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 28
-  NFA states :
-    main.component#2.namevalue#1.qvalue#9.escape#2.#1
-    main.component#2.namevalue#1.qvalue#9.escape#2.#2
-    main.component#5.namevalue#1.qvalue#9.escape#2.#1
-    main.component#5.namevalue#1.qvalue#9.escape#2.#2
-    main.component#9.namevalue#1.qvalue#9.escape#2.#1
-    main.component#9.namevalue#1.qvalue#9.escape#2.#2
-
-  Forward route : (from state 22)
-   (START)->6:[\055]->10:[=]->3:["]->0:[\t ]->12:[\\]->(HERE)
-  Transitions :
-    3:["] -> 34
-    12:[\\] -> 34
-
-DFA state 29
-  NFA states :
-    main.component#2.namevalue#1.qvalue#9.escape#1.out
-    main.component#2.namevalue#1.qvalue#9.qv1
-    main.component#2.namevalue#1.qvalue#9.#1
-    main.component#2.namevalue#1.qvalue#9.escape#2.in
-    main.component#2.namevalue#1.qvalue#9.qv2
-    main.component#5.namevalue#1.qvalue#9.escape#1.out
-    main.component#5.namevalue#1.qvalue#9.qv1
-    main.component#5.namevalue#1.qvalue#9.#1
-    main.component#5.namevalue#1.qvalue#9.escape#2.in
-    main.component#5.namevalue#1.qvalue#9.qv2
-    main.component#9.namevalue#1.qvalue#9.escape#1.out
-    main.component#9.namevalue#1.qvalue#9.qv1
-    main.component#9.namevalue#1.qvalue#9.#1
-    main.component#9.namevalue#1.qvalue#9.escape#2.in
-    main.component#9.namevalue#1.qvalue#9.qv2
-
-  Forward route : (from state 23)
-   (START)->6:[\055]->10:[=]->3:["]->12:[\\]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 22
-    2:[!#-),:<>-@[]^`{-~] -> 22
-    3:["] -> 27
-    4:[*] -> 22
-    5:[+.] -> 22
-    6:[\055] -> 22
-    7:[/] -> 22
-    8:[0-9] -> 22
-    9:[;] -> 22
-    10:[=] -> 22
-    11:[A-Z_a-z] -> 22
-    12:[\\] -> 28
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-DFA state 30
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.optwhite#20.in
-    main.component#2.namevalue#1.optwhite#20.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.optwhite#20.in
-    main.component#5.namevalue#1.optwhite#20.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.optwhite#20.in
-    main.component#9.namevalue#1.optwhite#20.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 25)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->2:[!#-),:<>-@[]^`{-~]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 30
-    1:[\r] -> 30
-    9:[;] -> 8
-  NFA exit tags applying :
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-  Attributes for <action> : GOT_NAMEVALUE_CONT
-
-DFA state 31
-  NFA states :
-    main.component#2.namevalue#1.qvalue#16.qv1
-    main.component#2.namevalue#1.qvalue#16.#1
-    main.component#2.namevalue#1.qvalue#16.escape#2.in
-    main.component#2.namevalue#1.qvalue#16.qv2
-    main.component#5.namevalue#1.qvalue#16.qv1
-    main.component#5.namevalue#1.qvalue#16.#1
-    main.component#5.namevalue#1.qvalue#16.escape#2.in
-    main.component#5.namevalue#1.qvalue#16.qv2
-    main.component#9.namevalue#1.qvalue#16.qv1
-    main.component#9.namevalue#1.qvalue#16.#1
-    main.component#9.namevalue#1.qvalue#16.escape#2.in
-    main.component#9.namevalue#1.qvalue#16.qv2
-
-  Forward route : (from state 26)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 31
-    2:[!#-),:<>-@[]^`{-~] -> 31
-    3:["] -> 35
-    4:[*] -> 31
-    5:[+.] -> 31
-    6:[\055] -> 31
-    7:[/] -> 31
-    8:[0-9] -> 31
-    9:[;] -> 31
-    10:[=] -> 31
-    11:[A-Z_a-z] -> 31
-    12:[\\] -> 36
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-DFA state 32
-  NFA states :
-    main.component#2.namevalue#1.qvalue#16.escape#1.#1
-    main.component#2.namevalue#1.qvalue#16.escape#1.#2
-    main.component#5.namevalue#1.qvalue#16.escape#1.#1
-    main.component#5.namevalue#1.qvalue#16.escape#1.#2
-    main.component#9.namevalue#1.qvalue#16.escape#1.#1
-    main.component#9.namevalue#1.qvalue#16.escape#1.#2
-
-  Forward route : (from state 26)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->12:[\\]->(HERE)
-  Transitions :
-    3:["] -> 37
-    12:[\\] -> 37
-
-DFA state 33
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.optwhite#10.in
-    main.component#2.namevalue#1.optwhite#10.out
-    main.component#2.namevalue#1.out_normal
-    main.component#2.namevalue#1.#19
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.optwhite#10.in
-    main.component#5.namevalue#1.optwhite#10.out
-    main.component#5.namevalue#1.out_normal
-    main.component#5.namevalue#1.#19
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.optwhite#10.in
-    main.component#9.namevalue#1.optwhite#10.out
-    main.component#9.namevalue#1.out_normal
-    main.component#9.namevalue#1.#19
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 27)
-   (START)->6:[\055]->10:[=]->3:["]->0:[\t ]->3:["]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 33
-    1:[\r] -> 33
-    9:[;] -> 8
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 34
-  NFA states :
-    main.component#2.namevalue#1.qvalue#9.qv1
-    main.component#2.namevalue#1.qvalue#9.#1
-    main.component#2.namevalue#1.qvalue#9.escape#2.in
-    main.component#2.namevalue#1.qvalue#9.escape#2.out
-    main.component#2.namevalue#1.qvalue#9.qv2
-    main.component#5.namevalue#1.qvalue#9.qv1
-    main.component#5.namevalue#1.qvalue#9.#1
-    main.component#5.namevalue#1.qvalue#9.escape#2.in
-    main.component#5.namevalue#1.qvalue#9.escape#2.out
-    main.component#5.namevalue#1.qvalue#9.qv2
-    main.component#9.namevalue#1.qvalue#9.qv1
-    main.component#9.namevalue#1.qvalue#9.#1
-    main.component#9.namevalue#1.qvalue#9.escape#2.in
-    main.component#9.namevalue#1.qvalue#9.escape#2.out
-    main.component#9.namevalue#1.qvalue#9.qv2
-
-  Forward route : (from state 28)
-   (START)->6:[\055]->10:[=]->3:["]->0:[\t ]->12:[\\]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 22
-    2:[!#-),:<>-@[]^`{-~] -> 22
-    3:["] -> 27
-    4:[*] -> 22
-    5:[+.] -> 22
-    6:[\055] -> 22
-    7:[/] -> 22
-    8:[0-9] -> 22
-    9:[;] -> 22
-    10:[=] -> 22
-    11:[A-Z_a-z] -> 22
-    12:[\\] -> 28
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-DFA state 35
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.#16
-    main.component#2.namevalue#1.qvalue#16.out
-    main.component#2.namevalue#1.optwhite#17.in
-    main.component#2.namevalue#1.optwhite#17.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.#16
-    main.component#5.namevalue#1.qvalue#16.out
-    main.component#5.namevalue#1.optwhite#17.in
-    main.component#5.namevalue#1.optwhite#17.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.#16
-    main.component#9.namevalue#1.qvalue#16.out
-    main.component#9.namevalue#1.optwhite#17.in
-    main.component#9.namevalue#1.optwhite#17.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 31)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->0:[\t ]->3:["]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 38
-    1:[\r] -> 38
-    9:[;] -> 8
-  NFA exit tags applying :
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-  Attributes for <action> : GOT_NAMEVALUE_CONT
-
-DFA state 36
-  NFA states :
-    main.component#2.namevalue#1.qvalue#16.escape#2.#1
-    main.component#2.namevalue#1.qvalue#16.escape#2.#2
-    main.component#5.namevalue#1.qvalue#16.escape#2.#1
-    main.component#5.namevalue#1.qvalue#16.escape#2.#2
-    main.component#9.namevalue#1.qvalue#16.escape#2.#1
-    main.component#9.namevalue#1.qvalue#16.escape#2.#2
-
-  Forward route : (from state 31)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->0:[\t ]->12:[\\]->(HERE)
-  Transitions :
-    3:["] -> 39
-    12:[\\] -> 39
-
-DFA state 37
-  NFA states :
-    main.component#2.namevalue#1.qvalue#16.escape#1.out
-    main.component#2.namevalue#1.qvalue#16.qv1
-    main.component#2.namevalue#1.qvalue#16.#1
-    main.component#2.namevalue#1.qvalue#16.escape#2.in
-    main.component#2.namevalue#1.qvalue#16.qv2
-    main.component#5.namevalue#1.qvalue#16.escape#1.out
-    main.component#5.namevalue#1.qvalue#16.qv1
-    main.component#5.namevalue#1.qvalue#16.#1
-    main.component#5.namevalue#1.qvalue#16.escape#2.in
-    main.component#5.namevalue#1.qvalue#16.qv2
-    main.component#9.namevalue#1.qvalue#16.escape#1.out
-    main.component#9.namevalue#1.qvalue#16.qv1
-    main.component#9.namevalue#1.qvalue#16.#1
-    main.component#9.namevalue#1.qvalue#16.escape#2.in
-    main.component#9.namevalue#1.qvalue#16.qv2
-
-  Forward route : (from state 32)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->12:[\\]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 31
-    2:[!#-),:<>-@[]^`{-~] -> 31
-    3:["] -> 35
-    4:[*] -> 31
-    5:[+.] -> 31
-    6:[\055] -> 31
-    7:[/] -> 31
-    8:[0-9] -> 31
-    9:[;] -> 31
-    10:[=] -> 31
-    11:[A-Z_a-z] -> 31
-    12:[\\] -> 36
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-DFA state 38
-  NFA states :
-    main.#2
-    main.component#2.namevalue#1.optwhite#17.in
-    main.component#2.namevalue#1.optwhite#17.out
-    main.component#2.namevalue#1.out_continue
-    main.component#2.namevalue#1.#20
-    main.component#2.namevalue#1.out
-    main.component#2.out
-    main.#3
-    main.optwhite#3.in
-    main.optwhite#3.out
-    main.#5
-    main.component#5.namevalue#1.optwhite#17.in
-    main.component#5.namevalue#1.optwhite#17.out
-    main.component#5.namevalue#1.out_continue
-    main.component#5.namevalue#1.#20
-    main.component#5.namevalue#1.out
-    main.component#5.out
-    main.#6
-    main.optwhite#6.in
-    main.optwhite#6.out
-    main.#10
-    main.component#9.namevalue#1.optwhite#17.in
-    main.component#9.namevalue#1.optwhite#17.out
-    main.component#9.namevalue#1.out_continue
-    main.component#9.namevalue#1.#20
-    main.component#9.namevalue#1.out
-    main.component#9.out
-    main.#11
-    main.optwhite#10.in
-    main.optwhite#10.out
-
-  Forward route : (from state 35)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->0:[\t ]->3:["]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 3
-    0:[\t ] -> 38
-    1:[\r] -> 38
-    9:[;] -> 8
-  NFA exit tags applying :
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-  Attributes for <action> : GOT_NAMEVALUE_CONT
-
-DFA state 39
-  NFA states :
-    main.component#2.namevalue#1.qvalue#16.qv1
-    main.component#2.namevalue#1.qvalue#16.#1
-    main.component#2.namevalue#1.qvalue#16.escape#2.in
-    main.component#2.namevalue#1.qvalue#16.escape#2.out
-    main.component#2.namevalue#1.qvalue#16.qv2
-    main.component#5.namevalue#1.qvalue#16.qv1
-    main.component#5.namevalue#1.qvalue#16.#1
-    main.component#5.namevalue#1.qvalue#16.escape#2.in
-    main.component#5.namevalue#1.qvalue#16.escape#2.out
-    main.component#5.namevalue#1.qvalue#16.qv2
-    main.component#9.namevalue#1.qvalue#16.qv1
-    main.component#9.namevalue#1.qvalue#16.#1
-    main.component#9.namevalue#1.qvalue#16.escape#2.in
-    main.component#9.namevalue#1.qvalue#16.escape#2.out
-    main.component#9.namevalue#1.qvalue#16.qv2
-
-  Forward route : (from state 36)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->0:[\t ]->12:[\\]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 31
-    2:[!#-),:<>-@[]^`{-~] -> 31
-    3:["] -> 35
-    4:[*] -> 31
-    5:[+.] -> 31
-    6:[\055] -> 31
-    7:[/] -> 31
-    8:[0-9] -> 31
-    9:[;] -> 31
-    10:[=] -> 31
-    11:[A-Z_a-z] -> 31
-    12:[\\] -> 36
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-
-Entry states in DFA:
-Entry <in> : 0
-Searching for dead states...
-(no dead states found)
-
------------------------------
------- COMPRESSING DFA ------
------------------------------
-Old DFA state 0 becomes 0
-Old DFA state 1 becomes 0 (formerly 0)
-Old DFA state 2 becomes 1
-Old DFA state 3 becomes 2
-Old DFA state 4 becomes 3
-Old DFA state 5 becomes 4
-Old DFA state 6 becomes 5
-Old DFA state 7 becomes 6
-Old DFA state 8 becomes 7
-Old DFA state 9 becomes 8
-Old DFA state 10 becomes 9
-Old DFA state 11 becomes 10
-Old DFA state 12 becomes 11
-Old DFA state 13 becomes 12
-Old DFA state 14 becomes 13
-Old DFA state 15 becomes 8 (formerly 9)
-Old DFA state 16 becomes 14
-Old DFA state 17 becomes 15
-Old DFA state 18 becomes 16
-Old DFA state 19 becomes 17
-Old DFA state 20 becomes 18
-Old DFA state 21 becomes 19
-Old DFA state 22 becomes 20
-Old DFA state 23 becomes 21
-Old DFA state 24 becomes 17 (formerly 19)
-Old DFA state 25 becomes 22
-Old DFA state 26 becomes 23
-Old DFA state 27 becomes 19 (formerly 21)
-Old DFA state 28 becomes 21 (formerly 23)
-Old DFA state 29 becomes 20 (formerly 22)
-Old DFA state 30 becomes 24
-Old DFA state 31 becomes 25
-Old DFA state 32 becomes 26
-Old DFA state 33 becomes 19 (formerly 21)
-Old DFA state 34 becomes 20 (formerly 22)
-Old DFA state 35 becomes 24 (formerly 30)
-Old DFA state 36 becomes 26 (formerly 32)
-Old DFA state 37 becomes 25 (formerly 31)
-Old DFA state 38 becomes 24 (formerly 30)
-Old DFA state 39 becomes 25 (formerly 31)
-Entry <in>, formerly state 0, now state 0
--------------------------------
-DFA structure after compression
--------------------------------
-DFA state 0
-  Forward route :
-   (START)->(HERE)
-  Transitions :
-    0:[\t ] -> 0
-    1:[\r] -> 0
-    6:[\055] -> 1
-    8:[0-9] -> 1
-    11:[A-Z_a-z] -> 1
-
-DFA state 1
-  Forward route : (from state 0)
-   (START)->6:[\055]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 3
-    1:[\r] -> 4
-    4:[*] -> 5
-    6:[\055] -> 1
-    7:[/] -> 6
-    8:[0-9] -> 1
-    9:[;] -> 7
-    10:[=] -> 8
-    11:[A-Z_a-z] -> 1
-  NFA exit tags applying :
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-  Attributes for <copier> : COPY_TO_NAME
-  Attributes for <action> : GOT_NAME
-
-DFA state 2
-  Forward route : (from state 1)
-   (START)->6:[\055]->EOS->(HERE)
-  Transitions :
-  NFA exit tags applying :
-    GOT_TERMINATOR
-  Attributes for <action> : GOT_TERMINATOR
-
-DFA state 3
-  Forward route : (from state 1)
-   (START)->6:[\055]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 3
-    1:[\r] -> 4
-    4:[*] -> 5
-    6:[\055] -> 9
-    8:[0-9] -> 9
-    9:[;] -> 7
-    10:[=] -> 8
-    11:[A-Z_a-z] -> 9
-  Use state 1 as basis (4 fixups)
-  NFA exit tags applying :
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-    GOT_NAME_TRAILING_SPACE
-    COPY_TO_NAME
-  Attributes for <copier> : COPY_TO_NAME
-  Attributes for <action> : GOT_NAME_TRAILING_SPACE
-
-DFA state 4
-  Forward route : (from state 1)
-   (START)->6:[\055]->1:[\r]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 4
-    1:[\r] -> 4
-    9:[;] -> 7
-    10:[=] -> 8
-
-DFA state 5
-  Forward route : (from state 1)
-   (START)->6:[\055]->4:[*]->(HERE)
-  Transitions :
-    8:[0-9] -> 10
-
-DFA state 6
-  Forward route : (from state 1)
-   (START)->6:[\055]->7:[/]->(HERE)
-  Transitions :
-    5:[+.] -> 11
-    6:[\055] -> 11
-    8:[0-9] -> 11
-    11:[A-Z_a-z] -> 11
-    12:[\\] -> 11
-
-DFA state 7
-  Forward route : (from state 1)
-   (START)->6:[\055]->9:[;]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 12
-    1:[\r] -> 12
-    6:[\055] -> 1
-    8:[0-9] -> 1
-    11:[A-Z_a-z] -> 1
-  NFA exit tags applying :
-    GOT_TERMINATOR
-  Attributes for <action> : GOT_TERMINATOR
-
-DFA state 8
-  Forward route : (from state 1)
-   (START)->6:[\055]->10:[=]->(HERE)
-  Transitions :
-    EOS -> 13
-    0:[\t ] -> 8
-    1:[\r] -> 8
-    2:[!#-),:<>-@[]^`{-~] -> 14
-    3:["] -> 15
-    4:[*] -> 14
-    5:[+.] -> 14
-    6:[\055] -> 14
-    7:[/] -> 14
-    8:[0-9] -> 14
-    10:[=] -> 14
-    11:[A-Z_a-z] -> 14
-
-DFA state 9
-  Forward route : (from state 3)
-   (START)->6:[\055]->0:[\t ]->6:[\055]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 3
-    1:[\r] -> 4
-    4:[*] -> 5
-    6:[\055] -> 9
-    8:[0-9] -> 9
-    9:[;] -> 7
-    10:[=] -> 8
-    11:[A-Z_a-z] -> 9
-  Use state 1 as basis (4 fixups)
-  NFA exit tags applying :
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-    GOT_NAME
-    COPY_TO_NAME
-  Attributes for <copier> : COPY_TO_NAME
-  Attributes for <action> : GOT_NAME
-
-DFA state 10
-  Forward route : (from state 5)
-   (START)->6:[\055]->4:[*]->8:[0-9]->(HERE)
-  Transitions :
-    0:[\t ] -> 16
-    1:[\r] -> 16
-    8:[0-9] -> 10
-    10:[=] -> 17
-
-DFA state 11
-  Forward route : (from state 6)
-   (START)->6:[\055]->7:[/]->5:[+.]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 18
-    1:[\r] -> 18
-    5:[+.] -> 11
-    6:[\055] -> 11
-    8:[0-9] -> 11
-    9:[;] -> 7
-    11:[A-Z_a-z] -> 11
-    12:[\\] -> 11
-  Use state 6 as basis (4 fixups)
-  NFA exit tags applying :
-    GOT_MAJORMINOR
-    COPY_TO_MINOR
-    GOT_MAJORMINOR
-    COPY_TO_MINOR
-    GOT_MAJORMINOR
-    COPY_TO_MINOR
-  Attributes for <copier> : COPY_TO_MINOR
-  Attributes for <action> : GOT_MAJORMINOR
-
-DFA state 12
-  Forward route : (from state 7)
-   (START)->6:[\055]->9:[;]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 12
-    1:[\r] -> 12
-    6:[\055] -> 1
-    8:[0-9] -> 1
-    11:[A-Z_a-z] -> 1
-  Use state 7 as basis (0 fixups)
-
-DFA state 13
-  Forward route : (from state 8)
-   (START)->6:[\055]->10:[=]->EOS->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 18
-    1:[\r] -> 18
-    9:[;] -> 7
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 14
-  Forward route : (from state 8)
-   (START)->6:[\055]->10:[=]->2:[!#-),:<>-@[]^`{-~]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 19
-    1:[\r] -> 19
-    2:[!#-),:<>-@[]^`{-~] -> 14
-    4:[*] -> 14
-    5:[+.] -> 14
-    6:[\055] -> 14
-    7:[/] -> 14
-    8:[0-9] -> 14
-    9:[;] -> 7
-    10:[=] -> 14
-    11:[A-Z_a-z] -> 14
-  Use state 8 as basis (5 fixups)
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    COPY_TO_VALUE
-    GOT_NAMEVALUE
-    COPY_TO_VALUE
-    GOT_NAMEVALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 15
-  Forward route : (from state 8)
-   (START)->6:[\055]->10:[=]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 20
-    2:[!#-),:<>-@[]^`{-~] -> 20
-    4:[*] -> 20
-    5:[+.] -> 20
-    6:[\055] -> 20
-    7:[/] -> 20
-    8:[0-9] -> 20
-    9:[;] -> 20
-    10:[=] -> 20
-    11:[A-Z_a-z] -> 20
-    12:[\\] -> 21
-
-DFA state 16
-  Forward route : (from state 10)
-   (START)->6:[\055]->4:[*]->8:[0-9]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 16
-    1:[\r] -> 16
-    10:[=] -> 17
-
-DFA state 17
-  Forward route : (from state 10)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->(HERE)
-  Transitions :
-    0:[\t ] -> 17
-    1:[\r] -> 17
-    2:[!#-),:<>-@[]^`{-~] -> 22
-    3:["] -> 23
-    4:[*] -> 22
-    5:[+.] -> 22
-    6:[\055] -> 22
-    7:[/] -> 22
-    8:[0-9] -> 22
-    10:[=] -> 22
-    11:[A-Z_a-z] -> 22
-
-DFA state 18
-  Forward route : (from state 11)
-   (START)->6:[\055]->7:[/]->5:[+.]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 18
-    1:[\r] -> 18
-    9:[;] -> 7
-  Use state 13 as basis (0 fixups)
-
-DFA state 19
-  Forward route : (from state 14)
-   (START)->6:[\055]->10:[=]->2:[!#-),:<>-@[]^`{-~]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 19
-    1:[\r] -> 19
-    9:[;] -> 7
-  NFA exit tags applying :
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-    GOT_NAMEVALUE
-  Attributes for <action> : GOT_NAMEVALUE
-
-DFA state 20
-  Forward route : (from state 15)
-   (START)->6:[\055]->10:[=]->3:["]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 20
-    2:[!#-),:<>-@[]^`{-~] -> 20
-    3:["] -> 19
-    4:[*] -> 20
-    5:[+.] -> 20
-    6:[\055] -> 20
-    7:[/] -> 20
-    8:[0-9] -> 20
-    9:[;] -> 20
-    10:[=] -> 20
-    11:[A-Z_a-z] -> 20
-    12:[\\] -> 21
-  Use state 15 as basis (1 fixups)
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-DFA state 21
-  Forward route : (from state 15)
-   (START)->6:[\055]->10:[=]->3:["]->12:[\\]->(HERE)
-  Transitions :
-    3:["] -> 20
-    12:[\\] -> 20
-
-DFA state 22
-  Forward route : (from state 17)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->2:[!#-),:<>-@[]^`{-~]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 24
-    1:[\r] -> 24
-    2:[!#-),:<>-@[]^`{-~] -> 22
-    4:[*] -> 22
-    5:[+.] -> 22
-    6:[\055] -> 22
-    7:[/] -> 22
-    8:[0-9] -> 22
-    9:[;] -> 7
-    10:[=] -> 22
-    11:[A-Z_a-z] -> 22
-  Use state 17 as basis (5 fixups)
-  NFA exit tags applying :
-    GOT_NAMEVALUE_CONT
-    COPY_TO_VALUE
-    GOT_NAMEVALUE_CONT
-    COPY_TO_VALUE
-    GOT_NAMEVALUE_CONT
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-  Attributes for <action> : GOT_NAMEVALUE_CONT
-
-DFA state 23
-  Forward route : (from state 17)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->(HERE)
-  Transitions :
-    0:[\t ] -> 25
-    2:[!#-),:<>-@[]^`{-~] -> 25
-    4:[*] -> 25
-    5:[+.] -> 25
-    6:[\055] -> 25
-    7:[/] -> 25
-    8:[0-9] -> 25
-    9:[;] -> 25
-    10:[=] -> 25
-    11:[A-Z_a-z] -> 25
-    12:[\\] -> 26
-
-DFA state 24
-  Forward route : (from state 22)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->2:[!#-),:<>-@[]^`{-~]->0:[\t ]->(HERE)
-  Transitions :
-    EOS -> 2
-    0:[\t ] -> 24
-    1:[\r] -> 24
-    9:[;] -> 7
-  NFA exit tags applying :
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-    GOT_NAMEVALUE_CONT
-  Attributes for <action> : GOT_NAMEVALUE_CONT
-
-DFA state 25
-  Forward route : (from state 23)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->0:[\t ]->(HERE)
-  Transitions :
-    0:[\t ] -> 25
-    2:[!#-),:<>-@[]^`{-~] -> 25
-    3:["] -> 24
-    4:[*] -> 25
-    5:[+.] -> 25
-    6:[\055] -> 25
-    7:[/] -> 25
-    8:[0-9] -> 25
-    9:[;] -> 25
-    10:[=] -> 25
-    11:[A-Z_a-z] -> 25
-    12:[\\] -> 26
-  Use state 23 as basis (1 fixups)
-  NFA exit tags applying :
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-    COPY_TO_VALUE
-  Attributes for <copier> : COPY_TO_VALUE
-
-DFA state 26
-  Forward route : (from state 23)
-   (START)->6:[\055]->4:[*]->8:[0-9]->10:[=]->3:["]->12:[\\]->(HERE)
-  Transitions :
-    3:["] -> 25
-    12:[\\] -> 25
-
-
-Entry states in DFA:
-Entry <in> : 0
diff --git a/src/mairix/nvptypes.h b/src/mairix/nvptypes.h
@@ -1,43 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2006,2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 NVPTYPES_H
-#define NVPTYPES_H
-
-enum nvp_action {
-  GOT_NAMEVALUE,
-  GOT_NAMEVALUE_CONT,
-  GOT_NAME,
-  GOT_NAME_TRAILING_SPACE,
-  GOT_MAJORMINOR,
-  GOT_TERMINATOR,
-  GOT_NOTHING
-};
-
-enum nvp_copier {
-  COPY_TO_NAME,
-  COPY_TO_MINOR,
-  COPY_TO_VALUE,
-  COPY_NOWHERE
-};
-
-#endif
diff --git a/src/mairix/old_docs/mairix.texi b/src/mairix/old_docs/mairix.texi
@@ -1,885 +0,0 @@
-\input texinfo
-@c {{{ Main header stuff
-@afourwide
-@paragraphindent 0
-@setfilename mairix.info
-@settitle User guide for the mairix program
-@c @setchapternewpage off
-
-@ifinfo
-@dircategory Utilities
-@direntry
-* mairix: (mairix).			Indexing/searching utility for maildir folders
-@end direntry
-@end ifinfo
-
-@titlepage
-@sp 10
-@title The mairix program
-@subtitle This manual describes how to use
-@subtitle the mairix program for indexing and
-@subtitle searching email messages stored in maildir folders.
-@author Richard P. Curnow
-@page
-@vskip 0pt plus 1filll
-Copyright @copyright{} 2002,2003,2004,2005 Richard P. Curnow
-@end titlepage
-
-@contents
-@c }}}
-
-@ifnottex
-@node Top
-@top
-@menu
-* Introduction::    
-* Installation::    Compiling and installing the software
-* Use::             Quickstart guide and examples of use
-@end menu
-@end ifnottex
-
-@node Introduction
-@chapter Introduction
-@menu
-* Background::      How mairix came to be written.
-@end menu
-
-@node Background
-@section Background
-The @emph{mairix} program arose from a need to index and search 100's or 1000's
-of email messages in an efficient way.  It began life supporting just Maildir
-format folder, but now MH and mbox formats are also supported.
-
-I use the @emph{mutt} email client.  @emph{mutt} has a feature called
-@emph{limit}, where the display of messages in the current folder can be
-filtered based on matching regular expressions in particular parts of the
-messages.  I find this really useful.  But there is a snag - it only works on
-the current folder.  If you have messages spread across many folders, you're
-out of luck with limit.  OK - so why not keep all messages in a single folder?
-The problem is that the performance drops badly.  This is true regardless of
-folder format - mbox, maildir etc, though probably worse for some formats than
-others depending on the sizes of messages in the folders.
-
-So on the one hand, we want small folders to keep the performance high.  But on
-the other hand, we want useful searching.
-
-I use the maildir format for my incoming folders.  This scheme has one file per
-message.  On my inboxes@footnote{of which I have many, because I (naturally)
-use @emph{procmail} to split my incoming mail}, I like this for 2 reasons :
-
-@itemize @bullet
-@item Fast deletion of messages I don't want to keep (spam, circulars, mailing
-list threads I'm not interested in etc).  (Compare mbox, where the whole file
-would need to be rewritten.)
-@item No locking issues whatever.  Maybe I'm over cautious, but I don't really
-trust all that locking stuff to protect a single mbox file in all cases, and a
-single file seems just too vulnerable to corruption.)  Also, I sometimes read
-the mail over NFS mounted filesystems, where locking tends to be a real
-disaster area.
-@end itemize
-
-Since I'm using maildir for inboxes, I've traditionally used it for all my
-folders, for uniformity.
-
-So, I hear you ask, if you use a one-file-per-message format, why not just use
-find + egrep to search for messages?  I saw the following problems with this:
-
-@itemize @bullet
-@item What if I want to find all messages to/cc me, from Homer Simpson, dated
-between 1 and 2 months ago, with the word "wubble" in the body?  This would
-involve a pretty nasty set of regexps in a pipeline of separate egreps (and
-bear in mind, headers could be split over line boundaries...)
-@item What if the message body has quoted-printable (or worse, base64) transfer
-encoding?  The egrep for "wubble" could come very unstuck.
-@item How would the matching messages be conveniently arranged into a new
-folder to allow browsing with mutt?
-@item What if I wanted to see all messages in the same threads as those
-matching the above condition?
-@item If I had 1000's of messages, this wasn't going to be quick, especially if
-I wanted to keep tuning the search condition.@footnote{This may be a non-issue
-for people with the lastest technology under their desk, but at the time I
-started writing mairix, I had a 1996 model 486 at home}.
-@end itemize
-
-So find + egrep was a non-starter.  I looked around for other technology.  I
-found @emph{grepmail}, but this only works for mbox format folders, and
-involved scanning each message every time (so lost on the speed issue).
-
-I decided that this was going to be my next project, and mairix was born.  By
-the way, the name originally came from abbreviating @emph{MAildIR IndeX}, but
-this is now an anachronism since MH and mbox are supported too.
-
-@node Installation
-@chapter Installation
-
-There is not much to this.  In the simplest case you can just do
-
-@example
-./configure
-make
-make install
-@end example
-
-You need to be root to run the final step unless you're installing under your
-own home directory somewhere.
-
-However, you might want to tune the options further.  The @file{configure}
-script shares its common options with the usual autoconf-generated scripts,
-even though it's not autoconf-generated itself.  For example, a fuller build could use
-
-@example
-CC=gcc CFLAGS="-O2 -Wall" ./configure \
-    --prefix=/opt/mairix \
-    --infodir=/usr/share/info
-make
-make install
-make docs
-make install_docs
-@end example
-
-The final step is to create a @file{~/.mairixrc} file.  An example is included
-in the file @file{dotmairixrc.eg}.  Just copy that to @file{~/.mairixrc} and edit
-it.
-
-@node Use
-@chapter Use
-
-@menu
-* use_intro::       Overview of use
-* capabilities::    Indexing strategy and search capabilities
-* mairixrc::        The @file{~/.mairixrc} file 
-* mfolder_setup::   Setting up the match folder
-* command_line::    Command line options
-* date_syntax::     Syntax used for date searches
-@end menu
-
-@node use_intro
-@section Overview of use
-
-@emph{mairix} has two modes of use : index building and searching.  The
-searching mode runs whenever the command line contains any expressions to
-search for.  Otherwise, the indexing mode is run.
-
-To begin with, an indexing run must be performed before searching will work at
-all.  Otherwise your search will be operating on an empty database and won't
-produce any output.
-
-The output of the search mode is usually placed in a @emph{match folder}. You
-can select the type of folder that is used.  For Maildir, it is just a normal
-maildir directory (i.e. containing @file{new}, @file{tmp} and @file{cur})
-subdirectories.  If you select MH it is a directory containing entries with
-numerical filenames, so you can open it as a normal MH folder in your mail
-program.  If you select mbox, it is a single file in mbox format.
-
-You configure the path for the match folder in your @file{~/.mairixrc} file.
-When writing to a mfolder in maildir or MH format, mairix will populate it with
-symbolic links pointing to the paths of the real messages that were matched by
-the search expression.@footnote{Although symlinks use up more inodes than hard
-links, I decided they were more useful because it makes it possible to see the
-filenames of the original messages via @command{ls -l}.}  If a message in a
-mbox folder matches, mairix will copy the message contents to a single file in
-the mfolder directory.
-
-If the mfolder is in mbox format, mairix will copy the message contents of each
-matching message into the mfolder file.  (There is no way of exploiting
-symlinks to avoid the copying in this case.)
-
-If desired, mairix can produce just a list of files that match the search
-expression and omit the building of the match folder (the so-called 'raw'
-output mode).  This mode of operation may be useful in communicating the
-results of the search to other programs.
-
-@node capabilities
-@section Indexing strategy and search capabilities
-
-@emph{mairix} works exclusively in terms of @emph{words}.  The index that's
-built in non-search mode contains a table of which words occur in which
-messages.  Hence, the search capability is based on finding messages that
-contain particular words.  @emph{mairix} defines a word as any string of
-alphanumeric characters + underscore.  Any whitespace, punctuation, hyphens etc
-are treated as word boundaries.
-
-@emph{mairix} has special handling for the @t{To:}, @t{Cc:} and @t{From:}
-headers.  Besides the normal word scan, these headers are scanned a second
-time, where the characters @samp{@@}, @samp{-} and @samp{.} are also treated as
-word characters.  This allows most (if not all) email addresses to appear in
-the database as single words.  So if you have a mail from
-@t{wibble@@foobar.zzz}, it will match on both these searches
-
-@example
-mairix f:foobar
-mairix f:wibble@@foobar.zzz
-@end example
-
-It should be clear by now that the searching cannot be used to find messages
-matching general regular expressions.  Personally, I don't find that much use
-anyway for locating old messages - I'm far more likely to remember particular
-keywords that were in the messages, or details of the recipients, or the
-approximate date.
-
-It's also worth pointing out that there is no 'locality' information stored, so
-you can't search for messages that have one words 'close' to some other word.
-For every message and every word, there is a simple yes/no condition stored -
-whether the message contains the word in a particular header or in the body.
-So far this has proved to be adequate.  mairix has a similar feel to using an
-Internet search engine.
-
-There are three further searching criteria that are supported (besides word
-searching):
-
-@itemize @bullet
-@item Searching for messages whose @t{Date:} header is in a particular range
-@item Searching for messages whose size is in a particular range.  (I see this
-being used mainly for finding 'huge' messages, as you're most likely to want to
-cull these to recover disc space.)
-@item Searching for messages with a particular substring in their paths.  You
-can use this feature to limit the search to particular folders in your mail
-hierarchy, for example.
-@end itemize
-
-@node mairixrc
-@section The @file{~/.mairixrc} file
-
-@subsection Overview
-
-This file contains information about where you keep your mail folders, where
-you want the index file to be stored and where you want the match folder to
-be, into which the search mode places the symlinks.
-
-mairix searches for this file at @file{~/.mairixrc} unless you specify the
-@samp{-f} command line option.
-
-If a # character appears in the file, the rest of that line is ignored.  This
-allows you to specify comments.
-
-There are 3 entries (@samp{base}, @samp{mfolder} and @samp{database}) that must
-appear in the file.  Also at least one of @samp{maildir}, @samp{mh} and
-@samp{mbox} must appear.  Optionally, the @samp{mformat} entry may
-appear.  An example illustrates:
-
-@example
-base=/home/richard/mail
-maildir=new-mail:new-chrony
-maildir=recent...:ancient...
-mh=an_mh_folder
-mbox=archive1:archive2
-mfolder=mfolder
-mformat=maildir
-database=/home/richard/.mairix_database
-@end example
-
-@subsection mairixrc file keys
-The keys are as follows:
-
-@table @asis
-@item base
-This is the path to the common parent directory of all your maildir folders.
-@item maildir
-This is a colon-separated list of the Maildir folders (relative to @samp{base})
-that you want indexed.  Any entry that ends @samp{...} is recursively scanned
-to find any Maildir folders underneath it.
-
-More than one line starting with @samp{maildir} can be included.  In this case,
-mairix joins the lines together with colons as though a single list of folders had
-been given on a single very long line.
-
-Each colon-separated entry may be a wildcard.  See the discussion under mbox (below) for the
-wildcard syntax.  For example
-
-@example
-maildir=zzz/foo*...
-@end example
-
-will match maildir folders like these (relative to the folder_base)
-
-@example
-zzz/foobar/xyz
-zzz/fooquux
-zzz/foo
-zzz/fooabc/u/v/w
-@end example
-
-and 
-
-@example
-maildir=zzz/foo[abc]*
-@end example
-
-will match maildir folders like these (relative to the folder_base)
-
-@example
-zzz/fooa
-zzz/fooaaaxyz
-zzz/foobcd
-zzz/fooccccccc
-@end example
-
-If a folder name contains a colon, you can write this by using the sequence
-@samp{\:} to escape the colon.  Otherwise, the backslash character is treated
-normally.  (If the folder name actually contains the sequence @samp{\:}, you're
-out of luck.)
-
-@item mh
-This is a colon-separated list of the MH folders (relative to @samp{base}) that
-you want indexed.  Any entry that ends @samp{...} is recursively scanned to
-find any MH folders underneath it.
-
-More than one line starting with @samp{mh} can be included.  In this case,
-mairix joins the lines together with colons as though a single list of folders had
-been given on a single very long line.
-
-Each colon-separated entry may be a wildcard, see the discussion under maildir
-(above) and mbox (below) for the syntax and semantics of specifying wildcards.
-
-@item mbox
-This is a colon-separated list of the mbox folders (relative to @samp{base}) that
-you want indexed.
-
-Each colon-separated item in the list can be suffixed by @samp{...}.  If the
-item matches a regular file, that file is treated as a mbox folder and the
-@samp{...} suffix is ignored.  If the item matches a directory, a recursive
-scan of everything inside that directory is made, and all regular files are
-initially considered as mbox folders.  (Any directories found in this scan are
-themselves scanned, since the scan is recursive.)
-
-Each colon-separated item may contain wildcard operators, but only in its final
-path component.  The wildcard operators currently supported are
-
-@table @asis
-@item *
-Match zero or more characters (each character matched is arbitrary)
-@item ?
-Match exactly one arbitrary character
-@item [abcs-z]
-Character class : match a single character from the set a, b, c, s, t, u, v, w,
-x, y and z.
-
-To include a literal @samp{]} in the class, place it immediately after the opening @samp{[}.
-To include a literal @samp{-} in the class, place it immediately before the closing @samp{]}.
-
-@end table
-
-If these metacharacters are included in non-final path components, they have no
-special meaning.
-
-Here are some examples
-
-@table @asis
-@item mbox=foo/bar*
-matches @file{foo/bar}, @file{foo/bar1}, @file{foo/barrrr} etc
-@item mbox=foo*/bar*
-matches @file{foo*/bar}, @file{foo*/bar1}, @file{foo*/barrrr} etc
-@item mbox=foo/*
-matches @file{foo/bar}, @file{foo/bar1}, @file{foo/barrrr}, @file{foo/foo}, @file{foo/x} etc
-@item mbox=foo...
-matches any regular file in the tree rooted at @file{foo}
-@item mbox=foo/*...
-same as before
-@item mbox=foo/[a-z]*...
-matches @file{foo/a}, @file{foo/aardvark/xxx}, @file{foo/zzz/foobar},
-@file{foo/w/x/y/zzz}, but @b{not} @file{foo/A/foobar}
-@end table
-
-Regular files that are mbox folder candidates are examined internally.  Only
-files containing standard mbox @samp{From } separator lines will be scanned for
-messages.
-
-If a regular file has a name ending in @file{.gz}, and gzip support is compiled
-into the mairix binary, the file will be treated as a gzipped mbox.  
-
-If a regular file has a name ending in @file{.bz2}, and bzip support is compiled
-into the mairix binary, the file will be treated as a bzip2'd mbox.  
-
-More than one line starting with @samp{mbox} can be included.  In this case,
-mairix joins the lines together with colons as though a single list of folders had
-been given on a single very long line.
-
-mairix performs @b{no} locking of mbox folders when it is accessing them.  If a
-mail delivery program is modifying the mbox at the same time, it is likely that
-one or messages in the mbox will never get indexed by mairix (until the
-database is removed and recreated from scratch, anyway.)  The assumption is
-that mairix will be used to index archive folders rather than incoming ones, so
-this is unlikely to be much of a problem in reality.
-
-@emph{mairix} can support a maximum of 65536 separate mboxes, and a maximum of
-65536 messages within any one mbox.
-
-@item omit 
-This is a colon-separated list of glob patterns for folders to be
-omitted from the indexing.  This allows wide wildcards to be used in the
-@emph{maildir}, @emph{mh} and @emph{mbox} arguments, with the @emph{omit}
-option used to selectively remove unwanted folders from the folder lists.
-Within the glob patterns, a single @samp{*} matches any sequence of characters
-other than @samp{/}.  However @samp{**} matches any sequence of characters
-including @samp{/}.  This allows glob patterns to be constructed which have a
-wildcard for just one directory component, or for any number of directory
-components.
-
-The @emph{omit} option can be specified as many times as required so that the
-list of patterns doesn't all have to fit on one line.
-
-As an example,
-
-@example
-mbox=bulk...
-omit=bulk/spam*
-@end example
-
-will index all mbox folders at any level under the @file{bulk} subdirectory of
-the base folder, except for those folders whose names start @file{bulk/spam},
-e.g. @file{bulk/spam}, @file{bulk/spam2005} etc.  In constrast, 
-
-@example
-mbox=bulk...
-omit=bulk/spam**
-@end example
-
-will index all mbox folders at any level under the @file{bulk} subdirectory of
-the base folder, except for those folders whose names start @file{bulk/spam},
-e.g. @file{bulk/spam}, @file{bulk/spam2005}, @file{bulk/spam/2005},
-@file{bulk/spam/2005/jan} etc.
-
-@item nochecks
-This takes no arguments.  If a line starting with @samp{nochecks} is present,
-it is the equivalent of specifying the @samp{-Q} flag to every indexing run.
-
-@item mfolder
-This defines the name of the @emph{match} folder (within the directory
-specified by @samp{base}) into which the search mode writes its output.
-(If the mformat used is @samp{raw}, then this setting is not
-used and may be excluded.)
-
-If the first character of the @b{mfolder} value is @samp{/} or @samp{.}, it is
-taken as a pathname in its own right.  This allows you to specify absolute
-paths and paths relative to the current directory where the mfolder should be
-written.  Otherwise, the value of @b{mfolder} is appended to the value of
-@b{base}, in the same way as for the source folders.
-
-@item mformat
-This defines the type of folder used for the @emph{match folder} where the
-search results go.  There are four valid settings for this @samp{mh},
-@samp{maildir}, @samp{mbox} or @samp{raw}.  If the @samp{raw} setting is used then
-mairix will just print out the path names of the files that match and
-no match folder will be created.  @samp{maildir} is the default if this
-option is not defined.  The setting is case-insensitive.
-
-@item database
-This defines the path where mairix's index database is kept.  You can keep this
-file anywhere you like.
-@end table
-
-It is illegal to have a folder listed twice.  Once mairix has built a list of
-all the messages currently in your folders, it will search for duplicates
-before proceeding.  If any duplicates are found (arising from the same folder
-being specified twice), it will give an error message and exit.  This is to
-prevent corrupting the index database file.
-
-@subsection mairixrc expansions
-
-The part of each line in @file{.mairixrc} following the equals sign can contain
-the following types of expansion:
-
-@table @asis
-@item Home directory expansion
-If the sequence @samp{~/} appears at the start of the text after the equals
-sign, it is expanded to the user's home directory.  Example:
-
-@example
-database=~/Mail/mairix_database
-@end example
-
-@item Environment expansion
-If a @samp{$} is followed by a sequence of alpha-numeric characters (or
-@samp{_}), the whole string is replaced by looking up the corresponding
-environment variable.  Similarly, if @samp{$} is followed by an open brace
-(@samp{@{}), everything up to the next close brace is looked up as an
-environment variable and the result replaces the entire sequence.
-
-Suppose in the shell we do
-@example
-export FOO=bar
-@end example
-
-and the @file{.mairixrc} file contains
-@example
-maildir=xxx/$FOO
-mbox=yyy/a$@{FOO@}b
-@end example
-
-this is equivalent to
-@example
-maildir=xxx/bar
-mbox=yyy/abarb
-@end example
-
-If the specified environment variable is not set, the replacement is the empty
-string.
-
-@end table
-
-@node mfolder_setup
-@section Setting up the match folder
-If the match folder does not exist when running in search mode, it is
-automatically created.  For @samp{mformat=maildir} (the default), this
-should be all you need to do.  If you use @samp{mformat=mh}, you may
-have to run some commands before your mailer will recognize the folder.  e.g.
-for mutt, you could do
-
-@example
-mkdir -p /home/richard/Mail/mfolder
-touch /home/richard/Mail/mfolder/.mh_sequences
-@end example
-
-which seems to work.  Alternatively, within mutt, you could set @var{mbox_type}
-to @samp{mh} and save a message to @samp{+mfolder} to have mutt set up the
-structure for you in advance.
-
-If you use Sylpheed, the best way seems to be to create the new folder from
-within Sylpheed before letting mairix write into it.  This seems to be all you
-need to do.
-
-@node command_line
-@section Command line options
-
-The command line syntax is
-
-For indexing mode:
-@example
-mairix [-f path] [-p] [-v] [-Q]
-@end example
-For search mode
-@example
-mairix [-f path] [-t] [-v] [-a] [-r] [-o mfolder] expr1 [expr2] ... [exprn]
-@end example
-For database dump mode
-@example
-mairix [-f path] -d
-@end example
-
-The @samp{-f} or @samp{--rcfile} flag allows a different path to the
-@file{mairixrc} file to be given, replacing the default of @file{~/.mairixrc}.
-
-The @samp{-p} or @samp{--purge} flag is used in indexing mode.  Indexing works
-incrementally.  When new messages are found, they are scanned and information
-about the words they contain is appended onto the existing information.  When
-messages are deleted, holes are normally left in the message sequence.  These
-holes take up space in the database file.  This flag will compress the deleted
-paths out of the database to save space.  Additionally, where @samp{mbox}
-folders are in use, information in the database about folders that no longer
-exist, or which are no longer referenced in the rc-file, will be purged also.
-
-The @samp{-v} or @samp{--verbose} flag is used in indexing mode.  It causes
-more information to be shown during the indexing process.  In search mode, it
-causes debug information to be shown if there are problems creating the
-symlinks.  (Normally this would be an annoyance.  If a message matches multiple
-queries when using @samp{-a}, mairix will try to create the same symlink
-multiple times.  This prevents the same message being shown multiple times in
-the match folder.)
-
-The @samp{-Q} or @samp{--no-integrity-checks} flag is used in indexing mode.
-Normally, mairix will do various integrity checks on the database after loading
-it in, and before writing the modified database out again.  The checking helps
-to detect mairix bugs much earlier, but it has a performance penalty.  This
-flag skips the checks, at the cost of some loss in robustness.  See also the
-@samp{nochecks} directive in @ref{mairixrc}.
-
-The @samp{--unlock} flag is used in any mode.  mairix dot-locks the database
-file to prevent corruption due to concurrent accesses.  If the process holding
-the lock exits prematurely for any reason, the lockfile will be left behind.
-By using the @samp{--unlock} option, an unwanted lockfile can be conveniently
-removed.
-
-The @samp{-t} or @samp{--threads} option applies to search mode.  Normally,
-only the messages matching all the specified expressions are included in the
-@emph{match folder} that is built.  With the @samp{-t} flag, any message in
-the same thread as one of the matched messages will be included too.  Note, the
-threading is based on processing the @t{Message-ID}, @t{In-Reply-To} and
-@t{References} headers in the messages.  Some mailers don't generate these
-headers in a co-operative way and will cause problems with this threading
-support.  (Outlook seems to be one culprit.)  If you are plagued by this
-problem, the 'edit threads' patch to mutt may be useful to you.
-
-The @samp{-d} or @samp{--dump} option causes mairix to dump the database
-contents in human-readable form to stdout.  It is mainly for use in debugging.
-If this option is specified, neither indexing nor searching are performed.
-
-The @samp{-a} or @samp{--augment} option also applies to search mode.
-Normally, the first action of the search mode is to clear any existing message
-links from the match folder.  With the @samp{-a} flag, this step is
-suppressed.  It allows the folder contents to be built up by matching with 2 or
-more diverse sets of match expressions.  If this mode is used, and a message
-matches multiple queries, only a single symlink will be created for it.
-
-The @samp{-r} or @samp{--raw-output} option is used to force the raw output
-mode for a particular search, in preference to the output format defined by the
-@samp{mformat} line in the @file{mairixrc} file.  This may be useful for
-identifying which mbox contains a particular match, since there is way to see
-this when the matching messages are placed in the mfolder in this case.  (Note
-for matches in maildir and MH folders when @samp{mformat} is maildir or MH, the
-symbolic links in the mfolder will show the path to the matching message.)
-
-The @samp{-o} or @samp{--mfolder} option is used in search mode to specify a
-match folder different to the one specified in the @file{mairixrc} to be
-used.  The path given by the @samp{mfolder} argument after this flag is
-relative to the folder base directory given in the @file{mairixrc} file, in the
-same way as the directory in the mfolder specification in that file is.  So if
-your @file{mairixrc} file contains
-
-@example
-base=/home/foobar/Mail
-@end example
-
-and you run mairix like this
-
-@example
-mairix -o mfolder2 make,money,fast
-@end example
-
-mairix will find all of your saved junk emails containing these three words and
-put the results into @file{/home/foobar/Mail/mfolder2}.
-
-The @samp{-o} argument obeys the same conventions regarding initial @samp{/}
-and @samp{.} characters as the @b{mfolder} line in the @file{.mairixrc} file
-does.
-
-@emph{Mairix} will refuse to output search results (whether specified
-by the @samp{-o} or in the @file{.mairixrc} file) into one of the
-folders that are indexed; it figures out that list by looking in the
-@file{.mairixrc} file, or in the file you specify using the @samp{-f}
-option.  This sanity check prevents you inadvertantly destroying one
-of your important folders (but won't catch all such cases, sadly).
-
-The search mode runs when there is at least one search expression.  Search
-expressions can take forms such as (in increasing order of complexity):
-
-@itemize @bullet
-@item A date expression.  The format for specifying the date is described in section @ref{date_syntax}.
-
-@item A size expression.  This matches all messages whose size in bytes is in a
-particular range.  For example, to match all messages bigger than 1 Megabyte
-the following command can be used
-
-@example
-mairix z:1m-
-@end example
-
-To match all messages between 10kbytes and 20kbytes in size, the following
-command can be used:
-
-@example
-mairix z:10k-20k
-@end example
-
-@item A word, e.g. @samp{pointer}.  This matches any message with the word
-@samp{pointer} in the @t{To}, @t{Cc}, @t{From} or @t{Subject} headers, or in
-the message body.@footnote{Message body is taken to mean any body part of type
-text/plain or text/html.  For text/html, text within meta tags is ignored.  In
-particular, the URLs inside <A HREF="..."> tags are not currently indexed.
-Non-text attachments are ignored.  If there's an attachment of type
-message/rfc822, this is parsed and the match is performed on this sub-message
-too.  If a hit occurs, the enclosing message is treated as having a hit.}
-
-@item A word in a particular part of the message, e.g. @samp{s:pointer}.  This
-matches any message with the word @samp{pointer} in the subject.  The
-qualifiers for this are :
-
-@table @asis
-@item @t{t:pointer}
-to match @samp{pointer} in the @t{To:} header, 
-@item @t{c:pointer}
-to match @samp{pointer} in the @t{Cc:} header, 
-@item @t{a:pointer}
-to match @samp{pointer} in the @t{To:}, @t{Cc:} or @t{From:} headers (@samp{a} meaning @samp{address}), 
-@item @t{f:pointer}
-to match @samp{pointer} in the @t{From:} header, 
-@item @t{s:pointer}
-to match @samp{pointer} in the @t{Subject:} header, 
-@item @t{b:pointer}
-to match @samp{pointer} in the message body.
-@item @t{m:pointer}
-to match messages having a Message-ID header of @samp{pointer}. 
-@end table
-
-Multiple fields may be specified, e.g. @t{sb:pointer} to match in the
-@t{Subject:} header or the body.
-
-@item A negated word, e.g. @samp{s:~pointer}.  This matches all messages that
-don't have the word @samp{pointer} in the subject line.
-
-@item A substring match, e.g. @samp{s:point=}.  This matches all messages
-containing a word in their subject line where the word has @samp{point} as a
-substring, e.g. @samp{pointer}, @samp{disappoint}.
-
-@item An approximate match, e.g. @samp{s:point=1}.  This matches all messages
-containing a word in their subject line where the word has @samp{point} as a
-substring with at most one error, e.g. @samp{jointed} contains @samp{joint}
-which can be got from @samp{point} with one letter changed.  An error can be a
-single letter changed, inserted or deleted.
-
-@item A left-anchored substring match, e.g. @samp{s:^point=}.  This matches all
-messages containing a word in their subject line where the word begins with the
-string @samp{point}.  (This feature is intended to be useful for inflected
-languages where the substring search is used to avoid the grammatical ending on
-the word.)  This left-anchored facility can be combined with the approximate
-match facility, e.g. @samp{s:^point=1}.  
-
-Note, if the @samp{^} prefix is used without the @samp{=} suffix, it is ignored.
-For example, @samp{s:^point} means the same thing as @samp{s:point}.
-
-@item A disjunction, e.g. @samp{s:pointer/dereference}.  This matches all
-messages with one or both of the words @samp{pointer} and @samp{dereference} in
-their subject lines.
-
-@item Each disjunction may be a conjunction, e.g.
-@samp{s:null,pointer/dereference=2} matches all messages whose subject lines
-either contain both the words @samp{null} and @samp{pointer}, or contain the
-word @samp{dereference} with up to 2 errors (or both).
-
-@item A path expression.  This matches all messages with a particular substring
-in their path.  The syntax is very similar to that for words within the message
-(above), and all the rules for @samp{+}, @samp{,}, approximate matching etc are
-the same.  The word prefix used for a path expression is @samp{p:}.  Examples:
-
-@example
-mairix p:/archive/
-@end example
-
-matches all messages with @samp{/archive/} in their path, and
-
-@example
-mairix p:wibble=1 s:wibble=1
-@end example
-
-matches all messages with @samp{wibble} in their path and in their subject
-line, allowing up to 1 error in each case (the errors may be different for a
-particular message.)
-
-Path expressions always use substring matches and never exact matches (it's
-very unlikely you want to type in the whole of a message path as a search
-expression!)  The matches are always @b{case-sensitive}.  (All matches on words
-within messages are case-insensitive.)  There is a limit of 32 characters on
-the match expression.
-
-@end itemize
-
-The binding order of the constructions is:
-
-@enumerate
-@item Individual command line arguments define separate conditions which are
-AND-ed together
-
-@item Within a single argument, the letters before the colon define which
-message parts the expression applies to.  If there is no colon, the expression
-applies to all the headers listed earlier and the  body.
-
-@item After the colon, commas delineate separate disjuncts, which are OR-ed together.
-
-@item Each disjunct may contain separate conjuncts, which are separated by plus
-signs.  These conditions are AND-ed together.
-
-@item Each conjunct may start with a tilde to negate it, and may be followed by
-a slash to indicate a substring match, optionally followed by an integer to
-define the maximum number of errors allowed.
-
-@end enumerate
-
-Now some examples.  Suppose my email address is @email{richard@@doesnt.exist}.
-
-The following will match all messages newer than 3 months from me with the word
-@samp{chrony} in the subject line:
-
-@example
-mairix d:3m- f:richard+doesnt+exist s:chrony
-@end example
-
-Suppose I don't mind a few spurious matches on the address, I want a wider date
-range, and I suspect that some messages I replied to might have had the subject
-keyword spelt wrongly (let's allow up to 2 errors):
-
-@example
-mairix d:6m- f:richard s:chrony=2
-@end example
-
-@node date_syntax
-@section Syntax used for specifying dates
-This section describes the syntax used for specifying dates when searching
-using the @samp{d:} option.
-
-Dates are specified as a range.  The start and end of the range can both be
-specified.  Alternatively, if the start is omitted, it is treated as being the
-beginning of time.  If the end is omitted, it is treated as the current time.
-
-There are 4 basic formats:
-@table @samp
-@item d:start-end
-Specify both start and end explicitly
-@item d:start-
-Specify start, end is the current time
-@item d:-end
-Specify end, start is 'a long time ago' (i.e. early enough to include any message).
-@item d:period
-Specify start and end implicitly, as the start and end of the period given.
-@end table
-
-The start and end can be specified either absolute or relative.  A relative
-endpoint is given as a number followed by a single letter defining the scaling:
-
-@multitable @columnfractions 0.15 0.2 0.2 0.45
-@item @b{letter} @tab @b{meaning} @tab @b{example} @tab @b{meaning}
-@item d @tab days  @tab 3d @tab 3 days
-@item w @tab weeks @tab 2w @tab 2 weeks (14 days)
-@item m @tab months @tab 5m @tab 5 months (150 days)
-@item y @tab years @tab 4y @tab 4 years (4*365 days)
-@end multitable
-
-Months are always treated as 30 days, and years as 365 days, for this purpose.
-
-Absolute times can be specified in a lot of forms.  Some forms have different
-meanings when they define a start date from that when they define an end date.
-Where a single expression specifies both the start and end (i.e. where the
-argument to d: doesn't contain a @samp{-}), it will usually have different
-interpretations in the two cases.
-
-In the examples below, suppose the current date is Sunday May 18th, 2003 (when
-I started to write this material.)
-
-@multitable @columnfractions 0.24 0.24 0.24 0.28
-@item @b{Example} @tab @b{Start date} @tab @b{End date} @tab @b{Notes}
-@item d:20030301@minus{}20030425 @tab March 1st, 2003 @tab 25th April, 2003
-@item d:030301@minus{}030425 @tab March 1st, 2003 @tab April 25th, 2003 @tab century assumed
-@item d:mar1@minus{}apr25    @tab March 1st, 2003 @tab April 25th, 2003
-@item d:Mar1@minus{}Apr25    @tab March 1st, 2003 @tab April 25th, 2003 @tab case insensitive
-@item d:MAR1@minus{}APR25    @tab March 1st, 2003 @tab April 25th, 2003 @tab case insensitive
-@item d:1mar@minus{}25apr    @tab March 1st, 2003 @tab April 25th, 2003 @tab date and month in either order
-@item d:2002          @tab January 1st, 2002 @tab December 31st, 2002 @tab whole year
-@item d:mar           @tab March 1st, 2003 @tab March 31st, 2003 @tab most recent March
-@item d:oct           @tab October 1st, 2002 @tab October 31st, 2002 @tab most recent October
-@item d:21oct@minus{}mar     @tab October 21st, 2002 @tab March 31st, 2003 @tab start before end
-@item d:21apr@minus{}mar     @tab April 21st, 2002 @tab March 31st, 2003 @tab start before end
-@item d:21apr@minus{}        @tab April 21st, 2003 @tab May 18th, 2003 @tab end omitted
-@item d:@minus{}21apr        @tab January 1st, 1900 @tab April 21st, 2003 @tab start omitted
-@item d:6w@minus{}2w         @tab April 6th, 2003 @tab May 4th, 2003 @tab both dates relative
-@item d:21apr@minus{}1w      @tab April 21st, 2003 @tab May 11th, 2003 @tab one date relative
-@item d:21apr@minus{}2y      @tab April 21st, 2001 @tab May 11th, 2001 @tab start before end
-@item d:99@minus{}11         @tab January 1st, 1999 @tab May 11th, 2003 @tab 2 digits are a day of the month if possible, otherwise a year
-@item d:99oct@minus{}1oct    @tab October 1st, 1999 @tab October 1st, 2002 @tab end before now, single digit is a day of the month
-@item d:99oct@minus{}01oct   @tab October 1st, 1999 @tab October 31st, 2001 @tab 2 digits starting with zero treated as a year
-@item d:oct99@minus{}oct1    @tab October 1st, 1999 @tab October 1st, 2002 @tab day and month in either order
-@item d:oct99@minus{}oct01   @tab October 1st, 1999 @tab October 31st, 2001 @tab year and month in either order
-@end multitable
-
-The principles in the table work as follows.
-@itemize @bullet
-@item 
-When the expression defines a period of more than a day (i.e. if a month or
-year is specified), the earliest day in the period is taken when the start date
-is defined, and the last day in the period if the end of the range is being
-defined.
-@item
-The end date is always taken to be on or before the current date.
-@item 
-The start date is always taken to be on or before the end date.
-@end itemize
-
-@bye
-@c vim:cms=@c\ %s:fdm=marker:fdc=5:syntax=off
diff --git a/src/mairix/reader.c b/src/mairix/reader.c
@@ -1,212 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Database reader */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <sys/mman.h>
-
-#include "reader.h"
-#include "memmac.h"
-#include "mairix.h"
-
-int read_increment(unsigned char **encpos) {/*{{{*/
-  unsigned char *j = *encpos;
-  int result;
-  unsigned char x0, x1, x2, x3;
-
-  x0 = *j++;
-  if ((x0 & 0xc0) == 0xc0) {
-    /* 4 byte encoding */
-    x1 = *j++;
-    x2 = *j++;
-    x3 = *j++;
-    result = ((x0 & 0x3f) << 24) + (x1 << 16) + (x2 << 8) + x3;
-  } else if (x0 & 0x80) {
-    /* 2 byte encoding */
-    x1 = *j++;
-    result = ((x0 & 0x7f) << 8) + x1;
-  } else {
-    /* Single byte encoding */
-    result = x0;
-  }
-
-  *encpos = j;
-  return result;
-}
-/*}}}*/
-static void read_toktable_db(char *data, struct toktable_db *toktable, int start, unsigned int *uidata)/*{{{*/
-{
-  int n;
-  n = toktable->n = uidata[start];
-  toktable->tok_offsets = uidata + uidata[start+1];
-  toktable->enc_offsets = uidata + uidata[start+2];
-  return;
-}
-/*}}}*/
-static void read_toktable2_db(char *data, struct toktable2_db *toktable, int start, unsigned int *uidata)/*{{{*/
-{
-  int n;
-  n = toktable->n = uidata[start];
-  toktable->tok_offsets = uidata + uidata[start+1];
-  toktable->enc0_offsets = uidata + uidata[start+2];
-  toktable->enc1_offsets = uidata + uidata[start+3];
-  return;
-}
-/*}}}*/
-struct read_db *open_db(char *filename)/*{{{*/
-{
-  int fd, len;
-  char *data;
-  struct stat sb;
-  struct read_db *result;
-  unsigned int *uidata;
-  unsigned char *ucdata;
-
-  fd = open(filename, O_RDONLY);
-  if (fd < 0) {
-    report_error("open", filename);
-    unlock_and_exit (2);
-  }
-
-  if (fstat(fd, &sb) < 0) {
-    report_error("stat", filename);
-    unlock_and_exit(2);
-  }
-
-  len = sb.st_size;
-
-  data = (char *) mmap(0, len, PROT_READ, MAP_SHARED, fd, 0);
-  if (data == MAP_FAILED) {
-    report_error("reader:mmap", filename);
-    unlock_and_exit(2);
-  }
-
-  if (!data) {
-    /* Empty file opened => database corrupt for sure */
-    if (close(fd) < 0) {
-      report_error("close", filename);
-      unlock_and_exit(2);
-    }
-    return NULL;
-  }
-
-  if (close(fd) < 0) {
-    report_error("close", filename);
-    unlock_and_exit(2);
-  }
-
-  result = new(struct read_db);
-  uidata = (unsigned int *) data; /* alignment is assured */
-  ucdata = (unsigned char *) data;
-  result->len = len;
-  result->data = data;
-
-  /*{{{ Magic number check */
-  if (ucdata[0] == HEADER_MAGIC0 ||
-      ucdata[1] == HEADER_MAGIC1 ||
-      ucdata[2] == HEADER_MAGIC2) {
-    if (ucdata[3] != HEADER_MAGIC3) {
-      fprintf(stderr, "Another version of this program produced the existing database!  Please rebuild.\n");
-      unlock_and_exit(2);
-    }
-  } else {
-    fprintf(stderr, "The existing database wasn't produced by this program!  Please rebuild.\n");
-    unlock_and_exit(2);
-  }
-  /*}}}*/
-  /* {{{ Endianness check */
-  if (uidata[UI_ENDIAN] == 0x11223344) {
-    fprintf(stderr, "The endianness of the database is reversed for this machine\n");
-    unlock_and_exit(2);
-  } else if (uidata[UI_ENDIAN] != 0x44332211) {
-    fprintf(stderr, "The endianness of this machine is strange (or database is corrupt)\n");
-    unlock_and_exit(2);
-  }
-  /* }}} */
-
-  /* Now build tables of where things are in the file */
-  result->n_msgs = uidata[UI_N_MSGS];
-  result->msg_type_and_flags = ucdata + uidata[UI_MSG_TYPE_AND_FLAGS];
-  result->path_offsets = uidata + uidata[UI_MSG_CDATA];
-  result->mtime_table = uidata + uidata[UI_MSG_MTIME];
-  result->size_table = uidata + uidata[UI_MSG_SIZE];
-  result->date_table = uidata + uidata[UI_MSG_DATE];
-  result->tid_table  = uidata + uidata[UI_MSG_TID];
-
-  result->n_mboxen            = uidata[UI_MBOX_N];
-  result->mbox_paths_table    = uidata + uidata[UI_MBOX_PATHS];
-  result->mbox_entries_table  = uidata + uidata[UI_MBOX_ENTRIES];
-  result->mbox_mtime_table    = uidata + uidata[UI_MBOX_MTIME];
-  result->mbox_size_table     = uidata + uidata[UI_MBOX_SIZE];
-  result->mbox_checksum_table = uidata + uidata[UI_MBOX_CKSUM];
-
-  result->hash_key = uidata[UI_HASH_KEY];
-
-  read_toktable_db(data, &result->to, UI_TO_BASE, uidata);
-  read_toktable_db(data, &result->cc, UI_CC_BASE, uidata);
-  read_toktable_db(data, &result->from, UI_FROM_BASE, uidata);
-  read_toktable_db(data, &result->subject, UI_SUBJECT_BASE, uidata);
-  read_toktable_db(data, &result->body, UI_BODY_BASE, uidata);
-  read_toktable_db(data, &result->attachment_name, UI_ATTACHMENT_NAME_BASE, uidata);
-  read_toktable2_db(data, &result->msg_ids, UI_MSGID_BASE, uidata);
-
-  return result;
-}
-/*}}}*/
-static void free_toktable_db(struct toktable_db *x)/*{{{*/
-{
-  /* Nothing to do */
-}
-/*}}}*/
-static void free_toktable2_db(struct toktable2_db *x)/*{{{*/
-{
-  /* Nothing to do */
-}
-/*}}}*/
-void close_db(struct read_db *x)/*{{{*/
-{
-  free_toktable_db(&x->to);
-  free_toktable_db(&x->cc);
-  free_toktable_db(&x->from);
-  free_toktable_db(&x->subject);
-  free_toktable_db(&x->body);
-  free_toktable_db(&x->attachment_name);
-  free_toktable2_db(&x->msg_ids);
-
-  if (munmap(x->data, x->len) < 0) {
-    perror("munmap");
-    unlock_and_exit(2);
-  }
-  free(x);
-  return;
-}
-/*}}}*/
-
diff --git a/src/mairix/reader.h b/src/mairix/reader.h
@@ -1,182 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002-2004,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 READER_H
-#define READER_H
-
-/* MX, then a high byte, then the version no. */
-#define HEADER_MAGIC0 'M'
-#define HEADER_MAGIC1 'X'
-#define HEADER_MAGIC2 0xA5
-#define HEADER_MAGIC3 0x03
-
-/*{{{ Constants for file data positions */
-#define UI_ENDIAN          1
-#define UI_N_MSGS          2
-
-/* Offset to byte-per-message table encoding message types */
-#define UI_MSG_TYPE_AND_FLAGS 3
-
-/* Header positions containing offsets to the per-message tables. */
-/* Character data:
- * for maildir/MH : the path of the box.
- * for mbox : index of mbox containing the message */
-
-#define UI_MSG_CDATA       4
-/* For maildir/MH : mtime of file containing message */
-#define UI_MSG_MTIME       5
-/* For mbox msgs : the offset into the file */
-#define UI_MSG_OFFSET      5
-/* For all formats : message size */
-#define UI_MSG_SIZE        6
-/* For mbox msgs : offset into file */
-#define UI_MSG_START       6
-/* These are common to Maildir,MH,mbox messages */
-#define UI_MSG_DATE        7
-#define UI_MSG_TID         8
-
-/* Header positions for mbox (file-level) information */
-/* Number of mboxes */
-#define UI_MBOX_N          9
-#define UI_MBOX_PATHS     10
-#define UI_MBOX_ENTRIES   11
-/* mtime of mboxes */
-#define UI_MBOX_MTIME     12
-/* Size in bytes */
-#define UI_MBOX_SIZE      13
-/* Base of checksums for messages in each mbox */
-#define UI_MBOX_CKSUM     14
-
-#define UI_HASH_KEY       15
-
-/* Header positions for token tables */
-#define UI_TO_BASE        16
-#define UI_CC_BASE        19
-#define UI_FROM_BASE      22
-#define UI_SUBJECT_BASE   25
-#define UI_BODY_BASE      28
-#define UI_ATTACHMENT_NAME_BASE 31
-#define UI_MSGID_BASE     34
-
-/* Larger than the last table offset. */
-#define UI_HEADER_LEN     40
-#define UC_HEADER_LEN     ((UI_HEADER_LEN) << 2)
-
-#define UI_N_OFFSET        0
-#define UI_TOK_OFFSET      1
-#define UI_ENC_OFFSET      2
-
-#define UI_TO_N           (UI_TO_BASE + UI_N_OFFSET)
-#define UI_TO_TOK         (UI_TO_BASE + UI_TOK_OFFSET)
-#define UI_TO_ENC         (UI_TO_BASE + UI_ENC_OFFSET)
-#define UI_CC_N           (UI_CC_BASE + UI_N_OFFSET)
-#define UI_CC_TOK         (UI_CC_BASE + UI_TOK_OFFSET)
-#define UI_CC_ENC         (UI_CC_BASE + UI_ENC_OFFSET)
-#define UI_FROM_N         (UI_FROM_BASE + UI_N_OFFSET)
-#define UI_FROM_TOK       (UI_FROM_BASE + UI_TOK_OFFSET)
-#define UI_FROM_ENC       (UI_FROM_BASE + UI_ENC_OFFSET)
-#define UI_SUBJECT_N      (UI_SUBJECT_BASE + UI_N_OFFSET)
-#define UI_SUBJECT_TOK    (UI_SUBJECT_BASE + UI_TOK_OFFSET)
-#define UI_SUBJECT_ENC    (UI_SUBJECT_BASE + UI_ENC_OFFSET)
-#define UI_BODY_N         (UI_BODY_BASE + UI_N_OFFSET)
-#define UI_BODY_TOK       (UI_BODY_BASE + UI_TOK_OFFSET)
-#define UI_BODY_ENC       (UI_BODY_BASE + UI_ENC_OFFSET)
-#define UI_ATTACHMENT_NAME_N    (UI_ATTACHMENT_NAME_BASE + UI_N_OFFSET)
-#define UI_ATTACHMENT_NAME_TOK  (UI_ATTACHMENT_NAME_BASE + UI_TOK_OFFSET)
-#define UI_ATTACHMENT_NAME_ENC  (UI_ATTACHMENT_NAME_BASE + UI_ENC_OFFSET)
-#define UI_MSGID_N        (UI_MSGID_BASE + UI_N_OFFSET)
-#define UI_MSGID_TOK      (UI_MSGID_BASE + UI_TOK_OFFSET)
-#define UI_MSGID_ENC0     (UI_MSGID_BASE + UI_ENC_OFFSET)
-#define UI_MSGID_ENC1     (UI_MSGID_ENC0 + 1)
-
-/*}}}*/
-
-/*{{{ Literals used for encoding messages types in database file */
-#define DB_MSG_DEAD 0
-/* maildir/MH : one file per message */
-#define DB_MSG_FILE 1
-/* mbox : multiple files per message */
-#define DB_MSG_MBOX 2
-/*}}}*/
-
-#define FLAG_SEEN    (1<<3)
-#define FLAG_REPLIED (1<<4)
-#define FLAG_FLAGGED (1<<5)
-
-struct toktable_db {/*{{{*/
-  unsigned int n; /* number of entries in this table */
-  unsigned int *tok_offsets; /* offset to table of token offsets */
-  unsigned int *enc_offsets; /* offset to table of encoding offsets */
-};
-/*}}}*/
-struct toktable2_db {/*{{{*/
-  unsigned int n; /* number of entries in this table */
-  unsigned int *tok_offsets; /* offset to table of token offsets */
-  unsigned int *enc0_offsets; /* offset to table of encoding offsets */
-  unsigned int *enc1_offsets; /* offset to table of encoding offsets */
-};
-/*}}}*/
-struct read_db {/*{{{*/
-  /* Raw file parameters, needed later for munmap */
-  char *data;
-  int len;
-
-  /* Pathname information */
-  int n_msgs;
-  unsigned char *msg_type_and_flags;
-  unsigned int *path_offsets; /* or (mbox index, msg index) */
-  unsigned int *mtime_table; /* or offset into mbox */
-  unsigned int *size_table;  /* either file size or span inside mbox */
-  unsigned int *date_table;
-  unsigned int *tid_table;
-
-  int n_mboxen;
-  unsigned int *mbox_paths_table;
-  unsigned int *mbox_entries_table; /* table of number of messages per mbox */
-  unsigned int *mbox_mtime_table;
-  unsigned int *mbox_size_table;
-  unsigned int *mbox_checksum_table;
-
-  unsigned int hash_key;
-
-  struct toktable_db to;
-  struct toktable_db cc;
-  struct toktable_db from;
-  struct toktable_db subject;
-  struct toktable_db body;
-  struct toktable_db attachment_name;
-  struct toktable2_db msg_ids;
-
-};
-/*}}}*/
-
-struct read_db *open_db(char *filename);
-void close_db(struct read_db *x);
-
-static inline int rd_msg_type(struct read_db *db, int i) {
-  return db->msg_type_and_flags[i] & 0x7;
-}
-
-/* Common to search and db reader. */
-int read_increment(unsigned char **encpos);
-
-#endif /* READER_H */
diff --git a/src/mairix/rfc822.c b/src/mairix/rfc822.c
@@ -1,1536 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006,2007,2010
- * rfc2047 decode:
- * Copyright (C) Mikael Ylikoski 2002
- * gzip mbox support:
- * Copyright (C) Ico Doornekamp 2005
- * Copyright (C) Felipe Gustavo de Almeida 2005
- * bzip2 mbox support:
- * Copyright (C) Paramjit Oberoi 2005
- * caching uncompressed mbox data:
- * Copyright (C) Chris Mason 2006
- * memory leak fixes:
- * Copyright (C) Samuel Tardieu 2008
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "mairix.h"
-#include "nvp.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#ifdef USE_GZIP_MBOX
-#  include <zlib.h>
-#endif
-#ifdef USE_BZIP_MBOX
-#  include <bzlib.h>
-#endif
-
-struct DLL {/*{{{*/
-  struct DLL *next;
-  struct DLL *prev;
-};
-/*}}}*/
-static void enqueue(void *head, void *x)/*{{{*/
-{
-  /* Declare this way so it can be used with any kind of double linked list
-   * having next & prev pointers in its first two words. */
-  struct DLL *h = (struct DLL *) head;
-  struct DLL *xx = (struct DLL *) x;
-  xx->next = h;
-  xx->prev = h->prev;
-  h->prev->next = xx;
-  h->prev = xx;
-  return;
-}
-/*}}}*/
-
-enum encoding_type {/*{{{*/
-  ENC_UNKNOWN,
-  ENC_NONE,
-  ENC_BINARY,
-  ENC_7BIT,
-  ENC_8BIT,
-  ENC_QUOTED_PRINTABLE,
-  ENC_BASE64,
-  ENC_UUENCODE
-};
-/*}}}*/
-struct content_type_header {/*{{{*/
-  const char *major; /* e.g. text */
-  const char *minor; /* e.g. plain */
-  const char *boundary; /* for multipart */
-  /* charset? */
-};
-/*}}}*/
-struct line {/*{{{*/
-  struct line *next;
-  struct line *prev;
-  char *text;
-};
-/*}}}*/
-
-static void init_headers(struct headers *hdrs)/*{{{*/
-{
-  hdrs->to = NULL;
-  hdrs->cc = NULL;
-  hdrs->from = NULL;
-  hdrs->subject = NULL;
-  hdrs->message_id = NULL;
-  hdrs->in_reply_to = NULL;
-  hdrs->references = NULL;
-  hdrs->date = 0;
-  hdrs->flags.seen = 0;
-  hdrs->flags.replied = 0;
-  hdrs->flags.flagged = 0;
-};
-/*}}}*/
-static void splice_header_lines(struct line *header)/*{{{*/
-{
-  /* Deal with newline then tab in header */
-  struct line *x, *next;
-  for (x=header->next; x!=header; x=next) {
-#if 0
-    printf("next header, x->text=%08lx\n", x->text);
-    printf("header=<%s>\n", x->text);
-#endif
-    next = x->next;
-    if (isspace(x->text[0] & 0xff)) {
-      /* Glue to previous line */
-      char *p, *newbuf, *oldbuf;
-      struct line *y;
-      for (p=x->text; *p; p++) {
-        if (!isspace(*(unsigned char *)p)) break;
-      }
-      p--; /* point to final space */
-      y = x->prev;
-#if 0
-      printf("y=%08lx p=%08lx\n", y->text, p);
-#endif
-      newbuf = new_array(char, strlen(y->text) + strlen(p) + 1);
-      strcpy(newbuf, y->text);
-      strcat(newbuf, p);
-      oldbuf = y->text;
-      y->text = newbuf;
-      free(oldbuf);
-      y->next = x->next;
-      x->next->prev = y;
-      free(x->text);
-      free(x);
-    }
-  }
-  return;
-}
-/*}}}*/
-static int audit_header(struct line *header)/*{{{*/
-{
-  /* Check for obvious broken-ness
-   * 1st line has no leading spaces, single word then colon
-   * following lines have leading spaces or single word followed by colon
-   * */
-  struct line *x;
-  int first=1;
-  int count=1;
-  for (x=header->next; x!=header; x=x->next) {
-    int has_leading_space=0;
-    int is_blank;
-    int has_word_colon=0;
-
-    if (1 || first) {
-      /* Ignore any UUCP or mbox style From line at the start */
-      if (!strncmp("From ", x->text, 5)) {
-        continue;
-      }
-      /* Ignore escaped From line at the start */
-      if (!strncmp(">From ", x->text, 6)) {
-        continue;
-      }
-    }
-
-    is_blank = !(x->text[0]);
-    if (!is_blank) {
-      char *p;
-      int saw_char = 0;
-      has_leading_space = isspace(x->text[0] & 0xff);
-      has_word_colon = 0; /* default */
-      p = x->text;
-      while(*p) {
-        if(*p == ':') {
-          has_word_colon = saw_char;
-          break;
-        } else if (isspace(*(unsigned char *) p)) {
-          has_word_colon = 0;
-          break;
-        } else {
-          saw_char = 1;
-        }
-        p++;
-      }
-    }
-
-    if (( first && (is_blank || has_leading_space || !has_word_colon)) ||
-        (!first && (is_blank || !(has_leading_space || has_word_colon)))) {
-#if 0
-      fprintf(stderr, "Header line %d <%s> fails because:", count, x->text);
-      if (first && is_blank) { fprintf(stderr, " [first && is_blank]"); }
-      if (first && has_leading_space) { fprintf(stderr, " [first && has_leading_space]"); }
-      if (first && !has_word_colon) { fprintf(stderr, " [first && !has_word_colon]"); }
-      if (!first && is_blank) { fprintf(stderr, " [!first && is_blank]"); }
-      if (!first && !(has_leading_space||has_word_colon)) { fprintf(stderr, " [!first && !has_leading_space||has_word_colon]"); }
-      fprintf(stderr, "\n");
-#endif
-      /* Header fails the audit */
-      return 0;
-    }
-    first = 0;
-    count++;
-  }
-  /* If we get here the header must have been OK */
-  return 1;
-}/*}}}*/
-static int match_string(const char *ref, const char *candidate)/*{{{*/
-{
-  int len = strlen(ref);
-  return !strncasecmp(ref, candidate, len);
-}
-/*}}}*/
-
-static char equal_table[] = {/*{{{*/
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 00-0f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 10-1f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 20-2f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,  /* 30-3f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 40-4f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 50-5f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 60-6f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 70-7f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 80-8f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 90-9f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* a0-af */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* b0-bf */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* c0-cf */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* d0-df */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* e0-ef */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   /* f0-ff */
-};
-/*}}}*/
-static int base64_table[] = {/*{{{*/
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 00-0f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 10-1f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  62,  -1,  -1,  -1,  63,  /* 20-2f */
-   52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  -1,  -1,  -1,   0,  -1,  -1,  /* 30-3f */
-   -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  /* 40-4f */
-   15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  -1,  -1,  -1,  -1,  -1,  /* 50-5f */
-   -1,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  /* 60-6f */
-   41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  -1,  -1,  -1,  -1,  -1,  /* 70-7f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 80-8f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 90-9f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* a0-af */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* b0-bf */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* c0-cf */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* d0-df */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* e0-ef */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1   /* f0-ff */
-};
-/*}}}*/
-static int hex_to_val(char x) {/*{{{*/
-  switch (x) {
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      return (x - '0');
-      break;
-    case 'a':
-    case 'b':
-    case 'c':
-    case 'd':
-    case 'e':
-    case 'f':
-      return 10 + (x - 'a');
-      break;
-    case 'A':
-    case 'B':
-    case 'C':
-    case 'D':
-    case 'E':
-    case 'F':
-      return 10 + (x - 'A');
-      break;
-    default:
-      return 0;
-  }
-}
-/*}}}*/
-static void decode_header_value(char *text){/*{{{*/
-  /* rfc2047 decode, written by Mikael Ylikoski */
-
-  char *s, *a, *b, *e, *p, *q;
-
-  for (p = q = s = text; (s = strstr(s, "=?")); s = e + 2) {
-    if (p == q)
-      p = q = s;
-    else
-      while (q != s)
-        *p++ = *q++;
-    s += 2;
-    a = strchr(s, '?');
-    if (!a) break;
-    a++;
-    b = strchr(a, '?');
-    if (!b) break;
-    b++;
-    e = strstr(b, "?=");
-    if (!e) break;
-    /* have found an encoded-word */
-    if (b - a != 2)
-      continue; /* unknown encoding */
-    if (*a == 'q' || *a == 'Q') {
-      int val;
-      q = b;
-      while (q < e) {
-        if (*q == '_') {
-          *p++ = 0x20;
-          q++;
-        } else if (*q == '=') {
-          q++;
-          val = hex_to_val(*q++) << 4;
-          val += hex_to_val(*q++);
-          *p++ = val;
-        } else
-          *p++ = *q++;
-      }
-    } else if (*a == 'b' || *a == 'B') {
-      int reg, nc, eq; /* register, #characters in reg, #equals */
-      int dc; /* decoded character */
-      eq = reg = nc = 0;
-      for (q = b; q < e; q++) {
-        unsigned char cq = *(unsigned char *)q;
-        dc = base64_table[cq];
-        eq += equal_table[cq];
-
-        if (dc >= 0) {
-          reg <<= 6;
-          reg += dc;
-          nc++;
-          if (nc == 4) {
-            *p++ = ((reg >> 16) & 0xff);
-            if (eq < 2) *p++ = ((reg >> 8) & 0xff);
-            if (eq < 1) *p++ = reg & 0xff;
-            nc = reg = 0;
-            if (eq) break;
-          }
-        }
-      }
-    } else {
-      continue; /* unknown encoding */
-    }
-    q = e + 2;
-  }
-  if (p == q) return;
-  while (*q != '\0')
-    *p++ = *q++;
-  *p = '\0';
-}
-/*}}}*/
-static char *copy_header_value(char *text){/*{{{*/
-  char *p;
-  for (p = text; *p && (*p != ':'); p++) ;
-  if (!*p) return NULL;
-  p++;
-  p = new_string(p);
-  decode_header_value(p);
-  return p;
-}
-/*}}}*/
-static void copy_or_concat_header_value(char **previous, char *text){/*{{{*/
-  char *p = copy_header_value(text);
-  if (*previous)
-  {
-    *previous = extend_string(*previous, ", ");
-    *previous = extend_string(*previous, p);
-    free(p);
-  }
-  else
-    *previous = p;
-}
-/*}}}*/
-static enum encoding_type decode_encoding_type(const char *e)/*{{{*/
-{
-  enum encoding_type result;
-  const char *p;
-  if (!e) {
-    result = ENC_NONE;
-  } else {
-    for (p=e; *p && isspace(*(unsigned char *)p); p++) ;
-    if (   match_string("7bit", p)
-        || match_string("7-bit", p)
-        || match_string("7 bit", p)) {
-      result = ENC_7BIT;
-    } else if (match_string("8bit", p)
-            || match_string("8-bit", p)
-            || match_string("8 bit", p)) {
-      result = ENC_8BIT;
-    } else if (match_string("quoted-printable", p)) {
-      result = ENC_QUOTED_PRINTABLE;
-    } else if (match_string("base64", p)) {
-      result = ENC_BASE64;
-    } else if (match_string("binary", p)) {
-      result = ENC_BINARY;
-    } else if (match_string("x-uuencode", p)) {
-      result = ENC_UUENCODE;
-    } else {
-      fprintf(stderr, "Warning: unknown encoding type: '%s'\n", e);
-      result = ENC_UNKNOWN;
-    }
-  }
-  return result;
-}
-/*}}}*/
-static void parse_content_type(struct nvp *ct_nvp, struct content_type_header *result)/*{{{*/
-{
-  result->major = NULL;
-  result->minor = NULL;
-  result->boundary = NULL;
-
-  result->major = nvp_major(ct_nvp);
-  if (result->major) {
-    result->minor = nvp_minor(ct_nvp);
-  } else {
-    result->minor = NULL;
-    result->major = nvp_first(ct_nvp);
-  }
-
-  result->boundary = nvp_lookupcase(ct_nvp, "boundary");
-}
-
-/*}}}*/
-static char *looking_at_ws_then_newline(char *start)/*{{{*/
-{
-  char *result;
-  result = start;
-  do {
-         if (*result == '\n')   return result;
-    else if (!isspace(*(unsigned char *) result)) return NULL;
-    else                        result++;
-  } while (1);
-
-  /* Can't get here */
-  assert(0);
-}
-/*}}}*/
-
-static char *unencode_data(struct msg_src *src, char *input, int input_len, const char *enc, int *output_len)/*{{{*/
-{
-  enum encoding_type encoding;
-  char *result, *end_result;
-  char *end_input;
-
-  encoding = decode_encoding_type(enc);
-  end_input = input + input_len;
-
-  /* All mime encodings result in expanded data, so this is guaranteed to
-   * safely oversize the output array */
-  result = new_array(char, input_len + 1);
-
-  /* Now decode */
-  switch (encoding) {
-    case ENC_7BIT:/*{{{*/
-    case ENC_8BIT:
-    case ENC_BINARY:
-    case ENC_NONE:
-      {
-        memcpy(result, input, input_len);
-        end_result = result + input_len;
-      }
-      break;
-/*}}}*/
-    case ENC_QUOTED_PRINTABLE:/*{{{*/
-      {
-        char *p, *q;
-        p = result;
-        for (p=result, q=input;
-             q<end_input; ) {
-
-          if (*q == '=') {
-            /* followed by optional whitespace then \n?  discard them. */
-            char *r;
-            int val;
-            q++;
-            r = looking_at_ws_then_newline(q);
-            if (r) {
-              q = r + 1; /* Point into next line */
-              continue;
-            }
-            /* not that case. */
-            val =  hex_to_val(*q++) << 4;
-            val += hex_to_val(*q++);
-            *p++ = val;
-
-          } else {
-            /* Normal character */
-            *p++ = *q++;
-          }
-        }
-        end_result = p;
-      }
-      break;
-/*}}}*/
-    case ENC_BASE64:/*{{{*/
-      {
-        char *p, *q;
-        int reg, nc, eq; /* register, #characters in reg, #equals */
-        int dc; /* decoded character */
-        eq = reg = nc = 0;
-        for (q=input, p=result; q<end_input; q++) {
-          unsigned char cq =  * (unsigned char *)q;
-          /* Might want a 256 entry array instead of this sub-optimal mess
-           * eventually. */
-          dc = base64_table[cq];
-          eq += equal_table[cq];
-
-          if (dc >= 0) {
-            reg <<= 6;
-            reg += dc;
-            nc++;
-            if (nc == 4) {
-              *p++ = ((reg >> 16) & 0xff);
-              if (eq < 2) *p++ = ((reg >> 8) & 0xff);
-              if (eq < 1) *p++ = reg & 0xff;
-              nc = reg = 0;
-              if (eq) goto done_base_64;
-            }
-          }
-        }
-      done_base_64:
-        end_result = p;
-      }
-      break;
-        /*}}}*/
-    case ENC_UUENCODE:/*{{{*/
-      {
-        char *p, *q;
-        /* Find 'begin ' */
-        for (q = input; q < end_input - 6 && memcmp(q, "begin ", 6); q++)
-          ;
-        q += 6;
-        /* skip to EOL */
-        while (q < end_input && *q != '\n')
-          q++;
-        p = result;
-        while (q < end_input) { /* process line */
-#define DEC(c) (((c) - ' ') & 077)
-          int len = DEC(*q++);
-          if (len == 0)
-            break;
-          for (; len > 0; q += 4, len -= 3) {
-            if (len >= 3) {
-              *p++ = DEC(q[0]) << 2 | DEC(q[1]) >> 4;
-              *p++ = DEC(q[1]) << 4 | DEC(q[2]) >> 2;
-              *p++ = DEC(q[2]) << 6 | DEC(q[3]);
-            } else {
-              if (len >= 1)
-                *p++ = DEC(q[0]) << 2 | DEC(q[1]) >> 4;
-              if (len >= 2)
-                *p++ = DEC(q[1]) << 4 | DEC(q[2]) >> 2;
-            }
-          }
-          while (q < end_input && *q != '\n')
-            q++;
-        }
-        end_result = p;
-      }
-      break;
-        /*}}}*/
-    case ENC_UNKNOWN:/*{{{*/
-      fprintf(stderr, "Unknown encoding type in %s\n", format_msg_src(src));
-      /* fall through - ignore this data */
-    /*}}}*/
-    default:/*{{{*/
-      end_result = result;
-      break;
-      /*}}}*/
-  }
-  *output_len = end_result - result;
-  result[*output_len] = '\0'; /* for convenience with text/plain etc to make it printable */
-  return result;
-}
-/*}}}*/
-char *format_msg_src(struct msg_src *src)/*{{{*/
-{
-  static char *buffer = NULL;
-  static int buffer_len = 0;
-  char *result;
-  int len;
-  switch (src->type) {
-    case MS_FILE:
-      result = src->filename;
-      break;
-    case MS_MBOX:
-      len = strlen(src->filename);
-      len += 32;
-      if (!buffer || (len > buffer_len)) {
-        free(buffer);
-        buffer = new_array(char, len);
-        buffer_len = len;
-      }
-      sprintf(buffer, "%s[%d,%d)", src->filename,
-          (int) src->start, (int) (src->start + src->len));
-      result = buffer;
-      break;
-    default:
-      result = NULL;
-      break;
-  }
-  return result;
-}
-/*}}}*/
-static int split_and_splice_header(struct msg_src *src, char *data, struct line *header, char **body_start)/*{{{*/
-{
-  char *sol, *eol;
-  int blank_line;
-  header->next = header->prev = header;
-  sol = data;
-  do {
-    if (!*sol) break;
-    blank_line = 1; /* until proven otherwise */
-    eol = sol;
-    while (*eol && (*eol != '\n')) {
-      if (!isspace(*(unsigned char *) eol)) blank_line = 0;
-      eol++;
-    }
-    if (*eol == '\n') {
-      if (!blank_line) {
-        int line_length = eol - sol;
-        char *line_text = new_array(char, 1 + line_length);
-        struct line *new_header;
-
-        strncpy(line_text, sol, line_length);
-        line_text[line_length] = '\0';
-        new_header = new(struct line);
-        new_header->text = line_text;
-        enqueue(header, new_header);
-      }
-      sol = eol + 1; /* Start of next line */
-    } else { /* must be null char */
-      fprintf(stderr, "Got null character whilst processing header of %s\n",
-          format_msg_src(src));
-      return -1; /* & leak memory */
-    }
-  } while (!blank_line);
-
-  *body_start = sol;
-
-  if (audit_header(header)) {
-    splice_header_lines(header);
-    return 0;
-  } else {
-#if 0
-    /* Caller generates message */
-    fprintf(stderr, "Message had bad rfc822 headers, ignoring\n");
-#endif
-    return -1;
-  }
-}
-/*}}}*/
-
-/* Forward prototypes */
-static void do_multipart(struct msg_src *src, char *input, int input_len,
-    const char *boundary, struct attachment *atts,
-    enum data_to_rfc822_error *error);
-
-/*{{{ do_body() */
-static void do_body(struct msg_src *src,
-    char *body_start, int body_len,
-    struct nvp *ct_nvp, struct nvp *cte_nvp,
-    struct nvp *cd_nvp,
-    struct attachment *atts,
-    enum data_to_rfc822_error *error)
-{
-  char *decoded_body;
-  int decoded_body_len;
-  const char *content_transfer_encoding;
-  content_transfer_encoding = NULL;
-  if (cte_nvp) {
-    content_transfer_encoding = nvp_first(cte_nvp);
-    if (!content_transfer_encoding) {
-      fprintf(stderr, "Giving up on %s, content_transfer_encoding header not parseable\n",
-          format_msg_src(src));
-      return;
-    }
-  }
-
-  decoded_body = unencode_data(src, body_start, body_len, content_transfer_encoding, &decoded_body_len);
-
-  if (ct_nvp) {
-    struct content_type_header ct;
-    parse_content_type(ct_nvp, &ct);
-    if (ct.major && !strcasecmp(ct.major, "multipart")) {
-      do_multipart(src, decoded_body, decoded_body_len, ct.boundary, atts, error);
-      /* Don't need decoded body any longer - copies have been taken if
-       * required when handling multipart attachments. */
-      free(decoded_body);
-      if (error && (*error == DTR8_MISSING_END)) return;
-    } else {
-      /* unipart */
-      struct attachment *new_att;
-      const char *disposition;
-      new_att = new(struct attachment);
-      disposition = cd_nvp ? nvp_first(cd_nvp) : NULL;
-      if (disposition && !strcasecmp(disposition, "attachment")) {
-        const char *lookup;
-        lookup = nvp_lookupcase(cd_nvp, "filename");
-        if (lookup) {
-          new_att->filename = new_string(lookup);
-        } else {
-          /* Some messages have name=... in content-type: instead of
-           * filename=... in content-disposition. */
-          lookup = nvp_lookup(ct_nvp, "name");
-          if (lookup) {
-            new_att->filename = new_string(lookup);
-          } else {
-            new_att->filename = NULL;
-          }
-        }
-      } else {
-        new_att->filename = NULL;
-      }
-      if (ct.major && !strcasecmp(ct.major, "text")) {
-        if (ct.minor && !strcasecmp(ct.minor, "plain")) {
-          new_att->ct = CT_TEXT_PLAIN;
-        } else if (ct.minor && !strcasecmp(ct.minor, "html")) {
-          new_att->ct = CT_TEXT_HTML;
-        } else {
-          new_att->ct = CT_TEXT_OTHER;
-        }
-      } else if (ct.major && !strcasecmp(ct.major, "message") &&
-                 ct.minor && !strcasecmp(ct.minor, "rfc822")) {
-        new_att->ct = CT_MESSAGE_RFC822;
-      } else {
-        new_att->ct = CT_OTHER;
-      }
-
-      if (new_att->ct == CT_MESSAGE_RFC822) {
-        new_att->data.rfc822 = data_to_rfc822(src, decoded_body, decoded_body_len, error);
-        free(decoded_body); /* data no longer needed */
-      } else {
-        new_att->data.normal.len = decoded_body_len;
-        new_att->data.normal.bytes = decoded_body;
-      }
-      enqueue(atts, new_att);
-    }
-  } else {
-    /* Treat as text/plain {{{*/
-    struct attachment *new_att;
-    new_att = new(struct attachment);
-    new_att->filename = NULL;
-    new_att->ct = CT_TEXT_PLAIN;
-    new_att->data.normal.len = decoded_body_len;
-    /* Add null termination on the end */
-    new_att->data.normal.bytes = new_array(char, decoded_body_len + 1);
-    memcpy(new_att->data.normal.bytes, decoded_body, decoded_body_len + 1);
-    free(decoded_body);
-    enqueue(atts, new_att);/*}}}*/
-  }
-}
-/*}}}*/
-/*{{{ do_attachment() */
-static void do_attachment(struct msg_src *src,
-    char *start, char *after_end,
-    struct attachment *atts)
-{
-  /* decode attachment and add to attachment list */
-  struct line header, *x, *nx;
-  char *body_start;
-  int body_len;
-
-  struct nvp *ct_nvp, *cte_nvp, *cd_nvp, *nvp;
-
-  if (split_and_splice_header(src, start, &header, &body_start) < 0) {
-    fprintf(stderr, "Giving up on attachment with bad header in %s\n",
-        format_msg_src(src));
-    return;
-  }
-
-  /* Extract key headers */
-  ct_nvp = cte_nvp = cd_nvp = NULL;
-  for (x=header.next; x!=&header; x=x->next) {
-    if ((nvp = make_nvp(src, x->text, "content-type:"))) {
-      ct_nvp = nvp;
-    } else if ((nvp = make_nvp(src, x->text, "content-transfer-encoding:"))) {
-      cte_nvp = nvp;
-    } else if ((nvp = make_nvp(src, x->text, "content-disposition:"))) {
-      cd_nvp = nvp;
-    }
-  }
-
-#if 0
-  if (ct_nvp) {
-    fprintf(stderr, "======\n");
-    fprintf(stderr, "Dump of content-type hdr\n");
-    nvp_dump(ct_nvp, stderr);
-    free(ct_nvp);
-  }
-
-  if (cte_nvp) {
-    fprintf(stderr, "======\n");
-    fprintf(stderr, "Dump of content-transfer-encoding hdr\n");
-    nvp_dump(cte_nvp, stderr);
-    free(cte_nvp);
-  }
-#endif
-
-  if (body_start > after_end) {
-    /* This is a (maliciously?) b0rken attachment, e.g. maybe empty */
-    if (verbose) {
-      fprintf(stderr, "Message %s contains an invalid attachment, length=%d bytes\n",
-          format_msg_src(src), (int)(after_end - start));
-    }
-  } else {
-    body_len = after_end - body_start;
-    /* Ignore errors in nested body parts. */
-    do_body(src, body_start, body_len, ct_nvp, cte_nvp, cd_nvp, atts, NULL);
-  }
-
-  /* Free header memory */
-  for (x=header.next; x!=&header; x=nx) {
-    nx = x->next;
-    free(x->text);
-    free(x);
-  }
-
-  if (ct_nvp) free_nvp(ct_nvp);
-  if (cte_nvp) free_nvp(cte_nvp);
-  if (cd_nvp) free_nvp(cd_nvp);
-}
-/*}}}*/
-/*{{{ do_multipart() */
-static void do_multipart(struct msg_src *src,
-    char *input, int input_len,
-    const char *boundary,
-    struct attachment *atts,
-    enum data_to_rfc822_error *error)
-{
-  char *b0, *b1, *be, *bx;
-  char *line_after_b0, *start_b1_search_from;
-  int boundary_len;
-  int looking_at_end_boundary;
-
-  if (!boundary) {
-    fprintf(stderr, "Can't process multipart message %s with no boundary string\n",
-        format_msg_src(src));
-    if (error) *error = DTR8_MULTIPART_SANS_BOUNDARY;
-    return;
-  }
-
-  boundary_len = strlen(boundary);
-
-  b0 = NULL;
-  line_after_b0 = input;
-  be = input + input_len;
-
-  do {
-    int boundary_ok;
-    start_b1_search_from = line_after_b0;
-    do {
-      /* reject boundaries that aren't a whole line */
-      b1 = NULL;
-      for (bx = start_b1_search_from; bx < be - (boundary_len + 4); bx++) {
-        if (bx[0] == '-' && bx[1] == '-' &&
-            !strncmp(bx+2, boundary, boundary_len)) {
-          b1 = bx;
-          break;
-        }
-      }
-      if (!b1) {
-        if (error)
-          *error = DTR8_MISSING_END;
-        return;
-      }
-
-      looking_at_end_boundary = (b1[boundary_len+2] == '-' &&
-          b1[boundary_len+3] == '-');
-      boundary_ok = 1;
-      if ((b1 > input) && (*(b1-1) != '\n'))
-        boundary_ok = 0;
-      if (!looking_at_end_boundary && (b1 + boundary_len + 2 < input + input_len) && (*(b1 + boundary_len + 2) != '\n'))
-        boundary_ok = 0;
-      if (!boundary_ok) {
-        char *eol = strchr(b1, '\n');
-        if (!eol) {
-          fprintf(stderr, "Oops, didn't find another normal boundary in %s\n",
-              format_msg_src(src));
-          return;
-        }
-        start_b1_search_from = 1 + eol;
-      }
-    } while (!boundary_ok);
-
-    /* b1 is now looking at a good boundary, which might be the final one */
-
-    if (b0) {
-      /* don't treat preamble as an attachment */
-      do_attachment(src, line_after_b0, b1, atts);
-    }
-
-    b0 = b1;
-    line_after_b0 = strchr(b0, '\n');
-    if (line_after_b0 == 0)
-      line_after_b0 = b0 + strlen(b0);
-    else
-      ++line_after_b0;
-  } while (b1 < be && !looking_at_end_boundary);
-}
-/*}}}*/
-static time_t parse_rfc822_date(char *date_string)/*{{{*/
-{
-  struct tm tm;
-  char *s, *z;
-  /* Format [weekday ,] day-of-month month year hour:minute:second timezone.
-
-     Some of the ideas, sanity checks etc taken from parse.c in the mutt
-     sources, credit to Michael R. Elkins et al
-     */
-
-  s = date_string;
-  z = strchr(s, ',');
-  if (z) s = z + 1;
-  while (*s && isspace(*s)) s++;
-  /* Should now be looking at day number */
-  if (!isdigit(*s)) goto tough_cheese;
-  tm.tm_mday = atoi(s);
-  if (tm.tm_mday > 31) goto tough_cheese;
-
-  while (isdigit(*s)) s++;
-  while (*s && isspace(*s)) s++;
-  if (!*s) goto tough_cheese;
-  if      (!strncasecmp(s, "jan", 3)) tm.tm_mon =  0;
-  else if (!strncasecmp(s, "feb", 3)) tm.tm_mon =  1;
-  else if (!strncasecmp(s, "mar", 3)) tm.tm_mon =  2;
-  else if (!strncasecmp(s, "apr", 3)) tm.tm_mon =  3;
-  else if (!strncasecmp(s, "may", 3)) tm.tm_mon =  4;
-  else if (!strncasecmp(s, "jun", 3)) tm.tm_mon =  5;
-  else if (!strncasecmp(s, "jul", 3)) tm.tm_mon =  6;
-  else if (!strncasecmp(s, "aug", 3)) tm.tm_mon =  7;
-  else if (!strncasecmp(s, "sep", 3)) tm.tm_mon =  8;
-  else if (!strncasecmp(s, "oct", 3)) tm.tm_mon =  9;
-  else if (!strncasecmp(s, "nov", 3)) tm.tm_mon = 10;
-  else if (!strncasecmp(s, "dec", 3)) tm.tm_mon = 11;
-  else goto tough_cheese;
-
-  while (!isspace(*s)) s++;
-  while (*s && isspace(*s)) s++;
-  if (!isdigit(*s)) goto tough_cheese;
-  tm.tm_year = atoi(s);
-  if (tm.tm_year < 70) {
-    tm.tm_year += 100;
-  } else if (tm.tm_year >= 1900) {
-    tm.tm_year -= 1900;
-  }
-
-  while (isdigit(*s)) s++;
-  while (*s && isspace(*s)) s++;
-  if (!*s) goto tough_cheese;
-
-  /* Now looking at hms */
-  /* For now, forget this.  The searching will be vague enough that nearest day is good enough. */
-
-  tm.tm_hour = 0;
-  tm.tm_min = 0;
-  tm.tm_sec = 0;
-  tm.tm_isdst = 0;
-  return mktime(&tm);
-
-tough_cheese:
-  return (time_t) -1; /* default value */
-}
-/*}}}*/
-
-static void scan_status_flags(const char *s, struct headers *hdrs)/*{{{*/
-{
-  const char *p;
-  for (p=s; *p; p++) {
-    switch (*p) {
-      case 'R': hdrs->flags.seen = 1; break;
-      case 'A': hdrs->flags.replied = 1; break;
-      case 'F': hdrs->flags.flagged = 1; break;
-      default: break;
-    }
-  }
-}
-/*}}}*/
-
-/*{{{ data_to_rfc822() */
-struct rfc822 *data_to_rfc822(struct msg_src *src,
-    char *data, int length,
-    enum data_to_rfc822_error *error)
-{
-  struct rfc822 *result;
-  char *body_start;
-  struct line header;
-  struct line *x, *nx;
-  struct nvp *ct_nvp, *cte_nvp, *cd_nvp, *nvp;
-  int body_len;
-
-  if (error) *error = DTR8_OK; /* default */
-  result = new(struct rfc822);
-  init_headers(&result->hdrs);
-  result->atts.next = result->atts.prev = &result->atts;
-
-  if (split_and_splice_header(src, data, &header, &body_start) < 0) {
-    if (verbose) {
-      fprintf(stderr, "Giving up on message %s with bad header\n",
-          format_msg_src(src));
-    }
-    if (error) *error = DTR8_BAD_HEADERS;
-    return NULL;
-  }
-
-  /* Extract key headers {{{*/
-  ct_nvp = cte_nvp = cd_nvp = NULL;
-  for (x=header.next; x!=&header; x=x->next) {
-    if      (match_string("to", x->text))
-      copy_or_concat_header_value(&result->hdrs.to, x->text);
-    else if (match_string("cc", x->text))
-      copy_or_concat_header_value(&result->hdrs.cc, x->text);
-    else if (!result->hdrs.from && match_string("from", x->text))
-      result->hdrs.from = copy_header_value(x->text);
-    else if (!result->hdrs.subject && match_string("subject", x->text))
-      result->hdrs.subject = copy_header_value(x->text);
-    else if (!ct_nvp && (nvp = make_nvp(src, x->text, "content-type:")))
-      ct_nvp = nvp;
-    else if (!cte_nvp && (nvp = make_nvp(src, x->text, "content-transfer-encoding:")))
-      cte_nvp = nvp;
-    else if (!cd_nvp && (nvp = make_nvp(src, x->text, "content-disposition:")))
-      cd_nvp = nvp;
-    else if (!result->hdrs.date && match_string("date", x->text)) {
-      char *date_string = copy_header_value(x->text);
-      result->hdrs.date = parse_rfc822_date(date_string);
-      free(date_string);
-    } else if (!result->hdrs.message_id && match_string("message-id", x->text))
-      result->hdrs.message_id = copy_header_value(x->text);
-    else if (!result->hdrs.in_reply_to && match_string("in-reply-to", x->text))
-      result->hdrs.in_reply_to = copy_header_value(x->text);
-    else if (!result->hdrs.references && match_string("references", x->text))
-      result->hdrs.references = copy_header_value(x->text);
-    else if (match_string("status", x->text))
-      scan_status_flags(x->text + sizeof("status:"), &result->hdrs);
-    else if (match_string("x-status", x->text))
-      scan_status_flags(x->text + sizeof("x-status:"), &result->hdrs);
-  }
-/*}}}*/
-
-  /* Process body */
-  body_len = length - (body_start - data);
-  do_body(src, body_start, body_len, ct_nvp, cte_nvp, cd_nvp, &result->atts, error);
-
-  /* Free header memory */
-  for (x=header.next; x!=&header; x=nx) {
-    nx = x->next;
-    free(x->text);
-    free(x);
-  }
-
-  if (ct_nvp) free_nvp(ct_nvp);
-  if (cte_nvp) free_nvp(cte_nvp);
-  if (cd_nvp) free_nvp(cd_nvp);
-
-  return result;
-
-}
-/*}}}*/
-
-#define ALLOC_NONE   1
-#define ALLOC_MMAP   2
-#define ALLOC_MALLOC 3
-
-int data_alloc_type;
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-
-#define SIZE_STEP (8 * 1024 * 1024)
-
-#define COMPRESSION_NONE 0
-#define COMPRESSION_GZIP 1
-#define COMPRESSION_BZIP 2
-
-static int get_compression_type(const char *filename) {/*{{{*/
-  size_t len = strlen(filename);
-  int ptr;
-
-#ifdef USE_GZIP_MBOX
-  ptr = len - 3;
-  if (len > 3 && strncasecmp(filename + ptr, ".gz", 3) == 0) {
-    return COMPRESSION_GZIP;
-  }
-#endif
-
-#ifdef USE_BZIP_MBOX
-  ptr = len - 4;
-  if (len > 3 && strncasecmp(filename + ptr, ".bz2", 4) == 0) {
-    return COMPRESSION_BZIP;
-  }
-#endif
-
-  return COMPRESSION_NONE;
-}
-/*}}}*/
-
-static int is_compressed(const char *filename) {/*{{{*/
-  return (get_compression_type(filename) != COMPRESSION_NONE);
-}
-/*}}}*/
-
-struct zFile {/*{{{*/
-  union {
-    /* Both gzFile and BZFILE* are defined as void pointers
-     * in their respective header files.
-     */
-#ifdef USE_GZIP_MBOX
-    gzFile gzf;
-#endif
-#ifdef USE_BZIP_MBOX
-    BZFILE *bzf;
-#endif
-    void *zptr;
-  } foo;
-  int type;
-};
-/*}}}*/
-
-static struct zFile * xx_zopen(const char *filename, const char *mode) {/*{{{*/
-  struct zFile *zf = new(struct zFile);
-
-  zf->type = get_compression_type(filename);
-  switch (zf->type) {
-#ifdef USE_GZIP_MBOX
-    case COMPRESSION_GZIP:
-      zf->foo.gzf = gzopen(filename, "rb");
-      break;
-#endif
-#ifdef USE_BZIP_MBOX
-    case COMPRESSION_BZIP:
-      zf->foo.bzf = BZ2_bzopen(filename, "rb");
-      break;
-#endif
-    default:
-      zf->foo.zptr = NULL;
-      break;
-  }
-
-  if (!zf->foo.zptr) {
-    free(zf);
-    return 0;
-  }
-
-  return zf;
-}
-/*}}}*/
-static void xx_zclose(struct zFile *zf) {/*{{{*/
-  switch (zf->type) {
-#ifdef USE_GZIP_MBOX
-    case COMPRESSION_GZIP:
-      gzclose(zf->foo.gzf);
-      break;
-#endif
-#ifdef USE_BZIP_MBOX
-    case COMPRESSION_BZIP:
-      BZ2_bzclose(zf->foo.bzf);
-      break;
-#endif
-    default:
-      zf->foo.zptr = NULL;
-      break;
-  }
-  free(zf);
-}
-/*}}}*/
-static int xx_zread(struct zFile *zf, void *buf, int len) {/*{{{*/
-  switch (zf->type) {
-#ifdef USE_GZIP_MBOX
-    case COMPRESSION_GZIP:
-      return gzread(zf->foo.gzf, buf, len);
-      break;
-#endif
-#ifdef USE_BZIP_MBOX
-    case COMPRESSION_BZIP:
-      return BZ2_bzread(zf->foo.bzf, buf, len);
-      break;
-#endif
-    default:
-      return 0;
-      break;
-  }
-}
-/*}}}*/
-#endif
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-/* do we need ROCACHE_SIZE > 1? the code supports any number here */
-#define ROCACHE_SIZE 1
-struct ro_mapping {
-  char *filename;
-  unsigned char *map;
-  size_t len;
-};
-static int ro_cache_init = 0;
-static struct ro_mapping ro_mapping_cache[ROCACHE_SIZE];
-
-/* find a temp file in the mapping cache.  If nothing is found lasti is
- * set to the next slot to use for insertion.  You have to check that slot
- * to see if it is currently in use
- */
-static struct ro_mapping *find_ro_cache(const char *filename, int *lasti)
-{
-  int i = 0;
-  struct ro_mapping *ro = NULL;
-  if (lasti)
-    *lasti = 0;
-  if (!ro_cache_init)
-    return NULL;
-  for (i = 0 ; i < ROCACHE_SIZE ; i++) {
-    ro = ro_mapping_cache + i;
-    if (!ro->map) {
-      if (lasti)
-        *lasti = i;
-      return NULL;
-    }
-    if (strcmp(filename, ro->filename) == 0)
-      return ro;
-  }
-  /* if we're here, the map is full.  They will reuse slot 0 */
-  return NULL;
-}
-
-/*
- * put a new tempfile into the cache.  It is mmaped as part of this function
- * so you can safely close the file handle after calling this.
- */
-static struct ro_mapping *add_ro_cache(const char *filename, int fd, size_t len)
-{
-  int i = 0;
-  struct ro_mapping *ro = NULL;
-  if (!ro_cache_init) {
-    memset(&ro_mapping_cache, 0, sizeof(ro_mapping_cache));
-    ro_cache_init = 1;
-  }
-  ro = find_ro_cache(filename, &i);
-  if (ro) {
-    fprintf(stderr, "%s already in ro cache\n", filename);
-    return NULL;
-  }
-  ro = ro_mapping_cache + i;
-  if (ro->map) {
-    munmap(ro->map, ro->len);
-    ro->map = NULL;
-    free(ro->filename);
-  }
-  ro->map = (unsigned char *)mmap(0, len, PROT_READ, MAP_SHARED, fd, 0);
-  if (ro->map == MAP_FAILED) {
-    ro->map = NULL;
-    perror("rfc822:mmap");
-    return NULL;
-  }
-  ro->len = len;
-  ro->filename = new_string(filename);
-  return ro;
-}
-#endif /* USE_GZIP_MBOX || USE_BZIP_MBOX */
-
-void create_ro_mapping(const char *filename, unsigned char **data, int *len)/*{{{*/
-{
-  struct stat sb;
-  int fd;
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-  struct zFile *zf;
-#endif
-
-  if (stat(filename, &sb) < 0)
-  {
-    report_error("stat", filename);
-    *data = NULL;
-    return;
-  }
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-  if(is_compressed(filename)) {
-    unsigned char *p;
-    size_t cur_read;
-    struct ro_mapping *ro;
-    FILE *tmpf;
-
-    /* this branch never returns things that are freeable */
-    data_alloc_type = ALLOC_NONE;
-    ro = find_ro_cache(filename, NULL);
-    if (ro) {
-      *data = ro->map;
-      *len = ro->len;
-      return;
-    }
-
-    if(verbose) {
-      fprintf(stderr, "Decompressing %s...\n", filename);
-    }
-
-    tmpf = tmpfile();
-    if (!tmpf) {
-      perror("tmpfile");
-      goto comp_error;
-    }
-    zf = xx_zopen(filename, "rb");
-    if (!zf) {
-      fprintf(stderr, "Could not open %s\n", filename);
-      goto comp_error;
-    }
-    p = new_array(unsigned char, SIZE_STEP);
-    cur_read = xx_zread(zf, p, SIZE_STEP);
-    if (fwrite(p, cur_read, 1, tmpf) != 1) {
-      fprintf(stderr, "failed writing to temp file for %s\n", filename);
-      goto comp_error;
-    }
-    *len = cur_read;
-    if (cur_read >= SIZE_STEP) {
-      while(1) {
-        int ret;
-        cur_read = xx_zread(zf, p, SIZE_STEP);
-        if (cur_read <= 0)
-          break;
-        *len += cur_read;
-        ret = fwrite(p, cur_read, 1, tmpf);
-        if (ret != 1) {
-          fprintf(stderr, "failed writing to temp file for %s\n", filename);
-          goto comp_error;
-        }
-      }
-    }
-    free(p);
-    xx_zclose(zf);
-
-    if(*len > 0) {
-      ro = add_ro_cache(filename, fileno(tmpf), *len);
-      if (!ro)
-        goto comp_error;
-      *data = ro->map;
-      *len = ro->len;
-    } else {
-      *data = NULL;
-    }
-    fclose(tmpf);
-    return;
-
-comp_error:
-    *data = NULL;
-    *len = 0;
-    if (tmpf)
-      fclose(tmpf);
-    return;
-  }
-#endif /* USE_GZIP_MBOX || USE_BZIP_MBOX */
-
-  *len = sb.st_size;
-  if (*len == 0) {
-    *data = NULL;
-    return;
-  }
-
-  if (!S_ISREG(sb.st_mode)) {
-    *data = NULL;
-    return;
-  }
-
-  fd = open(filename, O_RDONLY);
-  if (fd < 0)
-  {
-    report_error("open", filename);
-    *data = NULL;
-    return;
-  }
-
-  *data = (unsigned char *) mmap(0, *len, PROT_READ, MAP_SHARED, fd, 0);
-  if (close(fd) < 0)
-    report_error("close", filename);
-  if (*data == MAP_FAILED) {
-    report_error("rfc822:mmap", filename);
-    *data = NULL;
-    return;
-  }
-  data_alloc_type = ALLOC_MMAP;
-}
-/*}}}*/
-void free_ro_mapping(unsigned char *data, int len)/*{{{*/
-{
-  int r;
-
-  if(data_alloc_type == ALLOC_MALLOC) {
-    free(data);
-  }
-
-  if(data_alloc_type == ALLOC_MMAP) {
-    r = munmap(data, len);
-    if(r < 0) {
-      fprintf(stderr, "munmap() errord\n");
-      exit(1);
-    }
-  }
-}
-/*}}}*/
-
-static struct msg_src *setup_msg_src(char *filename)/*{{{*/
-{
-  static struct msg_src result;
-  result.type = MS_FILE;
-  result.filename = filename;
-  return &result;
-}
-/*}}}*/
-struct rfc822 *make_rfc822(char *filename)/*{{{*/
-{
-  int len;
-  unsigned char *data;
-  struct rfc822 *result;
-
-  create_ro_mapping(filename, &data, &len);
-
-  /* Don't process empty files */
-  result = NULL;
-
-  if (data)
-  {
-    struct msg_src *src;
-    /* Now process the data */
-    src = setup_msg_src(filename);
-    /* For one message per file, ignore missing end boundary condition. */
-    result = data_to_rfc822(src, (char *) data, len, NULL);
-
-    free_ro_mapping(data, len);
-  }
-
-  return result;
-}
-/*}}}*/
-void free_rfc822(struct rfc822 *msg)/*{{{*/
-{
-  struct attachment *a, *na;
-
-  if (!msg) return;
-
-  if (msg->hdrs.to) free(msg->hdrs.to);
-  if (msg->hdrs.cc) free(msg->hdrs.cc);
-  if (msg->hdrs.from) free(msg->hdrs.from);
-  if (msg->hdrs.subject) free(msg->hdrs.subject);
-  if (msg->hdrs.message_id) free(msg->hdrs.message_id);
-  if (msg->hdrs.in_reply_to) free(msg->hdrs.in_reply_to);
-  if (msg->hdrs.references) free(msg->hdrs.references);
-
-  for (a = msg->atts.next; a != &msg->atts; a = na) {
-    na = a->next;
-    if (a->filename) free(a->filename);
-    if (a->ct == CT_MESSAGE_RFC822) {
-      free_rfc822(a->data.rfc822);
-    } else {
-      free(a->data.normal.bytes);
-    }
-    free(a);
-  }
-  free(msg);
-}
-/*}}}*/
-
-#ifdef TEST
-
-static void do_indent(int indent)/*{{{*/
-{
-  int i;
-  for (i=indent; i>0; i--) {
-    putchar(' ');
-  }
-}
-/*}}}*/
-static void show_header(char *tag, char *x, int indent)/*{{{*/
-{
-  if (x) {
-    do_indent(indent);
-    printf("%s: %s\n", tag, x);
-  }
-}
-/*}}}*/
-static void show_rfc822(struct rfc822 *msg, int indent)/*{{{*/
-{
-  struct attachment *a;
-  show_header("From", msg->hdrs.from, indent);
-  show_header("To", msg->hdrs.to, indent);
-  show_header("Cc", msg->hdrs.cc, indent);
-  show_header("Date", msg->hdrs.date, indent);
-  show_header("Subject", msg->hdrs.subject, indent);
-
-  for (a = msg->atts.next; a != &msg->atts; a=a->next) {
-    printf("========================\n");
-    switch (a->ct) {
-      case CT_TEXT_PLAIN: printf("Attachment type text/plain\n"); break;
-      case CT_TEXT_HTML: printf("Attachment type text/html\n"); break;
-      case CT_TEXT_OTHER: printf("Attachment type text/non-plain\n"); break;
-      case CT_MESSAGE_RFC822: printf("Attachment type message/rfc822\n"); break;
-      case CT_OTHER: printf("Attachment type other\n"); break;
-    }
-    if (a->ct != CT_MESSAGE_RFC822) {
-      printf("%d bytes\n", a->data.normal.len);
-    }
-    if ((a->ct == CT_TEXT_PLAIN) || (a->ct == CT_TEXT_HTML) || (a->ct == CT_TEXT_OTHER)) {
-      printf("----------\n");
-      printf("%s\n", a->data.normal.bytes);
-    }
-    if (a->ct == CT_MESSAGE_RFC822) {
-      show_rfc822(a->data.rfc822, indent + 4);
-    }
-  }
-}
-/*}}}*/
-
-int main (int argc, char **argv)/*{{{*/
-{
-  struct rfc822 *msg;
-
-  if (argc < 2) {
-    fprintf(stderr, "Need a path\n");
-    unlock_and_exit(2);
-  }
-
-  msg = make_rfc822(argv[1]);
-  show_rfc822(msg, 0);
-  free_rfc822(msg);
-
-  /* Print out some stuff */
-
-  return 0;
-}
-/*}}}*/
-#endif /* TEST */
diff --git a/src/mairix/search.c b/src/mairix/search.c
@@ -1,1445 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <assert.h>
-#include <dirent.h>
-#include <errno.h>
-
-/* Lame fix for systems where NAME_MAX isn't defined after including the above
- * set of .h files (Solaris, FreeBSD so far).  Probably grossly oversized but
- * it'll do. */
-
-#if !defined(NAME_MAX)
-#define NAME_MAX 4096
-#endif
-
-#include "mairix.h"
-#include "reader.h"
-#include "memmac.h"
-
-static void mark_hits_in_table(struct read_db *db, struct toktable_db *tt, int hit_tok, char *hits)/*{{{*/
-{
-  /* mark files containing matched token */
-  int idx;
-  unsigned char *j, *first_char;
-  idx = 0;
-  first_char = (unsigned char *) db->data + tt->enc_offsets[hit_tok];
-  for (j = first_char; *j != 0xff; ) {
-    idx += read_increment(&j);
-    assert(idx < db->n_msgs);
-    hits[idx] = 1;
-  }
-}
-/*}}}*/
-static void mark_hits_in_table2(struct read_db *db, struct toktable2_db *tt, int hit_tok, char *hits)/*{{{*/
-{
-  /* mark files containing matched token */
-  int idx;
-  unsigned char *j, *first_char;
-  idx = 0;
-  first_char = (unsigned char *) db->data + tt->enc1_offsets[hit_tok];
-  for (j = first_char; *j != 0xff; ) {
-    idx += read_increment(&j);
-    assert(idx < db->n_msgs);
-    hits[idx] = 1;
-  }
-}
-/*}}}*/
-
-/* See "Fast text searching with errors, Sun Wu and Udi Manber, TR 91-11,
-   University of Arizona.  I have been informed that this algorithm is NOT
-   patented.  This implementation of it is entirely the work of Richard P.
-   Curnow - I haven't looked at any related source (webglimpse, agrep etc) in
-   writing this.
-*/
-static void build_match_vector(char *substring, unsigned long *a, unsigned long *hit)/*{{{*/
-{
-  int len;
-  char *p;
-  int i;
-
-  len = strlen(substring);
-  if (len > 31 || len == 0) {
-    fprintf(stderr, "Can't match patterns longer than 31 characters or empty\n");
-    unlock_and_exit(2);
-  }
-  memset(a, 0xff, 256 * sizeof(unsigned long));
-  for (p=substring, i=0; *p; p++, i++) {
-    a[(unsigned int) *(unsigned char *)p] &= ~(1UL << i);
-  }
-  *hit = ~(1UL << (len-1));
-  return;
-}
-/*}}}*/
-static int substring_match_0(unsigned long *a, unsigned long hit, int left_anchor, char *token)/*{{{*/
-{
-  int got_hit=0;
-  char *p;
-  unsigned long r0;
-  unsigned long anchor, anchor1;
-
-  r0 = ~0;
-  got_hit = 0;
-  anchor = 0;
-  anchor1 = left_anchor ? 0x1 : 0x0;
-  for(p=token; *p; p++) {
-    int idx = (unsigned int) *(unsigned char *)p;
-    r0 = (r0<<1) | anchor | a[idx];
-    if (~(r0 | hit)) {
-      got_hit = 1;
-      break;
-    }
-    anchor = anchor1;
-  }
-  return got_hit;
-}
-/*}}}*/
-static int substring_match_1(unsigned long *a, unsigned long hit, int left_anchor, char *token)/*{{{*/
-{
-  int got_hit=0;
-  char *p;
-  unsigned long r0, r1, nr0;
-  unsigned long anchor, anchor1;
-
-  r0 = ~0;
-  r1 = r0<<1;
-  got_hit = 0;
-  anchor = 0;
-  anchor1 = left_anchor ? 0x1 : 0x0;
-  for(p=token; *p; p++) {
-    int idx = (unsigned int) *(unsigned char *)p;
-    nr0 = (r0<<1) | anchor | a[idx];
-    r1  = ((r1<<1) | anchor | a[idx]) & ((r0 & nr0) << 1) & r0;
-    r0  = nr0;
-    if (~((r0 & r1) | hit)) {
-      got_hit = 1;
-      break;
-    }
-    anchor = anchor1;
-  }
-  return got_hit;
-}
-/*}}}*/
-static int substring_match_2(unsigned long *a, unsigned long hit, int left_anchor, char *token)/*{{{*/
-{
-  int got_hit=0;
-  char *p;
-  unsigned long r0, r1, r2, nr0, nr1;
-  unsigned long anchor, anchor1;
-
-  r0 = ~0;
-  r1 = r0<<1;
-  r2 = r1<<1;
-  got_hit = 0;
-  anchor = 0;
-  anchor1 = left_anchor ? 0x1 : 0x0;
-  for(p=token; *p; p++) {
-    int idx = (unsigned int) *(unsigned char *)p;
-    nr0 =  (r0<<1) | anchor | a[idx];
-    nr1 = ((r1<<1) | anchor | a[idx]) & ((r0 & nr0) << 1) & r0;
-    r2  = ((r2<<1) | anchor | a[idx]) & ((r1 & nr1) << 1) & r1;
-    r0  = nr0;
-    r1  = nr1;
-    if (~((r0 & r1 & r2) | hit)) {
-      got_hit = 1;
-      break;
-    }
-    anchor = anchor1;
-  }
-  return got_hit;
-}
-/*}}}*/
-static int substring_match_3(unsigned long *a, unsigned long hit, int left_anchor, char *token)/*{{{*/
-{
-  int got_hit=0;
-  char *p;
-  unsigned long r0, r1, r2, r3, nr0, nr1, nr2;
-  unsigned long anchor, anchor1;
-
-  r0 = ~0;
-  r1 = r0<<1;
-  r2 = r1<<1;
-  r3 = r2<<1;
-  got_hit = 0;
-  anchor = 0;
-  anchor1 = left_anchor ? 0x1 : 0x0;
-  for(p=token; *p; p++) {
-    int idx = (unsigned int) *(unsigned char *)p;
-    nr0 =  (r0<<1) | anchor | a[idx];
-    nr1 = ((r1<<1) | anchor | a[idx]) & ((r0 & nr0) << 1) & r0;
-    nr2 = ((r2<<1) | anchor | a[idx]) & ((r1 & nr1) << 1) & r1;
-    r3  = ((r3<<1) | anchor | a[idx]) & ((r2 & nr2) << 1) & r2;
-    r0  = nr0;
-    r1  = nr1;
-    r2  = nr2;
-    if (~((r0 & r1 & r2 & r3) | hit)) {
-      got_hit = 1;
-      break;
-    }
-    anchor = anchor1;
-  }
-  return got_hit;
-}
-/*}}}*/
-static int substring_match_general(unsigned long *a, unsigned long hit, int left_anchor, char *token, int max_errors, unsigned long *r, unsigned long *nr)/*{{{*/
-{
-  int got_hit=0;
-  char *p;
-  int j;
-  unsigned long anchor, anchor1;
-
-  r[0] = ~0;
-  anchor = 0;
-  anchor1 = left_anchor ? 0x1 : 0x0;
-  for (j=1; j<=max_errors; j++) {
-    r[j] = r[j-1] << 1;
-  }
-  got_hit = 0;
-  for(p=token; *p; p++) {
-    int idx = (unsigned int) *(unsigned char *)p;
-    int d;
-    unsigned int compo;
-
-    compo = nr[0] = ((r[0]<<1) | anchor | a[idx]);
-    for (d=1; d<=max_errors; d++) {
-      nr[d] = ((r[d]<<1) | anchor | a[idx])
-        & ((r[d-1] & nr[d-1])<<1)
-        & r[d-1];
-      compo &= nr[d];
-    }
-    memcpy(r, nr, (1 + max_errors) * sizeof(unsigned long));
-    if (~(compo | hit)) {
-      got_hit = 1;
-      break;
-    }
-    anchor = anchor1;
-  }
-  return got_hit;
-}
-/*}}}*/
-
-static void match_substring_in_table(struct read_db *db, struct toktable_db *tt, char *substring, int max_errors, int left_anchor, char *hits)/*{{{*/
-{
-
-  int i, got_hit;
-  unsigned long a[256];
-  unsigned long *r=NULL, *nr=NULL;
-  unsigned long hit;
-  char *token;
-
-  build_match_vector(substring, a, &hit);
-
-  got_hit = 0;
-  if (max_errors > 3) {
-    r = new_array(unsigned long, 1 + max_errors);
-    nr = new_array(unsigned long, 1 + max_errors);
-  }
-  for (i=0; i<tt->n; i++) {
-    token = db->data + tt->tok_offsets[i];
-    switch (max_errors) {
-      /* Optimise common cases for few errors to allow optimizer to keep bitmaps
-       * in registers */
-      case 0:
-        got_hit = substring_match_0(a, hit, left_anchor, token);
-        break;
-      case 1:
-        got_hit = substring_match_1(a, hit, left_anchor, token);
-        break;
-      case 2:
-        got_hit = substring_match_2(a, hit, left_anchor, token);
-        break;
-      case 3:
-        got_hit = substring_match_3(a, hit, left_anchor, token);
-        break;
-      default:
-        got_hit = substring_match_general(a, hit, left_anchor, token, max_errors, r, nr);
-        break;
-    }
-    if (got_hit) {
-      mark_hits_in_table(db, tt, i, hits);
-    }
-  }
-  if (r)  free(r);
-  if (nr) free(nr);
-}
-/*}}}*/
-static void match_substring_in_paths(struct read_db *db, char *substring, int max_errors, int left_anchor, char *hits)/*{{{*/
-{
-
-  int i;
-  unsigned long a[256];
-  unsigned long *r=NULL, *nr=NULL;
-  unsigned long hit;
-
-  build_match_vector(substring, a, &hit);
-
-  if (max_errors > 3) {
-    r = new_array(unsigned long, 1 + max_errors);
-    nr = new_array(unsigned long, 1 + max_errors);
-  }
-  for (i=0; i<db->n_msgs; i++) {
-    char *token = NULL;
-    unsigned int mbix, msgix;
-    switch (rd_msg_type(db, i)) {
-      case DB_MSG_FILE:
-        token = db->data + db->path_offsets[i];
-        break;
-      case DB_MSG_MBOX:
-        decode_mbox_indices(db->path_offsets[i], &mbix, &msgix);
-        token = db->data + db->mbox_paths_table[mbix];
-        break;
-      case DB_MSG_DEAD:
-        hits[i] = 0; /* never match on dead paths */
-        goto next_message;
-    }
-
-    assert(token);
-
-    switch (max_errors) {
-      /* Optimise common cases for few errors to allow optimizer to keep bitmaps
-       * in registers */
-      case 0:
-        hits[i] = substring_match_0(a, hit, left_anchor, token);
-        break;
-      case 1:
-        hits[i] = substring_match_1(a, hit, left_anchor, token);
-        break;
-      case 2:
-        hits[i] = substring_match_2(a, hit, left_anchor, token);
-        break;
-      case 3:
-        hits[i] = substring_match_3(a, hit, left_anchor, token);
-        break;
-      default:
-        hits[i] = substring_match_general(a, hit, left_anchor, token, max_errors, r, nr);
-        break;
-    }
-next_message:
-    (void) 0;
-  }
-
-  if (r)  free(r);
-  if (nr) free(nr);
-}
-/*}}}*/
-static void match_string_in_table(struct read_db *db, struct toktable_db *tt, char *key, char *hits)/*{{{*/
-{
-  /* TODO : replace with binary search? */
-  int i;
-
-  for (i=0; i<tt->n; i++) {
-    if (!strcmp(key, db->data + tt->tok_offsets[i])) {
-      /* get all matching files */
-      mark_hits_in_table(db, tt, i, hits);
-    }
-  }
-}
-/*}}}*/
-static void match_string_in_table2(struct read_db *db, struct toktable2_db *tt, char *key, char *hits)/*{{{*/
-{
-  /* TODO : replace with binary search? */
-  int i;
-
-  for (i=0; i<tt->n; i++) {
-    if (!strcmp(key, db->data + tt->tok_offsets[i])) {
-      /* get all matching files */
-      mark_hits_in_table2(db, tt, i, hits);
-    }
-  }
-}
-/*}}}*/
-static int parse_size_expr(char *x)/*{{{*/
-{
-  int result;
-  int n;
-
-  if (1 == sscanf(x, "%d%n", &result, &n)) {
-    x += n;
-    switch (*x) {
-      case 'k':
-      case 'K':
-        result <<= 10;
-        break;
-      case 'm':
-      case 'M':
-        result <<= 20;
-        break;
-      default:
-        break;
-    }
-
-    return result;
-  } else {
-    fprintf(stderr, "Could not parse message size expression <%s>\n", x);
-    return -1;
-  }
-}
-/*}}}*/
-static void parse_size_range(char *size_expr, int *has_start, int *start, int *has_end, int *end)/*{{{*/
-{
-  char *x = size_expr;
-  char *dash;
-  int len;
-
-  if (*x == ':') x++;
-  len = strlen(x);
-  dash = strchr(x, '-');
-  *has_start = *has_end = 0;
-  if (dash) {
-    char *p, *q;
-    if (dash > x) {
-      char *s;
-      s = new_array(char, dash - x + 1);
-      for (p=s, q=x; q<dash; ) *p++ = *q++;
-      *p = 0;
-      *start = parse_size_expr(s);
-      *has_start = 1;
-      free(s);
-    }
-    if (dash[1]) { /* dash not at end of arg */
-      char *e;
-      e = new_array(char, (x + len) - dash);
-      for (p=e, q=dash+1; *q; ) *p++ = *q++;
-      *p = 0;
-      *end = parse_size_expr(e);
-      *has_end = 1;
-      free(e);
-    }
-  } else {
-    *has_start = 0;
-    *end = parse_size_expr(size_expr);
-    *has_end = 1;
-  }
-  return;
-}
-/*}}}*/
-static void find_size_matches_in_table(struct read_db *db, char *size_expr, char *hits)/*{{{*/
-{
-  int start, end;
-  int has_start, has_end, start_cond, end_cond;
-  int i;
-
-  start = end = -1; /* avoid compiler warning about uninitialised variables. */
-  parse_size_range(size_expr, &has_start, &start, &has_end, &end);
-  if (has_start && has_end) {
-    /* Allow user to put the endpoints in backwards */
-    if (start > end) {
-      int temp = start;
-      start = end;
-      end = temp;
-    }
-  }
-
-  for (i=0; i<db->n_msgs; i++) {
-    start_cond = has_start ? (db->size_table[i] > start) : 1;
-    end_cond   = has_end   ? (db->size_table[i] < end  ) : 1;
-    if (start_cond && end_cond) {
-      hits[i] = 1;
-    }
-  }
-}
-/*}}}*/
-static void find_date_matches_in_table(struct read_db *db, char *date_expr, char *hits)/*{{{*/
-{
-  time_t start, end;
-  int has_start, has_end, start_cond, end_cond;
-  int i;
-  int status;
-
-  status = scan_date_string(date_expr, &start, &has_start, &end, &has_end);
-  if (status) {
-    unlock_and_exit (2);
-  }
-
-  if (has_start && has_end) {
-    /* Allow user to put the endpoints in backwards */
-    if (start > end) {
-      time_t temp = start;
-      start = end;
-      end = temp;
-    }
-  }
-
-  for (i=0; i<db->n_msgs; i++) {
-    start_cond = has_start ? (db->date_table[i] > start) : 1;
-    end_cond   = has_end   ? (db->date_table[i] < end  ) : 1;
-    if (start_cond && end_cond) {
-      hits[i] = 1;
-    }
-  }
-}
-/*}}}*/
-static void find_flag_matches_in_table(struct read_db *db, char *flag_expr, char *hits)/*{{{*/
-{
-  int pos_seen, neg_seen;
-  int pos_replied, neg_replied;
-  int pos_flagged, neg_flagged;
-  int negate;
-  char *p;
-  int i;
-
-  negate = 0;
-  pos_seen = neg_seen = 0;
-  pos_replied = neg_replied = 0;
-  pos_flagged = neg_flagged = 0;
-  for (p=flag_expr; *p; p++) {
-    switch (*p) {
-      case '-':
-        negate = 1;
-        break;
-      case 's':
-      case 'S':
-        if (negate) neg_seen = 1;
-        else pos_seen = 1;
-        negate = 0;
-        break;
-      case 'r':
-      case 'R':
-        if (negate) neg_replied = 1;
-        else pos_replied = 1;
-        negate = 0;
-        break;
-      case 'f':
-      case 'F':
-        if (negate) neg_flagged = 1;
-        else pos_flagged = 1;
-        negate = 0;
-        break;
-      default:
-        fprintf(stderr, "Did not understand the character '%c' (0x%02x) in the flags argument F:%s\n",
-            isprint(*p) ? *p : '.',
-            (int) *(unsigned char *) p,
-            flag_expr);
-        break;
-    }
-  }
-
-  for (i=0; i<db->n_msgs; i++) {
-    if ((!pos_seen || (db->msg_type_and_flags[i] & FLAG_SEEN)) &&
-        (!neg_seen || !(db->msg_type_and_flags[i] & FLAG_SEEN)) &&
-        (!pos_replied || (db->msg_type_and_flags[i] & FLAG_REPLIED)) &&
-        (!neg_replied || !(db->msg_type_and_flags[i] & FLAG_REPLIED)) &&
-        (!pos_flagged || (db->msg_type_and_flags[i] & FLAG_FLAGGED)) &&
-        (!neg_flagged || !(db->msg_type_and_flags[i] & FLAG_FLAGGED))) {
-      hits[i] = 1;
-    }
-  }
-}
-/*}}}*/
-
-static char *mk_maildir_path(int token, char *output_dir, int is_in_new,
-    int is_seen, int is_replied, int is_flagged)/*{{{*/
-{
-  char *result;
-  char uniq_buf[48];
-  int len;
-
-  len = strlen(output_dir) + 64; /* oversize */
-  result = new_array(char, len + 1 + sizeof(":2,FRS"));
-  strcpy(result, output_dir);
-  strcat(result, is_in_new ? "/new/" : "/cur/");
-  sprintf(uniq_buf, "123456789.%d.mairix", token);
-  strcat(result, uniq_buf);
-  if (is_seen || is_replied || is_flagged) {
-    strcat(result, ":2,");
-  }
-  if (is_flagged) strcat(result, "F");
-  if (is_replied) strcat(result, "R");
-  if (is_seen) strcat(result, "S");
-  return result;
-}
-/*}}}*/
-static char *mk_mh_path(int token, char *output_dir)/*{{{*/
-{
-  char *result;
-  char uniq_buf[8];
-  int len;
-
-  len = strlen(output_dir) + 10; /* oversize */
-  result = new_array(char, len);
-  strcpy(result, output_dir);
-  strcat(result, "/");
-  sprintf(uniq_buf, "%d", token+1);
-  strcat(result, uniq_buf);
-  return result;
-}
-/*}}}*/
-static int looks_like_maildir_new_p(const char *p)/*{{{*/
-{
-  const char *s1, *s2;
-  s2 = p;
-  while (*s2) s2++;
-  while ((s2 > p) && (*s2 != '/')) s2--;
-  if (s2 <= p) return 0;
-  s1 = s2 - 1;
-  while ((s1 > p) && (*s1 != '/')) s1--;
-  if (s1 <= p) return 0;
-  if (!strncmp(s1, "/new/", 5)) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-/*}}}*/
-static void create_symlink(char *link_target, char *new_link)/*{{{*/
-{
-  // added possibility to move files (delete origin)
-  if (do_movefiles>0) {
-    if( rename(link_target, new_link) != 0) {
-      if (verbose) {
-	perror("rename");
-	fprintf(stderr, "Failed rename <%s> -> <%s>\n", link_target, new_link);
-      }
-    }
-
-  } else if ((!do_hardlinks && symlink(link_target, new_link) < 0) || link(link_target, new_link)) {
-    if (verbose) {
-      perror("symlink");
-      fprintf(stderr, "Failed path <%s> -> <%s>\n", link_target, new_link);
-    }
-  }
-}
-/*}}}*/
-static void mbox_terminate(const unsigned char *data, int len, FILE *out)/*{{{*/
-{
-  if (len == 0)
-    fputs("\n", out);
-  else if (len == 1) {
-    if (data[0] != '\n')
-      fputs("\n", out);
-  }
-  else if (data[len-1] != '\n')
-    fputs("\n\n", out);
-  else if (data[len-2] != '\n')
-    fputs("\n", out);
-}
-/*}}}*/
-static void append_file_to_mbox(const char *path, FILE *out)/*{{{*/
-{
-  unsigned char *data;
-  int len;
-  create_ro_mapping(path, &data, &len);
-  if (data) {
-    fprintf(out, "From mairix@mairix Mon Jan  1 12:34:56 1970\n");
-    fprintf(out, "X-source-folder: %s\n", path);
-    fwrite (data, sizeof(unsigned char), len, out);
-    mbox_terminate(data, len, out);
-    free_ro_mapping(data, len);
-  }
-  return;
-}
-/*}}}*/
-
-static int had_failed_checksum;
-
-static void get_validated_mbox_msg(struct read_db *db, int msg_index,/*{{{*/
-                                   int *mbox_index,
-                                   unsigned char **mbox_data, int *mbox_len,
-                                   unsigned char **msg_data,  int *msg_len)
-{
-  /* msg_data==NULL if checksum mismatches */
-  unsigned char *start;
-  checksum_t csum;
-  unsigned int mbi, msgi;
-
-  *msg_data = NULL;
-  *msg_len = 0;
-
-  decode_mbox_indices(db->path_offsets[msg_index], &mbi, &msgi);
-  *mbox_index = mbi;
-
-  create_ro_mapping(db->data + db->mbox_paths_table[mbi], mbox_data, mbox_len);
-  if (!*mbox_data) return;
-
-  start = *mbox_data + db->mtime_table[msg_index];
-
-  /* Ensure that we don't run off the end of the mmap'd file */
-  if (db->mtime_table[msg_index] >= *mbox_len)
-    *msg_len = 0;
-  else if (db->mtime_table[msg_index] + db->size_table[msg_index] >= *mbox_len)
-    *msg_len = *mbox_len - db->mtime_table[msg_index];
-  else
-    *msg_len = db->size_table[msg_index];
-
-  compute_checksum((char *)start, *msg_len, &csum);
-  if (!memcmp((db->data + db->mbox_checksum_table[mbi] + (msgi * sizeof(checksum_t))), &csum, sizeof(checksum_t))) {
-    *msg_data = start;
-  } else {
-    had_failed_checksum = 1;
-  }
-  return;
-}
-/*}}}*/
-static void append_mboxmsg_to_mbox(struct read_db *db, int msg_index, FILE *out)/*{{{*/
-{
-  /* Need to common up code with try_copy_to_path */
-  unsigned char *mbox_start, *msg_start;
-  int mbox_len, msg_len;
-  int mbox_index;
-
-  get_validated_mbox_msg(db, msg_index, &mbox_index, &mbox_start, &mbox_len, &msg_start, &msg_len);
-  if (msg_start) {
-    /* Artificial from line, we don't have the envelope sender so this is
-       going to be artificial anyway. */
-    fprintf(out, "From mairix@mairix Mon Jan  1 12:34:56 1970\n");
-    fprintf(out, "X-source-folder: %s\n",
-            db->data + db->mbox_paths_table[mbox_index]);
-    fwrite(msg_start, sizeof(unsigned char), msg_len, out);
-    mbox_terminate(msg_start, msg_len, out);
-  }
-  if (mbox_start) {
-    free_ro_mapping(mbox_start, mbox_len);
-  }
-}
-/*}}}*/
-static void try_copy_to_path(struct read_db *db, int msg_index, char *target_path)/*{{{*/
-{
-  unsigned char *data;
-  int mbox_len, msg_len;
-  int mbi;
-  FILE *out;
-  unsigned char *start;
-
-  get_validated_mbox_msg(db, msg_index, &mbi, &data, &mbox_len, &start, &msg_len);
-
-  if (start) {
-    out = fopen(target_path, "wb");
-    if (out) {
-      fprintf(out, "X-source-folder: %s\n",
-              db->data + db->mbox_paths_table[mbi]);
-      fwrite(start, sizeof(char), msg_len?msg_len-1:0, out);
-      fclose(out);
-    }
-  }
-
-  if (data) {
-    free_ro_mapping(data, mbox_len);
-  }
-  return;
-}
-/*}}}*/
-static struct msg_src *setup_mbox_msg_src(char *filename, off_t start, size_t len)/*{{{*/
-{
-  static struct msg_src result;
-  result.type = MS_MBOX;
-  result.filename = filename;
-  result.start = start;
-  result.len = len;
-  return &result;
-}
-/*}}}*/
-
-static void get_flags_from_file(struct read_db *db, int idx, int *is_seen, int *is_replied, int *is_flagged)
-{
-  *is_seen = (db->msg_type_and_flags[idx] & FLAG_SEEN) ? 1 : 0;
-  *is_replied = (db->msg_type_and_flags[idx] & FLAG_REPLIED) ? 1 : 0;
-  *is_flagged = (db->msg_type_and_flags[idx] & FLAG_FLAGGED) ? 1 : 0;
-}
-
-static void string_tolower(char *str)
-{
-  char *p;
-  for (p=str; *p; p++) {
-    *p = tolower(*(unsigned char *)p);
-  }
-}
-
-static int do_search(struct read_db *db, char **args, char *output_path, int show_threads, enum folder_type ft, int verbose)/*{{{*/
-{
-  char *colon, *start_words;
-  int do_body, do_subject, do_from, do_to, do_cc, do_date, do_size;
-  int do_att_name;
-  int do_flags;
-  int do_path, do_msgid;
-  char *key;
-  char *hit0, *hit1, *hit2, *hit3;
-  int i;
-  int n_hits;
-  int left_anchor;
-
-  had_failed_checksum = 0;
-
-  hit0 = new_array(char, db->n_msgs);
-  hit1 = new_array(char, db->n_msgs);
-  hit2 = new_array(char, db->n_msgs);
-  hit3 = new_array(char, db->n_msgs);
-
-  /* Argument structure is
-   * x:tokena+tokenb,~tokenc,tokend+tokene
-   *
-   * + (and) binds more tightly than ,
-   * , (or)  binds more tightly than separate args
-   *
-   *
-   * hit1 gathers the tokens and'ed with +
-   * hit2 gathers the tokens  or'ed with ,
-   * hit3 gathers the separate args and'ed with <gap>
-   * */
-
-
-  /* Everything matches until proven otherwise */
-  memset(hit3, 1, db->n_msgs);
-
-  while (*args) {
-    /* key is a single argument, separate args are and-ed together */
-    key = *args++;
-
-    memset(hit2, 0, db->n_msgs);
-    memset(hit1, 1, db->n_msgs);
-
-    do_to = 0;
-    do_cc = 0;
-    do_from = 0;
-    do_subject = 0;
-    do_body = 0;
-    do_date = 0;
-    do_size = 0;
-    do_path = 0;
-    do_msgid = 0;
-    do_att_name = 0;
-    do_flags = 0;
-
-    colon = strchr(key, ':');
-
-    if (colon) {
-      char *p;
-      for (p=key; p<colon; p++) {
-        switch(*p) {
-          case 'b': do_body = 1; break;
-          case 's': do_subject = 1; break;
-          case 't': do_to = 1; break;
-          case 'c': do_cc = 1; break;
-          case 'f': do_from = 1; break;
-          case 'r': do_to = do_cc = 1; break;
-          case 'a': do_to = do_cc = do_from = 1; break;
-          case 'd': do_date = 1; break;
-          case 'z': do_size = 1; break;
-          case 'p': do_path = 1; break;
-          case 'm': do_msgid = 1; break;
-          case 'n': do_att_name = 1; break;
-          case 'F': do_flags = 1; break;
-          default: fprintf(stderr, "Unknown key type <%c>\n", *p); break;
-        }
-      }
-      if (do_msgid && (p-key) > 1) {
-        fprintf(stderr, "Message-ID key <m> can't be used with other keys\n");
-        unlock_and_exit(2);
-      }
-      start_words = 1 + colon;
-    } else {
-      do_body = do_subject = do_to = do_cc = do_from = 1;
-      start_words = key;
-    }
-
-    if (do_date || do_size || do_flags) {
-      memset(hit0, 0, db->n_msgs);
-      if (do_date) {
-        find_date_matches_in_table(db, start_words, hit0);
-      } else if (do_size) {
-        find_size_matches_in_table(db, start_words, hit0);
-      } else if (do_flags) {
-        find_flag_matches_in_table(db, start_words, hit0);
-      }
-
-      /* AND-combine match vectors */
-      for (i=0; i<db->n_msgs; i++) {
-        hit1[i] &= hit0[i];
-      }
-    } else if (do_msgid) {
-      char *lower_word = new_string(start_words);
-      string_tolower(lower_word);
-      memset(hit0, 0, db->n_msgs);
-      match_string_in_table2(db, &db->msg_ids, lower_word, hit0);
-      free(lower_word);
-      /* AND-combine match vectors */
-      for (i=0; i<db->n_msgs; i++) {
-        hit1[i] &= hit0[i];
-      }
-    } else {
-/*{{{  Scan over separate words within this argument */
-
-    do {
-      /* / = 'or' separator
-       * , = 'and' separator */
-      char *orsep;
-      char *andsep;
-      char *word, *orig_word, *lower_word;
-      char *equal;
-      int negate;
-      int had_orsep;
-      int max_errors;
-
-      orsep = strchr(start_words, '/');
-      andsep  = strchr(start_words, ',');
-      had_orsep = 0;
-
-      if (andsep && (!orsep || (andsep < orsep))) {
-        char *p, *q;
-        word = new_array(char, 1 + (andsep - start_words)); /* maybe oversize */
-        for (p=word, q=start_words; q < andsep; q++) {
-          if (!isspace(*(unsigned char *)q)) {
-            *p++ = *q;
-          }
-        }
-        *p = 0;
-        start_words = andsep + 1;
-      } else if (orsep) { /* comes before + if there's a + */
-        char *p, *q;
-        word = new_array(char, 1 + (orsep - start_words)); /* maybe oversize */
-        for (p=word, q=start_words; q < orsep; q++) {
-          if (!isspace(*(unsigned char *)q)) {
-            *p++ = *q;
-          }
-        }
-        *p = 0;
-        start_words = orsep + 1;
-        had_orsep = 1;
-
-      } else {
-        word = new_string(start_words);
-        while (*start_words) ++start_words;
-      }
-
-      orig_word = word;
-
-      if (word[0] == '~') {
-        negate = 1;
-        word++;
-      } else {
-        negate = 0;
-      }
-
-      if (word[0] == '^') {
-        left_anchor = 1;
-        word++;
-      } else {
-        left_anchor = 0;
-      }
-
-      equal = strchr(word, '=');
-      if (equal) {
-        *equal = 0;
-        max_errors = atoi(equal + 1);
-        /* Extend this to do anchoring etc */
-      } else {
-        max_errors = 0; /* keep GCC quiet */
-      }
-
-      /* Canonicalise search string to lowercase, since the database has all
-       * tokens handled that way.  But not for path search! */
-      lower_word = new_string(word);
-      string_tolower(lower_word);
-
-      memset(hit0, 0, db->n_msgs);
-      if (equal) {
-        if (do_to) match_substring_in_table(db, &db->to, lower_word, max_errors, left_anchor, hit0);
-        if (do_cc) match_substring_in_table(db, &db->cc, lower_word, max_errors, left_anchor, hit0);
-        if (do_from) match_substring_in_table(db, &db->from, lower_word, max_errors, left_anchor, hit0);
-        if (do_subject) match_substring_in_table(db, &db->subject, lower_word, max_errors, left_anchor, hit0);
-        if (do_body) match_substring_in_table(db, &db->body, lower_word, max_errors, left_anchor, hit0);
-        if (do_att_name) match_substring_in_table(db, &db->attachment_name, lower_word, max_errors, left_anchor, hit0);
-        if (do_path) match_substring_in_paths(db, word, max_errors, left_anchor, hit0);
-      } else {
-        if (do_to) match_string_in_table(db, &db->to, lower_word, hit0);
-        if (do_cc) match_string_in_table(db, &db->cc, lower_word, hit0);
-        if (do_from) match_string_in_table(db, &db->from, lower_word, hit0);
-        if (do_subject) match_string_in_table(db, &db->subject, lower_word, hit0);
-        if (do_body) match_string_in_table(db, &db->body, lower_word, hit0);
-        if (do_att_name) match_string_in_table(db, &db->attachment_name, lower_word, hit0);
-        /* FIXME */
-        if (do_path) match_substring_in_paths(db, word, 0, left_anchor, hit0);
-      }
-
-      free(lower_word);
-
-      /* AND-combine match vectors */
-      for (i=0; i<db->n_msgs; i++) {
-        if (negate) {
-          hit1[i] &= !hit0[i];
-        } else {
-          hit1[i] &= hit0[i];
-        }
-      }
-
-      if (had_orsep) {
-        /* OR-combine match vectors */
-        for (i=0; i<db->n_msgs; i++) {
-          hit2[i] |= hit1[i];
-        }
-        memset(hit1, 1, db->n_msgs);
-      }
-
-      free(orig_word);
-
-    } while (*start_words);
-/*}}}*/
-    }
-
-    /* OR-combine match vectors */
-    for (i=0; i<db->n_msgs; i++) {
-      hit2[i] |= hit1[i];
-    }
-
-    /* AND-combine match vectors */
-    for (i=0; i<db->n_msgs; i++) {
-      hit3[i] &= hit2[i];
-    }
-  }
-
-  n_hits = 0;
-
-  if (show_threads) {/*{{{*/
-    char *tids;
-    tids = new_array(char, db->n_msgs);
-    memset(tids, 0, db->n_msgs);
-    for (i=0; i<db->n_msgs; i++) {
-      if (hit3[i]) {
-        tids[db->tid_table[i]] = 1;
-      }
-    }
-    for (i=0; i<db->n_msgs; i++) {
-      if (tids[db->tid_table[i]]) {
-        hit3[i] = 1;
-      }
-    }
-    free(tids);
-  }
-/*}}}*/
-  switch (ft) {
-    case FT_MAILDIR:/*{{{*/
-      for (i=0; i<db->n_msgs; i++) {
-        if (hit3[i]) {
-          int is_seen, is_replied, is_flagged;
-          get_flags_from_file(db, i, &is_seen, &is_replied, &is_flagged);
-          switch (rd_msg_type(db, i)) {
-            case DB_MSG_FILE:
-              {
-                char *target_path;
-                char *message_path;
-                int is_in_new;
-                message_path = db->data + db->path_offsets[i];
-                is_in_new = looks_like_maildir_new_p(message_path);
-                target_path = mk_maildir_path(i, output_path, is_in_new, is_seen, is_replied, is_flagged);
-                create_symlink(message_path, target_path);
-                free(target_path);
-                ++n_hits;
-              }
-              break;
-            case DB_MSG_MBOX:
-              {
-                char *target_path = mk_maildir_path(i, output_path, !is_seen, is_seen, is_replied, is_flagged);
-                try_copy_to_path(db, i, target_path);
-                free(target_path);
-                ++n_hits;
-              }
-              break;
-            case DB_MSG_DEAD:
-              break;
-          }
-        }
-      }
-      break;
-/*}}}*/
-    case FT_MH:/*{{{*/
-      for (i=0; i<db->n_msgs; i++) {
-        if (hit3[i]) {
-          switch (rd_msg_type(db, i)) {
-            case DB_MSG_FILE:
-              {
-                char *target_path = mk_mh_path(i, output_path);
-                create_symlink(db->data + db->path_offsets[i], target_path);
-                free(target_path);
-                ++n_hits;
-              }
-              break;
-            case DB_MSG_MBOX:
-              {
-                char *target_path = mk_mh_path(i, output_path);
-                try_copy_to_path(db, i, target_path);
-                free(target_path);
-                ++n_hits;
-              }
-              break;
-            case DB_MSG_DEAD:
-              break;
-          }
-        }
-      }
-      break;
-/*}}}*/
-    case FT_MBOX:/*{{{*/
-      {
-        FILE *out;
-        out = fopen(output_path, "ab");
-        if (!out) {
-          fprintf(stderr, "Cannot open output folder %s\n", output_path);
-          unlock_and_exit(1);
-        }
-
-        for (i=0; i<db->n_msgs; i++) {
-          if (hit3[i]) {
-            switch (rd_msg_type(db, i)) {
-              case DB_MSG_FILE:
-                {
-                  append_file_to_mbox(db->data + db->path_offsets[i], out);
-                  ++n_hits;
-                }
-                break;
-              case DB_MSG_MBOX:
-                {
-                  append_mboxmsg_to_mbox(db, i, out);
-                  ++n_hits;
-                }
-                break;
-              case DB_MSG_DEAD:
-                break;
-            }
-          }
-        }
-        fclose(out);
-      }
-
-      break;
-/*}}}*/
-    case FT_RAW:/*{{{*/
-      for (i=0; i<db->n_msgs; i++) {
-        if (hit3[i]) {
-          switch (rd_msg_type(db, i)) {
-            case DB_MSG_FILE:
-              {
-                ++n_hits;
-                printf("%s\n", db->data + db->path_offsets[i]);
-              }
-              break;
-            case DB_MSG_MBOX:
-              {
-                unsigned int mbix, msgix;
-                int start, len, after_end;
-                start = db->mtime_table[i];
-                len   = db->size_table[i];
-                after_end = start + len;
-                ++n_hits;
-                decode_mbox_indices(db->path_offsets[i], &mbix, &msgix);
-                printf("mbox:%s [%d,%d)\n", db->data + db->mbox_paths_table[mbix], start, after_end);
-              }
-              break;
-            case DB_MSG_DEAD:
-              break;
-          }
-        }
-      }
-      break;
-/*}}}*/
-    case FT_EXCERPT:/*{{{*/
-      for (i=0; i<db->n_msgs; i++) {
-        if (hit3[i]) {
-          struct rfc822 *parsed = NULL;
-          switch (rd_msg_type(db, i)) {
-            case DB_MSG_FILE:
-              {
-                char *filename;
-                ++n_hits;
-                printf("---------------------------------\n");
-                filename = db->data + db->path_offsets[i];
-                printf("%s\n", filename);
-                parsed = make_rfc822(filename);
-              }
-              break;
-            case DB_MSG_MBOX:
-              {
-                unsigned int mbix, msgix;
-                int start, len, after_end;
-                unsigned char *mbox_start, *msg_start;
-                int mbox_len, msg_len;
-                int mbox_index;
-
-                start = db->mtime_table[i];
-                len   = db->size_table[i];
-                after_end = start + len;
-                ++n_hits;
-                printf("---------------------------------\n");
-                decode_mbox_indices(db->path_offsets[i], &mbix, &msgix);
-                printf("mbox:%s [%d,%d)\n", db->data + db->mbox_paths_table[mbix], start, after_end);
-
-                get_validated_mbox_msg(db, i, &mbox_index, &mbox_start, &mbox_len, &msg_start, &msg_len);
-                if (msg_start) {
-                  enum data_to_rfc822_error error;
-                  struct msg_src *msg_src;
-                  msg_src = setup_mbox_msg_src(db->data + db->mbox_paths_table[mbix], start, msg_len);
-                  parsed = data_to_rfc822(msg_src, (char *) msg_start, msg_len, &error);
-                }
-                if (mbox_start) {
-                  free_ro_mapping(mbox_start, mbox_len);
-                }
-              }
-              break;
-            case DB_MSG_DEAD:
-              break;
-          }
-
-          if (parsed) {
-            char datebuf[64];
-            struct tm *thetm;
-            if (parsed->hdrs.to)      printf("  To:         %s\n", parsed->hdrs.to);
-            if (parsed->hdrs.cc)      printf("  Cc:         %s\n", parsed->hdrs.cc);
-            if (parsed->hdrs.from)    printf("  From:       %s\n", parsed->hdrs.from);
-            if (parsed->hdrs.subject) printf("  Subject:    %s\n", parsed->hdrs.subject);
-            if (parsed->hdrs.message_id)
-                                      printf("  Message-ID: %s\n", parsed->hdrs.message_id);
-            thetm = gmtime(&parsed->hdrs.date);
-            strftime(datebuf, sizeof(datebuf), "%a, %d %b %Y", thetm);
-            printf("  Date:        %s\n", datebuf);
-            free_rfc822(parsed);
-          }
-        }
-      }
-      break;
-/*}}}*/
-    default:
-      assert(0);
-      break;
-  }
-
-  free(hit0);
-  free(hit1);
-  free(hit2);
-  free(hit3);
-  if ((ft != FT_RAW) && (ft != FT_EXCERPT)) {
-    printf("Matched %d messages\n", n_hits);
-  }
-  fflush(stdout);
-
-  if (had_failed_checksum) {
-    fprintf(stderr,
-            "WARNING : \n"
-            "Matches were found in mbox folders but the message checksums failed.\n"
-            "You may need to run mairix in indexing mode then repeat your search.\n");
-  }
-
-  /* Return error code 1 to the shell if no messages were matched. */
-  return (n_hits == 0) ? 1 : 0;
-}
-/*}}}*/
-
-static int directory_exists_remove_other(char *name)/*{{{*/
-{
-  struct stat sb;
-
-  if (stat(name, &sb) < 0) {
-    return 0;
-  }
-  if (S_ISDIR(sb.st_mode)) {
-    return 1;
-  } else {
-    /* Try to remove. */
-    unlink(name);
-    return 0;
-  }
-}
-/*}}}*/
-static void create_dir(char *path)/*{{{*/
-{
-  if (mkdir(path, 0700) < 0) {
-    fprintf(stderr, "Could not create directory %s\n", path);
-    unlock_and_exit(2);
-  }
-  fprintf(stderr, "Created directory %s\n", path);
-  return;
-}
-/*}}}*/
-static void maybe_create_maildir(char *path)/*{{{*/
-{
-  char *subdir, *tailpos;
-  int len;
-
-  if (!directory_exists_remove_other(path)) {
-    create_dir(path);
-  }
-
-  len = strlen(path);
-  subdir = new_array(char, len + 5);
-  strcpy(subdir, path);
-  strcpy(subdir+len, "/");
-  tailpos = subdir + len + 1;
-
-  strcpy(tailpos,"cur");
-  if (!directory_exists_remove_other(subdir)) {
-    create_dir(subdir);
-  }
-  strcpy(tailpos,"new");
-  if (!directory_exists_remove_other(subdir)) {
-    create_dir(subdir);
-  }
-  strcpy(tailpos,"tmp");
-  if (!directory_exists_remove_other(subdir)) {
-    create_dir(subdir);
-  }
-  free(subdir);
-  return;
-}
-/*}}}*/
-static void clear_maildir_subfolder(char *path, char *subdir)/*{{{*/
-{
-  char *sdir;
-  char *fpath;
-  int len;
-  DIR *d;
-  struct dirent *de;
-  struct stat sb;
-
-  len = strlen(path) + strlen(subdir);
-
-  sdir = new_array(char, len + 2);
-  fpath = new_array(char, len + 3 + NAME_MAX);
-  strcpy(sdir, path);
-  strcat(sdir, "/");
-  strcat(sdir, subdir);
-
-  d = opendir(sdir);
-  if (d) {
-    while ((de = readdir(d))) {
-      strcpy(fpath, sdir);
-      strcat(fpath, "/");
-      strcat(fpath, de->d_name);
-      if (lstat(fpath, &sb) >= 0) {
-        /* Deal with both symlinks to maildir/MH messages as well as real files
-         * where mbox messages have been written. */
-        if (S_ISLNK(sb.st_mode) || S_ISREG(sb.st_mode)) {
-          /* FIXME : Can you unlink from a directory while doing a readdir loop over it? */
-          if (unlink(fpath) < 0) {
-            fprintf(stderr, "Unlinking %s failed\n", fpath);
-          }
-        }
-      }
-    }
-    closedir(d);
-  }
-
-  free(fpath);
-  free(sdir);
-}
-/*}}}*/
-static void clear_mh_folder(char *path)/*{{{*/
-{
-  char *fpath;
-  int len;
-  DIR *d;
-  struct dirent *de;
-  struct stat sb;
-
-  len = strlen(path);
-
-  fpath = new_array(char, len + 3 + NAME_MAX);
-
-  d = opendir(path);
-  if (d) {
-    while ((de = readdir(d))) {
-      if (valid_mh_filename_p(de->d_name)) {
-        strcpy(fpath, path);
-        strcat(fpath, "/");
-        strcat(fpath, de->d_name);
-        if (lstat(fpath, &sb) >= 0) {
-          /* See under maildir above for explanation */
-          if (S_ISLNK(sb.st_mode) || S_ISREG(sb.st_mode)) {
-            /* FIXME : Can you unlink from a directory while doing a readdir loop over it? */
-            if (unlink(fpath) < 0) {
-              fprintf(stderr, "Unlinking %s failed\n", fpath);
-            }
-          }
-        }
-      }
-    }
-    closedir(d);
-  }
-
-  free(fpath);
-}
-/*}}}*/
-static void clear_mbox_folder(char *path)/*{{{*/
-{
-  unlink(path);
-}
-/*}}}*/
-
-int search_top(int do_threads, int do_augment, char *database_path, char *complete_mfolder, char **argv, enum folder_type ft, int verbose)/*{{{*/
-{
-  struct read_db *db;
-  int result;
-
-  db = open_db(database_path);
-
-  switch (ft) {
-    case FT_MAILDIR:
-      maybe_create_maildir(complete_mfolder);
-      break;
-    case FT_MH:
-      if (!directory_exists_remove_other(complete_mfolder)) {
-        create_dir(complete_mfolder);
-      }
-      break;
-    case FT_MBOX:
-      /* Nothing to do */
-      break;
-    case FT_RAW:
-    case FT_EXCERPT:
-      break;
-    default:
-      assert(0);
-  }
-
-  if (!do_augment) {
-    switch (ft) {
-      case FT_MAILDIR:
-        clear_maildir_subfolder(complete_mfolder, "new");
-        clear_maildir_subfolder(complete_mfolder, "cur");
-        break;
-      case FT_MH:
-        clear_mh_folder(complete_mfolder);
-        break;
-      case FT_MBOX:
-        clear_mbox_folder(complete_mfolder);
-        break;
-      case FT_RAW:
-      case FT_EXCERPT:
-        break;
-      default:
-        assert(0);
-    }
-  }
-
-  result = do_search(db, argv, complete_mfolder, do_threads, ft, verbose);
-  free(complete_mfolder);
-  close_db(db);
-  return result;
-}
-/*}}}*/
-
-
diff --git a/src/mairix/stats.c b/src/mairix/stats.c
@@ -1,128 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002-2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "mairix.h"
-#include "memmac.h"
-#include "reader.h"
-
-static void do_toktable(struct toktable *x, int *lc, int *elc, int *ec, int size, int *ml, int *mel, int *me)
-{
-  int i;
-  for (i=0; i<x->size; i++) {
-    struct token *tok = x->tokens[i];
-    unsigned char *j, *last_char;
-    int incr;
-
-    if (tok) {
-      int len = strlen(tok->text);
-      if (len > size) {
-        fprintf(stderr, "Token length %d exceeds size\n", len);
-      } else {
-        lc[len]++;
-        if (len > *ml) *ml = len;
-      }
-
-      /* Deal with encoding length */
-      if (tok->match0.n > size) {
-        fprintf(stderr, "Token encoding length %d exceeds size\n", tok->match0.n);
-      } else {
-        elc[tok->match0.n]++;
-        if (tok->match0.n > *mel) *mel = tok->match0.n;
-      }
-
-      /* Deal with encoding */
-      j = tok->match0.msginfo;
-      last_char = j + tok->match0.n;
-      while (j < last_char) {
-        incr = read_increment(&j);
-        if (incr > size) {
-          fprintf(stderr, "Encoding increment %d exceeds size\n", incr);
-        } else {
-          ec[incr]++;
-          if (incr > *me) *me = incr;
-        }
-      }
-    }
-  }
-}
-
-void print_table(int *x, int max) {
-  int total, sum;
-  int i;
-  int kk, kk1;
-
-  total = 0;
-  for (i = 0; i<=max; i++) {
-    total += x[i];
-  }
-  sum = 0;
-  kk1 = 0;
-  for (i = 0; i<=max; i++) {
-    sum += x[i];
-    kk = (int)((double)sum*256.0/(double)total);
-    printf("%5d : %5d %3d %3d\n", i, x[i], kk-kk1, kk);
-    kk1 = kk;
-  }
-}
-
-void get_db_stats(struct database *db)
-{
-  /* Deal with paths later - problem is, they will be biased by length of folder_base at the moment. */
-
-  int size = 4096;
-  int *len_counts, *enc_len_counts, *enc_counts;
-  int max_len, max_enc_len, max_enc;
-
-  max_len = 0;
-  max_enc_len = 0;
-  max_enc = 0;
-
-  len_counts = new_array(int, size);
-  memset(len_counts, 0, size * sizeof(int));
-  enc_len_counts = new_array(int, size);
-  memset(enc_len_counts, 0, size * sizeof(int));
-  enc_counts = new_array(int, size);
-  memset(enc_counts, 0, size * sizeof(int));
-
-  do_toktable(db->to, len_counts, enc_len_counts, enc_counts, size, &max_len, &max_enc_len, &max_enc);
-  do_toktable(db->cc, len_counts, enc_len_counts, enc_counts, size, &max_len, &max_enc_len, &max_enc);
-  do_toktable(db->from, len_counts, enc_len_counts, enc_counts, size, &max_len, &max_enc_len, &max_enc);
-  do_toktable(db->subject, len_counts, enc_len_counts, enc_counts, size, &max_len, &max_enc_len, &max_enc);
-  do_toktable(db->body, len_counts, enc_len_counts, enc_counts, size, &max_len, &max_enc_len, &max_enc);
-#if 0
-  /* no longer works now that the msg_ids table has 2 encoding chains.  fix
-   * this when required. */
-  do_toktable(db->msg_ids, len_counts, enc_len_counts, enc_counts, size, &max_len, &max_enc_len, &max_enc);
-#endif
-
-  printf("Max token length : %d\n", max_len);
-  print_table(len_counts, max_len);
-
-  printf("Max encoding vector length : %d\n", max_enc_len);
-  print_table(enc_len_counts, max_enc_len);
-
-  printf("Max encoding increment : %d\n", max_enc);
-  print_table(enc_counts, max_enc);
-
-  return;
-}
-
diff --git a/src/mairix/tok.c b/src/mairix/tok.c
@@ -1,344 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002-2004, 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Functions for handling tokens */
-
-#include <assert.h>
-#include <ctype.h>
-#include "mairix.h"
-
-static void init_matches(struct matches *m) {/*{{{*/
-  m->msginfo = NULL;
-  m->n = 0;
-  m->max = 0;
-  m->highest = 0;
-}
-/*}}}*/
-struct token *new_token(void)/*{{{*/
-{
-  struct token *result = new(struct token);
-  result->text = NULL;
-  init_matches(&result->match0);
-  return result;
-}
-/*}}}*/
-struct token2 *new_token2(void)/*{{{*/
-{
-  struct token2 *result = new(struct token2);
-  result->text = NULL;
-  init_matches(&result->match0);
-  init_matches(&result->match1);
-  return result;
-}
-/*}}}*/
-void free_token(struct token *x)/*{{{*/
-{
-  if (x->text) free(x->text);
-  if (x->match0.msginfo) free(x->match0.msginfo);
-  free(x);
-}
-/*}}}*/
-void free_token2(struct token2 *x)/*{{{*/
-{
-  if (x->text) free(x->text);
-  if (x->match0.msginfo) free(x->match0.msginfo);
-  if (x->match1.msginfo) free(x->match1.msginfo);
-  free(x);
-}
-/*}}}*/
-struct toktable *new_toktable(void)/*{{{*/
-{
-  struct toktable *result = new(struct toktable);
-  result->tokens = NULL;
-  result->n = 0;
-  result->hwm = 0;
-  result->size = 0;
-  return result;
-}
-/*}}}*/
-struct toktable2 *new_toktable2(void)/*{{{*/
-{
-  struct toktable2 *result = new(struct toktable2);
-  result->tokens = NULL;
-  result->n = 0;
-  result->hwm = 0;
-  result->size = 0;
-  return result;
-}
-/*}}}*/
-void free_toktable(struct toktable *x)/*{{{*/
-{
-  if (x->tokens) {
-    int i;
-    for (i=0; i<x->size; i++) {
-      if (x->tokens[i]) {
-        free_token(x->tokens[i]);
-      }
-    }
-    free(x->tokens);
-  }
-  free(x);
-}
-/*}}}*/
-void free_toktable2(struct toktable2 *x)/*{{{*/
-{
-  if (x->tokens) {
-    int i;
-    for (i=0; i<x->size; i++) {
-      if (x->tokens[i]) {
-        free_token2(x->tokens[i]);
-      }
-    }
-    free(x->tokens);
-  }
-  free(x);
-}
-/*}}}*/
-/* FIXME : This stuff really needs cleaning up. */
-static void enlarge_toktable(struct toktable *table)/*{{{*/
-{
-  if (table->size == 0) {
-    int i;
-    /* initial allocation */
-    table->size = 1024;
-    table->mask = table->size - 1;
-    table->tokens = new_array(struct token *, table->size);
-    for (i=0; i<table->size; i++) {
-      table->tokens[i] = NULL;
-    }
-  } else {
-    struct token **old_tokens;
-    int old_size = table->size;
-    int i;
-    /* reallocate */
-    old_tokens = table->tokens;
-    table->size <<= 1;
-    table->mask = table->size - 1;
-    table->tokens = new_array(struct token *, table->size);
-    for (i=0; i<table->size; i++) {
-      table->tokens[i] = NULL;
-    }
-    for (i=0; i<old_size; i++) {
-      unsigned long new_index;
-      if (old_tokens[i]) {
-        new_index = old_tokens[i]->hashval & table->mask;
-        while (table->tokens[new_index]) {
-          new_index++;
-          new_index &= table->mask;
-        }
-        table->tokens[new_index] = old_tokens[i];
-      }
-    }
-    free(old_tokens);
-  }
-  table->hwm = (table->size >> 2) + (table->size >> 3); /* allow 3/8 of nodes to be used */
-}
-/*}}}*/
-static void enlarge_toktable2(struct toktable2 *table)/*{{{*/
-{
-  if (table->size == 0) {
-    int i;
-    /* initial allocation */
-    table->size = 1024;
-    table->mask = table->size - 1;
-    table->tokens = new_array(struct token2 *, table->size);
-    for (i=0; i<table->size; i++) {
-      table->tokens[i] = NULL;
-    }
-  } else {
-    struct token2 **old_tokens;
-    int old_size = table->size;
-    int i;
-    /* reallocate */
-    old_tokens = table->tokens;
-    table->size <<= 1;
-    table->mask = table->size - 1;
-    table->tokens = new_array(struct token2 *, table->size);
-    for (i=0; i<table->size; i++) {
-      table->tokens[i] = NULL;
-    }
-    for (i=0; i<old_size; i++) {
-      unsigned long new_index;
-      if (old_tokens[i]) {
-        new_index = old_tokens[i]->hashval & table->mask;
-        while (table->tokens[new_index]) {
-          new_index++;
-          new_index &= table->mask;
-        }
-        table->tokens[new_index] = old_tokens[i];
-      }
-    }
-    free(old_tokens);
-  }
-  table->hwm = (table->size >> 2) + (table->size >> 3); /* allow 3/8 of nodes to be used */
-}
-/*}}}*/
-static int insert_value(unsigned char *x, int val)/*{{{*/
-{
-  assert(val >= 0);
-  if (val <= 127) {
-    *x = val;
-    return 1;
-  } else if (val <= 16383) {
-    *x++ = (val >> 8) | 0x80;
-    *x   = (val & 0xff);
-    return 2;
-  } else {
-    int a = (val >> 24);
-    assert (a <= 63);
-    *x++ = a | 0xc0;
-    *x++ = ((val >> 16) & 0xff);
-    *x++ = ((val >>  8) & 0xff);
-    *x   = (val         & 0xff);
-    return 4;
-  }
-}
-/*}}}*/
-void check_and_enlarge_encoding(struct matches *m)/*{{{*/
-{
-  if (m->n + 4 >= m->max) {
-    if (m->max == 0) {
-      m->max = 16;
-    } else {
-      m->max += (m->max >> 1);
-    }
-    m->msginfo = grow_array(unsigned char, m->max, m->msginfo);
-  }
-}
-/*}}}*/
-void insert_index_on_encoding(struct matches *m, int idx)/*{{{*/
-{
-  if (m->n == 0) {
-    /* Always encode value */
-    m->n += insert_value(m->msginfo + m->n, idx);
-  } else {
-    assert(idx >= m->highest);
-    if (idx > m->highest) {
-      int increment = idx - m->highest;
-      m->n += insert_value(m->msginfo + m->n, increment);
-    } else {
-      /* token has already been seen in this file */
-    }
-  }
-  m->highest = idx;
-}
-/*}}}*/
-void add_token_in_file(int file_index, unsigned int hash_key, char *tok_text, struct toktable *table)/*{{{*/
-{
-  unsigned long hash;
-  int index;
-  struct token *tok;
-  char *lc_tok_text;
-  char *p;
-
-  lc_tok_text = new_string((char*)tok_text);
-  for (p = lc_tok_text; *p; p++) {
-    *p = tolower(*(unsigned char *) p);
-  }
-  /* 2nd arg is string length */
-  hash = hashfn((unsigned char *) lc_tok_text, p - lc_tok_text, hash_key);
-
-  if (table->n >= table->hwm) {
-    enlarge_toktable(table);
-  }
-
-  index = hash & table->mask;
-  while (table->tokens[index]) {
-    /* strcmp ok as text has been tolower'd earlier */
-    if (!strcmp(lc_tok_text, table->tokens[index]->text))
-      break;
-    index++;
-    index &= table->mask;
-  }
-
-  if (!table->tokens[index]) {
-    /* Allocate new */
-    struct token *new_tok = new_token();
-    /* New token takes ownership of lc_tok_text, no need to free that later. */
-    new_tok->text = (char *) lc_tok_text;
-    new_tok->hashval = hash; /* save full width for later */
-    table->tokens[index] = new_tok;
-    ++table->n;
-  } else {
-    free(lc_tok_text);
-  }
-
-  tok = table->tokens[index];
-
-  check_and_enlarge_encoding(&tok->match0);
-  insert_index_on_encoding(&tok->match0, file_index);
-}
-/*}}}*/
-void add_token2_in_file(int file_index, unsigned int hash_key, char *tok_text, struct toktable2 *table, int add_to_chain1)/*{{{*/
-{
-  unsigned long hash;
-  int index;
-  struct token2 *tok;
-  char *lc_tok_text;
-  char *p;
-
-  lc_tok_text = new_string(tok_text);
-  for (p = lc_tok_text; *p; p++) {
-    *p = tolower(*(unsigned char *) p);
-  }
-  /* 2nd arg is string length */
-  hash = hashfn((unsigned char *) lc_tok_text, p - lc_tok_text, hash_key);
-
-  if (table->n >= table->hwm) {
-    enlarge_toktable2(table);
-  }
-
-  index = hash & table->mask;
-  while (table->tokens[index]) {
-    /* strcmp ok as text has been tolower'd earlier */
-    if (!strcmp(lc_tok_text, table->tokens[index]->text))
-      break;
-    index++;
-    index &= table->mask;
-  }
-
-  if (!table->tokens[index]) {
-    /* Allocate new */
-    struct token2 *new_tok = new_token2();
-    /* New token takes ownership of lc_tok_text, no need to free that later. */
-    new_tok->text = lc_tok_text;
-    new_tok->hashval = hash; /* save full width for later */
-    table->tokens[index] = new_tok;
-    ++table->n;
-  } else {
-    free(lc_tok_text);
-  }
-
-  tok = table->tokens[index];
-
-  check_and_enlarge_encoding(&tok->match0);
-  insert_index_on_encoding(&tok->match0, file_index);
-  if (add_to_chain1) {
-    check_and_enlarge_encoding(&tok->match1);
-    insert_index_on_encoding(&tok->match1, file_index);
-  }
-}
-/*}}}*/
-
-
-
-
diff --git a/src/mairix/version.h b/src/mairix/version.h
@@ -1,4 +0,0 @@
-#ifndef VERSION_H
-#define VERSION_H 1
-#define PROGRAM_VERSION "0.23"
-#endif /* VERSION_H */
diff --git a/src/mairix/version.txt b/src/mairix/version.txt
@@ -1 +0,0 @@
-0.23
diff --git a/src/mairix/writer.c b/src/mairix/writer.c
@@ -1,614 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-/* Write the database to disc. */
-
-#include "mairix.h"
-#include "reader.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <sys/mman.h>
-
-struct write_map_toktable {/*{{{*/
-
-  /* Table of character offsets to null-terminated token texts */
-  int tok_offset;
-
-  /* Table of character offsets to byte strings containing compressed
-   * delta-encoding of file indices matching the token */
-  int enc_offset;
-};/*}}}*/
-struct write_map_toktable2 {/*{{{*/
-
-  /* Table of character offsets to null-terminated token texts */
-  int tok_offset;
-
-  /* Table of character offsets to byte strings containing compressed
-   * delta-encoding of file indices matching the token */
-  int enc0_offset;
-  int enc1_offset;
-};/*}}}*/
-
-struct write_map {/*{{{*/
-/* Contain offset information for the various tables.
-   UI stuff in 4 byte units rel to base addr.
-   Char stuff in byte units rel to base addr. */
-
-  /* Path information */
-  int path_offset;
-  int mtime_offset; /* Message file mtimes (maildir/mh), mbox number (mbox) */
-  int size_offset; /* Message sizes (maildir/mh), entry in respective mbox (mbox) */
-  int date_offset; /* Message dates (all folder types) */
-  int tid_offset;  /* Thread group index table (all folder types) */
-
-  int mbox_paths_offset;
-  int mbox_entries_offset;
-  int mbox_mtime_offset;
-  int mbox_size_offset;
-  /* Character offset to checksum of first msg in the mbox.  Positions of
-   * subsequent messages computed by indexing - no explicit table entries
-   * anywhere. */
-  int mbox_checksum_offset;
-
-  struct write_map_toktable to;
-  struct write_map_toktable cc;
-  struct write_map_toktable from;
-  struct write_map_toktable subject;
-  struct write_map_toktable body;
-  struct write_map_toktable attachment_name;
-  struct write_map_toktable2 msg_ids;
-
-  /* To get base address for character data */
-  int beyond_last_ui_offset;
-};
-/*}}}*/
-
-static void create_rw_mapping(char *filename, size_t len, int *out_fd, char **out_data)/*{{{*/
-{
-  int fd;
-  char *data;
-  struct stat sb;
-
-  fd = open(filename, O_RDWR | O_CREAT, 0600);
-  if (fd < 0) {
-    report_error("open", filename);
-    unlock_and_exit(2);
-  }
-
-  if (fstat(fd, &sb) < 0) {
-    report_error("stat", filename);
-    unlock_and_exit(2);
-  }
-
-  if (sb.st_size < len) {
-    /* Extend */
-    if (lseek(fd, len - 1, SEEK_SET) < 0) {
-      report_error("lseek", filename);
-      unlock_and_exit(2);
-    }
-    if (write(fd, "\000", 1) < 0) {
-      report_error("write", filename);
-      unlock_and_exit(2);
-    }
-  } else if (sb.st_size > len) {
-    /* Truncate */
-    if (ftruncate(fd, len) < 0) {
-      report_error("ftruncate", filename);
-      unlock_and_exit(2);
-    }
-  } else {
-    /* Exactly the right length already - nothing to do! */
-  }
-
-  data = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-  if (data == MAP_FAILED) {
-    report_error("writer:mmap", filename);
-    unlock_and_exit(2);
-  }
-
-  *out_data = data;
-  *out_fd = fd;
-}
-/*}}}*/
-
-static int toktable_char_length(struct toktable *tab)/*{{{*/
-{
-  int result = 0;
-  int i;
-  for (i=0; i<tab->size; i++) {
-    if (tab->tokens[i]) {
-      result += (1 + strlen(tab->tokens[i]->text));
-      result += (1 + tab->tokens[i]->match0.n);
-    }
-  }
-  return result;
-}
-/*}}}*/
-static int toktable2_char_length(struct toktable2 *tab)/*{{{*/
-{
-  int result = 0;
-  int i;
-  for (i=0; i<tab->size; i++) {
-    if (tab->tokens[i]) {
-      result += (1 + strlen(tab->tokens[i]->text));
-      result += (1 + tab->tokens[i]->match0.n);
-      result += (1 + tab->tokens[i]->match1.n);
-    }
-  }
-  return result;
-}
-/*}}}*/
-static int char_length(struct database *db)/*{{{*/
-{
-  /* Return total length of character data to be written. */
-  int result;
-  int i;
-
-  result = 0;
-
-  /* For type table. */
-  result += db->n_msgs;
-
-  for (i=0; i<db->n_msgs; i++) {
-    switch (db->type[i]) {
-      case MTY_DEAD:
-        break;
-      case MTY_MBOX:
-        break;
-      case MTY_FILE:
-        assert(db->msgs[i].src.mpf.path);
-        result += (1 + strlen(db->msgs[i].src.mpf.path));
-        break;
-    }
-  }
-
-  for (i=0; i<db->n_mboxen; i++) {
-    struct mbox *mb = &db->mboxen[i];
-    result += mb->n_msgs * sizeof(checksum_t);
-    if (mb->path) {
-      result += (1 + strlen(mb->path));
-    }
-  }
-
-  result += toktable_char_length(db->to);
-  result += toktable_char_length(db->cc);
-  result += toktable_char_length(db->from);
-  result += toktable_char_length(db->subject);
-  result += toktable_char_length(db->body);
-  result += toktable_char_length(db->attachment_name);
-  result += toktable2_char_length(db->msg_ids);
-
-  return result;
-}
-/*}}}*/
-
-static void compute_mapping(struct database *db, struct write_map *map)/*{{{*/
-{
-  int total = UI_HEADER_LEN;
-
-  map->path_offset  = total, total += db->n_msgs;
-  map->mtime_offset = total, total += db->n_msgs;
-  map->date_offset  = total, total += db->n_msgs;
-  map->size_offset  = total, total += db->n_msgs;
-  map->tid_offset   = total, total += db->n_msgs;
-
-  map->mbox_paths_offset = total, total += db->n_mboxen;
-  map->mbox_entries_offset = total, total += db->n_mboxen;
-  map->mbox_mtime_offset = total, total += db->n_mboxen;
-  map->mbox_size_offset  = total, total += db->n_mboxen;
-  map->mbox_checksum_offset = total, total += db->n_mboxen;
-
-  map->to.tok_offset = total, total += db->to->n;
-  map->to.enc_offset = total, total += db->to->n;
-
-  map->cc.tok_offset = total, total += db->cc->n;
-  map->cc.enc_offset = total, total += db->cc->n;
-
-  map->from.tok_offset = total, total += db->from->n;
-  map->from.enc_offset = total, total += db->from->n;
-
-  map->subject.tok_offset = total, total += db->subject->n;
-  map->subject.enc_offset = total, total += db->subject->n;
-
-  map->body.tok_offset = total, total += db->body->n;
-  map->body.enc_offset = total, total += db->body->n;
-
-  map->attachment_name.tok_offset = total, total += db->attachment_name->n;
-  map->attachment_name.enc_offset = total, total += db->attachment_name->n;
-
-  map->msg_ids.tok_offset = total, total += db->msg_ids->n;
-  map->msg_ids.enc0_offset = total, total += db->msg_ids->n;
-  map->msg_ids.enc1_offset = total, total += db->msg_ids->n;
-
-  map->beyond_last_ui_offset = total;
-}
-/*}}}*/
-static void write_header(char *data, unsigned int *uidata, struct database *db, struct write_map *map)/*{{{*/
-{
-  /* Endianness-independent writes - at least the magic number will be
-   * recognized if the database is read by this program on a machine of
-   * opposite endianness. */
-  unsigned char *ucdata = (unsigned char *) data;
-
-  ucdata[0] = HEADER_MAGIC0;
-  ucdata[1] = HEADER_MAGIC1;
-  ucdata[2] = HEADER_MAGIC2;
-  ucdata[3] = HEADER_MAGIC3;
-
-  uidata[UI_ENDIAN] = 0x44332211; /* For checking reversed endianness on read */
-  uidata[UI_N_MSGS] = db->n_msgs;
-  uidata[UI_MSG_CDATA] = map->path_offset; /* offset table of ptrs to filenames */
-  uidata[UI_MSG_MTIME] = map->mtime_offset; /* offset of mtime table */
-  uidata[UI_MSG_DATE] = map->date_offset; /* offset of table of message Date: header lines as time_t */
-  uidata[UI_MSG_SIZE] = map->size_offset; /* offset of table of message sizes in bytes */
-  uidata[UI_MSG_TID] = map->tid_offset; /* offset of table of thread group numbers */
-
-  uidata[UI_MBOX_N] = db->n_mboxen;
-  uidata[UI_MBOX_PATHS] = map->mbox_paths_offset;
-  uidata[UI_MBOX_ENTRIES] = map->mbox_entries_offset;
-  uidata[UI_MBOX_MTIME] = map->mbox_mtime_offset;
-  uidata[UI_MBOX_SIZE]  = map->mbox_size_offset;
-  uidata[UI_MBOX_CKSUM] = map->mbox_checksum_offset;
-
-  uidata[UI_HASH_KEY] = db->hash_key;
-
-  uidata[UI_TO_N] = db->to->n;
-  uidata[UI_TO_TOK] = map->to.tok_offset;
-  uidata[UI_TO_ENC] = map->to.enc_offset;
-
-  uidata[UI_CC_N] = db->cc->n;
-  uidata[UI_CC_TOK] = map->cc.tok_offset;
-  uidata[UI_CC_ENC] = map->cc.enc_offset;
-
-  uidata[UI_FROM_N] = db->from->n;
-  uidata[UI_FROM_TOK] = map->from.tok_offset;
-  uidata[UI_FROM_ENC] = map->from.enc_offset;
-
-  uidata[UI_SUBJECT_N] = db->subject->n;
-  uidata[UI_SUBJECT_TOK] = map->subject.tok_offset;
-  uidata[UI_SUBJECT_ENC] = map->subject.enc_offset;
-
-  uidata[UI_BODY_N] = db->body->n;
-  uidata[UI_BODY_TOK] = map->body.tok_offset;
-  uidata[UI_BODY_ENC] = map->body.enc_offset;
-
-  uidata[UI_ATTACHMENT_NAME_N] = db->attachment_name->n;
-  uidata[UI_ATTACHMENT_NAME_TOK] = map->attachment_name.tok_offset;
-  uidata[UI_ATTACHMENT_NAME_ENC] = map->attachment_name.enc_offset;
-
-  uidata[UI_MSGID_N]    = db->msg_ids->n;
-  uidata[UI_MSGID_TOK]  = map->msg_ids.tok_offset;
-  uidata[UI_MSGID_ENC0] = map->msg_ids.enc0_offset;
-  uidata[UI_MSGID_ENC1] = map->msg_ids.enc1_offset;
-
-  return;
-}
-/*}}}*/
-static char *write_type_and_flag_table(struct database *db, unsigned int *uidata, char *data, char *cdata)/*{{{*/
-{
-  int i;
-  for (i=0; i<db->n_msgs; i++) {
-    struct msgpath *msgdata = db->msgs + i;
-    switch (db->type[i]) {
-      case MTY_FILE:
-        cdata[i] = DB_MSG_FILE;
-        break;
-      case MTY_MBOX:
-        cdata[i] = DB_MSG_MBOX;
-        break;
-      case MTY_DEAD:
-        cdata[i] = DB_MSG_DEAD;
-        break;
-    }
-
-    if (msgdata->seen)    cdata[i] |= FLAG_SEEN;
-    if (msgdata->replied) cdata[i] |= FLAG_REPLIED;
-    if (msgdata->flagged) cdata[i] |= FLAG_FLAGGED;
-  }
-  uidata[UI_MSG_TYPE_AND_FLAGS] = cdata - data;
-  return cdata + db->n_msgs;
-}
-/*}}}*/
-static char *write_messages(struct database *db, struct write_map *map, unsigned int *uidata, char *data, char *cdata)/*{{{*/
-{
-  int i;
-  char *start_cdata = cdata;
-
-  for (i=0; i<db->n_msgs; i++) {
-    int slen;
-    switch (db->type[i]) {
-      case MTY_FILE:
-        slen = strlen(db->msgs[i].src.mpf.path);
-        uidata[map->path_offset + i] = cdata - data;
-        uidata[map->mtime_offset + i] = db->msgs[i].src.mpf.mtime;
-        uidata[map->size_offset + i] = db->msgs[i].src.mpf.size;
-        uidata[map->date_offset + i] = db->msgs[i].date;
-        uidata[map->tid_offset + i]  = db->msgs[i].tid;
-        memcpy(cdata, db->msgs[i].src.mpf.path, 1 + slen); /* include trailing null */
-        cdata += (1 + slen);
-        break;
-      case MTY_MBOX:
-        {
-          int mbno = db->msgs[i].src.mbox.file_index;
-          int msgno = db->msgs[i].src.mbox.msg_index;
-          struct mbox *mb = &db->mboxen[mbno];
-          uidata[map->path_offset + i] = encode_mbox_indices(mbno, msgno);
-          uidata[map->mtime_offset + i] = mb->start[msgno];
-          uidata[map->size_offset + i] = mb->len[msgno];
-          uidata[map->date_offset + i] = db->msgs[i].date;
-          uidata[map->tid_offset + i]  = db->msgs[i].tid;
-        }
-        break;
-      case MTY_DEAD:
-        uidata[map->path_offset + i] = 0; /* Can't ever happen for real */
-        uidata[map->mtime_offset + i] = 0; /* For cleanliness */
-        uidata[map->size_offset + i] = 0;  /* For cleanliness */
-        /* The following line is necessary, otherwise 'random' tid
-         * information is written to the database, which can crash the search
-         * functions. */
-        uidata[map->tid_offset + i]  = db->msgs[i].tid;
-        break;
-    }
-  }
-  if (verbose) {
-    printf("Wrote %d messages (%d bytes of tables, %d bytes of text)\n",
-           db->n_msgs, 4*5*db->n_msgs, (int)(cdata - start_cdata));
-  }
-  return cdata; /* new value */
-}
-/*}}}*/
-#if 0
-static int compare_tokens(const void *a, const void *b)/*{{{*/
-{
-  const struct token **aa = (const struct token **) a;
-  const struct token **bb = (const struct token **) b;
-  return strcmp((*aa)->text, (*bb)->text);
-}
-/*}}}*/
-#endif
-
-static  char *write_mbox_headers(struct database *db, struct write_map *map, unsigned int *uidata, char *data, char *cdata)/*{{{*/
-{
-  int i, len;
-  char *start_cdata = cdata;
-
-  for (i=0; i<db->n_mboxen; i++) {
-    struct mbox *mb = &db->mboxen[i];
-    uidata[map->mbox_entries_offset + i] = mb->n_msgs;
-    uidata[map->mbox_mtime_offset + i] = mb->current_mtime;
-    uidata[map->mbox_size_offset  + i] = mb->current_size;
-    if (mb->path) {
-      uidata[map->mbox_paths_offset + i] = cdata - data;
-      len = strlen(mb->path);
-      memcpy(cdata, mb->path, 1+len);
-      cdata += 1+len;
-    } else {
-      uidata[map->mbox_paths_offset + i] = 0;
-    }
-  }
-  if (verbose) {
-    printf("Wrote %d mbox headers (%d bytes of tables, %d bytes of paths)\n",
-        db->n_mboxen, 4*4*db->n_mboxen, (int)(cdata - start_cdata));
-  }
-  return cdata;
-}
-/*}}}*/
-static char * write_mbox_checksums(struct database *db, struct write_map *map, unsigned int *uidata, char *data, char *cdata)/*{{{*/
-{
-  int i, j;
-  char *start_cdata = cdata;
-
-  for (i=0; i<db->n_mboxen; i++) {
-    struct mbox *mb = &db->mboxen[i];
-    uidata[map->mbox_checksum_offset + i] = cdata - data;
-    for (j=0; j<mb->n_msgs; j++) {
-      memcpy(cdata, mb->check_all[j], sizeof(checksum_t));
-      cdata += sizeof(checksum_t);
-    }
-  }
-  if (verbose) {
-    printf("Wrote %d bytes of mbox message checksums\n",
-           (int)(cdata - start_cdata));
-  }
-  return cdata;
-}
-/*}}}*/
-
-static char *write_toktable(struct toktable *tab, struct write_map_toktable *map, unsigned int *uidata, char *data, char *cdata, char *header_name)/*{{{*/
-{
-  int i, j, n, max;
-  char *start_cdata, *mid_cdata;
-  struct token **stok;
-  stok = new_array(struct token *, tab->n);
-  max = tab->size;
-  n = tab->n;
-
-  for (i=0, j=0; i<max; i++) {
-    struct token *tok = tab->tokens[i];
-    if (tok) {
-      stok[j++] = tok;
-    }
-  }
-
-  assert(j == n);
-
-#if 0
-  /* The search functions don't rely on the tokens being sorted.  So not
-   * sorting here will save time. */
-  qsort(stok, n, sizeof(struct token *), compare_tokens);
-#endif
-
-  start_cdata = cdata;
-
-  /* FIXME : Eventually, the tokens have to be sorted - need to feed them from
-   * a different data structure (array with no holes) */
-  for (i=0; i<n; i++) {
-    int slen;
-    uidata[map->tok_offset + i] = cdata - data;
-    slen = strlen(stok[i]->text);
-    memcpy(cdata, stok[i]->text, 1 + slen);
-    cdata += (1 + slen);
-  }
-
-  mid_cdata = cdata;
-
-  for (i=0; i<n; i++) {
-    int dlen;
-    dlen = stok[i]->match0.n;
-    uidata[map->enc_offset + i] = cdata - data;
-    memcpy(cdata, stok[i]->match0.msginfo, dlen);
-    cdata += dlen;
-    *cdata++ = 0xff; /* termination character */
-  }
-
-  if (verbose) {
-    printf("%s: Wrote %d tokens (%d bytes of tables, %d bytes of text, %d bytes of hit encoding)\n",
-            header_name, n, 2*4*n, (int)(mid_cdata - start_cdata), (int)(cdata - mid_cdata));
-  }
-
-  free(stok);
-  return cdata;
-}
-/*}}}*/
-static char *write_toktable2(struct toktable2 *tab, struct write_map_toktable2 *map, unsigned int *uidata, char *data, char *cdata, char *header_name)/*{{{*/
-{
-  int i, j, n, max;
-  char *start_cdata, *mid_cdata;
-  struct token2 **stok;
-  stok = new_array(struct token2 *, tab->n);
-  max = tab->size;
-  n = tab->n;
-
-  for (i=0, j=0; i<max; i++) {
-    struct token2 *tok = tab->tokens[i];
-    if (tok) {
-      stok[j++] = tok;
-    }
-  }
-
-  assert(j == n);
-
-#if 0
-  /* The search functions don't rely on the tokens being sorted.  So not
-   * sorting here will save time. */
-  qsort(stok, n, sizeof(struct token *), compare_tokens);
-#endif
-
-  start_cdata = cdata;
-
-  /* FIXME : Eventually, the tokens have to be sorted - need to feed them from
-   * a different data structure (array with no holes) */
-  for (i=0; i<n; i++) {
-    int slen;
-    uidata[map->tok_offset + i] = cdata - data;
-    slen = strlen(stok[i]->text);
-    memcpy(cdata, stok[i]->text, 1 + slen);
-    cdata += (1 + slen);
-  }
-
-  mid_cdata = cdata;
-
-  for (i=0; i<n; i++) {
-    int dlen;
-    dlen = stok[i]->match0.n;
-    uidata[map->enc0_offset + i] = cdata - data;
-    memcpy(cdata, stok[i]->match0.msginfo, dlen);
-    cdata += dlen;
-    *cdata++ = 0xff; /* termination character */
-  }
-
-  for (i=0; i<n; i++) {
-    int dlen;
-    dlen = stok[i]->match1.n;
-    uidata[map->enc1_offset + i] = cdata - data;
-    memcpy(cdata, stok[i]->match1.msginfo, dlen);
-    cdata += dlen;
-    *cdata++ = 0xff; /* termination character */
-  }
-
-  if (verbose) {
-    printf("%s: Wrote %d tokens (%d bytes of tables, %d bytes of text, %d bytes of hit encoding)\n",
-            header_name, n, 2*4*n, (int)(mid_cdata - start_cdata), (int)(cdata - mid_cdata));
-  }
-
-  free(stok);
-  return cdata;
-}
-/*}}}*/
-void write_database(struct database *db, char *filename, int do_integrity_checks)/*{{{*/
-{
-  int file_len;
-  int fd;
-  char *data, *cdata;
-  unsigned int *uidata;
-  struct write_map map;
-
-  if (do_integrity_checks) {
-    check_database_integrity(db);
-  }
-
-  if (!verify_mbox_size_constraints(db)) {
-    unlock_and_exit(1);
-  }
-
-  /* Work out mappings */
-  compute_mapping(db, &map);
-
-  file_len = char_length(db) + (4 * map.beyond_last_ui_offset);
-
-  create_rw_mapping(filename, file_len, &fd, &data);
-  uidata = (unsigned int *) data; /* align(int) < align(page)! */
-  cdata = data + (4 * map.beyond_last_ui_offset);
-
-  write_header(data, uidata, db, &map);
-  cdata = write_type_and_flag_table(db, uidata, data, cdata);
-  cdata = write_messages(db, &map, uidata, data, cdata);
-  cdata = write_mbox_headers(db, &map, uidata, data, cdata);
-  cdata = write_mbox_checksums(db, &map, uidata, data, cdata);
-  cdata = write_toktable(db->to, &map.to, uidata, data, cdata, "To");
-  cdata = write_toktable(db->cc, &map.cc, uidata, data, cdata, "Cc");
-  cdata = write_toktable(db->from, &map.from, uidata, data, cdata, "From");
-  cdata = write_toktable(db->subject, &map.subject, uidata, data, cdata, "Subject");
-  cdata = write_toktable(db->body, &map.body, uidata, data, cdata, "Body");
-  cdata = write_toktable(db->attachment_name, &map.attachment_name, uidata, data, cdata, "Attachment Name");
-  cdata = write_toktable2(db->msg_ids, &map.msg_ids, uidata, data, cdata, "(Threading)");
-
-  /* Write data */
-  /* Unmap / close file */
-  if (munmap(data, file_len) < 0) {
-    report_error("munmap", filename);
-    unlock_and_exit(2);
-  }
-  if (fsync(fd) < 0) {
-    report_error("fsync", filename);
-    unlock_and_exit(2);
-  }
-  if (close(fd) < 0) {
-    report_error("close", filename);
-    unlock_and_exit(2);
-  }
-}
-  /*}}}*/
diff --git a/src/nvp.c b/src/nvp.c
@@ -1,416 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2006,2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#ifdef VERBOSE_TEST
-#define TEST 1
-#endif
-
-/* Parse name/value pairs from mail headers into a lookup table. */
-#include <stdio.h>
-#include <ctype.h>
-#include "mairix.h"
-#include "nvptypes.h"
-#include "nvpscan.h"
-#include "nvp.h"
-
-enum nvp_type {/*{{{*/
-  NVP_NAME,
-  NVP_MAJORMINOR,
-  NVP_NAMEVALUE
-};
-/*}}}*/
-struct nvp_entry {/*{{{*/
-  struct nvp_entry *next;
-  struct nvp_entry *prev;
-  enum nvp_type type;
-  char *lhs;
-  char *rhs;
-};
-/*}}}*/
-struct nvp {/*{{{*/
-  struct nvp_entry *first, *last;
-};
-/*}}}*/
-static void append(struct nvp *nvp, struct nvp_entry *ne)/*{{{*/
-{
-  ne->next = NULL;
-  ne->prev = nvp->last;
-  if (nvp->last) nvp->last->next = ne;
-  else nvp->first = ne;
-  nvp->last = ne;
-}
-/*}}}*/
-static void append_name(struct nvp *nvp, char *name)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = new(struct nvp_entry);
-  ne->type = NVP_NAME;
-  ne->lhs = new_string(name);
-  append(nvp, ne);
-}
-/*}}}*/
-static void append_majorminor(struct nvp *nvp, char *major, char *minor)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = new(struct nvp_entry);
-  ne->type = NVP_MAJORMINOR;
-  ne->lhs = new_string(major);
-  ne->rhs = new_string(minor);
-  append(nvp, ne);
-
-}
-/*}}}*/
-static void append_namevalue(struct nvp *nvp, char *name, char *value)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = new(struct nvp_entry);
-  ne->type = NVP_NAMEVALUE;
-  ne->lhs = new_string(name);
-  ne->rhs = new_string(value);
-  append(nvp, ne);
-}
-/*}}}*/
-static void combine_namevalue(struct nvp *nvp, char *name, char *value)/*{{{*/
-{
-  struct nvp_entry *n;
-  for (n=nvp->first; n; n=n->next) {
-    if (n->type == NVP_NAMEVALUE) {
-      if (!strcmp(n->lhs, name)) {
-        char *new_rhs;
-        new_rhs = new_array(char, strlen(n->rhs) + strlen(value) + 1);
-        strcpy(new_rhs, n->rhs);
-        strcat(new_rhs, value);
-        free(n->rhs);
-        n->rhs = new_rhs;
-        return;
-      }
-    }
-  }
-  /* No match : it's the first one */
-  append_namevalue(nvp, name, value);
-}
-/*}}}*/
-static void release_nvp(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *e, *ne;
-  for (e=nvp->first; e; e=ne) {
-    ne = e->next;
-    switch (e->type) {
-      case NVP_NAME:
-        free(e->lhs);
-        break;
-      case NVP_MAJORMINOR:
-      case NVP_NAMEVALUE:
-        free(e->lhs);
-        free(e->rhs);
-        break;
-    }
-    free(e);
-  }
-  free(nvp);
-}
-/*}}}*/
-struct nvp *make_nvp(struct msg_src *src, char *s, const char *pfx)/*{{{*/
-{
-  int current_state;
-  unsigned int tok;
-  char *q;
-  unsigned char qq;
-  char name[256];
-  char minor[256];
-  char value[256];
-  enum nvp_action last_action, current_action;
-  struct nvp *result;
-  size_t pfxlen;
-  char *nn, *mm, *vv;
-
-  pfxlen = strlen(pfx);
-  if (strncasecmp(pfx, s, pfxlen))
-    return NULL;
-  s += pfxlen;
-
-  result = new(struct nvp);
-  result->first = result->last = NULL;
-
-  current_state = nvp_in;
-
-  q = s;
-  nn = name;
-  mm = minor;
-  vv = value;
-  last_action = GOT_NOTHING;
-  do {
-    qq = *(unsigned char *) q;
-    if (qq) {
-      tok = nvp_char2tok[qq];
-    } else {
-      tok = nvp_EOS;
-    }
-    current_state = nvp_next_state(current_state, tok);
-#ifdef VERBOSE_TEST
-    fprintf(stderr, "Char %02x (%c) tok=%d new_current_state=%d\n",
-        qq, ((qq>=32) && (qq<=126)) ? qq : '.',
-        tok, current_state);
-#endif
-
-    if (current_state < 0) {
-#ifdef TEST
-      fprintf(stderr, "'%s' could not be parsed\n", s);
-#else
-      fprintf(stderr, "Header '%s%s' in %s could not be parsed\n",
-          pfx, s, format_msg_src(src));
-#endif
-      release_nvp(result);
-      return NULL;
-    }
-
-    switch (nvp_copier[current_state]) {
-      case COPY_TO_NAME:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "  COPY_TO_NAME\n");
-#endif
-        *nn++ = *q;
-        break;
-      case COPY_TO_MINOR:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "  COPY_TO_MINOR\n");
-#endif
-        *mm++ = *q;
-        break;
-      case COPY_TO_VALUE:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "  COPY_TO_VALUE\n");
-#endif
-        *vv++ = *q;
-        break;
-      case COPY_NOWHERE:
-        break;
-    }
-
-    current_action = nvp_action[current_state];
-    switch (current_action) {
-      case GOT_NAME:
-      case GOT_NAME_TRAILING_SPACE:
-      case GOT_MAJORMINOR:
-      case GOT_NAMEVALUE:
-      case GOT_NAMEVALUE_CONT:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "   Setting last action to %d\n", current_action);
-#endif
-        last_action = current_action;
-        break;
-      case GOT_TERMINATOR:
-#ifdef VERBOSE_TEST
-        fprintf(stderr, "   Hit terminator; last_action=%d\n", last_action);
-#endif
-        switch (last_action) {
-          case GOT_NAME:
-            *nn = 0;
-            append_name(result, name);
-            break;
-          case GOT_NAME_TRAILING_SPACE:
-            while (isspace(*--nn)) {}
-            *++nn = 0;
-            append_name(result, name);
-            break;
-          case GOT_MAJORMINOR:
-            *nn = 0;
-            *mm = 0;
-            append_majorminor(result, name, minor);
-            break;
-          case GOT_NAMEVALUE:
-            *nn = 0;
-            *vv = 0;
-            append_namevalue(result, name, value);
-            break;
-          case GOT_NAMEVALUE_CONT:
-            *nn = 0;
-            *vv = 0;
-            combine_namevalue(result, name, value);
-            break;
-          default:
-            break;
-        }
-        nn = name;
-        mm = minor;
-        vv = value;
-        break;
-      case GOT_NOTHING:
-        break;
-    }
-
-    q++;
-  } while (tok != nvp_EOS);
-
-  return result;
-}
-/*}}}*/
-void free_nvp(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne, *nne;
-  for (ne = nvp->first; ne; ne=nne) {
-    nne = ne->next;
-    switch (ne->type) {
-      case NVP_NAME:
-        free(ne->lhs);
-        break;
-      case NVP_MAJORMINOR:
-      case NVP_NAMEVALUE:
-        free(ne->lhs);
-        free(ne->rhs);
-        break;
-    }
-    free(ne);
-  }
-  free(nvp);
-}
-/*}}}*/
-const char *nvp_lookup(struct nvp *nvp, const char *name)/*{{{*/
-{
-  struct nvp_entry *ne;
-  for (ne = nvp->first; ne; ne=ne->next) {
-    if (ne->type == NVP_NAMEVALUE) {
-      if (!strcmp(ne->lhs, name)) {
-        return ne->rhs;
-      }
-    }
-  }
-  return NULL;
-}
-/*}}}*/
-const char *nvp_lookupcase(struct nvp *nvp, const char *name)/*{{{*/
-{
-  struct nvp_entry *ne;
-  for (ne = nvp->first; ne; ne=ne->next) {
-    if (ne->type == NVP_NAMEVALUE) {
-      if (!strcasecmp(ne->lhs, name)) {
-        return ne->rhs;
-      }
-    }
-  }
-  return NULL;
-}
-/*}}}*/
-
-void nvp_dump(struct nvp *nvp, FILE *out)/*{{{*/
-{
-  struct nvp_entry *ne;
-  fprintf(out, "----\n");
-  for (ne = nvp->first; ne; ne=ne->next) {
-    switch (ne->type) {
-      case NVP_NAME:
-        fprintf(out, "NAME: %s\n", ne->lhs);
-        break;
-      case NVP_MAJORMINOR:
-        fprintf(out, "MAJORMINOR: %s/%s\n", ne->lhs, ne->rhs);
-        break;
-      case NVP_NAMEVALUE:
-        fprintf(out, "NAMEVALUE: %s=%s\n", ne->lhs, ne->rhs);
-        break;
-    }
-  }
-}
-/*}}}*/
-
-/* In these cases, we only look at the first entry */
-const char *nvp_major(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = nvp->first;
-  if (ne) {
-    if (ne->type == NVP_MAJORMINOR) {
-      return ne->lhs;
-    } else {
-      return NULL;
-    }
-  } else {
-    return NULL;
-  }
-}
-/*}}}*/
-const char *nvp_minor(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = nvp->first;
-  if (ne) {
-    if (ne->type == NVP_MAJORMINOR) {
-      return ne->rhs;
-    } else {
-      return NULL;
-    }
-  } else {
-    return NULL;
-  }
-}
-/*}}}*/
-const char *nvp_first(struct nvp *nvp)/*{{{*/
-{
-  struct nvp_entry *ne;
-  ne = nvp->first;
-  if (ne) {
-    if (ne->type == NVP_NAME) {
-      return ne->lhs;
-    } else {
-      return NULL;
-    }
-  } else {
-    return NULL;
-  }
-}
-/*}}}*/
-
-#ifdef TEST
-
-static void do_test(char *s)
-{
-  struct nvp *n;
-  n = make_nvp(NULL, s, "");
-  if (n) {
-    nvp_dump(n, stderr);
-    free_nvp(n);
-  }
-}
-
-
-int main (int argc, char **argv) {
-  struct nvp *n;
-#if 0
-  do_test("attachment; filename=\"foo.c\"; prot=ro");
-  do_test("attachment; filename= \"foo bar.c\" ;prot=ro");
-  do_test("attachment ; filename= \"foo bar.c\" ;prot= ro");
-  do_test("attachment ; filename= \"foo bar.c\" ;prot= ro");
-  do_test("attachment ; filename= \"foo ;  bar.c\" ;prot= ro");
-  do_test("attachment ; x*0=\"hi \"; x*1=\"there\"");
-#endif
-
-  do_test("application/vnd.ms-excel;       name=\"thequiz.xls\"");
-#if 0
-  do_test("inline; filename*0=\"aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj\t kkkkllll\"");
-  do_test(" text/plain ; name= \"foo bar.c\" ;prot= ro/rw; read/write; read= foo bar");
-#endif
-  return 0;
-}
-#endif
-
-
-
-
diff --git a/src/nvp.h b/src/nvp.h
@@ -1,38 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2006,2010
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 NVP_H
-#define NVP_H
-
-struct nvp;
-struct msg_src;
-extern struct nvp *make_nvp(struct msg_src *, char *, const char *);
-extern void free_nvp(struct nvp *);
-extern void nvp_dump(struct nvp *nvp, FILE *out);
-extern const char *nvp_major(struct nvp *n);
-extern const char *nvp_minor(struct nvp *n);
-extern const char *nvp_first(struct nvp *n);
-extern const char *nvp_lookup(struct nvp *n, const char *name);
-extern const char *nvp_lookupcase(struct nvp *n, const char *name);
-
-#endif
-
diff --git a/src/nvp.nfa b/src/nvp.nfa
@@ -1,197 +0,0 @@
-#########################################################################
-#
-# mairix - message index builder and finder for maildir folders.
-#
-# Copyright (C) Richard P. Curnow  2006,2007
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# 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.
-#
-# =======================================================================
-
-Tokens EOS
-Abbrev VALUE = [\041-~]~[\\";]
-Abbrev QVALUE = VALUE | [\011\040;] | <escape:in->out>
-Abbrev NAME1 = [0-9a-zA-Z_\-]
-Abbrev MINOR = NAME1 | [\.\-+]
-Abbrev OWS = <optwhite:in->out>
-
-%{
-#include "nvptypes.h"
-%}
-
-Block escape {
-    State in
-        [\\] ; [\\] -> out
-        [\\] ; ["]  -> out
-}
-
-Block optwhite {
-    State in
-        -> out
-        # I have seen headers with ^M in them...
-        [ \t\r] -> in
-}
-
-Block name {
-    # This needs to cope with embedded spaces, e.g. for mailers that write '7
-    # bit' instead of '7bit'
-    State in
-        NAME1 -> name1
-
-    State name1
-        = COPY_TO_NAME
-        = GOT_NAME
-        NAME1 -> name1
-        [ \t] -> name2
-        -> out
-
-    State name2
-        = COPY_TO_NAME
-        = GOT_NAME_TRAILING_SPACE
-        [ \t] -> name2
-        NAME1 -> name1
-        -> out
-
-    State out
-}
-
-Block value {
-    State in
-        VALUE -> v1
-    State v1
-        = COPY_TO_VALUE
-        -> out
-        VALUE -> v1
-}
-
-Block qvalue {
-    State in
-        ["] -> qv0
-
-    State qv0
-        QVALUE -> qv1
-
-    State qv1
-        = COPY_TO_VALUE
-        QVALUE -> qv1
-        -> qv2
-
-    State qv2
-        ["] -> out
-}
-
-Block digits {
-    State in
-        [0-9] -> out
-        [0-9] -> in
-}
-
-Block namevalue {
-    State in
-        OWS ; <name:in->out> ; OWS ; [=] -> rhs_normal
-        OWS ; <name:in->out> ; [*] ; <digits:in->out> ; OWS ; [=] -> rhs_continue
-
-    State rhs_normal
-        OWS ; <qvalue:in->out> ; OWS -> out_normal
-        OWS ; <value:in->out> ; OWS -> out_normal
-        OWS ; ; EOS -> out_normal
-
-    State rhs_continue
-        OWS ; <qvalue:in->out> ; OWS -> out_continue
-        OWS ; <value:in->out> ; OWS -> out_continue
-
-    State out_normal = GOT_NAMEVALUE
-        -> out
-    State out_continue = GOT_NAMEVALUE_CONT
-        -> out
-}
-
-Block major {
-    State in
-        NAME1 -> name1
-
-    State name1
-        NAME1 -> name1
-        -> out
-}
-
-Block minor {
-    State in
-        MINOR -> minor1
-
-    State minor1
-        = COPY_TO_MINOR
-        MINOR -> minor1
-        -> out
-}
-
-Block majorminor {
-    State in
-        <major:in->out> -> foo
-
-    State foo
-        [/] -> bar
-
-    State bar
-        <minor:in->out> -> out
-
-    State out = GOT_MAJORMINOR
-}
-
-Block component {
-    State in
-        <namevalue:in->out> -> out
-        <name:in->out> -> out
-        <majorminor:in->out> -> out
-}
-
-Block main {
-    State in Entry in
-        OWS ; <component:in->out> ; OWS ; EOS -> out2
-        OWS ; <component:in->out> ; OWS ; [;] ; OWS ; EOS -> out2
-        OWS ; <component:in->out> ; OWS ; [;] -> in2
-        
-    State in2
-        = GOT_TERMINATOR
-        -> in
-
-    State out2
-        = GOT_TERMINATOR
-        -> out
-}
-
-Defattr 0
-Prefix nvp
-
-Group action {
-    Attr GOT_NAMEVALUE
-    Attr GOT_NAMEVALUE_CONT
-    Attr GOT_NAME
-    Attr GOT_NAME_TRAILING_SPACE
-    Attr GOT_MAJORMINOR
-    Attr GOT_TERMINATOR
-    Defattr GOT_NOTHING
-    Type "enum nvp_action"
-}
-
-Group copier {
-    Attr COPY_TO_NAME
-    Attr COPY_TO_MINOR
-    Attr COPY_TO_VALUE
-    Defattr COPY_NOWHERE
-    Type "enum nvp_copier"
-}
-
-# vim:et:sts=4:sw=4:ht=8
-
diff --git a/src/nvptypes.h b/src/nvptypes.h
@@ -1,43 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2006,2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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 NVPTYPES_H
-#define NVPTYPES_H
-
-enum nvp_action {
-  GOT_NAMEVALUE,
-  GOT_NAMEVALUE_CONT,
-  GOT_NAME,
-  GOT_NAME_TRAILING_SPACE,
-  GOT_MAJORMINOR,
-  GOT_TERMINATOR,
-  GOT_NOTHING
-};
-
-enum nvp_copier {
-  COPY_TO_NAME,
-  COPY_TO_MINOR,
-  COPY_TO_VALUE,
-  COPY_NOWHERE
-};
-
-#endif
diff --git a/src/rfc822_mairix.c b/src/rfc822_mairix.c
@@ -1,1536 +0,0 @@
-/*
-  mairix - message index builder and finder for maildir folders.
-
- **********************************************************************
- * Copyright (C) Richard P. Curnow  2002,2003,2004,2005,2006,2007,2010
- * rfc2047 decode:
- * Copyright (C) Mikael Ylikoski 2002
- * gzip mbox support:
- * Copyright (C) Ico Doornekamp 2005
- * Copyright (C) Felipe Gustavo de Almeida 2005
- * bzip2 mbox support:
- * Copyright (C) Paramjit Oberoi 2005
- * caching uncompressed mbox data:
- * Copyright (C) Chris Mason 2006
- * memory leak fixes:
- * Copyright (C) Samuel Tardieu 2008
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- **********************************************************************
- */
-
-#include "mairix.h"
-#include "nvp.h"
-
-#include <assert.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#ifdef USE_GZIP_MBOX
-#  include <zlib.h>
-#endif
-#ifdef USE_BZIP_MBOX
-#  include <bzlib.h>
-#endif
-
-struct DLL {/*{{{*/
-  struct DLL *next;
-  struct DLL *prev;
-};
-/*}}}*/
-static void enqueue(void *head, void *x)/*{{{*/
-{
-  /* Declare this way so it can be used with any kind of double linked list
-   * having next & prev pointers in its first two words. */
-  struct DLL *h = (struct DLL *) head;
-  struct DLL *xx = (struct DLL *) x;
-  xx->next = h;
-  xx->prev = h->prev;
-  h->prev->next = xx;
-  h->prev = xx;
-  return;
-}
-/*}}}*/
-
-enum encoding_type {/*{{{*/
-  ENC_UNKNOWN,
-  ENC_NONE,
-  ENC_BINARY,
-  ENC_7BIT,
-  ENC_8BIT,
-  ENC_QUOTED_PRINTABLE,
-  ENC_BASE64,
-  ENC_UUENCODE
-};
-/*}}}*/
-struct content_type_header {/*{{{*/
-  const char *major; /* e.g. text */
-  const char *minor; /* e.g. plain */
-  const char *boundary; /* for multipart */
-  /* charset? */
-};
-/*}}}*/
-struct line {/*{{{*/
-  struct line *next;
-  struct line *prev;
-  char *text;
-};
-/*}}}*/
-
-static void init_headers(struct headers *hdrs)/*{{{*/
-{
-  hdrs->to = NULL;
-  hdrs->cc = NULL;
-  hdrs->from = NULL;
-  hdrs->subject = NULL;
-  hdrs->message_id = NULL;
-  hdrs->in_reply_to = NULL;
-  hdrs->references = NULL;
-  hdrs->date = 0;
-  hdrs->flags.seen = 0;
-  hdrs->flags.replied = 0;
-  hdrs->flags.flagged = 0;
-};
-/*}}}*/
-static void splice_header_lines(struct line *header)/*{{{*/
-{
-  /* Deal with newline then tab in header */
-  struct line *x, *next;
-  for (x=header->next; x!=header; x=next) {
-#if 0
-    printf("next header, x->text=%08lx\n", x->text);
-    printf("header=<%s>\n", x->text);
-#endif
-    next = x->next;
-    if (isspace(x->text[0] & 0xff)) {
-      /* Glue to previous line */
-      char *p, *newbuf, *oldbuf;
-      struct line *y;
-      for (p=x->text; *p; p++) {
-        if (!isspace(*(unsigned char *)p)) break;
-      }
-      p--; /* point to final space */
-      y = x->prev;
-#if 0
-      printf("y=%08lx p=%08lx\n", y->text, p);
-#endif
-      newbuf = new_array(char, strlen(y->text) + strlen(p) + 1);
-      strcpy(newbuf, y->text);
-      strcat(newbuf, p);
-      oldbuf = y->text;
-      y->text = newbuf;
-      free(oldbuf);
-      y->next = x->next;
-      x->next->prev = y;
-      free(x->text);
-      free(x);
-    }
-  }
-  return;
-}
-/*}}}*/
-static int audit_header(struct line *header)/*{{{*/
-{
-  /* Check for obvious broken-ness
-   * 1st line has no leading spaces, single word then colon
-   * following lines have leading spaces or single word followed by colon
-   * */
-  struct line *x;
-  int first=1;
-  int count=1;
-  for (x=header->next; x!=header; x=x->next) {
-    int has_leading_space=0;
-    int is_blank;
-    int has_word_colon=0;
-
-    if (1 || first) {
-      /* Ignore any UUCP or mbox style From line at the start */
-      if (!strncmp("From ", x->text, 5)) {
-        continue;
-      }
-      /* Ignore escaped From line at the start */
-      if (!strncmp(">From ", x->text, 6)) {
-        continue;
-      }
-    }
-
-    is_blank = !(x->text[0]);
-    if (!is_blank) {
-      char *p;
-      int saw_char = 0;
-      has_leading_space = isspace(x->text[0] & 0xff);
-      has_word_colon = 0; /* default */
-      p = x->text;
-      while(*p) {
-        if(*p == ':') {
-          has_word_colon = saw_char;
-          break;
-        } else if (isspace(*(unsigned char *) p)) {
-          has_word_colon = 0;
-          break;
-        } else {
-          saw_char = 1;
-        }
-        p++;
-      }
-    }
-
-    if (( first && (is_blank || has_leading_space || !has_word_colon)) ||
-        (!first && (is_blank || !(has_leading_space || has_word_colon)))) {
-#if 0
-      fprintf(stderr, "Header line %d <%s> fails because:", count, x->text);
-      if (first && is_blank) { fprintf(stderr, " [first && is_blank]"); }
-      if (first && has_leading_space) { fprintf(stderr, " [first && has_leading_space]"); }
-      if (first && !has_word_colon) { fprintf(stderr, " [first && !has_word_colon]"); }
-      if (!first && is_blank) { fprintf(stderr, " [!first && is_blank]"); }
-      if (!first && !(has_leading_space||has_word_colon)) { fprintf(stderr, " [!first && !has_leading_space||has_word_colon]"); }
-      fprintf(stderr, "\n");
-#endif
-      /* Header fails the audit */
-      return 0;
-    }
-    first = 0;
-    count++;
-  }
-  /* If we get here the header must have been OK */
-  return 1;
-}/*}}}*/
-static int match_string(const char *ref, const char *candidate)/*{{{*/
-{
-  int len = strlen(ref);
-  return !strncasecmp(ref, candidate, len);
-}
-/*}}}*/
-
-static char equal_table[] = {/*{{{*/
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 00-0f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 10-1f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 20-2f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,  /* 30-3f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 40-4f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 50-5f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 60-6f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 70-7f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 80-8f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 90-9f */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* a0-af */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* b0-bf */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* c0-cf */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* d0-df */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* e0-ef */
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   /* f0-ff */
-};
-/*}}}*/
-static int base64_table[] = {/*{{{*/
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 00-0f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 10-1f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  62,  -1,  -1,  -1,  63,  /* 20-2f */
-   52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  -1,  -1,  -1,   0,  -1,  -1,  /* 30-3f */
-   -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  /* 40-4f */
-   15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  -1,  -1,  -1,  -1,  -1,  /* 50-5f */
-   -1,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  /* 60-6f */
-   41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  -1,  -1,  -1,  -1,  -1,  /* 70-7f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 80-8f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* 90-9f */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* a0-af */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* b0-bf */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* c0-cf */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* d0-df */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  /* e0-ef */
-   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1   /* f0-ff */
-};
-/*}}}*/
-static int hex_to_val(char x) {/*{{{*/
-  switch (x) {
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      return (x - '0');
-      break;
-    case 'a':
-    case 'b':
-    case 'c':
-    case 'd':
-    case 'e':
-    case 'f':
-      return 10 + (x - 'a');
-      break;
-    case 'A':
-    case 'B':
-    case 'C':
-    case 'D':
-    case 'E':
-    case 'F':
-      return 10 + (x - 'A');
-      break;
-    default:
-      return 0;
-  }
-}
-/*}}}*/
-static void decode_header_value(char *text){/*{{{*/
-  /* rfc2047 decode, written by Mikael Ylikoski */
-
-  char *s, *a, *b, *e, *p, *q;
-
-  for (p = q = s = text; (s = strstr(s, "=?")); s = e + 2) {
-    if (p == q)
-      p = q = s;
-    else
-      while (q != s)
-        *p++ = *q++;
-    s += 2;
-    a = strchr(s, '?');
-    if (!a) break;
-    a++;
-    b = strchr(a, '?');
-    if (!b) break;
-    b++;
-    e = strstr(b, "?=");
-    if (!e) break;
-    /* have found an encoded-word */
-    if (b - a != 2)
-      continue; /* unknown encoding */
-    if (*a == 'q' || *a == 'Q') {
-      int val;
-      q = b;
-      while (q < e) {
-        if (*q == '_') {
-          *p++ = 0x20;
-          q++;
-        } else if (*q == '=') {
-          q++;
-          val = hex_to_val(*q++) << 4;
-          val += hex_to_val(*q++);
-          *p++ = val;
-        } else
-          *p++ = *q++;
-      }
-    } else if (*a == 'b' || *a == 'B') {
-      int reg, nc, eq; /* register, #characters in reg, #equals */
-      int dc; /* decoded character */
-      eq = reg = nc = 0;
-      for (q = b; q < e; q++) {
-        unsigned char cq = *(unsigned char *)q;
-        dc = base64_table[cq];
-        eq += equal_table[cq];
-
-        if (dc >= 0) {
-          reg <<= 6;
-          reg += dc;
-          nc++;
-          if (nc == 4) {
-            *p++ = ((reg >> 16) & 0xff);
-            if (eq < 2) *p++ = ((reg >> 8) & 0xff);
-            if (eq < 1) *p++ = reg & 0xff;
-            nc = reg = 0;
-            if (eq) break;
-          }
-        }
-      }
-    } else {
-      continue; /* unknown encoding */
-    }
-    q = e + 2;
-  }
-  if (p == q) return;
-  while (*q != '\0')
-    *p++ = *q++;
-  *p = '\0';
-}
-/*}}}*/
-static char *copy_header_value(char *text){/*{{{*/
-  char *p;
-  for (p = text; *p && (*p != ':'); p++) ;
-  if (!*p) return NULL;
-  p++;
-  p = new_string(p);
-  decode_header_value(p);
-  return p;
-}
-/*}}}*/
-static void copy_or_concat_header_value(char **previous, char *text){/*{{{*/
-  char *p = copy_header_value(text);
-  if (*previous)
-  {
-    *previous = extend_string(*previous, ", ");
-    *previous = extend_string(*previous, p);
-    free(p);
-  }
-  else
-    *previous = p;
-}
-/*}}}*/
-static enum encoding_type decode_encoding_type(const char *e)/*{{{*/
-{
-  enum encoding_type result;
-  const char *p;
-  if (!e) {
-    result = ENC_NONE;
-  } else {
-    for (p=e; *p && isspace(*(unsigned char *)p); p++) ;
-    if (   match_string("7bit", p)
-        || match_string("7-bit", p)
-        || match_string("7 bit", p)) {
-      result = ENC_7BIT;
-    } else if (match_string("8bit", p)
-            || match_string("8-bit", p)
-            || match_string("8 bit", p)) {
-      result = ENC_8BIT;
-    } else if (match_string("quoted-printable", p)) {
-      result = ENC_QUOTED_PRINTABLE;
-    } else if (match_string("base64", p)) {
-      result = ENC_BASE64;
-    } else if (match_string("binary", p)) {
-      result = ENC_BINARY;
-    } else if (match_string("x-uuencode", p)) {
-      result = ENC_UUENCODE;
-    } else {
-      fprintf(stderr, "Warning: unknown encoding type: '%s'\n", e);
-      result = ENC_UNKNOWN;
-    }
-  }
-  return result;
-}
-/*}}}*/
-static void parse_content_type(struct nvp *ct_nvp, struct content_type_header *result)/*{{{*/
-{
-  result->major = NULL;
-  result->minor = NULL;
-  result->boundary = NULL;
-
-  result->major = nvp_major(ct_nvp);
-  if (result->major) {
-    result->minor = nvp_minor(ct_nvp);
-  } else {
-    result->minor = NULL;
-    result->major = nvp_first(ct_nvp);
-  }
-
-  result->boundary = nvp_lookupcase(ct_nvp, "boundary");
-}
-
-/*}}}*/
-static char *looking_at_ws_then_newline(char *start)/*{{{*/
-{
-  char *result;
-  result = start;
-  do {
-         if (*result == '\n')   return result;
-    else if (!isspace(*(unsigned char *) result)) return NULL;
-    else                        result++;
-  } while (1);
-
-  /* Can't get here */
-  assert(0);
-}
-/*}}}*/
-
-static char *unencode_data(struct msg_src *src, char *input, int input_len, const char *enc, int *output_len)/*{{{*/
-{
-  enum encoding_type encoding;
-  char *result, *end_result;
-  char *end_input;
-
-  encoding = decode_encoding_type(enc);
-  end_input = input + input_len;
-
-  /* All mime encodings result in expanded data, so this is guaranteed to
-   * safely oversize the output array */
-  result = new_array(char, input_len + 1);
-
-  /* Now decode */
-  switch (encoding) {
-    case ENC_7BIT:/*{{{*/
-    case ENC_8BIT:
-    case ENC_BINARY:
-    case ENC_NONE:
-      {
-        memcpy(result, input, input_len);
-        end_result = result + input_len;
-      }
-      break;
-/*}}}*/
-    case ENC_QUOTED_PRINTABLE:/*{{{*/
-      {
-        char *p, *q;
-        p = result;
-        for (p=result, q=input;
-             q<end_input; ) {
-
-          if (*q == '=') {
-            /* followed by optional whitespace then \n?  discard them. */
-            char *r;
-            int val;
-            q++;
-            r = looking_at_ws_then_newline(q);
-            if (r) {
-              q = r + 1; /* Point into next line */
-              continue;
-            }
-            /* not that case. */
-            val =  hex_to_val(*q++) << 4;
-            val += hex_to_val(*q++);
-            *p++ = val;
-
-          } else {
-            /* Normal character */
-            *p++ = *q++;
-          }
-        }
-        end_result = p;
-      }
-      break;
-/*}}}*/
-    case ENC_BASE64:/*{{{*/
-      {
-        char *p, *q;
-        int reg, nc, eq; /* register, #characters in reg, #equals */
-        int dc; /* decoded character */
-        eq = reg = nc = 0;
-        for (q=input, p=result; q<end_input; q++) {
-          unsigned char cq =  * (unsigned char *)q;
-          /* Might want a 256 entry array instead of this sub-optimal mess
-           * eventually. */
-          dc = base64_table[cq];
-          eq += equal_table[cq];
-
-          if (dc >= 0) {
-            reg <<= 6;
-            reg += dc;
-            nc++;
-            if (nc == 4) {
-              *p++ = ((reg >> 16) & 0xff);
-              if (eq < 2) *p++ = ((reg >> 8) & 0xff);
-              if (eq < 1) *p++ = reg & 0xff;
-              nc = reg = 0;
-              if (eq) goto done_base_64;
-            }
-          }
-        }
-      done_base_64:
-        end_result = p;
-      }
-      break;
-        /*}}}*/
-    case ENC_UUENCODE:/*{{{*/
-      {
-        char *p, *q;
-        /* Find 'begin ' */
-        for (q = input; q < end_input - 6 && memcmp(q, "begin ", 6); q++)
-          ;
-        q += 6;
-        /* skip to EOL */
-        while (q < end_input && *q != '\n')
-          q++;
-        p = result;
-        while (q < end_input) { /* process line */
-#define DEC(c) (((c) - ' ') & 077)
-          int len = DEC(*q++);
-          if (len == 0)
-            break;
-          for (; len > 0; q += 4, len -= 3) {
-            if (len >= 3) {
-              *p++ = DEC(q[0]) << 2 | DEC(q[1]) >> 4;
-              *p++ = DEC(q[1]) << 4 | DEC(q[2]) >> 2;
-              *p++ = DEC(q[2]) << 6 | DEC(q[3]);
-            } else {
-              if (len >= 1)
-                *p++ = DEC(q[0]) << 2 | DEC(q[1]) >> 4;
-              if (len >= 2)
-                *p++ = DEC(q[1]) << 4 | DEC(q[2]) >> 2;
-            }
-          }
-          while (q < end_input && *q != '\n')
-            q++;
-        }
-        end_result = p;
-      }
-      break;
-        /*}}}*/
-    case ENC_UNKNOWN:/*{{{*/
-      fprintf(stderr, "Unknown encoding type in %s\n", format_msg_src(src));
-      /* fall through - ignore this data */
-    /*}}}*/
-    default:/*{{{*/
-      end_result = result;
-      break;
-      /*}}}*/
-  }
-  *output_len = end_result - result;
-  result[*output_len] = '\0'; /* for convenience with text/plain etc to make it printable */
-  return result;
-}
-/*}}}*/
-char *format_msg_src(struct msg_src *src)/*{{{*/
-{
-  static char *buffer = NULL;
-  static int buffer_len = 0;
-  char *result;
-  int len;
-  switch (src->type) {
-    case MS_FILE:
-      result = src->filename;
-      break;
-    case MS_MBOX:
-      len = strlen(src->filename);
-      len += 32;
-      if (!buffer || (len > buffer_len)) {
-        free(buffer);
-        buffer = new_array(char, len);
-        buffer_len = len;
-      }
-      sprintf(buffer, "%s[%d,%d)", src->filename,
-          (int) src->start, (int) (src->start + src->len));
-      result = buffer;
-      break;
-    default:
-      result = NULL;
-      break;
-  }
-  return result;
-}
-/*}}}*/
-static int split_and_splice_header(struct msg_src *src, char *data, struct line *header, char **body_start)/*{{{*/
-{
-  char *sol, *eol;
-  int blank_line;
-  header->next = header->prev = header;
-  sol = data;
-  do {
-    if (!*sol) break;
-    blank_line = 1; /* until proven otherwise */
-    eol = sol;
-    while (*eol && (*eol != '\n')) {
-      if (!isspace(*(unsigned char *) eol)) blank_line = 0;
-      eol++;
-    }
-    if (*eol == '\n') {
-      if (!blank_line) {
-        int line_length = eol - sol;
-        char *line_text = new_array(char, 1 + line_length);
-        struct line *new_header;
-
-        strncpy(line_text, sol, line_length);
-        line_text[line_length] = '\0';
-        new_header = new(struct line);
-        new_header->text = line_text;
-        enqueue(header, new_header);
-      }
-      sol = eol + 1; /* Start of next line */
-    } else { /* must be null char */
-      fprintf(stderr, "Got null character whilst processing header of %s\n",
-          format_msg_src(src));
-      return -1; /* & leak memory */
-    }
-  } while (!blank_line);
-
-  *body_start = sol;
-
-  if (audit_header(header)) {
-    splice_header_lines(header);
-    return 0;
-  } else {
-#if 0
-    /* Caller generates message */
-    fprintf(stderr, "Message had bad rfc822 headers, ignoring\n");
-#endif
-    return -1;
-  }
-}
-/*}}}*/
-
-/* Forward prototypes */
-static void do_multipart(struct msg_src *src, char *input, int input_len,
-    const char *boundary, struct attachment *atts,
-    enum data_to_rfc822_error *error);
-
-/*{{{ do_body() */
-static void do_body(struct msg_src *src,
-    char *body_start, int body_len,
-    struct nvp *ct_nvp, struct nvp *cte_nvp,
-    struct nvp *cd_nvp,
-    struct attachment *atts,
-    enum data_to_rfc822_error *error)
-{
-  char *decoded_body;
-  int decoded_body_len;
-  const char *content_transfer_encoding;
-  content_transfer_encoding = NULL;
-  if (cte_nvp) {
-    content_transfer_encoding = nvp_first(cte_nvp);
-    if (!content_transfer_encoding) {
-      fprintf(stderr, "Giving up on %s, content_transfer_encoding header not parseable\n",
-          format_msg_src(src));
-      return;
-    }
-  }
-
-  decoded_body = unencode_data(src, body_start, body_len, content_transfer_encoding, &decoded_body_len);
-
-  if (ct_nvp) {
-    struct content_type_header ct;
-    parse_content_type(ct_nvp, &ct);
-    if (ct.major && !strcasecmp(ct.major, "multipart")) {
-      do_multipart(src, decoded_body, decoded_body_len, ct.boundary, atts, error);
-      /* Don't need decoded body any longer - copies have been taken if
-       * required when handling multipart attachments. */
-      free(decoded_body);
-      if (error && (*error == DTR8_MISSING_END)) return;
-    } else {
-      /* unipart */
-      struct attachment *new_att;
-      const char *disposition;
-      new_att = new(struct attachment);
-      disposition = cd_nvp ? nvp_first(cd_nvp) : NULL;
-      if (disposition && !strcasecmp(disposition, "attachment")) {
-        const char *lookup;
-        lookup = nvp_lookupcase(cd_nvp, "filename");
-        if (lookup) {
-          new_att->filename = new_string(lookup);
-        } else {
-          /* Some messages have name=... in content-type: instead of
-           * filename=... in content-disposition. */
-          lookup = nvp_lookup(ct_nvp, "name");
-          if (lookup) {
-            new_att->filename = new_string(lookup);
-          } else {
-            new_att->filename = NULL;
-          }
-        }
-      } else {
-        new_att->filename = NULL;
-      }
-      if (ct.major && !strcasecmp(ct.major, "text")) {
-        if (ct.minor && !strcasecmp(ct.minor, "plain")) {
-          new_att->ct = CT_TEXT_PLAIN;
-        } else if (ct.minor && !strcasecmp(ct.minor, "html")) {
-          new_att->ct = CT_TEXT_HTML;
-        } else {
-          new_att->ct = CT_TEXT_OTHER;
-        }
-      } else if (ct.major && !strcasecmp(ct.major, "message") &&
-                 ct.minor && !strcasecmp(ct.minor, "rfc822")) {
-        new_att->ct = CT_MESSAGE_RFC822;
-      } else {
-        new_att->ct = CT_OTHER;
-      }
-
-      if (new_att->ct == CT_MESSAGE_RFC822) {
-        new_att->data.rfc822 = data_to_rfc822(src, decoded_body, decoded_body_len, error);
-        free(decoded_body); /* data no longer needed */
-      } else {
-        new_att->data.normal.len = decoded_body_len;
-        new_att->data.normal.bytes = decoded_body;
-      }
-      enqueue(atts, new_att);
-    }
-  } else {
-    /* Treat as text/plain {{{*/
-    struct attachment *new_att;
-    new_att = new(struct attachment);
-    new_att->filename = NULL;
-    new_att->ct = CT_TEXT_PLAIN;
-    new_att->data.normal.len = decoded_body_len;
-    /* Add null termination on the end */
-    new_att->data.normal.bytes = new_array(char, decoded_body_len + 1);
-    memcpy(new_att->data.normal.bytes, decoded_body, decoded_body_len + 1);
-    free(decoded_body);
-    enqueue(atts, new_att);/*}}}*/
-  }
-}
-/*}}}*/
-/*{{{ do_attachment() */
-static void do_attachment(struct msg_src *src,
-    char *start, char *after_end,
-    struct attachment *atts)
-{
-  /* decode attachment and add to attachment list */
-  struct line header, *x, *nx;
-  char *body_start;
-  int body_len;
-
-  struct nvp *ct_nvp, *cte_nvp, *cd_nvp, *nvp;
-
-  if (split_and_splice_header(src, start, &header, &body_start) < 0) {
-    fprintf(stderr, "Giving up on attachment with bad header in %s\n",
-        format_msg_src(src));
-    return;
-  }
-
-  /* Extract key headers */
-  ct_nvp = cte_nvp = cd_nvp = NULL;
-  for (x=header.next; x!=&header; x=x->next) {
-    if ((nvp = make_nvp(src, x->text, "content-type:"))) {
-      ct_nvp = nvp;
-    } else if ((nvp = make_nvp(src, x->text, "content-transfer-encoding:"))) {
-      cte_nvp = nvp;
-    } else if ((nvp = make_nvp(src, x->text, "content-disposition:"))) {
-      cd_nvp = nvp;
-    }
-  }
-
-#if 0
-  if (ct_nvp) {
-    fprintf(stderr, "======\n");
-    fprintf(stderr, "Dump of content-type hdr\n");
-    nvp_dump(ct_nvp, stderr);
-    free(ct_nvp);
-  }
-
-  if (cte_nvp) {
-    fprintf(stderr, "======\n");
-    fprintf(stderr, "Dump of content-transfer-encoding hdr\n");
-    nvp_dump(cte_nvp, stderr);
-    free(cte_nvp);
-  }
-#endif
-
-  if (body_start > after_end) {
-    /* This is a (maliciously?) b0rken attachment, e.g. maybe empty */
-    if (verbose) {
-      fprintf(stderr, "Message %s contains an invalid attachment, length=%d bytes\n",
-          format_msg_src(src), (int)(after_end - start));
-    }
-  } else {
-    body_len = after_end - body_start;
-    /* Ignore errors in nested body parts. */
-    do_body(src, body_start, body_len, ct_nvp, cte_nvp, cd_nvp, atts, NULL);
-  }
-
-  /* Free header memory */
-  for (x=header.next; x!=&header; x=nx) {
-    nx = x->next;
-    free(x->text);
-    free(x);
-  }
-
-  if (ct_nvp) free_nvp(ct_nvp);
-  if (cte_nvp) free_nvp(cte_nvp);
-  if (cd_nvp) free_nvp(cd_nvp);
-}
-/*}}}*/
-/*{{{ do_multipart() */
-static void do_multipart(struct msg_src *src,
-    char *input, int input_len,
-    const char *boundary,
-    struct attachment *atts,
-    enum data_to_rfc822_error *error)
-{
-  char *b0, *b1, *be, *bx;
-  char *line_after_b0, *start_b1_search_from;
-  int boundary_len;
-  int looking_at_end_boundary;
-
-  if (!boundary) {
-    fprintf(stderr, "Can't process multipart message %s with no boundary string\n",
-        format_msg_src(src));
-    if (error) *error = DTR8_MULTIPART_SANS_BOUNDARY;
-    return;
-  }
-
-  boundary_len = strlen(boundary);
-
-  b0 = NULL;
-  line_after_b0 = input;
-  be = input + input_len;
-
-  do {
-    int boundary_ok;
-    start_b1_search_from = line_after_b0;
-    do {
-      /* reject boundaries that aren't a whole line */
-      b1 = NULL;
-      for (bx = start_b1_search_from; bx < be - (boundary_len + 4); bx++) {
-        if (bx[0] == '-' && bx[1] == '-' &&
-            !strncmp(bx+2, boundary, boundary_len)) {
-          b1 = bx;
-          break;
-        }
-      }
-      if (!b1) {
-        if (error)
-          *error = DTR8_MISSING_END;
-        return;
-      }
-
-      looking_at_end_boundary = (b1[boundary_len+2] == '-' &&
-          b1[boundary_len+3] == '-');
-      boundary_ok = 1;
-      if ((b1 > input) && (*(b1-1) != '\n'))
-        boundary_ok = 0;
-      if (!looking_at_end_boundary && (b1 + boundary_len + 2 < input + input_len) && (*(b1 + boundary_len + 2) != '\n'))
-        boundary_ok = 0;
-      if (!boundary_ok) {
-        char *eol = strchr(b1, '\n');
-        if (!eol) {
-          fprintf(stderr, "Oops, didn't find another normal boundary in %s\n",
-              format_msg_src(src));
-          return;
-        }
-        start_b1_search_from = 1 + eol;
-      }
-    } while (!boundary_ok);
-
-    /* b1 is now looking at a good boundary, which might be the final one */
-
-    if (b0) {
-      /* don't treat preamble as an attachment */
-      do_attachment(src, line_after_b0, b1, atts);
-    }
-
-    b0 = b1;
-    line_after_b0 = strchr(b0, '\n');
-    if (line_after_b0 == 0)
-      line_after_b0 = b0 + strlen(b0);
-    else
-      ++line_after_b0;
-  } while (b1 < be && !looking_at_end_boundary);
-}
-/*}}}*/
-static time_t parse_rfc822_date(char *date_string)/*{{{*/
-{
-  struct tm tm;
-  char *s, *z;
-  /* Format [weekday ,] day-of-month month year hour:minute:second timezone.
-
-     Some of the ideas, sanity checks etc taken from parse.c in the mutt
-     sources, credit to Michael R. Elkins et al
-     */
-
-  s = date_string;
-  z = strchr(s, ',');
-  if (z) s = z + 1;
-  while (*s && isspace(*s)) s++;
-  /* Should now be looking at day number */
-  if (!isdigit(*s)) goto tough_cheese;
-  tm.tm_mday = atoi(s);
-  if (tm.tm_mday > 31) goto tough_cheese;
-
-  while (isdigit(*s)) s++;
-  while (*s && isspace(*s)) s++;
-  if (!*s) goto tough_cheese;
-  if      (!strncasecmp(s, "jan", 3)) tm.tm_mon =  0;
-  else if (!strncasecmp(s, "feb", 3)) tm.tm_mon =  1;
-  else if (!strncasecmp(s, "mar", 3)) tm.tm_mon =  2;
-  else if (!strncasecmp(s, "apr", 3)) tm.tm_mon =  3;
-  else if (!strncasecmp(s, "may", 3)) tm.tm_mon =  4;
-  else if (!strncasecmp(s, "jun", 3)) tm.tm_mon =  5;
-  else if (!strncasecmp(s, "jul", 3)) tm.tm_mon =  6;
-  else if (!strncasecmp(s, "aug", 3)) tm.tm_mon =  7;
-  else if (!strncasecmp(s, "sep", 3)) tm.tm_mon =  8;
-  else if (!strncasecmp(s, "oct", 3)) tm.tm_mon =  9;
-  else if (!strncasecmp(s, "nov", 3)) tm.tm_mon = 10;
-  else if (!strncasecmp(s, "dec", 3)) tm.tm_mon = 11;
-  else goto tough_cheese;
-
-  while (!isspace(*s)) s++;
-  while (*s && isspace(*s)) s++;
-  if (!isdigit(*s)) goto tough_cheese;
-  tm.tm_year = atoi(s);
-  if (tm.tm_year < 70) {
-    tm.tm_year += 100;
-  } else if (tm.tm_year >= 1900) {
-    tm.tm_year -= 1900;
-  }
-
-  while (isdigit(*s)) s++;
-  while (*s && isspace(*s)) s++;
-  if (!*s) goto tough_cheese;
-
-  /* Now looking at hms */
-  /* For now, forget this.  The searching will be vague enough that nearest day is good enough. */
-
-  tm.tm_hour = 0;
-  tm.tm_min = 0;
-  tm.tm_sec = 0;
-  tm.tm_isdst = 0;
-  return mktime(&tm);
-
-tough_cheese:
-  return (time_t) -1; /* default value */
-}
-/*}}}*/
-
-static void scan_status_flags(const char *s, struct headers *hdrs)/*{{{*/
-{
-  const char *p;
-  for (p=s; *p; p++) {
-    switch (*p) {
-      case 'R': hdrs->flags.seen = 1; break;
-      case 'A': hdrs->flags.replied = 1; break;
-      case 'F': hdrs->flags.flagged = 1; break;
-      default: break;
-    }
-  }
-}
-/*}}}*/
-
-/*{{{ data_to_rfc822() */
-struct rfc822 *data_to_rfc822(struct msg_src *src,
-    char *data, int length,
-    enum data_to_rfc822_error *error)
-{
-  struct rfc822 *result;
-  char *body_start;
-  struct line header;
-  struct line *x, *nx;
-  struct nvp *ct_nvp, *cte_nvp, *cd_nvp, *nvp;
-  int body_len;
-
-  if (error) *error = DTR8_OK; /* default */
-  result = new(struct rfc822);
-  init_headers(&result->hdrs);
-  result->atts.next = result->atts.prev = &result->atts;
-
-  if (split_and_splice_header(src, data, &header, &body_start) < 0) {
-    if (verbose) {
-      fprintf(stderr, "Giving up on message %s with bad header\n",
-          format_msg_src(src));
-    }
-    if (error) *error = DTR8_BAD_HEADERS;
-    return NULL;
-  }
-
-  /* Extract key headers {{{*/
-  ct_nvp = cte_nvp = cd_nvp = NULL;
-  for (x=header.next; x!=&header; x=x->next) {
-    if      (match_string("to", x->text))
-      copy_or_concat_header_value(&result->hdrs.to, x->text);
-    else if (match_string("cc", x->text))
-      copy_or_concat_header_value(&result->hdrs.cc, x->text);
-    else if (!result->hdrs.from && match_string("from", x->text))
-      result->hdrs.from = copy_header_value(x->text);
-    else if (!result->hdrs.subject && match_string("subject", x->text))
-      result->hdrs.subject = copy_header_value(x->text);
-    else if (!ct_nvp && (nvp = make_nvp(src, x->text, "content-type:")))
-      ct_nvp = nvp;
-    else if (!cte_nvp && (nvp = make_nvp(src, x->text, "content-transfer-encoding:")))
-      cte_nvp = nvp;
-    else if (!cd_nvp && (nvp = make_nvp(src, x->text, "content-disposition:")))
-      cd_nvp = nvp;
-    else if (!result->hdrs.date && match_string("date", x->text)) {
-      char *date_string = copy_header_value(x->text);
-      result->hdrs.date = parse_rfc822_date(date_string);
-      free(date_string);
-    } else if (!result->hdrs.message_id && match_string("message-id", x->text))
-      result->hdrs.message_id = copy_header_value(x->text);
-    else if (!result->hdrs.in_reply_to && match_string("in-reply-to", x->text))
-      result->hdrs.in_reply_to = copy_header_value(x->text);
-    else if (!result->hdrs.references && match_string("references", x->text))
-      result->hdrs.references = copy_header_value(x->text);
-    else if (match_string("status", x->text))
-      scan_status_flags(x->text + sizeof("status:"), &result->hdrs);
-    else if (match_string("x-status", x->text))
-      scan_status_flags(x->text + sizeof("x-status:"), &result->hdrs);
-  }
-/*}}}*/
-
-  /* Process body */
-  body_len = length - (body_start - data);
-  do_body(src, body_start, body_len, ct_nvp, cte_nvp, cd_nvp, &result->atts, error);
-
-  /* Free header memory */
-  for (x=header.next; x!=&header; x=nx) {
-    nx = x->next;
-    free(x->text);
-    free(x);
-  }
-
-  if (ct_nvp) free_nvp(ct_nvp);
-  if (cte_nvp) free_nvp(cte_nvp);
-  if (cd_nvp) free_nvp(cd_nvp);
-
-  return result;
-
-}
-/*}}}*/
-
-#define ALLOC_NONE   1
-#define ALLOC_MMAP   2
-#define ALLOC_MALLOC 3
-
-int data_alloc_type;
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-
-#define SIZE_STEP (8 * 1024 * 1024)
-
-#define COMPRESSION_NONE 0
-#define COMPRESSION_GZIP 1
-#define COMPRESSION_BZIP 2
-
-static int get_compression_type(const char *filename) {/*{{{*/
-  size_t len = strlen(filename);
-  int ptr;
-
-#ifdef USE_GZIP_MBOX
-  ptr = len - 3;
-  if (len > 3 && strncasecmp(filename + ptr, ".gz", 3) == 0) {
-    return COMPRESSION_GZIP;
-  }
-#endif
-
-#ifdef USE_BZIP_MBOX
-  ptr = len - 4;
-  if (len > 3 && strncasecmp(filename + ptr, ".bz2", 4) == 0) {
-    return COMPRESSION_BZIP;
-  }
-#endif
-
-  return COMPRESSION_NONE;
-}
-/*}}}*/
-
-static int is_compressed(const char *filename) {/*{{{*/
-  return (get_compression_type(filename) != COMPRESSION_NONE);
-}
-/*}}}*/
-
-struct zFile {/*{{{*/
-  union {
-    /* Both gzFile and BZFILE* are defined as void pointers
-     * in their respective header files.
-     */
-#ifdef USE_GZIP_MBOX
-    gzFile gzf;
-#endif
-#ifdef USE_BZIP_MBOX
-    BZFILE *bzf;
-#endif
-    void *zptr;
-  } foo;
-  int type;
-};
-/*}}}*/
-
-static struct zFile * xx_zopen(const char *filename, const char *mode) {/*{{{*/
-  struct zFile *zf = new(struct zFile);
-
-  zf->type = get_compression_type(filename);
-  switch (zf->type) {
-#ifdef USE_GZIP_MBOX
-    case COMPRESSION_GZIP:
-      zf->foo.gzf = gzopen(filename, "rb");
-      break;
-#endif
-#ifdef USE_BZIP_MBOX
-    case COMPRESSION_BZIP:
-      zf->foo.bzf = BZ2_bzopen(filename, "rb");
-      break;
-#endif
-    default:
-      zf->foo.zptr = NULL;
-      break;
-  }
-
-  if (!zf->foo.zptr) {
-    free(zf);
-    return 0;
-  }
-
-  return zf;
-}
-/*}}}*/
-static void xx_zclose(struct zFile *zf) {/*{{{*/
-  switch (zf->type) {
-#ifdef USE_GZIP_MBOX
-    case COMPRESSION_GZIP:
-      gzclose(zf->foo.gzf);
-      break;
-#endif
-#ifdef USE_BZIP_MBOX
-    case COMPRESSION_BZIP:
-      BZ2_bzclose(zf->foo.bzf);
-      break;
-#endif
-    default:
-      zf->foo.zptr = NULL;
-      break;
-  }
-  free(zf);
-}
-/*}}}*/
-static int xx_zread(struct zFile *zf, void *buf, int len) {/*{{{*/
-  switch (zf->type) {
-#ifdef USE_GZIP_MBOX
-    case COMPRESSION_GZIP:
-      return gzread(zf->foo.gzf, buf, len);
-      break;
-#endif
-#ifdef USE_BZIP_MBOX
-    case COMPRESSION_BZIP:
-      return BZ2_bzread(zf->foo.bzf, buf, len);
-      break;
-#endif
-    default:
-      return 0;
-      break;
-  }
-}
-/*}}}*/
-#endif
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-/* do we need ROCACHE_SIZE > 1? the code supports any number here */
-#define ROCACHE_SIZE 1
-struct ro_mapping {
-  char *filename;
-  unsigned char *map;
-  size_t len;
-};
-static int ro_cache_init = 0;
-static struct ro_mapping ro_mapping_cache[ROCACHE_SIZE];
-
-/* find a temp file in the mapping cache.  If nothing is found lasti is
- * set to the next slot to use for insertion.  You have to check that slot
- * to see if it is currently in use
- */
-static struct ro_mapping *find_ro_cache(const char *filename, int *lasti)
-{
-  int i = 0;
-  struct ro_mapping *ro = NULL;
-  if (lasti)
-    *lasti = 0;
-  if (!ro_cache_init)
-    return NULL;
-  for (i = 0 ; i < ROCACHE_SIZE ; i++) {
-    ro = ro_mapping_cache + i;
-    if (!ro->map) {
-      if (lasti)
-        *lasti = i;
-      return NULL;
-    }
-    if (strcmp(filename, ro->filename) == 0)
-      return ro;
-  }
-  /* if we're here, the map is full.  They will reuse slot 0 */
-  return NULL;
-}
-
-/*
- * put a new tempfile into the cache.  It is mmaped as part of this function
- * so you can safely close the file handle after calling this.
- */
-static struct ro_mapping *add_ro_cache(const char *filename, int fd, size_t len)
-{
-  int i = 0;
-  struct ro_mapping *ro = NULL;
-  if (!ro_cache_init) {
-    memset(&ro_mapping_cache, 0, sizeof(ro_mapping_cache));
-    ro_cache_init = 1;
-  }
-  ro = find_ro_cache(filename, &i);
-  if (ro) {
-    fprintf(stderr, "%s already in ro cache\n", filename);
-    return NULL;
-  }
-  ro = ro_mapping_cache + i;
-  if (ro->map) {
-    munmap(ro->map, ro->len);
-    ro->map = NULL;
-    free(ro->filename);
-  }
-  ro->map = (unsigned char *)mmap(0, len, PROT_READ, MAP_SHARED, fd, 0);
-  if (ro->map == MAP_FAILED) {
-    ro->map = NULL;
-    perror("rfc822:mmap");
-    return NULL;
-  }
-  ro->len = len;
-  ro->filename = new_string(filename);
-  return ro;
-}
-#endif /* USE_GZIP_MBOX || USE_BZIP_MBOX */
-
-void create_ro_mapping(const char *filename, unsigned char **data, int *len)/*{{{*/
-{
-  struct stat sb;
-  int fd;
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-  struct zFile *zf;
-#endif
-
-  if (stat(filename, &sb) < 0)
-  {
-    report_error("stat", filename);
-    *data = NULL;
-    return;
-  }
-
-#if USE_GZIP_MBOX || USE_BZIP_MBOX
-  if(is_compressed(filename)) {
-    unsigned char *p;
-    size_t cur_read;
-    struct ro_mapping *ro;
-    FILE *tmpf;
-
-    /* this branch never returns things that are freeable */
-    data_alloc_type = ALLOC_NONE;
-    ro = find_ro_cache(filename, NULL);
-    if (ro) {
-      *data = ro->map;
-      *len = ro->len;
-      return;
-    }
-
-    if(verbose) {
-      fprintf(stderr, "Decompressing %s...\n", filename);
-    }
-
-    tmpf = tmpfile();
-    if (!tmpf) {
-      perror("tmpfile");
-      goto comp_error;
-    }
-    zf = xx_zopen(filename, "rb");
-    if (!zf) {
-      fprintf(stderr, "Could not open %s\n", filename);
-      goto comp_error;
-    }
-    p = new_array(unsigned char, SIZE_STEP);
-    cur_read = xx_zread(zf, p, SIZE_STEP);
-    if (fwrite(p, cur_read, 1, tmpf) != 1) {
-      fprintf(stderr, "failed writing to temp file for %s\n", filename);
-      goto comp_error;
-    }
-    *len = cur_read;
-    if (cur_read >= SIZE_STEP) {
-      while(1) {
-        int ret;
-        cur_read = xx_zread(zf, p, SIZE_STEP);
-        if (cur_read <= 0)
-          break;
-        *len += cur_read;
-        ret = fwrite(p, cur_read, 1, tmpf);
-        if (ret != 1) {
-          fprintf(stderr, "failed writing to temp file for %s\n", filename);
-          goto comp_error;
-        }
-      }
-    }
-    free(p);
-    xx_zclose(zf);
-
-    if(*len > 0) {
-      ro = add_ro_cache(filename, fileno(tmpf), *len);
-      if (!ro)
-        goto comp_error;
-      *data = ro->map;
-      *len = ro->len;
-    } else {
-      *data = NULL;
-    }
-    fclose(tmpf);
-    return;
-
-comp_error:
-    *data = NULL;
-    *len = 0;
-    if (tmpf)
-      fclose(tmpf);
-    return;
-  }
-#endif /* USE_GZIP_MBOX || USE_BZIP_MBOX */
-
-  *len = sb.st_size;
-  if (*len == 0) {
-    *data = NULL;
-    return;
-  }
-
-  if (!S_ISREG(sb.st_mode)) {
-    *data = NULL;
-    return;
-  }
-
-  fd = open(filename, O_RDONLY);
-  if (fd < 0)
-  {
-    report_error("open", filename);
-    *data = NULL;
-    return;
-  }
-
-  *data = (unsigned char *) mmap(0, *len, PROT_READ, MAP_SHARED, fd, 0);
-  if (close(fd) < 0)
-    report_error("close", filename);
-  if (*data == MAP_FAILED) {
-    report_error("rfc822:mmap", filename);
-    *data = NULL;
-    return;
-  }
-  data_alloc_type = ALLOC_MMAP;
-}
-/*}}}*/
-void free_ro_mapping(unsigned char *data, int len)/*{{{*/
-{
-  int r;
-
-  if(data_alloc_type == ALLOC_MALLOC) {
-    free(data);
-  }
-
-  if(data_alloc_type == ALLOC_MMAP) {
-    r = munmap(data, len);
-    if(r < 0) {
-      fprintf(stderr, "munmap() errord\n");
-      exit(1);
-    }
-  }
-}
-/*}}}*/
-
-static struct msg_src *setup_msg_src(char *filename)/*{{{*/
-{
-  static struct msg_src result;
-  result.type = MS_FILE;
-  result.filename = filename;
-  return &result;
-}
-/*}}}*/
-struct rfc822 *make_rfc822(char *filename)/*{{{*/
-{
-  int len;
-  unsigned char *data;
-  struct rfc822 *result;
-
-  create_ro_mapping(filename, &data, &len);
-
-  /* Don't process empty files */
-  result = NULL;
-
-  if (data)
-  {
-    struct msg_src *src;
-    /* Now process the data */
-    src = setup_msg_src(filename);
-    /* For one message per file, ignore missing end boundary condition. */
-    result = data_to_rfc822(src, (char *) data, len, NULL);
-
-    free_ro_mapping(data, len);
-  }
-
-  return result;
-}
-/*}}}*/
-void free_rfc822(struct rfc822 *msg)/*{{{*/
-{
-  struct attachment *a, *na;
-
-  if (!msg) return;
-
-  if (msg->hdrs.to) free(msg->hdrs.to);
-  if (msg->hdrs.cc) free(msg->hdrs.cc);
-  if (msg->hdrs.from) free(msg->hdrs.from);
-  if (msg->hdrs.subject) free(msg->hdrs.subject);
-  if (msg->hdrs.message_id) free(msg->hdrs.message_id);
-  if (msg->hdrs.in_reply_to) free(msg->hdrs.in_reply_to);
-  if (msg->hdrs.references) free(msg->hdrs.references);
-
-  for (a = msg->atts.next; a != &msg->atts; a = na) {
-    na = a->next;
-    if (a->filename) free(a->filename);
-    if (a->ct == CT_MESSAGE_RFC822) {
-      free_rfc822(a->data.rfc822);
-    } else {
-      free(a->data.normal.bytes);
-    }
-    free(a);
-  }
-  free(msg);
-}
-/*}}}*/
-
-#ifdef TEST
-
-static void do_indent(int indent)/*{{{*/
-{
-  int i;
-  for (i=indent; i>0; i--) {
-    putchar(' ');
-  }
-}
-/*}}}*/
-static void show_header(char *tag, char *x, int indent)/*{{{*/
-{
-  if (x) {
-    do_indent(indent);
-    printf("%s: %s\n", tag, x);
-  }
-}
-/*}}}*/
-static void show_rfc822(struct rfc822 *msg, int indent)/*{{{*/
-{
-  struct attachment *a;
-  show_header("From", msg->hdrs.from, indent);
-  show_header("To", msg->hdrs.to, indent);
-  show_header("Cc", msg->hdrs.cc, indent);
-  show_header("Date", msg->hdrs.date, indent);
-  show_header("Subject", msg->hdrs.subject, indent);
-
-  for (a = msg->atts.next; a != &msg->atts; a=a->next) {
-    printf("========================\n");
-    switch (a->ct) {
-      case CT_TEXT_PLAIN: printf("Attachment type text/plain\n"); break;
-      case CT_TEXT_HTML: printf("Attachment type text/html\n"); break;
-      case CT_TEXT_OTHER: printf("Attachment type text/non-plain\n"); break;
-      case CT_MESSAGE_RFC822: printf("Attachment type message/rfc822\n"); break;
-      case CT_OTHER: printf("Attachment type other\n"); break;
-    }
-    if (a->ct != CT_MESSAGE_RFC822) {
-      printf("%d bytes\n", a->data.normal.len);
-    }
-    if ((a->ct == CT_TEXT_PLAIN) || (a->ct == CT_TEXT_HTML) || (a->ct == CT_TEXT_OTHER)) {
-      printf("----------\n");
-      printf("%s\n", a->data.normal.bytes);
-    }
-    if (a->ct == CT_MESSAGE_RFC822) {
-      show_rfc822(a->data.rfc822, indent + 4);
-    }
-  }
-}
-/*}}}*/
-
-int main (int argc, char **argv)/*{{{*/
-{
-  struct rfc822 *msg;
-
-  if (argc < 2) {
-    fprintf(stderr, "Need a path\n");
-    unlock_and_exit(2);
-  }
-
-  msg = make_rfc822(argv[1]);
-  show_rfc822(msg, 0);
-  free_rfc822(msg);
-
-  /* Print out some stuff */
-
-  return 0;
-}
-/*}}}*/
-#endif /* TEST */