updated for version 7.0d04
diff --git a/src/diff.c b/src/diff.c
index 4896c04..f5577f1 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1807,7 +1807,8 @@
     char_u	*line_org;
     char_u	*line_new;
     int		i;
-    int		si, ei_org, ei_new;
+    int		si_org, si_new;
+    int		ei_org, ei_new;
     diff_T	*dp;
     int		idx;
     int		off;
@@ -1838,34 +1839,66 @@
 	    if (off >= dp->df_count[i])
 		continue;
 	    added = FALSE;
-	    line_new = ml_get_buf(curtab->tp_diffbuf[i], dp->df_lnum[i] + off, FALSE);
+	    line_new = ml_get_buf(curtab->tp_diffbuf[i],
+						 dp->df_lnum[i] + off, FALSE);
 
 	    /* Search for start of difference */
-	    for (si = 0; line_org[si] != NUL && line_org[si] == line_new[si]; )
-		++si;
+	    si_org = si_new = 0;
+	    while (line_org[si_org] != NUL)
+	    {
+		if ((diff_flags & DIFF_IWHITE)
+			&& vim_iswhite(line_org[si_org])
+			&& vim_iswhite(line_new[si_new]))
+		{
+		    si_org = skipwhite(line_org + si_org) - line_org;
+		    si_new = skipwhite(line_new + si_new) - line_new;
+		}
+		else
+		{
+		    if (line_org[si_org] != line_new[si_new])
+			break;
+		    ++si_org;
+		    ++si_new;
+		}
+	    }
 #ifdef FEAT_MBYTE
 	    if (has_mbyte)
 	    {
 		/* Move back to first byte of character in both lines (may
 		 * have "nn^" in line_org and "n^ in line_new). */
-		si -= (*mb_head_off)(line_org, line_org + si);
-		si -= (*mb_head_off)(line_new, line_new + si);
+		si_org -= (*mb_head_off)(line_org, line_org + si_org);
+		si_new -= (*mb_head_off)(line_new, line_new + si_new);
 	    }
 #endif
-	    if (*startp > si)
-		*startp = si;
+	    if (*startp > si_org)
+		*startp = si_org;
 
 	    /* Search for end of difference, if any. */
-	    if (line_org[si] != NUL || line_new[si] != NUL)
+	    if (line_org[si_org] != NUL || line_new[si_new] != NUL)
 	    {
 		ei_org = (int)STRLEN(line_org);
 		ei_new = (int)STRLEN(line_new);
-		while (ei_org >= *startp && ei_new >= *startp
-			&& ei_org >= 0 && ei_new >= 0
-			&& line_org[ei_org] == line_new[ei_new])
+		while (ei_org >= *startp && ei_new >= si_new
+						&& ei_org >= 0 && ei_new >= 0)
 		{
-		    --ei_org;
-		    --ei_new;
+		    if ((diff_flags & DIFF_IWHITE)
+			    && vim_iswhite(line_org[ei_org])
+			    && vim_iswhite(line_new[ei_new]))
+		    {
+			while (ei_org >= *startp
+					     && vim_iswhite(line_org[ei_org]))
+			    --ei_org;
+			while (ei_new >= si_new
+					     && vim_iswhite(line_new[ei_new]))
+			    --ei_new;
+		    }
+		    else
+		    {
+			if (line_org[ei_org] != line_new[ei_new])
+			    break;
+			--ei_org;
+			--ei_new;
+		    }
 		}
 		if (*endp < ei_org)
 		    *endp = ei_org;
diff --git a/src/edit.c b/src/edit.c
index a57787a..8fd9ed4 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -2140,7 +2140,7 @@
      * - a copy of fname, FREE_FNAME is set to free later THE allocated mem.
      * - NULL otherwise.	--Acevedo */
     if (fname != NULL
-	    && compl_curr_match
+	    && compl_curr_match != NULL
 	    && compl_curr_match->cp_fname != NULL
 	    && STRCMP(fname, compl_curr_match->cp_fname) == 0)
 	match->cp_fname = compl_curr_match->cp_fname;
@@ -2501,6 +2501,11 @@
 						    * compl_match_arraysize));
 	if (compl_match_array != NULL)
 	{
+	    /* If the current match is the original text don't find the first
+	     * match after it, don't highlight anything. */
+	    if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
+		shown_match_ok = TRUE;
+
 	    i = 0;
 	    compl = compl_first_match;
 	    do
@@ -2571,8 +2576,10 @@
 	    if (compl_match_array[i].pum_text == compl_shown_match->cp_str
 		    || compl_match_array[i].pum_text
 				      == compl_shown_match->cp_text[CPT_ABBR])
+	    {
+		cur = i;
 		break;
-	cur = i;
+	    }
     }
 
     if (compl_match_array != NULL)
