diff --git a/core/Tracker/Cache.php b/core/Tracker/Cache.php
index 7319818e4129048365eb104c2a727ac08a676b6d..2acf983c78d0953aae9c08ffbd2ecfacac7641db 100644
--- a/core/Tracker/Cache.php
+++ b/core/Tracker/Cache.php
@@ -15,7 +15,6 @@ use Piwik\Config;
 use Piwik\Piwik;
 use Piwik\CacheFile;
 use Piwik\Tracker;
-use Piwik\Plugins\UserCountry\LocationProvider;
 
 /**
  * Simple cache mechanism used in Tracker to avoid requesting settings from mysql on every request
@@ -104,8 +103,8 @@ class Cache
         $cacheContent = array(
             'isBrowserTriggerEnabled'   => Rules::isBrowserTriggerEnabled(),
             'lastTrackerCronRun'        => Piwik_GetOption('lastTrackerCronRun'),
-            'currentLocationProviderId' => LocationProvider::getCurrentProviderId(),
         );
+        Piwik_PostEvent('Tracker.setTrackerCacheGeneral', array(&$cacheContent));
         self::setCacheGeneral($cacheContent);
         return $cacheContent;
     }
diff --git a/core/Tracker/Request.php b/core/Tracker/Request.php
index 068709024531a9ba3fc5aee634abbfd555ed27df..e81838b23331e3d4cf28d88a549b180f3a8a5992 100644
--- a/core/Tracker/Request.php
+++ b/core/Tracker/Request.php
@@ -8,7 +8,6 @@ use Piwik\Cookie;
 use Piwik\IP;
 use Piwik\Tracker;
 use Piwik\Tracker\Cache;
-use Piwik\Plugins\UserCountry\LocationProvider;
 
 /**
  * Piwik - Open source web analytics
@@ -483,29 +482,29 @@ class Request
         return $this->forcedVisitorId;
     }
 
-    public function enrichLocation($location)
+    public function overrideLocation(&$visitorInfo)
     {
         if (!$this->isAuthenticated()) {
-            return $location;
+            return;
         }
 
         // check for location override query parameters (ie, lat, long, country, region, city)
         static $locationOverrideParams = array(
-            'country' => array('string', LocationProvider::COUNTRY_CODE_KEY),
-            'region'  => array('string', LocationProvider::REGION_CODE_KEY),
-            'city'    => array('string', LocationProvider::CITY_NAME_KEY),
-            'lat'     => array('float', LocationProvider::LATITUDE_KEY),
-            'long'    => array('float', LocationProvider::LONGITUDE_KEY),
+            'country' => array('string', 'location_country'),
+            'region'  => array('string', 'location_region'),
+            'city'    => array('string', 'location_city'),
+            'lat'     => array('float', 'location_latitude'),
+            'long'    => array('float', 'location_longitude'),
         );
         foreach ($locationOverrideParams as $queryParamName => $info) {
-            list($type, $locationResultKey) = $info;
+            list($type, $visitorInfoKey) = $info;
 
             $value = Common::getRequestVar($queryParamName, false, $type, $this->params);
             if (!empty($value)) {
-                $location[$locationResultKey] = $value;
+                $visitorInfo[$visitorInfoKey] = $value;
             }
         }
-        return $location;
+        return;
     }
 
     public function getPlugins()
diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php
index f051658bba79098a8358035c3029e8cd50f3ab8a..3f3d7588ec7b5fc1ae7d719f2249816b992231ff 100644
--- a/core/Tracker/Visit.php
+++ b/core/Tracker/Visit.php
@@ -39,7 +39,6 @@ use Piwik\Tracker\Request;
 use Piwik\Tracker\Referrer;
 use Exception;
 use Piwik\Tracker\VisitExcluded;
-use Piwik\Plugins\UserCountry\LocationProvider;
 use UserAgentParser;
 
 /**
@@ -477,10 +476,6 @@ class Visit implements Tracker\VisitInterface
             'location_browser_lang'     => $userInfo['location_browser_lang'],
         );
 
-        // add optional location components
-        $location = $this->getVisitorLocation($userInfo['location_browser_lang']);
-        $this->updateVisitInfoWithLocation($location);
-
         // Add Custom variable key,value to the visitor array
         $this->visitorInfo = array_merge($this->visitorInfo, $this->visitorCustomVariables);
 
@@ -489,6 +484,8 @@ class Visit implements Tracker\VisitInterface
         );
         Piwik_PostEvent('Tracker.newVisitorInformation', array(&$this->visitorInfo, $extraInfo));
 
+        $this->request->overrideLocation($this->visitorInfo);
+
         $debugVisitInfo = $this->visitorInfo;
         $debugVisitInfo['idvisitor'] = bin2hex($debugVisitInfo['idvisitor']);
         $debugVisitInfo['config_id'] = bin2hex($debugVisitInfo['config_id']);
@@ -510,77 +507,6 @@ class Visit implements Tracker\VisitInterface
         return $t;
     }
 
-    /**
-     * Returns the location of the visitor, based on the visitor's IP and browser language.
-     *
-     * @param string $browserLang
-     * @return array See LocationProvider::getLocation for more info.
-     */
-    private function getVisitorLocation($browserLang)
-    {
-        $location = array();
-        $userInfo = array('lang' => $browserLang, 'ip' => IP::N2P($this->getVisitorIp()));
-        Piwik_PostEvent('Tracker.getVisitorLocation', array(&$location, $userInfo));
-
-        $location = $this->request->enrichLocation($location);
-
-        if (empty($location['country_code'])) // sanity check
-        {
-            $location['country_code'] = self::UNKNOWN_CODE;
-        }
-
-        return $location;
-    }
-
-    /**
-     * Sets visitor info array with location info.
-     *
-     * @param array $location See LocationProvider::getLocation for more info.
-     */
-    private function updateVisitInfoWithLocation($location)
-    {
-        static $logVisitToLowerLocationMapping = array(
-            'location_country' => LocationProvider::COUNTRY_CODE_KEY,
-        );
-
-        static $logVisitToLocationMapping = array(
-            'location_region'    => LocationProvider::REGION_CODE_KEY,
-            'location_city'      => LocationProvider::CITY_NAME_KEY,
-            'location_latitude'  => LocationProvider::LATITUDE_KEY,
-            'location_longitude' => LocationProvider::LONGITUDE_KEY,
-        );
-
-        foreach ($logVisitToLowerLocationMapping as $column => $locationKey) {
-            if (!empty($location[$locationKey])) {
-                $this->visitorInfo[$column] = strtolower($location[$locationKey]);
-            }
-        }
-
-        foreach ($logVisitToLocationMapping as $column => $locationKey) {
-            if (!empty($location[$locationKey])) {
-                $this->visitorInfo[$column] = $location[$locationKey];
-            }
-        }
-
-        // if the location has provider/organization info, set it
-        if (!empty($location[LocationProvider::ISP_KEY])) {
-            $providerValue = $location[LocationProvider::ISP_KEY];
-
-            // if the org is set and not the same as the isp, add it to the provider value
-            if (!empty($location[LocationProvider::ORG_KEY])
-                && $location[LocationProvider::ORG_KEY] != $providerValue
-            ) {
-                $providerValue .= ' - ' . $location[LocationProvider::ORG_KEY];
-            }
-        } else if (!empty($location[LocationProvider::ORG_KEY])) {
-            $providerValue = $location[LocationProvider::ORG_KEY];
-        }
-
-        if (isset($providerValue)) {
-            $this->visitorInfo['location_provider'] = $providerValue;
-        }
-    }
-
     /**
      * Save new visitor information to log_visit table.
      * Provides pre- and post- event hooks (Tracker.saveVisitorInformation and Tracker.saveVisitorInformation.end) for plugins
diff --git a/plugins/UserCountry/UserCountry.php b/plugins/UserCountry/UserCountry.php
index cf5bbfdd687b8a0b055da4e4450c5f253bb0de7c..b4b5adc658c6cfba381374708ca1dbc9f8273860 100644
--- a/plugins/UserCountry/UserCountry.php
+++ b/plugins/UserCountry/UserCountry.php
@@ -15,6 +15,7 @@ use Piwik\Common;
 use Piwik\Piwik;
 use Piwik\WidgetsList;
 use Piwik\Url;
+use Piwik\IP;
 use Piwik\Plugins\UserCountry\Archiver;
 use Piwik\Plugins\UserCountry\GeoIPAutoUpdater;
 use Piwik\Plugins\UserCountry\LocationProvider;
@@ -48,14 +49,20 @@ class UserCountry extends \Piwik\Plugin
             'API.getSegmentsMetadata'                  => 'getSegmentsMetadata',
             'AssetManager.getStylesheetFiles'          => 'getStylesheetFiles',
             'AssetManager.getJsFiles'                  => 'getJsFiles',
-            'Tracker.getVisitorLocation'               => 'getVisitorLocation',
+            'Tracker.newVisitorInformation'            => 'getVisitorLocation',
             'TaskScheduler.getScheduledTasks'          => 'getScheduledTasks',
             'ViewDataTable.getReportDisplayProperties' => 'getReportDisplayProperties',
             'Translate.getClientSideTranslationKeys'   => 'getClientSideTranslationKeys',
+            'Tracker.setTrackerCacheGeneral'           => 'setTrackerCacheGeneral'
         );
         return $hooks;
     }
 
+    public function setTrackerCacheGeneral(&$cache)
+    {
+        $cache['currentLocationProviderId'] = LocationProvider::getCurrentProviderId();
+    }
+
     public function getScheduledTasks(&$tasks)
     {
         // add the auto updater task
@@ -72,10 +79,17 @@ class UserCountry extends \Piwik\Plugin
         $jsFiles[] = "plugins/UserCountry/javascripts/userCountry.js";
     }
 
-    public function getVisitorLocation(&$location, $visitorInfo)
+    public function getVisitorLocation(&$visitorInfo, $extraInfo)
     {
         require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php";
 
+        $userInfo = array(
+            'lang' => $visitorInfo['location_browser_lang'],
+            'ip' => IP::N2P($visitorInfo['location_ip'])
+        );
+
+        $location = array();
+
         $id = Common::getCurrentLocationProviderId();
         $provider = LocationProvider::getProviderById($id);
         if ($provider === false) {
@@ -84,17 +98,74 @@ class UserCountry extends \Piwik\Plugin
             Common::printDebug("GEO: no current location provider sent, falling back to default '$id' one.");
         }
 
-        $location = $provider->getLocation($visitorInfo);
+        $location = $provider->getLocation($userInfo);
 
         // if we can't find a location, use default provider
         if ($location === false) {
             $defaultId = DefaultProvider::ID;
             $provider = LocationProvider::getProviderById($defaultId);
-            $location = $provider->getLocation($visitorInfo);
+            $location = $provider->getLocation($userInfo);
             Common::printDebug("GEO: couldn't find a location with Geo Module '$id', using Default '$defaultId' provider as fallback...");
             $id = $defaultId;
         }
         Common::printDebug("GEO: Found IP location (provider '" . $id . "'): " . var_export($location, true));
+
+        if (empty($location['country_code'])) { // sanity check
+            $location['country_code'] = \Piwik\Tracker\Visit::UNKNOWN_CODE;
+        }
+
+        // add optional location components
+        $this->updateVisitInfoWithLocation($visitorInfo, $location);
+    }
+
+    /**
+     * Sets visitor info array with location info.
+     *
+     * @param array $visitorInfo
+     * @param array $location See LocationProvider::getLocation for more info.
+     */
+    private function updateVisitInfoWithLocation(&$visitorInfo, $location)
+    {
+        static $logVisitToLowerLocationMapping = array(
+            'location_country' => LocationProvider::COUNTRY_CODE_KEY,
+        );
+
+        static $logVisitToLocationMapping = array(
+            'location_region'    => LocationProvider::REGION_CODE_KEY,
+            'location_city'      => LocationProvider::CITY_NAME_KEY,
+            'location_latitude'  => LocationProvider::LATITUDE_KEY,
+            'location_longitude' => LocationProvider::LONGITUDE_KEY,
+        );
+
+        foreach ($logVisitToLowerLocationMapping as $column => $locationKey) {
+            if (!empty($location[$locationKey])) {
+                $visitorInfo[$column] = strtolower($location[$locationKey]);
+            }
+        }
+
+        foreach ($logVisitToLocationMapping as $column => $locationKey) {
+            if (!empty($location[$locationKey])) {
+                $visitorInfo[$column] = $location[$locationKey];
+            }
+        }
+
+        // if the location has provider/organization info, set it
+        if (!empty($location[LocationProvider::ISP_KEY])) {
+            $providerValue = $location[LocationProvider::ISP_KEY];
+
+            // if the org is set and not the same as the isp, add it to the provider value
+            if (!empty($location[LocationProvider::ORG_KEY])
+                && $location[LocationProvider::ORG_KEY] != $providerValue
+            ) {
+                $providerValue .= ' - ' . $location[LocationProvider::ORG_KEY];
+            }
+        } else if (!empty($location[LocationProvider::ORG_KEY])) {
+            $providerValue = $location[LocationProvider::ORG_KEY];
+        }
+
+        if (isset($providerValue)) {
+            $visitorInfo['location_provider'] = $providerValue;
+        }
     }
 
     public function addWidgets()
