updated for version 7.0017
diff --git a/src/GvimExt/gvimext.cpp b/src/GvimExt/gvimext.cpp
index 1cb0b83..5a175d3 100644
--- a/src/GvimExt/gvimext.cpp
+++ b/src/GvimExt/gvimext.cpp
@@ -630,7 +630,7 @@
 	    *pos = 0;
 	}
 	// Now concatenate
-	strncpy(temp, _("Edit with existing Vim - &"), MAX_PATH - 1);
+	strncpy(temp, _("Edit with existing Vim - "), MAX_PATH - 1);
 	strncat(temp, title, MAX_PATH - 1);
 	InsertMenu(hMenu,
 		indexMenu++,
diff --git a/src/Makefile b/src/Makefile
index fade47f..72f0cb8 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1202,7 +1202,7 @@
 
 # All GUI files
 ALL_GUI_SRC  = gui.c gui_gtk.c gui_gtk_f.c gui_motif.c gui_athena.c gui_gtk_x11.c gui_x11.c gui_at_sb.c gui_at_fs.c pty.c gui_kde.cc gui_kde_wid.cc gui_kde_x11.cc gui_kde_wid_moc.cc
-ALL_GUI_PRO  = gui.pro gui_gtk.pro gui_motif.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w16.pro gui_w32.pro gui_amiga.pro gui_photon.pro gui_kde.pro gui_kde_x11.pro
+ALL_GUI_PRO  = gui.pro gui_gtk.pro gui_motif.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w16.pro gui_w32.pro gui_amiga.pro gui_photon.pro
 
 # }}}
 
diff --git a/src/digraph.c b/src/digraph.c
index de61ce2..4c15d49 100644
--- a/src/digraph.c
+++ b/src/digraph.c
@@ -1428,6 +1428,7 @@
 	{'L', 'i', 0x20a4},
 	{'P', 't', 0x20a7},
 	{'W', '=', 0x20a9},
+	{'=', 'e', 0x20ac}, /* euro */
 	{'o', 'C', 0x2103},
 	{'c', 'o', 0x2105},
 	{'o', 'F', 0x2109},
diff --git a/src/eval.c b/src/eval.c
index df83da5..492feba 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -8526,46 +8526,46 @@
     unsigned	len;
 
     oldval = vimvars[VV_CMDARG].val;
-    if (eap != NULL)
+    if (eap == NULL)
     {
-	if (eap->force_bin == FORCE_BIN)
-	    len = 6;
-	else if (eap->force_bin == FORCE_NOBIN)
-	    len = 8;
-	else
-	    len = 0;
-	if (eap->force_ff != 0)
-	    len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
-# ifdef FEAT_MBYTE
-	if (eap->force_enc != 0)
-	    len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
-# endif
-
-	newval = alloc(len + 1);
-	if (newval == NULL)
-	    return NULL;
-
-	if (eap->force_bin == FORCE_BIN)
-	    sprintf((char *)newval, " ++bin");
-	else if (eap->force_bin == FORCE_NOBIN)
-	    sprintf((char *)newval, " ++nobin");
-	else
-	    *newval = NUL;
-	if (eap->force_ff != 0)
-	    sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
-						    eap->cmd + eap->force_ff);
-# ifdef FEAT_MBYTE
-	if (eap->force_enc != 0)
-	    sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
-						   eap->cmd + eap->force_enc);
-# endif
-	vimvars[VV_CMDARG].val = newval;
-	return oldval;
+	vim_free(oldval);
+	vimvars[VV_CMDARG].val = oldarg;
+	return NULL;
     }
 
-    vim_free(oldval);
-    vimvars[VV_CMDARG].val = oldarg;
-    return NULL;
+    if (eap->force_bin == FORCE_BIN)
+	len = 6;
+    else if (eap->force_bin == FORCE_NOBIN)
+	len = 8;
+    else
+	len = 0;
+    if (eap->force_ff != 0)
+	len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
+# ifdef FEAT_MBYTE
+    if (eap->force_enc != 0)
+	len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
+# endif
+
+    newval = alloc(len + 1);
+    if (newval == NULL)
+	return NULL;
+
+    if (eap->force_bin == FORCE_BIN)
+	sprintf((char *)newval, " ++bin");
+    else if (eap->force_bin == FORCE_NOBIN)
+	sprintf((char *)newval, " ++nobin");
+    else
+	*newval = NUL;
+    if (eap->force_ff != 0)
+	sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
+						eap->cmd + eap->force_ff);
+# ifdef FEAT_MBYTE
+    if (eap->force_enc != 0)
+	sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
+					       eap->cmd + eap->force_enc);
+# endif
+    vimvars[VV_CMDARG].val = newval;
+    return oldval;
 }
 #endif
 
diff --git a/src/fileio.c b/src/fileio.c
index c925775..bf29748 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4066,7 +4066,7 @@
 	{
 #ifdef FEAT_MBYTE
 	    if (write_info.bw_conv_error)
-		errmsg = (char_u *)_("E513: write error, conversion failed");
+		errmsg = (char_u *)_("E513: write error, conversion failed (make 'fenc' empty to override)");
 	    else
 #endif
 		if (got_int)
diff --git a/src/globals.h b/src/globals.h
index 83e6c4b..9337134 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -677,6 +677,7 @@
 /* Codepage nr of 'encoding'.  Negative means it's not been set yet, zero
  * means 'encoding' is not a valid codepage. */
 EXTERN int	enc_codepage INIT(= -1);
+EXTERN int	enc_latin9 INIT(= FALSE);	/* 'encoding' is latin9 */
 # endif
 EXTERN int	has_mbyte INIT(= 0);		/* any multi-byte encoding */
 
diff --git a/src/gui_gtk.c b/src/gui_gtk.c
index 0d552c0..ed4e5bc 100644
--- a/src/gui_gtk.c
+++ b/src/gui_gtk.c
@@ -749,6 +749,10 @@
 
 	    text    = CONVERT_TO_UTF8(menu->dname);
 	    tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]);
+	    if (tooltip != NULL && !utf_valid_string(tooltip, NULL))
+		/* Invalid text, can happen when 'encoding' is changed.  Avoid
+		 * a nasty GTK error message, skip the tooltip. */
+		CONVERT_TO_UTF8_FREE(tooltip);
 
 	    menu->id = gtk_toolbar_insert_item(
 		    toolbar,
@@ -993,6 +997,8 @@
 
 # ifdef HAVE_GTK2
 	tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]);
+	if (tooltip == NULL || utf_valid_string(tooltip, NULL))
+	    /* Only set the tooltip when it's valid utf-8. */
 # else
 	tooltip = menu->strings[MENU_INDEX_TIP];
 # endif
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index aed649b..bc72773 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -5239,6 +5239,14 @@
 	int		last_glyph_rbearing;
 	int		cells = 0;  /* cells occupied by current cluster */
 
+	/* Safety check: pango crashes when invoked with invalid utf-8
+	 * characters. */
+	if (!utf_valid_string(s, s + len))
+	{
+	    column_offset = len;
+	    goto skipitall;
+	}
+
 	/* original width of the current cluster */
 	cluster_width = PANGO_SCALE * gui.char_width;
 
@@ -5372,6 +5380,7 @@
 	pango_attr_list_unref(attr_list);
     }
 
