diff --git a/ChangeLog b/ChangeLog
index 62054409c2309cfa89568732056af4dce13ce5a8..109edc6fac32489c53f669e7d540be5e397b5f3c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -175,12 +175,12 @@ CVS code -
 	  paragraph-searching utility functions when possible instead of
 	  duplicating code.  Also overhaul the justify code to make it
 	  leave the right number of spaces at the ends of the lines of a
-	  paragraph, to make it (partially) support multibyte
-	  characters, and to make it simpler.  Also, don't remove a
-	  space after a duplicate character in punct anymore, as it
-	  doesn't really make us more compatible with Pico.  New
-	  functions do_para_begin_void() and do_para_end_void(); changes
-	  to justify_format(), do_para_begin(), inpar(), do_para_end(),
+	  paragraph, to make it support multibyte characters, and to
+	  make it simpler.  Also, don't remove a space after a duplicate
+	  character in punct anymore, as it doesn't really make us more
+	  compatible with Pico.  New functions mbstrchr(),
+	  do_para_begin_void(), and do_para_end_void(); changes to
+	  justify_format(), do_para_begin(), inpar(), do_para_end(),
 	  break_line(), do_para_search() (renamed find_paragraph()), and
 	  do_justify(); removal of breakable(). (DLR)
 	- Still more steps toward full wide/multibyte character support.
diff --git a/src/chars.c b/src/chars.c
index ae807a7b204ce98ef8e01daabf8dd0d5ae225831..79c66b89b1d29f8e4f0a9d9ae1ea3a3806728d08 100644
--- a/src/chars.c
+++ b/src/chars.c
@@ -811,3 +811,48 @@ size_t mbstrnlen(const char *s, size_t maxlen)
 		nstrnlen(s, maxlen);
 #endif
 }