@@ -2951,6 +2958,8 @@
 	ins_compl_free();
 	compl_started = FALSE;
 	compl_matches = 0;
+	compl_cont_status = 0;
+	compl_cont_mode = 0;
     }
 
     line = ml_get_curline();
@@ -2983,6 +2992,15 @@
 	    }
 	}
 
+	/* Go to the original text, since none of the matches is inserted. */
+	if (compl_first_match->cp_prev != NULL
+		&& (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT))
+	    compl_shown_match = compl_first_match->cp_prev;
+	else
+	    compl_shown_match = compl_first_match;
+	compl_curr_match = compl_shown_match;
+	compl_shows_dir = compl_direction;
+
 	/* Show the popup menu with a different set of matches. */
 	ins_compl_show_pum();
 	compl_used_match = FALSE;
diff --git a/src/eval.c b/src/eval.c
index 45efab7..8728608 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4696,8 +4696,8 @@
 }
 
 /*
- * Evaluate an "[expr]" or "[expr:expr]" index.
- * "*arg" points to the '['.
+ * Evaluate an "[expr]" or "[expr:expr]" index.  Also "dict.key".
+ * "*arg" points to the '[' or '.'.
  * Returns FAIL or OK. "*arg" is advanced to after the ']'.
  */
     static int
@@ -4867,7 +4867,9 @@
 
 		    if (n2 < 0)
 			n2 = len + n2;
-		    if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1))
+		    else if (n2 >= len)
+			n2 = len - 1;
+		    if (!empty2 && (n2 < 0 || n2 + 1 < n1))
 		    {
 			if (verbose)
 			    EMSGN(_(e_listidx), n2);
diff --git a/src/gui_w48.c b/src/gui_w48.c
index 7592c7f..f99662f 100644
--- a/src/gui_w48.c
+++ b/src/gui_w48.c
@@ -2118,7 +2118,7 @@
     hChild = rChild.bottom - rChild.top;
 
     /* If Vim is minimized put the window in the middle of the screen. */
-    if (IsMinimized(hwndParent))
+    if (hwndParent == NULL || IsMinimized(hwndParent))
     {
 #ifdef WIN16
 	rParent.left = 0;
diff --git a/src/misc1.c b/src/misc1.c
index 905df15..dd1da46 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -4658,18 +4658,30 @@
     pos_T	*pos;
     char_u	*line;
     char_u	*p;
+    int		cur_maxcomment = ind_maxcomment;
 
-    if ((pos = findmatchlimit(NULL, '*', FM_BACKWARD, ind_maxcomment)) == NULL)
-	return NULL;
+    for (;;)
+    {
+	pos = findmatchlimit(NULL, '*', FM_BACKWARD, cur_maxcomment);
+	if (pos == NULL)
+	    break;
 
-    /*
-     * Check if the comment start we found is inside a string.
-     */
-    line = ml_get(pos->lnum);
-    for (p = line; *p && (unsigned)(p - line) < pos->col; ++p)
-	p = skip_string(p);
-    if ((unsigned)(p - line) > pos->col)
-	return NULL;
+	/*
+	 * Check if the comment start we found is inside a string.
+	 * If it is then restrict the search to below this line and try again.
+	 */
+	line = ml_get(pos->lnum);
+	for (p = line; *p && (unsigned)(p - line) < pos->col; ++p)
+	    p = skip_string(p);
+	if ((unsigned)(p - line) <= pos->col)
+	    break;
+	cur_maxcomment = curwin->w_cursor.lnum - pos->lnum - 1;
+	if (cur_maxcomment <= 0)
+	{
+	    pos = NULL;
+	    break;
+	}
+    }
     return pos;
 }
 
@@ -4770,6 +4782,7 @@
 static int	cin_iselse __ARGS((char_u *));
 static int	cin_isdo __ARGS((char_u *));
 static int	cin_iswhileofdo __ARGS((char_u *, linenr_T, int));
+static int	cin_iswhileofdo_end __ARGS((int terminated, int	ind_maxparen, int ind_maxcomment));
 static int	cin_isbreak __ARGS((char_u *));
 static int	cin_is_cpp_baseclass __ARGS((char_u *line, colnr_T *col));
 static int	get_baseclass_amount __ARGS((int col, int ind_maxparen, int ind_maxcomment, int ind_cpp_baseclass));
@@ -5078,7 +5091,7 @@
 
 /*
  * Find indent for line "lnum", ignoring any case or jump label.
- * Also return a pointer to the text (after the label).
+ * Also return a pointer to the text (after the label) in "pp".
  *   label:	if (asdf && asdfasdf)
  *		^
  */
@@ -5442,6 +5455,66 @@
     return retval;
 }
 