+skipitall:
     if (flags & DRAW_UNDERL)
 	gdk_draw_line(gui.drawarea->window,
 		      gui.text_gc,
diff --git a/src/gui_mac.c b/src/gui_mac.c
index 645e0b5..f60567e 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -2200,6 +2200,7 @@
     KeySym		key_sym;
     int			key_char;
     int			modifiers;
+    int			simplify = FALSE;
 
     /* Mask the mouse (as per user setting) */
     if (p_mh)
@@ -2253,7 +2254,7 @@
 
     /* Handle special keys. */
 #if 0
-    /* Why have this been removed? */
+    /* Why has this been removed? */
     if	(!(theEvent->modifiers & (cmdKey | controlKey | rightControlKey)))
 #endif
     {
@@ -2270,11 +2271,14 @@
 # endif
 			key_char = TO_SPECIAL(special_keys[i].vim_code0,
 						special_keys[i].vim_code1);
-		    key_char = simplify_key(key_char,&modifiers);
+		    simplify = TRUE;
 		    break;
 		}
     }
 
+    /* For some keys the modifier is included in the char itself. */
+    if (simplify || key_char == TAB || key_char == ' ')
+	key_char = simplify_key(key_char, &modifiers);
 
     /* Add the modifier to the input bu if needed */
     /* Do not want SHIFT-A or CTRL-A with modifier */
diff --git a/src/gui_w32.c b/src/gui_w32.c
index a3a7ffa..ef20a28 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -1709,6 +1709,33 @@
 }
 #endif
 
+#ifdef FEAT_MBYTE
+/*
+ * Convert latin9 text to ucs-2.
+ */
+    static void
+latin9_to_ucs(char_u *text, int len, WCHAR *unicodebuf)
+{
+    int		c;
+
+    while (len-- >= 0)
+    {
+	c = *text++;
+	switch (c)
+	{
+	    case 0xa4: c = 0x20ac; break;   /* euro */
+	    case 0xa6: c = 0x0160; break;   /* S hat */
+	    case 0xa8: c = 0x0161; break;   /* S -hat */
+	    case 0xb4: c = 0x017d; break;   /* Z hat */
+	    case 0xb8: c = 0x017e; break;   /* Z -hat */
+	    case 0xbc: c = 0x0152; break;   /* OE */
+	    case 0xbd: c = 0x0153; break;   /* oe */
+	    case 0xbe: c = 0x0178; break;   /* Y */
+	}
+	*unicodebuf++ = c;
+    }
+}
+#endif
 
 #ifdef FEAT_RIGHTLEFT
 /*
@@ -1907,7 +1934,9 @@
     /* Check if the Unicode buffer exists and is big enough.  Create it
      * with the same lengt as the multi-byte string, the number of wide
      * characters is always equal or smaller. */
-    if ((enc_utf8 || (enc_codepage > 0 && (int)GetACP() != enc_codepage))
+    if ((enc_utf8
+		|| (enc_codepage > 0 && (int)GetACP() != enc_codepage)
+		|| enc_latin9)
 	    && (unicodebuf == NULL || len > unibuflen))
     {
 	vim_free(unicodebuf);
@@ -1950,13 +1979,16 @@
 			     foptions, pcliprect, unicodebuf, clen, unicodepdy);
 	len = cells;	/* used for underlining */
     }
-    else if (enc_codepage > 0 && (int)GetACP() != enc_codepage)
+    else if ((enc_codepage > 0 && (int)GetACP() != enc_codepage) || enc_latin9)
     {
 	/* If we want to display codepage data, and the current CP is not the
 	 * ANSI one, we need to go via Unicode. */
 	if (unicodebuf != NULL)
 	{
-	    len = MultiByteToWideChar(enc_codepage,
+	    if (enc_latin9)
+		latin9_to_ucs(text, len, unicodebuf);
+	    else
+		len = MultiByteToWideChar(enc_codepage,
 			MB_PRECOMPOSED,
 			(char *)text, len,
 			(LPWSTR)unicodebuf, unibuflen);
diff --git a/src/gui_w48.c b/src/gui_w48.c
index 7b8d8de..eeaf651 100644
--- a/src/gui_w48.c
+++ b/src/gui_w48.c
@@ -3277,6 +3277,7 @@
     return 0;
 }
 
+
 /*
  * Get command line arguments.
  * Use "prog" as the name of the program and "cmdline" as the arguments.
@@ -3299,6 +3300,14 @@
     char	**argv = NULL;
     int		round;
 
+#ifdef FEAT_MBYTE
+    /* Try using the Unicode version first, it takes care of conversion when
+     * 'encoding' is changed. */
+    argc = get_cmd_argsW(&argv);
+    if (argc != 0)
+	goto done;
+#endif
+
     /* Handle the program name.  Remove the ".exe" extension, and find the 1st
      * non-space. */
     p = strrchr(prog, '.');
@@ -3405,8 +3414,9 @@
 	}
     }
 
-    argv[argc] = NULL;		/* NULL-terminated list */
+done:
 
+    argv[argc] = NULL;		/* NULL-terminated list */
     *argvp = argv;
     return argc;
 }
diff --git a/src/mbyte.c b/src/mbyte.c
index a71fb51..0710966 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -216,7 +216,7 @@
 #define IDX_ISO_14	13
     {"iso-8859-14",	ENC_8BIT,		0},
 #define IDX_ISO_15	14
-    {"iso-8859-15",	ENC_8BIT,		0},
+    {"iso-8859-15",	ENC_8BIT + ENC_LATIN9,	0},
 #define IDX_KOI8_R	15
     {"koi8-r",		ENC_8BIT,		0},
 #define IDX_KOI8_U	16
@@ -534,6 +534,7 @@
 
 #ifdef WIN3264
     enc_codepage = encname2codepage(p_enc);
+    enc_latin9 = (STRCMP(p_enc, "iso-8859-15") == 0);
 #endif
 
     /*
@@ -2486,6 +2487,36 @@
     return 1 - dbcs_head_off(base, p);
 }
 
+#if defined(HAVE_GTK2) || defined(PROTO)
+/*
+ * Return TRUE if string "s" is a valid utf-8 string.
+ * When "end" is NULL stop at the first NUL.
+ * When "end" is positive stop there.
+ */
+    int
+utf_valid_string(s, end)
+    char_u	*s;
+    char_u	*end;
+{
+    int		l;
+    char_u	*p = s;
+
+    while (end == NULL ? *p != NUL : p < end)
+    {
+	if ((*p & 0xc0) == 0x80)
+	    return FALSE;	/* invalid lead byte */
+	l = utf8len_tab[*p];
+	if (end != NULL && p + l > end)
+	    return FALSE;	/* incomplete byte sequence */
+	++p;
+	while (--l > 0)
+	    if ((*p++ & 0xc0) != 0x80)
+		return FALSE;	/* invalid trail byte */
+    }
+    return TRUE;
+}
+#endif
+
 #if defined(FEAT_GUI) || defined(PROTO)
 /*
  * Special version of mb_tail_off() for use in ScreenLines[].
@@ -5453,11 +5484,22 @@
 	vcp->vc_type = CONV_TO_UTF8;
 	vcp->vc_factor = 2;	/* up to twice as long */
     }