diff --git a/tests/PHPUnit/BaseFixture.php b/tests/PHPUnit/BaseFixture.php
index ccf516fc40dd12d9fff39e20ada6bfd6d5c5f179..ff2cb74a61a6f28d04db4823e9fb076ffa07c2f6 100644
--- a/tests/PHPUnit/BaseFixture.php
+++ b/tests/PHPUnit/BaseFixture.php
@@ -18,6 +18,7 @@ use Piwik\Plugins\UsersManager\API as APIUsersManager;
 use Piwik\ReportRenderer;
 use Piwik\Site;
 use Piwik\Url;
+use Piwik\Db;
 
 /**
  * Base type for all integration test fixtures. Integration test fixtures
@@ -75,7 +76,7 @@ abstract class Test_Piwik_BaseFixture extends PHPUnit_Framework_Assert
         );
 
         // Manually set the website creation date to a day earlier than the earliest day we record stats for
-        \Zend_Registry::get('db')->update(Common::prefixTable("site"),
+        Db::get()->update(Common::prefixTable("site"),
             array('ts_created' => Date::factory($dateTime)->subDay(1)->getDatetime()),
             "idsite = $idSite"
         );
@@ -178,6 +179,9 @@ abstract class Test_Piwik_BaseFixture extends PHPUnit_Framework_Assert
      */
     public static function checkBulkTrackingResponse($response) {
         $data = json_decode($response, true);
+        if (!is_array($data)) {
+            echo "Bulk tracking response is not an array: " . var_export($data, true) . "\n";
+        }
         self::assertArrayHasKey('status', $data);
         self::assertEquals('success', $data['status']);
     }
