Determine if the user's operating system is Nokia.

@param Os $os
@param UserAgent $userAgent

@return bool
425583
private static function checkNokia(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'Nokia') !== false) {
            $os->setVersion($os::VERSION_UNKNOWN);
            $os->setName($os::NOKIA);
            $os->setIsMobile(true);

            return true;
        }

        return false;
    }
611613
private static function checkChromeOs(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), ' CrOS') !== false ||
            stripos($userAgent->getUserAgentString(), 'CrOS ') !== false
        ) {
            $os->setName($os::CHROME_OS);
            if (preg_match('/Chrome\/([\d\.]*)/i', $userAgent->getUserAgentString(), $matches)) {
                $os->setVersion($matches[1]);
            }
            return true;
        }

        return false;
    }
771630
public function isTablet($userAgent = null)
    {
        $this->setDetectionType(self::DETECTION_TYPE_MOBILE);

        foreach (self::$tabletDevices as $_regex) {
            if ($this->match($_regex, $userAgent)) {
                return true;
            }
        }

        return false;
    }
913627
public static function getMobileCatchAllId($userAgent) {
		foreach (self::$mobileCatchAllIds as $key => $deviceId) {
			if (strpos($userAgent, $key) !== false) {
				return $deviceId;
			}
		}
		return WURFL_Constants::NO_MATCH;
	}