+    else if ((from_prop & ENC_LATIN9) && (to_prop & ENC_UNICODE))
+    {
+	/* Internal latin9 -> utf-8 conversion. */
+	vcp->vc_type = CONV_9_TO_UTF8;
+	vcp->vc_factor = 3;	/* up to three as long (euro sign) */
+    }
     else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_LATIN1))
     {
 	/* Internal utf-8 -> latin1 conversion. */
 	vcp->vc_type = CONV_TO_LATIN1;
     }
+    else if ((from_prop & ENC_UNICODE) && (to_prop & ENC_LATIN9))
+    {
+	/* Internal utf-8 -> latin9 conversion. */
+	vcp->vc_type = CONV_TO_LATIN9;
+    }
 #ifdef WIN3264
     /* Win32-specific codepage <-> codepage conversion without iconv. */
     else if (((from_prop & ENC_UNICODE) || encname2codepage(from) > 0)
@@ -5622,12 +5664,13 @@
 	    d = retval;
 	    for (i = 0; i < len; ++i)
 	    {
-		if (ptr[i] < 0x80)
-		    *d++ = ptr[i];
+		c = ptr[i];
+		if (c < 0x80)
+		    *d++ = c;
 		else
 		{
-		    *d++ = 0xc0 + ((unsigned)ptr[i] >> 6);
-		    *d++ = 0x80 + (ptr[i] & 0x3f);
+		    *d++ = 0xc0 + ((unsigned)c >> 6);
+		    *d++ = 0x80 + (c & 0x3f);
 		}
 	    }
 	    *d = NUL;
@@ -5635,7 +5678,34 @@
 		*lenp = (int)(d - retval);
 	    break;
 
+	case CONV_9_TO_UTF8:	/* latin9 to utf-8 conversion */
+	    retval = alloc(len * 3 + 1);
+	    if (retval == NULL)
+		break;
+	    d = retval;
+	    for (i = 0; i < len; ++i)
+	    {
+		c = ptr[i];
+		switch (c)
+		{
+		    case 0xa4: c = 0x20ac; break;   /* euro */
+		    case 0xa6: c = 0x0160; break;   /* S hat */
+		    case 0xa8: c = 0x0161; break;   /* S -hat */
+		    case 0xb4: c = 0x017d; break;   /* Z hat */
+		    case 0xb8: c = 0x017e; break;   /* Z -hat */
+		    case 0xbc: c = 0x0152; break;   /* OE */
+		    case 0xbd: c = 0x0153; break;   /* oe */
+		    case 0xbe: c = 0x0178; break;   /* Y */
+		}
+		d += utf_char2bytes(c, d);
+	    }
+	    *d = NUL;
+	    if (lenp != NULL)
+		*lenp = (int)(d - retval);
+	    break;
+
 	case CONV_TO_LATIN1:	/* utf-8 to latin1 conversion */
+	case CONV_TO_LATIN9:	/* utf-8 to latin9 conversion */
 	    retval = alloc(len + 1);
 	    if (retval == NULL)
 		break;
@@ -5658,6 +5728,26 @@
 		else
 		{
 		    c = utf_ptr2char(ptr + i);
+		    if (vcp->vc_type == CONV_TO_LATIN9)
+			switch (c)
+			{
+			    case 0x20ac: c = 0xa4; break;   /* euro */
+			    case 0x0160: c = 0xa6; break;   /* S hat */
+			    case 0x0161: c = 0xa8; break;   /* S -hat */
+			    case 0x017d: c = 0xb4; break;   /* Z hat */
+			    case 0x017e: c = 0xb8; break;   /* Z -hat */
+			    case 0x0152: c = 0xbc; break;   /* OE */
+			    case 0x0153: c = 0xbd; break;   /* oe */
+			    case 0x0178: c = 0xbe; break;   /* Y */
+			    case 0xa4:
+			    case 0xa6:
+			    case 0xa8:
+			    case 0xb4:
+			    case 0xb8:
+			    case 0xbc:
+			    case 0xbd:
+			    case 0xbe: c = 0x100; break; /* not in latin9 */
+			}
 		    if (!utf_iscomposing(c))	/* skip composing chars */
 		    {
 			if (c < 0x100)
diff --git a/src/menu.c b/src/menu.c
index fc8411f..258b84d 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -392,6 +392,8 @@
 	    map_to = (char_u *)"";
 	    map_buf = NULL;
 	}
+	else if (modes & MENU_TIP_MODE)
+	    map_buf = NULL;	/* Menu tips are plain text. */
 	else
 	    map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE);
 	menuarg.modes = modes;
diff --git a/src/os_mswin.c b/src/os_mswin.c
index 7b5da8a..7f2288e 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -267,6 +267,10 @@
     AnsiUpperBuff(toupper_tab, 256);
     AnsiLowerBuff(tolower_tab, 256);
 #endif
+
+#if defined(FEAT_MBYTE) && !defined(FEAT_GUI)
+    (void)get_cmd_argsW(NULL);
+#endif
 }
 
 
@@ -298,7 +302,25 @@
     gui_mch_settitle(title, icon);
 # else
     if (title != NULL)
+    {
+#  ifdef FEAT_MBYTE
+	if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+	{
+	    /* Convert the title from 'encoding' to the active codepage. */
+	    WCHAR	*wp = enc_to_ucs2(title, NULL);
+	    int	n;
+
+	    if (wp != NULL)
+	    {
+		n = SetConsoleTitleW(wp);
+		vim_free(wp);
+		if (n != 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+		    return;
+	    }
+	}
+#  endif
 	SetConsoleTitle(title);
+    }
 # endif
 }
 
diff --git a/src/os_w32exe.c b/src/os_w32exe.c
index 7bdcead..ac9bf3c 100644
--- a/src/os_w32exe.c
+++ b/src/os_w32exe.c
@@ -30,24 +30,6 @@
 	__ARGS((int argc, char **argv));
 int (_cdecl *pmain)(int, char **);
 
-#ifdef FEAT_MBYTE
-/* The commandline arguments in UCS2. */
-static DWORD	nArgsW = 0;
-static LPWSTR	*ArglistW = NULL;
-static int	global_argc;
-static char	**global_argv;
-
-static int	used_file_argc = 0;	/* last argument in global_argv[] used
-					   for the argument list. */
-static int	*used_file_indexes = NULL; /* indexes in global_argv[] for
-					      command line arguments added to
-					      the argument list */
-static int	used_file_count = 0;	/* nr of entries in used_file_indexes */
-static int	used_file_literal = FALSE;  /* take file names literally */
-static int	used_file_full_path = FALSE;  /* file name was full path */
-static int	used_alist_count = 0;
-#endif
-
 #ifndef PROTO
 #ifdef FEAT_GUI
 #ifndef VIMDLL
@@ -76,56 +58,14 @@
      * startup path (so the .vimrc file can be found w/o a VIM env. var.) */
     GetModuleFileName(NULL, prog, 255);
 
-    /* Separate the command line into arguments.  Use the Unicode functions
-     * when possible. When 'encoding' is later changed these are used to
-     * recode the arguments. */
-#ifdef FEAT_MBYTE
-    ArglistW = CommandLineToArgvW(GetCommandLineW(), &nArgsW);
-    if (ArglistW != NULL)
-    {
-	argv = malloc((nArgsW + 1) * sizeof(char *));
-	if (argv != NULL)
-	{
-	    int		i;
-
-	    argv[argc] = NULL;
-	    argc = nArgsW;
-	    for (i = 0; i < argc; ++i)
-	    {
-		int	len;
-
-		WideCharToMultiByte_alloc(GetACP(), 0,
-				ArglistW[i], wcslen(ArglistW[i]) + 1,
-				(LPSTR *)&argv[i], &len, 0, 0);
-		if (argv[i] == NULL)
-		{
-		    while (i > 0)
-			free(argv[--i]);
-		    free(argv);
-		    argc = 0;
-		}
-	    }
-	}
-    }
-
+    argc = get_cmd_args(prog, (char *)lpszCmdLine, &argv, &tofree);
     if (argc == 0)
