updated for version 7.0045
diff --git a/src/edit.c b/src/edit.c
index cb2d82a..175256e 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -6121,8 +6121,11 @@
 	    im_set_active(TRUE);
 # endif
     }
-    if (regname == NUL)
+    if (regname == NUL || !valid_yank_reg(regname, FALSE))
+    {
+	vim_beep();
 	need_redraw = TRUE;	/* remove the '"' */
+    }
     else
     {
 #endif
diff --git a/src/hashtable.c b/src/hashtable.c
index 1dea067..e6651e3 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -336,7 +336,8 @@
     else
     {
 	/* Allocate an array. */
-	newarray = (hashitem_T *)alloc((unsigned)(sizeof(hashitem_T) * newsize));
+	newarray = (hashitem_T *)alloc((unsigned)
+					      (sizeof(hashitem_T) * newsize));
 	if (newarray == NULL)
 	{
 	    /* Out of memory.  When there are NULL items still return OK.
diff --git a/src/mbyte.c b/src/mbyte.c
index f53a8ec..f309255 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -2407,6 +2407,7 @@
     return (int)(p - q);
 }
 
+#if defined(FEAT_EVAL) || defined(PROTO)
 /*
  * Copy a character from "*fp" to "*tp" and advance the pointers.
  */
@@ -2421,6 +2422,7 @@
     *tp += l;
     *fp += l;
 }
+#endif
 
 /*
  * Return the offset from "p" to the first byte of a character.  When "p" is
diff --git a/src/ops.c b/src/ops.c
index ddc0aab..4a05292 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -813,6 +813,7 @@
 /*
  * Set y_current and y_append, according to the value of "regname".
  * Cannot handle the '_' register.
+ * Must only be called with a valid register name!
  *
  * If regname is 0 and writing, use register 0
  * If regname is 0 and reading, use previous register
@@ -2996,10 +2997,11 @@
 #endif
 
 /*
- * put contents of register "regname" into the text
- * flags: PUT_FIXINDENT	make indent look nice
- *	  PUT_CURSEND	leave cursor after end of new text
- *	  PUT_LINE	force linewise put (":put")
+ * Put contents of register "regname" into the text.
+ * Caller must check "regname" to be valid!
+ * "flags": PUT_FIXINDENT	make indent look nice
+ *	    PUT_CURSEND		leave cursor after end of new text
+ *	    PUT_LINE		force linewise put (":put")
  */
     void
 do_put(regname, dir, count, flags)
@@ -3635,6 +3637,7 @@
 	if (regname == '=')
 	    vim_free(y_array);
     }
+    /* If the cursor is past the end of the line put it at the end. */
     if (gchar_cursor() == NUL
 	    && curwin->w_cursor.col > 0
 	    && !(restart_edit || (State & INSERT)))
diff --git a/src/search.c b/src/search.c
index 17dc5bd..2bcdf24 100644
--- a/src/search.c
+++ b/src/search.c
@@ -503,8 +503,8 @@
     regmmatch_T	regmatch;
     char_u	*ptr;
     colnr_T	matchcol;
-    colnr_T	startcol;
     lpos_T	endpos;
+    lpos_T	matchpos;
     int		loop;
     pos_T	start_pos;
     int		at_first_line;
@@ -512,7 +512,6 @@
     int		match_ok;
     long	nmatched;
     int		submatch = 0;
-    linenr_T	first_lnum;
 #ifdef FEAT_SEARCH_EXTRA
     int		break_loop = FALSE;
 #else
@@ -573,9 +572,8 @@
 					   lnum += dir, at_first_line = FALSE)
 	    {
 		/*
-		 * Look for a match somewhere in the line.
+		 * Look for a match somewhere in line "lnum".
 		 */
-		first_lnum = lnum;
 		nmatched = vim_regexec_multi(&regmatch, win, buf,
 							    lnum, (colnr_T)0);
 		/* Abort searching on an error (e.g., out of stack). */
@@ -584,13 +582,12 @@
 		if (nmatched > 0)
 		{
 		    /* match may actually be in another line when using \zs */
-		    lnum += regmatch.startpos[0].lnum;
-		    ptr = ml_get_buf(buf, lnum, FALSE);
-		    startcol = regmatch.startpos[0].col;
+		    matchpos = regmatch.startpos[0];
 		    endpos = regmatch.endpos[0];
 # ifdef FEAT_EVAL
 		    submatch = first_submatch(&regmatch);
 # endif
+		    ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
 
 		    /*
 		     * Forward search in the first line: match should be after
@@ -601,16 +598,20 @@
 		    {
 			match_ok = TRUE;
 			/*
+			 * When the match starts in a next line it's certainly
+			 * past the start position.
 			 * When match lands on a NUL the cursor will be put
 			 * one back afterwards, compare with that position,
 			 * otherwise "/$" will get stuck on end of line.
 			 */
-			while ((options & SEARCH_END)
-				?  (nmatched == 1
-				    && (int)endpos.col - 1
+			while (matchpos.lnum == 0
+				&& ((options & SEARCH_END)
+				    ?  (nmatched == 1
+					&& (int)endpos.col - 1
 					     < (int)start_pos.col + extra_col)
-				: ((int)startcol - (ptr[startcol] == NUL)
-					    < (int)start_pos.col + extra_col))
+				    : ((int)matchpos.col
+						  - (ptr[matchpos.col] == NUL)
+					    < (int)start_pos.col + extra_col)))
 			{
 			    /*
 			     * If vi-compatible searching, continue at the end
@@ -628,7 +629,7 @@
 				}
 				matchcol = endpos.col;
 				/* for empty match: advance one char */
-				if (matchcol == startcol
+				if (matchcol == matchpos.col
 						      && ptr[matchcol] != NUL)
 				{
 #ifdef FEAT_MBYTE
@@ -642,7 +643,7 @@
 			    }
 			    else
 			    {
-				matchcol = startcol;
+				matchcol = matchpos.col;
 				if (ptr[matchcol] != NUL)
 				{
 #ifdef FEAT_MBYTE
@@ -656,12 +657,13 @@
 			    }
 			    if (ptr[matchcol] == NUL
 				    || (nmatched = vim_regexec_multi(&regmatch,
-					      win, buf, lnum, matchcol)) == 0)
+					      win, buf, lnum + matchpos.lnum,
+					      matchcol)) == 0)
 			    {
 				match_ok = FALSE;
 				break;
 			    }
-			    startcol = regmatch.startpos[0].col;
+			    matchpos = regmatch.startpos[0];
 			    endpos = regmatch.endpos[0];
 # ifdef FEAT_EVAL
 			    submatch = first_submatch(&regmatch);
@@ -669,7 +671,7 @@
 
 			    /* Need to get the line pointer again, a
 			     * multi-line search may have made it invalid. */
-			    ptr = ml_get_buf(buf, lnum, FALSE);
+			    ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
 			}
 			if (!match_ok)
 			    continue;
@@ -686,20 +688,29 @@
 			match_ok = FALSE;
 			for (;;)
 			{
-			    if (!at_first_line
-				    || ((options & SEARCH_END)
-					?  (nmatched == 1
-					    && (int)regmatch.endpos[0].col - 1
+			    /* Remember a position that is before the start
+			     * position, we use it if it's the last match in
+			     * the line.  Always accept a position after
+			     * wrapping around. */
+			    if (loop
+				|| ((options & SEARCH_END)
+				    ? (lnum + regmatch.endpos[0].lnum
+							      < start_pos.lnum
+					|| (lnum + regmatch.endpos[0].lnum
+							     == start_pos.lnum
+					     && (int)regmatch.endpos[0].col - 1
 								   + extra_col
-							<= (int)start_pos.col)
-					: ((int)regmatch.startpos[0].col
+							<= (int)start_pos.col))
+				    : (lnum + regmatch.startpos[0].lnum
+							      < start_pos.lnum
+					|| (lnum + regmatch.startpos[0].lnum
+							     == start_pos.lnum
+					     && (int)regmatch.startpos[0].col
 								   + extra_col
-						      <= (int)start_pos.col)))
+						      <= (int)start_pos.col))))
 			    {
-				/* Remember this position, we use it if it's
-				 * the last match in the line. */
 				match_ok = TRUE;
-				startcol = regmatch.startpos[0].col;
+				matchpos = regmatch.startpos[0];
 				endpos = regmatch.endpos[0];
 # ifdef FEAT_EVAL
 				submatch = first_submatch(&regmatch);
@@ -721,7 +732,7 @@
 				    break;
 				matchcol = endpos.col;
 				/* for empty match: advance one char */
-				if (matchcol == startcol
+				if (matchcol == matchpos.col
 						      && ptr[matchcol] != NUL)
 				{
 #ifdef FEAT_MBYTE
@@ -735,7 +746,10 @@
 			    }
 			    else
 			    {
-				matchcol = startcol;
+				/* Stop when the match is in a next line. */
+				if (matchpos.lnum > 0)
+				    break;
+				matchcol = matchpos.col;
 				if (ptr[matchcol] != NUL)
 				{
 #ifdef FEAT_MBYTE
@@ -749,12 +763,13 @@
 			    }
 			    if (ptr[matchcol] == NUL
 				    || (nmatched = vim_regexec_multi(&regmatch,
-					      win, buf, lnum, matchcol)) == 0)
+					      win, buf, lnum + matchpos.lnum,
+							      matchcol)) == 0)
 				break;
 
 			    /* Need to get the line pointer again, a
 			     * multi-line search may have made it invalid. */
-			    ptr = ml_get_buf(buf, lnum, FALSE);
+			    ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE);
 			}
 
 			/*
@@ -767,13 +782,13 @@
 
 		    if (options & SEARCH_END && !(options & SEARCH_NOOF))
 		    {
-			pos->lnum = endpos.lnum + first_lnum;
+			pos->lnum = lnum + endpos.lnum;
 			pos->col = endpos.col - 1;
 		    }
 		    else
 		    {
-			pos->lnum = lnum;
-			pos->col = startcol;
+			pos->lnum = lnum + matchpos.lnum;
+			pos->col = matchpos.col;
 		    }
 #ifdef FEAT_VIRTUALEDIT
 		    pos->coladd = 0;
@@ -781,7 +796,7 @@
 		    found = 1;
 
 		    /* Set variables used for 'incsearch' highlighting. */
-		    search_match_lines = endpos.lnum - (lnum - first_lnum);
+		    search_match_lines = endpos.lnum - matchpos.lnum;
 		    search_match_endcol = endpos.col;
 		    break;
 		}
diff --git a/src/structs.h b/src/structs.h
index 19cfbe5..6482e30 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -936,8 +936,8 @@
 {
     long_u	ht_mask;	/* mask used for hash value (nr of items in
 				 * array is "ht_mask" + 1) */
-    int		ht_used;	/* number of items used */
-    int		ht_filled;	/* number of items used + removed */
+    long_u	ht_used;	/* number of items used */
+    long_u	ht_filled;	/* number of items used + removed */
     int		ht_locked;	/* counter for hash_lock() */
     int		ht_error;	/* when set growing failed, can't add more
 				   items before growing works */
diff --git a/src/version.h b/src/version.h
index 0053ec4..3362a98 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 Jan 25)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 25, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jan 27)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jan 27, compiled "