diff --git a/7.4.852 b/7.4.852
new file mode 100644
index 0000000..c820cba
--- /dev/null
+++ b/7.4.852
@@ -0,0 +1,594 @@
+To: vim_dev@googlegroups.com
+Subject: Patch 7.4.852
+Fcc: outbox
+From: Bram Moolenaar <Bram@moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 7.4.852
+Problem:    On MS-Windows console Vim uses ANSI APIs for keyboard input and
+            console output, it cannot input/output Unicode characters.
+Solution:   Use Unicode APIs for console I/O. (Ken Takata, Yasuhiro Matsumoto)
+Files:      src/os_win32.c, src/ui.c, runtime/doc/options.txt
+
+
+*** ../vim-7.4.851/src/os_win32.c	2015-09-01 20:23:30.408603580 +0200
+--- src/os_win32.c	2015-09-01 20:28:43.193363546 +0200
+***************
+*** 213,220 ****
+  static void standend(void);
+  static void visual_bell(void);
+  static void cursor_visible(BOOL fVisible);
+! static BOOL write_chars(LPCSTR pchBuf, DWORD cchToWrite);
+! static char_u tgetch(int *pmodifiers, char_u *pch2);
+  static void create_conin(void);
+  static int s_cursor_visible = TRUE;
+  static int did_create_conin = FALSE;
+--- 213,220 ----
+  static void standend(void);
+  static void visual_bell(void);
+  static void cursor_visible(BOOL fVisible);
+! static DWORD write_chars(char_u *pchBuf, DWORD cbToWrite);
+! static WCHAR tgetch(int *pmodifiers, WCHAR *pch2);
+  static void create_conin(void);
+  static int s_cursor_visible = TRUE;
+  static int did_create_conin = FALSE;
+***************
+*** 265,279 ****
+      if (!win8_or_later)
+      {
+  	if (nLength == -1)
+! 	    return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents);
+! 	return ReadConsoleInput(hInput, lpBuffer, 1, &dwEvents);
+      }
+  
+      if (s_dwMax == 0)
+      {
+  	if (nLength == -1)
+! 	    return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents);
+! 	if (!ReadConsoleInput(hInput, s_irCache, IRSIZE, &dwEvents))
+  	    return FALSE;
+  	s_dwIndex = 0;
+  	s_dwMax = dwEvents;
+--- 265,279 ----
+      if (!win8_or_later)
+      {
+  	if (nLength == -1)
+! 	    return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
+! 	return ReadConsoleInputW(hInput, lpBuffer, 1, &dwEvents);
+      }
+  
+      if (s_dwMax == 0)
+      {
+  	if (nLength == -1)
+! 	    return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents);
+! 	if (!ReadConsoleInputW(hInput, s_irCache, IRSIZE, &dwEvents))
+  	    return FALSE;
+  	s_dwIndex = 0;
+  	s_dwMax = dwEvents;
+***************
+*** 868,876 ****
+  #endif
+  
+  #if defined(__GNUC__) && !defined(__MINGW32__)  && !defined(__CYGWIN__)
+! # define AChar AsciiChar
+  #else
+! # define AChar uChar.AsciiChar
+  #endif
+  
+  /* The return code indicates key code size. */
+--- 868,876 ----
+  #endif
+  
+  #if defined(__GNUC__) && !defined(__MINGW32__)  && !defined(__CYGWIN__)
+! # define UChar UnicodeChar
+  #else
+! # define UChar uChar.UnicodeChar
+  #endif
+  
+  /* The return code indicates key code size. */
+***************
+*** 889,900 ****
+  
+      if (s_iIsDead == 2)
+      {
+! 	pker->AChar = (CHAR) awAnsiCode[1];
+  	s_iIsDead = 0;
+  	return 1;
+      }
+  
+!     if (pker->AChar != 0)
+  	return 1;
+  
+      vim_memset(abKeystate, 0, sizeof (abKeystate));
+--- 889,900 ----
+  
+      if (s_iIsDead == 2)
+      {
+! 	pker->UChar = (WCHAR) awAnsiCode[1];
+  	s_iIsDead = 0;
+  	return 1;
+      }
+  
+!     if (pker->UChar != 0)
+  	return 1;
+  
+      vim_memset(abKeystate, 0, sizeof (abKeystate));
+***************
+*** 909,915 ****
+      }
+  
+      /* Clear any pending dead keys */
+!     ToAscii(VK_SPACE, MapVirtualKey(VK_SPACE, 0), abKeystate, awAnsiCode, 0);
+  
+      if (uMods & SHIFT_PRESSED)
+  	abKeystate[VK_SHIFT] = 0x80;
+--- 909,915 ----
+      }
+  
+      /* Clear any pending dead keys */
+!     ToUnicode(VK_SPACE, MapVirtualKey(VK_SPACE, 0), abKeystate, awAnsiCode, 2, 0);
+  
+      if (uMods & SHIFT_PRESSED)
+  	abKeystate[VK_SHIFT] = 0x80;
+***************
+*** 922,932 ****
+  	    abKeystate[VK_MENU] = abKeystate[VK_RMENU] = 0x80;
+      }
+  
+!     s_iIsDead = ToAscii(pker->wVirtualKeyCode, pker->wVirtualScanCode,
+! 			abKeystate, awAnsiCode, 0);
+  
+      if (s_iIsDead > 0)
+! 	pker->AChar = (CHAR) awAnsiCode[0];
+  
+      return s_iIsDead;
+  }
+--- 922,932 ----
+  	    abKeystate[VK_MENU] = abKeystate[VK_RMENU] = 0x80;
+      }
+  
+!     s_iIsDead = ToUnicode(pker->wVirtualKeyCode, pker->wVirtualScanCode,
+! 			abKeystate, awAnsiCode, 2, 0);
+  
+      if (s_iIsDead > 0)
+! 	pker->UChar = (WCHAR) awAnsiCode[0];
+  
+      return s_iIsDead;
+  }
+***************
+*** 953,960 ****
+      static BOOL
+  decode_key_event(
+      KEY_EVENT_RECORD	*pker,
+!     char_u		*pch,
+!     char_u		*pch2,
+      int			*pmodifiers,
+      BOOL		fDoPost)
+  {
+--- 953,960 ----
+      static BOOL
+  decode_key_event(
+      KEY_EVENT_RECORD	*pker,
+!     WCHAR		*pch,
+!     WCHAR		*pch2,
+      int			*pmodifiers,
+      BOOL		fDoPost)
+  {
+***************
+*** 982,988 ****
+      }
+  
+      /* special cases */
+!     if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0 && pker->AChar == NUL)
+      {
+  	/* Ctrl-6 is Ctrl-^ */
+  	if (pker->wVirtualKeyCode == '6')
+--- 982,988 ----
+      }
+  
+      /* special cases */
+!     if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0 && pker->UChar == NUL)
+      {
+  	/* Ctrl-6 is Ctrl-^ */
+  	if (pker->wVirtualKeyCode == '6')
+***************
+*** 1044,1050 ****
+  	*pch = NUL;
+      else
+      {
+! 	*pch = (i > 0) ? pker->AChar : NUL;
+  
+  	if (pmodifiers != NULL)
+  	{
+--- 1044,1050 ----
+  	*pch = NUL;
+      else
+      {
+! 	*pch = (i > 0) ? pker->UChar : NUL;
+  
+  	if (pmodifiers != NULL)
+  	{
+***************
+*** 1436,1442 ****
+      DWORD	    dwNow = 0, dwEndTime = 0;
+      INPUT_RECORD    ir;
+      DWORD	    cRecords;
+!     char_u	    ch, ch2;
+  
+      if (msec > 0)
+  	/* Wait until the specified time has elapsed. */
+--- 1436,1442 ----
+      DWORD	    dwNow = 0, dwEndTime = 0;
+      INPUT_RECORD    ir;
+      DWORD	    cRecords;
+!     WCHAR	    ch, ch2;
+  
+      if (msec > 0)
+  	/* Wait until the specified time has elapsed. */
+***************
+*** 1523,1529 ****
+  #ifdef FEAT_MBYTE_IME
+  		/* Windows IME sends two '\n's with only one 'ENTER'.  First:
+  		 * wVirtualKeyCode == 13. second: wVirtualKeyCode == 0 */
+! 		if (ir.Event.KeyEvent.uChar.UnicodeChar == 0
+  			&& ir.Event.KeyEvent.wVirtualKeyCode == 13)
+  		{
+  		    read_console_input(g_hConIn, &ir, 1, &cRecords);
+--- 1523,1529 ----
+  #ifdef FEAT_MBYTE_IME
+  		/* Windows IME sends two '\n's with only one 'ENTER'.  First:
+  		 * wVirtualKeyCode == 13. second: wVirtualKeyCode == 0 */
+! 		if (ir.Event.KeyEvent.UChar == 0
+  			&& ir.Event.KeyEvent.wVirtualKeyCode == 13)
+  		{
+  		    read_console_input(g_hConIn, &ir, 1, &cRecords);
+***************
+*** 1586,1595 ****
+  /*
+   * Get a keystroke or a mouse event
+   */
+!     static char_u
+! tgetch(int *pmodifiers, char_u *pch2)
+  {
+!     char_u ch;
+  
+      for (;;)
+      {
+--- 1586,1595 ----
+  /*
+   * Get a keystroke or a mouse event
+   */
+!     static WCHAR
+! tgetch(int *pmodifiers, WCHAR *pch2)
+  {
+!     WCHAR ch;
+  
+      for (;;)
+      {
+***************
+*** 1658,1668 ****
+  #define TYPEAHEADLEN 20
+      static char_u   typeahead[TYPEAHEADLEN];	/* previously typed bytes. */
+      static int	    typeaheadlen = 0;
+- #ifdef FEAT_MBYTE
+-     static char_u   *rest = NULL;	/* unconverted rest of previous read */
+-     static int	    restlen = 0;
+-     int		    unconverted;
+- #endif
+  
+      /* First use any typeahead that was kept because "buf" was too small. */
+      if (typeaheadlen > 0)
+--- 1658,1663 ----
+***************
+*** 1761,1798 ****
+  	else
+  #endif
+  	{
+! 	    char_u	ch2 = NUL;
+  	    int		modifiers = 0;
+  
+  	    c = tgetch(&modifiers, &ch2);
+  
+- #ifdef FEAT_MBYTE
+- 	    /* stolen from fill_input_buf() in ui.c */
+- 	    if (rest != NULL)
+- 	    {
+- 		/* Use remainder of previous call, starts with an invalid
+- 		 * character that may become valid when reading more. */
+- 		if (restlen > TYPEAHEADLEN - typeaheadlen)
+- 		    unconverted = TYPEAHEADLEN - typeaheadlen;
+- 		else
+- 		    unconverted = restlen;
+- 		mch_memmove(typeahead + typeaheadlen, rest, unconverted);
+- 		if (unconverted == restlen)
+- 		{
+- 		    vim_free(rest);
+- 		    rest = NULL;
+- 		}
+- 		else
+- 		{
+- 		    restlen -= unconverted;
+- 		    mch_memmove(rest, rest + unconverted, restlen);
+- 		}
+- 		typeaheadlen += unconverted;
+- 	    }
+- 	    else
+- 		unconverted = 0;
+- #endif
+- 
+  	    if (typebuf_changed(tb_change_cnt))
+  	    {
+  		/* "buf" may be invalid now if a client put something in the
+--- 1756,1766 ----
+  	else
+  #endif
+  	{
+! 	    WCHAR	ch2 = NUL;
+  	    int		modifiers = 0;
+  
+  	    c = tgetch(&modifiers, &ch2);
+  
+  	    if (typebuf_changed(tb_change_cnt))
+  	    {
+  		/* "buf" may be invalid now if a client put something in the
+***************
+*** 1816,1842 ****
+  		int	n = 1;
+  		int     conv = FALSE;
+  
+- 		typeahead[typeaheadlen] = c;
+- 		if (ch2 != NUL)
+- 		{
+- 		    typeahead[typeaheadlen + 1] = 3;
+- 		    typeahead[typeaheadlen + 2] = ch2;
+- 		    n += 2;
+- 		}
+  #ifdef FEAT_MBYTE
+! 		/* Only convert normal characters, not special keys.  Need to
+! 		 * convert before applying ALT, otherwise mapping <M-x> breaks
+! 		 * when 'tenc' is set. */
+! 		if (input_conv.vc_type != CONV_NONE
+! 						&& (ch2 == NUL || c != K_NUL))
+  		{
+! 		    conv = TRUE;
+! 		    typeaheadlen -= unconverted;
+! 		    n = convert_input_safe(typeahead + typeaheadlen,
+! 				n + unconverted, TYPEAHEADLEN - typeaheadlen,
+! 				rest == NULL ? &rest : NULL, &restlen);
+  		}
+  #endif
+  
+  		if (conv)
+  		{
+--- 1784,1819 ----
+  		int	n = 1;
+  		int     conv = FALSE;
+  
+  #ifdef FEAT_MBYTE
+! 		if (ch2 == NUL)
+  		{
+! 		    int	    i;
+! 		    char_u  *p;
+! 		    WCHAR   ch[2];
+! 
+! 		    ch[0] = c;
+! 		    if (c >= 0xD800 && c <= 0xDBFF)	/* High surrogate */
+! 		    {
+! 			ch[1] = tgetch(&modifiers, &ch2);
+! 			n++;
+! 		    }
+! 		    p = utf16_to_enc(ch, &n);
+! 		    if (p != NULL)
+! 		    {
+! 			for (i = 0; i < n; i++)
+! 			    typeahead[typeaheadlen + i] = p[i];
+! 			vim_free(p);
+! 		    }
+  		}
++ 		else
+  #endif
++ 		    typeahead[typeaheadlen] = c;
++ 		if (ch2 != NUL)
++ 		{
++ 		    typeahead[typeaheadlen + n] = 3;
++ 		    typeahead[typeaheadlen + n + 1] = (char_u)ch2;
++ 		    n += 2;
++ 		}
+  
+  		if (conv)
+  		{
+***************
+*** 5366,5392 ****
+  
+  
+  /*
+!  * write `cchToWrite' characters in `pchBuf' to the screen
+!  * Returns the number of characters actually written (at least one).
+   */
+!     static BOOL
+  write_chars(
+!     LPCSTR pchBuf,
+!     DWORD  cchToWrite)
+  {
+      COORD coord = g_coord;
+      DWORD written;
+  
+!     FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cchToWrite,
+! 				coord, &written);
+!     /* When writing fails or didn't write a single character, pretend one
+!      * character was written, otherwise we get stuck. */
+!     if (WriteConsoleOutputCharacter(g_hConOut, pchBuf, cchToWrite,
+! 				coord, &written) == 0
+! 	    || written == 0)
+! 	written = 1;
+  
+!     g_coord.X += (SHORT) written;
+  
+      while (g_coord.X > g_srScrollRegion.Right)
+      {
+--- 5343,5415 ----
+  
+  
+  /*
+!  * write `cbToWrite' bytes in `pchBuf' to the screen
+!  * Returns the number of bytes actually written (at least one).
+   */
+!     static DWORD
+  write_chars(
+!     char_u *pchBuf,
+!     DWORD  cbToWrite)
+  {
+      COORD coord = g_coord;
+      DWORD written;
+  
+! #ifdef FEAT_MBYTE
+!     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+!     {
+! 	static WCHAR	*unicodebuf = NULL;
+! 	static int	unibuflen = 0;
+! 	int		length;
+! 	DWORD		n, cchwritten, cells;
+! 
+! 	length = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pchBuf, cbToWrite, 0, 0);
+! 	if (unicodebuf == NULL || length > unibuflen)
+! 	{
+! 	    vim_free(unicodebuf);
+! 	    unicodebuf = (WCHAR *)lalloc(length * sizeof(WCHAR), FALSE);
+! 	    unibuflen = length;
+! 	}
+! 	MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pchBuf, cbToWrite,
+! 			    unicodebuf, unibuflen);
+! 
+! 	cells = mb_string2cells(pchBuf, cbToWrite);
+! 	FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cells,
+! 				    coord, &written);
+! 	/* When writing fails or didn't write a single character, pretend one
+! 	 * character was written, otherwise we get stuck. */
+! 	if (WriteConsoleOutputCharacterW(g_hConOut, unicodebuf, length,
+! 		    coord, &cchwritten) == 0
+! 		|| cchwritten == 0)
+! 	    cchwritten = 1;
+! 
+! 	if (cchwritten == length)
+! 	{
+! 	    written = cbToWrite;
+! 	    g_coord.X += (SHORT)cells;
+! 	}
+! 	else
+! 	{
+! 	    char_u *p = pchBuf;
+! 	    for (n = 0; n < cchwritten; n++)
+! 		mb_cptr_adv(p);
+! 	    written = p - pchBuf;
+! 	    g_coord.X += (SHORT)mb_string2cells(pchBuf, written);
+! 	}
+!     }
+!     else
+! #endif
+!     {
+! 	FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cbToWrite,
+! 				    coord, &written);
+! 	/* When writing fails or didn't write a single character, pretend one
+! 	 * character was written, otherwise we get stuck. */
+! 	if (WriteConsoleOutputCharacter(g_hConOut, (LPCSTR)pchBuf, cbToWrite,
+! 		    coord, &written) == 0
+! 		|| written == 0)
+! 	    written = 1;
+  
+! 	g_coord.X += (SHORT) written;
+!     }
+  
+      while (g_coord.X > g_srScrollRegion.Right)
+      {
+*** ../vim-7.4.851/src/ui.c	2015-08-11 19:13:55.146175594 +0200
+--- src/ui.c	2015-09-01 20:27:49.069924312 +0200
+***************
+*** 42,48 ****
+      /* Don't output anything in silent mode ("ex -s") unless 'verbose' set */
+      if (!(silent_mode && p_verbose == 0))
+      {
+! #ifdef FEAT_MBYTE
+  	char_u	*tofree = NULL;
+  
+  	if (output_conv.vc_type != CONV_NONE)
+--- 42,48 ----
+      /* Don't output anything in silent mode ("ex -s") unless 'verbose' set */
+      if (!(silent_mode && p_verbose == 0))
+      {
+! #if defined(FEAT_MBYTE) && !defined(WIN3264)
+  	char_u	*tofree = NULL;
+  
+  	if (output_conv.vc_type != CONV_NONE)
+***************
+*** 56,62 ****
+  
+  	mch_write(s, len);
+  
+! #ifdef FEAT_MBYTE
+  	if (output_conv.vc_type != CONV_NONE)
+  	    vim_free(tofree);
+  #endif
+--- 56,62 ----
+  
+  	mch_write(s, len);
+  
+! #if defined(FEAT_MBYTE) && !defined(WIN3264)
+  	if (output_conv.vc_type != CONV_NONE)
+  	    vim_free(tofree);
+  #endif
+*** ../vim-7.4.851/runtime/doc/options.txt	2015-07-21 17:53:11.573528028 +0200
+--- runtime/doc/options.txt	2015-09-01 20:29:21.724964297 +0200
+***************
+*** 7377,7390 ****
+  	the GUI it only applies to the keyboard ( 'encoding' is used for the
+  	display).  Except for the Mac when 'macatsui' is off, then
+  	'termencoding' should be "macroman".
+- 	In the Win32 console version the default value is the console codepage
+- 	when it differs from the ANSI codepage.
+  								*E617*
+  	Note: This does not apply to the GTK+ 2 GUI.  After the GUI has been
+  	successfully initialized, 'termencoding' is forcibly set to "utf-8".
+  	Any attempts to set a different value will be rejected, and an error
+  	message is shown.
+! 	For the Win32 GUI 'termencoding' is not used for typed characters,
+  	because the Win32 system always passes Unicode characters.
+  	When empty, the same encoding is used as for the 'encoding' option.
+  	This is the normal value.
+--- 7396,7407 ----
+  	the GUI it only applies to the keyboard ( 'encoding' is used for the
+  	display).  Except for the Mac when 'macatsui' is off, then
+  	'termencoding' should be "macroman".
+  								*E617*
+  	Note: This does not apply to the GTK+ 2 GUI.  After the GUI has been
+  	successfully initialized, 'termencoding' is forcibly set to "utf-8".
+  	Any attempts to set a different value will be rejected, and an error
+  	message is shown.
+! 	For the Win32 GUI and console versions 'termencoding' is not used,
+  	because the Win32 system always passes Unicode characters.
+  	When empty, the same encoding is used as for the 'encoding' option.
+  	This is the normal value.
+*** ../vim-7.4.851/src/version.c	2015-09-01 20:23:30.408603580 +0200
+--- src/version.c	2015-09-01 20:27:43.713979797 +0200
+***************
+*** 743,744 ****
+--- 743,746 ----
+  {   /* Add new patch number below this line */
++ /**/
++     852,
+  /**/
+
+-- 
+(letter from Mark to Mike, about the film's probable certificate)
+      I would like to get back to the Censor and agree to lose the shits, take
+      the odd Jesus Christ out and lose Oh fuck off, but to retain 'fart in
+      your general direction', 'castanets of your testicles' and 'oral sex'
+      and ask him for an 'A' rating on that basis.
+                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
+
+ /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
+///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
+\\\  an exciting new programming language -- http://www.Zimbu.org        ///
+ \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///