@param string $userAgent

@return string
554494
public function normalize($userAgent)
    {
        $model = HTCMacHandler::getHTCMacModel($userAgent, false);

        if ($model !== null) {
            $prefix = $model . WurflConstants::RIS_DELIMITER;

            return $prefix . $userAgent;
        }

        return $userAgent;
    }
597464
public function normalize($userAgent)
    {
        $model = MaemoHandler::getMaemoModel($userAgent);

        if ($model !== null) {
            $prefix = 'Maemo ' . $model . WurflConstants::RIS_DELIMITER;

            return $prefix . $userAgent;
        }

        return $userAgent;
    }
639867
public function applyConclusiveMatch($userAgent)
    {
        if (Utils::checkIfContains($userAgent, 'GoogleImageProxy')) {
            return 'google_image_proxy';
        }

        if (Utils::checkIfStartsWith($userAgent, 'Mozilla')) {
            $tolerance = Utils::firstCloseParen($userAgent);
        } else {
            $tolerance = Utils::firstSlash($userAgent);
        }

        return $this->getDeviceIDFromRIS($userAgent, $tolerance);
    }
488282
protected function filterBrowserNames(array $userAgent)
    {
        // IE11 hasn't 'MSIE' in its user agent string
        if (empty($userAgent['browser_name']) && $userAgent['browser_engine'] === 'trident' && strpos($userAgent['string'], 'rv:')) {
            $userAgent['browser_name'] = 'msie';
            $userAgent['browser_version'] = preg_replace('|.+rv:([0-9]+(?:\.[0-9]+)+).+|', '$1', $userAgent['string']);

            return $userAgent;
        }

        return $userAgent;
    }
251742
public function browser($userAgent = null)
    {
        // Get browser rules
        $rules = $this->mergeRules(
            static::$additionalBrowsers, // NEW
            static::$browsers
        );

        return $this->findDetectionRulesAgainstUA($rules, $userAgent);
    }
1371908
public function normalize(string $userAgent): string
    {
        $userAgent = preg_replace('/([\d]+)EMobile/', '$1; IEMobile', $userAgent);

        $userAgent = str_replace(
            ['Macintoshntel', 'cpu=PPC=Mac'],
            ['Macintosh; Intel', 'cpu=PPC;os=Mac'],
            $userAgent
        );

        $userAgent = preg_replace('/([\\\\]+)/i', '', $userAgent);
        $userAgent = preg_replace('/Versio\//', 'Version/', $userAgent);

        $userAgent = str_replace(
            ['i686 (x86_64)', 'X11buntu', 'Chr0me'],
            ['i686 on x86_64', 'X11; Ubuntu', 'Chrome'],
            $userAgent
        );

        return $userAgent;
    }
1226234
public function applyRecoveryCatchAllMatch($userAgent)
    {
        if (Utils::isDesktopBrowserHeavyDutyAnalysis($userAgent)) {
            return WurflConstants::GENERIC_WEB_BROWSER;
        }

        if (Utils::checkIfContains($userAgent, 'CoreMedia')) {
            return 'apple_iphone_coremedia_ver1';
        }

        if (Utils::checkIfContains($userAgent, 'Windows CE')) {
            return 'generic_ms_mobile';
        }

        if (Utils::checkIfContains($userAgent, 'UP.Browser/7.2')) {
            return 'opwv_v72_generic';
        }

        if (Utils::checkIfContains($userAgent, 'UP.Browser/7')) {
            return 'opwv_v7_generic';
        }

        if (Utils::checkIfContains($userAgent, 'UP.Browser/6.2')) {
            return 'opwv_v62_generic';
        }

        if (Utils::checkIfContains($userAgent, 'UP.Browser/6')) {
            return 'opwv_v6_generic';
        }

        if (Utils::checkIfContains($userAgent, 'UP.Browser/5')) {
            return 'upgui_generic';
        }

        if (Utils::checkIfContains($userAgent, 'UP.Browser/4')) {
            return 'uptext_generic';
        }

        if (Utils::checkIfContains($userAgent, 'UP.Browser/3')) {
            return 'uptext_generic';
        }

        // Series 60
        if (Utils::checkIfContains($userAgent, 'Series60')) {
            return 'nokia_generic_series60';
        }

        // Access/Net Front
        if (Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.0', 'ACS-NF/3.0'))) {
            return 'generic_netfront_ver3';
        }

        if (Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.1', 'ACS-NF/3.1'))) {
            return 'generic_netfront_ver3_1';
        }

        if (Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.2', 'ACS-NF/3.2'))) {
            return 'generic_netfront_ver3_2';
        }

        if (Utils::checkIfContainsAnyOf($userAgent, array('NetFront/3.3', 'ACS-NF/3.3'))) {
            return 'generic_netfront_ver3_3';
        }

        if (Utils::checkIfContains($userAgent, 'NetFront/3.4')) {
            return 'generic_netfront_ver3_4';
        }

        if (Utils::checkIfContains($userAgent, 'NetFront/3.5')) {
            return 'generic_netfront_ver3_5';
        }

        if (Utils::checkIfContains($userAgent, 'NetFront/4.0')) {
            return 'generic_netfront_ver4_0';
        }

        // Contains Mozilla/, but not at the beginning of the UA
        // ie: MOTORAZR V8/R601_G_80.41.17R Mozilla/4.0 (compatible; MSIE 6.0 Linux; MOTORAZR V88.50) Profile/MIDP-2.0 Configuration/CLDC-1.1 Opera 8.50[zh]
        if (strpos($userAgent, 'Mozilla/') > 0) {
            return WurflConstants::GENERIC_XHTML;
        }

        if (Utils::checkIfContainsAnyOf(
            $userAgent,
            array('Obigo', 'AU-MIC/2', 'AU-MIC-', 'AU-OBIGO/', 'Teleca Q03B1')
        )
        ) {
            return WurflConstants::GENERIC_XHTML;
        }

        // DoCoMo
        if (Utils::checkIfStartsWithAnyOf($userAgent, array('DoCoMo', 'KDDI'))) {
            return 'docomo_generic_jap_ver1';
        }

        if (Utils::isMobileBrowser($userAgent)) {
            return WurflConstants::GENERIC_MOBILE;
        }

        return WurflConstants::GENERIC;
    }
