diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,12 @@
+# 6.3.0.0
+
+  - Update to Bibutils 6.3.
+
+  - Enable NBIB support.
+
+  - Expose additional options values.
+
+
 # 6.2.0.1
 
   - This is a patch release fixing MacOS X compilation.
diff --git a/bibutils/adsout.c b/bibutils/adsout.c
--- a/bibutils/adsout.c
+++ b/bibutils/adsout.c
@@ -1,8 +1,8 @@
 /*
  * adsout.c
  *
- * Copyright (c) Richard Mathar 2007-2017
- * Copyright (c) Chris Putnam 2007-2017
+ * Copyright (c) Richard Mathar 2007-2018
+ * Copyright (c) Chris Putnam 2007-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -98,6 +98,7 @@
 		{ "communication",             TYPE_COMMUNICATION },
 		{ "manuscript",                TYPE_MANUSCRIPT },
 		{ "report",                    TYPE_REPORT },
+		{ "technical report",          TYPE_REPORT },
 		{ "legal case and case notes", TYPE_CASE },
 		{ "patent",                    TYPE_PATENT },
 	};
@@ -108,8 +109,9 @@
 
 	for ( i=0; i<in->n; ++i ) {
 		tag = in->tag[i].data;
-		if ( strcasecmp( tag, "GENRE" )!=0 &&
-		     strcasecmp( tag, "NGENRE" )!=0 ) continue;
+		if ( strcasecmp( tag, "GENRE:MARC" ) &&
+		     strcasecmp( tag, "GENRE:BIBUTILS" ) &&
+		     strcasecmp( tag, "GENRE:UNKNOWN" ) ) continue;
 		data = in->data[i].data;
 		for ( j=0; j<nmatch_genres; ++j ) {
 			if ( !strcasecmp( data, match_genres[j].name ) ) {
@@ -358,9 +360,9 @@
 	int n;
 
 	n = fields_find( in, "AUTHOR", LEVEL_MAIN );
-	if ( n==-1 ) n = fields_find( in, "AUTHOR", LEVEL_ANY );
+	if ( n==FIELDS_NOTFOUND ) n = fields_find( in, "AUTHOR", LEVEL_ANY );
 
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		name = fields_value( in, n, FIELDS_CHRP );
 		return name[0];
 	} else return '\0';
@@ -373,7 +375,7 @@
 	int n, j;
 
 	n = fields_find( in, "TITLE", LEVEL_HOST );
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		jrnl = fields_value( in, n, FIELDS_CHRP );
 		for ( j=0; j<njournals; j++ ) {
 			if ( !strcasecmp( jrnl, journals[j]+6 ) )
@@ -394,8 +396,8 @@
 
 	/** YYYY */
 	n = fields_find( in, "DATE:YEAR", LEVEL_ANY );
-	if ( n==-1 ) n = fields_find( in, "PARTDATE:YEAR", LEVEL_ANY );
-	if ( n!=-1 ) output_4digit_value( outstr, atoi( fields_value( in, n, FIELDS_CHRP ) ) );
+	if ( n==FIELDS_NOTFOUND ) n = fields_find( in, "PARTDATE:YEAR", LEVEL_ANY );
+	if ( n!=FIELDS_NOTFOUND ) output_4digit_value( outstr, atoi( fields_value( in, n, FIELDS_CHRP ) ) );
 
 	/** JJJJ */
 	n = get_journalabbr( in );
@@ -409,12 +411,12 @@
 
 	/** VVVV */
 	n = fields_find( in, "VOLUME", LEVEL_ANY );
-	if ( n!=-1 ) output_4digit_value( outstr+9, atoi( fields_value( in, n, FIELDS_CHRP ) ) );
+	if ( n!=FIELDS_NOTFOUND ) output_4digit_value( outstr+9, atoi( fields_value( in, n, FIELDS_CHRP ) ) );
 
 	/** MPPPP */
 	n = fields_find( in, "PAGES:START", LEVEL_ANY );
-	if ( n==-1 ) n = fields_find( in, "ARTICLENUMBER", LEVEL_ANY );
-	if ( n!=-1 ) {
+	if ( n==FIELDS_NOTFOUND ) n = fields_find( in, "ARTICLENUMBER", LEVEL_ANY );
+	if ( n!=FIELDS_NOTFOUND ) {
 		page = atoll( fields_value( in, n, FIELDS_CHRP ) );
 		output_4digit_value( outstr+14, page );
 		if ( page>=10000 ) {
diff --git a/bibutils/bibcore.c b/bibutils/bibcore.c
--- a/bibutils/bibcore.c
+++ b/bibutils/bibcore.c
@@ -1,7 +1,7 @@
 /*
  * bibcore.c
  *
- * Copyright (c) Chris Putnam 2005-2017
+ * Copyright (c) Chris Putnam 2005-2018
  *
  * Source code released under the GPL version 2
  *
@@ -43,16 +43,16 @@
 		case BIBL_BIBLATEXIN:   fprintf( fp, " (BIBL_BIBLATEXIN)\n" );   break;
 		case BIBL_EBIIN:        fprintf( fp, " (BIBL_EBIIN)\n" );        break;
 		case BIBL_WORDIN:       fprintf( fp, " (BIBL_WORDIN)\n" );       break;
-		default:                fprintf( fp, " (Illegal)\n" );           break;
+		case BIBL_NBIBIN:       fprintf( fp, " (BIBL_NBIBIN)\n" );       break;
+		default:                fprintf( fp, " (Illegal value %d)\n", p->readformat ); break;
 	}
 	fprintf( fp, "\tcharsetin=%d\n", p->charsetin );
-/*	fprintf( fp, "\tcharsetin=%d (%s)\n", p->charsetin, get_charsetname( p->charsetin ) );*/
 	fprintf( fp, "\tcharsetin_src=%d", p->charsetin_src );
 	switch ( p->charsetin_src ) {
 		case 0:  fprintf( fp, " (BIBL_SRC_DEFAULT)\n" ); break;
 		case 1:  fprintf( fp, " (BIBL_SRC_FILE)\n" );    break;
 		case 2:  fprintf( fp, " (BIBL_SRC_USER)\n" );    break;
-		default: fprintf( fp, " (Illegal value!)\n" );   break;
+		default: fprintf( fp, " (Illegal value %d)\n", p->charsetin_src );   break;
 	}
 	fprintf( fp, "\tutf8in=%d\n", p->utf8in );
 	fprintf( fp, "\tlatexin=%d\n", p->latexin );
@@ -68,16 +68,15 @@
 		case BIBL_ISIOUT:       fprintf( fp, " (BIBL_ISIOUT)\n" );       break;
 		case BIBL_WORD2007OUT:  fprintf( fp, " (BIBL_WORD2007OUT)\n" );  break;
 		case BIBL_ADSABSOUT:    fprintf( fp, " (BIBL_ADSABSOUT)\n" );    break;
-		default:                fprintf( fp, " (Illegal)\n" );           break;
+		default:                fprintf( fp, " (Illegal value %d)\n", p->writeformat ); break;
 	}
-/*	fprintf( fp, "\tcharsetout=%d (%s)\n", p->charsetout, get_charsetname( p->charsetout ) );*/
 	fprintf( fp, "\tcharsetout=%d\n", p->charsetout );
 	fprintf( fp, "\tcharsetout_src=%d", p->charsetout_src );
 	switch ( p->charsetout_src ) {
 		case 0:  fprintf( fp, " (BIBL_SRC_DEFAULT)\n" ); break;
 		case 1:  fprintf( fp, " (BIBL_SRC_FILE)\n" );    break;
 		case 2:  fprintf( fp, " (BIBL_SRC_USER)\n" );    break;
-		default: fprintf( fp, " (Illegal value!)\n" );   break;
+		default: fprintf( fp, " (Illegal value %d)\n", p->charsetout_src ); break;
 	}
 	fprintf( fp, "\tutf8out=%d\n", p->utf8out );
 	fprintf( fp, "\tutf8bom=%d\n", p->utf8bom );
@@ -274,7 +273,7 @@
 		case BIBL_ERR_CANTOPEN:
 			fprintf( stderr, "Can't open." ); break;
 		default:
-			fprintf( stderr, "Cannot identify error code."); break;
+			fprintf( stderr, "Cannot identify error code %d.", err ); break;
 	}
 	fprintf( stderr, "\n" );
 }
@@ -337,9 +336,9 @@
 /* extract_tag_value
  *
  * Extract the tag and the value for ALWAYS/DEFAULT
- * entries like: "NGENRE|Masters thesis"
+ * entries like: "GENRE:BIBUTILS|Masters thesis"
  *
- * tag = "NGENRE"
+ * tag = "GENRE:BIBUTILS"
  * value = "Masters thesis"
  */
 static int
@@ -394,7 +393,7 @@
 		}
 
 		n = fields_find( f, tag.data, level );
-		if ( n==-1 ) {
+		if ( n==FIELDS_NOTFOUND ) {
 			status = fields_add( f, tag.data, value.data, level );
 			if ( status!=FIELDS_OK ) {
 				ret = BIBL_ERR_MEMERR;
@@ -473,13 +472,11 @@
 			if ( !ok ) {
 				ret = BIBL_ERR_MEMERR;
 				bibl_free( bin );
-				fields_free( ref );
-				free( ref );
+				fields_delete( ref );
 				goto out;
 			}
 		} else {
-			fields_free( ref );
-			free( ref );
+			fields_delete( ref );
 		}
 		str_empty( &reference );
 		if ( fcharset!=CHARSET_UNKNOWN ) {
@@ -596,9 +593,9 @@
 		goto out;
 	}
 
-	status = fields_add( f, "REFNUM", refnum.data, 0 );
+	status = fields_add( f, "REFNUM", refnum.data, LEVEL_MAIN );
 	if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-	else *n = fields_find( f, "REFNUM", 0 );
+	else *n = fields_find( f, "REFNUM", LEVEL_MAIN );
 
 out:
 	str_free( &refnum );
@@ -616,8 +613,8 @@
 
 	for ( i=0; i<b->nrefs; ++i ) {
 		ref = b->ref[i];
-		n = fields_find( ref, "REFNUM", 0 );
-		if ( n==-1 ) {
+		n = fields_find( ref, "REFNUM", LEVEL_MAIN );
+		if ( n==FIELDS_NOTFOUND ) {
 			status = build_refnum( ref, i+1, &n );
 			if ( status!=BIBL_OK ) return status;
 		}
@@ -641,13 +638,13 @@
 
 	str_init( &citekey );
 
-	n1 = fields_find( f, "AUTHOR", 0 );
-	if ( n1==-1 ) n1 = fields_find( f, "AUTHOR", -1 );
-	n2 = fields_find( f, "DATE:YEAR", 0 );
-	if ( n2==-1 ) n2 = fields_find( f, "DATE:YEAR", -1 );
-	if ( n2==-1 ) n2 = fields_find( f, "PARTDATE:YEAR", 0 );
-	if ( n2==-1 ) n2 = fields_find( f, "PARTDATE:YEAR", -1 );
-	if ( n1!=-1 && n2!=-1 ) {
+	n1 = fields_find( f, "AUTHOR", LEVEL_MAIN );
+	if ( n1==FIELDS_NOTFOUND ) n1 = fields_find( f, "AUTHOR", LEVEL_ANY );
+	n2 = fields_find( f, "DATE:YEAR", LEVEL_MAIN );
+	if ( n2==FIELDS_NOTFOUND ) n2 = fields_find( f, "DATE:YEAR", LEVEL_ANY );
+	if ( n2==FIELDS_NOTFOUND ) n2 = fields_find( f, "PARTDATE:YEAR", LEVEL_MAIN );
+	if ( n2==FIELDS_NOTFOUND ) n2 = fields_find( f, "PARTDATE:YEAR", LEVEL_ANY );
+	if ( n1!=FIELDS_NOTFOUND && n2!=FIELDS_NOTFOUND ) {
 		p = f->data[n1].data;
 		while ( p && *p && *p!='|' ) {
 			if ( !is_ws( *p ) ) str_addchar( &citekey, *p ); 
@@ -671,7 +668,7 @@
 		sprintf( buf, "ref%d\n", nref );
 		str_strcpyc( &citekey, buf );
 	}
-	ret = fields_find( f, "REFNUM", -1 );
+	ret = fields_find( f, "REFNUM", LEVEL_ANY );
 out:
 	str_free( &citekey );
 	return ret;
@@ -709,8 +706,8 @@
 			}
 			nsame++;
 			dup[j] = -1;
-			n = fields_find( b->ref[j], "REFNUM", -1 );
-			if ( n!=-1 ) {
+			n = fields_find( b->ref[j], "REFNUM", LEVEL_ANY );
+			if ( n!=FIELDS_NOTFOUND ) {
 				str_strcpy(&((b->ref[j])->data[n]),&tmp);
 				if ( str_memerr( &((b->ref[j])->data[n]) ) ) {
 					status = BIBL_ERR_MEMERR;
@@ -732,9 +729,9 @@
 	str *s;
 	for ( i=0; i<b->nrefs; ++i ) {
 		f = b->ref[i];
-		n = fields_find( f, "REFNUM", -1 );
-		if ( n==-1 ) n = generate_citekey( f, i );
-		if ( n!=-1 && f->data[n].data ) {
+		n = fields_find( f, "REFNUM", LEVEL_ANY );
+		if ( n==FIELDS_NOTFOUND ) n = generate_citekey( f, i );
+		if ( n!=FIELDS_NOTFOUND && f->data[n].data ) {
 			s = slist_add( citekeys, &(f->data[n]) );
 			if ( !s ) return BIBL_ERR_MEMERR;
 		} else {
@@ -837,15 +834,31 @@
 	if ( !fp ) return BIBL_ERR_BADINPUT;
 	if ( !p )  return BIBL_ERR_BADINPUT;
 
-	if ( bibl_illegalinmode( p->readformat ) ) return BIBL_ERR_BADINPUT;
+	if ( bibl_illegalinmode( p->readformat ) ) {
+		if ( debug_set( p ) ) {
+			fflush( stdout );
+			report_params( stderr, "bibl_read", p );
+		}
+		return BIBL_ERR_BADINPUT;
+	}
 
 	status = bibl_setreadparams( &lp, p );
-	if ( status!=BIBL_OK ) return status;
+	if ( status!=BIBL_OK ) {
+		if ( debug_set( p ) ) {
+			fflush( stdout );
+			report_params( stderr, "bibl_read", p );
+		}
+		return status;
+	}
 
 	bibl_init( &bin );
 
 	status = read_ref( fp, &bin, filename, &lp );
 	if ( status!=BIBL_OK ) {
+		if ( debug_set( p ) ) {
+			fflush( stdout );
+			report_params( stderr, "bibl_read", &lp );
+		}
 		bibl_freeparams( &lp );
 		return status;
 	}
@@ -924,7 +937,7 @@
 	else if ( mode==BIBL_MODSOUT )       strcpy( suffix, "xml" );
 	else if ( mode==BIBL_RISOUT )        strcpy( suffix, "ris" );
 	else if ( mode==BIBL_WORD2007OUT )   strcpy( suffix, "xml" );
-	found = fields_find( reffields, "REFNUM", 0 );
+	found = fields_find( reffields, "REFNUM", LEVEL_MAIN );
 	/* find new filename based on reference */
 	if ( found!=-1 ) {
 		sprintf( outfile,"%s.%s",reffields->data[found].data, suffix );
@@ -984,7 +997,7 @@
 	if ( !b ) return BIBL_ERR_BADINPUT;
 	if ( !p ) return BIBL_ERR_BADINPUT;
 	if ( bibl_illegaloutmode( p->writeformat ) ) return BIBL_ERR_BADINPUT;
-	if ( !fp && ( !p || !p->singlerefperfile ) ) return BIBL_ERR_BADINPUT;
+	if ( !fp && !p->singlerefperfile ) return BIBL_ERR_BADINPUT;
 
 	status = bibl_setwriteparams( &lp, p );
 	if ( status!=BIBL_OK ) return status;
diff --git a/bibutils/bibformats.h b/bibutils/bibformats.h
--- a/bibutils/bibformats.h
+++ b/bibutils/bibformats.h
@@ -1,7 +1,7 @@
 /*
  * bibformats.h
  *
- * Copyright (c) Chris Putnam 2007-2017
+ * Copyright (c) Chris Putnam 2007-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/bibl.c b/bibutils/bibl.c
--- a/bibutils/bibl.c
+++ b/bibutils/bibl.c
@@ -1,7 +1,7 @@
 /*
  * bibl.c
  *
- * Copyright (c) Chris Putnam 2005-2017
+ * Copyright (c) Chris Putnam 2005-2018
  *
  * Source code released under the GPL version 2
  *
@@ -66,7 +66,7 @@
 {
 	long i;
 	for ( i=0; i<b->nrefs; ++i )
-		fields_free( b->ref[i] );
+		fields_delete( b->ref[i] );
 	if ( b->ref ) free( b->ref );
 	b->ref = NULL;
 	b->nrefs = b->maxrefs = 0;
diff --git a/bibutils/bibl.h b/bibutils/bibl.h
--- a/bibutils/bibl.h
+++ b/bibutils/bibl.h
@@ -1,7 +1,7 @@
 /*
  * bibl.h
  *
- * Copyright (c) Chris Putnam 2005-2017
+ * Copyright (c) Chris Putnam 2005-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/biblatexin.c b/bibutils/biblatexin.c
--- a/bibutils/biblatexin.c
+++ b/bibutils/biblatexin.c
@@ -1,8 +1,8 @@
 /*
  * biblatexin.c
  *
- * Copyright (c) Chris Putnam 2008-2017
- * Copyright (c) Johannes Wilm 2010-2017
+ * Copyright (c) Chris Putnam 2008-2018
+ * Copyright (c) Johannes Wilm 2010-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -417,7 +417,7 @@
 	strs_init( &s1, &s2, NULL );
 	while ( *p && *p!='{' && *p!='(' ) p++;
 	if ( *p=='{' || *p=='(' ) p++;
-	p = process_biblatexline( skip_ws( p ), &s1, &s2, 0, nref, pm );
+	(void) process_biblatexline( skip_ws( p ), &s1, &s2, 0, nref, pm );
 	if ( str_has_value( &s2 ) ) {
 		str_findreplace( &s2, "\\ ", " " );
 		if ( str_memerr( &s2 ) ) { status = BIBL_ERR_MEMERR; goto out; }
@@ -605,7 +605,7 @@
 		goto out;
 	}
 
-	p = str_cpytodelim( &s, p, "", 0 );
+	(void) str_cpytodelim( &s, p, "", 0 );
 	if ( str_memerr( &s ) ) {
 		status = BIBL_ERR_MEMERR;
 		goto out;
@@ -686,8 +686,8 @@
 	int n;
 	long i;
 	for ( i=0; i<bin->nrefs; ++i ) {
-		n = fields_find( bin->ref[i], "refnum", -1 );
-		if ( n==-1 ) continue;
+		n = fields_find( bin->ref[i], "refnum", LEVEL_ANY );
+		if ( n==FIELDS_NOTFOUND ) continue;
 		if ( !strcmp( bin->ref[i]->data[n].data, citekey ) ) return i;
 	}
 	return -1;
@@ -696,13 +696,11 @@
 static void
 biblatexin_nocrossref( bibl *bin, long i, int n, param *p )
 {
-	int n1 = fields_find( bin->ref[i], "REFNUM", -1 );
+	int n1 = fields_find( bin->ref[i], "REFNUM", LEVEL_ANY );
 	if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
-	fprintf( stderr, "Cannot find cross-reference '%s'", 
-			bin->ref[i]->data[n].data);
-	if ( n1!=-1 )
-		fprintf( stderr, " for reference '%s'\n", 
-				bin->ref[i]->data[n1].data );
+	fprintf( stderr, "Cannot find cross-reference '%s'", bin->ref[i]->data[n].data);
+	if ( n1!=FIELDS_NOTFOUND )
+		fprintf( stderr, " for reference '%s'", bin->ref[i]->data[n1].data );
 	fprintf( stderr, "\n" );
 }
 
@@ -711,7 +709,7 @@
 {
 	int j, nl, ntype, fstatus;
 	char *type, *nt, *nd;
-	ntype = fields_find( ref, "INTERNAL_TYPE", -1 );
+	ntype = fields_find( ref, "INTERNAL_TYPE", LEVEL_ANY );
 	type = ( char * ) fields_value( ref, ntype, FIELDS_CHRP_NOUSE );
 	for ( j=0; j<cross->n; ++j ) {
 		nt = ( char * ) fields_tag( cross, j, FIELDS_CHRP_NOUSE );
@@ -738,8 +736,8 @@
 	long i;
         for ( i=0; i<bin->nrefs; ++i ) {
 		ref = bin->ref[i];
-		n = fields_find( ref, "CROSSREF", -1 );
-		if ( n==-1 ) continue;
+		n = fields_find( ref, "CROSSREF", LEVEL_ANY );
+		if ( n==FIELDS_NOTFOUND ) continue;
 		fields_setused( ref, n );
 		ncross = biblatexin_findref(bin, (char*)fields_value(ref,n, FIELDS_CHRP_NOUSE));
 		if ( ncross==-1 ) {
@@ -803,8 +801,8 @@
 
 	ntypename = fields_find( bibin, "INTERNAL_TYPE", LEVEL_MAIN );
 	nrefname  = fields_find( bibin, "REFNUM",        LEVEL_MAIN );
-	if ( nrefname!=-1 )  refname  = fields_value( bibin, nrefname,  FIELDS_CHRP_NOUSE );
-        if ( ntypename!=-1 ) typename = fields_value( bibin, ntypename, FIELDS_CHRP_NOUSE );
+	if ( nrefname!=FIELDS_NOTFOUND )  refname  = fields_value( bibin, nrefname,  FIELDS_CHRP_NOUSE );
+        if ( ntypename!=FIELDS_NOTFOUND ) typename = fields_value( bibin, ntypename, FIELDS_CHRP_NOUSE );
 
 	return get_reftype( typename, nrefs, p->progname, p->all, p->nall, refname, &is_default, REFTYPE_CHATTY );
 }
@@ -1055,14 +1053,14 @@
 	int fstatus1, fstatus2;
 
 	if ( !strcasecmp( str_cstr( invalue ), "magazine" ) ) {
-		fstatus1 = fields_add( bibout, "NGENRE", "magazine article", LEVEL_MAIN );
-		fstatus2 = fields_add( bibout, "NGENRE", "magazine",         LEVEL_HOST );
+		fstatus1 = fields_add( bibout, "GENRE:BIBUTILS", "magazine article", LEVEL_MAIN );
+		fstatus2 = fields_add( bibout, "GENRE:BIBUTILS", "magazine",         LEVEL_HOST );
 		if ( fstatus1!=FIELDS_OK || fstatus2!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 
 	else if ( !strcasecmp( str_cstr( invalue ), "newspaper" ) ) {
-		fstatus1 = fields_add( bibout, "NGENRE", "newspaper article", LEVEL_MAIN );
-		fstatus2 = fields_add( bibout, "GENRE",  "newspaper",         LEVEL_HOST );
+		fstatus1 = fields_add( bibout, "GENRE:BIBUTILS", "newspaper article", LEVEL_MAIN );
+		fstatus2 = fields_add( bibout, "GENRE:MARC",     "newspaper",         LEVEL_HOST );
 		if ( fstatus1!=FIELDS_OK || fstatus2!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 
@@ -1074,7 +1072,7 @@
 biblatexin_bltschool( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
 {
 	int fstatus;
-	if ( fields_find( bibin, "institution", LEVEL_ANY ) != -1 )
+	if ( fields_find( bibin, "institution", LEVEL_ANY ) != FIELDS_NOTFOUND )
 		return BIBL_OK;
 	else {
 		fstatus = fields_add( bibout, outtag, str_cstr( invalue ), level );
@@ -1090,15 +1088,15 @@
 	int fstatus = FIELDS_OK;
 	/* type in the @thesis is used to distinguish Ph.D. and Master's thesis */
 	if ( !strncasecmp( p, "phdthesis", 9 ) ) {
-		fstatus = fields_replace_or_add( bibout, "NGENRE", "Ph.D. thesis", level );
+		fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Ph.D. thesis", level );
 	} else if ( !strncasecmp( p, "mastersthesis", 13 ) || !strncasecmp( p, "masterthesis", 12 ) ) {
-		fstatus = fields_replace_or_add( bibout, "NGENRE", "Masters thesis", level );
+		fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Masters thesis", level );
 	} else if ( !strncasecmp( p, "mathesis", 8 ) ) {
-		fstatus = fields_replace_or_add( bibout, "NGENRE", "Masters thesis", level );
+		fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Masters thesis", level );
 	} else if ( !strncasecmp( p, "diploma", 7 ) ) {
-		fstatus = fields_replace_or_add( bibout, "NGENRE", "Diploma thesis", level );
+		fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Diploma thesis", level );
 	} else if ( !strncasecmp( p, "habilitation", 12 ) ) {
-		fstatus = fields_replace_or_add( bibout, "NGENRE", "Habilitation thesis", level );
+		fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Habilitation thesis", level );
 	}
 	if ( fstatus==FIELDS_OK ) return BIBL_OK;
 	else return BIBL_ERR_MEMERR;
@@ -1110,11 +1108,11 @@
 	int neprint, netype, fstatus;
 	char *eprint = NULL, *etype = NULL;
 
-	neprint = fields_find( bibin, "eprint", -1 );
-	netype  = fields_find( bibin, "eprinttype", -1 );
+	neprint = fields_find( bibin, "eprint",     LEVEL_ANY );
+	netype  = fields_find( bibin, "eprinttype", LEVEL_ANY );
 
-	if ( neprint!=-1 ) eprint = bibin->data[neprint].data;
-	if ( netype!=-1 )  etype =  bibin->data[netype].data;
+	if ( neprint!=FIELDS_NOTFOUND ) eprint = bibin->data[neprint].data;
+	if ( netype!=FIELDS_NOTFOUND )  etype =  bibin->data[netype].data;
 
 	if ( eprint && etype ) {
 		if ( !strncasecmp( etype, "arxiv", 5 ) ) {
@@ -1152,7 +1150,7 @@
 static int
 biblatexin_btgenre( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
 {
-	if ( fields_add( bibout, "NGENRE", str_cstr( invalue ), level ) == FIELDS_OK ) return BIBL_OK;
+	if ( fields_add( bibout, "GENRE:BIBUTILS", str_cstr( invalue ), level ) == FIELDS_OK ) return BIBL_OK;
 	else return BIBL_ERR_MEMERR;
 }
 
@@ -1174,9 +1172,9 @@
 	int fstatus;
 
         if ( !strncasecmp( str_cstr( invalue ), "Diplom", 6 ) )
-                fstatus = fields_replace_or_add( bibout, "NGENRE", "Diploma thesis", level );
+                fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Diploma thesis", level );
         else if ( !strncasecmp( str_cstr( invalue ), "Habilitation", 13 ) )
-                fstatus = fields_replace_or_add( bibout, "NGENRE", "Habilitation thesis", level );
+                fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Habilitation thesis", level );
         else
 		fstatus = fields_add( bibout, "PUBLISHER", str_cstr( invalue ), level );
 
@@ -1216,7 +1214,7 @@
 	for ( i=1; i<neditors; ++i )
 		if ( !strcasecmp( intag->data, editor_fields[i] ) ) n = i;
 	ntype = fields_find( bibin, editor_types[n], LEVEL_ANY );
-	if ( ntype!=-1 ) {
+	if ( ntype!=FIELDS_NOTFOUND ) {
 		type = fields_value( bibin, ntype, FIELDS_CHRP_NOUSE );
 		if ( !strcasecmp( type, "collaborator" ) )  usetag = "COLLABORATOR";
 		else if ( !strcasecmp( type, "compiler" ) ) usetag = "COMPILER";
@@ -1255,7 +1253,7 @@
 		[ BLT_EDITOR      ] = biblatexin_blteditor,
 		[ HOWPUBLISHED    ] = biblatexin_howpublished,
 		[ URL             ] = generic_url,
-		[ BT_GENRE        ] = biblatexin_btgenre,
+		[ GENRE           ] = biblatexin_btgenre,
 		[ BT_EPRINT       ] = biblatexin_bteprint,
 		[ BLT_THESIS_TYPE ] = biblatexin_bltthesistype,
 		[ BLT_SCHOOL      ] = biblatexin_bltschool,
diff --git a/bibutils/bibtexin.c b/bibutils/bibtexin.c
--- a/bibutils/bibtexin.c
+++ b/bibutils/bibtexin.c
@@ -1,7 +1,7 @@
 /*
  * bibtexin.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -292,11 +292,6 @@
 					if ( !isdigit( *q ) ) ok = 0;
 					q++;
 				}
-				if ( !ok ) {
-					fprintf( stderr, "%s: Warning: Non-numeric "
-					   "BibTeX elements should be in quotations or "
-					   "curly brackets in reference.\n", pm->progname );
-				}
 			}
 		}
 		i++;
@@ -560,7 +555,7 @@
 	if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }
 
 	/* ...return deleted fragment to str in */
-	p = str_cpytodelim( &s, p, "", 0 );
+	(void) str_cpytodelim( &s, p, "", 0 );
 	if ( str_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }
 	str_swapstrings( &s, in );
 
@@ -727,7 +722,7 @@
 	long i;
 	for ( i=0; i<bin->nrefs; ++i ) {
 		n = fields_find( bin->ref[i], "refnum", LEVEL_ANY );
-		if ( n==-1 ) continue;
+		if ( n==FIELDS_NOTFOUND ) continue;
 		if ( !strcmp( bin->ref[i]->data[n].data, citekey ) ) return i;
 	}
 	return -1;
@@ -740,7 +735,7 @@
 	if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
 	fprintf( stderr, "Cannot find cross-reference '%s'",
 			bin->ref[i]->data[n].data );
-	if ( n1!=-1 ) fprintf( stderr, " for reference '%s'\n",
+	if ( n1!=FIELDS_NOTFOUND ) fprintf( stderr, " for reference '%s'\n",
 			bin->ref[i]->data[n1].data );
 	fprintf( stderr, "\n" );
 }
@@ -785,7 +780,7 @@
 	for ( i=0; i<bin->nrefs; ++i ) {
 		bibref = bin->ref[i];
 		n = fields_find( bibref, "CROSSREF", LEVEL_ANY );
-		if ( n==-1 ) continue;
+		if ( n==FIELDS_NOTFOUND ) continue;
 		fields_setused( bibref, n );
 		ncross = bibtexin_findref( bin, (char*) fields_value( bibref, n, FIELDS_CHRP ) );
 		if ( ncross==-1 ) {
@@ -824,8 +819,8 @@
 
 	ntypename = fields_find( bibin, "INTERNAL_TYPE", LEVEL_MAIN );
 	nrefname  = fields_find( bibin, "REFNUM",        LEVEL_MAIN );
-	if ( nrefname!=-1 )  refname  = fields_value( bibin, nrefname,  FIELDS_CHRP_NOUSE );
-	if ( ntypename!=-1 ) typename = fields_value( bibin, ntypename, FIELDS_CHRP_NOUSE );
+	if ( nrefname!=FIELDS_NOTFOUND )  refname  = fields_value( bibin, nrefname,  FIELDS_CHRP_NOUSE );
+	if ( ntypename!=FIELDS_NOTFOUND ) typename = fields_value( bibin, ntypename, FIELDS_CHRP_NOUSE );
 
 	return get_reftype( typename, nrefs, p->progname, p->all, p->nall, refname, &is_default, REFTYPE_CHATTY );
 }
@@ -882,7 +877,7 @@
 {
 	int n, fstatus;
 	n = fields_find( bibin, "publisher", LEVEL_ANY );
-	if ( n==-1 )
+	if ( n==FIELDS_NOTFOUND )
 		fstatus = fields_add( bibout, "PUBLISHER", str_cstr( invalue ), level );
 	else
 		fstatus = fields_add( bibout, "ORGANIZER:CORP", str_cstr( invalue ), level );
@@ -1009,10 +1004,10 @@
 {
 	int fstatus, status = BIBL_OK;
 	if ( !strncasecmp( str_cstr( invalue ), "Diplom", 6 ) ) {
-		fstatus = fields_replace_or_add( bibout, "GENRE", "Diploma thesis", level );
+		fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Diploma thesis", level );
 		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
 	} else if ( !strncasecmp( str_cstr( invalue ), "Habilitation", 13 ) ) {
-		fstatus = fields_replace_or_add( bibout, "GENRE", "Habilitation thesis", level );
+		fstatus = fields_replace_or_add( bibout, "GENRE:BIBUTILS", "Habilitation thesis", level );
 		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
 	} else if ( is_embedded_link( str_cstr( invalue ) ) ) {
 		status =  urls_split_and_add( str_cstr( invalue ), bibout, level );
@@ -1097,8 +1092,8 @@
 
 	/* ...do we have an archivePrefix too? */
 	n = fields_find( bibin, "ARCHIVEPREFIX", level );
-	if ( n==-1 ) n = fields_find( bibin, "EPRINTTYPE", level );
-	if ( n!=-1 ) {
+	if ( n==FIELDS_NOTFOUND ) n = fields_find( bibin, "EPRINTTYPE", level );
+	if ( n!=FIELDS_NOTFOUND ) {
 		prefix = fields_value( bibin, n, FIELDS_CHRP );
 		return process_eprint_with_prefix( bibout, prefix, invalue, level );
 	}
@@ -1248,12 +1243,12 @@
 
 	/* ...look only at '@inbook' references */
 	n = fields_find( bibin, "INTERNAL_TYPE", LEVEL_ANY );
-	if ( n==-1 ) return 0;
+	if ( n==FIELDS_NOTFOUND ) return 0;
 	if ( strcasecmp( fields_value( bibin, n, FIELDS_CHRP ), "INBOOK" ) ) return 0;
 
 	/* ...look to see if 'booktitle="yyy"' exists */
 	n = fields_find( bibin, "BOOKTITLE", LEVEL_ANY );
-	if ( n==-1 ) return 0;
+	if ( n==FIELDS_NOTFOUND ) return 0;
 	else return 1;
 }
 
@@ -1291,6 +1286,7 @@
 		[ HOWPUBLISHED ] = bibtexin_howpublished,
 		[ LINKEDFILE   ] = bibtexin_linkedfile,
 		[ NOTES        ] = generic_notes,
+		[ GENRE        ] = generic_genre,
 		[ BT_SENTE     ] = bibtexin_btsente,
 		[ BT_ORG       ] = bibtexin_btorg,
 		[ URL          ] = generic_url
diff --git a/bibutils/bibtexout.c b/bibutils/bibtexout.c
--- a/bibutils/bibtexout.c
+++ b/bibutils/bibtexout.c
@@ -1,7 +1,7 @@
 /*
  * bibtexout.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -67,57 +67,81 @@
 };
 
 static int
+is_genre_element( fields *in, int n )
+{
+	char *tag;
+
+	tag = fields_tag( in, n, FIELDS_CHRP );
+
+	if ( !strcasecmp( tag, "GENRE:MARC"     ) ) return 1;
+	if ( !strcasecmp( tag, "GENRE:BIBUTILS" ) ) return 1;
+	if ( !strcasecmp( tag, "GENRE:UNKNOWN"  ) ) return 1;
+
+	return 0;
+}
+
+static int
+is_issuance_element( fields *in, int n )
+{
+	if ( !strcasecmp( fields_tag( in, n, FIELDS_CHRP ), "ISSUANCE" ) ) return 1;
+	else return 0;
+}
+
+static int
 bibtexout_type( fields *in, char *filename, int refnum, param *p )
 {
 	int type = TYPE_UNKNOWN, i, maxlevel, n, level;
-	char *tag, *genre;
+	char *genre;
 
-	/* determine bibliography type */
+	/* determine bibliography type from GENRE */
 	for ( i=0; i<in->n; ++i ) {
-		tag = fields_tag( in, i, FIELDS_CHRP );
-		if ( strcasecmp( tag, "GENRE" ) && strcasecmp( tag, "NGENRE" ) ) continue;
+		if ( !is_genre_element( in, i ) ) continue;
 		genre = fields_value( in, i, FIELDS_CHRP );
 		level = in->level[i];
 		if ( !strcasecmp( genre, "periodical" ) ||
 		     !strcasecmp( genre, "academic journal" ) ||
 		     !strcasecmp( genre, "magazine" ) ||
 		     !strcasecmp( genre, "newspaper" ) ||
-		     !strcasecmp( genre, "article" ) )
+		     !strcasecmp( genre, "article" ) ) {
 			type = TYPE_ARTICLE;
-		else if ( !strcasecmp( genre, "instruction" ) )
+		} else if ( !strcasecmp( genre, "instruction" ) ) {
 			type = TYPE_MANUAL;
-		else if ( !strcasecmp( genre, "unpublished" ) )
+		} else if ( !strcasecmp( genre, "unpublished" ) ) {
 			type = TYPE_UNPUBLISHED;
-		else if ( !strcasecmp( genre, "conference publication" ) ) {
+		} else if ( !strcasecmp( genre, "conference publication" ) ) {
 			if ( level==0 ) type=TYPE_PROCEEDINGS;
 			else type = TYPE_INPROCEEDINGS;
 		} else if ( !strcasecmp( genre, "collection" ) ) {
 			if ( level==0 ) type=TYPE_COLLECTION;
 			else type = TYPE_INCOLLECTION;
-		} else if ( !strcasecmp( genre, "report" ) )
+		} else if ( !strcasecmp( genre, "report" ) ||
+		            !strcasecmp( genre, "technical report" ) ) {
 			type = TYPE_REPORT;
-		else if ( !strcasecmp( genre, "book chapter" ) )
+		} else if ( !strcasecmp( genre, "book chapter" ) ) {
 			type = TYPE_INBOOK;
-		else if ( !strcasecmp( genre, "book" ) ) {
+		} else if ( !strcasecmp( genre, "book" ) ) {
 			if ( level==0 ) type = TYPE_BOOK;
 			else type = TYPE_INBOOK;
 		} else if ( !strcasecmp( genre, "thesis" ) ) {
 			if ( type==TYPE_UNKNOWN ) type=TYPE_PHDTHESIS;
-		} else if ( !strcasecmp( genre, "Ph.D. thesis" ) )
+		} else if ( !strcasecmp( genre, "Ph.D. thesis" ) ) {
 			type = TYPE_PHDTHESIS;
-		else if ( !strcasecmp( genre, "Masters thesis" ) )
+		} else if ( !strcasecmp( genre, "Masters thesis" ) ) {
 			type = TYPE_MASTERSTHESIS;
-		else  if ( !strcasecmp( genre, "electronic" ) )
+		} else if ( !strcasecmp( genre, "electronic" ) ) {
 			type = TYPE_ELECTRONIC;
+		} else if ( !strcasecmp( genre, "miscellaneous" ) ) {
+			type = TYPE_MISC;
+		}
 	}
+
+	/* check type from ISSUANCE */
 	if ( type==TYPE_UNKNOWN ) {
 		for ( i=0; i<in->n; ++i ) {
-			tag = fields_tag( in, i, FIELDS_CHRP );
-			if ( strcasecmp( tag, "ISSUANCE" ) ) continue;
+			if ( !is_issuance_element( in, i ) ) continue;
 			genre = fields_value( in, i, FIELDS_CHRP );
 			if ( !strcasecmp( genre, "monographic" ) ) {
-				if ( in->level[i]==0 ) type = TYPE_BOOK;
-				else if ( in->level[i]==1 ) type = TYPE_MISC;
+				if ( level==0 ) type = TYPE_BOOK;
 			}
 		}
 	}
@@ -130,7 +154,7 @@
 			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
 			fprintf( stderr, "Cannot identify TYPE in reference %d ", refnum+1 );
 			n = fields_find( in, "REFNUM", LEVEL_ANY );
-			if ( n!=-1 ) 
+			if ( n!=FIELDS_NOTFOUND ) 
 				fprintf( stderr, " %s", (char*) fields_value( in, n, FIELDS_CHRP ) );
 			fprintf( stderr, " (defaulting to @Misc)\n" );
 			type = TYPE_MISC;
@@ -243,7 +267,7 @@
 	char *p;
 
 	n = fields_find( in, "REFNUM", LEVEL_ANY );
-	if ( ( format_opts & BIBL_FORMAT_BIBOUT_DROPKEY ) || n==-1 ) {
+	if ( ( format_opts & BIBL_FORMAT_BIBOUT_DROPKEY ) || n==FIELDS_NOTFOUND ) {
 		fstatus = fields_add( out, "REFNUM", "", LEVEL_MAIN );
 		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
 	}
@@ -278,7 +302,7 @@
 	int n, fstatus;
 
 	n = fields_find( in, intag, LEVEL_ANY );
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		fields_setused( in, n );
 		fstatus = fields_add( out, outtag, fields_value( in, n, FIELDS_CHRP ), LEVEL_MAIN );
 		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
@@ -462,16 +486,14 @@
 static int
 append_title( fields *in, char *bibtag, int level, fields *out, int format_opts )
 {
-	int title = -1,     short_title = -1;
-	int subtitle = -1,  short_subtitle = -1;
-	int use_title = -1, use_subtitle = -1;
+	int title, short_title, subtitle, short_subtitle, use_title, use_subtitle;
 
 	title          = fields_find( in, "TITLE",         level );
 	short_title    = fields_find( in, "SHORTTITLE",    level );
 	subtitle       = fields_find( in, "SUBTITLE",      level );
 	short_subtitle = fields_find( in, "SHORTSUBTITLE", level );
 
-	if ( title==-1 || ( ( format_opts & BIBL_FORMAT_BIBOUT_SHORTTITLE ) && level==1 ) ) {
+	if ( title==FIELDS_NOTFOUND || ( ( format_opts & BIBL_FORMAT_BIBOUT_SHORTTITLE ) && level==1 ) ) {
 		use_title    = short_title;
 		use_subtitle = short_subtitle;
 	}
@@ -540,7 +562,7 @@
 	sprintf( date, "DATE:%s", date_element );
 	n = fields_find( in, date, LEVEL_ANY );
 
-	if ( n==-1 ) {
+	if ( n==FIELDS_NOTFOUND ) {
 		sprintf( partdate, "PARTDATE:%s", date_element );
 		n = fields_find( in, partdate, LEVEL_ANY );
 	}
@@ -556,7 +578,7 @@
 	int n, month, fstatus;
 
 	n = find_date( in, "YEAR" );
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		fields_setused( in, n );
 		fstatus = fields_add( out, "year", in->data[n].data, LEVEL_MAIN );
 		if ( fstatus!=FIELDS_OK ) {
@@ -598,7 +620,7 @@
 	str url;
 
 	n = fields_find( in, "ARXIV", LEVEL_ANY );
-	if ( n==-1 ) return;
+	if ( n==FIELDS_NOTFOUND ) return;
 
 	fields_setused( in, n );
 
@@ -650,24 +672,23 @@
 	int n, fstatus;
 
 	n = fields_find( in, "ISIREFNUM", LEVEL_ANY );
-	if ( n!=-1 ) {
-		fstatus = fields_add( out, "note", fields_value( in, n, FIELDS_CHRP ), LEVEL_MAIN );
-		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
-	}
+	if ( n==FIELDS_NOTFOUND ) return;
+
+	fstatus = fields_add( out, "note", fields_value( in, n, FIELDS_CHRP ), LEVEL_MAIN );
+	if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
 }
 
-static int
-append_articlenumber( fields *in, fields *out )
+static void
+append_articlenumber( fields *in, fields *out, int *status )
 {
 	int n, fstatus;
 
 	n = fields_find( in, "ARTICLENUMBER", LEVEL_ANY );
-	if ( n!=-1 ) {
-		fields_setused( in, n );
-		fstatus = fields_add( out, "pages", fields_value( in, n, FIELDS_CHRP ), LEVEL_MAIN );
-		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
-	}
-	return BIBL_OK;
+	if ( n==FIELDS_NOTFOUND );
+
+	fields_setused( in, n );
+	fstatus = fields_add( out, "pages", fields_value( in, n, FIELDS_CHRP ), LEVEL_MAIN );
+	if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
 }
 
 static int
@@ -702,7 +723,7 @@
 {
 	*sn = fields_find( in, "PAGES:START", LEVEL_ANY );
 	*en = fields_find( in, "PAGES:STOP",  LEVEL_ANY );
-	if ( *sn==-1 && *en==-1 ) return 0;
+	if ( *sn==FIELDS_NOTFOUND && *en==FIELDS_NOTFOUND ) return 0;
 	else return 1;
 }
 
@@ -713,7 +734,7 @@
 	str pages;
 
 	if ( !pages_are_defined( in, &sn, &en ) ) {
-		*status = append_articlenumber( in, out );
+		append_articlenumber( in, out, status );
 		return;
 	}
 
@@ -741,28 +762,29 @@
 static void
 append_issue_number( fields *in, fields *out, int *status )
 {
+	char issue[] = "issue", number[] = "number", *use_issue = number;
 	int nissue  = fields_find( in, "ISSUE",  LEVEL_ANY );
 	int nnumber = fields_find( in, "NUMBER", LEVEL_ANY );
 	int fstatus;
 
-	if ( nissue!=-1 && nnumber!=-1 ) {
+	if ( nissue!=FIELDS_NOTFOUND && nnumber!=FIELDS_NOTFOUND ) use_issue = issue;
+
+	if ( nissue!=FIELDS_NOTFOUND ) {
 		fields_setused( in, nissue );
-		fields_setused( in, nnumber );
-		fstatus = fields_add( out, "issue", fields_value( in, nissue, FIELDS_CHRP ), LEVEL_MAIN );
+		fstatus = fields_add( out, use_issue, fields_value( in, nissue, FIELDS_CHRP ), LEVEL_MAIN );
 		if ( fstatus!=FIELDS_OK ) {
 			*status = BIBL_ERR_MEMERR;
 			return;
 		}
-		fstatus = fields_add( out, "number", fields_value( in, nnumber, FIELDS_CHRP ), LEVEL_MAIN );
-		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
-	} else if ( nissue!=-1 ) {
-		fields_setused( in, nissue );
-		fstatus = fields_add( out, "number", fields_value( in, nissue, FIELDS_CHRP ), LEVEL_MAIN );
-		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
-	} else if ( nnumber!=-1 ) {
+	}
+
+	if ( nnumber!=FIELDS_NOTFOUND ) {
 		fields_setused( in, nnumber );
 		fstatus = fields_add( out, "number", fields_value( in, nnumber, FIELDS_CHRP ), LEVEL_MAIN );
-		if ( fstatus!=FIELDS_OK ) *status = BIBL_ERR_MEMERR;
+		if ( fstatus!=FIELDS_OK ) {
+			*status = BIBL_ERR_MEMERR;
+			return;
+		}
 	}
 }
 
diff --git a/bibutils/bibtextypes.c b/bibutils/bibtextypes.c
--- a/bibutils/bibtextypes.c
+++ b/bibutils/bibtextypes.c
@@ -1,7 +1,7 @@
 /*
  * bibtypes.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -53,12 +53,12 @@
 	{ "refnum",       "REFNUM",         SIMPLE,       LEVEL_MAIN },
 	{ "crossref",     "CROSSREF",       SIMPLE,       LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",        KEYWORD,      LEVEL_MAIN },
-	{ "",             "INTERNAL_TYPE|ARTICLE",   ALWAYS, LEVEL_MAIN },
-	{ "",             "ISSUANCE|continuing",     ALWAYS, LEVEL_HOST },
-	{ "",             "RESOURCE|text",           ALWAYS, LEVEL_MAIN },
-	{ "",             "NGENRE|journal article",  ALWAYS, LEVEL_MAIN },
-	{ "",             "GENRE|periodical",        ALWAYS, LEVEL_HOST },
-	{ "",             "NGENRE|academic journal", ALWAYS, LEVEL_HOST }
+	{ "",             "INTERNAL_TYPE|ARTICLE",           ALWAYS, LEVEL_MAIN },
+	{ "",             "ISSUANCE|continuing",             ALWAYS, LEVEL_HOST },
+	{ "",             "RESOURCE|text",                   ALWAYS, LEVEL_MAIN },
+	{ "",             "GENRE:MARC|periodical",           ALWAYS, LEVEL_HOST },
+	{ "",             "GENRE:BIBUTILS|journal article",  ALWAYS, LEVEL_MAIN },
+	{ "",             "GENRE:BIBUTILS|academic journal", ALWAYS, LEVEL_HOST }
 };
 
 /* Book */
@@ -87,7 +87,7 @@
 	{ "location",     "LOCATION",       SIMPLE,       LEVEL_MAIN },
 	{ "note",         "NOTES",          NOTES,        LEVEL_MAIN },
 	{ "annote",       "ANNOTE",         SIMPLE,       LEVEL_MAIN },
-	{ "type",         "GENRE",          SIMPLE,       LEVEL_MAIN },
+	{ "type",         "GENRE:UKNOWN",   GENRE,        LEVEL_MAIN },
 	{ "key",          "BIBKEY",         SIMPLE,       LEVEL_MAIN },
 	{ "ftp",          "",               URL,          LEVEL_MAIN },
 	{ "url",          "",               URL,          LEVEL_MAIN },
@@ -104,7 +104,7 @@
 	{ "",             "INTERNAL_TYPE|BOOK",   ALWAYS, LEVEL_MAIN },
 	{ "",             "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
 	{ "",             "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },
-	{ "",             "GENRE|book",           ALWAYS, LEVEL_MAIN }
+	{ "",             "GENRE:MARC|book",      ALWAYS, LEVEL_MAIN }
 };
 
 /* Technical reports */
@@ -142,11 +142,11 @@
 	{ "howpublished", "",           HOWPUBLISHED, LEVEL_MAIN },
 	{ "refnum",       "REFNUM",     SIMPLE,       LEVEL_MAIN },
 	{ "crossref",     "CROSSREF",   SIMPLE,       LEVEL_MAIN },
-	{ "type",         "GENRE",      SIMPLE,       LEVEL_MAIN },
+	{ "type",         "GENRE:UKNOWN", GENRE,      LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",    KEYWORD,      LEVEL_MAIN },
-	{ "",         "INTERNAL_TYPE|REPORT", ALWAYS, LEVEL_MAIN },
-	{ "",         "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|report",         ALWAYS, LEVEL_MAIN }
+	{ "", "INTERNAL_TYPE|REPORT",        ALWAYS,  LEVEL_MAIN },
+	{ "", "RESOURCE|text",               ALWAYS,  LEVEL_MAIN },
+	{ "", "GENRE:MARC|technical report", ALWAYS,  LEVEL_MAIN },
 };
 
 static lookups manual[] = {
@@ -183,7 +183,7 @@
 	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
 	{ "",         "INTERNAL_TYPE|REPORT", ALWAYS, LEVEL_MAIN },
 	{ "",         "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|instruction",    ALWAYS, LEVEL_MAIN }
+	{ "",         "GENRE:MARC|instruction", ALWAYS, LEVEL_MAIN }
 };
 
 /* Part of a book (e.g. chapter or section) */
@@ -217,19 +217,19 @@
 	{ "pdf",          "FILEATTACH",SIMPLE, LEVEL_MAIN },
 	{ "sentelink",    "FILEATTACH",BT_SENTE, LEVEL_MAIN },
 	{ "file",         "FILEATTACH",LINKEDFILE,   LEVEL_MAIN },
-	{ "howpublished", "",    HOWPUBLISHED, LEVEL_MAIN },
-	{ "refnum",       "REFNUM",    SIMPLE, LEVEL_MAIN },
-	{ "crossref",     "CROSSREF",  SIMPLE, LEVEL_MAIN },
-	{ "type",         "GENRE",      SIMPLE, LEVEL_MAIN },
-	{ "note",         "NOTES",        NOTES,   LEVEL_MAIN },
-	{ "annote",       "ANNOTE",    SIMPLE, LEVEL_MAIN },
-	{ "key",          "BIBKEY",          SIMPLE, LEVEL_MAIN },
+	{ "howpublished", "",    HOWPUBLISHED,  LEVEL_MAIN },
+	{ "refnum",       "REFNUM",    SIMPLE,  LEVEL_MAIN },
+	{ "crossref",     "CROSSREF",  SIMPLE,  LEVEL_MAIN },
+	{ "type",         "GENRE:UNKNOWN", GENRE,  LEVEL_MAIN },
+	{ "note",         "NOTES",     NOTES,   LEVEL_MAIN },
+	{ "annote",       "ANNOTE",    SIMPLE,  LEVEL_MAIN },
+	{ "key",          "BIBKEY",    SIMPLE,  LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
-	{ "",             "INTERNAL_TYPE|INBOOK", ALWAYS, LEVEL_MAIN },
-	{ "",             "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
-	{ "",             "ISSUANCE|monographic", ALWAYS, LEVEL_HOST },
-	{ "",             "NGENRE|book chapter",  ALWAYS, LEVEL_MAIN },
-	{ "",             "GENRE|book",           ALWAYS, LEVEL_HOST }
+	{ "",             "INTERNAL_TYPE|INBOOK",        ALWAYS, LEVEL_MAIN },
+	{ "",             "RESOURCE|text",               ALWAYS, LEVEL_MAIN },
+	{ "",             "ISSUANCE|monographic",        ALWAYS, LEVEL_HOST },
+	{ "",             "GENRE:BIBUTILS|book chapter", ALWAYS, LEVEL_MAIN },
+	{ "",             "GENRE:MARC|book",             ALWAYS, LEVEL_HOST }
 };
 
 /* References of papers in conference proceedings */
@@ -264,7 +264,7 @@
 	{ "pdf",          "FILEATTACH",SIMPLE, LEVEL_MAIN },
 	{ "sentelink",    "FILEATTACH",BT_SENTE, LEVEL_MAIN },
 	{ "file",         "FILEATTACH",LINKEDFILE,   LEVEL_MAIN },
-	{ "type",      "GENRE",      SIMPLE, LEVEL_MAIN },
+	{ "type",      "GENRE:UNKNOWN",   GENRE,  LEVEL_MAIN },
 	{ "note",         "NOTES",        NOTES,   LEVEL_MAIN },
 	{ "annote",       "ANNOTE",    SIMPLE, LEVEL_MAIN },
 	{ "key",          "BIBKEY",          SIMPLE, LEVEL_MAIN },
@@ -274,7 +274,7 @@
 	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
 	{ "",         "INTERNAL_TYPE|INPROCEEDINGS",  ALWAYS, LEVEL_MAIN },
 	{ "",         "RESOURCE|text",                ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|conference publication", ALWAYS, LEVEL_HOST }
+	{ "",         "GENRE:MARC|conference publication", ALWAYS, LEVEL_HOST }
 };
 
 /* Used for a section of a book with its own title */
@@ -301,7 +301,7 @@
 	{ "abstract",  "ABSTRACT",  SIMPLE, LEVEL_MAIN },
 	{ "contents",  "CONTENTS",  SIMPLE, LEVEL_HOST },
 	{ "language",  "LANGUAGE",  SIMPLE, LEVEL_MAIN },
-	{ "type",      "GENRE",     SIMPLE, LEVEL_MAIN },
+	{ "type",      "GENRE:UNKNOWN",     GENRE,  LEVEL_MAIN },
 	{ "note",      "NOTES",     NOTES,  LEVEL_MAIN },
 	{ "annote",    "ANNOTE",    SIMPLE, LEVEL_MAIN },
 	{ "key",       "BIBKEY",    SIMPLE, LEVEL_MAIN },
@@ -319,7 +319,7 @@
 	{ "",         "INTERNAL_TYPE|INCOLLECTION", ALWAYS, LEVEL_MAIN },
 	{ "",         "RESOURCE|text",              ALWAYS, LEVEL_MAIN },
 	{ "",         "ISSUANCE|monographic",       ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|collection",           ALWAYS, LEVEL_HOST }
+	{ "",         "GENRE:BIBUTILS|collection",  ALWAYS, LEVEL_HOST }
 };
 
 /* Proceedings */
@@ -359,9 +359,9 @@
 	{ "refnum",    "REFNUM",    SIMPLE, LEVEL_MAIN },
 	{ "crossref",     "CROSSREF",  SIMPLE, LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
-	{ "",         "INTERNAL_TYPE|PROCEEDINGS",    ALWAYS, LEVEL_MAIN },
-	{ "",         "RESOURCE|text",                ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|conference publication", ALWAYS, LEVEL_MAIN }
+	{ "",         "INTERNAL_TYPE|PROCEEDINGS",         ALWAYS, LEVEL_MAIN },
+	{ "",         "RESOURCE|text",                     ALWAYS, LEVEL_MAIN },
+	{ "",         "GENRE:MARC|conference publication", ALWAYS, LEVEL_MAIN }
 };
 
 static lookups phds[] = {
@@ -381,20 +381,20 @@
 	{ "pdf",          "FILEATTACH",SIMPLE, LEVEL_MAIN },
 	{ "sentelink",    "FILEATTACH",BT_SENTE, LEVEL_MAIN },
 	{ "file",         "FILEATTACH",LINKEDFILE,   LEVEL_MAIN },
-	{ "howpublished", "" ,   HOWPUBLISHED, LEVEL_MAIN },
-	{ "language",     "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "location",     "LOCATION",     SIMPLE, LEVEL_MAIN },
-	{ "note",         "NOTES",        NOTES,   LEVEL_MAIN },
-	{ "annote",       "ANNOTE",    SIMPLE, LEVEL_MAIN },
-	{ "key",          "BIBKEY",          SIMPLE, LEVEL_MAIN },
-	{ "type",         "GENRE",         SIMPLE, LEVEL_MAIN },
-	{ "refnum",    "REFNUM",    SIMPLE, LEVEL_MAIN },
-	{ "crossref",     "CROSSREF",  SIMPLE, LEVEL_MAIN },
+	{ "howpublished", "" ,   HOWPUBLISHED,  LEVEL_MAIN },
+	{ "language",     "LANGUAGE",  SIMPLE,  LEVEL_MAIN },
+	{ "location",     "LOCATION",  SIMPLE,  LEVEL_MAIN },
+	{ "note",         "NOTES",     NOTES,   LEVEL_MAIN },
+	{ "annote",       "ANNOTE",    SIMPLE,  LEVEL_MAIN },
+	{ "key",          "BIBKEY",    SIMPLE,  LEVEL_MAIN },
+	{ "type",         "GENRE:UNKNOWN",     GENRE,   LEVEL_MAIN },
+	{ "refnum",       "REFNUM",    SIMPLE,  LEVEL_MAIN },
+	{ "crossref",     "CROSSREF",  SIMPLE,  LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
-	{ "",         "INTERNAL_TYPE|THESIS", ALWAYS,  LEVEL_MAIN },
-	{ "",         "RESOURCE|text",        ALWAYS,  LEVEL_MAIN },
-	{ "",         "GENRE|thesis",         ALWAYS,  LEVEL_MAIN },
-	{ "",         "NGENRE|Ph.D. thesis",  DEFAULT, LEVEL_MAIN }
+	{ "",         "INTERNAL_TYPE|THESIS",        ALWAYS,  LEVEL_MAIN },
+	{ "",         "RESOURCE|text",               ALWAYS,  LEVEL_MAIN },
+	{ "",         "GENRE:MARC|thesis",           ALWAYS,  LEVEL_MAIN },
+	{ "",         "GENRE:BIBUTILS|Ph.D. thesis", DEFAULT, LEVEL_MAIN }
 };
 
 static lookups masters[] = {
@@ -411,23 +411,23 @@
 	{ "doi",       "DOI",       SIMPLE, LEVEL_MAIN },
 	{ "ftp",       "",          URL,   LEVEL_MAIN },
 	{ "url",       "",          URL,   LEVEL_MAIN },
-	{ "pdf",          "FILEATTACH",SIMPLE, LEVEL_MAIN },
-	{ "sentelink",    "FILEATTACH",BT_SENTE, LEVEL_MAIN },
-	{ "file",         "FILEATTACH",LINKEDFILE,   LEVEL_MAIN },
-	{ "language",     "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "location",     "LOCATION",     SIMPLE, LEVEL_MAIN },
-	{ "note",         "NOTES",        NOTES,   LEVEL_MAIN },
-	{ "annote",       "ANNOTE",    SIMPLE, LEVEL_MAIN },
-	{ "key",          "BIBKEY",          SIMPLE, LEVEL_MAIN },
-	{ "type",         "GENRE",         SIMPLE, LEVEL_MAIN },
-	{ "howpublished", "",    HOWPUBLISHED, LEVEL_MAIN },
-	{ "refnum",    "REFNUM",    SIMPLE, LEVEL_MAIN },
-	{ "crossref",     "CROSSREF",  SIMPLE, LEVEL_MAIN },
-	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
-	{ "",         "INTERNAL_TYPE|THESIS",  ALWAYS,  LEVEL_MAIN },
-	{ "",         "RESOURCE|text",         ALWAYS,  LEVEL_MAIN },
-	{ "",         "GENRE|thesis",          ALWAYS,  LEVEL_MAIN },
-	{ "",         "NGENRE|Masters thesis", DEFAULT, LEVEL_MAIN }
+	{ "pdf",          "FILEATTACH", SIMPLE, LEVEL_MAIN },
+	{ "sentelink",    "FILEATTACH", BT_SENTE, LEVEL_MAIN },
+	{ "file",         "FILEATTACH", LINKEDFILE,   LEVEL_MAIN },
+	{ "language",     "LANGUAGE",   SIMPLE,  LEVEL_MAIN },
+	{ "location",     "LOCATION",   SIMPLE,  LEVEL_MAIN },
+	{ "note",         "NOTES",      NOTES,   LEVEL_MAIN },
+	{ "annote",       "ANNOTE",     SIMPLE,  LEVEL_MAIN },
+	{ "key",          "BIBKEY",     SIMPLE,  LEVEL_MAIN },
+	{ "type",         "GENRE:UNKNOWN",      GENRE,   LEVEL_MAIN },
+	{ "howpublished", "",    HOWPUBLISHED,   LEVEL_MAIN },
+	{ "refnum",       "REFNUM",     SIMPLE,  LEVEL_MAIN },
+	{ "crossref",     "CROSSREF",   SIMPLE,  LEVEL_MAIN },
+	{ "keywords",     "KEYWORD",    KEYWORD, LEVEL_MAIN },
+	{ "",         "INTERNAL_TYPE|THESIS",          ALWAYS,  LEVEL_MAIN },
+	{ "",         "RESOURCE|text",                 ALWAYS,  LEVEL_MAIN },
+	{ "",         "GENRE:MARC|thesis",             ALWAYS,  LEVEL_MAIN },
+	{ "",         "GENRE:BIBUTILS|Masters thesis", DEFAULT, LEVEL_MAIN }
 };
 
 /* Unpublished */
@@ -462,7 +462,7 @@
 	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
 	{ "",         "INTERNAL_TYPE|BOOK", ALWAYS, LEVEL_MAIN },
 	{ "",         "RESOURCE|text",      ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|unpublished",  ALWAYS, LEVEL_MAIN }
+	{ "",         "GENRE:BIBUTILS|unpublished", ALWAYS, LEVEL_MAIN }
 };
 
 /*
@@ -494,7 +494,7 @@
 	{ "howpublished", "",    HOWPUBLISHED, LEVEL_MAIN },
 	{ "language",     "LANGUAGE",     SIMPLE, LEVEL_MAIN },
 	{ "refnum",    "REFNUM",    SIMPLE, LEVEL_MAIN },
-	{ "type",      "GENRE",      SIMPLE, LEVEL_MAIN },
+	{ "type",      "GENRE:UNKNOWN",      GENRE,  LEVEL_MAIN },
 	{ "number",    "NUMBER",      SIMPLE,  LEVEL_MAIN },
 	{ "revision",  "EDITION",    SIMPLE,  LEVEL_MAIN },
 	{ "location",     "LOCATION",     SIMPLE, LEVEL_MAIN },
@@ -541,7 +541,7 @@
 	{ "crossref",     "CROSSREF",  SIMPLE, LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",   KEYWORD, LEVEL_MAIN },
 	{ "",            "RESOURCE|text",    ALWAYS, LEVEL_MAIN },
-	{ "",            "GENRE|periodical", ALWAYS, LEVEL_MAIN }
+	{ "",            "GENRE:MARC|periodical", ALWAYS, LEVEL_MAIN }
 };
 
 /*
@@ -576,13 +576,13 @@
 	{ "sentelink",    "FILEATTACH",  BT_SENTE,     LEVEL_MAIN },
 	{ "file",         "FILEATTACH",  LINKEDFILE,   LEVEL_MAIN },
 	{ "howpublished", "",            HOWPUBLISHED, LEVEL_MAIN },
-	{ "type",         "GENRE",       SIMPLE,       LEVEL_MAIN },
+	{ "type",         "GENRE:UNKNOWN",       GENRE,       LEVEL_MAIN },
 	{ "refnum",       "REFNUM",      SIMPLE,       LEVEL_MAIN },
 	{ "crossref",     "CROSSREF",    SIMPLE,       LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",     KEYWORD,      LEVEL_MAIN },
 	{ "",         "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
 	{ "",         "INTERNAL_TYPE|PATENT", ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|patent",         ALWAYS, LEVEL_MAIN },
+	{ "",         "GENRE:MARC|patent",    ALWAYS, LEVEL_MAIN },
 };
 
 /*
@@ -619,7 +619,8 @@
 	{ "language",     "LANGUAGE",       SIMPLE,       LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",        KEYWORD,      LEVEL_MAIN },
         { "",         "RESOURCE|software, multimedia", ALWAYS, LEVEL_MAIN },
-	{ "",         "GENRE|electronic",              ALWAYS, LEVEL_MAIN },
+	{ "",         "GENRE:MARC|web site",           ALWAYS, LEVEL_MAIN },
+	{ "",         "GENRE:BIBUTILS|electronic",     ALWAYS, LEVEL_MAIN },
 };
 
 static lookups misc[] = {
@@ -652,7 +653,8 @@
 	{ "key",          "BIBKEY",         SIMPLE,       LEVEL_MAIN },
 	{ "language",     "LANGUAGE",       SIMPLE,       LEVEL_MAIN },
 	{ "keywords",     "KEYWORD",        KEYWORD,      LEVEL_MAIN },
-	{ "",             "INTERNAL_TYPE|MISC",       ALWAYS, LEVEL_MAIN },
+	{ "",             "INTERNAL_TYPE|MISC",           ALWAYS, LEVEL_MAIN },
+	{ "",             "GENRE:BIBUTILS|miscellaneous", ALWAYS, LEVEL_MAIN },
 };
 
 #define ORIG(a) ( &(a[0]) )
diff --git a/bibutils/bibutils.c b/bibutils/bibutils.c
--- a/bibutils/bibutils.c
+++ b/bibutils/bibutils.c
@@ -1,7 +1,7 @@
 /*
  * bibutils.c
  *
- * Copyright (c) Chris Putnam 2005-2017
+ * Copyright (c) Chris Putnam 2005-2018
  *
  * Source code released under the GPL version 2
  *
@@ -24,6 +24,7 @@
 	case BIBL_ENDNOTEXMLIN: endxmlin_initparams( p, progname ); break;
 	case BIBL_MEDLINEIN:    medin_initparams( p, progname ); break;
 	case BIBL_MODSIN:       modsin_initparams( p, progname ); break;
+	case BIBL_NBIBIN:       nbibin_initparams( p, progname ); break;
 	case BIBL_RISIN:        risin_initparams( p, progname ); break;
 	case BIBL_WORDIN:       wordin_initparams( p, progname ); break;
 	default: /* internal error */;
diff --git a/bibutils/bibutils.h b/bibutils/bibutils.h
--- a/bibutils/bibutils.h
+++ b/bibutils/bibutils.h
@@ -1,7 +1,7 @@
 /*
  * bibutils.h
  *
- * Copyright (c) Chris Putnam 2005-2017
+ * Copyright (c) Chris Putnam 2005-2018
  *
  * Source code released under GPL version 2
  *
diff --git a/bibutils/bltypes.c b/bibutils/bltypes.c
--- a/bibutils/bltypes.c
+++ b/bibutils/bltypes.c
@@ -1,8 +1,8 @@
 /*
  * bltypes.c
  *
- * Copyright (c) Chris Putnam 2008-2017
- * Copyright (c) Johannes Wilm 2010-2017
+ * Copyright (c) Chris Putnam 2008-2018
+ * Copyright (c) Johannes Wilm 2010-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -86,8 +86,8 @@
 	{ "",                "INTERNAL_TYPE|ARTICLE",  ALWAYS,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|continuing",    ALWAYS,          LEVEL_HOST   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "NGENRE|journal article", DEFAULT,         LEVEL_MAIN   },
-	{ "",                "GENRE|periodical",       DEFAULT,         LEVEL_HOST   }
+	{ "",                "GENRE:BIBUTILS|journal article", DEFAULT, LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|periodical",          DEFAULT, LEVEL_HOST   }
 };
 
 /* Book */
@@ -161,7 +161,7 @@
 	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|book",             ALWAYS,          LEVEL_MAIN   }
+	{ "",                "GENRE:MARC|book",        ALWAYS,          LEVEL_MAIN   }
 };
 
 /* Booklet */
@@ -189,7 +189,7 @@
 	{ "month",           "DATE:MONTH",             SIMPLE,          LEVEL_MAIN   },
 	{ "date",            "DATE",                   SIMPLE,          LEVEL_MAIN   },   /*WRONG*/
 	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },
-	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },
+	{ "type",            "GENRE:UNKNOWN",          GENRE,           LEVEL_MAIN   },
 	{ "note",            "NOTES",                  NOTES,           LEVEL_MAIN   },
 	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
 	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
@@ -214,7 +214,7 @@
 	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|book",             ALWAYS,          LEVEL_MAIN   }
+	{ "",                "GENRE:MARC|book",        ALWAYS,          LEVEL_MAIN   }
 };
 
 static lookups collection[] = {
@@ -285,7 +285,7 @@
 	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|book",             ALWAYS,          LEVEL_MAIN   }
+	{ "",                "GENRE:MARC|book",        ALWAYS,          LEVEL_MAIN   }
 };
 
 /* Part of a book (e.g. chapter or section) */
@@ -362,8 +362,8 @@
 	{ "",                "INTERNAL_TYPE|INBOOK",   ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_HOST   },
-        { "",                "NGENRE|book chapter",    ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|book",             ALWAYS,          LEVEL_HOST   }
+        { "",                "GENRE:BIBUTILS|book chapter", ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|book",             ALWAYS,          LEVEL_HOST   }
 };
 
 /* incollection */
@@ -444,7 +444,7 @@
 	{ "",                "INTERNAL_TYPE|INCOLLECTION", ALWAYS,      LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|collection",       ALWAYS,          LEVEL_HOST   }
+	{ "",                "GENRE:BIBUTILS|collection",      ALWAYS,          LEVEL_HOST   }
 };
 
 /* inproceedings */
@@ -527,7 +527,7 @@
 	{ "",                "INTERNAL_TYPE|INPROCEEDINGS", ALWAYS,     LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|monographic",   ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|conference publication", ALWAYS,    LEVEL_HOST   }
+	{ "",                "GENRE:MARC|conference publication", ALWAYS,    LEVEL_HOST   }
 };
 
 static lookups manual[] = {
@@ -561,7 +561,7 @@
 	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },
 	{ "edition",         "EDITION",                SIMPLE,          LEVEL_MAIN   },
 	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },
-	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },
+	{ "type",            "GENRE:UNKNOWN",          GENRE,           LEVEL_MAIN   },
 	{ "series",          "TITLE",                  SIMPLE,          LEVEL_HOST   },
 	{ "number",          "NUMBER",                 SIMPLE,          LEVEL_MAIN   },
 	{ "note",            "NOTES",                  NOTES,           LEVEL_MAIN   },
@@ -589,7 +589,7 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|REPORT",   ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|instruction",      ALWAYS,          LEVEL_MAIN   }
+	{ "",                "GENRE:MARC|instruction",      ALWAYS,          LEVEL_MAIN   }
 };
 
 static lookups misc[] = {
@@ -617,7 +617,7 @@
 	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },
 	{ "howpublished",    "",                       HOWPUBLISHED,    LEVEL_MAIN   },
 	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },
-	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },
+	{ "type",            "GENRE:UNKNOWN",          GENRE,           LEVEL_MAIN   },
 	{ "note",            "NOTES",                  NOTES,           LEVEL_MAIN   },
 	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
 	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
@@ -638,6 +638,7 @@
 	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|MISC",     ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:BIBUTILS|miscellaneous",   ALWAYS,          LEVEL_MAIN   },
 };
 
 static lookups online[] = {
@@ -664,7 +665,7 @@
 	{ "year",            "DATE:YEAR",              SIMPLE,          LEVEL_MAIN   },
 	{ "language",        "LANGUAGE",               SIMPLE,          LEVEL_MAIN   },
 	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },
-	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },
+	{ "type",            "GENRE:UNKNOWN",          GENRE,           LEVEL_MAIN   },
 	{ "note",            "NOTES",                  NOTES,           LEVEL_MAIN   },
 	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
 	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
@@ -685,7 +686,7 @@
 	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
         { "",                "RESOURCE|software, multimedia", ALWAYS,   LEVEL_MAIN   },
-	{ "",                "NGENRE|web page",        ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|web page",    ALWAYS,          LEVEL_MAIN   },
 };
 
 static lookups patent[] = {
@@ -700,7 +701,7 @@
 	{ "month",           "DATE:MONTH",             SIMPLE,          LEVEL_MAIN   },
 	{ "year",            "DATE:YEAR",              SIMPLE,          LEVEL_MAIN   },
 	{ "version",         "EDITION",                SIMPLE,          LEVEL_MAIN   },
-	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },
+	{ "type",            "GENRE:UKNOWN",           GENRE,           LEVEL_MAIN   },
 	{ "note",            "NOTES",                  NOTES,           LEVEL_MAIN   },
 	{ "annote",          "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
 	{ "annotation",      "ANNOTATION",             SIMPLE,          LEVEL_MAIN   },
@@ -719,7 +720,7 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|PATENT",   ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|patent",           ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|patent",      ALWAYS,          LEVEL_MAIN   },
 };
 
 /*
@@ -778,8 +779,8 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "ISSUANCE|continuing",    ALWAYS,          LEVEL_HOST   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|issue",            ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|periodical",       ALWAYS,          LEVEL_HOST   }
+	{ "",                "GENRE:MARC|issue",       ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|periodical",  ALWAYS,          LEVEL_HOST   }
 };
 
 static lookups proceedings[] = {
@@ -851,7 +852,7 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },
         { "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-        { "",                "GENRE|conference publication", ALWAYS,    LEVEL_MAIN   }
+        { "",                "GENRE:MARC|conference publication", ALWAYS,    LEVEL_MAIN   }
 };
 
 /* Technical reports */
@@ -862,7 +863,7 @@
 	{ "titleaddon",      "TITLEADDON",             TITLE,           LEVEL_MAIN   },
 	{ "shorttitle",      "SHORTTITLE",             SIMPLE,          LEVEL_MAIN   },
 	{ "series",          "TITLE",                  TITLE,           LEVEL_HOST   },
-	{ "type",            "GENRE",                  BT_GENRE,        LEVEL_MAIN   },
+	{ "type",            "GENRE:UNKNOWN",          GENRE,           LEVEL_MAIN   },
 	{ "institution",     "SPONSOR:ASIS",           SIMPLE,          LEVEL_MAIN   },
 	{ "year",            "DATE:YEAR",              SIMPLE,          LEVEL_MAIN   },
 	{ "month",           "DATE:MONTH",             SIMPLE,          LEVEL_MAIN   },
@@ -891,9 +892,9 @@
 	{ "address",         "ADDRESS",                SIMPLE,          LEVEL_MAIN   },
 	{ "hyphenation",     "LANGCATALOG",            SIMPLE,          LEVEL_MAIN   },
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
-	{ "",                "INTERNAL_TYPE|REPORT",   ALWAYS,          LEVEL_MAIN   },
-	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|report",           ALWAYS,          LEVEL_MAIN   }
+	{ "",                "INTERNAL_TYPE|REPORT",        ALWAYS,     LEVEL_MAIN   },
+	{ "",                "RESOURCE|text",               ALWAYS,     LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|technical report", ALWAYS,     LEVEL_MAIN   },
 };
 
 /* Unpublished */
@@ -923,7 +924,7 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|BOOK",     ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|unpublished",      ALWAYS,          LEVEL_MAIN   }
+	{ "",                "GENRE:BIBUTILS|unpublished",     ALWAYS,          LEVEL_MAIN   }
 };
 
 static lookups thesis[] = {
@@ -957,7 +958,7 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|THESIS",   ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|thesis",           ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|thesis",      ALWAYS,          LEVEL_MAIN   },
 };
 
 static lookups phdthesis[] = {
@@ -991,8 +992,8 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|THESIS",   ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|thesis",           ALWAYS,          LEVEL_MAIN   },
-	{ "",                "NGENRE|Ph.D. thesis",    DEFAULT,         LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|thesis",      ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:BIBUTILS|Ph.D. thesis",DEFAULT,     LEVEL_MAIN   },
 };
 
 static lookups mastersthesis[] = {
@@ -1026,8 +1027,8 @@
 	{ "refnum",          "REFNUM",                 SIMPLE,          LEVEL_MAIN   },
 	{ "",                "INTERNAL_TYPE|THESIS",   ALWAYS,          LEVEL_MAIN   },
 	{ "",                "RESOURCE|text",          ALWAYS,          LEVEL_MAIN   },
-	{ "",                "GENRE|thesis",           ALWAYS,          LEVEL_MAIN   },
-	{ "",                "NGENRE|Masters thesis",  DEFAULT,         LEVEL_MAIN   },
+	{ "",                "GENRE:MARC|thesis",      ALWAYS,          LEVEL_MAIN   },
+	{ "",                "GENRE:BIBUTILS|Masters thesis",  DEFAULT, LEVEL_MAIN   },
 };
 
 #define ORIG(a) ( &(a[0]) )
diff --git a/bibutils/bu_auth.c b/bibutils/bu_auth.c
new file mode 100644
--- /dev/null
+++ b/bibutils/bu_auth.c
@@ -0,0 +1,61 @@
+/*
+ * bu_auth.c
+ *
+ * Copyright (c) Chris Putnam 2017-2018
+ *
+ * Source code released under the GPL version 2
+ */
+#include <string.h>
+#include "bu_auth.h"
+
+const char *bu_genre[] = {
+	"academic journal",
+	"airtel",
+	"collection",
+	"communication",
+	"Diploma thesis",
+	"Doctoral thesis",
+	"electronic",
+	"e-mail communication"
+	"Habilitation thesis",
+	"handwritten note",
+	"hearing",
+	"journal article",
+	"magazine",
+	"magazine article",
+	"manuscript",
+	"Masters thesis",
+	"memo",
+	"miscellaneous",
+	"newspaper article",
+	"pamphlet",
+	"Ph.D. thesis",
+	"press release",
+	"teletype",
+	"television broadcast",
+	"unpublished"
+};
+int nbu_genre = sizeof( bu_genre ) / sizeof( const char *);
+
+static int
+position_in_list( const char *list[], int nlist, const char *query )
+{
+	int i;
+	for ( i=0; i<nlist; ++i ) {
+		if ( !strcasecmp( query, list[i] ) ) return i;
+	}
+	return -1;
+}
+
+int
+bu_findgenre( const char *query )
+{
+	return position_in_list( bu_genre, nbu_genre, query );
+}
+
+int
+is_bu_genre( const char *query )
+{
+	if ( bu_findgenre( query ) != -1 ) return 1;
+	return 0;
+}
diff --git a/bibutils/bu_auth.h b/bibutils/bu_auth.h
new file mode 100644
--- /dev/null
+++ b/bibutils/bu_auth.h
@@ -0,0 +1,17 @@
+/*
+ * bu_auth.h
+ *
+ * Recognize added vocabulary for genre terms added by bibutils.
+ *
+ * Copyright (c) Chris Putnam 2017-2018
+ *
+ * Source code released under the GPL version 2
+ *
+ */
+#ifndef BU_AUTH_H
+#define BU_AUTH_H
+
+int bu_findgenre( const char *query );
+int is_bu_genre( const char *query );
+
+#endif
diff --git a/bibutils/charsets.c b/bibutils/charsets.c
--- a/bibutils/charsets.c
+++ b/bibutils/charsets.c
@@ -1,7 +1,7 @@
 /*
  * charsets.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/charsets.h b/bibutils/charsets.h
--- a/bibutils/charsets.h
+++ b/bibutils/charsets.h
@@ -1,7 +1,7 @@
 /*
  * charsets.h
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/copacin.c b/bibutils/copacin.c
--- a/bibutils/copacin.c
+++ b/bibutils/copacin.c
@@ -1,7 +1,7 @@
 /*
  * copacin.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Program and source code released under the GPL version 2
  *
diff --git a/bibutils/copactypes.c b/bibutils/copactypes.c
--- a/bibutils/copactypes.c
+++ b/bibutils/copactypes.c
@@ -1,7 +1,7 @@
 /*
  * copactypes.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Program and source code released under the GPL version 2
  *
diff --git a/bibutils/ebiin.c b/bibutils/ebiin.c
--- a/bibutils/ebiin.c
+++ b/bibutils/ebiin.c
@@ -1,7 +1,7 @@
 /*
  * ebiin.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -12,6 +12,8 @@
 #include "str.h"
 #include "str_conv.h"
 #include "fields.h"
+#include "bu_auth.h"
+#include "marc_auth.h"
 #include "xml.h"
 #include "xml_encoding.h"
 #include "bibformats.h"
@@ -69,14 +71,14 @@
 			if ( m!=CHARSET_UNKNOWN ) file_charset = m;
 		}
 		if ( line->data )
-			startptr = xml_findstart( line->data, "Publication" );
+			startptr = xml_find_start( line->data, "Publication" );
 		if ( startptr || inref ) {
 			if ( inref ) str_strcat( &tmp, line );
 			else {
 				str_strcatc( &tmp, startptr );
 				inref = 1;
 			}
-			endptr = xml_findend( str_cstr( &tmp ), "Publication" );
+			endptr = xml_find_end( str_cstr( &tmp ), "Publication" );
 			if ( endptr ) {
 				str_segcpy( reference, str_cstr( &tmp ), endptr );
 				haveref = 1;
@@ -105,19 +107,19 @@
 	int i, status;
 	char *d;
 
-	if ( !xml_hasvalue( node ) ) goto out;
+	if ( !xml_has_value( node ) ) goto out;
 
-	d = xml_value( node );
+	d = xml_value_cstr( node );
 	for ( i=0; i<nc; ++i ) {
 		if ( c[i].a==NULL ) {
-			if ( xml_tagexact( node, c[i].in ) ) {
+			if ( xml_tag_matches( node, c[i].in ) ) {
 				*found = 1;
 				status = fields_add( info, c[i].out, d, c[i].level );
 				if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 				else return BIBL_OK;
 			}
 		} else {
-			if ( xml_tag_attrib( node, c[i].in, c[i].a, c[i].aval)){
+			if ( xml_tag_has_attribute( node, c[i].in, c[i].a, c[i].aval ) ){
 				*found = 1;
 				status = fields_add( info, c[i].out, d, c[i].level );
 				if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
@@ -139,8 +141,8 @@
 ebiin_title( xml *node, fields *info, int title_level )
 {
 	int status;
-	if ( xml_hasvalue( node ) ) {
-		status = fields_add( info, "TITLE", xml_value( node ), title_level );
+	if ( xml_has_value( node ) ) {
+		status = fields_add( info, "TITLE", xml_value_cstr( node ), title_level );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	return BIBL_OK;
@@ -152,57 +154,91 @@
  *             <MedlineDate>2003 Jan-Feb</MedlineDate>
  */
 static int
-ebiin_medlinedate_year( fields *info, char *p, str *s, int level, char **end )
+ebiin_medlinedate_year( fields *info, char *p, int level, char **end )
 {
-	int status;
-	*end = str_cpytodelim( s, p, " \t\n\r", 0 );
-	if ( str_memerr( s ) ) return BIBL_ERR_MEMERR;
-	if ( str_has_value( s ) ) {
-		status = fields_add( info, "PARTDATE:YEAR", s->data, level );
-		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
+	int fstatus, status = BIBL_OK;
+	str s;
+
+	str_init( &s );
+
+	*end = str_cpytodelim( &s, p, " \t\n\r", 0 );
+	if ( str_memerr( &s ) ) {
+		status = BIBL_ERR_MEMERR;
+		goto out;
 	}
-	return BIBL_OK;
-}
-static int
-ebiin_medlinedate_month( fields *info, char *p, str *s, int level, char **end )
-{
-	int status;
-	*end = str_cpytodelim( s, p, " \t\n\r", 0 );
-	str_findreplace( s, "-", "/" );
-	if ( str_memerr( s ) ) return BIBL_ERR_MEMERR;
-	if ( str_has_value( s ) ) {
-		status = fields_add( info, "PARTDATE:MONTH", s->data, level );
-		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
+	if ( str_has_value( &s ) ) {
+		fstatus = fields_add( info, "PARTDATE:YEAR", str_cstr( &s ), level );
+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
 	}
-	return BIBL_OK;
+out:
+	str_free( &s );
+	return status;
 }
 static int
-ebiin_medlinedate_day( fields *info, char *p, str *s, int level, char **end )
+ebiin_medlinedate_month( fields *info, char *p, int level, char **end )
 {
-	int status;
-	*end = str_cpytodelim( s, p, " \t\n\r", 0 );
-	if ( str_memerr( s ) ) return BIBL_ERR_MEMERR;
-	if ( str_has_value( s ) ) {
-		status = fields_add( info, "PARTDATE:DAY", s->data, level );
-		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
+	int fstatus, status = BIBL_OK;
+	str s;
+
+	str_init( &s );
+
+	*end = str_cpytodelim( &s, p, " \t\n\r", 0 );
+	str_findreplace( &s, "-", "/" );
+	if ( str_memerr( &s ) ) {
+		status = BIBL_ERR_MEMERR;
+		goto out;
 	}
-	return BIBL_OK;
+	if ( str_has_value( &s ) ) {
+		fstatus = fields_add( info, "PARTDATE:MONTH", str_cstr( &s ), level );
+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
+	}
+out:
+	str_free( &s );
+	return status;
 }
+
 static int
-ebiin_medlinedate( fields *info, char *p, int level )
+ebiin_medlinedate_day( fields *info, char *p, int level, char **end )
 {
-	int status;
+	int fstatus, status = BIBL_OK;
 	str s;
+
 	str_init( &s );
-	status = ebiin_medlinedate_year( info, skip_ws( p ), &s, level, &p );
-	if ( status==BIBL_OK && *p )
-		status = ebiin_medlinedate_month( info, skip_ws( p ), &s, level, &p );
-	if ( status==BIBL_OK && *p )
-		status = ebiin_medlinedate_day( info, skip_ws( p ), &s, level, &p );
+
+	*end = str_cpytodelim( &s, p, " \t\n\r", 0 );
+	if ( str_memerr( &s ) ) {
+		status = BIBL_ERR_MEMERR;
+		goto out;
+	}
+	if ( str_has_value( &s ) ) {
+		fstatus = fields_add( info, "PARTDATE:DAY", str_cstr( &s ), level );
+		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
+	}
+out:
 	str_free( &s );
 	return status;
 }
 
+static int
+ebiin_medlinedate( fields *info, xml *node, int level )
+{
+	int status = BIBL_OK;
+	char *p;
+
+	if ( !xml_has_value( node ) ) return status;
+
+	p = xml_value_cstr( node );
+
+	if ( *p )
+		status = ebiin_medlinedate_year( info, skip_ws( p ), level, &p );
+	if ( *p && status==BIBL_OK )
+		status = ebiin_medlinedate_month( info, skip_ws( p ), level, &p );
+	if ( *p && status==BIBL_OK )
+		status = ebiin_medlinedate_day( info, skip_ws( p ), level, &p );
+
+	return status;
+}
+
 /* <Journal>
  *    <ISSN>0027-8424</ISSN>
  *    <JournalIssue PrintYN="Y">
@@ -244,12 +280,12 @@
 		{ "Language", NULL, NULL, "LANGUAGE",       1 },
 	};
 	int nc = sizeof( c ) / sizeof( c[0] ), status, found;
-	if ( xml_hasvalue( node ) ) {
+	if ( xml_has_value( node ) ) {
 		status = ebiin_doconvert( node, info, c, nc, &found );
 		if ( status!=BIBL_OK ) return status;
 		if ( !found ) {
-			if ( xml_tagexact( node, "MedlineDate" ) ) {
-				status = ebiin_medlinedate( info, xml_value( node ), 1 );
+			if ( xml_tag_matches( node, "MedlineDate" ) ) {
+				status = ebiin_medlinedate( info, node, LEVEL_HOST );
 				if ( status!=BIBL_OK ) return status;
 			}
 		}
@@ -286,7 +322,7 @@
 	}
 
 	/* ...end page */
-	p = str_cpytodelim( &ep, skip_ws( p ), " \t\n\r", 0 );
+	(void) str_cpytodelim( &ep, skip_ws( p ), " \t\n\r", 0 );
 	if ( str_memerr( &ep ) ) {
 		ret = BIBL_ERR_MEMERR;
 		goto out;
@@ -303,7 +339,7 @@
 		if ( sp.len > ep.len ) {
 			for ( i=sp.len-ep.len; i<sp.len; ++i )
 				sp.data[i] = ep.data[i-sp.len+ep.len];
-				up = &(sp);
+			up = &(sp);
 		} else up = &(ep);
 		status = fields_add( info, "PAGES:STOP", up->data, level );
 		if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
@@ -317,8 +353,8 @@
 ebiin_pagination( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagexact( node, "Pages" ) && node->value ) {
-		status = ebiin_pages( info, xml_value( node ) );
+	if ( xml_tag_matches_has_value( node, "Pages" ) ) {
+		status = ebiin_pages( info, xml_value_cstr( node ) );
 		if ( status!=BIBL_OK ) return status;
 	}
 	if ( node->down ) {
@@ -340,8 +376,8 @@
 ebiin_abstract( xml *node, fields *info )
 {
 	int status;
-	if ( xml_hasvalue( node ) && xml_tagexact( node, "AbstractText" ) ) {
-		status = fields_add( info, "ABSTRACT", xml_value( node ), 0 );
+	if ( xml_tag_matches_has_value( node, "AbstractText" ) ) {
+		status = fields_add( info, "ABSTRACT", xml_value_cstr( node ), 0 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	else if ( node->next ) {
@@ -365,22 +401,22 @@
 {
 	int status;
 	char *p;
-	if ( xml_tagexact( node, "LastName" ) ) {
+	if ( xml_tag_matches( node, "LastName" ) ) {
 		if ( name->len ) {
 			str_prepend( name, "|" );
-			str_prepend( name, xml_value( node ) );
+			str_prepend( name, xml_value_cstr( node ) );
 		}
-		else str_strcatc( name, xml_value( node ) );
-	} else if ( xml_tagexact( node, "ForeName" ) || 
-	            xml_tagexact( node, "FirstName" ) ) {
-		p = xml_value( node );
+		else str_strcat( name, xml_value( node ) );
+	} else if ( xml_tag_matches( node, "ForeName" ) ||
+	            xml_tag_matches( node, "FirstName" ) ) {
+		p = xml_value_cstr( node );
 		while ( p && *p ) {
 			if ( name->len ) str_addchar( name, '|' );
-			while ( *p && *p==' ' ) p++;
+			while ( *p==' ' ) p++;
 			while ( *p && *p!=' ' ) str_addchar( name, *p++ );
 		}
-	} else if ( xml_tagexact( node, "Initials" ) && !strchr( name->data, '|' ) ) {
-		p = xml_value( node );
+	} else if ( xml_tag_matches( node, "Initials" ) && !strchr( name->data, '|' ) ) {
+		p = xml_value_cstr( node );
 		while ( p && *p ) {
 			if ( name->len ) str_addchar( name, '|' );
 			if ( !is_ws(*p ) ) str_addchar( name, *p++ );
@@ -408,7 +444,7 @@
 	str_init( &name );
 	node = node->down;
 	while ( node ) {
-		if ( xml_tagexact( node, "Author" ) && node->down ) {
+		if ( xml_tag_matches( node, "Author" ) && node->down ) {
 			status = ebiin_author( node->down, &name );
 			if ( status!=BIBL_OK ) goto out;
 			if ( name.len ) {
@@ -440,8 +476,8 @@
 ebiin_journal2( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagwithvalue( node, "TitleAbbreviation" ) ) {
-		status = fields_add( info, "TITLE", xml_value( node ), 1 );
+	if ( xml_tag_matches_has_value( node, "TitleAbbreviation" ) ) {
+		status = fields_add( info, "TITLE", xml_value_cstr( node ), 1 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
@@ -469,8 +505,8 @@
 ebiin_meshheading( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagwithvalue( node, "DescriptorName" ) ) {
-		status = fields_add( info, "KEYWORD", xml_value( node ), 0 );
+	if ( xml_tag_matches_has_value( node, "DescriptorName" ) ) {
+		status = fields_add( info, "KEYWORD", xml_value_cstr( node ), 0 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->next ) {
@@ -484,7 +520,7 @@
 ebiin_meshheadinglist( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagexact( node, "MeshHeading" ) && node->down ) {
+	if ( xml_tag_matches( node, "MeshHeading" ) && node->down ) {
 		status = ebiin_meshheading( node->down, info );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -528,34 +564,43 @@
 		{ "Edition",                NULL, NULL, "EDITION",        1 },
 	};
 	int ninbook = sizeof( inbook ) / sizeof( inbook[0] );
-	xml_convert *c;
 	int nc, status, found;
-	if ( book_level==0 ) { c = book; nc = nbook; }
-	else { c = inbook; nc = ninbook; }
-	if ( xml_hasvalue( node ) ) {
-		status = ebiin_doconvert( node, info, c, nc, &found );
+	xml_convert *c;
+
+	if ( book_level==0 ) {
+		c  = book;
+		nc = nbook;
+	}
+	else {
+		c  = inbook;
+		nc = ninbook;
+	}
+
+	status = ebiin_doconvert( node, info, c, nc, &found );
+	if ( status!=BIBL_OK ) return status;
+
+	if ( !found ) {
+		status = BIBL_OK;
+		if ( xml_tag_matches( node, "MedlineDate" ) )
+			status = ebiin_medlinedate( info, node, book_level );
+		else if ( xml_tag_matches( node, "Title" ) )
+			status = ebiin_title( node, info, book_level );
+		else if ( xml_tag_matches( node, "Pagination" ) && node->down )
+			status = ebiin_pagination( node->down, info );
+		else if ( xml_tag_matches( node, "Abstract" ) && node->down )
+			status = ebiin_abstract( node->down, info );
+		else if ( xml_tag_matches( node, "AuthorList" ) )
+			status = ebiin_authorlist( node, info, book_level );
+		else if ( xml_tag_matches( node, "PubDate" ) && node->down )
+			status = ebiin_book( node->down, info, book_level );
 		if ( status!=BIBL_OK ) return status;
-		if ( !found ) {
-			status = BIBL_OK;
-			if ( xml_tagexact( node, "MedlineDate" ) )
-				status = ebiin_medlinedate( info, xml_value( node ), book_level);
-			else if ( xml_tagexact( node, "Title" ) )
-				status = ebiin_title( node, info, book_level );
-			else if ( xml_tagexact( node, "Pagination" ) && node->down )
-				status = ebiin_pagination( node->down, info );
-			else if ( xml_tagexact( node, "Abstract" ) && node->down )
-				status = ebiin_abstract( node->down, info );
-			else if ( xml_tagexact( node, "AuthorList" ) )
-				status = ebiin_authorlist( node, info, book_level );
-			else if ( xml_tagexact( node, "PubDate" ) && node->down)
-				status = ebiin_book( node->down, info, book_level );
-			if ( status!=BIBL_OK ) return status;
-		}
 	}
+
 	if ( node->next ) {
 		status = ebiin_book( node->next, info, book_level );
 		if ( status!=BIBL_OK ) return status;
 	}
+
 	return BIBL_OK;
 }
 
@@ -564,18 +609,18 @@
 {
 	int status = BIBL_OK;
 
-	if ( xml_tagexact( node, "Journal" ) ) 
+	if ( xml_tag_matches( node, "Journal" ) )
 		status = ebiin_journal1( node, info );
-	else if ( node->down && ( xml_tagexact( node, "Book" ) || 
-			xml_tagexact(node, "Report") )) 
+	else if ( node->down && ( xml_tag_matches( node, "Book" ) ||
+			xml_tag_matches(node, "Report") ))
 		status = ebiin_book( node->down, info, 1 );
-	else if ( xml_tagexact( node, "ArticleTitle" ) )
+	else if ( xml_tag_matches( node, "ArticleTitle" ) )
 		status = ebiin_title( node, info, 0 );
-	else if ( xml_tagexact( node, "Pagination" ) && node->down )
+	else if ( xml_tag_matches( node, "Pagination" ) && node->down )
 		status = ebiin_pagination( node->down, info );
-	else if ( xml_tagexact( node, "Abstract" ) && node->down )
+	else if ( xml_tag_matches( node, "Abstract" ) && node->down )
 		status = ebiin_abstract( node->down, info );
-	else if ( xml_tagexact( node, "AuthorList" ) )
+	else if ( xml_tag_matches( node, "AuthorList" ) )
 		status = ebiin_authorlist( node, info, 0 );
 	if ( status!=BIBL_OK ) return status;
 
@@ -592,15 +637,15 @@
 {
 	int status = BIBL_OK;
 	if ( node->down ) {
-		if ( xml_tagexact( node, "Article" ) )
+		if ( xml_tag_matches( node, "Article" ) )
 			status = ebiin_article( node->down, info );
-		else if ( xml_tagexact( node, "Book" ) )
+		else if ( xml_tag_matches( node, "Book" ) )
 			status = ebiin_book( node->down, info, 0 );
-		else if ( xml_tagexact( node, "Report" ) )
+		else if ( xml_tag_matches( node, "Report" ) )
 			status = ebiin_book( node->down, info, 0 );
-		else if ( xml_tagexact( node, "JournalInfo" ) )
+		else if ( xml_tag_matches( node, "JournalInfo" ) )
 			status = ebiin_journal2( node->down, info );
-		else if ( xml_tagexact( node, "MeshHeadingList" ) )
+		else if ( xml_tag_matches( node, "MeshHeadingList" ) )
 			status = ebiin_meshheadinglist( node->down, info );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -620,7 +665,7 @@
 	int reslvl, isslvl, gen1lvl, gen2lvl;
 	int status;
 
-	type = xml_getattrib( node, "Type" );
+	type = xml_attribute( node, "Type" );
 	if ( !type || type->len==0 ) return BIBL_OK;
 
 	if ( !strcmp( type->data, "JournalArticle" ) ) {
@@ -657,11 +702,21 @@
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( genre1 ) {
-		status = fields_add( info, "GENRE", genre1, gen1lvl );
+		if ( is_marc_genre( genre1 ) )
+			status = fields_add( info, "GENRE:MARC", genre1, gen1lvl );
+		else if ( is_bu_genre( genre1 ) )
+			status = fields_add( info, "GENRE:BIBUTILS", genre1, gen1lvl );
+		else
+			status = fields_add( info, "GENRE:UNKNOWN", genre1, gen1lvl );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( genre2 ) {
-		status = fields_add( info, "GENRE", genre2, gen2lvl );
+		if ( is_marc_genre( genre2 ) )
+			status = fields_add( info, "GENRE:MARC", genre2, gen2lvl );
+		else if ( is_bu_genre( genre2 ) )
+			status = fields_add( info, "GENRE:BIBUTILS", genre2, gen2lvl );
+		else
+			status = fields_add( info, "GENRE:UNKNOWN", genre2, gen2lvl );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 
@@ -672,7 +727,7 @@
 ebiin_assembleref( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagexact( node, "Publication" ) && node->down ) {
+	if ( xml_tag_matches( node, "Publication" ) && node->down ) {
 		status = ebiin_fixtype( node, info );
 		if ( status!=BIBL_OK ) return status;
 		status = ebiin_publication( node->down, info );
@@ -695,7 +750,7 @@
 	xml top;
 
 	xml_init( &top );
-	xml_tree( data, &top );
+	xml_parse( data, &top );
 	status = ebiin_assembleref( &top, ebiin );
 	xml_free( &top );
 
diff --git a/bibutils/endin.c b/bibutils/endin.c
--- a/bibutils/endin.c
+++ b/bibutils/endin.c
@@ -1,7 +1,7 @@
 /*
  * endin.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -256,7 +256,7 @@
 {
 	str *t, *v;
 	t = fields_tag( endin, n, FIELDS_STRP_NOUSE );
-	if ( str_is_empty( t ) || strcmp( t->data, "%A" ) ) return 0;
+	if ( str_is_empty( t ) || strcmp( str_cstr( t ), "%A" ) ) return 0;
 	v = fields_value( endin, n, FIELDS_STRP_NOUSE );
 	if ( str_is_empty( v ) ) return 0;
 	if ( v->data[v->len-1]!=',' ) return 0;
@@ -264,45 +264,70 @@
 }
 
 static int
+add_wiley_author( fields *endin, char *intag, str *instring, int inlevel, str *name, int authornum )
+{
+	int fstatus;
+
+	/* if first author, just replace the data string in the field */
+	if ( authornum==0 ) {
+		str_strcpy( instring, name );
+		if ( str_memerr( instring ) ) return BIBL_ERR_MEMERR;
+	}
+
+	/* otherwise, append the author */
+	else {
+		fstatus = fields_add( endin, intag, str_cstr( name ), inlevel );
+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
+	}
+
+	return BIBL_OK;
+}
+
+static int
 cleanup_wiley_author( fields *endin, int n )
 {	
+	int status=BIBL_OK, inlevel, authornum = 0;
 	str *instring, copy, name;
-	int status, nauthor = 0;
-	char *p;
+	char *p, *intag;
 
 	strs_init( &copy, &name, NULL );
 
-	instring = &( endin->data[n] );
+	intag    = fields_tag  ( endin, n, FIELDS_CHRP_NOUSE );
+	instring = fields_value( endin, n, FIELDS_STRP_NOUSE );
+	inlevel  = fields_level( endin, n );
+
 	str_strcpy( &copy, instring );
+	p = str_cstr( &copy );
 
-	p = copy.data;
 	while ( *p ) {
+
 		if ( *p==',' ) {
-			if ( str_memerr( &name ) )
-				return BIBL_ERR_MEMERR;
-			if ( nauthor==0 ) {
-				/* ...replace the first author in the field */
-				str_strcpy( instring, &name );
-				if ( str_memerr( instring ) )
-					return BIBL_ERR_MEMERR;
-			} else {
-				status = fields_add( endin, endin->tag[n].data,
-					name.data, endin->level[n] );
-				if ( status!=FIELDS_OK )
-					return BIBL_ERR_MEMERR;
+			if ( str_memerr( &name ) ) {
+				status = BIBL_ERR_MEMERR;
+				goto out;
 			}
+
+			status = add_wiley_author( endin, intag, instring, inlevel, &name, authornum );
+			if ( status!=BIBL_OK ) goto out;
+
 			str_empty( &name );
-			nauthor++;
+			authornum++;
+
 			p++;
 			while ( is_ws( *p ) ) p++;
-		} else {
+		}
+
+		else {
 			str_addchar( &name, *p );
 			p++;
 		}
 	}
 
+	if ( str_has_value( &name ) )
+		status = add_wiley_author( endin, intag, instring, inlevel, &name, authornum );
+out:
 	strs_free( &copy, &name, NULL );
-	return BIBL_OK;
+	return status;
 }
 
 static int
@@ -434,7 +459,7 @@
 		if ( *p==',' ) p++;
 
 		/* ...get year */
-		p = str_cpytodelim( &date, skip_ws( p ), " \t\n\r", 0 );
+		(void) str_cpytodelim( &date, skip_ws( p ), " \t\n\r", 0 );
 		if ( str_memerr( &date ) ) return BIBL_ERR_MEMERR;
 		if ( str_has_value( &date ) ) {
 			status = fields_add( bibout, tags[0][part], date.data, level );
@@ -514,6 +539,7 @@
 		[ PAGES        ] = generic_pages,
 		[ NOTES        ] = generic_notes,
 		[ URL          ] = generic_url,
+		[ GENRE        ] = generic_genre,
 		[ TYPE         ] = endin_type,
 		[ DATE         ] = endin_date,
         };
diff --git a/bibutils/endout.c b/bibutils/endout.c
--- a/bibutils/endout.c
+++ b/bibutils/endout.c
@@ -1,7 +1,7 @@
 /*
  * endout.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -224,6 +224,7 @@
 		{ "rehearsal",                 TYPE_AUDIOVISUAL },
 /*		{ "remote sensing image",      TYPE_GENERIC },*/
 /*		{ "reporting",                 TYPE_GENERIC },*/
+		{ "report",                    TYPE_REPORT },
 /*		{ "review",                    TYPE_GENERIC },*/
 /*		{ "script",                    TYPE_GENERIC },*/
 /*		{ "series",                    TYPE_GENERIC },*/
@@ -235,7 +236,7 @@
 /*		{ "statistics",                TYPE_GENERIC },*/
 /*		{ "survey of literature",      TYPE_GENERIC },*/
 		{ "technical drawing",         TYPE_ARTWORK },
-		{ "techincal report",          TYPE_REPORT },
+		{ "technical report",          TYPE_REPORT },
 		{ "thesis",                    TYPE_THESIS },
 /*		{ "toy",                       TYPE_GENERIC },*/
 /*		{ "transparency",              TYPE_GENERIC },*/
@@ -253,7 +254,6 @@
 		{ "Habilitation thesis",       TYPE_HABILITATIONTHESIS },
 		{ "communication",             TYPE_COMMUNICATION },
 		{ "manuscript",                TYPE_MANUSCRIPT },
-		{ "report",                    TYPE_REPORT },
 		{ "unpublished",               TYPE_UNPUBLISHED },
 	};
 	int nmatch_genres = sizeof( match_genres ) / sizeof( match_genres[0] );
@@ -264,8 +264,9 @@
 	/* Determine type from genre information */
 	for ( i=0; i<in->n; ++i ) {
 		tag = fields_tag( in, i, FIELDS_CHRP );
-		if ( strcasecmp( tag, "GENRE" )!=0 &&
-		     strcasecmp( tag, "NGENRE" )!=0 ) continue;
+		if ( strcasecmp( tag, "GENRE:MARC" )!=0 &&
+		     strcasecmp( tag, "GENRE:BIBUTILS" )!=0 &&
+		     strcasecmp( tag, "GENRE:UNKNOWN" )!=0 ) continue;
 		data = fields_value( in, i, FIELDS_CHRP );
 		for ( j=0; j<nmatch_genres; ++j ) {
 			if ( !strcasecmp( data, match_genres[j].name ) ) {
@@ -350,8 +351,8 @@
 		else {
 			if ( p->progname ) fprintf( stderr, "%s: ", p->progname );
 			fprintf( stderr, "Cannot identify TYPE in reference %lu ", refnum+1 );
-			n = fields_find( in, "REFNUM", -1 );
-			if ( n!=-1 )
+			n = fields_find( in, "REFNUM", LEVEL_ANY );
+			if ( n!=FIELDS_NOTFOUND )
 				fprintf( stderr, " %s", (char *) fields_value( in, n, FIELDS_CHRP ) );
 			fprintf( stderr, " (defaulting to generic)\n" );
 			type = TYPE_GENERIC;
@@ -565,6 +566,52 @@
 }
 
 static void
+append_genrehint( int type, fields *out, vplist *a, int *status )
+{
+	vplist_index i;
+	int fstatus;
+	char *g;
+
+	for ( i=0; i<a->n; ++i ) {
+		g = ( char * ) vplist_get( a, i );
+		if ( !strcmp( g, "journal article" ) && type==TYPE_ARTICLE ) continue;
+		if ( !strcmp( g, "academic journal" ) && type==TYPE_ARTICLE ) continue;
+		if ( !strcmp( g, "collection" ) && type==TYPE_INBOOK ) continue;
+		if ( !strcmp( g, "television broadcast" ) && type==TYPE_FILMBROADCAST ) continue;
+		if ( !strcmp( g, "electronic" ) && type==TYPE_PROGRAM ) continue;
+		if ( !strcmp( g, "magazine" ) && type==TYPE_MAGARTICLE ) continue;
+		if ( !strcmp( g, "miscellaneous" ) && type==TYPE_GENERIC ) continue;
+		if ( !strcmp( g, "hearing" ) && type==TYPE_HEARING ) continue;
+		if ( !strcmp( g, "communication" ) && type==TYPE_COMMUNICATION ) continue;
+		if ( !strcmp( g, "report" ) && type==TYPE_REPORT ) continue;
+		if ( !strcmp( g, "book chapter" ) && type==TYPE_INBOOK ) continue;
+		fstatus = fields_add( out, "%9", g, LEVEL_MAIN );
+		if ( fstatus!=FIELDS_OK ) {
+			*status = BIBL_ERR_MEMERR;
+			return;
+		}
+	}
+}
+
+static void
+append_all_genrehint( int type, fields *in, fields *out, int *status )
+{
+	vplist a;
+
+	vplist_init( &a );
+
+	fields_findv_each( in, LEVEL_ANY, FIELDS_CHRP, &a, "GENRE:BIBUTILS" );
+	append_genrehint( type, out, &a, status );
+
+	vplist_empty( &a );
+
+	fields_findv_each( in, LEVEL_ANY, FIELDS_CHRP, &a, "GENRE:UNKNOWN" );
+	append_genrehint( type, out, &a, status );
+
+	vplist_free( &a );
+}
+
+static void
 append_thesishint( int type, fields *out, int *status )
 {
 	int fstatus;
@@ -705,7 +752,7 @@
 	append_easy    ( in, "ABSTRACT",           "%X", LEVEL_ANY, out, &status );
 	append_easy    ( in, "CLASSIFICATION"   ,  "%L", LEVEL_ANY, out, &status );
 	append_easyall ( in, "KEYWORD",            "%K", LEVEL_ANY, out, &status );
-	append_easyall ( in, "NGENRE",             "%9", LEVEL_ANY, out, &status );
+	append_all_genrehint(  type, in, out, &status );
 	append_thesishint( type, out, &status );
 	append_easyall ( in, "DOI",                "%R", LEVEL_ANY, out, &status );
 	append_easyall ( in, "URL",                "%U", LEVEL_ANY, out, &status );
diff --git a/bibutils/endtypes.c b/bibutils/endtypes.c
--- a/bibutils/endtypes.c
+++ b/bibutils/endtypes.c
@@ -1,1205 +1,1207 @@
 /*
  * endtypes.c
  *
- * Copyright (c) Chris Putnam 2003-2017
- *
- * Program and source code released under the GPL version 2
- *
- */
-#include <stdio.h>
-#include <string.h>
-#include "is_ws.h"
-#include "fields.h"
-#include "reftypes.h"
-
-/* if no specific type can be identified */
-static lookups generic[] = {
-	{ "%0", "INTERNAL_TYPE", TYPE,   LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE,  LEVEL_MAIN },
-	{ "%J", "TITLE",     TITLE,  LEVEL_HOST }, /* for refer formats */
-	{ "%E", "2ND_AUTHOR",PERSON, LEVEL_MAIN },
-	{ "%B", "2ND_TITLE", SIMPLE, LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE, LEVEL_MAIN }, 
-	{ "%V", "VOLUME" ,   SIMPLE, LEVEL_MAIN },
-	{ "%6", "NUMVOLUMES",SIMPLE, LEVEL_HOST },
-	{ "%N", "NUMBER",    SIMPLE, LEVEL_MAIN },
-	{ "%P", "PAGES",        PAGES,  LEVEL_MAIN },
-	{ "%&", "SECTION",      SIMPLE, LEVEL_MAIN },
-	{ "%Y", "AUTHOR",   PERSON, LEVEL_SERIES },
-	{ "%S", "TITLE",     TITLE, LEVEL_SERIES },
-	{ "%7", "EDITION",      SIMPLE, LEVEL_MAIN },
-	{ "%8", "DATE:MONTH",    DATE,   LEVEL_MAIN },
-	{ "%9", "GENRE",        SIMPLE, LEVEL_MAIN },
-	{ "%?", "SUB_AUTHOR",   PERSON, LEVEL_MAIN }, /* subsidiary-authors */
-	{ "%!", "SHORTTITLE",   TITLE,  LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER", SERIALNO,  LEVEL_MAIN },
-	{ "%(", "TITLE",        SIMPLE, LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_MAIN },
-	{ "%*", "REVIEWEDITEM", SIMPLE, LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,  LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,  LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,  LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,  LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,  LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,  LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE, LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE, LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE, LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE, LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",     SIMPLE, LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES, LEVEL_MAIN },
-	{ "%U", "URL",          URL,    LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%Z", "NOTES",        SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN }
-};
-
-static lookups journalarticle[] = {
-	{ "%0", "INTERNAL_TYPE",         TYPE,     LEVEL_MAIN },
-	{ "%A", "AUTHOR",       PERSON,   LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",   PERSON,   LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE",SIMPLE, LEVEL_MAIN },
-	{ "%D", "PARTDATE:YEAR",     SIMPLE,   LEVEL_MAIN },
-	{ "%T", "TITLE" ,       TITLE,    LEVEL_MAIN },
-	{ "%J", "TITLE",        TITLE,    LEVEL_HOST }, /* journal title */
-	{ "%B", "TITLE",        TITLE,    LEVEL_HOST }, /* journal title */
-	{ "%C", "ADDRESS",      SIMPLE,   LEVEL_MAIN },
-	{ "%V", "VOLUME" ,      SIMPLE,   LEVEL_MAIN },
-	{ "%N", "ISSUE",        SIMPLE,   LEVEL_MAIN },
-	{ "%P", "PAGES",        PAGES,    LEVEL_MAIN },
-	{ "%I", "PUBLISHER",    SIMPLE,   LEVEL_HOST }, 
-	{ "%8", "PARTDATE:MONTH",    DATE,     LEVEL_MAIN },
-	{ "%9", "GENRE",        SIMPLE,   LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",   TITLE,    LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER", SERIALNO, LEVEL_HOST },
-	{ "%(", "TITLE",        SIMPLE,   LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,  LEVEL_MAIN },
-	{ "%*", "REVIEWEDITEM", SIMPLE,   LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE,   LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE,   LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE,   LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE,   LEVEL_MAIN },
-	{ "%X", "ABSTRACT",     SIMPLE,   LEVEL_MAIN },
-	{ "%U", "URL",          URL,      LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES,    LEVEL_MAIN },
-	{ "%Z", "NOTES",        NOTES,    LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE,   LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE,   LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE,   LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE,   LEVEL_MAIN },  /* physical location */
-	{ "%^", "CAPTION",      SIMPLE,   LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE,   LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE,   LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE,   LEVEL_MAIN },
-	{ "  ", "ISSUANCE|continuing",    ALWAYS, LEVEL_HOST },
-	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-        { "  ", "GENRE|journal article",  ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|periodical",       ALWAYS, LEVEL_HOST },
-	{ "  ", "GENRE|academic journal", ALWAYS, LEVEL_HOST }
-};
-
-static lookups magazinearticle[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,    LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON,  LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "PARTDATE:YEAR",  SIMPLE,  LEVEL_MAIN },
-	{ "%T", "TITLE",     TITLE,   LEVEL_MAIN },
-	{ "%J", "TITLE",     TITLE,   LEVEL_HOST }, /* magazine name */
-	{ "%B", "TITLE",     TITLE,   LEVEL_HOST }, /* magazine name */
-	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
-	{ "%V", "VOLUME",    SIMPLE,  LEVEL_MAIN },
-	{ "%N", "ISSUE",     SIMPLE,  LEVEL_MAIN },
-	{ "%P", "PAGES",     PAGES,   LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE,    LEVEL_HOST }, 
-	{ "%8", "PARTDATE:MONTH", DATE,    LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,   LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER",      SERIALNO,LEVEL_HOST },
-	{ "%(", "TITLE",     SIMPLE,  LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_MAIN },
-	{ "%*", "REVIEWEDITEM",SIMPLE,LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,  LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,  LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,  LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,  LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,  LEVEL_MAIN },
-	{ "%U", "URL",       URL,     LEVEL_MAIN },
-	{ "%O", "NOTES",     SIMPLE,  LEVEL_MAIN },
-	{ "%Z", "NOTES",     SIMPLE,  LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE,LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "ISSUANCE|continuing",  ALWAYS, LEVEL_HOST },
-	{ "  ", "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|periodical",     ALWAYS, LEVEL_HOST },
-	{ "  ", "GENRE|magazine",       ALWAYS, LEVEL_HOST }
-};
-
-static lookups newspaperarticle[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,    LEVEL_MAIN },
-	{ "%A", "REPORTER",  PERSON,  LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "PARTDATE:YEAR",  SIMPLE,  LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE,   LEVEL_MAIN },
-	{ "%J", "TITLE",     TITLE,   LEVEL_HOST }, /* newspaper name */
-	{ "%B", "TITLE",     TITLE,   LEVEL_HOST }, /* newspaper name */
-	{ "%V", "VOLUME" ,   SIMPLE,  LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
-	{ "%N", "ISSUE",     SIMPLE,  LEVEL_MAIN },
-	{ "%P", "PAGES",     PAGES,   LEVEL_MAIN },
-	{ "%7", "EDITION",   SIMPLE,  LEVEL_MAIN },
-	{ "%8", "PARTDATE:MONTH", DATE,    LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,   LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER",      SERIALNO, LEVEL_MAIN },
-	{ "%(", "TITLE",     SIMPLE, LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE, LEVEL_MAIN },
-	{ "%*", "REVIEWEDITEM",SIMPLE,LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,  LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,  LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,  LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,  LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,  LEVEL_MAIN },
-	{ "%U", "URL",       URL,     LEVEL_MAIN },
-	{ "%O", "NOTES",     SIMPLE,  LEVEL_MAIN },
-	{ "%Z", "NOTES",     SIMPLE,  LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%+", "AUTHORADDRESS",SIMPLE,LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "ISSUANCE|continuing",    ALWAYS, LEVEL_HOST },
-	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|newspaper",        ALWAYS, LEVEL_HOST }
-};
-
-static lookups book[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,      LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON,    LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE,    LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE,     LEVEL_MAIN },
-	{ "%E", "AUTHOR",    PERSON,    LEVEL_HOST }, /* SERIES_AUTHOR */
-	{ "%B", "TITLE",     TITLE,     LEVEL_HOST }, /* SERIES_TITLE */
-	{ "%S", "TITLE",     TITLE,     LEVEL_SERIES },
-	{ "%C", "ADDRESS",   SIMPLE,    LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE,    LEVEL_MAIN }, 
-	{ "%V", "VOLUME" ,   SIMPLE,    LEVEL_MAIN },
-	{ "%N", "NUMBER",    SIMPLE,    LEVEL_MAIN },
-	{ "%6", "NUMVOLUMES",SIMPLE,    LEVEL_MAIN },
-	{ "%P", "PAGES:TOTAL", SIMPLE,LEVEL_MAIN },
-	{ "%7", "EDITION",   SIMPLE,    LEVEL_MAIN },
-	{ "%?", "TRANSLATOR",PERSON,    LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,     LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER",      SERIALNO,    LEVEL_MAIN },
-	{ "%(", "TITLE",     SIMPLE,   LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,     LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,     LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,     LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,     LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,     LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,     LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,    LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,    LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,    LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,    LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,    LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%U", "URL",       URL,       LEVEL_MAIN },
-	{ "%Z", "NOTES",     SIMPLE,    LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "GENRE|book", ALWAYS,   LEVEL_MAIN },
-	{ "  ", "ISSUANCE|monographic", ALWAYS,   LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups booksection[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,      LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON,    LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE,    LEVEL_HOST },
-	{ "%T", "TITLE" ,    TITLE,     LEVEL_MAIN },
-	{ "%E", "EDITOR",    PERSON,    LEVEL_HOST }, /* editor for book */
-	{ "%B", "TITLE",     TITLE,     LEVEL_HOST }, /* book title */
-	{ "%C", "ADDRESS",   SIMPLE,    LEVEL_HOST },
-	{ "%I", "PUBLISHER", SIMPLE,    LEVEL_HOST }, 
-	{ "%N", "NUMBER",    SIMPLE,    LEVEL_HOST },
-	{ "%V", "VOLUME" ,   SIMPLE,    LEVEL_MAIN },
-	{ "%6", "NUMVOLUMES",SIMPLE,    LEVEL_HOST },
-	{ "%P", "PAGES",     PAGES,     LEVEL_MAIN },
-	{ "%Y", "EDITOR",    PERSON,    LEVEL_SERIES },
-	{ "%S", "TITLE",     TITLE,     LEVEL_SERIES },
-	{ "%7", "EDITION",   SIMPLE,    LEVEL_HOST },
-	{ "%?", "TRANSLATOR",PERSON,    LEVEL_HOST },
-	{ "%!", "SHORTTITLE",TITLE,     LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER",      SERIALNO,    LEVEL_HOST },
-	{ "%(", "TITLE",     SIMPLE,   LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_HOST },
-	{ "%1", "CUSTOM1",   NOTES,     LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,     LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,     LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,     LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,     LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,     LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,    LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,    LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,    LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,    LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,    LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%U", "URL",       URL,       LEVEL_MAIN },
-	{ "%Z", "NOTES",     SIMPLE,    LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-        { "  ", "GENRE|book chapter",   ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|book",           ALWAYS, LEVEL_HOST },
-	{ "  ", "ISSUANCE|monographic", ALWAYS, LEVEL_HOST },
-	{ "  ", "RESOURCE|text",        ALWAYS, LEVEL_MAIN }
-};
-
-static lookups editedbook[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,      LEVEL_MAIN },
-	{ "%A", "EDITOR",    PERSON,    LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE,    LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE,     LEVEL_MAIN },
-	{ "%E", "EDITOR",    PERSON,    LEVEL_HOST }, /* SERIES_EDITOR */
-	{ "%B", "TITLE",     TITLE,     LEVEL_HOST }, /* SERIES_TITLE */
-	{ "%C", "ADDRESS",   SIMPLE,    LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE,    LEVEL_MAIN }, 
-	{ "%N", "NUMBER",    SIMPLE,    LEVEL_MAIN },
-	{ "%V", "VOLUME" ,   SIMPLE,    LEVEL_MAIN },
-	{ "%6", "NUMVOLUMES",SIMPLE,    LEVEL_HOST },
-	{ "%P", "PAGES:TOTAL", SIMPLE,LEVEL_MAIN },
-	{ "%7", "EDITION",   SIMPLE,    LEVEL_MAIN },
-	{ "%?", "TRANSLATOR",PERSON,    LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,     LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER",      SERIALNO,    LEVEL_MAIN },
-	{ "%(", "TITLE",     SIMPLE,   LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,     LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,     LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,     LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,     LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,     LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,     LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,    LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,    LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,    LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,    LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,    LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%U", "URL",       URL,       LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "GENRE|book", ALWAYS, LEVEL_MAIN },
-	{ "  ", "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups manuscript[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,    LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON,  LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE,  LEVEL_MAIN },
-	{ "%T", "TITLE",     TITLE,   LEVEL_MAIN },
-	{ "%B", "TITLE",     TITLE,   LEVEL_HOST }, /* COLLECTION_TITLE */
-	{ "%C", "ADDRESS",   SIMPLE,  LEVEL_MAIN },
-	{ "%N", "NUMBER",    SIMPLE,  LEVEL_MAIN },
-	{ "%P", "PAGES",     PAGES,   LEVEL_MAIN },
-	{ "%8", "DATE:MONTH", DATE,    LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE,  LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,   LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,  LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,  LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,  LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,  LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,  LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,   LEVEL_MAIN },
-	{ "%U", "URL",       URL,     LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,   LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,   LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,   LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,   LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,   LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,   LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,   LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE,LEVEL_MAIN},
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|manuscript", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups communication[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,    LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON,  LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE,  LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE,   LEVEL_MAIN },
-	{ "%E", "RECIPIENT", PERSON,  LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE,  LEVEL_MAIN },
-	{ "%V", "VOLUME",    SIMPLE,  LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE,  LEVEL_MAIN },
-	{ "%8", "DATE:MONTH", DATE,    LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE,  LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,   LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,  LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,  LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,  LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,  LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,  LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,   LEVEL_MAIN },
-	{ "%U", "URL",       URL,     LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,   LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,   LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,   LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,   LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,   LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,   LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,   LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%+", "AUTHORADDRESS",SIMPLE,LEVEL_MAIN},
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "GENRE|communication", ALWAYS, LEVEL_MAIN}
-};
-
-static lookups proceedings[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,    LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON,  LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE,  LEVEL_HOST },
-	{ "%T", "TITLE" ,    TITLE,   LEVEL_MAIN },
-	{ "%E", "EDITOR",    PERSON,  LEVEL_MAIN },
-	{ "%B", "TITLE",     SIMPLE,  LEVEL_HOST }, 
-	{ "%C", "ADDRESS",   SIMPLE,  LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE,  LEVEL_MAIN }, 
-	{ "%V", "VOLUME" ,   SIMPLE,  LEVEL_MAIN },
-	{ "%6", "NUMVOLUMES",SIMPLE,  LEVEL_HOST },
-	{ "%N", "NUMBER",    SIMPLE,  LEVEL_MAIN },
-	{ "%P", "PAGES",     PAGES,   LEVEL_MAIN },
-	{ "%Y", "EDITOR",    PERSON,  LEVEL_SERIES },
-	{ "%S", "TITLE",     TITLE,   LEVEL_SERIES },
-	{ "%7", "EDITION",   SIMPLE,  LEVEL_HOST },
-	{ "%8", "DATE:MONTH", DATE,    LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,   LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,   LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,   LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,   LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,   LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,   LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,   LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,  LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,  LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,  LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,  LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,  LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,   LEVEL_MAIN },
-	{ "%U", "URL",       URL,     LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,   LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE,LEVEL_MAIN},
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|conference publication", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups conferencepaper[] = {
-	{ "%0", "INTERNAL_TYPE",         TYPE,     LEVEL_MAIN },
-	{ "%A", "AUTHOR",       PERSON,   LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",   PERSON,   LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE",SIMPLE, LEVEL_MAIN },
-	{ "%D", "PARTDATE:YEAR",     SIMPLE,   LEVEL_MAIN },
-	{ "%T", "TITLE" ,       TITLE,    LEVEL_MAIN },
-	{ "%J", "TITLE",        TITLE,    LEVEL_HOST }, /* journal title */
-	{ "%B", "TITLE",        TITLE,    LEVEL_HOST }, /* journal title */
-	{ "%C", "ADDRESS",      SIMPLE,   LEVEL_MAIN },
-	{ "%V", "VOLUME" ,      SIMPLE,   LEVEL_MAIN },
-	{ "%N", "ISSUE",        SIMPLE,   LEVEL_MAIN },
-	{ "%P", "PAGES",        PAGES,    LEVEL_MAIN },
-	{ "%I", "PUBLISHER",    SIMPLE,   LEVEL_HOST }, 
-	{ "%8", "PARTDATE:MONTH",    DATE,     LEVEL_MAIN },
-	{ "%9", "GENRE",        SIMPLE,   LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",   TITLE,    LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER", SERIALNO, LEVEL_HOST },
-	{ "%(", "TITLE",        SIMPLE,   LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,  LEVEL_MAIN },
-	{ "%*", "REVIEWEDITEM", SIMPLE,   LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE,   LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE,   LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE,   LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE,   LEVEL_MAIN },
-	{ "%X", "ABSTRACT",     SIMPLE,   LEVEL_MAIN },
-	{ "%U", "URL",          URL,      LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES,    LEVEL_MAIN },
-	{ "%Z", "NOTES",        NOTES,    LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE,   LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE,   LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE,   LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE,   LEVEL_MAIN },  /* physical location */
-	{ "%^", "CAPTION",      SIMPLE,   LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE,   LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE,   LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE,   LEVEL_MAIN },
-	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|conference publication", ALWAYS, LEVEL_HOST }
-};
-
-static lookups thesis[] = {
-	{ "%0", "INTERNAL_TYPE",         TYPE,   LEVEL_MAIN },
-	{ "%A", "AUTHOR",       PERSON, LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",   PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",         SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,       TITLE,  LEVEL_MAIN },
-	{ "%B", "ACADEMIC_DEPARTMENT", SIMPLE, LEVEL_MAIN },
-	{ "%C", "ADDRESS",      SIMPLE, LEVEL_MAIN },
-	{ "%I", "PUBLISHER",    SIMPLE, LEVEL_MAIN }, 
-	{ "%V", "VOLUME",       SIMPLE, LEVEL_MAIN },
-	{ "%P", "PAGES:TOTAL",  PAGES,  LEVEL_MAIN },
-	{ "%9", "GENRE",        SIMPLE, LEVEL_MAIN }, /* thesis type */
-	{ "%8", "DATE:MONTH",   DATE,   LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",   TITLE,  LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,  LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,  LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,  LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,  LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,  LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,  LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE, LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE, LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE, LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE, LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",     SIMPLE, LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%U", "URL",          URL,    LEVEL_MAIN },
-	{ "%Z", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text",ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|thesis", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups program[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,  LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON   , LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE   , LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE    , LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE   , LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE   , LEVEL_MAIN },
-	{ "%7", "VERSION",   SIMPLE   , LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE   , LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE   , LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE   , LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE   , LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE   , LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE   , LEVEL_MAIN },
-	{ "%O", "NOTES",     SIMPLE   , LEVEL_MAIN },
-	{ "%U", "URL",       URL,       LEVEL_MAIN },
-	{ "%Z", "NOTES",     SIMPLE   , LEVEL_MAIN },
-	{ "%1", "COMPUTER",  SIMPLE   , LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   SIMPLE   , LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   SIMPLE   , LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   SIMPLE   , LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   SIMPLE   , LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   SIMPLE   , LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE    , LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|software, multimedia", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups audiovisual[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE     , LEVEL_MAIN },
-	{ "%A", "WRITER",    PERSON   , LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE   , LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE    , LEVEL_MAIN },
-	{ "%B", "TITLE",     TITLE    , LEVEL_HOST }, /* COLLECTION_TITLE */
-	{ "%C", "ADDRESS",   SIMPLE   , LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE   , LEVEL_MAIN },
-	{ "%V", "EXTENTOFWORK",     SIMPLE   , LEVEL_MAIN },
-	{ "%N", "NUMBER",    SIMPLE   , LEVEL_MAIN },
-	{ "%8", "DATE:MONTH", DATE     , LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE   , LEVEL_MAIN },
-	{ "%?", "PERFORMER", PERSON   , LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE    , LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE   , LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE   , LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE   , LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE   , LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE   , LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%U", "URL",       URL,       LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,     LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,     LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,     LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,     LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,     LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,     LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|mixed material", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups broadcast[] = {
-	{ "%0", "INTERNAL_TYPE",         TYPE,     LEVEL_MAIN },
-	{ "%A", "AUTHOR",       PERSON,   LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",   PERSON,   LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",         SIMPLE,   LEVEL_MAIN },
-	{ "%T", "TITLE" ,       TITLE,    LEVEL_MAIN },
-	{ "%E", "DIRECTOR",     PERSON,   LEVEL_MAIN },
-	{ "%B", "TITLE",        TITLE,    LEVEL_HOST }, /* SERIES_TITLE */
-	{ "%C", "ADDRESS",      SIMPLE,   LEVEL_MAIN },
-	{ "%I", "PUBLISHER",    SIMPLE,   LEVEL_MAIN },
-	{ "%Y", "PRODUCER",     PERSON,   LEVEL_MAIN },
-	{ "%8", "DATE:MONTH",        DATE,     LEVEL_MAIN },
-	{ "%9", "GENRE",        SIMPLE,   LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",   TITLE,    LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER", SERIALNO, LEVEL_MAIN },
-	{ "%?", "PERFORMER",    PERSON,   LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE,   LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE,   LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE,   LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE,   LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",     SIMPLE,   LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES,    LEVEL_MAIN },
-	{ "%U", "URL",          URL,      LEVEL_MAIN },
-	{ "%Z", "NOTES",        SIMPLE,   LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE,   LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE,   LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE,   LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE,   LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE,   LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE,   LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|moving image", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups electronic[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE      , LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON    , LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE    , LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE     , LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE    , LEVEL_MAIN }, 
-	{ "%V", "ACCESS_YEAR",  SIMPLE , LEVEL_MAIN },
-	{ "%N", "ACCESS_DATE",  DATE   , LEVEL_MAIN },
-	{ "%7", "EDITION",   SIMPLE,     LEVEL_MAIN },
-	{ "%8", "UPDATE_DATE", DATE,     LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE,     LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,      LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,      LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,      LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,      LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,      LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,      LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,      LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,     LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,     LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,     LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,     LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,      LEVEL_MAIN },
-	{ "%U", "URL",       URL,        LEVEL_MAIN },
-	{ "%V", "VOLUME",    SIMPLE,     LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,      LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%+", "AUTHORADDRESS",SIMPLE , LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-        { " ",  "RESOURCE|software, multimedia",    ALWAYS, LEVEL_MAIN },
-        { " ",  "GENRE|electronic",       ALWAYS, LEVEL_MAIN },
-};
-
-static lookups webpage[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE      , LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON    , LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE    , LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE     , LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE    , LEVEL_MAIN }, 
-	{ "%V", "ACCESS_YEAR",  SIMPLE , LEVEL_MAIN },
-	{ "%N", "ACCESS_DATE",  DATE   , LEVEL_MAIN },
-	{ "%7", "EDITION",   SIMPLE,     LEVEL_MAIN },
-	{ "%8", "UPDATE_DATE", DATE,     LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE,     LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,      LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,      LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,      LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,      LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,      LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,      LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,      LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,     LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,     LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,     LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,     LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,      LEVEL_MAIN },
-	{ "%U", "URL",       URL,        LEVEL_MAIN },
-	{ "%V", "VOLUME",    SIMPLE,     LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,      LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%+", "AUTHORADDRESS",SIMPLE , LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-        { " ",  "RESOURCE|software, multimedia",    ALWAYS, LEVEL_MAIN },
-        { " ",  "GENRE|web page",       ALWAYS, LEVEL_MAIN },
-};
-
-static lookups artwork[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE     , LEVEL_MAIN },
-	{ "%A", "ARTIST",    PERSON   , LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",         SIMPLE   , LEVEL_MAIN },
-	{ "%T", "TITLE" ,       TITLE    , LEVEL_MAIN },
-	{ "%C", "ADDRESS",      SIMPLE   , LEVEL_MAIN },
-	{ "%I", "PUBLISHER",    SIMPLE   , LEVEL_MAIN },
-	{ "%8", "DATE:MONTH",        DATE,   LEVEL_MAIN },
-	{ "%9", "GENRE",        SIMPLE, LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",   TITLE,  LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE, LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE, LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE, LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE, LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",     SIMPLE, LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%U", "URL",          URL,    LEVEL_MAIN },
-	{ "%Z", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,  LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,  LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,  LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,  LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,  LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,  LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "GENRE|art original", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups report[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE     , LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON   , LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE   , LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE    , LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE   , LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE, LEVEL_MAIN },
-	{ "%P", "PAGES",     PAGES, LEVEL_MAIN },
-	{ "%8", "DATE:MONTH",     DATE, LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE,    LEVEL_MAIN },
-	{ "%N", "NUMBER",    SIMPLE,    LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER", SERIALNO, LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE,     LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE,    LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE,    LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE,    LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE,    LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE,    LEVEL_MAIN },
-	{ "%O", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%U", "URL",       URL,       LEVEL_MAIN },
-	{ "%Z", "NOTES",     NOTES,     LEVEL_MAIN },
-	{ "%1", "CUSTOM1",   NOTES,     LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   NOTES,     LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   NOTES,     LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   NOTES,     LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   NOTES,     LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   NOTES,     LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|report", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups map[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE     , LEVEL_MAIN },
-	{ "%A", "CARTOGRAPHER",    PERSON   , LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE   , LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE    , LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE   , LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE   , LEVEL_MAIN },
-	{ "%7", "EDITION",   SIMPLE   , LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE   , LEVEL_MAIN },
-	{ "%!", "SHORTTITLE",TITLE    , LEVEL_MAIN },
-	{ "%M", "ACCESSNUM", SIMPLE   , LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",SIMPLE   , LEVEL_MAIN },
-	{ "%F", "REFNUM",    SIMPLE   , LEVEL_MAIN },
-	{ "%K", "KEYWORD",   SIMPLE   , LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",  SIMPLE   , LEVEL_MAIN },
-	{ "%O", "NOTES",     SIMPLE   , LEVEL_MAIN },
-	{ "%U", "URL",       URL,       LEVEL_MAIN },
-	{ "%Z", "NOTES",     SIMPLE   , LEVEL_MAIN },
-	{ "%1", "SCALE",     SIMPLE   , LEVEL_MAIN },
-	{ "%2", "CUSTOM2",   SIMPLE   , LEVEL_MAIN },
-	{ "%3", "CUSTOM3",   SIMPLE   , LEVEL_MAIN },
-	{ "%4", "CUSTOM4",   SIMPLE   , LEVEL_MAIN },
-	{ "%#", "CUSTOM5",   SIMPLE   , LEVEL_MAIN },
-	{ "%$", "CUSTOM6",   SIMPLE   , LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|cartographic", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|map", ALWAYS,  LEVEL_MAIN }
-};
-
-static lookups patent[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE, LEVEL_MAIN    },
-	{ "%A", "AUTHOR",    PERSON, LEVEL_MAIN  },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE, LEVEL_MAIN  },
-	{ "%T", "TITLE" ,    TITLE, LEVEL_MAIN   },
-	{ "%B", "PUBLISHED_SOURCE", SIMPLE, LEVEL_MAIN},
-	{ "%C", "COUNTRY",   SIMPLE, LEVEL_MAIN  },
-	{ "%I", "ASSIGNEE",  SIMPLE, LEVEL_MAIN  },
-	{ "%V", "VOLUME",    SIMPLE, LEVEL_MAIN  },
-	{ "%N", "ISSUE",     SIMPLE, LEVEL_MAIN  },
-	{ "%P", "PAGES",     SIMPLE, LEVEL_MAIN  },
-	{ "%@", "NUMBER",    SIMPLE, LEVEL_MAIN  },
-	{ "%M", "ACCESSNUM", SIMPLE, LEVEL_MAIN  },
-	{ "%L", "CALLNUMBER",SIMPLE, LEVEL_MAIN  },
-	{ "%F", "REFNUM",    SIMPLE, LEVEL_MAIN  },
-	{ "%K", "KEYWORD",   SIMPLE, LEVEL_MAIN  }, 
-	{ "%X", "ABSTRACT",  SIMPLE, LEVEL_MAIN  },
-	{ "%O", "NOTES",     SIMPLE, LEVEL_MAIN  },
-	{ "%U", "URL",       URL,    LEVEL_MAIN  },
-	{ "%Z", "NOTES",     SIMPLE, LEVEL_MAIN  },
-	{ "%1", "SCALE",     SIMPLE, LEVEL_MAIN  },
-	{ "%2", "CUSTOM2",   SIMPLE, LEVEL_MAIN  },
-	{ "%3", "CUSTOM3",   SIMPLE, LEVEL_MAIN  },
-	{ "%4", "CUSTOM4",   SIMPLE, LEVEL_MAIN  },
-	{ "%#", "CUSTOM5",   SIMPLE, LEVEL_MAIN  },
-	{ "%$", "CUSTOM6",   SIMPLE, LEVEL_MAIN  },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|patent", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups hearing[] = {
-	{ "%0", "INTERNAL_TYPE",         TYPE, LEVEL_MAIN    },
-	{ "%D", "DATE:YEAR",         SIMPLE, LEVEL_MAIN  },
-	{ "%H", "TRANSLATOR",   PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,       TITLE, LEVEL_MAIN   },
-	{ "%B", "COMMITTEE:CORP", SIMPLE, LEVEL_MAIN  },
-	{ "%C", "ADDRESS",      SIMPLE, LEVEL_MAIN  },
-	{ "%I", "PUBLISHER",    SIMPLE, LEVEL_MAIN  }, 
-	{ "%6", "NUMVOLUMES",   SIMPLE, LEVEL_MAIN  },
-	{ "%N", "NUMBER",       SIMPLE, LEVEL_MAIN  },
-	{ "%P", "PAGES:TOTAL",  PAGES,  LEVEL_MAIN  },
-	{ "%S", "LEGISLATIVEBODY:CORP", SIMPLE, LEVEL_MAIN  },
-	{ "%7", "SESSION",       SIMPLE, LEVEL_MAIN  },
-	{ "%8", "DATE:MONTH",         DATE,   LEVEL_MAIN  },
-	{ "%!", "SHORTTITLE",    TITLE,  LEVEL_MAIN  },
-	{ "%(", "TITLE",         SIMPLE, LEVEL_ORIG }, /* orig publication */
-	{ "%M", "ACCESSNUM",     SIMPLE, LEVEL_MAIN  },
-	{ "%L", "CALLNUMBER",    SIMPLE, LEVEL_MAIN  },
-	{ "%F", "REFNUM",        SIMPLE, LEVEL_MAIN  },
-	{ "%K", "KEYWORD",       SIMPLE, LEVEL_MAIN  }, 
-	{ "%X", "ABSTRACT",      SIMPLE, LEVEL_MAIN  },
-	{ "%O", "NOTES",         NOTES,  LEVEL_MAIN  },
-	{ "%U", "URL",           URL,    LEVEL_MAIN  },
-	{ "%Z", "NOTES",         NOTES,  LEVEL_MAIN  },
-	{ "%1", "CUSTOM1",       NOTES,  LEVEL_MAIN  },
-	{ "%2", "CUSTOM2",       NOTES,  LEVEL_MAIN  },
-	{ "%3", "CUSTOM3",       NOTES,  LEVEL_MAIN  },
-	{ "%4", "CUSTOM4",       NOTES,  LEVEL_MAIN  },
-	{ "%9", "GENRE",         SIMPLE, LEVEL_MAIN  },
-	{ "%#", "CUSTOM5",       NOTES,  LEVEL_MAIN  },
-	{ "%$", "CUSTOM6",       NOTES,  LEVEL_MAIN  },
-	{ "%>", "PDFLINK",       SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",   SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",      SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",       SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",    SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",      SIMPLE, LEVEL_MAIN },
-	{ "  ", "GENRE|hearing", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups bill[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE, LEVEL_MAIN    },
-	{ "%D", "DATE:YEAR",      SIMPLE, LEVEL_MAIN  },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE, LEVEL_MAIN   },
-	{ "%B", "CODE",      SIMPLE, LEVEL_MAIN  },
-	{ "%V", "CODEVOLUME",SIMPLE, LEVEL_MAIN   },
-	{ "%N", "BILLNUMBER",SIMPLE, LEVEL_MAIN   },
-	{ "%P", "CODEPAGES", SIMPLE, LEVEL_MAIN  },
-	{ "%&", "CODESECTION",SIMPLE, LEVEL_MAIN  },
-	{ "%S", "LEGISLATIVEBODY:CORP", SIMPLE, LEVEL_MAIN  },
-	{ "%7", "SESSION",   SIMPLE, LEVEL_MAIN  },
-	{ "%8", "DATE:MONTH", DATE, LEVEL_MAIN    },
-	{ "%?", "SPONSOR",   PERSON, LEVEL_MAIN  },
-	{ "%!", "SHORTTITLE",TITLE,  LEVEL_MAIN   },
-	{ "%(", "TITLE",     SIMPLE, LEVEL_ORIG  }, /* original pub */
-	{ "%M", "ACCESSNUM", SIMPLE, LEVEL_MAIN  },
-	{ "%L", "CALLNUMBER",SIMPLE, LEVEL_MAIN   },
-	{ "%F", "REFNUM",    SIMPLE, LEVEL_MAIN  },
-	{ "%K", "KEYWORD",   SIMPLE, LEVEL_MAIN  }, 
-	{ "%X", "ABSTRACT",  SIMPLE, LEVEL_MAIN  },
-	{ "%O", "NOTES",     NOTES,  LEVEL_MAIN  },
-	{ "%U", "URL",       URL,    LEVEL_MAIN  },
-	{ "%Z", "NOTES",     NOTES,  LEVEL_MAIN  },
-	{ "%1", "CUSTOM1",   NOTES,  LEVEL_MAIN  },
-	{ "%2", "CUSTOM2",   NOTES,  LEVEL_MAIN  },
-	{ "%3", "CUSTOM3",   NOTES,  LEVEL_MAIN  },
-	{ "%4", "CUSTOM4",   NOTES,  LEVEL_MAIN  },
-	{ "%#", "CUSTOM5",   NOTES,  LEVEL_MAIN  },
-	{ "%$", "CUSTOM6",   NOTES,  LEVEL_MAIN  },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|legislation", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups statute[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE, LEVEL_MAIN    },
-	{ "%D", "DATE:YEAR",      SIMPLE, LEVEL_MAIN  },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE, LEVEL_MAIN   },
-	{ "%B", "CODE",      SIMPLE, LEVEL_MAIN  },
-	{ "%V", "CODENUMBER",SIMPLE, LEVEL_MAIN   },
-	{ "%N", "PUBLICLAWNUMBER",    SIMPLE, LEVEL_MAIN  },
-	{ "%P", "PAGES",     PAGES, LEVEL_MAIN    },
-	{ "%&", "SECTION",   SIMPLE, LEVEL_MAIN  },
-	{ "%7", "SESSION",   SIMPLE, LEVEL_MAIN  },
-	{ "%8", "DATE:MONTH", DATE, LEVEL_MAIN    },
-	{ "%!", "SHORTTITLE",TITLE,  LEVEL_MAIN   },
-	{ "%(", "TITLE",     SIMPLE, LEVEL_ORIG  }, /* original pub */
-	{ "%M", "ACCESSNUM", SIMPLE, LEVEL_MAIN  },
-	{ "%L", "CALLNUMBER",SIMPLE, LEVEL_MAIN   },
-	{ "%F", "REFNUM",    SIMPLE, LEVEL_MAIN  },
-	{ "%K", "KEYWORD",   SIMPLE, LEVEL_MAIN  }, 
-	{ "%X", "ABSTRACT",  SIMPLE, LEVEL_MAIN  },
-	{ "%O", "NOTES",     NOTES,  LEVEL_MAIN  },
-	{ "%U", "URL",       URL,    LEVEL_MAIN  },
-	{ "%Z", "NOTES",     NOTES,  LEVEL_MAIN  },
-	{ "%1", "CUSTOM1",   NOTES,  LEVEL_MAIN  },
-	{ "%2", "CUSTOM2",   NOTES,  LEVEL_MAIN  },
-	{ "%3", "CUSTOM3",   NOTES,  LEVEL_MAIN  },
-	{ "%4", "CUSTOM4",   NOTES,  LEVEL_MAIN  },
-	{ "%#", "CUSTOM5",   NOTES,  LEVEL_MAIN  },
-	{ "%$", "CUSTOM6",   NOTES,  LEVEL_MAIN  },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|legislation", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups lawcase[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE, LEVEL_MAIN    },
-	{ "%D", "DATE:YEAR",      SIMPLE, LEVEL_MAIN  },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE, LEVEL_MAIN   },
-	{ "%E", "REPORTER",  TITLE, LEVEL_HOST   }, /*Reporter is name of book*/
-	{ "%B", "CODE",      SIMPLE, LEVEL_MAIN  },
-	{ "%I", "COURT:CORP",     SIMPLE, LEVEL_MAIN  },
-	{ "%V", "VOLUME",    SIMPLE, LEVEL_MAIN   },
-	{ "%N", "PUBLICLAWNUMBER",    SIMPLE, LEVEL_MAIN  },
-	{ "%P", "STARTPAGE",     SIMPLE, LEVEL_MAIN  },
-	{ "%8", "DATE:MONTH", DATE, LEVEL_MAIN    },
-	{ "%?", "COUNSEL",   PERSON, LEVEL_MAIN  },
-	{ "%!", "SHORTTITLE",TITLE,  LEVEL_MAIN   },
-	{ "%(", "TITLE",     SIMPLE, LEVEL_ORIG  }, /* original pub */
-	{ "%M", "ACCESSNUM", SIMPLE, LEVEL_MAIN  },
-	{ "%L", "CALLNUMBER",SIMPLE, LEVEL_MAIN  },
-	{ "%F", "REFNUM",    SIMPLE, LEVEL_MAIN  },
-	{ "%K", "KEYWORD",   SIMPLE, LEVEL_MAIN  }, 
-	{ "%X", "ABSTRACT",  SIMPLE, LEVEL_MAIN  },
-	{ "%O", "NOTES",     NOTES,  LEVEL_MAIN  },
-	{ "%U", "URL",       URL,    LEVEL_MAIN  },
-	{ "%Z", "NOTES",     NOTES,  LEVEL_MAIN  },
-	{ "%1", "CUSTOM1",   NOTES,  LEVEL_MAIN  },
-	{ "%2", "CUSTOM2",   NOTES,  LEVEL_MAIN  },
-	{ "%3", "CUSTOM3",   NOTES,  LEVEL_MAIN  },
-	{ "%4", "CUSTOM4",   NOTES,  LEVEL_MAIN  },
-	{ "%#", "CUSTOM5",   NOTES,  LEVEL_MAIN  },
-	{ "%$", "CUSTOM6",   NOTES,  LEVEL_MAIN  },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|legal case and case notes", ALWAYS, LEVEL_MAIN }
-};
-
-static lookups chart[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,   LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE,  LEVEL_MAIN },
-	{ "%J", "TITLE",     TITLE,  LEVEL_HOST }, /* for refer formats */
-	{ "%E", "2ND_AUTHOR",PERSON, LEVEL_MAIN },
-	{ "%B", "2ND_TITLE", SIMPLE, LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE, LEVEL_MAIN }, 
-	{ "%V", "VOLUME" ,   SIMPLE, LEVEL_MAIN },
-	{ "%6", "NUMVOLUMES",SIMPLE, LEVEL_HOST },
-	{ "%N", "NUMBER",    SIMPLE, LEVEL_MAIN },
-	{ "%P", "PAGES",     PAGES,  LEVEL_MAIN },
-	{ "%&", "SECTION",   SIMPLE, LEVEL_MAIN },
-	{ "%Y", "AUTHOR",    PERSON, LEVEL_SERIES },
-	{ "%S", "TITLE",     TITLE,  LEVEL_SERIES },
-	{ "%7", "EDITION",   SIMPLE, LEVEL_MAIN },
-	{ "%8", "DATE:MONTH",     DATE,   LEVEL_MAIN },
-	{ "%9", "GENRE",     SIMPLE, LEVEL_MAIN },
-	{ "%?", "SUB_AUTHOR",   PERSON, LEVEL_MAIN }, /* subsidiary-authors */
-	{ "%!", "SHORTTITLE",   TITLE,  LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER", SERIALNO,  LEVEL_MAIN },
-	{ "%(", "TITLE",        SIMPLE, LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_MAIN },
-	{ "%*", "REVIEWEDITEM", SIMPLE, LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,  LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,  LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,  LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,  LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,  LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,  LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE, LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE, LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE, LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE, LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",     SIMPLE, LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%U", "URL",          URL,    LEVEL_MAIN },
-	{ "%Z", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "  ", "GENRE|chart",  ALWAYS, LEVEL_MAIN }
-};
-
-static lookups unpublished[] = {
-	{ "%0", "INTERNAL_TYPE",      TYPE,   LEVEL_MAIN },
-	{ "%A", "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
-	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
-	{ "%D", "DATE:YEAR",      SIMPLE, LEVEL_MAIN },
-	{ "%T", "TITLE" ,    TITLE,  LEVEL_MAIN },
-	{ "%J", "TITLE",     TITLE,  LEVEL_HOST }, /* for refer formats */
-	{ "%E", "2ND_AUTHOR",PERSON, LEVEL_MAIN },
-	{ "%B", "2ND_TITLE", SIMPLE, LEVEL_MAIN },
-	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
-	{ "%I", "PUBLISHER", SIMPLE, LEVEL_MAIN }, 
-	{ "%V", "VOLUME" ,   SIMPLE, LEVEL_MAIN },
-	{ "%6", "NUMVOLUMES",SIMPLE, LEVEL_HOST },
-	{ "%N", "NUMBER",    SIMPLE, LEVEL_MAIN },
-	{ "%P", "PAGES",        PAGES,  LEVEL_MAIN },
-	{ "%&", "SECTION",      SIMPLE, LEVEL_MAIN },
-	{ "%Y", "AUTHOR",   PERSON, LEVEL_SERIES },
-	{ "%S", "TITLE",    TITLE, LEVEL_SERIES },
-	{ "%7", "EDITION",      SIMPLE, LEVEL_MAIN },
-	{ "%8", "DATE:MONTH",    DATE,   LEVEL_MAIN },
-	{ "%9", "GENRE",        SIMPLE, LEVEL_MAIN },
-	{ "%?", "SUB_AUTHOR",   PERSON, LEVEL_MAIN }, /* subsidiary-authors */
-	{ "%!", "SHORTTITLE",   TITLE,  LEVEL_MAIN },
-	{ "%@", "SERIALNUMBER", SERIALNO,  LEVEL_MAIN },
-	{ "%(", "TITLE",        SIMPLE, LEVEL_ORIG }, /* original pub */
-	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_MAIN },
-	{ "%*", "REVIEWEDITEM", SIMPLE, LEVEL_MAIN },
-	{ "%1", "CUSTOM1",      NOTES,  LEVEL_MAIN },
-	{ "%2", "CUSTOM2",      NOTES,  LEVEL_MAIN },
-	{ "%3", "CUSTOM3",      NOTES,  LEVEL_MAIN },
-	{ "%4", "CUSTOM4",      NOTES,  LEVEL_MAIN },
-	{ "%#", "CUSTOM5",      NOTES,  LEVEL_MAIN },
-	{ "%$", "CUSTOM6",      NOTES,  LEVEL_MAIN },
-	{ "%M", "ACCESSNUM",    SIMPLE, LEVEL_MAIN },
-	{ "%L", "CALLNUMBER",   SIMPLE, LEVEL_MAIN },
-	{ "%F", "REFNUM",       SIMPLE, LEVEL_MAIN },
-	{ "%K", "KEYWORD",      SIMPLE, LEVEL_MAIN }, 
-	{ "%X", "ABSTRACT",     SIMPLE, LEVEL_MAIN },
-	{ "%O", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%U", "URL",          URL,    LEVEL_MAIN },
-	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
-	{ "%Z", "NOTES",        NOTES,  LEVEL_MAIN },
-	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
-	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
-	{ "%+", "AUTHORADDRESS",SIMPLE, LEVEL_MAIN },
-	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
-	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
-	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
-	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
-        { " ",         "INTERNAL_TYPE|BOOK",       ALWAYS, LEVEL_MAIN },
-        { " ",         "RESOURCE|text",   ALWAYS, LEVEL_MAIN },
-        { " ",         "GENRE|unpublished",      ALWAYS, LEVEL_MAIN },
+ * Copyright (c) Chris Putnam 2003-2018
+ *
+ * Program and source code released under the GPL version 2
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "is_ws.h"
+#include "fields.h"
+#include "reftypes.h"
+
+/* if no specific type can be identified */
+static lookups generic[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%J", "TITLE",           TITLE,    LEVEL_HOST }, /* for refer formats */
+	{ "%E", "2ND_AUTHOR",      PERSON,   LEVEL_MAIN },
+	{ "%B", "2ND_TITLE",       SIMPLE,   LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME" ,         SIMPLE,   LEVEL_MAIN },
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_HOST },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%&", "SECTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%Y", "AUTHOR",          PERSON,   LEVEL_SERIES },
+	{ "%S", "TITLE",           TITLE,    LEVEL_SERIES },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%?", "SUB_AUTHOR",      PERSON,   LEVEL_MAIN }, /* subsidiary-authors */
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",  SIMPLE,   LEVEL_MAIN },
+	{ "%*", "REVIEWEDITEM",    SIMPLE,   LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%Z", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN }
+};
+
+static lookups journalarticle[] = {
+	{ "%0", "INTERNAL_TYPE",         TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",       PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",   PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE",SIMPLE, LEVEL_MAIN },
+	{ "%D", "PARTDATE:YEAR",     SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,       TITLE,    LEVEL_MAIN },
+	{ "%J", "TITLE",        TITLE,    LEVEL_HOST }, /* journal title */
+	{ "%B", "TITLE",        TITLE,    LEVEL_HOST }, /* journal title */
+	{ "%C", "ADDRESS",      SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME" ,      SIMPLE,   LEVEL_MAIN },
+	{ "%N", "ISSUE",        SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",        PAGES,    LEVEL_MAIN },
+	{ "%I", "PUBLISHER",    SIMPLE,   LEVEL_HOST }, 
+	{ "%8", "PARTDATE:MONTH", DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",  GENRE,   LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",   TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER", SERIALNO, LEVEL_HOST },
+	{ "%(", "TITLE",        SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",SIMPLE,  LEVEL_MAIN },
+	{ "%*", "REVIEWEDITEM", SIMPLE,   LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",    SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",   SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",      SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",     SIMPLE,   LEVEL_MAIN },
+	{ "%U", "URL",          URL,      LEVEL_MAIN },
+	{ "%O", "NOTES",        NOTES,    LEVEL_MAIN },
+	{ "%Z", "NOTES",        NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",      SIMPLE,   LEVEL_MAIN },
+	{ "%G", "LANGUAGE",     SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",  SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%^", "CAPTION",      SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",   SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",  SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",     SIMPLE,   LEVEL_MAIN },
+	{ "  ", "ISSUANCE|continuing",             ALWAYS, LEVEL_HOST },
+	{ "  ", "RESOURCE|text",                   ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:BIBUTILS|journal article",  ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|periodical",           ALWAYS, LEVEL_HOST },
+	{ "  ", "GENRE:BIBUTILS|academic journal", ALWAYS, LEVEL_HOST }
+};
+
+static lookups magazinearticle[] = {
+	{ "%0", "INTERNAL_TYPE",      TYPE,    LEVEL_MAIN },
+	{ "%A", "AUTHOR",    PERSON,  LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
+	{ "%D", "PARTDATE:YEAR",  SIMPLE,  LEVEL_MAIN },
+	{ "%T", "TITLE",     TITLE,   LEVEL_MAIN },
+	{ "%J", "TITLE",     TITLE,   LEVEL_HOST }, /* magazine name */
+	{ "%B", "TITLE",     TITLE,   LEVEL_HOST }, /* magazine name */
+	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
+	{ "%V", "VOLUME",    SIMPLE,  LEVEL_MAIN },
+	{ "%N", "ISSUE",     SIMPLE,  LEVEL_MAIN },
+	{ "%P", "PAGES",     PAGES,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER", SIMPLE,    LEVEL_HOST },
+	{ "%8", "PARTDATE:MONTH", DATE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",TITLE,   LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",      SERIALNO,LEVEL_HOST },
+	{ "%(", "TITLE",     SIMPLE,  LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",SIMPLE,LEVEL_MAIN },
+	{ "%*", "REVIEWEDITEM",SIMPLE,LEVEL_MAIN },
+	{ "%M", "ACCESSNUM", SIMPLE,  LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",SIMPLE,  LEVEL_MAIN },
+	{ "%F", "REFNUM",    SIMPLE,  LEVEL_MAIN },
+	{ "%K", "KEYWORD",   SIMPLE,  LEVEL_MAIN },
+	{ "%X", "ABSTRACT",  SIMPLE,  LEVEL_MAIN },
+	{ "%U", "URL",       URL,     LEVEL_MAIN },
+	{ "%O", "NOTES",     SIMPLE,  LEVEL_MAIN },
+	{ "%Z", "NOTES",     SIMPLE,  LEVEL_MAIN },
+	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",SIMPLE,LEVEL_MAIN },
+	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
+	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
+	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
+	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
+	{ "  ", "ISSUANCE|continuing",     ALWAYS, LEVEL_HOST },
+	{ "  ", "RESOURCE|text",           ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|periodical",   ALWAYS, LEVEL_HOST },
+	{ "  ", "GENRE:BIBUTILS|magazine", ALWAYS, LEVEL_HOST }
+};
+
+static lookups newspaperarticle[] = {
+	{ "%0", "INTERNAL_TYPE",      TYPE,    LEVEL_MAIN },
+	{ "%A", "REPORTER",  PERSON,  LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",PERSON, LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
+	{ "%D", "PARTDATE:YEAR",  SIMPLE,  LEVEL_MAIN },
+	{ "%T", "TITLE" ,    TITLE,   LEVEL_MAIN },
+	{ "%J", "TITLE",     TITLE,   LEVEL_HOST }, /* newspaper name */
+	{ "%B", "TITLE",     TITLE,   LEVEL_HOST }, /* newspaper name */
+	{ "%V", "VOLUME" ,   SIMPLE,  LEVEL_MAIN },
+	{ "%C", "ADDRESS",   SIMPLE, LEVEL_MAIN },
+	{ "%N", "ISSUE",     SIMPLE,  LEVEL_MAIN },
+	{ "%P", "PAGES",     PAGES,   LEVEL_MAIN },
+	{ "%7", "EDITION",   SIMPLE,  LEVEL_MAIN },
+	{ "%8", "PARTDATE:MONTH", DATE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",TITLE,   LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",      SERIALNO, LEVEL_MAIN },
+	{ "%(", "TITLE",     SIMPLE, LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",SIMPLE, LEVEL_MAIN },
+	{ "%*", "REVIEWEDITEM",SIMPLE,LEVEL_MAIN },
+	{ "%M", "ACCESSNUM", SIMPLE,  LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",SIMPLE,  LEVEL_MAIN },
+	{ "%F", "REFNUM",    SIMPLE,  LEVEL_MAIN },
+	{ "%K", "KEYWORD",   SIMPLE,  LEVEL_MAIN },
+	{ "%X", "ABSTRACT",  SIMPLE,  LEVEL_MAIN },
+	{ "%U", "URL",       URL,     LEVEL_MAIN },
+	{ "%O", "NOTES",     SIMPLE,  LEVEL_MAIN },
+	{ "%Z", "NOTES",     SIMPLE,  LEVEL_MAIN },
+	{ "%1", "CUSTOM1",      NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",      NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",      NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",      NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",      NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",      NOTES,    LEVEL_MAIN },
+	{ "%G", "LANGUAGE",     SIMPLE, LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",  SIMPLE, LEVEL_MAIN },  /* physical location */
+	{ "%+", "AUTHORADDRESS",SIMPLE,LEVEL_MAIN },
+	{ "%>", "PDFLINK",      SIMPLE, LEVEL_MAIN },
+	{ "%^", "CAPTION",      SIMPLE, LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",   SIMPLE, LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",  SIMPLE, LEVEL_MAIN },
+	{ "%~", "DATABASE",     SIMPLE, LEVEL_MAIN },
+	{ "  ", "ISSUANCE|continuing",  ALWAYS, LEVEL_HOST },
+	{ "  ", "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|newspaper", ALWAYS, LEVEL_HOST }
+};
+
+static lookups book[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%E", "AUTHOR",          PERSON,   LEVEL_HOST }, /* SERIES_AUTHOR */
+	{ "%B", "TITLE",           TITLE,    LEVEL_HOST }, /* SERIES_TITLE */
+	{ "%S", "TITLE",           TITLE,    LEVEL_SERIES },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME" ,         SIMPLE,   LEVEL_MAIN },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES:TOTAL",     SIMPLE,   LEVEL_MAIN },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%?", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",  SIMPLE,   LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|book",      ALWAYS, LEVEL_MAIN },
+	{ "  ", "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",        ALWAYS, LEVEL_MAIN }
+};
+
+static lookups booksection[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_HOST },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%E", "EDITOR",          PERSON,   LEVEL_HOST }, /* editor for book */
+	{ "%B", "TITLE",           TITLE,    LEVEL_HOST }, /* book title */
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_HOST },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_HOST },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_HOST },
+	{ "%V", "VOLUME" ,         SIMPLE,   LEVEL_MAIN },
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_HOST },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%Y", "EDITOR",          PERSON,   LEVEL_SERIES },
+	{ "%S", "TITLE",           TITLE,    LEVEL_SERIES },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_HOST },
+	{ "%?", "TRANSLATOR",      PERSON,   LEVEL_HOST },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_HOST },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",  SIMPLE,   LEVEL_HOST },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+        { "  ", "GENRE:BIBUTILS|book chapter", ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|book",             ALWAYS, LEVEL_HOST },
+	{ "  ", "ISSUANCE|monographic",        ALWAYS, LEVEL_HOST },
+	{ "  ", "RESOURCE|text",               ALWAYS, LEVEL_MAIN }
+};
+
+static lookups editedbook[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "EDITOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%E", "EDITOR",          PERSON,   LEVEL_HOST }, /* SERIES_EDITOR */
+	{ "%B", "TITLE",           TITLE,    LEVEL_HOST }, /* SERIES_TITLE */
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME" ,         SIMPLE,   LEVEL_MAIN },
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_HOST },
+	{ "%P", "PAGES:TOTAL",     SIMPLE,   LEVEL_MAIN },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%?", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",  SIMPLE,   LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|book",      ALWAYS, LEVEL_MAIN },
+	{ "  ", "ISSUANCE|monographic", ALWAYS, LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",        ALWAYS, LEVEL_MAIN }
+};
+
+static lookups manuscript[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,   LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON, LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON, LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE, LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,  LEVEL_MAIN },
+	{ "%B", "TITLE",           TITLE,  LEVEL_HOST }, /* COLLECTION_TITLE */
+	{ "%C", "ADDRESS",         SIMPLE, LEVEL_MAIN },
+	{ "%N", "NUMBER",          SIMPLE, LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,  LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,   LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,  LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,  LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE, LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE, LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE, LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE, LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE, LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,  LEVEL_MAIN },
+	{ "%U", "URL",             URL,    LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,  LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,  LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,  LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,  LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,  LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,  LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,  LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE, LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE, LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE, LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE, LEVEL_MAIN },  /* physical location */
+	{ "%^", "CAPTION",         SIMPLE, LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE, LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE, LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE, LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",             ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:BIBUTILS|manuscript", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups communication[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,   LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON, LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON, LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE, LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE, LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,  LEVEL_MAIN },
+	{ "%E", "RECIPIENT",       PERSON, LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE, LEVEL_MAIN },
+	{ "%V", "VOLUME",          SIMPLE, LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE, LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,   LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,  LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,  LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE, LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE, LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE, LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE, LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE, LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,  LEVEL_MAIN },
+	{ "%U", "URL",             URL,    LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,  LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,  LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,  LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,  LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,  LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,  LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,  LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE, LEVEL_MAIN },  /* physical location */
+	{ "%+", "AUTHORADDRESS",   SIMPLE, LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE, LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE, LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE, LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE, LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE, LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE, LEVEL_MAIN },
+	{ "  ", "GENRE:BIBUTILS|communication", ALWAYS, LEVEL_MAIN}
+};
+
+static lookups proceedings[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_HOST },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%E", "EDITOR",          PERSON,   LEVEL_MAIN },
+	{ "%B", "TITLE",           SIMPLE,   LEVEL_HOST },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME" ,         SIMPLE,   LEVEL_MAIN },
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_HOST },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%Y", "EDITOR",          PERSON,   LEVEL_SERIES },
+	{ "%S", "TITLE",           TITLE,    LEVEL_SERIES },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_HOST },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",                     ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|conference publication", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups conferencepaper[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "PARTDATE:YEAR",   SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%J", "TITLE",           TITLE,    LEVEL_HOST }, /* journal title */
+	{ "%B", "TITLE",           TITLE,    LEVEL_HOST }, /* journal title */
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME" ,         SIMPLE,   LEVEL_MAIN },
+	{ "%N", "ISSUE",           SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_HOST },
+	{ "%8", "PARTDATE:MONTH",  DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_HOST },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",  SIMPLE,   LEVEL_MAIN },
+	{ "%*", "REVIEWEDITEM",    SIMPLE,   LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",                     ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|conference publication", ALWAYS, LEVEL_HOST }
+};
+
+static lookups thesis[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%B", "ACADEMIC_DEPARTMENT", SIMPLE, LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME",          SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES:TOTAL",     PAGES,    LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN }, /* thesis type */
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",     ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|thesis", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups program[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%7", "VERSION",         SIMPLE,   LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%1", "COMPUTER",        SIMPLE,   LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         SIMPLE,   LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         SIMPLE,   LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         SIMPLE,   LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         SIMPLE,   LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         SIMPLE,   LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|software, multimedia", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups audiovisual[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "WRITER",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%B", "TITLE",           TITLE,    LEVEL_HOST }, /* COLLECTION_TITLE */
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%V", "EXTENTOFWORK",    SIMPLE,   LEVEL_MAIN },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%?", "PERFORMER",       PERSON,   LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|mixed material", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups broadcast[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%E", "DIRECTOR",        PERSON,   LEVEL_MAIN },
+	{ "%B", "TITLE",           TITLE,    LEVEL_HOST }, /* SERIES_TITLE */
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%Y", "PRODUCER",        PERSON,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_MAIN },
+	{ "%?", "PERFORMER",       PERSON,   LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|moving image",               ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|motion picture",           ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:BIBUTILS|television broadcast", ALWAYS, LEVEL_MAIN },
+};
+
+static lookups electronic[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN }, 
+	{ "%V", "ACCESS_YEAR",     SIMPLE,   LEVEL_MAIN },
+	{ "%N", "ACCESS_DATE",     DATE,     LEVEL_MAIN },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "UPDATE_DATE",     DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%V", "VOLUME",          SIMPLE,   LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+        { " ",  "RESOURCE|software, multimedia", ALWAYS, LEVEL_MAIN },
+        { " ",  "GENRE:MARC|electronic",         ALWAYS, LEVEL_MAIN },
+};
+
+static lookups webpage[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN }, 
+	{ "%V", "ACCESS_YEAR",     SIMPLE,   LEVEL_MAIN },
+	{ "%N", "ACCESS_DATE",     DATE,     LEVEL_MAIN },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "UPDATE_DATE",     DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%V", "VOLUME",          SIMPLE,   LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+        { " ",  "RESOURCE|software, multimedia", ALWAYS, LEVEL_MAIN },
+        { " ",  "GENRE:MARC|web page",           ALWAYS, LEVEL_MAIN },
+};
+
+static lookups artwork[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "ARTIST",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|art original", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups report[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UKNOWN",    GENRE,    LEVEL_MAIN },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",               ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|technical report", ALWAYS, LEVEL_MAIN },
+};
+
+static lookups map[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "CARTOGRAPHER",    PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%9", "GENRE:UKNOWN",    GENRE,    LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%1", "SCALE",           SIMPLE,   LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         SIMPLE,   LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         SIMPLE,   LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         SIMPLE,   LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         SIMPLE,   LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         SIMPLE,   LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|cartographic", ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|map",        ALWAYS, LEVEL_MAIN }
+};
+
+static lookups patent[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE" ,          TITLE,    LEVEL_MAIN },
+	{ "%B", "PUBLISHED_SOURCE",SIMPLE,   LEVEL_MAIN },
+	{ "%C", "COUNTRY",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "ASSIGNEE",        SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME",          SIMPLE,   LEVEL_MAIN },
+	{ "%N", "ISSUE",           SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           SIMPLE,   LEVEL_MAIN },
+	{ "%@", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           SIMPLE,   LEVEL_MAIN },
+	{ "%1", "SCALE",           SIMPLE,   LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         SIMPLE,   LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         SIMPLE,   LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         SIMPLE,   LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         SIMPLE,   LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         SIMPLE,   LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",     ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|patent", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups hearing[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%B", "COMMITTEE:CORP",  SIMPLE,   LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN }, 
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_MAIN },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES:TOTAL",     PAGES,    LEVEL_MAIN },
+	{ "%S", "LEGISLATIVEBODY:CORP", SIMPLE, LEVEL_MAIN },
+	{ "%7", "SESSION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* orig publication */
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "GENRE:BIBUTILS|hearing",ALWAYS, LEVEL_MAIN }
+};
+
+static lookups bill[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%B", "CODE",            SIMPLE,   LEVEL_MAIN },
+	{ "%V", "CODEVOLUME",      SIMPLE,   LEVEL_MAIN },
+	{ "%N", "BILLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%P", "CODEPAGES",       SIMPLE,   LEVEL_MAIN },
+	{ "%&", "CODESECTION",     SIMPLE,   LEVEL_MAIN },
+	{ "%S", "LEGISLATIVEBODY:CORP", SIMPLE, LEVEL_MAIN },
+	{ "%7", "SESSION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%?", "SPONSOR",         PERSON,   LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|legislation", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups statute[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%B", "CODE",            SIMPLE,   LEVEL_MAIN },
+	{ "%V", "CODENUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%N", "PUBLICLAWNUMBER", SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%&", "SECTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%7", "SESSION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|legislation", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups lawcase[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%E", "REPORTER",        TITLE,    LEVEL_HOST }, /*Reporter is name of book*/
+	{ "%B", "CODE",            SIMPLE,   LEVEL_MAIN },
+	{ "%I", "COURT:CORP",      SIMPLE,   LEVEL_MAIN },
+	{ "%V", "VOLUME",          SIMPLE,   LEVEL_MAIN },
+	{ "%N", "PUBLICLAWNUMBER", SIMPLE,   LEVEL_MAIN },
+	{ "%P", "STARTPAGE",       SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%?", "COUNSEL",         PERSON,   LEVEL_MAIN },
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",                        ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|legal case and case notes", ALWAYS, LEVEL_MAIN }
+};
+
+static lookups chart[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%J", "TITLE",           TITLE,    LEVEL_HOST }, /* for refer formats */
+	{ "%E", "2ND_AUTHOR",      PERSON,   LEVEL_MAIN },
+	{ "%B", "2ND_TITLE",       SIMPLE,   LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN }, 
+	{ "%V", "VOLUME" ,         SIMPLE,   LEVEL_MAIN },
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_HOST },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%&", "SECTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%Y", "AUTHOR",          PERSON,   LEVEL_SERIES },
+	{ "%S", "TITLE",           TITLE,    LEVEL_SERIES },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%?", "SUB_AUTHOR",      PERSON,   LEVEL_MAIN }, /* subsidiary-authors */
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",  SIMPLE,   LEVEL_MAIN },
+	{ "%*", "REVIEWEDITEM",    SIMPLE,   LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|chart",  ALWAYS, LEVEL_MAIN }
+};
+
+static lookups unpublished[] = {
+	{ "%0", "INTERNAL_TYPE",   TYPE,     LEVEL_MAIN },
+	{ "%A", "AUTHOR",          PERSON,   LEVEL_MAIN },
+	{ "%H", "TRANSLATOR",      PERSON,   LEVEL_MAIN },
+	{ "%Q", "TRANSLATEDTITLE", SIMPLE,   LEVEL_MAIN },
+	{ "%D", "DATE:YEAR",       SIMPLE,   LEVEL_MAIN },
+	{ "%T", "TITLE",           TITLE,    LEVEL_MAIN },
+	{ "%J", "TITLE",           TITLE,    LEVEL_HOST }, /* for refer formats */
+	{ "%E", "2ND_AUTHOR",      PERSON,   LEVEL_MAIN },
+	{ "%B", "2ND_TITLE",       SIMPLE,   LEVEL_MAIN },
+	{ "%C", "ADDRESS",         SIMPLE,   LEVEL_MAIN },
+	{ "%I", "PUBLISHER",       SIMPLE,   LEVEL_MAIN }, 
+	{ "%V", "VOLUME",          SIMPLE,   LEVEL_MAIN },
+	{ "%6", "NUMVOLUMES",      SIMPLE,   LEVEL_HOST },
+	{ "%N", "NUMBER",          SIMPLE,   LEVEL_MAIN },
+	{ "%P", "PAGES",           PAGES,    LEVEL_MAIN },
+	{ "%&", "SECTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%Y", "AUTHOR",          PERSON,   LEVEL_SERIES },
+	{ "%S", "TITLE",           TITLE,    LEVEL_SERIES },
+	{ "%7", "EDITION",         SIMPLE,   LEVEL_MAIN },
+	{ "%8", "DATE:MONTH",      DATE,     LEVEL_MAIN },
+	{ "%9", "GENRE:UNKNOWN",   GENRE,    LEVEL_MAIN },
+	{ "%?", "SUB_AUTHOR",      PERSON,   LEVEL_MAIN }, /* subsidiary-authors */
+	{ "%!", "SHORTTITLE",      TITLE,    LEVEL_MAIN },
+	{ "%@", "SERIALNUMBER",    SERIALNO, LEVEL_MAIN },
+	{ "%(", "TITLE",           SIMPLE,   LEVEL_ORIG }, /* original pub */
+	{ "%)", "REPRINTEDITION",  SIMPLE,   LEVEL_MAIN },
+	{ "%*", "REVIEWEDITEM",    SIMPLE,   LEVEL_MAIN },
+	{ "%1", "CUSTOM1",         NOTES,    LEVEL_MAIN },
+	{ "%2", "CUSTOM2",         NOTES,    LEVEL_MAIN },
+	{ "%3", "CUSTOM3",         NOTES,    LEVEL_MAIN },
+	{ "%4", "CUSTOM4",         NOTES,    LEVEL_MAIN },
+	{ "%#", "CUSTOM5",         NOTES,    LEVEL_MAIN },
+	{ "%$", "CUSTOM6",         NOTES,    LEVEL_MAIN },
+	{ "%M", "ACCESSNUM",       SIMPLE,   LEVEL_MAIN },
+	{ "%L", "CALLNUMBER",      SIMPLE,   LEVEL_MAIN },
+	{ "%F", "REFNUM",          SIMPLE,   LEVEL_MAIN },
+	{ "%K", "KEYWORD",         SIMPLE,   LEVEL_MAIN },
+	{ "%X", "ABSTRACT",        SIMPLE,   LEVEL_MAIN },
+	{ "%O", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%U", "URL",             URL,      LEVEL_MAIN },
+	{ "%>", "PDFLINK",         SIMPLE,   LEVEL_MAIN },
+	{ "%Z", "NOTES",           NOTES,    LEVEL_MAIN },
+	{ "%W", "PHYSICALLOC",     SIMPLE,   LEVEL_MAIN },  /* physical location */
+	{ "%G", "LANGUAGE",        SIMPLE,   LEVEL_MAIN },
+	{ "%+", "AUTHORADDRESS",   SIMPLE,   LEVEL_MAIN },
+	{ "%^", "CAPTION",         SIMPLE,   LEVEL_MAIN },
+	{ "%[", "ACCESSDATE",      SIMPLE,   LEVEL_MAIN },
+	{ "%=", "LASTMODDATE",     SIMPLE,   LEVEL_MAIN },
+	{ "%~", "DATABASE",        SIMPLE,   LEVEL_MAIN },
+        { "  ", "INTERNAL_TYPE|BOOK",         ALWAYS, LEVEL_MAIN },
+        { "  ", "RESOURCE|text",              ALWAYS, LEVEL_MAIN },
+        { "  ", "GENRE:BIBUTILS|unpublished", ALWAYS, LEVEL_MAIN },
 };
 
 
diff --git a/bibutils/endxmlin.c b/bibutils/endxmlin.c
--- a/bibutils/endxmlin.c
+++ b/bibutils/endxmlin.c
@@ -1,7 +1,7 @@
 /*
  * endxmlin.c
  *
- * Copyright (c) Chris Putnam 2006-2017
+ * Copyright (c) Chris Putnam 2006-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -85,10 +85,10 @@
 	while ( !haveref && !done ) {
 		if ( line->data ) {
 			if ( !inref ) {
-				startptr = xml_findstart( line->data, "RECORD" );
+				startptr = xml_find_start( line->data, "RECORD" );
 				if ( startptr ) inref = 1;
 			} else
-				endptr = xml_findend( line->data, "RECORD" );
+				endptr = xml_find_end( line->data, "RECORD" );
 		}
 
 		/* If no <record> tag, we can trim up to last 8 bytes */
@@ -107,8 +107,8 @@
 			str_strcatc( line, buf );
 		} else {
 			/* we can reallocate in the str_strcat, so re-find */
-			startptr = xml_findstart( line->data, "RECORD" );
-			endptr = xml_findend( line->data, "RECORD" );
+			startptr = xml_find_start( line->data, "RECORD" );
+			endptr = xml_find_end( line->data, "RECORD" );
 			str_segcpy( reference, startptr, endptr );
 			/* clear out information in line */
 			str_strcpyc( &tmp, endptr );
@@ -151,15 +151,15 @@
 {
 	int status;
 
-	if ( str_has_value( node->value ) ) {
-		str_strcat( s, node->value );
+	if ( xml_has_value( node ) ) {
+		str_strcat( s, &(node->value) );
 		if ( str_memerr( s ) ) return BIBL_ERR_MEMERR;
 	}
-	if ( node->down && xml_tagexact( node->down, "style" ) ) {
+	if ( node->down && xml_tag_matches( node->down, "style" ) ) {
 		status = endxmlin_datar( node->down, s );
 		if ( status!=BIBL_OK ) return status;
 	}
-	if ( xml_tagexact( node, "style" ) && node->next ) {
+	if ( xml_tag_matches( node, "style" ) && node->next ) {
 		status = endxmlin_datar( node->next, s );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -207,7 +207,7 @@
 	str title;
 	str_init( &title );
 	for ( i=0; i<n; ++i ) {
-		if ( xml_tagexact( node, a[i].attrib ) && node->down ) {
+		if ( xml_tag_matches( node, a[i].attrib ) && node->down ) {
 			str_empty( &title );
 			status = endxmlin_datar( node, &title );
 			if ( status!=BIBL_OK ) return BIBL_ERR_MEMERR;
@@ -271,7 +271,7 @@
 	};
 	int i, status, n = sizeof( a ) / sizeof ( a[0] );
 	for ( i=0; i<n; ++i ) {
-		if ( xml_tagexact( node, a[i].attrib ) && node->down ) {
+		if ( xml_tag_matches( node, a[i].attrib ) && node->down ) {
 			status = endxmlin_contributor( node->down, info, a[i].internal, 0 );
 			if ( status!=BIBL_OK ) return status;
 		}
@@ -287,7 +287,7 @@
 endxmlin_keyword( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagexact( node, "keyword" ) ) {
+	if ( xml_tag_matches( node, "keyword" ) ) {
 		status = endxmlin_data( node, "%K", info, 0 );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -301,7 +301,7 @@
 static int
 endxmlin_keywords( xml *node, fields *info )
 {
-	if ( node->down && xml_tagexact( node->down, "keyword" ) )
+	if ( node->down && xml_tag_matches( node->down, "keyword" ) )
 		return endxmlin_keyword( node->down, info );
 	return BIBL_OK;
 }
@@ -313,7 +313,7 @@
 static int
 endxmlin_ern( xml *node, fields *info )
 {
-	if ( xml_tagexact( node, "electronic-resource-num" ) )
+	if ( xml_tag_matches( node, "electronic-resource-num" ) )
 		return endxmlin_data( node, "DOI", info, 0 );
 	return BIBL_OK;
 }
@@ -321,7 +321,7 @@
 static int
 endxmlin_language( xml *node, fields *info )
 {
-	if ( xml_tagexact( node, "language" ) )
+	if ( xml_tag_matches( node, "language" ) )
 		return endxmlin_data( node, "%G", info, 0 );
 	return BIBL_OK;
 }
@@ -337,7 +337,7 @@
 endxmlin_fileattach( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagexact( node, "url" ) ) {
+	if ( xml_tag_matches( node, "url" ) ) {
 		status = endxmlin_data( node, "FILEATTACH", info, 0 );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -356,17 +356,17 @@
 endxmlin_urls( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagexact( node, "pdf-urls" ) && node->down ) {
+	if ( xml_tag_matches( node, "pdf-urls" ) && node->down ) {
 		status = endxmlin_fileattach( node->down, info );
 		if ( status!=BIBL_OK ) return status;
-	} else if ( xml_tagexact( node, "url" ) ) {
+	} else if ( xml_tag_matches( node, "url" ) ) {
 		status = endxmlin_data( node, "%U", info, 0 );
 		if ( status!=BIBL_OK ) return status;
 	} else {
 		if ( node->down ) {
-			if ( xml_tagexact( node->down, "related-urls" ) ||
-			     xml_tagexact( node->down, "pdf-urls" ) ||
-			     xml_tagexact( node->down, "url" ) ) {
+			if ( xml_tag_matches( node->down, "related-urls" ) ||
+			     xml_tag_matches( node->down, "pdf-urls" ) ||
+			     xml_tag_matches( node->down, "url" ) ) {
 				status = endxmlin_urls( node->down, info );
 				if ( status!=BIBL_OK ) return status;
 			}
@@ -382,10 +382,10 @@
 static int
 endxmlin_pubdates( xml *node, fields *info )
 {
-	if ( xml_tagexact( node, "date" ) )
+	if ( xml_tag_matches( node, "date" ) )
 		return endxmlin_data( node, "%8", info, 0 );
 	else {
-		if ( node->down && xml_tagexact( node->down, "date" ) )
+		if ( node->down && xml_tag_matches( node->down, "date" ) )
 			return endxmlin_pubdates( node->down, info );
 	}
 	return BIBL_OK;
@@ -395,18 +395,18 @@
 endxmlin_dates( xml *node, fields *info )
 {
 	int status;
-	if ( xml_tagexact( node, "year" ) ) {
+	if ( xml_tag_matches( node, "year" ) ) {
 		status = endxmlin_data( node, "%D", info, 0 );
 		if ( status!=BIBL_OK ) return status;
 	} else {
 		if ( node->down ) {
-			if ( xml_tagexact( node->down, "year" ) ) {
+			if ( xml_tag_matches( node->down, "year" ) ) {
 				status = endxmlin_dates( node->down, info );
 				if ( status!=BIBL_OK ) return status;
 			}
-			if ( xml_tagexact( node->down, "pub-dates" ) ) {
+			if ( xml_tag_matches( node->down, "pub-dates" ) ) {
 				status = endxmlin_pubdates( node->down, info );
-				if ( status!=BIBL_OK );
+				if ( status!=BIBL_OK ) return status;
 			}
 		}
 	}
@@ -426,7 +426,7 @@
 	int status;
 	str *s;
 
-	s = xml_getattrib( node, "name" );
+	s = xml_attribute( node, "name" );
 	if ( str_has_value( s ) ) {
 		status = fields_add( info, "%0", str_cstr( s ), 0 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
@@ -465,63 +465,63 @@
 		{ "custom6", "%$" },
 	};
 	int i, status, n = sizeof ( a ) / sizeof( a[0] );
-	if ( xml_tagexact( node, "DATABASE" ) ) {
-	} else if ( xml_tagexact( node, "SOURCE-APP" ) ) {
-	} else if ( xml_tagexact( node, "REC-NUMBER" ) ) {
-	} else if ( xml_tagexact( node, "ref-type" ) ) {
+	if ( xml_tag_matches( node, "DATABASE" ) ) {
+	} else if ( xml_tag_matches( node, "SOURCE-APP" ) ) {
+	} else if ( xml_tag_matches( node, "REC-NUMBER" ) ) {
+	} else if ( xml_tag_matches( node, "ref-type" ) ) {
 		status = endxmlin_reftype( node, info );
 		if ( status!=BIBL_OK ) return status;
-	} else if ( xml_tagexact( node, "contributors" ) ) {
+	} else if ( xml_tag_matches( node, "contributors" ) ) {
 		if ( node->down ) {
 			status = endxmlin_contributors( node->down, info );
 			if ( status!=BIBL_OK ) return status;
 		}
-	} else if ( xml_tagexact( node, "titles" ) ) {
+	} else if ( xml_tag_matches( node, "titles" ) ) {
 		if ( node->down ) endxmlin_titles( node->down, info );
-	} else if ( xml_tagexact( node, "keywords" ) ) {
+	} else if ( xml_tag_matches( node, "keywords" ) ) {
 		status = endxmlin_keywords( node, info );
 		if ( status!=BIBL_OK ) return status;
-	} else if ( xml_tagexact( node, "urls" ) ) {
+	} else if ( xml_tag_matches( node, "urls" ) ) {
 		status = endxmlin_urls( node, info );
 		if ( status!=BIBL_OK ) return status;
-	} else if ( xml_tagexact( node, "electronic-resource-num" ) ) {
+	} else if ( xml_tag_matches( node, "electronic-resource-num" ) ) {
 		status = endxmlin_ern( node, info );
 		if ( status!=BIBL_OK ) return status;
-	} else if ( xml_tagexact( node, "dates" ) ) {
+	} else if ( xml_tag_matches( node, "dates" ) ) {
 		status = endxmlin_dates( node, info );
 		if ( status!=BIBL_OK ) return status;
-	} else if ( xml_tagexact( node, "language" ) ) {
+	} else if ( xml_tag_matches( node, "language" ) ) {
 		status = endxmlin_language( node, info );
 		if ( status!=BIBL_OK ) return status;
-	} else if ( xml_tagexact( node, "periodical" ) ) {
-	} else if ( xml_tagexact( node, "secondary-volume" ) ) {
-	} else if ( xml_tagexact( node, "secondary-issue" ) ) {
-	} else if ( xml_tagexact( node, "reprint-status" ) ) {
-	} else if ( xml_tagexact( node, "orig-pub" ) ) {
-	} else if ( xml_tagexact( node, "report-id" ) ) {
-	} else if ( xml_tagexact( node, "coden" ) ) {
-	} else if ( xml_tagexact( node, "caption" ) ) {
-	} else if ( xml_tagexact( node, "research-notes" ) ) {
-	} else if ( xml_tagexact( node, "work-type" ) ) {
-	} else if ( xml_tagexact( node, "reviewed-item" ) ) {
-	} else if ( xml_tagexact( node, "availability" ) ) {
-	} else if ( xml_tagexact( node, "remote-source" ) ) {
-	} else if ( xml_tagexact( node, "meeting-place" ) ) {
-	} else if ( xml_tagexact( node, "work-location" ) ) {
-	} else if ( xml_tagexact( node, "work-extent" ) ) {
-	} else if ( xml_tagexact( node, "pack-method" ) ) {
-	} else if ( xml_tagexact( node, "size" ) ) {
-	} else if ( xml_tagexact( node, "repro-ratio" ) ) {
-	} else if ( xml_tagexact( node, "remote-database-name" ) ) {
-	} else if ( xml_tagexact( node, "remote-database-provider" ) ) {
-	} else if ( xml_tagexact( node, "access-date" ) ) {
-	} else if ( xml_tagexact( node, "modified-data" ) ) {
-	} else if ( xml_tagexact( node, "misc1" ) ) {
-	} else if ( xml_tagexact( node, "misc2" ) ) {
-	} else if ( xml_tagexact( node, "misc3" ) ) {
+	} else if ( xml_tag_matches( node, "periodical" ) ) {
+	} else if ( xml_tag_matches( node, "secondary-volume" ) ) {
+	} else if ( xml_tag_matches( node, "secondary-issue" ) ) {
+	} else if ( xml_tag_matches( node, "reprint-status" ) ) {
+	} else if ( xml_tag_matches( node, "orig-pub" ) ) {
+	} else if ( xml_tag_matches( node, "report-id" ) ) {
+	} else if ( xml_tag_matches( node, "coden" ) ) {
+	} else if ( xml_tag_matches( node, "caption" ) ) {
+	} else if ( xml_tag_matches( node, "research-notes" ) ) {
+	} else if ( xml_tag_matches( node, "work-type" ) ) {
+	} else if ( xml_tag_matches( node, "reviewed-item" ) ) {
+	} else if ( xml_tag_matches( node, "availability" ) ) {
+	} else if ( xml_tag_matches( node, "remote-source" ) ) {
+	} else if ( xml_tag_matches( node, "meeting-place" ) ) {
+	} else if ( xml_tag_matches( node, "work-location" ) ) {
+	} else if ( xml_tag_matches( node, "work-extent" ) ) {
+	} else if ( xml_tag_matches( node, "pack-method" ) ) {
+	} else if ( xml_tag_matches( node, "size" ) ) {
+	} else if ( xml_tag_matches( node, "repro-ratio" ) ) {
+	} else if ( xml_tag_matches( node, "remote-database-name" ) ) {
+	} else if ( xml_tag_matches( node, "remote-database-provider" ) ) {
+	} else if ( xml_tag_matches( node, "access-date" ) ) {
+	} else if ( xml_tag_matches( node, "modified-data" ) ) {
+	} else if ( xml_tag_matches( node, "misc1" ) ) {
+	} else if ( xml_tag_matches( node, "misc2" ) ) {
+	} else if ( xml_tag_matches( node, "misc3" ) ) {
 	} else {
 		for ( i=0; i<n; ++i ) {
-			if ( xml_tagexact( node, a[i].attrib ) ) {
+			if ( xml_tag_matches( node, a[i].attrib ) ) {
 				status = endxmlin_data( node, a[i].internal, info, 0 );
 				if ( status!=BIBL_OK ) return status;
 			}
@@ -538,10 +538,10 @@
 endxmlin_assembleref( xml *node, fields *info )
 {
 	int status;
-	if ( str_is_empty( node->tag ) ) {
+	if ( str_is_empty( &(node->tag) ) ) {
 		if ( node->down )
 			return endxmlin_assembleref( node->down, info );
-	} else if ( xml_tagexact( node, "RECORD" ) ) {
+	} else if ( xml_tag_matches( node, "RECORD" ) ) {
 		if ( node->down ) {
 			status = endxmlin_record( node->down, info );
 			if ( status!=BIBL_OK ) return status;
@@ -563,7 +563,7 @@
 	xml top;
 
 	xml_init( &top );
-	xml_tree( data, &top );
+	xml_parse( data, &top );
 	status = endxmlin_assembleref( &top, fin );
 	xml_free( &top );
 
diff --git a/bibutils/entities.c b/bibutils/entities.c
--- a/bibutils/entities.c
+++ b/bibutils/entities.c
@@ -1,7 +1,7 @@
 /*
  * entities.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/entities.h b/bibutils/entities.h
--- a/bibutils/entities.h
+++ b/bibutils/entities.h
@@ -1,7 +1,7 @@
 /*
  * entities.h
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/fields.c b/bibutils/fields.c
--- a/bibutils/fields.c
+++ b/bibutils/fields.c
@@ -1,7 +1,7 @@
 /*
  * fields.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
@@ -47,6 +47,13 @@
 	fields_init( f );
 }
 
+void
+fields_delete( fields *f )
+{
+	fields_free( f );
+	free( f );
+}
+
 static int
 fields_alloc( fields *f )
 {
@@ -108,6 +115,7 @@
 _fields_add( fields *f, char *tag, char *data, int level, int mode )
 {
 	int i, n, status;
+	str *t, *d;
 
 	if ( !tag || !data ) return FIELDS_OK;
 
@@ -122,9 +130,11 @@
 	/* Don't duplicate identical entries if FIELDS_NO_DUPS */
 	if ( mode == FIELDS_NO_DUPS ) {
 		for ( i=0; i<f->n; i++ ) {
+			t = &(f->tag[i]);
+			d = &(f->data[i]);
 			if ( f->level[i]==level &&
-			     !strcasecmp( f->tag[i].data, tag ) &&
-			     !strcasecmp( f->data[i].data, data ) )
+			     !strcasecmp( str_cstr( t ), tag ) &&
+			     !strcasecmp( str_cstr( d ), data ) )
 				return FIELDS_OK;
 		}
 	}
@@ -209,7 +219,7 @@
 /* fields_find()
  *
  * Return position [0,f->n) for match of the tag.
- * Return -1 if tag isn't found.
+ * Return FIELDS_NOTFOUND if tag isn't found.
  */
 int
 fields_find( fields *f, char *tag, int level )
@@ -227,7 +237,7 @@
 		}
 	}
 
-	return -1;
+	return FIELDS_NOTFOUND;
 }
 
 int
@@ -270,7 +280,7 @@
 fields_replace_or_add( fields *f, char *tag, char *data, int level )
 {
 	int n = fields_find( f, tag, level );
-	if ( n==-1 ) return fields_add( f, tag, data, level );
+	if ( n==FIELDS_NOTFOUND ) return fields_add( f, tag, data, level );
 	else {
 		str_strcpyc( &(f->data[n]), data );
 		if ( str_memerr( &(f->data[n]) ) ) return FIELDS_ERR;
@@ -381,10 +391,10 @@
 void *
 fields_findv( fields *f, int level, int mode, char *tag )
 {
-	int i, found = -1;
+	int i, found = FIELDS_NOTFOUND;
 	intptr_t retn;
 
-	for ( i=0; i<f->n && found==-1; ++i ) {
+	for ( i=0; i<f->n && found==FIELDS_NOTFOUND; ++i ) {
 
 		if ( !fields_match_level( f, i, level ) ) continue;
 		if ( !fields_match_casetag( f, i, tag ) ) continue;
@@ -399,7 +409,7 @@
 		}
 	}
 
-	if ( found==-1 ) return NULL;
+	if ( found==FIELDS_NOTFOUND ) return NULL;
 
 	if ( mode & FIELDS_SETUSE_FLAG )
 		fields_setused( f, found );
@@ -432,30 +442,35 @@
 	return NULL;
 }
 
-static void
+static int
 fields_findv_each_add( fields *f, int mode, int n, vplist *a )
 {
-	intptr_t retn;
+	int status;
+	void *v;
 
-	if ( n<0 || n>= f->n ) return;
+	if ( n<0 || n>= f->n ) return FIELDS_OK;
 
 	if ( mode & FIELDS_SETUSE_FLAG )
 		fields_setused( f, n );
 
 	if ( mode & FIELDS_STRP_FLAG ) {
-		vplist_add( a, (void *) &(f->data[n]) );
+		v = ( void * ) &( f->data[n] );
 	} else if ( mode & FIELDS_POSP_FLAG ) {
-		retn = n;
-		vplist_add( a, (void *) retn );
+		v = ( void * )( (long) n );
 	} else {
-		vplist_add( a, (void *) f->data[n].data );
+		v = ( void * ) str_cstr( &( f->data[n] ) );
 	}
+
+	status = vplist_add( a, v );
+
+	if ( status==VPLIST_OK ) return FIELDS_OK;
+	else return FIELDS_ERR;
 }
 
-void
+int
 fields_findv_each( fields *f, int level, int mode, vplist *a, char *tag )
 {
-	int i;
+	int i, status;
 
 	for ( i=0; i<f->n; ++i ) {
 
@@ -463,59 +478,80 @@
 		if ( !fields_match_casetag( f, i, tag ) ) continue;
 
 		if ( f->data[i].len!=0 ) {
-			fields_findv_each_add( f, mode, i, a );
+			status = fields_findv_each_add( f, mode, i, a );
+			if ( status!=FIELDS_OK ) return status;
 		} else {
 			if ( mode & FIELDS_NOLENOK_FLAG ) {
-				fields_findv_each_add( f, mode, i, a );
+				status = fields_findv_each_add( f, mode, i, a );
+				if ( status!=FIELDS_OK ) return status;
 			} else {
 				f->used[i] = 1; /* Suppress "noise" of unused */
 			}
 		}
 
 	}
+
+	return FIELDS_OK;
 }
 
-void
+static int
+fields_build_tags( va_list argp, vplist *tags )
+{
+	int status;
+	char *tag;
+
+	while ( ( tag = ( char * ) va_arg( argp, char * ) ) ) {
+		status = vplist_add( tags, tag );
+		if ( status!=VPLIST_OK ) return FIELDS_ERR;
+	}
+
+	return FIELDS_OK;
+}
+
+static int
+fields_match_casetags( fields *f, int n, vplist *tags )
+{
+	int i;
+
+	for ( i=0; i<tags->n; ++i )
+		if ( fields_match_casetag( f, n, vplist_get( tags, i ) ) ) return 1;
+
+	return 0;
+}
+
+int
 fields_findv_eachof( fields *f, int level, int mode, vplist *a, ... )
 {
+	int i, status;
 	va_list argp;
 	vplist tags;
-	char *tag;
-	int i, j, found;
 
 	vplist_init( &tags );
 
 	/* build list of tags to search for */
 	va_start( argp, a );
-	while ( ( tag = ( char * ) va_arg( argp, char * ) ) )
-		vplist_add( &tags, tag );
+	status = fields_build_tags( argp, &tags );
 	va_end( argp );
+	if ( status!=FIELDS_OK ) goto out;
 
 	/* search list */
 	for ( i=0; i<f->n; ++i ) {
 
 		if ( !fields_match_level( f, i, level ) ) continue;
-
-		found = 0;
-		for ( j=0; j<tags.n && !found; ++j ) {
-			if ( fields_match_casetag( f, i, vplist_get( &tags, j ) ) )
-				found = 1;
-		}
-		if ( !found ) continue;
+		if ( !fields_match_casetags( f, i, &tags ) ) continue;
 
-		if ( f->data[i].len!=0 ) {
-			fields_findv_each_add( f, mode, i, a );
+		if ( f->data[i].len!=0 || ( mode & FIELDS_NOLENOK_FLAG ) ) {
+			status = fields_findv_each_add( f, mode, i, a );
+			if ( status!=FIELDS_OK ) goto out;
 		} else {
-			if ( mode & FIELDS_NOLENOK_FLAG ) {
-				fields_findv_each_add( f, mode, i, a );
-			} else {
-				f->used[i] = 1; /* Suppress "noise" of unused */
-			}
+			f->used[i] = 1; /* Suppress "noise" of unused */
 		}
 
 	}
 
+out:
 	vplist_free( &tags );
+	return status;
 }
 
 void
diff --git a/bibutils/fields.h b/bibutils/fields.h
--- a/bibutils/fields.h
+++ b/bibutils/fields.h
@@ -1,7 +1,7 @@
 /*
  * fields.h
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
@@ -12,13 +12,14 @@
 #define FIELDS_OK     (1)
 #define FIELDS_ERR    (0)
 
+#define FIELDS_NOTFOUND (-1)
+
+#define LEVEL_ORIG   (-2)
 #define LEVEL_ANY    (-1)
 #define LEVEL_MAIN    (0)
 #define LEVEL_HOST    (1)
 #define LEVEL_SERIES  (2)
 
-#define LEVEL_ORIG (-2)
-
 #include <stdarg.h>
 #include "str.h"
 #include "vplist.h"
@@ -34,13 +35,14 @@
 
 void    fields_init( fields *f );
 fields *fields_new( void );
+void    fields_delete( fields *f );
 void    fields_free( fields *f );
 
 #define FIELDS_CAN_DUP (0)
 #define FIELDS_NO_DUPS (1)
 
-#define fields_add( a, b, c, d )         _fields_add( a, b, c, d, FIELDS_NO_DUPS )
-#define fields_add_can_dup( a, b, c, d ) _fields_add( a, b, c, d, FIELDS_CAN_DUP )
+#define fields_add( a, b, c, d )                      _fields_add( a, b, c, d, FIELDS_NO_DUPS )
+#define fields_add_can_dup( a, b, c, d )              _fields_add( a, b, c, d, FIELDS_CAN_DUP )
 #define fields_add_tagsuffix( a, b, c, d, e )         _fields_add( a, b, c, d, e, FIELDS_NO_DUPS )
 #define fields_add_tagsuffix_can_dup( a, b, c, d, e ) _fields_add( a, b, c, d, e, FIELDS_CAN_DUP )
 
@@ -89,7 +91,7 @@
 void *fields_findv( fields *f, int level, int mode, char *tag );
 void *fields_findv_firstof( fields *f, int level, int mode, ... );
 
-void  fields_findv_each( fields *f, int level, int mode, vplist *a, char *tag );
-void  fields_findv_eachof( fields *f, int level, int mode, vplist *a, ... );
+int   fields_findv_each( fields *f, int level, int mode, vplist *a, char *tag );
+int   fields_findv_eachof( fields *f, int level, int mode, vplist *a, ... );
 
 #endif
diff --git a/bibutils/gb18030.h b/bibutils/gb18030.h
--- a/bibutils/gb18030.h
+++ b/bibutils/gb18030.h
@@ -1,7 +1,7 @@
 /*
  * gb18030.h
  *
- * Copyright (c) Chris Putnam 2008-2017
+ * Copyright (c) Chris Putnam 2008-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/generic.c b/bibutils/generic.c
--- a/bibutils/generic.c
+++ b/bibutils/generic.c
@@ -1,11 +1,13 @@
 /* generic.c
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Source code released under GPL version 2
  *
  * xxxx_convertf() stubs that can be shared.
  */
+#include "bu_auth.h"
+#include "marc_auth.h"
 #include "name.h"
 #include "notes.h"
 #include "pages.h"
@@ -24,7 +26,7 @@
 int
 generic_url( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
 {
-	return urls_split_and_add( invalue->data, bibout, level );
+	return urls_split_and_add( str_cstr( invalue ), bibout, level );
 }
 
 int
@@ -44,14 +46,14 @@
 int
 generic_person( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
 {
-        if ( name_add( bibout, outtag, invalue->data, level, &(pm->asis), &(pm->corps) ) ) return BIBL_OK;
+        if ( name_add( bibout, outtag, str_cstr( invalue ), level, &(pm->asis), &(pm->corps) ) ) return BIBL_OK;
         else return BIBL_ERR_MEMERR;
 }
 
 int
 generic_serialno( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
 {
-	if ( addsn( bibout, invalue->data, level ) ) return BIBL_OK;
+	if ( addsn( bibout, str_cstr( invalue ), level ) ) return BIBL_OK;
 	return BIBL_ERR_MEMERR;
 }
 
@@ -59,7 +61,7 @@
 int
 generic_simple( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
 {
-	if ( fields_add( bibout, outtag, invalue->data, level ) == FIELDS_OK ) return BIBL_OK;
+	if ( fields_add( bibout, outtag, str_cstr( invalue ), level ) == FIELDS_OK ) return BIBL_OK;
 	else return BIBL_ERR_MEMERR;
 }
 
@@ -74,8 +76,24 @@
 int
 generic_title( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
 {
-        if ( title_process( bibout, outtag, invalue->data, level, pm->nosplittitle ) ) return BIBL_OK;
+        if ( title_process( bibout, outtag, str_cstr( invalue ), level, pm->nosplittitle ) ) return BIBL_OK;
         else return BIBL_ERR_MEMERR;
 }
 
+int
+generic_genre( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout )
+{
+	int status;
 
+	if ( is_marc_genre( str_cstr( invalue ) ) )
+		status = fields_add( bibout, "GENRE:MARC", str_cstr( invalue ), level );
+
+	else if ( is_bu_genre( str_cstr( invalue ) ) )
+		status = fields_add( bibout, "GENRE:BIBUTILS", str_cstr( invalue ), level );
+
+	else
+		status = fields_add( bibout, "GENRE:UNKNOWN", str_cstr( invalue ), level );
+
+	if ( status == FIELDS_OK ) return BIBL_OK;
+	else return BIBL_ERR_MEMERR;
+}
diff --git a/bibutils/generic.h b/bibutils/generic.h
--- a/bibutils/generic.h
+++ b/bibutils/generic.h
@@ -1,6 +1,6 @@
 /* generic.h
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Source code released under GPL version 2
  *
@@ -19,5 +19,6 @@
 int generic_simple  ( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout );
 int generic_skip    ( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout );
 int generic_title   ( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout );
+int generic_genre   ( fields *bibin, int n, str *intag, str *invalue, int level, param *pm, char *outtag, fields *bibout );
 
 #endif
diff --git a/bibutils/intlist.c b/bibutils/intlist.c
--- a/bibutils/intlist.c
+++ b/bibutils/intlist.c
@@ -1,7 +1,7 @@
 /*
  * intlist.c
  *
- * Copyright (c) Chris Putnam 2007-2017
+ * Copyright (c) Chris Putnam 2007-2018
  *
  * Version 1/12/2017
  *
diff --git a/bibutils/intlist.h b/bibutils/intlist.h
--- a/bibutils/intlist.h
+++ b/bibutils/intlist.h
@@ -1,7 +1,7 @@
 /*
  * intlist.h
  *
- * Copyright (c) Chris Putnam 2007-2017
+ * Copyright (c) Chris Putnam 2007-2018
  *
  * Version 01/12/2017
  *
diff --git a/bibutils/is_ws.c b/bibutils/is_ws.c
--- a/bibutils/is_ws.c
+++ b/bibutils/is_ws.c
@@ -1,7 +1,7 @@
 /*
  * is_ws.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/is_ws.h b/bibutils/is_ws.h
--- a/bibutils/is_ws.h
+++ b/bibutils/is_ws.h
@@ -1,7 +1,7 @@
 /*
  * is_ws.h
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/isiin.c b/bibutils/isiin.c
--- a/bibutils/isiin.c
+++ b/bibutils/isiin.c
@@ -1,7 +1,7 @@
 /*
  * isiin.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -170,7 +170,7 @@
 {
 	int status;
 
-	if ( str_has_value( value ) ) {
+	if ( str_has_value( tag ) && str_has_value( value ) ) {
 		status = fields_add( isiin, str_cstr( tag ), str_cstr( value ), 0 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		*tag_added = 1;
@@ -272,8 +272,8 @@
 	ntypename = fields_find( isiin, "PT", LEVEL_MAIN );
 	nrefname  = fields_find( isiin, "UT", LEVEL_MAIN );
 
-	if ( nrefname!=-1 )  refname  = fields_value( isiin, nrefname,  FIELDS_CHRP_NOUSE );
-	if ( ntypename!=-1 ) typename = fields_value( isiin, ntypename, FIELDS_CHRP_NOUSE );
+	if ( nrefname!=FIELDS_NOTFOUND )  refname  = fields_value( isiin, nrefname,  FIELDS_CHRP_NOUSE );
+	if ( ntypename!=FIELDS_NOTFOUND ) typename = fields_value( isiin, ntypename, FIELDS_CHRP_NOUSE );
 
 	return get_reftype( typename, nref, p->progname, p->all, p->nall, refname, &is_default, REFTYPE_CHATTY );
 }
@@ -297,10 +297,11 @@
 		if ( !strcasecmp( t->data, "AF" ) ) has_af++;
 	}
 	if ( has_af ) authortype = use_af;
-	else authortype = use_au;
+	else if ( has_au ) authortype = use_au;
+	else return BIBL_OK; /* no authors */
+
 	for ( i=0; i<nfields; ++i ) {
 		t = fields_tag( isiin, i, FIELDS_STRP );
-		if ( !strcasecmp( t->data, "AU" ) ) has_au++;
 		if ( strcasecmp( t->data, authortype ) ) continue;
 		d = fields_value( isiin, i, FIELDS_STRP );
 		n = process_findoldtag( authortype, reftype, all, nall );
diff --git a/bibutils/isiout.c b/bibutils/isiout.c
--- a/bibutils/isiout.c
+++ b/bibutils/isiout.c
@@ -1,7 +1,7 @@
 /*
  * isiout.c
  *
- * Copyright (c) Chris Putnam 2008-2017
+ * Copyright (c) Chris Putnam 2008-2018
  *
  * Source code released under the GPL version 2
  *
@@ -61,8 +61,9 @@
 	n = fields_num( in );
         for ( i=0; i<n; ++i ) {
 		tag = fields_tag( in, i, FIELDS_CHRP );
-                if ( strcasecmp( tag, "GENRE" ) &&
-                     strcasecmp( tag, "NGENRE") ) continue;
+                if ( strcasecmp( tag, "GENRE:MARC" ) &&
+		     strcasecmp( tag, "GENRE:BIBUTILS" ) &&
+		     strcasecmp( tag, "GENRE:UNKNOWN" ) ) continue;
 		value = fields_value( in, i, FIELDS_CHRP );
 		level = fields_level( in, i );
                 if ( !strcasecmp( value, "periodical" ) ||
diff --git a/bibutils/isitypes.c b/bibutils/isitypes.c
--- a/bibutils/isitypes.c
+++ b/bibutils/isitypes.c
@@ -1,7 +1,7 @@
 /*
  * isitypes.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -13,169 +13,166 @@
 #include "reftypes.h"
 
 static lookups article[] = {
-	{ "AU",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "AF",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "TI",     "TITLE",     TITLE,  LEVEL_MAIN },
-	{ "SO",     "TITLE",     TITLE,  LEVEL_HOST }, /* full journal name */
-	{ "JI",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* abbr journal name */
-	{ "J9",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* 29char journal name */
-	{ "PU",     "PUBLISHER", SIMPLE, LEVEL_HOST },
-	{ "PI",     "ADDRESS",   SIMPLE, LEVEL_HOST }, /* publisher city */
-	{ "C1",     "ADDRESS",   SIMPLE, LEVEL_MAIN }, /* author address */
-	{ "PA",     "ADDRESS",   SIMPLE, LEVEL_HOST }, /* publisher address */
-	{ "RP",     "REPRINTADDRESS", SIMPLE, LEVEL_MAIN },
-	{ "PY",     "PARTDATE:YEAR",  SIMPLE, LEVEL_MAIN },
-	{ "PD",     "PARTDATE:MONTH", SIMPLE, LEVEL_MAIN },
-	{ "VL",     "VOLUME",    SIMPLE, LEVEL_MAIN },
-	{ "AR",     "ARTICLENUMBER", SIMPLE, LEVEL_MAIN }, /* AR=article number that Phys. Rev. B uses instead of page numbers */
-	{ "BP",     "PAGES:START", SIMPLE, LEVEL_MAIN },
-	{ "EP",     "PAGES:STOP",   SIMPLE, LEVEL_MAIN },
-	{ "PG",     "PAGES:TOTAL", SIMPLE, LEVEL_MAIN },
-	{ "IS",     "ISSUE",     SIMPLE, LEVEL_MAIN },
-	{ "SN",     "SERIALNUMBER", SERIALNO, LEVEL_HOST },
-	{ "AB",     "ABSTRACT",  SIMPLE, LEVEL_MAIN },
-	{ "NF",     "NOTES",     NOTES,  LEVEL_MAIN },
-	{ "DE",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* author keywords */
-	{ "ID",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* new ISI keywords */
-	{ "LA",     "LANGUAGE",  SIMPLE, LEVEL_MAIN },
-	{ "TC",     "TIMESCITED", SIMPLE, LEVEL_MAIN },
-	{ "NR",     "NUMBERREFS", SIMPLE, LEVEL_MAIN },
-	{ "CR",     "CITEDREFS",  SIMPLE, LEVEL_MAIN },
-	{ "PT",     " ",         TYPE,   LEVEL_HOST },
-	{ "DT",     "DOCUMENTTYPE", TYPE, LEVEL_MAIN },
-	{ "GA",     "ISIDELIVERNUM", SIMPLE, LEVEL_MAIN}, /*ISI document delivery number */
-	{ "UT",     "ISIREFNUM", SIMPLE, LEVEL_MAIN }, /* ISI unique article identifer */
-	{ "DI",     "DOI",       SIMPLE, LEVEL_MAIN },
-
+	{ "AU",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "AF",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "TI",     "TITLE",                 TITLE,    LEVEL_MAIN },
+	{ "SO",     "TITLE",                 TITLE,    LEVEL_HOST }, /* full journal name */
+	{ "JI",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* abbr journal name */
+	{ "J9",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* 29char journal name */
+	{ "PU",     "PUBLISHER",             SIMPLE,   LEVEL_HOST },
+	{ "PI",     "ADDRESS",               SIMPLE,   LEVEL_HOST }, /* publisher city */
+	{ "C1",     "ADDRESS",               SIMPLE,   LEVEL_MAIN }, /* author address */
+	{ "PA",     "ADDRESS",               SIMPLE,   LEVEL_HOST }, /* publisher address */
+	{ "RP",     "REPRINTADDRESS",        SIMPLE,   LEVEL_MAIN },
+	{ "PY",     "PARTDATE:YEAR",         SIMPLE,   LEVEL_MAIN },
+	{ "PD",     "PARTDATE:MONTH",        SIMPLE,   LEVEL_MAIN },
+	{ "VL",     "VOLUME",                SIMPLE,   LEVEL_MAIN },
+	{ "AR",     "ARTICLENUMBER",         SIMPLE,   LEVEL_MAIN }, /* AR=article number that Phys. Rev. B uses instead of page numbers */
+	{ "BP",     "PAGES:START",           SIMPLE,   LEVEL_MAIN },
+	{ "EP",     "PAGES:STOP",            SIMPLE,   LEVEL_MAIN },
+	{ "PG",     "PAGES:TOTAL",           SIMPLE,   LEVEL_MAIN },
+	{ "IS",     "ISSUE",                 SIMPLE,   LEVEL_MAIN },
+	{ "SN",     "SERIALNUMBER",          SERIALNO, LEVEL_HOST },
+	{ "AB",     "ABSTRACT",              SIMPLE,   LEVEL_MAIN },
+	{ "NF",     "NOTES",                 NOTES,    LEVEL_MAIN },
+	{ "DE",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* author keywords */
+	{ "ID",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* new ISI keywords */
+	{ "LA",     "LANGUAGE",              SIMPLE,   LEVEL_MAIN },
+	{ "TC",     "TIMESCITED",            SIMPLE,   LEVEL_MAIN },
+	{ "NR",     "NUMBERREFS",            SIMPLE,   LEVEL_MAIN },
+	{ "CR",     "CITEDREFS",             SIMPLE,   LEVEL_MAIN },
+	{ "PT",     " ",                     TYPE,     LEVEL_HOST },
+	{ "DT",     "DOCUMENTTYPE",          TYPE,     LEVEL_MAIN },
+	{ "GA",     "ISIDELIVERNUM",         SIMPLE,   LEVEL_MAIN }, /* ISI document delivery number */
+	{ "UT",     "ISIREFNUM",             SIMPLE,   LEVEL_MAIN }, /* ISI unique article identifer */
+	{ "DI",     "DOI",                   SIMPLE,   LEVEL_MAIN },
 	{ " ",      "INTERNAL_TYPE|ARTICLE",           ALWAYS, LEVEL_MAIN },
-	{ " ",      "ISSUANCE|continuing",    ALWAYS, LEVEL_HOST },
-	{ " ",      "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-	{ " ",      "GENRE|journal article",  ALWAYS, LEVEL_MAIN },
-	{ " ",      "GENRE|periodical",       ALWAYS, LEVEL_HOST },
-	{ " ",      "GENRE|academic journal", ALWAYS, LEVEL_HOST }
+	{ " ",      "ISSUANCE|continuing",             ALWAYS, LEVEL_HOST },
+	{ " ",      "RESOURCE|text",                   ALWAYS, LEVEL_MAIN },
+	{ " ",      "GENRE:BIBUTILS|journal article",  ALWAYS, LEVEL_MAIN },
+	{ " ",      "GENRE:MARC|periodical",           ALWAYS, LEVEL_HOST },
+	{ " ",      "GENRE:BIBUTILS|academic journal", ALWAYS, LEVEL_HOST }
 };
 
 static lookups book[] = {
-	{ "AU",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "AF",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "TI",     "TITLE",     TITLE,  LEVEL_MAIN },
-	{ "SO",     "TITLE",     TITLE,  LEVEL_HOST }, /* full journal name */
-	{ "JI",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* abbr journal name */
-	{ "J9",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* 29char journal name */
-	{ "PU",     "PUBLISHER", SIMPLE, LEVEL_MAIN },
-	{ "PI",     "ADDRESS",   SIMPLE, LEVEL_MAIN }, /* publisher city */
-	{ "C1",     "ADDRESS",   SIMPLE, LEVEL_MAIN }, /* author address */
-	{ "PA",     "ADDRESS",   SIMPLE, LEVEL_MAIN }, /* publisher address */
-	{ "RP",     "REPRINTADDRESS", SIMPLE, LEVEL_MAIN },
-	{ "PY",     "DATE:YEAR",      SIMPLE, LEVEL_MAIN },
-	{ "PD",     "DATE:MONTH",     SIMPLE, LEVEL_MAIN },
-	{ "VL",     "VOLUME",    SIMPLE, LEVEL_MAIN },
-	{ "BP",     "PAGES:START", SIMPLE, LEVEL_MAIN },
-	{ "EP",     "PAGES:STOP",  SIMPLE, LEVEL_MAIN },
-	{ "PG",     "PAGES:TOTAL", SIMPLE, LEVEL_MAIN },
-	{ "IS",     "ISSUE",       SIMPLE, LEVEL_MAIN },
-	{ "SN",     "SERIALNUMBER", SERIALNO, LEVEL_HOST },
-	{ "AB",     "ABSTRACT",  SIMPLE, LEVEL_MAIN },
-	{ "NF",     "NOTES",     NOTES,  LEVEL_MAIN },
-	{ "DE",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* author keywords */
-	{ "ID",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* new ISI keywords */
-	{ "LA",     "LANGUAGE",  SIMPLE, LEVEL_MAIN },
-	{ "TC",     "TIMESCITED", SIMPLE, LEVEL_MAIN },
-	{ "NR",     "NUMBERREFS", SIMPLE, LEVEL_MAIN },
-	{ "CR",     "CITEDREFS",  SIMPLE, LEVEL_MAIN },
-	{ "PT",     " ",         TYPE,   LEVEL_MAIN },
-	{ "DT",     "DOCUMENTTYPE", TYPE, LEVEL_MAIN },
-	{ "GA",     "ISIDELIVERNUM", SIMPLE, LEVEL_MAIN}, /*ISI document delivery number */
-	{ "UT",     "ISIREFNUM", SIMPLE, LEVEL_MAIN }, /* ISI unique article identifer */
-	
-	{ "PT",     " ",         TYPE,   LEVEL_HOST },
-	{ "DI",     "DOI",       SIMPLE, LEVEL_MAIN },
-	{ " ",         "INTERNAL_TYPE|BOOK",       ALWAYS, LEVEL_MAIN },
-	{ " ",         "ISSUANCE|monographic",    ALWAYS, LEVEL_MAIN },
-	{ " ",         "RESOURCE|text",   ALWAYS, LEVEL_MAIN },
-	{ " ",         "GENRE|book",      ALWAYS, LEVEL_MAIN }
+	{ "AU",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "AF",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "TI",     "TITLE",                 TITLE,    LEVEL_MAIN },
+	{ "SO",     "TITLE",                 TITLE,    LEVEL_HOST }, /* full journal name */
+	{ "JI",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* abbr journal name */
+	{ "J9",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* 29char journal name */
+	{ "PU",     "PUBLISHER",             SIMPLE,   LEVEL_MAIN },
+	{ "PI",     "ADDRESS",               SIMPLE,   LEVEL_MAIN }, /* publisher city */
+	{ "C1",     "ADDRESS",               SIMPLE,   LEVEL_MAIN }, /* author address */
+	{ "PA",     "ADDRESS",               SIMPLE,   LEVEL_MAIN }, /* publisher address */
+	{ "RP",     "REPRINTADDRESS",        SIMPLE,   LEVEL_MAIN },
+	{ "PY",     "DATE:YEAR",             SIMPLE,   LEVEL_MAIN },
+	{ "PD",     "DATE:MONTH",            SIMPLE,   LEVEL_MAIN },
+	{ "VL",     "VOLUME",                SIMPLE,   LEVEL_MAIN },
+	{ "BP",     "PAGES:START",           SIMPLE,   LEVEL_MAIN },
+	{ "EP",     "PAGES:STOP",            SIMPLE,   LEVEL_MAIN },
+	{ "PG",     "PAGES:TOTAL",           SIMPLE,   LEVEL_MAIN },
+	{ "IS",     "ISSUE",                 SIMPLE,   LEVEL_MAIN },
+	{ "SN",     "SERIALNUMBER",          SERIALNO, LEVEL_HOST },
+	{ "AB",     "ABSTRACT",              SIMPLE,   LEVEL_MAIN },
+	{ "NF",     "NOTES",                 NOTES,    LEVEL_MAIN },
+	{ "DE",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* author keywords */
+	{ "ID",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* new ISI keywords */
+	{ "LA",     "LANGUAGE",              SIMPLE,   LEVEL_MAIN },
+	{ "TC",     "TIMESCITED",            SIMPLE,   LEVEL_MAIN },
+	{ "NR",     "NUMBERREFS",            SIMPLE,   LEVEL_MAIN },
+	{ "CR",     "CITEDREFS",             SIMPLE,   LEVEL_MAIN },
+	{ "PT",     " ",                     TYPE,     LEVEL_MAIN },
+	{ "DT",     "DOCUMENTTYPE",          TYPE,     LEVEL_MAIN },
+	{ "GA",     "ISIDELIVERNUM",         SIMPLE,   LEVEL_MAIN }, /* ISI document delivery number */
+	{ "UT",     "ISIREFNUM",             SIMPLE,   LEVEL_MAIN }, /* ISI unique article identifer */
+	{ "PT",     " ",                     TYPE,     LEVEL_HOST },
+	{ "DI",     "DOI",                   SIMPLE,   LEVEL_MAIN },
+	{ " ",      "INTERNAL_TYPE|BOOK",              ALWAYS, LEVEL_MAIN },
+	{ " ",      "ISSUANCE|monographic",            ALWAYS, LEVEL_MAIN },
+	{ " ",      "RESOURCE|text",                   ALWAYS, LEVEL_MAIN },
+	{ " ",      "GENRE:MARC|book",                 ALWAYS, LEVEL_MAIN }
 };
 
 static lookups inbook[] = {
-	{ "AU",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "AF",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "TI",     "TITLE",     TITLE,  LEVEL_MAIN },
-	{ "SO",     "TITLE",     TITLE,  LEVEL_HOST }, /* full journal name */
-	{ "JI",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* abbr journal name */
-	{ "J9",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* 29char journal name */
-	{ "PU",     "PUBLISHER", SIMPLE, LEVEL_HOST },
-	{ "PI",     "ADDRESS",   SIMPLE, LEVEL_HOST }, /* publisher city */
-	{ "C1",     "ADDRESS",   SIMPLE, LEVEL_MAIN }, /* author address */
-	{ "PA",     "ADDRESS",   SIMPLE, LEVEL_HOST }, /* publisher address */
-	{ "RP",     "REPRINTADDRESS", SIMPLE, LEVEL_MAIN },
-	{ "PY",     "PARTDATE:YEAR",  SIMPLE, LEVEL_MAIN },
-	{ "PD",     "PARTDATE:MONTH", SIMPLE, LEVEL_MAIN },
-	{ "VL",     "VOLUME",    SIMPLE, LEVEL_MAIN },
-	{ "BP",     "PAGES:START", SIMPLE, LEVEL_MAIN },
-	{ "EP",     "PAGES:STOP",  SIMPLE, LEVEL_MAIN },
-	{ "PG",     "PAGES:TOTAL", SIMPLE, LEVEL_HOST },
-	{ "IS",     "ISSUE",       SIMPLE, LEVEL_MAIN },
-	{ "SN",     "SERIALNUMBER", SERIALNO, LEVEL_HOST },
-	{ "AB",     "ABSTRACT",  SIMPLE, LEVEL_MAIN },
-	{ "NF",     "NOTES",     NOTES,  LEVEL_MAIN },
-	{ "DE",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* author keywords */
-	{ "ID",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* new ISI keywords */
-	{ "LA",     "LANGUAGE",  SIMPLE, LEVEL_MAIN },
-	{ "TC",     "TIMESCITED", SIMPLE, LEVEL_MAIN },
-	{ "NR",     "NUMBERREFS", SIMPLE, LEVEL_MAIN },
-	{ "CR",     "CITEDREFS",  SIMPLE, LEVEL_MAIN },
-	{ "PT",     " ",         TYPE,   LEVEL_HOST },
-	{ "DT",     "DOCUMENTTYPE", TYPE, LEVEL_MAIN },
-	{ "GA",     "ISIDELIVERNUM", SIMPLE, LEVEL_MAIN}, /*ISI document delivery number */
-	{ "UT",     "ISIREFNUM", SIMPLE, LEVEL_MAIN }, /* ISI unique article identifer */
-	{ "DI",     "DOI",       SIMPLE, LEVEL_MAIN },
-	{ " ",      "INTERNAL_TYPE|INBOOK", ALWAYS, LEVEL_MAIN },
-	{ " ",      "RESOURCE|text",        ALWAYS, LEVEL_MAIN },
-	{ " ",      "ISSUANCE|monographic", ALWAYS, LEVEL_HOST },
-        { " ",      "GENRE|book chapter",   ALWAYS, LEVEL_MAIN },
-	{ " ",      "GENRE|book",           ALWAYS, LEVEL_HOST }
+	{ "AU",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "AF",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "TI",     "TITLE",                 TITLE,    LEVEL_MAIN },
+	{ "SO",     "TITLE",                 TITLE,    LEVEL_HOST }, /* full journal name */
+	{ "JI",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* abbr journal name */
+	{ "J9",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* 29char journal name */
+	{ "PU",     "PUBLISHER",             SIMPLE,   LEVEL_HOST },
+	{ "PI",     "ADDRESS",               SIMPLE,   LEVEL_HOST }, /* publisher city */
+	{ "C1",     "ADDRESS",               SIMPLE,   LEVEL_MAIN }, /* author address */
+	{ "PA",     "ADDRESS",               SIMPLE,   LEVEL_HOST }, /* publisher address */
+	{ "RP",     "REPRINTADDRESS",        SIMPLE,   LEVEL_MAIN },
+	{ "PY",     "PARTDATE:YEAR",         SIMPLE,   LEVEL_MAIN },
+	{ "PD",     "PARTDATE:MONTH",        SIMPLE,   LEVEL_MAIN },
+	{ "VL",     "VOLUME",                SIMPLE,   LEVEL_MAIN },
+	{ "BP",     "PAGES:START",           SIMPLE,   LEVEL_MAIN },
+	{ "EP",     "PAGES:STOP",            SIMPLE,   LEVEL_MAIN },
+	{ "PG",     "PAGES:TOTAL",           SIMPLE,   LEVEL_HOST },
+	{ "IS",     "ISSUE",                 SIMPLE,   LEVEL_MAIN },
+	{ "SN",     "SERIALNUMBER",          SERIALNO, LEVEL_HOST },
+	{ "AB",     "ABSTRACT",              SIMPLE,   LEVEL_MAIN },
+	{ "NF",     "NOTES",                 NOTES,    LEVEL_MAIN },
+	{ "DE",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* author keywords */
+	{ "ID",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* new ISI keywords */
+	{ "LA",     "LANGUAGE",              SIMPLE,   LEVEL_MAIN },
+	{ "TC",     "TIMESCITED",            SIMPLE,   LEVEL_MAIN },
+	{ "NR",     "NUMBERREFS",            SIMPLE,   LEVEL_MAIN },
+	{ "CR",     "CITEDREFS",             SIMPLE,   LEVEL_MAIN },
+	{ "PT",     " ",                     TYPE,     LEVEL_HOST },
+	{ "DT",     "DOCUMENTTYPE",          TYPE,     LEVEL_MAIN },
+	{ "GA",     "ISIDELIVERNUM",         SIMPLE,   LEVEL_MAIN }, /* ISI document delivery number */
+	{ "UT",     "ISIREFNUM",             SIMPLE,   LEVEL_MAIN }, /* ISI unique article identifer */
+	{ "DI",     "DOI",                   SIMPLE,   LEVEL_MAIN },
+	{ " ",      "INTERNAL_TYPE|INBOOK",            ALWAYS, LEVEL_MAIN },
+	{ " ",      "RESOURCE|text",                   ALWAYS, LEVEL_MAIN },
+	{ " ",      "ISSUANCE|monographic",            ALWAYS, LEVEL_HOST },
+        { " ",      "GENRE:BIBUTILS|book chapter",     ALWAYS, LEVEL_MAIN },
+	{ " ",      "GENRE:MARC|book",                 ALWAYS, LEVEL_HOST }
 };
 
 static lookups bookinseries[] = {
-	{ "AU",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "AF",     "AUTHOR",    PERSON, LEVEL_MAIN },
-	{ "TI",     "TITLE",     TITLE,  LEVEL_MAIN },
-	{ "SO",     "TITLE",     TITLE,  LEVEL_MAIN },
-	{ "SE",     "TITLE",     TITLE,  LEVEL_HOST },
-	{ "BS",     "SUBTITLE",  TITLE,  LEVEL_HOST },
-	{ "JI",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* abbr journal name */
-	{ "J9",     "SHORTTITLE",TITLE,  LEVEL_HOST }, /* 29char journal name */
-	{ "PU",     "PUBLISHER", SIMPLE, LEVEL_HOST },
-	{ "PI",     "ADDRESS",   SIMPLE, LEVEL_HOST }, /* publisher city */
-	{ "C1",     "ADDRESS",   SIMPLE, LEVEL_MAIN }, /* author address */
-	{ "PA",     "ADDRESS",   SIMPLE, LEVEL_HOST }, /* publisher address */
-	{ "RP",     "REPRINTADDRESS", SIMPLE, LEVEL_MAIN },
-	{ "PY",     "PARTDATE:YEAR",  SIMPLE, LEVEL_MAIN },
-	{ "PD",     "PARTDATE:MONTH", SIMPLE, LEVEL_MAIN },
-	{ "VL",     "VOLUME",    SIMPLE, LEVEL_MAIN },
-	{ "BP",     "PAGES:START", SIMPLE, LEVEL_MAIN },
-	{ "EP",     "PAGES:STOP",  SIMPLE, LEVEL_MAIN },
-	{ "PG",     "PAGES:TOTAL", SIMPLE, LEVEL_MAIN },
-	{ "IS",     "ISSUE",     SIMPLE, LEVEL_MAIN },
-	{ "SN",     "SERIALNUMBER", SERIALNO, LEVEL_HOST },
-	{ "AB",     "ABSTRACT",  SIMPLE, LEVEL_MAIN },
-	{ "NF",     "NOTES",     NOTES,  LEVEL_MAIN },
-	{ "DE",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* author keywords */
-	{ "ID",     "KEYWORD",   KEYWORD, LEVEL_MAIN }, /* new ISI keywords */
-	{ "LA",     "LANGUAGE",  SIMPLE, LEVEL_MAIN },
-	{ "TC",     "TIMESCITED", SIMPLE, LEVEL_MAIN },
-	{ "NR",     "NUMBERREFS", SIMPLE, LEVEL_MAIN },
-	{ "CR",     "CITEDREFS",  SIMPLE, LEVEL_MAIN },
-	{ "PT",     " ",         TYPE,   LEVEL_HOST },
-	{ "DT",     "DOCUMENTTYPE", TYPE, LEVEL_MAIN },
-	{ "GA",     "ISIDELIVERNUM", SIMPLE, LEVEL_MAIN}, /*ISI document delivery number */
-	{ "UT",     "ISIREFNUM", SIMPLE, LEVEL_MAIN }, /* ISI unique article identifer */
-	{ "DI",     "DOI",       SIMPLE, LEVEL_MAIN },
-
+	{ "AU",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "AF",     "AUTHOR",                PERSON,   LEVEL_MAIN },
+	{ "TI",     "TITLE",                 TITLE,    LEVEL_MAIN },
+	{ "SO",     "TITLE",                 TITLE,    LEVEL_MAIN },
+	{ "SE",     "TITLE",                 TITLE,    LEVEL_HOST },
+	{ "BS",     "SUBTITLE",              TITLE,    LEVEL_HOST },
+	{ "JI",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* abbr journal name */
+	{ "J9",     "SHORTTITLE",            TITLE,    LEVEL_HOST }, /* 29char journal name */
+	{ "PU",     "PUBLISHER",             SIMPLE,   LEVEL_HOST },
+	{ "PI",     "ADDRESS",               SIMPLE,   LEVEL_HOST }, /* publisher city */
+	{ "C1",     "ADDRESS",               SIMPLE,   LEVEL_MAIN }, /* author address */
+	{ "PA",     "ADDRESS",               SIMPLE,   LEVEL_HOST }, /* publisher address */
+	{ "RP",     "REPRINTADDRESS",        SIMPLE,   LEVEL_MAIN },
+	{ "PY",     "PARTDATE:YEAR",         SIMPLE,   LEVEL_MAIN },
+	{ "PD",     "PARTDATE:MONTH",        SIMPLE,   LEVEL_MAIN },
+	{ "VL",     "VOLUME",                SIMPLE,   LEVEL_MAIN },
+	{ "BP",     "PAGES:START",           SIMPLE,   LEVEL_MAIN },
+	{ "EP",     "PAGES:STOP",            SIMPLE,   LEVEL_MAIN },
+	{ "PG",     "PAGES:TOTAL",           SIMPLE,   LEVEL_MAIN },
+	{ "IS",     "ISSUE",                 SIMPLE,   LEVEL_MAIN },
+	{ "SN",     "SERIALNUMBER",          SERIALNO, LEVEL_HOST },
+	{ "AB",     "ABSTRACT",              SIMPLE,   LEVEL_MAIN },
+	{ "NF",     "NOTES",                 NOTES,    LEVEL_MAIN },
+	{ "DE",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* author keywords */
+	{ "ID",     "KEYWORD",               KEYWORD,  LEVEL_MAIN }, /* new ISI keywords */
+	{ "LA",     "LANGUAGE",              SIMPLE,   LEVEL_MAIN },
+	{ "TC",     "TIMESCITED",            SIMPLE,   LEVEL_MAIN },
+	{ "NR",     "NUMBERREFS",            SIMPLE,   LEVEL_MAIN },
+	{ "CR",     "CITEDREFS",             SIMPLE,   LEVEL_MAIN },
+	{ "PT",     " ",                     TYPE,     LEVEL_HOST },
+	{ "DT",     "DOCUMENTTYPE",          TYPE,     LEVEL_MAIN },
+	{ "GA",     "ISIDELIVERNUM",         SIMPLE,   LEVEL_MAIN }, /* ISI document delivery number */
+	{ "UT",     "ISIREFNUM",             SIMPLE,   LEVEL_MAIN }, /* ISI unique article identifer */
+	{ "DI",     "DOI",                   SIMPLE,   LEVEL_MAIN },
 	{ " ",      "INTERNAL_TYPE|INCOLLECTION",      ALWAYS, LEVEL_MAIN },
-	{ " ",      "ISSUANCE|monographic",   ALWAYS, LEVEL_HOST },
-	{ " ",      "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-	{ " ",      "GENRE|collection",       ALWAYS, LEVEL_MAIN }
+	{ " ",      "ISSUANCE|monographic",            ALWAYS, LEVEL_HOST },
+	{ " ",      "RESOURCE|text",                   ALWAYS, LEVEL_MAIN },
+	{ " ",      "GENRE:BIBUTILS|collection",       ALWAYS, LEVEL_MAIN }
 };
 
 #define ORIG(a) ( &(a[0]) )
diff --git a/bibutils/iso639_1.c b/bibutils/iso639_1.c
--- a/bibutils/iso639_1.c
+++ b/bibutils/iso639_1.c
@@ -208,4 +208,3 @@
 	}
 	return NULL;
 }
-
diff --git a/bibutils/iso639_1.h b/bibutils/iso639_1.h
--- a/bibutils/iso639_1.h
+++ b/bibutils/iso639_1.h
@@ -4,6 +4,6 @@
 #ifndef ISO639_1_H
 #define ISO639_1_H
 
-extern char * iso639_1_from_code( const char *code );
+char * iso639_1_from_code( const char *code );
 
 #endif
diff --git a/bibutils/iso639_2.c b/bibutils/iso639_2.c
--- a/bibutils/iso639_2.c
+++ b/bibutils/iso639_2.c
@@ -639,7 +639,8 @@
 {
 	int ok;
 	ok = check_alphabetical();
-	return EXIT_SUCCESS;
+	if ( ok ) return EXIT_SUCCESS;
+	return EXIT_FAILURE;
 }
 
 #endif
diff --git a/bibutils/iso639_2.h b/bibutils/iso639_2.h
--- a/bibutils/iso639_2.h
+++ b/bibutils/iso639_2.h
@@ -4,7 +4,7 @@
 #ifndef ISO639_2_H
 #define ISO639_2_H
 
-extern char * iso639_2_from_code( char *code );
-extern char * iso639_2_from_language( char *lang );
+char * iso639_2_from_code( char *code );
+char * iso639_2_from_language( char *lang );
 
 #endif
diff --git a/bibutils/iso639_3.h b/bibutils/iso639_3.h
--- a/bibutils/iso639_3.h
+++ b/bibutils/iso639_3.h
@@ -4,6 +4,6 @@
 #ifndef ISO639_3_H
 #define ISO639_3_H
 
-extern char * iso639_3_from_code( const char *code );
+char * iso639_3_from_code( const char *code );
 
 #endif
diff --git a/bibutils/latex.c b/bibutils/latex.c
--- a/bibutils/latex.c
+++ b/bibutils/latex.c
@@ -3,7 +3,7 @@
  *
  * convert between latex special chars and unicode
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/latex.h b/bibutils/latex.h
--- a/bibutils/latex.h
+++ b/bibutils/latex.h
@@ -1,7 +1,7 @@
 /*
  * latex.h
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/marc.c b/bibutils/marc.c
deleted file mode 100644
--- a/bibutils/marc.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * marc.c
- *
- * Copyright (c) Chris Putnam 2004-2017
- *
- * Source code released under the GPL version 2
- *
- */
-#include "marc.h"
-#include <string.h>
-
-int
-marc_findgenre( char *query )
-{
-	char *marc[] = { 
-		"abstract or summary",
-		"art original", 
-		"art reproduction",
-		"article",
-		"atlas",
-		"autobiography", 
-		"bibliography",
-		"biography",
-		"book",
-		"calendar",
-		"catalog", 
-		"chart",
-		"comic or graphic novel",
-		"comic strip",
-		"conference publication",
-		"database",
-		"dictionary",
-		"diorama",
-		"directory",
-		"discography",
-		"drama",
-		"encyclopedia",
-		"essay",
-		"festschrift",
-		"fiction",
-       		"filmography",
-		"filmstrip",
-		"finding aid",
-		"flash card",
-		"folktale",
-		"font",
-		"game",
-		"government publication",
-		"graphic",
-		"globe",
-		"handbook",
-		"history",
-		"humor, satire",
-		"hymnal",
-		"index",
-		"instruction",
-		"interview",
-		"issue",
-		"journal",
-		"kit",
-		"language instruction",
-		"law report or digest",
-		"legal article",
-		"legal case and case notes",
-		"legislation",
-		"letter",
-		"loose-leaf",
-		"map",
-		"memoir",
-		"microscope slide",
-		"model",
-		"motion picture",
-		"multivolume monograph",
-		"newspaper",
-		"novel",
-		"numeric data",
-		"offprint",
-		"online system or service",
-		"patent",
-		"periodical",
-		"picture",
-		"poetry",
-		"programmed text",
-		"realia",
-		"rehearsal",
-		"remote sensing image",
-		"reporting",
-		"review",
-		"series",
-		"short story",
-		"slide",
-		"sound",
-		"speech",
-		"standard or specification",
-		"statistics",
-		"survey of literature",
-		"technical drawing",
-		"technical report",
-		"thesis",
-		"toy",
-		"transparency",
-		"treaty",
-		"videorecording",
-		"web site",
-		"yearbook",
-	};
-	int nmarc = sizeof( marc ) / sizeof( char* );
-	int i;
-	for ( i=0; i<nmarc; ++i ) {
-		if ( !strcasecmp( query, marc[i] ) ) return i;
-	}
-	return -1;
-}
-
-int
-marc_findresource( char *query )
-{
-	char *marc[] = { 
-		"cartographic",
-		"kit",
-		"mixed material",
-		"moving image",
-		"notated music",
-		"software, multimedia",
-		"sound recording",
-		"sound recording - musical",
-		"sound recording - nonmusical",
-		"still image",
-		"text",
-		"three dimensional object"
-	};
-	int nmarc = sizeof( marc ) / sizeof( char* );
-	int i;
-	for ( i=0; i<nmarc; ++i ) {
-		if ( !strcasecmp( query, marc[i] ) ) return i;
-	}
-	return -1;
-}
diff --git a/bibutils/marc.h b/bibutils/marc.h
deleted file mode 100644
--- a/bibutils/marc.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * marc.h
- *
- * Copyright (c) Chris Putnam 2008-2017
- *
- * Source code released under the GPL version 2
- *
- */
-#ifndef MARC_H
-#define MARC_H
-
-extern int marc_findgenre( char *query );
-extern int marc_findresource( char *query );
-
-#endif
diff --git a/bibutils/marc_auth.c b/bibutils/marc_auth.c
new file mode 100644
--- /dev/null
+++ b/bibutils/marc_auth.c
@@ -0,0 +1,156 @@
+/*
+ * marc_auth.c
+ *
+ * Copyright (c) Chris Putnam 2004-2018
+ *
+ * Source code released under the GPL version 2
+ *
+ */
+#include "marc_auth.h"
+#include <string.h>
+
+static const char *marc_genre[] = {
+	"abstract or summary",
+	"art original",
+	"art reproduction",
+	"article",
+	"atlas",
+	"autobiography",
+	"bibliography",
+	"biography",
+	"book",
+	"calendar",
+	"catalog",
+	"chart",
+	"comic or graphic novel",
+	"comic strip",
+	"conference publication",
+	"database",
+	"dictionary",
+	"diorama",
+	"directory",
+	"discography",
+	"drama",
+	"encyclopedia",
+	"essay",
+	"festschrift",
+	"fiction",
+	"filmography",
+	"filmstrip",
+	"finding aid",
+	"flash card",
+	"folktale",
+	"font",
+	"game",
+	"government publication",
+	"graphic",
+	"globe",
+	"handbook",
+	"history",
+	"humor, satire",
+	"hymnal",
+	"index",
+	"instruction",
+	"interview",
+	"issue",
+	"journal",
+	"kit",
+	"language instruction",
+	"law report or digest",
+	"legal article",
+	"legal case and case notes",
+	"legislation",
+	"letter",
+	"loose-leaf",
+	"map",
+	"memoir",
+	"microscope slide",
+	"model",
+	"motion picture",
+	"multivolume monograph",
+	"newspaper",
+	"novel",
+	"numeric data",
+	"offprint",
+	"online system or service",
+	"patent",
+	"periodical",
+	"picture",
+	"poetry",
+	"programmed text",
+	"realia",
+	"rehearsal",
+	"remote sensing image",
+	"reporting",
+	"review",
+	"series",
+	"short story",
+	"slide",
+	"sound",
+	"speech",
+	"standard or specification",
+	"statistics",
+	"survey of literature",
+	"technical drawing",
+	"technical report",
+	"thesis",
+	"toy",
+	"transparency",
+	"treaty",
+	"videorecording",
+	"web site",
+	"yearbook",
+};
+static int nmarc_genre = sizeof( marc_genre ) / sizeof( const char* );
+
+static const char *marc_resource[] = {
+	"cartographic",
+	"kit",
+	"mixed material",
+	"moving image",
+	"notated music",
+	"software, multimedia",
+	"sound recording",
+	"sound recording - musical",
+	"sound recording - nonmusical",
+	"still image",
+	"text",
+	"three dimensional object"
+};
+static int nmarc_resource = sizeof( marc_resource ) / sizeof( const char* );
+
+static int
+position_in_list( const char *list[], int nlist, const char *query )
+{
+	int i;
+	for ( i=0; i<nlist; ++i ) {
+		if ( !strcasecmp( query, list[i] ) ) return i;
+	}
+	return -1;
+}
+
+int
+marc_findgenre( const char *query )
+{
+	return position_in_list( marc_genre, nmarc_genre, query );
+}
+
+int
+is_marc_genre( const char *query )
+{
+	if ( marc_findgenre( query ) != -1 ) return 1;
+	else return 0;
+}
+
+int
+marc_findresource( const char *query )
+{
+	return position_in_list( marc_resource, nmarc_resource, query );
+}
+
+int
+is_marc_resource( const char *query )
+{
+	if ( marc_findresource( query ) != -1 ) return 1;
+	else return 0;
+}
diff --git a/bibutils/marc_auth.h b/bibutils/marc_auth.h
new file mode 100644
--- /dev/null
+++ b/bibutils/marc_auth.h
@@ -0,0 +1,19 @@
+/*
+ * marc_auth.h
+ *
+ * Recognize the MARC authority vocabulary for genre and resource.
+ *
+ * Copyright (c) Chris Putnam 2008-2018
+ *
+ * Source code released under the GPL version 2
+ *
+ */
+#ifndef MARC_AUTH_H
+#define MARC_AUTH_H
+
+int marc_findgenre( const char *query );
+int is_marc_genre( const char *query );
+int marc_findresource( const char *query );
+int is_marc_resource( const char *query );
+
+#endif
diff --git a/bibutils/medin.c b/bibutils/medin.c
--- a/bibutils/medin.c
+++ b/bibutils/medin.c
@@ -1,7 +1,7 @@
 /*
  * medin.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
@@ -73,7 +73,7 @@
 	char *startptr=NULL;
 	int i;
 	for ( i=0; i<nwrapper && startptr==NULL; ++i ) {
-		startptr = xml_findstart( buf, wrapper[ i ] );
+		startptr = xml_find_start( buf, wrapper[ i ] );
 		if ( startptr && *ntype==-1 ) *ntype = i;
 	}
 	return startptr;
@@ -82,7 +82,7 @@
 static char *
 medin_findendwrapper( char *buf, int ntype )
 {
-	char *endptr = xml_findend( buf, wrapper[ ntype ] );
+	char *endptr = xml_find_end( buf, wrapper[ ntype ] );
 	return endptr;
 }
 
@@ -136,17 +136,17 @@
 	int i, fstatus;
 	char *d;
 	*found = 0;
-	if ( !xml_hasvalue( node ) ) return BIBL_OK;
-	d = xml_value( node );
+	if ( !xml_has_value( node ) ) return BIBL_OK;
+	d = xml_value_cstr( node );
 	for ( i=0; i<nc && *found==0; ++i ) {
 		if ( c[i].a==NULL ) {
-			if ( xml_tagexact( node, c[i].in ) ) {
+			if ( xml_tag_matches( node, c[i].in ) ) {
 				*found = 1;
 				fstatus = fields_add( info, c[i].out, d, c[i].level );
 				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 			}
 		} else {
-			if ( xml_tag_attrib( node, c[i].in, c[i].a, c[i].aval)){
+			if ( xml_tag_has_attribute( node, c[i].in, c[i].a, c[i].aval ) ) {
 				*found = 1;
 				fstatus = fields_add( info, c[i].out, d, c[i].level );
 				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
@@ -163,8 +163,8 @@
 medin_articletitle( xml *node, fields *info )
 {
 	int fstatus, status = BIBL_OK;
-	if ( xml_hasvalue( node ) ) {
-		fstatus = fields_add( info, "TITLE", xml_value( node ), 0 );
+	if ( xml_has_value( node ) ) {
+		fstatus = fields_add( info, "TITLE", xml_value_cstr( node ), 0 );
 		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
 	}
 	return status;
@@ -196,7 +196,7 @@
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 
-	p = str_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );
+	(void) str_cpytodelim( &tmp, skip_ws( p ), " \t\n\r", 0 );
 	if ( str_memerr( &tmp ) ) return BIBL_ERR_MEMERR;
 
 	if ( str_has_value( &tmp ) ) {
@@ -216,7 +216,7 @@
 {
 	char *code, *language;
 	int fstatus;
-	code = xml_value( node );
+	code = xml_value_cstr( node );
 	if ( !code ) return BIBL_OK;
 	language = iso639_2_from_code( code );
 	if ( language )
@@ -269,15 +269,15 @@
 		{ "Day",             NULL, NULL, "PARTDATE:DAY",   1 },
 	};
 	int nc = sizeof( c ) / sizeof( c[0] ), status, found;
-	if ( xml_hasvalue( node ) ) {
+	if ( xml_has_value( node ) ) {
 		status = medin_doconvert( node, info, c, nc, &found );
 		if ( status!=BIBL_OK ) return status;
 		if ( !found ) {
-			if ( xml_tagexact( node, "MedlineDate" ) ) {
-				status = medin_medlinedate( info, xml_value( node ), 1 );
+			if ( xml_tag_matches( node, "MedlineDate" ) ) {
+				status = medin_medlinedate( info, xml_value_cstr( node ), 1 );
 				if ( status!=BIBL_OK ) return status;
 			}
-			if ( xml_tagexact( node, "Language" ) ) {
+			if ( xml_tag_matches( node, "Language" ) ) {
 				status = medin_language( node, info, 1 );
 				if ( status!=BIBL_OK ) return status;
 			}
@@ -304,15 +304,15 @@
 	int i, fstatus, status;
 	str sp, ep;
 	char *p, *pp;
-	if ( xml_tagexact( node, "MedlinePgn" ) && node->value ) {
+	if ( xml_tag_matches( node, "MedlinePgn" ) && node->value.len ) {
 		strs_init( &sp, &ep, NULL );
-		p = str_cpytodelim( &sp, xml_value( node ), "-", 1 );
+		p = str_cpytodelim( &sp, xml_value_cstr( node ), "-", 1 );
 		if ( str_memerr( &sp ) ) return BIBL_ERR_MEMERR;
 		if ( str_has_value( &sp ) ) {
 			fstatus = fields_add( info, "PAGES:START", str_cstr( &sp ), 1 );
 			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		}
-		p = str_cpytodelim( &ep, p, "", 0 );
+		(void) str_cpytodelim( &ep, p, "", 0 );
 		if ( str_memerr( &ep ) ) return BIBL_ERR_MEMERR;
 		if ( str_has_value( &ep ) ) {
 			if ( sp.len > ep.len ) {
@@ -344,8 +344,8 @@
 medin_abstract( xml *node, fields *info )
 {
 	int fstatus;
-	if ( xml_tagwithvalue( node, "AbstractText" ) ) {
-		fstatus = fields_add( info, "ABSTRACT", xml_value( node ), 0 );
+	if ( xml_tag_matches_has_value( node, "AbstractText" ) ) {
+		fstatus = fields_add( info, "ABSTRACT", xml_value_cstr( node ), 0 );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	} else if ( node->next ) return medin_abstract( node->next, info );
 	return BIBL_OK;
@@ -367,22 +367,22 @@
 medin_author( xml *node, str *name )
 {
 	char *p;
-	if ( xml_tagexact( node, "LastName" ) ) {
+	if ( xml_tag_matches( node, "LastName" ) ) {
 		if ( str_has_value( name ) ) {
 			str_prepend( name, "|" );
-			str_prepend( name, xml_value( node ) );
+			str_prepend( name, xml_value_cstr( node ) );
 		}
-		else str_strcatc( name, xml_value( node ) );
-	} else if ( xml_tagexact( node, "ForeName" ) || 
-	            xml_tagexact( node, "FirstName" ) ) {
-		p = xml_value( node );
+		else str_strcat( name, xml_value( node ) );
+	} else if ( xml_tag_matches( node, "ForeName" ) ||
+	            xml_tag_matches( node, "FirstName" ) ) {
+		p = xml_value_cstr( node );
 		while ( p && *p ) {
 			if ( str_has_value( name ) ) str_addchar( name, '|' );
-			while ( *p && *p==' ' ) p++;
+			while ( *p==' ' ) p++;
 			while ( *p && *p!=' ' ) str_addchar( name, *p++ );
 		}
-	} else if ( xml_tagexact( node, "Initials" ) && !strchr( name->data, '|' )) {
-		p = xml_value( node );
+	} else if ( xml_tag_matches( node, "Initials" ) && !strchr( name->data, '|' )) {
+		p = xml_value_cstr( node );
 		while ( p && *p ) {
 			if ( str_has_value( name ) ) str_addchar( name, '|' );
 			if ( !is_ws(*p) ) str_addchar( name, *p++ );
@@ -395,8 +395,8 @@
 static int
 medin_corpauthor( xml *node, str *name )
 {
-	if ( xml_tagexact( node, "CollectiveName" ) ) {
-		str_strcpyc( name, xml_value( node ) );
+	if ( xml_tag_matches( node, "CollectiveName" ) ) {
+		str_strcpy( name, xml_value( node ) );
 	} else if ( node->next ) medin_corpauthor( node->next, name );
 	return BIBL_OK;
 }
@@ -410,7 +410,7 @@
 	str_init( &name );
 	node = node->down;
 	while ( node ) {
-		if ( xml_tagexact( node, "Author" ) && node->down ) {
+		if ( xml_tag_matches( node, "Author" ) && node->down ) {
 			status = medin_author( node->down, &name );
 			tag = "AUTHOR";
 			if ( str_is_empty( &name ) ) {
@@ -446,8 +446,8 @@
 medin_journal2( xml *node, fields *info )
 {
 	int fstatus, status = BIBL_OK;
-	if ( xml_tagwithvalue( node, "MedlineTA" ) && fields_find( info, "TITLE", 1 )==-1 ) {
-		fstatus = fields_add( info, "TITLE", xml_value( node ), 1 );
+	if ( xml_tag_matches_has_value( node, "MedlineTA" ) && fields_find( info, "TITLE", LEVEL_HOST )==FIELDS_NOTFOUND ) {
+		fstatus = fields_add( info, "TITLE", xml_value_cstr( node ), 1 );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
@@ -472,8 +472,8 @@
 medin_meshheading( xml *node, fields *info )
 {
 	int fstatus, status = BIBL_OK;
-	if ( xml_tagwithvalue( node, "DescriptorName" ) ) {
-		fstatus = fields_add( info, "KEYWORD", xml_value( node ), 0 );
+	if ( xml_tag_matches_has_value( node, "DescriptorName" ) ) {
+		fstatus = fields_add( info, "KEYWORD", xml_value_cstr( node ), 0 );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->next ) status = medin_meshheading( node->next, info );
@@ -484,7 +484,7 @@
 medin_meshheadinglist( xml *node, fields *info )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "MeshHeading" ) && node->down ) {
+	if ( xml_tag_matches( node, "MeshHeading" ) && node->down ) {
 		status = medin_meshheading( node->down, info );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -532,20 +532,20 @@
 medin_article( xml *node, fields *info )
 {
 	int fstatus, status = BIBL_OK;
-	if ( xml_tagexact( node, "Journal" ) )
+	if ( xml_tag_matches( node, "Journal" ) )
 		status = medin_journal1( node, info );
-	else if ( xml_tagexact( node, "ArticleTitle" ) )
+	else if ( xml_tag_matches( node, "ArticleTitle" ) )
 		status = medin_articletitle( node, info );
-	else if ( xml_tagexact( node, "Pagination" ) && node->down )
+	else if ( xml_tag_matches( node, "Pagination" ) && node->down )
 		status = medin_pagination( node->down, info );
-	else if ( xml_tagexact( node, "Abstract" ) && node->down )
+	else if ( xml_tag_matches( node, "Abstract" ) && node->down )
 		status = medin_abstract( node->down, info );
-	else if ( xml_tagexact( node, "AuthorList" ) )
+	else if ( xml_tag_matches( node, "AuthorList" ) )
 		status = medin_authorlist( node, info );
-	else if ( xml_tagexact( node, "Language" ) )
+	else if ( xml_tag_matches( node, "Language" ) )
 		status = medin_language( node, info, 0 );
-	else if ( xml_tagexact( node, "Affiliation" ) ) {
-		fstatus = fields_add( info, "ADDRESS", xml_value( node ), 0 );
+	else if ( xml_tag_matches( node, "Affiliation" ) ) {
+		fstatus = fields_add( info, "ADDRESS", xml_value_cstr( node ), 0 );
 		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
 	}
 	if ( status!=BIBL_OK ) return status;
@@ -557,16 +557,16 @@
 medin_medlinecitation( xml *node, fields *info )
 {
 	int fstatus, status = BIBL_OK;
-	if ( xml_tagexact( node, "PMID" ) && node->value->data ) {
-		fstatus = fields_add( info, "PMID", node->value->data, 0 );
+	if ( xml_tag_matches_has_value( node, "PMID" ) ) {
+		fstatus = fields_add( info, "PMID", xml_value_cstr( node ), 0 );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
-		if ( xml_tagexact( node, "Article" ) ) {
+		if ( xml_tag_matches( node, "Article" ) ) {
 			status = medin_article( node->down, info );
-		} else if ( xml_tagexact( node, "MedlineJournalInfo" ) ) {
+		} else if ( xml_tag_matches( node, "MedlineJournalInfo" ) ) {
 			status = medin_journal2( node->down, info );
-		} else if ( xml_tagexact( node, "MeshHeadingList" ) )
+		} else if ( xml_tag_matches( node, "MeshHeadingList" ) )
 			status = medin_meshheadinglist( node->down, info );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -579,9 +579,9 @@
 {
 	int status = BIBL_OK;
 	if ( node->down ) {
-		if ( xml_tagexact( node, "MedlineCitation" ) )
+		if ( xml_tag_matches( node, "MedlineCitation" ) )
 			status = medin_medlinecitation( node->down, info );
-		else if ( xml_tagexact( node, "PubmedData" ) )
+		else if ( xml_tag_matches( node, "PubmedData" ) )
 			status = medin_pubmeddata( node->down, info );
 		if ( status!=BIBL_OK ) return status;
 	}
@@ -594,9 +594,9 @@
 {
 	int status = BIBL_OK;
 	if ( node->down ) {
-		if ( xml_tagexact( node, "PubmedArticle" ) )
+		if ( xml_tag_matches( node, "PubmedArticle" ) )
 			status = medin_pubmedarticle( node->down, info );
-		else if ( xml_tagexact( node, "MedlineCitation" ) )
+		else if ( xml_tag_matches( node, "MedlineCitation" ) )
 			status = medin_medlinecitation( node->down, info );
 		else
 			status = medin_assembleref( node->down, info );
@@ -614,9 +614,9 @@
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		status = fields_add( info, "ISSUANCE", "continuing", 1 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
-		status = fields_add( info, "GENRE", "periodical", 1 );
+		status = fields_add( info, "GENRE:MARC", "periodical", 1 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
-		status = fields_add( info, "GENRE", "academic journal", 1 );
+		status = fields_add( info, "GENRE:BIBUTILS", "academic journal", 1 );
 		if ( status!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		status = BIBL_OK;
 	}
@@ -631,7 +631,7 @@
 	xml top;
 
 	xml_init( &top );
-	xml_tree( data, &top );
+	xml_parse( data, &top );
 	status = medin_assembleref( &top, medin );
 	xml_free( &top );
 
diff --git a/bibutils/modsin.c b/bibutils/modsin.c
--- a/bibutils/modsin.c
+++ b/bibutils/modsin.c
@@ -1,7 +1,7 @@
 /*
  * modsin.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
@@ -19,7 +19,8 @@
 #include "name.h"
 #include "reftypes.h"
 #include "modstypes.h"
-#include "marc.h"
+#include "bu_auth.h"
+#include "marc_auth.h"
 #include "url.h"
 #include "iso639_1.h"
 #include "iso639_2.h"
@@ -76,9 +77,9 @@
 modsin_detailr( xml *node, str *value )
 {
 	int status = BIBL_OK;
-	if ( node->value && node->value->len ) {
+	if ( xml_has_value( node ) ) {
 		if ( value->len ) str_addchar( value, ' ' );
-		str_strcat( value, node->value );
+		str_strcat( value, xml_value( node ) );
 		if ( str_memerr( value ) ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
@@ -97,7 +98,7 @@
 	int fstatus, status = BIBL_OK;
 	if ( node->down ) {
 		strs_init( &type, &value, NULL );
-		tp = xml_getattrib( node, "type" );
+		tp = xml_attribute( node, "type" );
 		if ( tp ) {
 			str_strcpy( &type, tp );
 			str_toupper( &type );
@@ -121,11 +122,14 @@
 modsin_date( xml *node, fields *info, int level, int part )
 {
 	int fstatus, status = BIBL_OK;
-	char *tag, *p = NULL;
+	char *tag, *p;
 	str s;
-	if ( node->value ) p = node->value->data;
+
+	str_init( &s );
+
+	p = xml_value_cstr( node );
+
 	if ( p ) {
-		str_init( &s );
 
 		p = str_cpytodelim( &s, skip_ws( p ), "-", 1 );
 		if ( str_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }
@@ -143,16 +147,18 @@
 			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }
 		}
 
-		p = str_cpytodelim( &s, skip_ws( p ), "", 0 );
+		(void) str_cpytodelim( &s, skip_ws( p ), "", 0 );
 		if ( str_memerr( &s ) ) { status = BIBL_ERR_MEMERR; goto out; }
 		if ( str_has_value( &s ) ) {
 			tag = ( part ) ? "PARTDATE:DAY" : "DATE:DAY";
 			fstatus =  fields_add( info, tag, str_cstr( &s ), level );
 			if ( fstatus!=FIELDS_OK ) { status = BIBL_ERR_MEMERR; goto out; }
 		}
-out:
-		str_free( &s );
+
 	}
+
+out:
+	str_free( &s );
 	return status;
 }
 
@@ -160,17 +166,17 @@
 modsin_pager( xml *node, str *sp, str *ep, str *tp, str *lp )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "start" ) ) {
-		str_strcpy( sp, node->value );
+	if ( xml_tag_matches_has_value( node, "start" ) ) {
+		str_strcpy( sp, xml_value( node ) );
 		if ( str_memerr( sp ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "end" ) ) {
-		str_strcpy( ep, node->value );
+	} else if ( xml_tag_matches_has_value( node, "end" ) ) {
+		str_strcpy( ep, xml_value( node ) );
 		if ( str_memerr( ep ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "total" ) ) {
-		str_strcpy( tp, node->value );
+	} else if ( xml_tag_matches_has_value( node, "total" ) ) {
+		str_strcpy( tp, xml_value( node ) );
 		if ( str_memerr( tp ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "list" ) ) {
-		str_strcpy( lp, node->value );
+	} else if ( xml_tag_matches_has_value( node, "list" ) ) {
+		str_strcpy( lp, xml_value( node ) );
 		if ( str_memerr( lp ) ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
@@ -222,12 +228,12 @@
 modsin_titler( xml *node, str *title, str *subtitle )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "title" ) ) {
+	if ( xml_tag_matches_has_value( node, "title" ) ) {
 		if ( str_has_value( title ) ) str_strcatc( title, " : " );
-		str_strcat( title, node->value );
+		str_strcat( title, xml_value( node ) );
 		if ( str_memerr( title ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "subTitle" ) ) {
-		str_strcat( subtitle, node->value );
+	} else if ( xml_tag_matches_has_value( node, "subTitle" ) ) {
+		str_strcat( subtitle, xml_value( node ) );
 		if ( str_memerr( subtitle ) ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
@@ -255,7 +261,7 @@
 	if ( !dnode ) return status;
 
 	strs_init( &title, &subtitle, NULL );
-	abbr = xml_tag_attrib( node, "titleInfo", "type", "abbreviated" );
+	abbr = xml_tag_has_attribute( node, "titleInfo", "type", "abbreviated" );
 
 	status = modsin_titler( dnode, &title, &subtitle );
 	if ( status!=BIBL_OK ) goto out;
@@ -343,12 +349,12 @@
 modsin_asis_corp_r( xml *node, str *name, str *role )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "namePart" ) ) {
-		str_strcpy( name, node->value );
+	if ( xml_tag_matches_has_value( node, "namePart" ) ) {
+		str_strcpy( name, xml_value( node ) );
 		if ( str_memerr( name ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "roleTerm" ) ) {
+	} else if ( xml_tag_matches_has_value( node, "roleTerm" ) ) {
 		if ( role->len ) str_addchar( role, '|' );
-		str_strcat( role, node->value );
+		str_strcat( role, xml_value( node ) );
 		if ( str_memerr( role ) ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
@@ -383,8 +389,10 @@
 static int
 modsin_roler( xml *node, str *roles )
 {
-	if ( roles->len ) str_addchar( roles, '|' );
-	str_strcat( roles, node->value );
+	if ( xml_has_value( node ) ) {
+		if ( roles->len ) str_addchar( roles, '|' );
+		str_strcat( roles, xml_value( node ) );
+	}
 	if ( str_memerr( roles ) ) return BIBL_ERR_MEMERR;
 	else return BIBL_OK;
 }
@@ -394,26 +402,28 @@
 {
 	int status = BIBL_OK;
 
-	if ( xml_tag_attrib( node, "namePart", "type", "family" ) ) {
+	if ( !xml_has_value( node ) ) return status;
+
+	if ( xml_tag_has_attribute( node, "namePart", "type", "family" ) ) {
 		if ( str_has_value( familyname ) ) str_addchar( familyname, ' ' );
-		str_strcat( familyname, node->value );
+		str_strcat( familyname, xml_value( node ) );
 		if ( str_memerr( familyname ) ) status = BIBL_ERR_MEMERR;
 	}
 
-	else if ( xml_tag_attrib( node, "namePart", "type", "suffix") ||
-	          xml_tag_attrib( node, "namePart", "type", "termsOfAddress" )) {
+	else if ( xml_tag_has_attribute( node, "namePart", "type", "suffix"         ) ||
+	          xml_tag_has_attribute( node, "namePart", "type", "termsOfAddress" ) ) {
 		if ( str_has_value( suffix ) ) str_addchar( suffix, ' ' );
-		str_strcat( suffix, node->value );
+		str_strcat( suffix, xml_value( node ) );
 		if ( str_memerr( suffix ) ) status = BIBL_ERR_MEMERR;
 	}
 
-	else if (xml_tag_attrib( node, "namePart", "type", "date") ){
+	else if ( xml_tag_has_attribute( node, "namePart", "type", "date" ) ) {
 		/* no nothing */
 	}
 
 	else {
 		if ( str_has_value( givenname ) ) str_addchar( givenname, '|' );
-		str_strcat( givenname, node->value );
+		str_strcat( givenname, xml_value( node ) );
 		if ( str_memerr( givenname ) ) status = BIBL_ERR_MEMERR;
 	}
 
@@ -434,15 +444,15 @@
 
 	while ( dnode ) {
 
-		if ( xml_tagexact( dnode, "namePart" ) ) {
+		if ( xml_tag_matches( dnode, "namePart" ) ) {
 			status = modsin_personr( dnode, &familyname, &givenname, &suffix );
 			if ( status!=BIBL_OK ) goto out;
 		}
 
-		else if ( xml_tagexact( dnode, "role" ) ) {
+		else if ( xml_tag_matches( dnode, "role" ) ) {
 			rnode = dnode->down;
 			while ( rnode ) {
-				if ( xml_tagexact( rnode, "roleTerm" ) ) {
+				if ( xml_tag_matches( rnode, "roleTerm" ) ) {
 					status = modsin_roler( rnode, &roles );
 					if ( status!=BIBL_OK ) goto out;
 				}
@@ -509,7 +519,7 @@
 
 	tag = ( school ) ? school_tag : address_tag;
 
-	fstatus = fields_add( info, tag, xml_value( node ), level );
+	fstatus = fields_add( info, tag, xml_value_cstr( node ), level );
 	if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 
 	return BIBL_OK;
@@ -523,12 +533,12 @@
 
 	str_init( &s );
 
-	auth = xml_getattrib( node, "authority" );
+	auth = xml_attribute( node, "authority" );
 	if ( auth && auth->len ) {
 		str_strcpy( &s, auth );
 		str_addchar( &s, '|' );
 	}
-	str_strcat( &s, node->value );
+	str_strcat( &s, xml_value( node ) );
 
 	if ( str_memerr( &s ) ) {
 		status = BIBL_ERR_MEMERR;
@@ -548,7 +558,7 @@
 	int status = BIBL_OK;
 	str *type;
 
-	type = xml_getattrib( node, "type" );
+	type = xml_attribute( node, "type" );
 	if ( str_has_value( type ) ) {
 		if ( !strcmp( str_cstr( type ), "text" ) )
 			status = modsin_placeterm_text( node, info, level, school );
@@ -563,16 +573,20 @@
 modsin_placer( xml *node, fields *info, int level, int school )
 {
 	int status = BIBL_OK;
-	if ( xml_tag_attrib( node, "place", "type", "school" ) ) {
+
+	if ( xml_tag_has_attribute( node, "place", "type", "school" ) ) {
 		school = 1;
-	} else if ( xml_tagexact( node, "placeTerm" ) ) {
+	} else if ( xml_tag_matches( node, "placeTerm" ) ) {
 		status = modsin_placeterm( node, info, level, school );
 	}
+
 	if ( node->down ) {
 		status = modsin_placer( node->down, info, level, school );
 		if ( status!=BIBL_OK ) return status;
 	}
+
 	if ( node->next ) status = modsin_placer( node->next, info, level, school );
+
 	return status;
 }
 
@@ -580,26 +594,31 @@
 modsin_origininfor( xml *node, fields *info, int level, str *pub, str *add, str *addc, str *ed, str *iss )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "dateIssued" ) )
+
+	if ( xml_tag_matches( node, "dateIssued" ) ) {
 		status = modsin_date( node, info, level, 0 );
-	else if ( xml_tagexact( node, "publisher" ) && xml_hasvalue( node ) ) {
-		str_strcat( pub, node->value );
+	} else if ( xml_tag_matches( node, "place" ) ) {
+		status = modsin_placer( node, info, level, 0 );
+	} else if ( xml_tag_matches_has_value( node, "publisher" ) ) {
+		str_strcat( pub, xml_value( node ) );
 		if ( str_memerr( pub ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "edition" ) && xml_hasvalue( node ) ) {
-		str_strcat( ed, node->value );
+	} else if ( xml_tag_matches_has_value( node, "edition" ) ) {
+		str_strcat( ed, xml_value( node ) );
 		if( str_memerr( ed ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "issuance" ) && xml_hasvalue( node ) ) {
-		str_strcat( iss, node->value );
+	} else if ( xml_tag_matches_has_value( node, "issuance" ) ) {
+		str_strcat( iss, xml_value( node ) );
 		if ( str_memerr( iss ) ) return BIBL_ERR_MEMERR;
-	} else if ( xml_tagexact( node, "place" ) && xml_hasvalue( node ) )
-		status = modsin_placer( node, info, level, 0 );
+	}
 	if ( status!=BIBL_OK ) return status;
+
 	if ( node->down ) {
 		status = modsin_origininfor( node->down, info, level, pub, add, addc, ed, iss );
 		if ( status!=BIBL_OK ) return status;
 	}
+
 	if ( node->next )
 		status = modsin_origininfor( node->next, info, level, pub, add, addc, ed, iss );
+
 	return status;
 }
 
@@ -643,14 +662,18 @@
 modsin_subjectr( xml *node, fields *info, int level )
 {
 	int fstatus, status = BIBL_OK;
-	if ( xml_tag_attrib( node, "topic", "class", "primary" ) ) {
-		fstatus = fields_add( info, "EPRINTCLASS", node->value->data, level );
+	if ( xml_tag_has_attribute( node, "topic", "class", "primary" ) && xml_has_value( node ) ) {
+		fstatus = fields_add( info, "EPRINTCLASS", xml_value_cstr( node ), level );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
-	else if ( xml_tagexact( node, "topic" ) || xml_tagexact( node, "geographic" )) {
-		fstatus = fields_add( info, "KEYWORD", node->value->data, level );
+	else if ( xml_tag_matches_has_value( node, "topic" ) ) {
+		fstatus = fields_add( info, "KEYWORD", xml_value_cstr( node ), level );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
+	else if ( xml_tag_matches_has_value( node, "geographic" ) ) {
+		fstatus = fields_add( info, "KEYWORD", xml_value_cstr( node ), level );
+		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
+	}
 	if ( node->down ) {
 		status = modsin_subjectr( node->down, info, level );
 		if ( status!=BIBL_OK ) return status;
@@ -672,7 +695,7 @@
 {
 	int fstatus;
 	str *ns;
-	ns = xml_getattrib( node, "ID" );
+	ns = xml_attribute( node, "ID" );
 	if ( str_has_value( ns ) ) {
 		fstatus = fields_add( info, "REFNUM", str_cstr( ns ), level );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
@@ -680,35 +703,31 @@
 	return BIBL_OK;
 }
 
+/* modsin_genre()
+ *
+ * MARC authority terms tagged with "GENRE:MARC"
+ * bibutils authority terms tagged with "GENRE:BIBUTILS"
+ * unknown terms tagged with "GENRE:UNKNOWN"
+ */
 static int
 modsin_genre( xml *node, fields *info, int level )
 {
-	char *added[] = { "manuscript", "academic journal", "magazine",
-		"hearing", "report", "Ph.D. thesis", "Masters thesis",
-		"Diploma thesis", "Doctoral thesis", "Habilitation thesis",
-		"collection", "handwritten note", "communication",
-		"teletype", "airtel", "memo", "e-mail communication",
-		"press release", "television broadcast", "electronic"
-	};
-	int nadded = sizeof( added ) /sizeof( char *);
-	int i, ismarc = 0, isadded = 0, fstatus;
+	int fstatus;
 	char *d;
 
-	if ( !xml_hasvalue( node ) ) return BIBL_OK;
-	d = xml_value( node );
-	if ( marc_findgenre( d )!=-1 ) ismarc = 1;
-	if ( !ismarc ) {
-		for ( i=0; i<nadded && ismarc==0 && isadded==0; ++i )
-			if ( !strcasecmp( d, added[i] ) ) isadded = 1;
-	}
+	if ( !xml_has_value( node ) ) return BIBL_OK;
 
-	if ( ismarc || isadded ) 
-		fstatus = fields_add( info, "GENRE", d, level );
+	d = xml_value_cstr( node );
+
+	if ( is_marc_genre( d ) )
+		fstatus = fields_add( info, "GENRE:MARC", d, level );
+	else if ( is_bu_genre( d ) )
+		fstatus = fields_add( info, "GENRE:BIBUTILS", d, level );
 	else
-		fstatus = fields_add( info, "NGENRE", d, level );
-	if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
+		fstatus = fields_add( info, "GENRE:UNKNOWN", d, level );
 
-	return BIBL_OK;
+	if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
+	else return BIBL_OK;
 }
 
 /* in MODS version 3.5
@@ -725,17 +744,17 @@
 {
 	int fstatus, status = BIBL_OK;
 	char *d = NULL;
-	if ( xml_tagexact( node, "languageTerm" ) ) {
-		if ( xml_hasvalue( node ) ) {
-			if ( xml_hasattrib( node, "type", "code" ) ) {
-				if ( xml_hasattrib( node, "authority", "iso639-1" ) )
-					d = iso639_1_from_code( xml_value( node ) );
-				else if ( xml_hasattrib( node, "authority", "iso639-2b" ) )
-					d = iso639_2_from_code( xml_value( node ) );
-				else if ( xml_hasattrib( node, "authority", "iso639-3" ))
-					d = iso639_3_from_code( xml_value( node ) );
+	if ( xml_tag_matches( node, "languageTerm" ) ) {
+		if ( xml_has_value( node ) ) {
+			if ( xml_has_attribute( node, "type", "code" ) ) {
+				if ( xml_has_attribute( node, "authority", "iso639-1" ) )
+					d = iso639_1_from_code( xml_value_cstr( node ) );
+				else if ( xml_has_attribute( node, "authority", "iso639-2b" ) )
+					d = iso639_2_from_code( xml_value_cstr( node ) );
+				else if ( xml_has_attribute( node, "authority", "iso639-3" ))
+					d = iso639_3_from_code( xml_value_cstr( node ) );
 			}
-			if ( !d ) d  = xml_value( node );
+			if ( !d ) d  = xml_value_cstr( node );
 			fstatus = fields_add( info, "LANGUAGE", d, level );
 			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		}
@@ -749,8 +768,8 @@
 {
 	int fstatus, status = BIBL_OK;
 	/* Old versions of MODS had <language>English</language> */
-	if ( xml_hasvalue( node ) ) {
-		fstatus = fields_add( info, "LANGUAGE", xml_value( node ), level );
+	if ( xml_has_value( node ) ) {
+		fstatus = fields_add( info, "LANGUAGE", xml_value_cstr( node ), level );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 
@@ -763,8 +782,8 @@
 modsin_simple( xml *node, fields *info, char *tag, int level )
 {
 	int fstatus;
-	if ( xml_hasvalue( node ) ) {
-		fstatus = fields_add( info, tag, xml_value( node ), level );
+	if ( xml_has_value( node ) ) {
+		fstatus = fields_add( info, tag, xml_value_cstr( node ), level );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	return BIBL_OK;
@@ -778,25 +797,25 @@
 	char *fileattach = "FILEATTACH";
 	char *tag=NULL;
 
-	if ( xml_tagexact( node, "url" ) ) {
-		if ( xml_hasattrib( node, "access", "raw object" ) )
+	if ( xml_tag_matches( node, "url" ) ) {
+		if ( xml_has_attribute( node, "access", "raw object" ) )
 			tag = fileattach;
 		else
 			tag = url;
 	}
-	else if ( xml_tagexact( node, "physicalLocation" ) ) {
-		if ( xml_hasattrib( node, "type", "school" ) )
+	else if ( xml_tag_matches( node, "physicalLocation" ) ) {
+		if ( xml_has_attribute( node, "type", "school" ) )
 			tag = "SCHOOL";
 		else
 			tag = "LOCATION";
 	}
 
 	if ( tag == url ) {
-		status = urls_split_and_add( xml_value( node ), info, level );
+		status = urls_split_and_add( xml_value_cstr( node ), info, level );
 		if ( status!=BIBL_OK ) return status;
 	}
 	else if ( tag ) {
-		fstatus = fields_add( info, tag, xml_value( node ), level );
+		fstatus = fields_add( info, tag, xml_value_cstr( node ), level );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 
@@ -820,9 +839,9 @@
 modsin_descriptionr( xml *node, str *s )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "extent" ) ||
-	     xml_tagexact( node, "note" ) ) {
-		str_strcpy( s, node->value );
+	if ( xml_tag_matches( node, "extent" ) ||
+	     xml_tag_matches( node, "note" ) ) {
+		str_strcpy( s, &(node->value) );
 		if ( str_memerr( s ) ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) {
@@ -843,8 +862,8 @@
 		status = modsin_descriptionr( node->down, &s );
 		if ( status!=BIBL_OK ) goto out;
 	} else {
-		if ( node->value && node->value->len > 0 )
-			str_strcpy( &s, node->value );
+		if ( node->value.len > 0 )
+			str_strcpy( &s, &(node->value) );
 		if ( str_memerr( &s ) ) {
 			status = BIBL_ERR_MEMERR;
 			goto out;
@@ -866,13 +885,13 @@
 modsin_partr( xml *node, fields *info, int level )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "detail" ) )
+	if ( xml_tag_matches( node, "detail" ) )
 		status = modsin_detail( node, info, level );
-	else if ( xml_tag_attrib( node, "extent", "unit", "page" ) )
+	else if ( xml_tag_has_attribute( node, "extent", "unit", "page" ) )
 		status = modsin_page( node, info, level );
-	else if ( xml_tag_attrib( node, "extent", "unit", "pages" ) )
+	else if ( xml_tag_has_attribute( node, "extent", "unit", "pages" ) )
 		status = modsin_page( node, info, level );
-	else if ( xml_tagexact( node, "date" ) )
+	else if ( xml_tag_matches( node, "date" ) )
 		status = modsin_date( node, info, level, 1 );
 	if ( status!=BIBL_OK ) return status;
 	if ( node->next ) status = modsin_partr( node->next, info, level );
@@ -891,14 +910,13 @@
 modsin_classification( xml *node, fields *info, int level )
 {
 	int fstatus, status = BIBL_OK;
-	char *tag, *d;
-	if ( xml_hasvalue( node ) ) {
-		d = xml_value( node );
-		if ( xml_tag_attrib( node, "classification", "authority", "lcc" ) )
+	char *tag;
+	if ( xml_has_value( node ) ) {
+		if ( xml_tag_has_attribute( node, "classification", "authority", "lcc" ) )
 			tag = "LCC";
 		else
 			tag = "CLASSIFICATION";
-		fstatus = fields_add( info, tag, d, level );
+		fstatus = fields_add( info, tag, xml_value_cstr( node ), level );
 		if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 	}
 	if ( node->down ) status = modsin_classification( node->down, info, level );
@@ -910,14 +928,12 @@
 {
 	int fstatus;
 	xml *curr;
-	char *d;
 
 	/* extract recordIdentifier */
 	curr = node;
 	while ( curr ) {
-		if ( xml_tagexact( curr, "recordIdentifier" ) && xml_hasvalue( curr ) ) {
-			d = xml_value( curr );
-			fstatus = fields_add( info, "REFNUM", d, level );
+		if ( xml_tag_matches_has_value( curr, "recordIdentifier" ) ) {
+			fstatus = fields_add( info, "REFNUM", xml_value_cstr( curr ), level );
 			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		}
 		curr = curr->next;
@@ -949,10 +965,10 @@
 		{ "jstor",         "JSTOR",       0, 0 },
 	};
 	int i, fstatus, n = sizeof( ids ) / sizeof( ids[0] );
-	if ( !node->value || node->value->len==0 ) return BIBL_OK;
+	if ( node->value.len==0 ) return BIBL_OK;
 	for ( i=0; i<n; ++i ) {
-		if ( xml_tag_attrib( node, "identifier", "type", ids[i].mods ) ) {
-			fstatus = fields_add( info, ids[i].internal, node->value->data, level );
+		if ( xml_tag_has_attribute( node, "identifier", "type", ids[i].mods ) ) {
+			fstatus = fields_add( info, ids[i].internal, xml_value_cstr( node ), level );
 			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		}
 	}
@@ -973,7 +989,7 @@
 	int i, found = 0, status = BIBL_OK;
 
 	for ( i=0; i<nsimple && found==0; i++ ) {
-		if ( xml_tagexact( node, simple[i].mods ) ) {
+		if ( xml_tag_matches( node, simple[i].mods ) ) {
 			status = modsin_simple( node, info, simple[i].internal, level );
 			if ( status!=BIBL_OK ) return status;
 			found = 1;
@@ -981,41 +997,41 @@
 	}
 
 	if ( !found ) {
-		if ( xml_tagexact( node, "titleInfo" ) )
+		if ( xml_tag_matches( node, "titleInfo" ) )
 			modsin_title( node, info, level );
-		else if ( xml_tag_attrib( node, "name", "type", "personal" ) )
+		else if ( xml_tag_has_attribute( node, "name", "type", "personal" ) )
 			status = modsin_person( node, info, level );
-		else if ( xml_tag_attrib( node, "name", "type", "corporate" ) )
+		else if ( xml_tag_has_attribute( node, "name", "type", "corporate" ) )
 			status = modsin_asis_corp( node, info, level, ":CORP" );
-		else if ( xml_tagexact( node, "name" ) )
+		else if ( xml_tag_matches( node, "name" ) )
 			status = modsin_asis_corp( node, info, level, ":ASIS" );
-		else if ( xml_tagexact( node, "recordInfo" ) && node->down )
+		else if ( xml_tag_matches( node, "recordInfo" ) && node->down )
 			status = modsin_recordinfo( node->down, info, level );
-		else if  ( xml_tagexact( node, "part" ) )
+		else if  ( xml_tag_matches( node, "part" ) )
 			modsin_part( node, info, level );
-		else if ( xml_tagexact( node, "identifier" ) )
+		else if ( xml_tag_matches( node, "identifier" ) )
 			status = modsin_identifier( node, info, level );
-		else if ( xml_tagexact( node, "originInfo" ) )
+		else if ( xml_tag_matches( node, "originInfo" ) )
 			status = modsin_origininfo( node, info, level );
-		else if ( xml_tagexact( node, "language" ) )
+		else if ( xml_tag_matches( node, "language" ) )
 			status = modsin_language( node, info, level );
-		else if ( xml_tagexact( node, "genre" ) )
+		else if ( xml_tag_matches( node, "genre" ) )
 			status = modsin_genre( node, info, level );
-		else if ( xml_tagexact( node, "date" ) )
+		else if ( xml_tag_matches( node, "date" ) )
 			status = modsin_date( node, info, level, 0 );
-		else if ( xml_tagexact( node, "subject" ) )
+		else if ( xml_tag_matches( node, "subject" ) )
 			status = modsin_subject( node, info, level );
-		else if ( xml_tagexact( node, "classification" ) )
+		else if ( xml_tag_matches( node, "classification" ) )
 			status = modsin_classification( node, info, level );
-		else if ( xml_tagexact( node, "location" ) )
+		else if ( xml_tag_matches( node, "location" ) )
 			status = modsin_location( node, info, level );
-		else if ( xml_tagexact( node, "physicalDescription" ) )
+		else if ( xml_tag_matches( node, "physicalDescription" ) )
 			status = modsin_description( node, info, level );
-		else if ( xml_tag_attrib( node, "relatedItem", "type", "host" ) ||
-			  xml_tag_attrib( node, "relatedItem", "type", "series" ) ) {
+		else if ( xml_tag_has_attribute( node, "relatedItem", "type", "host" ) ||
+			  xml_tag_has_attribute( node, "relatedItem", "type", "series" ) ) {
 			if ( node->down ) status = modsin_mods( node->down, info, level+1 );
 		}
-		else if ( xml_tag_attrib( node, "relatedItem", "type", "original" ) ) {
+		else if ( xml_tag_has_attribute( node, "relatedItem", "type", "original" ) ) {
 			if ( node->down ) status = modsin_mods( node->down, info, LEVEL_ORIG );
 		}
 
@@ -1031,7 +1047,7 @@
 modsin_assembleref( xml *node, fields *info )
 {
 	int status = BIBL_OK;
-	if ( xml_tagexact( node, "mods" ) ) {
+	if ( xml_tag_matches( node, "mods" ) ) {
 		status = modsin_id1( node, info, 0 );
 		if ( status!=BIBL_OK ) return status;
 		if ( node->down ) {
@@ -1053,7 +1069,7 @@
 	xml top;
 
 	xml_init( &top );
-	xml_tree( data, &top );
+	xml_parse( data, &top );
 	status = modsin_assembleref( &top, modsin );
 	xml_free( &top );
 
@@ -1069,12 +1085,12 @@
 modsin_startptr( char *p )
 {
 	char *startptr;
-	startptr = xml_findstart( p, "mods:mods" );
+	startptr = xml_find_start( p, "mods:mods" );
 	if ( startptr ) {
 		/* set namespace if found */
 		xml_pns = modsns;
 	} else {
-		startptr = xml_findstart( p, "mods" );
+		startptr = xml_find_start( p, "mods" );
 		if ( startptr ) xml_pns = NULL;
 	}
 	return startptr;
@@ -1083,7 +1099,7 @@
 static char *
 modsin_endptr( char *p )
 {
-	return xml_findend( p, "mods" );
+	return xml_find_end( p, "mods" );
 }
 
 static int
diff --git a/bibutils/modsout.c b/bibutils/modsout.c
--- a/bibutils/modsout.c
+++ b/bibutils/modsout.c
@@ -1,7 +1,7 @@
 /*
  * modsout.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
@@ -18,7 +18,8 @@
 #include "iso639_2.h"
 #include "utf8.h"
 #include "modstypes.h"
-#include "marc.h"
+#include "bu_auth.h"
+#include "marc_auth.h"
 #include "bibformats.h"
 
 static void modsout_writeheader( FILE *outptr, param *p );
@@ -171,7 +172,7 @@
 
 	for ( i=0; i<nparts; ++i ) {
 		parts[i].pos = fields_find( f, parts[i].internal, level );
-		n += ( parts[i].pos!=-1 );
+		n += ( parts[i].pos!=FIELDS_NOTFOUND );
 	}
 
 	return n;
@@ -196,9 +197,9 @@
 	output_tag( outptr, lvl2indent(level),               "titleInfo", NULL,      TAG_CLOSE,     TAG_NEWLINE, NULL );
 
 	/* output shorttitle if it's different from normal title */
-	if ( shrttl!=-1 ) {
+	if ( shrttl!=FIELDS_NOTFOUND ) {
 		val = (char *) fields_value( f, shrttl, FIELDS_CHRP );
-		if ( ttl==-1 || subttl!=-1 || strcmp(f->data[ttl].data,val) ) {
+		if ( ttl==FIELDS_NOTFOUND || subttl!=FIELDS_NOTFOUND || strcmp(f->data[ttl].data,val) ) {
 			output_tag( outptr, lvl2indent(level),               "titleInfo", NULL, TAG_OPEN,      TAG_NEWLINE, "type", "abbreviated", NULL );
 			output_tag( outptr, lvl2indent(incr_level(level,1)), "title",     val,  TAG_OPENCLOSE, TAG_NEWLINE, NULL );
 			output_tag( outptr, lvl2indent(level),               "titleInfo", NULL, TAG_CLOSE,     TAG_NEWLINE, NULL );
@@ -376,7 +377,7 @@
 			datepos[i] = fields_find( f, src_names[i], level );
 		else
 			datepos[i] = fields_find( f, alt_names[i], level );
-		if ( datepos[i]!=-1 ) found = 1;
+		if ( datepos[i]!=FIELDS_NOTFOUND ) found = 1;
 	}
 
 	return found;
@@ -528,7 +529,7 @@
 {
 	int n;
 	n = fields_find( f, "LANGUAGE", level );
-	if ( n!=-1 )
+	if ( n!=FIELDS_NOTFOUND )
 		output_language_core( f, n, outptr, "language", level );
 }
 
@@ -539,7 +540,7 @@
 	int n;
 
 	n = fields_find( f, "DESCRIPTION", level );
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		val = ( char * ) fields_value( f, n, FIELDS_CHRP );
 		output_tag( outptr, lvl2indent(level),               "physicalDescription", NULL, TAG_OPEN,      TAG_NEWLINE, NULL );
 		output_tag( outptr, lvl2indent(incr_level(level,1)), "note",                val,  TAG_OPENCLOSE, TAG_NEWLINE, NULL );
@@ -554,7 +555,7 @@
 	int n;
 
 	n = fields_find( f, "CONTENTS", level );
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		val = (char *) fields_value( f, n, FIELDS_CHRP );
 		output_tag( outptr, lvl2indent(level), "tableOfContents", val, TAG_OPENCLOSE, TAG_NEWLINE, NULL );
 	}
@@ -742,7 +743,7 @@
 {
 	int n;
 	n = fields_find( f, "LANGCATALOG", level );
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		output_tag( outptr, lvl2indent(level), "recordInfo", NULL, TAG_OPEN, TAG_NEWLINE, NULL );
 		output_language_core( f, n, outptr, "languageOfCataloging", incr_level(level,1) );
 		output_tag( outptr, lvl2indent(level), "recordInfo", NULL, TAG_CLOSE, TAG_NEWLINE, NULL );
@@ -752,20 +753,27 @@
 /* output_genre()
  *
  * <genre authority="marcgt">thesis</genre>
- * <genre>Diploma thesis</genre>
+ * <genre authority="bibutilsgt">Diploma thesis</genre>
  */
 static void
 output_genre( fields *f, FILE *outptr, int level )
 {
-	char *value, *attr, *attrvalue="marcgt";
+	char *value, *attr = NULL, *attrvalue = NULL;
 	int i, n;
 
 	n = fields_num( f );
 	for ( i=0; i<n; ++i ) {
 		if ( fields_level( f, i ) != level ) continue;
-		if ( !fields_match_tag( f, i, "GENRE" ) && !fields_match_tag( f, i, "NGENRE" ) ) continue;
+		if ( !fields_match_tag( f, i, "GENRE:MARC" ) && !fields_match_tag( f, i, "GENRE:BIBUTILS" ) && !fields_match_tag( f, i, "GENRE:UNKNOWN" ) ) continue;
 		value = fields_value( f, i, FIELDS_CHRP );
-		attr = ( marc_findgenre( value ) == -1 ) ? NULL : "authority";
+		if ( is_marc_genre( value ) ) {
+			attr      = "authority";
+			attrvalue = "marcgt";
+		}
+		else if ( is_bu_genre( value ) ) {
+			attr      = "authority";
+			attrvalue = "bibutilsgt";
+		}
 		output_tag( outptr, lvl2indent(level), "genre", value, TAG_OPENCLOSE, TAG_NEWLINE, attr, attrvalue, NULL );
 	}
 }
@@ -781,9 +789,9 @@
 	int n;
 
 	n = fields_find( f, "RESOURCE", level );
-	if ( n!=-1 ) {
+	if ( n!=FIELDS_NOTFOUND ) {
 		value = fields_value( f, n, FIELDS_CHRP );
-		if ( marc_findresource( value )!=-1 ) {
+		if ( is_marc_resource( value ) ) {
 			output_fil( outptr, lvl2indent(level), "typeOfResource", f, n, TAG_OPENCLOSE, TAG_NEWLINE, NULL );
 		} else {
 			fprintf( stderr, "Illegal typeofResource = '%s'\n", value );
@@ -797,8 +805,8 @@
 	int n;
 
 	/* silence warnings about INTERNAL_TYPE being unused */
-	n = fields_find( f, "INTERNAL_TYPE", 0 );
-	if ( n!=-1 ) fields_setused( f, n );
+	n = fields_find( f, "INTERNAL_TYPE", LEVEL_MAIN );
+	if ( n!=FIELDS_NOTFOUND ) fields_setused( f, n );
 
 	output_resource( f, outptr, level );
 	output_genre( f, outptr, level );
@@ -937,7 +945,7 @@
 	int pdflink    = fields_find( f, "PDFLINK",    level );
 	int i, n;
 
-	if ( url==-1 && location==-1 && pdflink==-1 && fileattach==-1 ) return;
+	if ( url==FIELDS_NOTFOUND && location==FIELDS_NOTFOUND && pdflink==FIELDS_NOTFOUND && fileattach==FIELDS_NOTFOUND ) return;
 	output_tag( outptr, lvl2indent(level), "location", NULL, TAG_OPEN, TAG_NEWLINE, NULL );
 
 	n = fields_num( f );
@@ -987,8 +995,8 @@
 	int n;
 	fprintf( outptr, "<mods");
 	if ( !dropkey ) {
-		n = fields_find( f, "REFNUM", 0 );
-		if ( n!=-1 ) {
+		n = fields_find( f, "REFNUM", LEVEL_MAIN );
+		if ( n!=FIELDS_NOTFOUND ) {
 			fprintf( outptr, " ID=\"");
 			output_refnum( f, n, outptr );
 			fprintf( outptr, "\"");
diff --git a/bibutils/modstypes.c b/bibutils/modstypes.c
--- a/bibutils/modstypes.c
+++ b/bibutils/modstypes.c
@@ -1,7 +1,7 @@
 /*
  * modstypes.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *      
diff --git a/bibutils/modstypes.h b/bibutils/modstypes.h
--- a/bibutils/modstypes.h
+++ b/bibutils/modstypes.h
@@ -1,7 +1,7 @@
 /*
  * modstypes.h
  *
- * Copyright (c) Chris Putnam 2008-2017
+ * Copyright (c) Chris Putnam 2008-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/name.c b/bibutils/name.c
--- a/bibutils/name.c
+++ b/bibutils/name.c
@@ -3,7 +3,7 @@
  *
  * mangle names w/ and w/o commas
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
@@ -41,7 +41,7 @@
 		nch = 0;
 		if ( nseps==1 ) {
 			if ( suffix ) {
-				str_addchar( s, ' ' );
+				str_strcatc( s, " " );
 				str_strcatc( s, suffix+2 );
 			}
 			str_addchar( s, ',' );
@@ -114,16 +114,16 @@
 	suffix_value_t suffixes[] = {
 		{ "Jr."   ,   JUNIOR              },
 		{ "Jr"    ,   JUNIOR              },
-		{ "Jr.,"  ,   JUNIOR | WITHCOMMA },
-		{ "Jr,"   ,   JUNIOR | WITHCOMMA },
+		{ "Jr.,"  ,   JUNIOR | WITHCOMMA  },
+		{ "Jr,"   ,   JUNIOR | WITHCOMMA  },
 		{ "Sr."   ,   SENIOR              },
 		{ "Sr"    ,   SENIOR              },
-		{ "Sr.,"  ,   SENIOR | WITHCOMMA },
-		{ "Sr,"   ,   SENIOR | WITHCOMMA },
+		{ "Sr.,"  ,   SENIOR | WITHCOMMA  },
+		{ "Sr,"   ,   SENIOR | WITHCOMMA  },
 		{ "III"   ,   THIRD               },
-		{ "III,"  ,   THIRD  | WITHCOMMA },
+		{ "III,"  ,   THIRD  | WITHCOMMA  },
 		{ "IV"    ,   FOURTH              },
-		{ "IV,"   ,   FOURTH | WITHCOMMA },
+		{ "IV,"   ,   FOURTH | WITHCOMMA  },
 	};
 	int i, nsuffixes = sizeof( suffixes ) / sizeof( suffixes[0] );
 	for ( i=0; i<nsuffixes; ++i ) {
@@ -411,8 +411,8 @@
 int
 name_parse( str *outname, str *inname, slist *asis, slist *corps )
 {
+	int status, ret = 1;
 	slist tokens;
-	int ret = 1;
 
 	str_empty( outname );
 	if ( !inname || !inname->len ) return ret;
@@ -430,7 +430,12 @@
 	}
 
 	str_findreplace( inname, ",", ", " );
-	slist_tokenize( &tokens, inname, " ", 1 );
+	status = slist_tokenize( &tokens, inname, " ", 1 );
+	if ( status!=SLIST_OK ) {
+		str_strcpy( outname, inname );
+		ret = 2;
+		goto out;
+	}
 
 	if ( tokens.n==1 ) {
 		str_strcpy( outname, inname );
diff --git a/bibutils/name.h b/bibutils/name.h
--- a/bibutils/name.h
+++ b/bibutils/name.h
@@ -3,7 +3,7 @@
  *
  * mangle names w/ and w/o commas
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/nbibin.c b/bibutils/nbibin.c
--- a/bibutils/nbibin.c
+++ b/bibutils/nbibin.c
@@ -1,7 +1,7 @@
 /*
  * nbibin.c
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Source code released under the GPL version 2
  *
@@ -261,7 +261,7 @@
 	vplist a;
 
 	nrefname  = fields_find( nbib, "PMID", LEVEL_MAIN );
-	if ( nrefname!=-1 ) refname = fields_value( nbib, nrefname, FIELDS_CHRP_NOUSE );
+	if ( nrefname!=FIELDS_NOTFOUND ) refname = fields_value( nbib, nrefname, FIELDS_CHRP_NOUSE );
 
 	vplist_init( &a );
 
diff --git a/bibutils/nbibtypes.c b/bibutils/nbibtypes.c
--- a/bibutils/nbibtypes.c
+++ b/bibutils/nbibtypes.c
@@ -1,7 +1,7 @@
 /*
  * nbibtypes.c
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Program and source code released under the GPL version 2
  *
@@ -47,12 +47,12 @@
 	{ "AID",    "DOI",                DOI,    LEVEL_MAIN }, /* Article ID? -- can be DOI/PII */
 	{ "PST",    "",                   SKIP,   LEVEL_MAIN },
 	{ "SO",     "",                   SKIP,   LEVEL_MAIN },
-	{ " ",      "INTERNAL_TYPE|ARTICLE",  ALWAYS, LEVEL_MAIN },
-	{ " ",      "ISSUANCE|continuing",    ALWAYS, LEVEL_HOST },
-	{ " ",      "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-	{ " ",      "GENRE|journal article",  ALWAYS, LEVEL_MAIN },
-	{ " ",      "GENRE|periodical",       ALWAYS, LEVEL_HOST },
-	{ " ",      "GENRE|academic journal", ALWAYS, LEVEL_HOST }
+	{ " ",      "INTERNAL_TYPE|ARTICLE",   ALWAYS, LEVEL_MAIN },
+	{ " ",      "ISSUANCE|continuing",     ALWAYS, LEVEL_HOST },
+	{ " ",      "RESOURCE|text",           ALWAYS, LEVEL_MAIN },
+	{ " ",      "GENRE:BIBUTILS|journal article",  ALWAYS, LEVEL_MAIN },
+	{ " ",      "GENRE:MARC|periodical",        ALWAYS, LEVEL_HOST },
+	{ " ",      "GENRE:BIBUTILS|academic journal", ALWAYS, LEVEL_HOST }
 };
 
 #define ORIG(a) ( &(a[0]) )
diff --git a/bibutils/notes.c b/bibutils/notes.c
--- a/bibutils/notes.c
+++ b/bibutils/notes.c
@@ -1,7 +1,7 @@
 /*
  * notes.c
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Program and source code released under the GPL version 2
  *
diff --git a/bibutils/notes.h b/bibutils/notes.h
--- a/bibutils/notes.h
+++ b/bibutils/notes.h
@@ -1,7 +1,7 @@
 /*
  * notes.h
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/pages.c b/bibutils/pages.c
--- a/bibutils/pages.c
+++ b/bibutils/pages.c
@@ -1,7 +1,7 @@
 /*
  * pages.c
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Program and source code released under GPL verison 2
  */
diff --git a/bibutils/pages.h b/bibutils/pages.h
--- a/bibutils/pages.h
+++ b/bibutils/pages.h
@@ -1,7 +1,7 @@
 /*
  * pages.h
  *
- * Copyright (c) Chris Putnam 2016-2017
+ * Copyright (c) Chris Putnam 2016-2018
  *
  * Program and source code released under the GPL version 2
  */
diff --git a/bibutils/reftypes.c b/bibutils/reftypes.c
--- a/bibutils/reftypes.c
+++ b/bibutils/reftypes.c
@@ -1,7 +1,7 @@
 /*
  * reftypes.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/reftypes.h b/bibutils/reftypes.h
--- a/bibutils/reftypes.h
+++ b/bibutils/reftypes.h
@@ -1,7 +1,7 @@
 /*
  * reftypes.h
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
@@ -31,8 +31,8 @@
 #define LINKEDFILE      (12)
 #define KEYWORD         (13)
 #define URL             (14)
-#define BT_SENTE        (15) /* Bibtex 'Sente' */
-#define BT_GENRE        (16) /* Bibtex Genre */
+#define GENRE           (15)
+#define BT_SENTE        (16) /* Bibtex 'Sente' */
 #define BT_EPRINT       (17) /* Bibtex 'Eprint' */
 #define BT_ORG          (18) /* Bibtex Organization */
 #define BLT_THESIS_TYPE (19) /* Biblatex Thesis Type */
diff --git a/bibutils/risin.c b/bibutils/risin.c
--- a/bibutils/risin.c
+++ b/bibutils/risin.c
@@ -1,7 +1,7 @@
 /*
  * risin.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
@@ -316,8 +316,8 @@
 
 	ntypename = fields_find( risin, "TY", LEVEL_MAIN );
 	nrefname  = fields_find( risin, "ID", LEVEL_MAIN );
-	if ( ntypename!=-1 ) typename = fields_value( risin, ntypename, FIELDS_CHRP_NOUSE );
-	if ( nrefname!=-1 )  refname  = fields_value( risin, nrefname,  FIELDS_CHRP_NOUSE );
+	if ( ntypename!=FIELDS_NOTFOUND ) typename = fields_value( risin, ntypename, FIELDS_CHRP_NOUSE );
+	if ( nrefname!=FIELDS_NOTFOUND )  refname  = fields_value( risin, nrefname,  FIELDS_CHRP_NOUSE );
 
 	return get_reftype( typename, nref, p->progname, p->all, p->nall, refname, &is_default, REFTYPE_CHATTY );
 }
@@ -490,7 +490,7 @@
 		     !strcasecmp(value,"Diploma Thesis")||
 		     !strcasecmp(value,"Doctoral Thesis")||
 		     !strcasecmp(value,"Habilitation Thesis")) {
-			fstatus = fields_add( bibout, "GENRE", value, 0 );
+			fstatus = fields_add( bibout, "GENRE:BIBUTILS", value, 0 );
 			if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
 		}
 	}
@@ -513,10 +513,11 @@
 		[ 0 ... NUM_REFTYPES-1 ] = generic_null,
 		[ SIMPLE       ] = generic_simple,
 		[ TITLE        ] = generic_title,
-		[ PERSON       ] = risin_person,
 		[ SERIALNO     ] = generic_serialno,
 		[ NOTES        ] = generic_notes,
 		[ URL          ] = generic_url,
+		[ GENRE        ] = generic_genre,
+		[ PERSON       ] = risin_person,
 		[ DATE         ] = risin_date,
 		[ DOI          ] = risin_doi,
 		[ LINKEDFILE   ] = risin_linkedfile,
diff --git a/bibutils/risout.c b/bibutils/risout.c
--- a/bibutils/risout.c
+++ b/bibutils/risout.c
@@ -1,7 +1,7 @@
 /*
  * risout.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
@@ -180,6 +180,7 @@
 		{ "Doctoral thesis",           TYPE_DOCTORALTHESIS },
 		{ "Habilitation thesis",       TYPE_HABILITATIONTHESIS },
 		{ "report",                    TYPE_REPORT },
+		{ "technical report",          TYPE_REPORT },
 		{ "abstract or summary",       TYPE_ABSTRACT },
 		{ "patent",                    TYPE_PATENT },
 		{ "unpublished",               TYPE_UNPUBLISHED },
@@ -193,7 +194,7 @@
 
 	for ( i=0; i<fields_num( f ); ++i ) {
 		tag = ( char * ) fields_tag( f, i, FIELDS_CHRP );
-		if ( strcmp( tag, "GENRE" ) && strcmp( tag, "NGENRE" ) ) continue;
+		if ( strcmp( tag, "GENRE:MARC" ) && strcmp( tag, "GENRE:BIBUTILS" ) && strcmp( tag, "GENRE:UNKNOWN") ) continue;
 		value = ( char * ) fields_value( f, i, FIELDS_CHRP );
 		for ( j=0; j<nmatch_genres; ++j )
 			if ( !strcasecmp( match_genres[j].name, value ) )
diff --git a/bibutils/ristypes.c b/bibutils/ristypes.c
--- a/bibutils/ristypes.c
+++ b/bibutils/ristypes.c
@@ -1,7 +1,7 @@
 /*
  * ristypes.c
  *
- * Copyright (c) Chris Putnam 2003-2017
+ * Copyright (c) Chris Putnam 2003-2018
  *
  * Source code released under the GPL version 2
  *
@@ -159,12 +159,12 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_MAIN },   /* Deprecated? */
 	{ "Y1", "PARTDATE:YEAR",DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "PARTDATE:MONTH",SIMPLE, LEVEL_MAIN },   /* Access Date */
-	{ "  ", "INTERNAL_TYPE|ARTICLE",  ALWAYS, LEVEL_MAIN },
-	{ "  ", "ISSUANCE|continuing",    ALWAYS, LEVEL_HOST },
-	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|journal article",  ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|periodical",       ALWAYS, LEVEL_HOST },
-	{ "  ", "GENRE|academic journal", ALWAYS, LEVEL_HOST }
+	{ "  ", "INTERNAL_TYPE|ARTICLE",           ALWAYS, LEVEL_MAIN },
+	{ "  ", "ISSUANCE|continuing",             ALWAYS, LEVEL_HOST },
+	{ "  ", "RESOURCE|text",                   ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:BIBUTILS|journal article",  ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|periodical",           ALWAYS, LEVEL_HOST },
+	{ "  ", "GENRE:BIBUTILS|academic journal", ALWAYS, LEVEL_HOST }
 };
 
 /* magazine article */
@@ -240,10 +240,10 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_MAIN },   /* Deprecated? */
 	{ "Y1", "PARTDATE:YEAR",DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "PARTDATE:MONTH",SIMPLE, LEVEL_MAIN },   /* Access Date */
-	{ "  ", "ISSUANCE|continuing",    ALWAYS, LEVEL_HOST },
-	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|periodical",       ALWAYS, LEVEL_HOST },
-	{ "  ", "GENRE|magazine",         ALWAYS, LEVEL_HOST }
+	{ "  ", "ISSUANCE|continuing",     ALWAYS, LEVEL_HOST },
+	{ "  ", "RESOURCE|text",           ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|periodical",   ALWAYS, LEVEL_HOST },
+	{ "  ", "GENRE:BIBUTILS|magazine", ALWAYS, LEVEL_HOST }
 };
 
 static lookups newsarticle[] = {
@@ -321,7 +321,7 @@
 	{ "  ", "INTERNAL_TYPE|NEWSARTICLE", ALWAYS, LEVEL_MAIN },
 	{ "  ", "ISSUANCE|continuing",       ALWAYS, LEVEL_HOST },
 	{ "  ", "RESOURCE|text",             ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|newspaper",           ALWAYS, LEVEL_HOST }
+	{ "  ", "GENRE:MARC|newspaper",           ALWAYS, LEVEL_HOST }
 };
 
 static lookups book[] = {
@@ -398,7 +398,7 @@
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ "  ", "ISSUANCE|monographic",   ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|book",             ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|book",             ALWAYS, LEVEL_MAIN },
 	{ "  ", "RESOURCE|text",          ALWAYS, LEVEL_MAIN }
 };
 
@@ -475,8 +475,8 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_HOST },   /* Deprecated? */
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_HOST },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_HOST },   /* Access Date */
-	{ "  ", "GENRE|book chapter",   ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|book",           ALWAYS, LEVEL_HOST },
+	{ "  ", "GENRE:BIBUTILS|book chapter",   ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|book",           ALWAYS, LEVEL_HOST },
 	{ "  ", "ISSUANCE|monographic", ALWAYS, LEVEL_HOST },
 	{ "  ", "RESOURCE|text",        ALWAYS, LEVEL_MAIN }
 };
@@ -556,7 +556,7 @@
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_HOST },   /* Access Date */
 	{ "  ", "INTERNAL_TYPE|CONFERENCE",     ALWAYS, LEVEL_MAIN },
 	{ "  ", "RESOURCE|text",                ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|conference publication", ALWAYS, LEVEL_HOST }
+	{ "  ", "GENRE:MARC|conference publication", ALWAYS, LEVEL_HOST }
 };
 
 static lookups statute[] = {
@@ -634,7 +634,7 @@
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ "  ", "INTERNAL_TYPE|STATUTE", ALWAYS, LEVEL_MAIN },
 	{ "  ", "RESOURCE|text",         ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|legislation",     ALWAYS, LEVEL_MAIN }
+	{ "  ", "GENRE:MARC|legislation",     ALWAYS, LEVEL_MAIN }
 };
 
 static lookups hearing[] = {
@@ -711,7 +711,7 @@
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ "  ", "INTERNAL_TYPE|HEARING", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|hearing",         ALWAYS, LEVEL_MAIN }
+	{ "  ", "GENRE:BIBUTILS|hearing",         ALWAYS, LEVEL_MAIN }
 };
 
 static lookups cases[] = {
@@ -788,7 +788,7 @@
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ "  ", "INTERNAL_TYPE|CASE",              ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|legal case and case notes", ALWAYS, LEVEL_MAIN }
+	{ "  ", "GENRE:MARC|legal case and case notes", ALWAYS, LEVEL_MAIN }
 };
 
 static lookups communication[] = {
@@ -833,7 +833,7 @@
 	{ "L4", "FIGATTACH",    LINKEDFILE,  LEVEL_MAIN },   /* Figure Attachment (local, not URL) */
 	{ "LA", "LANGUAGE",     SIMPLE,  LEVEL_MAIN },   /* Language */
 	{ "LB", "LABEL",        SIMPLE,  LEVEL_MAIN },   /* Label */
-	{ "M1", "GENRE",        SIMPLE,  LEVEL_MAIN },   /* Misc or Number? */
+	{ "M1", "GENRE:UKNOWN", GENRE,   LEVEL_MAIN },   /* Misc or Number? */
 	{ "M2", "NOTES",        NOTES,   LEVEL_MAIN },   /* Misc or Deprecated? */
 	{ "M3", "NOTES",        NOTES,   LEVEL_MAIN },   /* Misc or Type of Work? */
 	{ "N1", "NOTES",        NOTES,   LEVEL_MAIN },   /* Notes */
@@ -864,8 +864,8 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_MAIN },   /* Deprecated? */
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
-	{ "  ", "INTERNAL_TYPE|ARTICLE", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|communication",   ALWAYS, LEVEL_MAIN }
+	{ "  ", "INTERNAL_TYPE|ARTICLE",          ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:BIBUTILS|communication",   ALWAYS, LEVEL_MAIN }
 };
 
 static lookups thesis[] = {
@@ -943,7 +943,7 @@
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ "  ", "INTERNAL_TYPE|THESIS",  ALWAYS,  LEVEL_MAIN },
 	{ "  ", "RESOURCE|text",         ALWAYS,  LEVEL_MAIN },
-	{ "  ", "GENRE|thesis",          ALWAYS,  LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|thesis",          ALWAYS,  LEVEL_MAIN },
 };
 
 static lookups report[] = {
@@ -1019,9 +1019,9 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_MAIN },   /* Deprecated? */
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
-	{ "  ", "INTERNAL_TYPE|REPORT",  ALWAYS,  LEVEL_MAIN },
-	{ "  ", "RESOURCE|text",         ALWAYS,  LEVEL_MAIN },
-	{ "  ", "GENRE|report",          ALWAYS,  LEVEL_MAIN }
+	{ "  ", "INTERNAL_TYPE|REPORT",        ALWAYS, LEVEL_MAIN },
+	{ "  ", "RESOURCE|text",               ALWAYS, LEVEL_MAIN },
+	{ "  ", "GENRE:MARC|technical report", ALWAYS, LEVEL_MAIN }
 };
 
 static lookups abstract[] = {
@@ -1097,7 +1097,7 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_MAIN },   /* Deprecated? */
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
-	{ "  ", "GENRE|abstract or summary", ALWAYS,  LEVEL_MAIN }
+	{ "  ", "GENRE:MARC|abstract or summary", ALWAYS,  LEVEL_MAIN }
 };
 
 static lookups program[] = {
@@ -1250,7 +1250,7 @@
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ "  ", "RESOURCE|text", ALWAYS, LEVEL_MAIN },
-	{ "  ", "GENRE|patent",  ALWAYS, LEVEL_MAIN }
+	{ "  ", "GENRE:MARC|patent",  ALWAYS, LEVEL_MAIN }
 };
 
 static lookups electric[] = {
@@ -1327,7 +1327,7 @@
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ " ",  "RESOURCE|software, multimedia", ALWAYS, LEVEL_MAIN },
-	{ " ",  "GENRE|electronic",              ALWAYS, LEVEL_MAIN },
+	{ " ",  "GENRE:MARC|electronic",              ALWAYS, LEVEL_MAIN },
 };
 
 static lookups pamphlet[] = {
@@ -1404,7 +1404,7 @@
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
 	{ " ",  "RESOURCE|text",  ALWAYS, LEVEL_MAIN },
-	{ " ",  "GENRE|pamphlet", ALWAYS, LEVEL_MAIN },
+	{ " ",  "GENRE:BIBUTILS|pamphlet", ALWAYS, LEVEL_MAIN },
 };
 
 static lookups map[] = {
@@ -1480,8 +1480,8 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_MAIN },   /* Deprecated? */
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated? */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
-	{ " ",  "RESOURCE|cartographic",   ALWAYS, LEVEL_MAIN },
-	{ " ",  "GENRE|map",               ALWAYS, LEVEL_MAIN }
+	{ " ",  "RESOURCE|cartographic", ALWAYS, LEVEL_MAIN },
+	{ " ",  "GENRE:MARC|map",        ALWAYS, LEVEL_MAIN }
 };
 
 static lookups unpublished[] = {
@@ -1557,8 +1557,8 @@
 	{ "VO", "VOLUME",       SIMPLE,  LEVEL_MAIN },   /* Deprecated? */
 	{ "Y1", "DATE:YEAR",    DATE,    LEVEL_MAIN },   /* Deprecated */
 	{ "Y2", "DATE:MONTH",   SIMPLE,  LEVEL_MAIN },   /* Access Date */
-	{ " ",  "RESOURCE|text",     ALWAYS, LEVEL_MAIN },
-	{ " ",  "GENRE|unpublished", ALWAYS, LEVEL_MAIN }
+	{ " ",  "RESOURCE|text",              ALWAYS, LEVEL_MAIN },
+	{ " ",  "GENRE:BIBUTILS|unpublished", ALWAYS, LEVEL_MAIN }
 };
 
 #define ORIG(a) ( &(a[0]) )
diff --git a/bibutils/serialno.c b/bibutils/serialno.c
--- a/bibutils/serialno.c
+++ b/bibutils/serialno.c
@@ -1,7 +1,7 @@
 /*
  * serialno.c
  *
- * Copyright (c) Chris Putnam 2005-2017
+ * Copyright (c) Chris Putnam 2005-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/serialno.h b/bibutils/serialno.h
--- a/bibutils/serialno.h
+++ b/bibutils/serialno.h
@@ -1,7 +1,7 @@
 /*
  * serialno.h
  *
- * Copyright (c) Chris Putnam 2005-2017
+ * Copyright (c) Chris Putnam 2005-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/slist.c b/bibutils/slist.c
--- a/bibutils/slist.c
+++ b/bibutils/slist.c
@@ -1,9 +1,9 @@
 /*
  * slist.c
  *
- * version: 2017-07-04
+ * version: 2017-11-14
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
@@ -319,7 +319,7 @@
 }
 
 str *
-slist_addvp( slist *a, unsigned char mode, void *vp )
+slist_addvp( slist *a, int mode, void *vp )
 {
 	str *s = NULL;
 	int status;
@@ -358,7 +358,7 @@
 }
 
 str *
-slist_addvp_unique( slist *a, unsigned char mode, void *vp )
+slist_addvp_unique( slist *a, int mode, void *vp )
 {
 	str *s;
 	int n;
@@ -387,7 +387,7 @@
 }
 
 int
-slist_addvp_all( slist *a, unsigned char mode, ... )
+slist_addvp_all( slist *a, int mode, ... )
 {
 	int ret = SLIST_OK;
 	va_list ap;
diff --git a/bibutils/slist.h b/bibutils/slist.h
--- a/bibutils/slist.h
+++ b/bibutils/slist.h
@@ -1,9 +1,9 @@
 /*
  * slist.h
  *
- * version: 2017-07-04
+ * version: 2017-11-14
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
@@ -54,15 +54,15 @@
 int     slist_copy( slist *to, slist *from );
 void    slist_swap( slist *a, slist_index n1, slist_index n2 );
 
-str *   slist_addvp( slist *a, unsigned char mode, void *vp );
+str *   slist_addvp( slist *a, int mode, void *vp );
 str *   slist_addc( slist *a, const char *value );
 str *   slist_add( slist *a, str *value );
 
-int     slist_addvp_all( slist *a, unsigned char mode, ... );
+int     slist_addvp_all( slist *a, int mode, ... );
 int     slist_addc_all( slist *a, ... );
 int     slist_add_all( slist *a, ... );
 
-str *   slist_addvp_unique( slist *a, unsigned char mode, void *vp );
+str *   slist_addvp_unique( slist *a, int mode, void *vp );
 str *   slist_addc_unique( slist *a, const char *value );
 str *   slist_add_unique( slist *a, str *value );
 
diff --git a/bibutils/str.c b/bibutils/str.c
--- a/bibutils/str.c
+++ b/bibutils/str.c
@@ -3,7 +3,7 @@
  *
  * Version: 2017-07-03
  *
- * Copyright (c) Chris Putnam 1999-2017
+ * Copyright (c) Chris Putnam 1999-2018
  *
  * Source code released under the GPL version 2
  *
@@ -43,7 +43,7 @@
 	if (size < minsize) size = minsize;
 	newptr = (char *) realloc( s->data, sizeof( *(s->data) )*size );
 	if ( !newptr ) {
-		fprintf(stderr,"Error.  Cannot reallocate memory (%ld bytes) in str_realloc.\n", sizeof(*(s->data))*size);
+		fprintf( stderr,"Error.  Cannot reallocate memory (%lu bytes) in str_realloc.\n", sizeof(*(s->data))*size );
 		exit( EXIT_FAILURE );
 	}
 	s->data = newptr;
@@ -65,8 +65,7 @@
 	if ( size < minsize ) size = minsize;
 	newptr = (char *) malloc( sizeof( *(s->data) ) * size );
 	if ( !newptr ) {
-		fprintf( stderr, "Error.  Cannot reallocate memory (%d bytes)"
-			" in str_realloc.\n", sizeof(*(s->data))*size );
+		fprintf( stderr, "Error.  Cannot reallocate memory (%lu bytes) in str_realloc.\n", sizeof(*(s->data))*size );
 		exit( EXIT_FAILURE );
 	}
 	if ( s->data ) {
@@ -174,7 +173,7 @@
 	if ( minsize > str_initlen ) size = minsize;
 	s->data = (char *) malloc (sizeof( *(s->data) ) * size);
 	if ( !s->data ) {
-		fprintf(stderr,"Error.  Cannot allocate memory in str_initalloc.\n");
+		fprintf(stderr,"Error.  Cannot allocate memory in str_initalloc, requested %lu characters.\n", size );
 		exit( EXIT_FAILURE );
 	}
 	s->data[0]='\0';
diff --git a/bibutils/str.h b/bibutils/str.h
--- a/bibutils/str.h
+++ b/bibutils/str.h
@@ -3,7 +3,7 @@
  *
  * Version: 2017-07-03
  *
- * Copyright (c) Chris Putnam 1999-2017
+ * Copyright (c) Chris Putnam 1999-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/str_conv.c b/bibutils/str_conv.c
--- a/bibutils/str_conv.c
+++ b/bibutils/str_conv.c
@@ -1,7 +1,7 @@
 /*
  * str_conv.c
  *
- * Copyright (c) Chris Putnam 1999-2017
+ * Copyright (c) Chris Putnam 1999-2018
  *
  * Source code released under the GPL version 2
  *
@@ -24,7 +24,7 @@
 addentity( str *s, unsigned int ch )
 {
 	char buf[512];
-	sprintf( buf, "&#%d;", ch );
+	sprintf( buf, "&#%u;", ch );
 	str_strcatc( s, buf );
 }
 
@@ -176,7 +176,16 @@
 
 	if ( !s || s->len==0 ) return ok;
 
-	str_init( &ns );
+	/* Ensure that string is internally allocated.
+	 * This fixes NULL pointer derefernce in CVE-2018-10775 in bibutils
+	 * as a string with a valid data pointer is potentially replaced
+	 * by a string without a valid data pointer due to it being invalid
+	 * unicode.
+	 * This probably also fixes CVE-2018-10773 and CVE-2018-10774 which
+	 * are NULL dereferences also likely due to a fuzzer, but without
+	 * test cases in the report, I can't be completely sure.
+	 */
+	str_initstrc( &ns, "" );
 
 	if ( charsetin==CHARSET_UNKNOWN ) charsetin = CHARSET_DEFAULT;
 	if ( charsetout==CHARSET_UNKNOWN ) charsetout = CHARSET_DEFAULT;
@@ -193,4 +202,3 @@
 
 	return ok;
 }
-
diff --git a/bibutils/str_conv.h b/bibutils/str_conv.h
--- a/bibutils/str_conv.h
+++ b/bibutils/str_conv.h
@@ -1,7 +1,7 @@
 /*
  * str_conv.h
  *
- * Copyright (c) Chris Putnam 1999-2017
+ * Copyright (c) Chris Putnam 1999-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/strsearch.c b/bibutils/strsearch.c
--- a/bibutils/strsearch.c
+++ b/bibutils/strsearch.c
@@ -1,6 +1,6 @@
 /* strsearch.c
  *
- * Copyright (c) Chris Putnam 1995-2017
+ * Copyright (c) Chris Putnam 1995-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/strsearch.h b/bibutils/strsearch.h
--- a/bibutils/strsearch.h
+++ b/bibutils/strsearch.h
@@ -1,7 +1,7 @@
 /*
  * strsearch.h
  *
- * Copyright (c) Chris Putnam 1995-2017
+ * Copyright (c) Chris Putnam 1995-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/title.c b/bibutils/title.c
--- a/bibutils/title.c
+++ b/bibutils/title.c
@@ -3,7 +3,7 @@
  *
  * process titles into title/subtitle pairs for MODS
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/title.h b/bibutils/title.h
--- a/bibutils/title.h
+++ b/bibutils/title.h
@@ -3,7 +3,7 @@
  *
  * process titles into title/subtitle pairs for MODS
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL verison 2
  *
diff --git a/bibutils/unicode.h b/bibutils/unicode.h
--- a/bibutils/unicode.h
+++ b/bibutils/unicode.h
@@ -1,7 +1,7 @@
 /*
  * unicode.h
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Program and source code released under the GPL version 2
  */
diff --git a/bibutils/url.c b/bibutils/url.c
--- a/bibutils/url.c
+++ b/bibutils/url.c
@@ -9,7 +9,7 @@
  * is_doi()
  * Check for DOI buried in another field.
  *
- * Copyright (c) Chris Putnam 2008-2017
+ * Copyright (c) Chris Putnam 2008-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/url.h b/bibutils/url.h
--- a/bibutils/url.h
+++ b/bibutils/url.h
@@ -1,7 +1,7 @@
 /*
  * url.h
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/utf8.c b/bibutils/utf8.c
--- a/bibutils/utf8.c
+++ b/bibutils/utf8.c
@@ -1,7 +1,7 @@
 /*
  * utf8.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/utf8.h b/bibutils/utf8.h
--- a/bibutils/utf8.h
+++ b/bibutils/utf8.h
@@ -1,7 +1,7 @@
 /*
  * utf8.h
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/vplist.c b/bibutils/vplist.c
--- a/bibutils/vplist.c
+++ b/bibutils/vplist.c
@@ -3,7 +3,7 @@
  *
  * Version: 1/9/2017
  *
- * Copyright (c) Chris Putnam 2011-2017
+ * Copyright (c) Chris Putnam 2011-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/vplist.h b/bibutils/vplist.h
--- a/bibutils/vplist.h
+++ b/bibutils/vplist.h
@@ -5,7 +5,7 @@
  *
  * Version: 1/9/2017
  *
- * Copyright (c) Chris Putnam 2011-2017
+ * Copyright (c) Chris Putnam 2011-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/bibutils/wordin.c b/bibutils/wordin.c
--- a/bibutils/wordin.c
+++ b/bibutils/wordin.c
@@ -1,7 +1,7 @@
 /*
  * wordin.c
  *
- * Copyright (c) Chris Putnam 2010-2017
+ * Copyright (c) Chris Putnam 2010-2018
  *
  * Source code released under the GPL version 2
  *
@@ -61,15 +61,13 @@
 static char *
 wordin_findstartwrapper( char *buf, int *ntype )
 {
-	char *startptr = xml_findstart( buf, "b:Source" );
-	return startptr;
+	return xml_find_start( buf, "b:Source" );
 }
 
 static char *
 wordin_findendwrapper( char *buf, int ntype )
 {
-	char *endptr = xml_findend( buf, "b:Source" );
-	return endptr;
+	return xml_find_end( buf, "b:Source" );
 }
 
 static int
@@ -128,10 +126,10 @@
 static int
 wordin_person_last( xml *node, str *name )
 {
-	while ( node && !xml_tagexact( node, "b:Last" ) )
+	while ( node && !xml_tag_matches( node, "b:Last" ) )
 		node = node->next;
-	if ( node && str_has_value( node->value ) ) {
-		str_strcpyc( name, xml_value( node ) );
+	if ( xml_has_value( node ) ) {
+		str_strcpy( name, xml_value( node ) );
 		if ( str_memerr( name ) ) return BIBL_ERR_MEMERR;
 	}
 	return BIBL_OK;
@@ -148,10 +146,10 @@
 wordin_person_first( xml *node, str *name )
 {
 	for ( ; node; node=node->next ) {
-		if ( !xml_tagexact( node, "b:First" ) ) continue;
-		if ( str_has_value( node->value ) ) {
+		if ( !xml_tag_matches( node, "b:First" ) ) continue;
+		if ( xml_has_value( node ) ) {
 			if ( str_has_value( name ) ) str_addchar( name, '|' );
-			str_strcatc( name, xml_value( node ) );
+			str_strcat( name, xml_value( node ) );
 			if ( str_memerr( name ) ) return BIBL_ERR_MEMERR;
 		}
 	}
@@ -189,11 +187,11 @@
 wordin_people( xml *node, fields *info, char *type )
 {
 	int ret = BIBL_OK;
-	if ( xml_tagexact( node, "b:Author" ) && node->down ) {
+	if ( xml_tag_matches( node, "b:Author" ) && node->down ) {
 		ret = wordin_people( node->down, info, type );
-	} else if ( xml_tagexact( node, "b:NameList" ) && node->down ) {
+	} else if ( xml_tag_matches( node, "b:NameList" ) && node->down ) {
 		ret = wordin_people( node->down, info, type );
-	} else if ( xml_tagexact( node, "b:Person" ) ) {
+	} else if ( xml_tag_matches( node, "b:Person" ) ) {
 		if ( node->down ) ret = wordin_person( node->down, info, type );
 		if ( ret!=BIBL_OK ) return ret;
 		if ( node->next ) ret = wordin_people( node->next, info, type );
@@ -210,7 +208,7 @@
 
 	strs_init( &sp, &ep, NULL );
 
-	p = xml_value( node );
+	p = xml_value_cstr( node );
 	while ( *p && *p!='-' )
 		str_addchar( &sp, *p++ );
 	if ( str_memerr( &sp ) ) {
@@ -256,34 +254,34 @@
 wordin_reference( xml *node, fields *info )
 {
 	int status, ret = BIBL_OK;
-	if ( xml_hasvalue( node ) ) {
-		if ( xml_tagexact( node, "b:Tag" ) ) {
-			status = fields_add( info, "REFNUM", xml_value( node ), 0 );
+	if ( xml_has_value( node ) ) {
+		if ( xml_tag_matches( node, "b:Tag" ) ) {
+			status = fields_add( info, "REFNUM", xml_value_cstr( node ), 0 );
 			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-		} else if ( xml_tagexact( node, "b:SourceType" ) ) {
-		} else if ( xml_tagexact( node, "b:City" ) ) {
-			status = fields_add( info, "ADDRESS", xml_value( node ), 0 );
+		} else if ( xml_tag_matches( node, "b:SourceType" ) ) {
+		} else if ( xml_tag_matches( node, "b:City" ) ) {
+			status = fields_add( info, "ADDRESS", xml_value_cstr( node ), 0 );
 			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-		} else if ( xml_tagexact( node, "b:Publisher" ) ) {
-			status = fields_add( info, "PUBLISHER", xml_value( node ), 0 );
+		} else if ( xml_tag_matches( node, "b:Publisher" ) ) {
+			status = fields_add( info, "PUBLISHER", xml_value_cstr( node ), 0 );
 			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-		} else if ( xml_tagexact( node, "b:Title" ) ) {
-			status = fields_add( info, "TITLE", xml_value( node ), 0 );
+		} else if ( xml_tag_matches( node, "b:Title" ) ) {
+			status = fields_add( info, "TITLE", xml_value_cstr( node ), 0 );
 			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-		} else if ( xml_tagexact( node, "b:JournalName" ) ) {
-			status = fields_add( info, "TITLE", xml_value( node ), 1 );
+		} else if ( xml_tag_matches( node, "b:JournalName" ) ) {
+			status = fields_add( info, "TITLE", xml_value_cstr( node ), 1 );
 			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-		} else if ( xml_tagexact( node, "b:Volume" ) ) {
-			status = fields_add( info, "VOLUME", xml_value( node ), 1 );
+		} else if ( xml_tag_matches( node, "b:Volume" ) ) {
+			status = fields_add( info, "VOLUME", xml_value_cstr( node ), 1 );
 			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-		} else if ( xml_tagexact( node, "b:Comments" ) ) {
-			status = fields_add( info, "NOTES", xml_value( node ), 0 );
+		} else if ( xml_tag_matches( node, "b:Comments" ) ) {
+			status = fields_add( info, "NOTES", xml_value_cstr( node ), 0 );
 			if ( status!=FIELDS_OK ) ret = BIBL_ERR_MEMERR;
-		} else if ( xml_tagexact( node, "b:Pages" ) ) {
+		} else if ( xml_tag_matches( node, "b:Pages" ) ) {
 			ret = wordin_pages( node, info );
-		} else if ( xml_tagexact( node, "b:Author" ) && node->down ) {
+		} else if ( xml_tag_matches( node, "b:Author" ) && node->down ) {
 			ret = wordin_people( node->down, info, "AUTHOR" );
-		} else if ( xml_tagexact( node, "b:Editor" ) && node->down ) {
+		} else if ( xml_tag_matches( node, "b:Editor" ) && node->down ) {
 			ret = wordin_people( node->down, info, "EDITOR" );
 		}
 	}
@@ -295,9 +293,9 @@
 wordin_assembleref( xml *node, fields *info )
 {
 	int ret = BIBL_OK;
-	if ( xml_tagexact( node, "b:Source" ) ) {
+	if ( xml_tag_matches( node, "b:Source" ) ) {
 		if ( node->down ) ret = wordin_reference( node->down, info );
-	} else if ( str_is_empty( node->tag ) && node->down ) {
+	} else if ( str_is_empty( &(node->tag) ) && node->down ) {
 		ret = wordin_assembleref( node->down, info );
 	}
 	return ret;
@@ -310,7 +308,7 @@
 	xml top;
 
 	xml_init( &top );
-	xml_tree( data, &top );
+	xml_parse( data, &top );
 	status = wordin_assembleref( &top, wordin );
 	xml_free( &top );
 
diff --git a/bibutils/wordout.c b/bibutils/wordout.c
--- a/bibutils/wordout.c
+++ b/bibutils/wordout.c
@@ -3,7 +3,7 @@
  * 
  * (Word 2007 format)
  *
- * Copyright (c) Chris Putnam 2007-2017
+ * Copyright (c) Chris Putnam 2007-2018
  *
  * Source code released under the GPL version 2
  *
@@ -166,7 +166,7 @@
         int i, n;
         for ( i=0; i<nc; ++i ) {
                 n = fields_find( info, c[i].oldtag, c[i].code );
-                if ( n!=-1 ) output_item( info, outptr, c[i].newtag, c[i].prefix, n, 0 );
+                if ( n!=FIELDS_NOTFOUND ) output_item( info, outptr, c[i].newtag, c[i].prefix, n, 0 );
         }
 
 }
@@ -178,25 +178,26 @@
 
 static
 outtype genres[] = {
-	{ TYPE_PATENT, "patent" },
-	{ TYPE_REPORT, "report" },
-	{ TYPE_CASE,   "legal case and case notes" },
-	{ TYPE_ART,    "art original" },
-	{ TYPE_ART,    "art reproduction" },
-	{ TYPE_ART,    "comic strip" },
-	{ TYPE_ART,    "diorama" },
-	{ TYPE_ART,    "graphic" },
-	{ TYPE_ART,    "model" },
-	{ TYPE_ART,    "picture" },
+	{ TYPE_PATENT,           "patent" },
+	{ TYPE_REPORT,           "report" },
+	{ TYPE_REPORT,           "technical report" },
+	{ TYPE_CASE,             "legal case and case notes" },
+	{ TYPE_ART,              "art original" },
+	{ TYPE_ART,              "art reproduction" },
+	{ TYPE_ART,              "comic strip" },
+	{ TYPE_ART,              "diorama" },
+	{ TYPE_ART,              "graphic" },
+	{ TYPE_ART,              "model" },
+	{ TYPE_ART,              "picture" },
 	{ TYPE_ELECTRONICSOURCE, "electronic" },
-	{ TYPE_FILM,   "videorecording" },
-	{ TYPE_FILM,   "motion picture" },
-	{ TYPE_SOUNDRECORDING, "sound" },
-	{ TYPE_PERFORMANCE, "rehersal" },
-	{ TYPE_INTERNETSITE, "web site" },
-	{ TYPE_INTERVIEW, "interview" },
-	{ TYPE_INTERVIEW, "communication" },
-	{ TYPE_MISC, "misc" },
+	{ TYPE_FILM,             "videorecording" },
+	{ TYPE_FILM,             "motion picture" },
+	{ TYPE_SOUNDRECORDING,   "sound" },
+	{ TYPE_PERFORMANCE,      "rehersal" },
+	{ TYPE_INTERNETSITE,     "web site" },
+	{ TYPE_INTERVIEW,        "interview" },
+	{ TYPE_INTERVIEW,        "communication" },
+	{ TYPE_MISC,             "misc" },
 };
 int ngenres = sizeof( genres ) / sizeof( genres[0] );
 
@@ -207,7 +208,7 @@
 	char *genre, *tag;
 	for ( i=0; i<info->n; ++i ) {
 		tag = (char *) fields_tag( info, i, FIELDS_CHRP );
-		if ( strcasecmp( tag, "GENRE" ) && strcasecmp( tag, "NGENRE" ) ) continue;
+		if ( strcasecmp( tag, "GENRE:MARC" ) && strcasecmp( tag, "GENRE:BIBUTILS" ) && strcasecmp( tag, "GENRE:UNKNOWN" ) ) continue;
 		genre = (char *) fields_value( info, i, FIELDS_CHRP );
 		for ( j=0; j<ngenres; ++j ) {
 			if ( !strcasecmp( genres[j].out, genre ) )
@@ -252,7 +253,7 @@
 	char *tag, *resource;
 	for ( i=0; i<info->n; ++i ) {
 		tag = (char *) fields_tag( info, i, FIELDS_CHRP );
-		if ( strcasecmp( tag, "GENRE" ) && strcasecmp( tag, "NGENRE" ) ) continue;
+		if ( strcasecmp( tag, "RESOURCE" ) ) continue;
 		resource = (char *) fields_value( info, i, FIELDS_CHRP );
 		if ( !strcasecmp( resource, "moving image" ) )
 			type = TYPE_FILM;
diff --git a/bibutils/xml.c b/bibutils/xml.c
--- a/bibutils/xml.c
+++ b/bibutils/xml.c
@@ -1,7 +1,7 @@
 /*
  * xml.c
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
@@ -15,72 +15,41 @@
 
 char *xml_pns = NULL;
 
-static xml_attrib *
-xmlattrib_new( void )
-{
-	xml_attrib *a = (xml_attrib *) malloc( sizeof( xml_attrib ) );
-	if ( a ) {
-		slist_init( &(a->attrib) );
-		slist_init( &(a->value) );
-	}
-	return a;
-}
-
-static void
-xmlattrib_add( xml_attrib *a, char *attrib, char *value  )
-{
-	if ( attrib ) slist_addc( &(a->attrib), attrib );
-	else slist_addc( &(a->attrib), "" );
-	if ( value ) slist_addc( &(a->value), value );
-	else slist_addc( &(a->value), "" );
-}
-
-static void
-xmlattrib_free( xml_attrib *a )
+void
+xml_init( xml *node )
 {
-	slist_free( &(a->attrib) );
-	slist_free( &(a->value ) );
+	str_init( &(node->tag) );
+	str_init( &(node->value) );
+	slist_init( &(node->attributes) );
+	slist_init( &(node->attribute_values) );
+	node->down = NULL;
+	node->next = NULL;
 }
 
 static xml *
 xml_new( void )
 {
-	xml *x = ( xml * ) malloc( sizeof( xml ) );
-	if ( x ) xml_init( x );
-	return x;
+	xml *node = ( xml * ) malloc( sizeof( xml ) );
+	if ( node ) xml_init( node );
+	return node;
 }
 
-void
-xml_free( xml *x )
+static void
+xml_delete( xml *node )
 {
-	if ( x->tag ) {
-		str_free( x->tag );
-		free( x->tag );
-	}
-	if ( x->value ) {
-		str_free( x->value );
-		free( x->value );
-	}
-	if ( x->a ) {
-		xmlattrib_free( x->a );
-		free( x->a );
-	}
-	if ( x->down ) xml_free( x->down );
-	if ( x->next ) xml_free( x->next );
+	xml_free( node );
+	free( node );
 }
 
 void
-xml_init( xml *x )
+xml_free( xml *node )
 {
-	x->tag = str_new();
-	x->value = str_new();
-	x->a = NULL;
-	x->down = NULL;
-	x->next = NULL;
-	if ( !(x->tag) || !(x->value) ) {
-		fprintf(stderr,"xml_init: memory error.\n");
-		exit( EXIT_FAILURE );
-	}
+	str_free( &(node->tag) );
+	str_free( &(node->value) );
+	slist_free( &(node->attributes) );
+	slist_free( &(node->attribute_values) );
+	if ( node->down ) xml_delete( node->down );
+	if ( node->next ) xml_delete( node->next );
 }
 
 enum {
@@ -92,7 +61,7 @@
 };
 
 static int
-xml_terminator( char *p, int *type )
+xml_is_terminator( char *p, int *type )
 {
 	if ( *p=='>' ) {
 		return 1;
@@ -110,88 +79,128 @@
 	return 0;
 }
 
+static int
+xml_add_attribute( xml *node, char *attribute, char *attribute_value  )
+{
+	str *s;
+
+	if ( attribute )
+		s = slist_addc( &(node->attributes), attribute );
+	else
+		s = slist_addc( &(node->attributes), "" );
+	if ( s==NULL ) return 0;
+
+	if ( attribute_value )
+		s = slist_addc( &(node->attribute_values), attribute_value );
+	else
+		s = slist_addc( &(node->attribute_values), "" );
+	if ( s==NULL ) {
+		(void) slist_remove( &(node->attributes), node->attributes.n-1 );
+		return 0;
+	}
+	return 1;
+}
+
 static char *
-xml_processattrib( char *p, xml_attrib **ap, int *type )
+xml_processattrib( char *p, xml *node, int *type )
 {
-	xml_attrib *a = NULL;
 	char quote_character = '\"';
 	int inquotes = 0;
 	str aname, aval;
+
 	str_init( &aname );
 	str_init( &aval );
-	while ( *p && !xml_terminator(p,type) ) {
+
+	while ( *p && !xml_is_terminator( p, type ) ) {
+
 		/* get attribute name */
 		while ( *p==' ' || *p=='\t' ) p++;
-		while ( *p && !strchr( "= \t", *p ) && !xml_terminator(p,type)){
+		while ( *p && !strchr( "= \t", *p ) && !xml_is_terminator( p, type ) ){
 			str_addchar( &aname, *p );
 			p++;
 		}
+
+		/* equals sign */
 		while ( *p==' ' || *p=='\t' ) p++;
 		if ( *p=='=' ) p++;
-		/* get attribute value */
 		while ( *p==' ' || *p=='\t' ) p++;
+
+		/* get attribute value */
 		if ( *p=='\"' || *p=='\'' ) {
 			if ( *p=='\'' ) quote_character = *p;
 			inquotes=1;
 			p++;
 		}
-		while ( *p && ((!xml_terminator(p,type) && !strchr("= \t", *p ))||inquotes)){
+		while ( *p && ((!xml_is_terminator(p,type) && !strchr("= \t", *p ))||inquotes)){
 			if ( *p==quote_character ) inquotes=0;
 			else str_addchar( &aval, *p );
 			p++;
 		}
 		if ( str_has_value( &aname ) ) {
-			if ( !a ) a = xmlattrib_new();
-			xmlattrib_add( a, str_cstr( &aname ), str_cstr( &aval ) );
+			xml_add_attribute( node, str_cstr( &aname ), str_cstr( &aval ) );
 		}
+
 		str_empty( &aname );
 		str_empty( &aval );
 	}
+
 	str_free( &aname );
 	str_free( &aval );
-	*ap = a;
+
 	return p;
 }
 
 /*
  * xml_processtag
  *
- *      XML_COMMENT   <!-- ....  -->
+ *                        start right after '<'
+ *                        *
+ *      XML_COMMENT      <!-- ....  -->
  * 	XML_DESCRIPTOR   <?.....>
- * 	XML_OPEN      <A>
- * 	XML_CLOSE     </A>
- * 	XML_OPENCLOSE <A/>
+ * 	XML_OPEN         <A>
+ * 	XML_CLOSE        </A>
+ * 	XML_OPENCLOSE    <A/>
  */
 static char *
-xml_processtag( char *p, str *tag, xml_attrib **attrib, int *type )
+xml_processtag( char *p, xml *node, int *type )
 {
-	*attrib = NULL;
-	if ( *p=='<' ) p++;
+	str tag;
+
+	str_init( &tag );
+
 	if ( *p=='!' ) {
-		while ( *p && *p!='>' ) str_addchar( tag, *p++ );
 		*type = XML_COMMENT;
-	} else if ( *p=='?' ) {
+		while ( *p && *p!='>' ) p++;
+	}
+	else if ( *p=='?' ) {
 		*type = XML_DESCRIPTOR;
 		p++; /* skip '?' */
-		while ( *p && !strchr( " \t", *p ) && !xml_terminator(p,type) )
-			str_addchar( tag, *p++ );
+		while ( *p && !strchr( " \t", *p ) && !xml_is_terminator(p,type) )
+			str_addchar( &tag, *p++ );
 		if ( *p==' ' || *p=='\t' )
-			p = xml_processattrib( p, attrib, type );
-	} else if ( *p=='/' ) {
-		while ( *p && !strchr( " \t", *p ) && !xml_terminator(p,type) )
-			str_addchar( tag, *p++ );
+			p = xml_processattrib( p, node, type );
+	}
+	else if ( *p=='/' ) {
 		*type = XML_CLOSE;
+		while ( *p && !strchr( " \t", *p ) && !xml_is_terminator(p,type) )
+			str_addchar( &tag, *p++ );
 		if ( *p==' ' || *p=='\t' ) 
-			p = xml_processattrib( p, attrib, type );
-	} else {
+			p = xml_processattrib( p, node, type );
+	}
+	else {
 		*type = XML_OPEN;
-		while ( *p && !strchr( " \t", *p ) && !xml_terminator(p,type) )
-			str_addchar( tag, *p++ );
+		while ( *p && !strchr( " \t", *p ) && !xml_is_terminator(p,type) )
+			str_addchar( &tag, *p++ );
 		if ( *p==' ' || *p=='\t' ) 
-			p = xml_processattrib( p, attrib, type );
+			p = xml_processattrib( p, node, type );
 	}
 	while ( *p && *p!='>' ) p++;
 	if ( *p=='>' ) p++;
+
+	str_strcpy( &(node->tag), &tag );
+
+	str_free( &tag );
+
 	return p;
 }
 
@@ -207,102 +216,99 @@
 }
 
 char *
-xml_tree( char *p, xml *onode )
+xml_parse( char *p, xml *onode )
 {
-	str tag;
-	xml_attrib *attrib;
 	int type, is_style = 0;
-
-	str_init( &tag );
+	xml *nnode;
 
 	while ( *p ) {
+
 		/* retain white space for <style> tags in endnote xml */
-		if ( onode->tag && str_cstr( onode->tag ) &&
-			!strcasecmp( str_cstr( onode->tag ),"style") ) is_style=1;
+		if ( str_cstr( &(onode->tag) ) &&
+			!strcasecmp( str_cstr( &(onode->tag) ),"style") ) is_style=1;
+
 		while ( *p && *p!='<' ) {
-			if ( onode->value->len>0 || is_style || !is_ws( *p ) )
-				str_addchar( onode->value, *p );
+			if ( onode->value.len>0 || is_style || !is_ws( *p ) )
+				str_addchar( &(onode->value), *p );
 			p++;
 		}
+
 		if ( *p=='<' ) {
-			str_empty( &tag );
-			p = xml_processtag( p, &tag, &attrib, &type );
-			if ( type==XML_OPEN || type==XML_OPENCLOSE ||
-			     type==XML_DESCRIPTOR ) {
-				xml *nnode = xml_new();
-				str_strcpy( nnode->tag, &tag );
-				nnode->a = attrib;
+			nnode = xml_new();
+			p = xml_processtag( p+1, nnode, &type );
+			if ( type==XML_OPEN || type==XML_OPENCLOSE || type==XML_DESCRIPTOR ) {
 				xml_appendnode( onode, nnode );
 				if ( type==XML_OPEN )
-					p = xml_tree( p, nnode );
+					p = xml_parse( p, nnode );
 			} else if ( type==XML_CLOSE ) {
 				/*check to see if it's closing for this one*/
+				xml_delete( nnode );
 				goto out; /* assume it's right for now */
+			} else {
+				xml_delete( nnode );
 			}
 		}
+
 	}
 out:
-	str_free( &tag );
 	return p;
 }
 
 void
-xml_draw( xml *x, int n )
+xml_draw( xml *node, int n )
 {
-	int i,j;
-	if ( !x ) return;
+	slist_index j;
+	int i;
+
+	if ( !node ) return;
+
 	for ( i=0; i<n; ++i ) printf( "    " );
-	printf("n=%d tag='%s' value='%s'\n", n, str_cstr( x->tag ), str_cstr( x->value ) );
-	if ( x->a ) {
-		for ( j=0; j<x->a->value.n; ++j ) {
-			for ( i=0; i<n; ++i ) printf( "    " );
-			printf("    attrib='%s' value='%s'\n",
-				slist_cstr( &(x->a)->attrib, j ),
-				slist_cstr( &(x->a)->attrib, j ) );
-		}
+
+	printf("n=%d tag='%s' value='%s'\n", n, str_cstr( &(node->tag) ), str_cstr( &(node->value) ) );
+
+	for ( j=0; j<node->attributes.n; ++j ) {
+		for ( i=0; i<n; ++i ) printf( "    " );
+		printf( "    attribute='%s' value='%s'\n",
+			slist_cstr( &(node->attributes), j ),
+			slist_cstr( &(node->attribute_values), j )
+		);
 	}
-	if ( x->down ) xml_draw( x->down, n+1 );
-	if ( x->next ) xml_draw( x->next, n );
+
+	if ( node->down ) xml_draw( node->down, n+1 );
+	if ( node->next ) xml_draw( node->next, n );
 }
 
 char *
-xml_findstart( char *buffer, char *tag )
+xml_find_start( char *buffer, char *tag )
 {
 	str starttag;
 	char *p;
 
-	str_init( &starttag );
-	str_addchar( &starttag, '<' );
-	str_strcatc( &starttag, tag );
-	str_addchar( &starttag, ' ' );
-	p = strsearch( buffer, str_cstr( &starttag ) );
+	str_initstrsc( &starttag, "<", tag, " ", NULL );
 
+	p = strsearch( buffer, str_cstr( &starttag ) );
 	if ( !p ) {
 		starttag.data[ starttag.len-1 ] = '>';
 		p = strsearch( buffer, str_cstr( &starttag ) );
 	}
 
 	str_free( &starttag );
+
 	return p;
 }
 
 char *
-xml_findend( char *buffer, char *tag )
+xml_find_end( char *buffer, char *tag )
 {
 	str endtag;
 	char *p;
 
-	str_init( &endtag );
-	str_strcpyc( &endtag, "</" );
-	if ( xml_pns ) {
-		str_strcatc( &endtag, xml_pns );
-		str_addchar( &endtag, ':' );
-	}
-	str_strcatc( &endtag, tag );
-	str_addchar( &endtag, '>' );
+	if ( xml_pns )
+		str_initstrsc( &endtag, "</", xml_pns, ":", tag, ">", NULL );
+	else
+		str_initstrsc( &endtag, "</", tag, ">", NULL );
 
 	p = strsearch( buffer, str_cstr( &endtag ) );
-
 	if ( p && *p ) {
 		if ( *p ) p++;  /* skip <random_tag></end> combo */
 		while ( *p && *(p-1)!='>' ) p++;
@@ -313,102 +319,101 @@
 }
 
 static int
-xml_tagexact_simple( xml* node, char *s )
+xml_tag_matches_simple( xml* node, const char *tag )
 {
-	if ( node->tag->len!=strlen( s ) ) return 0;
-	if ( strcasecmp( str_cstr( node->tag ), s ) ) return 0;
+	if ( node->tag.len!=strlen( tag ) ) return 0;
+	if ( strcasecmp( str_cstr( &(node->tag) ), tag ) ) return 0;
 	return 1;
 }
 static int
-xml_tagexact_pns( xml* node, char *s )
+xml_tag_matches_pns( xml* node, const char *tag )
 {
 	int found = 0;
-	str tag;
+	str pnstag;
 
-	str_init( &tag );
-	str_strcpyc( &tag, xml_pns );
-	str_addchar( &tag, ':' );
-	str_strcatc( &tag, s );
-	if ( node->tag->len==tag.len &&
-			!strcasecmp( str_cstr( node->tag ), str_cstr( &tag ) ) )
+	str_initstrsc( &pnstag, xml_pns, ":", tag, NULL );
+	if ( node->tag.len==pnstag.len &&
+			!strcasecmp( str_cstr( &(node->tag) ), str_cstr( &pnstag ) ) )
 		found = 1;
-	str_free( &tag );
+	str_free( &pnstag );
 
 	return found;
 }
 int
-xml_tagexact( xml *node, char *s )
+xml_tag_matches( xml *node, const char *tag )
 {
-	if ( xml_pns ) return xml_tagexact_pns( node, s );
-	else           return xml_tagexact_simple( node, s );
+	if ( xml_pns ) return xml_tag_matches_pns   ( node, tag );
+	else           return xml_tag_matches_simple( node, tag );
 }
 
 int
-xml_hasattrib( xml *node, char *attrib, char *value )
+xml_tag_matches_has_value( xml *node, const char *tag )
 {
-	xml_attrib *na = node->a;
-	char *a, *v;
-	int i;
-
-	if ( na ) {
+	if ( xml_tag_matches( node, tag ) && xml_has_value( node ) ) return 1;
+	return 0;
+}
 
-		for ( i=0; i<na->attrib.n; ++i ) {
-			a = slist_cstr( &(na->attrib), i );
-			v = slist_cstr( &(na->value),  i );
-			if ( !a || !v ) continue;
-			if ( !strcasecmp( a, attrib ) && !strcasecmp( v, value ) )
-				return 1;
-		}
+int
+xml_has_attribute( xml *node, const char *attribute, const char *attribute_value )
+{
+	slist_index i;
+	char *a, *v;
 
+	for ( i=0; i<node->attributes.n; ++i ) {
+		a = slist_cstr( &(node->attributes), i );
+		v = slist_cstr( &(node->attribute_values), i );
+		if ( !a || !v ) continue;
+		if ( !strcasecmp( a, attribute ) && !strcasecmp( v, attribute_value ) )
+			return 1;
 	}
 
 	return 0;
 }
 
 int
-xml_tag_attrib( xml *node, char *s, char *attrib, char *value )
+xml_tag_has_attribute( xml *node, const char *tag, const char *attribute, const char *attribute_value )
 {
-	if ( !xml_tagexact( node, s ) ) return 0;
-	return xml_hasattrib( node, attrib, value );
+	if ( !xml_tag_matches( node, tag ) ) return 0;
+	return xml_has_attribute( node, attribute, attribute_value );
 }
 
 str *
-xml_getattrib( xml *node, char *attrib )
+xml_attribute( xml *node, const char *attribute )
 {
-	xml_attrib *na = node->a;
-	str *ns = NULL;
-	int i;
+	slist_index n;
 
-	if ( na ) {
-		for ( i=0; i<na->attrib.n; ++i )
-			if ( !strcasecmp( slist_cstr( &(na->attrib), i ), attrib ) )
-				ns = slist_str( &(na->value), i );
-	}
-	return ns;
+	n = slist_findc( &(node->attributes), attribute );
+	if ( slist_wasnotfound( &(node->attributes), n ) ) return NULL;
+	else return slist_str( &(node->attribute_values), n );
 }
 
 int
-xml_hasvalue( xml *node )
+xml_has_value( xml *node )
 {
-	if ( node && node->value && str_cstr( node->value ) ) return 1;
+	if ( node && str_has_value( &(node->value) ) ) return 1;
 	return 0;
 }
 
-char *
+str *
 xml_tag( xml *node )
 {
-	return str_cstr( node->tag );
+	return &(node->tag);
 }
 
 char *
+xml_tag_cstr( xml *node )
+{
+	return str_cstr( &(node->tag) );
+}
+
+str *
 xml_value( xml *node )
 {
-	return str_cstr( node->value );
+	return &(node->value);
 }
 
-int
-xml_tagwithvalue( xml *node, char *tag )
+char *
+xml_value_cstr( xml *node )
 {
-	if ( !xml_hasvalue( node ) ) return 0;
-	return xml_tagexact( node, tag );
+	return str_cstr( &(node->value) );
 }
diff --git a/bibutils/xml.h b/bibutils/xml.h
--- a/bibutils/xml.h
+++ b/bibutils/xml.h
@@ -1,7 +1,7 @@
 /*
  * xml.h
  *
- * Copyright (c) Chris Putnam 2004-2017
+ * Copyright (c) Chris Putnam 2004-2018
  *
  * Source code released under the GPL version 2
  *
@@ -12,34 +12,32 @@
 #include "slist.h"
 #include "str.h"
 
-typedef struct xml_attrib {
-	slist attrib;
-	slist value;
-} xml_attrib;
-
 typedef struct xml {
-	str *tag;
-	str *value;
-	xml_attrib *a;
+	str tag;
+	str value;
+	slist attributes;
+	slist attribute_values;
 	struct xml *down;
 	struct xml *next;
 } xml;
 
-void     xml_init        ( xml *x );
-void     xml_free        ( xml *x );
-str *    xml_getattrib   ( xml *node, char *attrib );
-char *   xml_findstart   ( char *buffer, char *tag );
-char *   xml_findend     ( char *buffer, char *tag );
-int      xml_tagexact    ( xml *node, char *s );
-int      xml_tag_attrib  ( xml *node, char *s, char *attrib, char *value );
-int      xml_hasattrib   ( xml *node, char *attrib, char *value );
-char *   xml_tree        ( char *p, xml *onode );
-int      xml_hasvalue    ( xml *node );
-char *   xml_value       ( xml *node );
-char *   xml_tag         ( xml *node );
-int      xml_tagwithvalue( xml *node, char *tag );
+void   xml_init                 ( xml *node );
+void   xml_free                 ( xml *node );
+int    xml_has_value            ( xml *node );
+str *  xml_value                ( xml *node );
+char * xml_value_cstr           ( xml *node );
+str *  xml_tag                  ( xml *node );
+char * xml_tag_cstr             ( xml *node );
+int    xml_tag_matches          ( xml *node, const char *tag );
+int    xml_tag_matches_has_value( xml *node, const char *tag );
+str *  xml_attribute            ( xml *node, const char *attribute );
+char * xml_find_start           ( char *buffer, char *tag );
+char * xml_find_end             ( char *buffer, char *tag );
+int    xml_tag_has_attribute    ( xml *node, const char *tag, const char *attribute, const char *attribute_value );
+int    xml_has_attribute        ( xml *node, const char *attribute, const char *attribute_value );
+char * xml_parse                ( char *p, xml *onode );
 
-extern char *   xml_pns; /* global Namespace */
+char * xml_pns; /* global Namespace */
 
 #endif
 
diff --git a/bibutils/xml_encoding.c b/bibutils/xml_encoding.c
--- a/bibutils/xml_encoding.c
+++ b/bibutils/xml_encoding.c
@@ -1,7 +1,7 @@
 /*
  * xml_getencoding.c
  *
- * Copyright (c) Chris Putnam 2007-2017
+ * Copyright (c) Chris Putnam 2007-2018
  *
  * Source code released under the GPL version 2
  *
@@ -22,8 +22,8 @@
 	str *s;
 	char *t;
 
-	if ( xml_tagexact( node, "xml" ) ) {
-		s = xml_getattrib( node, "encoding" );
+	if ( xml_tag_matches( node, "xml" ) ) {
+		s = xml_attribute( node, "encoding" );
 		if ( str_has_value( s ) ) {
 			t = str_cstr( s );
 			if ( !strcasecmp( t, "UTF-8" ) )
@@ -66,7 +66,7 @@
 			str_init( &descriptor );
 			str_segcpy( &descriptor, p, q+2 );
 			xml_init( &descriptxml );
-			xml_tree( str_cstr( &descriptor ), &descriptxml );
+			xml_parse( str_cstr( &descriptor ), &descriptxml );
 			file_charset = xml_getencodingr( &descriptxml );
 			xml_free( &descriptxml );
 			str_free( &descriptor );
diff --git a/bibutils/xml_encoding.h b/bibutils/xml_encoding.h
--- a/bibutils/xml_encoding.h
+++ b/bibutils/xml_encoding.h
@@ -1,7 +1,7 @@
 /*
  * xml_getencoding.h
  *
- * Copyright (c) Chris Putnam 2007-2017
+ * Copyright (c) Chris Putnam 2007-2018
  *
  * Source code released under the GPL version 2
  *
diff --git a/hs-bibutils.cabal b/hs-bibutils.cabal
--- a/hs-bibutils.cabal
+++ b/hs-bibutils.cabal
@@ -1,5 +1,5 @@
 name:               hs-bibutils
-version:            6.2.0.1
+version:            6.3.0.0
 homepage:           https://github.com/wilx/hs-bibutils
 
 synopsis:           Haskell bindings to bibutils, the bibliography
@@ -31,30 +31,31 @@
         bibutils/bibformats.h bibutils/biblatexin.c bibutils/bibl.c
         bibutils/bibl.h bibutils/bibtexin.c bibutils/bibtexout.c
         bibutils/bibtextypes.c bibutils/bibutils.c bibutils/bibutils.h
-        bibutils/bltypes.c bibutils/charsets.c bibutils/charsets.h
-        bibutils/copacin.c bibutils/copactypes.c bibutils/ebiin.c
-        bibutils/endin.c bibutils/endout.c bibutils/endtypes.c
-        bibutils/endxmlin.c bibutils/entities.c bibutils/entities.h
-        bibutils/fields.c bibutils/fields.h bibutils/gb18030.c
-        bibutils/gb18030_enumeration.c bibutils/gb18030.h bibutils/generic.c
-        bibutils/generic.h bibutils/intlist.c bibutils/intlist.h
-        bibutils/isiin.c bibutils/isiout.c bibutils/isitypes.c
-        bibutils/iso639_1.c bibutils/iso639_1.h bibutils/iso639_2.c
-        bibutils/iso639_2.h bibutils/iso639_3.c bibutils/iso639_3.h
-        bibutils/is_ws.c bibutils/is_ws.h bibutils/latex.c bibutils/latex.h
-        bibutils/marc.c bibutils/marc.h bibutils/medin.c bibutils/modsin.c
-        bibutils/modsout.c bibutils/modstypes.c bibutils/modstypes.h
-        bibutils/name.c bibutils/name.h bibutils/nbibin.c
-        bibutils/nbibtypes.c bibutils/notes.c bibutils/notes.h
-        bibutils/pages.c bibutils/pages.h bibutils/reftypes.c
-        bibutils/reftypes.h bibutils/risin.c bibutils/risout.c
-        bibutils/ristypes.c bibutils/serialno.c bibutils/serialno.h
-        bibutils/slist.c bibutils/slist.h bibutils/str.c bibutils/str_conv.c
-        bibutils/str_conv.h bibutils/str.h bibutils/strsearch.c
-        bibutils/strsearch.h bibutils/title.c bibutils/title.h
-        bibutils/unicode.c bibutils/unicode.h bibutils/url.c bibutils/url.h
-        bibutils/utf8.c bibutils/utf8.h bibutils/vplist.c bibutils/vplist.h
-        bibutils/wordin.c bibutils/wordout.c bibutils/xml.c
+        bibutils/bltypes.c bibutils/bu_auth.c bibutils/bu_auth.h
+        bibutils/charsets.c bibutils/charsets.h bibutils/copacin.c
+        bibutils/copactypes.c bibutils/ebiin.c bibutils/endin.c
+        bibutils/endout.c bibutils/endtypes.c bibutils/endxmlin.c
+        bibutils/entities.c bibutils/entities.h bibutils/fields.c
+        bibutils/fields.h bibutils/gb18030.c bibutils/gb18030_enumeration.c
+        bibutils/gb18030.h bibutils/generic.c bibutils/generic.h
+        bibutils/intlist.c bibutils/intlist.h bibutils/isiin.c
+        bibutils/isiout.c bibutils/isitypes.c bibutils/iso639_1.c
+        bibutils/iso639_1.h bibutils/iso639_2.c bibutils/iso639_2.h
+        bibutils/iso639_3.c bibutils/iso639_3.h bibutils/is_ws.c
+        bibutils/is_ws.h bibutils/latex.c bibutils/latex.h
+        bibutils/marc_auth.c bibutils/marc_auth.h bibutils/medin.c
+        bibutils/modsin.c bibutils/modsout.c bibutils/modstypes.c
+        bibutils/modstypes.h bibutils/name.c bibutils/name.h
+        bibutils/nbibin.c bibutils/nbibtypes.c bibutils/notes.c
+        bibutils/notes.h bibutils/pages.c bibutils/pages.h
+        bibutils/reftypes.c bibutils/reftypes.h bibutils/risin.c
+        bibutils/risout.c bibutils/ristypes.c bibutils/serialno.c
+        bibutils/serialno.h bibutils/slist.c bibutils/slist.h bibutils/str.c
+        bibutils/str_conv.c bibutils/str_conv.h bibutils/str.h
+        bibutils/strsearch.c bibutils/strsearch.h bibutils/title.c
+        bibutils/title.h bibutils/unicode.c bibutils/unicode.h bibutils/url.c
+        bibutils/url.h bibutils/utf8.c bibutils/utf8.h bibutils/vplist.c
+        bibutils/vplist.h bibutils/wordin.c bibutils/wordout.c bibutils/xml.c
         bibutils/xml_encoding.c bibutils/xml_encoding.h bibutils/xml.h
         README.md ChangeLog.md
 
@@ -69,25 +70,25 @@
     includes: bibutils.h
     c-sources:
         cbits/stub.c
-        bibutils/adsout.c bibutils/bibcore.c
+        bibutils/adsout.c bibutils/adsout_journals.c bibutils/bibcore.c
         bibutils/biblatexin.c bibutils/bibl.c bibutils/bibtexin.c
         bibutils/bibtexout.c bibutils/bibtextypes.c bibutils/bibutils.c
-        bibutils/bltypes.c bibutils/charsets.c bibutils/copacin.c
-        bibutils/copactypes.c bibutils/ebiin.c bibutils/endin.c
-        bibutils/endout.c bibutils/endtypes.c bibutils/endxmlin.c
-        bibutils/entities.c bibutils/fields.c bibutils/gb18030.c
-        bibutils/generic.c bibutils/intlist.c
+        bibutils/bltypes.c bibutils/bu_auth.c bibutils/charsets.c
+        bibutils/copacin.c bibutils/copactypes.c bibutils/ebiin.c
+        bibutils/endin.c bibutils/endout.c bibutils/endtypes.c
+        bibutils/endxmlin.c bibutils/entities.c bibutils/fields.c
+        bibutils/gb18030.c bibutils/generic.c bibutils/intlist.c
         bibutils/isiin.c bibutils/isiout.c bibutils/isitypes.c
         bibutils/iso639_1.c bibutils/iso639_2.c bibutils/iso639_3.c
-        bibutils/is_ws.c bibutils/latex.c bibutils/marc.c bibutils/medin.c
-        bibutils/modsin.c bibutils/modsout.c bibutils/modstypes.c
-        bibutils/name.c bibutils/nbibin.c bibutils/nbibtypes.c
-        bibutils/notes.c bibutils/pages.c bibutils/reftypes.c
-        bibutils/risin.c bibutils/risout.c bibutils/ristypes.c
-        bibutils/serialno.c bibutils/slist.c bibutils/str.c
-        bibutils/str_conv.c bibutils/strsearch.c bibutils/title.c
-        bibutils/unicode.c bibutils/url.c bibutils/utf8.c bibutils/vplist.c
-        bibutils/wordin.c bibutils/wordout.c bibutils/xml.c
+        bibutils/is_ws.c bibutils/latex.c bibutils/marc_auth.c
+        bibutils/medin.c bibutils/modsin.c bibutils/modsout.c
+        bibutils/modstypes.c bibutils/name.c bibutils/nbibin.c
+        bibutils/nbibtypes.c bibutils/notes.c bibutils/pages.c
+        bibutils/reftypes.c bibutils/risin.c bibutils/risout.c
+        bibutils/ristypes.c bibutils/serialno.c bibutils/slist.c
+        bibutils/str.c bibutils/str_conv.c bibutils/strsearch.c
+        bibutils/title.c bibutils/unicode.c bibutils/url.c bibutils/utf8.c
+        bibutils/vplist.c bibutils/wordin.c bibutils/wordout.c bibutils/xml.c
         bibutils/xml_encoding.c
 
     if impl(ghc >= 6.10)
diff --git a/src/Text/Bibutils.hsc b/src/Text/Bibutils.hsc
--- a/src/Text/Bibutils.hsc
+++ b/src/Text/Bibutils.hsc
@@ -64,7 +64,9 @@
     , unsetAddcount
     , setSinglerefperfile
     , unsetSinglerefperfile
+    , setOutputRawOpts
     , setVerbose
+    , setVerboseLevel
     , unsetVerbose
 
     -- * Input Formats
@@ -78,6 +80,9 @@
     , medline_in
     , biblatex_in
     , endnotexml_in
+    , ebi_in
+    , word_in
+    , nbib_in
 
     -- * Output Formats
     , BiblioOut
@@ -97,6 +102,8 @@
     , bibout_brackets
     , bibout_uppercase
     , bibout_strictkey
+    , bibout_shorttitle
+    , bibout_dropkey
     , modsout_dropkey
 
     -- * Charsets
@@ -105,6 +112,8 @@
     , bibl_charset_unicode
     , bibl_charset_gb18030
     , bibl_charset_default
+    , bibl_charset_utf8_default
+    , bibl_charset_bom_default
 
     -- * Return Status
     , Status
@@ -113,6 +122,11 @@
     , bibl_err_memerr
     , bibl_err_cantopen
 
+    -- * Raw
+    , Raw
+    , bibl_raw_with_charset_convert
+    , bibl_raw_with_make_ref_id
+
     ) where
 
 import Control.Monad
@@ -304,11 +318,21 @@
 unsetSinglerefperfile p
     = setParam p $ \param -> param { singlerefperfile = 0 }
 
+-- | Set the output charset.
+setOutputRawOpts ::  ForeignPtr Param -> [Raw] -> IO ()
+setOutputRawOpts p os
+    = setParam p $ \param -> param { output_raw = unRaw $ combineRawOpts os }
+
 -- | Verbose output.
 setVerbose ::  ForeignPtr Param -> IO ()
 setVerbose p
     = setParam p $ \param -> param { verbose = 1 }
 
+-- | Verbose output.
+setVerboseLevel ::  ForeignPtr Param -> Int -> IO ()
+setVerboseLevel p v
+    = setParam p $ \param -> param { verbose = toEnum v }
+
 -- | Suppress verbose output.
 unsetVerbose ::  ForeignPtr Param -> IO ()
 unsetVerbose p
@@ -385,6 +409,9 @@
  , medline_in    = BIBL_MEDLINEIN
  , endnotexml_in = BIBL_ENDNOTEXMLIN
  , biblatex_in   = BIBL_BIBLATEXIN
+ , ebi_in        = BIBL_EBIIN
+ , word_in       = BIBL_WORDIN
+ , nbib_in       = BIBL_NBIBIN
  }
 
 newtype BiblioOut = BiblioOut { unBiblioOut :: CInt }
@@ -411,6 +438,8 @@
  , bibout_brackets   = BIBL_FORMAT_BIBOUT_BRACKETS
  , bibout_uppercase  = BIBL_FORMAT_BIBOUT_UPPERCASE
  , bibout_strictkey  = BIBL_FORMAT_BIBOUT_STRICTKEY
+ , bibout_shorttitle = BIBL_FORMAT_BIBOUT_SHORTTITLE
+ , bibout_dropkey    = BIBL_FORMAT_BIBOUT_DROPKEY
  , modsout_dropkey   = BIBL_FORMAT_MODSOUT_DROPKEY
  }
 
@@ -424,14 +453,28 @@
  , bibl_err_cantopen = BIBL_ERR_CANTOPEN
  }
 
+newtype Raw = Raw { unRaw :: CUChar }
+    deriving ( Eq, Show )
+
+#{enum Raw, Raw
+ , bibl_raw_with_charset_convert = BIBL_RAW_WITHCHARCONVERT
+ , bibl_raw_with_make_ref_id     = BIBL_RAW_WITHMAKEREFID
+ }
+
 newtype Charset = Charset { charset :: CInt } deriving ( Eq )
 
 #{enum Charset, Charset
-, bibl_charset_unknown = BIBL_CHARSET_UNKNOWN
-, bibl_charset_unicode = BIBL_CHARSET_UNICODE
-, bibl_charset_gb18030 = BIBL_CHARSET_GB18030
-, bibl_charset_default = BIBL_CHARSET_DEFAULT
+ , bibl_charset_unknown      = BIBL_CHARSET_UNKNOWN
+ , bibl_charset_unicode      = BIBL_CHARSET_UNICODE
+ , bibl_charset_gb18030      = BIBL_CHARSET_GB18030
+ , bibl_charset_default      = BIBL_CHARSET_DEFAULT
+ , bibl_charset_utf8_default = BIBL_CHARSET_UTF8_DEFAULT
+ , bibl_charset_bom_default  = BIBL_CHARSET_BOM_DEFAULT
  }
+
+-- Combine a list of output options into a single option, using bitwise (.|.)
+combineRawOpts :: [Raw] -> Raw
+combineRawOpts = Raw . foldr ((.|.) . unRaw) 0
 
 -- Combine a list of options into a single option, using bitwise (.|.)
 combineFormatOpts :: [FormatOpt] -> FormatOpt