1016631
public function detectVersion(string $useragent): VersionInterface
    {
        $doMatch = preg_match('/CPU like Mac OS X/', $useragent);

        if ($doMatch) {
            return (new VersionFactory())->set('1.0');
        }

        $doMatch = preg_match('/mobile\/(\d+[A-Z]\d+(?:[a-z])?)/i', $useragent, $matches);

        if ($doMatch) {
            $buildVersion = iOSbuild::getVersion($matches[1]);

            if (false !== $buildVersion) {
                return (new VersionFactory())->set($buildVersion);
            }
        }

        $doMatch = preg_match('/applecoremedia\/\d+\.\d+\.\d+\.(\d+[A-Z]\d+(?:[a-z])?)/i', $useragent, $matches);

        if ($doMatch) {
            $buildVersion = iOSbuild::getVersion($matches[1]);

            if (false !== $buildVersion) {
                return (new VersionFactory())->set($buildVersion);
            }
        }

        if (false !== mb_stripos($useragent, 'darwin')) {
            $searches = [
                '/darwin\/18\.2/i' => '12.2',
                '/darwin\/18\.1/i' => '12.1',
                '/darwin\/18/i' => '12.0',
                '/darwin\/17\.7/i' => '11.4',
                '/darwin\/17\.6/i' => '11.4',
                '/cfnetwork\/897(\.\d+)? darwin\/17\.5/i' => '11.3',
                '/darwin\/17\.4/i' => '11.2',
                '/darwin\/17\.3/i' => '11.2',
                '/darwin\/17\.2/i' => '11.1',
                '/darwin\/17/i' => '11.0',
                '/darwin\/16\.7/i' => '10.3.3',
                '/darwin\/16\.6/i' => '10.3.2',
                '/darwin\/16\.5/i' => '10.3',
                '/darwin\/16\.3/i' => '10.2',
                '/darwin\/16\.1/i' => '10.1',
                '/darwin\/16/i' => '10.0',
                '/darwin\/15\.6/i' => '9.3.3',
                '/darwin\/15\.5/i' => '9.3.2',
                '/darwin\/15\.4/i' => '9.3',
                '/cfnetwork\/758\.3(\.\d+)? darwin\/15/i' => '9.3',
                '/cfnetwork\/758\.2(\.\d+)? darwin\/15/i' => '9.2',
                '/cfnetwork\/758\.1(\.\d+)? darwin\/15/i' => '9.1',
                '/darwin\/15/i' => '9.0',
                '/cfnetwork\/711\.[45](\.\d+)? darwin\/14/i' => '8.4',
                '/cfnetwork\/711\.3(\.\d+)? darwin\/14/i' => '8.3',
                '/cfnetwork\/711\.2(\.\d+)? darwin\/14/i' => '8.2',
                '/cfnetwork\/711\.1(\.\d+)? darwin\/14/i' => '8.1',
                '/cfnetwork\/711([\.\d]+)? darwin\/14/i' => '8.0',
                '/cfnetwork\/709(\.\d+)? darwin\/14/i' => '8.0',
                '/cfnetwork\/672\.1(\.\d+)? darwin\/14/i' => '7.1',
                '/darwin\/14/i' => '7.0',
                '/cfnetwork\/609\.1(\.\d+)? darwin\/13/i' => '6.1',
                '/darwin\/13/i' => '6.0',
                '/cfnetwork\/548\.1(\.\d+)? darwin\/11/i' => '5.1',
                '/cfnetwork\/548([\.\d]+)? darwin\/11/i' => '5.0',
                '/darwin\/11/i' => '4.3',
                '/darwin\/10\.4/i' => '4.2',
                '/cfnetwork\/485\.10(\.\d+)? darwin\/10\.3/i' => '4.1',
                '/cfnetwork\/485\.2(\.\d+)? darwin\/10\.3/i' => '4.0',
                '/darwin\/10\.3/i' => '3.2',
                '/cfnetwork\/459 darwin\/10/i' => '3.1',
                '/darwin\/10/i' => '3.0',
                '/darwin\/9\.4/i' => '2.1',
                '/darwin\/9\.3/i' => '2.0',
                '/darwin\/9/i' => '1.0',
            ];

            foreach ($searches as $rule => $version) {
                if (preg_match($rule, $useragent)) {
                    return (new VersionFactory())->set($version);
                }
            }
        }

        $doMatch = preg_match('/^apple-(?:iphone|ip[ao]d)\d+[c,_]\d+\/([\d\.]+)$/i', $useragent, $matches);

        if ($doMatch) {
            // @see https://justworks.ca/blog/ios-and
            $map = [
                '508.11' => '2.2.1',
                '701.341' => '3.0',
                '701.400' => '3.0.1',
                '703.144' => '3.1',
                '704.11' => '3.1.2',
                '705.18' => '3.1.3',
                '702.367' => '3.2',
                '702.405' => '3.2.1',
                '702.500' => '3.2.2',
                '801.293' => '4.0',
                '801.306' => '4.0.1',
                '801.400' => '4.0.2',
                '802.117' => '4.1',
                '802.118' => '4.1',
                '803.148' => '4.2.1',
                '803.14800001' => '4.2.1',
                '805.128' => '4.2.5',
                '805.200' => '4.2.6',
                '805.303' => '4.2.7',
                '805.401' => '4.2.8',
                '805.501' => '4.2.9',
                '805.600' => '4.2.10',
                '806.190' => '4.3',
                '806.191' => '4.3',
                '807.4' => '4.3.1',
                '808.7' => '4.3.2',
                '808.8' => '4.3.2',
                '810.2' => '4.3.3',
                '810.3' => '4.3.3',
                '811.2' => '4.3.4',
                '812.1' => '4.3.5',
                '901.334' => '5.0',
                '901.40' => '5.0.1',
                '902.17' => '5.1',
                '902.206' => '5.1.1',
                '1001.40' => '6.0',
                '1001.52' => '6.0.1',
                '1002.14' => '6.1',
                '1002.146' => '6.1.2',
                '1002.329' => '6.1.3',
                '1002.350' => '6.1.3',
                '1101.465' => '7.0',
                '1101.470' => '7.0.1',
                '1101.47000001' => '7.0.1',
                '1101.501' => '7.0.2',
                '1102.511' => '7.0.3',
                '1102.55400001' => '7.0.4',
                '1102.601' => '7.0.5',
                '1102.651' => '7.0.6',
                '1104.167' => '7.1',
                '1104.169' => '7.1',
                '1104.201' => '7.1.1',
                '1104.257' => '7.1.2',
                '1201.365' => '8.0',
                '1201.366' => '8.0.1',
                '1201.405' => '8.0.2',
                '1202.410' => '8.1',
                '1202.411' => '8.1',
                '1202.435' => '8.1.1',
                '1202.436' => '8.1.1',
                '1202.440' => '8.1.2',
                '1202.445' => '8.1.2',
                '1202.466' => '8.1.3',
                '1204.508' => '8.2',
                '1206.69' => '8.3',
                '1208.143' => '8.4',
                '1208.321' => '8.4.1',
                '1301.342' => '9.0',
                '1301.344' => '9.0',
                '1301.402' => '9.0.1',
                '1301.404' => '9.0.1',
                '1301.452' => '9.0.2',
                '1302.143' => '9.1',
                '1303.075' => '9.2',
                '1304.15' => '9.2.1',
                '1305.234' => '9.3',
                '1305.328' => '9.3.1',
                '1306.69' => '9.3.2',
                '1306.72' => '9.3.2',
                '1307.34' => '9.3.3',
                '1307.35' => '9.3.4',
                '1307.36' => '9.3.5',
                '1401.403' => '10.0.1',
                '1401.456' => '10.0.2',
                '1402.72' => '10.1',
                '1402.100' => '10.1.1',
                '1403.92' => '10.2',
                '1404.27' => '10.2.1',
                '1405.277' => '10.3',
                '1405.304' => '10.3.1',
                '1406.89' => '10.3.2',
                '1406.8089' => '10.3.2',
                '1407.60' => '10.3.3',
                '1501.372' => '11.0',
                '1501.402' => '11.0.1',
                '1501.421' => '11.0.2',
                '1501.432' => '11.0.3',
                '1502.93' => '11.1',
                '1502.150' => '11.1.1',
                '1502.202' => '11.1.2',
                '1503.114' => '11.2',
                '1503.153' => '11.2.1',
                '1503.202' => '11.2.2',
                '1504.60' => '11.2.5',
                '1504.100' => '11.2.6',
                '1505.216' => '11.3',
                '1505.302' => '11.3.1',
                '1506.79' => '11.4',
                '1507.77' => '11.4.1',
                '1601.366' => '12.0',
                '1601.405' => '12.0.1',
                '1602.92' => '12.1',
                '1603.50' => '12.1.1',
            ];

            if (isset($map[$matches[1]])) {
                return (new VersionFactory())->set($map[$matches[1]]);
            }
        }

        $searches = [
            'IphoneOSX',
            'CPU OS_?',
            'CPU iOS',
            'CPU iPad OS',
            'iPhone OS\;FBSV',
            'iPhone OS',
            'iPhone_OS',
            'IUC\(U\;iOS',
            'iPh OS',
            'iosv',
            'iPad\/',
            'iOS',
        ];

        $detectedVersion = (new VersionFactory())->detectVersion($useragent, $searches);

        if ('10.10' === $detectedVersion->getVersion(VersionInterface::IGNORE_MICRO)) {
            return (new VersionFactory())->set('8.0.0');
        }

        return $detectedVersion;
    }
