/*
Pluralize a word, obeying any stored exceptions.

@param string $word the word to pluralize
172787
public static function pluralize($word) {
        foreach(self::$_exceptions as $exception) {
			if($exception['singular'] == $word){
				return $exception['plural'];
			}
        }

        return parent::pluralize($word);
	}
787333
public function pluralize($items = null) : Manipulator
    {
        /**
         * Optional parameter to determine if a string
         * should be pluralized.
         */
        if (!is_null($items)) {
            $count = is_numeric($items) ? $items : count($items);

            if ($count <= 1) {
                return $this;
            }
        }

        return new static(Inflector::pluralize($this->string));
    }
972777
protected function decamelize($word)
    {
        return preg_replace_callback(
            '/(^|[a-z])([A-Z])/',
            function ($matches) {
                return strtolower(strlen($matches[1]) ? $matches[1] . "_" . $matches[2] : $matches[2]);
            },
            $word
        );
    }
595862
public static function fix_case($word) {
    # Fix case for words split by periods (J.P.)
    if (strpos($word, '.') !== false) {
      $word = self::safe_ucfirst(".", $word);;
    }
    # Fix case for words split by hyphens (Kimura-Fay)
    if (strpos($word, '-') !== false) {
      $word = self::safe_ucfirst("-", $word);
    }
    # Special case for single letters
    if (strlen($word) == 1) {
      $word = strtoupper($word);
    }
    # Special case for 2-letter words
    if (strlen($word) == 2) {
      # Both letters vowels (uppercase both)
      if (in_array(strtolower($word{0}), self::$dict['vowels']) && in_array(strtolower($word{1}), self::$dict['vowels'])) {
        $word = strtoupper($word);
      }
      # Both letters consonants (uppercase both)
      if (!in_array(strtolower($word{0}), self::$dict['vowels']) && !in_array(strtolower($word{1}), self::$dict['vowels'])) {
        $word = strtoupper($word);
      }
      # First letter is vowel, second letter consonant (uppercase first)
      if (in_array(strtolower($word{0}), self::$dict['vowels']) && !in_array(strtolower($word{1}), self::$dict['vowels'])) {
        $word = ucfirst(strtolower($word));
      }
      # First letter consonant, second letter vowel or "y" (uppercase first)
      if (!in_array(strtolower($word{0}), self::$dict['vowels']) && (in_array(strtolower($word{1}), self::$dict['vowels']) || strtolower($word{1}) == 'y')) {
        $word = ucfirst(strtolower($word));
      }
    }
    # Fix case for words which aren't initials, but are all upercase or lowercase
    if ( (strlen($word) >= 3) && (ctype_upper($word) || ctype_lower($word)) ) {
      $word = ucfirst(strtolower($word));
    }
    return $word;
  }
1160810
public static function plural($word)
    {
        if(is_array($word)) {
            $ret = [];
            foreach($word as $key => $value) {
                $ret[$key] = Str::plural($value);
            }

            return $ret;
        }

        return Inflector::plural($word);
    }
867317
public static function singularize($word) {
		if (isset(static::$_singularized[$word])) {
			return static::$_singularized[$word];
		}
		if (empty(static::$_singular['irregular'])) {
			static::$_singular['irregular'] = array_flip(static::$_plural['irregular']);
		}
		extract(static::$_singular);

		if (!isset($regexUninflected) || !isset($regexIrregular)) {
			$regexUninflected = static::_enclose(join('|', $uninflected + static::$_uninflected));
			$regexIrregular = static::_enclose(join('|', array_keys($irregular)));
			static::$_singular += compact('regexUninflected', 'regexIrregular');
		}
		if (preg_match("/(.*)\\b({$regexIrregular})\$/i", $word, $regs)) {
			$singular = substr($word, 0, 1) . substr($irregular[strtolower($regs[2])], 1);
			return static::$_singularized[$word] = $regs[1] . $singular;
		}
		if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
			return static::$_singularized[$word] = $word;
		}
		foreach ($rules as $rule => $replacement) {
			if (preg_match($rule, $word)) {
				return static::$_singularized[$word] = preg_replace($rule, $replacement, $word);
			}
		}
		return static::$_singularized[$word] = $word;
	}