1021165
public function applyConclusiveMatch($userAgent)
    {
        //High accuracy mode
        $tolerance = Utils::firstCloseParen($userAgent);

        return $this->getDeviceIDFromRIS($userAgent, $tolerance);
    }
427679
public function applyConclusiveMatch($userAgent)
    {
        $tolerance = Utils::toleranceToRisDelimeter($userAgent);
        if ($tolerance !== false) {
            return $this->getDeviceIDFromRIS($userAgent, $tolerance);
        }

        return WurflConstants::NO_MATCH;
    }
1197156
public function applyConclusiveMatch($userAgent)
    {
        $find      = 'NetFrontLifeBrowser/2.2';
        $tolerance = strpos($userAgent, $find) + strlen($find);

        if ($tolerance > strlen($userAgent)) {
            $tolerance = strlen($userAgent);
        }

        return $this->getDeviceIDFromRIS($userAgent, $tolerance);
    }
414384
public function normalize($userAgent)
    {

        //Match a CFNetwork UA
        if (preg_match('#CFNetwork/(\d+\.?[0-9]*)#', $userAgent, $matches)) {
            $cfNetworkVersion = sprintf('%.2f', round($matches[1], 2, PHP_ROUND_HALF_DOWN));

            return 'CFNetwork/' . $cfNetworkVersion . ' ' . $userAgent;
        }

        return $userAgent;
    }
313882
public function userAgent($useragent) {

		if(false === is_string($useragent)) {
            return trigger_error(sprintf('Argument 1 passed to %s() must be of the type string, "%s" given', __METHOD__, gettype($useragent)), E_USER_ERROR);
        }

		$this -> options[CURLOPT_USERAGENT] = $useragent;

		return $this;
	}
833889
public function applyRecoveryMatch($userAgent)
    {
        foreach (self::$constantIDs as $keyword => $deviceId) {
            if (Utils::checkIfContains($userAgent, $keyword)) {
                return $deviceId;
            }
        }

        if (Utils::checkIfContains($userAgent, 'Opera Mobi')) {
            return 'generic_opera_mini_version4';
        }

        return 'generic_opera_mini_version1';
    }
448366
public function normalize($userAgent)
    {
        $index = strpos($userAgent, 'UP.Link');

        if ($index !== false) {
            return substr($userAgent, 0, $index);
        }

        return $userAgent;
    }