607793
private static function checkSymbOS(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'SymbOS') !== false) {
            $os->setName($os::SYMBOS);

            return true;
        }

        return false;
    }
325560
public function applyConclusiveMatch($userAgent)
    {
        $idx       = strpos($userAgent, 'Nokia');
        $tolerance = Utils::indexOfAnyOrLength($userAgent, array('/', ' '), $idx);

        return $this->getDeviceIDFromRIS($userAgent, $tolerance);
    }
179322
public function applyRecoveryMatch($userAgent)
    {
        if (Utils::checkIfContains($userAgent, 'Series60')) {
            return 'nokia_generic_series60';
        }

        if (Utils::checkIfContains($userAgent, 'Series80')) {
            return 'nokia_generic_series80';
        }

        if (Utils::checkIfContains($userAgent, 'MeeGo')) {
            return 'nokia_generic_meego';
        }

        return WurflConstants::NO_MATCH;
    }
1328688
public static function isMobileBrowser($userAgent)
    {
        $userAgent_lower = strtolower($userAgent);
        if (self::$isMobileBrowser === null) {
            if (self::isDesktopBrowser($userAgent)) {
                self::$isMobileBrowser = false;
            } elseif (self::checkIfContainsAnyOf($userAgent_lower, self::$mobileBrowsers)) {
                self::$isMobileBrowser = true;
            } elseif (self::regexContains($userAgent, '/[^\d]\d{3}x\d{3}/')) {
                self::$isMobileBrowser = true;
            } else {
                self::$isMobileBrowser = false;
            }
        }

        return self::$isMobileBrowser;
    }
326301
private static function checkFreeBSD(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'FreeBSD') !== false) {
            $os->setVersion($os::VERSION_UNKNOWN);
            $os->setName($os::FREEBSD);

            return true;
        }

        return false;
    }
1153788
private static function checkOS2(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'OS\/2') !== false) {
            $os->setVersion($os::VERSION_UNKNOWN);
            $os->setName($os::OS2);

            return true;
        }

        return false;
    }
930568
public static function getWindowsPhoneVersion($userAgent)
    {
        if (preg_match('|Windows ?Phone(?: ?OS)? ?(\d+\.\d+)|', $userAgent, $matches)) {
            if (strpos($matches[1], '10.0') !== false) {
                return '10.0';
            } elseif (strpos($matches[1], '6.3') !== false || strpos($matches[1], '8.1') !== false) {
                return '8.1';
            } elseif (strpos($matches[1], '8.') !== false) {
                return '8.0';
            } elseif (strpos($matches[1], '7.8') !== false) {
                return '7.8';
            } elseif (strpos($matches[1], '7.10') !== false || strpos($matches[1], '7.5') !== false) {
                return '7.5';
            } elseif (strpos($matches[1], '6.5') !== false) {
                return '6.5';
            } else {
                return '7.0';
            }
        }

        return null;
    }
942970
public static function isRobot($userAgent)
    {
        self::$isRobot = false;
        $userAgent     = strtolower($userAgent);

        foreach (self::$robots as $key) {
            if (strpos($userAgent, $key) !== false) {
                self::$isRobot = true;
                break;
            }
        }

        return self::$isRobot;
    }