1282599
public static function singularize(string $word): string
	{
		if (isset(static::$_cache['singularize'][$word])) {
			return static::$_cache['singularize'][$word];
		}

		if (!isset(static::$_cache['irregular']['singular'])) {
			static::$_cache['irregular']['singular'] = '(?:' . \implode('|', static::$_irregular) . ')';
		}

		if (\preg_match('/(.*?(?:\\b|_))(' . static::$_cache['irregular']['singular'] . ')$/i', $word, $regs)) {
			static::$_cache['singularize'][$word] = $regs[1] . $regs[2][0] .
				\substr(\array_search(\strtolower($regs[2]), static::$_irregular, true), 1);

			return static::$_cache['singularize'][$word];
		}

		if (!isset(static::$_cache['uninflected'])) {
			static::$_cache['uninflected'] = '(?:' . \implode('|', static::$_uninflected) . ')';
		}

		if (\preg_match('/^(' . static::$_cache['uninflected'] . ')$/i', $word, $regs)) {
			static::$_cache['pluralize'][$word] = $word;

			return $word;
		}

		foreach (static::$_singular as $rule => $replacement) {
			if (\preg_match($rule, $word)) {
				static::$_cache['singularize'][$word] = \preg_replace($rule, $replacement, $word);

				return static::$_cache['singularize'][$word];
			}
		}
		static::$_cache['singularize'][$word] = $word;

		return $word;
	}
594539
public static function pluralize($word)
        {
            if (isset(static::$_pluralized[$word])) {
                return static::$_pluralized[$word];
            }

            extract(static::$_plural);

            if (!isset($regexUninflected) || !isset($regexIrregular)) {
                $regexUninflected = static::_enclose(join('|', $uninflected + static::$_uninflected));
                $regexIrregular = static::_enclose(join('|', array_keys($irregular)));

                static::$_plural += compact('regexUninflected', 'regexIrregular');
            }

            if (preg_match('/(' . $regexUninflected . ')$/i', $word, $regs)) {
                return static::$_pluralized[$word] = $word;
            }

            if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
                $plural = substr($word, 0, 1) . substr($irregular[static::lower($regs[2])], 1);

                return static::$_pluralized[$word] = $regs[1] . $plural;
            }

            foreach ($rules as $rule => $replacement) {
                if (preg_match($rule, $word)) {
                    return static::$_pluralized[$word] = preg_replace($rule, $replacement, $word);
                }
            }

            return static::$_pluralized[$word] = $word;
        }
827281
public static function pluralize(string $word): string
	{
		if (isset(static::$_cache['pluralize'][$word])) {
			return static::$_cache['pluralize'][$word];
		}

		if (!isset(static::$_cache['irregular']['pluralize'])) {
			static::$_cache['irregular']['pluralize'] = '(?:' . \implode('|', \array_keys(static::$_irregular)) . ')';
		}

		if (\preg_match('/(.*?(?:\\b|_))(' . static::$_cache['irregular']['pluralize'] . ')$/i', $word, $regs)) {
			static::$_cache['pluralize'][$word] = $regs[1] . $regs[2][0] .
				\substr(static::$_irregular[\strtolower($regs[2])], 1);

			return static::$_cache['pluralize'][$word];
		}

		if (!isset(static::$_cache['uninflected'])) {
			static::$_cache['uninflected'] = '(?:' . \implode('|', static::$_uninflected) . ')';
		}

		if (\preg_match('/^(' . static::$_cache['uninflected'] . ')$/i', $word, $regs)) {
			static::$_cache['pluralize'][$word] = $word;

			return $word;
		}

		foreach (static::$_plural as $rule => $replacement) {
			if (\preg_match($rule, $word)) {
				static::$_cache['pluralize'][$word] = \preg_replace($rule, $replacement, $word);

				return static::$_cache['pluralize'][$word];
			}
		}

		return $word;
	}
1104998
public static function underscore($word)
        {
            if (isset(static::$_underscored[$word])) {
                return static::$_underscored[$word];
            }

            return static::$_underscored[$word] = static::lower(static::slug($word, '_'));
        }
