public static function match($password, array $userInputs = [])
    {
        $matches = [];
        $passwordLength = strlen($password);

        $sequences = self::LOWER.self::UPPER.self::DIGITS;
        $revSequences = strrev($sequences);

        for ($i = 0; $i < $passwordLength; ++$i) {
            $pattern = false;
            $j = $i + 2;
            // Check for sequence sizes of 3 or more.
            if ($j < $passwordLength) {
                $pattern = substr($password, $i, 3);
            }
            // Find beginning of pattern and then extract full sequences intersection.
            if ($pattern && false !== ($pos = strpos($sequences, $pattern))) {
                // Match only remaining password characters.
                $remainder = substr($password, $j + 1);
                $pattern .= static::intersect($sequences, $remainder, $pos + 3);
                $params = [
                    'ascending' => true,
                    'sequenceName' => static::getSequenceName($pos),
                    'sequenceSpace' => static::getSequenceSpace($pos),
                ];
                $matches[] = new static($password, $i, $i + strlen($pattern) - 1, $pattern, $params);
                // Skip intersecting characters on next loop.
                $i += strlen($pattern) - 1;
            }
            // Search the reverse sequence for pattern.
            elseif ($pattern && false !== ($pos = strpos($revSequences, $pattern))) {
                $remainder = substr($password, $j + 1);
                $pattern .= static::intersect($revSequences, $remainder, $pos + 3);
                $params = [
                    'ascending' => false,
                    'sequenceName' => static::getSequenceName($pos),
                    'sequenceSpace' => static::getSequenceSpace($pos),
                ];
                $matches[] = new static($password, $i, $i + strlen($pattern) - 1, $pattern, $params);
                $i += strlen($pattern) - 1;
            }
        }

        return $matches;
    }