diff --git a/tests/PHPUnit/Integration/OneVisitorOneWebsite_SeveralDaysDateRange_ArchivingTestsTest.php b/tests/PHPUnit/Integration/OneVisitorOneWebsite_SeveralDaysDateRange_ArchivingTestsTest.php
index 685cb731cbda127fca87d1d8a057dad8f105ab74..d796ca165567794ec19cfcc73c81c5e3ac86edfd 100755
--- a/tests/PHPUnit/Integration/OneVisitorOneWebsite_SeveralDaysDateRange_ArchivingTestsTest.php
+++ b/tests/PHPUnit/Integration/OneVisitorOneWebsite_SeveralDaysDateRange_ArchivingTestsTest.php
@@ -7,6 +7,7 @@
  */
 use Piwik\Piwik;
 use Piwik\Common;
+use Piwik\Db;
 
 /**
  * Tests some API using range periods & makes sure the correct amount of blob/numeric
@@ -100,10 +101,10 @@ class Test_Piwik_Integration_OneVisitorOneWebsite_SeveralDaysDateRange_Archiving
         );
         foreach ($tests as $table => $expectedRows) {
             $sql = "SELECT count(*) FROM " . Common::prefixTable($table) . " WHERE period = " . Piwik::$idPeriods['range'];
-            $countBlobs = \Zend_Registry::get('db')->fetchOne($sql);
+            $countBlobs = Db::get()->fetchOne($sql);
 
             if($expectedRows != $countBlobs) {
-                var_export(Zend_Registry::get('db')->fetchAll("SELECT * FROM " . Common::prefixTable($table). " WHERE period = " . Piwik::$idPeriods['range'] . " ORDER BY idarchive ASC"));
+                var_export(Db::get()->fetchAll("SELECT * FROM " . Common::prefixTable($table). " WHERE period = " . Piwik::$idPeriods['range'] . " ORDER BY idarchive ASC"));
             }
             $this->assertEquals($expectedRows, $countBlobs, "$table expected $expectedRows, got $countBlobs");
         }
diff --git a/tests/PHPUnit/Integration/TwoVisitsWithCustomVariables_SegmentMatchVisitorTypeTest.php b/tests/PHPUnit/Integration/TwoVisitsWithCustomVariables_SegmentMatchVisitorTypeTest.php
index 26a0c87605814b55a566e6aa8ce111bcc7e51cb9..74b24e01c87a6548c02abd52b4f930085c07245c 100755
--- a/tests/PHPUnit/Integration/TwoVisitsWithCustomVariables_SegmentMatchVisitorTypeTest.php
+++ b/tests/PHPUnit/Integration/TwoVisitsWithCustomVariables_SegmentMatchVisitorTypeTest.php
@@ -6,6 +6,7 @@
  * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  */
 use Piwik\Common;