367027
public function pluralize($word)
    {
        if ($plural = $this->getCache($word, 'pluralize')) {
            return $plural;
        }

        if (isset($this->_uncountables_keys[$word])) {
            return $word;
        }

        foreach ($this->_pluralizationRules as $regexp => $replacement) {
            $plural = preg_replace($regexp, $replacement, $word, -1, $matches);
            if ($matches > 0) {
                return $this->setCache($word, 'pluralize', $plural);
            }
        }

        return $this->setCache($word, 'pluralize', $word);
    }
1331220
public static function pluralize($word)
    {
        $lowerCasedWord = strtolower($word);
        foreach (static::$uncountables as $uncountable) {
            if (substr($lowerCasedWord, (-1 * strlen($uncountable))) == $uncountable) {
                return $word;
            }
        }
        foreach (static::$irregulars as $plural => $singular) {
            if (preg_match('/(' . $plural . ')$/i', $word, $arr)) {
                return preg_replace(
                    '/(' . $plural . ')$/i',
                    substr($arr[0], 0, 1) . substr($singular, 1),
                    $word
                );
            }
        }
        foreach (static::$plurals as $rule => $replacement) {
            if (preg_match($rule, $word)) {
                return preg_replace($rule, $replacement, $word);
            }
        }

        return false;
    }
1334227
protected function stemSingularWord($word)
    {
        $context = new Context($word, $this->dictionary, $this->visitorProvider);
        $context->execute();

        return $context->getResult();
    }
341350
public function pluralize(string $word, int $number = 2): string
    {
        return Typogrify::$plugin->typogrify->pluralize($word, $number);
    }
1015405
public static function stem($word)
    {
        $nounStem = self::roughStem(
            $word, self::$_nounMay, self::$_nounPre, self::$_nounPost, 
            self::$_nounMaxPre, self::$_nounMaxPost, self::$_nounMinStem
        );
        $verbStem = self::roughStem(
            $word, self::$_verbMay, self::$_verbPre, self::$_verbPost, 
            self::$_verbMaxPre, self::$_verbMaxPost, self::$_verbMinStem
        );
        
        if (mb_strlen($nounStem, 'UTF-8') < mb_strlen($verbStem, 'UTF-8')) {
            $stem = $nounStem;
        } else {
            $stem = $verbStem;
        }
        
        return $stem;
    }
220599
public static function pluralize($word) {
        if ('' === $word || null === $word) {
            return false;
        }
        $plural = array(
            '/(quiz)$/i'               => '$1zes',
            '/^(ox)$/i'                => '$1en',
            '/([m|l])ouse$/i'          => '$1ice',
            '/(matr|vert|ind)ix|ex$/i' => '$1ices',
            '/(x|ch|ss|sh)$/i'         => '$1es',
            '/([^aeiouy]|qu)ies$/i'    => '$1y',
            '/([^aeiouy]|qu)y$/i'      => '$1ies',
            '/(hive)$/i'               => '$1s',
            '/(?:([^f])fe|([lr])f)$/i' => '$1$2ves',
            '/sis$/i'                  => 'ses',
            '/([ti])um$/i'             => '$1a',
            '/(buffal|tomat)o$/i'      => '$1oes',
            '/(bu)s$/i'                => '$1ses',
            '/(alias|status)/i'        => '$1es',
            '/(octop|vir)us$/i'        => '$1i',
            '/(ax|test)is$/i'          => '$1es',
            '/s$/i'                    => 's',
        );

        $uncountableNouns = [
            'air',
            'anger',
            'beauty',
            'equipment',
            'evidence',
            'fish',
            'information',
            'knowledge',
            'love',
            'money',
            'news',
            'research',
            'rice',
            'safety',
            'series',
            'sheep',
            'species',
            'sugar',
            'tea',
            'water',
        ];

        $irregular = [
            'child'  => 'children',
            'leaf'   => 'leaves',
            'man'    => 'men',
            'move'   => 'moves',
            'person' => 'people',
            'sex'    => 'sexes',
        ];

        $lowerWord = strtolower($word);
        foreach ($uncountableNouns as $noun) {
            if (substr($lowerWord, -strlen($noun)) === $noun) {
                return $word . '_list';
            }
        }

        foreach ($irregular as $_singular => $_plural) {
            $length = strlen($_singular);
            if (substr($lowerWord, -$length) === $_singular) {
                return substr($word, 0, -$length) . $_plural;
            }
        }

        foreach ($plural as $search => $replacement) {
            if (($r = preg_replace($search, $replacement, $word)) !== $word) {
                return $r;
            }
        }
        return $word . 's';
    }
