about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2001-06-03 21:17:35 -0400
committerThomas E. Dickey <dickey@invisible-island.net>2001-06-03 21:17:35 -0400
commitd1349dd61e0c9248ec9be3edaa37a67952e44300 (patch)
treecc38442efa38ebd0cbb683866bc0ac8caf066a69 /src
parent8c68f693cc82e6650afff52fe478c0ccde4bc015 (diff)
downloadlynx-snapshots-d1349dd61e0c9248ec9be3edaa37a67952e44300.tar.gz
snapshot of project "lynx", label v2-8-4dev_21
Diffstat (limited to 'src')
-rw-r--r--src/AttrList.h15
-rw-r--r--src/DefaultStyle.c8
-rw-r--r--src/GridText.c1017
-rw-r--r--src/GridText.h6
-rw-r--r--src/HTAlert.c23
-rw-r--r--src/HTFWriter.c2
-rw-r--r--src/HTInit.c10
-rw-r--r--src/HTML.c193
-rw-r--r--src/LYBookmark.c288
-rw-r--r--src/LYBookmark.h11
-rw-r--r--src/LYCharSets.h7
-rw-r--r--src/LYCharUtils.c618
-rw-r--r--src/LYCookie.c115
-rw-r--r--src/LYCookie.h1
-rw-r--r--src/LYCurses.c119
-rw-r--r--src/LYCurses.h114
-rw-r--r--src/LYDownload.c2
-rw-r--r--src/LYEdit.c92
-rw-r--r--src/LYEdit.h4
-rw-r--r--src/LYExtern.c53
-rw-r--r--src/LYExtern.h1
-rw-r--r--src/LYForms.c26
-rw-r--r--src/LYGlobalDefs.h37
-rw-r--r--src/LYHash.h6
-rw-r--r--src/LYHistory.c20
-rw-r--r--src/LYJump.c4
-rw-r--r--src/LYKeymap.c51
-rw-r--r--src/LYKeymap.h16
-rw-r--r--src/LYLocal.c427
-rw-r--r--src/LYLocal.h6
-rw-r--r--src/LYMail.c24
-rw-r--r--src/LYMain.c543
-rw-r--r--src/LYMainLoop.c215
-rw-r--r--src/LYNews.c20
-rw-r--r--src/LYOptions.c671
-rw-r--r--src/LYOptions.h3
-rw-r--r--src/LYPrint.c4
-rw-r--r--src/LYReadCFG.c726
-rw-r--r--src/LYSearch.c301
-rw-r--r--src/LYSearch.h2
-rw-r--r--src/LYShowInfo.c6
-rw-r--r--src/LYShowInfo.h2
-rw-r--r--src/LYStrings.c460
-rw-r--r--src/LYStrings.h21
-rw-r--r--src/LYStructs.h49
-rw-r--r--src/LYStyle.c54
-rw-r--r--src/LYStyle.h4
-rw-r--r--src/LYUtils.c151
-rw-r--r--src/LYUtils.h1
-rw-r--r--src/LYrcFile.c1538
-rw-r--r--src/LYrcFile.h12
-rw-r--r--src/TRSTable.c337
-rw-r--r--src/TRSTable.h6
-rw-r--r--src/UCAuto.c40
-rw-r--r--src/UCdomap.c234
-rw-r--r--src/chrtrans/makefile.dos6
-rw-r--r--src/makefile.dos30
-rw-r--r--src/makefile.in2
58 files changed, 3630 insertions, 5124 deletions
diff --git a/src/AttrList.h b/src/AttrList.h
index 28f43ee6..1fac1e8e 100644
--- a/src/AttrList.h
+++ b/src/AttrList.h
@@ -26,21 +26,6 @@ enum {
  DSTYLE_ELEMENTS
 };
 
-enum {
- MSTYLE_NORMAL = 0,
- MSTYLE_EM = 1,
- MSTYLE_STRONG = 2,
- MSTYLE_PHYSICAL = 3,
- MSTYLE_A = 4,
- MSTYLE_A_OFF = 4,
- MSTYLE_A_ON,
- MSTYLE_BOLD,
- MSTYLE_UL,
- MSTYLE_STATUS,
- MSTYLE_CANDY,
- MSTYLE_NOMORE
-};
-
 typedef struct {
  int color; /* color highlighting to be done */
  int mono; /* mono highlighting to be done */
diff --git a/src/DefaultStyle.c b/src/DefaultStyle.c
index c3b2eb66..8549a3bf 100644
--- a/src/DefaultStyle.c
+++ b/src/DefaultStyle.c
@@ -20,14 +20,6 @@ PRIVATE CONST HTTabStop tabs_8[] = {
 	{0, 0 }		/* Terminate */
 };
 
-#ifdef NOT_USED
-PRIVATE HTTabStop tabs_16[] = {
-	{ 0, 16 }, {0, 32}, {0, 48}, {0, 64}, {0, 80},
-	{0, 96}, {0, 112},
-	{0, 0 }		/* Terminate */
-};
-#endif /* NOT_USED */
-
 /* Template:
 **	link to next, name, tag,
 **	font, size, colour, 		superscript, anchor id,
diff --git a/src/GridText.c b/src/GridText.c
index e61ddbd9..af7d2422 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -61,25 +61,28 @@ unsigned int cached_styles[CACHEH][CACHEW];
 
 #include <LYJustify.h>
 
-#ifdef USE_COLOR_STYLE_UNUSED
-void LynxClearScreenCache NOARGS
-{
-    int i,j;
-
-    CTRACE((tfp, "GridText: flushing cached screen styles\n"));
-    for (i=0;i<CACHEH;i++)
-	for (j=0;j<CACHEW;j++)
-	    cached_styles[i][j]=s_a;
-}
+#ifdef USE_CURSES_PADS
+#  define DISPLAY_COLS (LYwideLines ? MAX_COLS : LYcols)
+#  define WRAP_COLS(text) ((text)->stbl ?				\
+			   (LYtableCols <= 0				\
+			    ? DISPLAY_COLS : (LYtableCols * LYcols)/12)	\
+			   : LYcols)
+#else
+#  define DISPLAY_COLS LYcols
+#  define WRAP_COLS(text) LYcols
 #endif
+
+#define FirstHTLine(text) ((text)->last_line->next)
+#define LastHTLine(text)  ((text)->last_line)
+
 #ifdef USE_COLOR_STYLE
 PRIVATE void LynxResetScreenCache NOARGS
 {
-    int i,j;
+    int i, j;
 
-    for (i=1; (i<CACHEH && i <= display_lines); i++) {
-	for (j=0;j<CACHEW;j++)
-	    cached_styles[i][j]=0;
+    for (i = 1; (i < CACHEH && i <= display_lines); i++) {
+	for (j = 0; j < CACHEW; j++)
+	    cached_styles[i][j] = 0;
     }
 }
 #endif /* USE_COLOR_STYLE */
@@ -137,8 +140,8 @@ PUBLIC int LYCacheSourceForAborted = SOURCE_CACHE_FOR_ABORTED_DROP;
 #endif
 
 #ifdef USE_SCROLLBAR
-PUBLIC int LYsb = FALSE;
-PUBLIC int LYsb_arrow = TRUE;
+PUBLIC BOOLEAN LYsb = FALSE;
+PUBLIC BOOLEAN LYsb_arrow = TRUE;
 PUBLIC int LYsb_begin = -1;
 PUBLIC int LYsb_end = -1;
 #endif
@@ -290,6 +293,7 @@ void POOL_FREE( pool_type , P* ptr)
 
 typedef struct _TextAnchor {
 	struct _TextAnchor *	next;
+	struct _TextAnchor *	prev;		/* www_user_search only! */
 	int			number;		/* For user interface */
 	int			line_pos;	/* Bytes/chars - extent too */
 	int			extent;		/* (see HText_trimHightext) */
@@ -329,7 +333,7 @@ struct _HText {
 	BOOLEAN			historical_comments;
 	BOOLEAN			minimal_comments;
 	BOOLEAN			soft_dquotes;
-	BOOLEAN			old_dtd;
+	int			old_dtd;
 	int			keypad_mode;
 	int			disp_lines;	/* Screen size */
 	int			disp_cols;	/* Used for reports only */
@@ -769,7 +773,7 @@ PUBLIC HText *	HText_new ARGS1(
     self->old_dtd = Old_DTD;
     self->keypad_mode = keypad_mode;
     self->disp_lines = LYlines;
-    self->disp_cols = LYcols;
+    self->disp_cols = DISPLAY_COLS;
 #endif
     /*
      *  If we are going to render the List Page, always merge in hidden
@@ -1102,8 +1106,8 @@ PRIVATE int display_line ARGS4(
      *  go over the COLS limit on the display.
      */
     j = (int)line->offset;
-    if (j > (int)LYcols - 1)
-	j = (int)LYcols - 1;
+    if (j > (int)DISPLAY_COLS - 1)
+	j = (int)DISPLAY_COLS - 1;
 #ifdef USE_SLANG
     SLsmg_forward (j);
     i = j;
@@ -1131,20 +1135,13 @@ PRIVATE int display_line ARGS4(
      */
     i_after_tgt = i;
     if (target) {
-	if (case_sensitive)
-	    cp_tgt = LYno_attr_mbcs_strstr(data,
-					   target,
-					   text->T.output_utf8, YES,
-					   &HitOffset,
-					   &LenNeeded);
-	else
-	    cp_tgt = LYno_attr_mbcs_case_strstr(data,
-						target,
-						text->T.output_utf8, YES,
-						&HitOffset,
-						&LenNeeded);
+	cp_tgt = LYno_attr_mb_strstr(data,
+				       target,
+				       text->T.output_utf8, YES,
+				       &HitOffset,
+				       &LenNeeded);
 	if (cp_tgt) {
-	    if (((int)line->offset + LenNeeded) >= LYcols) {
+	    if (((int)line->offset + LenNeeded) >= DISPLAY_COLS) {
 		cp_tgt = NULL;
 	    } else {
 		text->page_has_target = YES;
@@ -1158,25 +1155,17 @@ PRIVATE int display_line ARGS4(
 #endif /* SHOW_WHEREIS_TARGETS */
 #endif /* USE_COLOR_STYLE */
 
-    while ((i < LYcols) && ((buffer[0] = *data) != '\0')) {
+    while ((i < DISPLAY_COLS) && ((buffer[0] = *data) != '\0')) {
 
 #ifndef USE_COLOR_STYLE
 #if defined(SHOW_WHEREIS_TARGETS)
 	if (cp_tgt && i >= i_after_tgt) {
 	    if (intarget) {
-
-		if (case_sensitive)
-		    cp_tgt = LYno_attr_mbcs_strstr(data,
-						target,
-						text->T.output_utf8, YES,
-						&HitOffset,
-						&LenNeeded);
-		else
-		    cp_tgt = LYno_attr_mbcs_case_strstr(data,
-						     target,
-						text->T.output_utf8, YES,
-						&HitOffset,
-						&LenNeeded);
+		cp_tgt = LYno_attr_mb_strstr(data,
+					    target,
+					    text->T.output_utf8, YES,
+					    &HitOffset,
+					    &LenNeeded);
 		if (cp_tgt) {
 		    i_start_tgt = i + HitOffset;
 		    i_after_tgt = i + LenNeeded;
@@ -1344,7 +1333,7 @@ PRIVATE int display_line ARGS4(
 		    /*
 		     *  For CJK strings, by Masanobu Kimura.
 		     */
-		    if (i >= LYcols) goto after_while;
+		    if (i >= DISPLAY_COLS) goto after_while;
 
 		    buffer[1] = *data;
 		    buffer[2] = '\0';
@@ -1365,15 +1354,6 @@ PRIVATE int display_line ARGS4(
 		     */
 		    LastDisplayChar = 'M';
 		} else {
-#if 0	/* last-ditch attempt to prevent 0x9B to screen - disabled  */
-#if defined(UNIX) || defined(VMS)
-		    if (!dump_output_immediately &&
-			UCH(buffer[0]) == 128+27) {
-			LYaddstr("~^");
-			buffer[0] ^= 0xc0;
-		    }
-#endif
-#endif
 		    LYaddstr(buffer);
 		    LastDisplayChar = buffer[0];
 		}
@@ -1625,9 +1605,9 @@ PRIVATE void display_scrollbar ARGS1(
 	/* Use rounding to get as many positions into top_skip==h - sh - 1
 	   as into top_skip == 1:
 	   1--->1, text->Lines - display_lines + 1--->h - sh. */
-	top_skip = 1 +
+	top_skip = (int) (1 +
 	    1. * (h - sh - 1) * text->top_of_screen
-		/(text->Lines - display_lines + 1);
+		/ (text->Lines - display_lines + 1));
     }
     bot_skip = h - sh - top_skip;
 
@@ -1644,7 +1624,7 @@ PRIVATE void display_scrollbar ARGS1(
 	    LynxChangeStyle(s, ABS_ON);
 	}
 #endif /* USE_COLOR_STYLE */
-	LYmove(1, LYcols - 1);
+	LYmove(1, LYcols + LYshiftWin - 1);
 	addch_raw(ACS_UARROW);
 #ifdef USE_COLOR_STYLE
 	LynxChangeStyle(s, STACK_OFF);
@@ -1665,7 +1645,7 @@ PRIVATE void display_scrollbar ARGS1(
 	if (i-1 <= h - bot_skip && i > h - bot_skip)
 	    LynxChangeStyle(s_sb_bar, STACK_OFF);
 #endif /* USE_COLOR_STYLE */
-	LYmove(i + off, LYcols - 1);
+	LYmove(i + off, LYcols + LYshiftWin - 1);
 	if (i > top_skip && i <= h - bot_skip)
 	    LYaddch(ACS_BLOCK);
 	else
@@ -1685,7 +1665,7 @@ PRIVATE void display_scrollbar ARGS1(
 	    LynxChangeStyle(s, ABS_ON);
 	}
 #endif /* USE_COLOR_STYLE */
-	LYmove(h + 2, LYcols - 1);
+	LYmove(h + 2, LYcols + LYshiftWin - 1);
 	addch_raw(ACS_DARROW);
 #ifdef USE_COLOR_STYLE
 	LynxChangeStyle(s, STACK_OFF);
@@ -1773,7 +1753,7 @@ PRIVATE void display_page ARGS3(
     else if (line_number < 0)
 	line_number = 0;
 
-    for (i = 0, line = text->last_line->next;		/* Find line */
+    for (i = 0, line = FirstHTLine(text);		/* Find line */
 	 i < line_number && (line != text->last_line);
 	 i++, line = line->next) {			/* Loop */
 #ifndef VMS
@@ -1803,7 +1783,6 @@ PRIVATE void display_page ARGS3(
 	 *  Also we don't want to do this for -dump and -source etc.
 	 */
 	LYCursesON) {
-	charset_last_displayed = current_char_set;
 #ifdef EXP_CHARTRANS_AUTOSWITCH
 	/*
 	 *  Currently implemented only for LINUX
@@ -1811,6 +1790,7 @@ PRIVATE void display_page ARGS3(
 	UCChangeTerminalCodepage(current_char_set,
 				 &LYCharSet_UC[current_char_set]);
 #endif /* EXP_CHARTRANS_AUTOSWITCH */
+	charset_last_displayed = current_char_set;
     }
 
     /*
@@ -1915,18 +1895,12 @@ PRIVATE void display_page ARGS3(
 	    data = (char *)line->data;
 	    offset = (int)line->offset;
 	    while ((target && *target) &&
-		   (case_sensitive ?
-		    (cp = LYno_attr_mbcs_strstr(data,
-						target,
-						text->T.output_utf8, YES,
-						NULL,
-						&LenNeeded)) != NULL :
-		    (cp = LYno_attr_mbcs_case_strstr(data,
-						     target,
-						text->T.output_utf8, YES,
-						NULL,
-						&LenNeeded)) != NULL) &&
-		   ((int)line->offset + LenNeeded) < LYcols) {
+		    (cp = LYno_attr_mb_strstr(data,
+					      target,
+					      text->T.output_utf8, YES,
+					      NULL,
+					      &LenNeeded)) != NULL &&
+		   ((int)line->offset + LenNeeded) < DISPLAY_COLS) {
 		int itmp = 0;
 		int written = 0;
 		int x_pos = offset + (int)(cp - data);
@@ -2004,15 +1978,6 @@ PRIVATE void display_page ARGS3(
 			    tmp[1] = '\0';
 			    written += 2;
 			} else {
-#if 0	/* last-ditch attempt to prevent 0x9B to screen - disabled  */
-#if defined(UNIX) || defined(VMS)
-			    if (!dump_output_immediately &&
-				UCH(tmp[0]) == 128+27) {
-				LYaddstr("~^");
-				tmp[0] ^= 0xc0;
-			    }
-#endif
-#endif
 			    LYaddstr(tmp);
 			    written++;
 			}
@@ -2316,7 +2281,7 @@ PUBLIC void HText_beginAppend ARGS1(
 #ifdef USE_SLANG
 #define LYcols_cu (dump_output_immediately ? MAX_COLS : SLtt_Screen_Cols)
 #else
-#define LYcols_cu (dump_output_immediately ? MAX_COLS : LYcols)
+#define LYcols_cu (dump_output_immediately ? MAX_COLS : DISPLAY_COLS)
 #endif
 
 /*	Add a new line of text
@@ -2461,6 +2426,7 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7(
     HTLine * mod_line;
     char *newdata;
     char *s = line->data;
+    char *pre = s;
     char *copied = line->data, *t;
 
     if (!(line && line->size && ninserts))
@@ -2489,15 +2455,15 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7(
 		      ? oldpos[ip]
 		      /* Include'em all! */
 		      : (line->size <= MAX_LINE ? MAX_LINE+1 : line->size+1));
-	char *pre = s;
+	pre = s;
 
 	/* Fast forward to char==curlim or EOL.  Stop *before* the
 	   style-change chars. */
 	while (*s) {
 	    if ( text && text->T.output_utf8
-		 && UCH(*s) >= 0x80 && UCH(*s) <  0xC0 )
+		 && UCH(*s) >= 0x80 && UCH(*s) <  0xC0 ) {
 		pre = s + 1;
-	    else if (!IsSpecialAttrChar(*s)) {	/* At a "displayed" char */
+	    } else if (!IsSpecialAttrChar(*s)) { /* At a "displayed" char */
 		if (ioldc >= curlim)
 		    break;
 		ioldc++;
@@ -2512,18 +2478,18 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7(
 				   &head_processed,
 				   copied - line->data, pre - line->data,
 				   shift);
-#if defined(USE_COLOR_STYLE)		/* Move styles too */
+#if defined(USE_COLOR_STYLE)	/* Move styles too */
 #define NStyle mod_line->styles[istyle]
-	for (; istyle < line->numstyles && NStyle.horizpos < curlim ; istyle++)
+	for (; istyle < line->numstyles && (int) NStyle.horizpos < curlim ; istyle++)
 	    /* Should not we include OFF-styles at curlim? */
 	    NStyle.horizpos += shift;
 #endif
 	while (copied < pre)	/* Copy verbatim to byte == pre */
 	    *t++ = *copied++;
-	if (ip < ninserts) {		/* Insert spaces */
+	if (ip < ninserts) {	/* Insert spaces */
 	    int delta = newpos[ip] - oldpos[ip] - shift;
 
-	    if (delta < 0) {		/* Not used yet? */
+	    if (delta < 0) {	/* Not used yet? */
 		while (delta++ < 0 && t > newdata && t[-1] == ' ')
 		    t--, shift--;
 	    } else
@@ -2533,6 +2499,8 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7(
 	}
 	ip++;
     }
+    while (pre < s)	/* Copy remaining style-codes */
+	*t++ = *pre++;
     /* Check whether the last anchor continues on the next line */
     if (head_processed && prev_anchor && prev_anchor->line_num == line_number)
 	prev_anchor->extent += shift;
@@ -2763,8 +2731,9 @@ PRIVATE void split_line ARGS2(
 	       underline_on || bold_on ||
 	       alignment != HT_LEFT ||
 	       style->wordWrap || style->freeFormat ||
-	       style->spaceBefore || style->spaceAfter))
+	       style->spaceBefore || style->spaceAfter)) {
 	p--;	/*  Strip trailers. */
+    }
     TailTrim = previous->data + previous->size - 1 - p;	/*  Strip trailers. */
     previous->size -= TailTrim;
     p[1] = '\0';
@@ -2803,12 +2772,12 @@ PRIVATE void split_line ARGS2(
 	 *  The second loop below may then handle remaining changes. - kw */
 	while (from >= previous->styles && to >= line->styles) {
 	    *to = *from;
-	    if (to->horizpos > s_post)
+	    if ((int) to->horizpos > s_post)
 		to->horizpos += - s_post + SpecialAttrChars;
-	    else if (to->horizpos > s_pre &&
+	    else if ((int) to->horizpos > s_pre &&
 		     (to->direction == STACK_ON ||
 		      to->direction == ABS_ON))
-		to->horizpos = (to->horizpos < s) ? 0 : SpecialAttrChars;
+		to->horizpos = ((int) to->horizpos < s) ? 0 : SpecialAttrChars;
 	    else
 		break;
 	    to--;
@@ -2841,7 +2810,7 @@ PRIVATE void split_line ARGS2(
 	    } else if (scan->direction == STACK_ON) {
 		if ( at_end->direction == STACK_ON
 		     && at_end->style == scan->style
-		     && at_end->horizpos >= s_pre )
+		     && (int) at_end->horizpos >= s_pre )
 		    at_end--;
 		else if (at_end >= previous->styles + MAX_STYLES_ON_LINE - 1) {
 		    CTRACE((tfp, "BUG: style overflow before split_line.\n"));
@@ -2866,7 +2835,7 @@ PRIVATE void split_line ARGS2(
 		    break;
 		}
 	    }
-	    if (scan->horizpos > s_pre)
+	    if ((int) scan->horizpos > s_pre)
 		scan->horizpos = s_pre;
 	    scan--;
 	}
@@ -2930,9 +2899,11 @@ PRIVATE void split_line ARGS2(
 	    ctrl_chars_on_previous_line--;
 
 	/* @@ first line indent */
-	spare =  (LYcols-1) -
+	spare =  (WRAP_COLS(text)-1) -
 	    (int)style->rightIndent - indent +
 	    ctrl_chars_on_previous_line - previous->size;
+	if (spare < 0 && LYwideLines)	/* Can be wider than screen */
+	    spare = 0;
 
 	if (spare > 0 && !dump_output_immediately &&
 	    text->T.output_utf8 && ctrl_chars_on_previous_line) {
@@ -3097,7 +3068,7 @@ PRIVATE void split_line ARGS2(
      && justify_max_void_percent > 0
      && justify_max_void_percent <= 100
      && justify_max_void_percent >= ((100*spare)
-				  / ((LYcols - 1)
+				  / ((WRAP_COLS(text) - 1)
 				   - (int)style->rightIndent
 				   - indent
 				   + ctrl_chars_on_previous_line))) {
@@ -3247,6 +3218,7 @@ PRIVATE void split_line ARGS2(
     this_line_was_split = FALSE;
     have_raw_nbsps = FALSE;
 #endif /* EXP_JUSTIFY_ELTS */
+    return;
 } /* split_line */
 
 
@@ -3327,7 +3299,7 @@ PUBLIC void HText_setStyle ARGS2(
 */
 PUBLIC void HText_appendCharacter ARGS2(
 	HText *,	text,
-	char,		ch)
+	int,		ch)
 {
     HTLine * line;
     HTStyle * style;
@@ -3431,7 +3403,7 @@ PUBLIC void HText_appendCharacter ARGS2(
 	unsigned char c;
 	enum _detected_kcode save_d_kcode;
 
-	c = ch;
+	c = UCH(ch);
 	save_d_kcode = text->detected_kcode;
 	switch (text->SJIS_status) {
 	case SJIS_state_has_bad_code:
@@ -3525,8 +3497,9 @@ PUBLIC void HText_appendCharacter ARGS2(
     /*
      *  Make sure we don't hang on escape sequences.
      */
-    if (ch == CH_ESC && HTCJK == NOCJK)			/* decimal 27  S/390 -- gil -- 1504 */
+    if (ch == CH_ESC && HTCJK == NOCJK) {		/* decimal 27  S/390 -- gil -- 1504 */
 	return;
+    }
 #ifndef USE_SLANG
     /*
      *  Block 8-bit chars not allowed by the current display character
@@ -3650,7 +3623,7 @@ PUBLIC void HText_appendCharacter ARGS2(
 			text->kcode = NOKANJI;
 		    }
 		    return;
-		} else if ((0 <= ch) && (ch < 32)) {
+		} else if (UCH(ch) < 32) {
 		    text->state = S_text;
 		    text->kanji_buf = '\0';
 		    if (HTCJK == JAPANESE) {
@@ -3673,19 +3646,7 @@ PUBLIC void HText_appendCharacter ARGS2(
 		} else {
 		    text->kanji_buf = '\216';
 		    ch |= 0200;
-#if 0 /* This conversion is done after. --TH */
-#ifdef SH_EX
-		    /**** Add Next Line by patakuti ****/
-		    text->permissible_split = (int)text->last_line->size;
-		    {
-			unsigned char hi, low;
-			JISx0201TO0208_EUC(0x8e, ch, &hi, &low);
-			text->kanji_buf = hi;
-			ch = low;
 		}
-#endif
-#endif
-	}
 		break;
 	} /* end switch */
 
@@ -3751,7 +3712,8 @@ PUBLIC void HText_appendCharacter ARGS2(
 
     if (IsSpecialAttrChar(ch) && ch != LY_SOFT_NEWLINE) {
 #if !defined(USE_COLOR_STYLE) || !defined(NO_DUMP_WITH_BACKSPACES)
-	if (line->size >= (MAX_LINE-1)) return;
+	if (line->size >= (MAX_LINE-1))
+	    return;
 #if defined(USE_COLOR_STYLE) && !defined(NO_DUMP_WITH_BACKSPACES)
 	if (with_backspaces && HTCJK==NOCJK && !text->T.output_utf8) {
 #endif
@@ -3852,22 +3814,13 @@ PUBLIC void HText_appendCharacter ARGS2(
 		    + utfxtra_on_this_line == 0)
 		    HText_appendCharacter (text, LY_SOFT_NEWLINE);
 	    }
-	    line->data[line->size++] = ch;
+	    line->data[line->size++] = (char) ch;
 	    line->data[line->size] = '\0';
 	    utfxtra_on_this_line++;
 	    ctrl_chars_on_this_line++;
 	    return;
 	} else if (ch & 0x80) {	/* a first char of UTF-8 sequence - kw */
-	    if ((line->size > (MAX_LINE-7))
-#if 0	/* the equivalent check should already happen below */
-		|| (indent + (int)(line->offset + line->size) +
-		    utfxtra_on_this_line - ctrl_chars_on_this_line +
-		    ((line->size > 0) &&
-		     (int)(line->data[line->size-1] ==
-				LY_SOFT_HYPHEN ?
-					     1 : 0)) >= (LYcols_cu))
-#endif /* 0 */
-		) {
+	    if ((line->size > (MAX_LINE-7))) {
 		if (!text->permissible_split || text->source) {
 		    text->permissible_split = line->size;
 		    while (text->permissible_split > 0 &&
@@ -3987,7 +3940,7 @@ PUBLIC void HText_appendCharacter ARGS2(
 	else
 	    target_cu = target + (here_cu - here);
 
-	if (target > (LYcols-1) - (int)style->rightIndent &&
+	if (target > (WRAP_COLS(text)-1) - (int)style->rightIndent &&
 	    HTOutputFormat != WWW_SOURCE) {
 	    new_line(text);
 	} else {
@@ -3995,8 +3948,8 @@ PUBLIC void HText_appendCharacter ARGS2(
 	     *  Can split here. - FM
 	     */
 	    text->permissible_split = line->size;
-	    if (target_cu > (LYcols-1))
-		target -= target_cu - (LYcols-1);
+	    if (target_cu > (WRAP_COLS(text)-1))
+		target -= target_cu - (WRAP_COLS(text)-1);
 	    if (line->size == 0) {
 		line->offset = line->offset + target - here;
 	    } else {
@@ -4018,7 +3971,7 @@ check_WrapSource:
 	 */
 	int target = (int)(line->offset + line->size) - ctrl_chars_on_this_line;
 	int target_cu = target + utfxtra_on_this_line;
-	if (target >= (LYcols-1) - style->rightIndent -
+	if (target >= (WRAP_COLS(text)-1) - style->rightIndent -
 	    (((HTCJK != NOCJK) && text->kanji_buf) ? 1 : 0) ||
 	    (text->T.output_utf8 &&
 	     target_cu + UTF_XLEN(ch) >= (LYcols_cu-1))
@@ -4057,7 +4010,7 @@ check_WrapSource:
      */
     if (text->IgnoreExcess &&
 	(((indent + (int)line->offset + (int)line->size) +
-	  (int)style->rightIndent - ctrl_chars_on_this_line) >= (LYcols-1) ||
+	  (int)style->rightIndent - ctrl_chars_on_this_line) >= (WRAP_COLS(text)-1) ||
 	 ((indent + (int)line->offset + (int)line->size) +
 	  utfxtra_on_this_line - ctrl_chars_on_this_line) >= (LYcols_cu-1)))
 	return;
@@ -4071,7 +4024,7 @@ check_WrapSource:
 	 ((line->size > 0) &&
 	  (int)(line->data[line->size-1] ==
 				LY_SOFT_HYPHEN ?
-					     1 : 0))) >= (LYcols - 1) ||
+					     1 : 0))) >= (WRAP_COLS(text) - 1) ||
 	(text->T.output_utf8 &&
 	 (((indent + (int)line->offset + (int)line->size) +
 	   utfxtra_on_this_line - ctrl_chars_on_this_line +
@@ -4097,8 +4050,9 @@ check_WrapSource:
 		  *  If we don't wrap here we might get a segmentation fault.
 		  *  but let's see what happens
 		  */
-		if ((int)line->size >= (int)(MAX_LINE-1))
+		if ((int)line->size >= (int)(MAX_LINE-1)) {
 		   new_line(text);  /* try not to linewrap */
+		}
 	} else {
 		/*
 		 *  For normal stuff like pre let's go ahead and
@@ -4109,13 +4063,14 @@ check_WrapSource:
 		     && dont_wrap_pre) {
 		    if ((int)line->size >= (int)(MAX_LINE-1))
 			new_line(text);
-		} else
+		} else {
 		    new_line(text);
+		}
 
 	}
     } else if ((int)line->size >= (int)(MAX_LINE-1)) {
 	/*
-	 *  Never overrun memory if LYcols is set to a large value - KW
+	 *  Never overrun memory if DISPLAY_COLS is set to a large value - KW
 	 */
 	new_line(text);
     }
@@ -4181,19 +4136,6 @@ check_WrapSource:
 			text->kcode = NOKANJI;
 		}
 
-#if 0 /* This judgement routine is replaced by above one. -- TH */
-		if (text->kcode == NOKANJI)
-		{
-		    if (IS_SJIS(hi, lo, text->in_sjis) && IS_EUC(hi, lo)) {
-			text->kcode = NOKANJI;
-		    } else if (IS_SJIS(hi, lo, text->in_sjis)) {
-			text->kcode = SJIS;
-		    } else if (IS_EUC(hi, lo)) {
-			text->kcode = EUC;
-		    }
-		}
-#endif
-
 		switch (kanji_code) {
 		case EUC:
 		    if (text->kcode == SJIS) {
@@ -4245,42 +4187,6 @@ check_WrapSource:
 	    }
 	    text->kanji_buf = 0;
 	}
-#if 0
-	if (HTCJK != NOCJK && text->kanji_buf) {
-	    hi = UCH(text->kanji_buf), lo = UCH(ch);
-	    if (HTCJK == JAPANESE && text->kcode == NOKANJI) {
-		if (IS_SJIS(hi, lo, text->in_sjis) && IS_EUC(hi, lo)) {
-		    text->kcode = NOKANJI;
-		} else if (IS_SJIS(hi, lo, text->in_sjis)) {
-		    text->kcode = SJIS;
-		} else if (IS_EUC(hi, lo)) {
-		    text->kcode = EUC;
-		}
-	    }
-	    if (HTCJK == JAPANESE &&
-		(kanji_code == EUC) && (text->kcode == SJIS)) {
-		SJIS_TO_EUC1(hi, lo, tmp);
-		line->data[line->size++] = tmp[0];
-		line->data[line->size++] = tmp[1];
-	    } else if (HTCJK == JAPANESE &&
-		       (kanji_code == EUC) && (text->kcode == EUC)) {
-#ifdef CONV_JISX0201KANA_JISX0208KANA
-		JISx0201TO0208_EUC(hi, lo, &hi, &lo);
-#endif
-		line->data[line->size++] = hi;
-		line->data[line->size++] = lo;
-	    } else if (HTCJK == JAPANESE &&
-		       (kanji_code == SJIS) && (text->kcode == EUC)) {
-		EUC_TO_SJIS1(hi, lo, tmp);
-		line->data[line->size++] = tmp[0];
-		line->data[line->size++] = tmp[1];
-	    } else {
-		line->data[line->size++] = hi;
-		line->data[line->size++] = lo;
-	    }
-	    text->kanji_buf = 0;
-	}
-#endif
 #ifndef CONV_JISX0201KANA_JISX0208KANA
 	else if ((HTCJK == JAPANESE) && IS_SJIS_X0201KANA(UCH((ch))) &&
 		 (kanji_code == EUC)) {
@@ -4314,6 +4220,7 @@ check_WrapSource:
 	    ctrl_chars_on_this_line++;
 	}
     }
+    return;
 }
 
 #ifdef USE_COLOR_STYLE
@@ -4347,7 +4254,7 @@ PUBLIC void _internal_HTC ARGS3(HText *,text, int,style, int,dir)
 	     *  And in UTF-8 display mode all non-initial bytes are
 	     *  counted as ctrl_chars. - kw
 	     */
-	    if (line->styles[line->numstyles].horizpos >= ctrl_chars_on_this_line)
+	    if ((int) line->styles[line->numstyles].horizpos >= ctrl_chars_on_this_line)
 		line->styles[line->numstyles].horizpos -= ctrl_chars_on_this_line;
 	    line->styles[line->numstyles].style     = style;
 	    line->styles[line->numstyles].direction = dir;
@@ -4440,7 +4347,7 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2(
 	return -1;
     else
 	newpos = oldpos + ncols;
-    for (line = me->last_line->next; i < lineno; line = line->next, i++) {
+    for (line = FirstHTLine(me); i < lineno; line = line->next, i++) {
 	if (!line) {
 	    free(oldpos);
 	    return -1;
@@ -4482,8 +4389,10 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2(
 	    if (width > max_width)
 		max_width = width;
 #ifdef EXP_NESTED_TABLES
-	    if (width && last_nonempty < lineno)
-		last_nonempty = lineno;
+	    if (nested_tables) {
+		if (width && last_nonempty < lineno)
+		    last_nonempty = lineno;
+	    }
 #endif
 	    CTRACE((tfp, "line %d true/max width:%d/%d oldpos: NONE\n",
 		   lineno, width, max_width));
@@ -4525,8 +4434,10 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2(
 	    if (width > max_width)
 		max_width = width;
 #ifdef EXP_NESTED_TABLES
-	    if (width && last_nonempty < lineno)
-		last_nonempty = lineno;
+	    if (nested_tables) {
+		if (width && last_nonempty < lineno)
+		    last_nonempty = lineno;
+	    }
 #endif
 	    if (TRACE) {
 		int ip;
@@ -4563,7 +4474,7 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2(
 	alignment = style->alignment;
     indent = style->leftIndent;
     /* Calculate spare character positions */
-    spare = (LYcols-1) -
+    spare = (WRAP_COLS(me)-1) -
 	(int)style->rightIndent - indent - max_width;
     if (spare < 0 && (int)style->rightIndent + spare >= 0) {
 	/*
@@ -4628,8 +4539,10 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2(
 	}
     }
 #ifdef EXP_NESTED_TABLES
-    if (max_width)
-	Stbl_update_enclosing(me->stbl, max_width, last_nonempty);
+    if (nested_tables) {
+	if (max_width)
+	    Stbl_update_enclosing(me->stbl, max_width, last_nonempty);
+    }
 #endif
     CTRACE((tfp, " %d:done\n", lineno));
     free(oldpos);
@@ -4651,17 +4564,16 @@ PUBLIC void HText_cancelStbl ARGS1(
     }
     CTRACE((tfp, "cancelStbl: ok, will do.\n"));
 #ifdef EXP_NESTED_TABLES
-    {
-    STable_info *stbl = me->stbl;
-    while (stbl) {
-	STable_info *enclosing = Stbl_get_enclosing(stbl);
-	Stbl_free(stbl);
-	stbl = enclosing;
-    }
-    }
-#else
-    Stbl_free(me->stbl);
+    if (nested_tables) {
+	STable_info *stbl = me->stbl;
+	while (stbl) {
+	    STable_info *enclosing = Stbl_get_enclosing(stbl);
+	    Stbl_free(stbl);
+	    stbl = enclosing;
+	}
+    } else
 #endif
+    Stbl_free(me->stbl);
     me->stbl = NULL;
 }
 
@@ -4677,18 +4589,25 @@ PUBLIC void HText_startStblTABLE ARGS2(
 
     if (!me)
 	return;
+
 #ifdef EXP_NESTED_TABLES
-    if (current)
-	new_line(me);
-#else
-    if (me->stbl)
-	HText_cancelStbl(me);	/* auto cancel previously open table */
+    if (nested_tables) {
+	if (current)
+	    new_line(me);
+    } else
 #endif
+    {
+	if (me->stbl)
+	    HText_cancelStbl(me);	/* auto cancel previously open table */
+    }
+
     me->stbl = Stbl_startTABLE(alignment);
     if (me->stbl) {
 	CTRACE((tfp, "startStblTABLE: started.\n"));
 #ifdef EXP_NESTED_TABLES
-	Stbl_set_enclosing(me->stbl, current, me->last_anchor_before_stbl);
+	if (nested_tables) {
+	    Stbl_set_enclosing(me->stbl, current, me->last_anchor_before_stbl);
+	}
 #endif
 	me->last_anchor_before_stbl = me->last_anchor;
     } else {
@@ -4723,15 +4642,18 @@ PUBLIC int HText_endStblTABLE ARGS1(
 #endif  /* DISP_PARTIAL */
     }
 #ifdef EXP_NESTED_TABLES
-    enclosing = Stbl_get_enclosing(me->stbl);
-    me->last_anchor_before_stbl = Stbl_get_last_anchor_before(me->stbl);
+    if (nested_tables) {
+	enclosing = Stbl_get_enclosing(me->stbl);
+	me->last_anchor_before_stbl = Stbl_get_last_anchor_before(me->stbl);
+    } else
 #endif
     Stbl_free(me->stbl);
 #ifdef EXP_NESTED_TABLES
-    me->stbl = enclosing;
-#else
-    me->stbl = NULL;
+    if (nested_tables)
+	me->stbl = enclosing;
+    else
 #endif
+    me->stbl = NULL;
     return enclosing != 0;
 }
 
@@ -4907,7 +4829,7 @@ PUBLIC int HText_beginAnchor ARGS3(
 }
 
 /* If !really, report whether the anchor is empty. */
-PRIVATE int HText_endAnchor0 ARGS3(
+PRIVATE BOOL HText_endAnchor0 ARGS3(
 	HText *,	text,
 	int,		number,
 	int,		really)
@@ -4951,7 +4873,7 @@ PRIVATE int HText_endAnchor0 ARGS3(
 
 	CTRACE((tfp,
 	   "BUG: HText_endAnchor0: internal error: last anchor was input field!\n"));
-	return 0;
+	return FALSE;
     }
     if (a->number) {
 	/*
@@ -5099,7 +5021,7 @@ PRIVATE int HText_endAnchor0 ARGS3(
 	}
 	if (!really) {			/* Just report whether it is empty */
 	    a->extent -= extent_adjust;
-	    return i==0;
+	    return (BOOL)(i == 0);
 	}
 	if (i == 0) {
 	    /*
@@ -5111,7 +5033,7 @@ PRIVATE int HText_endAnchor0 ARGS3(
 
 	    CTRACE((tfp,
 		   "HText_endAnchor0: hidden (line,pos,ext,BlankExtent):(%d,%d,%d,%d)",
-		   a->line_num,a->line_pos,a->extent,
+		   a->line_num, a->line_pos, a->extent,
 		   BlankExtent));
 
 	    /*
@@ -5364,7 +5286,7 @@ PRIVATE int HText_endAnchor0 ARGS3(
 	}
     } else {
 	if (!really)			/* Just report whether it is empty */
-	    return 0;
+	    return FALSE;
 	/*
 	 *  It's a named anchor without an HREF, so it
 	 *  should be registered but not shown as a
@@ -5373,7 +5295,7 @@ PRIVATE int HText_endAnchor0 ARGS3(
 	a->show_anchor = NO;
 	a->extent = 0;
     }
-    return 0;
+    return FALSE;
 }
 
 PUBLIC void HText_endAnchor ARGS2(
@@ -5478,7 +5400,7 @@ PUBLIC void HText_endAppend ARGS1(
     /*
      *  Get the first line.
      */
-    line_ptr = text->last_line->next;
+    line_ptr = FirstHTLine(text);
 
     /*
      *  Remove the blank lines at the end of document.
@@ -5559,7 +5481,7 @@ PUBLIC void HText_trimHightext ARGS3(
     /*
      *  Get the first line.
      */
-    line_ptr = text->last_line->next;
+    line_ptr = FirstHTLine(text);
     cur_line = 0;
 
     /*
@@ -5569,7 +5491,7 @@ PUBLIC void HText_trimHightext ARGS3(
     for (anchor_ptr = text->first_anchor;
 	anchor_ptr;
 	prev_a = anchor_ptr, anchor_ptr=anchor_ptr->next) {
-	int have_soft_newline_in_1st_line=0;
+	int have_soft_newline_in_1st_line = 0;
 re_parse:
 	/*
 	 *  Find the right line.
@@ -5912,7 +5834,7 @@ PUBLIC int HTGetRelLinkNum ARGS3(
      * -- find previous closest numbered link
      */
     for (a = HTMainText->first_anchor; a; a = a->next) {
-	CTRACE((tfp,"  a->line_num=%d, a->number=%d\n",a->line_num,a->number));
+	CTRACE((tfp,"  a->line_num=%d, a->number=%d\n", a->line_num, a->number));
 	if ( a->line_num >= scrtop ) break;
 	if ( a->number == 0 ) continue;
 	l = a;
@@ -6388,13 +6310,6 @@ PUBLIC int HTGetLinkOrFieldStart ARGS5(
 	    if (*go_line <= group_to_go->prev_anchor_line)
 		*go_line = group_to_go->prev_anchor_line + 1;
 
-#if 0
-	    if (*go_line > HTMainText->top_of_screen &&
-		*go_line < HTMainText->top_of_screen+(display_lines) &&
-		HTMainText->top_of_screen+(display_lines) <= a->line_num &&
-		HTMainText->top_of_screen+2*(display_lines) <= HTMainText->Lines)
-		*go_line = HTMainText->top_of_screen+(display_lines);
-#endif
 	    if (*go_line < 0)
 		*go_line = 0;
 	    if (linknum)
@@ -6441,7 +6356,7 @@ PUBLIC BOOL HText_getFirstTargetInLine ARGS7(
     /*
      *  Find the line and set up its data and offset - FM
      */
-    for (i = 0, line = text->last_line->next;
+    for (i = 0, line = FirstHTLine(text);
 	 i < line_num && (line != text->last_line);
 	 i++, line = line->next) {
 	if (line->next == NULL) {
@@ -6459,18 +6374,12 @@ PUBLIC BOOL HText_getFirstTargetInLine ARGS7(
      *  strip any special characters from the loaded line
      *  data, and return TRUE. - FM
      */
-    if ((case_sensitive ?
-	 (cp = LYno_attr_mbcs_strstr(LineData,
-				     target,
-				     utf_flag, YES,
-				     &HitOffset,
-				     &LenNeeded)) != NULL :
-	 (cp = LYno_attr_mbcs_case_strstr(LineData,
-				     target,
-				     utf_flag, YES,
-				     &HitOffset,
-				     &LenNeeded)) != NULL) &&
-	(LineOffset + LenNeeded) < LYcols) {
+    if (((cp = LYno_attr_mb_strstr(LineData,
+				   target,
+				   utf_flag, YES,
+				   &HitOffset,
+				   &LenNeeded)) != NULL) &&
+	(LineOffset + LenNeeded) < DISPLAY_COLS) {
 	/*
 	 *  We had a hit so load the results,
 	 *  remove IsSpecial characters from
@@ -6909,7 +6818,7 @@ PUBLIC BOOL HText_select ARGS1(
 	/* text->UCLYhndl is not reset by META, so use a more circumvent way */
 	if ( text->node_anchor->UCStages->s[UCT_STAGE_HTEXT].LYhndl
 	     != current_char_set )
-	    Switch_Display_Charset(text->node_anchor->UCStages->s[UCT_STAGE_HTEXT].LYhndl, 0);
+	    Switch_Display_Charset(text->node_anchor->UCStages->s[UCT_STAGE_HTEXT].LYhndl, SWITCH_DISPLAY_CHARSET_MAYBE);
 #endif
 	if (HTMainText) {
 	    if (HText_hasUTF8OutputSet(HTMainText) &&
@@ -7262,7 +7171,7 @@ PUBLIC int do_www_search ARGS1(
 	_statusline(EDIT_CURRENT_QUERY);
     QueryTotal = (search_queries ? HTList_count(search_queries) : 0);
     recall = (((PreviousSearch && QueryTotal >= 2) ||
-	       (!PreviousSearch && QueryTotal >= 1)) ? RECALL : NORECALL);
+	       (!PreviousSearch && QueryTotal >= 1)) ? RECALL_URL : NORECALL);
     QueryNum = QueryTotal;
 get_query:
     if ((ch=LYgetstr(searchstring, VISIBLE,
@@ -7467,7 +7376,7 @@ PUBLIC void print_wwwfile_to_fd ARGS2(
     if (!HTMainText)
 	return;
 
-    line = HTMainText->last_line->next;
+    line = FirstHTLine(HTMainText);
     for (;; line = line->next) {
 	if (!first && line->data[0] != LY_SOFT_NEWLINE) {
 	    fputc('\n',fp);
@@ -7565,7 +7474,7 @@ PUBLIC void print_crawl_to_fd ARGS3(
     if (!HTMainText)
 	return;
 
-    line = HTMainText->last_line->next;
+    line = FirstHTLine(HTMainText);
     fprintf(fp, "THE_URL:%s\n", thelink);
     if (thetitle != NULL) {
 	fprintf(fp, "THE_TITLE:%s\n", thetitle);
@@ -7680,199 +7589,238 @@ PRIVATE void adjust_search_result ARGS3(
     }
 }
 
-/*
-   John Bley, April 1, 1999 (No joke)
-   www_user_search_internals was spawned from www_user_search to
-   remove a cut-n-paste coding hack: basically, this entire function
-   was duplicated at the two points that www_user_search now calls it.
-   And, because www_user_search has a return value defined as modification
-   of the screen and some global values, and since it used an awkward for(;;)
-   construct, this method has to distinguish between when it's "really"
-   returning and when it's just falling through via a break; in the
-   infinite-for-loop.  So, basically, we have a large amount of arguments
-   since this loop used to be directly in www_user_search, and we return
-   1 to say we're "really" returning and 0 to indicate we fell through.
-   Also, due to exactly one difference between the first pass of this
-   code and the second pass, we have the "firstpass" argument, which is
-   true iff it's the first pass.
-
-   I hate cut-n-paste coding.
+PRIVATE BOOL anchor_has_target ARGS2(
+	TextAnchor *,	a,
+	char *,		target)
+{
+    OptionType * option;
+    char *stars = NULL, *cp;
+
+    /*
+     *  Search the hightext string, and hightext2 if present,
+     *  taking the case_sensitive setting into account. - FM
+     */
+    if (LYno_attr_strstr(a->hightext, target)
+     || LYno_attr_strstr(a->hightext2, target)) {
+	return TRUE;
+    }
+
+    /*
+     *  Search the relevant form fields, taking the
+     *  case_sensitive setting into account. - FM
+     */
+    if ((a->input_field != NULL && a->input_field->value != NULL) &&
+	a->input_field->type != F_HIDDEN_TYPE) {
+	if (a->input_field->type == F_PASSWORD_TYPE) {
+	    /*
+	     *  Check the actual, hidden password, and then
+	     *  the displayed string. - FM
+	     */
+	    if (LYno_attr_strstr(a->input_field->value, target)) {
+		return TRUE;
+	    }
+	    StrAllocCopy(stars, a->input_field->value);
+	    for (cp = stars; *cp != '\0'; cp++)
+		*cp = '*';
+	    if (LYno_attr_strstr(stars, target)) {
+		FREE(stars);
+		return TRUE;
+	    }
+	    FREE(stars);
+       } else if (a->input_field->type == F_OPTION_LIST_TYPE) {
+	    /*
+	     *  Search the option strings that are displayed
+	     *  when the popup is invoked. - FM
+	     */
+	    option = a->input_field->select_list;
+	    while (option != NULL) {
+		if (LYno_attr_strstr(option->name, target)) {
+		    return TRUE;
+		}
+		option = option->next;
+	    }
+	} else if (a->input_field->type == F_RADIO_TYPE) {
+	    /*
+	     *  Search for checked or unchecked parens. - FM
+	     */
+	    if (a->input_field->num_value) {
+		cp = checked_radio;
+	    } else {
+		cp = unchecked_radio;
+	    }
+	    if (LYno_attr_strstr(cp, target)) {
+		return TRUE;
+	    }
+	} else if (a->input_field->type == F_CHECKBOX_TYPE) {
+	    /*
+	     *  Search for checked or unchecked square brackets. - FM
+	     */
+	    if (a->input_field->num_value) {
+		cp = checked_box;
+	    } else {
+		cp = unchecked_box;
+	    }
+	    if (LYno_attr_strstr(cp, target)) {
+		return TRUE;
+	    }
+	} else {
+	    /*
+	     *  Check the values intended for display.
+	     *  May have been found already via the
+	     *  hightext search, but make sure here
+	     *  that the entire value is searched. - FM
+	     */
+	    if (LYno_attr_strstr(a->input_field->value, target)) {
+		return TRUE;
+	    }
+	}
+    }
+    return FALSE;
+}
+
+PRIVATE TextAnchor *line_num_to_anchor ARGS1(
+    int,	line_num)
+{
+    TextAnchor *a;
+
+    if (HTMainText != 0) {
+	a = HTMainText->first_anchor;
+	while (a != 0 && a->line_num < line_num) {
+	    a = a->next;
+	}
+    } else {
+	a = 0;
+    }
+    return a;
+}
+
+PRIVATE int line_num_in_text ARGS2(
+    HText *,		text,
+    HTLine *,		line)
+{
+    int result = 1;
+    HTLine *temp = FirstHTLine(text);
+
+    while (temp != line) {
+	temp = temp->next;
+	++result;
+    }
+    return result;
+}
+
+/* Computes the 'prev' pointers on demand, and returns the one for the given
+ * anchor.
  */
-PRIVATE int www_user_search_internals ARGS8(
-	int,		firstpass,
+PRIVATE TextAnchor *get_prev_anchor ARGS1(
+    TextAnchor *,	a)
+{
+    TextAnchor *p, *q;
+
+    if (a->prev == 0) {
+	if ((p = HTMainText->first_anchor) != 0) {
+	    while ((q = p->next) != 0) {
+		q->prev = p;
+		p = q;
+	    }
+	}
+    }
+    return a->prev;
+}
+
+PRIVATE int www_search_forward ARGS5(
 	int,		start_line,
 	document *,	doc,
 	char *,		target,
-	TextAnchor *,	a,
 	HTLine *,	line,
-	int *,		count,
-	int *,		tentative_result)
+	int,		count)
 {
-    OptionType * option;
-    char *stars = NULL, *cp;
+    BOOL wrapped = FALSE;
+    TextAnchor *a = line_num_to_anchor(count - 1);
+    int tentative_result = -1;
 
     for (;;) {
-	while ((a != NULL) && a->line_num == (*count - 1)) {
+	while ((a != NULL) && a->line_num == (count - 1)) {
 	    if (a->show_anchor &&
 		!(a->link_type == INPUT_ANCHOR
 		  && a->input_field->type == F_HIDDEN_TYPE)) {
-		if (((a->hightext != NULL && case_sensitive == TRUE) &&
-		     LYno_attr_char_strstr(a->hightext, target)) ||
-		    ((a->hightext != NULL && case_sensitive == FALSE) &&
-		     LYno_attr_char_case_strstr(a->hightext, target))) {
-		    adjust_search_result(doc, *count, start_line);
-		    return 1;
-		}
-		if (((a->hightext2 != NULL && case_sensitive == TRUE) &&
-		     LYno_attr_char_strstr(a->hightext2, target)) ||
-		    ((a->hightext2 != NULL && case_sensitive == FALSE) &&
-		     LYno_attr_char_case_strstr(a->hightext2, target))) {
-		    adjust_search_result(doc, *count, start_line);
+		if (anchor_has_target(a, target)) {
+		    adjust_search_result(doc, count, start_line);
 		    return 1;
 		}
-
-		/*
-		 *  Search the relevant form fields, taking the
-		 *  case_sensitive setting into account. - FM
-		 */
-		if ((a->input_field != NULL && a->input_field->value != NULL) &&
-		    a->input_field->type != F_HIDDEN_TYPE) {
-		    if (a->input_field->type == F_PASSWORD_TYPE) {
-			/*
-			 *  Check the actual, hidden password, and then
-			 *  the displayed string. - FM
-			 */
-			if (((case_sensitive == TRUE) &&
-			     LYno_attr_char_strstr(a->input_field->value,
-						   target)) ||
-			    ((case_sensitive == FALSE) &&
-			     LYno_attr_char_case_strstr(a->input_field->value,
-							target))) {
-			    adjust_search_result(doc, *count, start_line);
-			    return 1;
-			}
-			StrAllocCopy(stars, a->input_field->value);
-			for (cp = stars; *cp != '\0'; cp++)
-			    *cp = '*';
-			if (((case_sensitive == TRUE) &&
-			     LYno_attr_char_strstr(stars, target)) ||
-			    ((case_sensitive == FALSE) &&
-			     LYno_attr_char_case_strstr(stars, target))) {
-			    FREE(stars);
-			    adjust_search_result(doc, *count, start_line);
-			    return 1;
-			}
-			FREE(stars);
-		   } else if (a->input_field->type == F_OPTION_LIST_TYPE) {
-			/*
-			 *  Search the option strings that are displayed
-			 *  when the popup is invoked. - FM
-			 */
-			option = a->input_field->select_list;
-			while (option != NULL) {
-			    if (((option->name != NULL &&
-				  case_sensitive == TRUE) &&
-				 LYno_attr_char_strstr(option->name,
-						       target)) ||
-				((option->name != NULL &&
-				  case_sensitive == FALSE) &&
-				 LYno_attr_char_case_strstr(option->name,
-							    target))) {
-				adjust_search_result(doc, *count, start_line);
-				return 1;
-			    }
-			    option = option->next;
-			}
-		    } else if (a->input_field->type == F_RADIO_TYPE) {
-			/*
-			 *  Search for checked or unchecked parens. - FM
-			 */
-			if (a->input_field->num_value) {
-			    cp = checked_radio;
-			} else {
-			    cp = unchecked_radio;
-			}
-			if (((case_sensitive == TRUE) &&
-			     LYno_attr_char_strstr(cp, target)) ||
-			    ((case_sensitive == FALSE) &&
-			     LYno_attr_char_case_strstr(cp, target))) {
-			    adjust_search_result(doc, *count, start_line);
-			    return 1;
-			}
-		    } else if (a->input_field->type == F_CHECKBOX_TYPE) {
-			/*
-			 *  Search for checked or unchecked
-			 *  square brackets. - FM
-			 */
-			if (a->input_field->num_value) {
-			    cp = checked_box;
-			} else {
-			    cp = unchecked_box;
-			}
-			if (((case_sensitive == TRUE) &&
-			     LYno_attr_char_strstr(cp, target)) ||
-			    ((case_sensitive == FALSE) &&
-			     LYno_attr_char_case_strstr(cp, target))) {
-			    adjust_search_result(doc, *count, start_line);
-			    return 1;
-			}
-		    } else {
-			/*
-			 *  Check the values intended for display.
-			 *  May have been found already via the
-			 *  hightext search, but make sure here
-			 *  that the entire value is searched. - FM
-			 */
-			if (((case_sensitive == TRUE) &&
-			     LYno_attr_char_strstr(a->input_field->value,
-						   target)) ||
-			    ((case_sensitive == FALSE) &&
-			     LYno_attr_char_case_strstr(a->input_field->value,
-							target))) {
-			    adjust_search_result(doc, *count, start_line);
-			    return 1;
-			}
-		    }
-		}
 	    }
 	    a = a->next;
 	}
-	if (a != NULL && a->line_num <= (*count - 1)) {
-	    a = a->next;
-	}
 
-	if (case_sensitive && LYno_attr_char_strstr(line->data, target)) {
-	    *tentative_result = *count;
+	if (LYno_attr_strstr(line->data, target)) {
+	    tentative_result = count;
 	    break;
-	} else if (!case_sensitive &&
-		   LYno_attr_char_case_strstr(line->data, target)) {
-	    *tentative_result = *count;
-	    break;
-	/* Note: this is where the two passes differ */
-	} else if (firstpass && line == HTMainText->last_line) {
-	    /* next line */
+	} else if (line == HTMainText->last_line) {
+	    count = 0;
+	    wrapped = TRUE;
+	} else if (count == start_line && wrapped) {
+	    HTUserMsg2(STRING_NOT_FOUND, target);
+	    return -1;
+	}
+	line = line->next;
+	count++;
+    }
+    if (tentative_result > 0) {
+	adjust_search_result(doc, tentative_result, start_line);
+    }
+    return 0;
+}
+
+PRIVATE int www_search_backward ARGS5(
+	int,		start_line,
+	document *,	doc,
+	char *,		target,
+	HTLine *,	line,
+	int,		count)
+{
+    BOOL wrapped = FALSE;
+    TextAnchor *a = line_num_to_anchor(count - 1);
+    int tentative_result = -1;
+
+    for (;;) {
+	while ((a != NULL) && a->line_num == (count - 1)) {
+	    if (a->show_anchor &&
+		!(a->link_type == INPUT_ANCHOR
+		  && a->input_field->type == F_HIDDEN_TYPE)) {
+		if (anchor_has_target(a, target)) {
+		    adjust_search_result(doc, count, start_line);
+		    return 1;
+		}
+	    }
+	    a = get_prev_anchor(a);
+	}
+
+	if (LYno_attr_strstr(line->data, target)) {
+	    tentative_result = count;
 	    break;
-	} else if (!firstpass && *count > start_line) {
+	} else if (line == FirstHTLine(HTMainText)) {
+	    count = line_num_in_text(HTMainText, LastHTLine(HTMainText)) + 1;
+	    wrapped = TRUE;
+	} else if (count == start_line && wrapped) {
 	    HTUserMsg2(STRING_NOT_FOUND, target);
-	    return 1;			/* end */
-	} else {			/* end */
-	    line = line->next;
-	    (*count)++;
+	    return -1;
 	}
+	line = line->prev;
+	count--;
+    }
+    if (tentative_result > 0) {
+	adjust_search_result(doc, tentative_result, start_line);
     }
-    /* No, man, we just fell through.  You want to call us again. */
     return 0;
 }
 
-PUBLIC void www_user_search ARGS3(
+PUBLIC void www_user_search ARGS4(
 	int,		start_line,
 	document *,	doc,
-	char *,		target)
+	char *,		target,
+	int,		direction)
 {
     HTLine * line;
     int count;
-    int tentative_result = -1;
-    TextAnchor *a;
 
     if (!HTMainText) {
 	return;
@@ -7881,41 +7829,24 @@ PUBLIC void www_user_search ARGS3(
     /*
      *  Advance to the start line.
      */
-    line = HTMainText->last_line->next;
-    for (count = 1; count <= start_line; line = line->next, count++) {
-	if (line == HTMainText->last_line) {
-	    line = HTMainText->last_line->next; /* set to first line */
-	    count = 1;
-	    break;
+    line = FirstHTLine(HTMainText);
+    if (start_line + direction > 0) {
+	for (count = 1; count < start_line + direction; line = line->next, count++) {
+	    if (line == HTMainText->last_line) {
+		line = FirstHTLine(HTMainText);
+		count = 1;
+		break;
+	    }
 	}
-    }
-    a = HTMainText->first_anchor;
-    while (a && a->line_num < count - 1) {
-	a = a->next;
-    }
-    if (www_user_search_internals(1, start_line, doc, target,
-	a, line, &count, &tentative_result) == 1) {
-	return; /* Return the www_user_search_internals result */
+    } else {
+	line = HTMainText->last_line;
+	count = line_num_in_text(HTMainText, line);
     }
 
-    if (tentative_result > 0) {
-	adjust_search_result(doc, tentative_result, start_line);
-	return;
-    }
-    /* That didn't work, search from the beginning instead */
-    line = HTMainText->last_line->next; /* set to first line */
-    count = 1;
-    a = HTMainText->first_anchor;
-    while (a && a->line_num < count - 1) {
-	a = a->next;
-    }
-    if (www_user_search_internals(0, start_line, doc, target,
-	a, line, &count, &tentative_result) == 1) {
-	return; /* Return the www_user_search_internals result */
-    }
-    if (tentative_result > 0) {
-	adjust_search_result(doc, tentative_result, start_line);
-    }
+    if (direction >= 0)
+	www_search_forward(start_line, doc, target, line, count);
+    else
+	www_search_backward(start_line, doc, target, line, count);
 }
 
 PUBLIC void user_message ARGS2(
@@ -8043,9 +7974,6 @@ PRIVATE HTProtocol scm = { "source-cache-mem", 0, 0 }; /* dummy - kw */
 PUBLIC BOOLEAN HTreparse_document NOARGS
 {
     BOOLEAN ok = FALSE;
-#if 0
-    char *source_url = NULL;	/* unused - see comments below */
-#endif
 
     if (!HTMainAnchor || LYCacheSource == SOURCE_CACHE_NONE ||
 	(LYCacheSource == SOURCE_CACHE_FILE &&
@@ -8104,11 +8032,6 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	 * the SourceCacheWriter to not regenerate the cache file (which
 	 * would be an unnecessary "loop"). - kw
 	 */
-#if 0 /* If cache writer looked at physical not protocol, we could use this: */
-	LYLocalFileToURL(&source_url, HTMainAnchor->source_cache_file);
-	HTAnchor_setPhysical(HTMainAnchor, source_url);
-	FREE(source_url);
-#endif /* 0 */
 	HTAnchor_setProtocol(HTMainAnchor, &HTFile);
 	ret = HTParseFile(format, HTOutputFormat, HTMainAnchor, fp, NULL);
 	LYCloseInput(fp);
@@ -8164,12 +8087,6 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	 */
 	HTAnchor_setProtocol(HTMainAnchor, &scm); /* cheating -
 				   anything != &HTTP or &HTTPS would do - kw */
-#if 0 /* If cache writer looked at physical not protocol, we could use this: */
-	HTSprintf0(&source_url, "source-cache-mem:%p",
-		   HTMainAnchor->source_cache_chunk);
-	HTAnchor_setPhysical(HTMainAnchor, source_url);
-	FREE(source_url);
-#endif /* 0 */
 	ret = HTParseMem(format, HTOutputFormat, HTMainAnchor,
 			HTMainAnchor->source_cache_chunk, NULL);
 	ok = (BOOL) (ret == HT_LOADED);
@@ -8203,12 +8120,12 @@ PUBLIC BOOLEAN HTcan_reparse_document NOARGS
 
 PRIVATE void trace_setting_change ARGS3(
 	CONST char *,	name,
-	BOOLEAN,	prev_setting,
-	BOOLEAN,	new_setting)
+	int,		prev_setting,
+	int,		new_setting)
 {
     if (prev_setting != new_setting)
-	CTRACE((tfp, "HTdocument_settings_changed: %s setting has changed (was %s, now %s)\n",
-	       name, prev_setting ? "ON" : "OFF", new_setting ? "ON" : "OFF"));
+	CTRACE((tfp, "HTdocument_settings_changed: %s setting has changed (was %d, now %d)\n",
+	       name, prev_setting, new_setting));
 }
 
 PUBLIC BOOLEAN HTdocument_settings_changed NOARGS
@@ -8248,10 +8165,10 @@ PUBLIC BOOLEAN HTdocument_settings_changed NOARGS
 	trace_setting_change("OLD_DTD", HTMainText->old_dtd, Old_DTD);
 	trace_setting_change("KEYPAD_MODE",
 			     HTMainText->keypad_mode, keypad_mode);
-	if (HTMainText->disp_lines != LYlines || HTMainText->disp_cols != LYcols)
+	if (HTMainText->disp_lines != LYlines || HTMainText->disp_cols != DISPLAY_COLS)
 	    CTRACE((tfp,
 		   "HTdocument_settings_changed: Screen size has changed (was %dx%d, now %dx%d)\n",
-		   HTMainText->disp_cols, HTMainText->disp_lines, LYcols, LYlines));
+		   HTMainText->disp_cols, HTMainText->disp_lines, DISPLAY_COLS, LYlines));
     }
 
     return (HTMainText->clickable_images != clickable_images ||
@@ -8264,7 +8181,7 @@ PUBLIC BOOLEAN HTdocument_settings_changed NOARGS
 	    HTMainText->soft_dquotes != soft_dquotes ||
 	    HTMainText->old_dtd != Old_DTD ||
 	    HTMainText->keypad_mode != keypad_mode ||
-	    HTMainText->disp_cols != LYcols);
+	    HTMainText->disp_cols != DISPLAY_COLS);
 }
 #endif
 
@@ -8497,10 +8414,10 @@ PUBLIC int HText_getCurrentColumn ARGS1(
 PUBLIC int HText_getMaximumColumn ARGS1(
 	HText *,	text)
 {
-    int column = (LYcols-2);
+    int column = (DISPLAY_COLS-2);
     if (text) {
-	column = ((int)text->style->rightIndent ? (LYcols-2) :
-		  ((LYcols-1) - (int)text->style->rightIndent));
+	column = ((int)text->style->rightIndent ? (DISPLAY_COLS-2) :
+		  ((DISPLAY_COLS-1) - (int)text->style->rightIndent));
     }
     return column;
 }
@@ -9047,7 +8964,7 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
 	} else {
 	    while (op_ptr->next) {
 		number++;
-		op_ptr=op_ptr->next;
+		op_ptr = op_ptr->next;
 	    }
 	    number++;  /* add one more */
 
@@ -9609,7 +9526,7 @@ PUBLIC int HText_beginInput ARGS3(
 	     *  text entry lines can be long, and will be scrolled
 	     *  horizontally within the editing window. - FM
 	     */
-	    MaximumSize = (LYcols - 1) -
+	    MaximumSize = (WRAP_COLS(text) - 1) -
 			  (int)text->style->leftIndent -
 			  (int)text->style->rightIndent;
 
@@ -9639,8 +9556,8 @@ PUBLIC int HText_beginInput ARGS3(
 	     *  are types with small placeholders, and/or are a
 	     *  type which is handled via a popup window. - FM
 	     */
-	    if (f->size > LYcols-10)
-		f->size = LYcols-10;  /* maximum */
+	    if (f->size > WRAP_COLS(text)-10)
+		f->size = WRAP_COLS(text)-10;  /* maximum */
 	    break;
     }
 
@@ -9963,7 +9880,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 		     p && *p && !(field_has_8bit && field_has_special);
 		     p++)
 		    if ((*p == HT_NON_BREAK_SPACE) ||
-		       (*p == HT_EN_SPACE) ||
+		        (*p == HT_EN_SPACE) ||
 			(*p == LY_SOFT_HYPHEN)) {
 			field_has_special = YES;
 		    } else if ((*p & 0x80) != 0) {
@@ -11184,10 +11101,6 @@ PUBLIC void HText_setKcode ARGS3(
 	       !strcmp(charset, "x-euc") ||	/* 1997/11/28 (Fri) 18:11:24 */
 	       !strcmp(charset, "euc-jp") ||
 	       !strncmp(charset, "x-euc-", 6) ||
-#if 0 /* iso-2022-jp* shouldn't be treated as euc-jp */
-	       !strcmp(charset, "iso-2022-jp") ||
-	       !strcmp(charset, "iso-2022-jp-2") ||
-#endif
 	       !strcmp(charset, "euc-kr") ||
 	       !strcmp(charset, "iso-2022-kr") ||
 	       !strcmp(charset, "big5") ||
@@ -11500,6 +11413,7 @@ PRIVATE int increment_tagged_htline ARGS6(
     int   n;
     int   new_n;
     int   pre_n;
+    int   post_n;
     int   fixup = 0;
 
 
@@ -11549,7 +11463,7 @@ PRIVATE int increment_tagged_htline ARGS6(
 		    plx   = TRUE;
 		    break;
 		}
-		if (isdigit(UCH(*t++)) != 0) {
+		if (isdigit(UCH(*t++))) {
 		    n++;
 		    continue;
 		} else {
@@ -11568,7 +11482,7 @@ PRIVATE int increment_tagged_htline ARGS6(
 	     *   nn), one of which is the [tag], and the other being part of
 	     *   a document.  In such a case, the 1st [nn] string will get
 	     *   incremented; the 2nd one won't, which makes it a 50-50 chance
-	     *   of being correct, if and when such an unlikely juxitposition
+	     *   of being correct, if and when such an unlikely juxtaposition
 	     *   of text ever occurs.  Further validation tests of the [nnn]
 	     *   string are probably not possible, since little of the actual
 	     *   anchor-associated-text is retained in the TextAnchor or the
@@ -11590,7 +11504,7 @@ PRIVATE int increment_tagged_htline ARGS6(
 		    /*
 		     *  If the number of digits in an existing [tag] increased
 		     *  (eg, [99] --> [100], etc), we need to "adjust" its
-		     *  horizontal position, and that of all subsequant tags
+		     *  horizontal position, and that of all subsequent tags
 		     *  that may be on the same line.  PITA.
 		     *
 		     *  [This seems to work as long as a tag isn't a line
@@ -11618,7 +11532,7 @@ PRIVATE int increment_tagged_htline ARGS6(
 			if (st_anchor) st_anchor = st_anchor->next;
 		    }
 		}
-	   }
+	    }
 
 	    /*
 	     *  Unfortunately, valid [tag] strings *can* be split across two
@@ -11631,9 +11545,11 @@ PRIVATE int increment_tagged_htline ARGS6(
 	     *
 	     *  We use lxbuf[] to deal with the two lines involved.
 	     */
-	    if (plx) {
+	    pre_n = strlen (p);	/* count of 1st part chars in this line */
+	    post_n = strlen(ht->next->data);
+	    if (plx
+	     && (pre_n + post_n + 2 < (int) sizeof(lxbuf))) {
 		strcpy (lx, p);      /* <- 1st part of a possible lx'ing tag */
-		pre_n = strlen (p);  /* count of 1st part chars in this line */
 		strcat (lx, ht->next->data);   /* tack on NEXT line	     */
 
 		t     = lx;
@@ -11644,7 +11560,7 @@ PRIVATE int increment_tagged_htline ARGS6(
 		 *  Go hunting again for just digits, followed by tag end ']'.
 		 */
 		while (*t != ']') {
-		    if (isdigit(UCH(*t++)) != 0) {
+		    if (isdigit(UCH(*t++))) {
 			n++;
 			continue;
 		    } else {
@@ -11659,7 +11575,9 @@ PRIVATE int increment_tagged_htline ARGS6(
 		 *  above], and if it matches, increment it into the buffer,
 		 *  along with the 2nd line's text.
 		 */
-		if ((valid) && (n > 0)) {
+		if ((valid)
+		 && (n > 0)
+		 && (n + post_n + 2) < MAX_LINE) {
 		    val = atoi (lx);
 		    if ((val == *old_val) || (*old_val == 0)) {
 			if (*old_val != 0)
@@ -11737,7 +11655,7 @@ PRIVATE void insert_new_textarea_anchor ARGS2(
      *   YAS (Yet Another Struct), but there are too many structs{}
      *   floating around in here, as it is.  IMNSHO.]
      */
-    for (htline = HTMainText->last_line->next, i = 0;
+    for (htline = FirstHTLine(HTMainText), i = 0;
 	 anchor->line_num != i;                i++) {
 	htline = htline->next;
 	if (htline == HTMainText->last_line)
@@ -11904,7 +11822,7 @@ PRIVATE void update_subsequent_anchors ARGS4(
      */
     if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
 	anchor = start_anchor->next;
-	while (htline != HTMainText->last_line->next) {
+	while (htline != FirstHTLine(HTMainText)) {
 
 	    while (anchor) {
 		if ((anchor->number - n) == start_tag)
@@ -11964,7 +11882,7 @@ finish:
 
     return;
 
-hang_detected:  /* uglyness has happened; inform user and do the best we can */
+hang_detected:  /* ugliness has happened; inform user and do the best we can */
 
     HTAlert(gettext("Hang Detect: TextAnchor struct corrupted - suggest aborting!"));
     goto finish;
@@ -11991,7 +11909,6 @@ PUBLIC int HText_ExtEditForm ARGS1(
 
     char       *ed_temp;
     FILE       *fp;
-    int		rv;
 
     TextAnchor *anchor_ptr;
     TextAnchor *start_anchor  = NULL;
@@ -12013,7 +11930,6 @@ PUBLIC int HText_ExtEditForm ARGS1(
     HTLine     *htline	 = NULL;
 
     char       *ebuf;
-    char       *tbuf = NULL;
     char       *line;
     char       *lp;
     char       *cp;
@@ -12089,47 +12005,9 @@ PUBLIC int HText_ExtEditForm ARGS1(
      */
     ed_offset[0] = 0; /* pre-ANSI compilers don't initialize aggregates - TD */
     if (((entry_line - start_line) > 0) && editor_can_position())
-#ifdef VMS
-	sprintf (ed_offset, "-%d", ((entry_line - start_line) + 1));
-    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_temp, ed_offset);
-#else
-	sprintf (ed_offset, "+%d", ((entry_line - start_line) + 1));
-    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_offset, ed_temp);
-#endif
+	sprintf (ed_offset, "%d", ((entry_line - start_line) + 1));
 
-#ifdef UNIX
-    set_errno(0);
-#endif
-    rv = LYSystem (tbuf);	/* finally the editor is called */
-    if (rv) {
-	/*
-	 *  If something went wrong, we should probably return soon;
-	 *  currently we don't, but at least put out a message. - kw
-	 */
-#ifdef UNIX
-	int rvhi = (rv >> 8);
-	CTRACE((tfp, "ExtEditForm: system() returned %d (0x%x), %s\n",
-	       rv, rv, errno ? LYStrerror(errno) : "reason unknown"));
-	LYFixCursesOn("show error warning:");
-	if (rv != -1 && (rv && 0xff) && !rvhi) {
-	    HTAlwaysAlert(NULL, gettext("Editor killed by signal"));
-	} else if (!(rv == -1 || (rvhi == 127 && errno))) {
-	    HTUserMsg2(gettext("Editor returned with error status, %s"),
-		       errno ? LYStrerror(errno) : gettext("reason unknown."));
-	} else
-#endif
-	    HTAlwaysAlert(NULL, ERROR_SPAWNING_EDITOR);
-    }
-
-#ifdef UNIX
-    /*
-     *  Delete backup file, if that's your style.
-     */
-    HTSprintf0 (&tbuf, "%s~", ed_temp);
-    if (stat (tbuf, &stat_info) == 0)
-	remove (tbuf);
-#endif
-    FREE(tbuf);
+    edit_temporary_file(ed_temp, ed_offset, NULL);
 
     CTRACE((tfp, "GridText: returned from editor (%s)\n", editor));
 
@@ -12451,8 +12329,8 @@ PUBLIC void HText_ExpandTextarea ARGS2(
 
 
 /*
- *  Insert the contents of a file into a TEXTAREA between the cursorline,
- *  and the line preceeding it.
+ *  Insert the contents of a file into a TEXTAREA between the cursor line,
+ *  and the line preceding it.
  *
  *  Returns the number of lines that the cursor should be moved so that it
  *  will end up on the 1st line in the TEXTAREA following the inserted file
@@ -12604,7 +12482,7 @@ PUBLIC int HText_InsertFile ARGS1(
      *   line).  Beware of the differences ... some are a bit subtle to
      *   notice.]
      */
-    for (htline = HTMainText->last_line->next, i = 0;
+    for (htline = FirstHTLine(HTMainText), i = 0;
 	 anchor_ptr->line_num != i;            i++) {
 	htline = htline->next;
 	if (htline == HTMainText->last_line)
@@ -12763,7 +12641,6 @@ PUBLIC int HText_InsertFile ARGS1(
      */
     update_subsequent_anchors (newlines, end_anchor, htline, match_tag);
 
-
     /*
      *  Cleanup time.
      */
@@ -12945,15 +12822,6 @@ PRIVATE void redraw_part_of_line ARGS4(
 		     */
 		    LastDisplayChar = 'M';
 		} else {
-#if 0	/* last-ditch attempt to prevent 0x9B to screen - disabled  */
-#if defined(UNIX) || defined(VMS)
-		    if (!dump_output_immediately &&
-			UCH(buffer[0]) == 128+27) {
-			LYaddstr("~^");
-			buffer[0] ^= 0xc0;
-		    }
-#endif
-#endif
 		    LYaddstr(buffer);
 		    LastDisplayChar = buffer[0];
 		}
@@ -13041,8 +12909,8 @@ PRIVATE void move_to_glyph ARGS10(
      *  go over the COLS limit on the display.
      */
     i = (int)offset;
-    if (i > (int)LYcols - 1)
-	i = (int)LYcols - 1;
+    if (i > (int)DISPLAY_COLS - 1)
+	i = (int)DISPLAY_COLS - 1;
 
     linkvlen = hightext ? LYmbcsstrlen(hightext, utf_flag, YES) : 0;
 
@@ -13060,20 +12928,13 @@ PRIVATE void move_to_glyph ARGS10(
      */
     i_after_tgt = i;
     if (target) {
-	if (case_sensitive)
-	    cp_tgt = LYno_attr_mbcs_strstr(sdata,
-					   target,
-					   utf_flag, YES,
-					   &HitOffset,
-					   &LenNeeded);
-	else
-	    cp_tgt = LYno_attr_mbcs_case_strstr(sdata,
-						target,
-						utf_flag, YES,
-						&HitOffset,
-						&LenNeeded);
+	cp_tgt = LYno_attr_mb_strstr(sdata,
+				     target,
+				     utf_flag, YES,
+				     &HitOffset,
+				     &LenNeeded);
 	if (cp_tgt) {
-	    if ((int)offset + LenNeeded >= LYcols ||
+	    if ((int)offset + LenNeeded >= DISPLAY_COLS ||
 		((int)offset + HitOffset >= XP + linkvlen)) {
 		cp_tgt = NULL;
 	    } else {
@@ -13094,7 +12955,7 @@ PRIVATE void move_to_glyph ARGS10(
      *  XP_draw_min) is found, or when we reach the link itself (if
      *  highlight is non-NULL). - kw
      */
-    while ((i < LYcols - 1) && data < end_of_data && (*data != '\0')) {
+    while ((i < DISPLAY_COLS - 1) && data < end_of_data && (*data != '\0')) {
 
 	if (data && hightext && i >= XP && !incurlink) {
 
@@ -13153,11 +13014,6 @@ PRIVATE void move_to_glyph ARGS10(
 			    LYstartTargetEmphasis();
 			}
 		    }
-#if 0
-		} else {
-		    if (inunderline)	inU = YES;
-		    lynx_start_link_color (flag, inU);
-#endif
 		}
 #endif /* SHOW_WHEREIS_TARGETS */
 	    } else {
@@ -13194,18 +13050,12 @@ PRIVATE void move_to_glyph ARGS10(
 
 		if (incurlink && flag && i == XP - 1)
 		    cp_tgt = NULL;
-		else if (case_sensitive)
-		    cp_tgt = LYno_attr_mbcs_strstr(sdata,
-						   target,
-						   utf_flag, YES,
-						   &HitOffset,
-						   &LenNeeded);
 		else
-		    cp_tgt = LYno_attr_mbcs_case_strstr(sdata,
-							target,
-							utf_flag, YES,
-							&HitOffset,
-							&LenNeeded);
+		    cp_tgt = LYno_attr_mb_strstr(sdata,
+						 target,
+						 utf_flag, YES,
+						 &HitOffset,
+						 &LenNeeded);
 		if (cp_tgt) {
 		    i_start_tgt = i + HitOffset;
 		    i_after_tgt = i + LenNeeded;
@@ -13440,7 +13290,7 @@ PRIVATE void move_to_glyph ARGS10(
 		    /*
 		     *  For CJK strings, by Masanobu Kimura.
 		     */
-		    if (drawing && (i < LYcols - 1)) {
+		    if (drawing && (i < DISPLAY_COLS - 1)) {
 			buffer[1] = *data;
 			LYaddstr(buffer);
 			buffer[1] = '\0';
@@ -13461,15 +13311,6 @@ PRIVATE void move_to_glyph ARGS10(
 		    LastDisplayChar = 'M';
 		} else {
 		    if (drawing) {
-#if 0	/* last-ditch attempt to prevent 0x9B to screen - disabled  */
-#if defined(UNIX) || defined(VMS)
-			if (!dump_output_immediately &&
-			    UCH(buffer[0]) == 128+27) {
-			    LYaddstr("~^");
-			    buffer[0] ^= 0xc0;
-			}
-#endif
-#endif
 			LYaddstr(buffer);
 		    }
 		    LastDisplayChar = buffer[0];
@@ -13543,7 +13384,7 @@ PUBLIC void LYMoveToLink ARGS6(
     if (!HTMainText) {
 	todr = NULL;
     } else if (HTMainText->stale) {
-	todr = HTMainText->last_line->next;
+	todr = FirstHTLine(HTMainText);
 	n = links[cur].ly - pvtTITLE_HEIGHT + HTMainText->top_of_screen;
     } else {
 	todr = HTMainText->top_of_screen_line;
diff --git a/src/GridText.h b/src/GridText.h
index 47fbeb04..ad36becc 100644
--- a/src/GridText.h
+++ b/src/GridText.h
@@ -230,7 +230,11 @@ extern void user_message PARAMS((
 
 #define _user_message(msg, arg)	mustshow = TRUE, user_message(msg, arg)
 
-extern void www_user_search PARAMS((int start_line, document *doc, char *target));
+extern void www_user_search PARAMS((
+	int		start_line,
+	document *	doc,
+	char *		target,
+	int		direction));
 
 extern void print_crawl_to_fd PARAMS((
 	FILE *		fp,
diff --git a/src/HTAlert.c b/src/HTAlert.c
index e9917a1a..32452b62 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -24,10 +24,22 @@
 
 #include <HTParse.h>
 
+#undef timezone	/* U/Win defines this in time.h, hides implementation detail */
+
 #if defined(HAVE_FTIME) && defined(HAVE_SYS_TIMEB_H)
 #include <sys/timeb.h>
 #endif
 
+/*
+ * 'napms()' is preferable to 'sleep()' in any case because it does not
+ * interfere with output, but also because it can be less than a second.
+ */
+#ifdef HAVE_NAPMS
+#define LYSleep(n) napms(n)
+#else
+#define LYSleep(n) sleep(n)
+#endif
+
 /*	Issue a message about a problem.		HTAlert()
 **	--------------------------------
 */
@@ -80,7 +92,7 @@ PUBLIC void HTInfoMsg ARGS1(
     if (Msg && *Msg) {
 	CTRACE((tfp, "Info message: %s\n", Msg));
 	LYstore_message(Msg);
-	sleep(InfoSecs);
+	LYSleep(InfoSecs);
     }
 }
 
@@ -193,6 +205,9 @@ PUBLIC void HTReadProgress ARGS2(
 #endif
 #endif
 
+    if (!LYShowTransferRate)
+	LYTransferRate = rateOFF;
+
     if (bytes == 0) {
 	first = last = last_active = now;
 	bytes_last = bytes;
@@ -1000,19 +1015,19 @@ PUBLIC int HTConfirmPostRedirect ARGS2(
 PUBLIC void LYSleepAlert NOARGS
 {
     if (okToSleep())
-	sleep(AlertSecs);
+	LYSleep(AlertSecs);
 }
 
 PUBLIC void LYSleepInfo NOARGS
 {
     if (okToSleep())
-	sleep(InfoSecs);
+	LYSleep(InfoSecs);
 }
 
 PUBLIC void LYSleepMsg NOARGS
 {
     if (okToSleep())
-	sleep(MessageSecs);
+	LYSleep(MessageSecs);
 }
 
 /*
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index 3afa76db..629857e5 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -506,7 +506,7 @@ PRIVATE void chrcat ARGS2(
 	int,		ch)
 {
     result += strlen(result);
-    *result++ = ch;
+    *result++ = (char)ch;
     *result = 0;
 }
 
diff --git a/src/HTInit.c b/src/HTInit.c
index e3e734e4..47be396a 100644
--- a/src/HTInit.c
+++ b/src/HTInit.c
@@ -171,6 +171,12 @@ PUBLIC void HTFormatInit NOARGS
   */
  HTReorderPresentation(WWW_PLAINTEXT, WWW_PRESENT);
  HTReorderPresentation(WWW_HTML, WWW_PRESENT);
+
+ /*
+  * Analyze the list, and set 'get_accept' for those whose representations
+  * are not redundant.
+  */
+ HTFilterPresentations();
 }
 
 PUBLIC void HTPreparsedFormatInit NOARGS
@@ -651,7 +657,7 @@ PRIVATE int ExitWithError ARGS1(
 /* Reverse the entries from each mailcap after it has been read, so that
  * earlier entries have precedence.  Set to 0 to get traditional lynx
  * behavior, which means that the last match wins. - kw */
-#define reverse_mailcap 1
+static int reverse_mailcap = 1;
 
 PRIVATE int HTLoadTypesConfigFile ARGS1(
 	char *,		fn)
@@ -1084,7 +1090,7 @@ PRIVATE int HTGetLine ARGS3(
 	if (s[i] == CR) {
 	    r = fgetc(f);
 	    if (r == LF)
-		s[i] = r;
+		s[i] = (char) r;
 	    else if (r != EOF)
 		ungetc(r, f);
 	}
diff --git a/src/HTML.c b/src/HTML.c
index 4175b026..c6ba442e 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -239,10 +239,6 @@ PUBLIC BOOL LYBadHTML ARGS1(
 */
 PUBLIC void HTML_put_character ARGS2(HTStructured *, me, char, c)
 {
-#if 0 /* def KANJI_CODE_OVERRIDE */
-    static unsigned char save_ch1 = 0;
-    static unsigned char save_ch2 = 0;
-#endif
     /*
      *	Ignore all non-MAP content when just
      *	scanning a document for MAPs. - FM
@@ -423,25 +419,6 @@ PUBLIC void HTML_put_character ARGS2(HTStructured *, me, char, c)
 	    } else {
 		me->inP = TRUE;
 		me->inLABEL = FALSE;
-#if 0 /* Should this check be done in HText_appendCharacter? */
-		if (last_kcode == EUC) {
-		    if (save_ch1 && !save_ch2) {
-			if (UCH(c) & 0x80) {
-			    save_ch2 = c;
-			}
-			HText_appendCharacter(me->text, save_ch1);
-			HText_appendCharacter(me->text, save_ch2);
-			save_ch1 = save_ch2 = '\0';
-		    } else if (UCH(c) & 0x80) {
-			save_ch1 = c;
-			save_ch2 = '\0';
-		    } else {
-			HText_appendCharacter(me->text, c);
-		    }
-		} else {
-		    HText_appendCharacter(me->text, c);
-		}
-#endif
 		HText_appendCharacter(me->text, c);
 		me->in_word = YES;
 	    }
@@ -3931,72 +3908,6 @@ PRIVATE int HTML_start_element ARGS6(
 			0,
 			NULL,
 			NULL, YES, TRUE, &intern_flag);
-#if 0
-	me->inFIG = TRUE;
-	if (me->inA) {
-	    SET_SKIP_STACK(HTML_A);
-	    HTML_end_element(me, HTML_A, include);
-	}
-	if (!present ||
-	    (present && !present[HTML_FIG_ISOBJECT])) {
-	    LYEnsureDoubleSpace(me);
-	    LYResetParagraphAlignment(me);
-	    me->inFIGwithP = TRUE;
-	} else {
-	    me->inFIGwithP = FALSE;
-	    HTML_put_character(me, ' ');  /* space char may be ignored */
-	}
-	CHECK_ID(HTML_FIG_ID);
-	me->in_word = NO;
-	me->inP = FALSE;
-
-	if (clickable_images && present && present[HTML_FIG_SRC] &&
-	    value[HTML_FIG_SRC] && *value[HTML_FIG_SRC] != '\0') {
-	    StrAllocCopy(href, value[HTML_FIG_SRC]);
-	    CHECK_FOR_INTERN(intern_flag,href);
-	    url_type = LYLegitimizeHREF(me, &href, TRUE, TRUE);
-	    if (*href) {
-		/*
-		 *  Check whether a base tag is in effect. - FM
-		 */
-		if ((me->inBASE && *href != '#') &&
-		    (temp = HTParse(href, me->base_href, PARSE_ALL)) &&
-		    *temp != '\0')
-		    /*
-		     *	Use reference related to the base.
-		     */
-		    StrAllocCopy(href, temp);
-		FREE(temp);
-
-		/*
-		 *  Check whether to fill in localhost. - FM
-		 */
-		LYFillLocalFileURL(&href,
-				   ((*href != '#' &&
-				     me->inBASE) ?
-				   me->base_href : me->node_anchor->address));
-
-		me->CurrentA = HTAnchor_findChildAndLink(
-					me->node_anchor,	/* Parent */
-					NULL,			/* Tag */
-					href,			/* Addresss */
-					INTERN_LT);		/* Type */
-		HText_beginAnchor(me->text, me->inUnderline, me->CurrentA);
-		if (me->inBoldH == FALSE)
-		    HText_appendCharacter(me->text, LY_BOLD_START_CHAR);
-		HTML_put_string(me, (present[HTML_FIG_ISOBJECT] ?
-		      (present[HTML_FIG_IMAGEMAP] ?
-					"(IMAGE)" : "(OBJECT)") : "[FIGURE]"));
-		if (me->inBoldH == FALSE)
-		    HText_appendCharacter(me->text, LY_BOLD_END_CHAR);
-		HText_endAnchor(me->text, 0);
-		HTML_put_character(me, '-');
-		HTML_put_character(me, ' '); /* space char may be ignored */
-		me->in_word = NO;
-	    }
-	    FREE(href);
-	}
-#endif
 	break;
 
     case HTML_OBJECT:
@@ -4954,8 +4865,8 @@ PRIVATE int HTML_start_element ARGS6(
 		 */
 		for (i = 0; I.value[i]; i++) {
 		    HTML_put_character(me,
-				       (I.value[i] ==  ' ' ?
-					HT_NON_BREAK_SPACE : I.value[i]));
+				       (char)(I.value[i] ==  ' ' ?
+					      HT_NON_BREAK_SPACE : I.value[i]));
 		}
 		while (i++ < chars) {
 		    HTML_put_character(me, HT_NON_BREAK_SPACE);
@@ -5244,7 +5155,7 @@ PRIVATE int HTML_start_element ARGS6(
 		    &I_value,
 		    ATTR_CS_IN,
 		    I.value_cs,
-		    (me->UsePlainSpace && !me->HiddenValue),
+		    (BOOL)(me->UsePlainSpace && !me->HiddenValue),
 		    me->UsePlainSpace,
 		    me->HiddenValue);
 		I.value = I_value;
@@ -5456,8 +5367,9 @@ PRIVATE int HTML_start_element ARGS6(
 		     */
 		    for (i = 0; I.value[i]; i++)
 			HTML_put_character(me,
-					   (I.value[i] ==  ' ' ?
-					    HT_NON_BREAK_SPACE : I.value[i]));
+					   (char)(I.value[i] ==  ' '
+						   ? HT_NON_BREAK_SPACE
+						   : I.value[i]));
 		    while (i++ < chars)
 			HTML_put_character(me, HT_NON_BREAK_SPACE);
 		}
@@ -5804,9 +5716,11 @@ PRIVATE int HTML_start_element ARGS6(
 	 *  table tracking code.  Cancel tracking, it would only make
 	 *  things worse. - kw
 	 */
-#ifndef EXP_NESTED_TABLES
-	HText_cancelStbl(me->text);
+#ifdef EXP_NESTED_TABLES
+	if (!nested_tables)
 #endif
+	HText_cancelStbl(me->text);
+
 	if (me->inA) {
 	    SET_SKIP_STACK(HTML_A);
 	    HTML_end_element(me, HTML_A, include);
@@ -6008,7 +5922,7 @@ PRIVATE int HTML_start_element ARGS6(
 		}
 	    }
 	    HText_startStblCOL(me->text, span, stbl_align,
-			       (ElementNumber == HTML_COLGROUP));
+			       (BOOL)(ElementNumber == HTML_COLGROUP));
 	}
 	CHECK_ID(HTML_COL_ID);
 	break;
@@ -6051,7 +5965,7 @@ PRIVATE int HTML_start_element ARGS6(
 		}
 	    }
 	    HText_startStblTD(me->text, colspan, rowspan, stbl_align,
-			      (ElementNumber == HTML_TH));
+			      (BOOL)(ElementNumber == HTML_TH));
 	}
 	me->in_word = NO;
 	break;
@@ -6219,7 +6133,7 @@ PRIVATE int HTML_end_element ARGS3(
      *	SGML_EMPTY in HTMLDTD.c. - FM & KW
      */
     if (HTML_dtd.tags[element_number].contents != SGML_EMPTY) {
-	skip_stack_requested = me->skip_stack > 0;
+	skip_stack_requested = (BOOL) (me->skip_stack > 0);
 	if ((element_number != me->sp[0].tag_number) &&
 	    me->skip_stack <= 0 &&
 	    HTML_dtd.tags[HTML_LH].contents != SGML_EMPTY &&
@@ -6415,7 +6329,7 @@ PRIVATE int HTML_end_element ARGS3(
 	 *  charset routines. - FM
 	 */
 	if (me->node_anchor->bookmark && *me->node_anchor->bookmark) {
-	    if ((LYMultiBookmarks == TRUE) ||
+	    if ((LYMultiBookmarks != MBM_OFF) ||
 		((bookmark_page && *bookmark_page) &&
 		 strcmp(me->node_anchor->bookmark, bookmark_page))) {
 		if (!include)
@@ -7625,9 +7539,11 @@ End_Object:
 	break;
 
     case HTML_TABLE:
-#ifndef EXP_NESTED_TABLES
-	me->inTABLE = FALSE;
+#ifdef EXP_NESTED_TABLES
+	if (!nested_tables)
 #endif
+	me->inTABLE = FALSE;
+
 	if (!strcmp(me->sp->style->name, "Preformatted")) {
 	    break;
 	}
@@ -7639,10 +7555,12 @@ End_Object:
 	change_paragraph_style(me, me->sp->style);
 	UPDATE_STYLE;
 #ifdef EXP_NESTED_TABLES
-	me->inTABLE = HText_endStblTABLE(me->text);
-#else
-	HText_endStblTABLE(me->text);
+	if (nested_tables) {
+	    me->inTABLE = HText_endStblTABLE(me->text);
+	} else
 #endif
+	HText_endStblTABLE(me->text);
+
 	me->current_default_alignment = me->sp->style->alignment;
 	if (me->List_Nesting_Level >= 0)
 	    HText_NegateLineOne(me->text);
@@ -8321,53 +8239,6 @@ PUBLIC HTStructured* HTML_new ARGS3(
     class_string[0] = '\0';
 #endif
 
-#ifdef NOTUSED_FOTEMODS
-    /*
-    **	If the anchor already has stage info, make sure that it is
-    **	appropriate for the current display charset.  HTMIMEConvert()
-    **	does this for the http and https schemes, and HTCharsetFormat()
-    **	does it for the file and and ftp schemes, be we need to do it,
-    **	if necessary, for the gateway schemes. - FM
-    */
-    if (me->node_anchor->UCStages) {
-	if (HTAnchor_getUCLYhndl(me->node_anchor,
-				 UCT_STAGE_STRUCTURED) != current_char_set) {
-	    /*
-	    **	We are reloading due to a change in the display character
-	    **	set.  Free the stage info and let the stage info creation
-	    **	mechanisms create a new UCStages structure appropriate for
-	    **	the current display character set. - FM
-	    */
-	    FREE(anchor->UCStages);
-	} else if (HTAnchor_getUCLYhndl(me->node_anchor,
-					UCT_STAGE_MIME) == current_char_set) {
-	    /*
-	    **	The MIME stage is set to the current display character
-	    **	set.  If it is CJK, and HTCJK does not point to a CJK
-	    **	character set, assume we are reloading due to a raw
-	    **	mode toggle and reset the MIME and PARSER stages to
-	    **	an ISO Latin 1 default. - FM
-	    */
-	    LYUCcharset *p_in = HTAnchor_getUCInfoStage(me->node_anchor,
-							UCT_STAGE_MIME);
-	    if (p_in->enc == UCT_ENC_CJK && HTCJK == NOCJK) {
-		HTAnchor_resetUCInfoStage(me->node_anchor, LATIN1,
-					  UCT_STAGE_MIME,
-					  UCT_SETBY_DEFAULT);
-		HTAnchor_setUCInfoStage(me->node_anchor, LATIN1,
-					UCT_STAGE_MIME,
-					UCT_SETBY_DEFAULT);
-		HTAnchor_resetUCInfoStage(me->node_anchor, LATIN1,
-					  UCT_STAGE_PARSER,
-					  UCT_SETBY_DEFAULT);
-		HTAnchor_setUCInfoStage(me->node_anchor, LATIN1,
-					UCT_STAGE_PARSER,
-					UCT_SETBY_DEFAULT);
-	    }
-	}
-    }
-#endif /* NOTUSED_FOTEMODS */
-
     /*
     **	Create a chartrans stage info structure for the anchor,
     **	if it does not exist already (in which case the default
@@ -8404,11 +8275,6 @@ PUBLIC HTStructured* HTML_new ARGS3(
 					 UCT_STAGE_STRUCTURED);
     me->outUCLYhndl = HTAnchor_getUCLYhndl(me->node_anchor,
 					   UCT_STAGE_STRUCTURED);
-#ifdef NOTUSED_FOTEMODS
-    UCSetTransParams(&me->T,
-		     me->inUCLYhndl, me->inUCI,
-		     me->outUCLYhndl, me->outUCI);
-#endif
 
     me->target = stream;
     if (stream)
@@ -8619,10 +8485,6 @@ PRIVATE HTStream* CacheThru_new ARGS2(
 	if (anchor->source_cache_file) {
 	    CTRACE((tfp, "SourceCacheWriter: If successful, will replace source cache file %s\n",
 		    anchor->source_cache_file));
-#if 0 /* No, let's NOT do this. - kw 1999-12-05 */
-	    FREE(stream);
-	    return target;
-#endif
 	}
 
 	/*
@@ -8649,10 +8511,6 @@ PRIVATE HTStream* CacheThru_new ARGS2(
 	    CTRACE((tfp,
 		    "SourceCacheWriter: If successful, will replace memory chunk %p\n",
 		    (void *)anchor->source_cache_chunk));
-#if 0 /* No, let's NOT do this. - kw 1999-12-05 */
-	    FREE(stream);
-	    return target;
-#endif
 	}
 
 #ifdef SAVE_TIME_NOT_SPACE
@@ -8769,11 +8627,6 @@ PUBLIC HTStream* HTMLToC ARGS3(
 	HTStream *,		sink)
 {
     HTStructured * html;
-#if 0
-    if (!sink)
-	sink = HTStreamStack(WWW_SOURCE, HTAtom_for("www/dump"),
-	HTOutputStream, anchor);
-#endif
     if (sink)
 	(*sink->isa->put_string)(sink, "/* ");	/* Before even title */
     html = HTML_new(anchor, WWW_PLAINTEXT, sink);
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index cfe8c837..f5a5d911 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -25,6 +25,24 @@ PUBLIC char *MBM_A_subdescript[MBM_V_MAXFILES+1];
 PRIVATE BOOLEAN is_mosaic_hotlist = FALSE;
 PRIVATE char * convert_mosaic_bookmark_file PARAMS((char *filename_buffer));
 
+PUBLIC int LYindex2MBM ARGS1(int, n)
+{
+    static char MBMcodes[MBM_V_MAXFILES+2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    return n >= 0 && n <= MBM_V_MAXFILES ? MBMcodes[n] : '?';
+}
+
+PUBLIC int LYMBM2index ARGS1(int, ch)
+{
+    if ((ch = TOUPPER(ch)) > 0) {
+	char *letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	char *result = strchr(letters, ch);
+	if (result != 0
+	 && (result - letters) <= MBM_V_MAXFILES)
+	    return (result - letters);
+    }
+    return -1;
+}
+
 PRIVATE void
 show_bookmark_not_defined NOARGS
 {
@@ -253,7 +271,7 @@ PUBLIC void save_bookmark_link ARGS2(
      *	If the link will be added to the same
      *	bookmark file, get confirmation. - FM
      */
-    if (LYMultiBookmarks == TRUE &&
+    if (LYMultiBookmarks != MBM_OFF &&
 	strstr(HTLoadedDocumentURL(),
 	       (*BookmarkPage == '.' ?
 		    (BookmarkPage+1) : BookmarkPage)) != NULL) {
@@ -354,7 +372,7 @@ PUBLIC void save_bookmark_link ARGS2(
 	else
 	    fprintf(fp, "<META %s %s>\n",
 		    "http-equiv=\"content-type\"",
-		    "content=\"text/html;charset=iso-2022-jp\""); 
+		    "content=\"text/html;charset=iso-2022-jp\"");
 #else
 	LYAddMETAcharsetToFD(fp, -1);
 #endif	/* !_WINDOWS */
@@ -679,7 +697,7 @@ PUBLIC int select_multi_bookmarks NOARGS
     /*
      *	If not enabled, pick the "default" (0).
      */
-    if (LYMultiBookmarks == FALSE || LYHaveSubBookmarks() == FALSE) {
+    if (LYMultiBookmarks == MBM_OFF || LYHaveSubBookmarks() == FALSE) {
 	if (MBM_A_subbookmark[0]) /* If it exists! */
 	    return(0);
 	else
@@ -691,7 +709,7 @@ PUBLIC int select_multi_bookmarks NOARGS
      *	the 2 redraws of the screen, if LYMBMAdvnced is TRUE.  '=' will
      *	still show the screen and let them do it the "long" way.
      */
-    if (LYMBMAdvanced && user_mode == ADVANCED_MODE) {
+    if (LYMultiBookmarks == MBM_ADVANCED && user_mode == ADVANCED_MODE) {
 	LYMBM_statusline(MULTIBOOKMARKS_SELECT);
 get_advanced_choice:
 	c = LYgetch();
@@ -733,8 +751,7 @@ get_advanced_choice:
 		 *  Convert to an array index, act on it if valid.
 		 *  Otherwise, get another keystroke.
 		 */
-		c = TOUPPER(c) - 'A';
-		if (c < 0 || c > MBM_V_MAXFILES) {
+		if ((c = LYMBM2index(c)) < 0) {
 		    goto get_advanced_choice;
 		}
 	}
@@ -755,20 +772,18 @@ get_advanced_choice:
  */
 PUBLIC int select_menu_multi_bookmarks NOARGS
 {
-    int c, MBM_tmp_count, MBM_allow;
+    int c, d, MBM_tmp_count, MBM_allow;
     int MBM_screens, MBM_from, MBM_to, MBM_current;
 
     /*
      *	If not enabled, pick the "default" (0).
      */
-    if (LYMultiBookmarks == FALSE)
+    if (LYMultiBookmarks == MBM_OFF)
 	return(0);
 
     /*
      *	Filip M. Gieszczykiewicz (filipg@paranoia.com) & FM
      *	---------------------------------------------------
-     *	LYMultiBookmarks - TRUE when multi_support enabled.
-     *
      *	MBM_A_subbookmark[n] - Hold values of the respective
      *	"multi_bookmarkn" in the lynxrc file.
      *
@@ -804,137 +819,128 @@ PUBLIC int select_menu_multi_bookmarks NOARGS
 
     MBM_current = 1; /* Gotta start somewhere :-) */
 
-draw_bookmark_choices:
-    MBM_from = MBM_allow * MBM_current - MBM_allow;
-    if (MBM_from < 0)
-	MBM_from = 0; /* 0 is default bookmark... */
-    if (MBM_current != 1)
-	MBM_from++;
+    for (;;) {
+	MBM_from = MBM_allow * MBM_current - MBM_allow;
+	if (MBM_from < 0)
+	    MBM_from = 0; /* 0 is default bookmark... */
+	if (MBM_current != 1)
+	    MBM_from++;
 
-    MBM_to = (MBM_allow * MBM_current);
-    if (MBM_to > MBM_V_MAXFILES)
-	MBM_to = MBM_V_MAXFILES;
-
-    /*
-     *	Display menu of bookmarks.  NOTE that we avoid printw()'s
-     *	to increase the chances that any non-ASCII or multibyte/CJK
-     *	characters will be handled properly. - FM
-     */
-    LYclear();
-    LYmove(1, 5);
-    lynx_start_h1_color ();
-    if (MBM_screens > 1) {
-	char *shead_buffer = 0;
-	HTSprintf0(&shead_buffer,
-		MULTIBOOKMARKS_SHEAD_MASK, MBM_current, MBM_screens);
-	LYaddstr(shead_buffer);
-	FREE(shead_buffer);
-    } else {
-	LYaddstr(MULTIBOOKMARKS_SHEAD);
-    }
-
-    lynx_stop_h1_color ();
-
-    MBM_tmp_count = 0;
-    for (c = MBM_from; c <= MBM_to; c++) {
-	LYmove(3+MBM_tmp_count, 5);
-	LYaddch(UCH((c + 'A')));
-	LYaddstr(" : ");
-	if (MBM_A_subdescript[c])
-	    LYaddstr(MBM_A_subdescript[c]);
-	LYmove(3+MBM_tmp_count,36);
-	LYaddch('(');
-	if (MBM_A_subbookmark[c])
-	    LYaddstr(MBM_A_subbookmark[c]);
-	LYaddch(')');
-	MBM_tmp_count++;
-    }
-
-    /*
-     *	Don't need to show it if it all fits on one screen!
-     */
-    if (MBM_screens > 1) {
-	LYmove(LYlines-2, 0);
-	LYaddstr("'");
-	start_bold();
-	LYaddstr("[");
-	stop_bold();
-	LYaddstr("' ");
-	LYaddstr(PREVIOUS);
-	LYaddstr(", '");
-	start_bold();
-	LYaddstr("]");
-	stop_bold();
-	LYaddstr("' ");
-	LYaddstr(NEXT_SCREEN);
-    }
+	MBM_to = (MBM_allow * MBM_current);
+	if (MBM_to > MBM_V_MAXFILES)
+	    MBM_to = MBM_V_MAXFILES;
 
-    LYMBM_statusline(MULTIBOOKMARKS_SAVE);
-get_bookmark_choice:
-    c = LYgetch();
-#ifdef VMS
-    if (HadVMSInterrupt) {
-	HadVMSInterrupt = FALSE;
-	c = 7;
-    }
-#endif /* VMS */
-
-    if (LYisNonAlnumKeyname(c, LYK_PREV_DOC) ||
-	c == 7 || c == 3) {
 	/*
-	 *  Treat left-arrow, ^G, or ^C as cancel.
+	 *  Display menu of bookmarks.  NOTE that we avoid printw()'s
+	 *  to increase the chances that any non-ASCII or multibyte/CJK
+	 *  characters will be handled properly. - FM
 	 */
-	return(-2);
-    }
+	LYclear();
+	LYmove(1, 5);
+	lynx_start_h1_color ();
+	if (MBM_screens > 1) {
+	    char *shead_buffer = 0;
+	    HTSprintf0(&shead_buffer,
+		    MULTIBOOKMARKS_SHEAD_MASK, MBM_current, MBM_screens);
+	    LYaddstr(shead_buffer);
+	    FREE(shead_buffer);
+	} else {
+	    LYaddstr(MULTIBOOKMARKS_SHEAD);
+	}
 
-    if (LYisNonAlnumKeyname(c, LYK_REFRESH)) {
-	/*
-	 *  Refresh the screen.
-	 */
-	lynx_force_repaint();
-	LYrefresh();
-	goto get_bookmark_choice;
-    }
+	lynx_stop_h1_color ();
+
+	MBM_tmp_count = 0;
+	for (c = MBM_from; c <= MBM_to; c++) {
+	    LYmove(3+MBM_tmp_count, 5);
+	    LYaddch(LYindex2MBM(c));
+	    LYaddstr(" : ");
+	    if (MBM_A_subdescript[c])
+		LYaddstr(MBM_A_subdescript[c]);
+	    LYmove(3+MBM_tmp_count,36);
+	    LYaddch('(');
+	    if (MBM_A_subbookmark[c])
+		LYaddstr(MBM_A_subbookmark[c]);
+	    LYaddch(')');
+	    MBM_tmp_count++;
+	}
 
-    if (LYisNonAlnumKeyname(c, LYK_ACTIVATE)) {
 	/*
-	 *  Assume default bookmark file on ENTER or right-arrow.
+	 *  Don't need to show it if it all fits on one screen!
 	 */
-	return(MBM_A_subbookmark[0] ? 0 : -1);
-    }
+	if (MBM_screens > 1) {
+	    LYmove(LYlines-2, 0);
+	    LYaddstr("'");
+	    start_bold();
+	    LYaddstr("[");
+	    stop_bold();
+	    LYaddstr("' ");
+	    LYaddstr(PREVIOUS);
+	    LYaddstr(", '");
+	    start_bold();
+	    LYaddstr("]");
+	    stop_bold();
+	    LYaddstr("' ");
+	    LYaddstr(NEXT_SCREEN);
+	}
 
-    /*
-     *	Next range, if available.
-     */
-    if ((c == ']' ||  LYisNonAlnumKeyname(c, LYK_NEXT_PAGE)) &&
-	MBM_screens > 1) {
-	if (++MBM_current > MBM_screens)
-	    MBM_current = 1;
-	goto draw_bookmark_choices;
-    }
+	LYMBM_statusline(MULTIBOOKMARKS_SAVE);
 
-    /*
-     *	Previous range, if available.
-     */
-    if ((c == '[' ||  LYisNonAlnumKeyname(c, LYK_PREV_PAGE)) &&
-	MBM_screens > 1) {
-	if (--MBM_current <= 0)
-	    MBM_current = MBM_screens;
-	goto draw_bookmark_choices;
-    }
+	for (;;) {
+	    c = LYgetch();
+#ifdef VMS
+	    if (HadVMSInterrupt) {
+		HadVMSInterrupt = FALSE;
+		c = 7;
+	    }
+#endif /* VMS */
 
-    c = TOUPPER(c) - 'A';
-    /*
-     *	See if we have a bookmark like that.
-     */
-    if (c < 0 || c > MBM_V_MAXFILES) {
-	goto get_bookmark_choice;
-    } else if (!MBM_A_subbookmark[c]) {
-	show_bookmark_not_defined();
-	LYMBM_statusline(MULTIBOOKMARKS_SAVE);
-	goto get_bookmark_choice;
-    } else {
-	return(c);
+	    if ((d = LYMBM2index(c)) >= 0) {
+		/*
+		 *  See if we have a bookmark like that.
+		 */
+		if (MBM_A_subbookmark[d] != NULL)
+		    return(d);
+
+		show_bookmark_not_defined();
+		LYMBM_statusline(MULTIBOOKMARKS_SAVE);
+	    } else if (LYisNonAlnumKeyname(c, LYK_PREV_DOC) ||
+		c == 7 || c == 3) {
+		/*
+		 *  Treat left-arrow, ^G, or ^C as cancel.
+		 */
+		return(-2);
+	    } else if (LYisNonAlnumKeyname(c, LYK_REFRESH)) {
+		/*
+		 *  Refresh the screen.
+		 */
+		lynx_force_repaint();
+		LYrefresh();
+	    } else if (LYisNonAlnumKeyname(c, LYK_ACTIVATE)) {
+		/*
+		 *  Assume default bookmark file on ENTER or right-arrow.
+		 */
+		return(MBM_A_subbookmark[0] ? 0 : -1);
+	    } else if ((c == ']' ||  LYisNonAlnumKeyname(c, LYK_NEXT_PAGE)) &&
+		MBM_screens > 1) {
+		/*
+		 *  Next range, if available.
+		 */
+		if (++MBM_current > MBM_screens)
+		    MBM_current = 1;
+		break;
+	    }
+
+	    else if ((c == '[' ||  LYisNonAlnumKeyname(c, LYK_PREV_PAGE)) &&
+		MBM_screens > 1) {
+		/*
+		 *  Previous range, if available.
+		 */
+		if (--MBM_current <= 0)
+		    MBM_current = MBM_screens;
+		break;
+	    }
+	}
     }
 }
 
@@ -958,7 +964,7 @@ PUBLIC BOOLEAN LYHaveSubBookmarks NOARGS
 /*
  *  This function passes a string to _statusline(), making
  *  sure it is at the bottom of the screen if LYMultiBookmarks
- *  is TRUE, otherwise, letting it go to the normal statusline
+ *  is not MBM_OFF, otherwise, letting it go to the normal statusline
  *  position based on the current user mode.  We want to use
  *  _statusline() so that any multibyte/CJK characters in the
  *  string will be handled properly. - FM
@@ -966,7 +972,7 @@ PUBLIC BOOLEAN LYHaveSubBookmarks NOARGS
 PUBLIC void LYMBM_statusline  ARGS1(
 	char *,		text)
 {
-    if (LYMultiBookmarks == TRUE && user_mode == NOVICE_MODE) {
+    if (LYMultiBookmarks != MBM_OFF && user_mode == NOVICE_MODE) {
 	LYStatusLine = (LYlines - 1);
 	_statusline(text);
 	LYStatusLine = -1;
@@ -1096,3 +1102,21 @@ PRIVATE  char* title_convert8bit ARGS1(CONST char *, Title)
     FREE(ncr);
     return(buf);
 }
+
+/*
+ * Since this is the "Default Bookmark File", we save it as a global, and as
+ * the first MBM_A_subbookmark entry.
+ */
+PUBLIC void set_default_bookmark_page ARGS1(
+	char *,		value)
+{
+    if (value != 0) {
+	if (bookmark_page == 0
+	 || strcmp(bookmark_page, value)) {
+	    StrAllocCopy(bookmark_page, value);
+	}
+	StrAllocCopy(BookmarkPage, bookmark_page);
+	StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
+	StrAllocCopy(MBM_A_subdescript[0], MULTIBOOKMARKS_DEFAULT);
+    }
+}
diff --git a/src/LYBookmark.h b/src/LYBookmark.h
index e4898c71..681777e5 100644
--- a/src/LYBookmark.h
+++ b/src/LYBookmark.h
@@ -6,13 +6,16 @@
 #include <LYStructs.h>
 #endif /* LYSTRUCTS_H */
 
+extern BOOLEAN LYHaveSubBookmarks NOPARAMS;
 extern char * get_bookmark_filename PARAMS((char **name));
-extern void save_bookmark_link PARAMS((char *address, char *title));
-extern void remove_bookmark_link PARAMS((int cur, char *cur_bookmark_page));
-extern int select_multi_bookmarks NOPARAMS;
+extern int LYMBM2index PARAMS((int ch));
+extern int LYindex2MBM PARAMS((int n));
 extern int select_menu_multi_bookmarks NOPARAMS;
-extern BOOLEAN LYHaveSubBookmarks NOPARAMS;
+extern int select_multi_bookmarks NOPARAMS;
 extern void LYMBM_statusline PARAMS((char *text));
+extern void remove_bookmark_link PARAMS((int cur, char *cur_bookmark_page));
+extern void save_bookmark_link PARAMS((char *address, char *title));
+extern void set_default_bookmark_page PARAMS((char * value));
 
 #endif /* LYBOOKMARK_H */
 
diff --git a/src/LYCharSets.h b/src/LYCharSets.h
index d5372e0d..709c0160 100644
--- a/src/LYCharSets.h
+++ b/src/LYCharSets.h
@@ -107,7 +107,12 @@ extern int auto_display_charset;
 #endif
 
 #ifdef CAN_SWITCH_DISPLAY_CHARSET
-extern int Switch_Display_Charset PARAMS((int ord, int really));
+enum switch_display_charset_t {
+    SWITCH_DISPLAY_CHARSET_MAYBE,
+    SWITCH_DISPLAY_CHARSET_REALLY,
+    SWITCH_DISPLAY_CHARSET_SIZECHANGE
+};
+extern int Switch_Display_Charset PARAMS((int ord, enum switch_display_charset_t really));
 extern int Find_Best_Display_Charset PARAMS((int ord));
 extern char *charsets_directory;
 extern char *charset_switch_rules;
diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c
index 3a15f269..8c5ae7df 100644
--- a/src/LYCharUtils.c
+++ b/src/LYCharUtils.c
@@ -929,562 +929,6 @@ PUBLIC void LYGetChartransInfo ARGS1(
 				      UCT_STAGE_STRUCTURED);
 }
 
-#ifdef NOTUSED_FOTEMODS
-/*
-**  This function reallocates an allocated string and converts
-**  characters for the current display character set.  It assumes
-**  that invalid control characters have been dealt with by the
-**  SGML (or other initial) parser of the document input stream
-**  (i.e., are present only if elements or global flags have been
-**  set to allow them), and that otherwise this is a copy of the
-**  string with the charset of the input stream.  It handles Lynx
-**  special characters based on the 'me' structure's element values
-**  (the me->UsePlainSpace and me->HiddenValue elements, and its
-**  chartrans related elements), and calls to other functions which
-**  return structure element values.  HTChunk functions are used to
-**  keep memory allocations at a minimum. - FM
-*/
-PUBLIC void LYExpandString ARGS2(
-	HTStructured *,		me,
-	char **,		str)
-{
-    char *p = *str;
-    HTChunk *s;
-    BOOLEAN plain_space, hidden;
-    char c;
-    unsigned char c_unsign;
-    char saved_char_in = '\0';
-    BOOLEAN chk;
-    UCode_t code, uck;
-    char replace_buf [64];
-    char utf_buf[8], utf_count = 0;
-    char *utf_buf_p = utf_buf;
-    UCode_t utf_char = 0, value;
-    CONST char *name;
-    int i, j, high, low, diff = 0;
-
-    /*
-    **	Don't do anything if we have no structure
-    **	or string, or are in CJK mode. - FM
-    */
-    if (!me || !p || *p == '\0' ||
-	HTCJK != NOCJK)
-	return;
-
-    /*
-    **	Set "convenience copies" of me structure
-    **	elements. - FM
-    */
-    plain_space = me->UsePlainSpace;
-    hidden = me->HiddenValue;
-
-    /*
-    **	Check for special input charsets - FM
-    */
-    if (!strcmp(me->inUCI->MIMEname, "x-transparent")) {
-	/*
-	**  Conversions not intended. - FM
-	*/
-	return;
-    }
-    if (!strcmp(me->inUCI->MIMEname, "mnemonic") ||
-	!strcmp(me->inUCI->MIMEname, "mnemonic+ascii+0")) {
-	/*
-	**  All ASCII representations of Unicode characters,
-	**  and we have no reverse translation code for the
-	**  multibyte characters, so punt. - FM
-	*/
-	return;
-    }
-    if (me->inUCLYhndl < 0 || me->outUCLYhndl < 0) {
-	/*
-	**  The chartrans procedure failed, so we don't
-	**  do anything, and hope for the best. - FM
-	*/
-	CTRACE((tfp, "LYExpandString: Bad in (%d) or out (%d) handle(s).\n",
-		    me->inUCLYhndl, me->outUCLYhndl));
-	return;
-    }
-
-    /*
-    **	Zero the UTF-8 multibytes buffer. - FM
-    */
-    utf_buf[0] = utf_buf[6] = utf_buf[7] = '\0';
-
-    /*
-    **	Set up an HTChunk for accumulating the expanded copy
-    **	of the string, so that allocations are done in 128
-    **	byte increments, only as required. - FM
-    */
-    s = HTChunkCreate(128);
-
-    /*
-    **	Check each character in the original string,
-    **	and add the characters or substitutions to
-    **	our clean copy. - FM
-    */
-    for (i = 0; p[i]; i++) {
-	/*
-	**  Make sure the character is handled as Unicode
-	**  whenever that's appropriate.  - FM
-	*/
-	c = p[i];
-	c_unsign = UCH(c);
-	code = (UCode_t)c_unsign;
-	saved_char_in = '\0';
-	/*
-	**  Combine any UTF-8 multibytes into Unicode
-	**  to check for special characters. - FM
-	*/
-	if (me->T.decode_utf8) {
-	    /*
-	    **	Our input charset is UTF-8, so check
-	    **	for non-ASCII characters. - FM
-	    */
-	    if (TOASCII(c_unsign) > 127) {  /* S/390 -- gil -- 1703 */
-		/*
-		**  We have an octet from a multibyte character. - FM
-		*/
-		if (utf_count > 0 && (c & 0xc0) == 0x80) {
-		    /*
-		    **	Adjust the UCode_t value, add the octet
-		    **	to the buffer, and decrement the byte
-		    **	count. - FM
-		    */
-		    utf_char = (utf_char << 6) | (c & 0x3f);
-		    utf_count--;
-		    *utf_buf_p = c;
-		    utf_buf_p++;
-		    if (utf_count == 0) {
-			/*
-			**  We have all of the bytes, so terminate
-			**  the buffer and set 'code' to the UCode_t
-			**  value. - FM
-			*/
-			*utf_buf_p = '\0';
-			code = utf_char;
-			/*
-			**  Set up the monobyte character
-			**  values or non-character flags
-			**  and fall through. - FM
-			*/
-			if (code > 0 && code < 256) {
-			    c = ((char)(code & 0xff));
-			    c_unsign = UCH(c);
-			}
-		    } else {
-			/*
-			**  Get the next byte. - FM
-			*/
-			continue;
-		    }
-		} else {
-		    /*
-		    **	Start handling a new multibyte character. - FM
-		    */
-		    utf_buf[0] = c;
-		    utf_buf_p = &utf_buf[1];
-		    if ((c & 0xe0) == 0xc0) {
-			utf_count = 1;
-			utf_char = (c & 0x1f);
-		    } else if ((c & 0xf0) == 0xe0) {
-			utf_count = 2;
-			utf_char = (c & 0x0f);
-		    } else if ((c & 0xf8) == 0xf0) {
-			utf_count = 3;
-			utf_char = (c & 0x07);
-		    } else if ((c & 0xfc) == 0xf8) {
-			utf_count = 4;
-			utf_char = (c & 0x03);
-		    } else if ((c & 0xfe) == 0xfc) {
-			utf_count = 5;
-			utf_char = (c & 0x01);
-		    } else {
-			/*
-			**  We got garbage, even though it should
-			**  have been filtered out by the SGML or
-			**  input stream parser, so we'll ignore
-			**  it. - FM
-			*/
-			utf_count = 0;
-			utf_buf[0] = '\0';
-			utf_buf_p = utf_buf;
-		    }
-		    /*
-		    **	Get the next byte. - FM
-		    */
-		    continue;
-		}
-	    } else if (utf_count > 0) {
-		/*
-		**  Got an ASCII character when expecting
-		**  UTF-8 multibytes, so ignore the buffered
-		**  multibyte characters and fall through with
-		**  the current ASCII character. - FM
-		*/
-		utf_count = 0;
-		utf_buf[0] = '\0';
-		utf_buf_p = utf_buf;
-		code = (UCode_t)c_unsign;
-	    } else {
-		/*
-		**  Got a valid ASCII character, so fall
-		**  through with it. - FM
-		*/
-		code = (UCode_t)c_unsign;
-	    }
-	}
-	/*
-	**  Convert characters from non-UTF-8 charsets
-	**  to Unicode (if appropriate). - FM
-	*/
-	if (!(me->T.decode_utf8 &&
-	      UCH(p[i]) > 127)) {
-#ifdef NOTDEFINED
-	    if (me->T.strip_raw_char_in)
-		saved_char_in = c;
-#endif /* NOTDEFINED */
-	    if (me->T.trans_to_uni &&
-		(code >= LYlowest_eightbit[me->inUCLYhndl] ||
-		 (code < 32 && code != 0 &&
-		  me->T.trans_C0_to_uni))) {
-		/*
-		**  Convert the octet to Unicode. - FM
-		*/
-		code = (UCode_t)UCTransToUni(c, me->inUCLYhndl);
-		if (code > 0) {
-		    saved_char_in = c;
-		    if (code < 256) {
-			c = ((char)(code & 0xff));
-			c_unsign = UCH(c);
-		    }
-		}
-	    } else if (code < ' ' && code != 0 &&  /* S/390 -- gil -- 1720 */
-		       me->T.trans_C0_to_uni) {
-		/*
-		**  Quote from SGML.c:
-		**	"This else if may be too ugly to keep. - KW"
-		*/
-		if (me->T.trans_from_uni &&
-		    (((code = UCTransToUni(c, me->inUCLYhndl)) >= ' ') ||  /* S/390 -- gil -- 1737 */
-		     (me->T.transp &&
-		      (code = UCTransToUni(c, me->inUCLYhndl)) > 0))) {
-		    saved_char_in = c;
-		    if (code < 256) {
-			c = ((char)(code & 0xff));
-			c_unsign = UCH(c);
-		    }
-		} else {
-		    uck = -1;
-		    if (me->T.transp) {
-			uck = UCTransCharStr(replace_buf, 60, c,
-					     me->inUCLYhndl,
-					     me->inUCLYhndl, NO);
-		    }
-		    if (!me->T.transp || uck < 0) {
-			uck = UCTransCharStr(replace_buf, 60, c,
-					     me->inUCLYhndl,
-					     me->outUCLYhndl, YES);
-		    }
-		    if (uck == 0) {
-			continue;
-		    } else if (uck < 0) {
-			utf_buf[0] = '\0';
-			code = UCH(c);
-		    } else {
-			c = replace_buf[0];
-			if (c && replace_buf[1]) {
-			    HTChunkPuts(s, replace_buf);
-			    continue;
-			}
-		    }
-		    utf_buf[0] = '\0';
-		    code = UCH(c);
-		} /*  Next line end of ugly stuff for C0. - KW */
-	    } else {
-		utf_buf[0] = '\0';
-		code = UCH(c);
-	    }
-	}
-	/*
-	**  Ignore low ISO 646 7-bit control characters
-	**  if they sneaked through (should have been
-	**  filtered by the parser). - FM
-	*/
-	if (code < ' ' &&  /* S/390 -- gil -- 1754 */
-	    c != 9 && c != 10 && c != 13) {
-	    continue;
-	}
-	/*
-	**  Ignore 127 if we don't have HTPassHighCtrlRaw
-	**  and it sneaked through (should have been
-	**  filtered by the parser). - FM
-	*/
-	if (TOASCII(c) == 127 &&  /* S/390 -- gil -- 1771 */
-	    !(me->T.transp ||
-	      code >= LYlowest_eightbit[me->inUCLYhndl])) {
-	    continue;
-	}
-	/*
-	**  Ignore 8-bit control characters 128 - 159 if we don't
-	**  have HTPassHighCtrlRaw set and they sneaked through
-	**  (should have been filtered by the parser). - FM
-	*/
-	if (TOASCII(code) > 127 && TOASCII(code) < 160 &&  /* S/390 -- gil -- 1788 */
-	    !(me->T.transp ||
-	      code >= LYlowest_eightbit[me->inUCLYhndl])) {
-	    continue;
-	}
-	/*
-	**  For 160 (nbsp), substitute Lynx special character
-	**  (or a space if plain_space or hidden is set) if
-	**  HTPassHighCtrlRaw is not set. - FM
-	*/
-	if (code == CH_NBSP) {  /* S/390 -- gil -- 1805 */
-	    if (!me->T.pass_160_173_raw) {
-		if (plain_space || hidden) {
-		    HTChunkPutc(s, ' ');
-		} else {
-		    HTChunkPutc(s, HT_NON_BREAK_SPACE);
-		}
-	    } else if (!me->T.output_utf8) {
-		HTChunkPutc(s, ((char)(code & 0xff)));
-	    } else if (me->T.decode_utf8 && *utf_buf) {
-		HTChunkPuts(s, utf_buf);
-		utf_buf[0] == '\0';
-		utf_buf_p = utf_buf;
-	    } else {
-		HTChunkPutUtf8Char(s, code);
-	    }
-	    continue;
-	}
-	/*
-	**  For 173 (shy), substitute Lynx special character
-	**  (or skip it if plain_space or hidden is set) if
-	**  HTPassHighCtrlRaw is not set. - FM
-	*/
-	if (code == CH_SHY) {  /* S/390 -- gil -- 1822 */
-	    if (!me->T.pass_160_173_raw) {
-		if (!(plain_space || hidden)) {
-		    HTChunkPutc(s, LY_SOFT_HYPHEN);
-		}
-	    } else if (!me->T.output_utf8) {
-		HTChunkPutc(s, ((char)(code & 0xff)));
-	    } else if (me->T.decode_utf8 && *utf_buf) {
-		HTChunkPuts(s, utf_buf);
-		utf_buf[0] == '\0';
-		utf_buf_p = utf_buf;
-	    } else {
-		HTChunkPutUtf8Char(s, code);
-	    }
-	    continue;
-	}
-	/*
-	**  For 8194 (ensp), 8195 (emsp), or 8201 (thinsp), use
-	**  an ASCII space (32) if plain_space or hidden is TRUE,
-	**  otherwise use the Lynx special character. - FM
-	*/
-	if (code == 8194 || code == 8195 || code == 8201) {
-	    if (plain_space || hidden) {
-		HTChunkPutc(s, ' ');
-	    } else {
-		HTChunkPutc(s, HT_EN_SPACE);
-	    }
-	    if (me->T.decode_utf8 && *utf_buf) {
-		utf_buf[0] == '\0';
-		utf_buf_p = utf_buf;
-	    }
-	    continue;
-	}
-	/*
-	**  If we want the raw character, pass it now. - FM
-	*/
-	if (me->T.use_raw_char_in && saved_char_in) {
-	    HTChunkPutc(s, saved_char_in);
-	    continue;
-	}
-	/*
-	**  Seek a translation from the chartrans tables.
-	*/
-	if ((chk = (me->T.trans_from_uni && code >= 160)) &&
-	    (uck = UCTransUniChar(code, me->outUCLYhndl)) >= 32 &&
-	    uck < 256 &&
-	    (uck < 127 ||
-	     uck >= LYlowest_eightbit[me->outUCLYhndl])) {
-	    HTChunkPutc(s, ((char)(uck & 0xff)));
-	    continue;
-	} else if (chk &&
-		   (uck == -4 ||
-		    (me->T.repl_translated_C0 &&
-		     uck > 0 && uck < ' ')) &&  /* S/390 -- gil -- 1839 */
-		   /*
-		   **  Not found; look for replacement string.
-		   */
-		   (uck = UCTransUniCharStr(replace_buf,
-					    60, code,
-					    me->outUCLYhndl,
-					    0) >= 0)) {
-	    /*
-	    **	Got a replacement string.
-	    */
-	    HTChunkPuts(s, replace_buf);
-	    continue;
-	}
-	/*
-	**  If we want raw UTF-8, output that now. - FM
-	*/
-	if (me->T.output_utf8 &&
-	    TOASCII(code) > 127 && code <= 0x7fffffffL) {  /* S/390 -- gil -- 1856 */
-	    if (me->T.decode_utf8 && *utf_buf) {
-		HTChunkPuts(s, utf_buf);
-		utf_buf[0] == '\0';
-		utf_buf_p = utf_buf;
-	    } else {
-		HTChunkPutUtf8Char(s, code);
-	    }
-	    continue;
-	}
-	/*
-	**  If it's any other (> 160) 8-bit character
-	**  and we have not set HTPassEightBitRaw
-	**  nor have the "ISO Latin 1" character set selected,
-	**  back translate for our character set. - FM
-	*/
-	if (code > 160 && code < 256 &&
-	     me->outUCLYhndl != LATIN1 &&
-	     (!(HTPassEightBitRaw ||
-		(me->T.do_8bitraw && !me->T.trans_from_uni)))) {
-	    value = (code - 160);
-	    name = HTMLGetEntityName(value);
-	    for (low = 0, high = HTML_dtd.number_of_entities;
-		 high > low;
-		 diff < 0 ? (low = j+1) : (high = j)) {
-		/*
-		**  Binary search.
-		*/
-		j = (low + (high-low)/2);
-		diff = strcmp(HTML_dtd.entity_names[j], name);
-		if (diff == 0) {
-		    HTChunkPuts(s, LYCharSets[me->outUCLYhndl][j]);
-		    break;
-		}
-	    }
-	    if (diff == 0) {
-		continue;
-	    }
-	}
-	/*
-	**  If it's ASCII at this point, use it. - FM
-	*/
-	if (TOASCII(code) < 127 && code > 0) {  /* S/390 -- gil -- 1873 */
-	    HTChunkPutc(s, ((char)(code & 0xff)));
-	    continue;
-	}
-	/*
-	**  At this point, if we should have translated, the
-	**  translation has failed.  We should have sent UTF-8
-	**  output to the parser already, but what the heck,
-	**  try again. - FM
-	*/
-	if (me->T.output_utf8 && *utf_buf) {
-	    HTChunkPuts(s, utf_buf);
-	    utf_buf[0] == '\0';
-	    utf_buf_p = utf_buf;
-	    continue;
-	}
-#ifdef NOTDEFINED
-	/*
-	**  Check for a strippable koi8-r 8-bit character. - FM
-	*/
-	if (me->T.strip_raw_char_in &&
-	    UCH(saved_char_in) >= 192 &&
-	    UCH(saved_char_in) < 255 &&
-	    saved_char_in) {
-	    /*
-	    **	KOI8 special: strip high bit, gives (somewhat) readable
-	    **	ASCII or KOI7 - it was constructed that way! - KW
-	    */
-	    HTChunkPutc(s, (saved_char_in & 0x7f));
-	    continue;
-	}
-#endif /* NOTDEFINED */
-	/*
-	**  Ignore 8204 (zwnj), 8205 (zwj)
-	**  8206 (lrm), and 8207 (rlm),
-	**  if we get to here. - FM
-	*/
-	if (code == 8204 || code == 8205 ||
-	    code == 8206 || code == 8207) {
-	    CTRACE((tfp, "LYExpandString: Ignoring '%ld'.\n", code));
-	    if (me->T.decode_utf8 && *utf_buf) {
-		utf_buf[0] == '\0';
-		utf_buf_p = utf_buf;
-	    }
-	    continue;
-	}
-	/*
-	**  If we don't actually want the character,
-	**  make it safe and output that now. - FM
-	*/
-	if ((c_unsign > 0 &&
-	     c_unsign < LYlowest_eightbit[me->outUCLYhndl]) ||
-	    (me->T.trans_from_uni && !HTPassEightBitRaw)) {
-	    /*
-	    **	If we do not have the "7-bit approximations" as our
-	    **	output character set (in which case we did it already)
-	    **	seek a translation for that.  Otherwise, or if the
-	    **	translation fails, use UHHH notation. - FM
-	    */
-	    if ((chk = (me->outUCLYhndl !=
-			UCGetLYhndl_byMIME("us-ascii"))) &&
-		(uck = UCTransUniChar(code,
-				      UCGetLYhndl_byMIME("us-ascii")))
-				      >= ' ' && TOASCII(uck) < 127) {  /* S/390 -- gil -- 1890 */
-		/*
-		**  Got an ASCII character (yippey). - FM
-		*/
-		c = ((char)(uck & 0xff));
-		HTChunkPutc(s, c);
-		continue;
-	    } else if ((uck == -4) &&
-		       (uck = UCTransUniCharStr(replace_buf,
-						60, code,
-						UCGetLYhndl_byMIME("us-ascii"),
-						0) >= 0)) {
-		/*
-		**  Got a replacement string (yippey). - FM
-		*/
-		HTChunkPuts(s, replace_buf);
-		continue;
-	    } else {
-		/*
-		**  Out of luck, so use the UHHH notation (ugh). - FM
-		*/
-		sprintf(replace_buf, "U%.2lX", TOASCII(code));  /* S/390 -- gil -- 1907 */
-		HTChunkPuts(s, replace_buf);
-		continue;
-	    }
-	}
-	/*
-	**  If we get to here and have a monobyte character,
-	**  pass it. - FM
-	*/
-	if (c_unsign > 0 && c_unsign < 256) {
-	    HTChunkPutc(s, c);
-	}
-    }
-
-    /*
-    **	Terminate the expanded string,
-    **	replace the original, and free
-    **	the chunk. - FM
-    */
-    HTChunkTerminate(s);
-    StrAllocCopy(*str, s->data);
-    HTChunkFree(s);
-}
-#endif /* NOTUSED_FOTEMODS */
-
 /*
  *  Given an UCS character code, will fill buffer passed in as q with
  *  the code's UTF-8 encoding.
@@ -1973,22 +1417,14 @@ PUBLIC char ** LYUCFullyTranslateString ARGS9(
 		    /* What else can we do? */
 		    code = UCH(*p);
 		}
-#ifdef NOTUSED_FOTEMODS
-	    } else if (T.strip_raw_char_in &&
-		       UCH(*p) >= 0xc0 &&
-		       UCH(*p) < 255) {
-		code = ((*p & 0x7f));
-		state = S_got_outchar;
-		break;
-#endif /* NOTUSED_FOTEMODS */
 	    } else if (!T.trans_from_uni) {
 		state = S_got_outchar;
 		break;
 	    }
 	    /*
-		    **	Substitute Lynx special character for
-		    **	160 (nbsp) if use_lynx_specials is set.
-		    */
+	    **	Substitute Lynx special character for
+	    **	160 (nbsp) if use_lynx_specials is set.
+	    */
 	    if (use_lynx_specials && !Back &&
 		(code == 160 || code == 173)) {
 		code = ((code==160 ? HT_NON_BREAK_SPACE : LY_SOFT_HYPHEN));
@@ -2398,30 +1834,23 @@ PUBLIC char ** LYUCFullyTranslateString ARGS9(
 
 	case S_recover:
 	    if (what == P_decimal || what == P_hex) {
-		    /*
-		    **	Illegal or not yet handled value.
-		    **	Return "&#" verbatim and continue
-		    **	from there. - FM
-		    */
-		    *q++ = '&';
-		    *q++ = '#';
-		    if (what == P_hex)
-			*q++ = 'x';
-		    if (cpe != '\0')
-			*(p-1) = cpe;
-		    p = cp;
-		    state = S_done;
+		/*
+		**  Illegal or not yet handled value.
+		**  Return "&#" verbatim and continue
+		**  from there. - FM
+		*/
+		*q++ = '&';
+		*q++ = '#';
+		if (what == P_hex)
+		    *q++ = 'x';
+		if (cpe != '\0')
+		    *(p-1) = cpe;
+		p = cp;
+		state = S_done;
 	    } else if (what == P_named) {
 		*cp = cpe;
 		*q++ = '&';
 		state = S_done;
-#ifdef NOTUSED_FOTEMODS
-	    } else if (T.strip_raw_char_in &&
-		UCH(*p) >= 0xc0 &&
-		UCH(*p) < 255) {
-		code = (((*p) & 0x7f));
-		state = S_got_outchar;
-#endif /* NOTUSED_FOTEMODS */
 	    } else if (!T.output_utf8 && stype == st_HTML && !hidden &&
 		!(HTPassEightBitRaw &&
 		 UCH(*p) >= lowest_8)) {
@@ -2441,7 +1870,6 @@ PUBLIC char ** LYUCFullyTranslateString ARGS9(
 		cp++;
 	    cpe = *cp;
 	    *cp = '\0';
-/*	    ppuni = cp - 1; */
 	    name = p;
 	    state = S_check_name;
 	    break;
@@ -2837,7 +2265,7 @@ PUBLIC void LYHandleMETA ARGS4(
 
 #ifdef CAN_SWITCH_DISPLAY_CHARSET
 	    /* Allow a switch to a more suitable display charset */
-	    if (Switch_Display_Charset (chndl, 0)) {
+	    if (Switch_Display_Charset (chndl, SWITCH_DISPLAY_CHARSET_MAYBE)) {
 		/* UCT_STAGE_STRUCTURED and UCT_STAGE_HTEXT
 		   should have the same setting for UCInfoStage. */
 		int structured = HTAnchor_getUCInfoStage(me->node_anchor,
@@ -3383,15 +2811,11 @@ PUBLIC void LYHandleSELECT ARGS5(
 	    me->select_disabled = TRUE;
 	if (present && present[HTML_SELECT_SIZE] &&
 	    value[HTML_SELECT_SIZE] && *value[HTML_SELECT_SIZE]) {
-#ifdef NOTDEFINED
-	    StrAllocCopy(size, value[HTML_SELECT_SIZE]);
-#else
 	    /*
 	     *	Let the size be determined by the number of OPTIONs. - FM
 	     */
 	    CTRACE((tfp, "LYHandleSELECT: Ignoring SIZE=\"%s\" for SELECT.\n",
 			value[HTML_SELECT_SIZE]));
-#endif /* NOTDEFINED */
 	}
 
 	if (me->inBoldH == TRUE &&
@@ -3562,7 +2986,13 @@ PUBLIC int LYLegitimizeHREF ARGS4(
 	    *pound = '\0';
 	    convert_to_spaces(fragment, FALSE);
 	}
-	LYRemoveBlanks(*href);
+	/*
+	 * No blanks really belong in the HREF, but if it refers to an actual
+	 * file, it may actually have blanks in the name.  Try to accommodate.
+	 */
+	convert_to_spaces(*href, FALSE);
+	LYTrimLeading(*href);
+	LYTrimTrailing(*href);
 	if (fragment != NULL) {
 	    StrAllocCat(*href, fragment);
 	    FREE(fragment);
diff --git a/src/LYCookie.c b/src/LYCookie.c
index df847365..163b84c4 100644
--- a/src/LYCookie.c
+++ b/src/LYCookie.c
@@ -260,6 +260,42 @@ PRIVATE BOOLEAN port_matches ARGS2(
 }
 
 /*
+ * Returns the length of the given path ignoring trailing slashes.
+ */
+PRIVATE int ignore_trailing_slash ARGS1(CONST char *, a)
+{
+    int len = strlen(a);
+    while (len > 1 && a[len-1] == '/')
+	--len;
+    return len;
+}
+
+/*
+ * Check if the path 'a' is a prefix of path 'b', ignoring trailing slashes
+ * in either, since they denote an empty component.
+ */
+PRIVATE BOOL is_prefix ARGS2(CONST char *, a, CONST char *, b)
+{
+    int len_a = ignore_trailing_slash(a);
+    int len_b = ignore_trailing_slash(b);
+
+    if (len_a > len_b) {
+	return FALSE;
+    } else {
+	if (strncmp(a, b, len_a) != 0) {
+	    return FALSE;
+	}
+	if (len_a < len_b && (len_a > 1 || a[0] != '/')) {
+	    if (b[len_a] != '\0'
+	     && b[len_a] != '/') {
+		return FALSE;
+	     }
+	}
+    }
+    return TRUE;
+}
+
+/*
 **  Store a cookie somewhere in the domain list. - AK & FM
 */
 PRIVATE void store_cookie ARGS3(
@@ -321,7 +357,7 @@ PRIVATE void store_cookie ARGS3(
      * then we want to bypass this check.  The user should be queried
      * if set to INVCHECK_QUERY.
      */
-    if (strncmp(co->path, path, co->pathlen) != 0) {
+    if (!is_prefix(co->path, path)) {
 	invcheck_behaviour_t invcheck_bv = (de ? de->invcheck_bv
 	    				       : DEFAULT_INVCHECK_BV);
 	switch (invcheck_bv) {
@@ -642,7 +678,7 @@ PRIVATE char * scan_cookie_sublist ARGS6(
 			host_matches(hostname, co->domain),
 			path, co->path,
 			(co->pathlen > 0)
-			    ? strncmp(path, co->path, co->pathlen)
+			    ? !is_prefix(path, co->path)
 			    : 0,
 			(co->flags & COOKIE_FLAG_SECURE)
 			    ? " secure"
@@ -664,7 +700,7 @@ PRIVATE char * scan_cookie_sublist ARGS6(
 	 */
 	if (((co != NULL) &&
 	     host_matches(hostname, co->domain)) &&
-	    (co->pathlen == 0 || !strncmp(path, co->path, co->pathlen))) {
+	    (co->pathlen == 0 || is_prefix(path, co->path))) {
 	    /*
 	     *	Skip if the secure flag is set and we don't have
 	     *	a secure connection.  HTTP.c presently treats only
@@ -1896,15 +1932,7 @@ PUBLIC void LYSetCookie ARGS3(
     } else if (!strncasecomp(address, "https:", 6)) {
 	port = 443;
     }
-    if (((path = HTParse(address, "",
-			 PARSE_PATH|PARSE_PUNCTUATION)) != NULL) &&
-	(ptr = strrchr(path, '/')) != NULL) {
-	if (ptr == path) {
-	    *(ptr+1) = '\0';	/* Leave a single '/' alone */
-	} else {
-	    *ptr = '\0';
-	}
-    }
+    path = HTParse(address, "", PARSE_PATH|PARSE_PUNCTUATION);
     if (!(SetCookie && *SetCookie) &&
 	!(SetCookie2 && *SetCookie2)) {
 	/*
@@ -2173,9 +2201,6 @@ PUBLIC void LYLoadCookies ARGS1 (
 PUBLIC void LYStoreCookies ARGS1 (
 	char *,		cookie_file)
 {
-#if 0
-    char *buf = NULL;
-#endif
     HTList *dl, *cl;
     domain_entry *de;
     cookie *co;
@@ -2210,24 +2235,6 @@ PUBLIC void LYStoreCookies ARGS1 (
 	     */
 	    continue;
 
-#if 0
-	switch (de->bv) {
-	case (ACCEPT_ALWAYS):
-	    HTSprintf0(&buf, COOKIES_ALWAYS_ALLOWED);
-	    break;
-	case (REJECT_ALWAYS):
-	    HTSprintf0(&buf, COOKIES_NEVER_ALLOWED);
-	    break;
-	case (QUERY_USER):
-	    HTSprintf0(&buf, COOKIES_ALLOWED_VIA_PROMPT);
-	    break;
-	case (FROM_FILE):	/* not used any more - kw */
-	    HTSprintf0(&buf, gettext("(From Cookie Jar)"));
-	    break;
-	}
-	/* FIXME: buf unused */
-#endif
-
 	/*
 	 *  Show the domain's cookies. - FM
 	 */
@@ -2743,7 +2750,7 @@ Delete_all_cookies_in_domain:
 
 PUBLIC void cookie_domain_flag_set ARGS2(
 	char *, 	domainstr,
-	int, 	flag)
+	int, 		flag)
 {
     domain_entry *de = NULL;
     domain_entry *de2 = NULL;
@@ -2853,6 +2860,46 @@ PUBLIC void cookie_domain_flag_set ARGS2(
     FREE(dstr);
 }
 
+/*
+ * If any COOKIE_{ACCEPT,REJECT}_DOMAINS have been defined, process them. 
+ * These are comma delimited lists of domains.  - BJP
+ *
+ * And for query/strict/loose invalid cookie checking.  - BJP
+ */
+PUBLIC void LYConfigCookies NOARGS
+{
+    static CONST struct {
+	char **domain;
+	int flag;
+	int once;
+    } table[] = {
+	{ &LYCookieSAcceptDomains,	FLAG_ACCEPT_ALWAYS,   TRUE },
+	{ &LYCookieSRejectDomains,	FLAG_REJECT_ALWAYS,   TRUE },
+	{ &LYCookieSStrictCheckDomains, FLAG_INVCHECK_STRICT, TRUE },
+	{ &LYCookieSLooseCheckDomains,	FLAG_INVCHECK_LOOSE,  TRUE },
+	{ &LYCookieSQueryCheckDomains,	FLAG_INVCHECK_QUERY,  TRUE },
+	{ &LYCookieAcceptDomains,	FLAG_ACCEPT_ALWAYS,   FALSE },
+	{ &LYCookieRejectDomains,	FLAG_REJECT_ALWAYS,   FALSE },
+	{ &LYCookieStrictCheckDomains,	FLAG_INVCHECK_STRICT, FALSE },
+	{ &LYCookieLooseCheckDomains,	FLAG_INVCHECK_LOOSE,  FALSE },
+	{ &LYCookieQueryCheckDomains,	FLAG_INVCHECK_QUERY,  FALSE },
+    };
+    unsigned n;
+
+    for (n = 0; n < TABLESIZE(table); n++) {
+	if (*(table[n].domain) != NULL) {
+	    cookie_domain_flag_set(*(table[n].domain), table[n].flag);
+	    /*
+	     * Discard the value for system settings after we've used them.
+	     * The local settings will be merged with the contents of .lynxrc
+	     */
+	    if (table[n].once) {
+		FREE(*(table[n].domain));
+	    }
+	}
+    }
+}
+
 #ifdef GLOBALDEF_IS_MACRO
 #define _LYCOOKIE_C_GLOBALDEF_1_INIT { "LYNXCOOKIE",LYHandleCookies,0}
 GLOBALDEF (HTProtocol,LYLynxCookies,_LYCOOKIE_C_GLOBALDEF_1_INIT);
diff --git a/src/LYCookie.h b/src/LYCookie.h
index 7767003a..f038ed2d 100644
--- a/src/LYCookie.h
+++ b/src/LYCookie.h
@@ -43,5 +43,6 @@ extern void LYLoadCookies PARAMS((
 extern void cookie_domain_flag_set PARAMS((
 	char * 		domainstr,
 	int 		flag));
+extern void LYConfigCookies NOPARAMS;
 
 #endif /* LYCOOKIES_H */
diff --git a/src/LYCurses.c b/src/LYCurses.c
index 49d48567..8c4f6534 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -50,7 +50,8 @@ char *XCursesProgramName = "Lynx";
 #ifdef USE_CURSES_PADS
 WINDOW *LYwin = 0;
 int LYshiftWin = 0;
-int LYlineWrap = TRUE;
+int LYwideLines = FALSE;
+int LYtableCols = 0;			/* in 1/12 of screen width */
 #endif
 
 /*
@@ -61,6 +62,10 @@ int LYlineWrap = TRUE;
 PRIVATE int dumbterm PARAMS((char *terminal));
 BOOLEAN LYCursesON = FALSE;
 
+#if defined(USE_BLINK) && defined(__EMX__)
+PRIVATE void make_blink_boldbg NOARGS;
+#endif
+
 #if USE_COLOR_TABLE || defined(USE_SLANG)
 PUBLIC int Current_Attr, Masked_Attr;
 #endif
@@ -206,6 +211,8 @@ PRIVATE void sl_suspend ARGS1(
 #else
 
 #ifdef FANCY_CURSES
+
+#ifndef VMS
 /* definitions for the mono attributes we can use */
 static struct {
     char *name;
@@ -233,6 +240,7 @@ PUBLIC int string_to_attr ARGS1(
     }
     return 0;
 }
+#endif /* VMS */
 
 #ifdef USE_COLOR_STYLE
 PRIVATE char *attr_to_string ARGS1(
@@ -328,6 +336,7 @@ PUBLIC void LYbox ARGS2(
      *	specify our own ASCII characters for the corners and call
      *	wborder() instead of box(). - kw
      */
+    LynxWChangeStyle(win, s_menu_frame, STACK_ON);
 #ifdef HAVE_WBORDER
     if (!boxvert || !boxhori)
 	box(win, boxvert, boxhori);
@@ -338,6 +347,7 @@ PUBLIC void LYbox ARGS2(
 #else
     box(win, boxvert, boxhori);
 #endif
+    LynxWChangeStyle(win, s_menu_frame, STACK_OFF);
 #ifdef CSS
     if (formfield)
 	wcurses_css(win, "frame", ABS_OFF);
@@ -412,7 +422,7 @@ PRIVATE int LYAttrset ARGS3(
     }
 }
 
-PRIVATE void curses_w_style ARGS3(
+PUBLIC void curses_w_style ARGS3(
 	WINDOW*,	win,
 	int,		style,
 	int,		dir)
@@ -469,7 +479,7 @@ PRIVATE void curses_w_style ARGS3(
 			"in LynxChangeStyle(curses_w_style)"));
 	    last_colorattr_ptr--;
 	}
-	last_styles[last_colorattr_ptr++] = getattrs(LYwin);
+	last_styles[last_colorattr_ptr++] = getattrs(win);
 	/* don't cache style changes for active links */
 #if OMIT_SCN_KEEPING
 	/* since we don't compute the hcode to stack off in HTML.c, we
@@ -537,7 +547,9 @@ PUBLIC void curses_style ARGS2(
 }
 #endif /* USE_COLOR_STYLE */
 
+#ifndef USE_SLANG
 PRIVATE BOOL lynx_called_initscr = FALSE;
+#endif
 
 #if HAVE_USE_DEFAULT_COLORS && USE_DEFAULT_COLORS
 /*
@@ -837,11 +849,7 @@ PUBLIC void start_curses NOARGS
 	 *  If set, the blink escape sequence will turn on high
 	 *  intensity background (rxvt and maybe Linux console).
 	 */
-	if (LYShowColor && (Lynx_Color_Flags & SL_LYNX_USE_BLINK)) {
-	    SLtt_Blink_Mode = 1;
-	} else {
-	    SLtt_Blink_Mode = 0;
-	}
+	SLtt_Blink_Mode = term_blink_is_boldbg;
 #endif /* (VMS || REAL_UNIX_SYSTEM) && !__CYGWIN__  */
     }
 #ifdef __DJGPP__
@@ -944,7 +952,7 @@ PUBLIC void start_curses NOARGS
 #ifdef USE_CURSES_PADS
 	LYwin = newpad(LYlines, MAX_COLS);
 	LYshiftWin = 0;
-	LYlineWrap = TRUE;
+	LYwideLines = FALSE;
 #endif
 
 #if defined(USE_KEYMAPS) && defined(NCURSES_VERSION)
@@ -1062,6 +1070,11 @@ PUBLIC void start_curses NOARGS
     LYclear();
 #endif
 
+#if defined(USE_BLINK) && defined(__EMX__)
+    if (term_blink_is_boldbg)		/* Now actually make it so! */
+	make_blink_boldbg();
+#endif
+
     LYCursesON = TRUE;
     CTRACE((tfp, "start_curses: done.\n"));
 }  /* end of start_curses() */
@@ -1155,8 +1168,8 @@ PUBLIC void lynx_enable_mouse ARGS1(int,state)
  * SVr4 curses (and ncurses) initialize the terminal I/O to raw mode, and
  * simulate other modes in the library.  This means that when running, it
  * simulates the OCRNL setting.  Normally that is not a problem.  However, when
- * spawning a subprocess (e.g., xli), the subprocess may write to the screen. 
- * Fine so far - curses resets the terminal I/O to the normal state on exit. 
+ * spawning a subprocess (e.g., xli), the subprocess may write to the screen.
+ * Fine so far - curses resets the terminal I/O to the normal state on exit.
  * But the subprocess's messages can still be coming to the screen when lynx
  * returns to the screen mode.  This function delays restoring OCRNL until
  * after the first getch() call.
@@ -1173,29 +1186,37 @@ PUBLIC void lynx_enable_mouse ARGS1(int,state)
  */
 PUBLIC void lynx_nl2crlf ARGS1(int, normal GCC_UNUSED)
 {
-    
-#if defined(NCURSES_VERSION) && defined(SET_TTY) && defined(TERMIOS) && defined(ONLCR)
+#if defined(NCURSES_VERSION_PATCH) && defined(SET_TTY) && defined(TERMIOS) && defined(ONLCR)
     static TTY saved_tty;
     static int did_save = FALSE;
     static int waiting = FALSE;
+    static int can_fix = TRUE;
 
     if (!did_save) {
 	saved_tty = cur_term->Nttyb;
 	did_save = TRUE;
+#if NCURSES_VERSION_PATCH < 20010529
+	/* workaround for optimizer bug with nonl() */
+	if ((tigetstr("cud1") != 0 && *tigetstr("cud1") == '\n')
+	 || (tigetstr("ind")  != 0 && *tigetstr("ind")  == '\n'))
+	    can_fix = FALSE;
+#endif
     }
-    if (normal) {
-	if (!waiting) {
-	    cur_term->Nttyb.c_oflag |= ONLCR;
-	    waiting = TRUE;
-	    nonl();
-	}
-    } else {
-	if (waiting) {
-	    cur_term->Nttyb = saved_tty;
-	    SET_TTY(fileno(stdout), &saved_tty);
-	    waiting = FALSE;
-	    nl();
-	    LYrefresh();
+    if (can_fix) {
+	if (normal) {
+	    if (!waiting) {
+		cur_term->Nttyb.c_oflag |= ONLCR;
+		waiting = TRUE;
+		nonl();
+	    }
+	} else {
+	    if (waiting) {
+		cur_term->Nttyb = saved_tty;
+		SET_TTY(fileno(stdout), &saved_tty);
+		waiting = FALSE;
+		nl();
+		LYrefresh();
+	    }
 	}
     }
 #endif
@@ -1308,7 +1329,6 @@ PUBLIC BOOLEAN setup ARGS1(
     LYLowerCase(term);
 
     printf("%s%s\n", gettext("Terminal ="), term);
-    sleep(InfoSecs);
     if ((strlen(term) < 5) ||
 	strncmp(term, "vt", 2) || !isdigit(term[2])) {
 	printf("%s\n",
@@ -1479,8 +1499,12 @@ PUBLIC void LYpaddstr ARGS3(
 	int,		width,
 	CONST char *,	the_string)
 {
+    int y, x;
+    getyx(the_window, y, x);
+    if (width + x >= LYcols)
+	width = LYcols - x - 1;
+    LYwaddnstr(the_window, the_string, width);
     width -= strlen(the_string);
-    LYwaddstr(the_window, the_string);
     while (width-- > 0)
 	waddstr(the_window, " ");
 }
@@ -1507,6 +1531,22 @@ PUBLIC WINDOW *LYstartPopup ARGS4(
 	HTAlert(POPUP_FAILED);
     } else {
 	LYsubwindow(form_window);
+#  ifdef USE_COLOR_STYLE
+	{
+	    attr_t b;
+
+	    /* Get a proper value for the attribute */
+	    LynxWChangeStyle(form_window, s_menu_bg, STACK_ON);
+	    b = getattrs(form_window);
+	    LynxWChangeStyle(form_window, s_menu_bg, STACK_OFF);
+	    wbkgd(form_window, b | ' ');
+	    /* wbkgdset does not make a lot of sense with USE_COLOR_STYLE
+	       since it *forces* attributes on all the cells in the window.
+	       Undo the change done in LYsubwindow, since we set our styles.
+	     */
+	    wbkgdset(form_window, (b & ~(A_BOLD|A_BLINK)) | ' ');
+	}
+#  endif
     }
 #endif /* USE_SLANG */
     return form_window;
@@ -1556,7 +1596,11 @@ PUBLIC void LYtouchline ARGS1(
      * Alpha, since prior ports of curses were broken.  BSD touchline() has a
      * 4th parameter since it is used internally by touchwin().
      */
-    touchline(LYwin, row, 1, 0);
+#if defined(HAVE_BSD_TOUCHLINE)
+    touchline(LYwin, row, 0, COLS);
+#else
+    touchline(LYwin, row, 1);
+#endif
 #else
 #if !defined(USE_SLANG)
     touchwin(LYwin);
@@ -2142,7 +2186,7 @@ PUBLIC void LYrefresh NOARGS
     if (LYwin != stdscr) {
 	/*
 	 * Workaround for special case where lynx is prompting for a mailto,
-	 * and has a subject line that is wider than the screen.  The 
+	 * and has a subject line that is wider than the screen.  The
 	 * wnoutrefresh() call resets newscr's position to match stdscr's,
 	 * which happens to be the window's origin because we were not updating
 	 * that, and other stray wmove's in lynx fail because the coordinate
@@ -2362,3 +2406,18 @@ PUBLIC void LYstowCursor ARGS3(
     wrefresh(win);
 #endif /* USE_SLANG  */
 }
+
+#if defined(USE_BLINK) && defined(__EMX__) /* Can't put it earler due to BOOLEAN conflict */
+#  define BOOLEAN os2BOOLEAN
+#  define INCL_VIO
+#  include "os2.h"
+PRIVATE void make_blink_boldbg NOARGS
+{
+    VIOINTENSITY buf;		/* VIO windows have it anyway, */
+				/* but FS session need a switch */
+    buf.cb = sizeof(buf);
+    buf.type = 2;		/* VIOINTENSITY request */
+    buf.fs = 1;			/* Intensity == boldbg */
+    VioSetState(&buf,0);
+}
+#endif
diff --git a/src/LYCurses.h b/src/LYCurses.h
index f4be459f..ff38908f 100644
--- a/src/LYCurses.h
+++ b/src/LYCurses.h
@@ -56,7 +56,34 @@ typedef struct {
     int width;
 } WINDOW;
 
+/* slang doesn't really do windows... */
+#define waddch(w,c)  LYaddch(c)
 #define waddstr(w,s) addstr(s)
+#define wmove(win, row, col) SLsmg_gotorc((win)->top_y + (row), (win)->left_x + (col));
+
+#ifndef SLSMG_UARROW_CHAR
+#define SLSMG_UARROW_CHAR '^'
+#endif
+
+#ifndef SLSMG_DARROW_CHAR
+#define SLSMG_DARROW_CHAR 'v'
+#endif
+
+#ifndef SLSMG_LARROW_CHAR
+#define SLSMG_LARROW_CHAR '<'
+#endif
+
+#ifndef SLSMG_RARROW_CHAR
+#define SLSMG_RARROW_CHAR '>'
+#endif
+
+#ifndef SLSMG_CKBRD_CHAR
+#define SLSMG_CKBRD_CHAR '#'
+#endif
+
+#ifndef SLSMG_BLOCK_CHAR
+#define SLSMG_BLOCK_CHAR '#'
+#endif
 
 #ifndef ACS_UARROW  
 #define ACS_UARROW  SLSMG_UARROW_CHAR
@@ -130,23 +157,40 @@ typedef struct {
 #undef MOUSE_MOVED	/* conflict between PDCURSES and _WIN32 */
 #endif /* _MSC_VER */
 
+/*
+ * Do this to build with glibc 2.1.3 (apparently it was not used to build a
+ * system before release).
+ */
+#include <signal.h>
+
+#undef CS			/* some BSD versions of curses use this */
+#define CS curses_CS		/* ...but we don't */
+
+#ifdef ERR
+#undef ERR			/* all versions of curses define this */
+#endif
+
 #ifdef HAVE_CONFIG_H
-# ifdef HAVE_NCURSES_H
-#  include <ncurses.h>
+# ifdef HAVE_NCURSES_NCURSES_H
+#   include <ncurses/ncurses.h>
 # else
-#  ifdef HAVE_CURSESX_H
-#   include <cursesX.h>		/* Ultrix */
+#  ifdef HAVE_NCURSES_H
+#   include <ncurses.h>
 #  else
-#   ifdef HAVE_JCURSES_H
-#    include <jcurses.h>	/* sony_news */
+#   ifdef HAVE_CURSESX_H
+#    include <cursesX.h>	/* Ultrix */
 #   else
-#    ifdef PDCURSES
-#     include <pdcurses.h>	/* for PDCurses */
+#    ifdef HAVE_JCURSES_H
+#     include <jcurses.h>	/* sony_news */
 #    else
-#     ifdef HAVE_XCURSES
-#      include <xcurses.h>	/* PDCurses' UNIX port */
+#     ifdef PDCURSES
+#      include <pdcurses.h>	/* for PDCurses */
 #     else
-#      include <curses.h>	/* default */
+#      ifdef HAVE_XCURSES
+#       include <xcurses.h>	/* PDCurses' UNIX port */
+#      else
+#       include <curses.h>	/* default */
+#      endif
 #     endif
 #    endif
 #   endif
@@ -157,10 +201,19 @@ typedef struct {
 #  define getbkgd(w) wgetbkgd(w)	/* workaround pre-1.9.9g bug */
 # endif
 
-#if defined(NCURSES_VERSION) && defined(HAVE_DEFINE_KEY)
-#include <term.h>
-#define USE_KEYMAPS		1
-#endif
+# ifdef FANCY_CURSES
+#  if defined(NCURSES) && defined(HAVE_NCURSES_TERM_H)
+#    include <ncurses/term.h>
+#  else
+#   if defined(HAVE_TERM_H)
+#    include <term.h>
+#   endif
+#  endif
+# endif
+
+# if defined(NCURSES_VERSION) && defined(HAVE_DEFINE_KEY)
+#  define USE_KEYMAPS		1
+# endif
 
 #else
 # if defined(VMS) && defined(__GNUC__)
@@ -269,9 +322,13 @@ extern int LYcols;	/* replaces COLS */
 #ifdef USE_CURSES_PADS
 extern WINDOW *LYwin;
 extern int LYshiftWin;
-extern int LYlineWrap;
+extern int LYwideLines;
+extern int LYtableCols;
 #else
 #define LYwin stdscr
+#define LYshiftWin	0
+#define LYwideLines	0
+#define LYtableCols	0
 #endif
 
 #if defined(USE_COLOR_TABLE) || defined(USE_SLANG)
@@ -315,7 +372,11 @@ extern void curses_style PARAMS((int style, int dir));
 extern void setHashStyle PARAMS((int style, int color, int cattr, int mono, char* element));
 extern void setStyle PARAMS((int style, int color, int cattr, int mono));
 extern void wcurses_css PARAMS((WINDOW * win, char* name, int dir));
-#define LynxChangeStyle(style,dir) curses_style(style,dir)
+extern void curses_w_style PARAMS((WINDOW* win, int style, int	dir));
+#  define LynxChangeStyle(style,dir) curses_style(style,dir)
+#  define LynxWChangeStyle(win,style,dir) curses_w_style(win,style,dir)
+#else
+#  define LynxWChangeStyle(win,style,dir)	(void)1
 #endif /* USE_COLOR_STYLE */
 
 #if USE_COLOR_TABLE
@@ -337,8 +398,7 @@ extern unsigned int Lynx_Color_Flags;
 #endif
 
 #define SL_LYNX_USE_COLOR	1
-#define SL_LYNX_USE_BLINK	2
-#define SL_LYNX_OVERRIDE_COLOR	4
+#define SL_LYNX_OVERRIDE_COLOR	2
 
 #define start_bold()      	LYaddAttr(1)
 #define start_reverse()   	LYaddAttr(2)
@@ -522,6 +582,22 @@ FANCY_CURSES.  Check your config.log to see why the FANCY_CURSES test failed.
 
 #endif /* FANCY_CURSES */
 
+#ifndef ACS_UARROW  
+#define ACS_UARROW  '^'
+#endif
+
+#ifndef ACS_DARROW
+#define ACS_DARROW  'V'
+#endif
+
+#ifndef ACS_LARROW
+#define ACS_LARROW '{'
+#endif
+
+#ifndef ACS_RARROW
+#define ACS_RARROW '}'
+#endif
+
 #define LYaddch(ch)		waddch(LYwin, ch)
 
 #define addch_raw(ch)           LYaddch(ch)
diff --git a/src/LYDownload.c b/src/LYDownload.c
index 03a9ea5f..f211652e 100644
--- a/src/LYDownload.c
+++ b/src/LYDownload.c
@@ -122,7 +122,7 @@ PUBLIC void LYDownload ARGS1(
      *	Set up the sug_filenames recall buffer.
      */
     FnameTotal = (sug_filenames ? HTList_count(sug_filenames) : 0);
-    recall = ((FnameTotal >= 1) ? RECALL : NORECALL);
+    recall = ((FnameTotal >= 1) ? RECALL_URL : NORECALL);
     FnameNum = FnameTotal;
 
     if (method_number < 0) {
diff --git a/src/LYEdit.c b/src/LYEdit.c
index 453cab0b..288bd596 100644
--- a/src/LYEdit.c
+++ b/src/LYEdit.c
@@ -53,9 +53,6 @@ PUBLIC int edit_current_file ARGS3(
 	int,		lineno)
 {
     int result = FALSE;
-    int params = 1;
-    char *format = "%s %s";
-    char *command = NULL;
     char *filename = NULL;
 #if !(defined(VMS) || defined(DOSPATH) || defined(__EMX__))
     char *colon;
@@ -69,8 +66,11 @@ PUBLIC int edit_current_file ARGS3(
     unsigned char temp_buff[LY_MAXPATH];
 #endif
 
+    CTRACE((tfp, "edit_current_file(newfile=%s, cur=%d, lineno=%d)\n",
+		 newfile, cur, lineno));
+
     /*
-     *  If its a remote file then we can't edit it.
+     *  If it's a remote file then we can't edit it.
      */
     if (!LYisLocalFile(newfile)) {
 	HTUserMsg(CANNOT_EDIT_REMOTE_FILES);
@@ -155,17 +155,47 @@ PUBLIC int edit_current_file ARGS3(
     if (lineno > 0)
 	sprintf(position, "%d", lineno);
 
+    edit_temporary_file(filename, position, NULL);
+
+done:
+    /*
+     *  Restore the fragment if there was one. - FM
+     */
+    if (number_sign)
+	*number_sign = '#';
+
+    FREE(filename);
+    return (result);
+}
+
+PUBLIC void edit_temporary_file ARGS3(
+	char *,		filename,
+	char *,		position,
+	char *,		message)
+{
+    struct stat stat_info;
+    char *format = "%s %s";
+    char *command = NULL;
+    char *editor_arg = "";
+    int params = 1;
+    int rv;
+
+    if (strstr(editor, "pico")) {
+	editor_arg = " -t"; /* No prompt for filename to use */
+    }
     if (editor_can_position() && *position) {
 #ifdef VMS
-	format = "%s %s -%s";
+	format = "%s %s -%s%s";
 	HTAddXpand(&command, format, params++, editor);
 	HTAddParam(&command, format, params++, filename);
 	HTAddParam(&command, format, params++, position);
+	HTAddParam(&command, format, params++, editor_arg);
 	HTEndParam(&command, format, params);
 #else
-	format = "%s +%s %s";
+	format = "%s +%s%s %s";
 	HTAddXpand(&command, format, params++, editor);
 	HTAddParam(&command, format, params++, position);
+	HTAddParam(&command, format, params++, editor_arg);
 	HTAddParam(&command, format, params++, filename);
 	HTEndParam(&command, format, params);
 #endif
@@ -206,27 +236,49 @@ PUBLIC int edit_current_file ARGS3(
 	HTAddParam(&command, format, params++, filename);
 	HTEndParam(&command, format, params);
     }
+    if (message != NULL) {
+	_statusline(message);
+    }
 
     CTRACE((tfp, "LYEdit: %s\n", command));
     CTRACE_SLEEP(MessageSecs);
 
-    /*
-     *  Invoke the editor. - FM
-     */
     stop_curses();
-    LYSystem(command);
-    start_curses();
-
-    result = TRUE;
 
-done:
+#ifdef UNIX
+    set_errno(0);
+#endif
+    if ((rv = LYSystem(command)) != 0) {	/* Spawn Editor */
+	start_curses();
+	/*
+	 *  If something went wrong, we should probably return soon;
+	 *  currently we don't, but at least put out a message. - kw
+	 */
+	{
+#ifdef UNIX
+	    int rvhi = (rv >> 8);
+	    CTRACE((tfp, "ExtEditForm: system() returned %d (0x%x), %s\n",
+		   rv, rv, errno ? LYStrerror(errno) : "reason unknown"));
+	    LYFixCursesOn("show error warning:");
+	    if (rv != -1 && (rv && 0xff) && !rvhi) {
+		HTAlwaysAlert(NULL, gettext("Editor killed by signal"));
+	    } else if (!(rv == -1 || (rvhi == 127 && errno))) {
+		HTUserMsg2(gettext("Editor returned with error status, %s"),
+			   errno ? LYStrerror(errno) : gettext("reason unknown."));
+	    } else
+#endif
+		HTAlwaysAlert(NULL, ERROR_SPAWNING_EDITOR);
+	}
+    } else {
+	start_curses();
+    }
+#ifdef UNIX
     /*
-     *  Restore the fragment if there was one. - FM
+     *  Delete backup file, if that's your style.
      */
-    if (number_sign)
-	*number_sign = '#';
-
+    HTSprintf0 (&command, "%s~", filename);
+    if (stat (command, &stat_info) == 0)
+	remove (command);
+#endif
     FREE(command);
-    FREE(filename);
-    return (result);
 }
diff --git a/src/LYEdit.h b/src/LYEdit.h
index 84fec84a..7aa95815 100644
--- a/src/LYEdit.h
+++ b/src/LYEdit.h
@@ -5,8 +5,8 @@
 #include <HTUtils.h>
 #endif
 
-extern int edit_current_file PARAMS((char *newfile, int cur, int lineno));
-
 extern BOOLEAN editor_can_position NOPARAMS;
+extern int edit_current_file PARAMS((char *newfile, int cur, int lineno));
+extern void edit_temporary_file PARAMS((char * filename, char * position, char * message));
 
 #endif /* LYEDIT_H */
diff --git a/src/LYExtern.c b/src/LYExtern.c
index 4f341bb7..47476faf 100644
--- a/src/LYExtern.c
+++ b/src/LYExtern.c
@@ -28,14 +28,6 @@
 #include <LYStrings.h>
 
 #ifdef WIN_EX
-/* 1997/10/15 (Wed) 17:39:50 */
-
-#ifndef PATH_MAX
-#define PATH_MAX	1024
-#endif
-
-#define STRING_MAX	512
-
 /* ASCII char -> HEX digit */
 #define ASC2HEXD(x) (((x) >= '0' && (x) <= '9') ?               \
 		     ((x) - '0') : (toupper(x) - 'A' + 10))
@@ -73,37 +65,6 @@ static char *decode_string(char *s)
 }
 #endif	/* WIN_EX */
 
-#ifndef STRING_MAX
-#define	STRING_MAX 512
-#endif
-
-/* 1997/11/10 (Mon) 14:26:10 */
-PUBLIC char *string_short ARGS2(
-	char *,		str,
-	int,		cut_pos)
-{
-    char buff[STRING_MAX], *s, *d;
-    static char s_str[STRING_MAX];
-    int len;
-
-    LYstrncpy(buff, str, sizeof(buff)-1);
-    len = strlen(buff);
-    if (len > (LYcols - 10)) {
-	buff[cut_pos] = '.';
-	buff[cut_pos + 1] = '.';
-	for (s = (buff + len) - (LYcols - 10) + cut_pos + 1,
-	     d = (buff + cut_pos) + 2;
-	     s >= buff &&
-	     d >= buff &&
-	     d < buff + LYcols &&
-	     (*d++ = *s++) != 0; )
-	    ;
-	buff[LYcols] = 0;
-    }
-    strcpy(s_str, buff);
-    return (s_str);
-}
-
 #ifdef WIN_EX
 /*
  *  Quote the path to make it safe for shell command processing.
@@ -150,7 +111,7 @@ PRIVATE char *format_command ARGS2(
     char *,	param)
 {
 #ifdef WIN_EX
-    char pram_string[PATH_MAX];
+    char pram_string[LY_MAXPATH];
 #endif
     char *cmdbuf = NULL;
 
@@ -180,7 +141,7 @@ PRIVATE char *format_command ARGS2(
 
 	    format(&cmdbuf, command, host);
 	} else if (strnicmp("file://localhost/", param, 17) == 0) {
-	    char e_buff[PATH_MAX], *p;
+	    char e_buff[LY_MAXPATH], *p;
 
 	    p = param + 17;
 	    *e_buff = 0;
@@ -323,7 +284,7 @@ BOOL run_external ARGS2(
 #endif
     int redraw_flag = TRUE;
     char *cmdbuf = NULL;
-    int found = 0;
+    BOOL found = FALSE;
     int confirmed = TRUE;
 
     if (externals == NULL)
@@ -340,7 +301,7 @@ BOOL run_external ARGS2(
     if (cmdbuf != 0 && *cmdbuf != '\0') {
 #ifdef WIN_EX			/* 1997/10/17 (Fri) 14:07:50 */
 	int len;
-	char buff[PATH_MAX];
+	char buff[LY_MAXPATH];
 
 	CTRACE((tfp, "Lynx EXTERNAL: '%s'\n", cmdbuf));
 #ifdef WIN_GUI			/* 1997/11/06 (Thu) 14:17:15 */
@@ -349,7 +310,7 @@ BOOL run_external ARGS2(
 			       MB_ICONQUESTION | MB_SETFOREGROUND | MB_OKCANCEL)
 		    != IDCANCEL;
 #else
-	confirmed = HTConfirm(string_short(cmdbuf, 40)) != NO;
+	confirmed = HTConfirm(LYElideString(cmdbuf, 40)) != NO;
 #endif
 	if (confirmed) {
 	    len = strlen(cmdbuf);
@@ -361,7 +322,7 @@ BOOL run_external ARGS2(
 			   MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_OK);
 		SetConsoleTitle("Lynx for Win32");
 #else
-		HTConfirm(string_short(buff, 40));
+		HTConfirm(LYElideString(buff, 40));
 #endif
 		confirmed = FALSE;
 	    } else {
@@ -401,7 +362,7 @@ BOOL run_external ARGS2(
 			   "Lynx (EXTERNAL COMMAND EXEC)",
 			   MB_ICONSTOP | MB_SETFOREGROUND | MB_OK);
 #else
-		HTConfirm(string_short(buff, 40));
+		HTConfirm(LYElideString(buff, 40));
 #endif /* 1 */
 	    }
 #else	/* Not WIN_EX */
diff --git a/src/LYExtern.h b/src/LYExtern.h
index 909c41cd..51bf855f 100644
--- a/src/LYExtern.h
+++ b/src/LYExtern.h
@@ -7,7 +7,6 @@
 
 /*returns TRUE if something matching was executed*/
 BOOL run_external PARAMS((char * c, BOOL only_overriders));
-char *string_short PARAMS((char * str, int cut_pos));
 
 #ifdef WIN_EX
 extern char * quote_pathname PARAMS((char * pathname));
diff --git a/src/LYForms.c b/src/LYForms.c
index cdf84fc6..47538470 100644
--- a/src/LYForms.c
+++ b/src/LYForms.c
@@ -492,6 +492,7 @@ again:
 	}
 #endif /* VMS */
 
+	action = 0;
 #ifdef USE_MOUSE
 #  if defined(NCURSES) || defined(PDCURSES)
 	if (ch != -1 && (ch & LKC_ISLAC) && !(ch & LKC_ISLECLAC)) /* already lynxactioncode? */
@@ -505,10 +506,10 @@ again:
 	    if (MOUSE_Y_POS == cury) {
 		repeat = MOUSE_X_POS - curx;
 		if (repeat < 0) {
-		    ch = LTARROW;
+		    action = LYE_BACK;
 		    repeat = - repeat;
 		} else
-		    ch = RTARROW;
+		    action = LYE_FORW;
 	    }
 #else
 	    MEVENT	event;
@@ -519,10 +520,10 @@ again:
 	    if (event.y == cury) {
 		repeat = event.x - curx;
 		if (repeat < 0) {
-		    ch = LTARROW;
+		    action = LYE_BACK;
 		    repeat = - repeat;
 		} else
-		    ch = RTARROW;
+		    action = LYE_FORW;
 	    }
 #endif /* PDCURSES */
 	    else {
@@ -553,7 +554,8 @@ again:
 	if (peek_mouse_link() != -1)
 	    break;
 
-	action = EditBinding(ch);
+	if (!action)
+	    action = EditBinding(ch);
 	if ((action & LYE_DF) && !(action & LYE_FORM_LAC)) {
 	    last_xlkc = ch;
 	    action &= ~LYE_DF;
@@ -689,18 +691,6 @@ again:
 /* ASATAKU emacskey hack */
 #endif
 	switch (ch) {
-#ifdef NOTDEFINED	/* The first four are mapped to LYE_FORM_PASS now */
-	    case DNARROW:
-	    case UPARROW:
-	    case PGUP:
-	    case PGDOWN:
-	    case HOME:
-	    case END_KEY:
-	    case FIND_KEY:
-	    case SELECT_KEY:
-		goto breakfor;
-#endif /* NOTDEFINED */
-
 	    default:
 	    /*	[ 1999/04/14 (Wed) 15:01:33 ]
 	     *  Left arrrow in column 0 deserves special treatment here,
@@ -755,7 +745,7 @@ again:
 		if (repeat < 0)
 		    repeat = 1;
 		while (repeat--) {
-		    int rc = LYLineEdit(&MyEdit, ch, TRUE);
+		    int rc = LYEdit1(&MyEdit, ch, action & ~LYE_DF, TRUE);
 
 		    if (rc < 0) {
 			ch = -rc;
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index c7cdd705..54c7413d 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -115,15 +115,23 @@ extern char star_string[MAX_LINE + 1]; /* from GridText.c */
 #define STARS(n) \
  ((n) >= MAX_LINE ? star_string : &star_string[(MAX_LINE-1)] - (n))
 
-#define SHOW_COLOR_UNKNOWN	(-1)
-#define SHOW_COLOR_NEVER  0
-#define SHOW_COLOR_OFF	  1
-#define SHOW_COLOR_ON	  2
-#define SHOW_COLOR_ALWAYS 3
+typedef enum {
+    SHOW_COLOR_UNKNOWN = 0
+    , SHOW_COLOR_NEVER
+    , SHOW_COLOR_OFF
+    , SHOW_COLOR_ON
+    , SHOW_COLOR_ALWAYS
+} enumShowColor;
+
 extern int LYShowColor;		/* Show color or monochrome?	    */
-extern int LYChosenShowColor;	/* extended color/monochrome choice */
 extern int LYrcShowColor;	/* ... as read or last written	    */
 
+typedef enum {
+    MBM_OFF = 0
+    , MBM_STANDARD
+    , MBM_ADVANCED
+} enumMultiBookmarks;
+
 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
 extern BOOLEAN LYUseFormsOptions; /* use Forms-based options menu */
 #else
@@ -150,6 +158,7 @@ extern BOOLEAN LYCursesON;  	/* start_curses()->TRUE, stop_curses()->FALSE */
 extern BOOLEAN LYJumpFileURL;   /* URL from the jump file shortcuts? */
 extern BOOLEAN LYNewsPosting;	/* News posting supported if TRUE */
 extern BOOLEAN LYShowCursor;	/* Show the cursor or hide it?	    */
+extern BOOLEAN LYShowTransferRate;
 extern BOOLEAN LYUseDefShoCur;	/* Command line -show_cursor toggle */
 extern BOOLEAN LYUserSpecifiedURL;  /* URL from a goto or document? */
 extern BOOLEAN LYforce_HTML_mode;
@@ -333,6 +342,7 @@ extern BOOLEAN HEAD_request;         /* Do a HEAD request */
 extern BOOLEAN scan_for_buried_news_references;
 extern BOOLEAN bookmark_start;       /* Use bookmarks as startfile */
 extern BOOLEAN clickable_images;
+extern BOOLEAN nested_tables;
 extern BOOLEAN pseudo_inline_alts;
 extern BOOLEAN crawl;
 extern BOOLEAN traversal;
@@ -368,9 +378,8 @@ extern char *URLDomainSuffixes;
 extern BOOLEAN startfile_ok;
 extern BOOLEAN LYSelectPopups;		/* Cast popups to radio buttons? */
 extern BOOLEAN LYUseDefSelPop;		/* Command line -popup toggle    */
-extern BOOLEAN LYMultiBookmarks;	/* Multi bookmark support on?	 */
+extern int LYMultiBookmarks;		/* Multi bookmark support on?	 */
 extern BOOLEAN LYMBMBlocked;		/* Force MBM support off?	 */
-extern BOOLEAN LYMBMAdvanced;		/* MBM statusline for ADVANCED?	 */
 extern int LYStatusLine;		/* Line for statusline() or -1   */
 extern BOOLEAN LYCollapseBRs;		/* Collapse serial BRs?		 */
 extern BOOLEAN LYSetCookies;		/* Process Set-Cookie headers?	 */
@@ -409,7 +418,7 @@ extern BOOLEAN no_externals; 		/* don't allow the use of externals */
 extern BOOLEAN LYNoISMAPifUSEMAP;	/* Omit ISMAP link if MAP present? */
 extern int LYHiddenLinks;
 
-extern BOOLEAN Old_DTD;
+extern int Old_DTD;
 
 #define MBM_V_MAXFILES  25		/* Max number of sub-bookmark files */
 /*
@@ -456,7 +465,7 @@ extern int connect_timeout;
 
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
 extern BOOL textfields_need_activation;
-extern BOOL global_textfields_need_activation;
+extern BOOL textfields_activation_option;
 #ifdef INACTIVE_INPUT_STYLE_VH
 extern BOOL textinput_redrawn;
 #endif
@@ -513,8 +522,8 @@ extern int setmode(int handle, int amode);
 
 #ifdef USE_SCROLLBAR
 /* GridText.c */
-extern int LYsb;
-extern int LYsb_arrow;
+extern BOOLEAN LYsb;
+extern BOOLEAN LYsb_arrow;
 extern int LYsb_begin;
 extern int LYsb_end;
 #endif
@@ -523,4 +532,8 @@ extern int LYsb_end;
 extern char* hidden_link_marker;
 #endif
 
+#ifdef USE_BLINK
+extern BOOLEAN term_blink_is_boldbg;
+#endif
+
 #endif /* LYGLOBALDEFS_H */
diff --git a/src/LYHash.h b/src/LYHash.h
index 72039a04..80ecbece 100644
--- a/src/LYHash.h
+++ b/src/LYHash.h
@@ -50,6 +50,12 @@ extern int	s_prompt_sel;
 extern int	s_status;
 extern int	s_title;
 extern int	s_whereis;
+extern int	s_menu_frame;
+extern int	s_menu_bg;
+extern int	s_menu_number;
+extern int	s_menu_entry;
+extern int	s_menu_active;
+extern int	s_menu_sb;
 
 #ifdef USE_SCROLLBAR
 extern int	s_sb_aa;
diff --git a/src/LYHistory.c b/src/LYHistory.c
index 26ac340b..b012e230 100644
--- a/src/LYHistory.c
+++ b/src/LYHistory.c
@@ -226,6 +226,8 @@ PUBLIC BOOLEAN LYwouldPush ARGS2(
 	CONST char *,	title,
 	CONST char *,	docurl)
 {
+    BOOLEAN rc = FALSE;
+
     /*
      *  All non-pushable generated pages have URLs that begin with
      *  "file://localhost/" and end with HTML_SUFFIX. - kw
@@ -234,16 +236,18 @@ PUBLIC BOOLEAN LYwouldPush ARGS2(
 	size_t ulen;
 	if (strncmp(docurl, "file://localhost/", 17) != 0 ||
 	    (ulen = strlen(docurl)) <= strlen(HTML_SUFFIX) ||
-	    strcmp(docurl + ulen - strlen(HTML_SUFFIX), HTML_SUFFIX) != 0)
+	    strcmp(docurl + ulen - strlen(HTML_SUFFIX), HTML_SUFFIX) != 0) {
 	    /*
 	     *  If it is not a local HTML file, it may be a Web page that
 	     *  accidentally has the same title.  So return TRUE now. - kw
 	     */
 	    return TRUE;
+	}
     }
 
     if (docurl) {
-	return (LYIsUIPage(docurl, UIP_HISTORY)
+	rc = (BOOLEAN)
+		! (LYIsUIPage(docurl, UIP_HISTORY)
 		|| LYIsUIPage(docurl, UIP_PRINT_OPTIONS)
 		|| LYIsUIPage(docurl, UIP_DOWNLOAD_OPTIONS)
 #ifdef DIRED_SUPPORT
@@ -251,11 +255,10 @@ PUBLIC BOOLEAN LYwouldPush ARGS2(
 		|| LYIsUIPage(docurl, UIP_UPLOAD_OPTIONS)
 		|| LYIsUIPage(docurl, UIP_PERMIT_OPTIONS)
 #endif /* DIRED_SUPPORT */
-	    )
-	    ? FALSE
-	    : TRUE;
+	    );
     } else {
-	return (!strcmp(title, HISTORY_PAGE_TITLE)
+	rc = (BOOLEAN)
+		! (!strcmp(title, HISTORY_PAGE_TITLE)
 		|| !strcmp(title, PRINT_OPTIONS_TITLE)
 		|| !strcmp(title, DOWNLOAD_OPTIONS_TITLE)
 #ifdef DIRED_SUPPORT
@@ -263,10 +266,9 @@ PUBLIC BOOLEAN LYwouldPush ARGS2(
 		|| !strcmp(title, UPLOAD_OPTIONS_TITLE)
 		|| !strcmp(title, PERMIT_OPTIONS_TITLE)
 #endif /* DIRED_SUPPORT */
-	    )
-	    ? FALSE
-	    : TRUE;
+	    );
     }
+    return rc;
 }
 
 /*
diff --git a/src/LYJump.c b/src/LYJump.c
index 6f426153..d28468dc 100644
--- a/src/LYJump.c
+++ b/src/LYJump.c
@@ -213,11 +213,11 @@ PUBLIC char *LYJump ARGS1(int, key)
 
     ShortcutTotal = (jtp->history ? HTList_count(jtp->history) : 0);
     if (jump_buffer && *buf) {
-	recall = ((ShortcutTotal > 1) ? RECALL : NORECALL);
+	recall = ((ShortcutTotal > 1) ? RECALL_URL : NORECALL);
 	ShortcutNum = 0;
 	FirstShortcutRecall = FALSE;
     } else {
-	recall = ((ShortcutTotal >= 1) ? RECALL : NORECALL);
+	recall = ((ShortcutTotal >= 1) ? RECALL_URL : NORECALL);
 	ShortcutNum = ShortcutTotal;
 	FirstShortcutRecall = TRUE;
     }
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index 8f20e7e3..708f0e63 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -133,7 +133,7 @@ LYK_DOWNLOAD,        LYK_ELGOTO,  LYK_DIRED_MENU,   LYK_ECGOTO,
 LYK_HELP,            LYK_INDEX,      LYK_JUMP,      LYK_KEYMAP,
 /* H */              /* I */         /* J */        /* K */
 
-LYK_LIST,          LYK_MAIN_MENU,    LYK_NEXT,      LYK_OPTIONS,
+LYK_LIST,          LYK_MAIN_MENU,    LYK_PREV,      LYK_OPTIONS,
 /* L */              /* M */         /* N */        /* O */
 
 LYK_PRINT,          LYK_ABORT,    LYK_DEL_BOOKMARK, LYK_INDEX_SEARCH,
@@ -169,7 +169,7 @@ LYK_TAG_LINK,     LYK_PREV_DOC,   LYK_VIEW_BOOKMARK,   0,
 LYK_NOCACHE,            0,          LYK_INTERRUPT, LYK_SHIFT_LEFT,
 /* x */              /* y */          /* z */       /* { */
 
-LYK_LINEWRAP_TOGGLE, LYK_SHIFT_RIGHT,  0,          LYK_HISTORY,
+LYK_LINEWRAP_TOGGLE, LYK_SHIFT_RIGHT, LYK_NESTED_TABLES, LYK_HISTORY,
 /* | */               /* } */         /* ~ */       /* del */
 
 
@@ -784,6 +784,9 @@ PRIVATE Kcmd revmap[] = {
 	LYK_WHEREIS, "WHEREIS",
 	"search within the current document" ),
     DATA(
+	LYK_PREV, "PREV",
+	"search for the previous occurence" ),
+    DATA(
 	LYK_NEXT, "NEXT",
 	"search for the next occurence" ),
     DATA(
@@ -967,6 +970,11 @@ PRIVATE Kcmd revmap[] = {
 	LYK_TO_CLIPBOARD, "TO_CLIPBOARD",
 	"link's URL to Clip Board" ),
 #endif
+#ifdef EXP_NESTED_TABLES
+    DATA(
+	LYK_NESTED_TABLES, "NESTED_TABLES",
+	"toggle nested-table parsing on/off" ),
+#endif
     DATA(
 	LYK_UNKNOWN, NULL,
 	"" )
@@ -1234,7 +1242,7 @@ PRIVATE char *pretty_html ARGS1 (int, c)
 		}
 	    }
 	    if (!found) {
-		*dst++ = c;
+		*dst++ = (char) c;
 	    }
 	}
 	adj -= (dst - buf) - PRETTY_LEN;
@@ -1320,9 +1328,9 @@ PRIVATE void print_binding ARGS3(
 PUBLIC int lacname_to_lac ARGS1(
 	CONST char *,	func)
 {
-       Kcmd *mp = LYStringToKcmd(func);
+    Kcmd *mp = LYStringToKcmd(func);
 
-       return (mp != 0) ? (int) mp->code : -1;
+    return (mp != 0) ? (int) mp->code : -1;
 }
 
 /*
@@ -1333,17 +1341,17 @@ PUBLIC int lacname_to_lac ARGS1(
 PUBLIC int lecname_to_lec ARGS1(
 	CONST char *,	func)
 {
-       int i;
-       struct emap *mp;
-
-       if (func == NULL || *func == '\0')
-	       return (-1);
-       for (i = 0, mp = ekmap; (*mp).name != NULL; mp++, i++) {
-               if (strcmp((*mp).name, func) == 0) {
-                       return (*mp).code;
-               }
-       }
-       return (-1);
+    int i;
+    struct emap *mp;
+
+    if (func != NULL && *func != '\0') {
+	for (i = 0, mp = ekmap; (*mp).name != NULL; mp++, i++) {
+	    if (strcmp((*mp).name, func) == 0) {
+		return (*mp).code;
+	    }
+	}
+    }
+    return (-1);
 }
 
 /*
@@ -1490,7 +1498,7 @@ PUBLIC int remap ARGS3(
 	    key_override[c+1] = mp->code;
 	else
 #endif
-	    keymap[c+1] = mp->code;
+	    keymap[c+1] = (LYKeymap_t) mp->code;
 	return (c ? c : (int) LAC_TO_LKC0(mp->code)); /* don't return 0, successful */
     }
     return 0;
@@ -1761,9 +1769,12 @@ PUBLIC BOOL LYisNonAlnumKeyname ARGS2(
 	int,	ch,
 	int,	KeyName)
 {
-    if ((ch >= '0' && ch <= '9') ||
-        (ch >= 'A' && ch <= 'z') ||
-	ch < 0 || ch >= KEYMAP_SIZE)
+    if (ch < 0 || ch >= KEYMAP_SIZE)
+	return (FALSE);
+    if (ch > 0
+     && strchr("0123456789\
+ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz", ch) != NULL)
 	return (FALSE);
 
     return (BOOL) (keymap[ch+1] == KeyName);
diff --git a/src/LYKeymap.h b/src/LYKeymap.h
index 166df535..18db17c0 100644
--- a/src/LYKeymap.h
+++ b/src/LYKeymap.h
@@ -68,14 +68,6 @@ extern LYKeymap_t key_override[];
 				/* mask for lynxactioncode - must cover all
 				   assigned LYK_* values */
 
-
-#if 0
-/*  Substitute a single actioncode given a double one - NOT USED */
-#define LKC2_TO_LKC(c,n)   (((c) == -1 || !((c) & LKC_ISLECLAC)) ? (c) : \
-			    ((n) == 1) ? (((c) & LAC_MASK) | LKC_ISLAC) : \
-			    (((((c)&~LKC_ISLECLAC)>>LAC_SHIFT) & LAC_MASK) | LKC_ISLECLAC))
-#endif /* 0 */
-
 /*  Return lkc masking single actioncode, given an lkc masking a lac + lec */
 #define LKC2_TO_LKC(c)   (((c) == -1 || !((c) & LKC_ISLECLAC)) ? (c) : \
 			    (((c) & LAC_MASK) | LKC_ISLAC))
@@ -168,6 +160,7 @@ typedef enum {
   , LYK_OPTIONS
   , LYK_INDEX_SEARCH
   , LYK_WHEREIS
+  , LYK_PREV
   , LYK_NEXT
   , LYK_COMMENT
   , LYK_EDIT
@@ -265,6 +258,13 @@ typedef enum {
 #define LYK_PASTE_URL      LYK_UNKNOWN
 #define LYK_TO_CLIPBOARD   LYK_UNKNOWN
 #endif
+
+#ifdef EXP_NESTED_TABLES
+  , LYK_NESTED_TABLES
+#else
+#define LYK_NESTED_TABLES  LYK_UNKNOWN
+#endif
+
 } LYKeymapCode;
 
 /*
diff --git a/src/LYLocal.c b/src/LYLocal.c
index ae5e5701..4ef06fa2 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -67,11 +67,6 @@
 #define DIRED_MAXBUF 512
 #endif
 
-PRIVATE int LYExecv PARAMS((
-	char *		path,
-	char **		argv,
-	char *		msg));
-
 #ifdef DIRED_SUPPORT
 
 #ifdef OK_INSTALL
@@ -88,7 +83,7 @@ PRIVATE char *get_filename PARAMS((
 	size_t		bufsize));
 
 #ifdef OK_PERMIT
-PRIVATE BOOLEAN permit_location PARAMS((
+PRIVATE int permit_location PARAMS((
 	char *		destpath,
 	char *		srcpath,
 	char **		newpath));
@@ -327,6 +322,121 @@ PRIVATE BOOLEAN ok_localname ARGS2(char*, dst, CONST char*, src)
 }
 #endif /* OK_INSTALL */
 
+/*
+ *  Execute DIRED command, return -1 or 0 on failure, 1 success.
+ */
+PRIVATE int LYExecv ARGS3(
+	char *,		path,
+	char **,	argv,
+	char *,		msg)
+{
+    int rc = 0;
+#if defined(VMS)
+    CTRACE((tfp, "LYExecv:  Called inappropriately!\n"));
+#else
+#if defined(_WINDOWS)
+    if (!strcmp(path, TOUCH_PATH)) {
+#if defined(__BORLANDC__) || defined(__MINGW32__)
+	int fd = _creat(argv[1], S_IREAD | S_IWRITE);
+#else /* Visual C++ */
+	int fd = _creat(argv[1], _S_IREAD | _S_IWRITE);
+#endif
+	if (fd >= 0) {
+	    close(fd);
+	    return(1);
+	}
+    } else if (!strcmp(path, RM_PATH)) {
+	rc = remove(argv[2]);
+    } else {
+	CTRACE((tfp, "LYExecv:  Called inappropriately! (path=%s)\n", path));
+    }
+#else
+    int n;
+    char *tmpbuf = 0;
+#ifdef __DJGPP__
+    stop_curses();
+    HTSprintf0(&tmpbuf, "%s", path);
+    for (n = 1; argv[n] != 0; n++)
+	HTSprintf(&tmpbuf, " %s", argv[n]);
+    HTSprintf(&tmpbuf, "\n");
+    rc = LYSystem(tmpbuf) ? 0 : 1;
+#else
+    pid_t pid;
+#ifdef HAVE_TYPE_UNIONWAIT
+    union wait wstatus;
+#else
+    int wstatus;
+#endif
+
+    if (TRACE) {
+	CTRACE((tfp, "LYExecv path='%s'\n", path));
+	for (n = 0; argv[n] != 0; n++)
+	    CTRACE((tfp, "argv[%d] = '%s'\n", n, argv[n]));
+    }
+
+    rc = 1;		/* It will work */
+    stop_curses();
+    pid = fork();	/* fork and execute command */
+
+    switch (pid) {
+	case -1:
+	    HTSprintf0(&tmpbuf, gettext("Unable to %s due to system error!"), msg);
+	    rc = 0;
+	    break;	/* don't fall thru! - KW */
+
+	case 0:  /* child */
+#ifdef USE_EXECVP
+	    execvp(path, argv);	/* this uses our $PATH */
+#else
+	    execv(path, argv);
+#endif
+	    exit(EXIT_FAILURE);	/* execv failed, give wait() something to look at */
+	    /*NOTREACHED*/
+
+	default:  /* parent */
+#if !HAVE_WAITPID
+	    while (wait(&wstatus) != pid)
+		; /* do nothing */
+#else
+	    while (-1 == waitpid(pid, &wstatus, 0)) { /* wait for child */
+#ifdef EINTR
+		if (errno == EINTR)
+		    continue;
+#endif /* EINTR */
+#ifdef ERESTARTSYS
+		if (errno == ERESTARTSYS)
+		    continue;
+#endif /* ERESTARTSYS */
+		break;
+	    }
+#endif /* !HAVE_WAITPID */
+	    if (WEXITSTATUS(wstatus) != 0 ||
+		WTERMSIG(wstatus) > 0)	{ /* error return */
+		HTSprintf0(&tmpbuf, gettext("Probable failure to %s due to system error!"),
+				   msg);
+		rc = 0;
+	    }
+    }
+#endif /* __DJGPP__ */
+
+    if (rc == 0) {
+	/*
+	 *  Screen may have message from the failed execv'd command.
+	 *  Give user time to look at it before screen refresh.
+	 */
+	LYSleepAlert();
+    }
+    start_curses();
+    if (tmpbuf != 0) {
+	if (rc == 0)
+	    HTAlert(tmpbuf);
+	FREE(tmpbuf);
+    }
+
+#endif /* _WINDOWS */
+#endif /* VMS */
+    return(rc);
+}
 PRIVATE int move_file ARGS2(char *, source, char *, target)
 {
     int code;
@@ -388,7 +498,7 @@ PRIVATE BOOLEAN dir_has_same_owner ARGS2(struct stat *, info, int, owner)
 /*
  *  Remove all tagged files and directories.
  */
-PRIVATE BOOLEAN remove_tagged NOARGS
+PRIVATE int remove_tagged NOARGS
 {
     int ans;
     BOOL will_clear = TRUE;
@@ -450,7 +560,7 @@ PRIVATE BOOLEAN remove_tagged NOARGS
  *  If a user has enough permissions to move a file somewhere, the same
  *   uid with Lynx & dired can do the same thing.
  */
-PRIVATE BOOLEAN modify_tagged ARGS1(
+PRIVATE int modify_tagged ARGS1(
 	char *,		testpath)
 {
     char *cp;
@@ -606,7 +716,7 @@ PRIVATE BOOLEAN modify_tagged ARGS1(
 /*
  *  Modify the name of the specified item.
  */
-PRIVATE BOOLEAN modify_name ARGS1(
+PRIVATE int modify_name ARGS1(
 	char *,		testpath)
 {
     char *cp;
@@ -661,7 +771,7 @@ PRIVATE BOOLEAN modify_name ARGS1(
 /*
  *  Change the location of a file or directory.
  */
-PRIVATE BOOLEAN modify_location ARGS1(
+PRIVATE int modify_location ARGS1(
 	char *,		testpath)
 {
     char *cp;
@@ -748,7 +858,7 @@ PRIVATE BOOLEAN modify_location ARGS1(
 /*
  *  Modify name or location of a file or directory on localhost.
  */
-PUBLIC BOOLEAN local_modify ARGS2(
+PUBLIC int local_modify ARGS2(
 	document *,	doc,
 	char **,	newpath)
 {
@@ -821,7 +931,7 @@ PUBLIC BOOLEAN local_modify ARGS2(
 /*
  *  Create a new empty file in the current directory.
  */
-PRIVATE BOOLEAN create_file ARGS1(
+PRIVATE int create_file ARGS1(
 	char *,		current_location)
 {
     int code = FALSE;
@@ -831,38 +941,37 @@ PRIVATE BOOLEAN create_file ARGS1(
     char *bad_chars = ".~/";
 
     if (get_filename(gettext("Enter name of file to create: "),
-		     tmpbuf, sizeof(tmpbuf)) == NULL) {
-	return code;
-    }
+		     tmpbuf, sizeof(tmpbuf)) != NULL) {
 
-    if (!no_dotfiles && show_dotfiles) {
-	bad_chars = "~/";
-    }
+	if (!no_dotfiles && show_dotfiles) {
+	    bad_chars = "~/";
+	}
 
-    if (strstr(tmpbuf, "//") != NULL) {
-	HTAlert(gettext("Illegal redirection \"//\" found! Request ignored."));
-    } else if (strlen(tmpbuf) && strchr(bad_chars, tmpbuf[0]) == NULL) {
-	StrAllocCopy(testpath, current_location);
-	LYAddPathSep(&testpath);
+	if (strstr(tmpbuf, "//") != NULL) {
+	    HTAlert(gettext("Illegal redirection \"//\" found! Request ignored."));
+	} else if (strlen(tmpbuf) && strchr(bad_chars, tmpbuf[0]) == NULL) {
+	    StrAllocCopy(testpath, current_location);
+	    LYAddPathSep(&testpath);
 
-	/*
-	 *  Append the target filename to the current location.
-	 */
-	StrAllocCat(testpath, tmpbuf);
+	    /*
+	     *  Append the target filename to the current location.
+	     */
+	    StrAllocCat(testpath, tmpbuf);
 
-	/*
-	 *  Make sure the target does not already exist
-	 */
-	if (not_already_exists(testpath)) {
-	    char *msg = 0;
-	    HTSprintf0(&msg,gettext("create %s"),testpath);
-	    args[0] = "touch";
-	    args[1] = testpath;
-	    args[2] = (char *) 0;
-	    code = (LYExecv(TOUCH_PATH, args, msg) <= 0) ? -1 : 1;
-	    FREE(msg);
+	    /*
+	     *  Make sure the target does not already exist
+	     */
+	    if (not_already_exists(testpath)) {
+		char *msg = 0;
+		HTSprintf0(&msg,gettext("create %s"),testpath);
+		args[0] = "touch";
+		args[1] = testpath;
+		args[2] = (char *) 0;
+		code = (LYExecv(TOUCH_PATH, args, msg) <= 0) ? -1 : 1;
+		FREE(msg);
+	    }
+	    FREE(testpath);
 	}
-	FREE(testpath);
     }
     return code;
 }
@@ -870,7 +979,7 @@ PRIVATE BOOLEAN create_file ARGS1(
 /*
  *  Create a new directory in the current directory.
  */
-PRIVATE BOOLEAN create_directory ARGS1(
+PRIVATE int create_directory ARGS1(
 	char *,		current_location)
 {
     int code = FALSE;
@@ -880,35 +989,34 @@ PRIVATE BOOLEAN create_directory ARGS1(
     char *bad_chars = ".~/";
 
     if (get_filename(gettext("Enter name for new directory: "),
-		     tmpbuf, sizeof(tmpbuf)) == NULL) {
-	return code;
-    }
+		     tmpbuf, sizeof(tmpbuf)) != NULL) {
 
-    if (!no_dotfiles && show_dotfiles) {
-	bad_chars = "~/";
-    }
+	if (!no_dotfiles && show_dotfiles) {
+	    bad_chars = "~/";
+	}
 
-    if (strstr(tmpbuf, "//") != NULL) {
-	HTAlert(gettext("Illegal redirection \"//\" found! Request ignored."));
-    } else if (strlen(tmpbuf) && strchr(bad_chars, tmpbuf[0]) == NULL) {
-	StrAllocCopy(testpath, current_location);
-	LYAddPathSep(&testpath);
+	if (strstr(tmpbuf, "//") != NULL) {
+	    HTAlert(gettext("Illegal redirection \"//\" found! Request ignored."));
+	} else if (strlen(tmpbuf) && strchr(bad_chars, tmpbuf[0]) == NULL) {
+	    StrAllocCopy(testpath, current_location);
+	    LYAddPathSep(&testpath);
 
-	StrAllocCat(testpath, tmpbuf);
+	    StrAllocCat(testpath, tmpbuf);
 
-	/*
-	 *  Make sure the target does not already exist.
-	 */
-	if (not_already_exists(testpath)) {
-	    char *msg = 0;
-	    HTSprintf0(&msg,"make directory %s",testpath);
-	    args[0] = "mkdir";
-	    args[1] = testpath;
-	    args[2] = (char *) 0;
-	    code = (LYExecv(MKDIR_PATH, args, msg) <= 0) ? -1 : 1;
-	    FREE(msg);
+	    /*
+	     *  Make sure the target does not already exist.
+	     */
+	    if (not_already_exists(testpath)) {
+		char *msg = 0;
+		HTSprintf0(&msg,"make directory %s",testpath);
+		args[0] = "mkdir";
+		args[1] = testpath;
+		args[2] = (char *) 0;
+		code = (LYExecv(MKDIR_PATH, args, msg) <= 0) ? -1 : 1;
+		FREE(msg);
+	    }
+	    FREE(testpath);
 	}
-	FREE(testpath);
     }
     return code;
 }
@@ -916,7 +1024,7 @@ PRIVATE BOOLEAN create_directory ARGS1(
 /*
  *  Create a file or a directory at the current location.
  */
-PUBLIC BOOLEAN local_create ARGS1(
+PUBLIC int local_create ARGS1(
 	document *,	doc)
 {
     int ans;
@@ -946,7 +1054,7 @@ PUBLIC BOOLEAN local_create ARGS1(
 /*
  *  Remove a single file or directory.
  */
-PRIVATE BOOLEAN remove_single ARGS1(
+PRIVATE int remove_single ARGS1(
 	char *,		testpath)
 {
     int code = 0;
@@ -1012,7 +1120,7 @@ PRIVATE BOOLEAN remove_single ARGS1(
 /*
  *  Remove a file or a directory.
  */
-PUBLIC BOOLEAN local_remove ARGS1(
+PUBLIC int local_remove ARGS1(
 	document *,	doc)
 {
     char *cp, *tp;
@@ -1052,33 +1160,28 @@ PUBLIC BOOLEAN local_remove ARGS1(
 }
 
 #ifdef OK_PERMIT
-/*
- *  Table of permission strings and chmod values.
- *  Makes the code a bit cleaner.
- */
-static struct {
-    CONST char *string_mode;	/* Key for  value below */
-    long permit_bits;		/* Value for chmod/whatever */
-} permissions[] = {
-    {"IRUSR", S_IRUSR},
-    {"IWUSR", S_IWUSR},
-    {"IXUSR", S_IXUSR},
-    {"IRGRP", S_IRGRP},
-    {"IWGRP", S_IWGRP},
-    {"IXGRP", S_IXGRP},
-    {"IROTH", S_IROTH},
-    {"IWOTH", S_IWOTH},
-    {"IXOTH", S_IXOTH},
-    {NULL, 0}			/* Don't include setuid and friends;
-				   use shell access for that. */
-};
 
 PRIVATE char LYValidPermitFile[LY_MAXPATH] = "\0";
 
+PRIVATE long permit_bits ARGS1(char *, string_mode)
+{
+    if (!strcmp(string_mode, "IRUSR")) return S_IRUSR;
+    if (!strcmp(string_mode, "IWUSR")) return S_IWUSR;
+    if (!strcmp(string_mode, "IXUSR")) return S_IXUSR;
+    if (!strcmp(string_mode, "IRGRP")) return S_IRGRP;
+    if (!strcmp(string_mode, "IWGRP")) return S_IWGRP;
+    if (!strcmp(string_mode, "IXGRP")) return S_IXGRP;
+    if (!strcmp(string_mode, "IROTH")) return S_IROTH;
+    if (!strcmp(string_mode, "IWOTH")) return S_IWOTH;
+    if (!strcmp(string_mode, "IXOTH")) return S_IXOTH;
+    /* Don't include setuid and friends; use shell access for that. */
+    return 0;
+}
+
 /*
  *  Handle DIRED permissions.
  */
-PRIVATE BOOLEAN permit_location ARGS3(
+PRIVATE int permit_location ARGS3(
 	char *,		destpath,
 	char *,		srcpath,
 	char **,	newpath)
@@ -1278,22 +1381,18 @@ PRIVATE BOOLEAN permit_location ARGS3(
 		*cr++ = '\0';
 	    }
 	    if (strncmp(cp, "mode=", 5) == 0) { /* Magic string. */
-		int i;
-
-		for(i = 0; permissions[i].string_mode != NULL; i++) {
-		    if (strcmp(permissions[i].string_mode, cp+5) == 0) {
-			/*
-			 *  If restricted, only change eXecute
-			 *  permissions on directories.
-			 */
-			if (!no_change_exec_perms ||
-			    strchr(cp+5,'X') == NULL ||
-			    S_ISDIR(dir_info.st_mode))
-			    new_mode |= permissions[i].permit_bits;
-			break;
-		    }
-		}
-		if (permissions[i].string_mode == NULL) {
+		long mask = permit_bits(cp + 5);
+
+		if (mask != 0) {
+		    /*
+		     *  If restricted, only change eXecute
+		     *  permissions on directories.
+		     */
+		    if (!no_change_exec_perms
+		     || strchr(cp+5, 'X') == NULL
+		     || S_ISDIR(dir_info.st_mode))
+			new_mode |= mask;
+		} else {
 		    HTAlert(gettext("Invalid mode format."));
 		    return 0;
 		}
@@ -1756,7 +1855,7 @@ PUBLIC int dired_options ARGS2(
     dir = HTfullURL_toFile(doc->address);
     LYTrimPathSep(dir);
 
-    nothing_tagged = (HTList_isEmpty(tagged));
+    nothing_tagged = (BOOL) (HTList_isEmpty(tagged));
 
     BeginInternalPage(fp0, DIRED_MENU_TITLE, DIRED_MENU_HELP);
 
@@ -2311,7 +2410,7 @@ PRIVATE char * render_item ARGS6(
 		    break;
 		default:
 		    *BP_INC = '%';
-		    *BP_INC =*s;
+		    *BP_INC = *s;
 		    break;
 	    }
 	} else {
@@ -2333,119 +2432,3 @@ PRIVATE char * render_item ARGS6(
 }
 
 #endif /* DIRED_SUPPORT */
-
-/*
- *  Execute DIRED command, return -1 or 0 on failure, 1 success.
- */
-PRIVATE int LYExecv ARGS3(
-	char *,		path,
-	char **,	argv,
-	char *,		msg)
-{
-    int rc = 0;
-#if defined(VMS)
-    CTRACE((tfp, "LYExecv:  Called inappropriately!\n"));
-#else
-#if defined(_WINDOWS)
-    if (!strcmp(path, TOUCH_PATH)) {
-#if defined(__BORLANDC__) || defined(__MINGW32__)
-	int fd = _creat(argv[1], S_IREAD | S_IWRITE);
-#else /* Visual C++ */
-	int fd = _creat(argv[1], _S_IREAD | _S_IWRITE);
-#endif
-	if (fd >= 0) {
-	    close(fd);
-	    return(1);
-	}
-    } else if (!strcmp(path, RM_PATH)) {
-	rc = remove(argv[2]);
-    } else {
-	CTRACE((tfp, "LYExecv:  Called inappropriately! (path=%s)\n", path));
-    }
-#else
-    int n;
-    char *tmpbuf = 0;
-#ifdef __DJGPP__
-    stop_curses();
-    HTSprintf0(&tmpbuf, "%s", path);
-    for (n = 1; argv[n] != 0; n++)
-	HTSprintf(&tmpbuf, " %s", argv[n]);
-    HTSprintf(&tmpbuf, "\n");
-    rc = LYSystem(tmpbuf) ? 0 : 1;
-#else
-    pid_t pid;
-#ifdef HAVE_TYPE_UNIONWAIT
-    union wait wstatus;
-#else
-    int wstatus;
-#endif
-
-    if (TRACE) {
-	CTRACE((tfp, "LYExecv path='%s'\n", path));
-	for (n = 0; argv[n] != 0; n++)
-	    CTRACE((tfp, "argv[%d] = '%s'\n", n, argv[n]));
-    }
-
-    rc = 1;		/* It will work */
-    stop_curses();
-    pid = fork();	/* fork and execute command */
-
-    switch (pid) {
-	case -1:
-	    HTSprintf0(&tmpbuf, gettext("Unable to %s due to system error!"), msg);
-	    rc = 0;
-	    break;	/* don't fall thru! - KW */
-
-	case 0:  /* child */
-#ifdef USE_EXECVP
-	    execvp(path, argv);	/* this uses our $PATH */
-#else
-	    execv(path, argv);
-#endif
-	    exit(EXIT_FAILURE);	/* execv failed, give wait() something to look at */
-	    /*NOTREACHED*/
-
-	default:  /* parent */
-#if !HAVE_WAITPID
-	    while (wait(&wstatus) != pid)
-		; /* do nothing */
-#else
-	    while (-1 == waitpid(pid, &wstatus, 0)) { /* wait for child */
-#ifdef EINTR
-		if (errno == EINTR)
-		    continue;
-#endif /* EINTR */
-#ifdef ERESTARTSYS
-		if (errno == ERESTARTSYS)
-		    continue;
-#endif /* ERESTARTSYS */
-		break;
-	    }
-#endif /* !HAVE_WAITPID */
-	    if (WEXITSTATUS(wstatus) != 0 ||
-		WTERMSIG(wstatus) > 0)	{ /* error return */
-		HTSprintf0(&tmpbuf, gettext("Probable failure to %s due to system error!"),
-				   msg);
-		rc = 0;
-	    }
-    }
-#endif /* __DJGPP__ */
-
-    if (rc == 0) {
-	/*
-	 *  Screen may have message from the failed execv'd command.
-	 *  Give user time to look at it before screen refresh.
-	 */
-	LYSleepAlert();
-    }
-    start_curses();
-    if (tmpbuf != 0) {
-	if (rc == 0)
-	    HTAlert(tmpbuf);
-	FREE(tmpbuf);
-    }
-
-#endif /* _WINDOWS */
-#endif /* VMS */
-    return(rc);
-}
diff --git a/src/LYLocal.h b/src/LYLocal.h
index 4ba498d2..4a9f5636 100644
--- a/src/LYLocal.h
+++ b/src/LYLocal.h
@@ -8,9 +8,9 @@
 /* Special return code for LYMainLoop.c */
 #define PERMIT_FORM_RESULT (-99)
 
-extern BOOLEAN local_create PARAMS((document *doc));
-extern BOOLEAN local_modify PARAMS((document *doc, char **newpath));
-extern BOOLEAN local_remove PARAMS((document *doc));
+extern int local_create PARAMS((document *doc));
+extern int local_modify PARAMS((document *doc, char **newpath));
+extern int local_remove PARAMS((document *doc));
 #ifdef OK_INSTALL
 extern BOOLEAN local_install PARAMS((char *destpath, char *srcpath, char **newpath));
 #endif
diff --git a/src/LYMail.c b/src/LYMail.c
index 77ffeabe..d5432c7f 100644
--- a/src/LYMail.c
+++ b/src/LYMail.c
@@ -9,6 +9,7 @@
 #include <LYStrings.h>
 #include <GridText.h>
 #include <LYMail.h>
+#include <LYEdit.h>
 #include <LYCharSets.h>  /* to get current charset for mail header */
 
 #include <LYLeaks.h>
@@ -229,7 +230,7 @@ PRIVATE BOOLEAN trim_comma ARGS1(
 {
     if (address[(strlen(address) - 1)] == ',')
 	address[(strlen(address) - 1)] = '\0';
-    return *address == '\0';
+    return (BOOL) (*address == '\0');
 }
 
 /*
@@ -1431,10 +1432,6 @@ PUBLIC void reply_by_mail ARGS4(
 #endif /* !VMS */
 
     if (!no_editor && !EMPTY(editor)) {
-	/*
-	 *  Use an external editor for the message.
-	 */
-	char *editor_arg = "";
 
 	if (body) {
 	    cp1 = body;
@@ -1452,7 +1449,7 @@ PUBLIC void reply_by_mail ARGS4(
 	    if (HTConfirm(is_preparsed
 	    	? INC_PREPARSED_MSG_PROMPT
 		: INC_ORIG_MSG_PROMPT) == YES) {
-		print_wwwfile_to_fd(fd, (BOOLEAN)!is_preparsed);
+		print_wwwfile_to_fd(fd, (BOOL) !is_preparsed);
 	    }
 	}
 	LYCloseTempFP(fd);	/* Close the tmpfile. */
@@ -1464,20 +1461,7 @@ PUBLIC void reply_by_mail ARGS4(
 	/*
 	 *  Spawn the users editor on the mail file
 	 */
-	if (strstr(editor, "pico")) {
-	    editor_arg = " -t"; /* No prompt for filename to use */
-	}
-	command = 0;
-	HTSprintf0(&command, "%s%s %s", editor, editor_arg, my_tmpfile);
-	_statusline(SPAWNING_EDITOR_FOR_MAIL);
-	stop_curses();
-	if (LYSystem(command)) {	/* Spawn Editor */
-	    start_curses();
-	    HTAlert(ERROR_SPAWNING_EDITOR);
-	} else {
-	    start_curses();
-	}
-	FREE(command);
+	edit_temporary_file(my_tmpfile, "", SPAWNING_EDITOR_FOR_MAIL);
 
     } else if (body) {
 	/*
diff --git a/src/LYMain.c b/src/LYMain.c
index bf63a8ed..e93f1894 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -156,9 +156,8 @@ PUBLIC lynx_list_item_type *externals = NULL;
 #endif
 PUBLIC lynx_list_item_type *uploaders = NULL;
 PUBLIC int port_syntax = 1;
-PUBLIC int LYShowColor = SHOW_COLOR_UNKNOWN; /* to show or not to show */
-PUBLIC int LYChosenShowColor = SHOW_COLOR_UNKNOWN; /* whether to show and save */
-PUBLIC int LYrcShowColor = SHOW_COLOR_UNKNOWN;	/* ... as last read or written */
+PUBLIC int LYShowColor = SHOW_COLOR_UNKNOWN; /* to show or not */
+PUBLIC int LYrcShowColor = SHOW_COLOR_UNKNOWN; /* ... last used */
 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
 PUBLIC BOOLEAN LYUseFormsOptions = TRUE; /* use forms-based options menu */
 #endif
@@ -277,13 +276,14 @@ PUBLIC BOOLEAN no_compileopts_info = FALSE;
 
 PUBLIC BOOLEAN no_statusline = FALSE;
 PUBLIC BOOLEAN no_filereferer = TRUE;
-PUBLIC char LYRefererWithQuery = 'D'; /* 'D' for drop */
+PUBLIC char LYRefererWithQuery = 'D';	/* 'D' for drop */
 PUBLIC BOOLEAN local_host_only = FALSE;
 PUBLIC BOOLEAN override_no_download = FALSE;
-PUBLIC BOOLEAN show_dotfiles = FALSE; /* From rcfile if no_dotfiles is false */
+PUBLIC BOOLEAN show_dotfiles = FALSE;	/* From rcfile if no_dotfiles is false */
 PUBLIC BOOLEAN LYforce_HTML_mode = FALSE;
+
 #ifdef __DJGPP__
-PUBLIC BOOLEAN watt_debug = FALSE;  /* WATT-32 debugging */
+PUBLIC BOOLEAN watt_debug = FALSE;	/* WATT-32 debugging */
 #endif /* __DJGPP__ */
 
 #ifdef WIN_EX
@@ -292,7 +292,7 @@ PUBLIC char windows_drive[4];		/* 1998/01/13 (Tue) 21:13:24 */
 #endif
 
 #ifdef _WINDOWS
-#define	TIMEOUT	180		/* 1998/03/30 (Mon) 14:50:44 */
+#define	TIMEOUT	180			/* 1998/03/30 (Mon) 14:50:44 */
 PUBLIC int lynx_timeout = TIMEOUT;
 PUBLIC CRITICAL_SECTION critSec_DNS;	/* 1998/09/03 (Thu) 22:01:56 */
 PUBLIC CRITICAL_SECTION critSec_READ;	/* 1998/09/03 (Thu) 22:01:56 */
@@ -314,135 +314,145 @@ PUBLIC BOOLEAN no_table_center = FALSE;	/* 1998/10/09 (Fri) 15:12:49 */
 PUBLIC BOOLEAN mail_is_blat = TRUE;
 #endif
 
-PUBLIC char *editor = NULL;	/* the name of the current editor */
-PUBLIC char *jumpfile = NULL;	/* the name of the default jumps file */
-PUBLIC char *jumpprompt = NULL; /* the default jumps prompt */
-PUBLIC char *bookmark_page = NULL; /* the name of the default bookmark page */
-PUBLIC char *BookmarkPage = NULL;  /* the name of the current bookmark page */
-PUBLIC char *LynxHome = NULL;	/* the default Home HREF. */
-PUBLIC char *homepage = NULL;  /* home page or main screen */
-PUBLIC char *original_dir = NULL; /* the original directory */
-PUBLIC char *startfile = NULL;	/* the first file */
-PUBLIC char *helpfile = NULL;	/* the main help file */
-PUBLIC char *helpfilepath = NULL;   /* the path to the help file set */
-PUBLIC char *lynxjumpfile = NULL;   /* the current jump file URL */
-PUBLIC char *lynxlistfile = NULL;   /* the current list file URL */
-PUBLIC char *lynxlinksfile = NULL;  /* the current visited links file URL */
-PUBLIC char *startrealm = NULL;     /* the startfile realm */
-PUBLIC char *indexfile = NULL;	    /* an index file if there is one */
-PUBLIC int outgoing_mail_charset = -1;     /* translate mail to this charset */
-PUBLIC char *personal_mail_address = NULL; /* the users mail address */
-PUBLIC char *x_display = NULL;	    /* display environment variable */
-PUBLIC char *personal_type_map = NULL;	   /* .mailcap */
-PUBLIC char *global_type_map = NULL;	   /* global mailcap */
-PUBLIC char *global_extension_map = NULL;  /* global mime.types */
-PUBLIC char *personal_extension_map = NULL;/* .mime.types */
-PUBLIC char *language = NULL;	    /* preferred language */
-PUBLIC char *pref_charset = NULL;   /* preferred character set */
-PUBLIC BOOLEAN LYNewsPosting = NEWS_POSTING; /* News posting supported? */
-PUBLIC char *LynxSigFile = NULL;    /* Signature file, in or off home */
-PUBLIC char *system_mail = NULL;	  /* The path for sending mail */
-PUBLIC char *system_mail_flags = NULL;	  /* Flags for sending mail */
-PUBLIC char *lynx_cmd_logfile;	/* file to write keystroke commands, if any */
-PUBLIC char *lynx_cmd_script;	/* file to read keystroke commands, if any */
-PUBLIC char *lynx_cfg_file = NULL;	  /* location of active lynx.cfg */
-PUBLIC char *lynx_temp_space = NULL; /* The prefix for temporary file paths */
-PUBLIC char *lynx_save_space = NULL; /* The prefix for save to disk paths */
-PUBLIC char *LYHostName = NULL;		/* treat as a local host name */
-PUBLIC char *LYLocalDomain = NULL;	/* treat as a local domain tail */
-PUBLIC BOOLEAN clickable_images = MAKE_LINKS_FOR_ALL_IMAGES;
-PUBLIC BOOLEAN pseudo_inline_alts = MAKE_PSEUDO_ALTS_FOR_INLINES;
-PUBLIC BOOLEAN crawl = FALSE;	     /* Do crawl? */
-PUBLIC BOOLEAN traversal = FALSE;    /* Do traversals? */
-PUBLIC BOOLEAN check_realm = FALSE;  /* Restrict to the starting realm? */
-	       /* Links beyond a displayed page with no links? */
-PUBLIC BOOLEAN more_links = FALSE;
-PUBLIC int lynx_temp_subspace = 0;	/* > 0 if we made temp-directory */
-PUBLIC int     ccount = 0; /* Starting number for lnk#.dat files in crawls */
-PUBLIC BOOLEAN LYCancelledFetch = FALSE; /* TRUE if cancelled binary fetch */
-	       /* Include mime headers with source dump */
-PUBLIC BOOLEAN keep_mime_headers = FALSE;
-PUBLIC BOOLEAN no_url_redirection = FALSE; /* Don't follow URL redirections */
-PUBLIC char *form_post_data = NULL;  /* User data for post form */
-PUBLIC char *form_get_data = NULL;   /* User data for get form */
-PUBLIC char *http_error_file = NULL; /* Place HTTP status code in this file */
-	     /* Id:Password for protected documents */
-PUBLIC char *authentication_info[2] = {NULL, NULL};
-	     /* Id:Password for protected proxy servers */
-PUBLIC char *proxyauth_info[2] = {NULL, NULL};
+#ifdef USE_BLINK
+#  ifdef __EMX__
+PUBLIC BOOLEAN term_blink_is_boldbg = TRUE;
+#  else
+PUBLIC BOOLEAN term_blink_is_boldbg = FALSE;
+#  endif
+#endif
+
 PUBLIC BOOLEAN HEAD_request = FALSE;
-PUBLIC BOOLEAN scan_for_buried_news_references = TRUE;
-PUBLIC BOOLEAN LYRawMode;
+PUBLIC BOOLEAN LYAcceptAllCookies = ACCEPT_ALL_COOKIES; /* take all cookies? */
+PUBLIC BOOLEAN LYCancelledFetch = FALSE;/* TRUE if cancelled binary fetch */
+PUBLIC BOOLEAN LYCollapseBRs = COLLAPSE_BR_TAGS;  /* Collapse serial BRs? */
 PUBLIC BOOLEAN LYDefaultRawMode;
+PUBLIC BOOLEAN LYListNewsDates = LIST_NEWS_DATES;
+PUBLIC BOOLEAN LYListNewsNumbers = LIST_NEWS_NUMBERS;
+PUBLIC BOOLEAN LYMBMBlocked = BLOCK_MULTI_BOOKMARKS;
+PUBLIC BOOLEAN LYNewsPosting = NEWS_POSTING; /* News posting supported? */
+PUBLIC BOOLEAN LYNoFromHeader = TRUE;	/* Never send From header?	   */
+PUBLIC BOOLEAN LYNoRefererForThis=FALSE;/* No Referer header for this URL? */
+PUBLIC BOOLEAN LYNoRefererHeader=FALSE; /* Never send Referer header?	   */
+PUBLIC BOOLEAN LYRawMode;
+PUBLIC BOOLEAN LYSelectPopups = USE_SELECT_POPUPS;
+PUBLIC BOOLEAN LYSetCookies = SET_COOKIES; /* Process Set-Cookie headers? */
+PUBLIC BOOLEAN LYUseDefSelPop = TRUE;	/* Command line -popup toggle */
 PUBLIC BOOLEAN LYUseDefaultRawMode = TRUE;
-PUBLIC char *UCAssume_MIMEcharset = NULL;
-PUBLIC BOOLEAN UCSaveBookmarksInUnicode = FALSE;
-PUBLIC BOOLEAN UCForce8bitTOUPPER = FALSE; /* override locale for case-conversion? */
-PUBLIC int LYlines = DFT_ROWS;
-PUBLIC int LYcols = DFT_COLS;
-PUBLIC int dump_output_width = 0;
-PUBLIC linkstruct links[MAXLINKS];
-PUBLIC histstruct history[MAXHIST];
-PUBLIC int nlinks = 0;		/* number of links in memory */
-PUBLIC int nhist = 0;		/* number of history entries */
-PUBLIC BOOLEAN more = FALSE;	/* is there more text to display? */
-PUBLIC int InfoSecs;	/* Seconds to sleep() for Information messages */
-PUBLIC int MessageSecs; /* Seconds to sleep() for important Messages   */
-PUBLIC int AlertSecs;	/* Seconds to sleep() for HTAlert() messages   */
-PUBLIC BOOLEAN bookmark_start = FALSE;
-PUBLIC char *LYUserAgent = NULL;	/* Lynx User-Agent header	   */
-PUBLIC char *LYUserAgentDefault = NULL; /* Lynx default User-Agent header  */
 PUBLIC BOOLEAN LYUseMouse = FALSE;
-PUBLIC BOOLEAN LYNoRefererHeader=FALSE; /* Never send Referer header?	   */
-PUBLIC BOOLEAN LYNoRefererForThis=FALSE;/* No Referer header for this URL? */
-PUBLIC BOOLEAN LYNoFromHeader = TRUE;	/* Never send From header?	   */
-PUBLIC BOOLEAN LYListNewsNumbers = LIST_NEWS_NUMBERS;
-PUBLIC BOOLEAN LYListNewsDates = LIST_NEWS_DATES;
 PUBLIC BOOLEAN LYisConfiguredForX = FALSE;
-PUBLIC char *URLDomainPrefixes = NULL;
-PUBLIC char *URLDomainSuffixes = NULL;
+PUBLIC BOOLEAN UCForce8bitTOUPPER = FALSE; /* override locale for case-conversion? */
+PUBLIC BOOLEAN UCSaveBookmarksInUnicode = FALSE;
+PUBLIC BOOLEAN bookmark_start = FALSE;
+PUBLIC BOOLEAN check_realm = FALSE;  /* Restrict to the starting realm? */
+PUBLIC BOOLEAN clickable_images = MAKE_LINKS_FOR_ALL_IMAGES;
+PUBLIC BOOLEAN crawl = FALSE;		/* Do crawl? */
+PUBLIC BOOLEAN keep_mime_headers = FALSE; /* Include mime headers with source dump */
+PUBLIC BOOLEAN more = FALSE;		/* is there more text to display? */
+PUBLIC BOOLEAN more_links = FALSE;	/* Links beyond a displayed page with no links? */
+PUBLIC BOOLEAN no_url_redirection = FALSE; /* Don't follow URL redirections */
+PUBLIC BOOLEAN pseudo_inline_alts = MAKE_PSEUDO_ALTS_FOR_INLINES;
+PUBLIC BOOLEAN scan_for_buried_news_references = TRUE;
 PUBLIC BOOLEAN startfile_ok = FALSE;
 PUBLIC BOOLEAN startfile_stdin = FALSE;
-PUBLIC BOOLEAN LYSelectPopups = USE_SELECT_POPUPS;
-PUBLIC BOOLEAN LYUseDefSelPop = TRUE;	/* Command line -popup toggle */
-PUBLIC BOOLEAN LYMultiBookmarks = MULTI_BOOKMARK_SUPPORT;
-PUBLIC BOOLEAN LYMBMBlocked = BLOCK_MULTI_BOOKMARKS;
-PUBLIC BOOLEAN LYMBMAdvanced = TRUE;
-PUBLIC int LYStatusLine = -1;		 /* Line for statusline() if > -1 */
-PUBLIC BOOLEAN LYCollapseBRs = COLLAPSE_BR_TAGS;  /* Collapse serial BRs? */
-PUBLIC BOOLEAN LYSetCookies = SET_COOKIES; /* Process Set-Cookie headers? */
-PUBLIC BOOLEAN LYAcceptAllCookies = ACCEPT_ALL_COOKIES; /* take all cookies? */
+PUBLIC BOOLEAN traversal = FALSE;	/* Do traversals? */
+PUBLIC char *BookmarkPage = NULL;	/* the name of the current bookmark page */
 PUBLIC char *LYCookieAcceptDomains = NULL; /* domains to accept all cookies */
-PUBLIC char *LYCookieRejectDomains = NULL; /* domains to reject all cookies */
-PUBLIC char *LYCookieStrictCheckDomains = NULL; /* check strictly  */
 PUBLIC char *LYCookieLooseCheckDomains = NULL;  /* check loosely   */
 PUBLIC char *LYCookieQueryCheckDomains = NULL;  /* check w/a query */
+PUBLIC char *LYCookieRejectDomains = NULL; /* domains to reject all cookies */
 PUBLIC char *LYCookieSAcceptDomains = NULL; /* domains to accept all cookies */
-PUBLIC char *LYCookieSRejectDomains = NULL; /* domains to reject all cookies */
-PUBLIC char *LYCookieSStrictCheckDomains = NULL; /* check strictly  */
 PUBLIC char *LYCookieSLooseCheckDomains = NULL;  /* check loosely   */
 PUBLIC char *LYCookieSQueryCheckDomains = NULL;  /* check w/a query */
+PUBLIC char *LYCookieSRejectDomains = NULL; /* domains to reject all cookies */
+PUBLIC char *LYCookieSStrictCheckDomains = NULL; /* check strictly  */
+PUBLIC char *LYCookieStrictCheckDomains = NULL; /* check strictly  */
+PUBLIC char *LYHostName = NULL;		/* treat as a local host name */
+PUBLIC char *LYLocalDomain = NULL;	/* treat as a local domain tail */
+PUBLIC char *LYUserAgent = NULL;	/* Lynx User-Agent header	   */
+PUBLIC char *LYUserAgentDefault = NULL; /* Lynx default User-Agent header  */
+PUBLIC char *LynxHome = NULL;		/* the default Home HREF. */
+PUBLIC char *LynxSigFile = NULL;	/* Signature file, in or off home */
+PUBLIC char *UCAssume_MIMEcharset = NULL;
+PUBLIC char *URLDomainPrefixes = NULL;
+PUBLIC char *URLDomainSuffixes = NULL;
+PUBLIC char *authentication_info[2] = {NULL, NULL}; /* Id:Password for protected documents */
+PUBLIC char *bookmark_page = NULL;	/* the name of the default bookmark page */
+PUBLIC char *editor = NULL;		/* the name of the current editor */
+PUBLIC char *form_get_data = NULL;	/* User data for get form */
+PUBLIC char *form_post_data = NULL;	/* User data for post form */
+PUBLIC char *global_extension_map = NULL;  /* global mime.types */
+PUBLIC char *global_type_map = NULL;	/* global mailcap */
+PUBLIC char *helpfile = NULL;		/* the main help file */
+PUBLIC char *helpfilepath = NULL;	/* the path to the help file set */
+PUBLIC char *homepage = NULL;		/* home page or main screen */
+PUBLIC char *http_error_file = NULL;	/* Place HTTP status code in this file */
+PUBLIC char *indexfile = NULL;		/* an index file if there is one */
+PUBLIC char *jumpfile = NULL;		/* the name of the default jumps file */
+PUBLIC char *jumpprompt = NULL;		/* the default jumps prompt */
+PUBLIC char *language = NULL;		/* preferred language */
+PUBLIC char *lynx_cfg_file = NULL;	/* location of active lynx.cfg */
+PUBLIC char *lynx_cmd_logfile;		/* file to write keystroke commands, if any */
+PUBLIC char *lynx_cmd_script;		/* file to read keystroke commands, if any */
+PUBLIC char *lynx_save_space = NULL;	/* The prefix for save to disk paths */
+PUBLIC char *lynx_temp_space = NULL;	/* The prefix for temporary file paths */
+PUBLIC char *lynxjumpfile = NULL;	/* the current jump file URL */
+PUBLIC char *lynxlinksfile = NULL;	/* the current visited links file URL */
+PUBLIC char *lynxlistfile = NULL;	/* the current list file URL */
+PUBLIC char *original_dir = NULL;	/* the original directory */
+PUBLIC char *personal_extension_map = NULL;/* .mime.types */
+PUBLIC char *personal_mail_address = NULL; /* the users mail address */
+PUBLIC char *personal_type_map = NULL;	   /* .mailcap */
+PUBLIC char *pref_charset = NULL;	/* preferred character set */
+PUBLIC char *proxyauth_info[2] = {NULL, NULL}; /* Id:Password for protected proxy servers */
+PUBLIC char *startfile = NULL;		/* the first file */
+PUBLIC char *startrealm = NULL;		/* the startfile realm */
+PUBLIC char *system_mail = NULL;	/* The path for sending mail */
+PUBLIC char *system_mail_flags = NULL;	/* Flags for sending mail */
+PUBLIC char *x_display = NULL;		/* display environment variable */
+PUBLIC histstruct history[MAXHIST];
+PUBLIC int AlertSecs;			/* time-delay for HTAlert() messages   */
+PUBLIC int InfoSecs;			/* time-delay for Information messages */
+PUBLIC int LYMultiBookmarks = MULTI_BOOKMARK_SUPPORT;
+PUBLIC int LYStatusLine = -1;		/* Line for statusline() if > -1 */
+PUBLIC int LYcols = DFT_COLS;
+PUBLIC int LYlines = DFT_ROWS;
+PUBLIC int MessageSecs;			/* time-delay for important Messages   */
+PUBLIC int ccount = 0;			/* Starting number for lnk#.dat files in crawls */
+PUBLIC int dump_output_width = 0;
+PUBLIC int lynx_temp_subspace = 0;	/* > 0 if we made temp-directory */
+PUBLIC int nhist = 0;			/* number of history entries */
+PUBLIC int nlinks = 0;			/* number of links in memory */
+PUBLIC int outgoing_mail_charset = -1;	/* translate mail to this charset */
+PUBLIC linkstruct links[MAXLINKS];
 
 #ifndef DISABLE_BIBP
+PUBLIC BOOLEAN BibP_bibhost_available = FALSE;  /* until check succeeds  */
+PUBLIC BOOLEAN BibP_bibhost_checked = FALSE;  /*  until LYCheckBibHost   */
 PUBLIC BOOLEAN no_goto_bibp = FALSE;
-PUBLIC char *BibP_globalserver = NULL;   /* global server for bibp: links */
 PUBLIC char *BibP_bibhost = NULL;	 /* local server for bibp: links  */
-PUBLIC BOOLEAN BibP_bibhost_checked = FALSE;  /*  until LYCheckBibHost   */
-PUBLIC BOOLEAN BibP_bibhost_available = FALSE;  /* until check succeeds  */
+PUBLIC char *BibP_globalserver = NULL;   /* global server for bibp: links */
 #endif
 
 #ifdef EXP_PERSISTENT_COOKIES
-BOOLEAN persistent_cookies = FALSE;	/* disabled by default! */
+PUBLIC BOOLEAN persistent_cookies = FALSE; /* disabled by default! */
 PUBLIC char *LYCookieFile = NULL;	/* cookie read file */
 PUBLIC char *LYCookieSaveFile = NULL;	/* cookie save file */
 #endif /* EXP_PERSISTENT_COOKIES */
 
+#ifdef EXP_NESTED_TABLES
+PUBLIC BOOLEAN nested_tables = TRUE;
+#endif
+
+PUBLIC BOOLEAN LYShowTransferRate = TRUE;
 PUBLIC int LYTransferRate = rateEtaKB_maybe;
+
 PUBLIC char *XLoadImageCommand = NULL;	/* Default image viewer for X */
 PUBLIC BOOLEAN LYNoISMAPifUSEMAP = FALSE; /* Omit ISMAP link if MAP present? */
 PUBLIC int LYHiddenLinks = HIDDENLINKS_SEPARATE; /* Show hidden links? */
 
-PUBLIC BOOL Old_DTD = NO;
+PUBLIC int Old_DTD = NO;
+PRIVATE BOOL DTD_recovery = NO;
 
 #ifndef NO_LYNX_TRACE
 PUBLIC FILE *LYTraceLogFP = NULL;		/* Pointer for TRACE log  */
@@ -461,7 +471,7 @@ PUBLIC BOOLEAN LYPrependCharsetToSource = TRUE;
 PUBLIC BOOLEAN LYQuitDefaultYes = QUIT_DEFAULT_YES;
 PUBLIC BOOLEAN dont_wrap_pre = FALSE;
 
-PUBLIC int connect_timeout = 18000;/*=180000*0.1 - used in HTDoConnect.*/
+PUBLIC int connect_timeout = 18000; /*=180000*0.1 - used in HTDoConnect.*/
 
 #ifdef EXP_JUSTIFY_ELTS
 PUBLIC BOOL ok_justify = TRUE;
@@ -476,7 +486,7 @@ PUBLIC BOOL force_empty_hrefless_a = FALSE;
 
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
 PUBLIC BOOL textfields_need_activation = FALSE;
-PUBLIC BOOL global_textfields_need_activation = FALSE;
+PUBLIC BOOL textfields_activation_option = FALSE;
 #endif
 
 PUBLIC BOOLEAN textfield_prompt_at_left_edge = FALSE;
@@ -485,7 +495,6 @@ PUBLIC BOOLEAN textfield_prompt_at_left_edge = FALSE;
 PUBLIC char* hidden_link_marker = NULL;
 #endif
 
-
 #ifdef DISP_PARTIAL
 PUBLIC BOOLEAN display_partial_flag = TRUE; /* Display document during download */
 PUBLIC BOOLEAN debug_display_partial = FALSE; /* Show with MessageSecs delay */
@@ -1019,9 +1028,16 @@ PUBLIC int main ARGS2(
 #ifndef VMS
     StrAllocCopy(list_format, LIST_FORMAT);
 #endif /* !VMS */
-    InfoSecs	= (int)INFOSECS;
-    MessageSecs = (int)MESSAGESECS;
-    AlertSecs	= (int)ALERTSECS;
+
+#ifdef HAVE_NAPMS
+#define SECS2Secs(n) (1000 * (n))
+#else
+#define SECS2Secs(n) (n)
+#endif
+    InfoSecs	= SECS2Secs(INFOSECS);
+    MessageSecs = SECS2Secs(MESSAGESECS);
+    AlertSecs	= SECS2Secs(ALERTSECS);
+
     StrAllocCopy(helpfile, HELPFILE);
     StrAllocCopy(startfile, STARTFILE);
     LYTrimStartfile(startfile);
@@ -1585,7 +1601,7 @@ PUBLIC int main ARGS2(
 #ifdef USE_PRETTYSRC
     if ( (!Old_DTD) != TRUE ) /* skip if they are already initialized -HV */
 #endif
-    HTSwitchDTD((BOOLEAN)!Old_DTD);
+    HTSwitchDTD(!Old_DTD);
 
     /*
      * Set up the proper character set with the desired
@@ -1684,11 +1700,7 @@ PUBLIC int main ARGS2(
     if (!FileInitAlreadyDone)
 	HTFileInit();
 
-    if (LYUserAgent && *LYUserAgent &&
-		   !strstr(LYUserAgent, "Lynx") &&
-		   !strstr(LYUserAgent, "lynx") &&
-		   !strstr(LYUserAgent, "L_y_n_x") &&
-		   !strstr(LYUserAgent, "l_y_n_x")) {
+    if (!LYCheckUserAgent()) {
 	HTAlwaysAlert(gettext("Warning:"), UA_NO_LYNX_WARNING);
     }
 #ifdef SH_EX
@@ -1776,7 +1788,7 @@ PUBLIC int main ARGS2(
     if (no_multibook)
 	LYMBMBlocked = TRUE;
     if (dump_output_immediately || LYMBMBlocked || no_multibook) {
-	LYMultiBookmarks = FALSE;
+	LYMultiBookmarks = MBM_OFF;
 	LYMBMBlocked = TRUE;
 	no_multibook = TRUE;
     }
@@ -1975,16 +1987,13 @@ PUBLIC int main ARGS2(
      *	are all allocated and synchronized. - FM
      */
     if (!bookmark_page || *bookmark_page == '\0') {
-	StrAllocCopy(bookmark_page, "lynx_bookmarks");
-	StrAllocCat(bookmark_page, HTML_SUFFIX);
-	StrAllocCopy(BookmarkPage, bookmark_page);
-	StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
-	StrAllocCopy(MBM_A_subdescript[0], "Default");
+	temp = NULL;
+	HTSprintf0(&temp, "lynx_bookmarks%s", HTML_SUFFIX);
+	set_default_bookmark_page(temp);
+	FREE(temp);
     }
     if (!BookmarkPage || *BookmarkPage == '\0') {
-	StrAllocCopy(BookmarkPage, bookmark_page);
-	StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
-	StrAllocCopy(MBM_A_subdescript[0], MULTIBOOKMARKS_DEFAULT);
+	set_default_bookmark_page(bookmark_page);
     }
 
 #if !defined(VMS) && defined(SYSLOG_REQUESTED_URLS)
@@ -2055,9 +2064,9 @@ PUBLIC int main ARGS2(
 #endif
 
 	ena_csi((BOOLEAN)(LYlowest_eightbit[current_char_set] > 155));
-	LYOpenCloset();
 	status = mainloop();
-	LYCloseCloset();
+	LYCloseCloset(RECALL_URL);
+	LYCloseCloset(RECALL_MAIL);
 	cleanup();
 	exit(status);
     }
@@ -2154,10 +2163,6 @@ PUBLIC void reload_read_cfg NOARGS
 	HTAlwaysAlert(NULL, CANNOT_OPEN_TEMP);
 	return;
     }
-    /* save .lynxrc file in case we change something from Options Menu */
-    if (LYrcShowColor != SHOW_COLOR_UNKNOWN) {
-	SetupChosenShowColor();
-    }
     if (!save_rc(rcfp)) {
 	HTAlwaysAlert(NULL, OPTIONS_NOT_SAVED);
 	LYRemoveTemp(tempfile);
@@ -2270,35 +2275,11 @@ PUBLIC void reload_read_cfg NOARGS
  * Others are complicated and require a function call.
  */
 
-struct parse_args_type;
-typedef int (*ParseFunc) PARAMS((char *));
-
-typedef union {
-	BOOLEAN * set_value;
-	int *     int_value;
-	char **   str_value;
-	ParseFunc fun_value;
-} ParseUnion;
-
-/*
- * Storing the four types of data in separate fields costs about 1K of data.
- * However, this provides usable type-checking.  The initial version of the
- * parse_args_type used 'long' for all types, and dumped core when processing
- * "lynx -help".  (The compiler was unable to detect some minor errors).
- */
-#ifdef  PARSE_DEBUG
-#define ParseData BOOLEAN *set_value; int *int_value; char **str_value; ParseFunc fun_value
-#define PARSE_SET(n,t,v,h) {n,t,    v,  0,  0,  0,    h}
-#define PARSE_INT(n,t,v,h) {n,t,    0,  v,  0,  0,    h}
-#define PARSE_STR(n,t,v,h) {n,t,    0,  0,  v,  0,    h}
-#define PARSE_FUN(n,t,v,h) {n,t,    0,  0,  0,  v,    h}
-#else
-#define ParseData long value
-#define PARSE_SET(n,t,v,h) {n,t,   (long) (v),        h}
-#define PARSE_INT(n,t,v,h) {n,t,   (long) (v),        h}
-#define PARSE_STR(n,t,v,h) {n,t,   (long) (v),        h}
-#define PARSE_FUN(n,t,v,h) {n,t,   (long) (v),        h}
-#endif
+#define PARSE_SET(n,t,v,h) {n,    t, UNION_SET(v), h}
+#define PARSE_INT(n,t,v,h) {n,    t, UNION_INT(v), h}
+#define PARSE_STR(n,t,v,h) {n,    t, UNION_STR(v), h}
+#define PARSE_FUN(n,t,v,h) {n,    t, UNION_FUN(v), h}
+#define PARSE_NIL          {NULL, 0, UNION_DEF(0), NULL}
 
 typedef struct parse_args_type
 {
@@ -2327,7 +2308,7 @@ typedef struct parse_args_type
    ParseData;
    CONST char *help_string;
 }
-Parse_Args_Type;
+Config_Type;
 
 /* -auth, -pauth */
 PRIVATE int parse_authentication ARGS2(
@@ -2428,16 +2409,6 @@ PRIVATE int base_fun ARGS1(
     return 0;
 }
 
-#ifdef USE_SLANG
-/* -blink */
-PRIVATE int blink_fun ARGS1(
-	char *,			next_arg GCC_UNUSED)
-{
-    Lynx_Color_Flags |= SL_LYNX_USE_BLINK;
-    return 0;
-}
-#endif
-
 /* -cache */
 PRIVATE int cache_fun ARGS1(
 	char *,			next_arg)
@@ -3158,10 +3129,10 @@ PRIVATE int width_fun ARGS1(
 }
 
 /* NOTE: This table is sorted by name to make the help message useful */
-PRIVATE Parse_Args_Type Arg_Table [] =
+PRIVATE Config_Type Arg_Table [] =
 {
    PARSE_SET(
-      "accept_all_cookies", 4|SET_ARG,		&LYAcceptAllCookies,
+      "accept_all_cookies", 4|SET_ARG,		LYAcceptAllCookies,
       "\naccept cookies without prompting if Set-Cookie handling\nis on"
    ),
    PARSE_FUN(
@@ -3190,22 +3161,22 @@ PRIVATE Parse_Args_Type Arg_Table [] =
    ),
 #ifndef DISABLE_BIBP
    PARSE_STR(
-      "bibhost",	4|NEED_LYSTRING_ARG,	&BibP_bibhost,
+      "bibhost",	4|NEED_LYSTRING_ARG,	BibP_bibhost,
       "=URL\nlocal bibp server (default http://bibhost/)"
    ),
 #endif
-#ifdef USE_SLANG
-   PARSE_FUN(
-      "blink",		4|FUNCTION_ARG,		blink_fun,
-      "force high intensity bg colors in color mode"
+#ifdef USE_BLINK
+   PARSE_SET(
+      "blink",		4|SET_ARG,		term_blink_is_boldbg,
+      "enable bright background via the BLINK terminal attribute"
    ),
 #endif
    PARSE_SET(
-      "book",		4|SET_ARG,		&bookmark_start,
+      "book",		4|SET_ARG,		bookmark_start,
       "use the bookmark page as the startfile"
    ),
    PARSE_SET(
-      "buried_news",	4|TOGGLE_ARG,		&scan_for_buried_news_references,
+      "buried_news",	4|TOGGLE_ARG,		scan_for_buried_news_references,
       "toggles scanning of news articles for buried references"
    ),
    PARSE_FUN(
@@ -3213,26 +3184,26 @@ PRIVATE Parse_Args_Type Arg_Table [] =
       "=NUMBER\nNUMBER of documents cached in memory"
    ),
    PARSE_SET(
-      "case",		4|SET_ARG,		&case_sensitive,
+      "case",		4|SET_ARG,		case_sensitive,
       "enable case sensitive user searching"
    ),
 #ifdef SH_EX
    PARSE_SET(
-      "center",		4|TOGGLE_ARG,		&no_table_center,
+      "center",		4|TOGGLE_ARG,		no_table_center,
       "Toggle center alignment in HTML TABLE"
    ),
 #endif
    PARSE_STR(
-      "cfg",		2|NEED_LYSTRING_ARG,	&lynx_cfg_file,
+      "cfg",		2|NEED_LYSTRING_ARG,	lynx_cfg_file,
       "=FILENAME\nspecifies a lynx.cfg file other than the default"
    ),
 #ifdef EXP_CMD_LOGGING
    PARSE_STR(
-       "cmd_log",	2|NEED_LYSTRING_ARG,	&lynx_cmd_logfile,
+       "cmd_log",	2|NEED_LYSTRING_ARG,	lynx_cmd_logfile,
        "=FILENAME\nlog keystroke commands to the given file"
    ),
    PARSE_STR(
-       "cmd_script",	2|NEED_LYSTRING_ARG,	&lynx_cmd_script,
+       "cmd_script",	2|NEED_LYSTRING_ARG,	lynx_cmd_script,
        "=FILENAME\nread keystroke commands from the given file\n(see -cmd_log)"
    ),
 #endif
@@ -3247,34 +3218,34 @@ PRIVATE Parse_Args_Type Arg_Table [] =
    ),
 #endif
 #ifndef __DJGPP__
-   PARSE_SET(
-      "connect_timeout", 4|NEED_INT_ARG,	&connect_timeout,
+   PARSE_INT(
+      "connect_timeout", 4|NEED_INT_ARG,	connect_timeout,
       "=N\nset the N-second connection timeout"
    ),
 #endif
 #ifdef MISC_EXP
-   PARSE_SET(
+   PARSE_FUN(
       "convert_to",	4|FUNCTION_ARG,		convert_to_fun,
       "=FORMAT\nconvert input, FORMAT is in MIME type notation\n(experimental)"
    ),
 #endif
 #ifdef EXP_PERSISTENT_COOKIES
    PARSE_STR(
-      "cookie_file",	4|LYSTRING_ARG,		&LYCookieFile,
+      "cookie_file",	4|LYSTRING_ARG,		LYCookieFile,
       "=FILENAME\nspecifies a file to use to read cookies"
    ),
    PARSE_STR(
-      "cookie_save_file",	4|LYSTRING_ARG,	&LYCookieSaveFile,
+      "cookie_save_file",	4|LYSTRING_ARG,	LYCookieSaveFile,
       "=FILENAME\nspecifies a file to use to store cookies"
    ),
 #endif /* EXP_PERSISTENT_COOKIES */
    PARSE_SET(
-      "cookies",	4|TOGGLE_ARG,		&LYSetCookies,
+      "cookies",	4|TOGGLE_ARG,		LYSetCookies,
       "toggles handling of Set-Cookie headers"
    ),
 #ifndef VMS
    PARSE_SET(
-      "core",		4|TOGGLE_ARG,		&LYNoCore,
+      "core",		4|TOGGLE_ARG,		LYNoCore,
       "toggles forced core dumps on fatal errors"
    ),
 #endif
@@ -3285,13 +3256,13 @@ with -dump, format output as with -traversal, but to stdout"
    ),
 #ifdef DISP_PARTIAL
    PARSE_SET(
-      "debug_partial",	4|TOGGLE_ARG,		&debug_display_partial,
+      "debug_partial",	4|TOGGLE_ARG,		debug_display_partial,
       "incremental display stages with MessageSecs delay"
    ),
 #endif
 #if defined(SH_EX) && defined(WIN_EX)
-   PARSE_SET(
-      "delay",		4|NEED_INT_ARG,		&debug_delay,
+   PARSE_INT(
+      "delay",		4|NEED_INT_ARG,		debug_delay,
       "=NNN\nset the NNN msec delay at statusline message"
    ),
 #endif
@@ -3304,7 +3275,7 @@ with -dump, format output as with -traversal, but to stdout"
       "=MIMEname\ncharset for the terminal output"
    ),
    PARSE_SET(
-      "dont_wrap_pre",	4|SET_ARG,		&dont_wrap_pre,
+      "dont_wrap_pre",	4|SET_ARG,		dont_wrap_pre,
       "inhibit wrapping of text in <pre> when -dump'ing and\n\
 -crawl'ing, mark wrapped lines in interactive session"
    ),
@@ -3317,11 +3288,11 @@ with -dump, format output as with -traversal, but to stdout"
       "=EDITOR\nenable edit mode with specified editor"
    ),
    PARSE_SET(
-      "emacskeys",	4|SET_ARG,		&emacs_keys,
+      "emacskeys",	4|SET_ARG,		emacs_keys,
       "enable emacs-like key movement"
    ),
    PARSE_SET(
-      "enable_scrollback", 4|TOGGLE_ARG,	&enable_scrollback,
+      "enable_scrollback", 4|TOGGLE_ARG,	enable_scrollback,
       "\ntoggles compatibility with comm programs' scrollback\n\
 keys (may be incompatible with some curses packages)"
    ),
@@ -3339,34 +3310,34 @@ keys (may be incompatible with some curses packages)"
 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
 #ifdef VMS
    PARSE_SET(
-      "fileversions",	4|SET_ARG,		&HTVMSFileVersions,
+      "fileversions",	4|SET_ARG,		HTVMSFileVersions,
       "include all versions of files in local VMS directory\nlistings"
    ),
 #endif
    PARSE_SET(
-      "force_empty_hrefless_a",	4|SET_ARG,	&force_empty_hrefless_a,
+      "force_empty_hrefless_a",	4|SET_ARG,	force_empty_hrefless_a,
       "\nforce HREF-less 'A' elements to be empty (close them as\nsoon as they are seen)"
    ),
    PARSE_SET(
-      "force_html",	4|SET_ARG,		&LYforce_HTML_mode,
+      "force_html",	4|SET_ARG,		LYforce_HTML_mode,
       "forces the first document to be interpreted as HTML"
    ),
    PARSE_SET(
-      "force_secure",	4|TOGGLE_ARG,		&LYForceSSLCookiesSecure,
+      "force_secure",	4|TOGGLE_ARG,		LYForceSSLCookiesSecure,
       "toggles forcing of the secure flag for SSL cookies"
    ),
 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
    PARSE_SET(
-      "forms_options",	4|TOGGLE_ARG,		&LYUseFormsOptions,
+      "forms_options",	4|TOGGLE_ARG,		LYUseFormsOptions,
       "toggles forms-based vs old-style options menu"
    ),
 #endif
    PARSE_SET(
-      "from",		4|TOGGLE_ARG,		&LYNoFromHeader,
+      "from",		4|TOGGLE_ARG,		LYNoFromHeader,
       "toggle transmission of From headers"
    ),
    PARSE_SET(
-      "ftp",		4|UNSET_ARG,		&ftp_ok,
+      "ftp",		4|UNSET_ARG,		ftp_ok,
       "disable ftp access"
    ),
    PARSE_FUN(
@@ -3374,7 +3345,7 @@ keys (may be incompatible with some curses packages)"
       "user data for get forms, read from stdin,\nterminated by '---' on a line"
    ),
    PARSE_SET(
-      "head",		4|SET_ARG,		&HEAD_request,
+      "head",		4|SET_ARG,		HEAD_request,
       "send a HEAD request"
    ),
    PARSE_FUN(
@@ -3386,7 +3357,7 @@ keys (may be incompatible with some curses packages)"
       "=[option]\nhidden links: options are merge, listonly, or ignore"
    ),
    PARSE_SET(
-      "historical",	4|TOGGLE_ARG,		&historical_comments,
+      "historical",	4|TOGGLE_ARG,		historical_comments,
       "toggles use of '>' or '-->' as terminator for comments"
    ),
    PARSE_FUN(
@@ -3394,40 +3365,40 @@ keys (may be incompatible with some curses packages)"
       "=URL\nset homepage separate from start page"
    ),
    PARSE_SET(
-      "image_links",	4|TOGGLE_ARG,		&clickable_images,
+      "image_links",	4|TOGGLE_ARG,		clickable_images,
       "toggles inclusion of links for all images"
    ),
    PARSE_STR(
-      "index",		4|NEED_LYSTRING_ARG,	&indexfile,
+      "index",		4|NEED_LYSTRING_ARG,	indexfile,
       "=URL\nset the default index file to URL"
    ),
    PARSE_SET(
-      "ismap",		4|TOGGLE_ARG,		&LYNoISMAPifUSEMAP,
+      "ismap",		4|TOGGLE_ARG,		LYNoISMAPifUSEMAP,
       "toggles inclusion of ISMAP links when client-side\nMAPs are present"
    ),
 #ifdef EXP_JUSTIFY_ELTS
    PARSE_SET(
-      "justify",	4|SET_ARG,		&ok_justify,
+      "justify",	4|SET_ARG,		ok_justify,
       "do justification of text"
    ),
 #endif
    PARSE_INT(
-      "link",		4|NEED_INT_ARG,		&ccount,
+      "link",		4|NEED_INT_ARG,		ccount,
       "=NUMBER\nstarting count for lnk#.dat files produced by -crawl"
    ),
    PARSE_SET(
-      "localhost",	4|SET_ARG,		&local_host_only,
+      "localhost",	4|SET_ARG,		local_host_only,
       "disable URLs that point to remote hosts"
    ),
 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
    PARSE_SET(
-      "locexec",	4|SET_ARG,		&local_exec_on_local_files,
+      "locexec",	4|SET_ARG,		local_exec_on_local_files,
       "enable local program execution from local files only"
    ),
 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
 #if defined(USE_COLOR_STYLE)
    PARSE_STR(
-      "lss",		2|NEED_LYSTRING_ARG,	&lynx_lss_file,
+      "lss",		2|NEED_LYSTRING_ARG,	lynx_lss_file,
       "=FILENAME\nspecifies a lynx.lss file other than the default"
    ),
 #endif
@@ -3436,12 +3407,10 @@ keys (may be incompatible with some curses packages)"
       "include mime headers and force source dump"
    ),
    PARSE_SET(
-      "minimal",	4|TOGGLE_ARG,		&minimal_comments,
+      "minimal",	4|TOGGLE_ARG,		minimal_comments,
       "toggles minimal versus valid comment parsing"
    ),
 #ifndef DISABLE_NEWS
-#endif
-#ifndef DISABLE_NEWS
    PARSE_FUN(
       "newschunksize",	4|NEED_FUNCTION_ARG,	newschunksize_fun,
       "=NUMBER\nnumber of articles in chunked news listings"
@@ -3453,7 +3422,7 @@ keys (may be incompatible with some curses packages)"
 #endif
 #if USE_BLAT_MAILER
    PARSE_SET(
-      "noblat",		4|TOGGLE_ARG,		&mail_is_blat,
+      "noblat",		4|TOGGLE_ARG,		mail_is_blat,
       "select mail tool (`BLAT' ==> `sendmail')"
    ),
 #endif
@@ -3466,7 +3435,7 @@ keys (may be incompatible with some curses packages)"
       "disable directory browsing"
    ),
    PARSE_SET(
-      "nocc",		4|SET_ARG,		&LYNoCc,
+      "nocc",		4|SET_ARG,		LYNoCc,
       "disable Cc: prompts for self copies of mailings"
    ),
    PARSE_FUN(
@@ -3475,25 +3444,25 @@ keys (may be incompatible with some curses packages)"
    ),
 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
    PARSE_SET(
-      "noexec",		4|UNSET_ARG,		&local_exec,
+      "noexec",		4|UNSET_ARG,		local_exec,
       "disable local program execution (DEFAULT)"
    ),
 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
    PARSE_SET(
-      "nofilereferer",	4|SET_ARG,		&no_filereferer,
+      "nofilereferer",	4|SET_ARG,		no_filereferer,
       "disable transmission of Referer headers for file URLs"
    ),
    PARSE_SET(
-      "nolist",		4|SET_ARG,		&nolist,
+      "nolist",		4|SET_ARG,		nolist,
       "disable the link list feature in dumps"
    ),
    PARSE_SET(
-      "nolog",		4|UNSET_ARG,		&error_logging,
+      "nolog",		4|UNSET_ARG,		error_logging,
       "disable mailing of error messages to document owners"
    ),
 #if HAVE_SIGACTION && defined(SIGWINCH)
    PARSE_SET(
-      "nonrestarting_sigwinch", 4|SET_ARG,	&LYNonRestartingSIGWINCH,
+      "nonrestarting_sigwinch", 4|SET_ARG,	LYNonRestartingSIGWINCH,
       "\nmake window size change handler non-restarting"
    ),
 #endif /* HAVE_SIGACTION */
@@ -3502,15 +3471,15 @@ keys (may be incompatible with some curses packages)"
       "disable forced pauses for statusline messages"
    ),
    PARSE_SET(
-      "noprint",	4|SET_ARG,		&no_print,
+      "noprint",	4|SET_ARG,		no_print,
       "disable some print functions, like -restrictions=print"
    ),
    PARSE_SET(
-      "noredir",	4|SET_ARG,		&no_url_redirection,
+      "noredir",	4|SET_ARG,		no_url_redirection,
       "don't follow Location: redirection"
    ),
    PARSE_SET(
-      "noreferer",	4|SET_ARG,		&LYNoRefererHeader,
+      "noreferer",	4|SET_ARG,		LYNoRefererHeader,
       "disable transmission of Referer headers"
    ),
    PARSE_FUN(
@@ -3519,12 +3488,12 @@ keys (may be incompatible with some curses packages)"
    ),
 #ifdef SOCKS
    PARSE_SET(
-      "nosocks",	6|UNSET_ARG,		&socks_flag,
+      "nosocks",	6|UNSET_ARG,		socks_flag,
       "don't use SOCKS proxy for this session"
    ),
 #endif
    PARSE_SET(
-      "nostatus",	4|SET_ARG,		&no_statusline,
+      "nostatus",	4|SET_ARG,		no_statusline,
       "disable the miscellaneous information messages"
    ),
    PARSE_FUN(
@@ -3538,20 +3507,20 @@ keys (may be incompatible with some curses packages)"
    ),
 #endif
    PARSE_SET(
-      "number_fields",	4|SET_ARG,		&number_fields,
+      "number_fields",	4|SET_ARG,		number_fields,
       "force numbering of links as well as form input fields"
    ),
    PARSE_SET(
-      "number_links",	4|SET_ARG,		&number_links,
+      "number_links",	4|SET_ARG,		number_links,
       "force numbering of links"
    ),
 #ifdef DISP_PARTIAL
    PARSE_SET(
-      "partial",	4|TOGGLE_ARG,		&display_partial_flag,
+      "partial",	4|TOGGLE_ARG,		display_partial_flag,
       "toggles display partial pages while downloading"
    ),
    PARSE_INT(
-      "partial_thres",	4|NEED_INT_ARG,		&partial_threshold,
+      "partial_thres",	4|NEED_INT_ARG,		partial_threshold,
       "[=NUMBER]\nnumber of lines to render before repainting display\n\
 with partial-display logic"
    ),
@@ -3561,7 +3530,7 @@ with partial-display logic"
       "=id:pw\nauthentication information for protected proxy server"
    ),
    PARSE_SET(
-      "popup",		4|UNSET_ARG,		&LYUseDefSelPop,
+      "popup",		4|UNSET_ARG,		LYUseDefSelPop,
       "toggles handling of single-choice SELECT options via\npopup windows or as lists of radio buttons"
    ),
    PARSE_FUN(
@@ -3569,35 +3538,35 @@ with partial-display logic"
       "user data for post forms, read from stdin,\nterminated by '---' on a line"
    ),
    PARSE_SET(
-      "preparsed",	4|SET_ARG,		&LYPreparsedSource,
+      "preparsed",	4|SET_ARG,		LYPreparsedSource,
       "show parsed text/html with -source and in source view\n\
 to visualize how lynx behaves with invalid HTML"
    ),
 #ifdef USE_PRETTYSRC
    PARSE_SET(
-      "prettysrc",	4|SET_ARG,		&LYpsrc,
+      "prettysrc",	4|SET_ARG,		LYpsrc,
       "do syntax highlighting and hyperlink handling in source\nview"
    ),
 #endif
    PARSE_SET(
-      "print",		4|UNSET_ARG,		&no_print,
+      "print",		4|UNSET_ARG,		no_print,
       "enable print functions (DEFAULT), opposite of -noprint"
    ),
    PARSE_SET(
-      "pseudo_inlines", 4|TOGGLE_ARG,		&pseudo_inline_alts,
+      "pseudo_inlines", 4|TOGGLE_ARG,		pseudo_inline_alts,
       "toggles pseudo-ALTs for inlines with no ALT string"
    ),
    PARSE_SET(
-      "raw",		4|UNSET_ARG,		&LYUseDefaultRawMode,
+      "raw",		4|UNSET_ARG,		LYUseDefaultRawMode,
       "toggles default setting of 8-bit character translations\n\
 or CJK mode for the startup character set"
    ),
    PARSE_SET(
-      "realm",		4|SET_ARG,		&check_realm,
+      "realm",		4|SET_ARG,		check_realm,
       "restricts access to URLs in the starting realm"
    ),
    PARSE_SET(
-      "reload",		4|SET_ARG,		&reloading,
+      "reload",		4|SET_ARG,		reloading,
       "flushes the cache on a proxy server\n(only the first document affected)"
    ),
    PARSE_FUN(
@@ -3605,22 +3574,22 @@ or CJK mode for the startup character set"
       "=[options]\nuse -restrictions to see list"
    ),
    PARSE_SET(
-      "resubmit_posts", 4|TOGGLE_ARG,		&LYresubmit_posts,
+      "resubmit_posts", 4|TOGGLE_ARG,		LYresubmit_posts,
       "toggles forced resubmissions (no-cache) of forms with\n\
 method POST when the documents they returned are sought\n\
 with the PREV_DOC command or from the History List"
    ),
    PARSE_SET(
-      "rlogin",		4|UNSET_ARG,		&rlogin_ok,
+      "rlogin",		4|UNSET_ARG,		rlogin_ok,
       "disable rlogins"
    ),
 #ifdef USE_SCROLLBAR
    PARSE_SET(
-      "scrollbar",	4|TOGGLE_ARG,		&LYsb,
+      "scrollbar",	4|TOGGLE_ARG,		LYsb,
       "toggles showing scrollbar"
    ),
    PARSE_SET(
-      "scrollbar_arrow", 4|TOGGLE_ARG,		&LYsb_arrow,
+      "scrollbar_arrow", 4|TOGGLE_ARG,		LYsb_arrow,
       "toggles showing arrows at ends of the scrollbar"
    ),
 #endif
@@ -3629,27 +3598,27 @@ with the PREV_DOC command or from the History List"
       "require .www_browsable files to browse directories"
    ),
    PARSE_SET(
-      "short_url",	4|SET_ARG,		&long_url_ok,
+      "short_url",	4|SET_ARG,		long_url_ok,
       "enables examination of beginning and end of long URL in\nstatus line"
    ),
 #ifdef SH_EX
    PARSE_SET(
-      "show_cfg",	4|SET_ARG,		&show_cfg,
+      "show_cfg",	4|SET_ARG,		show_cfg,
       "Show `LYNX.CFG' setting"
    ),
 #endif
    PARSE_SET(
-      "show_cursor",	4|TOGGLE_ARG,		&LYUseDefShoCur,
+      "show_cursor",	4|TOGGLE_ARG,		LYUseDefShoCur,
       "toggles hiding of the cursor in the lower right corner"
    ),
 #ifdef EXP_READPROGRESS
    PARSE_SET(
-      "show_rate",	4|TOGGLE_ARG,		&LYTransferRate,
+      "show_rate",	4|TOGGLE_ARG,		LYShowTransferRate,
       "toggles display of transfer rate"
    ),
 #endif
    PARSE_SET(
-      "soft_dquotes",	4|TOGGLE_ARG,		&soft_dquotes,
+      "soft_dquotes",	4|TOGGLE_ARG,		soft_dquotes,
       "toggles emulation of the old Netscape and Mosaic bug which\n\
 treated '>' as a co-terminator for double-quotes and tags"
    ),
@@ -3658,60 +3627,60 @@ treated '>' as a co-terminator for double-quotes and tags"
       "dump the source of the first file to stdout and exit"
    ),
    PARSE_SET(
-      "stack_dump",	4|SET_ARG,		&stack_dump,
+      "stack_dump",	4|SET_ARG,		stack_dump,
       "disable SIGINT cleanup handler"
    ),
    PARSE_SET(
-      "startfile_ok",	4|SET_ARG,		&startfile_ok,
+      "startfile_ok",	4|SET_ARG,		startfile_ok,
       "allow non-http startfile and homepage with -validate"
    ),
    PARSE_SET(
-      "stdin",		4|SET_ARG,		&startfile_stdin,
+      "stdin",		4|SET_ARG,		startfile_stdin,
       "read startfile from standard input"
    ),
 #ifndef VMS
 #ifdef SYSLOG_REQUESTED_URLS
    PARSE_STR(
-      "syslog",		4|NEED_LYSTRING_ARG,	&syslog_txt,
+      "syslog",		4|NEED_LYSTRING_ARG,	syslog_txt,
       "=text\ninformation for syslog call"
    ),
 #endif
 #endif
    PARSE_SET(
-      "tagsoup",	4|SET_ARG,		&Old_DTD,
+      "tagsoup",	4|SET_ARG,		DTD_recovery,
       "use TagSoup rather than SortaSGML parser"
    ),
    PARSE_SET(
-      "telnet",		4|UNSET_ARG,		&telnet_ok,
+      "telnet",		4|UNSET_ARG,		telnet_ok,
       "disable telnets"
    ),
    PARSE_STR(
-      "term",		4|NEED_STRING_ARG,	&terminal,
+      "term",		4|NEED_STRING_ARG,	terminal,
       "=TERM\nset terminal type to TERM"
    ),
 #ifdef _WINDOWS
-   PARSE_SET(
-      "timeout",	4|SET_ARG,		&lynx_timeout,
+   PARSE_INT(
+      "timeout",	4|SET_ARG,		lynx_timeout,
       "set TCP/IP timeout"
    ),
 #endif
    PARSE_SET(
-      "tlog",		2|TOGGLE_ARG,		&LYUseTraceLog,
+      "tlog",		2|TOGGLE_ARG,		LYUseTraceLog,
       "toggles use of a Lynx Trace Log for the current session"
    ),
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
    PARSE_SET(
-      "tna",		4|SET_ARG,		&global_textfields_need_activation,
+      "tna",		4|SET_ARG,		textfields_activation_option,
       "turn on \"Textfields Need Activation\" mode"
    ),
 #endif
 #ifndef NO_LYNX_TRACE
    PARSE_SET(
-      "trace",		2|SET_ARG,		&WWW_TraceFlag,
+      "trace",		2|SET_ARG,		WWW_TraceFlag,
       "turns on Lynx trace mode"
    ),
-   PARSE_SET(
-      "trace_mask",	2|INT_ARG,		&WWW_TraceMask,
+   PARSE_INT(
+      "trace_mask",	2|INT_ARG,		WWW_TraceMask,
       "customize Lynx trace mode"
    ),
 #endif
@@ -3720,25 +3689,25 @@ treated '>' as a co-terminator for double-quotes and tags"
       "traverse all http links derived from startfile"
    ),
    PARSE_SET(
-      "underscore",	4|TOGGLE_ARG,		&use_underscore,
+      "underscore",	4|TOGGLE_ARG,		use_underscore,
       "toggles use of _underline_ format in dumps"
    ),
 #if defined(USE_MOUSE)
    PARSE_SET(
-      "use_mouse",	4|SET_ARG,		&LYUseMouse,
+      "use_mouse",	4|SET_ARG,		LYUseMouse,
       "turn on mouse support"
    ),
 #endif
    PARSE_STR(
-      "useragent",	4|NEED_LYSTRING_ARG,	&LYUserAgent,
+      "useragent",	4|NEED_LYSTRING_ARG,	LYUserAgent,
       "=Name\nset alternate Lynx User-Agent header"
    ),
    PARSE_SET(
-      "validate",	2|SET_ARG,		&LYValidate,
+      "validate",	2|SET_ARG,		LYValidate,
       "accept only http URLs (meant for validation)\nimplies more restrictions than -anonymous, but\ngoto is allowed for http and https"
    ),
    PARSE_SET(
-      "verbose",	4|TOGGLE_ARG,		&verbose_img,
+      "verbose",	4|TOGGLE_ARG,		verbose_img,
       "toggles [LINK], [IMAGE] and [INLINE] comments \nwith filenames of these images"
    ),
    PARSE_FUN(
@@ -3746,12 +3715,12 @@ treated '>' as a co-terminator for double-quotes and tags"
       "print Lynx version information"
    ),
    PARSE_SET(
-      "vikeys",		4|SET_ARG,		&vi_keys,
+      "vikeys",		4|SET_ARG,		vi_keys,
       "enable vi-like key movement"
    ),
 #ifdef __DJGPP__
    PARSE_SET(
-      "wdebug",		4|TOGGLE_ARG,		&watt_debug,
+      "wdebug",		4|TOGGLE_ARG,		watt_debug,
       "enables Waterloo tcp/ip packet debug. Prints to watt\ndebugfile"
   ),
 #endif /* __DJGPP__ */
@@ -3761,11 +3730,11 @@ treated '>' as a co-terminator for double-quotes and tags"
    ),
 #ifndef NO_DUMP_WITH_BACKSPACES
    PARSE_SET(
-      "with_backspaces", 4|SET_ARG,		&with_backspaces,
+      "with_backspaces", 4|SET_ARG,		with_backspaces,
       "emit backspaces in output if -dumping or -crawling\n(like 'man' does)"
    ),
 #endif
-   {NULL, 0, 0, NULL}
+   PARSE_NIL
 };
 
 PRIVATE void print_help_strings ARGS4(
@@ -3822,7 +3791,7 @@ PRIVATE void print_help_strings ARGS4(
 
 PRIVATE void print_help_and_exit ARGS1(int, exit_status)
 {
-    Parse_Args_Type *p;
+    Config_Type *p;
 
     if (pgm == NULL) pgm = "lynx";
 
@@ -3840,11 +3809,8 @@ in double-quotes (\"-\") on VMS)", NULL, TRUE);
 
     for (p = Arg_Table; p->name != 0; p++) {
 	char temp[LINESIZE], *value = temp;
-#ifdef PARSE_DEBUG
-	Parse_Args_Type * q = p;
-#else
-	ParseUnion *q = (ParseUnion *)(&(p->value));
-#endif
+	ParseUnionPtr q = ParseUnionOf(p);
+
 	switch (p->type & ARG_TYPE_MASK) {
 	    case TOGGLE_ARG:
 	    case SET_ARG:
@@ -3945,7 +3911,7 @@ PRIVATE BOOL parse_arg ARGS3(
 	unsigned,	mask,
 	int *,		i)
 {
-    Parse_Args_Type *p;
+    Config_Type *p;
     char *arg_name;
 #if EXTENDED_STARTFILE_RECALL
     static BOOLEAN had_nonoption = FALSE;
@@ -3982,7 +3948,7 @@ PRIVATE BOOL parse_arg ARGS3(
 	    }
 	}
 #endif
-	return (i != 0);
+	return (BOOL)(i != 0);
     }
 #if EXTENDED_OPTION_LOGIC
     if (strcmp(arg_name,"--") == 0) {
@@ -4009,11 +3975,7 @@ PRIVATE BOOL parse_arg ARGS3(
 
     p = Arg_Table;
     while (p->name != 0) {
-#ifdef PARSE_DEBUG
-	Parse_Args_Type *q = p;
-#else
-	ParseUnion *q = (ParseUnion *)(&(p->value));
-#endif
+	ParseUnionPtr q = ParseUnionOf(p);
 	ParseFunc fun;
 	char *next_arg = NULL;
 	char *temp_ptr = NULL;
@@ -4089,6 +4051,7 @@ PRIVATE BOOL parse_arg ARGS3(
 	     break;
 	}
 
+	Old_DTD = DTD_recovery;	/* BOOL != int */
 	return TRUE;
     }
 
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index fd5ae994..16d80296 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -990,7 +990,7 @@ PRIVATE int handle_LYK_ACTIVATE ARGS6(
 
 		textinput_activated = TRUE;
 		show_main_statusline(links[curdoc.link], FOR_INPUT);
-		textfields_need_activation = global_textfields_need_activation;
+		textfields_need_activation = textfields_activation_option;
 
 		return 0;
 	    }
@@ -1231,13 +1231,6 @@ gettext("Enctype multipart/form-data not yet supported!  Cannot submit."));
 		switch (LKC_TO_C(*c)) {
 		case '\n':
 		case '\r':
-#if 0
-		    if (peek_mouse_link() == curdoc.link) {
-			*c = DO_NOTHING;
-			break;
-		    }
-		    /* FALLTHRU */
-#endif
 		default:
 		    if ((real_cmd == LYK_ACTIVATE || real_cmd == LYK_SUBMIT) &&
 			F_TEXTLIKE(links[curdoc.link].form->type) &&
@@ -1553,7 +1546,7 @@ PRIVATE void handle_LYK_ADD_BOOKMARK ARGS3(
 		    goto check_add_bookmark_to_self;
 		}
 	    } else {
-		if (LYMultiBookmarks == FALSE &&
+		if (LYMultiBookmarks == MBM_OFF &&
 		    curdoc.bookmark != NULL &&
 		    strstr(curdoc.address,
 			   (*bookmark_page == '.'
@@ -1833,7 +1826,7 @@ PRIVATE BOOLEAN handle_LYK_COOKIE_JAR ARGS1(
 PRIVATE void handle_LYK_CREATE NOARGS
 {
     if (lynx_edit_mode && !no_dired_support) {
-	if (local_create(&curdoc)) {
+	if (local_create(&curdoc) > 0) {
 	    DIRED_UNCACHE_1;
 	    StrAllocCopy(newdoc.address, curdoc.address);
 	    FREE(curdoc.address);
@@ -1939,7 +1932,7 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
 		FREE(cp);
 	    } else {
 		/*
-		 *  We're viewing a local file.  Make it's
+		 *  We're viewing a local file.  Make its
 		 *  directory the CSwing argument. - FM
 		 */
 		StrAllocCopy(VMSdir, HTVMS_name("", cp));
@@ -2398,7 +2391,7 @@ PRIVATE int handle_LYK_ECGOTO ARGS5(
      */
     _statusline(EDIT_CURDOC_URL);
     if (((*ch = LYgetstr(user_input_buffer, VISIBLE,
-			MAX_LINE, RECALL)) >= 0) &&
+			MAX_LINE, RECALL_URL)) >= 0) &&
 	user_input_buffer[0] != '\0' &&
 	strcmp(user_input_buffer, curdoc.address)) {
 	if (!LYTrimStartfile(user_input_buffer)) {
@@ -2455,8 +2448,7 @@ PRIVATE void handle_LYK_EDIT ARGS2(
 		    if (S_ISREG(dir_info.st_mode)) {
 			StrAllocCopy(tp, links[curdoc.link].lname);
 			HTUnEscapeSome(tp, "/");
-			if (edit_current_file(tp,
-					      curdoc.link, Newline)) {
+			if (edit_current_file(tp, curdoc.link, Newline)) {
 			    DIRED_UNCACHE_1;
 			    StrAllocCopy(newdoc.address,
 					 curdoc.address);
@@ -2659,7 +2651,7 @@ PRIVATE int handle_LYK_ELGOTO ARGS5(
      */
     _statusline(EDIT_CURLINK_URL);
     if (((*ch = LYgetstr(user_input_buffer, VISIBLE,
-			MAX_LINE, RECALL)) >= 0) &&
+			MAX_LINE, RECALL_URL)) >= 0) &&
 	user_input_buffer[0] != '\0' &&
 	strcmp(user_input_buffer,
 	       ((links[curdoc.link].type == WWW_FORM_LINK_TYPE)
@@ -2918,11 +2910,11 @@ PRIVATE BOOLEAN handle_LYK_GOTO ARGS9(
 
     *URLTotal = (Goto_URLs ? HTList_count(Goto_URLs) : 0);
     if (goto_buffer && *user_input_buffer) {
-	*recall = ((*URLTotal > 1) ? RECALL : NORECALL);
+	*recall = ((*URLTotal > 1) ? RECALL_URL : NORECALL);
 	*URLNum = 0;
 	*FirstURLRecall = FALSE;
     } else {
-	*recall = ((*URLTotal >= 1) ? RECALL : NORECALL);
+	*recall = ((*URLTotal >= 1) ? RECALL_URL : NORECALL);
 	*URLNum = *URLTotal;
 	*FirstURLRecall = TRUE;
     }
@@ -3335,8 +3327,8 @@ PRIVATE BOOLEAN handle_LYK_INFO ARGS1(
      */
     if (!LYIsUIPage(curdoc.address, UIP_SHOWINFO)) {
 	if (do_change_link() != -1
-	 && showinfo(&curdoc, HText_getNumOfLines(),
-		     &newdoc, owner_address) >= 0) {
+	 && LYShowInfo(&curdoc, HText_getNumOfLines(),
+		       &newdoc, owner_address) >= 0) {
 	    LYRegisterUIPage(newdoc.address, UIP_SHOWINFO);
 	    StrAllocCopy(newdoc.title, SHOWINFO_TITLE);
 	    FREE(newdoc.post_data);
@@ -3470,7 +3462,7 @@ PRIVATE BOOLEAN handle_LYK_JUMP ARGS10(
 		LYJumpFileURL = FALSE;
 		StrAllocCopy(*old_user_input, user_input_buffer);
 		*URLTotal = (Goto_URLs ? HTList_count(Goto_URLs) : 0);
-		*recall = ((*URLTotal >= 1) ? RECALL : NORECALL);
+		*recall = ((*URLTotal >= 1) ? RECALL_URL : NORECALL);
 		*URLNum = *URLTotal;
 		*FirstURLRecall = TRUE;
 		if (!strcasecomp(ret, "Go :")) {
@@ -3710,6 +3702,16 @@ PRIVATE void handle_LYK_MODIFY ARGS1(
 }
 #endif /* DIRED_SUPPORT */
 
+#ifdef EXP_NESTED_TABLES
+PRIVATE BOOLEAN handle_LYK_NESTED_TABLES ARGS1(
+    int *,	cmd)
+{
+    nested_tables = !nested_tables;
+    HTUserMsg(nested_tables ? NESTED_TABLES_ON : NESTED_TABLES_OFF);
+    return reparse_or_reload(cmd);
+}
+#endif
+
 PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
     int *,	cmd,
     BOOLEAN *,	refresh_screen)
@@ -4460,7 +4462,7 @@ PRIVATE void handle_LYK_SWITCH_DTD NOARGS
     } /* end if no bypass */
 #endif
     Old_DTD = !Old_DTD;
-    HTSwitchDTD((BOOLEAN) !Old_DTD);
+    HTSwitchDTD(!Old_DTD);
     HTUserMsg(Old_DTD ? USING_DTD_0 : USING_DTD_1);
 #ifdef SOURCE_CACHE
     if (canreparse) {
@@ -4754,12 +4756,12 @@ PRIVATE void handle_LYK_VIEW_BOOKMARK ARGS3(
 
     /*
      *	See if a bookmark exists.
-     *	If it does replace newdoc.address with it's name.
+     *	If it does replace newdoc.address with its name.
      */
     if ((cp = get_bookmark_filename(&newdoc.address)) != NULL) {
 	if (*cp == '\0' || !strcmp(cp, " ") ||
 	    !strcmp(curdoc.address, newdoc.address)) {
-	    if (LYMultiBookmarks == TRUE)
+	    if (LYMultiBookmarks != MBM_OFF)
 		*refresh_screen = TRUE;
 	    return;
 	}
@@ -4781,7 +4783,7 @@ PRIVATE void handle_LYK_VIEW_BOOKMARK ARGS3(
 	    *old_c = real_c;
 	    LYMBM_statusline(BOOKMARKS_NOT_OPEN);
 	    LYSleepAlert();
-	    if (LYMultiBookmarks == TRUE) {
+	    if (LYMultiBookmarks != MBM_OFF) {
 		*refresh_screen = TRUE;
 	    }
 	}
@@ -4833,7 +4835,7 @@ PUBLIC void handle_LYK_WHEREIS ARGS2(
     int,	cmd,
     BOOLEAN *,	refresh_screen)
 {
-    BOOLEAN have_target_onscreen = (*prev_target != '\0' &&
+    BOOLEAN have_target_onscreen = (BOOLEAN) (*prev_target != '\0' &&
 				    HText_pageHasPrevTarget());
     BOOL found;
     int oldcur = curdoc.link; /* temporarily remember */
@@ -4843,7 +4845,7 @@ PUBLIC void handle_LYK_WHEREIS ARGS2(
     else
 	StrAllocCopy(remember_old_target, "");
 
-    if (cmd != LYK_NEXT) {
+    if (cmd == LYK_WHEREIS) {
 	/*
 	 *  Reset prev_target to force prompting
 	 *  for a new search string and to turn
@@ -4851,20 +4853,13 @@ PUBLIC void handle_LYK_WHEREIS ARGS2(
 	 *  is entered by the user.
 	 */
 	*prev_target = '\0';
-	found = textsearch(&curdoc, prev_target, sizeof(prev_target)-1, FALSE);
-    } else {
-	/*
-	 *  When the third argument is TRUE, the previous
-	 *  search string, if any, will be recalled from
-	 *  a buffer, loaded into prev_target, and used
-	 *  for the search without prompting for a new
-	 *  search string.  This allows the LYK_NEXT
-	 *  command to repeat a search in a new document,
-	 *  after prev_target was reset on fetch of that
-	 *  document.
-	 */
-	found = textsearch(&curdoc, prev_target, sizeof(prev_target)-1, TRUE);
     }
+    found = textsearch(&curdoc, prev_target, sizeof(prev_target)-1,
+		       (cmd == LYK_WHEREIS)
+		       ? 0
+		       : ((cmd == LYK_NEXT)
+			 ? 1
+			 : -1));
 
     /*
      *	Force a redraw to ensure highlighting of hits
@@ -5160,41 +5155,104 @@ PUBLIC void handle_LYK_CHDIR NOARGS
 #endif
 
 #ifdef USE_CURSES_PADS
-PRIVATE void handle_LYK_SHIFT_LEFT ARGS1(BOOLEAN *, flag)
+/*
+ * Having jumps larger than this is counter-productive.  Indeed, it is natural
+ * to expect that when the relevant text appears, one would "overshoot" and
+ * would scroll 3-4 extra full screens.  When going back, the "accumulation"
+ * logic would again start moving in full screens, so one would overshoot
+ * again, etc.
+ * 
+ * Going back, one can fix it in 28 keypresses. The relevant text will appear
+ * on the screen soon enough for the key-repeat to become not that important,
+ * and we are still moving in smaller steps than when we overshot.  Since key
+ * repeat is not important, even if we overshoot again, it is going to be by 30
+ * steps, which is easy to fix by reversing the direction again.
+ */
+PRIVATE int repeat_to_delta ARGS1(int, n)
 {
-    if (LYlineWrap) {
-	HTAlert(SHIFT_VS_LINEWRAP);
-    } else {
-	if (LYshiftWin > 0) {
-	    LYshiftWin--;
-	    *flag = TRUE;
+    int threshold = LYcols / 3;
+
+    while (threshold > 0) {
+	if (n >= threshold) {
+	    n = threshold;
+	    break;
 	}
+	threshold = (threshold * 2) / 3;
     }
+    return n;
 }
 
-PRIVATE void handle_LYK_SHIFT_RIGHT ARGS1(BOOLEAN *, flag)
+PRIVATE void handle_LYK_SHIFT_LEFT ARGS2(BOOLEAN *, flag, int, count)
 {
-    if (LYlineWrap) {
+    if (!LYwideLines) {
 	HTAlert(SHIFT_VS_LINEWRAP);
-    } else {
-	LYshiftWin++;
+	return;
+    }
+    if (LYshiftWin > 0) {
+	LYshiftWin -= repeat_to_delta(count);
 	*flag = TRUE;
     }
+    if (LYshiftWin < 0)
+	LYshiftWin = 0;
+}
+
+PRIVATE void handle_LYK_SHIFT_RIGHT ARGS2(BOOLEAN *, flag, int, count)
+{
+    if (!LYwideLines) {
+	HTAlert(SHIFT_VS_LINEWRAP);
+	return;
+    }
+    LYshiftWin += repeat_to_delta(count);
+    *flag = TRUE;
 }
 
 PRIVATE BOOLEAN handle_LYK_LINEWRAP_TOGGLE ARGS2(
     int *,	cmd,
     BOOLEAN *,	flag)
 {
-    LYlineWrap = !LYlineWrap;
-    if (LYlineWrap != 0) {
-	LYcols = LYscreenWidth();
+    static char *choices[] = {
+	"Try to fit screen width",
+	"No line wrap in columns",
+	"Wrap columns at screen width",
+	"Wrap columns at 3/4 screen width",
+	"Wrap columns at 2/3 screen width",
+	"Wrap columns at 1/2 screen width",
+	"Wrap columns at 1/3 screen width",
+	"Wrap columns at 1/4 screen width",
+	NULL
+    };
+    static int wrap[] = {
+	0,
+	0,
+	12,				/* In units of 1/12 */
+	9,
+	8,
+	6,
+	4,
+	3
+    };
+    int c;
+
+    /* Somehow the mouse is over the number instead of being over the
+       name, so we decrease x. */
+    c = LYChoosePopup(!LYwideLines, LYlines /2 - 2, LYcols/2-6,
+		      choices, TABLESIZE(choices) - 1, FALSE, TRUE);
+    /*
+     *  LYhandlePopupList() wasn't really meant to be used
+     *  outside of old-style Options menu processing.  One result of
+     *  mis-using it here is that we have to deal with side-effects
+     *  regarding SIGINT signal handler and the term_options global
+     *  variable. - kw
+     */
+    if (term_options)
+	return FALSE;
+    LYwideLines = c;
+    LYtableCols = wrap[c];
+
+    if (LYwideLines == 0)
 	LYshiftWin = 0;
-    } else {
-	LYcols = MAX_COLS;
-    }
     *flag = TRUE;
-    HTUserMsg(LYlineWrap ? LINEWRAP_ON : LINEWRAP_OFF);
+    HTUserMsg(LYwideLines ? LINEWRAP_OFF : LINEWRAP_ON);
     return reparse_or_reload(cmd);
 }
 #endif
@@ -5249,7 +5307,7 @@ int mainloop NOARGS
     BOOLEAN use_last_tfpos;
     unsigned int len;
     int i;
-    int follow_col = -1;
+    int follow_col = -1, key_count = 0, last_key = 0;
 
 /*
  *  curdoc.address contains the name of the file that is currently open.
@@ -5322,7 +5380,7 @@ initialize:
 	} else {
 	    /*
 	     *	See if a bookmark page exists.	If it does,
-	     *	replace newdoc.address with it's name
+	     *	replace newdoc.address with its name
 	     */
 	    if ((cp = get_bookmark_filename(&newdoc.address)) != NULL &&
 		 *cp != '\0' && strcmp(cp, " ")) {
@@ -5508,7 +5566,7 @@ try_again:
 		psrc_first_tag = TRUE;
 #endif
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
-		textfields_need_activation = global_textfields_need_activation;
+		textfields_need_activation = textfields_activation_option;
 #endif
 		FREE(LYRequestReferer);
 		/*
@@ -6448,7 +6506,7 @@ try_again:
 			HTUnEscape(temp_buff);
 		    }
 		    str_sjis(sjis_buff, temp_buff);
-		    set_ws_title(string_short(sjis_buff, 10));
+		    set_ws_title(LYElideString(sjis_buff, 10));
 		}
 	    }
 	} else {
@@ -6633,10 +6691,7 @@ try_again:
 		     *   Caveat emptor to anyone trying to change it.]
 		     */
 		    if ((links[curdoc.link].type       == WWW_FORM_LINK_TYPE &&
-			 links[curdoc.link].form->type == F_TEXTAREA_TYPE)
-/*			&&
-			 (peek_mouse_link() == -1) */
-			&&
+			 links[curdoc.link].form->type == F_TEXTAREA_TYPE) &&
 			((curdoc.link == nlinks-1 &&
 			  !(more && HText_TAHasMoreLines(curdoc.link, 1)))
 			 ||
@@ -6672,7 +6727,7 @@ try_again:
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
 			if (textfields_need_activation) {
 			    textinput_activated = TRUE;
-			    textfields_need_activation = global_textfields_need_activation;
+			    textfields_need_activation = textfields_activation_option;
 #ifdef INACTIVE_INPUT_STYLE_VH
 			    textinput_redrawn = TRUE;
 #endif
@@ -6695,19 +6750,6 @@ try_again:
 		    if (old_c != c && old_c != real_c && c != real_c)
 			real_c = c;
 		}
-#if 0
-#ifdef INACTIVE_INPUT_STYLE_VH
-	    } else if (curlink_is_editable && !textinput_redrawn) {
-		/*draw the text entry, but don't activate it*/
-		change_form_link_ex(&links[curdoc.link],
-				    &newdoc, &refresh_screen,
-				    links[curdoc.link].form->name,
-				    links[curdoc.link].form->value,
-				    use_last_tfpos, FALSE, TRUE);
-		c = DO_NOTHING;
-		textinput_redrawn = TRUE;
-#endif /* INACTIVE_INPUT_STYLE_VH */
-#endif
 	    } else {
 #if defined(TEXTFIELDS_MAY_NEED_ACTIVATION) && defined(INACTIVE_INPUT_STYLE_VH)
 		if (curlink_is_editable && !textinput_redrawn) {
@@ -6734,6 +6776,10 @@ try_again:
 		 */
 		real_c = c = LYgetch(); /* get user input */
 
+		if (c != last_key)
+		    key_count = 0;
+		key_count++;
+		last_key = c;
 #ifndef VMS
 		if (c == 3) {		/* ^C */
 		    /*
@@ -7200,6 +7246,12 @@ new_cmd:  /*
 	    handle_LYK_MAIN_MENU(&old_c, real_c);
 	    break;
 
+#ifdef EXP_NESTED_TABLES
+	case LYK_NESTED_TABLES:
+	    if (handle_LYK_NESTED_TABLES(&cmd))
+		goto new_cmd;
+	    break;
+#endif
 	case LYK_OPTIONS:	/* options screen */
 	    if (handle_LYK_OPTIONS(&cmd, &refresh_screen))
 		goto new_cmd;
@@ -7211,6 +7263,7 @@ new_cmd:  /*
 
 	case LYK_WHEREIS:	/* search within the document */
 	case LYK_NEXT:		/* find the next occurrence in the document */
+	case LYK_PREV:		/* find the previous occurrence in the document */
 	    handle_LYK_WHEREIS(cmd, &refresh_screen);
 	    break;
 
@@ -7404,10 +7457,10 @@ new_cmd:  /*
 #endif
 #ifdef USE_CURSES_PADS
 	case LYK_SHIFT_LEFT:
-	    handle_LYK_SHIFT_LEFT(&refresh_screen);
+	    handle_LYK_SHIFT_LEFT(&refresh_screen, key_count);
 	    break;
 	case LYK_SHIFT_RIGHT:
-	    handle_LYK_SHIFT_RIGHT(&refresh_screen);
+	    handle_LYK_SHIFT_RIGHT(&refresh_screen, key_count);
 	    break;
 	case LYK_LINEWRAP_TOGGLE:
 	    if (handle_LYK_LINEWRAP_TOGGLE(&cmd, &refresh_screen))
diff --git a/src/LYNews.c b/src/LYNews.c
index 72309078..0755d17f 100644
--- a/src/LYNews.c
+++ b/src/LYNews.c
@@ -14,6 +14,7 @@
 #include <GridText.h>
 #include <LYCharSets.h>
 #include <LYNews.h>
+#include <LYEdit.h>
 
 #include <LYGlobalDefs.h>
 
@@ -99,7 +100,6 @@ PUBLIC char *LYNewsPost ARGS2(
 	BOOLEAN,	followup)
 {
     char user_input[1024];
-    char *command = NULL;
     char CJKinput[1024];
     char *cp = NULL;
     CONST char *kp = NULL;
@@ -342,10 +342,6 @@ PUBLIC char *LYNewsPost ARGS2(
      *  Have the user create the message body.
      */
     if (!no_editor && editor && *editor != '\0') {
-	/*
-	 *  Use an external editor.
-	 */
-	char *editor_arg = "";
 
 	if (followup && nhist > 0) {
 	    /*
@@ -372,19 +368,7 @@ PUBLIC char *LYNewsPost ARGS2(
 	/*
 	 *  Spawn the user's editor on the news file.
 	 */
-	if (strstr(editor, "pico")) {
-	    editor_arg = " -t"; /* No prompt for filename to use */
-	}
-	HTSprintf0(&command, "%s%s %s", editor, editor_arg, my_tempfile);
-	_statusline(SPAWNING_EDITOR_FOR_NEWS);
-	stop_curses();
-	if (LYSystem(command)) {
-	    start_curses();
-	    HTAlert(ERROR_SPAWNING_EDITOR);
-	} else {
-	    start_curses();
-	}
-	FREE(command);
+	edit_temporary_file(my_tempfile, "", SPAWNING_EDITOR_FOR_NEWS);
 
 	nonempty = message_has_content(my_tempfile, &nonspaces);
 
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 230d380c..8de61b6b 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -26,6 +26,8 @@
 
 BOOLEAN term_options;
 
+PRIVATE int LYChosenShowColor = SHOW_COLOR_UNKNOWN; /* whether to show and save */
+
 PRIVATE void terminate_options	PARAMS((int sig));
 
 #if !defined(NO_OPTION_MENU) || (defined(USE_MOUSE) && (defined(NCURSES) || defined(PDCURSES)))
@@ -36,7 +38,20 @@ PRIVATE void terminate_options	PARAMS((int sig));
 PRIVATE BOOLEAN can_do_colors = 0;
 #endif
 
-PUBLIC int SetupChosenShowColor NOARGS
+PUBLIC BOOLEAN LYCheckUserAgent NOARGS
+{
+    if (LYUserAgent && *LYUserAgent) {
+	if (strstr(LYUserAgent, "Lynx") == 0
+	 && strstr(LYUserAgent, "lynx") == 0
+	 && strstr(LYUserAgent, "L_y_n_x") == 0
+	 && strstr(LYUserAgent, "l_y_n_x") == 0) {
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+PRIVATE void SetupChosenShowColor NOARGS
 {
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
     can_do_colors = 1;
@@ -68,7 +83,6 @@ PUBLIC int SetupChosenShowColor NOARGS
 	}
     }
 #endif /* USE_SLANG || COLOR_CURSES */
-    return LYChosenShowColor;
 }
 
 PRIVATE void validate_x_display NOPARAMS
@@ -246,6 +260,58 @@ PRIVATE void addlbl ARGS1(CONST char *, text)
 
 PUBLIC void LYoptions NOARGS
 {
+#define ShowBool(value) LYaddstr((value) ? "ON " : "OFF")
+    static char *bool_choices[] = {
+	"OFF",
+	"ON",
+	NULL
+    };
+    static char *caseless_choices[] = {
+	"CASE INSENSITIVE",
+	"CASE SENSITIVE",
+	NULL
+    };
+    static char *dirList_choices[] = {
+	"Directories first",
+	"Files first",
+	"Mixed style",
+	NULL
+    };
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+    static char *exec_choices[] = {
+	"ALWAYS OFF",
+	"FOR LOCAL FILES ONLY",
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+	"ALWAYS ON",
+#endif /* !NEVER_ALLOW_REMOTE_EXEC */
+	NULL
+    };
+#endif
+    static char *fileSort_choices[] = {
+	"By Filename",
+	"By Type",
+	"By Size",
+	"By Date",
+	NULL
+    };
+    static char *keypad_choices[] = {
+	"Numbers act as arrows",
+	"Links are numbered",
+	"Links and form fields are numbered",
+	NULL
+    };
+    static char *mbm_choices[] = {
+	"OFF     ",
+	"STANDARD",
+	"ADVANCED",
+	NULL
+    };
+    static char *userMode_choices[] = {
+	"Novice",
+	"Intermediate",
+	"Advanced",
+	NULL
+    };
 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
     int itmp;
 #endif /* ENABLE_OPTS_CHANGE_EXEC */
@@ -314,7 +380,6 @@ draw_options:
      *	NOTE that printw() should be avoided for strings that
      *	might have non-ASCII or multibyte/CJK characters. - FM
      */
-    response = 0;
 #if defined(FANCY_CURSES) || defined (USE_SLANG)
     if (enable_scrollback) {
 	LYclear();
@@ -343,12 +408,9 @@ draw_options:
 
     LYmove(L_HOME, 5);
     addlbl("mu(L)ti-bookmarks: ");
-    LYaddstr((LYMultiBookmarks ?
-	      (LYMBMAdvanced ? "ADVANCED"
-			     : "STANDARD")
-			     : "OFF     "));
+    LYaddstr(mbm_choices[LYMultiBookmarks]);
     LYmove(L_HOME, B_BOOK);
-    if (LYMultiBookmarks) {
+    if (LYMultiBookmarks != MBM_OFF) {
 	addlbl("review/edit (B)ookmarks files");
     } else {
 	addlbl("(B)ookmark file: ");
@@ -396,14 +458,13 @@ draw_options:
 
     LYmove(L_Rawmode, 5);
     addlbl("Raw 8-bit or CJK m(O)de      : ");
-    LYaddstr(LYRawMode ? "ON " : "OFF");
+    ShowBool(LYRawMode);
 
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
     LYmove(L_Color, B_COLOR);
     addlbl("show color (&)  : ");
     if (no_option_save) {
-	LYaddstr((LYShowColor == SHOW_COLOR_OFF ? "OFF" :
-						"ON "));
+	ShowBool(LYShowColor == SHOW_COLOR_OFF);
     } else {
 	switch (LYChosenShowColor) {
 	case SHOW_COLOR_NEVER:
@@ -428,23 +489,23 @@ draw_options:
 
     LYmove(L_Bool_A, B_VIKEYS);
     addlbl("(V)I keys: ");
-    LYaddstr(vi_keys ? "ON " : "OFF");
+    ShowBool(vi_keys);
 
     LYmove(L_Bool_A, B_EMACSKEYS);
     addlbl("e(M)acs keys: ");
-    LYaddstr(emacs_keys ? "ON " : "OFF");
+    ShowBool(emacs_keys);
 
     LYmove(L_Bool_A, B_SHOW_DOTFILES);
     addlbl("sho(W) dot files: ");
-    LYaddstr((!no_dotfiles && show_dotfiles) ? "ON " : "OFF");
+    ShowBool(!no_dotfiles && show_dotfiles);
 
     LYmove(L_Bool_B, B_SELECT_POPUPS);
     addlbl("popups for selec(T) fields   : ");
-    LYaddstr(LYSelectPopups ? "ON " : "OFF");
+    ShowBool(LYSelectPopups);
 
     LYmove(L_Bool_B, B_SHOW_CURSOR);
     addlbl("show cursor (@) : ");
-    LYaddstr(LYShowCursor ? "ON " : "OFF");
+    ShowBool(LYShowCursor);
 
     LYmove(L_Keypad, 5);
     addlbl("(K)eypad mode                : ");
@@ -479,7 +540,7 @@ draw_options:
 					  "Advanced    "));
 
     addlbl("  verbose images (!) : ");
-    LYaddstr( verbose_img ? "ON " : "OFF" );
+    ShowBool( verbose_img);
 
     LYmove(L_User_Agent, 5);
     addlbl("user (A)gent                 : ");
@@ -520,10 +581,11 @@ draw_options:
     LYaddstr("'");
     LYaddstr(TO_RETURN_SEGMENT);
 
+    response = 0;
     while (response != 'R' &&
 	   !LYisNonAlnumKeyname(response, LYK_PREV_DOC) &&
 	   response != '>' && !term_options &&
-	   LYCharIsINTERRUPT_NO_letter(response)) {
+	   !LYCharIsINTERRUPT_NO_letter(response)) {
 	if (AddValueAccepted == TRUE) {
 	    _statusline(VALUE_ACCEPTED);
 	    AddValueAccepted = FALSE;
@@ -654,48 +716,30 @@ draw_options:
 		    response = ' ';
 		    break;
 		}
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "OFF     ");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "STANDARD");
-		choices[2] = NULL;
-		StrAllocCopy(choices[2], "ADVANCED");
-		choices[3] = NULL;
 		if (!LYSelectPopups) {
-		    LYMultiBookmarks = LYChooseBoolean((LYMultiBookmarks *
-						       (1 + LYMBMAdvanced)),
+		    LYMultiBookmarks = LYChooseBoolean(LYMultiBookmarks,
 						      L_HOME, C_MULTI,
-						      choices);
+						      mbm_choices);
 		} else {
-		    LYMultiBookmarks = LYChoosePopup((LYMultiBookmarks *
-						     (1 + LYMBMAdvanced)),
+		    LYMultiBookmarks = LYChoosePopup(LYMultiBookmarks,
 						    L_HOME, (C_MULTI - 1),
-						    choices,
+						    mbm_choices,
 						    3, FALSE, FALSE);
 		}
-		if (LYMultiBookmarks == 2) {
-		    LYMultiBookmarks = TRUE;
-		    LYMBMAdvanced = TRUE;
-		} else {
-		    LYMBMAdvanced = FALSE;
-		}
 #if defined(VMS) || defined(USE_SLANG)
 		if (LYSelectPopups) {
 		    LYmove(L_HOME, C_MULTI);
 		    LYclrtoeol();
-		    LYaddstr(choices[(LYMultiBookmarks * (1 + LYMBMAdvanced))]);
+		    LYaddstr(mbm_choices[LYMultiBookmarks]);
 		}
 #endif /* VMS || USE_SLANG */
-		FREE(choices[0]);
-		FREE(choices[1]);
-		FREE(choices[2]);
 #if !defined(VMS) && !defined(USE_SLANG)
 		if (!LYSelectPopups)
 #endif /* !VMS && !USE_SLANG */
 		{
 		    LYmove(L_HOME, B_BOOK);
 		    LYclrtoeol();
-		    if (LYMultiBookmarks) {
+		    if (LYMultiBookmarks != MBM_OFF) {
 			LYaddstr(gettext("review/edit B)ookmarks files"));
 		    } else {
 			LYaddstr(gettext("B)ookmark file: "));
@@ -715,7 +759,7 @@ draw_options:
 		 *  change the bookmark page.
 		 */
 		if (!no_bookmark) {
-		    if (LYMultiBookmarks) {
+		    if (LYMultiBookmarks != MBM_OFF) {
 			edit_bookmarks();
 			signal(SIGINT, terminate_options);
 			goto draw_options;
@@ -748,8 +792,7 @@ draw_options:
 			break;
 		    } else {
 			StrAllocCopy(bookmark_page, display_option);
-			StrAllocCopy(MBM_A_subbookmark[0],
-				     bookmark_page);
+			StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
 			LYaddstr(bookmark_page);
 		    }
 		    LYclrtoeol();
@@ -766,37 +809,21 @@ draw_options:
 		break;
 
 	    case 'F':	/* Change ftp directory sorting. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "By Filename");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "By Type    ");
-		choices[2] = NULL;
-		StrAllocCopy(choices[2], "By Size    ");
-		choices[3] = NULL;
-		StrAllocCopy(choices[3], "By Date    ");
-		choices[4] = NULL;
 		if (!LYSelectPopups) {
 		    HTfileSortMethod = LYChooseBoolean(HTfileSortMethod,
 						      L_FTPSTYPE, -1,
-						      choices);
+						      fileSort_choices);
 		} else {
 		    HTfileSortMethod = LYChoosePopup(HTfileSortMethod,
 						    L_FTPSTYPE, -1,
-						    choices,
+						    fileSort_choices,
 						    4, FALSE, FALSE);
 #if defined(VMS) || defined(USE_SLANG)
 		    LYmove(L_FTPSTYPE, COL_OPTION_VALUES);
 		    LYclrtoeol();
-		    LYaddstr(choices[HTfileSortMethod]);
+		    LYaddstr(fileSort_choices[HTfileSortMethod]);
 #endif /* VMS || USE_SLANG */
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
-		FREE(choices[2]);
-		FREE(choices[3]);
 		response = ' ';
 		if (LYSelectPopups) {
 		    HANDLE_LYOPTIONS;
@@ -840,18 +867,9 @@ draw_options:
 		break;
 
 	    case 'S':	/* Change case sensitivity for searches. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "CASE INSENSITIVE");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "CASE SENSITIVE  ");
-		choices[2] = NULL;
 		case_sensitive = LYChooseBoolean(case_sensitive,
-						L_SSEARCH, -1, choices);
-		FREE(choices[0]);
-		FREE(choices[1]);
+						 L_SSEARCH, -1,
+						 caseless_choices);
 		response = ' ';
 		break;
 
@@ -874,10 +892,12 @@ draw_options:
 			curval = LYRawMode ? current_char_set : 0;
 		    if (!LYSelectPopups) {
 #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
-			UCLYhndl_for_unspec = assumed_doc_charset_map[LYChooseBoolean(
-			    charset_subsets[curval].assumed_idx,
-							     L_ASSUME_CHARSET, -1,
-							     assumed_charset_choices)];
+			UCLYhndl_for_unspec = assumed_doc_charset_map[
+			    LYChooseBoolean(charset_subsets[curval].assumed_idx,
+					    L_ASSUME_CHARSET, -1,
+					    assumed_charset_choices)
+					    ? 1
+					    : 0];
 #else
 			UCLYhndl_for_unspec = LYChooseBoolean(curval,
 							     L_ASSUME_CHARSET, -1,
@@ -885,11 +905,13 @@ draw_options:
 #endif
 		    } else {
 #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
-			UCLYhndl_for_unspec = assumed_doc_charset_map[LYChoosePopup(
-			    charset_subsets[curval].assumed_idx,
-							   L_ASSUME_CHARSET, -1,
-							   assumed_charset_choices,
-							   0, FALSE, FALSE)];
+			UCLYhndl_for_unspec = assumed_doc_charset_map[
+			    LYChoosePopup(charset_subsets[curval].assumed_idx,
+					  L_ASSUME_CHARSET, -1,
+					  assumed_charset_choices,
+					  0, FALSE, FALSE)
+					  ? 1
+					  : 0];
 #else
 			UCLYhndl_for_unspec = LYChoosePopup(curval,
 							   L_ASSUME_CHARSET, -1,
@@ -926,7 +948,7 @@ draw_options:
 			{
 			    LYmove(L_Rawmode, COL_OPTION_VALUES);
 			    LYclrtoeol();
-			    LYaddstr(LYRawMode ? "ON " : "OFF");
+			    ShowBool(LYRawMode);
 			}
 		    }
 		    FREE(assume_list);
@@ -987,7 +1009,7 @@ draw_options:
 		    {
 			LYmove(L_Rawmode, COL_OPTION_VALUES);
 			LYclrtoeol();
-			LYaddstr(LYRawMode ? "ON " : "OFF");
+			ShowBool(LYRawMode);
 		    }
 #ifdef CAN_SWITCH_DISPLAY_CHARSET
 		    /* Deduce whether the user wants autoswitch: */
@@ -1003,15 +1025,7 @@ draw_options:
 		break;
 
 	    case 'O':	/* Change raw mode setting. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "OFF");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "ON ");
-		choices[2] = NULL;
-		LYRawMode = LYChooseBoolean(LYRawMode, L_Rawmode, -1, choices);
+		LYRawMode = LYChooseBoolean(LYRawMode, L_Rawmode, -1, bool_choices);
 		/*
 		 *  Set the LYUseDefaultRawMode value and character
 		 *  handling if LYRawMode was changed. - FM
@@ -1021,8 +1035,6 @@ draw_options:
 		    HTMLSetCharacterHandling(current_char_set);
 		    CurrentRawMode = LYRawMode;
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
 		response = ' ';
 		break;
 
@@ -1097,46 +1109,26 @@ draw_options:
 		break;
 
 	    case 'V':	/* Change VI keys setting. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "OFF");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "ON ");
-		choices[2] = NULL;
 		vi_keys = LYChooseBoolean(vi_keys,
 					 L_Bool_A, C_VIKEYS,
-					 choices);
+					 bool_choices);
 		if (vi_keys) {
 		    set_vi_keys();
 		} else {
 		    reset_vi_keys();
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
 		response = ' ';
 		break;
 
 	    case 'M':	/* Change emacs keys setting. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "OFF");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "ON ");
-		choices[2] = NULL;
 		emacs_keys = LYChooseBoolean(emacs_keys,
 					    L_Bool_A, C_EMACSKEYS,
-					    choices);
+					    bool_choices);
 		if (emacs_keys) {
 		    set_emacs_keys();
 		} else {
 		    reset_emacs_keys();
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
 		response = ' ';
 		break;
 
@@ -1144,39 +1136,19 @@ draw_options:
 		if (no_dotfiles) {
 		    _statusline(DOTFILE_ACCESS_DISABLED);
 		} else {
-		    /*
-		     *	Copy strings into choice array.
-		     */
-		    choices[0] = NULL;
-		    StrAllocCopy(choices[0], "OFF");
-		    choices[1] = NULL;
-		    StrAllocCopy(choices[1], "ON ");
-		    choices[2] = NULL;
 		    show_dotfiles = LYChooseBoolean(show_dotfiles,
 						   L_Bool_A,
 						   C_SHOW_DOTFILES,
-						   choices);
-		    FREE(choices[0]);
-		    FREE(choices[1]);
+						   bool_choices);
 		}
 		response = ' ';
 		break;
 
 	    case 'T':	/* Change select popups setting. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "OFF");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "ON ");
-		choices[2] = NULL;
 		LYSelectPopups = LYChooseBoolean(LYSelectPopups,
 						L_Bool_B,
 						C_SELECT_POPUPS,
-						choices);
-		FREE(choices[0]);
-		FREE(choices[1]);
+						bool_choices);
 		response = ' ';
 		break;
 
@@ -1195,18 +1167,10 @@ draw_options:
 			break;
 		    }
 #endif
-		/*
-		 *  Copy strings into choice array.
-		 */
-		    choices[0] = NULL;
-		    StrAllocCopy(choices[0], "OFF");
-		    choices[1] = NULL;
-		    StrAllocCopy(choices[1], "ON ");
-		    choices[2] = NULL;
 		    LYShowColor = LYChooseBoolean((LYShowColor - 1),
 						 L_Color,
 						 C_COLOR,
-						 choices);
+						 bool_choices);
 		    if (LYShowColor == 0) {
 			LYShowColor = SHOW_COLOR_OFF;
 		    } else {
@@ -1215,9 +1179,9 @@ draw_options:
 		} else {		/* !no_option_save */
 		    BOOLEAN again = FALSE;
 		    int chosen;
-		/*
-		 *  Copy strings into choice array.
-		 */
+		    /*
+		     *  Copy strings into choice array.
+		     */
 		    choices[0] = NULL;
 		    StrAllocCopy(choices[0], "NEVER     ");
 		    choices[1] = NULL;
@@ -1269,11 +1233,11 @@ draw_options:
 		    if (has_colors())
 #endif
 			LYShowColor = chosen;
+		    FREE(choices[0]);
+		    FREE(choices[1]);
 		    FREE(choices[2]);
 		    FREE(choices[3]);
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
 		if (CurrentShowColor != LYShowColor) {
 		    lynx_force_repaint();
 		}
@@ -1289,50 +1253,27 @@ draw_options:
 #endif /* USE_SLANG or COLOR_CURSES */
 
 	    case '@':	/* Change show cursor setting. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "OFF");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "ON ");
-		choices[2] = NULL;
 		LYShowCursor = LYChooseBoolean(LYShowCursor,
 					      L_Bool_B,
 					      C_SHOW_CURSOR,
-					      choices);
-		FREE(choices[0]);
-		FREE(choices[1]);
+					      bool_choices);
 		response = ' ';
 		break;
 
 	    case 'K':	/* Change keypad mode. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0],
-			     "Numbers act as arrows             ");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1],
-			     "Links are numbered                ");
-		choices[2] = NULL;
-		StrAllocCopy(choices[2],
-			     "Links and form fields are numbered");
-		choices[3] = NULL;
 		if (!LYSelectPopups) {
 		    keypad_mode = LYChooseBoolean(keypad_mode,
 						 L_Keypad, -1,
-						 choices);
+						 keypad_choices);
 		} else {
 		    keypad_mode = LYChoosePopup(keypad_mode,
 						L_Keypad, -1,
-						choices,
+						keypad_choices,
 						3, FALSE, FALSE);
 #if defined(VMS) || defined(USE_SLANG)
 		    LYmove(L_Keypad, COL_OPTION_VALUES);
 		    LYclrtoeol();
-		    LYaddstr(choices[keypad_mode]);
+		    LYaddstr(keypad_choices[keypad_mode]);
 #endif /* VMS || USE_SLANG */
 		}
 		if (keypad_mode == NUMBERS_AS_ARROWS) {
@@ -1340,9 +1281,6 @@ draw_options:
 		} else {
 		    reset_numbers_as_arrows();
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
-		FREE(choices[2]);
 		response = ' ';
 		if (LYSelectPopups) {
 		    HANDLE_LYOPTIONS;
@@ -1397,34 +1335,21 @@ draw_options:
 
 #ifdef DIRED_SUPPORT
 	    case 'I':	/* Change local directory sorting. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "Directories first");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "Files first      ");
-		choices[2] = NULL;
-		StrAllocCopy(choices[2], "Mixed style      ");
-		choices[3] = NULL;
 		if (!LYSelectPopups) {
 		    dir_list_style = LYChooseBoolean(dir_list_style,
 						    L_Dired, -1,
-						    choices);
+						    dirList_choices);
 		} else {
 		    dir_list_style = LYChoosePopup(dir_list_style,
 						  L_Dired, -1,
-						  choices,
+						  dirList_choices,
 						  3, FALSE, FALSE);
 #if defined(VMS) || defined(USE_SLANG)
 		    LYmove(L_Dired, COL_OPTION_VALUES);
 		    LYclrtoeol();
-		    LYaddstr(choices[dir_list_style]);
+		    LYaddstr(dirList_choices[dir_list_style]);
 #endif /* VMS || USE_SLANG */
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
-		FREE(choices[2]);
 		response = ' ';
 		if (LYSelectPopups) {
 		    HANDLE_LYOPTIONS;
@@ -1433,38 +1358,25 @@ draw_options:
 #endif /* DIRED_SUPPORT */
 
 	    case 'U':	/* Change user mode. */
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "Novice      ");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "Intermediate");
-		choices[2] = NULL;
-		StrAllocCopy(choices[2], "Advanced    ");
-		choices[3] = NULL;
 		if (!LYSelectPopups) {
 		    user_mode = LYChooseBoolean(user_mode,
 						L_User_Mode, -1,
-						choices);
+						userMode_choices);
 		    use_assume_charset = (BOOL) (user_mode >= 2);
 		} else {
 		    user_mode = LYChoosePopup(user_mode,
 					      L_User_Mode, -1,
-					      choices,
+					      userMode_choices,
 					      3, FALSE, FALSE);
 		    use_assume_charset = (BOOL) (user_mode >= 2);
 #if defined(VMS) || defined(USE_SLANG)
 		    if (use_assume_charset == old_use_assume_charset) {
 			LYmove(L_User_Mode, COL_OPTION_VALUES);
 			LYclrtoeol();
-			LYaddstr(choices[user_mode]);
+			LYaddstr(userMode_choices[user_mode]);
 		    }
 #endif /* VMS || USE_SLANG */
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
-		FREE(choices[2]);
 		if (user_mode == NOVICE_MODE) {
 		    display_lines = (LYlines - 4);
 		} else {
@@ -1477,28 +1389,18 @@ draw_options:
 		break;
 
 	    case '!':
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "OFF");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "ON ");
-		choices[2] = NULL;
 		if (!LYSelectPopups) {
 		    verbose_img = LYChooseBoolean(verbose_img,
 						L_VERBOSE_IMAGES,
 						C_VERBOSE_IMAGES,
-						choices);
+						bool_choices);
 		} else {
 		    verbose_img = LYChoosePopup(verbose_img,
 					     L_VERBOSE_IMAGES,
 					     C_VERBOSE_IMAGES,
-					     choices,
+					     bool_choices,
 					     2, FALSE, FALSE);
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
 		response = ' ';
 		if (LYSelectPopups) {
 		    HANDLE_LYOPTIONS;
@@ -1538,11 +1440,7 @@ draw_options:
 		    if (ch == -1) {
 			HTInfoMsg(CANCELLED);
 			HTInfoMsg("");
-		    } else if (LYUserAgent && *LYUserAgent &&
-			!strstr(LYUserAgent, "Lynx") &&
-			!strstr(LYUserAgent, "lynx") &&
-			!strstr(LYUserAgent, "L_y_n_x") &&
-			!strstr(LYUserAgent, "l_y_n_x")) {
+		    } else if (!LYCheckUserAgent()) {
 			_statusline(UA_PLEASE_USE_LYNX);
 		    } else {
 			_statusline(VALUE_ACCEPTED);
@@ -1572,39 +1470,22 @@ draw_options:
 			itmp = 0;
 		    }
 		}
-		/*
-		 *  Copy strings into choice array.
-		 */
-		choices[0] = NULL;
-		StrAllocCopy(choices[0], "ALWAYS OFF          ");
-		choices[1] = NULL;
-		StrAllocCopy(choices[1], "FOR LOCAL FILES ONLY");
-		choices[2] = NULL;
-#ifndef NEVER_ALLOW_REMOTE_EXEC
-		StrAllocCopy(choices[2], "ALWAYS ON           ");
-		choices[3] = NULL;
-#endif /* !NEVER_ALLOW_REMOTE_EXEC */
 		if (!LYSelectPopups) {
 		    itmp = LYChooseBoolean(itmp,
 					  L_Exec, -1,
-					  choices);
+					  exec_choices);
 		} else {
 		    itmp = LYChoosePopup(itmp,
 					L_Exec, -1,
-					choices,
+					exec_choices,
 					0, (exec_frozen ? TRUE : FALSE),
 					FALSE);
 #if defined(VMS) || defined(USE_SLANG)
 		    LYmove(L_Exec, COL_OPTION_VALUES);
 		    LYclrtoeol();
-		    LYaddstr(choices[itmp]);
+		    LYaddstr(exec_choices[itmp]);
 #endif /* VMS || USE_SLANG */
 		}
-		FREE(choices[0]);
-		FREE(choices[1]);
-#ifndef NEVER_ALLOW_REMOTE_EXEC
-		FREE(choices[2]);
-#endif /* !NEVER_ALLOW_REMOTE_EXEC */
 		if (!exec_frozen) {
 		    switch (itmp) {
 			case 0:
@@ -1633,8 +1514,8 @@ draw_options:
 	    case '>':	/* Save current options to RC file. */
 		if (!no_option_save) {
 		    HTInfoMsg(SAVING_OPTIONS);
+		    LYrcShowColor = LYChosenShowColor;
 		    if (save_rc(NULL)) {
-			LYrcShowColor = LYChosenShowColor;
 			HTInfoMsg(OPTIONS_SAVED);
 		    } else {
 			HTAlert(OPTIONS_NOT_SAVED);
@@ -1666,9 +1547,30 @@ draw_options:
     signal(SIGINT, cleanup_sig);
 }
 
+PRIVATE int widest_choice ARGS1(
+	CONST char **,	choices)
+{
+    int n, width = 0;
+    for (n = 0; choices[n] != NULL; ++n) {
+	int len = strlen(choices[n]);
+	if (width < len)
+	    width = len;
+    }
+    return width;
+}
+
+PRIVATE void show_choice ARGS2(
+	CONST char *,	choice,
+	int,		width)
+{
+    int len = strlen(choice);
+    LYaddstr(choice);
+    while (len++ < width)
+	LYaddch(' ');
+}
+
 /*
- *  Take a boolean status,prompt the user for a new status,
- *  and return it.
+ *  Take a status code, prompt the user for a new status, and return it.
  */
 PRIVATE int boolean_choice ARGS4(
 	int,		cur_choice,
@@ -1681,6 +1583,7 @@ PRIVATE int boolean_choice ARGS4(
     int number = 0;
     int col = (column >= 0 ? column : COL_OPTION_VALUES);
     int orig_choice = cur_choice;
+    int width = widest_choice(choices);
 
     /*
      *	Get the number of choices and then make
@@ -1700,7 +1603,7 @@ PRIVATE int boolean_choice ARGS4(
      */
     LYmove(line, col);
     start_reverse();
-    LYaddstr(choices[cur_choice]);
+    show_choice(choices[cur_choice], width);
     if (LYShowCursor)
 	LYmove(line, (col - 1));
     LYrefresh();
@@ -1789,7 +1692,7 @@ PRIVATE int boolean_choice ARGS4(
 		    else
 			cur_choice++;
 	    }  /* end of switch */
-	    LYaddstr(choices[cur_choice]);
+	    show_choice(choices[cur_choice], width);
 	    if (LYShowCursor)
 		LYmove(line, (col - 1));
 	    LYrefresh();
@@ -1799,7 +1702,7 @@ PRIVATE int boolean_choice ARGS4(
 	     */
 	    LYmove(line, col);
 	    stop_reverse();
-	    LYaddstr(choices[cur_choice]);
+	    show_choice(choices[cur_choice], width);
 
 	    if (term_options) {
 		term_options = FALSE;
@@ -1808,7 +1711,7 @@ PRIVATE int boolean_choice ARGS4(
 	    } else {
 		_statusline(VALUE_ACCEPTED);
 	    }
-	    return (BOOL) (cur_choice);
+	    return cur_choice;
 	}
     }
 }
@@ -1883,7 +1786,7 @@ draw_bookmark_list:
 	for (a = ((MBM_V_MAXFILES/2 + 1) * (MBM_current - 1));
 		      a <= (MBM_current * MBM_V_MAXFILES/2 ); a++) {
 	    LYmove((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 5);
-	    LYaddch(UCH(a + 'A'));
+	    LYaddch(UCH(LYindex2MBM(a)));
 	    LYaddstr(" : ");
 	    if (MBM_A_subdescript[a])
 		LYaddstr(MBM_A_subdescript[a]);
@@ -1896,7 +1799,7 @@ draw_bookmark_list:
     } else {
 	for (a = 0; a <= MBM_V_MAXFILES; a++) {
 	    LYmove(3 + a, 5);
-	    LYaddch(UCH(a + 'A'));
+	    LYaddch(UCH(LYindex2MBM(a)));
 	    LYaddstr(" : ");
 	    if (MBM_A_subdescript[a])
 		LYaddstr(MBM_A_subdescript[a]);
@@ -2019,7 +1922,7 @@ draw_bookmark_list:
 	 *  that way.
 	 */
 	for (a = 0; a <= MBM_V_MAXFILES; a++) {
-	    if ((response - 'A') == a) {
+	    if (LYMBM2index(response) == a) {
 		if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
 		    if (MBM_current == 1 && a > (MBM_V_MAXFILES/2)) {
 			MBM_current = 2;
@@ -2061,7 +1964,7 @@ draw_bookmark_list:
 			     5);
 		    else
 			LYmove((3 + a), 5);
-		    LYaddch(UCH(a + 'A'));
+		    LYaddch(UCH(LYindex2MBM(a)));
 		    LYaddstr(" : ");
 		    if (MBM_A_subdescript[a])
 			LYaddstr(MBM_A_subdescript[a]);
@@ -2211,12 +2114,12 @@ static char * save_options_string	= "save_options";
 /*
  * Personal Preferences
  */
-static char * cookies_string		= "cookies";
+static char * cookies_string		= "set_cookies";
 static char * cookies_ignore_all_string = "ignore";
 static char * cookies_up_to_user_string = "ask user";
 static char * cookies_accept_all_string = "accept all";
 static char * x_display_string		= "display";
-static char * editor_string		= "editor";
+static char * editor_string		= "file_editor";
 static char * emacs_keys_string		= "emacs_keys";
 
 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
@@ -2244,9 +2147,9 @@ static OptValues keypad_mode_values[]	= {
 			      "Links and form fields are numbered",
 			      "links_and_forms" },
 	{ 0, 0, 0 }};
-static char * lineedit_style_string	= "lineedit_style";
-static char * mail_address_string	= "mail_address";
-static char * search_type_string	= "search_type";
+static char * lineedit_mode_string	= "lineedit_mode";
+static char * mail_address_string	= "personal_mail_address";
+static char * search_type_string	= "case_sensitive_searching";
 static OptValues search_type_values[] = {
 	{ FALSE,	    "Case insensitive",  "case_insensitive" },
 	{ TRUE,		    "Case sensitive",	 "case_sensitive" },
@@ -2270,8 +2173,8 @@ static OptValues user_mode_values[] = {
 
 static char * vi_keys_string		= "vi_keys";
 
-static char * visited_pages_type_string	= "visited_pages_type";
-static OptValues visited_pages_type_values[] = {
+static char * visited_links_string	= "visited_links";
+static OptValues visited_links_values[] = {
 	{ VISITED_LINKS_AS_FIRST_V, "By First Visit",	"first_visited" },
 	{ VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE,
 		    "By First Visit Reversed",	"first_visited_reversed" },
@@ -2285,13 +2188,14 @@ static OptValues visited_pages_type_values[] = {
  * Document Layout
  */
 #ifndef SH_EX	/* 1999/01/19 (Tue) */
-static char * DTD_recovery_string      = "DTD";
+static char * DTD_recovery_string      = "DTD_recovery";
 static OptValues DTD_type_values[] = {
 	/* Old_DTD variable */
 	{ TRUE,		    "relaxed (TagSoup mode)",	 "tagsoup" },
 	{ FALSE,	    "strict (SortaSGML mode)",	 "sortasgml" },
 	{ 0, 0, 0 }};
 #endif
+
 static char * select_popups_string     = "select_popups";
 static char * images_string            = "images";
 static char * images_ignore_all_string  = "ignore";
@@ -2307,32 +2211,37 @@ static OptValues verbose_images_type_values[] = {
 /*
  * Bookmark Options
  */
-static char * mbm_advanced_string	= "ADVANCED";
-static char * mbm_off_string		= "OFF";
-static char * mbm_standard_string	= "STANDARD";
-static char * mbm_string		= "multi_bookmarks_mode";
+static char * mbm_string		= "multi_bookmark";
+static OptValues mbm_values[] = {
+	{ MBM_OFF,		"OFF",			"OFF" },
+	{ MBM_STANDARD,		"STANDARD",		"STANDARD" },
+	{ MBM_ADVANCED,		"ADVANCED",		"ADVANCED" },
+	{ 0, 0, 0 }};
+
 static char * single_bookmark_string	= "single_bookmark_name";
 
 /*
  * Character Set Options
  */
 static char * assume_char_set_string	= "assume_char_set";
-static char * display_char_set_string	= "display_char_set";
+static char * display_char_set_string	= "character_set";
 static char * raw_mode_string		= "raw_mode";
 
 /*
  * File Management Options
  */
 static char * show_dotfiles_string	= "show_dotfiles";
+
 #ifdef DIRED_SUPPORT
-static char * dired_sort_string		= "dired_sort";
+static char * dired_sort_string		= "dir_list_style";
 static OptValues dired_values[] = {
 	{ 0,			"Directories first",	"dired_dir" },
 	{ FILES_FIRST,		"Files first",		"dired_files" },
 	{ MIXED_STYLE,		"Mixed style",		"dired_mixed" },
 	{ 0, 0, 0 }};
 #endif /* DIRED_SUPPORT */
-static char * ftp_sort_string = "ftp_sort";
+
+static char * ftp_sort_string		= "file_sorting_method";
 static OptValues ftp_sort_values[] = {
 	{ FILE_BY_NAME,		"By Name",		"ftp_by_name" },
 	{ FILE_BY_TYPE,		"By Type",		"ftp_by_type" },
@@ -2354,20 +2263,10 @@ static OptValues rate_values[] = {
 /*
  * Headers transferred to remote server
  */
-static char * preferred_doc_char_string = "preferred_doc_char";
-static char * preferred_doc_lang_string = "preferred_doc_lang";
+static char * preferred_doc_char_string = "preferred_charset";
+static char * preferred_doc_lang_string = "preferred_language";
 static char * user_agent_string		= "user_agent";
 
-#define PutLabel(fp, text) \
-	fprintf(fp,"  %-33s: ", text)
-
-#define PutLabelNotSaved(fp, text) \
-    if (!no_option_save) { \
-	int l=strlen(text); \
-	fprintf(fp,"  %s", text); \
-	fprintf(fp,"%s%-*s: ", (l<30)?" ":"", (l<30)?32-l:3, "(!)"); \
-    } else PutLabel(fp, text)
-
 #define PutTextInput(fp, Name, Value, Size, disable) \
 	fprintf(fp,\
 	"<input size=%d type=\"text\" name=\"%s\" value=\"%s\" %s>\n",\
@@ -2706,7 +2605,7 @@ PUBLIC int postoptions ARGS1(
 	}
 
 	/* Line edit style: SELECT */
-	if (!strcmp(data[i].tag, lineedit_style_string)) {
+	if (!strcmp(data[i].tag, lineedit_mode_string)) {
 	    int newval = atoi(data[i].value);
 	    int j;
 	    /* prevent spoofing attempt */
@@ -2791,20 +2690,20 @@ PUBLIC int postoptions ARGS1(
 	}
 
 	/* Type of visited pages page: SELECT */
-	if (!strcmp(data[i].tag, visited_pages_type_string))
-	   GetOptValues(visited_pages_type_values, data[i].value, &Visited_Links_As);
+	if (!strcmp(data[i].tag, visited_links_string))
+	   GetOptValues(visited_links_values, data[i].value, &Visited_Links_As);
 
 	/* Show Images: SELECT */
 	if (!strcmp(data[i].tag, images_string)) {
 	    if (!strcmp(data[i].value, images_ignore_all_string)
 			&& !(pseudo_inline_alts == FALSE && clickable_images == FALSE)) {
-		 pseudo_inline_alts = FALSE;
-		 clickable_images = FALSE;
+		pseudo_inline_alts = FALSE;
+		clickable_images = FALSE;
 		need_reload = TRUE;
 	    } else if (!strcmp(data[i].value, images_use_label_string)
 			&& !(pseudo_inline_alts == TRUE && clickable_images == FALSE)) {
-		 pseudo_inline_alts = TRUE;
-		 clickable_images = FALSE;
+		pseudo_inline_alts = TRUE;
+		clickable_images = FALSE;
 		need_reload = TRUE;
 	    } else if (!strcmp(data[i].value, images_use_links_string)
 			&& !(clickable_images == TRUE)) {
@@ -2834,15 +2733,7 @@ PUBLIC int postoptions ARGS1(
 
 	/* Bookmarks File Menu: SELECT */
 	if (!strcmp(data[i].tag, mbm_string) && (!LYMBMBlocked)) {
-	    if (!strcmp(data[i].value, mbm_off_string)) {
-		LYMultiBookmarks = FALSE;
-	    } else if (!strcmp(data[i].value, mbm_standard_string)) {
-		LYMultiBookmarks = TRUE;
-		LYMBMAdvanced = FALSE;
-	    } else if (!strcmp(data[i].value, mbm_advanced_string)) {
-		LYMultiBookmarks = TRUE;
-		LYMBMAdvanced = TRUE;
-	    }
+	    GetOptValues(mbm_values, data[i].value, &LYMultiBookmarks);
 	}
 
 	/* Default Bookmarks filename: INPUT */
@@ -2940,11 +2831,7 @@ PUBLIC int postoptions ARGS1(
 		   *(data[i].value)
 		   ? data[i].value
 		   : LYUserAgentDefault);
-		if (LYUserAgent && *LYUserAgent &&
-		   !strstr(LYUserAgent, "Lynx") &&
-		   !strstr(LYUserAgent, "lynx") &&
-		   !strstr(LYUserAgent, "L_y_n_x") &&
-		   !strstr(LYUserAgent, "l_y_n_x")) {
+		if (!LYCheckUserAgent()) {
 		    HTAlert(UA_PLEASE_USE_LYNX);
 		}
 	    }
@@ -2996,8 +2883,8 @@ PUBLIC int postoptions ARGS1(
     FREE(data);
     if (save_all) {
 	HTInfoMsg(SAVING_OPTIONS);
+	LYrcShowColor = LYChosenShowColor;
 	if (save_rc(NULL)) {
-	    LYrcShowColor = LYChosenShowColor;
 	    HTInfoMsg(OPTIONS_SAVED);
 	} else {
 	    HTAlert(OPTIONS_NOT_SAVED);
@@ -3150,7 +3037,76 @@ PRIVATE char *NewSecureValue NOARGS
 }
 
 /*
- * Okay, someone wants to change options.  So, lets gen up a form for them
+ * Note: the 'value' we are passing here is a local copy of the "same" string
+ * as is used in LYrcFile.c to index the savable options.
+ */
+PRIVATE void PutLabel ARGS3(
+	FILE *,		fp,
+	char *,		name,
+	char *,		value)
+{
+    if (will_save_rc(value) && !no_option_save) {
+	fprintf(fp, "  %-33s: ", name);
+    } else {
+	int l = strlen(name);
+	fprintf(fp, "  %s", name);
+	fprintf(fp, "%s%-*s: ",
+		(l < 30) ? " " : "",
+		(l < 30) ? 32 - l : 3, "(!)");
+    }
+}
+
+/*
+ * For given a list of the .lynxrc names for boolean flags that make up a
+ * composite setting, check if any are not writable for the .lynxrc file.  If
+ * so, return that name, so the subsequence will_save_rc() check in PutLabel()
+ * will flag the composite as not-saved.
+ */
+PRIVATE char *check_if_write_lynxrc ARGS1(char **, table)
+{
+    int n;
+    char *result = NULL;
+
+    for (n = 0; table[n] != 0; ++n) {
+	result = table[n];
+	if (!will_save_rc(result))
+	    break;
+    }
+    return result;
+}
+
+/*
+ * The options menu treats "Cookies" as a single enumeration, but it is read
+ * from lynx.cfg (and perhaps .lynxrc) as a set of booleans.  Check if any are
+ * not writable to .lynxrc, so we can show the user. 
+ */
+PRIVATE char *will_save_cookies NOARGS
+{
+    static char *table[] = {
+	"set_cookies",			/* LYSetCookies */
+	"accept_all_cookies",		/* LYAcceptAllCookies */
+	NULL
+    };
+    return check_if_write_lynxrc(table);
+}
+
+/*
+ * The options menu treats "Show images" as a single enumeration, but it is
+ * read from lynx.cfg (and perhaps .lynxrc) as a set of booleans.  Check if any
+ * are not writable to .lynxrc, so we can show the user. 
+ */
+PRIVATE char *will_save_images NOARGS
+{
+    static char *table[] = {
+	"make_pseudo_alts_for_inlines",	/* pseudo_inline_alts */
+	"make_links_for_all_images",	/* clickable_images */
+	NULL
+    };
+    return check_if_write_lynxrc(table);
+}
+
+/*
+ * Okay, someone wants to change options.  So, let's gen up a form for them
  * and pass it around.  Gor, this is ugly.  Be a lot easier in Bourne with
  * "here" documents.  :->
  * Basic Strategy:  For each option, throw up the appropriate type of
@@ -3253,26 +3209,24 @@ PRIVATE int gen_options ARGS1(
     /*****************************************************************/
 
     /* User Mode: SELECT */
-    PutLabel(fp0, gettext("User mode"));
+    PutLabel(fp0, gettext("User mode"), user_mode_string);
     BeginSelect(fp0, user_mode_string);
     PutOptValues(fp0, user_mode, user_mode_values);
     EndSelect(fp0);
 
     /* Editor: INPUT */
-    PutLabel(fp0, gettext("Editor"));
+    PutLabel(fp0, gettext("Editor"), editor_string);
     PutTextInput(fp0, editor_string, NOTEMPTY(editor), text_len,
 		      DISABLED(no_editor || system_editor));
 
     /* Search Type: SELECT */
-    PutLabel(fp0, gettext("Type of Search"));
+    PutLabel(fp0, gettext("Type of Search"), search_type_string);
     BeginSelect(fp0, search_type_string);
     PutOptValues(fp0, case_sensitive, search_type_values);
     EndSelect(fp0);
 
     /* Cookies: SELECT */
-    /* @@@ This is inconsistent - LYAcceptAllCookies gets saved to RC file
-       but LYSetCookies doesn't! */
-    PutLabelNotSaved(fp0, gettext("Cookies"));
+    PutLabel(fp0, gettext("Cookies"), will_save_cookies());
     BeginSelect(fp0, cookies_string);
     PutOption(fp0, !LYSetCookies,
 		   cookies_ignore_all_string,
@@ -3290,27 +3244,27 @@ PRIVATE int gen_options ARGS1(
     /*****************************************************************/
 
     /* Keypad Mode: SELECT */
-    PutLabel(fp0, gettext("Keypad mode"));
+    PutLabel(fp0, gettext("Keypad mode"), keypad_mode_string);
     BeginSelect(fp0, keypad_mode_string);
     PutOptValues(fp0, keypad_mode, keypad_mode_values);
     EndSelect(fp0);
 
     /* Emacs keys: ON/OFF */
-    PutLabel(fp0, gettext("Emacs keys"));
+    PutLabel(fp0, gettext("Emacs keys"), emacs_keys_string);
     BeginSelect(fp0, emacs_keys_string);
     PutOptValues(fp0, emacs_keys, bool_values);
     EndSelect(fp0);
 
     /* VI Keys: ON/OFF */
-    PutLabel(fp0, gettext("VI keys"));
+    PutLabel(fp0, gettext("VI keys"), vi_keys_string);
     BeginSelect(fp0, vi_keys_string);
     PutOptValues(fp0, vi_keys, bool_values);
     EndSelect(fp0);
 
     /* Line edit style: SELECT */
     if (LYLineeditNames[1]) { /* well, at least 2 line edit styles available */
-	PutLabel(fp0, "Line edit style");
-	BeginSelect(fp0, lineedit_style_string);
+	PutLabel(fp0, gettext("Line edit style"), lineedit_mode_string);
+	BeginSelect(fp0, lineedit_mode_string);
 	for (i = 0; LYLineeditNames[i]; i++) {
 	    char temp[16];
 	    sprintf(temp, "%d", i);
@@ -3321,7 +3275,7 @@ PRIVATE int gen_options ARGS1(
 
 #ifdef EXP_KEYBOARD_LAYOUT
     /* Keyboard layout: SELECT */
-    PutLabel(fp0, "Keyboard layout");
+    PutLabel(fp0, gettext("Keyboard layout"), kblayout_string);
     BeginSelect(fp0, kblayout_string);
     for (i = 0; LYKbLayoutNames[i]; i++) {
 	char temp[16];
@@ -3338,7 +3292,7 @@ PRIVATE int gen_options ARGS1(
     /*****************************************************************/
 
     /* Display Character Set: SELECT */
-    PutLabel(fp0, gettext("Display character set"));
+    PutLabel(fp0, gettext("Display character set"), display_char_set_string);
     BeginSelect(fp0, display_char_set_string);
     for (i = 0; LYchar_set_names[i]; i++) {
 	char temp[10];
@@ -3354,7 +3308,6 @@ PRIVATE int gen_options ARGS1(
     EndSelect(fp0);
 
     /* Assume Character Set: SELECT */
-    /* if (user_mode==ADVANCED_MODE) */
     {
 	int curval;
 	curval = UCLYhndl_for_unspec;
@@ -3368,7 +3321,7 @@ PRIVATE int gen_options ARGS1(
 		/* ok, LYRawMode, so use UCAssume_MIMEcharset */
 	    curval = safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset);
 	}
-	PutLabelNotSaved(fp0, gettext("Assumed document character set"));
+	PutLabel(fp0, gettext("Assumed document character set"), assume_char_set_string);
 	BeginSelect(fp0, assume_char_set_string);
 	for (i = 0; i < LYNumCharsets; i++) {
 #ifdef EXP_CHARSET_CHOICE
@@ -3388,9 +3341,9 @@ PRIVATE int gen_options ARGS1(
 	 * we split the header to make it more readable:
 	 * "CJK mode" for CJK display charsets, and "Raw 8-bit" for others.
 	 */
-	PutLabelNotSaved(fp0, gettext("CJK mode"));
+	PutLabel(fp0, gettext("CJK mode"), raw_mode_string);
     } else {
-	PutLabelNotSaved(fp0, gettext("Raw 8-bit"));
+	PutLabel(fp0, gettext("Raw 8-bit"), raw_mode_string);
     }
 
     BeginSelect(fp0, raw_mode_string);
@@ -3398,7 +3351,7 @@ PRIVATE int gen_options ARGS1(
     EndSelect(fp0);
 
     /* X Display: INPUT */
-    PutLabelNotSaved(fp0, gettext("X Display"));
+    PutLabel(fp0, gettext("X Display"),	x_display_string);
     PutTextInput(fp0, x_display_string, NOTEMPTY(x_display), text_len, "");
 
     /*
@@ -3410,7 +3363,7 @@ PRIVATE int gen_options ARGS1(
     /* Show Color: SELECT */
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
     SetupChosenShowColor();
-    PutLabel(fp0, gettext("Show color"));
+    PutLabel(fp0, gettext("Show color"), show_color_string);
     if (no_option_save) {
 	MaybeSelect(fp0, !can_do_colors, show_color_string);
 	if (LYShowColor == SHOW_COLOR_NEVER) {
@@ -3434,27 +3387,27 @@ PRIVATE int gen_options ARGS1(
 #endif /* USE_SLANG || COLOR_CURSES */
 
     /* Show cursor: ON/OFF */
-    PutLabel(fp0, gettext("Show cursor"));
+    PutLabel(fp0, gettext("Show cursor"), show_cursor_string);
     BeginSelect(fp0, show_cursor_string);
     PutOptValues(fp0, LYShowCursor, bool_values);
     EndSelect(fp0);
 
     /* Select Popups: ON/OFF */
-    PutLabel(fp0, gettext("Popups for select fields"));
+    PutLabel(fp0, gettext("Popups for select fields"), select_popups_string);
     BeginSelect(fp0, select_popups_string);
     PutOptValues(fp0, LYSelectPopups, bool_values);
     EndSelect(fp0);
 
 #ifndef SH_EX  /* 1999/01/19 (Tue) */
     /* HTML error recovery: SELECT */
-    PutLabelNotSaved(fp0, gettext("HTML error recovery"));
+    PutLabel(fp0, gettext("HTML error recovery"), DTD_recovery_string);
     BeginSelect(fp0, DTD_recovery_string);
     PutOptValues(fp0, Old_DTD, DTD_type_values);
     EndSelect(fp0);
 #endif
 
     /* Show Images: SELECT */
-    PutLabelNotSaved(fp0, gettext("Show images"));
+    PutLabel(fp0, gettext("Show images"), will_save_images());
     BeginSelect(fp0, images_string);
     PutOption(fp0, !pseudo_inline_alts && !clickable_images,
 		   images_ignore_all_string,
@@ -3468,7 +3421,7 @@ PRIVATE int gen_options ARGS1(
     EndSelect(fp0);
 
     /* Verbose Images: ON/OFF */
-    PutLabel(fp0, gettext("Verbose images"));
+    PutLabel(fp0, gettext("Verbose images"), verbose_images_string);
     BeginSelect(fp0, verbose_images_string);
     PutOptValues(fp0, verbose_img, verbose_images_type_values);
     EndSelect(fp0);
@@ -3480,23 +3433,23 @@ PRIVATE int gen_options ARGS1(
     /*****************************************************************/
 
     /* Mail Address: INPUT */
-    PutLabel(fp0, gettext("Personal mail address"));
+    PutLabel(fp0, gettext("Personal mail address"), mail_address_string);
     PutTextInput(fp0, mail_address_string,
 		      NOTEMPTY(personal_mail_address), text_len, "");
 
     /* Preferred Document Character Set: INPUT */
-    PutLabel(fp0, gettext("Preferred document character set"));
+    PutLabel(fp0, gettext("Preferred document character set"), preferred_doc_char_string);
     PutTextInput(fp0, preferred_doc_char_string,
 		      NOTEMPTY(pref_charset), cset_len+2, "");
 
     /* Preferred Document Language: INPUT */
-    PutLabel(fp0, gettext("Preferred document language"));
+    PutLabel(fp0, gettext("Preferred document language"), preferred_doc_lang_string);
     PutTextInput(fp0, preferred_doc_lang_string,
 		      NOTEMPTY(language), cset_len+2, "");
 
     /* User Agent: INPUT */
     if (!no_useragent) {
-	PutLabelNotSaved(fp0, gettext("User-Agent header"));
+	PutLabel(fp0, gettext("User-Agent header"), user_agent_string);
 	PutTextInput(fp0, user_agent_string,
 			  NOTEMPTY(LYUserAgent), text_len, "");
     }
@@ -3508,14 +3461,14 @@ PRIVATE int gen_options ARGS1(
     /*****************************************************************/
 
     /* FTP sort: SELECT */
-    PutLabel(fp0, gettext("FTP sort criteria"));
+    PutLabel(fp0, gettext("FTP sort criteria"),	ftp_sort_string);
     BeginSelect(fp0, ftp_sort_string);
     PutOptValues(fp0, HTfileSortMethod, ftp_sort_values);
     EndSelect(fp0);
 
 #ifdef DIRED_SUPPORT
     /* Local Directory Sort: SELECT */
-    PutLabel(fp0, gettext("Local directory sort criteria"));
+    PutLabel(fp0, gettext("Local directory sort criteria"), dired_sort_string);
     BeginSelect(fp0, dired_sort_string);
     PutOptValues(fp0, dir_list_style, dired_values);
     EndSelect(fp0);
@@ -3523,7 +3476,7 @@ PRIVATE int gen_options ARGS1(
 
     /* Show dot files: ON/OFF */
     if (!no_dotfiles) {
-	PutLabel(fp0, gettext("Show dot files"));
+	PutLabel(fp0, gettext("Show dot files"), show_dotfiles_string);
 	BeginSelect(fp0, show_dotfiles_string);
 	PutOptValues(fp0, show_dotfiles, bool_values);
 	EndSelect(fp0);
@@ -3531,7 +3484,7 @@ PRIVATE int gen_options ARGS1(
 
     /* Execution links: SELECT */
 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
-    PutLabel(fp0, gettext("Execution links"));
+    PutLabel(fp0, gettext("Execution links"), exec_links_string);
     BeginSelect(fp0, exec_links_string);
 #ifndef NEVER_ALLOW_REMOTE_EXEC
     PutOptValues(fp0, local_exec
@@ -3551,7 +3504,7 @@ PRIVATE int gen_options ARGS1(
 
 #ifdef EXP_READPROGRESS
     /* Local Directory Sort: SELECT */
-    PutLabel(fp0, gettext("Show transfer rate"));
+    PutLabel(fp0, gettext("Show transfer rate"), show_rate_string);
     BeginSelect(fp0, show_rate_string);
     PutOptValues(fp0, LYTransferRate, rate_values);
     EndSelect(fp0);
@@ -3565,35 +3518,27 @@ PRIVATE int gen_options ARGS1(
 
     /* Multi-Bookmark Mode: SELECT */
     if (!LYMBMBlocked) {
-	PutLabel(fp0, gettext("Multi-bookmarks"));
+	PutLabel(fp0, gettext("Multi-bookmarks"), mbm_string);
 	BeginSelect(fp0, mbm_string);
-	PutOption(fp0, !LYMultiBookmarks,
-		       mbm_off_string,
-		       mbm_off_string);
-	PutOption(fp0, LYMultiBookmarks && !LYMBMAdvanced,
-		       mbm_standard_string,
-		       mbm_standard_string);
-	PutOption(fp0, LYMultiBookmarks && LYMBMAdvanced,
-		       mbm_advanced_string,
-		       mbm_advanced_string);
+	PutOptValues(fp0, LYMultiBookmarks, mbm_values);
 	EndSelect(fp0);
     }
 
     /* Bookmarks File Menu: LINK/INPUT */
     if (LYMultiBookmarks) {
-	PutLabel(fp0, gettext("Review/edit Bookmarks files"));
+	PutLabel(fp0, gettext("Review/edit Bookmarks files"), mbm_string);
 	fprintf(fp0, "<a href=\"LYNXOPTIONS://MBM_MENU\">%s</a>\n",
 		    gettext("Goto multi-bookmark menu"));
     } else {
-	PutLabel(fp0, gettext("Bookmarks file"));
+	PutLabel(fp0, gettext("Bookmarks file"), single_bookmark_string);
 	PutTextInput(fp0, single_bookmark_string,
 			 NOTEMPTY(bookmark_page), text_len, "");
     }
 
     /* Visited Pages: SELECT */
-    PutLabel(fp0, gettext("Visited Pages"));
-    BeginSelect(fp0, visited_pages_type_string);
-    PutOptValues(fp0, Visited_Links_As, visited_pages_type_values);
+    PutLabel(fp0, gettext("Visited Pages"), visited_links_string);
+    BeginSelect(fp0, visited_links_string);
+    PutOptValues(fp0, Visited_Links_As, visited_links_values);
     EndSelect(fp0);
 
     if (!no_lynxcfg_info) {
diff --git a/src/LYOptions.h b/src/LYOptions.h
index ba486999..a606a382 100644
--- a/src/LYOptions.h
+++ b/src/LYOptions.h
@@ -6,6 +6,7 @@
 
 extern BOOLEAN term_options; /* for LYgetstr() */
 
+extern BOOLEAN LYCheckUserAgent NOPARAMS;
 extern void edit_bookmarks NOPARAMS;
 extern  int popup_choice PARAMS((
 	int		cur_choice,
@@ -19,8 +20,6 @@ extern  int popup_choice PARAMS((
 #define LYChoosePopup(cur, line, column, choices, length, disabled, mouse) \
 	popup_choice(cur, line, column, (CONST char **)choices, length, disabled, mouse)
 
-extern int SetupChosenShowColor NOPARAMS;
-
 #ifndef NO_OPTION_FORMS
 extern int postoptions PARAMS((document *newdoc));
 #endif /* !NO_OPTION_FORMS */
diff --git a/src/LYPrint.c b/src/LYPrint.c
index 12bf6605..360330a5 100644
--- a/src/LYPrint.c
+++ b/src/LYPrint.c
@@ -188,7 +188,7 @@ PRIVATE int RecallFilename ARGS5(
 	*total = (sug_filenames ? HTList_count(sug_filenames) : 0);
 	*now = *total;
     }
-    recall = ((*total >= 1) ? RECALL : NORECALL);
+    recall = ((*total >= 1) ? RECALL_URL : NORECALL);
 
     if ((ch = LYgetstr(filename, VISIBLE, LY_MAXPATH, recall)) < 0 ||
 	*filename == '\0' || ch == UPARROW || ch == DNARROW) {
@@ -509,7 +509,7 @@ PRIVATE void send_file_to_mail ARGS3(
 
     _statusline(MAIL_ADDRESS_PROMPT);
     LYstrncpy(user_response, personal_mail_address, sizeof(user_response)-1);
-    if (LYgetstr(user_response, VISIBLE, sizeof(user_response), NORECALL) < 0 ||
+    if (LYgetstr(user_response, VISIBLE, sizeof(user_response), RECALL_MAIL) < 0 ||
 	*user_response == '\0') {
 	CancelPrint(MAIL_REQUEST_CANCELLED);
     }
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index 5ba10be4..6328a52e 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -26,6 +26,7 @@
 #include <HTAlert.h>
 #include <LYHistory.h>
 #include <LYPrettySrc.h>
+#include <LYrcFile.h>
 
 #ifdef DIRED_SUPPORT
 #include <LYLocal.h>
@@ -45,7 +46,7 @@ PUBLIC BOOLEAN LYUseNoviceLineTwo = TRUE;
 /*
  *  Translate a TRUE/FALSE field in a string buffer.
  */
-PRIVATE int is_true ARGS1(
+PRIVATE BOOL is_true ARGS1(
 	char *, string)
 {
     if (!strncasecomp(string,"TRUE",4))
@@ -243,7 +244,7 @@ int default_fg = COLOR_WHITE;
 int default_bg = COLOR_BLACK;
 #endif
 
-static CONST char *Color_Strings[16] =
+PRIVATE CONST char *Color_Strings[16] =
 {
     "black",
     "red",
@@ -394,70 +395,59 @@ PRIVATE void parse_color ARGS1(
 }
 #endif /* USE_COLOR_TABLE */
 
-typedef int (*ParseFunc) PARAMS((char *));
-
-typedef union {
-	lynx_list_item_type ** add_value;
-	BOOLEAN * set_value;
-	int *	  int_value;
-	char **   str_value;
-	ParseFunc fun_value;
-	long	  def_value;
-} ConfigUnion;
-
-#ifdef	PARSE_DEBUG
-#define ParseData \
-	lynx_list_item_type** add_value; \
-	BOOLEAN *set_value; \
-	int *int_value; \
-	char **str_value; \
-	ParseFunc fun_value; \
-	long def_value
-#define PARSE_ADD(n,t,v) {n,t,	 &v,  0,  0,  0,  0,  0}
-#define PARSE_SET(n,t,v) {n,t,	  0,  v,  0,  0,  0,  0}
-#define PARSE_INT(n,t,v) {n,t,	  0,  0,  v,  0,  0,  0}
-#define PARSE_STR(n,t,v) {n,t,	  0,  0,  0,  v,  0,  0}
-#define PARSE_ENV(n,t,v) {n,t,	  0,  0,  0,  v,  0,  0}
-#define PARSE_FUN(n,t,v) {n,t,	  0,  0,  0,  0,  v,  0}
-#define PARSE_DEF(n,t,v) {n,t,	  0,  0,  0,  0,  0,  v}
-#else
-#define ParseData long value
-#define PARSE_ADD(n,t,v) {n,t,	 (long)&(v)}
-#define PARSE_SET(n,t,v) {n,t,	 (long) (v)}
-#define PARSE_INT(n,t,v) {n,t,	 (long) (v)}
-#define PARSE_STR(n,t,v) {n,t,	 (long) (v)}
-#define PARSE_ENV(n,t,v) {n,t,	 (long) (v)}
-#define PARSE_FUN(n,t,v) {n,t,	 (long) (v)}
-#define PARSE_DEF(n,t,v) {n,t,	 (long) (v)}
+#ifdef SOURCE_CACHE
+static Config_Enum tbl_source_cache[] = {
+    { "FILE",	SOURCE_CACHE_FILE },
+    { "MEMORY",	SOURCE_CACHE_MEMORY },
+    { "NONE",	SOURCE_CACHE_NONE },
+    { NULL,		-1 },
+};
+
+static Config_Enum tbl_abort_source_cache[] = {
+    { "KEEP",	SOURCE_CACHE_FOR_ABORTED_KEEP },
+    { "DROP",	SOURCE_CACHE_FOR_ABORTED_DROP },
+    { NULL,		-1 },
+};
 #endif
 
+#define PARSE_ADD(n,v)   {n, CONF_ADD_ITEM,    UNION_ADD(v), 0}
+#define PARSE_SET(n,v)   {n, CONF_BOOL,        UNION_SET(v), 0}
+#define PARSE_ENU(n,v,t) {n, CONF_ENUM,        UNION_INT(v), t}
+#define PARSE_INT(n,v)   {n, CONF_INT,         UNION_INT(v), 0}
+#define PARSE_TIM(n,v)   {n, CONF_TIME,        UNION_INT(v), 0}
+#define PARSE_STR(n,v)   {n, CONF_STR,         UNION_STR(v), 0}
+#define PARSE_Env(n,v)   {n, CONF_ENV,         UNION_ENV(v), 0}
+#define PARSE_ENV(n,v)   {n, CONF_ENV2,        UNION_ENV(v), 0}
+#define PARSE_FUN(n,v)   {n, CONF_FUN,         UNION_FUN(v), 0}
+#define PARSE_REQ(n,v)   {n, CONF_INCLUDE,     UNION_FUN(v), 0}
+#define PARSE_DEF(n,v)   {n, CONF_ADD_TRUSTED, UNION_DEF(v), 0}
+#define PARSE_NIL        {NULL,0,              UNION_DEF(0), 0}
+
+typedef enum {
+    CONF_UNSPECIFIED = 0
+    ,CONF_BOOL			/* BOOLEAN type */
+    ,CONF_FUN
+    ,CONF_TIME
+    ,CONF_ENUM
+    ,CONF_INT
+    ,CONF_STR
+    ,CONF_ENV			/* from environment variable */
+    ,CONF_ENV2			/* from environment VARIABLE */
+    ,CONF_INCLUDE		/* include file-- handle special */
+    ,CONF_ADD_ITEM
+    ,CONF_ADD_TRUSTED
+} Conf_Types;
+
 typedef struct
 {
    CONST char *name;
-   int type;
-#define CONF_UNSPECIFIED	0
-#define CONF_BOOL		1      /* BOOLEAN type */
-#define CONF_FUN		2
-#define CONF_INT		3
-#define CONF_STR		4
-#define CONF_ENV		5      /* from environment variable */
-#define CONF_ENV2		6      /* from environment VARIABLE */
-#define CONF_INCLUDE		7      /* include file-- handle special */
-#define CONF_ADD_ITEM		8
-#define CONF_ADD_TRUSTED	9
-
+   Conf_Types type;
    ParseData;
+   Config_Enum *table;
 }
 Config_Type;
 
-typedef struct
-{
-    CONST char *name;
-    int value;
-}
-Config_Enum;
-
-static BOOLEAN config_enum ARGS3(
+PRIVATE BOOLEAN LYgetEnum ARGS3(
     Config_Enum *,	table,
     CONST char *,	name,
     int *,		result)
@@ -482,7 +472,7 @@ static BOOLEAN config_enum ARGS3(
     return FALSE;		/* no match */
 }
 
-static int assume_charset_fun ARGS1(
+PRIVATE int assume_charset_fun ARGS1(
 	char *,		value)
 {
     UCLYhndl_for_unspec = safeUCGetLYhndl_byMIME(value);
@@ -495,21 +485,21 @@ static int assume_charset_fun ARGS1(
     return 0;
 }
 
-static int assume_local_charset_fun ARGS1(
+PRIVATE int assume_local_charset_fun ARGS1(
 	char *,		value)
 {
     UCLYhndl_HTFile_for_unspec = safeUCGetLYhndl_byMIME(value);
     return 0;
 }
 
-static int assume_unrec_charset_fun ARGS1(
+PRIVATE int assume_unrec_charset_fun ARGS1(
 	char *,		value)
 {
     UCLYhndl_for_unrec = safeUCGetLYhndl_byMIME(value);
     return 0;
 }
 
-static int character_set_fun ARGS1(
+PRIVATE int character_set_fun ARGS1(
 	char *,		value)
 {
     int i = UCGetLYhndl_byAnyName(value); /* by MIME or full name */
@@ -529,7 +519,7 @@ static int character_set_fun ARGS1(
     return 0;
 }
 
-static int outgoing_mail_charset_fun ARGS1(
+PRIVATE int outgoing_mail_charset_fun ARGS1(
 	char *,		value)
 {
     outgoing_mail_charset = UCGetLYhndl_byMIME(value);
@@ -542,7 +532,7 @@ static int outgoing_mail_charset_fun ARGS1(
 /*
  *  Process string buffer fields for ASSUMED_COLOR setting.
  */
-PRIVATE void assumed_color_fun ARGS1(
+PRIVATE int assumed_color_fun ARGS1(
 	char *, buffer)
 {
     char *fg = buffer, *bg;
@@ -574,11 +564,12 @@ PRIVATE void assumed_color_fun ARGS1(
      */
 #endif
     FREE(temp);
+    return 0;
 }
 #endif /* EXP_ASSUMED_COLOR */
 
 #ifdef USE_COLOR_TABLE
-static int color_fun ARGS1(
+PRIVATE int color_fun ARGS1(
 	char *,		value)
 {
     parse_color (value);
@@ -586,17 +577,14 @@ static int color_fun ARGS1(
 }
 #endif
 
-static int default_bookmark_file_fun ARGS1(
+PRIVATE int default_bookmark_file_fun ARGS1(
 	char *,		value)
 {
-    StrAllocCopy(bookmark_page, value);
-    StrAllocCopy(BookmarkPage, bookmark_page);
-    StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
-    StrAllocCopy(MBM_A_subdescript[0], MULTIBOOKMARKS_DEFAULT);
+    set_default_bookmark_page(value);
     return 0;
 }
 
-static int default_cache_size_fun ARGS1(
+PRIVATE int default_cache_size_fun ARGS1(
 	char *,		value)
 {
     HTCacheSize = atoi(value);
@@ -604,28 +592,14 @@ static int default_cache_size_fun ARGS1(
     return 0;
 }
 
-static int default_editor_fun ARGS1(
+PRIVATE int default_editor_fun ARGS1(
 	char *,		value)
 {
     if (!system_editor) StrAllocCopy(editor, value);
     return 0;
 }
 
-static int default_keypad_mode_fun ARGS1(
-	char *,		value)
-{
-   static Config_Enum table[] = {
-	{ "NUMBERS_AS_ARROWS",	NUMBERS_AS_ARROWS },
-	{ "LINKS_ARE_NUMBERED",	LINKS_ARE_NUMBERED },
-	{ "LINKS_AND_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
-	{ "LINKS_AND_FORM_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
-	{ NULL,			-1 }
-   };
-   config_enum(table, value, &keypad_mode );
-   return 0;
-}
-
-static int numbers_as_arrows_fun ARGS1(
+PRIVATE int numbers_as_arrows_fun ARGS1(
 	char *,		value)
 {
     if (is_true(value))
@@ -636,21 +610,8 @@ static int numbers_as_arrows_fun ARGS1(
     return 0;
 }
 
-static int default_user_mode_fun ARGS1(
-	char *,		value)
-{
-    static Config_Enum table[] = {
-    	{ "NOVICE",		NOVICE_MODE },
-	{ "INTERMEDIATE",	INTERMEDIATE_MODE },
-	{ "ADVANCED",		ADVANCED_MODE },
-	{ NULL,			-1 }
-    };
-    config_enum(table, value, &user_mode);
-    return 0;
-}
-
 #ifdef DIRED_SUPPORT
-static int dired_menu_fun ARGS1(
+PRIVATE int dired_menu_fun ARGS1(
 	char *,		value)
 {
     add_menu_item(value);
@@ -658,7 +619,7 @@ static int dired_menu_fun ARGS1(
 }
 #endif
 
-static int jumpfile_fun ARGS1(
+PRIVATE int jumpfile_fun ARGS1(
 	char *,		value)
 {
     char *buffer = NULL;
@@ -672,7 +633,7 @@ static int jumpfile_fun ARGS1(
 }
 
 #ifdef EXP_KEYBOARD_LAYOUT
-static int keyboard_layout_fun ARGS1(
+PRIVATE int keyboard_layout_fun ARGS1(
 	char *,		key)
 {
     if (!LYSetKbLayout(key))
@@ -681,7 +642,7 @@ static int keyboard_layout_fun ARGS1(
 }
 #endif /* EXP_KEYBOARD_LAYOUT */
 
-static int keymap_fun ARGS1(
+PRIVATE int keymap_fun ARGS1(
 	char *,		key)
 {
     char *func, *efunc;
@@ -779,7 +740,7 @@ static int keymap_fun ARGS1(
     return 0;
 }
 
-static int localhost_alias_fun ARGS1(
+PRIVATE int localhost_alias_fun ARGS1(
 	char *,		value)
 {
     LYAddLocalhostAlias(value);
@@ -787,7 +748,7 @@ static int localhost_alias_fun ARGS1(
 }
 
 #ifdef LYNXCGI_LINKS
-static int lynxcgi_environment_fun ARGS1(
+PRIVATE int lynxcgi_environment_fun ARGS1(
 	char *,		value)
 {
     add_lynxcgi_environment(value);
@@ -795,7 +756,7 @@ static int lynxcgi_environment_fun ARGS1(
 }
 #endif
 
-static int lynx_sig_file_fun ARGS1(
+PRIVATE int lynx_sig_file_fun ARGS1(
 	char *,		value)
 {
     char temp[LY_MAXPATH];
@@ -812,7 +773,7 @@ static int lynx_sig_file_fun ARGS1(
 }
 
 #ifndef DISABLE_NEWS
-static int news_chunk_size_fun ARGS1(
+PRIVATE int news_chunk_size_fun ARGS1(
 	char *,		value)
 {
     HTNewsChunkSize = atoi(value);
@@ -825,7 +786,7 @@ static int news_chunk_size_fun ARGS1(
     return 0;
 }
 
-static int news_max_chunk_fun ARGS1(
+PRIVATE int news_max_chunk_fun ARGS1(
 	char *,		value)
 {
     HTNewsMaxChunk = atoi(value);
@@ -838,17 +799,17 @@ static int news_max_chunk_fun ARGS1(
     return 0;
 }
 
-static int news_posting_fun ARGS1(
+PRIVATE int news_posting_fun ARGS1(
 	char *,		value)
 {
-    LYNewsPosting = (BOOL) is_true(value);
+    LYNewsPosting = is_true(value);
     no_newspost = (BOOL) (LYNewsPosting == FALSE);
     return 0;
 }
 #endif /* DISABLE_NEWS */
 
 #ifndef NO_RULES
-static int cern_rulesfile_fun ARGS1(
+PRIVATE int cern_rulesfile_fun ARGS1(
 	char *,		value)
 {
     char *rulesfile1 = NULL;
@@ -882,14 +843,14 @@ static int cern_rulesfile_fun ARGS1(
 }
 #endif /* NO_RULES */
 
-static int printer_fun ARGS1(
+PRIVATE int printer_fun ARGS1(
 	char *,		value)
 {
     add_item_to_list(value, &printers, TRUE);
     return 0;
 }
 
-static int referer_with_query_fun ARGS1(
+PRIVATE int referer_with_query_fun ARGS1(
 	char *,		value)
 {
     if (!strncasecomp(value, "SEND", 4))
@@ -901,34 +862,7 @@ static int referer_with_query_fun ARGS1(
     return 0;
 }
 
-#ifdef SOURCE_CACHE
-static int source_cache_fun ARGS1(
-	char *,		value)
-{
-    static Config_Enum table[] = {
-	{ "FILE",	SOURCE_CACHE_FILE },
-	{ "MEMORY",	SOURCE_CACHE_MEMORY },
-	{ "NONE",	SOURCE_CACHE_NONE },
-	{ NULL,		-1 },
-    };
-    config_enum(table, value, &LYCacheSource);
-    return 0;
-}
-
-static int source_cache_for_aborted_fun ARGS1(
-	char *,		value)
-{
-    static Config_Enum table[] = {
-	{ "KEEP",	SOURCE_CACHE_FOR_ABORTED_KEEP },
-	{ "DROP",	SOURCE_CACHE_FOR_ABORTED_DROP },
-	{ NULL,		-1 },
-    };
-    config_enum(table, value, &LYCacheSourceForAborted);
-    return 0;
-}
-#endif
-
-static int suffix_fun ARGS1(
+PRIVATE int suffix_fun ARGS1(
 	char *,		value)
 {
     char *mime_type, *p;
@@ -1006,7 +940,7 @@ static int suffix_fun ARGS1(
     return 0;
 }
 
-static int suffix_order_fun ARGS1(
+PRIVATE int suffix_order_fun ARGS1(
 	char *,		value)
 {
     char *p = value;
@@ -1034,7 +968,7 @@ static int suffix_order_fun ARGS1(
     return 0;
 }
 
-static int system_editor_fun ARGS1(
+PRIVATE int system_editor_fun ARGS1(
 	char *,		value)
 {
     StrAllocCopy(editor, value);
@@ -1042,26 +976,7 @@ static int system_editor_fun ARGS1(
     return 0;
 }
 
-static int transfer_rate_fun ARGS1(
-	char *,		value)
-{
-    static Config_Enum table[] = {
-	{ "NONE",	rateOFF },
-	{ "KB",		rateKB },
-	{ "TRUE",	rateKB },
-	{ "BYTES",	rateBYTES },
-	{ "FALSE",	rateBYTES },
-#ifdef EXP_READPROGRESS
-	{ "KB,ETA",	rateEtaKB },
-	{ "BYTES,ETA",	rateEtaBYTES },
-#endif
-	{ NULL,		-1 },
-    };
-    config_enum(table, value, &LYTransferRate);
-    return 0;
-}
-
-static int viewer_fun ARGS1(
+PRIVATE int viewer_fun ARGS1(
 	char *,		value)
 {
     char *mime_type;
@@ -1105,13 +1020,13 @@ static int viewer_fun ARGS1(
     return 0;
 }
 
-static int nonrest_sigwinch_fun ARGS1(
+PRIVATE int nonrest_sigwinch_fun ARGS1(
 	char *,		value)
 {
     if (!strncasecomp(value, "XWINDOWS", 8)) {
 	LYNonRestartingSIGWINCH = (BOOL) (LYgetXDisplay() != NULL);
     } else {
-	LYNonRestartingSIGWINCH = (BOOL) is_true(value);
+	LYNonRestartingSIGWINCH = is_true(value);
     }
     return 0;
 }
@@ -1202,7 +1117,7 @@ PRIVATE int parse_assumed_doc_charset_choice ARGS1(char*,p)
 #endif /* EXP_CHARSET_CHOICE */
 
 #ifdef USE_PRETTYSRC
-static void html_src_bad_syntax ARGS2(
+PRIVATE void html_src_bad_syntax ARGS2(
 	    char*, value,
 	    char*, option_name)
 {
@@ -1214,8 +1129,7 @@ static void html_src_bad_syntax ARGS2(
     exit_immediately(EXIT_FAILURE);
 }
 
-
-static int parse_html_src_spec ARGS3(
+PRIVATE int parse_html_src_spec ARGS3(
 	    HTlexeme, lexeme_code,
 	    char*, value,
 	    char*, option_name)
@@ -1277,7 +1191,7 @@ PRIVATE int psrcspec_fun ARGS1(char*,s)
 	return 0;
     }
     *e = '\0';
-    if (!config_enum(lexemnames, s, &found)) {
+    if (!LYgetEnum(lexemnames, s, &found)) {
 	CTRACE((tfp,"bad format of PRETTYSRC_SPEC setting value, ignored %s:%s\n",s,e+1));
 	return 0;
     }
@@ -1285,7 +1199,7 @@ PRIVATE int psrcspec_fun ARGS1(char*,s)
     return 0;
 }
 
-static int read_htmlsrc_attrname_xform ARGS1( char*,str)
+PRIVATE int read_htmlsrc_attrname_xform ARGS1( char*,str)
 {
     int val;
     if ( 1 == sscanf(str, "%d", &val) ) {
@@ -1300,7 +1214,7 @@ static int read_htmlsrc_attrname_xform ARGS1( char*,str)
     return 0;
 }
 
-static int read_htmlsrc_tagname_xform ARGS1( char*,str)
+PRIVATE int read_htmlsrc_tagname_xform ARGS1( char*,str)
 {
     int val;
     if ( 1 == sscanf(str,"%d",&val) ) {
@@ -1317,264 +1231,265 @@ static int read_htmlsrc_tagname_xform ARGS1( char*,str)
 #endif
 
 /* This table is searched ignoring case */
-static Config_Type Config_Table [] =
-{
-     PARSE_SET("accept_all_cookies", CONF_BOOL, &LYAcceptAllCookies),
-     PARSE_INT("alertsecs", CONF_INT, &AlertSecs),
-     PARSE_SET("always_resubmit_posts", CONF_BOOL, &LYresubmit_posts),
+PRIVATE Config_Type Config_Table [] =
+{ 
+     PARSE_SET("accept_all_cookies",   LYAcceptAllCookies),
+     PARSE_TIM("alertsecs",            AlertSecs),
+     PARSE_SET("always_resubmit_posts", LYresubmit_posts),
 #ifdef EXEC_LINKS
-     PARSE_DEF("always_trusted_exec", CONF_ADD_TRUSTED, ALWAYS_EXEC_PATH),
+     PARSE_DEF("always_trusted_exec",  ALWAYS_EXEC_PATH),
 #endif
-     PARSE_FUN("assume_charset", CONF_FUN, assume_charset_fun),
-     PARSE_FUN("assume_local_charset", CONF_FUN, assume_local_charset_fun),
-     PARSE_FUN("assume_unrec_charset", CONF_FUN, assume_unrec_charset_fun),
+     PARSE_FUN("assume_charset",       assume_charset_fun),
+     PARSE_FUN("assume_local_charset", assume_local_charset_fun),
+     PARSE_FUN("assume_unrec_charset", assume_unrec_charset_fun),
 #ifdef EXP_ASSUMED_COLOR
-     PARSE_FUN("assumed_color", CONF_FUN, assumed_color_fun),
+     PARSE_FUN("assumed_color",        assumed_color_fun),
 #endif
 #ifdef EXP_CHARSET_CHOICE
-     PARSE_FUN("assumed_doc_charset_choice",CONF_FUN,parse_assumed_doc_charset_choice),
+     PARSE_FUN("assumed_doc_charset_choice", parse_assumed_doc_charset_choice),
 #endif
 #ifdef DIRED_SUPPORT
-     PARSE_ENV("auto_uncache_dirlists", CONF_INT, &LYAutoUncacheDirLists),
+     PARSE_INT("auto_uncache_dirlists", LYAutoUncacheDirLists),
 #endif
 #ifndef DISABLE_BIBP
-     PARSE_STR("bibp_bibhost", CONF_STR, &BibP_bibhost),
-     PARSE_STR("bibp_globalserver", CONF_STR, &BibP_globalserver),
-#endif
-     PARSE_SET("block_multi_bookmarks", CONF_BOOL, &LYMBMBlocked),
-     PARSE_SET("bold_h1", CONF_BOOL, &bold_H1),
-     PARSE_SET("bold_headers", CONF_BOOL, &bold_headers),
-     PARSE_SET("bold_name_anchors", CONF_BOOL, &bold_name_anchors),
-     PARSE_SET("case_sensitive_always_on", CONF_BOOL, &case_sensitive),
-     PARSE_FUN("character_set", CONF_FUN, character_set_fun),
+     PARSE_STR("bibp_bibhost",         BibP_bibhost),
+     PARSE_STR("bibp_globalserver",    BibP_globalserver),
+#endif
+     PARSE_SET("block_multi_bookmarks", LYMBMBlocked),
+     PARSE_SET("bold_h1",              bold_H1),
+     PARSE_SET("bold_headers",         bold_headers),
+     PARSE_SET("bold_name_anchors",    bold_name_anchors),
+     PARSE_SET("case_sensitive_always_on", case_sensitive),
+     PARSE_FUN("character_set",        character_set_fun),
 #ifdef CAN_SWITCH_DISPLAY_CHARSET
-     PARSE_SET("charset_switch_rules", CONF_STR, &charset_switch_rules),
-     PARSE_SET("charsets_directory", CONF_STR, &charsets_directory),
+     PARSE_SET("charset_switch_rules", charset_switch_rules),
+     PARSE_SET("charsets_directory",   charsets_directory),
 #endif
-     PARSE_SET("checkmail", CONF_BOOL, &check_mail),
-     PARSE_SET("collapse_br_tags", CONF_BOOL, &LYCollapseBRs),
+     PARSE_SET("checkmail",            check_mail),
+     PARSE_SET("collapse_br_tags",     LYCollapseBRs),
 #ifdef USE_COLOR_TABLE
-     PARSE_FUN("color", CONF_FUN, color_fun),
+     PARSE_FUN("color",                color_fun),
 #endif
 #ifndef __DJGPP__
-     PARSE_INT("connect_timeout",CONF_INT,&connect_timeout),
+     PARSE_INT("connect_timeout",      connect_timeout),
 #endif
-     PARSE_STR("cookie_accept_domains", CONF_STR, &LYCookieSAcceptDomains),
+     PARSE_STR("cookie_accept_domains", LYCookieSAcceptDomains),
 #ifdef EXP_PERSISTENT_COOKIES
-     PARSE_STR("cookie_file", CONF_STR, &LYCookieFile),
-     PARSE_STR("cookie_save_file", CONF_STR, &LYCookieSaveFile),
+     PARSE_STR("cookie_file",          LYCookieFile),
+     PARSE_STR("cookie_save_file",     LYCookieSaveFile),
 #endif /* EXP_PERSISTENT_COOKIES */
-     PARSE_STR("cookie_loose_invalid_domains", CONF_STR, &LYCookieSLooseCheckDomains),
-     PARSE_STR("cookie_query_invalid_domains", CONF_STR, &LYCookieSQueryCheckDomains),
-     PARSE_STR("cookie_reject_domains", CONF_STR, &LYCookieSRejectDomains),
-     PARSE_STR("cookie_strict_invalid_domains", CONF_STR, &LYCookieSStrictCheckDomains),
-     PARSE_ENV("cso_proxy", CONF_ENV, 0 ),
+     PARSE_STR("cookie_loose_invalid_domains", LYCookieSLooseCheckDomains),
+     PARSE_STR("cookie_query_invalid_domains", LYCookieSQueryCheckDomains),
+     PARSE_STR("cookie_reject_domains", LYCookieSRejectDomains),
+     PARSE_STR("cookie_strict_invalid_domains", LYCookieSStrictCheckDomains),
+     PARSE_Env("cso_proxy", 0 ),
 #ifdef VMS
-     PARSE_STR("CSWING_PATH", CONF_STR, &LYCSwingPath),
-#endif
-     PARSE_FUN("default_bookmark_file", CONF_FUN, default_bookmark_file_fun),
-     PARSE_FUN("default_cache_size", CONF_FUN, default_cache_size_fun),
-     PARSE_FUN("default_editor", CONF_FUN, default_editor_fun),
-     PARSE_STR("default_index_file", CONF_STR, &indexfile),
-     PARSE_FUN("default_keypad_mode", CONF_FUN, default_keypad_mode_fun),
-     PARSE_FUN("default_keypad_mode_is_numbers_as_arrows", CONF_FUN, numbers_as_arrows_fun),
-     PARSE_FUN("default_user_mode", CONF_FUN, default_user_mode_fun),
+     PARSE_STR("CSWING_PATH", LYCSwingPath),
+#endif
+     PARSE_FUN("default_bookmark_file", default_bookmark_file_fun),
+     PARSE_FUN("default_cache_size",   default_cache_size_fun),
+     PARSE_FUN("default_editor",       default_editor_fun),
+     PARSE_STR("default_index_file",   indexfile),
+     PARSE_ENU("default_keypad_mode",  keypad_mode, tbl_keypad_mode),
+     PARSE_FUN("default_keypad_mode_is_numbers_as_arrows", numbers_as_arrows_fun),
+     PARSE_ENU("default_user_mode",    user_mode, tbl_user_mode),
 #if defined(VMS) && defined(VAXC) && !defined(__DECC)
-     PARSE_INT("default_virtual_memory_size", CONF_INT, &HTVirtualMemorySize),
+     PARSE_INT("default_virtual_memory_size", HTVirtualMemorySize),
 #endif
 #ifdef DIRED_SUPPORT
-     PARSE_FUN("dired_menu", CONF_FUN, dired_menu_fun),
+     PARSE_FUN("dired_menu",           dired_menu_fun),
 #endif
 #ifdef EXP_CHARSET_CHOICE
-     PARSE_FUN("display_charset_choice",CONF_FUN,parse_display_charset_choice),
+     PARSE_FUN("display_charset_choice", parse_display_charset_choice),
 #endif
-     PARSE_ADD("downloader", CONF_ADD_ITEM, downloaders),
-     PARSE_SET("emacs_keys_always_on", CONF_BOOL, &emacs_keys),
-     PARSE_SET("enable_scrollback", CONF_BOOL, &enable_scrollback),
+     PARSE_ADD("downloader",           downloaders),
+     PARSE_SET("emacs_keys_always_on", emacs_keys),
+     PARSE_FUN("enable_lynxrc",        enable_lynxrc),
+     PARSE_SET("enable_scrollback",    enable_scrollback),
 #ifdef USE_EXTERNALS
-     PARSE_ADD("external", CONF_ADD_ITEM, externals),
+     PARSE_ADD("external",             externals),
 #endif
-     PARSE_ENV("finger_proxy", CONF_ENV, 0 ),
+     PARSE_Env("finger_proxy",         0 ),
 #if defined(_WINDOWS)	/* 1998/10/05 (Mon) 17:34:15 */
-     PARSE_SET("focus_window", CONF_BOOL, &focus_window),
+     PARSE_SET("focus_window",         focus_window),
 #endif
-     PARSE_SET("force_8bit_toupper", CONF_BOOL, &UCForce8bitTOUPPER),
-     PARSE_SET("force_empty_hrefless_a", CONF_BOOL, &force_empty_hrefless_a),
-     PARSE_SET("force_ssl_cookies_secure", CONF_BOOL, &LYForceSSLCookiesSecure),
+     PARSE_SET("force_8bit_toupper",   UCForce8bitTOUPPER),
+     PARSE_SET("force_empty_hrefless_a", force_empty_hrefless_a),
+     PARSE_SET("force_ssl_cookies_secure", LYForceSSLCookiesSecure),
 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
-     PARSE_SET("forms_options", CONF_BOOL, &LYUseFormsOptions),
-#endif
-     PARSE_SET("ftp_passive", CONF_BOOL, &ftp_passive),
-     PARSE_ENV("ftp_proxy", CONF_ENV, 0 ),
-     PARSE_STR("global_extension_map", CONF_STR, &global_extension_map),
-     PARSE_STR("global_mailcap", CONF_STR, &global_type_map),
-     PARSE_ENV("gopher_proxy", CONF_ENV, 0 ),
-     PARSE_SET("gotobuffer", CONF_BOOL, &goto_buffer),
-     PARSE_STR("helpfile", CONF_STR, &helpfile),
+     PARSE_SET("forms_options",        LYUseFormsOptions),
+#endif
+     PARSE_SET("ftp_passive",          ftp_passive),
+     PARSE_Env("ftp_proxy",            0 ),
+     PARSE_STR("global_extension_map", global_extension_map),
+     PARSE_STR("global_mailcap",       global_type_map),
+     PARSE_Env("gopher_proxy",         0 ),
+     PARSE_SET("gotobuffer",           goto_buffer),
+     PARSE_STR("helpfile",             helpfile),
 #ifdef MARK_HIDDEN_LINKS
-     PARSE_STR("hidden_link_marker", CONF_STR, &hidden_link_marker),
+     PARSE_STR("hidden_link_marker",   hidden_link_marker),
 #endif
-     PARSE_SET("historical_comments", CONF_BOOL, &historical_comments),
+     PARSE_SET("historical_comments",  historical_comments),
 #ifdef USE_PRETTYSRC
-     PARSE_FUN("htmlsrc_attrname_xform", CONF_FUN, read_htmlsrc_attrname_xform),
-     PARSE_FUN("htmlsrc_tagname_xform", CONF_FUN, read_htmlsrc_tagname_xform),
-#endif
-     PARSE_ENV("http_proxy", CONF_ENV, 0 ),
-     PARSE_ENV("https_proxy", CONF_ENV, 0 ),
-     PARSE_FUN("include", CONF_INCLUDE, 0),
-     PARSE_INT("infosecs", CONF_INT, &InfoSecs),
-     PARSE_STR("jump_prompt", CONF_STR, &jumpprompt),
-     PARSE_SET("jumpbuffer", CONF_BOOL, &jump_buffer),
-     PARSE_FUN("jumpfile", CONF_FUN, jumpfile_fun),
+     PARSE_FUN("htmlsrc_attrname_xform", read_htmlsrc_attrname_xform),
+     PARSE_FUN("htmlsrc_tagname_xform", read_htmlsrc_tagname_xform),
+#endif
+     PARSE_Env("http_proxy",           0 ),
+     PARSE_Env("https_proxy",          0 ),
+     PARSE_REQ("include",              0),
+     PARSE_TIM("infosecs",             InfoSecs),
+     PARSE_STR("jump_prompt",          jumpprompt),
+     PARSE_SET("jumpbuffer",           jump_buffer),
+     PARSE_FUN("jumpfile",             jumpfile_fun),
 #ifdef EXP_JUSTIFY_ELTS
-     PARSE_SET("justify", CONF_BOOL, &ok_justify),
-     PARSE_SET("justify_max_void_percent", CONF_INT, &justify_max_void_percent),
+     PARSE_SET("justify",              ok_justify),
+     PARSE_INT("justify_max_void_percent", justify_max_void_percent),
 #endif
 #ifdef EXP_KEYBOARD_LAYOUT
-     PARSE_FUN("keyboard_layout", CONF_FUN, keyboard_layout_fun),
+     PARSE_FUN("keyboard_layout",      keyboard_layout_fun),
 #endif
-     PARSE_FUN("keymap", CONF_FUN, keymap_fun),
-     PARSE_SET("leftarrow_in_textfield_prompt", CONF_BOOL, &textfield_prompt_at_left_edge),
+     PARSE_FUN("keymap",               keymap_fun),
+     PARSE_SET("leftarrow_in_textfield_prompt", textfield_prompt_at_left_edge),
 #ifndef DISABLE_NEWS
-     PARSE_SET("list_news_numbers", CONF_BOOL, &LYListNewsNumbers),
-     PARSE_SET("list_news_dates", CONF_BOOL, &LYListNewsDates),
+     PARSE_SET("list_news_numbers",    LYListNewsNumbers),
+     PARSE_SET("list_news_dates",      LYListNewsDates),
 #endif
 #ifndef VMS
-     PARSE_STR("list_format", CONF_STR, &list_format),
+     PARSE_STR("list_format",          list_format),
 #endif
-     PARSE_FUN("localhost_alias", CONF_FUN, localhost_alias_fun),
-     PARSE_STR("local_domain", CONF_STR, &LYLocalDomain),
+     PARSE_FUN("localhost_alias",      localhost_alias_fun),
+     PARSE_STR("local_domain",         LYLocalDomain),
 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
-     PARSE_SET("local_execution_links_always_on", CONF_BOOL, &local_exec),
-     PARSE_SET("local_execution_links_on_but_not_remote", CONF_BOOL, &local_exec_on_local_files),
+     PARSE_SET("local_execution_links_always_on", local_exec),
+     PARSE_SET("local_execution_links_on_but_not_remote", local_exec_on_local_files),
 #endif
 #ifdef LYNXCGI_LINKS
-     PARSE_FUN("lynxcgi_environment", CONF_FUN, lynxcgi_environment_fun),
+     PARSE_FUN("lynxcgi_environment",  lynxcgi_environment_fun),
 #ifndef VMS
-     PARSE_STR("lynxcgi_document_root", CONF_STR, &LYCgiDocumentRoot),
+     PARSE_STR("lynxcgi_document_root", LYCgiDocumentRoot),
 #endif
 #endif
-     PARSE_STR("lynx_host_name", CONF_STR, &LYHostName),
-     PARSE_FUN("lynx_sig_file", CONF_FUN, lynx_sig_file_fun),
-     PARSE_SET("mail_system_error_logging", CONF_BOOL, &error_logging),
+     PARSE_STR("lynx_host_name",       LYHostName),
+     PARSE_FUN("lynx_sig_file",        lynx_sig_file_fun),
+     PARSE_SET("mail_system_error_logging", error_logging),
 #if USE_VMS_MAILER
-     PARSE_STR("mail_adrs", CONF_STR, &mail_adrs),
-#endif
-     PARSE_SET("make_links_for_all_images", CONF_BOOL, &clickable_images),
-     PARSE_SET("make_pseudo_alts_for_inlines", CONF_BOOL, &pseudo_inline_alts),
-     PARSE_INT("messagesecs", CONF_INT, &MessageSecs),
-     PARSE_SET("minimal_comments", CONF_BOOL, &minimal_comments),
-     PARSE_INT("multi_bookmark_support", CONF_BOOL, &LYMultiBookmarks),
-     PARSE_SET("ncr_in_bookmarks", CONF_BOOL, &UCSaveBookmarksInUnicode),
+     PARSE_STR("mail_adrs",            mail_adrs),
+#endif
+     PARSE_SET("make_links_for_all_images", clickable_images),
+     PARSE_SET("make_pseudo_alts_for_inlines", pseudo_inline_alts),
+     PARSE_TIM("messagesecs",          MessageSecs),
+     PARSE_SET("minimal_comments",     minimal_comments),
+     PARSE_ENU("multi_bookmark_support", LYMultiBookmarks, tbl_multi_bookmarks),
+     PARSE_SET("ncr_in_bookmarks",     UCSaveBookmarksInUnicode),
 #ifndef DISABLE_NEWS
-     PARSE_FUN("news_chunk_size", CONF_FUN, news_chunk_size_fun),
-     PARSE_FUN("news_max_chunk", CONF_FUN, news_max_chunk_fun),
-     PARSE_FUN("news_posting", CONF_FUN, news_posting_fun),
-     PARSE_ENV("news_proxy", CONF_ENV, 0),
-     PARSE_ENV("newspost_proxy", CONF_ENV, 0),
-     PARSE_ENV("newsreply_proxy", CONF_ENV, 0),
-     PARSE_ENV("nntp_proxy", CONF_ENV, 0),
-     PARSE_ENV("nntpserver", CONF_ENV2, 0), /* actually NNTPSERVER */
+     PARSE_FUN("news_chunk_size",      news_chunk_size_fun),
+     PARSE_FUN("news_max_chunk",       news_max_chunk_fun),
+     PARSE_FUN("news_posting",         news_posting_fun),
+     PARSE_Env("news_proxy",           0),
+     PARSE_Env("newspost_proxy",       0),
+     PARSE_Env("newsreply_proxy",      0),
+     PARSE_Env("nntp_proxy",           0),
+     PARSE_ENV("nntpserver",           0), /* actually NNTPSERVER */
 #endif
 #ifdef SH_EX
-     PARSE_SET("no_table_center", CONF_BOOL, &no_table_center),
+     PARSE_SET("no_table_center",      no_table_center),
 #endif
-     PARSE_SET("no_dot_files", CONF_BOOL, &no_dotfiles),
-     PARSE_SET("no_file_referer", CONF_BOOL, &no_filereferer),
+     PARSE_SET("no_dot_files",         no_dotfiles),
+     PARSE_SET("no_file_referer",      no_filereferer),
 #ifndef VMS
-     PARSE_SET("no_forced_core_dump", CONF_BOOL, &LYNoCore),
-#endif
-     PARSE_SET("no_from_header", CONF_BOOL, &LYNoFromHeader),
-     PARSE_SET("no_ismap_if_usemap", CONF_BOOL, &LYNoISMAPifUSEMAP),
-     PARSE_ENV("no_proxy", CONF_ENV, 0 ),
-     PARSE_SET("no_referer_header", CONF_BOOL, &LYNoRefererHeader),
-     PARSE_SET("nonrestarting_sigwinch", CONF_FUN, nonrest_sigwinch_fun),
-     PARSE_FUN("outgoing_mail_charset", CONF_FUN, outgoing_mail_charset_fun),
+     PARSE_SET("no_forced_core_dump",  LYNoCore),
+#endif
+     PARSE_SET("no_from_header",       LYNoFromHeader),
+     PARSE_SET("no_ismap_if_usemap",   LYNoISMAPifUSEMAP),
+     PARSE_Env("no_proxy",             0 ),
+     PARSE_SET("no_referer_header",    LYNoRefererHeader),
+     PARSE_FUN("nonrestarting_sigwinch", nonrest_sigwinch_fun),
+     PARSE_FUN("outgoing_mail_charset", outgoing_mail_charset_fun),
 #ifdef DISP_PARTIAL
-     PARSE_SET("partial", CONF_BOOL, &display_partial_flag),
-     PARSE_INT("partial_thres", CONF_INT, &partial_threshold),
+     PARSE_SET("partial",              display_partial_flag),
+     PARSE_INT("partial_thres",        partial_threshold),
 #endif
 #ifdef EXP_PERSISTENT_COOKIES
-     PARSE_SET("persistent_cookies", CONF_BOOL, &persistent_cookies),
+     PARSE_SET("persistent_cookies",   persistent_cookies),
 #endif /* EXP_PERSISTENT_COOKIES */
-     PARSE_STR("personal_mailcap", CONF_STR, &personal_type_map),
-     PARSE_STR("personal_extension_map", CONF_STR, &personal_extension_map),
-     PARSE_STR("preferred_charset", CONF_STR, &pref_charset),
-     PARSE_STR("preferred_language", CONF_STR, &language),
-     PARSE_SET("prepend_base_to_source", CONF_BOOL, &LYPrependBaseToSource),
-     PARSE_SET("prepend_charset_to_source", CONF_BOOL, &LYPrependCharsetToSource),
+     PARSE_STR("personal_mailcap",     personal_type_map),
+     PARSE_STR("personal_extension_map", personal_extension_map),
+     PARSE_STR("preferred_charset",    pref_charset),
+     PARSE_STR("preferred_language",   language),
+     PARSE_SET("prepend_base_to_source", LYPrependBaseToSource),
+     PARSE_SET("prepend_charset_to_source", LYPrependCharsetToSource),
 #ifdef USE_PRETTYSRC
-     PARSE_SET("prettysrc", CONF_BOOL, &LYpsrc),
-     PARSE_FUN("prettysrc_spec", CONF_FUN, psrcspec_fun),
-     PARSE_SET("prettysrc_view_no_anchor_numbering", CONF_BOOL, &psrcview_no_anchor_numbering),
-#endif
-     PARSE_FUN("printer", CONF_FUN, printer_fun),
-     PARSE_SET("quit_default_yes", CONF_BOOL, &LYQuitDefaultYes),
-     PARSE_SET("referer_with_query", CONF_FUN, referer_with_query_fun),
-     PARSE_SET("reuse_tempfiles", CONF_BOOL, &LYReuseTempfiles),
+     PARSE_SET("prettysrc",            LYpsrc),
+     PARSE_FUN("prettysrc_spec",       psrcspec_fun),
+     PARSE_SET("prettysrc_view_no_anchor_numbering", psrcview_no_anchor_numbering),
+#endif
+     PARSE_FUN("printer",              printer_fun),
+     PARSE_SET("quit_default_yes",     LYQuitDefaultYes),
+     PARSE_FUN("referer_with_query",   referer_with_query_fun),
+     PARSE_SET("reuse_tempfiles",      LYReuseTempfiles),
 #ifndef NO_RULES
-     PARSE_FUN("rule", CONF_FUN, HTSetConfiguration),
-     PARSE_FUN("rulesfile", CONF_FUN, cern_rulesfile_fun),
+     PARSE_FUN("rule",                 HTSetConfiguration),
+     PARSE_FUN("rulesfile",            cern_rulesfile_fun),
 #endif /* NO_RULES */
-     PARSE_STR("save_space", CONF_STR, &lynx_save_space),
-     PARSE_SET("scan_for_buried_news_refs", CONF_BOOL, &scan_for_buried_news_references),
+     PARSE_STR("save_space",           lynx_save_space),
+     PARSE_SET("scan_for_buried_news_refs", scan_for_buried_news_references),
 #ifdef USE_SCROLLBAR
-     PARSE_SET("scrollbar", CONF_BOOL, &LYsb),
-     PARSE_SET("scrollbar_arrow", CONF_BOOL, &LYsb_arrow),
-#endif
-     PARSE_SET("seek_frag_area_in_cur", CONF_BOOL, &LYSeekFragAREAinCur),
-     PARSE_SET("seek_frag_map_in_cur", CONF_BOOL, &LYSeekFragMAPinCur),
-     PARSE_SET("set_cookies", CONF_BOOL, &LYSetCookies),
-     PARSE_SET("show_cursor", CONF_BOOL, &LYShowCursor),
-     PARSE_SET("show_kb_rate", CONF_FUN, transfer_rate_fun),
-     PARSE_ENV("snews_proxy", CONF_ENV, 0 ),
-     PARSE_ENV("snewspost_proxy", CONF_ENV, 0 ),
-     PARSE_ENV("snewsreply_proxy", CONF_ENV, 0 ),
-     PARSE_SET("soft_dquotes", CONF_BOOL, &soft_dquotes),
+     PARSE_SET("scrollbar",            LYsb),
+     PARSE_SET("scrollbar_arrow",      LYsb_arrow),
+#endif
+     PARSE_SET("seek_frag_area_in_cur", LYSeekFragAREAinCur),
+     PARSE_SET("seek_frag_map_in_cur", LYSeekFragMAPinCur),
+     PARSE_SET("set_cookies",          LYSetCookies),
+     PARSE_SET("show_cursor",          LYShowCursor),
+     PARSE_ENU("show_kb_rate",         LYTransferRate, tbl_transfer_rate),
+     PARSE_Env("snews_proxy",          0 ),
+     PARSE_Env("snewspost_proxy",      0 ),
+     PARSE_Env("snewsreply_proxy",     0 ),
+     PARSE_SET("soft_dquotes",         soft_dquotes),
 #ifdef SOURCE_CACHE
-     PARSE_SET("source_cache", CONF_FUN, source_cache_fun),
-     PARSE_SET("source_cache_for_aborted",CONF_FUN, source_cache_for_aborted_fun),
-#endif
-     PARSE_STR("startfile", CONF_STR, &startfile),
-     PARSE_SET("strip_dotdot_urls", CONF_BOOL, &LYStripDotDotURLs),
-     PARSE_SET("substitute_underscores", CONF_BOOL, &use_underscore),
-     PARSE_FUN("suffix", CONF_FUN, suffix_fun),
-     PARSE_FUN("suffix_order", CONF_FUN, suffix_order_fun),
-     PARSE_FUN("system_editor", CONF_FUN, system_editor_fun),
-     PARSE_STR("system_mail", CONF_STR, &system_mail),
-     PARSE_STR("system_mail_flags", CONF_STR, &system_mail_flags),
-     PARSE_SET("tagsoup", CONF_BOOL, &Old_DTD),
+     PARSE_ENU("source_cache",         LYCacheSource, tbl_source_cache),
+     PARSE_ENU("source_cache_for_aborted", LYCacheSourceForAborted, tbl_abort_source_cache),
+#endif
+     PARSE_STR("startfile",            startfile),
+     PARSE_SET("strip_dotdot_urls",    LYStripDotDotURLs),
+     PARSE_SET("substitute_underscores", use_underscore),
+     PARSE_FUN("suffix",               suffix_fun),
+     PARSE_FUN("suffix_order",         suffix_order_fun),
+     PARSE_FUN("system_editor",        system_editor_fun),
+     PARSE_STR("system_mail",          system_mail),
+     PARSE_STR("system_mail_flags",    system_mail_flags),
+     PARSE_ENU("tagsoup",              Old_DTD, tbl_DTD_recovery),
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
-     PARSE_SET("textfields_need_activation", CONF_BOOL, &global_textfields_need_activation),
+     PARSE_SET("textfields_need_activation", textfields_activation_option),
 #endif
 #if defined(_WINDOWS)
-     PARSE_INT("timeout", CONF_INT, &lynx_timeout),
+     PARSE_INT("timeout",              lynx_timeout),
 #endif
 #ifdef EXEC_LINKS
-     PARSE_DEF("trusted_exec", CONF_ADD_TRUSTED, EXEC_PATH),
+     PARSE_DEF("trusted_exec",         EXEC_PATH),
 #endif
 #ifdef LYNXCGI_LINKS
-     PARSE_DEF("trusted_lynxcgi", CONF_ADD_TRUSTED, CGI_PATH),
+     PARSE_DEF("trusted_lynxcgi",      CGI_PATH),
 #endif
-     PARSE_STR("url_domain_prefixes", CONF_STR, &URLDomainPrefixes),
-     PARSE_STR("url_domain_suffixes", CONF_STR, &URLDomainSuffixes),
+     PARSE_STR("url_domain_prefixes",  URLDomainPrefixes),
+     PARSE_STR("url_domain_suffixes",  URLDomainSuffixes),
 #ifdef DIRED_SUPPORT
-     PARSE_ADD("uploader", CONF_ADD_ITEM, uploaders),
+     PARSE_ADD("uploader",             uploaders),
 #endif
 #ifdef VMS
-     PARSE_SET("use_fixed_records", CONF_BOOL, &UseFixedRecords),
+     PARSE_SET("use_fixed_records",    UseFixedRecords),
 #endif
 #if defined(USE_MOUSE)
-     PARSE_SET("use_mouse", CONF_BOOL, &LYUseMouse),
+     PARSE_SET("use_mouse",            LYUseMouse),
 #endif
-     PARSE_SET("use_select_popups", CONF_BOOL, &LYSelectPopups),
-     PARSE_SET("verbose_images", CONF_BOOL, &verbose_img),
-     PARSE_SET("vi_keys_always_on", CONF_BOOL, &vi_keys),
-     PARSE_FUN("viewer", CONF_FUN, viewer_fun),
-     PARSE_ENV("wais_proxy", CONF_ENV, 0 ),
-     PARSE_STR("xloadimage_command", CONF_STR, &XLoadImageCommand),
+     PARSE_SET("use_select_popups",    LYSelectPopups),
+     PARSE_SET("verbose_images",       verbose_img),
+     PARSE_SET("vi_keys_always_on",    vi_keys),
+     PARSE_FUN("viewer",               viewer_fun),
+     PARSE_Env("wais_proxy",           0 ),
+     PARSE_STR("xloadimage_command",   XLoadImageCommand),
 
-     {0, 0, 0}
+     PARSE_NIL
 };
 
 PRIVATE char *lynxcfginfo_url = NULL;	/* static */
@@ -1590,11 +1505,8 @@ PUBLIC void free_lynx_cfg NOARGS
     Config_Type *tbl;
 
     for (tbl = Config_Table; tbl->name != 0; tbl++) {
-#ifdef PARSE_DEBUG
-	Config_Type *q = tbl;
-#else
-	ConfigUnion *q = (ConfigUnion *)(&(tbl->value));
-#endif
+	ParseUnionPtr q = ParseUnionOf(tbl);
+
 	switch (tbl->type) {
 	case CONF_ENV:
 	    if (q->str_value != 0) {
@@ -1776,11 +1688,7 @@ PRIVATE void do_read_cfg ARGS5(
 	char *name, *value;
 	char *cp;
 	Config_Type *tbl;
-#ifdef PARSE_DEBUG
-	Config_Type *q;
-#else
-	ConfigUnion *q;
-#endif
+	ParseUnionPtr q;
 
 	/* Most lines in the config file are comment lines.  Weed them out
 	 * now.  Also, leading whitespace is ok, so trim it.
@@ -1839,17 +1747,13 @@ PRIVATE void do_read_cfg ARGS5(
 	    continue;
 	}
 
-#ifdef PARSE_DEBUG
-	q = tbl;
-#else
-	q = (ConfigUnion *)(&(tbl->value));
-#endif
+	q = ParseUnionOf(tbl);
 	switch ((fp0 != 0 && tbl->type != CONF_INCLUDE)
 		? CONF_UNSPECIFIED
 		: tbl->type) {
 	case CONF_BOOL:
 	    if (q->set_value != 0)
-		*(q->set_value) = (BOOL) is_true (value);
+		*(q->set_value) = is_true (value);
 	    break;
 
 	case CONF_FUN:
@@ -1857,13 +1761,26 @@ PRIVATE void do_read_cfg ARGS5(
 		(*(q->fun_value)) (value);
 	    break;
 
+	case CONF_TIME:
+	    if (q->int_value != 0) {
+		float ival;
+		if (1 == sscanf (value, "%f", &ival)) {
+#ifdef HAVE_NAPMS
+		    ival *= 1000;
+#endif
+		    *(q->int_value) = (int) ival;
+		}
+	    }
+	    break;
+
+	case CONF_ENUM:
+	    if (tbl->table != 0)
+		LYgetEnum(tbl->table, value, q->int_value);
+	    break;
+
 	case CONF_INT:
 	    if (q->int_value != 0) {
 		int ival;
-		/* Apparently, if an integer value is not present, then the
-		 * value is not changed.  So, use the sscanf function to make
-		 * this determination.
-		 */
 		if (1 == sscanf (value, "%d", &ival))
 		    *(q->int_value) = ival;
 	    }
@@ -2057,53 +1974,9 @@ PRIVATE void do_read_cfg ARGS5(
      *
      * And for query/strict/loose invalid cookie checking. - BJP
      */
-
-    if (LYCookieSAcceptDomains != NULL) {
-	cookie_domain_flag_set(LYCookieSAcceptDomains, FLAG_ACCEPT_ALWAYS);
-	FREE(LYCookieSAcceptDomains);
-    }
-
-    if (LYCookieSRejectDomains != NULL) {
-	cookie_domain_flag_set(LYCookieSRejectDomains, FLAG_REJECT_ALWAYS);
-	FREE(LYCookieSRejectDomains);
-    }
-
-    if (LYCookieSStrictCheckDomains != NULL) {
-	cookie_domain_flag_set(LYCookieSStrictCheckDomains, FLAG_INVCHECK_STRICT);
-	FREE(LYCookieSStrictCheckDomains);
-    }
-
-    if (LYCookieSLooseCheckDomains != NULL) {
-	cookie_domain_flag_set(LYCookieSLooseCheckDomains, FLAG_INVCHECK_LOOSE);
-	FREE(LYCookieSLooseCheckDomains);
-    }
-
-    if (LYCookieSQueryCheckDomains != NULL) {
-	cookie_domain_flag_set(LYCookieSQueryCheckDomains, FLAG_INVCHECK_QUERY);
-	FREE(LYCookieSQueryCheckDomains);
-    }
-
-    if (LYCookieAcceptDomains != NULL) {
-	cookie_domain_flag_set(LYCookieAcceptDomains, FLAG_ACCEPT_ALWAYS);
-    }
-
-    if (LYCookieRejectDomains != NULL) {
-	cookie_domain_flag_set(LYCookieRejectDomains, FLAG_REJECT_ALWAYS);
-    }
-
-    if (LYCookieStrictCheckDomains != NULL) {
-	cookie_domain_flag_set(LYCookieStrictCheckDomains, FLAG_INVCHECK_STRICT);
-    }
-
-    if (LYCookieLooseCheckDomains != NULL) {
-	cookie_domain_flag_set(LYCookieLooseCheckDomains, FLAG_INVCHECK_LOOSE);
-    }
-
-    if (LYCookieQueryCheckDomains != NULL) {
-	cookie_domain_flag_set(LYCookieQueryCheckDomains, FLAG_INVCHECK_QUERY);
-    }
-
+    LYConfigCookies();
 }
+
 /* this is a public interface to do_read_cfg */
 PUBLIC void read_cfg ARGS4(
 	char *, cfg_filename,
@@ -2111,8 +1984,7 @@ PUBLIC void read_cfg ARGS4(
 	int,	nesting_level,
 	FILE *,	fp0)
 {
-    do_read_cfg(cfg_filename,parent_filename,nesting_level,fp0,
-	NULL);
+    do_read_cfg(cfg_filename, parent_filename, nesting_level, fp0, NULL);
 }
 
 
@@ -2262,14 +2134,14 @@ PUBLIC int lynx_cfg_infopage ARGS1(
 	    }
 
 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
-    if (!no_compileopts_info) {
-	fprintf(fp0, "%s <a href=\"LYNXCOMPILEOPTS:\">%s</a>\n\n",
-		SEE_ALSO,
-		COMPILE_OPT_SEGMENT);
-    }
+	    if (!no_compileopts_info) {
+		fprintf(fp0, "%s <a href=\"LYNXCOMPILEOPTS:\">%s</a>\n\n",
+			SEE_ALSO,
+			COMPILE_OPT_SEGMENT);
+	    }
 #endif
 
-    /** a new experimental link ... **/
+	    /** a new experimental link ... **/
 	    if (user_mode == ADVANCED_MODE)
 		fprintf(fp0, "  <a href=\"LYNXCFG://reload\">%s</a>\n",
 			     gettext("RELOAD THE CHANGES"));
diff --git a/src/LYSearch.c b/src/LYSearch.c
index 252185f1..03961129 100644
--- a/src/LYSearch.c
+++ b/src/LYSearch.c
@@ -8,6 +8,95 @@
 
 #include <LYLeaks.h>
 
+PRIVATE BOOL link_has_target ARGS2(
+	linkstruct *,	a,
+	char *,		target)
+{
+    OptionType *option;
+    char *stars = NULL, *cp;
+
+    /*
+     *  Search the hightext string, and hightext2 if present,
+     *  taking the case_sensitive setting into account. - FM
+     */
+    if (LYno_attr_strstr(a->hightext, target)
+     || LYno_attr_strstr(a->hightext2, target)) {
+	return TRUE;
+    }
+
+    /*
+     *  Search the relevant form fields, taking the
+     *  case_sensitive setting into account. - FM
+     */
+    if ((a->form != NULL && a->form->value != NULL) &&
+	a->form->type != F_HIDDEN_TYPE) {
+	if (a->form->type == F_PASSWORD_TYPE) {
+	    /*
+	     *  Check the actual, hidden password, and then
+	     *  the displayed string. - FM
+	     */
+	    if (LYno_attr_strstr(a->form->value, target)) {
+		return TRUE;
+	    }
+	    StrAllocCopy(stars, a->form->value);
+	    for (cp = stars; *cp != '\0'; cp++)
+		*cp = '*';
+	    if (LYno_attr_strstr(stars, target)) {
+		FREE(stars);
+		return TRUE;
+	    }
+	    FREE(stars);
+	} else if (a->form->type == F_OPTION_LIST_TYPE) {
+	    /*
+	     *  Search the option strings that are displayed
+	     *  when the popup is invoked. - FM
+	     */
+	    option = a->form->select_list;
+	    while (option != NULL) {
+		if (LYno_attr_strstr(option->name, target)) {
+		    return TRUE;
+		}
+		option = option->next;
+	    }
+	} else if (a->form->type == F_RADIO_TYPE) {
+	    /*
+	     *  Search for checked or unchecked parens. - FM
+	     */
+	    if (a->form->num_value) {
+		cp = checked_radio;
+	    } else {
+		cp = unchecked_radio;
+	    }
+	    if (LYno_attr_strstr(cp, target)) {
+		return TRUE;
+	    }
+	} else if (a->form->type == F_CHECKBOX_TYPE) {
+	    /*
+	     *  Search for checked or unchecked square brackets. - FM
+	     */
+	    if (a->form->num_value) {
+		cp = checked_box;
+	    } else {
+		cp = unchecked_box;
+	    }
+	    if (LYno_attr_strstr(cp, target)) {
+		return TRUE;
+	    }
+	} else {
+	    /*
+	     *  Check the values intended for display.
+	     *  May have been found already via the
+	     *  hightext search, but make sure here
+	     *  that the entire value is searched. - FM
+	     */
+	    if (LYno_attr_strstr(a->form->value, target)) {
+		return TRUE;
+	    }
+	}
+    }
+    return FALSE;
+}
+
 /*
  *  Search for the target string inside of the links
  *  that are currently displayed on the screen beginning
@@ -16,140 +105,38 @@
  *  If not found do not reset cur and return FALSE.
  */
 
-PRIVATE int check_for_target_in_links ARGS2(
+PRIVATE int check_next_target_in_links ARGS2(
 	int *,		cur,
-	char *,		new_target)
+	char *,		target)
 {
-    int i = *cur + 1;
-    OptionType *option;
-    char *stars = NULL, *cp;
-
-    if (nlinks == 0)
-	return(FALSE);
-
-    for (; i < nlinks; i++) {
-	/*
-	 *  Search the hightext string, and hightext2 if present,
-	 *  taking the case_sensitive setting into account. - FM
-	 */
-	if (((links[i].hightext != NULL && case_sensitive == TRUE) &&
-	     LYno_attr_char_strstr(links[i].hightext, new_target)) ||
-	    ((links[i].hightext != NULL && case_sensitive == FALSE) &&
-	     LYno_attr_char_case_strstr(links[i].hightext, new_target))) {
-	    break;
-	}
-	if (((links[i].hightext2 != NULL && case_sensitive == TRUE) &&
-	     LYno_attr_char_strstr(links[i].hightext2, new_target)) ||
-	    ((links[i].hightext2 != NULL && case_sensitive == FALSE) &&
-	     LYno_attr_char_case_strstr(links[i].hightext2, new_target))) {
-	    break;
-	}
+    int i;
 
-	/*
-	 *  Search the relevant form fields, taking the
-	 *  case_sensitive setting into account. - FM
-	 */
-	if ((links[i].form != NULL && links[i].form->value != NULL) &&
-	    links[i].form->type != F_HIDDEN_TYPE) {
-	    if (links[i].form->type == F_PASSWORD_TYPE) {
-		/*
-		 *  Check the actual, hidden password, and then
-		 *  the displayed string. - FM
-		 */
-		if (((case_sensitive == TRUE) &&
-		     LYno_attr_char_strstr(links[i].form->value,
-					   new_target)) ||
-		    ((case_sensitive == FALSE) &&
-		     LYno_attr_char_case_strstr(links[i].form->value,
-						new_target))) {
-		    break;
-		}
-		StrAllocCopy(stars, links[i].form->value);
-		for (cp = stars; *cp != '\0'; cp++)
-		    *cp = '*';
-		if (((case_sensitive == TRUE) &&
-		     LYno_attr_char_strstr(stars, new_target)) ||
-		    ((case_sensitive == FALSE) &&
-		     LYno_attr_char_case_strstr(stars, new_target))) {
-		    FREE(stars);
-		    break;
-		}
-		FREE(stars);
-	    } else if (links[i].form->type == F_OPTION_LIST_TYPE) {
-		/*
-		 *  Search the option strings that are displayed
-		 *  when the popup is invoked. - FM
-		 */
-		option = links[i].form->select_list;
-		while (option != NULL) {
-		    if (((option->name != NULL &&
-			  case_sensitive == TRUE) &&
-			 LYno_attr_char_strstr(option->name, new_target)) ||
-			((option->name != NULL &&
-			  case_sensitive == FALSE) &&
-			 LYno_attr_char_case_strstr(option->name,
-						    new_target))) {
-			break;
-		    }
-		    option = option->next;
-		}
-		if (option != NULL) {
-		    break;
-		}
-	    } else if (links[i].form->type == F_RADIO_TYPE) {
-		/*
-		 *  Search for checked or unchecked parens. - FM
-		 */
-		if (links[i].form->num_value) {
-		    cp = checked_radio;
-		} else {
-		    cp = unchecked_radio;
-		}
-		if (((case_sensitive == TRUE) &&
-		     LYno_attr_char_strstr(cp, new_target)) ||
-		    ((case_sensitive == FALSE) &&
-		     LYno_attr_char_case_strstr(cp, new_target))) {
-		    break;
-		}
-	    } else if (links[i].form->type == F_CHECKBOX_TYPE) {
-		/*
-		 *  Search for checked or unchecked square brackets. - FM
-		 */
-		if (links[i].form->num_value) {
-		    cp = checked_box;
-		} else {
-		    cp = unchecked_box;
-		}
-		if (((case_sensitive == TRUE) &&
-		     LYno_attr_char_strstr(cp, new_target)) ||
-		    ((case_sensitive == FALSE) &&
-		     LYno_attr_char_case_strstr(cp, new_target))) {
-		    break;
-		}
-	    } else {
-		/*
-		 *  Check the values intended for display.
-		 *  May have been found already via the
-		 *  hightext search, but make sure here
-		 *  that the entire value is searched. - FM
-		 */
-		if (((case_sensitive == TRUE) &&
-		     LYno_attr_char_strstr(links[i].form->value,
-					   new_target)) ||
-		    ((case_sensitive == FALSE) &&
-		     LYno_attr_char_case_strstr(links[i].form->value,
-						new_target))) {
-		    break;
-		}
+    if (nlinks != 0) {
+	for (i = *cur + 1; i < nlinks; ++i) {
+	    if (link_has_target(&links[i], target)) {
+		*cur = i;
+		return TRUE;
 	    }
 	}
     }
+    return FALSE;
+}
 
-    if (i == nlinks)
-	return(FALSE);
+PRIVATE int check_prev_target_in_links ARGS2(
+	int *,		cur,
+	char *,		target)
+{
+    int i;
 
-    *cur = i;
-    return(TRUE);
+    if (nlinks != 0) {
+	for (i = *cur - 1; i >= 0; --i) {
+	    if (link_has_target(&links[i], target)) {
+		*cur = i;
+		return TRUE;
+	    }
+	}
+    }
+    return FALSE;
 }
 
 /*
@@ -161,14 +148,12 @@ PRIVATE int check_for_target_in_links ARGS2(
  *  This is the primary USER search engine and is case sensitive
  *  or case insensitive depending on the 'case_sensitive' global
  *  variable
- *
  */
-
 PUBLIC BOOL textsearch ARGS4(
 	document *,	cur_doc,
 	char *,		prev_target,
 	int,		target_size,
-	BOOL,		next)
+	int,		direction)
 {
     int offset;
     int oldcur = cur_doc->link;
@@ -189,13 +174,13 @@ PUBLIC BOOL textsearch ARGS4(
     }
 
     QueryTotal = (search_queries ? HTList_count(search_queries) : 0);
-    recall = ((QueryTotal >= 1) ? RECALL : NORECALL);
+    recall = ((QueryTotal >= 1) ? RECALL_URL : NORECALL);
     QueryNum = QueryTotal;
 
-    if (next)
+    if (direction != 0)
 	/*
-	 *  LYK_NEXT was pressed, so copy the
-	 *  buffer into prev_target. - FM
+	 *  LYK_NEXT or LYK_PREV was pressed, so copy the
+	 *  buffer into prev_target.
 	 */
 	LYstrncpy(prev_target, prev_target_buffer, target_size);
 
@@ -226,7 +211,7 @@ check_recall:
 	 *  No entry.  Simply return, retaining the current buffer.
 	 *  Because prev_target is now reset, highlighting of the
 	 *  previous search string will no longer occur, but it can
-	 *  be used again via LYK_NEXT.   - FM
+	 *  be used again via LYK_NEXT or LYK_PREV.
 	 */
 	HTInfoMsg(CANCELLED);
 	return(FALSE);
@@ -341,33 +326,45 @@ check_recall:
     LYstrncpy(prev_target_buffer, prev_target, sizeof(prev_target_buffer)-1);
     HTAddSearchQuery(prev_target_buffer);
 
-    /*
-     *  Search the links on the currently displayed page for
-     *  the string, starting after the current link. - FM
-     */
-    if (check_for_target_in_links(&cur_doc->link, prev_target)) {
+    if (direction < 0) {
+	offset = 0;
+	if (check_prev_target_in_links(&cur_doc->link, prev_target)) {
+	    /*
+	     *  Found in link, changed cur, we're done.
+	     */
+	    highlight(OFF, oldcur, prev_target);
+	    return(TRUE);
+	}
+    } else {
+
 	/*
-	 *  Found in link, changed cur, we're done.
+	 *  Search the links on the currently displayed page for
+	 *  the string, starting after the current link. - FM
 	 */
-	highlight(OFF, oldcur, prev_target);
-	return(TRUE);
-    }
+	if (check_next_target_in_links(&cur_doc->link, prev_target)) {
+	    /*
+	     *  Found in link, changed cur, we're done.
+	     */
+	    highlight(OFF, oldcur, prev_target);
+	    return(TRUE);
+	}
 
-    /*
-     *  We'll search the text starting from the
-     *  link we are on, or the next page.
-     */
-    if (nlinks == 0)
-	offset = (display_lines - 1);
-    else
-	offset = links[cur_doc->link].ly - 1;
+	/*
+	 *  We'll search the text starting from the
+	 *  link we are on, or the next page.
+	 */
+	if (nlinks == 0)
+	    offset = (display_lines - 1);
+	else
+	    offset = links[cur_doc->link].ly - 1;
+    }
 
     /*
      *  Resume search, this time for all text.
      *  Set www_search_result if string found,
      *  and position the hit near top of screen.
      */
-    www_user_search((cur_doc->line + offset), cur_doc, prev_target);
+    www_user_search((cur_doc->line + offset), cur_doc, prev_target, direction);
     if (cur_doc->link != oldcur) {
 	highlight(OFF, oldcur, prev_target);
 	return(TRUE);
diff --git a/src/LYSearch.h b/src/LYSearch.h
index 89d21529..f917c615 100644
--- a/src/LYSearch.h
+++ b/src/LYSearch.h
@@ -7,7 +7,7 @@
 #endif /* LYSTRUCT_H */
 
 extern BOOL textsearch PARAMS((document *cur_doc,
-			       char *prev_target, int target_size, BOOL next));
+			       char *prev_target, int target_size, int direction));
 
 #define IN_FILE 1
 #define IN_LINKS 2
diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c
index 464067d6..91eafbb4 100644
--- a/src/LYShowInfo.c
+++ b/src/LYShowInfo.c
@@ -36,7 +36,7 @@
  */
 PUBLIC BOOL LYVersionIsRelease NOARGS
 {
-    return strstr(LYNX_VERSION, "rel") != 0;
+    return (BOOL)(strstr(LYNX_VERSION, "rel") != 0);
 }
 
 PUBLIC char *LYVersionStatus NOARGS
@@ -56,11 +56,11 @@ PUBLIC char *LYVersionDate NOARGS
 }
 
 /*
- *  Showinfo prints a page of info about the current file and the link
+ *  LYShowInfo prints a page of info about the current file and the link
  *  that the cursor is on.
  */
 
-PUBLIC int showinfo ARGS4(
+PUBLIC int LYShowInfo ARGS4(
 	document *,	doc,
 	int,		size_of_file,
 	document *,	newdoc,
diff --git a/src/LYShowInfo.h b/src/LYShowInfo.h
index 038492a9..58f2c533 100644
--- a/src/LYShowInfo.h
+++ b/src/LYShowInfo.h
@@ -8,7 +8,7 @@
 extern BOOL LYVersionIsRelease NOPARAMS;
 extern char *LYVersionStatus NOPARAMS;
 extern char *LYVersionDate NOPARAMS;
-extern int showinfo PARAMS((document *doc, int size_of_file, document *newdoc,
+extern int LYShowInfo PARAMS((document *doc, int size_of_file, document *newdoc,
 							char *owner_address));
 
 #endif /* LYSHOWINFO_H */
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 0f6685de..ac164295 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -44,10 +44,14 @@ extern BOOL HTPassHighCtrlRaw;
 #define BUTTON_CTRL	0	/* Quick hack */
 #endif
 
-/*Allowing the user to press tab when entering URL to get the closest
-  match in the closet*/
+/*
+ * The edit_history lists allow the user to press tab when entering URL to get
+ * the closest match in the closet
+ */
 #define LYClosetSize 100
+
 static HTList *URL_edit_history;
+static HTList *MAIL_edit_history;
 
 /* If you want to add mouse support for some new platform, it's fairly
 ** simple to do.  Once you've determined the X and Y coordinates of
@@ -232,16 +236,6 @@ PUBLIC int fancy_mouse ARGS3(
 	} else {
 	    /* No scrolling or overflow checks necessary. */
 	    *position += delta;
-#if 0
-	    /* Immediate action looks reasonable since we have no help
-	     * available for individual options.  Moreover, one should be
-	     * able to position active element with <some modifier>-click-1
-	     * (but see remark above), or with click on left or right border.
-	     */
-	    if (!(event.bstate & (BUTTON1_DOUBLE_CLICKED
-				| BUTTON1_TRIPLE_CLICKED)))
-		goto redraw;
-#endif
 	    cmd = LYK_ACTIVATE;
 	}
     } else if (event.bstate & (BUTTON3_CLICKED | BUTTON3_DOUBLE_CLICKED | BUTTON3_TRIPLE_CLICKED)) {
@@ -256,27 +250,47 @@ PUBLIC int fancy_mouse ARGS3(
 }
 
 /*
+ * Manage the collection of edit-histories
+ */
+PRIVATE HTList *whichRecall ARGS1(
+    RecallType,		recall)
+{
+    HTList **list;
+
+    switch (recall) {
+    case RECALL_CMD:
+	return LYcommandList();
+    case RECALL_MAIL:
+	list = &MAIL_edit_history;
+	break;
+    default:
+	list = &URL_edit_history;
+	break;
+    }
+    if (*list == 0)
+	*list = HTList_new();
+    return *list;
+}
+
+/*
  * Remove the oldest item in the closet
  */
-PRIVATE void LYRemoveFromCloset NOARGS
+PRIVATE void LYRemoveFromCloset ARGS1(HTList *, list)
 {
-    char *data = HTList_removeFirstObject(URL_edit_history);
+    char *data = HTList_removeFirstObject(list);
 
     if (data != 0)
 	FREE(data);
 }
 
-PUBLIC void LYOpenCloset NOARGS
+PUBLIC void LYCloseCloset ARGS1(RecallType, recall)
 {
-    URL_edit_history = HTList_new();
-}
+    HTList *list = whichRecall(recall);
 
-PUBLIC void LYCloseCloset NOARGS
-{
-    while (!HTList_isEmpty(URL_edit_history) ) {
-	LYRemoveFromCloset();
+    while (!HTList_isEmpty(list) ) {
+	LYRemoveFromCloset(list);
     }
-    HTList_delete(URL_edit_history);	/* should already be empty */
+    HTList_delete(list);	/* should already be empty */
 }
 
 /*
@@ -284,9 +298,9 @@ PUBLIC void LYCloseCloset NOARGS
  * match, i.e., the newest since we search from the top.  This should be made
  * more intelligent, but works for now.
  */
-PRIVATE char * LYFindInCloset ARGS1(char*, base)
+PRIVATE char * LYFindInCloset ARGS2(RecallType, recall, char*, base)
 {
-    HTList *list = URL_edit_history;
+    HTList *list = whichRecall(recall);
     char *data;
     unsigned len = strlen(base);
 
@@ -299,14 +313,15 @@ PRIVATE char * LYFindInCloset ARGS1(char*, base)
     return(0);
 }
 
-PRIVATE void LYAddToCloset ARGS1(char*, str)
+PRIVATE void LYAddToCloset ARGS2(RecallType, recall, char*, str)
 {
+    HTList *list = whichRecall(recall);
     char *data = NULL;
 
     StrAllocCopy(data, str);
-    HTList_addObject(URL_edit_history, data);
-    while (HTList_count(URL_edit_history) > LYClosetSize)
-	LYRemoveFromCloset();
+    HTList_addObject(list, data);
+    while (HTList_count(list) > LYClosetSize)
+	LYRemoveFromCloset(list);
 }
 
 
@@ -420,7 +435,7 @@ PRIVATE int set_clicked_link ARGS4(
 
 	    l -= display_lines;
 	    if (l > 0)
-		LYSetNewline(frac * l + 1 + 0.5);
+		LYSetNewline((int)(frac * l + 1 + 0.5));
 	    return LYReverseKeymap(LYK_DO_NOTHING);
 	}
 
@@ -502,23 +517,6 @@ PRIVATE int set_clicked_link ARGS4(
 		    mouse_link = i;
 		}
 	    }
-#if 0	/* should not have second line if no first - kw */
-	    /* Check the second line */
-	    if (links[i].hightext2 != NULL) {
-		cur_err = XYdist(x, y,
-				 links[i].hightext2_offset,
-				 links[i].ly+1,
-				 strlen(links[i].hightext2));
-		if (cur_err == 0) {
-		    mouse_link = i;
-		    mouse_err = 0;
-		    break;
-		} else if (cur_err < mouse_err) {
-		    mouse_err = cur_err;
-		    mouse_link = i;
-		}
-	    }
-#endif
 	}
 	/*
 	 * If a link was hit, we must look for a key which will activate
@@ -1353,84 +1351,63 @@ PUBLIC int lynx_initialize_keymaps NOARGS
 #endif				       /* USE_KEYMAPS */
 
 
-#if defined(USE_MOUSE) && (defined(NCURSES) || defined(PDCURSES))
+#if defined(USE_MOUSE) && (defined(NCURSES))
 PRIVATE int LYmouse_menu ARGS4(int, x, int, y, int, atlink, int, code)
 {
-    static char *choices[] = {
-	"Quit",
-	"Home page",
-	"Previous document",
-	"Beginning of document",
-	"Page up",
-	"Half page up",
-	"Two lines up",
-	"History",
-	"Help",
-	"Do nothing (refresh)",
-	"Load again",
-	"Edit URL and load",
-	"Show info",
-	"Search",
-	"Print",
-	"Two lines down",
-	"Half page down",
-	"Page down",
-	"End of document",
-	"Bookmarks",
-	"Cookie jar",
-	"Search index",
-	"Set Options",
-	NULL
-    };
-    static char *choices_link[] = {
-	"Help",
-	"Do nothing",
-	"Activate this link",
-	"Show info",
-	"Download",
-	NULL
+#define ENT_ONLY_DOC	1
+#define ENT_ONLY_LINK	2
+    static const struct {
+	char *txt;
+	int  action;
+	unsigned int  flag;
+    } possible_entries[] = {
+	{"Quit",			LYK_ABORT,		ENT_ONLY_DOC},
+	{"Home page",			LYK_MAIN_MENU,		ENT_ONLY_DOC},
+	{"Previous document",		LYK_PREV_DOC,		ENT_ONLY_DOC},
+	{"Beginning of document",	LYK_HOME,		ENT_ONLY_DOC},
+	{"Page up",			LYK_PREV_PAGE,		ENT_ONLY_DOC},
+	{"Half page up",		LYK_UP_HALF,		ENT_ONLY_DOC},
+	{"Two lines up",		LYK_UP_TWO,		ENT_ONLY_DOC},
+	{"History",			LYK_HISTORY,		ENT_ONLY_DOC},
+	{"Help",			LYK_HELP,		0},
+	{"Do nothing (refresh)",	LYK_REFRESH,		0},
+	{"Load again",			LYK_RELOAD,		ENT_ONLY_DOC},
+	{"Edit Doc URL and load",	LYK_ECGOTO,		ENT_ONLY_DOC},
+	{"Edit Link URL and load",	LYK_ELGOTO,		ENT_ONLY_LINK},
+	{"Show info",			LYK_INFO,		0},
+	{"Search",			LYK_WHEREIS,		ENT_ONLY_DOC},
+	{"Print",			LYK_PRINT,		ENT_ONLY_DOC},
+	{"Two lines down",		LYK_DOWN_TWO,		ENT_ONLY_DOC},
+	{"Half page down",		LYK_DOWN_HALF,		ENT_ONLY_DOC},
+	{"Page down",			LYK_NEXT_PAGE,		ENT_ONLY_DOC},
+	{"End of document",		LYK_END,		ENT_ONLY_DOC},
+	{"Bookmarks",			LYK_VIEW_BOOKMARK,	ENT_ONLY_DOC},
+	{"Cookie jar",			LYK_COOKIE_JAR,		ENT_ONLY_DOC},
+	{"Search index",		LYK_INDEX_SEARCH,	ENT_ONLY_DOC},
+	{"Set Options",			LYK_OPTIONS,		ENT_ONLY_DOC},
+	{"Activate this link",		LYK_SUBMIT,		ENT_ONLY_LINK},
+	{"Download",			LYK_DOWNLOAD,		ENT_ONLY_LINK}
     };
-    static int actions[] = {
-	LYK_ABORT,
-	LYK_MAIN_MENU,
-	LYK_PREV_DOC,
-	LYK_HOME,
-	LYK_PREV_PAGE,
-	LYK_UP_HALF,
-	LYK_UP_TWO,
-	LYK_HISTORY,
-	LYK_HELP,
-	LYK_REFRESH,
-	LYK_RELOAD,
-	LYK_ECGOTO,
-	LYK_INFO,
-	LYK_WHEREIS,
-	LYK_PRINT,
-	LYK_DOWN_TWO,
-	LYK_DOWN_HALF,
-	LYK_NEXT_PAGE,
-	LYK_END,
-	LYK_VIEW_BOOKMARK,
-	LYK_COOKIE_JAR,
-	LYK_INDEX_SEARCH,
-	LYK_OPTIONS
-    };
-    static int actions_link[] = {
-	LYK_HELP,
-	LYK_DO_NOTHING,
-	LYK_SUBMIT,
-	LYK_INFO,
-	LYK_DOWNLOAD
-    };
-    int c, retlac;
+#define TOTAL_MENUENTRIES	TABLESIZE(possible_entries)
+    char *choices[TOTAL_MENUENTRIES + 1];
+    int actions[TOTAL_MENUENTRIES];
+
+    int c, c1, retlac, filter_out = (atlink ? ENT_ONLY_DOC : ENT_ONLY_LINK);
+
+    c = c1 = 0;
+    while (c < (int) TOTAL_MENUENTRIES) {
+	if (!(possible_entries[c].flag & filter_out)) {
+	    choices[c1] = possible_entries[c].txt;
+	    actions[c1++] = possible_entries[c].action;
+	}
+	c++;
+    }
+    choices[c1] = NULL;
 
     /* Somehow the mouse is over the number instead of being over the
        name, so we decrease x. */
     c = LYChoosePopup((atlink ? 2 : 10) - 1, y, (x > 5 ? x-5 : 1),
-		     (atlink ? choices_link : choices),
-		     (atlink
-		      ? TABLESIZE(actions_link)
-		      : TABLESIZE(actions)), FALSE, TRUE);
+		     choices, c1, FALSE, TRUE);
 
     /*
      *  LYhandlePopupList() wasn't really meant to be used
@@ -1443,7 +1420,7 @@ PRIVATE int LYmouse_menu ARGS4(int, x, int, y, int, atlink, int, code)
 	retlac = LYK_DO_NOTHING;
 	term_options = FALSE;
     } else {
-	retlac = atlink ? (actions_link[c]) : (actions[c]);
+	retlac = actions[c];
     }
 
     if (code == FOR_INPUT && mouse_link == -1) {
@@ -1616,7 +1593,7 @@ re_read:
 	    if (new_fd >= 0) {
 		FILE *frp;
 		close(new_fd);
-		freopen(term_name, TXT_R, stdin);
+		frp = freopen(term_name, TXT_R, stdin);
 		CTRACE((tfp,
 		"nozap: freopen(%s,\"r\",stdin) returned %p, stdin is now %p with fd %d.\n",
 			term_name, frp, stdin, fileno(stdin)));
@@ -1700,17 +1677,17 @@ re_read:
 
 	switch (a) {
 	case 'A': c = UPARROW; break;
-	case 'x': c = UPARROW; break;  /* keypad up on pc ncsa telnet */
+	case 'x': c = UPARROW; break;	/* keypad up on pc ncsa telnet */
 	case 'B': c = DNARROW; break;
-	case 'r': c = DNARROW; break; /* keypad down on pc ncsa telnet */
+	case 'r': c = DNARROW; break;	/* keypad down on pc ncsa telnet */
 	case 'C': c = RTARROW; break;
-	case 'v': c = RTARROW; break; /* keypad right on pc ncsa telnet */
+	case 'v': c = RTARROW; break;	/* keypad right on pc ncsa telnet */
 	case 'D': c = LTARROW; break;
-	case 't': c = LTARROW; break;  /* keypad left on pc ncsa telnet */
-	case 'y': c = PGUP;    break;  /* keypad on pc ncsa telnet */
-	case 's': c = PGDOWN;  break;  /* keypad on pc ncsa telnet */
-	case 'w': c = HOME;    break;  /* keypad on pc ncsa telnet */
-	case 'q': c = END_KEY; break;  /* keypad on pc ncsa telnet */
+	case 't': c = LTARROW; break;	/* keypad left on pc ncsa telnet */
+	case 'y': c = PGUP;    break;	/* keypad on pc ncsa telnet */
+	case 's': c = PGDOWN;  break;	/* keypad on pc ncsa telnet */
+	case 'w': c = HOME;    break;	/* keypad on pc ncsa telnet */
+	case 'q': c = END_KEY; break;	/* keypad on pc ncsa telnet */
 	case 'M':
 #if defined(USE_SLANG) && defined(USE_MOUSE)
 	   if (found_CSI(c,b))
@@ -1719,18 +1696,18 @@ re_read:
 	     }
 	   else
 #endif
-	     c = '\n'; /* keypad enter on pc ncsa telnet */
+	     c = '\n';		/* keypad enter on pc ncsa telnet */
 	   break;
 
 	case 'm':
 #ifdef VMS
 	    if (b != 'O')
 #endif /* VMS */
-		c = '-';  /* keypad on pc ncsa telnet */
+		c = '-';	/* keypad on pc ncsa telnet */
 	    break;
 	case 'k':
 	    if (b == 'O')
-		c = '+';  /* keypad + on my xterminal :) */
+		c = '+';	/* keypad + on my xterminal :) */
 	    else
 		done_esc = FALSE; /* we have another look below - kw */
 	    break;
@@ -1738,7 +1715,7 @@ re_read:
 #ifdef VMS
 	    if (b != 'O')
 #endif /* VMS */
-		c = '+';  /* keypad on pc ncsa telnet */
+		c = '+';	/* keypad on pc ncsa telnet */
 	    break;
 	case 'P':
 #ifdef VMS
@@ -1750,15 +1727,15 @@ re_read:
 #ifdef VMS
 	    if (b != 'O')
 #endif /* VMS */
-		c = F1;  /* macintosh help button */
+		c = F1;		/* macintosh help button */
 	    break;
 	case 'p':
 #ifdef VMS
 	    if (b == 'O')
 #endif /* VMS */
-		c = '0';  /* keypad 0 */
+		c = '0';	/* keypad 0 */
 	    break;
-	case '1':			    /** VTxxx  Find  **/
+	case '1':		/** VTxxx  Find  **/
 	    if (found_CSI(c,b) && (d=GetChar()) == '~')
 		c = FIND_KEY;
 	    else
@@ -2455,11 +2432,11 @@ PUBLIC void LYUpperCase ARGS1(
 	    }
 	    i++;
 	} else {
-	    buffer[i] = TOUPPER(buffer[i]);
+	    buffer[i] = UCH(TOUPPER(buffer[i]));
 	}
     }
 #else
-	buffer[i] = TOUPPER(buffer[i]);
+	buffer[i] = UCH(TOUPPER(buffer[i]));
 #endif
 }
 
@@ -2544,6 +2521,35 @@ PUBLIC void LYTrimTrailing ARGS1(
 	buffer[--i] = 0;
 }
 
+/* 1997/11/10 (Mon) 14:26:10, originally string_short() in LYExterns.c, but
+ * moved here because LYExterns is not always configured.
+ */
+PUBLIC char *LYElideString ARGS2(
+	char *,		str,
+	int,		cut_pos)
+{
+    char buff[MAX_LINE], *s, *d;
+    static char s_str[MAX_LINE];
+    int len;
+
+    LYstrncpy(buff, str, sizeof(buff)-1);
+    len = strlen(buff);
+    if (len > (LYcols - 10)) {
+	buff[cut_pos] = '.';
+	buff[cut_pos + 1] = '.';
+	for (s = (buff + len) - (LYcols - 10) + cut_pos + 1,
+	     d = (buff + cut_pos) + 2;
+	     s >= buff &&
+	     d >= buff &&
+	     d < buff + LYcols &&
+	     (*d++ = *s++) != 0; )
+	    ;
+	buff[LYcols] = 0;
+    }
+    strcpy(s_str, buff);
+    return (s_str);
+}
+
 /*
  * Trim a startfile, returning true if it looks like one of the Lynx tags.
  */
@@ -2794,6 +2800,7 @@ PUBLIC int LYEdit1 ARGS4(
      */
     int i;
     int length;
+    unsigned char uch;
 
     if (MaxLen <= 0)
 	return(0); /* Be defensive */
@@ -2822,13 +2829,10 @@ PUBLIC int LYEdit1 ARGS4(
 	    return(ch);
 	/* FALLTHRU */
 #endif
-    case LYE_CHAR: {
-	unsigned char uch = UCH(ch);
-
+    case LYE_CHAR:
+	uch = UCH(ch);
 	LYEditInsert(edit, &uch, 1, map_active, maxMessage);
 	return 0;			/* All changes already registered */
-    }
-    break;
 
     case LYE_C1CHAR:
 	/*
@@ -3282,13 +3286,6 @@ PUBLIC int get_popup_number ARGS3(
 #  define TmpStyleOff(s)
 #endif	/* defined USE_COLOR_STYLE */
 
-#ifndef ACS_LARROW
-#  define ACS_LARROW '{'
-#endif
-#ifndef ACS_RARROW
-#  define ACS_RARROW '}'
-#endif
-
 PUBLIC void LYRefreshEdit ARGS1(
 	EDREC *,	edit)
 {
@@ -3530,17 +3527,6 @@ PRIVATE void reinsertEdit ARGS2(
     }
 }
 
-PRIVATE HTList *whichRecall ARGS1(
-    RecallType,		recall)
-{
-    switch (recall) {
-    case RECALL_CMD:
-	return LYcommandList();
-    default:
-	return URL_edit_history;
-    }
-}
-
 PRIVATE int caselessCmpList ARGS2(
     CONST void *,	a,
     CONST void *,	b)
@@ -3671,13 +3657,29 @@ PRIVATE void draw_option ARGS7(
     if (reversed)
 	SLsmg_set_color(0);
 #else
-    wmove(win, entry, 2);
+    wmove(win, entry, 1);
+    LynxWChangeStyle(win, s_menu_entry, STACK_ON);
+    waddch(win, ' ');
+    LynxWChangeStyle(win, s_menu_entry, STACK_OFF);
+    LynxWChangeStyle(win, s_menu_number, STACK_ON);
     waddstr(win, Cnum);
+    LynxWChangeStyle(win, s_menu_number, STACK_OFF);
+#ifdef USE_COLOR_STYLE
+    LynxWChangeStyle(win, reversed ? s_menu_active : s_menu_entry, STACK_ON);
+#else
     if (reversed)
 	wstart_reverse(win);
+#endif
     LYpaddstr(win, width, value);
+#ifdef USE_COLOR_STYLE
+    LynxWChangeStyle(win, reversed ? s_menu_active : s_menu_entry, STACK_OFF);
+#else
     if (reversed)
 	wstop_reverse(win);
+#endif
+    LynxWChangeStyle(win, s_menu_entry, STACK_ON);
+    waddch(win, ' ');
+    LynxWChangeStyle(win, s_menu_entry, STACK_OFF);
 #endif /* USE_SLANG */
 }
 
@@ -3724,6 +3726,10 @@ PUBLIC int LYhandlePopupList ARGS9(
     char buffer[MAX_LINE];
     char *popup_status_msg = NULL;
     CONST char **Cptr = NULL;
+#define CAN_SCROLL_DOWN	1
+#define CAN_SCROLL_UP	2
+#define CAN_SCROLL	4
+    int can_scroll = 0, can_scroll_was = 0;
 
     orig_choice = cur_choice;
     if (cur_choice < 0)
@@ -3738,7 +3744,7 @@ PUBLIC int LYhandlePopupList ARGS9(
     }
     *prev_target = '\0';
     QueryTotal = (search_queries ? HTList_count(search_queries) : 0);
-    recall = ((QueryTotal >= 1) ? RECALL : NORECALL);
+    recall = ((QueryTotal >= 1) ? RECALL_URL : NORECALL);
     QueryNum = QueryTotal;
 
     /*
@@ -3836,6 +3842,8 @@ PUBLIC int LYhandlePopupList ARGS9(
      *  This is really fun, when the length is 4, it means 0 to 4, or 5.
      */
     length = (bottom - top) - 2;
+    if (length <= num_choices)
+	can_scroll = CAN_SCROLL;
 
     /*
      *  Move the window down if it's too high.
@@ -3913,7 +3921,7 @@ redraw:
 			 max_choices, i, choices[i]);
 	}
     }
-    LYbox(form_window, !numbered);
+    LYbox(form_window, (BOOLEAN)!numbered);
     Cptr = NULL;
 
     /*
@@ -3922,6 +3930,29 @@ redraw:
     while (cmd != LYK_ACTIVATE) {
 	int row = ((i + 1) - window_offset);
 
+	/* Show scroll indicators. */
+	if (can_scroll) {
+	    can_scroll = ((window_offset ? CAN_SCROLL_UP : 0)
+			  | (num_choices - window_offset >= length
+			     ? CAN_SCROLL_DOWN : 0));
+	    if (~can_scroll & can_scroll_was) {	/* Need to redraw */
+		LYbox(form_window, (BOOLEAN)!numbered);
+		can_scroll_was = 0;
+	    }
+	    if (can_scroll & ~can_scroll_was & CAN_SCROLL_UP) {
+		wmove(form_window, 1, Lnum + width + 3);
+		LynxWChangeStyle(form_window, s_menu_sb, STACK_ON);
+		waddch(form_window, ACS_UARROW);
+		LynxWChangeStyle(form_window, s_menu_sb, STACK_OFF);
+	    }
+	    if (can_scroll & ~can_scroll_was & CAN_SCROLL_DOWN) {
+		wmove(form_window, length, Lnum + width + 3);
+		LynxWChangeStyle(form_window, s_menu_sb, STACK_ON);
+		waddch(form_window, ACS_DARROW);
+		LynxWChangeStyle(form_window, s_menu_sb, STACK_OFF);
+	    }
+	}
+
 	/*
 	 *  Unreverse cur choice.
 	 */
@@ -4567,7 +4598,7 @@ restore_popup_statusline:
 		*prev_target = '\0';
 		QueryTotal = (search_queries ? HTList_count(search_queries)
 					     : 0);
-		recall = ((QueryTotal >= 1) ? RECALL : NORECALL);
+		recall = ((QueryTotal >= 1) ? RECALL_URL : NORECALL);
 		QueryNum = QueryTotal;
 		if (ReDraw == TRUE) {
 		    ReDraw = FALSE;
@@ -4611,7 +4642,7 @@ PUBLIC int LYgetstr ARGS4(
     MaxStringSize = (bufsize < sizeof(MyEdit.buffer)) ?
 		    (bufsize - 1) : (sizeof(MyEdit.buffer) - 1);
     LYSetupEdit(&MyEdit, inputline, MaxStringSize, (LYcols-1)-x);
-    MyEdit.hidden = hidden ;
+    MyEdit.hidden = (BOOL) hidden ;
 
     CTRACE((tfp, "called LYgetstr\n"));
     for (;;) {
@@ -4652,7 +4683,7 @@ again:
 
 	if (recall != NORECALL && (ch == UPARROW || ch == DNARROW)) {
 	    LYstrncpy(inputline, MyEdit.buffer, (int)bufsize);
-	    LYAddToCloset(MyEdit.buffer);
+	    LYAddToCloset(recall, MyEdit.buffer);
 	    CTRACE((tfp, "LYgetstr(%s) recall\n", inputline));
 	    return(ch);
 	}
@@ -4692,7 +4723,7 @@ again:
 	    if (xlec == last_xlec && recall != NORECALL) {
 		HTList *list = whichRecall(recall);
 		if (!HTList_isEmpty(list)) {
-		    char **data = sortedList(list, recall == RECALL_CMD);
+		    char **data = sortedList(list, (BOOL)(recall == RECALL_CMD));
 		    int old_y, old_x;
 		    int cur_choice = 0;
 		    int num_options = LYarrayLength((CONST char **)data);
@@ -4730,7 +4761,7 @@ again:
 		    FREE(data);
 		}
 	    } else {
-		reinsertEdit(&MyEdit, LYFindInCloset(MyEdit.buffer));
+		reinsertEdit(&MyEdit, LYFindInCloset(recall, MyEdit.buffer));
 	    }
 	    break;
 
@@ -4757,7 +4788,7 @@ again:
 	     */
 	    LYstrncpy(inputline, MyEdit.buffer, (int)bufsize);
 	    if (!hidden)
-		LYAddToCloset(MyEdit.buffer);
+		LYAddToCloset(recall, MyEdit.buffer);
 	    CTRACE((tfp, "LYgetstr(%s) LYE_ENTER\n", inputline));
 	    return(ch);
 
@@ -5475,70 +5506,6 @@ PUBLIC int UPPER8 ARGS2(int,ch1, int,ch2)
     return(-10);  /* mismatch, if we come to here */
 }
 
-
-#ifdef NOTUSED
-/*
-**   We extend this function for 8bit letters
-**   using Lynx internal chartrans feature:
-**   we assume that upper/lower case letters
-**   have their "7bit approximation" images (in def7_uni.tbl)
-**   matched case-insensitive (7bit).
-**
-**   By this technique we automatically cover *any* charset
-**   known for Lynx chartrans and need no any extra information for it.
-**
-**   The cost of this assumption is that several differently accented letters
-**   may be interpreted as equal, but this side effect is negligible
-**   if the user search string is more than one character long.  - LP
-**
-**   We enable new technique only if  DisplayCharsetMatchLocale = FALSE
-**   (see description in LYCharSets.c)
-*/
-PUBLIC int UPPER8 ARGS2(int,ch1, int,ch2)
-{
-
-    /* case-insensitive match for us-ascii */
-    if (UCH(TOASCII(ch1)) < 128 && UCH(TOASCII(ch2)) < 128)
-	return(TOUPPER(ch1) - TOUPPER(ch2));
-
-    /* case-insensitive match for upper half */
-    if (UCH(TOASCII(ch1)) > 127 &&  /* S/390 -- gil -- 2066 */
-	UCH(TOASCII(ch2)) > 127)
-    {
-	if (DisplayCharsetMatchLocale)
-	   return(TOUPPER(ch1) - TOUPPER(ch2)); /* old-style */
-	else
-	{
-	/* compare "7bit approximation" for letters >127   */
-	/* BTW, if we remove the check for >127 above	   */
-	/* we get even more "relaxed" insensitive match... */
-
-	int charset_in, charset_out, uck1, uck2;
-	char replace_buf1 [10], replace_buf2 [10];
-
-	charset_in  = current_char_set;  /* display character set */
-	charset_out = UCGetLYhndl_byMIME("us-ascii");
-
-	uck1 = UCTransCharStr(replace_buf1, sizeof(replace_buf1), (char)ch1,
-			      charset_in, charset_out, YES);
-	uck2 = UCTransCharStr(replace_buf2, sizeof(replace_buf2), (char)ch2,
-			      charset_in, charset_out, YES);
-
-	if ((uck1 > 0) && (uck2 > 0))  /* both replacement strings found */
-	    return (strcasecomp(replace_buf1, replace_buf2));
-
-	/* check to be sure we have not lost any strange characters */
-	/* which are not found in def7_uni.tbl but _equal_ in fact. */
-	/* this also applied for "x-transparent" display mode.	    */
-	if (UCH(ch1) == UCH(ch2))
-	    return(0);	 /* match */
-	}
-    }
-
-    return(-10);  /* mismatch, if we come to here */
-}
-#endif /* NOTUSED */
-
 /*
  * Replaces 'fgets()' calls into a fixed-size buffer with reads into a buffer
  * that is allocated.  When an EOF or error is found, the buffer is freed
@@ -5583,33 +5550,6 @@ static char basis_64[] =
 
 #define B64_LINE       76
 
-#if 0
-#define XX 255	/* illegal base64 char */
-#define EQ 254	/* padding */
-static unsigned char index_64[256] = {
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63,
-    52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,EQ,XX,XX,
-    XX, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
-    15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
-    XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
-    41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
-
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
-};
-
-#define GETC(str,len)  (len > 0 ? len--,*str++ : EOF)
-#define INVALID_B64(c) (index_64[UCH(c)] == XX)
-#endif
-
 PUBLIC void base64_encode ARGS3(
     char *,	dest,
     char *,	src,
@@ -5696,7 +5636,7 @@ PUBLIC void LYOpenCmdLogfile ARGS2(
 
 PUBLIC BOOL LYHaveCmdScript NOARGS
 {
-    return cmd_script != 0;
+    return (BOOL)(cmd_script != 0);
 }
 
 PUBLIC void LYOpenCmdScript NOARGS
diff --git a/src/LYStrings.h b/src/LYStrings.h
index af6e4fb2..9ccf87a1 100644
--- a/src/LYStrings.h
+++ b/src/LYStrings.h
@@ -5,8 +5,9 @@
 
 typedef enum {
     NORECALL = 0
-    , RECALL
+    , RECALL_URL
     , RECALL_CMD
+    , RECALL_MAIL
 } RecallType;
 
 /*  UPPER8(ch1,ch2) is an extension of (TOUPPER(ch1) - TOUPPER(ch2))  */
@@ -59,6 +60,7 @@ extern int LYmbcsstrlen PARAMS((
 	char *		str,
 	BOOL		utf_flag,
 	BOOL		count_gcells));
+
 extern char * LYno_attr_mbcs_strstr PARAMS((
 	char *		chptr,
 	CONST char *	tarptr,
@@ -73,6 +75,12 @@ extern char * LYno_attr_mbcs_case_strstr PARAMS((
 	BOOL		count_gcells,
 	int *		nstartp,
 	int *		nendp));
+
+#define LYno_attr_mb_strstr(chptr, tarptr, utf_flag, count_gcells, nstartp, nendp) \
+	(case_sensitive \
+	    ? LYno_attr_mbcs_strstr(chptr, tarptr, utf_flag, count_gcells, nstartp, nendp) \
+	    : LYno_attr_mbcs_case_strstr(chptr, tarptr, utf_flag, count_gcells, nstartp, nendp))
+
 extern char * LYno_attr_char_strstr PARAMS((
 	char *		chptr,
 	char *		tarptr));
@@ -80,6 +88,11 @@ extern char * LYno_attr_char_case_strstr PARAMS((
 	char *		chptr,
 	char *		tarptr));
 
+#define LYno_attr_strstr(chptr, tarptr) \
+	(case_sensitive \
+	? LYno_attr_char_strstr(chptr, tarptr) \
+	: LYno_attr_char_case_strstr(chptr, tarptr))
+
 extern char * SNACopy PARAMS((
 	char **		dest,
 	CONST char *	src,
@@ -278,6 +291,9 @@ extern int lynx_initialize_keymaps NOPARAMS;
 extern int map_string_to_keysym PARAMS((CONST char * src, int *lec));
 #endif
 
+extern char *LYElideString PARAMS((
+	char *		str,
+	int		cut_pos));
 extern void LYLowerCase PARAMS((
 	char *		buffer));
 extern void LYUpperCase PARAMS((
@@ -317,8 +333,7 @@ extern int LYEdit1 PARAMS((
 	int		ch,
 	int		action,
 	BOOL		maxMessage));
-extern void LYOpenCloset NOPARAMS;
-extern void LYCloseCloset NOPARAMS;
+extern void LYCloseCloset PARAMS((RecallType recall));
 extern int LYhandlePopupList PARAMS((
 	int		cur_choice,
 	int		ly,
diff --git a/src/LYStructs.h b/src/LYStructs.h
index 90020afd..fd95aee5 100644
--- a/src/LYStructs.h
+++ b/src/LYStructs.h
@@ -80,6 +80,8 @@ typedef struct _VisitedLink {
 extern histstruct history[MAXHIST];
 extern int nhist;
 
+/******************************************************************************/
+
 typedef struct _lynx_list_item_type {
     struct _lynx_list_item_type *next;  /* the next item in the linked list */
     char *name; 			/* a description of the item */
@@ -115,4 +117,51 @@ extern lynx_list_item_type *uploaders;
 extern lynx_list_item_type *externals;
 #endif
 
+/******************************************************************************/
+
+typedef struct
+{
+    CONST char *name;
+    int value;
+}
+Config_Enum;
+
+typedef int (*ParseFunc) PARAMS((char *));
+
+#define ParseUnionMembers \
+	lynx_list_item_type** add_value; \
+	BOOLEAN * set_value; \
+	int *     int_value; \
+	char **   str_value; \
+	ParseFunc fun_value; \
+	long	  def_value
+
+typedef union {
+	ParseUnionMembers;
+} ParseUnion;
+
+#ifdef	PARSE_DEBUG
+#define ParseUnionPtr Config_Type *
+#define ParseUnionOf(tbl) tbl
+#define ParseData ParseUnionMembers
+#define UNION_ADD(v) &v,  0,  0,  0,  0,  0
+#define UNION_SET(v)  0, &v,  0,  0,  0,  0
+#define UNION_INT(v)  0,  0, &v,  0,  0,  0
+#define UNION_STR(v)  0,  0,  0, &v,  0,  0
+#define UNION_ENV(v)  0,  0,  0,  v,  0,  0
+#define UNION_FUN(v)  0,  0,  0,  0,  v,  0
+#define UNION_DEF(v)  0,  0,  0,  0,  0,  v
+#else
+#define ParseUnionPtr ParseUnion *
+#define ParseUnionOf(tbl) (ParseUnionPtr)(&(tbl->value))
+#define ParseData long value
+#define UNION_ADD(v) (long)&(v)
+#define UNION_SET(v) (long)&(v)
+#define UNION_INT(v) (long)&(v)
+#define UNION_STR(v) (long)&(v)
+#define UNION_ENV(v) (long) (v)
+#define UNION_FUN(v) (long) (v)
+#define UNION_DEF(v) (long) (v)
+#endif
+
 #endif /* LYSTRUCTS_H */
diff --git a/src/LYStyle.c b/src/LYStyle.c
index 6477b42f..cdcaccae 100644
--- a/src/LYStyle.c
+++ b/src/LYStyle.c
@@ -1,6 +1,6 @@
 /* character level styles for Lynx
  * (c) 1996 Rob Partington -- donated to the Lyncei (if they want it :-)
- * @Id: LYStyle.c 1.44 Sun, 01 Apr 2001 17:51:46 -0700 dickey @
+ * @Id: LYStyle.c 1.45 Sun, 03 Jun 2001 12:58:00 -0700 dickey @
  */
 #include <HTUtils.h>
 #include <HTML.h>
@@ -67,6 +67,12 @@ PUBLIC int s_prompt_sel		= NOSTYLE;
 PUBLIC int s_status		= NOSTYLE;
 PUBLIC int s_title		= NOSTYLE;
 PUBLIC int s_whereis		= NOSTYLE;
+PUBLIC int s_menu_frame		= NOSTYLE;
+PUBLIC int s_menu_bg		= NOSTYLE;
+PUBLIC int s_menu_number	= NOSTYLE;
+PUBLIC int s_menu_entry		= NOSTYLE;
+PUBLIC int s_menu_active	= NOSTYLE;
+PUBLIC int s_menu_sb		= NOSTYLE;
 
 #ifdef USE_SCROLLBAR
 PUBLIC int s_sb_aa		= NOSTYLE;
@@ -78,14 +84,23 @@ PUBLIC int s_sb_naa		= NOSTYLE;
 /* start somewhere safe */
 #define MAX_COLOR 16
 PRIVATE int colorPairs = 0;
-PRIVATE unsigned char our_pairs[2][MAX_COLOR][MAX_COLOR];
+
+#ifdef USE_BLINK
+#  define MAX_BLINK	2
+#  define M_BLINK	A_BLINK
+#else
+#  define MAX_BLINK	1
+#  define M_BLINK	0
+#endif
+
+PRIVATE unsigned char our_pairs[2][MAX_BLINK][MAX_COLOR][MAX_COLOR];
 
 /* icky parsing of the style options */
 PRIVATE void parse_attributes ARGS5(char*,mono,char*,fg,char*,bg,int,style,char*,element)
 {
     int mA = 0;
-    short fA = default_fg;
-    short bA = default_bg;
+    short fA = (short) default_fg;
+    short bA = (short) default_bg;
     int cA = A_NORMAL;
     int newstyle = hash_code(element);
 
@@ -116,8 +131,8 @@ PRIVATE void parse_attributes ARGS5(char*,mono,char*,fg,char*,bg,int,style,char*
     }
     CTRACE2(TRACE_STYLE, (tfp, "CSS(CP):%d\n", colorPairs));
 
-    fA = check_color(fg, default_fg);
-    bA = check_color(bg, default_bg);
+    fA = (short) check_color(fg, default_fg);
+    bA = (short) check_color(bg, default_bg);
 
     if (style == -1) {			/* default */
 	CTRACE2(TRACE_STYLE, (tfp, "CSS(DEF):default_fg=%d, default_bg=%d\n", fA, bA));
@@ -129,6 +144,14 @@ PRIVATE void parse_attributes ARGS5(char*,mono,char*,fg,char*,bg,int,style,char*
     if (fA == NO_COLOR) {
 	bA = NO_COLOR;
     } else if (COLORS) {
+#ifdef USE_BLINK
+	if (term_blink_is_boldbg) {
+	    if (fA >= COLORS)
+		cA = A_BOLD;
+	    if (bA >= COLORS)
+		cA |= M_BLINK;
+	} else
+#endif
 	if (fA >= COLORS || bA >= COLORS)
 	    cA = A_BOLD;
 	if (fA >= COLORS)
@@ -151,15 +174,15 @@ PRIVATE void parse_attributes ARGS5(char*,mono,char*,fg,char*,bg,int,style,char*
 
 	if (fA < MAX_COLOR
 	 && bA < MAX_COLOR
-	 && our_pairs[cA == A_BOLD][fA][bA])
-	    curPair = our_pairs[cA == A_BOLD][fA][bA] - 1;
+	 && our_pairs[!!(cA & A_BOLD)][!!(cA & A_BLINK)][fA][bA])
+	    curPair = our_pairs[!!(cA & A_BOLD)][!!(cA & M_BLINK)][fA][bA] - 1;
 	else {
 	    curPair = ++colorPairs;
-	    init_pair(curPair, fA, bA);
+	    init_pair((short) curPair, fA, bA);
 	    if (fA < MAX_COLOR
 	     && bA < MAX_COLOR
 	     && curPair < 255)
-		our_pairs[cA == A_BOLD][fA][bA] = curPair + 1;
+		our_pairs[!!(cA & A_BOLD)][!!(cA & M_BLINK)][fA][bA] = curPair + 1;
 	}
 	CTRACE2(TRACE_STYLE, (tfp, "CSS(CURPAIR):%d\n", curPair));
 	if (style < DSTYLE_ELEMENTS)
@@ -209,6 +232,12 @@ PRIVATE void parse_style ARGS1(char*,buffer)
 	{ "edit.prompt.marked",	DSTYLE_ELEMENTS,	&s_prompt_sel },
 	{ "edit.prompt",	DSTYLE_ELEMENTS,	&s_prompt_edit },
 	{ "forwbackw.arrow",	DSTYLE_ELEMENTS,	&s_forw_backw },
+	{ "menu.frame",		DSTYLE_ELEMENTS,	&s_menu_frame },
+	{ "menu.bg",		DSTYLE_ELEMENTS,	&s_menu_bg },
+	{ "menu.n",		DSTYLE_ELEMENTS,	&s_menu_number },
+	{ "menu.entry",		DSTYLE_ELEMENTS,	&s_menu_entry },
+	{ "menu.active",	DSTYLE_ELEMENTS,	&s_menu_active },
+	{ "menu.sb",		DSTYLE_ELEMENTS,	&s_menu_sb },
     };
     unsigned n;
     BOOL found = FALSE;
@@ -401,6 +430,11 @@ PUBLIC void parse_userstyles NOARGS
     dft_style(s_aedit_pad,		s_aedit);
     dft_style(s_curedit,		s_aedit);
     dft_style(s_aedit_sel,		s_aedit);
+    dft_style(s_menu_bg,		s_normal);
+    dft_style(s_menu_entry,		s_menu_bg);
+    dft_style(s_menu_frame,		s_menu_bg);
+    dft_style(s_menu_number,		s_menu_bg);
+    dft_style(s_menu_active,		s_alink);
 }
 
 
diff --git a/src/LYStyle.h b/src/LYStyle.h
index 253ec986..66f87127 100644
--- a/src/LYStyle.h
+++ b/src/LYStyle.h
@@ -1,6 +1,8 @@
 #ifndef LYSTYLE_H
 #define LYSTYLE_H
 
+#include <HTUtils.h>
+
 #ifdef USE_COLOR_STYLE
 
 #include <AttrList.h>
@@ -24,13 +26,11 @@ extern void style_defaultStyleSheet NOPARAMS;
 
 extern int style_readFromFile PARAMS((char* file));
 
-
 extern void TrimColorClass PARAMS((
     CONST char *	tagname,
     char *		styleclassname,
     int *		phcode));
 
-
  /* this is an array of styles for tags that don't specify 'class' - the
     values from that array will be suggested by SGML.c by setting the
     following variable. Value of -1 means that style value should be calculated
diff --git a/src/LYUtils.c b/src/LYUtils.c
index 24494fc2..b6d01ab8 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -453,17 +453,11 @@ PUBLIC void highlight ARGS3(
 		   ((Offset + tLen) <= hoffset)) {
 		data = (Data + tlen);
 		offset = (Offset + tLen);
-		if ((case_sensitive ?
-		     (cp = LYno_attr_mbcs_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL :
-		     (cp = LYno_attr_mbcs_case_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL) &&
+		if (((cp = LYno_attr_mb_strstr(data,
+					       target,
+					       utf_flag, YES,
+					       &HitOffset,
+					       &LenNeeded)) != NULL) &&
 		    (offset + LenNeeded) < LYcols) {
 		    Data = cp;
 		    Offset = (offset + HitOffset);
@@ -701,17 +695,11 @@ PUBLIC void highlight ARGS3(
 					      (offset - Offset),
 					      utf_flag);
 		}
-		if ((case_sensitive ?
-		     (cp = LYno_attr_mbcs_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL :
-		     (cp = LYno_attr_mbcs_case_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL) &&
+		if (((cp = LYno_attr_mb_strstr(data,
+					       target,
+					       utf_flag, YES,
+					       &HitOffset,
+					       &LenNeeded)) != NULL) &&
 		    (offset + LenNeeded) < LYcols) {
 		    /*
 		     *	If the hit starts after the end of the hightext,
@@ -980,17 +968,11 @@ highlight_hit_within_hightext:
 					  (offset - Offset),
 					  utf_flag);
 	    }
-	    if ((case_sensitive ?
-		 (cp = LYno_attr_mbcs_strstr(data,
-					     target,
-					     utf_flag, YES,
-					     &HitOffset,
-					     &LenNeeded)) != NULL :
-		 (cp = LYno_attr_mbcs_case_strstr(data,
-					     target,
-					     utf_flag, YES,
-					     &HitOffset,
-					     &LenNeeded)) != NULL) &&
+	    if (((cp = LYno_attr_mb_strstr(data,
+					   target,
+					   utf_flag, YES,
+					   &HitOffset,
+					   &LenNeeded)) != NULL) &&
 		(offset + LenNeeded) < LYcols) {
 		/*
 		 *  If the hit starts after the end of the hightext,
@@ -1183,17 +1165,11 @@ highlight_search_hightext2:
 		   ((Offset + tLen) <= hoffset)) {
 		data = (Data + tlen);
 		offset = (Offset + tLen);
-		if ((case_sensitive ?
-		     (cp = LYno_attr_mbcs_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL :
-		     (cp = LYno_attr_mbcs_case_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL) &&
+		if (((cp = LYno_attr_mb_strstr(data,
+					       target,
+					       utf_flag, YES,
+					       &HitOffset,
+					       &LenNeeded)) != NULL) &&
 		    (offset + LenNeeded) < LYcols) {
 		    Data = cp;
 		    Offset = (offset + HitOffset);
@@ -1430,17 +1406,11 @@ highlight_search_hightext2:
 					      (offset - Offset),
 					      utf_flag);
 		}
-		if ((case_sensitive ?
-		     (cp = LYno_attr_mbcs_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL :
-		     (cp = LYno_attr_mbcs_case_strstr(data,
-						 target,
-						 utf_flag, YES,
-						 &HitOffset,
-						 &LenNeeded)) != NULL) &&
+		if (((cp = LYno_attr_mb_strstr(data,
+					       target,
+					       utf_flag, YES,
+					       &HitOffset,
+					       &LenNeeded)) != NULL) &&
 		    (offset + LenNeeded) < LYcols) {
 		    /*
 		     *	If the hit starts after the end of the hightext2,
@@ -1709,17 +1679,11 @@ highlight_hit_within_hightext2:
 					  (offset - Offset),
 					  utf_flag);
 	    }
-	    if ((case_sensitive ?
-		 (cp = LYno_attr_mbcs_strstr(data,
-					     target,
-					     utf_flag, YES,
-					     &HitOffset,
-					     &LenNeeded)) != NULL :
-		 (cp = LYno_attr_mbcs_case_strstr(data,
-					     target,
-					     utf_flag, YES,
-					     &HitOffset,
-					     &LenNeeded)) != NULL) &&
+	    if (((cp = LYno_attr_mb_strstr(data,
+					   target,
+					   utf_flag, YES,
+					   &HitOffset,
+					   &LenNeeded)) != NULL) &&
 		(offset + LenNeeded) < LYcols) {
 		/*
 		 *  If the hit starts after the end of the hightext2,
@@ -2277,6 +2241,7 @@ PRIVATE int DontCheck NOARGS
      * and expensive operation - TD
      */
 #if HAVE_GETTIMEOFDAY
+#undef timezone			/* U/Win defines a conflicting macro */
     {
 	struct timeval tv;
 	gettimeofday(&tv, (struct timezone *)0);
@@ -2297,7 +2262,7 @@ PUBLIC int HTCheckForInterrupt NOARGS
     int c;
     int cmd;
 #ifndef VMS /* UNIX stuff: */
-#ifndef USE_SLANG
+#if !defined(USE_SLANG) && defined(UNIX)
     struct timeval socket_timeout;
     int ret = 0;
     fd_set readfds;
@@ -2423,8 +2388,9 @@ PUBLIC int HTCheckForInterrupt NOARGS
 
 	    switch (cmd)
 	    {
-	    case LYK_WHEREIS: /* search within the document */
-	    case LYK_NEXT:	 /* search for the next occurrence in the document */
+	    case LYK_WHEREIS:	/* search within the document */
+	    case LYK_NEXT:	/* search for the next occurrence in the document */
+	    case LYK_PREV:	/* search for the previous occurrence in the document */
 		handle_LYK_WHEREIS(cmd, &do_refresh);
 		if (www_search_result != -1) {
 		    Newline_partial = www_search_result;
@@ -3508,12 +3474,8 @@ PUBLIC void size_change ARGS1(
 		old_lines, old_cols, LYlines, LYcols));
 #if defined(CAN_SWITCH_DISPLAY_CHARSET) && defined(CAN_AUTODETECT_DISPLAY_CHARSET)
 	/* May need to reload the font due to different char-box size */
-	if (current_char_set != auto_display_charset) {
-	    int old = current_char_set;
-
-	    Switch_Display_Charset(auto_display_charset, 1);
-	    Switch_Display_Charset(old, 1);
-	}
+	if (current_char_set != auto_display_charset)
+	    Switch_Display_Charset(current_char_set, SWITCH_DISPLAY_CHARSET_SIZECHANGE);
 #endif
     }
 #ifdef SIGWINCH
@@ -3935,7 +3897,7 @@ PRIVATE int fmt_tempname ARGS3(
      */
     counter = MAX_TEMPNAME;
     while (names_used < MAX_TEMPNAME) {
-	counter = ( (float)MAX_TEMPNAME * lynx_rand() ) / LYNX_RAND_MAX + 1;
+	counter = (unsigned)(( (float)MAX_TEMPNAME * lynx_rand() ) / LYNX_RAND_MAX + 1);
 	counter %= SIZE_TEMPNAME;	/* just in case... */
 	/*
 	 * Avoid reusing a temporary name, since there are places in the code
@@ -4961,7 +4923,7 @@ have_VMS_URL:
 
 #if defined(_WINDOWS) /* 1998/06/23 (Tue) 16:45:20 */
 
-PUBLIC int win32_check_interrupt()
+PUBLIC int win32_check_interrupt(void)
 {
     int c;
 
@@ -6555,7 +6517,7 @@ PUBLIC FILE *LYOpenTemp ARGS3(
 {
     FILE *fp = 0;
     BOOL txt = TRUE;
-    BOOL wrt = 'r';
+    char wrt = 'r';
     LY_TEMP *p;
 
     CTRACE((tfp, "LYOpenTemp(,%s,%s)\n", suffix, mode));
@@ -7341,27 +7303,6 @@ PUBLIC void LYLocalFileToURL ARGS2(
     StrAllocCat(*target, leaf);
 }
 
-#ifdef NOTDEFINED
-/* FIXME: this may be useful for pages that do not allow nested pages */
-PUBLIC int LYOpenInternalPage ARGS2(
-	FILE **,  fp0,
-	char **, newfile)
-{
-    static char tempfile[LY_MAXPATH];
-
-    LYRemoveTemp(tempfile);
-    if ((*fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w")) == NULL) {
-	HTAlert(CANNOT_OPEN_TEMP);
-	return(-1);
-    }
-
-    LYLocalFileToURL(newfile, tempfile);
-    LYforce_no_cache = TRUE;  /* don't cache this doc */
-
-    return(0);  /* OK */
-}
-#endif
-
 PUBLIC void BeginInternalPage ARGS3(
 	FILE *, fp0,
 	char*, Title,
@@ -8041,7 +7982,6 @@ PUBLIC char* get_clip_grab()
 {
     HANDLE hWnd;
     LPTSTR pLogData;
-    int val;
 
     hWnd = NULL;
     if (!OpenClipboard(hWnd)) {
@@ -8131,11 +8071,6 @@ PUBLIC char * w32_strerror(DWORD ercode)
      */
     if (ercode > WSABASEERR) {
 	hModule = GetModuleHandle("wsock32");
-#if 0
-	if (hModule == NULL) {
-	    hModule = LoadLibrary("wsock32");
-	}
-#endif
 	if (hModule == NULL)
 	    ercode = GetLastError();
 	else
@@ -8152,12 +8087,6 @@ PUBLIC char * w32_strerror(DWORD ercode)
 		  sizeof(msg_buff),
 		  NULL);
 
-#if 0
-    if (hModule) {
-	FreeLibrary(hModule);
-    }
-#endif
-
     strcpy(tmp_buff, msg_buff);
     p = q = tmp_buff;
     i = 0;
diff --git a/src/LYUtils.h b/src/LYUtils.h
index a9b990e5..db0b6bbe 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -101,7 +101,6 @@ extern int HTCheckForInterrupt NOPARAMS;
 extern int LYCheckForProxyURL PARAMS((char *filename));
 extern int LYConsoleInputFD PARAMS((BOOLEAN need_selectable));
 extern int LYCopyFile PARAMS((char *src, char *dst));
-extern int LYOpenInternalPage PARAMS((FILE **fp0, char **newfile));
 extern int LYRemoveTemp PARAMS((char *name));
 extern int LYSystem PARAMS((char *command));
 extern int LYValidateOutput PARAMS((char * filename));
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index 31eb8380..71068929 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -17,29 +17,28 @@
 #define FNAME_LYNXRC ".lynxrc"
 #endif /* FNAMES_8_3 */
 
-typedef struct
-{
-    CONST char *name;
-    int value;
-}
-Config_Enum;
-
-#define FIND_KEYWORD(cp, keyword) \
-    ((cp = LYstrstr(line_buffer, keyword)) != NULL && \
-     (cp - line_buffer) < number_sign)
-
+#define MSG_ENABLE_LYNXRC N_("Normally disabled.  See ENABLE_LYNXRC in lynx.cfg\n")
+#define NonNull(string) ((string) != 0 ? (string) : "")
 #define putBool(value) ((value) ? "on" : "off")
 
+PUBLIC Config_Enum tbl_DTD_recovery[] = {
+    { "on",		TRUE },
+    { "off",		FALSE },
+    { "sortasgml",	TRUE },
+    { "tagsoup",	FALSE },
+    { NULL,		-1 },
+};
+
 #ifdef DIRED_SUPPORT
-static Config_Enum dir_list_style_tbl[] = {
+PRIVATE Config_Enum tbl_dir_list_style[] = {
     { "FILES_FIRST",	FILES_FIRST },
     { "DIRECTORIES_FIRST", 0 },
     { "MIXED_STYLE",	MIXED_STYLE },
-    { NULL,		-1 },
+    { NULL,		MIXED_STYLE },
 };
 #endif
 
-static Config_Enum file_sort_tbl[] = {
+PRIVATE Config_Enum tbl_file_sort[] = {
     { "BY_FILENAME",	FILE_BY_NAME },
     { "BY_TYPE",	FILE_BY_TYPE },
     { "BY_SIZE",	FILE_BY_SIZE },
@@ -47,45 +46,68 @@ static Config_Enum file_sort_tbl[] = {
     { NULL,		-1 },
 };
 
-static Config_Enum keypad_mode_tbl[] = {
+PUBLIC Config_Enum tbl_keypad_mode[] = {
     { "LINKS_AND_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
     { "LINKS_AND_FORM_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
     { "LINKS_ARE_NUMBERED", LINKS_ARE_NUMBERED },
     { "NUMBERS_AS_ARROWS", NUMBERS_AS_ARROWS },
+    { NULL,		DEFAULT_KEYPAD_MODE }
+};
+
+PUBLIC Config_Enum tbl_multi_bookmarks[] = {
+    { "OFF",		MBM_OFF },
+    { "STANDARD",	MBM_STANDARD },
+    { "ON",		MBM_STANDARD },
+    { "ADVANCED",	MBM_ADVANCED },
     { NULL,		-1 }
 };
 
-static Config_Enum user_mode_tbl[] = {
+PRIVATE Config_Enum tbl_show_colors[] = {
+    { "default",	SHOW_COLOR_UNKNOWN },
+    { "default",	SHOW_COLOR_OFF },
+    { "default",	SHOW_COLOR_ON },
+    { "on",		SHOW_COLOR_UNKNOWN },
+    { "off",		SHOW_COLOR_UNKNOWN },
+    { "never",		SHOW_COLOR_NEVER },
+    { "always",		SHOW_COLOR_ALWAYS },
+    { NULL,		SHOW_COLOR_UNKNOWN }
+};
+
+PUBLIC Config_Enum tbl_transfer_rate[] = {
+    { "NONE",		rateOFF },
+    { "KB",		rateKB },
+    { "TRUE",		rateKB },
+    { "BYTES",		rateBYTES },
+    { "FALSE",		rateBYTES },
+#ifdef EXP_READPROGRESS
+    { "KB,ETA",		rateEtaKB },
+    { "BYTES,ETA",	rateEtaBYTES },
+#endif
+    { NULL,		-1 },
+};
+
+PUBLIC Config_Enum tbl_user_mode[] = {
     { "ADVANCED",	ADVANCED_MODE },
     { "INTERMEDIATE",	INTERMEDIATE_MODE },
     { "NOVICE",		NOVICE_MODE },
-    { NULL,		-1 }
+    { NULL,		NOVICE_MODE }
 };
 
-static Config_Enum visited_links_tbl[] = {
+PRIVATE Config_Enum tbl_visited_links[] = {
     { "FIRST_REVERSED",	VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE },
     { "FIRST",		VISITED_LINKS_AS_FIRST_V },
     { "TREE",		VISITED_LINKS_AS_TREE    },
     { "LAST_REVERSED",	VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE },
     { "LAST",		VISITED_LINKS_AS_LATEST  },
-    { NULL,		-1 }
+    { NULL,		DEFAULT_VISITED_LINKS }
 };
 
-PRIVATE char *SkipEquals ARGS1(char *, src)
-{
-    char *tmp;
-    if ((tmp = (char *)strchr(src, '=')) != NULL)
-	src = tmp + 1;
-    return LYSkipBlanks(src);
-}
-
 PRIVATE BOOL getBool ARGS1(char *, src)
 {
-    src = SkipEquals(src);
-    return (!strncasecomp(src, "on", 2) || !strncasecomp(src, "true", 4));
+    return (BOOL) (!strncasecomp(src, "on", 2) || !strncasecomp(src, "true", 4));
 }
 
-PRIVATE CONST char *putEnum ARGS2(
+PRIVATE CONST char *LYputEnum ARGS2(
     Config_Enum *,	table,
     int,		value)
 {
@@ -98,12 +120,11 @@ PRIVATE CONST char *putEnum ARGS2(
     return "?";
 }
 
-PRIVATE BOOL getEnum ARGS3(
+PRIVATE BOOL LYgetEnum ARGS3(
     Config_Enum *,	table,
     char *,		src,
     int *,		value)
 {
-    src = SkipEquals(src);
     while (table->name != 0) {
 	if (!strncasecomp(table->name, src, strlen(table->name))) {
 	    *value = table->value;
@@ -111,592 +132,217 @@ PRIVATE BOOL getEnum ARGS3(
 	}
 	table++;
     }
+    if (table->value >= 0) 	/* is there a default? */
+	*value = table->value;
     return FALSE;
 }
 
-/*  Read and process user options.
- *  If the passed-in fp is NULL, open the regular user defaults file
- *  for reading, otherwise use fp which has to be a file open for
- *  reading. - kw
- */
-PUBLIC void read_rc ARGS1(FILE *, fp)
+/* these are for data that are normally not read/written from .lynxrc */
+#define PARSE_SET(n,v,h)   {n,    1, CONF_BOOL,  UNION_SET(v), 0, 0, 0, h}
+#define PARSE_ARY(n,v,t,h) {n,    1, CONF_ARRAY, UNION_INT(v), t, 0, 0, h}
+#define PARSE_ENU(n,v,t,h) {n,    1, CONF_ENUM,  UNION_INT(v), 0, t, 0, h}
+#define PARSE_LIS(n,v,h)   {n,    1, CONF_LIS,   UNION_STR(v), 0, 0, 0, h}
+#define PARSE_STR(n,v,h)   {n,    1, CONF_STR,   UNION_STR(v), 0, 0, 0, h}
+#define PARSE_FUN(n,v,w,h) {n,    1, CONF_FUN,   UNION_FUN(v), 0, 0, w, h}
+#define PARSE_MBM(n,h)     {n,    1, CONF_MBM,   UNION_DEF(0), 0, 0, 0, h}
+
+/* these are for data that are optionally read/written from .lynxrc */
+#define MAYBE_SET(n,v,h)   {n,    0, CONF_BOOL,  UNION_SET(v), 0, 0, 0, h}
+#define MAYBE_ARY(n,v,t,h) {n,    0, CONF_ARRAY, UNION_INT(v), t, 0, 0, h}
+#define MAYBE_ENU(n,v,t,h) {n,    0, CONF_ENUM,  UNION_INT(v), 0, t, 0, h}
+#define MAYBE_LIS(n,v,h)   {n,    0, CONF_LIS,   UNION_STR(v), 0, 0, 0, h}
+#define MAYBE_STR(n,v,h)   {n,    0, CONF_STR,   UNION_STR(v), 0, 0, 0, h}
+#define MAYBE_FUN(n,v,w,h) {n,    0, CONF_FUN,   UNION_FUN(v), 0, 0, w, h}
+#define MAYBE_MBM(n,h)     {n,    0, CONF_MBM,   UNION_DEF(0), 0, 0, 0, h}
+
+#define PARSE_NIL          {NULL, 1, 0,          UNION_DEF(0), 0, 0, 0, 0}
+
+typedef enum {
+    CONF_UNSPECIFIED = 0
+    ,CONF_ARRAY
+    ,CONF_BOOL
+    ,CONF_FUN
+    ,CONF_INT
+    ,CONF_ENUM
+    ,CONF_LIS
+    ,CONF_MBM
+    ,CONF_STR
+} Conf_Types;
+
+typedef struct config_type
 {
-    char *line_buffer = NULL;
-    char rcfile[LY_MAXPATH];
-    char *cp;
-    int number_sign;
-    char MBM_line[256];
-    int  MBM_counter;
-    char *MBM_cp2, *MBM_cp1;
-    int  MBM_i2;
-
-    if (!fp) {
-	/*
-	 *  Make an RC file name.
-	 */
-	LYAddPathToHome(rcfile, sizeof(rcfile), FNAME_LYNXRC);
+    CONST char *name;
+    int enabled;		/* see lynx.cfg ENABLE_LYNXRC */
+    Conf_Types type;
+    ParseData;
+    char **strings;
+    Config_Enum *table;
+    void (*write_it) PARAMS((FILE * fp, struct config_type *));
+    char *note;
+} Config_Type;
+
+PRIVATE int get_assume_charset ARGS1(char *, value)
+{
+    int i;
 
-	/*
-	 *  Open the RC file for reading.
-	 */
-	if ((fp = fopen(rcfile, TXT_R)) == NULL) {
-	    return;
+    for (i = 0; i < LYNumCharsets; ++i) {
+    	if (!strcasecomp(value, LYCharSet_UC[i].MIMEname)) {
+	    UCLYhndl_for_unspec = i;
+	    break;
 	}
     }
+    return 0;
+}
 
-    /*
-     *  Process the entries.
-     */
-    while (LYSafeGets(&line_buffer, fp) != NULL) {
-	/*
-	 *  Remove any trailing white space.
-	 */
-	LYTrimTrailing(line_buffer);
-
-	/*
-	 *  Skip any comment or blank lines.
-	 */
-	if (line_buffer[0] == '\0' || line_buffer[0] == '#')
-	    continue;
-
-	/*
-	 *  Find the line position of the number sign if there is one.
-	 */
-	if ((cp = (char *)strchr(line_buffer, '#')) == NULL)
-	    number_sign = strlen(line_buffer) + 100;
-	else
-	    number_sign = cp - line_buffer;
-
-	/*
-	 *  File editor.
-	 */
-	if (!system_editor && FIND_KEYWORD(cp, "file_editor")) {
-
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(editor, cp);
-
-	/*
-	 *  Default bookmark file.
-	 */
-	} else if (FIND_KEYWORD(cp, "bookmark_file")) {
-
-	    cp = SkipEquals(cp);
-
-	    /*
-	     *  Since this is the "Default Bookmark File", we save it
-	     *  as a globals, and as the first MBM_A_subbookmark entry.
-	     */
-	    StrAllocCopy(bookmark_page, cp);
-	    StrAllocCopy(BookmarkPage, cp);
-	    StrAllocCopy(MBM_A_subbookmark[0], cp);
-	    StrAllocCopy(MBM_A_subdescript[0], MULTIBOOKMARKS_DEFAULT);
-
-	/*
-	 *  Multiple (sub)bookmark support settings.
-	 */
-	} else if (FIND_KEYWORD(cp, "sub_bookmarks")) {
-
-	   cp = SkipEquals(cp);
-	   if (!strncasecomp(cp, "standard", 8)) {
-	      LYMultiBookmarks = TRUE;
-	      LYMBMAdvanced = FALSE;
-	   } else if (!strncasecomp(cp, "advanced", 8)) {
-	      LYMultiBookmarks = TRUE;
-	      LYMBMAdvanced = TRUE;
-	   } else {
-	      LYMultiBookmarks = FALSE;
-	   }
-
-	/*
-	 *  Multiple (sub)bookmark definitions and descriptions.
-	 */
-	} else if (FIND_KEYWORD(cp, "multi_bookmark")) {
-
-	    /*
-	     *  Found the root, now cycle through all the
-	     *	possible spaces and match specific ones.
-	     */
-	    for (MBM_counter = 1;
-		 MBM_counter <= MBM_V_MAXFILES; MBM_counter++) {
-		sprintf(MBM_line, "multi_bookmark%c", (MBM_counter + 'A'));
-
-		if (FIND_KEYWORD(cp, MBM_line)) {
-		    if ((MBM_cp1 = (char *)strchr(cp, '=')) == NULL) {
-			break;
-		    } else {
-			if ((MBM_cp2 = (char *)strchr(cp, ',')) == NULL) {
-			    break;
-			} else {
-			    MBM_i2 = 0;
-			    /*
-			     *  skip over the '='.
-			     */
-			    MBM_cp1++;
-			    while (MBM_cp1 && MBM_cp1 != MBM_cp2) {
-				/*
-				 *  Skip spaces.
-				 */
-				if (isspace(UCH(*MBM_cp1))) {
-				    MBM_cp1++;
-				    continue;
-				} else {
-				    MBM_line[MBM_i2++] = *MBM_cp1++;
-				}
-			    }
-			    MBM_line[MBM_i2++] = '\0';
-
-			    StrAllocCopy(MBM_A_subbookmark[MBM_counter],
-					 MBM_line);
-
-			    /*
-			     *  Now get the description ',' and ->.
-			     */
-			    MBM_cp1 = (char *)strchr(cp, ',');
-
-			    MBM_i2 = 0;
-			    /*
-			     *  Skip over the ','.
-			     */
-			    MBM_cp1++;
-			    /*
-			     *  Eat spaces in front of description.
-			     */
-			    MBM_cp1 = LYSkipBlanks(MBM_cp1);
-			    while (*MBM_cp1)
-				MBM_line[MBM_i2++] = *MBM_cp1++;
-			    MBM_line[MBM_i2++] = '\0';
-
-			    StrAllocCopy(MBM_A_subdescript[MBM_counter],
-					 MBM_line);
-
-			    break;
-			}
-		    }
-		}
-	    }
-
-	/*
-	 *  FTP/file sorting method.
-	 */
-	} else if (FIND_KEYWORD(cp, "file_sorting_method")) {
-
-	    getEnum(file_sort_tbl, cp, &HTfileSortMethod);
-
-	/*
-	 *  Personal mail address.
-	 */
-	} else if (FIND_KEYWORD(cp, "personal_mail_address")) {
-
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(personal_mail_address, cp);
-
-	/*
-	 *  Searching type.
-	 */
-	} else if (FIND_KEYWORD(cp, "case_sensitive_searching")) {
-
-	    case_sensitive = getBool(cp);
-
-	/*
-	 *  Character set.
-	 */
-	} else if (FIND_KEYWORD(cp, "character_set")) {
-
-	    int i = 0;
-
-	    cp = SkipEquals(cp);
-
-	    i = UCGetLYhndl_byAnyName(cp); /* by MIME or full name */
-	    if (i < 0)
-		; /* do nothing here: so fallback to lynx.cfg */
-	    else
-		current_char_set = i;
-
-	/*
-	 *  Preferred language.
-	 */
-	} else if (FIND_KEYWORD(cp, "preferred_language")) {
-
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(language, cp);
-
-	/*
-	 *  Preferred charset.
-	 */
-	} else if (FIND_KEYWORD(cp, "preferred_charset")) {
-
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(pref_charset, cp);
-
-	/*
-	 *  VI keys.
-	 */
-	} else if (FIND_KEYWORD(cp, "vi_keys")) {
-
-	    vi_keys = getBool(cp);
-
-	/*
-	 *  EMACS keys.
-	 */
-	} else if (FIND_KEYWORD(cp, "emacs_keys")) {
-
-	    emacs_keys = getBool(cp);
-
-	/*
-	 *  Show dot files.
-	 */
-	} else if (FIND_KEYWORD(cp, "show_dotfiles")) {
-
-	    show_dotfiles = getBool(cp);
-
-	/*
-	 *  Show color.
-	 */
-	} else if (FIND_KEYWORD(cp, "show_color")) {
-
-	    cp = SkipEquals(cp);
-	    if (!strncasecomp(cp, "always", 6)) {
-		LYrcShowColor = SHOW_COLOR_ALWAYS;
-#if defined(USE_SLANG) || defined(COLOR_CURSES)
-		if (LYShowColor != SHOW_COLOR_NEVER)
-		    LYShowColor = SHOW_COLOR_ALWAYS;
-#endif /* USE_SLANG || COLOR_CURSES */
-	    } else if (!strncasecomp(cp, "never", 5)) {
-		LYrcShowColor = SHOW_COLOR_NEVER;
-#if defined(COLOR_CURSES)
-		if (LYShowColor == SHOW_COLOR_ON)
-		    LYShowColor = SHOW_COLOR_OFF;
-#endif /* COLOR_CURSES */
-	    }
-
-	/*
-	 *  Select popups.
-	 */
-	} else if (FIND_KEYWORD(cp, "select_popups")) {
-
-	    cp = SkipEquals(cp);
-	    if (!strncasecomp(cp, "off", 3))
-		LYSelectPopups = FALSE;
-	    else
-		LYSelectPopups = TRUE;
-
-	/*
-	 *  Show cursor.
-	 */
-	} else if (FIND_KEYWORD(cp, "show_cursor")) {
-
-	    cp = SkipEquals(cp);
-	    if (!strncasecomp(cp, "off", 3))
-		LYShowCursor = FALSE;
-	    else
-		LYShowCursor = TRUE;
-
-	/*
-	 *  Keypad mode.
-	 */
-	} else if (FIND_KEYWORD(cp, "keypad_mode")) {
-
-	    if (!getEnum(keypad_mode_tbl, cp, &keypad_mode))
-		keypad_mode = DEFAULT_KEYPAD_MODE;
-
-	/*
-	 *  Keyboard layout.
-	 */
-#ifdef EXP_KEYBOARD_LAYOUT
-	} else if (FIND_KEYWORD(cp, "kblayout")) {
-
-	    int i = 0;
-
-	    cp = SkipEquals(cp);
-	    for (; LYKbLayoutNames[i]; i++) {
-		if (!strcmp(cp, LYKbLayoutNames[i])) {
-		    current_layout = i;
-		    break;
-		}
-	    }
-#endif /* EXP_KEYBOARD_LAYOUT */
-
-	/*
-	 *  Line edit mode.
-	 */
-	} else if (FIND_KEYWORD(cp, "lineedit_mode")) {
-
-	    int i = 0;
-
-	    cp = SkipEquals(cp);
-	    for (; LYLineeditNames[i]; i++) {
-		if (!strncmp(cp, LYLineeditNames[i], strlen(cp))) {
-		    current_lineedit = i;
-		    break;
-		}
-	    }
-
-#ifdef DIRED_SUPPORT
-	/*
-	 *  Directory list style.
-	 */
-	} else if (FIND_KEYWORD(cp, "dir_list_style")) {
-
-	    if (!getEnum(dir_list_style_tbl, cp, &dir_list_style))
-		dir_list_style = MIXED_STYLE;
-#endif /* DIRED_SUPPORT */
-
-	/*
-	 *  Accept cookies from all domains?
-	 */
-	} else if (FIND_KEYWORD(cp, "accept_all_cookies")) {
-	    LYAcceptAllCookies = getBool(cp);
-
-	/*
-	 *  Accept all cookies from certain domains?
-	 */
-	} else if (FIND_KEYWORD(cp, "cookie_accept_domains")) {
-	    cp = SkipEquals(cp);
-	    cookie_domain_flag_set(cp, FLAG_ACCEPT_ALWAYS);
-	    if(LYCookieAcceptDomains != NULL) {
-		StrAllocCat(LYCookieAcceptDomains, ",");
-	    }
-	    StrAllocCat(LYCookieAcceptDomains, cp);
-
-
-	/*
-	 *  Reject all cookies from certain domains?
-	 */
-	} else if (FIND_KEYWORD(cp, "cookie_reject_domains")) {
-	    cp = SkipEquals(cp);
-	    cookie_domain_flag_set(cp, FLAG_REJECT_ALWAYS);
-	    if(LYCookieRejectDomains != NULL) {
-		StrAllocCat(LYCookieRejectDomains, ",");
-	    }
-	    StrAllocCat(LYCookieRejectDomains, cp);
-
-	/*
-	 *  Cookie domains to perform loose checks?
-	 */
-	} else if (FIND_KEYWORD(cp, "cookie_loose_invalid_domains")) {
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(LYCookieLooseCheckDomains, cp);
-	    cookie_domain_flag_set(cp, FLAG_INVCHECK_LOOSE);
-
-	/*
-	 *  Cookie domains to perform strict checks?
-	 */
-	} else if (FIND_KEYWORD(cp, "cookie_strict_invalid_domains")) {
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(LYCookieStrictCheckDomains, cp);
-	    cookie_domain_flag_set(cp, FLAG_INVCHECK_STRICT);
-
-	/*
-	 *  Cookie domains to query user over invalid cookies?
-	 */
-	} else if (FIND_KEYWORD(cp, "cookie_query_invalid_domains")) {
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(LYCookieQueryCheckDomains, cp);
-	    cookie_domain_flag_set(cp, FLAG_INVCHECK_QUERY);
-
-#ifdef EXP_PERSISTENT_COOKIES
-	/*
-	 *  File from which to read persistent cookies.
-	 */
-	} else if (FIND_KEYWORD(cp, "cookie_file")) {
-	    cp = SkipEquals(cp);
-	    StrAllocCopy(LYCookieFile, cp);
-#endif /* EXP_PERSISTENT_COOKIES */
-
-	/*
-	 *  User mode.
-	 */
-	} else if (FIND_KEYWORD(cp, "user_mode")) {
-
-	    if (!getEnum(user_mode_tbl, cp, &user_mode))
-		user_mode = NOVICE_MODE;
-
-#ifdef NOTUSED
-#ifdef DISP_PARTIAL
-	/*
-	 *  Partial display logic--set the threshold # of lines before
-	 *  Lynx redraws the screen
-	 */
-	} else if (FIND_KEYWORD(cp, "partial_thres")) {
-	    cp = SkipEquals(cp);
-	    if (atoi(cp) != 0)
-		partial_threshold = atoi(cp);
-#endif /* DISP_PARTIAL */
-#endif /* NOTUSED */
-
-#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
-	/*
-	 *  Local execution mode - all links.
-	 */
-	} else if (FIND_KEYWORD(cp, "run_all_execution_links")) {
-
-	    local_exec = getBool(cp);
-
-	/*
-	 *  Local execution mode - only links in local files.
-	 */
-	} else if (FIND_KEYWORD(cp, "run_execution_links_on_local_files")) {
-	    local_exec_on_local_files = getBool(cp);
-#endif /* ENABLE_OPTS_CHANGE_EXEC */
-
-	} else if (FIND_KEYWORD(cp, "verbose_images")) {
-	    verbose_img = getBool(cp);
-
-	} else if (FIND_KEYWORD(cp, "visited_links")) {
-	    if (!getEnum(visited_links_tbl, cp, &Visited_Links_As))
-		Visited_Links_As = DEFAULT_VISITED_LINKS;
-
-	} /* end of if */
-
-    } /* end of while */
+PRIVATE void put_assume_charset ARGS2(FILE *, fp, struct config_type *, tbl)
+{
+    int i;
 
-    LYCloseInput(fp);
-} /* big end */
+    for (i = 0; i < LYNumCharsets; ++i)
+	fprintf(fp, "#    %s\n", LYCharSet_UC[i].MIMEname);
+    fprintf(fp, "%s=%s\n\n", tbl->name, LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
+}
 
-/*
- * Write a set of comments.  Doing it this way avoids preprocessor problems
- * with the leading '#', makes it simpler to use gettext.
- */
-PRIVATE void write_list ARGS2(
-    	FILE *,		fp,
-	char *,		list)
+PRIVATE int get_display_charset ARGS1(char *, value)
 {
-    int first = TRUE;
-    while (*list != 0) {
-	int ch = *list++;
-	if (ch == '\n') {
-	    first = TRUE;
-	} else {
-	    if (first) {
-		fputs("# ", fp);
-		first = FALSE;
-	    }
-	}
-	fputc(ch, fp);
-    }
+    int i = 0;
+
+    i = UCGetLYhndl_byAnyName(value); /* by MIME or full name */
+    if (i >= 0)
+	current_char_set = i;
+    return 0;
 }
 
-/*  Save user options.
- *  If the passed-in fp is NULL, open the regular user defaults file
- *  for writing, otherwise use fp which has to be a temp file open for
- *  writing. - kw
- */
-PUBLIC int save_rc ARGS1(FILE *, fp)
+PRIVATE void put_display_charset ARGS2(FILE *, fp, struct config_type *, tbl)
 {
-    char rcfile[LY_MAXPATH];
-    BOOLEAN is_tempfile = (fp != NULL);
     int i;
-    int MBM_c;
 
-    if (!fp) {
-	/*
-	 *  Make a name.
-	 */
-	LYAddPathToHome(rcfile, sizeof(rcfile), FNAME_LYNXRC);
+    for (i = 0; LYchar_set_names[i]; i++)
+	fprintf(fp, "#    %s\n", LYchar_set_names[i]);
+    fprintf(fp, "%s=%s\n\n", tbl->name, LYchar_set_names[current_char_set]);
+}
 
-	/*
-	 *  Open the file for write.
-	 */
-	if ((fp = LYNewTxtFile(rcfile)) == NULL) {
-	    return FALSE;
-	}
-    }
+PRIVATE int get_editor ARGS1(char *, value)
+{
+    if (!system_editor)
+	StrAllocCopy(editor, value);
+    return 0;
+}
 
-    /*
-     *  Header.
-     */
-    write_list(fp, gettext("\
-Lynx User Defaults File\n\
-\n\
-This file contains options saved from the Lynx Options Screen (normally\n\
-with the '>' key).  There is normally no need to edit this file manually,\n\
-since the defaults here can be controlled from the Options Screen, and the\n\
-next time options are saved from the Options Screen this file will be\n\
-completely rewritten.  You have been warned...\n\
-If you are looking for the general configuration file - it is normally\n\
-called lynx.cfg, and it has different content and a different format.\n\
-It is not this file.\n\
-"));
-    fprintf(fp, "\n");
+PRIVATE void put_editor ARGS2(FILE *, fp, struct config_type *, tbl)
+{
+    fprintf(fp, "%s=%s\n\n", tbl->name, NonNull(editor));
+}
 
-    /*
-     *  File editor
-     */
-    write_list(fp, gettext("\
+/* This table is searched ignoring case */
+static Config_Type Config_Table [] =
+{
+    MAYBE_ENU("DTD_recovery",          Old_DTD,            tbl_DTD_recovery,
+              MSG_ENABLE_LYNXRC),
+    PARSE_SET("accept_all_cookies",    LYAcceptAllCookies, N_("\
+accept_all_cookies allows the user to tell Lynx to automatically\n\
+accept all cookies if desired.  The default is \"FALSE\" which will\n\
+prompt for each cookie.  Set accept_all_cookies to \"TRUE\" to accept\n\
+all cookies.\n\
+")),
+    MAYBE_FUN("assume_char_set",       get_assume_charset, put_assume_charset, MSG_ENABLE_LYNXRC),
+    PARSE_STR("bookmark_file",         bookmark_page,     N_("\
+bookmark_file specifies the name and location of the default bookmark\n\
+file into which the user can paste links for easy access at a later\n\
+date.\n\
+")),
+    PARSE_SET("case_sensitive_searching", case_sensitive, N_("\
+If case_sensitive_searching is \"on\" then when the user invokes a search\n\
+using the 's' or '/' keys, the search performed will be case sensitive\n\
+instead of case INsensitive.  The default is usually \"off\".\n\
+")),
+    PARSE_FUN("character_set",         get_display_charset, put_display_charset, N_("\
+The character_set definition controls the representation of 8 bit\n\
+characters for your terminal.  If 8 bit characters do not show up\n\
+correctly on your screen you may try changing to a different 8 bit\n\
+set or using the 7 bit character approximations.\n\
+Current valid characters sets are:\n\
+")),
+    PARSE_LIS("cookie_accept_domains", LYCookieAcceptDomains, N_("\
+cookie_accept_domains and cookie_reject_domains are comma-delimited\n\
+lists of domains from which Lynx should automatically accept or reject\n\
+all cookies.  If a domain is specified in both options, rejection will\n\
+take precedence.  The accept_all_cookies parameter will override any\n\
+settings made here.\n\
+")),
+#ifdef EXP_PERSISTENT_COOKIES
+    PARSE_STR("cookie_file",	       LYCookieFile, N_("\
+cookie_file specifies the file from which to read persistent cookies.\n\
+The default is ~/.lynx_cookies.\n\
+")),
+#endif
+    PARSE_STR("cookie_loose_invalid_domains", LYCookieLooseCheckDomains, N_("\
+cookie_loose_invalid_domains, cookie_strict_invalid_domains, and\n\
+cookie_query_invalid_domains are comma-delimited lists of which domains\n\
+should be subjected to varying degrees of validity checking.  If a\n\
+domain is set to strict checking, strict conformance to RFC2109 will\n\
+be applied.  A domain with loose checking will be allowed to set cookies\n\
+with an invalid path or domain attribute.  All domains will default to\n\
+querying the user for an invalid path or domain.\n\
+")),
+    PARSE_STR("cookie_query_invalid_domains", LYCookieQueryCheckDomains, NULL),
+    PARSE_LIS("cookie_reject_domains", LYCookieRejectDomains, NULL),
+    PARSE_STR("cookie_strict_invalid_domains", LYCookieStrictCheckDomains, NULL),
+#ifdef DIRED_SUPPORT
+    PARSE_ENU("dir_list_style",        dir_list_style,     tbl_dir_list_style, N_("\
+dir_list_styles specifies the directory list style under DIRED_SUPPORT\n\
+(if implemented).  The default is \"MIXED_STYLE\", which sorts both\n\
+files and directories together.  \"FILES_FIRST\" lists files first and\n\
+\"DIRECTORIES_FIRST\" lists directories first.\n\
+")),
+#endif
+    MAYBE_STR("display",               x_display,          MSG_ENABLE_LYNXRC),
+    PARSE_SET("emacs_keys",            emacs_keys, N_("\
+If emacs_keys is to \"on\" then the normal EMACS movement keys:\n\
+  ^N = down    ^P = up\n\
+  ^B = left    ^F = right\n\
+will be enabled.\n\
+")),
+    PARSE_FUN("file_editor",           get_editor,         put_editor, N_("\
 file_editor specifies the editor to be invoked when editing local files\n\
 or sending mail.  If no editor is specified, then file editing is disabled\n\
 unless it is activated from the command line, and the built-in line editor\n\
 will be used for sending mail.\n\
-"));
-    fprintf(fp, "file_editor=%s\n\n", (editor ? editor : ""));
-
-    /*
-     *  Default bookmark file.
-     */
-    write_list(fp, gettext("\
-bookmark_file specifies the name and location of the default bookmark\n\
-file into which the user can paste links for easy access at a later\n\
-date.\n\
-"));
-    fprintf(fp, "bookmark_file=%s\n\n", (bookmark_page ? bookmark_page : ""));
-
-    /*
-     *  Multiple (sub)bookmark support settings.
-     */
-    write_list(fp, gettext("\
-If sub_bookmarks is not turned \"off\", and multiple bookmarks have\n\
-been defined (see below), then all bookmark operations will first\n\
-prompt the user to select an active sub-bookmark file.  If the default\n\
-Lynx bookmark_file is defined (see above), it will be used as the\n\
-default selection.  When this option is set to \"advanced\", and the\n\
-user mode is advanced, the 'v'iew bookmark command will invoke a\n\
-statusline prompt instead of the menu seen in novice and intermediate\n\
-user modes.  When this option is set to \"standard\", the menu will be\n\
-presented regardless of user mode.\n\
-"));
-    fprintf(fp, "sub_bookmarks=%s\n\n", (LYMultiBookmarks ?
-					   (LYMBMAdvanced ?
-					       "advanced" : "standard")
-							  : "off"));
-
-    /*
-     *  Multiple (sub)bookmark definitions and descriptions.
-     */
-    write_list(fp, gettext("\
-The following allow you to define sub-bookmark files and descriptions.\n\
-The format is multi_bookmark<capital_letter>=<filename>,<description>\n\
-Up to 26 bookmark files (for the English capital letters) are allowed.\n\
-We start with \"multi_bookmarkB\" since 'A' is the default (see above).\n\
-"));
-    for (MBM_c = 1; MBM_c <= MBM_V_MAXFILES; MBM_c++)
-       fprintf(fp, "multi_bookmark%c=%s%s%s\n",
-		   (MBM_c + 'A'),
-		   (MBM_A_subbookmark[MBM_c] ?
-		    MBM_A_subbookmark[MBM_c] : ""),
-		   (MBM_A_subbookmark[MBM_c] ?
-					 "," : ""),
-		   (MBM_A_subdescript[MBM_c] ?
-		    MBM_A_subdescript[MBM_c] : ""));
-    fprintf(fp, "\n");
-
-    /*
-     *  FTP/file sorting method.
-     */
-    write_list(fp, gettext("\
+")),
+    PARSE_ENU("file_sorting_method",   HTfileSortMethod,   tbl_file_sort, N_("\
 The file_sorting_method specifies which value to sort on when viewing\n\
 file lists such as FTP directories.  The options are:\n\
    BY_FILENAME -- sorts on the name of the file\n\
    BY_TYPE     -- sorts on the type of the file\n\
    BY_SIZE     -- sorts on the size of the file\n\
    BY_DATE     -- sorts on the date of the file\n\
-"));
-    fprintf(fp, "file_sorting_method=%s\n\n",
-		putEnum(file_sort_tbl, HTfileSortMethod));
-
-    /*
-     *  Personal mail address.
-     */
-    write_list(fp, gettext("\
+")),
+#ifdef EXP_KEYBOARD_LAYOUT
+    PARSE_ARY("kblayout",              current_layout,     LYKbLayoutNames, NULL),
+#endif
+    PARSE_ENU("keypad_mode",           keypad_mode,        tbl_keypad_mode, NULL),
+    PARSE_ARY("lineedit_mode",         current_lineedit,   LYLineeditNames, N_("\
+lineedit_mode specifies the key binding used for inputting strings in\n\
+prompts and forms.  If lineedit_mode is set to \"Default Binding\" then\n\
+the following control characters are used for moving and deleting:\n\
+\n\
+             Prev  Next       Enter = Accept input\n\
+   Move char: <-    ->        ^G    = Cancel input\n\
+   Move word: ^P    ^N        ^U    = Erase line\n\
+ Delete char: ^H    ^R        ^A    = Beginning of line\n\
+ Delete word: ^B    ^F        ^E    = End of line\n\
+\n\
+Current lineedit modes are:\n\
+")),
+    MAYBE_SET("make_pseudo_alts_for_inlines", pseudo_inline_alts, MSG_ENABLE_LYNXRC),
+    MAYBE_SET("make_links_for_all_images", clickable_images, MSG_ENABLE_LYNXRC),
+    PARSE_MBM("multi_bookmark", N_("\
+The following allow you to define sub-bookmark files and descriptions.\n\
+The format is multi_bookmark<capital_letter>=<filename>,<description>\n\
+Up to 26 bookmark files (for the English capital letters) are allowed.\n\
+We start with \"multi_bookmarkB\" since 'A' is the default (see above).\n\
+")),
+    PARSE_STR("personal_mail_address", personal_mail_address, N_("\
 personal_mail_address specifies your personal mail address.  The\n\
 address will be sent during HTTP file transfers for authorization and\n\
 logging purposes, and for mailed comments.\n\
@@ -704,51 +350,8 @@ If you do not want this information given out, set the NO_FROM_HEADER\n\
 to TRUE in lynx.cfg, or use the -nofrom command line switch.  You also\n\
 could leave this field blank, but then you won't have it included in\n\
 your mailed comments.\n\
-"));
-    fprintf(fp, "personal_mail_address=%s\n\n",
-		(personal_mail_address ? personal_mail_address : ""));
-
-    /*
-     *  Searching type.
-     */
-    write_list(fp, gettext("\
-If case_sensitive_searching is \"on\" then when the user invokes a search\n\
-using the 's' or '/' keys, the search performed will be case sensitive\n\
-instead of case INsensitive.  The default is usually \"off\".\n\
-"));
-    fprintf(fp, "case_sensitive_searching=%s\n\n", putBool(case_sensitive));
-
-    /*
-     *  Character set.
-     */
-    write_list(fp, gettext("\
-The character_set definition controls the representation of 8 bit\n\
-characters for your terminal.  If 8 bit characters do not show up\n\
-correctly on your screen you may try changing to a different 8 bit\n\
-set or using the 7 bit character approximations.\n\
-Current valid characters sets are:\n\
-"));
-    for (i = 0; LYchar_set_names[i]; i++)
-	fprintf(fp, "#    %s\n", LYchar_set_names[i]);
-    fprintf(fp, "character_set=%s\n\n", LYchar_set_names[current_char_set]);
-
-
-    /*
-     *  Preferred language.
-     */
-    write_list(fp, gettext("\
-preferred_language specifies the language in MIME notation (e.g., en,\n\
-fr, may be a comma-separated list in decreasing preference)\n\
-which Lynx will indicate you prefer in requests to http servers.\n\
-If a file in that language is available, the server will send it.\n\
-Otherwise, the server will send the file in it's default language.\n\
-"));
-    fprintf(fp, "preferred_language=%s\n\n", (language ? language : ""));
-
-    /*
-     *  Preferred charset.
-     */
-    write_list(fp, gettext("\
+")),
+    PARSE_STR("preferred_charset",     pref_charset, N_("\
 preferred_charset specifies the character set in MIME notation (e.g.,\n\
 ISO-8859-2, ISO-8859-5) which Lynx will indicate you prefer in requests\n\
 to http servers using an Accept-Charset header.  The value should NOT\n\
@@ -761,15 +364,53 @@ and if the server cannot send a response which is acceptable\n\
 according to the Accept-Charset header, then the server SHOULD send\n\
 an error response, though the sending of an unacceptable response\n\
 is also allowed.\n\
-"));
-    fprintf(fp, "preferred_charset=%s\n\n",
-		(pref_charset ? pref_charset : ""));
-
-    /*
-     *  Show color.
-     */
-    if (LYChosenShowColor != SHOW_COLOR_UNKNOWN) {
-	write_list(fp, gettext("\
+")),
+    PARSE_STR("preferred_language",    language, N_("\
+preferred_language specifies the language in MIME notation (e.g., en,\n\
+fr, may be a comma-separated list in decreasing preference)\n\
+which Lynx will indicate you prefer in requests to http servers.\n\
+If a file in that language is available, the server will send it.\n\
+Otherwise, the server will send the file in it's default language.\n\
+")),
+    MAYBE_SET("raw_mode",              LYRawMode,          MSG_ENABLE_LYNXRC),
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+    PARSE_SET("run_all_execution_links", local_exec, N_("\
+If run_all_execution_links is set \"on\" then all local execution links\n\
+will be executed when they are selected.\n\
+\n\
+WARNING - This is potentially VERY dangerous.  Since you may view\n\
+          information that is written by unknown and untrusted sources\n\
+          there exists the possibility that Trojan horse links could be\n\
+          written.  Trojan horse links could be written to erase files\n\
+          or compromise security.  This should only be set to \"on\" if\n\
+          you are viewing trusted source information.\n\
+")),
+    PARSE_SET("run_execution_links_on_local_files", local_exec_on_local_files, N_("\
+If run_execution_links_on_local_files is set \"on\" then all local\n\
+execution links that are found in LOCAL files will be executed when they\n\
+are selected.  This is different from run_all_execution_links in that\n\
+only files that reside on the local system will have execution link\n\
+permissions.\n\
+\n\
+WARNING - This is potentially dangerous.  Since you may view\n\
+          information that is written by unknown and untrusted sources\n\
+          there exists the possibility that Trojan horse links could be\n\
+          written.  Trojan horse links could be written to erase files\n\
+          or compromise security.  This should only be set to \"on\" if\n\
+          you are viewing trusted source information.\n\
+")),
+#endif
+    PARSE_SET("select_popups",         LYSelectPopups, N_("\
+select_popups specifies whether the OPTIONs in a SELECT block which\n\
+lacks a MULTIPLE attribute are presented as a vertical list of radio\n\
+buttons or via a popup menu.  Note that if the MULTIPLE attribute is\n\
+present in the SELECT start tag, Lynx always will create a vertical list\n\
+of checkboxes for the OPTIONs.  A value of \"on\" will set popup menus\n\
+as the default while a value of \"off\" will set use of radio boxes.\n\
+The default can be overridden via the -popup command line toggle.\n\
+")),
+    MAYBE_SET("set_cookies",           LYSetCookies,      MSG_ENABLE_LYNXRC),
+    PARSE_ENU("show_color",            LYrcShowColor,     tbl_show_colors, N_("\
 show_color specifies how to set the color mode at startup.  A value of\n\
 \"never\" will force color mode off (treat the terminal as monochrome)\n\
 at startup even if the terminal appears to be color capable.  A value of\n\
@@ -785,82 +426,270 @@ the -color and -nocolor command line switches.\n\
 The mode set at startup can be changed via the \"show color\" option in\n\
 the 'o'ptions menu.  If the option settings are saved, the \"on\" and\n\
 \"off\" \"show color\" settings will be treated as \"default\".\n\
-"));
-     fprintf(fp, "show_color=%s\n\n",
-	     ((LYChosenShowColor == SHOW_COLOR_NEVER  ? "never"  :
-	       (LYChosenShowColor == SHOW_COLOR_ALWAYS ? "always" :
-						      "default"))));
-    }
-
-    /*
-     *  VI keys.
-     */
-    write_list(fp, gettext("\
+")),
+    PARSE_SET("show_cursor",           LYShowCursor, N_("\
+show_cursor specifies whether to 'hide' the cursor to the right (and\n\
+bottom, if possible) of the screen, or to place it to the left of the\n\
+current link in documents, or current option in select popup windows.\n\
+Positioning the cursor to the left of the current link or option is\n\
+helpful for speech or braille interfaces, and when the terminal is\n\
+one which does not distinguish the current link based on highlighting\n\
+or color.  A value of \"on\" will set positioning to the left as the\n\
+default while a value of \"off\" will set 'hiding' of the cursor.\n\
+The default can be overridden via the -show_cursor command line toggle.\n\
+")),
+    PARSE_SET("show_dotfiles",         show_dotfiles, N_("\
+show_dotfiles specifies that the directory listing should include\n\
+\"hidden\" (dot) files/directories.  If set \"on\", this will be\n\
+honored only if enabled via userdefs.h and/or lynx.cfg, and not\n\
+restricted via a command line switch.  If display of hidden files\n\
+is disabled, creation of such files via Lynx also is disabled.\n\
+")),
+#ifdef EXP_READPROGRESS
+    MAYBE_ENU("show_rate",             LYTransferRate,    tbl_transfer_rate,
+	      MSG_ENABLE_LYNXRC),
+#endif
+    PARSE_ENU("sub_bookmarks",         LYMultiBookmarks,  tbl_multi_bookmarks, N_("\
+If sub_bookmarks is not turned \"off\", and multiple bookmarks have\n\
+been defined (see below), then all bookmark operations will first\n\
+prompt the user to select an active sub-bookmark file.  If the default\n\
+Lynx bookmark_file is defined (see above), it will be used as the\n\
+default selection.  When this option is set to \"advanced\", and the\n\
+user mode is advanced, the 'v'iew bookmark command will invoke a\n\
+statusline prompt instead of the menu seen in novice and intermediate\n\
+user modes.  When this option is set to \"standard\", the menu will be\n\
+presented regardless of user mode.\n\
+")),
+    MAYBE_STR("user_agent",            LYUserAgent,        MSG_ENABLE_LYNXRC),
+    PARSE_ENU("user_mode",             user_mode,          tbl_user_mode, N_("\
+user_mode specifies the users level of knowledge with Lynx.  The\n\
+default is \"NOVICE\" which displays two extra lines of help at the\n\
+bottom of the screen to aid the user in learning the basic Lynx\n\
+commands.  Set user_mode to \"INTERMEDIATE\" to turn off the extra info.\n\
+Use \"ADVANCED\" to see the URL of the currently selected link at the\n\
+bottom of the screen.\n\
+")),
+    PARSE_SET("verbose_images",        verbose_img, N_("\
+If verbose_images is \"on\", lynx will print the name of the image\n\
+source file in place of [INLINE], [LINK] or [IMAGE]\n\
+See also VERBOSE_IMAGES in lynx.cfg\n\
+")),
+    PARSE_SET("vi_keys",               vi_keys, N_("\
 If vi_keys is set to \"on\", then the normal VI movement keys:\n\
   j = down    k = up\n\
   h = left    l = right\n\
 will be enabled.  These keys are only lower case.\n\
 Capital 'H', 'J' and 'K will still activate help, jump shortcuts,\n\
 and the keymap display, respectively.\n\
-"));
-     fprintf(fp, "vi_keys=%s\n\n", putBool(vi_keys));
+")),
+    PARSE_ENU("visited_links",         Visited_Links_As,   tbl_visited_links, N_("\
+The visited_links setting controls how Lynx organizes the information\n\
+in the Visited Links Page.\n\
+")),
 
-    /*
-     *  EMACS keys.
-     */
-    write_list(fp, gettext("\
-If emacs_keys is to \"on\" then the normal EMACS movement keys:\n\
-  ^N = down    ^P = up\n\
-  ^B = left    ^F = right\n\
-will be enabled.\n\
-"));
-    fprintf(fp, "emacs_keys=%s\n\n", putBool(emacs_keys));
+    PARSE_NIL
+};
 
-    /*
-     *  Show dot files.
-     */
-    write_list(fp, gettext("\
-show_dotfiles specifies that the directory listing should include\n\
-\"hidden\" (dot) files/directories.  If set \"on\", this will be\n\
-honored only if enabled via userdefs.h and/or lynx.cfg, and not\n\
-restricted via a command line switch.  If display of hidden files\n\
-is disabled, creation of such files via Lynx also is disabled.\n\
-"));
-    fprintf(fp, "show_dotfiles=%s\n\n", putBool(show_dotfiles));
+PRIVATE Config_Type *lookup_config ARGS1(
+	char *,		name)
+{
+    Config_Type *tbl = Config_Table;
+    char ch = (char) TOUPPER(*name);
 
-    /*
-     *  Select popups.
-     */
-    write_list(fp, gettext("\
-select_popups specifies whether the OPTIONs in a SELECT block which\n\
-lacks a MULTIPLE attribute are presented as a vertical list of radio\n\
-buttons or via a popup menu.  Note that if the MULTIPLE attribute is\n\
-present in the SELECT start tag, Lynx always will create a vertical list\n\
-of checkboxes for the OPTIONs.  A value of \"on\" will set popup menus\n\
-as the default while a value of \"off\" will set use of radio boxes.\n\
-The default can be overridden via the -popup command line toggle.\n\
-"));
-    fprintf(fp, "select_popups=%s\n\n", putBool(LYSelectPopups));
+    while (tbl->name != 0) {
+	if (tbl->enabled) {
+	    char ch1 = tbl->name[0];
+
+	    if ((ch == TOUPPER(ch1))
+		&& (0 == strcasecomp (name, tbl->name)))
+		break;
+	}
+
+	tbl++;
+    }
+    return tbl;
+}
+
+/*  Read and process user options.
+ *  If the passed-in fp is NULL, open the regular user defaults file
+ *  for reading, otherwise use fp which has to be a file open for
+ *  reading. - kw
+ */
+PUBLIC void read_rc ARGS1(FILE *, fp)
+{
+    char *buffer = NULL;
+    char rcfile[LY_MAXPATH];
+    char MBM_line[256];
+    int  n;
+
+    if (!fp) {
+	/*
+	 *  Make an RC file name, open it for reading.
+	 */
+	LYAddPathToHome(rcfile, sizeof(rcfile), FNAME_LYNXRC);
+	if ((fp = fopen(rcfile, TXT_R)) == NULL) {
+	    return;
+	}
+    }
 
     /*
-     *  Show cursor.
+     *  Process the entries.
      */
-    write_list(fp, gettext("\
-show_cursor specifies whether to 'hide' the cursor to the right (and\n\
-bottom, if possible) of the screen, or to place it to the left of the\n\
-current link in documents, or current option in select popup windows.\n\
-Positioning the cursor to the left of the current link or option is\n\
-helpful for speech or braille interfaces, and when the terminal is\n\
-one which does not distinguish the current link based on highlighting\n\
-or color.  A value of \"on\" will set positioning to the left as the\n\
-default while a value of \"off\" will set 'hiding' of the cursor.\n\
-The default can be overridden via the -show_cursor command line toggle.\n\
-"));
-    fprintf(fp, "show_cursor=%s\n\n", putBool(LYShowCursor));
+    while (LYSafeGets(&buffer, fp) != NULL) {
+	char *name, *value, *notes;
+	Config_Type *tbl;
+	ParseUnionPtr q;
+
+	/* Most lines in the config file are comment lines.  Weed them out
+	 * now.  Also, leading whitespace is ok, so trim it.
+	 */
+	LYTrimTrailing(buffer);
+	name = LYSkipBlanks(buffer);
+	if (ispunct(UCH(*name)) || *name == '\0')
+	    continue;
+
+	/*
+	 * Parse the "name=value" strings.
+	 */
+	if ((value = strchr(name, '=')) == 0)
+	    continue;
+	*value++ = '\0';
+	LYTrimTrailing(name);
+	value = LYSkipBlanks(value);
+	tbl = lookup_config(name);
+	if (tbl->name == 0) {
+	    char *special = "multi_bookmark";
+	    if (!strncasecomp(name, special, strlen(special))) {
+		tbl = lookup_config(special);
+	    }
+	    /* lynx ignores unknown keywords */
+	    if (tbl->name == 0)
+		continue;
+	}
+
+	q = ParseUnionOf(tbl);
+	switch (tbl->type) {
+	case CONF_BOOL:
+	    if (q->set_value != 0)
+		*(q->set_value) = getBool (value);
+	    break;
+
+	case CONF_FUN:
+	    if (q->fun_value != 0)
+		(*(q->fun_value)) (value);
+	    break;
+
+	case CONF_ARRAY:
+	    for (n = 0; tbl->strings[n] != 0; ++n) {
+		if (!strcasecomp(value, tbl->strings[n])) {
+		    *(q->int_value) = n;
+		    break;
+		}
+	    }
+	    break;
+
+	case CONF_ENUM:
+	    if (tbl->table != 0)
+		LYgetEnum(tbl->table, value, q->int_value);
+	    break;
+
+	case CONF_INT:
+	    if (q->int_value != 0) {
+		int ival;
+		if (1 == sscanf (value, "%d", &ival))
+		    *(q->int_value) = ival;
+	    }
+	    break;
+
+	case CONF_LIS:
+	    if (q->str_value != 0) {
+		if (*(q->str_value) != NULL)
+		    StrAllocCat(*(q->str_value), ",");
+		StrAllocCat(*(q->str_value), value);
+	    }
+	    break;
+
+	case CONF_MBM:
+	    for (n = 1; n <= MBM_V_MAXFILES; n++) {
+		sprintf(MBM_line, "multi_bookmark%c", LYindex2MBM(n));
+
+		if (!strcasecomp(name, MBM_line)) {
+		    if ((notes = strchr(value, ',')) != 0) {
+			*notes++ = '\0';
+			LYTrimTrailing(value);
+			notes = LYSkipBlanks(notes);
+		    } else {
+			notes = value + strlen(value);
+		    }
+		    StrAllocCopy(MBM_A_subbookmark[n], value);
+		    StrAllocCopy(MBM_A_subdescript[n], notes);
+		    break;
+		}
+	    }
+	    break;
+
+	case CONF_STR:
+	    if (q->str_value != 0)
+		StrAllocCopy(*(q->str_value), value);
+	    break;
 
+	case CONF_UNSPECIFIED:
+	    break;
+	}
+    }
+
+    LYCloseInput(fp);
+    LYConfigCookies();	/* update cookie settings, if any */
+
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
     /*
-     *  Keypad mode.
+     * We may override the commandline "-color" option with the .lynxrc file
      */
+    switch (LYrcShowColor) {
+    case SHOW_COLOR_ALWAYS:
+	if (LYShowColor != SHOW_COLOR_NEVER)
+	    LYShowColor = SHOW_COLOR_ALWAYS;
+	break;
+    case SHOW_COLOR_NEVER:
+	if (LYShowColor == SHOW_COLOR_ON)
+	    LYShowColor = SHOW_COLOR_OFF;
+	break;
+    default:
+	/* don't override */
+	break;
+    }
+#endif
+    set_default_bookmark_page(bookmark_page);
+}
+
+/*
+ * Write a set of comments.  Doing it this way avoids preprocessor problems
+ * with the leading '#', makes it simpler to use gettext.
+ */
+PRIVATE void write_list ARGS2(
+    	FILE *,		fp,
+	char *,		list)
+{
+    int first = TRUE;
+    while (*list != 0) {
+	int ch = *list++;
+	if (ch == '\n') {
+	    first = TRUE;
+	} else {
+	    if (first) {
+		fputs("# ", fp);
+		first = FALSE;
+	    }
+	}
+	fputc(ch, fp);
+    }
+}
+
+/*
+ * This is too long for some compilers.
+ */
+PRIVATE void explain_keypad_mode ARGS1(FILE *, fp)
+{
     write_list(fp, gettext("\
 If keypad_mode is set to \"NUMBERS_AS_ARROWS\", then the numbers on\n\
 your keypad when the numlock is on will act as arrow keys:\n\
@@ -888,191 +717,113 @@ NOTE: Some fixed format documents may look disfigured when\n\
 \"LINKS_ARE_NUMBERED\" or \"LINKS_AND_FORM_FIELDS_ARE_NUMBERED\" are\n\
 enabled.\n\
 "));
-    fprintf(fp, "keypad_mode=%s\n\n", putEnum(keypad_mode_tbl, keypad_mode));
+}
 
-#ifdef NOTUSED
-#ifdef DISP_PARTIAL
-    /*
-     *  Partial display threshold
-     */
-    write_list(fp, gettext("\
-partial_thres specifies the number of lines Lynx should download and render\n\
-before we redraw the screen in Partial Display logic\n\
-e.g., partial_thres=2\n\
-would have Lynx redraw every 2 lines that it renders\n\
-partial_thres=-1 would use the entire screensize\n\
-"));
-    fprintf(fp, "partial_thres=%d\n\n", partial_threshold);
-#endif /* DISP_PARTIAL */
-#endif /* NOTUSED */
+/*  Save user options.
+ *  If the passed-in fp is NULL, open the regular user defaults file
+ *  for writing, otherwise use fp which has to be a temp file open for
+ *  writing. - kw
+ */
+PUBLIC int save_rc ARGS1(FILE *, fp)
+{
+    Config_Type *tbl = Config_Table;
+    char rcfile[LY_MAXPATH];
+    BOOLEAN is_tempfile = (BOOL) (fp != NULL);
+    int n;
 
-    /*
-     *  Line edit mode.
-     */
-    write_list(fp, gettext("\
-lineedit_mode specifies the key binding used for inputting strings in\n\
-prompts and forms.  If lineedit_mode is set to \"Default Binding\" then\n\
-the following control characters are used for moving and deleting:\n\
-\n\
-             Prev  Next       Enter = Accept input\n\
-   Move char: <-    ->        ^G    = Cancel input\n\
-   Move word: ^P    ^N        ^U    = Erase line\n\
- Delete char: ^H    ^R        ^A    = Beginning of line\n\
- Delete word: ^B    ^F        ^E    = End of line\n\
-\n\
-Current lineedit modes are:\n\
-"));
-    {
-	char **bindings = LYLineeditNames;
-	while (*bindings) {
-	    fprintf(fp, "#    %s\n", *bindings);
-	    bindings++;
+    if (!fp) {
+	/*
+	 *  Make a name.
+	 */
+	LYAddPathToHome(rcfile, sizeof(rcfile), FNAME_LYNXRC);
+
+	/*
+	 *  Open the file for write.
+	 */
+	if ((fp = LYNewTxtFile(rcfile)) == NULL) {
+	    return FALSE;
 	}
     }
-    fprintf(fp, "lineedit_mode=%s\n\n", LYLineeditNames[current_lineedit]);
-#ifdef EXP_KEYBOARD_LAYOUT
-    fprintf(fp, "kblayout=%s\n\n", LYKbLayoutNames[current_layout]);
-#endif
-
-#ifdef DIRED_SUPPORT
-    /*
-     *  Directory list style.
-     */
-    write_list(fp, gettext("\
-dir_list_styles specifies the directory list style under DIRED_SUPPORT\n\
-(if implemented).  The default is \"MIXED_STYLE\", which sorts both\n\
-files and directories together.  \"FILES_FIRST\" lists files first and\n\
-\"DIRECTORIES_FIRST\" lists directories first.\n\
-"));
-    fprintf(fp, "dir_list_style=%s\n\n",
-		putEnum(dir_list_style_tbl, dir_list_style));
-#endif /* DIRED_SUPPORT */
-
-    /*
-     *  User mode.
-     */
-    write_list(fp, gettext("\
-user_mode specifies the users level of knowledge with Lynx.  The\n\
-default is \"NOVICE\" which displays two extra lines of help at the\n\
-bottom of the screen to aid the user in learning the basic Lynx\n\
-commands.  Set user_mode to \"INTERMEDIATE\" to turn off the extra info.\n\
-Use \"ADVANCED\" to see the URL of the currently selected link at the\n\
-bottom of the screen.\n\
-"));
-    fprintf(fp, "user_mode=%s\n\n",
-		putEnum(user_mode_tbl, user_mode));
-
-    /*
-     *  Cookie options
-     */
-    write_list(fp, gettext("\
-accept_all_cookies allows the user to tell Lynx to automatically\n\
-accept all cookies if desired.  The default is \"FALSE\" which will\n\
-prompt for each cookie.  Set accept_all_cookies to \"TRUE\" to accept\n\
-all cookies.\n\
-"));
-    fprintf(fp, "accept_all_cookies=%s\n\n", putBool(LYAcceptAllCookies));
-
-    write_list(fp, gettext("\
-cookie_accept_domains and cookie_reject_domains are comma-delimited\n\
-lists of domains from which Lynx should automatically accept or reject\n\
-all cookies.  If a domain is specified in both options, rejection will\n\
-take precedence.  The accept_all_cookies parameter will override any\n\
-settings made here.\n\
-"));
-    fprintf(fp, "cookie_accept_domains=%s\n",
-		    (LYCookieAcceptDomains == NULL ? ""
-		    : LYCookieAcceptDomains));
-    fprintf(fp, "cookie_reject_domains=%s\n\n",
-		    (LYCookieRejectDomains == NULL ? ""
-		    : LYCookieRejectDomains));
-
-
-    write_list(fp, gettext("\
-cookie_loose_invalid_domains, cookie_strict_invalid_domains, and\n\
-cookie_query_invalid_domains are comma-delimited lists of which domains\n\
-should be subjected to varying degrees of validity checking.  If a\n\
-domain is set to strict checking, strict conformance to RFC2109 will\n\
-be applied.  A domain with loose checking will be allowed to set cookies\n\
-with an invalid path or domain attribute.  All domains will default to\n\
-querying the user for an invalid path or domain.\n\
-"));
-    fprintf(fp, "cookie_loose_invalid_domains=%s\n",
-	    (LYCookieLooseCheckDomains == NULL) ? ""
-		    : LYCookieLooseCheckDomains);
-    fprintf(fp, "cookie_strict_invalid_domains=%s\n",
-	    (LYCookieStrictCheckDomains == NULL) ? ""
-		    : LYCookieStrictCheckDomains);
-    fprintf(fp, "cookie_query_invalid_domains=%s\n\n",
-	    (LYCookieQueryCheckDomains == NULL) ? ""
-		    : LYCookieQueryCheckDomains);
 
-
-#ifdef EXP_PERSISTENT_COOKIES
-    /*
-     *  Cookie read file.
-     */
-    write_list(fp, gettext("\
-cookie_file specifies the file from which to read persistent cookies.\n\
-The default is ~/.lynx_cookies.\n\
-"));
-    fprintf(fp, "cookie_file=%s\n\n",
-		(LYCookieFile == NULL ? "~/.lynx_cookies" : LYCookieFile));
-#endif /* EXP_PERSISTENT_COOKIES */
-
-
-
-#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
-    /*
-     *  Local execution mode - all links.
-     */
     write_list(fp, gettext("\
-If run_all_execution_links is set \"on\" then all local execution links\n\
-will be executed when they are selected.\n\
+Lynx User Defaults File\n\
 \n\
-WARNING - This is potentially VERY dangerous.  Since you may view\n\
-          information that is written by unknown and untrusted sources\n\
-          there exists the possibility that Trojan horse links could be\n\
-          written.  Trojan horse links could be written to erase files\n\
-          or compromise security.  This should only be set to \"on\" if\n\
-          you are viewing trusted source information.\n\
+This file contains options saved from the Lynx Options Screen (normally\n\
+with the '>' key).  There is normally no need to edit this file manually,\n\
+since the defaults here can be controlled from the Options Screen, and the\n\
+next time options are saved from the Options Screen this file will be\n\
+completely rewritten.  You have been warned...\n\
+If you are looking for the general configuration file - it is normally\n\
+called lynx.cfg, and it has different content and a different format.\n\
+It is not this file.\n\
 "));
-    fprintf(fp, "run_all_execution_links=%s\n\n", putBool(local_exec));
+    fprintf(fp, "\n");
 
-    /*
-     *  Local execution mode - only links in local files.
-     */
-    write_list(fp, gettext("\
-If run_execution_links_on_local_files is set \"on\" then all local\n\
-execution links that are found in LOCAL files will be executed when they\n\
-are selected.  This is different from run_all_execution_links in that\n\
-only files that reside on the local system will have execution link\n\
-permissions.\n\
-\n\
-WARNING - This is potentially dangerous.  Since you may view\n\
-          information that is written by unknown and untrusted sources\n\
-          there exists the possibility that Trojan horse links could be\n\
-          written.  Trojan horse links could be written to erase files\n\
-          or compromise security.  This should only be set to \"on\" if\n\
-          you are viewing trusted source information.\n\
-"));
-    fprintf(fp, "run_execution_links_on_local_files=%s\n\n",
-		putBool(local_exec_on_local_files));
-#endif /* defined(EXEC_LINKS) || defined(EXEC_SCRIPTS) */
+    while (tbl->name != 0) {
+	ParseUnionPtr q = ParseUnionOf(tbl);
 
-    write_list(fp, gettext("\
-If verbose_images is \"on\", lynx will print the name of the image\n\
-source file in place of [INLINE], [LINK] or [IMAGE]\n\
-See also VERBOSE_IMAGES in lynx.cfg\n\
-"));
-    fprintf(fp, "verbose_images=%s\n\n", putBool(verbose_img));
+	if (!tbl->enabled) {
+	    tbl++;
+	    continue;
+	} if (tbl->note != NULL) {
+	    write_list(fp, gettext(tbl->note));
+	} else if (tbl->table == tbl_keypad_mode) {
+	    explain_keypad_mode(fp);
+	}
 
-    write_list(fp, gettext("\
-The visited_links setting controls how Lynx organizes the information\n\
-in the Visited Links Page.\n\
-"));
-    fprintf(fp, "visited_links=%s\n\n",
-	    putEnum(visited_links_tbl, Visited_Links_As));
+	switch (tbl->type) {
+	case CONF_BOOL:
+	    fprintf(fp, "%s=%s\n\n", tbl->name, putBool(*(q->set_value)));
+	    break;
+
+	case CONF_FUN:
+	    if (tbl->write_it != 0)
+		tbl->write_it(fp, tbl);
+	    break;
+
+	case CONF_ARRAY:
+	    for (n = 0; tbl->strings[n] != 0; ++n)
+		fprintf(fp, "#    %s\n", tbl->strings[n]);
+	    fprintf(fp, "%s=%s\n\n", tbl->name,
+		    tbl->strings[*(q->int_value)]);
+	    break;
+
+	case CONF_ENUM:
+	    fprintf(fp, "%s=%s\n\n", tbl->name,
+		    LYputEnum(tbl->table, *(q->int_value)));
+	    break;
+
+	case CONF_INT:
+	    fprintf(fp, "%s=%d\n\n", tbl->name, *(q->int_value));
+	    break;
+
+	case CONF_MBM:
+	    for (n = 1; n <= MBM_V_MAXFILES; n++) {
+		fprintf(fp, "multi_bookmark%c=", LYindex2MBM(n));
+
+		fprintf(fp, "%s", NonNull(MBM_A_subbookmark[n]));
+		if (MBM_A_subdescript[n] != 0
+		 && *MBM_A_subdescript[n] != 0)
+		    fprintf(fp, ",%s", MBM_A_subdescript[n]);
+		fprintf(fp, "\n");
+	    }
+	    fprintf(fp, "\n");
+	    break;
+
+	case CONF_LIS:
+	    /* FALLTHRU */
+	case CONF_STR:
+	    fprintf(fp, "%s=%s\n\n", tbl->name,
+			(q->str_value != 0 && *(q->str_value) != 0)
+			    ? *(q->str_value)
+			    : "");
+	    break;
+
+	case CONF_UNSPECIFIED:
+	    break;
+	}
+	tbl++;
+    }
 
     /*
      *  Close the RC file.
@@ -1086,3 +837,34 @@ in the Visited Links Page.\n\
 
     return TRUE;
 }
+
+/*
+ * Returns true if the given name would be saved in .lynxrc
+ */
+PUBLIC BOOL will_save_rc ARGS1(char *, name)
+{
+    Config_Type *tbl = lookup_config(name);
+    return tbl->name != 0;
+}
+
+PUBLIC int enable_lynxrc ARGS1(
+	char *,		value)
+{
+    Config_Type *tbl;
+    char *colon = strchr(value, ':');
+
+    if (colon != 0) {
+	*colon++ = 0;
+	LYTrimLeading(value);
+	LYTrimTrailing(value);
+
+	for (tbl = Config_Table; tbl->name != 0; tbl++) {
+	    if (!strcasecomp(value, tbl->name)) {
+		tbl->enabled = getBool(colon);
+		CTRACE((tfp, "enable_lynxrc(%s) %s\n", value, putBool(tbl->enabled)));
+		break;
+	    }
+	}
+    }
+    return 0;
+}
diff --git a/src/LYrcFile.h b/src/LYrcFile.h
index 5a30c1c6..63e88d07 100644
--- a/src/LYrcFile.h
+++ b/src/LYrcFile.h
@@ -1,4 +1,3 @@
-
 #ifndef LYRCFILE_H
 #define LYRCFILE_H
 
@@ -6,8 +5,15 @@
 #include <LYStructs.h>
 #endif /* LYSTRUCTS_H */
 
-extern void read_rc PARAMS((FILE *));
+extern Config_Enum tbl_DTD_recovery[];
+extern Config_Enum tbl_keypad_mode[];
+extern Config_Enum tbl_multi_bookmarks[];
+extern Config_Enum tbl_transfer_rate[];
+extern Config_Enum tbl_user_mode[];
+
+extern BOOL will_save_rc PARAMS((char * name));
+extern int enable_lynxrc PARAMS((char * value));
 extern int save_rc PARAMS((FILE *));
+extern void read_rc PARAMS((FILE *));
 
 #endif /* LYRCFILE_H */
-
diff --git a/src/TRSTable.c b/src/TRSTable.c
index cb3980dc..f21a5012 100644
--- a/src/TRSTable.c
+++ b/src/TRSTable.c
@@ -10,6 +10,7 @@
 #include <HTStyle.h>		/* for HT_LEFT, HT_CENTER, HT_RIGHT */
 #include <LYCurses.h>
 #include <TRSTable.h>
+#include <LYGlobalDefs.h>
 
 #include <LYLeaks.h>
 
@@ -21,13 +22,17 @@
 #define ROWS_GROWBY 2
 #endif
 
-#define MAX_STBL_POS (LYcols-1)
+#ifdef USE_CURSES_PADS
+#  define MAX_STBL_POS (LYwideLines ? MAX_COLS - 1 : LYcols-1)
+#else
+#  define MAX_STBL_POS (LYcols-1)
+#endif
 
 /* must be different from HT_ALIGN_NONE and HT_LEFT, HT_CENTER etc.: */
-#define RESERVEDCELL (-2)  /* cell's alignment field is overloaded, this
-			      value means cell was reserved by ROWSPAN */
-#define EOCOLG (-2)	/* sumcols' Line field isn't used for line info, this
-			      special value means end of COLGROUP */
+#define RESERVEDCELL (-2)	/* cell's alignment field is overloaded, this
+				   value means cell was reserved by ROWSPAN */
+#define EOCOLG (-2)		/* sumcols' Line field isn't used for line info, this
+				   special value means end of COLGROUP */
 #ifndef NO_AGGRESSIVE_NEWROW
 #  define NO_AGGRESSIVE_NEWROW	0
 #endif
@@ -61,7 +66,6 @@ typedef struct _STable_states {
 				   state is CS__0?[ec]b) (??), or 0 */
 } STable_states;
 
-
 typedef struct _STable_cellinfo {
 	int	cLine;		/* lineno in doc (zero-based): -1 for
 				   contentless cells (and cells we do
@@ -70,7 +74,7 @@ typedef struct _STable_cellinfo {
 	int	pos;		/* column where cell starts */
 	int	len;		/* number of character positions */
 	int	colspan;	/* number of columns to span */
-	short	alignment;	/* one of HT_LEFT, HT_CENTER, HT_RIGHT,
+	int	alignment;	/* one of HT_LEFT, HT_CENTER, HT_RIGHT,
 				   or RESERVEDCELL */
 } STable_cellinfo;
 
@@ -97,7 +101,7 @@ typedef struct _STable_rowinfo {
        e) a singleline non-empty cell not at BOL;
 
        Summary: have seen a cell which is one of:
-       		(Notation: B: at BOL; L: last; E: the first row is non-empty)
+		(Notation: B: at BOL; L: last; E: the first row is non-empty)
 
 		bcde:	!B && !E
 		a1:	!L && !B
@@ -112,7 +116,7 @@ typedef struct _STable_rowinfo {
 	BOOL	ended;		/* if we saw </tr> */
 	int	allocated;	/* number of table cells allocated */
 	STable_cellinfo * cells;
-	short	alignment;	/* global align attribute for this row */
+	int	alignment;	/* global align attribute for this row */
 } STable_rowinfo;
 
 struct _STable_info {
@@ -189,7 +193,7 @@ struct _STable_info {
 PRIVATE int Stbl_finishCellInRow PARAMS((
     STable_rowinfo *	me,
     STable_states *	s,
-    BOOL		end_td,
+    int			end_td,
     int			lineno,
     int			pos));
 PRIVATE int Stbl_finishRowInTable PARAMS((
@@ -232,7 +236,8 @@ PUBLIC struct _STable_info * Stbl_startTABLE ARGS1(
 	me->s.x_td = -1;
 	me->s.icell_core = -1;
 #ifdef EXP_NESTED_TABLES
-	me->enclosing = 0;
+	if (nested_tables)
+	    me->enclosing = 0;
 #endif
     }
     return me;
@@ -272,8 +277,8 @@ PRIVATE int Stbl_addCellToRow ARGS9(
     int,		ncolinfo,
     STable_states *,	s,
     int,		colspan,
-    short,		alignment,
-    BOOL,		isheader,
+    int,		alignment,
+    int,		isheader,
     int,		lineno,
     int *,		ppos)
 {
@@ -294,7 +299,7 @@ PRIVATE int Stbl_addCellToRow ARGS9(
     if (me->ncells == 0)
 	s->prev_state = CS_invalid;
     else if (s->prev_state == CS_invalid ||
-	     (/*s->state != CS__new && */ s->state != CS__0new &&
+	     (s->state != CS__0new &&
 	      s->state != CS__ef && s->state != CS__0ef))
 	s->prev_state = s->state;
 
@@ -327,7 +332,6 @@ PRIVATE int Stbl_addCellToRow ARGS9(
 			    me->cells[i].cLine = lineno;
 			}
 		    me->Line = lineno;
-		    /* s->lineno = lineno; */
 		    break;
 		case CS__new:
 		case CS__eb:
@@ -349,7 +353,6 @@ PRIVATE int Stbl_addCellToRow ARGS9(
 		case CS__cb:
 		    goto trace_and_fail;
 		case CS__cf:
-/*		    HTAlert("foo woo!!"); */
 		    goto trace_and_fail;
 		case CS__0cb:
 		case CS__0cf:
@@ -387,7 +390,6 @@ PRIVATE int Stbl_addCellToRow ARGS9(
 	    case CS__0new:
 	    case CS__0ef:
 	    case CS__0eb:
-/*		me->Line = lineno; */
 		break;
 	    case CS__new:
 	    case CS__eb:
@@ -395,10 +397,6 @@ PRIVATE int Stbl_addCellToRow ARGS9(
 	    default:
 		*ppos = me->cells[me->ncells - 1].pos;	break;
 	    case CS__cbc:
-/*		*ppos = me->cells[me->ncells - 1].pos +
-		    me->cells[me->ncells - 1].len;
-		if (*ppos > 0)
-		    return -1; */
 		break;
 	    case CS_invalid:
 		break;
@@ -432,61 +430,6 @@ PRIVATE int Stbl_addCellToRow ARGS9(
 	}
     }
 
-#if 0				/* MEGA_COMMENTOUT */
-    if (lineno != me->Line) {
-	if (!me->fixed_line) {
-	    if (me->ncells == 0 ||
-		(*ppos == 0 && me->cells[me->ncells - 1].pos == 0)) {
-		if (me->ncells > 0)
-		    for (i = me->ncells + last_colspan - 2;
-			 i >= 0; i--) {
-			me->cells[i].pos = *ppos;
-			me->cells[i].cLine = lineno;
-		    }
-		me->Line = lineno;
-		s->state = CS__0new;
-	    }
-	    if (*ppos > 0 && me->ncells > 0 &&
-		(me->cells[me->ncells - 1].pos > 0 ||
-		 me->cells[me->ncells - 1].len > 0)) {
-		me->fixed_line = YES;
-
-	    }
-	}
-	if (me->fixed_line && lineno != me->Line) {
-	    if (me->cells[me->ncells - 1].pos > 0 &&
-		me->cells[me->ncells - 1].len > 0) {
-		goto trace_and_fail;
-	    } else if (me->cells[me->ncells - 1].pos == 0 &&
-		       me->cells[me->ncells - 1].len > 0) {
-		if (*ppos > 0 && *ppos > me->cells[0].pos)
-		    me->Line = lineno;
-		else
-		    *ppos = me->cells[me->ncells - 1].pos; /* == 0 */
-	    } else /* if (me->cells[me->ncells - 1].pos == 0 &&
-		       me->cells[me->ncells - 1].len <= 0) {
-		me->Line = lineno;
-	    } else */ {
-		*ppos = me->cells[me->ncells - 1].pos;
-	    }
-	}
-#if 0
-	for (i = 0; i < me->ncells; i++) {
-	    if (me->cells[i].cLine == lineno) {
-		break;
-	    } else if (me->cells[i].len <= 0) {
-		me->cells[i].cLine = lineno;
-		/* @@@ reset its pos too ?? */
-	    } else {
-		break;
-	    }
-	}
-	if (i < me->ncells && me->cells[i].cLine != lineno)
-	    goto trace_and_fail;
-	me->Line = lineno;
-#endif
-    }
-#endif /* MEGA_COMMENTOUT */
     s->state = newstate;
 
     if (me->ncells > 0 && me->cells[me->ncells - 1].colspan > 1) {
@@ -526,7 +469,7 @@ PRIVATE int Stbl_addCellToRow ARGS9(
     me->cells[me->ncells].colspan = colspan;
 
     if (alignment != HT_ALIGN_NONE)
-	    me->cells[me->ncells].alignment = alignment;
+	me->cells[me->ncells].alignment = alignment;
     else {
 	if (ncolinfo >= me->ncells + 1)
 	    me->cells[me->ncells].alignment = colinfo[me->ncells].alignment;
@@ -602,13 +545,13 @@ PRIVATE int Stbl_reserveCellsInRow ARGS3(
 PRIVATE int Stbl_finishCellInRow ARGS5(
     STable_rowinfo *,	me,
     STable_states *,	s,
-    BOOL,		end_td,
+    int,		end_td,
     int,		lineno,
     int,		pos)
 {
     STable_cellinfo *lastcell;
     cellstate_t newstate = CS_invalid;
-    BOOL multiline = NO, empty;
+    int multiline = NO, empty;
     int ret;
 
     CTRACE2(TRACE_TRST,
@@ -652,11 +595,7 @@ PRIVATE int Stbl_finishCellInRow ARGS5(
 		goto trace_and_return;
 	    case CS__0cb:
 		if (!me->fixed_line) {
-		    if (empty) { /* ##462_return_0 */
-/*			if (s->icell_core == -1)
-			    s->icell_core = lastcell->cLine; */ /* we don't know yet */
-			/* lastcell->cLine = lineno; */
-		    } else {	/* !empty */
+		    if (!empty) {
 			if (s->icell_core == -1)
 			    me->Line = -1;
 		    }
@@ -856,12 +795,6 @@ PRIVATE int Stbl_finishCellInRow ARGS5(
 		    if (empty) {
 			if (s->icell_core == -1)
 			    me->Line = lineno;
-			/* lastcell->Line = lineno; */
-#if 0	/* ?? */
-		    } else {	/* !empty */
-			if (s->icell_core == -1)
-			    me->Line = -1;
-#endif
 		    }
 		}
 		s->pending_len = 0; /* ##629 v */
@@ -977,56 +910,13 @@ PRIVATE int Stbl_finishCellInRow ARGS5(
 	} /* if (!end_td) ... else */
     } /* if (multiline) ... else */
 
-#if 0				/* MEGA_COMMENTOUT */
-    if (lineno != me->cells[0].cLine) {
-#if 0
-	int i;
-	for (i = ncells - 1; i >= 0; i--) {
-	    if (!(me->cells[i].len == 0 || me->cells[i].colspan == 0))
-		break;
-	}
-#endif
-	if (lineno >= lastcell->cLine) {
-	    if (me->fixed_line) {
-		if (pos == 0) {
-		    if (lastcell->len <= 0) {
-			return 0;
-		    } else {
-			return lastcell->len;
-		    }
-		} else {	/* pos != 0 */
-		    if (lastcell->len <= 0 && lineno > lastcell->cLine && lastcell->cLine <= me->Line) {
-			return 0;
-		    } else {
-			return -1;
-		    }
-		}
-	    } else {	/* not me->fixed_line */
-		if (pos == 0) {
-		    if (lastcell->len <= 0) {
-			return 0;
-		    } else {
-			return lastcell->len;
-		    }
-		} else {	/* pos != 0 */
-		    if (lastcell->len <= 0) {
-			return 0;
-		    } else {
-			if (me->ncells == 1 || lastcell->pos == 0) {
-			    return 0;
-			} else
-			    return -1;
-		    }
-		}
-	    }
-	}
-    }
-#endif /* MEGA_COMMENTOUT */
     s->state = newstate;
     ret = lastcell->len;
 #ifdef EXP_NESTED_TABLES
-    if (ret == -1 && pos == 0)
-	ret = 0; /* XXXX Hack to allow trailing <P> in multiline cells. */
+    if (nested_tables) {
+	if (ret == -1 && pos == 0)
+	    ret = 0; /* XXXX Hack to allow trailing <P> in multiline cells. */
+    }
 #endif
 
 /*    lastcell->len = pos - lastcell->pos; */
@@ -1136,7 +1026,7 @@ PRIVATE void Stbl_cancelRowSpans ARGS1(
  */
 PUBLIC int Stbl_addRowToTable ARGS3(
     STable_info *,	me,
-    short,		alignment,
+    int,		alignment,
     int,		lineno)
 {
     STable_rowinfo *rows, *row;
@@ -1149,18 +1039,7 @@ PUBLIC int Stbl_addRowToTable ARGS3(
 	if (s->pending_len > 0)
 	    me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len = s->pending_len;
 	s->pending_len = 0;
-/*	if (me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len >= 0 &&
-	    me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].cLine == lineno)
-	    Stbl_finishCellInTable(me, YES,
-				   lineno,
-		me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].pos +
-		me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len); */
     }
-#if 0
-    s->prev_state = s->state = CS_invalid;
-    s->lineno = -1;
-    s->icell_core = -1;
-#endif
     Stbl_finishRowInTable(me);
     if (me->nrows > 0 && me->rows[me->nrows-1].Line == lineno)
 	me->rows[me->nrows-1].Line = -1;
@@ -1253,9 +1132,6 @@ PRIVATE int Stbl_finishRowInTable ARGS1(
     s->prev_state = s->state = CS_invalid;
     s->lineno = -1;
 
-#if 0
-    if (lastrow->Line == -1 && s->icell_core >= 0)
-#endif
     if (s->icell_core >= 0 && !lastrow->fixed_line &&
 	lastrow->cells[s->icell_core].cLine >= 0)
 	lastrow->Line = lastrow->cells[s->icell_core].cLine;
@@ -1506,8 +1382,8 @@ PUBLIC int Stbl_addCellToTable ARGS7(
     STable_info *,	me,
     int,		colspan,
     int,		rowspan,
-    short,		alignment,
-    BOOL,		isheader,
+    int,		alignment,
+    int,		isheader,
     int,		lineno,
     int,		pos)
 {
@@ -1515,9 +1391,6 @@ PUBLIC int Stbl_addCellToTable ARGS7(
     STable_rowinfo *lastrow;
     STable_cellinfo *sumcols, *sumcol;
     int i, icell, ncells, sumpos;
-#if 0
-    int prevsumpos, advance;
-#endif
 
     CTRACE2(TRACE_TRST,
 	    (tfp, "TRST:Stbl_addCellToTable(lineno=%d, pos=%d, isheader=%d, cs=%d, rs=%d, al=%d)\n",
@@ -1531,16 +1404,18 @@ PUBLIC int Stbl_addCellToTable ARGS7(
     lastrow = me->rows + (me->nrows - 1);
 
 #ifdef EXP_NESTED_TABLES
-    /* If the last cell was finished by <BR></TD>, we need to fake an
-       appropriate amount of cells */
-    if (!NO_AGGRESSIVE_NEWROW && pos == 0 && lastrow->ncells > 0
-	&& lastrow->cells[lastrow->ncells-1].cLine != lineno) {
-	int rc = Stbl_fakeFinishCellInTable(me, lastrow, lineno, 0);
+    if (nested_tables) {
+	/* If the last cell was finished by <BR></TD>, we need to fake an
+	   appropriate amount of cells */
+	if (!NO_AGGRESSIVE_NEWROW && pos == 0 && lastrow->ncells > 0
+	    && lastrow->cells[lastrow->ncells-1].cLine != lineno) {
+	    int rc = Stbl_fakeFinishCellInTable(me, lastrow, lineno, 0);
 
-	if (rc < 0)
-	    return -1;
-	if (rc)
-	    lastrow = me->rows + (me->nrows - 1);
+	    if (rc < 0)
+		return -1;
+	    if (rc)
+		lastrow = me->rows + (me->nrows - 1);
+	}
     }
 #endif
     if (colspan == 0) {
@@ -1590,11 +1465,6 @@ PUBLIC int Stbl_addCellToTable ARGS7(
 	    }
 	}
     }
-#if 0
-    if (icell + colspan > me->ncols) {
-	me->sumcols[icell + colspan].pos = -1; /* not yet used @@@ ??? */
-    }
-#endif
     if (icell + 1 > me->ncols) {
 	me->ncols = icell + 1;
     }
@@ -1606,33 +1476,7 @@ PUBLIC int Stbl_addCellToTable ARGS7(
     update_sumcols0(me->sumcols, lastrow, sumpos,
 		    sumpos - (ncells > 0 ? me->sumcols[icell].pos : me->sumcols[icell].pos),
 		    icell, 0, me->allocated_sumcols);
-#if 0
-    prevsumpos = me->sumcols[icell].pos;
-    advance = sumpos - prevsumpos;
-    if (advance > 0) {
-	for (i = icell; i < me->allocated_sumcols; i++) {
-	    if (me->sumcols[i].pos >= 0)
-		me->sumcols[i].pos += advance;
-	    else {
-		me->sumcols[i].pos = sumpos;
-		break;
-	    }
-	}
-    }
-#endif
-
 
-#if 0
-	int prevopos = (ncells > 0 ? lastrow->cells[ncells-1].pos : 0);
-	int prevnpos = (ncells > 0 ? me->sumcols[ncells-1].pos : 0);
-#endif
-#if 0
-    if (pos > me->maxpos) {
-	me->maxpos = pos;
-	if (me->maxpos > /* @@@ max. line length we can accept */ MAX_STBL_POS)
-	    return -1;
-    }
-#endif
     me->maxpos = me->sumcols[me->allocated_sumcols-1].pos;
     if (me->maxpos > /* @@@ max. line length we can accept */ MAX_STBL_POS)
 	return -1;
@@ -1644,7 +1488,7 @@ PUBLIC int Stbl_addCellToTable ARGS7(
  */
 PUBLIC int Stbl_finishCellInTable ARGS4(
     STable_info *,	me,
-    BOOL,		end_td,
+    int,		end_td,
     int,		lineno,
     int,		pos)
 {
@@ -1669,14 +1513,16 @@ PUBLIC int Stbl_finishCellInTable ARGS4(
     }
 
 #ifdef EXP_NESTED_TABLES
-    if (!NO_AGGRESSIVE_NEWROW && !(end_td & TRST_FAKING_CELLS)) {
-	int rc = Stbl_fakeFinishCellInTable(me, lastrow, lineno, 1);
+    if (nested_tables) {
+	if (!NO_AGGRESSIVE_NEWROW && !(end_td & TRST_FAKING_CELLS)) {
+	    int rc = Stbl_fakeFinishCellInTable(me, lastrow, lineno, 1);
 
-	if (rc) {
-	    if (rc < 0)
-		return -1;
-	    lastrow = me->rows + (me->nrows - 1);
-	    icell = lastrow->ncells - 1;
+	    if (rc) {
+		if (rc < 0)
+		    return -1;
+		lastrow = me->rows + (me->nrows - 1);
+		icell = lastrow->ncells - 1;
+	    }
 	}
     }
 #endif
@@ -1711,19 +1557,6 @@ PUBLIC int Stbl_finishCellInTable ARGS4(
 	/* @@@ could overcount? */
 	if (len > spanlen)
 	    me->maxlen += (len - spanlen);
-#if 0	/* this is all quite bogus! */
-	if (me->sumcols[icell].colspan > 1)
-	    me->sumcols[icell+me->sumcols[icell].colspan].pos =
-		HTMAX(me->sumcols[icell].pos + len,
-		      me->sumcols[icell+me->sumcols[icell].colspan].pos);
-	if (lastrow->cells[icell].colspan > me->sumcols[icell].colspan) {
-	    me->sumcols[icell].colspan = lastrow->cells[icell].colspan;
-	    if (me->sumcols[icell].colspan > 1)
-		me->sumcols[icell+me->sumcols[icell].colspan].pos =
-		    HTMAX(me->sumcols[icell].pos + len,
-			  me->sumcols[icell+me->sumcols[icell].colspan].pos);
-	}
-#endif
     } else if (len > me->sumcols[icell].len) {
 	if (me->sumcols[icell + 1].colspan >= -1)
 	    me->maxlen += (len - me->sumcols[icell].len);
@@ -1736,51 +1569,19 @@ PUBLIC int Stbl_finishCellInTable ARGS4(
 			me->allocated_sumcols);
 	me->maxpos = me->sumcols[me->allocated_sumcols-1].pos;
     }
-#if 0
-    if (len > 0) {
-	int sumpos = pos;
-	int ispan = lastrow->cells[icell].colspan;
-	int prevsumpos = me->sumcols[icell + ispan].pos;
-	int advance;
-	if (lastrow->cells[icell].pos + len > sumpos)
-	    sumpos = lastrow->cells[icell].pos + len;
-	if (me->sumcols[icell+ispan-1].pos + me->sumcols[icell+ispan-1].len > sumpos)
-	    sumpos = me->sumcols[icell+ispan-1].pos + me->sumcols[icell+ispan-1].len;
-	advance = sumpos - prevsumpos;
-	if (advance > 0) {
-	    for (i = icell + ispan; i < me->allocated_sumcols; i++) {
-		if (me->sumcols[i].colspan < -1) {
-		    if (i + me->sumcols[i].colspan < icell + ispan) {
-			advance = sumpos - me->sumcols[i].pos;
-			if (i > 0)
-			    advance = HTMAX(advance,
-					    me->sumcols[i-1].pos + me->sumcols[i-1].len
-					    - (me->sumcols[i].pos));
-			if (advance <= 0)
-			    break;
-		    }
-		}
-		if (me->sumcols[i].pos >= 0)
-		    me->sumcols[i].pos += advance;
-		else {
-		    me->sumcols[i].pos = sumpos;
-		    break;
-		}
-	    }
-	}
-	me->maxpos = me->sumcols[me->allocated_sumcols-1].pos;
-    }
-#endif
 
     if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK)
 	lastrow->ended = ROW_ended_by_splitline;
 #ifdef EXP_NESTED_TABLES /* maxlen may already include contribution of a cell in this column */
-    if (me->maxlen > MAX_STBL_POS)
-	return -1;
-#else
-    if (me->maxlen + (xlen - len) > MAX_STBL_POS)
-	return -1;
+    if (nested_tables) {
+	if (me->maxlen > MAX_STBL_POS)
+	    return -1;
+    } else
 #endif
+    {
+	if (me->maxlen + (xlen - len) > MAX_STBL_POS)
+	    return -1;
+    }
     if (me->maxpos > /* @@@ max. line length we can accept */ MAX_STBL_POS)
 	return -1;
 
@@ -1902,11 +1703,6 @@ PUBLIC int Stbl_finishTABLE ARGS1(
 	if (s->pending_len > 0)
 	    me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len = s->pending_len;
 	s->pending_len = 0;
-/*	if (me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len >= 0)
-	    Stbl_finishCellInTable(me, YES,
-		me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].cLine,
-		me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].pos +
-		me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len); */
     }
     Stbl_finishRowInTable(me);
     for (i = 0; i < me->ncols; i++) {
@@ -1919,20 +1715,15 @@ PUBLIC int Stbl_finishTABLE ARGS1(
 	    curpos += me->sumcols[i].len;
 	}
     }
-#if 0				/* ??? */
-    for (j = 0; j < me->nrows; j++) {
-	STable_rowinfo *row = me->rows + i;
-	for (i = 0; i < row->ncells; i++) {
-	}
-    }
-#endif
-    return me->ncols;
+    /* need to recheck curpos: though it is checked each time a cell
+       is added, sometimes the result is ignored, as in split_line(). */
+    return (curpos > MAX_STBL_POS ? -1 : me->ncols);
 }
 
 PUBLIC short Stbl_getAlignment ARGS1(
     STable_info *,	me)
 {
-    return me ? me->alignment : HT_ALIGN_NONE;
+    return (short)(me ? me->alignment : HT_ALIGN_NONE);
 }
 
 PRIVATE int get_fixup_positions ARGS4(
@@ -2040,7 +1831,7 @@ PUBLIC void Stbl_update_enclosing ARGS3(
 	/* Fake <BR> in appropriate positions */
 	if (Stbl_finishCellInTable(me->enclosing, TRST_ENDCELL_LINEBREAK, l, max_width) < 0) {
 	    /* It is not handy to let the caller delete me->enclosing,
-	       and it does not buy us anything.  Do it directly. */
+	       and it does not buy us anything.	 Do it directly. */
 	    STable_info *stbl = me->enclosing;
 
 	    CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_update_enclosing: width too large, aborting enclosing\n"));
diff --git a/src/TRSTable.h b/src/TRSTable.h
index 02463640..38c496b2 100644
--- a/src/TRSTable.h
+++ b/src/TRSTable.h
@@ -9,9 +9,9 @@ typedef struct _STable_info STable_info;
 extern STable_info * Stbl_startTABLE PARAMS((short));
 extern int Stbl_finishTABLE PARAMS((STable_info *));
 extern void Stbl_free PARAMS((STable_info *));
-extern int Stbl_addRowToTable PARAMS((STable_info *, short, int));
-extern int Stbl_addCellToTable PARAMS((STable_info *, int, int, short, BOOL, int, int));
-extern int Stbl_finishCellInTable PARAMS((STable_info *, BOOL, int, int));
+extern int Stbl_addRowToTable PARAMS((STable_info *, int, int));
+extern int Stbl_addCellToTable PARAMS((STable_info *, int, int, int, int, int, int));
+extern int Stbl_finishCellInTable PARAMS((STable_info *, int, int, int));
 extern int Stbl_addColInfo PARAMS((STable_info *, int, short, BOOL));
 extern int Stbl_finishColGroup PARAMS((STable_info *));
 extern int Stbl_addRowGroup PARAMS((STable_info *, short));
diff --git a/src/UCAuto.c b/src/UCAuto.c
index fec1b052..1b455f97 100644
--- a/src/UCAuto.c
+++ b/src/UCAuto.c
@@ -290,12 +290,6 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
 	}
 	Utf = Is_Unset;
     } else if (!strcmp(name, "iso-8859-2")) {
-#ifdef NOTDEFINED
-	/*
-	 *  "setfont lat2-16.psf -u lat2.uni"
-	 */
-	status = call_setfont("lat2", SUFF2, "lat2.uni");
-#endif /* NOTDEFINED */
 	/*
 	 *  "setfont iso02.f16 -u iso02.uni"
 	 */
@@ -355,11 +349,6 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
 	Utf = Is_Unset;
     } else if (!strcmp(name, "cp866") ||
 	       !strcmp(name, "cp852") ||
-#if 0
-	       !strcmp(name, "cp861") ||
-	       !strcmp(name, "cp850") ||
-	       !strcmp(name, "cp437") ||
-#endif
 	       !strcmp(name, "cp862")) { /* MS-Kermit has these files */
 	HTSprintf0(&tmpbuf2, "%s.uni", name);
 	/*
@@ -462,7 +451,7 @@ PUBLIC void UCChangeTerminalCodepage ARGS2(
 
     if (newcs < 0)
 	newcs = auto_display_charset;
-    res = Switch_Display_Charset(newcs, 1);
+    res = Switch_Display_Charset(newcs, SWITCH_DISPLAY_CHARSET_REALLY);
     CTRACE((tfp, "UCChangeTerminalCodepage: Switch_Display_Charset(%d) returned %d\n", newcs, res));
 #else
     CTRACE((tfp, "UCChangeTerminalCodepage: Called, but not implemented!"));
@@ -535,11 +524,11 @@ PUBLIC int Find_Best_Display_Charset ARGS1 (int, ord)
 
 #  ifdef __EMX__
 /* Switch display for the best fit for LYCharSet_UC[ord].
-   If !REALLY, the switch is tentative only, another switch may happen
+   If really is MAYBE, the switch is tentative only, another switch may happen
    before the actual display.
 
    Returns the charset we switched to.  */
-PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really)
+PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, enum switch_display_charset_t, really)
 {
     CONST char *name;
     unsigned short cp;
@@ -548,24 +537,28 @@ PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really)
     UCHAR msgbuf[MAXPATHLEN + 80];
 
     CTRACE((tfp, "_Switch_Display_Charset(cp=%d, really=%d).\n", ord, really));
-    /* Do not trust current_char_set if really, we fake it without really! */
-    if (ord == current_char_set && !really)
+    /* Do not trust current_char_set unless REALLY, we fake it if MAYBE! */
+    if (ord == current_char_set && really == SWITCH_DISPLAY_CHARSET_MAYBE)
 	return ord;
     if (ord == auto_other_display_charset
 	|| ord == auto_display_charset || ord == font_loaded_for) {
-	if (!really)
+	if (really == SWITCH_DISPLAY_CHARSET_MAYBE)
 	    return ord; /* Report success, to avoid flicker, switch later */
     } else	/* Currently supports only koi8-r to cp866 translation */
 	ord = Find_Best_Display_Charset(ord);
 
+    /* Ignore sizechange unless the font is loaded */
+    if (ord != font_loaded_for && really == SWITCH_DISPLAY_CHARSET_SIZECHANGE)
+	return ord;
+
     if (ord == real_charsets[0] || ord == real_charsets[1]) {
 	ord1 = (ord == real_charsets[1]
 	       ? auto_other_display_charset : auto_display_charset);
-	if (!really)
+	if (really == SWITCH_DISPLAY_CHARSET_MAYBE)
 	    return ord; /* Can switch later, report success to avoid flicker */
     } else
 	ord1 = ord;
-    if (ord == current_char_set && !really)
+    if (ord == current_char_set && really == SWITCH_DISPLAY_CHARSET_MAYBE)
 	return ord;
 
     name = LYCharSet_UC[ord1].MIMEname;
@@ -663,12 +656,17 @@ PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really)
 }
 #  endif /* __EMX__ */
 
-PUBLIC int Switch_Display_Charset ARGS2 (CONST int, ord, CONST int, really)
+PUBLIC int Switch_Display_Charset ARGS2 (CONST int, ord, CONST enum switch_display_charset_t, really)
 {
     int prev = current_char_set;
     int res;
+    static int repeated;
 
-    if (!switch_display_charsets && !really)
+    if (!switch_display_charsets
+	&& (really == SWITCH_DISPLAY_CHARSET_MAYBE
+	    /* The first switch is not due to an interactive action */
+	    || (really == SWITCH_DISPLAY_CHARSET_REALLY
+		&& !(repeated++))))
 	return 0;
     res = _Switch_Display_Charset(ord, really);
     if (res < 0 || prev == res)		/* No change */
diff --git a/src/UCdomap.c b/src/UCdomap.c
index cc725694..4e97d837 100644
--- a/src/UCdomap.c
+++ b/src/UCdomap.c
@@ -69,9 +69,6 @@
 #include <viscii_uni.h>		/* Vietnamese (VISCII)	*/
 #include <cp866u_uni.h>		/* Ukrainian Cyrillic (866) */
 #include <koi8u_uni.h>		/* Ukrainian Cyrillic (koi8-u */
-#ifdef NOTDEFINED
-#include <mnem_suni.h>
-#endif /* NOTDEFINED */
 
 #ifdef CAN_AUTODETECT_DISPLAY_CHARSET
 int auto_display_charset = -1;
@@ -254,13 +251,6 @@ PRIVATE void set_inverse_transl PARAMS((
 	int		i));
 PRIVATE u16 *set_translate PARAMS((
 	int		m));
-#ifdef NOTDEFINED
-PRIVATE unsigned char inverse_translate PARAMS((int glyph));
-PRIVATE int con_set_trans_old PARAMS((unsigned char *arg));
-PRIVATE int con_get_trans_old PARAMS((unsigned char *arg));
-PRIVATE int con_set_trans_new PARAMS((u16 *arg));
-PRIVATE int con_get_trans_new PARAMS((u16 *arg));
-#endif /* NOTDEFINED */
 PRIVATE int UC_valid_UC_charset PARAMS((
 	int		UC_charset_hndl));
 PRIVATE void UC_con_set_trans PARAMS((
@@ -279,11 +269,6 @@ PRIVATE void con_clear_unimap PARAMS((
 	int		fordefault));
 PRIVATE void con_clear_unimap_str PARAMS((
 	int		fordefault));
-#ifdef NOTDEFINED
-PRIVATE int con_set_unimap PARAMS((
-	u16			ct,
-	struct unipair *	list));
-#endif /* NOTDEFINED */
 PRIVATE void con_set_default_unimap NOPARAMS;
 PRIVATE int UC_con_set_unimap PARAMS((
 	int		UC_charset_out_hndl,
@@ -292,12 +277,6 @@ PRIVATE int UC_con_set_unimap_str PARAMS((
 	u16			ct,
 	struct unipair_str *	list,
 	int			fordefault));
-#ifdef NOTDEFINED
-PRIVATE int con_get_unimap PARAMS((
-	u16			ct,
-	u16 *			uct,
-	struct unipair *	list));
-#endif /* NOTDEFINED */
 PRIVATE int conv_uni_to_pc PARAMS((
 	long			ucs,
 	int			usedefault));
@@ -354,7 +333,7 @@ PRIVATE void set_inverse_transl ARGS1(
 	    /*
 	     *	Prefer '-' above SHY etc.
 	     */
-	    q[glyph] = j;
+	    q[glyph] = UCH(j);
 	}
     }
 }
@@ -368,105 +347,6 @@ PRIVATE u16 *set_translate ARGS1(
 	return translations[m];
 }
 
-#ifdef NOTDEFINED
-/*
- * Inverse translation is impossible for several reasons:
- * 1. The font<->character maps are not 1-1.
- * 2. The text may have been written while a different translation map
- *    was active, or using Unicode.
- * Still, it is now possible to a certain extent to cut and paste non-ASCII.
- */
-PRIVATE unsigned char inverse_translate ARGS1(
-	int,		glyph)
-{
-    if (glyph < 0 || glyph >= MAX_GLYPH) {
-		return 0;
-    } else {
-	return ((inv_translate && inv_translate[glyph]) ?
-				   inv_translate[glyph] :
-				   UCH(glyph & 0xff));
-    }
-}
-
-/*
- *  Load customizable translation table.
- *  'arg' points to a 256 byte translation table.
- *
- *  The "old" variants are for translation directly to font (using the
- *  0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
- *  Unicodes explicitly.
- */
-PRIVATE int con_set_trans_old ARGS1(
-	unsigned char *,	arg)
-{
-    int i;
-    u16 *p = translations[USER_MAP];
-#if(0)
-    i = verify_area(VERIFY_READ, (void *)arg, E_TABSZ);
-    if (i)
-	return i;
-#endif
-    for (i = 0; i < E_TABSZ; i++)
-	p[i] = UNI_DIRECT_BASE | (u16)arg[i];
-
-    set_inverse_transl(USER_MAP);
-    return 0;
-}
-
-PRIVATE int con_get_trans_old ARGS1(
-	unsigned char *,	arg)
-{
-    int i, ch;
-    u16 *p = translations[USER_MAP];
-#if(0)
-    i = verify_area(VERIFY_WRITE, (void *)arg, E_TABSZ);
-    if (i)
-	return i;
-#endif
-    for (i = 0; i < E_TABSZ; i++) {
-	ch = conv_uni_to_pc(p[i]);
-#ifdef NOTDEFINED
-	put_user((ch & ~0xff) ? 0 : ch, arg+i);
-#endif /* NOTDEFINED */
-	arg[i] = UCH((ch & ~0xff) ? 0 : ch);
-    }
-    return 0;
-}
-
-PRIVATE int con_set_trans_new ARGS1(
-	u16 *,		arg)
-{
-    int i;
-    u16 *p = translations[USER_MAP];
-#if(0)
-    i = verify_area(VERIFY_READ, (void *)arg, E_TABSZ*sizeof(u16));
-    if (i)
-	return i;
-#endif
-    for (i = 0; i < E_TABSZ; i++)
-	p[i] = arg[i];
-
-    set_inverse_transl(USER_MAP);
-    return 0;
-}
-
-PRIVATE int con_get_trans_new ARGS1(
-	u16 *		arg)
-{
-    int i;
-    u16 *p = translations[USER_MAP];
-#if(0)
-    i = verify_area(VERIFY_WRITE, (void *)arg, E_TABSZ*sizeof(u16));
-    if (i)
-	return i;
-#endif
-    for (i = 0; i < E_TABSZ; i++)
-	arg[i] = p[i];
-
-    return 0;
-}
-#endif /* NOTDEFINED */
-
 PRIVATE int UC_valid_UC_charset ARGS1(
 	int,		UC_charset_hndl)
 {
@@ -723,27 +603,6 @@ PRIVATE void con_clear_unimap_str ARGS1(int, fordefault)
   }
 }
 
-#ifdef NOTDEFINED
-PRIVATE int con_set_unimap ARGS2(
-	u16,			ct,
-	struct unipair *,	list)
-{
-    int err = 0, err1, i;
-
-    while (ct--) {
-	if ((err1 = con_insert_unipair(list->unicode, list->fontpos)) != 0) {
-	    err = err1;
-	}
-	list++;
-    }
-
-    for (i = 0; i <= 3; i++) {
-	set_inverse_transl(i); /* Update all inverse translations */
-    }
-    return err;
-}
-#endif /* NOTDEFINED */
-
 /*
  *  Loads the unimap for the hardware font, as defined in uni_hash.tbl.
  *  The representation used was the most compact I could come up
@@ -767,12 +626,6 @@ PRIVATE void con_set_default_unimap NOARGS
 	}
     }
 
-#if 0
-    for (i = 0; i <= 3; i++) {
-	set_inverse_transl(i);	/* Update all inverse translations */
-    }
-#endif
-
     UC_default_unitable = dfont_unitable;
 
     con_clear_unimap_str(1);
@@ -862,39 +715,6 @@ PRIVATE int UC_con_set_unimap_str ARGS3(
     return err;
 }
 
-#ifdef NOTDEFINED
-PRIVATE int con_get_unimap ARGS3(
-	u16,			ct,
-	u16 *,			uct,
-	struct unipair *,	list)
-{
-    int i, j, k, ect;
-    u16 **p1, *p2;
-
-    ect = 0;
-    if (hashtable_contents_valid) {
-	for (i = 0; i < 32; i++) {
-	    if ((p1 = uni_pagedir[i]) != NULL) {
-		for (j = 0; j < 32; j++) {
-		    if ((p2 = *(p1++)) != NULL) {
-			for (k = 0; k < 64; k++) {
-			    if (*p2 < MAX_GLYPH && ect++ < ct) {
-				list->unicode = (u16) ((i<<11)+(j<<6)+k);
-				list->fontpos = (u16) *p2;
-				list++;
-			    }
-			    p2++;
-			}
-		    }
-		}
-	    }
-	}
-    }
-    *uct = ect;
-    return ((ect <= ct) ? 0 : -1);
-}
-#endif /* NOTDEFINED */
-
 PRIVATE int conv_uni_to_pc ARGS2(
 	long,		ucs,
 	int,		usedefault)
@@ -985,16 +805,6 @@ PRIVATE int conv_uni_to_str ARGS4(
 	 *  Zero-width space.
 	 */
 	return -2;
-#ifdef NOTDEFINED	/* We don't handle the following here: */
-    } else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE) {
-	/*
-	 *  UNI_DIRECT_BASE indicates the start of the region in the
-	 *  User Zone which always has a 1:1 mapping to the currently
-	 *  loaded font.  The UNI_DIRECT_MASK indicates the bit span
-	 *  of the region.
-	 */
-	return ucs & UNI_DIRECT_MASK;
-#endif /* NOTDEFINED */
     }
 
     if (usedefault) {
@@ -1124,7 +934,8 @@ PUBLIC int UCTransUniCharStr ARGS5(
 	}
 	src = conv_uni_to_pc(unicode, isdefault);
 	if (src >= 32) {
-	    outbuf[0] = src; outbuf[1] = '\0';
+	    outbuf[0] = (char)src;
+	    outbuf[1] = '\0';
 	    return 1;
 	}
     }
@@ -1143,7 +954,8 @@ PUBLIC int UCTransUniCharStr ARGS5(
     if (trydefault && chk_single_flag) {
 	src = conv_uni_to_pc(unicode, 1);
 	if (src >= 32) {
-	    outbuf[0] = src; outbuf[1] = '\0';
+	    outbuf[0] = (char)src;
+	    outbuf[1] = '\0';
 	    return 1;
 	}
     }
@@ -1166,7 +978,8 @@ PUBLIC int UCTransUniCharStr ARGS5(
 	if ((rc == -4) && (isdefault || trydefault))
 	    rc = conv_uni_to_pc(0xfffd, 1);
 	if (rc >= 32) {
-	    outbuf[0] = rc; outbuf[1] = '\0';
+	    outbuf[0] = (char)rc;
+	    outbuf[1] = '\0';
 	    return 1;
 	}
 	return rc;
@@ -1447,7 +1260,8 @@ PUBLIC int UCTransCharStr ARGS6(
 	}
 	src = conv_uni_to_pc(unicode, isdefault);
 	if (src >= 32) {
-	    outbuf[0] = src; outbuf[1] = '\0';
+	    outbuf[0] = (char)src;
+	    outbuf[1] = '\0';
 	    return 1;
 	}
     }
@@ -1466,7 +1280,8 @@ PUBLIC int UCTransCharStr ARGS6(
     if (trydefault && chk_single_flag) {
 	src = conv_uni_to_pc(unicode, 1);
 	if (src >= 32) {
-	    outbuf[0] = src; outbuf[1] = '\0';
+	    outbuf[0] = (char)src;
+	    outbuf[1] = '\0';
 	    return 1;
 	}
     }
@@ -1489,7 +1304,8 @@ PUBLIC int UCTransCharStr ARGS6(
 	if ((rc == -4) && (isdefault || trydefault))
 	    rc = conv_uni_to_pc(0xfffd, 1);
 	if (rc >= 32) {
-	    outbuf[0] = rc; outbuf[1] = '\0';
+	    outbuf[0] = (char)rc;
+	    outbuf[1] = '\0';
 	    return 1;
 	} else if (rc <= 0) {
 	    outbuf[0] = '\0';
@@ -1769,7 +1585,7 @@ PRIVATE CONST char ** UC_setup_LYCharSets_repl ARGS2(
 	for (i = 0; i < 256; i++) {
 	    if ((j = UCInfo[UC_charset_in_hndl].unicount[i])) {
 		if ((k = *pp) >= 160 && k < 256 && i >= lowest8) {
-		   ti[k-160] = i;
+		   ti[k-160] = UCH(i);
 		}
 		for (; j; j--) {
 		    pp++;
@@ -1822,7 +1638,7 @@ PRIVATE CONST char ** UC_setup_LYCharSets_repl ARGS2(
 	     *	We have an entity that is mapped to
 	     *	one valid eightbit latin1 char.
 	     */
-	    if (ti[UCH(*s8) - 160] >= lowest8 &&
+	    if (ti[UCH(*s8) - 160] >= UCH(lowest8) &&
 		!(s7[0] == ti[UCH(*s8) - 160] &&
 		s7[1] == '\0')) {
 		/*
@@ -1834,21 +1650,7 @@ PRIVATE CONST char ** UC_setup_LYCharSets_repl ARGS2(
 		    *p = s8;
 		} else {
 		    /*
-		     *			      ...or another byte...
-		     */
-#ifdef NOTDEFINED
-		    *p = (char *)malloc(2*sizeof(char));
-		    if (!*p) {
-			FREE(tp);
-			FREE(ti);
-			FREE(prepl);
-			return NULL;
-		    }
-		    (*p)[0] = ti[UCH(*s8) - 160];
-		    (*p)[1] = '\0';
-#else
-		    /*
-		     *	Use this instead... make those 1-char strings
+		     *	make those 1-char strings
 		     *	into HTAtoms, so they will be cleaned up
 		     *	at exit... all for the sake of preventing
 		     *	memory leaks, sigh.
@@ -1857,7 +1659,6 @@ PRIVATE CONST char ** UC_setup_LYCharSets_repl ARGS2(
 
 		    dummy[0] = ti[UCH(*s8) - 160];
 		    *p = HTAtom_name(HTAtom_for(dummy));
-#endif /* NOTDEFINED */
 		}
 		changed = 1;
 	    } else if (tp[UCH(*s8) - 160] &&
@@ -2268,9 +2069,6 @@ PUBLIC void UCInit NOARGS
     UC_CHARSET_SETUP_mnemonic;		  /* RFC 1345 Mnemonic	  */
     UC_CHARSET_SETUP_cp866u;		  /* Ukrainian Cyrillic (866) */
     UC_CHARSET_SETUP_koi8_u;		  /* Ukrainian Cyrillic (koi8-u) */
-#ifdef NOTDEFINED
-    UC_CHARSET_SETUP_mnem;
-#endif /* NOTDEFINED */
 
 #ifdef CAN_AUTODETECT_DISPLAY_CHARSET
 #  ifdef __EMX__
diff --git a/src/chrtrans/makefile.dos b/src/chrtrans/makefile.dos
index 3ba32967..03bb135d 100644
--- a/src/chrtrans/makefile.dos
+++ b/src/chrtrans/makefile.dos
@@ -12,11 +12,11 @@
 CFLAGS = $(MCFLAGS)
 
 CC = gcc
-MCFLAGS = -O1 -DDOSPATH -DNO_TTYTYP \
+MCFLAGS = -O2 -DDOSPATH -DNO_TTYTYP \
 -I. \
 -I../../WWW/Library/Implementation \
--I../../djgpp/watt32/inc \
--I../../djgpp/watt32/inc/sys \
+-I/djgpp/watt32/inc \
+-I/djgpp/watt32/inc/sys \
 -I../..
 
 .SUFFIXES: .tbl
diff --git a/src/makefile.dos b/src/makefile.dos
index 880c151a..daaa5b62 100644
--- a/src/makefile.dos
+++ b/src/makefile.dos
@@ -9,7 +9,7 @@ LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \
 LYEditmap.o LYCharSets.o LYCharUtils.o LYMap.o LYCookie.o LYExtern.o \
 LYStyle.o LYHash.o LYPrettySrc.o TRSTable.o
 
-CFLAGS= -O1 $(MCFLAGS) $(INTLFLAGS) -I. -I.. $(SLANGINC)
+CFLAGS= -O2 $(MCFLAGS) $(INTLFLAGS) -I. -I.. $(SLANGINC)
 
 # comment this line to suppress DIRED support
 DIRED_DEFS = \
@@ -18,7 +18,7 @@ DIRED_DEFS = \
  -DOK_TAR \
  -DOK_GZIP \
  -DOK_ZIP \
- -DOK_OVERRIDE 
+ -DOK_OVERRIDE
 
 # Use this option to enable optional and *experimental* color style.
 #ENABLE_COLOR_STYLE = \
@@ -36,37 +36,47 @@ MCFLAGS = \
  -DEXP_ADDRLIST_PAGE \
  -DEXP_ALT_BINDINGS \
  -DEXP_FILE_UPLOAD \
+ -DEXP_NESTED_TABLES \
  -DEXP_PERSISTENT_COOKIES \
  -DFANCY_CURSES \
- -DNCURSES \
  -DNOUSERS \
  -DNO_CUSERID \
  -DNO_TTYTYPE \
  -DNO_UTMP \
+ -DPDCURSES \
  -DSOURCE_CACHE \
  -DUSE_EXTERNALS \
  -DUSE_PRETTYSRC \
  -DUSE_ZLIB \
  -DWATT32 \
+ $(SSLFLAGS) \
+ $(SSLINC) \
  -I./chrtrans \
  -I../WWW/Library/Implementation \
- -I../curses \
- -I../djgpp/watt32/inc \
- -I../djgpp/watt32/inc/sys
+ -I/djgpp/pdcur24 \
+ -I/djgpp/watt32/inc \
+ -I/djgpp/watt32/inc/sys
 
 WWWLIB = \
  ../WWW/Library/djgpp/libwww.a \
- ../curses/pdcurses.a \
- ../djgpp/watt32/lib/libwatt.a
+ /djgpp/pdcur24/lib/pdcurses.a
 
-LIBS= -lz # -lintl
+LIBS= -L/djgpp/watt32/lib -lwatt -lz -lwmemu
+
+# Uncomment the following to enable Internationalization.
 #INTLFLAGS = -DHAVE_GETTEXT -DHAVE_LIBINTL_H
+#INTLLIBS= -lintl -liconv
+
+# Uncomment the followint to enable SSL.
+#SSLFLAGS = -DUSE_SSL
+#SSLLIB = -lssl -lcrypto
+#SSLINC = -I/djgpp/include/openssl
 
 all: lynx
 
 lynx:   message $(OBJS) $(WWWLIB)
 	@echo "Linking and creating Lynx executable"
-	$(CC) $(CFLAGS) -o lynx.exe  $(OBJS) $(WWWLIB) $(LIBS)
+	$(CC) $(CFLAGS) -o lynx.exe  $(OBJS) $(WWWLIB) $(SSLLIB) $(LIBS) $(INTLLIBS)
 	@echo "Welcome to Lynx!"
 
 message:
diff --git a/src/makefile.in b/src/makefile.in
index 36bdb424..7add67d9 100644
--- a/src/makefile.in
+++ b/src/makefile.in
@@ -41,7 +41,7 @@ WWWLIB		= $(top_builddir)/WWW/Library/Implementation/libwww.a
 INTLLIB		= @INTLDIR_MAKE@@INTLLIBS@
 INTLDIR_CPPFLAGS= @INTLDIR_CPPFLAGS@-I$(top_srcdir)/intl
 
-CPP_OPTS	= $(CHARSET_DEFS) $(DEFS) $(CPPFLAGS) \
+CPP_OPTS	= $(CPPFLAGS) $(DEFS) $(CHARSET_DEFS) \
 		-DLOCALEDIR=\"$(localedir)\" \
 		-I. \
 		-I$(top_builddir) \