+use Piwik\Db;
 
 /**
  * Tests use of custom variable segments.
@@ -87,10 +88,10 @@ class Test_Piwik_Integration_TwoVisitsWithCustomVariables_SegmentMatchVisitorTyp
         );
         foreach ($tests as $table => $expectedRows) {
             $sql = "SELECT count(*) FROM " . Common::prefixTable($table);
-            $countBlobs = \Zend_Registry::get('db')->fetchOne($sql);
+            $countBlobs = Db::get()->fetchOne($sql);
 
             if($expectedRows != $countBlobs) {
-                var_export(Zend_Registry::get('db')->fetchAll("SELECT * FROM " . Common::prefixTable($table) . " ORDER BY name, idarchive ASC"));
+                var_export(Db::get()->fetchAll("SELECT * FROM " . Common::prefixTable($table) . " ORDER BY name, idarchive ASC"));
             }
             $this->assertEquals($expectedRows, $countBlobs, "$table: %s");
         }
@@ -104,5 +105,4 @@ class Test_Piwik_Integration_TwoVisitsWithCustomVariables_SegmentMatchVisitorTyp
 
 Test_Piwik_Integration_TwoVisitsWithCustomVariables_SegmentMatchVisitorType::$fixture
     = new Test_Piwik_Fixture_TwoVisitsWithCustomVariables();
-Test_Piwik_Integration_TwoVisitsWithCustomVariables_SegmentMatchVisitorType::$fixture->doExtraQuoteTests = false;
-
+Test_Piwik_Integration_TwoVisitsWithCustomVariables_SegmentMatchVisitorType::$fixture->doExtraQuoteTests = false;
\ No newline at end of file
diff --git a/tests/PHPUnit/Integration/UrlNormalizationTest.php b/tests/PHPUnit/Integration/UrlNormalizationTest.php
index 64046122cd5a5e563852274c302aba23f3a6af72..fb67f0269d3da5c305ec6e758c1074f56a594fb1 100644
--- a/tests/PHPUnit/Integration/UrlNormalizationTest.php
+++ b/tests/PHPUnit/Integration/UrlNormalizationTest.php
@@ -1,6 +1,7 @@
 <?php
 use Piwik\Common;
 use Piwik\Tracker\Action;
+use Piwik\Db;
 
 /**
  * Tests the URL normalization.
@@ -87,14 +88,14 @@ class Test_Piwik_Integration_UrlNormalization extends IntegrationTestCase
     public function testCheckPostConditions()
     {
         $sql = "SELECT count(*) FROM " . Common::prefixTable('log_action');
-        $count = \Zend_Registry::get('db')->fetchOne($sql);
+        $count = Db::get()->fetchOne($sql);
         $expected = 9; // 4 urls + 5 titles
         $this->assertEquals($expected, $count, "only $expected actions expected");
 
         $sql = "SELECT name, url_prefix FROM " . Common::prefixTable('log_action')
             . " WHERE type = " . Action::TYPE_ACTION_URL
             . " ORDER BY idaction ASC";
-        $urls = \Zend_Registry::get('db')->fetchAll($sql);
+        $urls = Db::get()->fetchAll($sql);
         $expected = array(
             array('name' => 'example.org/foo/bar.html', 'url_prefix' => 0),
             array('name' => 'example.org/foo/bar2.html', 'url_prefix' => 3),
diff --git a/tests/PHPUnit/UITest.php b/tests/PHPUnit/UITest.php
index bf2bbc0032b22484b1e1edc2b6bb2ef9d1867ea1..d90516c292a26cbe3a405989ae23deb3cf5f29b7 100644
--- a/tests/PHPUnit/UITest.php
+++ b/tests/PHPUnit/UITest.php
@@ -10,6 +10,7 @@ use Piwik\AssetManager;
 use Piwik\Date;
 use Piwik\DbHelper;
 use Piwik\Plugins\VisitsSummary\API;
+use Piwik\Db;
 
 abstract class UITest extends IntegrationTestCase
 {
@@ -93,7 +94,7 @@ abstract class UITest extends IntegrationTestCase
 
         self::removeRecursiveLinks();
 
-        if (!Zend_Registry::get('db')) {
+        if (!Db::get()) {
             DbHelper::createDatabaseObject();
         }
 
@@ -106,7 +107,7 @@ abstract class UITest extends IntegrationTestCase
     {
         parent::setUp();
         
-        if (!Zend_Registry::get('db')) {
+        if (!Db::get()) {
             DbHelper::createDatabaseObject();
         }
     }
@@ -115,8 +116,7 @@ abstract class UITest extends IntegrationTestCase
     {
         parent::tearDown();
         
-        \Zend_Registry::get('db')->closeConnection();
-        \Zend_Registry::set('db', false);
+        Db::get()->closeConnection();
     }
     
     private static function runCaptureProgram($urlInfo)