935067
public static function pluralize( $name )
    {
        /** @noinspection SpellCheckingInspection */
        static $_blacklist = array(
            'Amoyese',
            'bison',
            'Borghese',
            'bream',
            'breeches',
            'britches',
            'buffalo',
            'cantus',
            'carp',
            'chassis',
            'clippers',
            'cod',
            'coitus',
            'Congoese',
            'contretemps',
            'corps',
            'debris',
            'deer',
            'diabetes',
            'djinn',
            'eland',
            'elk',
            'equipment',
            'Faroese',
            'flounder',
            'Foochowese',
            'gallows',
            'Genevese',
            'geese',
            'Genoese',
            'Gilbertese',
            'graffiti',
            'headquarters',
            'herpes',
            'hijinks',
            'Hottentotese',
            'information',
            'innings',
            'jackanapes',
            'Kiplingese',
            'Kongoese',
            'Lucchese',
            'mackerel',
            'Maltese',
            '.*?media',
            'metadata',
            'mews',
            'moose',
            'mumps',
            'Nankingese',
            'news',
            'nexus',
            'Niasese',
            'Pekingese',
            'Piedmontese',
            'pincers',
            'Pistoiese',
            'pliers',
            'Portuguese',
            'proceedings',
            'rabies',
            'rice',
            'rhinoceros',
            'salmon',
            'Sarawakese',
            'scissors',
            'sea[- ]bass',
            'series',
            'Shavese',
            'shears',
            'siemens',
            'species',
            'swine',
            'testes',
            'trousers',
            'trout',
            'tuna',
            'Vermontese',
            'Wenchowese',
            'whiting',
            'wildebeest',
            'Yengeese',
        );
        /** @noinspection SpellCheckingInspection */
        static $_rules = array(
            '/(s)tatus$/i'                                                                 => '\1\2tatuses',
            '/(quiz)$/i'                                                                   => '\1zes',
            '/^(ox)$/i'                                                                    => '\1en',
            '/(matr|vert|ind)(ix|ex)$/i'                                                   => '\1ices',
            '/([m|l])ouse$/i'                                                              => '\1ice',
            '/(x|ch|ss|sh|us|as|is|os)$/i'                                                 => '\1es',
            '/(shea|lea|loa|thie)f$/i'                                                     => '\1ves',
            '/(buffal|tomat|potat|ech|her|vet)o$/i'                                        => '\1oes',
            '/([^aeiouy]|qu)ies$/i'                                                        => '\1y',
            '/([^aeiouy]|qu)y$/i'                                                          => '\1ies',
            '/(?:([^f])fe|([lre])f)$/i'                                                    => '\1\2ves',
            '/([ti])um$/i'                                                                 => '\1a',
            '/sis$/i'                                                                      => 'ses',
            '/move$/i'                                                                     => 'moves',
            '/foot$/i'                                                                     => 'feet',
            '/human$/i'                                                                    => 'humans',
            '/tooth$/i'                                                                    => 'teeth',
            '/(bu)s$/i'                                                                    => '\1ses',
            '/(hive)$/i'                                                                   => '\1s',
            '/(p)erson$/i'                                                                 => '\1eople',
            '/(m)an$/i'                                                                    => '\1en',
            '/(c)hild$/i'                                                                  => '\1hildren',
            '/(alumn|bacill|cact|foc|fung|nucle|octop|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
            '/us$/i'                                                                       => 'uses',
            '/(alias)$/i'                                                                  => '\1es',
            '/(ax|cris|test)is$/i'                                                         => '\1es',
            '/s$/'                                                                         => 's',
            '/$/'                                                                          => 's',
        );

        if ( empty( $name ) || in_array( strtolower( $name ), $_blacklist ) )
        {
            return $name;
        }

        foreach ( $_rules as $_rule => $_replacement )
        {
            if ( preg_match( $_rule, $name ) )
            {
                return preg_replace( $_rule, $_replacement, $name );
            }
        }

        return $name;
    }