+/*
+ * Return TRUE if we are at the end of a do-while.
+ *    do
+ *       nothing;
+ *    while (foo
+ *             && bar);  <-- here
+ * Adjust the cursor to the line with "while".
+ */
+    static int
+cin_iswhileofdo_end(terminated, ind_maxparen, ind_maxcomment)
+    int	    terminated;
+    int	    ind_maxparen;
+    int	    ind_maxcomment;
+{
+    char_u	*line;
+    char_u	*p;
+    char_u	*s;
+    pos_T	*trypos;
+    int		i;
+
+    if (terminated != ';')	/* there must be a ';' at the end */
+	return FALSE;
+
+    p = line = ml_get_curline();
+    while (*p != NUL)
+    {
+	p = cin_skipcomment(p);
+	if (*p == ')')
+	{
+	    s = skipwhite(p + 1);
+	    if (*s == ';' && cin_nocode(s + 1))
+	    {
+		/* Found ");" at end of the line, now check there is "while"
+		 * before the matching '('.  XXX */
+		i = p - line;
+		curwin->w_cursor.col = i;
+		trypos = find_match_paren(ind_maxparen, ind_maxcomment);
+		if (trypos != NULL)
+		{
+		    s = cin_skipcomment(ml_get(trypos->lnum));
+		    if (*s == '}')		/* accept "} while (cond);" */
+			s = cin_skipcomment(s + 1);
+		    if (STRNCMP(s, "while", 5) == 0 && !vim_isIDc(s[5]))
+		    {
+			curwin->w_cursor.lnum = trypos->lnum;
+			return TRUE;
+		    }
+		}
+
+		/* Searching may have made "line" invalid, get it again. */
+		line = ml_get_curline();
+		p = line + i;
+	    }
+	}
+	if (*p != NUL)
+	    ++p;
+    }
+    return FALSE;
+}
+
     static int
 cin_isbreak(p)
     char_u  *p;
@@ -5716,7 +5789,7 @@
 	trypos = &pos_copy;
 	curwin->w_cursor = *trypos;
 	pos = NULL;
-	/* ignore the { if it's in a // comment */
+	/* ignore the { if it's in a // or / *  * / comment */
 	if ((colnr_T)cin_skip2pos(trypos) == trypos->col
 		&& (pos = find_start_comment(ind_maxcomment)) == NULL) /* XXX */
 	    break;