-#endif
     {
-	argc = get_cmd_args(prog, (char *)lpszCmdLine, &argv, &tofree);
-	if (argc == 0)
-	{
-	    MessageBox(0, "Could not allocate memory for command line.",
-								  "VIM Error", 0);
-	    return 0;
-	}
+	MessageBox(0, "Could not allocate memory for command line.",
+							      "VIM Error", 0);
+	return 0;
     }
 
-#ifdef FEAT_MBYTE
-    global_argc = argc;
-    global_argv = argv;
-    used_file_indexes = malloc(argc * sizeof(int));
-#endif
-
 #ifdef DYNAMIC_GETTEXT
     /* Initialize gettext library */
     dyn_libintl_init(NULL);
@@ -190,108 +130,9 @@
     free(argv);
     free(tofree);
 #ifdef FEAT_MBYTE
-    if (ArglistW != NULL)
-	GlobalFree(ArglistW);
+    free_cmd_argsW();
 #endif
 
     return 0;
 }
 #endif
-
-#ifdef FEAT_MBYTE
-/*
- * Remember "name" is an argument that was added to the argument list.
- * This avoids that we have to re-parse the argument list when fix_arg_enc()
- * is called.
- */
-    void
-used_file_arg(name, literal, full_path)
-    char	*name;
-    int		literal;
-    int		full_path;
-{
-    int		i;
-
-    if (used_file_indexes == NULL)
-	return;
-    for (i = used_file_argc + 1; i < global_argc; ++i)
-	if (STRCMP(global_argv[i], name) == 0)
-	{
-	    used_file_argc = i;
-	    used_file_indexes[used_file_count++] = i;
-	    break;
-	}
-    used_file_literal = literal;
-    used_file_full_path = full_path;
-}
-
-/*
- * Remember the length of the argument list as it was.  If it changes then we
- * leave it alone when 'encoding' is set.
- */
-    void
-set_alist_count(void)
-{
-    used_alist_count = GARGCOUNT;
-}
-
-/*
- * Fix the encoding of the command line arguments.  Invoked when 'encoding'
- * has been changed while starting up.  Use the UCS-2 command line arguments
- * and convert them to 'encoding'.
- */
-    void
-fix_arg_enc()
-{
-    int		i;
-    int		idx;
-    char_u	*str;
-
-    /* Safety checks:
-     * - if argument count differs between the wide and non-wide argument
-     *   list, something must be wrong.
-     * - the file name arguments must have been located.
-     * - the length of the argument list wasn't changed by the user.
-     */
-    if (global_argc != (int)nArgsW
-	    || ArglistW == NULL
-	    || used_file_indexes == NULL
-	    || used_file_count == 0
-	    || used_alist_count != GARGCOUNT)
-	return;
-
-    /* Clear the argument list.  Make room for the new arguments. */
-    alist_clear(&global_alist);
-    if (ga_grow(&global_alist.al_ga, used_file_count) == FAIL)
-	return;	    /* out of memory */
-
-    for (i = 0; i < used_file_count; ++i)
-    {
-	idx = used_file_indexes[i];
-	str = ucs2_to_enc(ArglistW[idx], NULL);
-	if (str != NULL)
-	    alist_add(&global_alist, str, used_file_literal ? 2 : 0);
-    }
-
-    if (!used_file_literal)
-    {
-	/* Now expand wildcards in the arguments. */
-	/* Temporarily add '(' and ')' to 'isfname'.  These are valid
-	 * filename characters but are excluded from 'isfname' to make
-	 * "gf" work on a file name in parenthesis (e.g.: see vim.h). */
-	do_cmdline_cmd((char_u *)":let SaVe_ISF = &isf|set isf+=(,)");
-	alist_expand();
-	do_cmdline_cmd((char_u *)":let &isf = SaVe_ISF|unlet SaVe_ISF");
-    }
-
-    /* If wildcard expansion failed, we are editing the first file of the
-     * arglist and there is no file name: Edit the first argument now. */
-    if (curwin->w_arg_idx == 0 && curbuf->b_fname == NULL)
-    {
-	do_cmdline_cmd((char_u *)":rewind");
-	if (GARGCOUNT == 1 && used_file_full_path)
-	    (void)vim_chdirfile(alist_name(&GARGLIST[0]));
-    }
-}
-#endif
-
diff --git a/src/os_win32.c b/src/os_win32.c
index bc6c7d4..fce48f9 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -92,6 +92,7 @@
 #define WINAPI
 #define WINBASEAPI
 typedef char * LPCSTR;
+typedef char * LPWSTR;
 typedef int ACCESS_MASK;
 typedef int BOOL;
 typedef int COLORREF;
@@ -301,19 +302,19 @@
 }
 
     static char *
-null_libintl_gettext(const char* msgid)
+null_libintl_gettext(const char *msgid)
 {
     return (char*)msgid;
 }
 
     static char *
-null_libintl_bindtextdomain(const char* domainname, const char* dirname)
+null_libintl_bindtextdomain(const char *domainname, const char *dirname)
 {
     return NULL;
 }
 
     static char *
-null_libintl_textdomain(const char* domainname)
+null_libintl_textdomain(const char *domainname)
 {
     return NULL;
 }
