diff --git a/7.2.060 b/7.2.060
new file mode 100644
index 0000000..ec6e6b7
--- /dev/null
+++ b/7.2.060
@@ -0,0 +1,1102 @@
+To: vim-dev@vim.org
+Subject: Patch 7.2.060
+Fcc: outbox
+From: Bram Moolenaar <Bram@moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 7.2.060
+Problem:    When a spell files has many compound rules it may take a very long
+	    time making the list of suggestions.  Displaying also can be slow
+	    when there are misspelled words.
+	    Can't parse some Hunspell .aff files.
+Solution:   Check if a compounding can possibly work before trying a
+	    combination, if the compound rules don't contain wildcards.
+	    Implement using CHECKCOMPOUNDPATTERN.
+	    Ignore COMPOUNDRULES.  Ignore a comment after most items.
+	    Accept ONLYINCOMPOUND as an alias for NEEDCOMPOUND.
+	    Accept FORBIDDENWORD as an alias for BAD.
+Files:	    runtime/doc/spell.txt, src/spell.c
+
+
+*** ../vim-7.2.059/runtime/doc/spell.txt	Sat Aug  9 19:36:52 2008
+--- runtime/doc/spell.txt	Sun Nov 30 16:30:02 2008
+***************
+*** 1,4 ****
+! *spell.txt*	For Vim version 7.2.  Last change: 2008 Jun 21
+  
+  
+  		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+--- 1,4 ----
+! *spell.txt*	For Vim version 7.2.  Last change: 2008 Nov 30
+  
+  
+  		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+***************
+*** 831,838 ****
+  
+  	# comment line ~
+  
+! With some items it's also possible to put a comment after it, but this isn't
+! supported in general.
+  
+  
+  ENCODING							*spell-SET*
+--- 831,841 ----
+  
+  	# comment line ~
+  
+! Items with a fixed number of arguments can be followed by a comment.  But only
+! if none of the arguments can contain white space.  The comment must start with
+! a "#" character.  Example:
+! 
+! 	KEEPCASE =  # fix case for words with this flag ~
+  
+  
+  ENCODING							*spell-SET*
+***************
+*** 965,970 ****
+--- 968,976 ----
+  
+  Note: When using utf-8 only characters up to 65000 may be used for flags.
+  
++ Note: even when using "num" or "long" the number of flags available to
++ compounding and prefixes is limited to about 250.
++ 
+  
+  AFFIXES
+  					    *spell-PFX* *spell-SFX*
+***************
+*** 1178,1183 ****
+--- 1185,1193 ----
+  The flag also applies to the word with affixes, thus this can be used to mark
+  a whole bunch of related words as bad.
+  
++ 							*spell-FORBIDDENWORD*
++ FORBIDDENWORD can be used just like BAD.  For compatibility with Hunspell.
++ 
+  							*spell-NEEDAFFIX*
+  The NEEDAFFIX flag is used to require that a word is used with an affix.  The
+  word itself is not a good word (unless there is an empty affix).  Example:
+***************
+*** 1268,1273 ****
+--- 1278,1287 ----
+  
+  	NEEDCOMPOUND & ~
+  
++ 							*spell-ONLYINCOMPOUND*
++ The ONLYINCOMPOUND does exactly the same as NEEDCOMPOUND.  Supported for
++ compatiblity with Hunspell.
++ 
+  							*spell-COMPOUNDMIN*
+  The minimal character length of a word used for compounding is specified with
+  COMPOUNDMIN.  Example:
+***************
+*** 1328,1333 ****
+--- 1342,1361 ----
+  rules.  Can also be used for an affix to count the affix as a compounding
+  word.
+  
++ 						*spell-CHECKCOMPOUNDPATTERN*
++ CHECKCOMPOUNDPATTERN is used to define patterns that, when matching at the
++ position where two words are compounded together forbids the compound.
++ For example:
++ 	CHECKCOMPOUNDPATTERN o e ~
++ 
++ This forbids compounding if the first word ends in "o" and the second word
++ starts with "e".
++ 
++ The arguments must be plain text, no patterns are actually supported, despite
++ the item name.  Case is always ignored.
++ 
++ The Hunspell feature to use three arguments and flags is not supported.
++ 
+  							*spell-SYLLABLE*
+  The SYLLABLE item defines characters or character sequences that are used to
+  count the number of syllables in a word.  Example:
+***************
+*** 1496,1501 ****
+--- 1524,1533 ----
+  ACCENT		(Hunspell)				*spell-ACCENT*
+  		Use MAP instead. |spell-MAP|
+  
++ BREAK		(Hunspell)				*spell-BREAK*
++ 		Define break points.  Unclear how it works exactly.
++ 		Not supported.
++ 
+  CHECKCOMPOUNDCASE  (Hunspell)			*spell-CHECKCOMPOUNDCASE*
+  		Disallow uppercase letters at compound word boundaries.
+  		Not supported.
+***************
+*** 1512,1520 ****
+  		Forbid three identical characters when compounding.  Not
+  		supported.
+  
+- CHECKCOMPOUNDPATTERN  (Hunspell)		*spell-CHECKCOMPOUNDPATTERN*
+- 		Forbid compounding when patterns match.  Not supported.
+- 
+  COMPLEXPREFIXES  (Hunspell)				*spell-COMPLEXPREFIXES*
+  		Enables using two prefixes.  Not supported.
+  
+--- 1544,1549 ----
+***************
+*** 1536,1548 ****
+  COMPOUNDMIDDLE	(Hunspell)				*spell-COMPOUNDMIDDLE*
+  		Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
+  
+  COMPOUNDSYLLABLE  (Hunspell)			*spell-COMPOUNDSYLLABLE*
+  		Use SYLLABLE and COMPOUNDSYLMAX instead. |spell-SYLLABLE|
+  		|spell-COMPOUNDSYLMAX|
+  
+! FORBIDDENWORD	(Hunspell)				*spell-FORBIDDENWORD*
+! 		Use BAD instead. |spell-BAD|
+! 
+  LANG		(Hunspell)				*spell-LANG*
+  		This specifies language-specific behavior.  This actually
+  		moves part of the language knowledge into the program,
+--- 1565,1582 ----
+  COMPOUNDMIDDLE	(Hunspell)				*spell-COMPOUNDMIDDLE*
+  		Use COMPOUNDRULE instead. |spell-COMPOUNDRULE|
+  
++ COMPOUNDRULES	(Hunspell)				*spell-COMPOUNDRULES*
++ 		Number of COMPOUNDRULE lines following.  Ignored, but the
++ 		argument must be a number.
++ 
+  COMPOUNDSYLLABLE  (Hunspell)			*spell-COMPOUNDSYLLABLE*
+  		Use SYLLABLE and COMPOUNDSYLMAX instead. |spell-SYLLABLE|
+  		|spell-COMPOUNDSYLMAX|
+  
+! KEY		(Hunspell)				*spell-KEY*
+! 		Define characters that are close together on the keyboard.
+! 		Used to give better suggestions.  Not supported.
+! 		
+  LANG		(Hunspell)				*spell-LANG*
+  		This specifies language-specific behavior.  This actually
+  		moves part of the language knowledge into the program,
+***************
+*** 1553,1562 ****
+  		Only needed for morphological analysis.
+  
+  MAXNGRAMSUGS	(Hunspell)				*spell-MAXNGRAMSUGS*
+! 		Not supported.
+! 
+! ONLYINCOMPOUND	(Hunspell)				*spell-ONLYINCOMPOUND*
+! 		Use NEEDCOMPOUND instead. |spell-NEEDCOMPOUND|
+  
+  PSEUDOROOT	(Hunspell)				*spell-PSEUDOROOT*
+  		Use NEEDAFFIX instead. |spell-NEEDAFFIX|
+--- 1587,1593 ----
+  		Only needed for morphological analysis.
+  
+  MAXNGRAMSUGS	(Hunspell)				*spell-MAXNGRAMSUGS*
+! 		Set number of n-gram suggestions.  Not supported.
+  
+  PSEUDOROOT	(Hunspell)				*spell-PSEUDOROOT*
+  		Use NEEDAFFIX instead. |spell-NEEDAFFIX|
+*** ../vim-7.2.059/src/spell.c	Sat Nov 29 20:18:44 2008
+--- src/spell.c	Sun Nov 30 20:59:13 2008
+***************
+*** 469,474 ****
+--- 469,475 ----
+      garray_T	sl_comppat;	/* CHECKCOMPOUNDPATTERN items */
+      regprog_T	*sl_compprog;	/* COMPOUNDRULE turned into a regexp progrm
+  				 * (NULL when no compounding) */
++     char_u	*sl_comprules;	/* all COMPOUNDRULE concatenated (or NULL) */
+      char_u	*sl_compstartflags; /* flags for first compound word */
+      char_u	*sl_compallflags; /* all flags for compound words */
+      char_u	sl_nobreak;	/* When TRUE: no spaces between words */
+***************
+*** 839,845 ****
+--- 840,849 ----
+  static void slang_clear __ARGS((slang_T *lp));
+  static void slang_clear_sug __ARGS((slang_T *lp));
+  static void find_word __ARGS((matchinf_T *mip, int mode));
++ static int match_checkcompoundpattern __ARGS((char_u *ptr, int wlen, garray_T *gap));
+  static int can_compound __ARGS((slang_T *slang, char_u *word, char_u *flags));
++ static int can_be_compound __ARGS((trystate_T *sp, slang_T *slang, char_u *compflags, int flag));
++ static int match_compoundrule __ARGS((slang_T *slang, char_u *compflags));
+  static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req));
+  static void find_prefix __ARGS((matchinf_T *mip, int mode));
+  static int fold_more __ARGS((matchinf_T *mip));
+***************
+*** 1519,1524 ****
+--- 1523,1533 ----
+  					    ((unsigned)flags >> 24)))
+  		    continue;
+  
++ 		/* If there is a match with a CHECKCOMPOUNDPATTERN rule
++ 		 * discard the compound word. */
++ 		if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat))
++ 		    continue;
++ 
+  		if (mode == FIND_COMPOUND)
+  		{
+  		    int	    capflags;
+***************
+*** 1577,1582 ****
+--- 1586,1596 ----
+  		    if (!can_compound(slang, fword, mip->mi_compflags))
+  			continue;
+  		}
++ 		else if (slang->sl_comprules != NULL
++ 			     && !match_compoundrule(slang, mip->mi_compflags))
++ 		    /* The compound flags collected so far do not match any
++ 		     * COMPOUNDRULE, discard the compounded word. */
++ 		    continue;
+  	    }
+  
+  	    /* Check NEEDCOMPOUND: can't use word without compounding. */
+***************
+*** 1727,1732 ****
+--- 1741,1779 ----
+  }
+  
+  /*
++  * Return TRUE if there is a match between the word ptr[wlen] and
++  * CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another
++  * word.
++  * A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
++  * end of ptr[wlen] and the second part matches after it.
++  */
++     static int
++ match_checkcompoundpattern(ptr, wlen, gap)
++     char_u	*ptr;
++     int		wlen;
++     garray_T	*gap;  /* &sl_comppat */
++ {
++     int		i;
++     char_u	*p;
++     int		len;
++ 
++     for (i = 0; i + 1 < gap->ga_len; i += 2)
++     {
++ 	p = ((char_u **)gap->ga_data)[i + 1];
++ 	if (STRNCMP(ptr + wlen, p, STRLEN(p)) == 0)
++ 	{
++ 	    /* Second part matches at start of following compound word, now
++ 	     * check if first part matches at end of previous word. */
++ 	    p = ((char_u **)gap->ga_data)[i];
++ 	    len = STRLEN(p);
++ 	    if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0)
++ 		return TRUE;
++ 	}
++     }
++     return FALSE;
++ }
++ 
++ /*
+   * Return TRUE if "flags" is a valid sequence of compound flags and "word"
+   * does not have too many syllables.
+   */
+***************
+*** 1773,1778 ****
+--- 1820,1917 ----
+  }
+  
+  /*
++  * Return TRUE when the sequence of flags in "compflags" plus "flag" can
++  * possibly form a valid compounded word.  This also checks the COMPOUNDRULE
++  * lines if they don't contain wildcards.
++  */
++     static int
++ can_be_compound(sp, slang, compflags, flag)
++     trystate_T	*sp;
++     slang_T	*slang;
++     char_u	*compflags;
++     int		flag;
++ {
++     /* If the flag doesn't appear in sl_compstartflags or sl_compallflags
++      * then it can't possibly compound. */
++     if (!byte_in_str(sp->ts_complen == sp->ts_compsplit
++ 		? slang->sl_compstartflags : slang->sl_compallflags, flag))
++ 	return FALSE;
++ 
++     /* If there are no wildcards, we can check if the flags collected so far
++      * possibly can form a match with COMPOUNDRULE patterns.  This only
++      * makes sense when we have two or more words. */
++     if (slang->sl_comprules != NULL && sp->ts_complen > sp->ts_compsplit)
++     {
++ 	int v;
++ 
++ 	compflags[sp->ts_complen] = flag;
++ 	compflags[sp->ts_complen + 1] = NUL;
++ 	v = match_compoundrule(slang, compflags + sp->ts_compsplit);
++ 	compflags[sp->ts_complen] = NUL;
++ 	return v;
++     }
++ 
++     return TRUE;
++ }
++ 
++ 
++ /*
++  * Return TRUE if the compound flags in compflags[] match the start of any
++  * compound rule.  This is used to stop trying a compound if the flags
++  * collected so far can't possibly match any compound rule.
++  * Caller must check that slang->sl_comprules is not NULL.
++  */
++     static int
++ match_compoundrule(slang, compflags)
++     slang_T	*slang;
++     char_u	*compflags;
++ {
++     char_u	*p;
++     int		i;
++     int		c;
++ 
++     /* loop over all the COMPOUNDRULE entries */
++     for (p = slang->sl_comprules; *p != NUL; ++p)
++     {
++ 	/* loop over the flags in the compound word we have made, match
++ 	 * them against the current rule entry */
++ 	for (i = 0; ; ++i)
++ 	{
++ 	    c = compflags[i];
++ 	    if (c == NUL)
++ 		/* found a rule that matches for the flags we have so far */
++ 		return TRUE;
++ 	    if (*p == '/' || *p == NUL)
++ 		break;  /* end of rule, it's too short */
++ 	    if (*p == '[')
++ 	    {
++ 		int match = FALSE;
++ 
++ 		/* compare against all the flags in [] */
++ 		++p;
++ 		while (*p != ']' && *p != NUL)
++ 		    if (*p++ == c)
++ 			match = TRUE;
++ 		if (!match)
++ 		    break;  /* none matches */
++ 	    }
++ 	    else if (*p != c)
++ 		break;  /* flag of word doesn't match flag in pattern */
++ 	    ++p;
++ 	}
++ 
++ 	/* Skip to the next "/", where the next pattern starts. */
++ 	p = vim_strchr(p, '/');
++ 	if (p == NULL)
++ 	    break;
++     }
++ 
++     /* Checked all the rules and none of them match the flags, so there
++      * can't possibly be a compound starting with these flags. */
++     return FALSE;
++ }
++ 
++ /*
+   * Return non-zero if the prefix indicated by "arridx" matches with the prefix
+   * ID in "flags" for the word "word".
+   * The WF_RAREPFX flag is included in the return value for a rare prefix.
+***************
+*** 2513,2521 ****
+--- 2652,2662 ----
+      lp->sl_midword = NULL;
+  
+      vim_free(lp->sl_compprog);
++     vim_free(lp->sl_comprules);
+      vim_free(lp->sl_compstartflags);
+      vim_free(lp->sl_compallflags);
+      lp->sl_compprog = NULL;
++     lp->sl_comprules = NULL;
+      lp->sl_compstartflags = NULL;
+      lp->sl_compallflags = NULL;
+  
+***************
+*** 3460,3465 ****
+--- 3601,3607 ----
+      char_u	*pp;
+      char_u	*cp;
+      char_u	*ap;
++     char_u	*crp;
+      int		cnt;
+      garray_T	*gap;
+  
+***************
+*** 3545,3550 ****
+--- 3687,3698 ----
+      slang->sl_compallflags = ap;
+      *ap = NUL;
+  
++     /* And a list of all patterns in their original form, for checking whether
++      * compounding may work in match_compoundrule().  This is freed when we
++      * encounter a wildcard, the check doesn't work then. */
++     crp = alloc(todo + 1);
++     slang->sl_comprules = crp;
++ 
+      pp = pat;
+      *pp++ = '^';
+      *pp++ = '\\';
+***************
+*** 3587,3592 ****
+--- 3735,3754 ----
+  		    atstart = 0;
+  	    }
+  	}
++ 
++ 	/* Copy flag to "sl_comprules", unless we run into a wildcard. */
++ 	if (crp != NULL)
++ 	{
++ 	    if (c == '+' || c == '*')
++ 	    {
++ 		vim_free(slang->sl_comprules);
++ 		slang->sl_comprules = NULL;
++ 		crp = NULL;
++ 	    }
++ 	    else
++ 		*crp++ = c;
++ 	}
++ 
+  	if (c == '/')	    /* slash separates two items */
+  	{
+  	    *pp++ = '\\';
+***************
+*** 3611,3616 ****
+--- 3773,3781 ----
+      *pp++ = '$';
+      *pp = NUL;
+  
++     if (crp != NULL)
++ 	*crp = NUL;
++ 
+      slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
+      vim_free(pat);
+      if (slang->sl_compprog == NULL)
+***************
+*** 4915,4920 ****
+--- 5080,5086 ----
+  } spellinfo_T;
+  
+  static afffile_T *spell_read_aff __ARGS((spellinfo_T *spin, char_u *fname));
++ static int is_aff_rule __ARGS((char_u **items, int itemcnt, char *rulename, int	 mincount));
+  static void aff_process_flags __ARGS((afffile_T *affile, affentry_T *entry));
+  static int spell_info_item __ARGS((char_u *s));
+  static unsigned affitem2flag __ARGS((int flagtype, char_u *item, char_u	*fname, int lnum));
+***************
+*** 5223,5230 ****
+  	/* Handle non-empty lines. */
+  	if (itemcnt > 0)
+  	{
+! 	    if (STRCMP(items[0], "SET") == 0 && itemcnt == 2
+! 						       && aff->af_enc == NULL)
+  	    {
+  #ifdef FEAT_MBYTE
+  		/* Setup for conversion from "ENC" to 'encoding'. */
+--- 5389,5395 ----
+  	/* Handle non-empty lines. */
+  	if (itemcnt > 0)
+  	{
+! 	    if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL)
+  	    {
+  #ifdef FEAT_MBYTE
+  		/* Setup for conversion from "ENC" to 'encoding'. */
+***************
+*** 5239,5245 ****
+  		    smsg((char_u *)_("Conversion in %s not supported"), fname);
+  #endif
+  	    }
+! 	    else if (STRCMP(items[0], "FLAG") == 0 && itemcnt == 2
+  					      && aff->af_flagtype == AFT_CHAR)
+  	    {
+  		if (STRCMP(items[1], "long") == 0)
+--- 5404,5410 ----
+  		    smsg((char_u *)_("Conversion in %s not supported"), fname);
+  #endif
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "FLAG", 2)
+  					      && aff->af_flagtype == AFT_CHAR)
+  	    {
+  		if (STRCMP(items[1], "long") == 0)
+***************
+*** 5284,5352 ****
+  			spin->si_info = p;
+  		    }
+  	    }
+! 	    else if (STRCMP(items[0], "MIDWORD") == 0 && itemcnt == 2
+  							   && midword == NULL)
+  	    {
+  		midword = getroom_save(spin, items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "TRY") == 0 && itemcnt == 2)
+  	    {
+  		/* ignored, we look in the tree for what chars may appear */
+  	    }
+  	    /* TODO: remove "RAR" later */
+! 	    else if ((STRCMP(items[0], "RAR") == 0
+! 			|| STRCMP(items[0], "RARE") == 0) && itemcnt == 2
+! 						       && aff->af_rare == 0)
+  	    {
+  		aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+  	    /* TODO: remove "KEP" later */
+! 	    else if ((STRCMP(items[0], "KEP") == 0
+! 		    || STRCMP(items[0], "KEEPCASE") == 0) && itemcnt == 2
+  						     && aff->af_keepcase == 0)
+  	    {
+  		aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "BAD") == 0 && itemcnt == 2
+! 						       && aff->af_bad == 0)
+  	    {
+  		aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "NEEDAFFIX") == 0 && itemcnt == 2
+  						    && aff->af_needaffix == 0)
+  	    {
+  		aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "CIRCUMFIX") == 0 && itemcnt == 2
+  						    && aff->af_circumfix == 0)
+  	    {
+  		aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "NOSUGGEST") == 0 && itemcnt == 2
+  						    && aff->af_nosuggest == 0)
+  	    {
+  		aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "NEEDCOMPOUND") == 0 && itemcnt == 2
+  						     && aff->af_needcomp == 0)
+  	    {
+  		aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDROOT") == 0 && itemcnt == 2
+  						     && aff->af_comproot == 0)
+  	    {
+  		aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDFORBIDFLAG") == 0
+! 				   && itemcnt == 2 && aff->af_compforbid == 0)
+  	    {
+  		aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+--- 5449,5519 ----
+  			spin->si_info = p;
+  		    }
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
+  							   && midword == NULL)
+  	    {
+  		midword = getroom_save(spin, items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "TRY", 2))
+  	    {
+  		/* ignored, we look in the tree for what chars may appear */
+  	    }
+  	    /* TODO: remove "RAR" later */
+! 	    else if ((is_aff_rule(items, itemcnt, "RAR", 2)
+! 			|| is_aff_rule(items, itemcnt, "RARE", 2))
+! 							 && aff->af_rare == 0)
+  	    {
+  		aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+  	    /* TODO: remove "KEP" later */
+! 	    else if ((is_aff_rule(items, itemcnt, "KEP", 2)
+! 			|| is_aff_rule(items, itemcnt, "KEEPCASE", 2))
+  						     && aff->af_keepcase == 0)
+  	    {
+  		aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if ((is_aff_rule(items, itemcnt, "BAD", 2)
+! 			|| is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
+! 							  && aff->af_bad == 0)
+  	    {
+  		aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
+  						    && aff->af_needaffix == 0)
+  	    {
+  		aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
+  						    && aff->af_circumfix == 0)
+  	    {
+  		aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
+  						    && aff->af_nosuggest == 0)
+  	    {
+  		aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
+! 			|| is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
+  						     && aff->af_needcomp == 0)
+  	    {
+  		aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
+  						     && aff->af_comproot == 0)
+  	    {
+  		aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
+! 						   && aff->af_compforbid == 0)
+  	    {
+  		aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+***************
+*** 5354,5361 ****
+  		    smsg((char_u *)_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
+  			    fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDPERMITFLAG") == 0
+! 				   && itemcnt == 2 && aff->af_comppermit == 0)
+  	    {
+  		aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+--- 5521,5528 ----
+  		    smsg((char_u *)_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
+  			    fname, lnum);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
+! 						   && aff->af_comppermit == 0)
+  	    {
+  		aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
+  								 fname, lnum);
+***************
+*** 5363,5369 ****
+  		    smsg((char_u *)_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
+  			    fname, lnum);
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDFLAG") == 0 && itemcnt == 2
+  							 && compflags == NULL)
+  	    {
+  		/* Turn flag "c" into COMPOUNDRULE compatible string "c+",
+--- 5530,5536 ----
+  		    smsg((char_u *)_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
+  			    fname, lnum);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
+  							 && compflags == NULL)
+  	    {
+  		/* Turn flag "c" into COMPOUNDRULE compatible string "c+",
+***************
+*** 5376,5382 ****
+  		    compflags = p;
+  		}
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDRULE") == 0 && itemcnt == 2)
+  	    {
+  		/* Concatenate this string to previously defined ones, using a
+  		 * slash to separate them. */
+--- 5543,5557 ----
+  		    compflags = p;
+  		}
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2))
+! 	    {
+! 		/* We don't use the count, but do check that it's a number and
+! 		 * not COMPOUNDRULE mistyped. */
+! 		if (atoi((char *)items[1]) == 0)
+! 		    smsg((char_u *)_("Wrong COMPOUNDRULES value in %s line %d: %s"),
+! 						       fname, lnum, items[1]);
+! 	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2))
+  	    {
+  		/* Concatenate this string to previously defined ones, using a
+  		 * slash to separate them. */
+***************
+*** 5395,5401 ****
+  		    compflags = p;
+  		}
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDWORDMAX") == 0 && itemcnt == 2
+  							      && compmax == 0)
+  	    {
+  		compmax = atoi((char *)items[1]);
+--- 5570,5576 ----
+  		    compflags = p;
+  		}
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
+  							      && compmax == 0)
+  	    {
+  		compmax = atoi((char *)items[1]);
+***************
+*** 5403,5409 ****
+  		    smsg((char_u *)_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDMIN") == 0 && itemcnt == 2
+  							   && compminlen == 0)
+  	    {
+  		compminlen = atoi((char *)items[1]);
+--- 5578,5584 ----
+  		    smsg((char_u *)_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
+  							   && compminlen == 0)
+  	    {
+  		compminlen = atoi((char *)items[1]);
+***************
+*** 5411,5417 ****
+  		    smsg((char_u *)_("Wrong COMPOUNDMIN value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "COMPOUNDSYLMAX") == 0 && itemcnt == 2
+  							   && compsylmax == 0)
+  	    {
+  		compsylmax = atoi((char *)items[1]);
+--- 5586,5592 ----
+  		    smsg((char_u *)_("Wrong COMPOUNDMIN value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
+  							   && compsylmax == 0)
+  	    {
+  		compsylmax = atoi((char *)items[1]);
+***************
+*** 5419,5450 ****
+  		    smsg((char_u *)_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "CHECKCOMPOUNDDUP") == 0 && itemcnt == 1)
+  	    {
+  		compoptions |= COMP_CHECKDUP;
+  	    }
+! 	    else if (STRCMP(items[0], "CHECKCOMPOUNDREP") == 0 && itemcnt == 1)
+  	    {
+  		compoptions |= COMP_CHECKREP;
+  	    }
+! 	    else if (STRCMP(items[0], "CHECKCOMPOUNDCASE") == 0 && itemcnt == 1)
+  	    {
+  		compoptions |= COMP_CHECKCASE;
+  	    }
+! 	    else if (STRCMP(items[0], "CHECKCOMPOUNDTRIPLE") == 0
+! 							      && itemcnt == 1)
+  	    {
+  		compoptions |= COMP_CHECKTRIPLE;
+  	    }
+! 	    else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0
+! 							      && itemcnt == 2)
+  	    {
+  		if (atoi((char *)items[1]) == 0)
+  		    smsg((char_u *)_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0
+! 							      && itemcnt == 3)
+  	    {
+  		garray_T    *gap = &spin->si_comppat;
+  		int	    i;
+--- 5594,5622 ----
+  		    smsg((char_u *)_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1))
+  	    {
+  		compoptions |= COMP_CHECKDUP;
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1))
+  	    {
+  		compoptions |= COMP_CHECKREP;
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1))
+  	    {
+  		compoptions |= COMP_CHECKCASE;
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1))
+  	    {
+  		compoptions |= COMP_CHECKTRIPLE;
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2))
+  	    {
+  		if (atoi((char *)items[1]) == 0)
+  		    smsg((char_u *)_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
+  						       fname, lnum, items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3))
+  	    {
+  		garray_T    *gap = &spin->si_comppat;
+  		int	    i;
+***************
+*** 5463,5486 ****
+  					       = getroom_save(spin, items[2]);
+  		}
+  	    }
+! 	    else if (STRCMP(items[0], "SYLLABLE") == 0 && itemcnt == 2
+  							  && syllable == NULL)
+  	    {
+  		syllable = getroom_save(spin, items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "NOBREAK") == 0 && itemcnt == 1)
+  	    {
+  		spin->si_nobreak = TRUE;
+  	    }
+! 	    else if (STRCMP(items[0], "NOSPLITSUGS") == 0 && itemcnt == 1)
+  	    {
+  		spin->si_nosplitsugs = TRUE;
+  	    }
+! 	    else if (STRCMP(items[0], "NOSUGFILE") == 0 && itemcnt == 1)
+  	    {
+  		spin->si_nosugfile = TRUE;
+  	    }
+! 	    else if (STRCMP(items[0], "PFXPOSTPONE") == 0 && itemcnt == 1)
+  	    {
+  		aff->af_pfxpostpone = TRUE;
+  	    }
+--- 5635,5658 ----
+  					       = getroom_save(spin, items[2]);
+  		}
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
+  							  && syllable == NULL)
+  	    {
+  		syllable = getroom_save(spin, items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "NOBREAK", 1))
+  	    {
+  		spin->si_nobreak = TRUE;
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1))
+  	    {
+  		spin->si_nosplitsugs = TRUE;
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1))
+  	    {
+  		spin->si_nosugfile = TRUE;
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1))
+  	    {
+  		aff->af_pfxpostpone = TRUE;
+  	    }
+***************
+*** 5771,5794 ****
+  		    }
+  		}
+  	    }
+! 	    else if (STRCMP(items[0], "FOL") == 0 && itemcnt == 2
+! 							       && fol == NULL)
+  	    {
+  		fol = vim_strsave(items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "LOW") == 0 && itemcnt == 2
+! 							       && low == NULL)
+  	    {
+  		low = vim_strsave(items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "UPP") == 0 && itemcnt == 2
+! 							       && upp == NULL)
+  	    {
+  		upp = vim_strsave(items[1]);
+  	    }
+! 	    else if ((STRCMP(items[0], "REP") == 0
+! 			|| STRCMP(items[0], "REPSAL") == 0)
+! 		    && itemcnt == 2)
+  	    {
+  		/* Ignore REP/REPSAL count */;
+  		if (!isdigit(*items[1]))
+--- 5943,5962 ----
+  		    }
+  		}
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL)
+  	    {
+  		fol = vim_strsave(items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL)
+  	    {
+  		low = vim_strsave(items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL)
+  	    {
+  		upp = vim_strsave(items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "REP", 2)
+! 		     || is_aff_rule(items, itemcnt, "REPSAL", 2))
+  	    {
+  		/* Ignore REP/REPSAL count */;
+  		if (!isdigit(*items[1]))
+***************
+*** 5819,5825 ****
+  					 : &spin->si_rep, items[1], items[2]);
+  		}
+  	    }
+! 	    else if (STRCMP(items[0], "MAP") == 0 && itemcnt == 2)
+  	    {
+  		/* MAP item or count */
+  		if (!found_map)
+--- 5987,5993 ----
+  					 : &spin->si_rep, items[1], items[2]);
+  		}
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "MAP", 2))
+  	    {
+  		/* MAP item or count */
+  		if (!found_map)
+***************
+*** 5856,5864 ****
+  		    ga_append(&spin->si_map, '/');
+  		}
+  	    }
+! 	    /* Accept "SAL from to" and "SAL from to # comment". */
+! 	    else if (STRCMP(items[0], "SAL") == 0
+! 		    && (itemcnt == 3 || (itemcnt > 3 && items[3][0] == '#')))
+  	    {
+  		if (do_sal)
+  		{
+--- 6024,6031 ----
+  		    ga_append(&spin->si_map, '/');
+  		}
+  	    }
+! 	    /* Accept "SAL from to" and "SAL from to  #comment". */
+! 	    else if (is_aff_rule(items, itemcnt, "SAL", 3))
+  	    {
+  		if (do_sal)
+  		{
+***************
+*** 5877,5888 ****
+  								: items[2]);
+  		}
+  	    }
+! 	    else if (STRCMP(items[0], "SOFOFROM") == 0 && itemcnt == 2
+  							  && sofofrom == NULL)
+  	    {
+  		sofofrom = getroom_save(spin, items[1]);
+  	    }
+! 	    else if (STRCMP(items[0], "SOFOTO") == 0 && itemcnt == 2
+  							    && sofoto == NULL)
+  	    {
+  		sofoto = getroom_save(spin, items[1]);
+--- 6044,6055 ----
+  								: items[2]);
+  		}
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
+  							  && sofofrom == NULL)
+  	    {
+  		sofofrom = getroom_save(spin, items[1]);
+  	    }
+! 	    else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
+  							    && sofoto == NULL)
+  	    {
+  		sofoto = getroom_save(spin, items[1]);
+***************
+*** 6017,6022 ****
+--- 6184,6205 ----
+  }
+  
+  /*
++  * Return TRUE when items[0] equals "rulename", there are "mincount" items or
++  * a comment is following after item "mincount".
++  */
++     static int
++ is_aff_rule(items, itemcnt, rulename, mincount)
++     char_u	**items;
++     int		itemcnt;
++     char	*rulename;
++     int		mincount;
++ {
++     return (STRCMP(items[0], rulename) == 0
++ 	    && (itemcnt == mincount
++ 		|| (itemcnt > mincount && items[mincount][0] == '#')));
++ }
++ 
++ /*
+   * For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
+   * ae_flags to ae_comppermit and ae_compforbid.
+   */
+***************
+*** 11492,11506 ****
+  		    vim_strncpy(preword + sp->ts_prewordlen,
+  			    tword + sp->ts_splitoff,
+  			    sp->ts_twordlen - sp->ts_splitoff);
+! 		    p = preword;
+! 		    while (*skiptowhite(p) != NUL)
+! 			p = skipwhite(skiptowhite(p));
+! 		    if (fword_ends && !can_compound(slang, p,
+! 						compflags + sp->ts_compsplit))
+! 			/* Compound is not allowed.  But it may still be
+! 			 * possible if we add another (short) word. */
+  			compound_ok = FALSE;
+  
+  		    /* Get pointer to last char of previous word. */
+  		    p = preword + sp->ts_prewordlen;
+  		    mb_ptr_back(preword, p);
+--- 11675,11698 ----
+  		    vim_strncpy(preword + sp->ts_prewordlen,
+  			    tword + sp->ts_splitoff,
+  			    sp->ts_twordlen - sp->ts_splitoff);
+! 
+! 		    /* Verify CHECKCOMPOUNDPATTERN  rules. */
+! 		    if (match_checkcompoundpattern(preword,  sp->ts_prewordlen,
+! 							  &slang->sl_comppat))
+  			compound_ok = FALSE;
+  
++ 		    if (compound_ok)
++ 		    {
++ 			p = preword;
++ 			while (*skiptowhite(p) != NUL)
++ 			    p = skipwhite(skiptowhite(p));
++ 			if (fword_ends && !can_compound(slang, p,
++ 						compflags + sp->ts_compsplit))
++ 			    /* Compound is not allowed.  But it may still be
++ 			     * possible if we add another (short) word. */
++ 			    compound_ok = FALSE;
++ 		    }
++ 
+  		    /* Get pointer to last char of previous word. */
+  		    p = preword + sp->ts_prewordlen;
+  		    mb_ptr_back(preword, p);
+***************
+*** 11697,11706 ****
+  			&& (slang->sl_compsylmax < MAXWLEN
+  			    || sp->ts_complen + 1 - sp->ts_compsplit
+  							  < slang->sl_compmax)
+! 			&& (byte_in_str(sp->ts_complen == sp->ts_compsplit
+! 					    ? slang->sl_compstartflags
+! 					    : slang->sl_compallflags,
+! 						    ((unsigned)flags >> 24))))
+  		{
+  		    try_compound = TRUE;
+  		    compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+--- 11889,11897 ----
+  			&& (slang->sl_compsylmax < MAXWLEN
+  			    || sp->ts_complen + 1 - sp->ts_compsplit
+  							  < slang->sl_compmax)
+! 			&& (can_be_compound(sp, slang,
+! 					 compflags, ((unsigned)flags >> 24))))
+! 
+  		{
+  		    try_compound = TRUE;
+  		    compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+*** ../vim-7.2.059/src/version.c	Sun Nov 30 15:15:56 2008
+--- src/version.c	Sun Nov 30 21:09:23 2008
+***************
+*** 678,679 ****
+--- 678,681 ----
+  {   /* Add new patch number below this line */
++ /**/
++     60,
+  /**/
+
+-- 
+DEAD PERSON:  I'm getting better!
+CUSTOMER:     No, you're not -- you'll be stone dead in a moment.
+MORTICIAN:    Oh, I can't take him like that -- it's against regulations.
+                                  The Quest for the Holy Grail (Monty Python)
+
+ /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
+///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
+\\\        download, build and distribute -- http://www.A-A-P.org        ///
+ \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
diff --git a/README.patches b/README.patches
index 7d14658..2a8aff2 100644
--- a/README.patches
+++ b/README.patches
@@ -51,3 +51,37 @@ Individual patches for Vim 7.2:
   1452  7.2.024  'history' can be made negative, causes out-of-memory error
   1470  7.2.025  a CursorHold event that invokes system() is retriggered
   2969  7.2.026  (after 7.2.010) 'K' uses the rest of the line
+  3235  7.2.027  can use cscope commands in the sandbox, might not be safe
+  1466  7.2.028  confusing error message for missing ()
+  1291  7.2.029  no completion for ":doautoall" like for ":doautocmd"
+  1546  7.2.030  (after 7.2.027) can't compile, ex_oldfiles undefined
+ 39400  7.2.031  file names from viminfo are not available to the user
+  1583  7.2.032  (after 7.2.031) can't compile with EXITFREE defined
+  2270  7.2.033  using "ucs-2le" for two-byte BOM, but text might be "utf-16le"
+  2372  7.2.034  memory leak in spell info when deleting a buffer
+  3522  7.2.035  mismatches for library and Vim alloc/free functions
+  7545  7.2.036  (extra) mismatches for library and Vim alloc/free functions
+  1576  7.2.037  double free with GTK 1 and compiled with EXITFREE
+  2438  7.2.038  overlapping arguments to memcpy()
+  1378  7.2.039  accessing freed memory on exit when EXITFREE is defined
+  1836  7.2.040  ":e ++ff=dos foo" gets "unix" 'ff' when CR before NL missing
+ 22993  7.2.041  diff messed up when editing a diff buffer in another tab page
+  4987  7.2.042  restoring view in autocmd sometimes doesn't work completely
+  2550  7.2.043  VMS: Too many chars escaped in filename and shell commands
+  5639  7.2.044  crash because of gcc 4 being over protective for strcpy()
+  2056  7.2.045  the Python interface has an empty entry in sys.path
+  1704  7.2.046  wrong check for filling buffer with encoding
+  2470  7.2.047  using -nb while it is not supported makes other side hang
+  4758  7.2.048  v:count and v:prevcount are not set correctly
+ 32552  7.2.049  (extra) Win32: the clipboard doesn't support UTF-16
+  8484  7.2.050  compiler warnings for not using return value of fwrite()
+ 15179  7.2.051  can't avoid 'wig' and 'suffixes' for glob() and globpath()
+  2611  7.2.052  synIDattr() doesn't support "sp" for special color
+  1754  7.2.053  crash when using WorkShop command ":ws foo"
+  2006  7.2.054  compilation warnings for fprintf format
+ 34319  7.2.055  various compiler warnings with strict checking
+  1635  7.2.056  (after 7.2.050) tests 58 and 59 fail
+  3210  7.2.057  (after 7.2.056) trying to put size_t in int variable
+  2338  7.2.058  can't add a feature name in the :version output
+  1847  7.2.059  diff is not always displayed properly
+ 34772  7.2.060  spell checking doesn't work well for compound words
diff --git a/vim.spec b/vim.spec
index 0b940e9..783da14 100644
--- a/vim.spec
+++ b/vim.spec
@@ -8,7 +8,7 @@
 %define desktop_file_utils_version 0.2.93
 %endif
 
-%define withnetbeans 0
+%define withnetbeans 1
 
 %define withvimspell 0
 %define withhunspell 0
@@ -18,13 +18,13 @@
 #used for pre-releases:
 %define beta %{nil}
 %define vimdir vim72%{?beta}
-%define patchlevel 026
+%define patchlevel 060
 
 Summary: The VIM editor
 URL:     http://www.vim.org/
 Name: vim
 Version: %{baseversion}.%{beta}%{patchlevel}
-Release: 2%{?dist}
+Release: 1%{?dist}
 License: Vim
 Group: Applications/Editors
 Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}%{?beta}%{?CVSDATE}.tar.bz2
@@ -45,6 +45,16 @@ Source13: vim-spell-files.tar.bz2
 Source14: spec-template
 Source15: http://www.cvjb.de/comp/vim/forth.vim
 
+# remove this for the next major version, CVE fixes:
+Source16: ftp://ftp.vim.org/vol/2/vim/runtime/plugin/netrwPlugin.vim
+Source17: ftp://ftp.vim.org/vol/2/vim/runtime/plugin/gzip.vim
+Source18: ftp://ftp.vim.org/vol/2/vim/runtime/filetype.vim
+Source19: ftp://ftp.vim.org/vol/2/vim/runtime/autoload/zip.vim
+Source20: ftp://ftp.vim.org/vol/2/vim/runtime/autoload/tar.vim
+Source21: ftp://ftp.vim.org/vol/2/vim/runtime/autoload/netrwFileHandlers.vim
+Source22: ftp://ftp.vim.org/vol/2/vim/runtime/autoload/netrw.vim
+Source23: ftp://ftp.vim.org/vol/2/vim/runtime/autoload/netrwSettings.vim
+
 Patch2002: vim-7.0-fixkeys.patch
 Patch2003: vim-6.2-specsyntax.patch
 Patch2004: vim-7.0-crv.patch
@@ -56,32 +66,66 @@ BuildRequires: hunspell-devel
 # Patches 001 < 999 are patches from the base maintainer.
 # If you're as lazy as me, generate the list using
 # for i in `seq 1 14`; do printf "Patch%03d: ftp://ftp.vim.org/pub/vim/patches/7.1/7.1.%03d\n" $i $i; done
-Patch001: 7.2.001
-Patch002: 7.2.002
-Patch003: 7.2.003
-Patch004: 7.2.004
-Patch005: 7.2.005
-Patch006: 7.2.006
-Patch007: 7.2.007
-Patch008: 7.2.008
-Patch009: 7.2.009
-Patch010: 7.2.010
-Patch011: 7.2.011
-Patch012: 7.2.012
-Patch013: 7.2.013
-Patch014: 7.2.014
-Patch015: 7.2.015
-Patch016: 7.2.016
-Patch017: 7.2.017
-Patch018: 7.2.018
-Patch019: 7.2.019
-Patch020: 7.2.020
-Patch021: 7.2.021
-Patch022: 7.2.022
-Patch023: 7.2.023
-Patch024: 7.2.024
-Patch025: 7.2.025
-Patch026: 7.2.026
+Patch001: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.001
+Patch002: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.002
+Patch003: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.003
+Patch004: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.004
+Patch005: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.005
+Patch006: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.006
+Patch007: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.007
+Patch008: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.008
+Patch009: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.009
+Patch010: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.010
+Patch011: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.011
+Patch012: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.012
+Patch013: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.013
+Patch014: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.014
+Patch015: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.015
+Patch016: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.016
+Patch017: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.017
+Patch018: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.018
+Patch019: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.019
+Patch020: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.020
+Patch021: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.021
+Patch022: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.022
+Patch023: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.023
+Patch024: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.024
+Patch025: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.025
+Patch026: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.026
+Patch027: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.027
+Patch028: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.028
+Patch029: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.029
+Patch030: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.030
+Patch031: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.031
+Patch032: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.032
+Patch033: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.033
+Patch034: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.034
+Patch035: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.035
+Patch036: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.036
+Patch037: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.037
+Patch038: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.038
+Patch039: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.039
+Patch040: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.040
+Patch041: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.041
+Patch042: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.042
+Patch043: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.043
+Patch044: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.044
+Patch045: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.045
+Patch046: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.046
+Patch047: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.047
+Patch048: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.048
+Patch049: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.049
+Patch050: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.050
+Patch051: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.051
+Patch052: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.052
+Patch053: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.053
+Patch054: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.054
+Patch055: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.055
+Patch056: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.056
+Patch057: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.057
+Patch058: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.058
+Patch059: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.059
+Patch060: ftp://ftp.vim.org/pub/vim/patches/7.2/7.2.060
 
 Patch3000: vim-7.0-syntax.patch
 Patch3002: vim-7.1-nowarnings.patch
@@ -241,6 +285,41 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk
 %patch024 -p0
 %patch025 -p0
 %patch026 -p0
+%patch027 -p0
+%patch028 -p0
+%patch029 -p0
+%patch030 -p0
+%patch031 -p0
+%patch032 -p0
+%patch033 -p0
+%patch034 -p0
+%patch035 -p0
+%patch036 -p0
+%patch037 -p0
+%patch038 -p0
+%patch039 -p0
+%patch040 -p0
+%patch041 -p0
+%patch042 -p0
+%patch043 -p0
+%patch044 -p0
+%patch045 -p0
+%patch046 -p0
+%patch047 -p0
+%patch048 -p0
+%patch049 -p0
+%patch050 -p0
+%patch051 -p0
+%patch052 -p0
+%patch053 -p0
+%patch054 -p0
+%patch055 -p0
+%patch056 -p0
+%patch057 -p0
+%patch058 -p0
+%patch059 -p0
+%patch060 -p0
+
 
 # install spell files
 %if %{withvimspell}
@@ -260,6 +339,14 @@ perl -pi -e "s,bin/nawk,bin/awk,g" runtime/tools/mve.awk
 %patch3011 -p1
 
 cp -f %{SOURCE15} runtime/syntax/forth.vim
+cp -f %{SOURCE16} runtime/plugin/netrwPlugin.vim
+cp -f %{SOURCE17} runtime/plugin/gzip.vim
+cp -f %{SOURCE18} runtime/plugin/filetype.vim
+cp -f %{SOURCE19} runtime/autoload/zip.vim
+cp -f %{SOURCE20} runtime/autoload/tar.vim
+cp -f %{SOURCE21} runtime/autoload/netrwFileHandlers.vim
+cp -f %{SOURCE22} runtime/autoload/netrw.vim
+cp -f %{SOURCE23} runtime/autoload/netrwSettings.vim
 
 
 %build
@@ -691,6 +778,12 @@ rm -rf $RPM_BUILD_ROOT
 %{_datadir}/icons/hicolor/*/apps/*
 
 %changelog
+* Mon Dec 01 2008 Karsten Hopp <karsten@redhat.com> 7.2.060-1
+- patchlevel 60
+
+* Mon Nov 10 2008 Karsten Hopp <karsten@redhat.com> 7.2.032-1
+- patchlevel 32
+
 * Mon Nov 03 2008 Karsten Hopp <karsten@redhat.com> 7.2.026-2
 - add more /usr/share/vim/vimfiles directories (#444387)