@@ -5738,7 +5811,7 @@
 {
     pos_T	cursor_save;
     pos_T	*trypos;
-    static pos_T	pos_copy;
+    static pos_T pos_copy;
 
     cursor_save = curwin->w_cursor;
     if ((trypos = findmatchlimit(NULL, '(', 0, ind_maxparen)) != NULL)
@@ -5942,6 +6015,11 @@
     int ind_matching_paren = 0;
 
     /*
+     * indent a closing parentheses under the previous line.
+     */
+    int ind_paren_prev = 0;
+
+    /*
      * Extra indent for comments.
      */
     int ind_comment = 0;
@@ -6079,6 +6157,7 @@
 	    case 'W': ind_unclosed_wrapped = n; break;
 	    case 'w': ind_unclosed_whiteok = n; break;
 	    case 'm': ind_matching_paren = n; break;
+	    case 'M': ind_paren_prev = n; break;
 	    case ')': ind_maxparen = n; break;
 	    case '*': ind_maxcomment = n; break;
 	    case 'g': ind_scopedecl = n; break;
@@ -6322,41 +6401,50 @@
 	 * If the matching paren is more than one line away, use the indent of
 	 * a previous non-empty line that matches the same paren.
 	 */
-	amount = -1;
-	cur_amount = MAXCOL;
-	our_paren_pos = *trypos;
-	for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum)
+	if (theline[0] == ')' && ind_paren_prev)
 	{
-	    l = skipwhite(ml_get(lnum));
-	    if (cin_nocode(l))		/* skip comment lines */
-		continue;
-	    if (cin_ispreproc_cont(&l, &lnum))	/* ignore #defines, #if, etc. */
-		continue;
-	    curwin->w_cursor.lnum = lnum;
-
-	    /* Skip a comment. XXX */
-	    if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
+	    /* Line up with the start of the matching paren line. */
+	    amount = get_indent_lnum(curwin->w_cursor.lnum - 1);  /* XXX */
+	}
+	else
+	{
+	    amount = -1;
+	    cur_amount = MAXCOL;
+	    our_paren_pos = *trypos;
+	    for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum)
 	    {
-		lnum = trypos->lnum + 1;
-		continue;
-	    }
+		l = skipwhite(ml_get(lnum));
+		if (cin_nocode(l))		/* skip comment lines */
+		    continue;
+		if (cin_ispreproc_cont(&l, &lnum))
+		    continue;			/* ignore #define, #if, etc. */
+		curwin->w_cursor.lnum = lnum;
 