+
+#ifndef DISABLE_JUSTIFY
+/* This function is equivalent to strchr() for multibyte strings. */
+char *mbstrchr(const char *s, char *c)
+{
+    assert(s != NULL && c != NULL);
+
+#ifdef NANO_WIDE
+    if (!ISSET(NO_UTF8)) {
+	char *s_mb = charalloc(MB_CUR_MAX);
+	const char *q = s;
+	wchar_t ws, wc;
+	int s_mb_len, c_mb_len = mbtowc(&wc, c, MB_CUR_MAX);
+
+	if (c_mb_len <= 0) {
+	    mbtowc(NULL, NULL, 0);
+	    wc = (unsigned char)*c;
+	}
+
+	while (*s != '\0') {
+	    s_mb_len = parse_mbchar(s, s_mb, NULL, NULL);
+
+	    if (mbtowc(&ws, s_mb, s_mb_len) <= 0) {
+		mbtowc(NULL, NULL, 0);
+		ws = (unsigned char)*s;
+	    }
+
+	    if (ws == wc)
+		break;
+
+	    s += s_mb_len;
+	    q += s_mb_len;
+	}
+
+	free(s_mb);
+
+	if (ws != wc)
+	    q = NULL;
+
+	return (char *)q;
+    } else
+#endif
+	return strchr(s, *c);
+}
+#endif
diff --git a/src/nano.c b/src/nano.c
index cdf6685e371507e86ef5ec9aeefb8230fa13ebbe..83bf41e19c9516bfe2325a95644c5f74a395b7be 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -2382,68 +2382,95 @@ void justify_format(filestruct *paragraph, size_t skip)
     new_end = new_paragraph_data + skip;
 
     while (*end != '\0') {
+	int end_len;
+
 	/* If this character is blank, make sure that it's a space with
 	 * no blanks after it. */
-	if (is_blank_char(*end)) {
+	if (is_blank_mbchar(end)) {
+	    end_len = parse_mbchar(end, NULL, NULL, NULL);
+
 	    *new_end = ' ';
 	    new_end++;
-	    end++;
+	    end += end_len;
 
-	    while (*end != '\0' && is_blank_char(*end)) {
-		end++;
-		shift++;
+	    while (*end != '\0' && is_blank_mbchar(end)) {
+		end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+		end += end_len;
+		shift += end_len;
 
 #ifndef NANO_SMALL
 		/* Keep track of the change in the current line. */
 		if (mark_beginbuf == paragraph &&
 			mark_beginx >= end - paragraph->data)
-		    mark_shift++;
+		    mark_shift += end_len;
 #endif
 	    }
 	/* If this character is punctuation optionally followed by a
 	 * bracket and then followed by blanks, make sure there are no
 	 * more than two blanks after it, and make sure that the blanks
 	 * are spaces. */
-	} else if (strchr(punct, *end) != NULL) {
-	    *new_end = *end;
-	    new_end++;
-	    end++;
+	} else if (mbstrchr(punct, end) != NULL) {
+	    end_len = parse_mbchar(end, NULL, NULL, NULL);
 
-	    if (*end != '\0' && strchr(brackets, *end) != NULL) {
+	    while (end_len > 0) {
 		*new_end = *end;
 		new_end++;
 		end++;
+		end_len--;
+	    }
+
+	    if (*end != '\0' && mbstrchr(brackets, end) != NULL) {
+		end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+		while (end_len > 0) {
+		    *new_end = *end;
+		    new_end++;
+		    end++;
+		    end_len--;
+		}
 	    }
 
-	    if (*end != '\0' && is_blank_char(*end)) {
+	    if (*end != '\0' && is_blank_mbchar(end)) {
+		end_len = parse_mbchar(end, NULL, NULL, NULL);
+
 		*new_end = ' ';
 		new_end++;
-		end++;
+		end += end_len;
 	    }
 
-	    if (*end != '\0' && is_blank_char(*end)) {
+	    if (*end != '\0' && is_blank_mbchar(end)) {
+		end_len = parse_mbchar(end, NULL, NULL, NULL);
+
 		*new_end = ' ';
 		new_end++;
-		end++;
+		end += end_len;
 	    }
 
-	    while (*end != '\0' && is_blank_char(*end)) {
-		end++;
-		shift++;
+	    while (*end != '\0' && is_blank_mbchar(end)) {
+		end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+		end += end_len;
+		shift += end_len;
 
 #ifndef NANO_SMALL
-	    /* Keep track of the change in the current line. */
-	    if (mark_beginbuf == paragraph &&
-		mark_beginx >= end - paragraph->data)
-		mark_shift++;
+		/* Keep track of the change in the current line. */
+		if (mark_beginbuf == paragraph &&
+			mark_beginx >= end - paragraph->data)
+		    mark_shift += end_len;
 #endif
 	    }
 	/* If this character is neither blank nor punctuation, leave it
 	 * alone. */
 	} else {
-	    *new_end = *end;
-	    new_end++;
-	    end++;
+	    end_len = parse_mbchar(end, NULL, NULL, NULL);
+
+	    while (end_len > 0) {
+		*new_end = *end;
+		new_end++;
+		end++;
+		end_len--;
+	    }
 	}
     }
 
@@ -2743,11 +2770,11 @@ ssize_t break_line(const char *line, ssize_t goal, bool force)
 	 * found with short enough display width.  */
     ssize_t cur_loc = 0;
 	/* Current index in line. */
+    int line_len;
 
     assert(line != NULL);
 
     while (*line != '\0' && goal >= 0) {
-	int line_len;
 	size_t pos = 0;
 
 	line_len = parse_mbchar(line, NULL, NULL, &pos);
@@ -2770,7 +2797,7 @@ ssize_t break_line(const char *line, ssize_t goal, bool force)
 	    bool found_blank = FALSE;
 
 	    while (*line != '\0') {
-		int line_len = parse_mbchar(line, NULL, NULL, NULL);
+		line_len = parse_mbchar(line, NULL, NULL, NULL);
 
 		if (is_blank_mbchar(line)) {
 		    if (!found_blank)
@@ -2786,11 +2813,18 @@ ssize_t break_line(const char *line, ssize_t goal, bool force)
 	}
     }
 
-    /* Perhaps the character after blank_loc is a blank.  But because
-     * of justify_format(), there can be only two adjacent. */
-    if (*(line - cur_loc + blank_loc + 1) == ' ' ||
-	*(line - cur_loc + blank_loc + 1) == '\0')
-	blank_loc++;
+    /* Move to the last blank after blank_loc, if there is one. */
+    line -= cur_loc;
+    line += blank_loc;
+    line_len = parse_mbchar(line, NULL, NULL, NULL);
+    line += line_len;
+
+    while (*line != '\0' && is_blank_mbchar(line)) {
+	line_len = parse_mbchar(line, NULL, NULL, NULL);
+
+	line += line_len;
+	blank_loc += line_len;
+    }
 
     return blank_loc;
 }
diff --git a/src/proto.h b/src/proto.h
index b6841634e49f577655bdd493986f482cc540577e..01b9a9a2af4f1a34ec31ffe8660bf6026dffae1b 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -207,6 +207,9 @@ size_t mbstrlen(const char *s);
 size_t nstrnlen(const char *s, size_t maxlen);
 #endif
 size_t mbstrnlen(const char *s, size_t maxlen);
+#ifndef DISABLE_JUSTIFY
+char *mbstrchr(const char *s, char *c);
+#endif
 
 /* Public functions in color.c. */
 #ifdef ENABLE_COLOR