diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php
index a1a96451475..866a83884a8 100644
--- a/auth/ldap/auth.php
+++ b/auth/ldap/auth.php
@@ -1646,8 +1646,7 @@ class auth_plugin_ldap extends auth_plugin_base {
             // Now start the whole NTLM machinery.
             if($this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESATTEMPT ||
                 $this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESFORM) {
-
-                if(check_browser_version('MSIE')) {
+                if (core_useragent::check_ie_version()) {
                     $sesskey = sesskey();
                     redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_magic.php?sesskey='.$sesskey);
                 } else if ($this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESFORM) {
diff --git a/auth/ldap/ntlmsso_magic.php b/auth/ldap/ntlmsso_magic.php
index 0d349c5eef9..2ac49a3022b 100644
--- a/auth/ldap/ntlmsso_magic.php
+++ b/auth/ldap/ntlmsso_magic.php
@@ -28,7 +28,7 @@ $file = $CFG->dirroot.'/pix/spacer.gif';
 
 if ($authplugin->ntlmsso_magic($sesskey) && file_exists($file)) {
     if (!empty($authplugin->config->ntlmsso_ie_fastpath)) {
-        if (check_browser_version('MSIE')) {
+        if (core_useragent::check_ie_version()) {
             // $PAGE->https_required() up above takes care of what $CFG->httpswwwroot should be.
             redirect($CFG->httpswwwroot.'/auth/ldap/ntlmsso_finish.php');
         }
diff --git a/course/view.php b/course/view.php
index cf3748a4c0d..5430b6c1f3e 100644
--- a/course/view.php
+++ b/course/view.php
@@ -219,8 +219,10 @@
         redirect($CFG->wwwroot .'/');
     }
 
+    $ajaxenabled = ajaxenabled();
+
     $completion = new completion_info($course);
-    if ($completion->is_enabled() && ajaxenabled()) {
+    if ($completion->is_enabled() && $ajaxenabled) {
         $PAGE->requires->string_for_js('completion-title-manual-y', 'completion');
         $PAGE->requires->string_for_js('completion-title-manual-n', 'completion');
         $PAGE->requires->string_for_js('completion-alt-manual-y', 'completion');
@@ -241,7 +243,7 @@
     $PAGE->set_heading($course->fullname);
     echo $OUTPUT->header();
 
-    if ($completion->is_enabled() && ajaxenabled()) {
+    if ($completion->is_enabled() && $ajaxenabled) {
         // This value tracks whether there has been a dynamic change to the page.
         // It is used so that if a user does this - (a) set some tickmarks, (b)
         // go to another page, (c) clicks Back button - the page will
diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php
index 1c6fd33913a..2e18c8cadd8 100644
--- a/grade/report/grader/lib.php
+++ b/grade/report/grader/lib.php
@@ -1582,15 +1582,15 @@ class grade_report_grader extends grade_report {
      * @return bool
      */
     public function is_fixed_students() {
-        global $USER, $CFG;
+        global $CFG;
         return $CFG->grade_report_fixedstudents &&
-            (check_browser_version('MSIE', '7.0') ||
-             check_browser_version('Firefox', '2.0') ||
-             check_browser_version('Gecko', '2006010100') ||
-             check_browser_version('Camino', '1.0') ||
-             check_browser_version('Opera', '6.0') ||
-             check_browser_version('Chrome', '6') ||
-             check_browser_version('Safari', '300'));
+            (core_useragent::check_ie_version('7.0') ||
+             core_useragent::check_firefox_version('2.0') ||
+             core_useragent::check_gecko_version('2006010100') ||
+             core_useragent::check_camino_version('1.0') ||
+             core_useragent::check_opera_version('6.0') ||
+             core_useragent::check_chrome_version('6') ||
+             core_useragent::check_safari_version('300'));
     }
 
     /**
diff --git a/group/index.php b/group/index.php
index ffd8f742f12..15116190e2c 100644
--- a/group/index.php
+++ b/group/index.php
@@ -152,7 +152,8 @@ $currenttab = 'groups';
 require('tabs.php');
 
 $disabled = 'disabled="disabled"';
-if (ajaxenabled()) {
+$ajaxenabled = ajaxenabled();
+if ($ajaxenabled) {
     // Some buttons are enabled if single group selected
     $showaddmembersform_disabled = $singlegroup ? '' : $disabled;
     $showeditgroupsettingsform_disabled = $singlegroup ? '' : $disabled;
@@ -178,7 +179,7 @@ echo '<tr>'."\n";
 echo "<td>\n";
 echo '<p><label for="groups"><span id="groupslabel">'.get_string('groups').':</span><span id="thegrouping">&nbsp;</span></label></p>'."\n";
 
-if (ajaxenabled()) { // TODO: move this to JS init!
+if ($ajaxenabled) { // TODO: move this to JS init!
     $onchange = 'M.core_group.membersCombo.refreshMembers();';
 } else {
     $onchange = '';
@@ -275,7 +276,7 @@ echo '</table>'."\n";
 echo '</div>'."\n";
 echo '</form>'."\n";
 
-if (ajaxenabled()) {
+if ($ajaxenabled) {
     $PAGE->requires->js_init_call('M.core_group.init_index', array($CFG->wwwroot, $courseid));
     $PAGE->requires->js_init_call('M.core_group.groupslist', array($preventgroupremoval));
 }
diff --git a/lib/ajax/tests/ajaxlib_test.php b/lib/ajax/tests/ajaxlib_test.php
deleted file mode 100644
index f8096f0f95e..00000000000
--- a/lib/ajax/tests/ajaxlib_test.php
+++ /dev/null
@@ -1,130 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Unit tests for (some of) ../ajaxlib.php.
- *
- * @package   core
- * @category  phpunit
- * @copyright 2009 Tim Hunt
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-global $CFG;
-require_once($CFG->libdir . '/ajax/ajaxlib.php');
-
-
-/**
- * Unit tests for ../ajaxlib.php functions.
- *
- * @copyright 2008 Tim Hunt
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class core_ajaxlib_testcase extends advanced_testcase {
-
-    var $user_agents = array(
-        'MSIE' => array(
-            '5.5' => array('Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'),
-            '6.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'),
-            '7.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)')
-        ),
-        'Firefox' => array(
-            '1.0.6'   => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'),
-            '1.5'     => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'),
-            '1.5.0.1' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'),
-            '2.0'     => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1',
-                'Ubuntu Linux AMD64' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)')
-        ),
-        'Safari' => array(
-            '312' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312'),
-            '2.0' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412')
-        ),
-        'Opera' => array(
-            '8.51' => array('Windows XP' => 'Opera/8.51 (Windows NT 5.1; U; en)'),
-            '9.0'  => array('Windows XP' => 'Opera/9.0 (Windows NT 5.1; U; en)',
-                'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)')
-        )
-    );
-
-    /**
-     * Uses the array of user agents to test ajax_lib::ajaxenabled
-     */
-    function test_ajaxenabled() {
-        global $CFG;
-
-        $this->resetAfterTest(true);
-
-        $CFG->enableajax = 1;
-
-        // Should be true
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
-        $this->assertTrue(ajaxenabled());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.5']['Windows XP'];
-        $this->assertTrue(ajaxenabled());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X'];
-        $this->assertTrue(ajaxenabled());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
-        $this->assertTrue(ajaxenabled());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2'];
-        $this->assertTrue(ajaxenabled());
-
-        // Should be false
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.0.6']['Windows XP'];
-        $this->assertFalse(ajaxenabled());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['312']['Mac OS X'];
-        $this->assertFalse(ajaxenabled());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['8.51']['Windows XP'];
-        $this->assertFalse(ajaxenabled());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['5.5']['Windows 2000'];
-        $this->assertFalse(ajaxenabled());
-
-        // Test array of tested browsers
-        $tested_browsers = array('MSIE' => 6.0, 'Gecko' => 20061111);
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
-        $this->assertTrue(ajaxenabled($tested_browsers));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2'];
-        $this->assertTrue(ajaxenabled($tested_browsers));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X'];
-        $this->assertFalse(ajaxenabled($tested_browsers));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
-        $this->assertFalse(ajaxenabled($tested_browsers));
-
-        $tested_browsers = array('Safari' => 412, 'Opera' => 9.0);
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
-        $this->assertFalse(ajaxenabled($tested_browsers));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2'];
-        $this->assertFalse(ajaxenabled($tested_browsers));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['2.0']['Mac OS X'];
-        $this->assertTrue(ajaxenabled($tested_browsers));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
-        $this->assertTrue(ajaxenabled($tested_browsers));
-    }
-}
diff --git a/lib/classes/useragent.php b/lib/classes/useragent.php
new file mode 100644
index 00000000000..95a6958cb31
--- /dev/null
+++ b/lib/classes/useragent.php
@@ -0,0 +1,760 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Environment class to aid with the detection and establishment of the working environment.
+ *
+ * @package    core
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * The user agent class.
+ *
+ * It's important to note that we do not like browser sniffing and its use in core code is highly discouraged.
+ * No new uses of this API will be integrated unless there is absolutely no alternative.
+ *
+ * This API supports the few browser checks we do have in core, all of which one day will hopefully be removed.
+ * The API will remain to support any third party use out there, however at some point like all code it will be deprecated.
+ *
+ * Use sparingly and only with good cause!
+ *
+ * @package    core
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_useragent {
+
+    /**
+     * The default for devices, think of as a computer.
+     */
+    const DEVICETYPE_DEFAULT = 'default';
+    /**
+     * Legacy devices, or at least legacy browsers. These are older devices/browsers
+     * that don't support standards.
+     */
+    const DEVICETYPE_LEGACY = 'legacy';
+    /**
+     * Mobile devices like your cell phone or hand held gaming device.
+     */
+    const DEVICETYPE_MOBILE = 'mobile';
+    /**
+     * Tables, larger than hand held, but still easily portable and smaller than a laptop.
+     */
+    const DEVICETYPE_TABLET = 'tablet';
+
+    /**
+     * An instance of this class.
+     * @var core_useragent
+     */
+    protected static $instance = null;
+
+    /**
+     * The device types we track.
+     * @var array
+     */
+    public static $devicetypes = array(
+        self::DEVICETYPE_DEFAULT,
+        self::DEVICETYPE_LEGACY,
+        self::DEVICETYPE_MOBILE,
+        self::DEVICETYPE_TABLET
+    );
+
+    /**
+     * The current requests user agent string if there was one.
+     * @var string|bool|null Null until initialised, false if none available, or string when available.
+     */
+    protected $useragent = null;
+
+    /**
+     * The users device type, one of self::DEVICETYPE_*.
+     * @var string null until initialised
+     */
+    protected $devicetype = null;
+
+    /**
+     * Custom device types entered into the admin interface.
+     * @var array
+     */
+    protected $devicetypecustoms = array();
+
+    /**
+     * True if the user agent supports ajax. False if not.
+     * @var bool|null Null until initialised, then true or false.
+     */
+    protected $supportsajax = null;
+
+    /**
+     * True if the user agent supports the display of svg images. False if not.
+     * @var bool|null Null until initialised, then true or false.
+     */
+    protected $supportssvg = null;
+
+    /**
+     * Get an instance of the user agent object.
+     *
+     * @param bool $reload If set to true the user agent will be reset and all ascertations remade.
+     * @param string $forceuseragent The string to force as the user agent, don't use unless absolutely unavoidable.
+     * @return core_useragent
+     */
+    public static function instance($reload = false, $forceuseragent = null) {
+        if (!self::$instance || $reload) {
+            self::$instance = new core_useragent($forceuseragent);
+        }
+        return self::$instance;
+    }
+
+    /**
+     * Constructs a new user agent object. Publically you must use the instance method above.
+     *
+     * @param string|null $forceuseragent Optional a user agent to force.
+     */
+    protected function __construct($forceuseragent = null) {
+        global $CFG;
+        if (!empty($CFG->devicedetectregex)) {
+            $this->devicetypecustoms = json_decode($CFG->devicedetectregex);
+        }
+        if ($forceuseragent !== null) {
+            $this->useragent = $forceuseragent;
+        } else if (!empty($_SERVER['HTTP_USER_AGENT'])) {
+            $this->useragent = $_SERVER['HTTP_USER_AGENT'];
+        } else {
+            $this->useragent = false;
+            $this->devicetype = self::DEVICETYPE_DEFAULT;
+        }
+        if (empty($CFG->enableajax)) {
+            $this->supportsajax = false;
+        }
+    }
+
+    /**
+     * Returns the user agent string.
+     * @return bool|string The user agent string or false if one isn't available.
+     */
+    public static function get_user_agent_string() {
+        $instance = self::instance();
+        return $instance->useragent;
+    }
+
+    /**
+     * Returns the device type we believe is being used.
+     * @return string
+     */
+    public static function get_device_type() {
+        $instance = self::instance();
+        if ($instance->devicetype === null) {
+            return $instance->guess_device_type();
+        }
+        return $instance->devicetype;
+    }
+
+    /**
+     * Guesses the device type the user agent is running on.
+     *
+     * @return string
+     */
+    protected function guess_device_type() {
+        global $CFG;
+        if (empty($CFG->enabledevicedetection)) {
+            $this->devicetype = self::DEVICETYPE_DEFAULT;
+            return $this->devicetype;
+        }
+        foreach ($this->devicetypecustoms as $value => $regex) {
+            if (preg_match($regex, $this->useragent)) {
+                $this->devicetype = $value;
+                return $this->devicetype;
+            }
+        }
+        if ($this->is_useragent_mobile()) {
+            $this->devicetype = 'mobile';
+        } else if ($this->is_useragent_tablet()) {
+            $this->devicetype = 'tablet';
+        } else if (substr($this->useragent, 0, 34) === 'Mozilla/4.0 (compatible; MSIE 6.0;') {
+            // Safe way to check for IE6 and not get false positives for some IE 7/8 users.
+            $this->devicetype = 'legacy';
+        } else {
+            $this->devicetype = self::DEVICETYPE_DEFAULT;
+        }
+        return $this->devicetype;
+    }
+
+    /**
+     * Returns true if the user appears to be on a mobile device.
+     * @return bool
+     */
+    protected function is_useragent_mobile() {
+        // Mobile detection PHP direct copy from open source detectmobilebrowser.com.
+        $phonesregex = '/android .+ mobile|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i';
+        $modelsregex = '/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i';
+        return (preg_match($phonesregex, $this->useragent) || preg_match($modelsregex, substr($this->useragent, 0, 4)));
+    }
+
+    /**
+     * Returns true if the user appears to be on a tablet.
+     * @return int
+     */
+    protected function is_useragent_tablet() {
+        $tabletregex = '/Tablet browser|android|iPad|iProd|GT-P1000|GT-I9000|SHW-M180S|SGH-T849|SCH-I800|Build\/ERE27|sholest/i';
+        return (preg_match($tabletregex, $this->useragent));
+    }
+
+    /**
+     * Gets a list of known device types.
+     *
+     * @param bool $includecustomtypes If set to true we'll include types that have been added by the admin.
+     * @return array
+     */
+    public static function get_device_type_list($includecustomtypes = true) {
+        $types = self::$devicetypes;
+        if ($includecustomtypes) {
+            $instance = self::instance();
+            $types = array_merge($types, array_keys($instance->devicetypecustoms));
+        }
+        return $types;
+    }
+
+    /**
+     * Returns the theme to use for the given device type.
+     *
+     * This used to be get_selected_theme_for_device_type.
+     * @param null|string $devicetype The device type to find out for. Defaults to the device the user is using,
+     * @return bool
+     */
+    public static function get_device_type_theme($devicetype = null) {
+        global $CFG;
+        if ($devicetype === null) {
+            $devicetype = self::get_device_type();
+        }
+        $themevarname = self::get_device_type_cfg_var_name($devicetype);
+        if (empty($CFG->$themevarname)) {
+            return false;
+        }
+        return $CFG->$themevarname;
+    }
+
+    /**
+     * Returns the CFG var used to find the theme to use for the given device.
+     *
+     * Used to be get_device_cfg_var_name.
+     *
+     * @param null|string $devicetype The device type to find out for. Defaults to the device the user is using,
+     * @return string
+     */
+    public static function get_device_type_cfg_var_name($devicetype = null) {
+        if ($devicetype == self::DEVICETYPE_DEFAULT || empty($devicetype)) {
+            return 'theme';
+        }
+        return 'theme' . $devicetype;
+    }
+
+    /**
+     * Gets the device type the user is currently using.
+     * @return string
+     */
+    public static function get_user_device_type() {
+        $device = self::get_device_type();
+        $switched = get_user_preferences('switchdevice'.$device, false);
+        if ($switched != false) {
+            return $switched;
+        }
+        return $device;
+    }
+
+    /**
+     * Switches the device type we think the user is using to what ever was given.
+     * @param string $newdevice
+     * @return bool
+     * @throws coding_exception
+     */
+    public static function set_user_device_type($newdevice) {
+        $devicetype = self::get_device_type();
+        if ($newdevice == $devicetype) {
+            unset_user_preference('switchdevice'.$devicetype);
+            return true;
+        } else {
+            $devicetypes = self::get_device_type_list();
+            if (in_array($newdevice, $devicetypes)) {
+                set_user_preference('switchdevice'.$devicetype, $newdevice);
+                return true;
+            }
+        }
+        throw new coding_exception('Invalid device type provided to set_user_device_type');
+    }
+
+    /**
+     * Returns true if the user agent matches the given brand and the version is equal to or greater than that specified.
+     *
+     * @param string $brand The branch to check for.
+     * @param scalar $version The version if we need to find out if it is equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_browser_version($brand, $version = null) {
+        switch ($brand) {
+
+            case 'MSIE':
+                // Internet Explorer.
+                return self::check_ie_version($version);
+
+            case 'Firefox':
+                // Mozilla Firefox browsers.
+                return self::check_firefox_version($version);
+
+            case 'Chrome':
+                return self::check_chrome_version($version);
+
+            case 'Opera':
+                // Opera.
+                return self::check_opera_version($version);
+
+            case 'Safari':
+                // Desktop version of Apple Safari browser - no mobile or touch devices.
+                return self::check_safari_version($version);
+
+            case 'Safari iOS':
+                // Safari on iPhone, iPad and iPod touch.
+                return self::check_safari_ios_version($version);
+
+            case 'WebKit':
+                // WebKit based browser - everything derived from it (Safari, Chrome, iOS, Android and other mobiles).
+                return self::check_webkit_version($version);
+
+            case 'Gecko':
+                // Gecko based browsers.
+                return self::check_gecko_version($version);
+
+            case 'WebKit Android':
+                // WebKit browser on Android.
+                return self::check_webkit_android_version($version);
+
+            case 'Camino':
+                // OSX browser using Gecke engine.
+                return self::check_camino_version($version);
+        }
+        // Who knows?! doesn't pass anyway.
+        return false;
+    }
+
+    /**
+     * Checks the user agent is camino based and that the version is equal to or greater than that specified.
+     *
+     * Camino browser is at the end of its life, its no longer being developed or supported, just don't worry about it.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    protected static function check_camino_version($version = null) {
+        // OSX browser using Gecko engine.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'Camino') === false) {
+            return false;
+        }
+        if (empty($version)) {
+            return true; // No version specified.
+        }
+        if (preg_match("/Camino\/([0-9\.]+)/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is Firefox based and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_firefox_version($version = null) {
+        // Mozilla Firefox browsers.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'Firefox') === false && strpos($useragent, 'Iceweasel') === false) {
+            return false;
+        }
+        if (empty($version)) {
+            return true; // No version specified..
+        }
+        if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $useragent, $match)) {
+            if (version_compare($match[2], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is Gecko based and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_gecko_version($version = null) {
+        // Gecko based browsers.
+        // Do not look for dates any more, we expect real Firefox version here.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (empty($version)) {
+            $version = 1;
+        } else if ($version > 20000000) {
+            // This is just a guess, it is not supposed to be 100% accurate!
+            if (preg_match('/^201/', $version)) {
+                $version = 3.6;
+            } else if (preg_match('/^200[7-9]/', $version)) {
+                $version = 3;
+            } else if (preg_match('/^2006/', $version)) {
+                $version = 2;
+            } else {
+                $version = 1.5;
+            }
+        }
+        if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $useragent, $match)) {
+            // Use real Firefox version if specified in user agent string.
+            if (version_compare($match[2], $version) >= 0) {
+                return true;
+            }
+        } else if (preg_match("/Gecko\/([0-9\.]+)/i", $useragent, $match)) {
+            // Gecko might contain date or Firefox revision, let's just guess the Firefox version from the date.
+            $browserver = $match[1];
+            if ($browserver > 20000000) {
+                // This is just a guess, it is not supposed to be 100% accurate!
+                if (preg_match('/^201/', $browserver)) {
+                    $browserver = 3.6;
+                } else if (preg_match('/^200[7-9]/', $browserver)) {
+                    $browserver = 3;
+                } else if (preg_match('/^2006/', $version)) {
+                    $browserver = 2;
+                } else {
+                    $browserver = 1.5;
+                }
+            }
+            if (version_compare($browserver, $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is IE and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_ie_version($version = null) {
+        // Internet Explorer.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'Opera') !== false) {
+            // Reject Opera.
+            return false;
+        }
+        // In case of IE we have to deal with BC of the version parameter.
+        if (is_null($version)) {
+            $version = 5.5; // Anything older is not considered a browser at all!
+        }
+        // IE uses simple versions, let's cast it to float to simplify the logic here.
+        $version = round($version, 1);
+        // See: http://www.useragentstring.com/pages/Internet%20Explorer/.
+        if (preg_match("/MSIE ([0-9\.]+)/", $useragent, $match)) {
+            $browser = $match[1];
+        } else {
+            return false;
+        }
+        // IE8 and later versions may pretend to be IE7 for intranet sites, use Trident version instead,
+        // the Trident should always describe the capabilities of IE in any emulation mode.
+        if ($browser === '7.0' and preg_match("/Trident\/([0-9\.]+)/", $useragent, $match)) {
+            $browser = $match[1] + 4; // NOTE: Hopefully this will work also for future IE versions.
+        }
+        $browser = round($browser, 1);
+        return ($browser >= $version);
+    }
+
+    /**
+     * Checks the user agent is Opera and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_opera_version($version = null) {
+        // Opera.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'Opera') === false) {
+            return false;
+        }
+        if (empty($version)) {
+            return true; // No version specified.
+        }
+        // Recent Opera useragents have Version/ with the actual version, e.g.:
+        // Opera/9.80 (Windows NT 6.1; WOW64; U; en) Presto/2.10.289 Version/12.01
+        // That's Opera 12.01, not 9.8.
+        if (preg_match("/Version\/([0-9\.]+)/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        } else if (preg_match("/Opera\/([0-9\.]+)/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is Webkit based and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_webkit_version($version = null) {
+        // WebKit based browser - everything derived from it (Safari, Chrome, iOS, Android and other mobiles).
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'AppleWebKit') === false) {
+            return false;
+        }
+        if (empty($version)) {
+            return true; // No version specified.
+        }
+        if (preg_match("/AppleWebKit\/([0-9.]+)/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is Safari based and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_safari_version($version = null) {
+        // Desktop version of Apple Safari browser - no mobile or touch devices.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'AppleWebKit') === false) {
+            return false;
+        }
+        // Look for AppleWebKit, excluding strings with OmniWeb, Shiira and SymbianOS and any other mobile devices.
+        if (strpos($useragent, 'OmniWeb')) {
+            // Reject OmniWeb.
+            return false;
+        }
+        if (strpos($useragent, 'Shiira')) {
+            // Reject Shiira.
+            return false;
+        }
+        if (strpos($useragent, 'SymbianOS')) {
+            // Reject SymbianOS.
+            return false;
+        }
+        if (strpos($useragent, 'Android')) {
+            // Reject Androids too.
+            return false;
+        }
+        if (strpos($useragent, 'iPhone') or strpos($useragent, 'iPad') or strpos($useragent, 'iPod')) {
+            // No Apple mobile devices here - editor does not work, course ajax is not touch compatible, etc.
+            return false;
+        }
+        if (strpos($useragent, 'Chrome')) { // Reject chrome browsers - it needs to be tested explicitly.
+            return false;
+        }
+
+        if (empty($version)) {
+            return true; // No version specified.
+        }
+        if (preg_match("/AppleWebKit\/([0-9.]+)/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is Chrome based and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_chrome_version($version = null) {
+        // Chrome.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'Chrome') === false) {
+            return false;
+        }
+        if (empty($version)) {
+            return true; // No version specified.
+        }
+        if (preg_match("/Chrome\/(.*)[ ]+/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is Webkit based and on Android and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_webkit_android_version($version = null) {
+        // WebKit browser on Android.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'Linux; U; Android') === false) {
+            return false;
+        }
+        if (empty($version)) {
+            return true; // No version specified.
+        }
+        if (preg_match("/AppleWebKit\/([0-9]+)/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks the user agent is Safari on iOS and that the version is equal to or greater than that specified.
+     *
+     * @param string|int $version A version to check for, returns true if its equal to or greater than that specified.
+     * @return bool
+     */
+    public static function check_safari_ios_version($version = null) {
+        // Safari on iPhone, iPad and iPod touch.
+        $useragent = self::get_user_agent_string();
+        if ($useragent === false) {
+            return false;
+        }
+        if (strpos($useragent, 'AppleWebKit') === false or strpos($useragent, 'Safari') === false) {
+            return false;
+        }
+        if (!strpos($useragent, 'iPhone') and !strpos($useragent, 'iPad') and !strpos($useragent, 'iPod')) {
+            return false;
+        }
+        if (empty($version)) {
+            return true; // No version specified.
+        }
+        if (preg_match("/AppleWebKit\/([0-9]+)/i", $useragent, $match)) {
+            if (version_compare($match[1], $version) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check if the user agent matches a given brand.
+     *
+     * Known brand: 'Windows','Linux','Macintosh','SGI','SunOS','HP-UX'
+     *
+     * @param string $brand
+     * @return bool
+     */
+    public static function check_browser_operating_system($brand) {
+        $useragent = self::get_user_agent_string();
+        return ($useragent !== false && preg_match("/$brand/i", $useragent));
+    }
+
+    /**
+     * Gets an array of CSS classes to represent the user agent.
+     * @return array
+     */
+    public static function get_browser_version_classes() {
+        $classes = array();
+        if (self::check_ie_version('0')) {
+            $classes[] = 'ie';
+            for ($i = 12; $i >= 6; $i--) {
+                if (self::check_ie_version($i)) {
+                    $classes[] = 'ie'.$i;
+                    break;
+                }
+            }
+        } else if (self::check_firefox_version() || self::check_gecko_version() || self::check_camino_version()) {
+            $classes[] = 'gecko';
+            if (preg_match('/rv\:([1-2])\.([0-9])/', self::get_user_agent_string(), $matches)) {
+                $classes[] = "gecko{$matches[1]}{$matches[2]}";
+            }
+        } else if (self::check_webkit_version()) {
+            $classes[] = 'safari';
+            if (self::check_safari_ios_version()) {
+                $classes[] = 'ios';
+            } else if (self::check_webkit_android_version()) {
+                $classes[] = 'android';
+            }
+        } else if (self::check_opera_version()) {
+            $classes[] = 'opera';
+        }
+        return $classes;
+    }
+
+    /**
+     * Returns true if the user agent supports the display of SVG images.
+     *
+     * @return bool
+     */
+    public static function supports_svg() {
+        // IE 5 - 8 don't support SVG at all.
+        $instance = self::instance();
+        if ($instance->supportssvg === null) {
+            if ($instance->useragent === false) {
+                // Can't be sure, just say no.
+                $instance->supportssvg = false;
+            } else if (self::check_ie_version() and !self::check_ie_version('9')) {
+                // IE < 9 doesn't support SVG. Say no.
+                $instance->supportssvg = false;
+            } else if (preg_match('#Android +[0-2]\.#', $instance->useragent)) {
+                // Android < 3 doesn't support SVG. Say no.
+                $instance->supportssvg = false;
+            } else if (self::check_opera_version()) {
+                // Opera 12 still does not support SVG well enough. Say no.
+                $instance->supportssvg = false;
+            } else {
+                // Presumed fine.
+                $instance->supportssvg = true;
+            }
+        }
+        return $instance->supportssvg;
+    }
+}
\ No newline at end of file
diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php
index 863480a6d1b..c5b65015ab9 100644
--- a/lib/deprecatedlib.php
+++ b/lib/deprecatedlib.php
@@ -4419,3 +4419,117 @@ function get_plugin_list_with_file($plugintype, $file, $include = false) {
         DEBUG_DEVELOPER);
     return core_component::get_plugin_list_with_file($plugintype, $file, $include);
 }
+
+/**
+ * Checks to see if is the browser operating system matches the specified brand.
+ *
+ * Known brand: 'Windows','Linux','Macintosh','SGI','SunOS','HP-UX'
+ *
+ * @deprecated since 2.6
+ * @param string $brand The operating system identifier being tested
+ * @return bool true if the given brand below to the detected operating system
+ */
+function check_browser_operating_system($brand) {
+    debugging('check_browser_operating_system has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::check_browser_operating_system($brand);
+}
+
+/**
+ * Checks to see if is a browser matches the specified
+ * brand and is equal or better version.
+ *
+ * @deprecated since 2.6
+ * @param string $brand The browser identifier being tested
+ * @param int $version The version of the browser, if not specified any version (except 5.5 for IE for BC reasons)
+ * @return bool true if the given version is below that of the detected browser
+ */
+function check_browser_version($brand, $version = null) {
+    debugging('check_browser_version has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::check_browser_version($brand, $version);
+}
+
+/**
+ * Returns whether a device/browser combination is mobile, tablet, legacy, default or the result of
+ * an optional admin specified regular expression.  If enabledevicedetection is set to no or not set
+ * it returns default
+ *
+ * @deprecated since 2.6
+ * @return string device type
+ */
+function get_device_type() {
+    debugging('get_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::get_device_type();
+}
+
+/**
+ * Returns a list of the device types supporting by Moodle
+ *
+ * @deprecated since 2.6
+ * @param boolean $incusertypes includes types specified using the devicedetectregex admin setting
+ * @return array $types
+ */
+function get_device_type_list($incusertypes = true) {
+    debugging('get_device_type_list has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::get_device_type_list($incusertypes);
+}
+
+/**
+ * Returns the theme selected for a particular device or false if none selected.
+ *
+ * @deprecated since 2.6
+ * @param string $devicetype
+ * @return string|false The name of the theme to use for the device or the false if not set
+ */
+function get_selected_theme_for_device_type($devicetype = null) {
+    debugging('get_selected_theme_for_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::get_device_type_theme($devicetype);
+}
+
+/**
+ * Returns the name of the device type theme var in $CFG because there is not a convention to allow backwards compatibility.
+ *
+ * @deprecated since 2.6
+ * @param string $devicetype
+ * @return string The config variable to use to determine the theme
+ */
+function get_device_cfg_var_name($devicetype = null) {
+    debugging('get_device_cfg_var_name has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::get_device_type_cfg_var_name($devicetype);
+}
+
+/**
+ * Allows the user to switch the device they are seeing the theme for.
+ * This allows mobile users to switch back to the default theme, or theme for any other device.
+ *
+ * @deprecated since 2.6
+ * @param string $newdevice The device the user is currently using.
+ * @return string The device the user has switched to
+ */
+function set_user_device_type($newdevice) {
+    debugging('set_user_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::set_user_device_type($newdevice);
+}
+
+/**
+ * Returns the device the user is currently using, or if the user has chosen to switch devices
+ * for the current device type the type they have switched to.
+ *
+ * @deprecated since 2.6
+ * @return string The device the user is currently using or wishes to use
+ */
+function get_user_device_type() {
+    debugging('get_user_device_type has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::get_user_device_type();
+}
+
+/**
+ * Returns one or several CSS class names that match the user's browser. These can be put
+ * in the body tag of the page to apply browser-specific rules without relying on CSS hacks
+ *
+ * @deprecated since 2.6
+ * @return array An array of browser version classes
+ */
+function get_browser_version_classes() {
+    debugging('get_browser_version_classes has been deprecated, please update your code to use core_useragent instead.', DEBUG_DEVELOPER);
+    return core_useragent::get_browser_version_classes();
+}
\ No newline at end of file
diff --git a/lib/editor/tinymce/lib.php b/lib/editor/tinymce/lib.php
index 838f845dcdd..a231f4165db 100644
--- a/lib/editor/tinymce/lib.php
+++ b/lib/editor/tinymce/lib.php
@@ -34,25 +34,25 @@ class tinymce_texteditor extends texteditor {
      * @return bool
      */
     public function supported_by_browser() {
-        if (check_browser_version('MSIE', 6)) {
+        if (core_useragent::check_ie_version(6)) {
             return true;
         }
-        if (check_browser_version('Gecko', 20030516)) {
+        if (core_useragent::check_firefox_version(20030516)) {
             return true;
         }
-        if (check_browser_version('Safari', 412)) {
+        if (core_useragent::check_safari_version(412)) {
             return true;
         }
-        if (check_browser_version('Chrome', 6)) {
+        if (core_useragent::check_chrome_version(6)) {
             return true;
         }
-        if (check_browser_version('Opera', 9)) {
+        if (core_useragent::check_opera_version(9)) {
             return true;
         }
-        if (check_browser_version('Safari iOS', 534)) {
+        if (core_useragent::check_safari_ios_version(534)) {
             return true;
         }
-        if (check_browser_version('WebKit', 534)) {
+        if (core_useragent::check_webkit_version(534)) {
             return true;
         }
 
diff --git a/lib/editor/tinymce/plugins/spellchecker/lib.php b/lib/editor/tinymce/plugins/spellchecker/lib.php
index 72d63236c95..a3c8540c1e1 100644
--- a/lib/editor/tinymce/plugins/spellchecker/lib.php
+++ b/lib/editor/tinymce/plugins/spellchecker/lib.php
@@ -63,7 +63,7 @@ class tinymce_spellchecker extends editor_tinymce_plugin {
 
     protected function is_legacy_browser() {
         // IE8 and IE9 are the only supported browsers that do not have spellchecker.
-        if (check_browser_version('MSIE', 5) and !check_browser_version('MSIE', 10)) {
+        if (core_useragent::check_ie_version() and !core_useragent::check_ie_version(10)) {
             return true;
         }
         // The rest of browsers supports spellchecking or is horribly outdated and we do not care...
diff --git a/lib/excellib.class.php b/lib/excellib.class.php
index 1e1355db0c2..77341cc21c3 100644
--- a/lib/excellib.class.php
+++ b/lib/excellib.class.php
@@ -120,7 +120,7 @@ class MoodleExcelWorkbook {
             header('Pragma: no-cache');
         }
 
-        if (check_browser_version('MSIE')) {
+        if (core_useragent::check_ie_version()) {
             $filename = rawurlencode($filename);
         } else {
             $filename = s($filename);
diff --git a/lib/filelib.php b/lib/filelib.php
index 79464ca400f..efe335a060a 100644
--- a/lib/filelib.php
+++ b/lib/filelib.php
@@ -2101,7 +2101,7 @@ function readstring_accel($string, $mimetype, $accelerate) {
 function send_temp_file($path, $filename, $pathisstring=false) {
     global $CFG;
 
-    if (check_browser_version('Firefox', '1.5')) {
+    if (core_useragent::check_firefox_version('1.5')) {
         // only FF is known to correctly save to disk before opening...
         $mimetype = mimeinfo('type', $filename);
     } else {
@@ -2121,7 +2121,7 @@ function send_temp_file($path, $filename, $pathisstring=false) {
     }
 
     // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
-    if (check_browser_version('MSIE')) {
+    if (core_useragent::check_ie_version()) {
         $filename = urlencode($filename);
     }
 
@@ -2197,12 +2197,12 @@ function send_file($path, $filename, $lifetime = 'default' , $filter=0, $pathiss
     // Use given MIME type if specified, otherwise guess it using mimeinfo.
     // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
     // only Firefox saves all files locally before opening when content-disposition: attachment stated
-    $isFF         = check_browser_version('Firefox', '1.5'); // only FF > 1.5 properly tested
+    $isFF         = core_useragent::check_firefox_version('1.5'); // only FF > 1.5 properly tested
     $mimetype     = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
                          ($mimetype ? $mimetype : mimeinfo('type', $filename));
 
     // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
-    if (check_browser_version('MSIE')) {
+    if (core_useragent::check_ie_version()) {
         $filename = rawurlencode($filename);
     }
 
@@ -2361,12 +2361,12 @@ function send_stored_file($stored_file, $lifetime=86400 , $filter=0, $forcedownl
     // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
     // only Firefox saves all files locally before opening when content-disposition: attachment stated
     $filename     = is_null($filename) ? $stored_file->get_filename() : $filename;
-    $isFF         = check_browser_version('Firefox', '1.5'); // only FF > 1.5 properly tested
+    $isFF         = core_useragent::check_firefox_version('1.5'); // only FF > 1.5 properly tested
     $mimetype     = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
                          ($stored_file->get_mimetype() ? $stored_file->get_mimetype() : mimeinfo('type', $filename));
 
     // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
-    if (check_browser_version('MSIE')) {
+    if (core_useragent::check_ie_version()) {
         $filename = rawurlencode($filename);
     }
 
diff --git a/lib/medialib.php b/lib/medialib.php
index 2dff8f29763..2de7fc633ec 100644
--- a/lib/medialib.php
+++ b/lib/medialib.php
@@ -983,8 +983,8 @@ class core_media_player_html5video extends core_media_player {
     public function embed($urls, $name, $width, $height, $options) {
         // Special handling to make videos play on Android devices pre 2.3.
         // Note: I tested and 2.3.3 (in emulator) works without, is 533.1 webkit.
-        $oldandroid = check_browser_version('WebKit Android') &&
-                !check_browser_version('WebKit Android', '533.1');
+        $oldandroid = core_useragent::check_webkit_android_version() &&
+                !core_useragent::check_webkit_android_version('533.1');
 
         // Build array of source tags.
         $sources = array();
@@ -1067,12 +1067,12 @@ OET;
                 // versions or manual plugins.
                 if ($ext === 'ogv' || $ext === 'webm') {
                     // Formats .ogv and .webm are not supported in IE or Safari.
-                    if (check_browser_version('MSIE') || check_browser_version('Safari')) {
+                    if (core_useragent::check_ie_version() || core_useragent::check_safari_version()) {
                         continue;
                     }
                 } else {
                     // Formats .m4v and .mp4 are not supported in Firefox or Opera.
-                    if (check_browser_version('Firefox') || check_browser_version('Opera')) {
+                    if (core_useragent::check_firefox_version() || core_useragent::check_opera_version()) {
                         continue;
                     }
                 }
@@ -1136,18 +1136,18 @@ OET;
             if (in_array($ext, $extensions)) {
                 if ($ext === 'ogg' || $ext === 'oga') {
                     // Formats .ogg and .oga are not supported in IE or Safari.
-                    if (check_browser_version('MSIE') || check_browser_version('Safari')) {
+                    if (core_useragent::check_ie_version() || core_useragent::check_safari_version()) {
                         continue;
                     }
                 } else {
                     // Formats .aac, .mp3, and .m4a are not supported in Firefox or Opera.
-                    if (check_browser_version('Firefox') || check_browser_version('Opera')) {
+                    if (core_useragent::check_firefox_version() || core_useragent::check_opera_version()) {
                         continue;
                     }
                 }
                 // Old Android versions (pre 2.3.3) 'support' audio tag but no codecs.
-                if (check_browser_version('WebKit Android') &&
-                        !check_browser_version('WebKit Android', '533.1')) {
+                if (core_useragent::check_webkit_android_version() &&
+                        !core_useragent::check_webkit_android_version('533.1')) {
                     continue;
                 }
 
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index 3a42fddbccc..ad04ace16d1 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -7415,448 +7415,6 @@ function check_php_version($version='5.2.4') {
     return (version_compare(phpversion(), $version) >= 0);
 }
 
-/**
- * Checks to see if is the browser operating system matches the specified brand.
- *
- * Known brand: 'Windows','Linux','Macintosh','SGI','SunOS','HP-UX'
- *
- * @uses $_SERVER
- * @param string $brand The operating system identifier being tested
- * @return bool true if the given brand below to the detected operating system
- */
-function check_browser_operating_system($brand) {
-    if (empty($_SERVER['HTTP_USER_AGENT'])) {
-        return false;
-    }
-
-    if (preg_match("/$brand/i", $_SERVER['HTTP_USER_AGENT'])) {
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * Checks to see if is a browser matches the specified
- * brand and is equal or better version.
- *
- * @uses $_SERVER
- * @param string $brand The browser identifier being tested
- * @param int $version The version of the browser, if not specified any version (except 5.5 for IE for BC reasons)
- * @return bool true if the given version is below that of the detected browser
- */
-function check_browser_version($brand, $version = null) {
-    if (empty($_SERVER['HTTP_USER_AGENT'])) {
-        return false;
-    }
-
-    $agent = $_SERVER['HTTP_USER_AGENT'];
-
-    switch ($brand) {
-
-        case 'Camino':
-            // OSX browser using Gecke engine.
-            if (strpos($agent, 'Camino') === false) {
-                return false;
-            }
-            if (empty($version)) {
-                return true; // No version specified.
-            }
-            if (preg_match("/Camino\/([0-9\.]+)/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'Firefox':
-            // Mozilla Firefox browsers.
-            if (strpos($agent, 'Iceweasel') === false and strpos($agent, 'Firefox') === false) {
-                return false;
-            }
-            if (empty($version)) {
-                return true; // No version specified..
-            }
-            if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $agent, $match)) {
-                if (version_compare($match[2], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'Gecko':
-            // Gecko based browsers.
-            // Do not look for dates any more, we expect real Firefox version here.
-            if (empty($version)) {
-                $version = 1;
-            } else if ($version > 20000000) {
-                // This is just a guess, it is not supposed to be 100% accurate!
-                if (preg_match('/^201/', $version)) {
-                    $version = 3.6;
-                } else if (preg_match('/^200[7-9]/', $version)) {
-                    $version = 3;
-                } else if (preg_match('/^2006/', $version)) {
-                    $version = 2;
-                } else {
-                    $version = 1.5;
-                }
-            }
-            if (preg_match("/(Iceweasel|Firefox)\/([0-9\.]+)/i", $agent, $match)) {
-                // Use real Firefox version if specified in user agent string.
-                if (version_compare($match[2], $version) >= 0) {
-                    return true;
-                }
-            } else if (preg_match("/Gecko\/([0-9\.]+)/i", $agent, $match)) {
-                // Gecko might contain date or Firefox revision, let's just guess the Firefox version from the date.
-                $browserver = $match[1];
-                if ($browserver > 20000000) {
-                    // This is just a guess, it is not supposed to be 100% accurate!
-                    if (preg_match('/^201/', $browserver)) {
-                        $browserver = 3.6;
-                    } else if (preg_match('/^200[7-9]/', $browserver)) {
-                        $browserver = 3;
-                    } else if (preg_match('/^2006/', $version)) {
-                        $browserver = 2;
-                    } else {
-                        $browserver = 1.5;
-                    }
-                }
-                if (version_compare($browserver, $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'MSIE':
-            // Internet Explorer.
-            if (strpos($agent, 'Opera') !== false) {
-                // Reject Opera.
-                return false;
-            }
-            // In case of IE we have to deal with BC of the version parameter.
-            if (is_null($version)) {
-                $version = 5.5; // Anything older is not considered a browser at all!
-            }
-            // IE uses simple versions, let's cast it to float to simplify the logic here.
-            $version = round($version, 1);
-            // See: http://www.useragentstring.com/pages/Internet%20Explorer/.
-            if (preg_match("/MSIE ([0-9\.]+)/", $agent, $match)) {
-                $browser = $match[1];
-            } else {
-                return false;
-            }
-            // IE8 and later versions may pretend to be IE7 for intranet sites, use Trident version instead,
-            // the Trident should always describe the capabilities of IE in any emulation mode.
-            if ($browser === '7.0' and preg_match("/Trident\/([0-9\.]+)/", $agent, $match)) {
-                $browser = $match[1] + 4; // NOTE: Hopefully this will work also for future IE versions.
-            }
-            $browser = round($browser, 1);
-            return ($browser >= $version);
-            break;
-
-        case 'Opera':
-            // Opera.
-            if (strpos($agent, 'Opera') === false) {
-                return false;
-            }
-            if (empty($version)) {
-                return true; // No version specified.
-            }
-            // Recent Opera useragents have Version/ with the actual version, e.g.:
-            // Opera/9.80 (Windows NT 6.1; WOW64; U; en) Presto/2.10.289 Version/12.01
-            // That's Opera 12.01, not 9.8.
-            if (preg_match("/Version\/([0-9\.]+)/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            } else if (preg_match("/Opera\/([0-9\.]+)/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'WebKit':
-            // WebKit based browser - everything derived from it (Safari, Chrome, iOS, Android and other mobiles).
-            if (strpos($agent, 'AppleWebKit') === false) {
-                return false;
-            }
-            if (empty($version)) {
-                return true; // No version specified.
-            }
-            if (preg_match("/AppleWebKit\/([0-9.]+)/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'Safari':
-            // Desktop version of Apple Safari browser - no mobile or touch devices.
-            if (strpos($agent, 'AppleWebKit') === false) {
-                return false;
-            }
-            // Look for AppleWebKit, excluding strings with OmniWeb, Shiira and SymbianOS and any other mobile devices
-            if (strpos($agent, 'OmniWeb')) { // Reject OmniWeb.
-                return false;
-            }
-            if (strpos($agent, 'Shiira')) { // Reject Shiira.
-                return false;
-            }
-            if (strpos($agent, 'SymbianOS')) { // Reject SymbianOS.
-                return false;
-            }
-            if (strpos($agent, 'Android')) { // Reject Androids too.
-                return false;
-            }
-            if (strpos($agent, 'iPhone') or strpos($agent, 'iPad') or strpos($agent, 'iPod')) {
-                // No Apple mobile devices here - editor does not work, course ajax is not touch compatible, etc.
-                return false;
-            }
-            if (strpos($agent, 'Chrome')) { // Reject chrome browsers - it needs to be tested explicitly.
-                return false;
-            }
-
-            if (empty($version)) {
-                return true; // No version specified.
-            }
-            if (preg_match("/AppleWebKit\/([0-9.]+)/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'Chrome':
-            if (strpos($agent, 'Chrome') === false) {
-                return false;
-            }
-            if (empty($version)) {
-                return true; // No version specified.
-            }
-            if (preg_match("/Chrome\/(.*)[ ]+/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'Safari iOS':
-            // Safari on iPhone, iPad and iPod touch.
-            if (strpos($agent, 'AppleWebKit') === false or strpos($agent, 'Safari') === false) {
-                return false;
-            }
-            if (!strpos($agent, 'iPhone') and !strpos($agent, 'iPad') and !strpos($agent, 'iPod')) {
-                return false;
-            }
-            if (empty($version)) {
-                return true; // No version specified.
-            }
-            if (preg_match("/AppleWebKit\/([0-9]+)/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-
-        case 'WebKit Android':
-            // WebKit browser on Android.
-            if (strpos($agent, 'Linux; U; Android') === false) {
-                return false;
-            }
-            if (empty($version)) {
-                return true; // No version specified.
-            }
-            if (preg_match("/AppleWebKit\/([0-9]+)/i", $agent, $match)) {
-                if (version_compare($match[1], $version) >= 0) {
-                    return true;
-                }
-            }
-            break;
-    }
-
-    return false;
-}
-
-/**
- * Returns whether a device/browser combination is mobile, tablet, legacy, default or the result of
- * an optional admin specified regular expression.  If enabledevicedetection is set to no or not set
- * it returns default
- *
- * @return string device type
- */
-function get_device_type() {
-    global $CFG;
-
-    if (empty($CFG->enabledevicedetection) || empty($_SERVER['HTTP_USER_AGENT'])) {
-        return 'default';
-    }
-
-    $useragent = $_SERVER['HTTP_USER_AGENT'];
-
-    if (!empty($CFG->devicedetectregex)) {
-        $regexes = json_decode($CFG->devicedetectregex);
-
-        foreach ($regexes as $value => $regex) {
-            if (preg_match($regex, $useragent)) {
-                return $value;
-            }
-        }
-    }
-
-    // Mobile detection PHP direct copy from open source detectmobilebrowser.com.
-    $phonesregex = '/android .+ mobile|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i';
-    $modelsregex = '/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i';
-    if (preg_match($phonesregex, $useragent) || preg_match($modelsregex, substr($useragent, 0, 4))) {
-        return 'mobile';
-    }
-
-    $tabletregex = '/Tablet browser|android|iPad|iProd|GT-P1000|GT-I9000|SHW-M180S|SGH-T849|SCH-I800|Build\/ERE27|sholest/i';
-    if (preg_match($tabletregex, $useragent)) {
-         return 'tablet';
-    }
-
-    // Safe way to check for IE6 and not get false positives for some IE 7/8 users.
-    if (substr($_SERVER['HTTP_USER_AGENT'], 0, 34) === 'Mozilla/4.0 (compatible; MSIE 6.0;') {
-        return 'legacy';
-    }
-
-    return 'default';
-}
-
-/**
- * Returns a list of the device types supporting by Moodle
- *
- * @param boolean $incusertypes includes types specified using the devicedetectregex admin setting
- * @return array $types
- */
-function get_device_type_list($incusertypes = true) {
-    global $CFG;
-
-    $types = array('default', 'legacy', 'mobile', 'tablet');
-
-    if ($incusertypes && !empty($CFG->devicedetectregex)) {
-        $regexes = json_decode($CFG->devicedetectregex);
-
-        foreach ($regexes as $value => $regex) {
-            $types[] = $value;
-        }
-    }
-
-    return $types;
-}
-
-/**
- * Returns the theme selected for a particular device or false if none selected.
- *
- * @param string $devicetype
- * @return string|false The name of the theme to use for the device or the false if not set
- */
-function get_selected_theme_for_device_type($devicetype = null) {
-    global $CFG;
-
-    if (empty($devicetype)) {
-        $devicetype = get_user_device_type();
-    }
-
-    $themevarname = get_device_cfg_var_name($devicetype);
-    if (empty($CFG->$themevarname)) {
-        return false;
-    }
-
-    return $CFG->$themevarname;
-}
-
-/**
- * Returns the name of the device type theme var in $CFG because there is not a convention to allow backwards compatibility.
- *
- * @param string $devicetype
- * @return string The config variable to use to determine the theme
- */
-function get_device_cfg_var_name($devicetype = null) {
-    if ($devicetype == 'default' || empty($devicetype)) {
-        return 'theme';
-    }
-
-    return 'theme' . $devicetype;
-}
-
-/**
- * Allows the user to switch the device they are seeing the theme for.
- * This allows mobile users to switch back to the default theme, or theme for any other device.
- *
- * @param string $newdevice The device the user is currently using.
- * @return string The device the user has switched to
- */
-function set_user_device_type($newdevice) {
-    global $USER;
-
-    $devicetype = get_device_type();
-    $devicetypes = get_device_type_list();
-
-    if ($newdevice == $devicetype) {
-        unset_user_preference('switchdevice'.$devicetype);
-    } else if (in_array($newdevice, $devicetypes)) {
-        set_user_preference('switchdevice'.$devicetype, $newdevice);
-    }
-}
-
-/**
- * Returns the device the user is currently using, or if the user has chosen to switch devices
- * for the current device type the type they have switched to.
- *
- * @return string The device the user is currently using or wishes to use
- */
-function get_user_device_type() {
-    $device = get_device_type();
-    $switched = get_user_preferences('switchdevice'.$device, false);
-    if ($switched != false) {
-        return $switched;
-    }
-    return $device;
-}
-
-/**
- * Returns one or several CSS class names that match the user's browser. These can be put
- * in the body tag of the page to apply browser-specific rules without relying on CSS hacks
- *
- * @return array An array of browser version classes
- */
-function get_browser_version_classes() {
-    $classes = array();
-
-    if (check_browser_version("MSIE", "0")) {
-        $classes[] = 'ie';
-        for ($i=12; $i>=6; $i--) {
-            if (check_browser_version("MSIE", $i)) {
-                $classes[] = 'ie'.$i;
-                break;
-            }
-        }
-
-    } else if (check_browser_version("Firefox") || check_browser_version("Gecko") || check_browser_version("Camino")) {
-        $classes[] = 'gecko';
-        if (preg_match('/rv\:([1-2])\.([0-9])/', $_SERVER['HTTP_USER_AGENT'], $matches)) {
-            $classes[] = "gecko{$matches[1]}{$matches[2]}";
-        }
-
-    } else if (check_browser_version("WebKit")) {
-        $classes[] = 'safari';
-        if (check_browser_version("Safari iOS")) {
-            $classes[] = 'ios';
-
-        } else if (check_browser_version("WebKit Android")) {
-            $classes[] = 'android';
-        }
-
-    } else if (check_browser_version("Opera")) {
-        $classes[] = 'opera';
-
-    }
-
-    return $classes;
-}
-
 /**
  * Determine if moodle installation requires update.
  *
diff --git a/lib/outputlib.php b/lib/outputlib.php
index be02e35db1e..e1051dd1cc1 100644
--- a/lib/outputlib.php
+++ b/lib/outputlib.php
@@ -656,7 +656,7 @@ class theme_config {
 
         if ($rev > -1) {
             $url = new moodle_url("$CFG->httpswwwroot/theme/styles.php");
-            $separate = (check_browser_version('MSIE', 5) && !check_browser_version('MSIE', 10));
+            $separate = (core_useragent::check_ie_version('5') && !core_useragent::check_ie_version('10'));
             if (!empty($CFG->slasharguments)) {
                 $slashargs = '';
                 if (!$svg) {
@@ -734,7 +734,7 @@ class theme_config {
                 // We do this because all modern browsers support SVG and this param will one day be removed.
                 $baseurl->param('svg', '0');
             }
-            if (check_browser_version('MSIE', 5)) {
+            if (core_useragent::check_ie_version('5')) {
                 // lalala, IE does not allow more than 31 linked CSS files from main document
                 $urls[] = new moodle_url($baseurl, array('theme'=>$this->name, 'type'=>'ie', 'subtype'=>'plugins'));
                 foreach ($css['parents'] as $parent=>$sheets) {
@@ -1359,24 +1359,9 @@ class theme_config {
     public function use_svg_icons() {
         global $CFG;
         if ($this->usesvg === null) {
+
             if (!isset($CFG->svgicons) || !is_bool($CFG->svgicons)) {
-                // IE 5 - 8 don't support SVG at all.
-                if (empty($_SERVER['HTTP_USER_AGENT'])) {
-                    // Can't be sure, just say no.
-                    $this->usesvg = false;
-                } else if (check_browser_version('MSIE', 0) and !check_browser_version('MSIE', 9)) {
-                    // IE < 9 doesn't support SVG. Say no.
-                    $this->usesvg = false;
-                } else if (preg_match('#Android +[0-2]\.#', $_SERVER['HTTP_USER_AGENT'])) {
-                    // Android < 3 doesn't support SVG. Say no.
-                    $this->usesvg = false;
-                } else if (check_browser_version('Opera', 0)) {
-                    // Opera 12 still does not support SVG well enough. Say no.
-                    $this->usesvg = false;
-                } else {
-                    // Presumed fine.
-                    $this->usesvg = true;
-                }
+                $this->usesvg = core_useragent::supports_svg();
             } else {
                 // Force them on/off depending upon the setting.
                 $this->usesvg = $CFG->svgicons;
diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php
index d61279a473b..e13340324b0 100644
--- a/lib/outputrenderers.php
+++ b/lib/outputrenderers.php
@@ -3037,7 +3037,7 @@ EOD;
      */
     protected function theme_switch_links() {
 
-        $actualdevice = get_device_type();
+        $actualdevice = core_useragent::get_device_type();
         $currentdevice = $this->page->devicetypeinuse;
         $switched = ($actualdevice != $currentdevice);
 
diff --git a/lib/pagelib.php b/lib/pagelib.php
index 7e733ee6a55..9c7db77892a 100644
--- a/lib/pagelib.php
+++ b/lib/pagelib.php
@@ -659,7 +659,7 @@ class moodle_page {
      */
     protected function magic_get_devicetypeinuse() {
         if (empty($this->_devicetypeinuse)) {
-            $this->_devicetypeinuse = get_user_device_type();
+            $this->_devicetypeinuse = core_useragent::get_user_device_type();
         }
         return $this->_devicetypeinuse;
     }
@@ -1549,12 +1549,12 @@ class moodle_page {
                         return $mnetpeertheme;
                     }
                     // First try for the device the user is using.
-                    $devicetheme = get_selected_theme_for_device_type($this->devicetypeinuse);
+                    $devicetheme = core_useragent::get_device_type_theme($this->devicetypeinuse);
                     if (!empty($devicetheme)) {
                         return $devicetheme;
                     }
                     // Next try for the default device (as a fallback).
-                    $devicetheme = get_selected_theme_for_device_type('default');
+                    $devicetheme = core_useragent::get_device_type_theme('default');
                     if (!empty($devicetheme)) {
                         return $devicetheme;
                     }
@@ -1636,7 +1636,7 @@ class moodle_page {
             $this->add_body_class('path-' . join('-', array_slice($pathbits, 0, $i)));
         }
 
-        $this->add_body_classes(get_browser_version_classes());
+        $this->add_body_classes(core_useragent::get_browser_version_classes());
         $this->add_body_class('dir-' . get_string('thisdirection', 'langconfig'));
         $this->add_body_class('lang-' . current_language());
         $this->add_body_class('yui-skin-sam'); // Make YUI happy, if it is used.
diff --git a/lib/setuplib.php b/lib/setuplib.php
index 1b43764f449..9f8653f5696 100644
--- a/lib/setuplib.php
+++ b/lib/setuplib.php
@@ -1174,7 +1174,7 @@ function disable_output_buffering() {
  */
 function redirect_if_major_upgrade_required() {
     global $CFG;
-    $lastmajordbchanges = 2013081400.00;
+    $lastmajordbchanges = 2013081600.00;
     if (empty($CFG->version) or (float)$CFG->version < $lastmajordbchanges or
             during_initial_install() or !empty($CFG->adminsetuppending)) {
         try {
diff --git a/lib/tests/medialib_test.php b/lib/tests/medialib_test.php
index 782ca196275..eea80f40183 100644
--- a/lib/tests/medialib_test.php
+++ b/lib/tests/medialib_test.php
@@ -67,8 +67,8 @@ class core_medialib_testcase extends advanced_testcase {
      */
     private function pretend_to_be_safari() {
         // Pretend to be using Safari browser (must support mp4 for tests to work).
-        $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) ' .
-                'AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1';
+        core_useragent::instance(true, 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) ' .
+                'AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1');
     }
 
     /**
@@ -76,7 +76,7 @@ class core_medialib_testcase extends advanced_testcase {
      */
     private function pretend_to_be_firefox() {
         // Pretend to be using Firefox browser (must support ogg for tests to work).
-        $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';
+        core_useragent::instance(true, 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0');
     }
 
     /**
diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php
index 60c3ed8d879..1c9fe7e80d9 100644
--- a/lib/tests/moodlelib_test.php
+++ b/lib/tests/moodlelib_test.php
@@ -30,57 +30,6 @@ class core_moodlelib_testcase extends advanced_testcase {
 
     public static $includecoverage = array('lib/moodlelib.php');
 
-    protected $user_agents = array(
-        'MSIE' => array(
-            '5.0' => array('Windows 98' => 'Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)'),
-            '5.5' => array('Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'),
-            '6.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'),
-            '7.0' => array('Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'),
-            '8.0' => array('Windows Vista' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)'),
-            '9.0' => array('Windows 7' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'),
-            '9.0i' => array('Windows 7' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)'),
-            '10.0' => array('Windows 8' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Touch)'),
-            '10.0i' => array('Windows 8' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)'),
-        ),
-        'Firefox' => array(
-            '1.0.6'   => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'),
-            '1.5'     => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'),
-            '1.5.0.1' => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'),
-            '2.0'     => array('Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1',
-                               'Ubuntu Linux AMD64' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)'),
-            '3.0.6'   => array('SUSE' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.6) Gecko/2009012700 SUSE/3.0.6-1.4 Firefox/3.0.6'),
-            '3.6'     => array('Linux' => 'Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6'),
-            '11.0'    => array('Windows' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0'),
-            '15.0a2'  => array('Windows' => 'Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2'),
-            '18.0'    => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/18.0 Firefox/18.0'),
-        ),
-        'SeaMonkey' => array(
-            '2.0' => array('Windows' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b3pre) Gecko/20081208 SeaMonkey/2.0'),
-            '2.1' => array('Linux' => 'Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20110609 Firefox/4.0.1 SeaMonkey/2.1'),
-            '2.3' => array('FreeBSD' => 'Mozilla/5.0 (X11; FreeBSD amd64; rv:6.0) Gecko/20110818 Firefox/6.0 SeaMonkey/2.3'),
-        ),
-        'Safari' => array(
-            '312' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312'),
-            '412' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412')
-        ),
-        'Safari iOS' => array(
-            '528' => array('iPhone' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; cs-cz) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16'),
-            '533' => array('iPad' => 'Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5'),
-        ),
-        'WebKit Android' => array(
-            '525' => array('G1 Phone' => 'Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 – G1 Phone'),
-            '530' => array('Nexus' => 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 –Nexus'),
-        ),
-        'Chrome' => array(
-            '8' => array('Mac OS X' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10'),
-        ),
-        'Opera' => array(
-            '8.51' => array('Windows XP' => 'Opera/8.51 (Windows NT 5.1; U; en)'),
-            '9.0'  => array('Windows XP' => 'Opera/9.0 (Windows NT 5.1; U; en)',
-                'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)')
-        )
-    );
-
     /**
      * Define a local decimal separator.
      *
@@ -205,257 +154,6 @@ class core_moodlelib_testcase extends advanced_testcase {
         $this->assertFalse(address_in_subnet('123.123.123.123', ''));
     }
 
-    /**
-     * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version
-     * works as expected.
-     */
-    public function test_check_browser_version() {
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['412']['Mac OS X'];
-        $this->assertTrue(check_browser_version('Safari'));
-        $this->assertTrue(check_browser_version('WebKit'));
-        $this->assertTrue(check_browser_version('Safari', '312'));
-        $this->assertFalse(check_browser_version('Safari', '500'));
-        $this->assertFalse(check_browser_version('Chrome'));
-        $this->assertFalse(check_browser_version('Safari iOS'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari iOS']['528']['iPhone'];
-        $this->assertTrue(check_browser_version('Safari iOS'));
-        $this->assertTrue(check_browser_version('WebKit'));
-        $this->assertTrue(check_browser_version('Safari iOS', '527'));
-        $this->assertFalse(check_browser_version('Safari iOS', 590));
-        $this->assertFalse(check_browser_version('Safari', '312'));
-        $this->assertFalse(check_browser_version('Safari', '500'));
-        $this->assertFalse(check_browser_version('Chrome'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['WebKit Android']['530']['Nexus'];
-        $this->assertTrue(check_browser_version('WebKit'));
-        $this->assertTrue(check_browser_version('WebKit Android', '527'));
-        $this->assertFalse(check_browser_version('WebKit Android', 590));
-        $this->assertFalse(check_browser_version('Safari'));
-        $this->assertFalse(check_browser_version('Chrome'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Chrome']['8']['Mac OS X'];
-        $this->assertTrue(check_browser_version('Chrome'));
-        $this->assertTrue(check_browser_version('WebKit'));
-        $this->assertTrue(check_browser_version('Chrome', 8));
-        $this->assertFalse(check_browser_version('Chrome', 10));
-        $this->assertFalse(check_browser_version('Safari', '1'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
-        $this->assertTrue(check_browser_version('Opera'));
-        $this->assertTrue(check_browser_version('Opera', '8.0'));
-        $this->assertFalse(check_browser_version('Opera', '10.0'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2'];
-        $this->assertTrue(check_browser_version('MSIE'));
-        $this->assertTrue(check_browser_version('MSIE', '5.0'));
-        $this->assertFalse(check_browser_version('MSIE', '7.0'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['5.0']['Windows 98'];
-        $this->assertFalse(check_browser_version('MSIE'));
-        $this->assertTrue(check_browser_version('MSIE', 0));
-        $this->assertTrue(check_browser_version('MSIE', '5.0'));
-        $this->assertFalse(check_browser_version('MSIE', '7.0'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['9.0']['Windows 7'];
-        $this->assertTrue(check_browser_version('MSIE'));
-        $this->assertTrue(check_browser_version('MSIE', 0));
-        $this->assertTrue(check_browser_version('MSIE', '5.0'));
-        $this->assertTrue(check_browser_version('MSIE', '9.0'));
-        $this->assertFalse(check_browser_version('MSIE', '10'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['9.0i']['Windows 7'];
-        $this->assertTrue(check_browser_version('MSIE'));
-        $this->assertTrue(check_browser_version('MSIE', 0));
-        $this->assertTrue(check_browser_version('MSIE', '5.0'));
-        $this->assertTrue(check_browser_version('MSIE', '9.0'));
-        $this->assertFalse(check_browser_version('MSIE', '10'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['10.0']['Windows 8'];
-        $this->assertTrue(check_browser_version('MSIE'));
-        $this->assertTrue(check_browser_version('MSIE', 0));
-        $this->assertTrue(check_browser_version('MSIE', '5.0'));
-        $this->assertTrue(check_browser_version('MSIE', '9.0'));
-        $this->assertTrue(check_browser_version('MSIE', '10'));
-        $this->assertFalse(check_browser_version('MSIE', '11'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['10.0i']['Windows 8'];
-        $this->assertTrue(check_browser_version('MSIE'));
-        $this->assertTrue(check_browser_version('MSIE', 0));
-        $this->assertTrue(check_browser_version('MSIE', '5.0'));
-        $this->assertTrue(check_browser_version('MSIE', '9.0'));
-        $this->assertTrue(check_browser_version('MSIE', '10'));
-        $this->assertFalse(check_browser_version('MSIE', '11'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Firefox', '1.5'));
-        $this->assertFalse(check_browser_version('Firefox', '3.0'));
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['1.0.6']['Windows XP'];
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Gecko', '1'));
-        $this->assertFalse(check_browser_version('Gecko', 20030516));
-        $this->assertFalse(check_browser_version('Gecko', 20051106));
-        $this->assertFalse(check_browser_version('Gecko', 2006010100));
-        $this->assertFalse(check_browser_version('Firefox', '1.5'));
-        $this->assertFalse(check_browser_version('Firefox', '3.0'));
-        $this->assertFalse(check_browser_version('Gecko', '2'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Firefox', '1.5'));
-        $this->assertTrue(check_browser_version('Gecko', '1'));
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-        $this->assertFalse(check_browser_version('Firefox', '3.0'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['3.6']['Linux'];
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Firefox', '1.5'));
-        $this->assertTrue(check_browser_version('Firefox', '3.0'));
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', '3.6'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-        $this->assertFalse(check_browser_version('Firefox', '4'));
-        $this->assertFalse(check_browser_version('Firefox', '10'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['3.6']['Linux'];
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Firefox', '1.5'));
-        $this->assertTrue(check_browser_version('Firefox', '3.0'));
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', '3.6'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-        $this->assertFalse(check_browser_version('Firefox', '4'));
-        $this->assertFalse(check_browser_version('Firefox', '10'));
-        $this->assertFalse(check_browser_version('Firefox', '18'));
-        $this->assertFalse(check_browser_version('Gecko', '4'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['15.0a2']['Windows'];
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Firefox', '1.5'));
-        $this->assertTrue(check_browser_version('Firefox', '3.0'));
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', '3.6'));
-        $this->assertTrue(check_browser_version('Gecko', '15.0'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-        $this->assertTrue(check_browser_version('Firefox', '4'));
-        $this->assertTrue(check_browser_version('Firefox', '10'));
-        $this->assertTrue(check_browser_version('Firefox', '15'));
-        $this->assertFalse(check_browser_version('Firefox', '18'));
-        $this->assertFalse(check_browser_version('Gecko', '18'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['18.0']['Mac OS X'];
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Firefox', '1.5'));
-        $this->assertTrue(check_browser_version('Firefox', '3.0'));
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', '3.6'));
-        $this->assertTrue(check_browser_version('Gecko', '15.0'));
-        $this->assertTrue(check_browser_version('Gecko', '18.0'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-        $this->assertTrue(check_browser_version('Firefox', '4'));
-        $this->assertTrue(check_browser_version('Firefox', '10'));
-        $this->assertTrue(check_browser_version('Firefox', '15'));
-        $this->assertTrue(check_browser_version('Firefox', '18'));
-        $this->assertFalse(check_browser_version('Firefox', '19'));
-        $this->assertFalse(check_browser_version('Gecko', '19'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['SeaMonkey']['2.0']['Windows'];
-
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-        $this->assertFalse(check_browser_version('Gecko', '3.6'));
-        $this->assertFalse(check_browser_version('Gecko', '4.0'));
-        $this->assertFalse(check_browser_version('Firefox'));
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['SeaMonkey']['2.1']['Linux'];
-        $this->assertTrue(check_browser_version('Gecko', '2'));
-        $this->assertTrue(check_browser_version('Gecko', '3.6'));
-        $this->assertTrue(check_browser_version('Gecko', '4.0'));
-        $this->assertTrue(check_browser_version('Gecko', 20030516));
-        $this->assertTrue(check_browser_version('Gecko', 20051106));
-        $this->assertTrue(check_browser_version('Gecko', 2006010100));
-        $this->assertTrue(check_browser_version('Firefox'));
-        $this->assertTrue(check_browser_version('Firefox', 4.0));
-        $this->assertFalse(check_browser_version('Firefox', 5));
-        $this->assertFalse(check_browser_version('Gecko', '18.0'));
-
-    }
-
-    public function test_get_browser_version_classes() {
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari']['412']['Mac OS X'];
-        $this->assertEquals(array('safari'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Chrome']['8']['Mac OS X'];
-        $this->assertEquals(array('safari'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Safari iOS']['528']['iPhone'];
-        $this->assertEquals(array('safari', 'ios'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['WebKit Android']['530']['Nexus'];
-        $this->assertEquals(array('safari', 'android'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Chrome']['8']['Mac OS X'];
-        $this->assertEquals(array('safari'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Opera']['9.0']['Windows XP'];
-        $this->assertEquals(array('opera'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['6.0']['Windows XP SP2'];
-        $this->assertEquals(array('ie', 'ie6'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['7.0']['Windows XP SP2'];
-        $this->assertEquals(array('ie', 'ie7'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['8.0']['Windows Vista'];
-        $this->assertEquals(array('ie', 'ie8'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['9.0']['Windows 7'];
-        $this->assertEquals(array('ie', 'ie9'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['9.0i']['Windows 7'];
-        $this->assertEquals(array('ie', 'ie9'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['10.0']['Windows 8'];
-        $this->assertEquals(array('ie', 'ie10'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['MSIE']['10.0i']['Windows 8'];
-        $this->assertEquals(array('ie', 'ie10'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['2.0']['Windows XP'];
-        $this->assertEquals(array('gecko', 'gecko18'), get_browser_version_classes());
-
-        $_SERVER['HTTP_USER_AGENT'] = $this->user_agents['Firefox']['3.0.6']['SUSE'];
-        $this->assertEquals(array('gecko', 'gecko19'), get_browser_version_classes());
-    }
-
-    public function test_get_device_type() {
-        // IE8 (common pattern ~1.5% of IE7/8 users have embedded IE6 agent).
-        $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; BT Openworld BB; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Hotbar 10.2.197.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)';
-        $this->assertEquals('default', get_device_type());
-        // Genuine IE6.
-        $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1; SV1; FunWebProducts; .NET CLR 1.0.3705; Media Center PC 2.8)';
-        $this->assertEquals('legacy', get_device_type());
-    }
-
     public function test_fix_utf8() {
         // Make sure valid data including other types is not changed.
         $this->assertSame(null, fix_utf8(null));
diff --git a/lib/tests/theme_config_test.php b/lib/tests/theme_config_test.php
index 14b22618ace..64be4cc3e12 100644
--- a/lib/tests/theme_config_test.php
+++ b/lib/tests/theme_config_test.php
@@ -105,7 +105,7 @@ class core_theme_config_testcase extends advanced_testcase {
             'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13' => true
         );
         foreach ($useragents as $agent => $expected) {
-            $_SERVER['HTTP_USER_AGENT'] = $agent;
+            core_useragent::instance(true, $agent);
             // We need to clone the theme as usesvg property is calculated only once.
             $testtheme = clone $theme;
             $imagefile = $testtheme->resolve_image_location('i/test', 'moodle', null);
diff --git a/lib/tests/useragent_test.php b/lib/tests/useragent_test.php
new file mode 100644
index 00000000000..21e0ef7b04a
--- /dev/null
+++ b/lib/tests/useragent_test.php
@@ -0,0 +1,419 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Tests the user agent class.
+ *
+ * @package    core
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * User agent test suite.
+ *
+ * @package    core
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_useragent_testcase extends basic_testcase {
+
+    /**
+     * User agents we'll be using to test.
+     * @var array
+     */
+    protected $user_agents = array(
+        'MSIE' => array(
+            '5.0' => array(
+                'Windows 98' => 'Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)'
+            ),
+            '5.5' => array(
+                'Windows 2000' => 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)'
+            ),
+            '6.0' => array(
+                'Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'
+            ),
+            '7.0' => array(
+                'Windows XP SP2' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'
+            ),
+            '8.0' => array(
+                'Windows Vista' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)'
+            ),
+            '9.0' => array(
+                'Windows 7' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)'
+            ),
+            '9.0i' => array(
+                'Windows 7' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)'
+            ),
+            '10.0' => array(
+                'Windows 8' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0; Touch)'
+            ),
+            '10.0i' => array(
+                'Windows 8' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)'
+            ),
+        ),
+        'Firefox' => array(
+            '1.0.6' => array(
+                'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.10) Gecko/20050716 Firefox/1.0.6'
+            ),
+            '1.5' => array(
+                'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.8) Gecko/20051107 Firefox/1.5'
+            ),
+            '1.5.0.1' => array(
+                'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'
+            ),
+            '2.0' => array(
+                'Windows XP' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1',
+                'Ubuntu Linux AMD64' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1) Gecko/20060601 Firefox/2.0 (Ubuntu-edgy)'
+            ),
+            '3.0.6' => array(
+                'SUSE' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.6) Gecko/2009012700 SUSE/3.0.6-1.4 Firefox/3.0.6'
+            ),
+            '3.6' => array(
+                'Linux' => 'Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6'
+            ),
+            '11.0' => array(
+                'Windows' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0'
+            ),
+            '15.0a2' => array(
+                'Windows' => 'Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2'
+            ),
+            '18.0' => array(
+                'Mac OS X' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/18.0 Firefox/18.0'
+            ),
+        ),
+        'SeaMonkey' => array(
+            '2.0' => array(
+                'Windows' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b3pre) Gecko/20081208 SeaMonkey/2.0'
+            ),
+            '2.1' => array(
+                'Linux' => 'Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20110609 Firefox/4.0.1 SeaMonkey/2.1'
+            ),
+            '2.3' => array(
+                'FreeBSD' => 'Mozilla/5.0 (X11; FreeBSD amd64; rv:6.0) Gecko/20110818 Firefox/6.0 SeaMonkey/2.3'
+            ),
+        ),
+        'Safari' => array(
+            '312' => array(
+                'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312'
+            ),
+            '412' => array(
+                'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412'
+            ),
+            '2.0' => array(
+                'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412'
+            )
+        ),
+        'Safari iOS' => array(
+            '528' => array(
+                'iPhone' => 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; cs-cz) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16'
+            ),
+            '533' => array(
+                'iPad' => 'Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5'
+            ),
+        ),
+        'WebKit Android' => array(
+            '525' => array(
+                'G1 Phone' => 'Mozilla/5.0 (Linux; U; Android 1.1; en-gb; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2 – G1 Phone'
+            ),
+            '530' => array(
+                'Nexus' => 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 –Nexus'
+            ),
+        ),
+        'Chrome' => array(
+            '8' => array(
+                'Mac OS X' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10'
+            ),
+        ),
+        'Opera' => array(
+            '8.51' => array(
+                'Windows XP' => 'Opera/8.51 (Windows NT 5.1; U; en)'
+            ),
+            '9.0'  => array(
+                'Windows XP' => 'Opera/9.0 (Windows NT 5.1; U; en)',
+                'Debian Linux' => 'Opera/9.01 (X11; Linux i686; U; en)'
+            )
+        )
+    );
+
+    /**
+     * Test instance generation.
+     */
+    public function test_instance() {
+        $this->assertInstanceOf('core_useragent', core_useragent::instance());
+        $this->assertInstanceOf('core_useragent', core_useragent::instance(true));
+    }
+
+    /**
+     * Modifies $_SERVER['HTTP_USER_AGENT'] manually to check if check_browser_version
+     * works as expected.
+     */
+    public function test_check_browser_version() {
+        core_useragent::instance(true, $this->user_agents['Safari']['412']['Mac OS X']);
+        $this->assertTrue(core_useragent::check_safari_version());
+        $this->assertTrue(core_useragent::check_webkit_version());
+        $this->assertTrue(core_useragent::check_safari_version('312'));
+        $this->assertFalse(core_useragent::check_safari_version('500'));
+        $this->assertFalse(core_useragent::check_chrome_version());
+        $this->assertFalse(core_useragent::check_safari_ios_version());
+
+        core_useragent::instance(true, $this->user_agents['Safari iOS']['528']['iPhone']);
+        $this->assertTrue(core_useragent::check_safari_ios_version());
+        $this->assertTrue(core_useragent::check_webkit_version());
+        $this->assertTrue(core_useragent::check_safari_ios_version('527'));
+        $this->assertFalse(core_useragent::check_safari_ios_version(590));
+        $this->assertFalse(core_useragent::check_safari_version('312'));
+        $this->assertFalse(core_useragent::check_safari_version('500'));
+        $this->assertFalse(core_useragent::check_chrome_version());
+
+        core_useragent::instance(true, $this->user_agents['WebKit Android']['530']['Nexus']);
+        $this->assertTrue(core_useragent::check_webkit_version());
+        $this->assertTrue(core_useragent::check_webkit_android_version('527'));
+        $this->assertFalse(core_useragent::check_webkit_android_version(590));
+        $this->assertFalse(core_useragent::check_safari_version());
+        $this->assertFalse(core_useragent::check_chrome_version());
+
+        core_useragent::instance(true, $this->user_agents['Chrome']['8']['Mac OS X']);
+        $this->assertTrue(core_useragent::check_chrome_version());
+        $this->assertTrue(core_useragent::check_webkit_version());
+        $this->assertTrue(core_useragent::check_chrome_version(8));
+        $this->assertFalse(core_useragent::check_chrome_version(10));
+        $this->assertFalse(core_useragent::check_safari_version('1'));
+
+        core_useragent::instance(true, $this->user_agents['Opera']['9.0']['Windows XP']);
+        $this->assertTrue(core_useragent::check_opera_version());
+        $this->assertTrue(core_useragent::check_opera_version('8.0'));
+        $this->assertFalse(core_useragent::check_opera_version('10.0'));
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['6.0']['Windows XP SP2']);
+        $this->assertTrue(core_useragent::check_ie_version());
+        $this->assertTrue(core_useragent::check_ie_version('5.0'));
+        $this->assertFalse(core_useragent::check_ie_version('7.0'));
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['5.0']['Windows 98']);
+        $this->assertFalse(core_useragent::check_ie_version());
+        $this->assertTrue(core_useragent::check_ie_version(0));
+        $this->assertTrue(core_useragent::check_ie_version('5.0'));
+        $this->assertFalse(core_useragent::check_ie_version('7.0'));
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['9.0']['Windows 7']);
+        $this->assertTrue(core_useragent::check_ie_version());
+        $this->assertTrue(core_useragent::check_ie_version(0));
+        $this->assertTrue(core_useragent::check_ie_version('5.0'));
+        $this->assertTrue(core_useragent::check_ie_version('9.0'));
+        $this->assertFalse(core_useragent::check_ie_version('10'));
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['9.0i']['Windows 7']);
+        $this->assertTrue(core_useragent::check_ie_version());
+        $this->assertTrue(core_useragent::check_ie_version(0));
+        $this->assertTrue(core_useragent::check_ie_version('5.0'));
+        $this->assertTrue(core_useragent::check_ie_version('9.0'));
+        $this->assertFalse(core_useragent::check_ie_version('10'));
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['10.0']['Windows 8']);
+        $this->assertTrue(core_useragent::check_ie_version());
+        $this->assertTrue(core_useragent::check_ie_version(0));
+        $this->assertTrue(core_useragent::check_ie_version('5.0'));
+        $this->assertTrue(core_useragent::check_ie_version('9.0'));
+        $this->assertTrue(core_useragent::check_ie_version('10'));
+        $this->assertFalse(core_useragent::check_ie_version('11'));
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['10.0i']['Windows 8']);
+        $this->assertTrue(core_useragent::check_ie_version());
+        $this->assertTrue(core_useragent::check_ie_version(0));
+        $this->assertTrue(core_useragent::check_ie_version('5.0'));
+        $this->assertTrue(core_useragent::check_ie_version('9.0'));
+        $this->assertTrue(core_useragent::check_ie_version('10'));
+        $this->assertFalse(core_useragent::check_ie_version('11'));
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['2.0']['Windows XP']);
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_firefox_version('1.5'));
+        $this->assertFalse(core_useragent::check_firefox_version('3.0'));
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['1.0.6']['Windows XP']);
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_gecko_version('1'));
+        $this->assertFalse(core_useragent::check_gecko_version(20030516));
+        $this->assertFalse(core_useragent::check_gecko_version(20051106));
+        $this->assertFalse(core_useragent::check_gecko_version(2006010100));
+        $this->assertFalse(core_useragent::check_firefox_version('1.5'));
+        $this->assertFalse(core_useragent::check_firefox_version('3.0'));
+        $this->assertFalse(core_useragent::check_gecko_version('2'));
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['2.0']['Windows XP']);
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_firefox_version('1.5'));
+        $this->assertTrue(core_useragent::check_gecko_version('1'));
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+        $this->assertFalse(core_useragent::check_firefox_version('3.0'));
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['3.6']['Linux']);
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_firefox_version('1.5'));
+        $this->assertTrue(core_useragent::check_firefox_version('3.0'));
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version('3.6'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+        $this->assertFalse(core_useragent::check_firefox_version('4'));
+        $this->assertFalse(core_useragent::check_firefox_version('10'));
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['3.6']['Linux']);
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_firefox_version('1.5'));
+        $this->assertTrue(core_useragent::check_firefox_version('3.0'));
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version('3.6'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+        $this->assertFalse(core_useragent::check_firefox_version('4'));
+        $this->assertFalse(core_useragent::check_firefox_version('10'));
+        $this->assertFalse(core_useragent::check_firefox_version('18'));
+        $this->assertFalse(core_useragent::check_gecko_version('4'));
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['15.0a2']['Windows']);
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_firefox_version('1.5'));
+        $this->assertTrue(core_useragent::check_firefox_version('3.0'));
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version('3.6'));
+        $this->assertTrue(core_useragent::check_gecko_version('15.0'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+        $this->assertTrue(core_useragent::check_firefox_version('4'));
+        $this->assertTrue(core_useragent::check_firefox_version('10'));
+        $this->assertTrue(core_useragent::check_firefox_version('15'));
+        $this->assertFalse(core_useragent::check_firefox_version('18'));
+        $this->assertFalse(core_useragent::check_gecko_version('18'));
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['18.0']['Mac OS X']);
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_firefox_version('1.5'));
+        $this->assertTrue(core_useragent::check_firefox_version('3.0'));
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version('3.6'));
+        $this->assertTrue(core_useragent::check_gecko_version('15.0'));
+        $this->assertTrue(core_useragent::check_gecko_version('18.0'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+        $this->assertTrue(core_useragent::check_firefox_version('4'));
+        $this->assertTrue(core_useragent::check_firefox_version('10'));
+        $this->assertTrue(core_useragent::check_firefox_version('15'));
+        $this->assertTrue(core_useragent::check_firefox_version('18'));
+        $this->assertFalse(core_useragent::check_firefox_version('19'));
+        $this->assertFalse(core_useragent::check_gecko_version('19'));
+
+        core_useragent::instance(true, $this->user_agents['SeaMonkey']['2.0']['Windows']);
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+        $this->assertFalse(core_useragent::check_gecko_version('3.6'));
+        $this->assertFalse(core_useragent::check_gecko_version('4.0'));
+        $this->assertFalse(core_useragent::check_firefox_version());
+
+        core_useragent::instance(true, $this->user_agents['SeaMonkey']['2.1']['Linux']);
+        $this->assertTrue(core_useragent::check_gecko_version('2'));
+        $this->assertTrue(core_useragent::check_gecko_version('3.6'));
+        $this->assertTrue(core_useragent::check_gecko_version('4.0'));
+        $this->assertTrue(core_useragent::check_gecko_version(20030516));
+        $this->assertTrue(core_useragent::check_gecko_version(20051106));
+        $this->assertTrue(core_useragent::check_gecko_version(2006010100));
+        $this->assertTrue(core_useragent::check_firefox_version());
+        $this->assertTrue(core_useragent::check_firefox_version(4.0));
+        $this->assertFalse(core_useragent::check_firefox_version(5));
+        $this->assertFalse(core_useragent::check_gecko_version('18.0'));
+
+    }
+
+    /**
+     * Test browser version classes functionality.
+     */
+    public function test_get_browser_version_classes() {
+        core_useragent::instance(true, $this->user_agents['Safari']['412']['Mac OS X']);
+        $this->assertEquals(array('safari'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['Chrome']['8']['Mac OS X']);
+        $this->assertEquals(array('safari'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['Safari iOS']['528']['iPhone']);
+        $this->assertEquals(array('safari', 'ios'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['WebKit Android']['530']['Nexus']);
+        $this->assertEquals(array('safari', 'android'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['Chrome']['8']['Mac OS X']);
+        $this->assertEquals(array('safari'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['Opera']['9.0']['Windows XP']);
+        $this->assertEquals(array('opera'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['6.0']['Windows XP SP2']);
+        $this->assertEquals(array('ie', 'ie6'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['7.0']['Windows XP SP2']);
+        $this->assertEquals(array('ie', 'ie7'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['8.0']['Windows Vista']);
+        $this->assertEquals(array('ie', 'ie8'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['9.0']['Windows 7']);
+        $this->assertEquals(array('ie', 'ie9'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['9.0i']['Windows 7']);
+        $this->assertEquals(array('ie', 'ie9'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['10.0']['Windows 8']);
+        $this->assertEquals(array('ie', 'ie10'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['MSIE']['10.0i']['Windows 8']);
+        $this->assertEquals(array('ie', 'ie10'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['2.0']['Windows XP']);
+        $this->assertEquals(array('gecko', 'gecko18'), core_useragent::get_browser_version_classes());
+
+        core_useragent::instance(true, $this->user_agents['Firefox']['3.0.6']['SUSE']);
+        $this->assertEquals(array('gecko', 'gecko19'), core_useragent::get_browser_version_classes());
+    }
+
+    /**
+     * Test device type detection.
+     */
+    public function test_get_device_type() {
+        // IE8 (common pattern ~1.5% of IE7/8 users have embedded IE6 agent).
+        $ie8 = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; BT Openworld BB; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Hotbar 10.2.197.0; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)';
+        core_useragent::instance(true, $ie8);
+        $this->assertEquals('default', core_useragent::get_device_type());
+        // Genuine IE6.
+        $ie6 = 'Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1; SV1; FunWebProducts; .NET CLR 1.0.3705; Media Center PC 2.8)';
+        core_useragent::instance(true, $ie6);
+        $this->assertEquals('legacy', core_useragent::get_device_type());
+
+        core_useragent::instance(true);
+    }
+}
\ No newline at end of file
diff --git a/lib/upgrade.txt b/lib/upgrade.txt
index 29a297f941f..35c524df093 100644
--- a/lib/upgrade.txt
+++ b/lib/upgrade.txt
@@ -24,71 +24,82 @@ Various previously deprecated functions have now been altered to throw DEBUG_DEV
 and will be removed in a future release (target: 2.8), a summary follows:
 
 Accesslib:
-    * get_context_instance()        ->  context_xxxx::instance()
-    * get_context_instance_by_id()  ->  context::instance_by_id($id)
-    * get_system_context()          ->  context_system::instance()
-    * context_moved()               ->  context::update_moved()
-    * preload_course_contexts()     ->  context_helper::preload_course()
-    * context_instance_preload()    ->  context_helper::preload_from_record()
-    * context_instance_preload_sql()->  context_helper::get_preload_record_columns_sql()
-    * get_contextlevel_name()       ->  context_helper::get_level_name()
-    * create_contexts()             ->  context_helper::create_instances()
-    * cleanup_contexts()            ->  context_helper::cleanup_instances()
-    * build_context_path()          ->  context_helper::build_all_paths()
-    * print_context_name()          ->  $context->get_context_name()
-    * mark_context_dirty()          ->  $context->mark_dirty()
-    * delete_context()              ->  $context->delete_content() or context_helper::delete_instance()
-    * get_context_url()             ->  $context->get_url()
-    * get_course_context()          ->  $context->get_course_context()
-    * get_parent_contexts()         ->  $context->get_parent_context_ids()
-    * get_parent_contextid()        ->  $context->get_parent_context()
-    * get_child_contexts()          ->  $context->get_child_contexts()
-    * rebuild_contexts()            ->  $context->reset_paths()
-    * get_user_courses_bycap()      ->  enrol_get_users_courses()
-    * get_courseid_from_context()   ->  $context->get_course_context(false)
-    * get_role_context_caps()       ->  (no replacement)
-    * load_temp_role()              ->  (no replacement)
-    * remove_temp_roles()           ->  (no replacement)
-    * get_related_contexts_string() ->  $context->get_parent_context_ids(true)
-    * get_recent_enrolments()       ->  (no replacement)
+    * get_context_instance()                ->  context_xxxx::instance()
+    * get_context_instance_by_id()          ->  context::instance_by_id($id)
+    * get_system_context()                  ->  context_system::instance()
+    * context_moved()                       ->  context::update_moved()
+    * preload_course_contexts()             ->  context_helper::preload_course()
+    * context_instance_preload()            ->  context_helper::preload_from_record()
+    * context_instance_preload_sql()        ->  context_helper::get_preload_record_columns_sql()
+    * get_contextlevel_name()               ->  context_helper::get_level_name()
+    * create_contexts()                     ->  context_helper::create_instances()
+    * cleanup_contexts()                    ->  context_helper::cleanup_instances()
+    * build_context_path()                  ->  context_helper::build_all_paths()
+    * print_context_name()                  ->  $context->get_context_name()
+    * mark_context_dirty()                  ->  $context->mark_dirty()
+    * delete_context()                      ->  $context->delete_content() or context_helper::delete_instance()
+    * get_context_url()                     ->  $context->get_url()
+    * get_course_context()                  ->  $context->get_course_context()
+    * get_parent_contexts()                 ->  $context->get_parent_context_ids()
+    * get_parent_contextid()                ->  $context->get_parent_context()
+    * get_child_contexts()                  ->  $context->get_child_contexts()
+    * rebuild_contexts()                    ->  $context->reset_paths()
+    * get_user_courses_bycap()              ->  enrol_get_users_courses()
+    * get_courseid_from_context()           ->  $context->get_course_context(false)
+    * get_role_context_caps()               ->  (no replacement)
+    * load_temp_role()                      ->  (no replacement)
+    * remove_temp_roles()                   ->  (no replacement)
+    * get_related_contexts_string()         ->  $context->get_parent_context_ids(true)
+    * get_recent_enrolments()               ->  (no replacement)
 
 Enrollment:
-    * get_course_participants()     -> get_enrolled_users()
-    * is_course_participant()       -> is_enrolled()
+    * get_course_participants()             -> get_enrolled_users()
+    * is_course_participant()               -> is_enrolled()
 
 Output:
-    * current_theme()               -> $PAGE->theme->name
-    * skip_main_destination()       -> $OUTPUT->skip_link_target()
-    * print_container()             -> $OUTPUT->container()
-    * print_container_start()       -> $OUTPUT->container_start()
-    * print_container_end()         -> $OUTPUT->container_end()
-    * print_continue()              -> $OUTPUT->continue_button()
-    * print_header()                -> $PAGE methods
-    * print_header_simple()         -> $PAGE methods
-    * print_side_block()            -> $OUTPUT->block()
-    * print_arrow()                 -> $OUTPUT->arrow()
-    * print_scale_menu_helpbutton() -> $OUTPUT->help_icon_scale($courseid, $scale)
-    * print_checkbox()              -> html_writer::checkbox()
+    * current_theme()                       -> $PAGE->theme->name
+    * skip_main_destination()               -> $OUTPUT->skip_link_target()
+    * print_container()                     -> $OUTPUT->container()
+    * print_container_start()               -> $OUTPUT->container_start()
+    * print_container_end()                 -> $OUTPUT->container_end()
+    * print_continue()                      -> $OUTPUT->continue_button()
+    * print_header()                        -> $PAGE methods
+    * print_header_simple()                 -> $PAGE methods
+    * print_side_block()                    -> $OUTPUT->block()
+    * print_arrow()                         -> $OUTPUT->arrow()
+    * print_scale_menu_helpbutton()         -> $OUTPUT->help_icon_scale($courseid, $scale)
+    * print_checkbox()                      -> html_writer::checkbox()
 
 Navigation:
-    * print_navigation()            -> $OUTPUT->navbar()
-    * build_navigation()            -> $PAGE->navbar methods
-    * navmenu()                     -> (no replacement)
+    * print_navigation()                    -> $OUTPUT->navbar()
+    * build_navigation()                    -> $PAGE->navbar methods
+    * navmenu()                             -> (no replacement)
 
 Calendar:
-    * add_event()                   -> calendar_event::create()
-    * update_event()                -> calendar_event->update()
-    * delete_event()                -> calendar_event->delete()
-    * hide_event()                  -> calendar_event->toggle_visibility(false)
-    * show_event()                  -> calendar_event->toggle_visibility(true)
+    * add_event()                           -> calendar_event::create()
+    * update_event()                        -> calendar_event->update()
+    * delete_event()                        -> calendar_event->delete()
+    * hide_event()                          -> calendar_event->toggle_visibility(false)
+    * show_event()                          -> calendar_event->toggle_visibility(true)
 
 Misc:
-    * filter_text()                 -> format_text(), format_string()...
-    * httpsrequired()               -> $PAGE->https_required()
-    * detect_munged_arguments()     -> clean_param([...], PARAM_FILE)
-    * mygroupid()                   -> groups_get_all_groups()
-    * js_minify()                   -> core_minify::js_files()
-    * css_minify_css()              -> core_minify::css_files()
+    * filter_text()                         -> format_text(), format_string()...
+    * httpsrequired()                       -> $PAGE->https_required()
+    * detect_munged_arguments()             -> clean_param([...], PARAM_FILE)
+    * mygroupid()                           -> groups_get_all_groups()
+    * js_minify()                           -> core_minify::js_files()
+    * css_minify_css()                      -> core_minify::css_files()
+
+User-agent related functions:
+    * check_browser_operating_system()      -> core_useragent::check_browser_operating_system()
+    * check_browser_version()               -> core_useragent::check_browser_version()
+    * get_device_type()                     -> core_useragent::get_device_type()
+    * get_device_type_list()                -> core_useragent::get_device_type_list()
+    * get_selected_theme_for_device_type()  -> core_useragent::get_device_type_theme()
+    * get_device_cfg_var_name()             -> core_useragent::get_device_type_cfg_var_name()
+    * set_user_device_type()                -> core_useragent::set_user_device_type()
+    * get_user_device_type()                -> core_useragent::get_user_device_type()
+    * get_browser_version_classes()         -> core_useragent::get_browser_version_classes()
 
 YUI:
     * moodle-core-notification has been deprecated with a recommendation of
diff --git a/mod/lti/locallib.php b/mod/lti/locallib.php
index dd1d9788d23..3f32ec16b25 100644
--- a/mod/lti/locallib.php
+++ b/mod/lti/locallib.php
@@ -1145,12 +1145,12 @@ function lti_get_launch_container($lti, $toolconfig) {
         $launchcontainer = LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS;
     }
 
-    $devicetype = get_device_type();
+    $devicetype = core_useragent::get_device_type();
 
     //Scrolling within the object element doesn't work on iOS or Android
     //Opening the popup window also had some issues in testing
     //For mobile devices, always take up the entire screen to ensure the best experience
-    if ($devicetype === 'mobile' || $devicetype === 'tablet' ) {
+    if ($devicetype === core_useragent::DEVICETYPE_MOBILE || $devicetype === core_useragent::DEVICETYPE_TABLET ) {
         $launchcontainer = LTI_LAUNCH_CONTAINER_REPLACE_MOODLE_WINDOW;
     }
 
diff --git a/theme/bootstrapbase/config.php b/theme/bootstrapbase/config.php
index 8ddf89567a6..37685cd731f 100644
--- a/theme/bootstrapbase/config.php
+++ b/theme/bootstrapbase/config.php
@@ -73,7 +73,7 @@ $THEME->layouts = array(
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
     ),
-    // part of course, typical for modules - default page layout if $cm specified in require_login()
+    // part of course, typical for modules - default page layout if $cm specified in require_login().
     'incourse' => array(
         'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
@@ -123,7 +123,7 @@ $THEME->layouts = array(
         'regions' => array(),
         'options' => array('nofooter'=>true, 'nocoursefooter'=>true),
     ),
-    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible
+    // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible.
     'embedded' => array(
         'file' => 'embedded.php',
         'regions' => array()
@@ -167,7 +167,7 @@ $THEME->javascripts_footer = array(
     'moodlebootstrap',
 );
 
-if (check_browser_version('MSIE') && !check_browser_version('MSIE', '9.0')) {
+if (core_useragent::check_ie_version() && core_useragent::check_ie_version('9.0')) {
     $THEME->javascripts[] = 'html5shiv';
 }
 
diff --git a/theme/index.php b/theme/index.php
index c51665f63a8..1dbeded965a 100644
--- a/theme/index.php
+++ b/theme/index.php
@@ -32,10 +32,10 @@ $unsettheme = optional_param('unsettheme', 0, PARAM_BOOL);
 admin_externalpage_setup('themeselector');
 
 if (!empty($device)) {
-    // Make sure the device requested is valid
-    $devices = get_device_type_list();
+    // Make sure the device requested is valid.
+    $devices = core_useragent::get_device_type_list();
     if (!in_array($device, $devices)) {
-        // The provided device isn't a valid device throw an error
+        // The provided device isn't a valid device throw an error.
         print_error('invaliddevicetype');
     }
 }
@@ -49,7 +49,7 @@ if ($reset and confirm_sesskey()) {
     // Load the theme to make sure it is valid.
     $theme = theme_config::load($choose);
     // Get the config argument for the chosen device.
-    $themename = get_device_cfg_var_name($device);
+    $themename = core_useragent::get_device_type_cfg_var_name($device);
     set_config($themename, $theme->name);
 
     // Create a new page for the display of the themes readme.
@@ -74,8 +74,8 @@ if ($reset and confirm_sesskey()) {
     echo $output->footer();
     exit;
 } else if ($device && $unsettheme && confirm_sesskey() && ($device != 'default')) {
-    //Unset the theme and continue.
-    unset_config(get_device_cfg_var_name($device));
+    // Unset the theme and continue.
+    unset_config(core_useragent::get_device_type_cfg_var_name($device));
     $device = '';
 }
 
@@ -92,15 +92,15 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) {
     $strthemenotselected = get_string('themenoselected', 'admin');
     $strthemeselect = get_string('themeselect', 'admin');
 
-    // Display the device selection screen
+    // Display the device selection screen.
     $table->id = 'admindeviceselector';
     $table->head = array(get_string('devicetype', 'admin'), get_string('currenttheme', 'admin'), get_string('info'));
 
-    $devices = get_device_type_list();
+    $devices = core_useragent::get_device_type_list();
     foreach ($devices as $thedevice) {
 
-        $headingthemename = ''; // To output the picked theme name when needed
-        $themename = get_selected_theme_for_device_type($thedevice);
+        $headingthemename = ''; // To output the picked theme name when needed.
+        $themename = core_useragent::get_device_type_theme($thedevice);
         if (!$themename && $thedevice == 'default') {
             $themename = theme_config::DEFAULT_THEME;
         }
@@ -108,24 +108,27 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) {
         $screenshotcell = $strthemenotselected;
         $unsetthemebutton = '';
         if ($themename) {
-            // Check the theme exists
+            // Check the theme exists.
             $themename = clean_param($themename, PARAM_THEME);
             if (empty($themename)) {
-                // Likely the theme has been deleted
-                unset_config(get_device_cfg_var_name($thedevice));
+                // Likely the theme has been deleted.
+                unset_config(core_useragent::get_device_type_cfg_var_name($thedevice));
             } else {
                 $strthemename = get_string('pluginname', 'theme_'.$themename);
-                // link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes, not the current one
-                $screenshoturl = new moodle_url('/theme/image.php', array('theme' => $themename, 'image' => 'screenshot', 'component' => 'theme'));
+                // Link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes,
+                // not the current one.
+                $screenshoturl = new moodle_url('/theme/image.php',
+                    array('theme' => $themename, 'image' => 'screenshot', 'component' => 'theme'));
                 // Contents of the screenshot/preview cell.
                 $screenshotcell = html_writer::empty_tag('img', array('src' => $screenshoturl, 'alt' => $strthemename));
-                // Show the name of the picked theme
+                // Show the name of the picked theme.
                 $headingthemename = $OUTPUT->heading($strthemename, 3);
             }
             // If not default device then show option to unset theme.
             if ($thedevice != 'default') {
                 $unsetthemestr = get_string('unsettheme', 'admin');
-                $unsetthemeurl = new moodle_url('/theme/index.php', array('device' => $thedevice, 'sesskey' => sesskey(), 'unsettheme' => true));
+                $unsetthemeurl = new moodle_url('/theme/index.php',
+                    array('device' => $thedevice, 'sesskey' => sesskey(), 'unsettheme' => true));
                 $unsetthemebutton = new single_button($unsetthemeurl, $unsetthemestr, 'get');
                 $unsetthemebutton = $OUTPUT->render($unsetthemebutton);
             }
@@ -145,8 +148,8 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) {
     // of themes to select.
     $heading = get_string('selecttheme', 'admin', $device);
     if (empty($device)) {
-        // if $CFG->enabledevicedetection is off this will return 'default'
-        $device = get_device_type();
+        // If $CFG->enabledevicedetection is off this will return 'default'.
+        $device = core_useragent::get_device_type();
     }
 
     $table->id = 'adminthemeselector';
@@ -164,7 +167,7 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) {
             continue;
         }
         if ($themename !== $theme->name) {
-            //obsoleted or broken theme, just skip for now
+            // Obsoleted or broken theme, just skip for now.
             continue;
         }
         if (empty($CFG->themedesignermode) && $theme->hidefromselector) {
@@ -179,31 +182,34 @@ if (!empty($CFG->enabledevicedetection) && empty($device)) {
         $infoitems = array();
         $rowclasses = array();
 
-        // Set up bools whether this theme is chosen either main or legacy
-        $ischosentheme = ($themename == get_selected_theme_for_device_type($device));
+        // Set up bools whether this theme is chosen either main or legacy.
+        $ischosentheme = ($themename == core_useragent::get_device_type_theme($device));
 
         if ($ischosentheme) {
-            // Is the chosen main theme
+            // Is the chosen main theme.
             $rowclasses[] = 'selectedtheme';
         }
 
-        // link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes, not the current one
-        $screenshotpath = new moodle_url('/theme/image.php', array('theme'=>$themename, 'image'=>'screenshot', 'component'=>'theme'));
+        // Link to the screenshot, now mandatory - the image path is hardcoded because we need image from other themes,
+        // not the current one.
+        $screenshotpath = new moodle_url('/theme/image.php',
+            array('theme'=>$themename, 'image'=>'screenshot', 'component'=>'theme'));
         // Contents of the first screenshot/preview cell.
         $row[] = html_writer::empty_tag('img', array('src'=>$screenshotpath, 'alt'=>$strthemename));
         // Contents of the second cell.
         $infocell = $OUTPUT->heading($strthemename, 3);
 
-        // Button to choose this as the main theme or unset this theme for
-        // devices other then default
+        // Button to choose this as the main theme or unset this theme for devices other then default.
         if (($ischosentheme) && ($device != 'default')) {
             $unsetthemestr = get_string('unsettheme', 'admin');
-            $unsetthemeurl = new moodle_url('/theme/index.php', array('device' => $device, 'unsettheme' => true, 'sesskey' => sesskey()));
+            $unsetthemeurl = new moodle_url('/theme/index.php',
+                array('device' => $device, 'unsettheme' => true, 'sesskey' => sesskey()));
             $unsetbutton = new single_button($unsetthemeurl, $unsetthemestr, 'get');
             $infocell .= $OUTPUT->render($unsetbutton);
         } else if ((!$ischosentheme)) {
             $setthemestr = get_string('usetheme');
-            $setthemeurl = new moodle_url('/theme/index.php', array('device' => $device, 'choose' => $themename, 'sesskey' => sesskey()));
+            $setthemeurl = new moodle_url('/theme/index.php',
+                array('device' => $device, 'choose' => $themename, 'sesskey' => sesskey()));
             $setthemebutton = new single_button($setthemeurl, $setthemestr, 'get');
             $infocell .= $OUTPUT->render($setthemebutton);
         }
diff --git a/theme/mymobile/config.php b/theme/mymobile/config.php
index c2b9cd2b81d..c162766fac8 100644
--- a/theme/mymobile/config.php
+++ b/theme/mymobile/config.php
@@ -142,10 +142,11 @@ $THEME->layouts = array(
 );
 
 // Get whether to show blocks and use appropriate pagelayout
-// this is necessary for block JS errors and other block problems
-$thisdevice = get_device_type();
-if ($thisdevice == "default" || $thisdevice == "tablet" || optional_param('mymobile_blocks', false, PARAM_BOOL)) {
-    // These are layouts with blocks
+// this is necessary for block JS errors and other block problems.
+$thisdevice = core_useragent::get_device_type();
+if ($thisdevice === core_useragent::DEVICETYPE_DEFAULT || $thisdevice === core_useragent::DEVICETYPE_TABLET ||
+    optional_param('mymobile_blocks', false, PARAM_BOOL)) {
+    // These are layouts with blocks.
     $blocklayouts = array('course', 'incourse', 'frontpage', 'mydashboard', 'mypublic');
     foreach ($blocklayouts as $layout) {
         $THEME->layouts[$layout]['regions'] = array('myblocks');
diff --git a/theme/switchdevice.php b/theme/switchdevice.php
index 084a1adaf82..213f0f3f4b0 100644
--- a/theme/switchdevice.php
+++ b/theme/switchdevice.php
@@ -31,6 +31,6 @@ $newdevice = required_param('device', PARAM_TEXT);
 
 require_sesskey();
 
-set_user_device_type($newdevice);
+core_useragent::set_user_device_type($newdevice);
 
 redirect($url);
diff --git a/version.php b/version.php
index c42ca0496cc..17a4b0d838d 100644
--- a/version.php
+++ b/version.php
@@ -29,11 +29,11 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2013081500.00;              // YYYYMMDD      = weekly release date of this DEV branch
-                                        //         RR    = release increments - 00 in DEV branches
-                                        //           .XX = incremental changes
+$version  = 2013081600.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+                                        //         RR    = release increments - 00 in DEV branches.
+                                        //           .XX = incremental changes.
 
-$release  = '2.6dev (Build: 20130815)'; // Human-friendly version name
+$release  = '2.6dev (Build: 20130808)'; // Human-friendly version name.
 
-$branch   = '26';                       // this version's branch
-$maturity = MATURITY_ALPHA;             // this version's maturity level
+$branch   = '26';                       // This version's branch.
+$maturity = MATURITY_ALPHA;             // This version's maturity level.