-	    /* XXX */
-	    if ((trypos = find_match_paren(
-			    corr_ind_maxparen(ind_maxparen, &cur_curpos),
+		/* Skip a comment. XXX */
+		if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
+		{
+		    lnum = trypos->lnum + 1;
+		    continue;
+		}
+
+		/* XXX */
+		if ((trypos = find_match_paren(
+				corr_ind_maxparen(ind_maxparen, &cur_curpos),
 						      ind_maxcomment)) != NULL
-		    && trypos->lnum == our_paren_pos.lnum
-		    && trypos->col == our_paren_pos.col)
-	    {
-		    amount = get_indent_lnum(lnum);	/* XXX */
+			&& trypos->lnum == our_paren_pos.lnum
+			&& trypos->col == our_paren_pos.col)
+		{
+			amount = get_indent_lnum(lnum);	/* XXX */
 
-		    if (theline[0] == ')')
-		    {
-			if (our_paren_pos.lnum != lnum && cur_amount > amount)
-			    cur_amount = amount;
-			amount = -1;
-		    }
-		break;
+			if (theline[0] == ')')
+			{
+			    if (our_paren_pos.lnum != lnum
+						       && cur_amount > amount)
+				cur_amount = amount;
+			    amount = -1;
+			}
+		    break;
+		}
 	    }
 	}
 
@@ -6367,9 +6455,34 @@
 	 */
 	if (amount == -1)
 	{
+	    int	    ignore_paren_col = 0;
+
 	    amount = skip_label(our_paren_pos.lnum, &look, ind_maxcomment);
+	    look = skipwhite(look);
+	    if (*look == '(')
+	    {
+		linenr_T    save_lnum = curwin->w_cursor.lnum;
+		char_u	    *line;
+		int	    look_col;
+
+		/* Ignore a '(' in front of the line that has a match before
+		 * our matching '('. */
+		curwin->w_cursor.lnum = our_paren_pos.lnum;
+		line = ml_get_curline();
+		look_col = look - line;
+		curwin->w_cursor.col = look_col + 1;
+		if ((trypos = findmatchlimit(NULL, ')', 0, ind_maxparen))
+								      != NULL
+			  && trypos->lnum == our_paren_pos.lnum
+			  && trypos->col < our_paren_pos.col)
+		    ignore_paren_col = trypos->col + 1;
+
+		curwin->w_cursor.lnum = save_lnum;
+		look = ml_get(our_paren_pos.lnum) + look_col;
+	    }
 	    if (theline[0] == ')' || ind_unclosed == 0
-		       || (!ind_unclosed_noignore && *skipwhite(look) == '('))
+		    || (!ind_unclosed_noignore && *look == '('
+						    && ignore_paren_col == 0))
 	    {
 		/*
 		 * If we're looking at a close paren, line up right there;
@@ -6439,16 +6552,17 @@
 		/* Line up with the start of the matching paren line. */
 	    }
 	    else if (ind_unclosed == 0 || (!ind_unclosed_noignore
-						  && *skipwhite(look) == '('))
+				    && *look == '(' && ignore_paren_col == 0))
 	    {
 		if (cur_amount != MAXCOL)
 		    amount = cur_amount;
 	    }
 	    else
 	    {
-		/* add ind_unclosed2 for each '(' before our matching one */
+		/* Add ind_unclosed2 for each '(' before our matching one, but
+		 * ignore (void) before the line (ignore_paren_col). */
 		col = our_paren_pos.col;
-		while (our_paren_pos.col > 0)
+		while (our_paren_pos.col > ignore_paren_col)
 		{
 		    --our_paren_pos.col;
 		    switch (*ml_get_pos(&our_paren_pos))
@@ -6887,7 +7001,12 @@
 			amount = n;
 			l = after_label(ml_get_curline());
 			if (l != NULL && cin_is_cinword(l))
-			    amount += ind_level + ind_no_brace;
+			{
+			    if (theline[0] == '{')
+				amount += ind_open_extra;
+			    else
+				amount += ind_level + ind_no_brace;
+			}
 			break;
 		    }
 
@@ -7259,8 +7378,8 @@
 		 * If so: Ignore until the matching "do".
 		 */
 							/* XXX */
-		else if (cin_iswhileofdo(l,
-					 curwin->w_cursor.lnum, ind_maxparen))
+		else if (cin_iswhileofdo_end(terminated, ind_maxparen,
+							      ind_maxcomment))
 		{
 		    /*
 		     * Found an unterminated line after a while ();, line up
diff --git a/src/search.c b/src/search.c
index a063a26..addb9cd 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1930,7 +1930,7 @@
 		    break;
 		--pos.lnum;
 
-		if (maxtravel && traveled++ > maxtravel)
+		if (maxtravel > 0 && ++traveled > maxtravel)
 		    break;
 
 		linep = ml_get(pos.lnum);
diff --git a/src/testdir/test3.in b/src/testdir/test3.in
index 8983118..b929279 100644
--- a/src/testdir/test3.in
+++ b/src/testdir/test3.in
Binary files differ
diff --git a/src/testdir/test3.ok b/src/testdir/test3.ok
index 2c7fd17..8c015a3 100644
--- a/src/testdir/test3.ok
+++ b/src/testdir/test3.ok
@@ -1,4 +1,4 @@
-/* start of AUTO matically checked */
+/* start of AUTO matically checked vim: set ts=4 : */
 {
 	if (test)
 		cmd1;
@@ -754,7 +754,39 @@
 	mMember(b)
 {
 }
+int main ()
+{
+	if (lala)
+		do
+			++(*lolo);
+		while (lili
+				&& lele);
+	lulu;
+}
 
+int main ()
+{
+	switch (c)
+	{
+		case 'c': if (cond)
+				  {
+				  }
+	}
+}
+
+main()
+{
+	(void) MyFancyFuasdfadsfnction(
+			argument);
+}
+
+main()
+{
+	char	foo[] = "/*";
+	/* as
+	   df */
+	hello
+}
 /* end of AUTO */
 
 
@@ -1142,3 +1174,12 @@
 			);
 }
 
+
+int main ()
+{
+	if (cond1 &&
+			cond2
+			)
+		foo;
+}
+
diff --git a/src/version.h b/src/version.h
index 11f5d83..843d9a1 100644
--- a/src/version.h
+++ b/src/version.h
@@ -35,6 +35,6 @@
  */
 #define VIM_VERSION_NODOT	"vim70d"
 #define VIM_VERSION_SHORT	"7.0d"
-#define VIM_VERSION_MEDIUM	"7.0d03 BETA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0d03 BETA (2006 Apr 13)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0d03 BETA (2006 Apr 13, compiled "
+#define VIM_VERSION_MEDIUM	"7.0d04 BETA"
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0d04 BETA (2006 Apr 14)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0d04 BETA (2006 Apr 14, compiled "