@@ -530,7 +531,7 @@
     __stdcall
 #endif
 win32_kbd_patch_key(
-    KEY_EVENT_RECORD* pker)
+    KEY_EVENT_RECORD *pker)
 {
     UINT uMods = pker->dwControlKeyState;
     static int s_iIsDead = 0;
@@ -734,8 +735,7 @@
  */
 # ifdef FEAT_GUI_W32
     void
-mch_setmouse(
-    int on)
+mch_setmouse(int on)
 {
 }
 # else
@@ -749,8 +749,7 @@
  * Enable or disable mouse input
  */
     void
-mch_setmouse(
-    int on)
+mch_setmouse(int on)
 {
     DWORD cmodein;
 
@@ -798,7 +797,7 @@
  */
     static BOOL
 decode_mouse_event(
-    MOUSE_EVENT_RECORD* pmer)
+    MOUSE_EVENT_RECORD *pmer)
 {
     static int s_nOldButton = -1;
     static int s_nOldMouseClick = -1;
@@ -1214,7 +1213,7 @@
  * return non-zero if a character is available
  */
     int
-mch_char_avail()
+mch_char_avail(void)
 {
     return WaitForChar(0L);
 }
@@ -1579,7 +1578,7 @@
  * GUI version of mch_init().
  */
     void
-mch_init()
+mch_init(void)
 {
 #ifndef __MINGW32__
     extern int _fmode;
@@ -1746,10 +1745,10 @@
 
 typedef struct ConsoleBufferStruct
 {
-    BOOL IsValid;
-    CONSOLE_SCREEN_BUFFER_INFO Info;
-    PCHAR_INFO Buffer;
-    COORD BufferSize;
+    BOOL			IsValid;
+    CONSOLE_SCREEN_BUFFER_INFO	Info;
+    PCHAR_INFO			Buffer;
+    COORD			BufferSize;
 } ConsoleBuffer;
 
 /*
@@ -1853,8 +1852,8 @@
  */
     static BOOL
 RestoreConsoleBuffer(
-    ConsoleBuffer *cb,
-    BOOL RestoreScreen)
+    ConsoleBuffer   *cb,
+    BOOL	    RestoreScreen)
 {
     COORD BufferCoord;
     SMALL_RECT WriteRegion;
@@ -1949,23 +1948,19 @@
  */
     static BOOL
 GetConsoleIcon(
-    HWND hWnd,
-    HICON *phIconSmall,
-    HICON *phIcon)
+    HWND	hWnd,
+    HICON	*phIconSmall,
+    HICON	*phIcon)
 {
     if (hWnd == NULL)
 	return FALSE;
 
     if (phIconSmall != NULL)
-    {
-	*phIconSmall = (HICON) SendMessage(hWnd, WM_GETICON,
-			    (WPARAM) ICON_SMALL, (LPARAM) 0);
-    }
+	*phIconSmall = (HICON)SendMessage(hWnd, WM_GETICON,
+					       (WPARAM)ICON_SMALL, (LPARAM)0);
     if (phIcon != NULL)
-    {
-	*phIcon = (HICON) SendMessage(hWnd, WM_GETICON,
-			    (WPARAM) ICON_BIG, (LPARAM) 0);
-    }
+	*phIcon = (HICON)SendMessage(hWnd, WM_GETICON,
+						 (WPARAM)ICON_BIG, (LPARAM)0);
     return TRUE;
 }
 
@@ -1979,26 +1974,22 @@
  */
     static BOOL
 SetConsoleIcon(
-    HWND hWnd,
-    HICON hIconSmall,
-    HICON hIcon)
+    HWND    hWnd,
+    HICON   hIconSmall,
+    HICON   hIcon)
 {
-    HICON hPrevIconSmall;
-    HICON hPrevIcon;
+    HICON   hPrevIconSmall;
+    HICON   hPrevIcon;
 
     if (hWnd == NULL)
 	return FALSE;
 
     if (hIconSmall != NULL)
-    {
-	hPrevIconSmall = (HICON) SendMessage(hWnd, WM_SETICON,
-			    (WPARAM) ICON_SMALL, (LPARAM) hIconSmall);
-    }
+	hPrevIconSmall = (HICON)SendMessage(hWnd, WM_SETICON,
+				      (WPARAM)ICON_SMALL, (LPARAM)hIconSmall);
     if (hIcon != NULL)
-    {
-	hPrevIcon = (HICON) SendMessage(hWnd, WM_SETICON,
-			    (WPARAM) ICON_BIG, (LPARAM) hIcon);
-    }
+	hPrevIcon = (HICON)SendMessage(hWnd, WM_SETICON,
+					     (WPARAM)ICON_BIG,(LPARAM) hIcon);
     return TRUE;
 }
 
@@ -2059,7 +2050,7 @@
  * non-GUI version of mch_init().
  */
     void
-mch_init()
+mch_init(void)
 {
 #ifndef FEAT_RESTORE_ORIG_SCREEN
     CONSOLE_SCREEN_BUFFER_INFO csbi;
@@ -2341,8 +2332,8 @@
  */
     int
 mch_get_user_name(
-    char_u *s,
-    int len)
+    char_u  *s,
+    int	    len)
 {
     char szUserName[MAX_COMPUTERNAME_LENGTH + 1];
     DWORD cch = sizeof szUserName;
@@ -2379,7 +2370,7 @@
  * return process ID
  */
     long
-mch_get_pid()
+mch_get_pid(void)
 {
     return (long)GetCurrentProcessId();
 }
@@ -2429,8 +2420,7 @@
  * else FILE_ATTRIBUTE_* defined in winnt.h
  */
     long
-mch_getperm(
-    char_u *name)
+mch_getperm(char_u *name)
 {
 #ifdef FEAT_MBYTE
     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
@@ -2457,8 +2447,8 @@
  */
     int
 mch_setperm(
-    char_u *name,
-    long perm)
+    char_u  *name,
+    long    perm)
 {
     perm |= FILE_ATTRIBUTE_ARCHIVE;	/* file has changed, set archive bit */
 #ifdef FEAT_MBYTE
@@ -2656,8 +2646,7 @@
  * Return NULL if the ACL is not available for whatever reason.
  */
     vim_acl_T
-mch_get_acl(fname)
-    char_u	*fname;
+mch_get_acl(char_u *fname)
 {
 #ifndef HAVE_ACL
     return (vim_acl_T)NULL;
@@ -2701,9 +2690,7 @@
  * This must only be called with "acl" equal to what mch_get_acl() returned.
  */
     void
-mch_set_acl(fname, acl)
-    char_u	*fname;
-    vim_acl_T	acl;
+mch_set_acl(char_u *fname, vim_acl_T acl)
 {
 #ifdef HAVE_ACL
     struct my_acl   *p = (struct my_acl *)acl;
@@ -2726,8 +2713,7 @@
 }
 
     void
-mch_free_acl(acl)
-    vim_acl_T	acl;
+mch_free_acl(vim_acl_T acl)
 {
 #ifdef HAVE_ACL
     struct my_acl   *p = (struct my_acl *)acl;
@@ -2791,8 +2777,7 @@
  * set the tty in (raw) ? "raw" : "cooked" mode
  */
     void
-mch_settmode(
-    int tmode)
+mch_settmode(int tmode)
 {
     DWORD cmodein;
     DWORD cmodeout;
@@ -2840,7 +2825,7 @@
  * Return OK when size could be determined, FAIL otherwise.
  */
     int
-mch_get_shellsize()
+mch_get_shellsize(void)
 {
     CONSOLE_SCREEN_BUFFER_INFO csbi;
 
@@ -2873,9 +2858,9 @@
  */
     static void
 ResizeConBufAndWindow(
-    HANDLE hConsole,
-    int xSize,
-    int ySize)
+    HANDLE  hConsole,
+    int	    xSize,
+    int	    ySize)
 {
     CONSOLE_SCREEN_BUFFER_INFO csbi;	/* hold current console buffer info */
     SMALL_RECT	    srWindowRect;	/* hold the new console size */
@@ -2955,7 +2940,7 @@
  * Set the console window to `Rows' * `Columns'
  */
     void
-mch_set_shellsize()
+mch_set_shellsize(void)
 {
     COORD coordScreen;
 
@@ -2984,7 +2969,7 @@
  * Rows and/or Columns has changed.
  */
     void
-mch_new_shellsize()
+mch_new_shellsize(void)
 {
     set_scroll_region(0, 0, Columns - 1, Rows - 1);
 }
@@ -2994,7 +2979,7 @@
  * Called when started up, to set the winsize that was delayed.
  */
     void
-mch_set_winsize_now()
+mch_set_winsize_now(void)
 {
     if (suppress_winsize == 2)
     {
@@ -3134,8 +3119,8 @@
  */
     int
 mch_call_shell(
-    char_u *cmd,
-    int options)	/* SHELL_*, see vim.h */
+    char_u  *cmd,
+    int	    options)	/* SHELL_*, see vim.h */
 {
     int		x = 0;
     int		tmode = cur_tmode;
@@ -3510,8 +3495,7 @@
  * Scroll the scroll region up by `cLines' lines
  */
     static void
-scroll(
-    unsigned cLines)
+scroll(unsigned cLines)
 {
     COORD oldcoord = g_coord;
 
@@ -3549,8 +3533,7 @@
  * Insert `cLines' lines at the current cursor position
  */
     static void
-insert_lines(
-    unsigned cLines)
+insert_lines(unsigned cLines)
 {
     SMALL_RECT	    source;
     COORD	    dest;
@@ -3591,8 +3574,7 @@
  * Delete `cLines' lines at the current cursor position
  */
     static void
-delete_lines(
-    unsigned cLines)
+delete_lines(unsigned cLines)
 {
     SMALL_RECT	    source;
     COORD	    dest;
@@ -3655,8 +3637,7 @@
  * See ../doc/os_win32.txt for the numbers.
  */
     static void
-textattr(
-    WORD wAttr)
+textattr(WORD wAttr)
 {
     g_attrCurrent = wAttr;
 
@@ -3665,8 +3646,7 @@
 
 
     static void
-textcolor(
-    WORD wAttr)
+textcolor(WORD wAttr)
 {
     g_attrCurrent = (g_attrCurrent & 0xf0) + wAttr;
 
@@ -3675,8 +3655,7 @@
 
 
     static void
-textbackground(
-    WORD wAttr)
+textbackground(WORD wAttr)
 {
     g_attrCurrent = (g_attrCurrent & 0x0f) + (wAttr << 4);
 
@@ -3688,7 +3667,7 @@
  * restore the default text attribute (whatever we started with)
  */
     static void
-normvideo()
+normvideo(void)
 {
     textattr(g_attrDefault);
 }
@@ -3711,7 +3690,7 @@
  * Turn off standout mode
  */
     static void
-standend()
+standend(void)
 {
     if (g_attrPreStandout)
     {
@@ -3725,7 +3704,7 @@
  * Set normal fg/bg color, based on T_ME.  Called whem t_me has been set.
  */
     void
-mch_set_normal_colors()
+mch_set_normal_colors(void)
 {
     char_u	*p;
     int		n;
@@ -3749,7 +3728,7 @@
  * visual bell: flash the screen
  */
     static void
-visual_bell()
+visual_bell(void)
 {
     COORD   coordOrigin = {0, 0};
     WORD    attrFlash = ~g_attrCurrent & 0xff;
@@ -3775,8 +3754,7 @@
  * Make the cursor visible or invisible
  */
     static void
-cursor_visible(
-    BOOL fVisible)
+cursor_visible(BOOL fVisible)
 {
     s_cursor_visible = fVisible;
 #ifdef MCH_CURSOR_SHAPE
@@ -4178,7 +4156,7 @@
  * check for an "interrupt signal": CTRL-break or CTRL-C
  */
     void
-mch_breakcheck()
+mch_breakcheck(void)
 {
 #ifndef FEAT_GUI_W32	    /* never used */
     if (g_fCtrlCPressed || g_fCBrkPressed)
@@ -4195,8 +4173,7 @@
  * Return sum of available physical and page file memory.
  */
     long_u
-mch_avail_mem(
-    int special)
+mch_avail_mem(int special)
 {
     MEMORYSTATUS	ms;
 
@@ -4382,7 +4359,7 @@
  * Get the default shell for the current hardware platform
  */
     char *
-default_shell()
+default_shell(void)
 {
     char* psz = NULL;
 
@@ -4867,5 +4844,177 @@
 
     return 1;
 }
+#endif
 
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * The command line arguments in UCS2
+ */
+static DWORD	nArgsW = 0;
+static LPWSTR	*ArglistW = NULL;
+static int	global_argc = 0;
+static char	**global_argv;
+
+static int	used_file_argc = 0;	/* last argument in global_argv[] used
+					   for the argument list. */
+static int	*used_file_indexes = NULL; /* indexes in global_argv[] for
+					      command line arguments added to
+					      the argument list */
+static int	used_file_count = 0;	/* nr of entries in used_file_indexes */
+static int	used_file_literal = FALSE;  /* take file names literally */
+static int	used_file_full_path = FALSE;  /* file name was full path */
+static int	used_alist_count = 0;
+
+
+/*
+ * Get the command line arguments.  Unicode version.
+ * Returns argc.  Zero when something fails.
+ */
+    int
+get_cmd_argsW(char ***argvp)
+{
+    char	**argv = NULL;
+    int		argc = 0;
+    int		i;
+
+    ArglistW = CommandLineToArgvW(GetCommandLineW(), &nArgsW);
+    if (ArglistW != NULL)
+    {
+	argv = malloc((nArgsW + 1) * sizeof(char *));
+	if (argv != NULL)
+	{
+	    argc = nArgsW;
+	    argv[argc] = NULL;
+	    for (i = 0; i < argc; ++i)
+	    {
+		int	len;
+
+		/* Convert each Unicode argument to the current codepage. */
+		WideCharToMultiByte_alloc(GetACP(), 0,
+				ArglistW[i], wcslen(ArglistW[i]) + 1,
+				(LPSTR *)&argv[i], &len, 0, 0);
+		if (argv[i] == NULL)
+		{
+		    /* Out of memory, clear everything. */
+		    while (i > 0)
+			free(argv[--i]);
+		    free(argv);
+		    argc = 0;
+		}
+	    }
+	}
+    }
+
+    global_argc = argc;
+    global_argv = argv;
+    if (argc > 0)
+	used_file_indexes = malloc(argc * sizeof(int));
+
+    if (argvp != NULL)
+	*argvp = argv;
+    return argc;
+}
+
+    void
+free_cmd_argsW(void)
+{
+    if (ArglistW != NULL)
+    {
+	GlobalFree(ArglistW);
+	ArglistW = NULL;
+    }
+}
+
+/*
+ * Remember "name" is an argument that was added to the argument list.
+ * This avoids that we have to re-parse the argument list when fix_arg_enc()
+ * is called.
+ */
+    void
+used_file_arg(char *name, int literal, int full_path)
+{
+    int		i;
+
+    if (used_file_indexes == NULL)
+	return;
+    for (i = used_file_argc + 1; i < global_argc; ++i)
+	if (STRCMP(global_argv[i], name) == 0)
+	{
+	    used_file_argc = i;
+	    used_file_indexes[used_file_count++] = i;
+	    break;
+	}
+    used_file_literal = literal;
+    used_file_full_path = full_path;
+}
+
+/*
+ * Remember the length of the argument list as it was.  If it changes then we
+ * leave it alone when 'encoding' is set.
+ */
+    void
+set_alist_count(void)
+{
+    used_alist_count = GARGCOUNT;
+}
+
+/*
+ * Fix the encoding of the command line arguments.  Invoked when 'encoding'
+ * has been changed while starting up.  Use the UCS-2 command line arguments
+ * and convert them to 'encoding'.
+ */
+    void
+fix_arg_enc(void)
+{
+    int		i;
+    int		idx;
+    char_u	*str;
+
+    /* Safety checks:
+     * - if argument count differs between the wide and non-wide argument
+     *   list, something must be wrong.
+     * - the file name arguments must have been located.
+     * - the length of the argument list wasn't changed by the user.
+     */
+    if (global_argc != (int)nArgsW
+	    || ArglistW == NULL
+	    || used_file_indexes == NULL
+	    || used_file_count == 0
+	    || used_alist_count != GARGCOUNT)
+	return;
+
+    /* Clear the argument list.  Make room for the new arguments. */
+    alist_clear(&global_alist);
+    if (ga_grow(&global_alist.al_ga, used_file_count) == FAIL)
+	return;	    /* out of memory */
+
+    for (i = 0; i < used_file_count; ++i)
+    {
+	idx = used_file_indexes[i];
+	str = ucs2_to_enc(ArglistW[idx], NULL);
+	if (str != NULL)
+	    alist_add(&global_alist, str, used_file_literal ? 2 : 0);
+    }
+
+    if (!used_file_literal)
+    {
+	/* Now expand wildcards in the arguments. */
+	/* Temporarily add '(' and ')' to 'isfname'.  These are valid
+	 * filename characters but are excluded from 'isfname' to make
+	 * "gf" work on a file name in parenthesis (e.g.: see vim.h). */
+	do_cmdline_cmd((char_u *)":let SaVe_ISF = &isf|set isf+=(,)");
+	alist_expand();
+	do_cmdline_cmd((char_u *)":let &isf = SaVe_ISF|unlet SaVe_ISF");
+    }
+
+    /* If wildcard expansion failed, we are editing the first file of the
+     * arglist and there is no file name: Edit the first argument now. */
+    if (curwin->w_arg_idx == 0 && curbuf->b_fname == NULL)
+    {
+	do_cmdline_cmd((char_u *)":rewind");
+	if (GARGCOUNT == 1 && used_file_full_path)
+	    (void)vim_chdirfile(alist_name(&GARGLIST[0]));
+    }
+}
 #endif
diff --git a/src/proto/gui_kde.pro b/src/proto/gui_kde.pro
index 3a52fa7..50671f4 100644
--- a/src/proto/gui_kde.pro
+++ b/src/proto/gui_kde.pro
@@ -1,4 +1,4 @@
-/* gui_kde.c */
+/* gui_kde.cc */
 void gui_mch_add_menu __ARGS((vimmenu_T *menu, int idx));
 void gui_mch_add_menu_item __ARGS((vimmenu_T *menu, int idx));
 void gui_mch_set_text_area_pos __ARGS((int x, int y, int w, int h));
@@ -16,4 +16,4 @@
 void gui_mch_replace_dialog __ARGS((exarg_T *eap));
 void ex_helpfind __ARGS((exarg_T *eap));
 void gui_make_popup __ARGS((char_u *path_name));
-/* vim: set ft=c : */
+/* vim: set ft=cpp : */
diff --git a/src/proto/gui_kde_x11.pro b/src/proto/gui_kde_x11.pro
index 7d968d9..c4eb5b0 100644
--- a/src/proto/gui_kde_x11.pro
+++ b/src/proto/gui_kde_x11.pro
@@ -1,4 +1,4 @@
-/* gui_kde_x11.c */
+/* gui_kde_x11.cc */
 void gui_mch_prepare __ARGS((int *argc, char **argv));
 void gui_mch_set_blinking __ARGS((long waittime, long on, long off));
 void gui_mch_stop_blink __ARGS((void));
@@ -59,4 +59,4 @@
 char_u *gui_mch_font_dialog __ARGS((char_u *oldval));
 void gui_mch_settitle __ARGS((char_u *title,char_u *icon));
 void gui_mch_update_codec __ARGS((void));
-/* vim: set ft=c : */
+/* vim: set ft=cpp : */
diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro
index 9567a0a..88f14f4 100644
--- a/src/proto/mbyte.pro
+++ b/src/proto/mbyte.pro
@@ -47,6 +47,7 @@
 int utf_head_off __ARGS((char_u *base, char_u *p));
 int mb_off_next __ARGS((char_u *base, char_u *p));
 int mb_tail_off __ARGS((char_u *base, char_u *p));
+int utf_valid_string __ARGS((char_u *s, char_u *end));
 int dbcs_screen_tail_off __ARGS((char_u *base, char_u *p));
 void mb_adjust_cursor __ARGS((void));
 void mb_adjustpos __ARGS((pos_T *lp));
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index 2daa146..185c8ad 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -45,4 +45,9 @@
 FILE *mch_fopen __ARGS((char *name, char *mode));
 int mch_copy_file_attribute __ARGS((char_u *from, char_u *to));
 int myresetstkoflw __ARGS((void));
+int get_cmd_argsW __ARGS((char ***argvp));
+void free_cmd_argsW __ARGS((void));
+void used_file_arg __ARGS((char *name, int literal, int full_path));
+void set_alist_count __ARGS((void));
+void fix_arg_enc __ARGS((void));
 /* vim: set ft=c : */
diff --git a/src/proto/syntax.pro b/src/proto/syntax.pro
index b4dd3ea..82cebce 100644
--- a/src/proto/syntax.pro
+++ b/src/proto/syntax.pro
@@ -13,7 +13,7 @@
 int syn_get_id __ARGS((long lnum, long col, int trans));
 int syn_get_foldlevel __ARGS((win_T *wp, long lnum));
 void init_highlight __ARGS((int both, int reset));
-int load_colors __ARGS((char_u *p));
+int load_colors __ARGS((char_u *name));
 void do_highlight __ARGS((char_u *line, int forceit, int init));
 void restore_cterm_colors __ARGS((void));
 void set_normal_colors __ARGS((void));
diff --git a/src/quickfix.c b/src/quickfix.c
index b939275..0cb9c69 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1124,6 +1124,7 @@
 # endif
 	    if (win_split(0, n) == FAIL)
 		goto theend;
+	    opened_window = TRUE;	/* close it when fail */
 
 	    if (curwin->w_height < p_hh)
 		win_setheight((int)p_hh);
@@ -1137,7 +1138,7 @@
      * If currently in the quickfix window, find another window to show the
      * file in.
      */
-    if (bt_quickfix(curbuf))
+    if (bt_quickfix(curbuf) && !opened_window)
     {
 	/*
 	 * If there is no file specified, we don't know where to go.
diff --git a/src/screen.c b/src/screen.c
index 628be9a..6c1d6cc 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -6651,9 +6651,14 @@
 			len = screen_Columns;
 		    else
 			len = Columns;
-		    mch_memmove(new_ScreenLines + new_LineOffset[new_row],
-			    ScreenLines + LineOffset[old_row],
-			    (size_t)len * sizeof(schar_T));
+#ifdef FEAT_MBYTE
+		    /* When switching to utf-8 dont copy characters, they
+		     * may be invalid now. */
+		    if (!(enc_utf8 && ScreenLinesUC == NULL))
+#endif
+			mch_memmove(new_ScreenLines + new_LineOffset[new_row],
+				ScreenLines + LineOffset[old_row],
+				(size_t)len * sizeof(schar_T));
 #ifdef FEAT_MBYTE
 		    if (enc_utf8 && ScreenLinesUC != NULL)
 		    {
diff --git a/src/structs.h b/src/structs.h
index 9297f13..4975af5 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -854,16 +854,18 @@
 
 #define CONV_NONE		0
 #define CONV_TO_UTF8		1
-#define CONV_TO_LATIN1		2
-#define CONV_ICONV		3
+#define CONV_9_TO_UTF8		2
+#define CONV_TO_LATIN1		3
+#define CONV_TO_LATIN9		4
+#define CONV_ICONV		5
 #ifdef WIN3264
-# define CONV_CODEPAGE		4	/* codepage -> codepage */
+# define CONV_CODEPAGE		10	/* codepage -> codepage */
 #endif
 #ifdef MACOS_X
-# define CONV_MAC_LATIN1	5
-# define CONV_LATIN1_MAC	6
-# define CONV_MAC_UTF8		7
-# define CONV_UTF8_MAC		8
+# define CONV_MAC_LATIN1	20
+# define CONV_LATIN1_MAC	21
+# define CONV_MAC_UTF8		22
+# define CONV_UTF8_MAC		23
 #endif
 
 /*
diff --git a/src/syntax.c b/src/syntax.c
index e99f097..4956aec 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -437,17 +437,21 @@
     linenr_T	parsed_lnum;
     linenr_T	first_stored;
     int		dist;
+    static int	changedtick = 0;	/* remember the last change ID */
 
     reg_syn = TRUE;	/* let vim_regexec() know we're using syntax */
 
     /*
      * After switching buffers, invalidate current_state.
+     * Also do this when a change was made, the current state may be invalid
+     * then.
      */
-    if (syn_buf != wp->w_buffer)
+    if (syn_buf != wp->w_buffer || changedtick != syn_buf->b_changedtick)
     {
 	invalidate_current_state();
 	syn_buf = wp->w_buffer;
     }
+    changedtick = syn_buf->b_changedtick;
     syn_win = wp;
 
     /*
@@ -7392,7 +7396,7 @@
 	return i + ATTR_OFF;
     }
 
-    if (table->ga_len + ATTR_OFF == 256)
+    if (table->ga_len + ATTR_OFF >= 256)
     {
 	/*
 	 * Running out of attribute entries!  remove all attributes, and
diff --git a/src/testdir/test.ok b/src/testdir/test.ok
deleted file mode 100644
index 1842af2..0000000
--- a/src/testdir/test.ok
+++ /dev/null
@@ -1,92 +0,0 @@
-Results of test49.vim:
-*** Test   1: OK (34695)
-*** Test   2: OK (34695)
-*** Test   3: OK (1384648195)
-*** Test   4: OK (32883)
-*** Test   5: OK (32883)
-*** Test   6: OK (603978947)
-*** Test   7: OK (90563)
-*** Test   8: OK (562493431)
-*** Test   9: OK (363)
-*** Test  10: OK (559615)
-*** Test  11: OK (2049)
-*** Test  12: OK (352256)
-*** Test  13: OK (145)
-*** Test  14: OK (42413)
-*** Test  15: OK (42413)
-*** Test  16: OK (8722)
-*** Test  17: OK (285127993)
-*** Test  18: OK (67224583)
-*** Test  19: OK (69275973)
-*** Test  20: OK (1874575085)
-*** Test  21: OK (147932225)
-*** Test  22: OK (4161)
-*** Test  23: OK (49)
-*** Test  24: OK (41)
-*** Test  25: OK (260177811)
-*** Test  26: OK (1681500476)
-*** Test  27: OK (1996459)
-*** Test  28: OK (1996459)
-*** Test  29: OK (170428555)
-*** Test  30: OK (190905173)
-*** Test  31: OK (190905173)
-*** Test  32: OK (354833067)
---- Test  33: sum = 178275600 (ok)
-*** Test  33: OK (1216907538)
-*** Test  34: OK (2146584868)
-*** Test  35: OK (2146584868)
-*** Test  36: OK (1071644672)
-*** Test  37: OK (1071644672)
-*** Test  38: OK (357908480)
-*** Test  39: OK (357908480)
-*** Test  40: OK (357908480)
-*** Test  41: OK (3076095)
-*** Test  42: OK (1505155949)
-*** Test  43: OK (1157763329)
-*** Test  44: OK (1031761407)
-*** Test  45: OK (1157763329)
-*** Test  46: OK (739407)
-*** Test  47: OK (371213935)
-*** Test  48: OK (756255461)
-*** Test  49: OK (179000669)
-*** Test  50: OK (363550045)
-*** Test  51: OK (40744667)
-*** Test  52: OK (1247112011)
-*** Test  53: OK (131071)
-*** Test  54: OK (2047)
-*** Test  55: OK (1023)
-*** Test  56: OK (511)
-*** Test  57: OK (2147450880)
-*** Test  58: OK (624945)
-*** Test  59: OK (2038431743)
-*** Test  60: OK (311511339)
-*** Test  61: OK (374889517)
-*** Test  62: OK (286331153)
-*** Test  63: OK (236978127)
-*** Test  64: OK (1499645335)
-*** Test  65: OK (70187)
-*** Test  66: OK (5464)
-*** Test  67: OK (212514423)
-*** Test  68: OK (212514423)
-*** Test  69: OK (8995471)
-*** Test  70: OK (69544277)
-*** Test  71: OK (34886997)
-*** Test  72: OK (1789569365)
-*** Test  73: OK (9032615)
-*** Test  74: OK (224907669)
-*** Test  75: OK (2000403408)
-*** Test  76: OK (1610087935)
-*** Test  77: OK (1388671)
-*** Test  78: OK (134217728)
-*** Test  79: OK (70288929)
-*** Test  80: OK (17895765)
-*** Test  81: OK (387)
-*** Test  82: OK (8454401)
-*** Test  83: OK (2835)
-*** Test  84: OK (934782101)
-*** Test  85: OK (198689)
---- Test  86: All tests were run with throwing exceptions on error.
-	      The $VIMNOERRTHROW control is not configured.
---- Test  86: All tests were run with throwing exceptions on interrupt.
-	      The $VIMNOINTTHROW control is not configured.
-*** Test  86: OK (50443995)
diff --git a/src/version.c b/src/version.c
index e656314..f27f0ea 100644
--- a/src/version.c
+++ b/src/version.c
@@ -17,6 +17,7 @@
  * Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred)
  * It has been changed beyond recognition since then.
  *
+ * Differences between version 6.x and 7.x can be found with ":help version7".
  * Differences between version 5.x and 6.x can be found with ":help version6".
  * Differences between version 4.x and 5.x can be found with ":help version5".
  * Differences between version 3.0 and 4.x can be found with ":help version4".
@@ -1028,7 +1029,7 @@
 	"",
 	N_("type  :q<Enter>               to exit         "),
 	N_("type  :help<Enter>  or  <F1>  for on-line help"),
-	N_("type  :help version6<Enter>   for version info"),
+	N_("type  :help version7<Enter>   for version info"),
 	NULL,
 	"",
 	N_("Running in Vi compatible mode"),
diff --git a/src/version.h b/src/version.h
index 5799d9c..67b47d5 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2004 June 30)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2004 June 30, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2004 Oct 4)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2004 Oct 4, compiled "
diff --git a/src/vim.h b/src/vim.h
index 66eed35..11ff2a5 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1715,7 +1715,8 @@
 # define ENC_2WORD	0x100	    /* Unicode: UTF-16 */
 
 # define ENC_LATIN1	0x200	    /* Latin1 */
-# define ENC_MACROMAN	0x400	    /* Mac Roman (not Macro Man! :-) */
+# define ENC_LATIN9	0x400	    /* Latin9 */
+# define ENC_MACROMAN	0x800	    /* Mac Roman (not Macro Man! :-) */
 #endif
 
 #ifdef FEAT_MBYTE