protected function dewidow( $text, array $func, $max_pull, $max_length, $word_number, $narrow_space ) {
		if ( $word_number < 1 ) {
			return $text; // We are done.
		}

		// Do what we have to do.
		return \preg_replace_callback(
			self::REGEX_START . ( $word_number - 1 ) . self::REGEX_END,
			function( array $widow ) use ( $func, $max_pull, $max_length, $word_number, $narrow_space ) {

				// If we are here, we know that widows are being protected in some fashion
				// with that, we will assert that widows should never be hyphenated or wrapped
				// as such, we will strip soft hyphens and zero-width-spaces.
				$widow['widow']    = self::strip_breaking_characters( $widow['widow'] );
				$widow['trailing'] = self::strip_breaking_characters( self::make_space_nonbreaking( $widow['trailing'], $narrow_space, $func['u'] ) );

				if (
					// Eject if widows neighbor is proceeded by a no break space (the pulled text would be too long).
					'' === $widow['space_before'] || false !== \strpos( $widow['space_before'], U::NO_BREAK_SPACE ) ||
					// Eject if widows neighbor length exceeds the max allowed or widow length exceeds max allowed.
					$func['strlen']( $widow['neighbor'] ) > $max_pull || $func['strlen']( $widow['widow'] ) > $max_length ||
					// Never replace thin and hair spaces with &nbsp;.
					self::is_narrow_space( $widow['space_between'] )
				) {
					return $widow['space_before'] . $widow['neighbor'] . $this->dewidow( $widow['space_between'] . $widow['widow'] . $widow['trailing'], $func, $max_pull, $max_length, $word_number - 1, $narrow_space );
				}

				// Let's protect some widows!
				return $widow['space_before'] . $widow['neighbor'] . U::NO_BREAK_SPACE . self::make_space_nonbreaking( $widow['widow'], $narrow_space, $func['u'] ) . $widow['trailing'];
			},
			$text
		);
	}