952254
public static function isDesktopBrowserHeavyDutyAnalysis($userAgent)
    {
        // Check Smart TV keywords
        if (self::isSmartTV($userAgent)) {
            return false;
        }

        //WP Desktop - Edge Mode
        if (self::checkIfContainsAll($userAgent, array('Mozilla/5.0 (Windows NT ', ' ARM;', ' Edge/'))) {
            return false;
        }

        // Chrome
        if (self::checkIfContains($userAgent, 'Chrome')
            && !self::checkIfContainsAnyOf($userAgent, array('Android', 'Ventana'))
        ) {
            return true;
        }

        // Check mobile keywords
        if (self::isMobileBrowser($userAgent)) {
            return false;
        }

        if (self::checkIfContains(
            $userAgent,
            'PPC'
        )
        ) {
            return false;
        } // PowerPC; not always mobile, but we'll kick it out

        // Firefox;  fennec is already handled in the \Wurfl\Constants::$MOBILE_BROWSERS keywords
        if (self::checkIfContains($userAgent, 'Firefox') && !self::checkIfContains($userAgent, 'Tablet')) {
            return true;
        }

        // Safari
        if (preg_match(
            '#^Mozilla/5\.0 \((?:Macintosh|Windows)[^\)]+\) AppleWebKit/[\d\.]+ \(KHTML, like Gecko\) Version/[\d\.]+ '
            . 'Safari/[\d\.]+$#',
            $userAgent
        )
        ) {
            return true;
        }

        // Opera Desktop
        if (self::checkIfStartsWithAnyOf($userAgent, array('Opera/9.80 (Windows NT', 'Opera/9.80 (Macintosh'))) {
            return true;
        }

        // Check desktop keywords
        if (self::isDesktopBrowser($userAgent)) {
            return true;
        }

        // Internet Explorer 11
        if (preg_match('/^Mozilla\/5\.0 \(Windows NT.+?Trident.+?; rv:\d\d\.\d+\)/', $userAgent)) {
            return true;
        }

        // Internet Explorer 9 or 10
        if (preg_match('/^Mozilla\/5\.0 \(compatible; MSIE (9|10)\.0; Windows NT \d\.\d/', $userAgent)) {
            return true;
        }

        // Internet Explorer <9
        if (preg_match('/^Mozilla\/4\.0 \(compatible; MSIE \d\.\d; Windows NT \d\.\d/', $userAgent)) {
            return true;
        }

        return false;
    }
907463
public function detectVersion(string $useragent): VersionInterface
    {
        if (false !== mb_stripos($useragent, 'android 2.1-update1')) {
            return (new VersionFactory())->set('2.1.1');
        }

        $search = [
            'android android',
            'android androidhouse team',
            'android wildpuzzlerom v8 froyo',
            'juc ?\(linux;',
            'linux; googletv',
            'android ouya',
            'android os',
            'andr[0o]id[;_ ]',
            'andr[0o]id\/',
            'andr[0o]id',
            'adr ',
            '\(os: ',
        ];

        $detectedVersion = (new VersionFactory())->detectVersion($useragent, $search);

        if ('0.0.0' !== $detectedVersion->getVersion()) {
            return $detectedVersion;
        }

        if (preg_match('/Linux; (\d+[\d\.]+)/', $useragent, $matches)) {
            return (new VersionFactory())->set($matches[1]);
        }

        if (false !== mb_stripos($useragent, 'gingerbread')) {
            return (new VersionFactory())->set('2.3.0');
        }

        if (false !== mb_stripos($useragent, 'android eclair')) {
            return (new VersionFactory())->set('2.1.0');
        }

        return new Version('0');
    }
536537
public static function isUserAgentMobile() {
		
		$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : '';
		
		$devices = array('phone', 'iphone', 'itouch', 'ipod', 'symbian', 'android', 'htc_', 'htc-',
				'palmos', 'blackberry', 'opera mini', 'iemobile', 'windows ce', 'nokia', 'fennec',
				'hiptop', 'kindle', 'mot ', 'mot-', 'webos\/', 'samsung', 'sonyericsson', '^sie-',
				'nintendo');
		
		if (preg_match('/' . implode('|', $devices) . '/', $user_agent)) {
			return TRUE;
		} else {
			return FALSE;
		}
		
	}
750451
private static function checkLinux(Os $os, UserAgent $userAgent)
    {
        if (stripos($userAgent->getUserAgentString(), 'Linux') !== false) {
            $os->setVersion($os::VERSION_UNKNOWN);
            $os->setName($os::LINUX);

            return true;
        }

        return false;
    }