994628
public function getBrowser(string $userAgent) : array
    {
        // Init variables
        $browserId = $this->getBrowserId($userAgent);
        $browserParentId = $this->getBrowserParentId($userAgent);

        // Get all settings for the found browser
        //
        // It's best to use a recursive query here, but some linux distributions like CentOS and RHEL
        // use old sqlite library versions (like 3.6.20 or 3.7.17), so that we have to check the
        // version here and fall back to multiple single queries in case of older versions.
        if (version_compare($this->getSqliteVersion(), '3.8.3', '>=')) {
            $query  = 'SELECT t3.property_key, t4.property_value FROM (';
            $query .= 'WITH RECURSIVE browser_recursive(browser_id,browser_parent_id) AS (';
            $query .= 'SELECT browser_id, browser_parent_id FROM browser WHERE browser_id = :id';
            $query .= ' UNION ALL ';
            $query .= 'SELECT browser.browser_id, browser.browser_parent_id FROM browser, browser_recursive ';
            $query .= 'WHERE browser_recursive.browser_parent_id IS NOT NULL ';
            $query .= 'AND browser.browser_id = browser_recursive.browser_parent_id';
            $query .= ') ';
            $query .= 'SELECT MAX(t2.browser_id) AS browser_id, t2.property_key_id FROM browser_recursive t1 ';
            $query .= 'JOIN browser_property t2 ON t2.browser_id = t1.browser_id ';
            $query .= 'GROUP BY t2.property_key_id';
            $query .= ') t1 ';
            $query .= 'JOIN browser_property t2 ON t2.browser_id = t1.browser_id ';
            $query .= 'AND t2.property_key_id = t1.property_key_id ';
            $query .= 'JOIN browser_property_key t3 ON t3.property_key_id = t2.property_key_id ';
            $query .= 'JOIN browser_property_value t4 ON t4.property_value_id = t2.property_value_id';
            $query .= ' UNION ALL ';
            $query .= 'SELECT \'browser_name_pattern\' AS property_key, browser_pattern AS property_value ';
            $query .= 'FROM browser WHERE browser_id = :id';
            $query .= ' UNION ALL ';
            $query .= 'SELECT \'Parent\' AS property_key, browser_pattern AS property_value ';
            $query .= 'FROM browser WHERE browser_id = :parent';
            $statement = $this->getAdapter()->prepare($query);
        } else {
            $query = 'SELECT browser_id, browser_parent_id FROM browser WHERE browser_id = :id';
            $statement = $this->getAdapter()->prepare($query);
            $browserIds = [];
            $lastBrowserId = $browserId;
            while ($lastBrowserId !== null) {
                $result = $statement->execute(['id' => $lastBrowserId]);

                $lastBrowserId = null;
                if (count($result) > 0) {
                    $browserIds[] = (int)$result[0]['browser_id'];
                    if ($result[0]['browser_parent_id'] !== null) {
                        $lastBrowserId = (int)$result[0]['browser_parent_id'];
                    }
                }
            }

            $query  = 'SELECT t3.property_key, t4.property_value FROM (';
            $query .= 'SELECT MAX(browser_id) AS browser_id, property_key_id ';
            $query .= 'FROM browser_property WHERE browser_id IN (' . implode(', ', $browserIds) . ') ';
            $query .= 'GROUP BY property_key_id';
            $query .= ') t1 ';
            $query .= 'JOIN browser_property t2 ON t2.browser_id = t1.browser_id ';
            $query .= 'AND t2.property_key_id = t1.property_key_id ';
            $query .= 'JOIN browser_property_key t3 ON t3.property_key_id = t2.property_key_id ';
            $query .= 'JOIN browser_property_value t4 ON t4.property_value_id = t2.property_value_id';
            $query .= ' UNION ALL ';
            $query .= 'SELECT \'browser_name_pattern\' AS property_key, browser_pattern AS property_value ';
            $query .= 'FROM browser WHERE browser_id = :id';
            $query .= ' UNION ALL ';
            $query .= 'SELECT \'Parent\' AS property_key, browser_pattern AS property_value ';
            $query .= 'FROM browser WHERE browser_id = :parent';
            $statement = $this->getAdapter()->prepare($query);
        }

        $properties = [];
        foreach ($statement->execute(['id' => $browserId, 'parent' => $browserParentId]) as $row) {
            $properties[$row['property_key']] = $row['property_value'];
        }

        // Set regular expression properties
        $propertyFilter = $this->getPropertyFilter();
        if (!$propertyFilter->isFiltered('browser_name_regex')) {
            $properties['browser_name_regex'] = $this->getRegExpForPattern($properties['browser_name_pattern']);
        }
        if ($propertyFilter->isFiltered('browser_name_pattern')) {
            unset($properties['browser_name_pattern']);
        }
        if ($propertyFilter->isFiltered('Parent')) {
            unset($properties['Parent']);
        }

        // IMPORTANT: Reset browserId and browserParentId for next call
        $this->browserId = null;
        $this->browserParentId = null;

        // The settings are in random order, so sort them
        return $this->sortProperties($properties);
    }
648462
public function applyExactMatch($userAgent)
    {
        if (array_key_exists($userAgent, $this->userAgentsWithDeviceID)) {
            return $this->userAgentsWithDeviceID[$userAgent];
        }

        return WurflConstants::NO_MATCH;
    }
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;
    }