func step4(word *snowballword.SnowballWord) bool {

	hadChange := false

	if word.String() == "voudrion" {
		log.Println("...", word)
	}

	// If the word ends s (unicode code point 115),
	// not preceded by a, i, o, u, è or s, delete it.
	//
	if idx := len(word.RS) - 1; idx >= 1 && word.RS[idx] == 115 {
		switch word.RS[idx-1] {

		case 97, 105, 111, 117, 232, 115:

			// Do nothing, preceded by a, i, o, u, è or s
			return false

		default:
			word.RemoveLastNRunes(1)
			hadChange = true

		}
	}

	// Note: all the following are restricted to the RV region.

	// Search for the longest among the following suffixes in RV.
	//
	suffix, suffixRunes := word.FirstSuffixIn(word.RVstart, len(word.RS),
		"Ière", "ière", "Ier", "ier", "ion", "e", "ë",
	)

	switch suffix {
	case "":
		return hadChange
	case "ion":

		// Delete if in R2 and preceded by s or t in RV

		const sLen int = 3 // equivalently, len(suffixRunes)
		idx := len(word.RS) - sLen - 1
		if word.FitsInR2(sLen) && idx >= 0 && word.FitsInRV(sLen+1) {
			if word.RS[idx] == 115 || word.RS[idx] == 116 {
				word.RemoveLastNRunes(sLen)
				return true
			}
		}
		return hadChange

	case "ier", "ière", "Ier", "Ière":
		// Replace with i
		word.ReplaceSuffixRunes(suffixRunes, []rune("i"), true)
		return true

	case "e":
		word.RemoveLastNRunes(1)
		return true

	case "ë":

		// If preceded by gu (unicode code point 103 & 117), delete
		idx := len(word.RS) - 1
		if idx >= 2 && word.RS[idx-2] == 103 && word.RS[idx-1] == 117 {
			word.RemoveLastNRunes(1)
			return true
		}
		return hadChange
	}

	return true
}
func step4(word *snowballword.SnowballWord) bool {

	hadChange := false

	if word.String() == "voudrion" {
		log.Println("...", word)
	}

	
	
	
	if idx := len(word.RS) - 1; idx >= 1 && word.RS[idx] == 115 {
		switch word.RS[idx-1] {

		case 97, 105, 111, 117, 232, 115:

			
			return false

		default:
			word.RemoveLastNRunes(1)
			hadChange = true

		}
	}

	

	
	
	suffix, suffixRunes := word.FirstSuffixIn(word.RVstart, len(word.RS),
		"Ière", "ière", "Ier", "ier", "ion", "e", "ë",
	)

	switch suffix {
	case "":
		return hadChange
	case "ion":

		

		const sLen int = 3 
		idx := len(word.RS) - sLen - 1
		if word.FitsInR2(sLen) && idx >= 0 && word.FitsInRV(sLen+1) {
			if word.RS[idx] == 115 || word.RS[idx] == 116 {
				word.RemoveLastNRunes(sLen)
				return true
			}
		}
		return hadChange

	case "ier", "ière", "Ier", "Ière":
		
		word.ReplaceSuffixRunes(suffixRunes, []rune("i"), true)
		return true

	case "e":
		word.RemoveLastNRunes(1)
		return true

	case "ë":

		
		idx := len(word.RS) - 1
		if idx >= 2 && word.RS[idx-2] == 103 && word.RS[idx-1] == 117 {
			word.RemoveLastNRunes(1)
			return true
		}
		return hadChange
	}

	return true
}
func step4 ( word * snowballword . SnowballWord ) bool { hadChange := false if word . String ( ) == " " { log . Println ( " " , word ) } // If the word ends s (unicode code point 115), // not preceded by a, i, o, u, è or s, delete it. // if idx := len ( word . RS ) - 1 ; idx >= 1 && word . RS [ idx ] == 115 { switch word . RS [ idx - 1 ] { case 97 , 105 , 111 , 117 , 232 , 115 : // Do nothing, preceded by a, i, o, u, è or s return false default : word . RemoveLastNRunes ( 1 ) hadChange = true } } // Note: all the following are restricted to the RV region. // Search for the longest among the following suffixes in RV. // suffix , suffixRunes := word . FirstSuffixIn ( word . RVstart , len ( word . RS ) , " , i " e " e " o " " " " ) switch suffix { case " " : return hadChange case " " : // Delete if in R2 and preceded by s or t in RV const sLen int = 3 // equivalently, len(suffixRunes) idx := len ( word . RS ) - sLen - 1 if word . FitsInR2 ( sLen ) && idx >= 0 && word . FitsInRV ( sLen + 1 ) { if word . RS [ idx ] == 115 || word . RS [ idx ] == 116 { word . RemoveLastNRunes ( sLen ) return true } } return hadChange case " " , " , I , I // Replace with i word . ReplaceSuffixRunes ( suffixRunes , [ ] rune ( " " ) , true ) return true case " " : word . RemoveLastNRunes ( 1 ) return true case " : // If preceded by gu (unicode code point 103 & 117), delete idx := len ( word . RS ) - 1 if idx >= 2 && word . RS [ idx - 2 ] == 103 && word . RS [ idx - 1 ] == 117 { word . RemoveLastNRunes ( 1 ) return true } return hadChange } return true }
// Step 4 is the cleaning up of residual suffixes.
//
Step 4 is the cleaning up of residual suffixes .