diff --git a/config/global.ini.php b/config/global.ini.php
index b246b8712718d0dcda61c6dce56c430655c5d057..69017538d9ec02f907fdbc8859c7c23959593f46 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -454,18 +454,6 @@ campaign_keyword_var_name = "pk_kwd,piwik_kwd,pk_keyword,utm_term"
 ; maximum length of a Page Title or a Page URL recorded in the log_action.name table
 page_maximum_length = 1024;
 
-; Anonymize a visitor's IP address after testing for "Ip exclude"
-; This value is the level of anonymization Piwik will use; if the IP anonymization is deactivated, this value is ignored.
-; For IPv4/IPv6 addresses, valid values are the number of octets in IP address to mask (from 0 to 4).
-; For IPv6 addresses 0..4 means that 0, 64, 80, 104 or all bits are masked.
-ip_address_mask_length = 1
-
-
-; Set this setting to 0 to let plugins use the full non-anonymized IP address when enriching visitor information.
-; When set to 1, by default, Geo Location via geoip and Provider reverse name lookups
-; will use the anonymized IP address when anonymization is enabled.
-use_anonymized_ip_for_visit_enrichment = 1
-
 ; Tracker cache files are the simple caching layer for Tracking.
 ; TTL: Time to live for cache files, in seconds. Default to 5 minutes.
 tracker_cache_file_ttl = 300
@@ -498,8 +486,20 @@ tracking_requests_require_authentication = 1
 delete_logs_enable = 0
 delete_logs_schedule_lowest_interval = 7
 delete_logs_older_than = 180
+delete_logs_max_rows_per_query = 100000
 enable_auto_database_size_estimate = 1
 
+[Deletereports]
+delete_reports_enable                = 0
+delete_reports_older_than            = 12
+delete_reports_keep_basic_metrics    = 1
+delete_reports_keep_day_reports      = 0
+delete_reports_keep_week_reports     = 0
+delete_reports_keep_month_reports    = 1
+delete_reports_keep_year_reports     = 1
+delete_reports_keep_range_reports    = 0
+delete_reports_keep_segment_reports  = 0
+
 [mail]
 defaultHostnameIfEmpty = defaultHostnameIfEmpty.example.org ; default Email @hostname, if current host can't be read from system variables
 transport = ; smtp (using the configuration below) or empty (using built-in mail() function)
diff --git a/core/Config.php b/core/Config.php
index 8f76eb7d72811bdc600f3369a32313805089a189..1da843e915299eca45d762fd6d63cfbd694bf33f 100644
--- a/core/Config.php
+++ b/core/Config.php
@@ -110,6 +110,7 @@ class Config extends Singleton
             $this->configCache['Segments'] = $this->configGlobal['Segments'];
             $this->configCache['Tracker'] = $this->configGlobal['Tracker'];
             $this->configCache['Deletelogs'] = $this->configGlobal['Deletelogs'];
+            $this->configCache['Deletereports'] = $this->configGlobal['Deletereports'];
         }
 
         // for unit tests, we set that no plugin is installed. This will force
@@ -128,7 +129,6 @@ class Config extends Singleton
 
         // to avoid weird session error in travis
         $this->configCache['General']['session_save_handler'] = 'dbtables';
-
     }
 
     /**
diff --git a/core/Plugin/ControllerAdmin.php b/core/Plugin/ControllerAdmin.php
index b4c017c62b146345e04f186f61a6811251db85cd..41c14ff67ba079d8c1ce02ff503b13a8f3516403 100644
--- a/core/Plugin/ControllerAdmin.php
+++ b/core/Plugin/ControllerAdmin.php
@@ -146,7 +146,7 @@ abstract class ControllerAdmin extends Controller
         NotificationManager::cancelAllNonPersistent();
     }
 
-    static protected function isDataPurgeSettingsEnabled()
+    static public function isDataPurgeSettingsEnabled()
     {
         return (bool) Config::getInstance()->General['enable_delete_old_data_settings_admin'];
     }
diff --git a/core/Tracker.php b/core/Tracker.php
index eef3543959f2adf7bfd9e79a0a988711bbe8ca74..311c6a68e79b620dfbe9cf2e145d98372bf570f2 100644
--- a/core/Tracker.php
+++ b/core/Tracker.php
@@ -16,6 +16,7 @@ use Piwik\Tracker\Db\Pdo\Mysql;
 use Piwik\Tracker\Request;
 use Piwik\Tracker\Visit;
 use Piwik\Tracker\VisitInterface;
+use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
 
 /**
  * Class used by the logging script piwik.php called by the javascript tag.
@@ -745,13 +746,14 @@ class Tracker
         }
 
         // Tests can force the enabling of IP anonymization
-        $forceIpAnonymization = false;
         if (Common::getRequestVar('forceIpAnonymization', false, null, $args) == 1) {
-            self::updateTrackerConfig('ip_address_mask_length', 2);
 
-            \Piwik\Plugins\PrivacyManager\IPAnonymizer::activate();
+            self::connectDatabaseIfNotConnected();
+
+            $privacyConfig = new PrivacyManagerConfig();
+            $privacyConfig->ipAddressMaskLength = 2;
 
-            $forceIpAnonymization = true;
+            \Piwik\Plugins\PrivacyManager\IPAnonymizer::activate();
         }
 
         // Custom IP to use for this visitor
@@ -775,7 +777,6 @@ class Tracker
 
         // Disable provider plugin, because it is so slow to do many reverse ip lookups
         self::setPluginsNotToLoad($pluginsDisabled);
-
     }
 
     /**
diff --git a/core/Updates/2.0.4-b8.php b/core/Updates/2.0.4-b8.php
index be19a93bf16efc9e668d03c7eaa982dc969b9795..ff5ac157188aa9863d83059f60ce45359b7b8e14 100644
--- a/core/Updates/2.0.4-b8.php
+++ b/core/Updates/2.0.4-b8.php
@@ -9,17 +9,12 @@
 
 namespace Piwik\Updates;
 
-use Piwik\Common;
-use Piwik\Date;
 use Piwik\Db;
-use Piwik\Option;
-use Piwik\Plugins\CoreAdminHome\CustomLogo;
-use Piwik\Plugins\UsersManager\API as UsersManagerApi;
-use Piwik\Plugins\MobileMessaging\MobileMessaging;
-use Piwik\Updater;
 use Piwik\Config;
-use Piwik\UpdaterErrorException;
 use Piwik\Updates;
+use Piwik\UpdaterErrorException;
+use Piwik\Plugins\CoreAdminHome\CustomLogo;
+use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
 
 /**
  */
@@ -33,26 +28,51 @@ class Updates_2_0_4_b8 extends Updates
     static function update()
     {
         try {
-            self::migrateBrandingConfigToDatabase();
+            $config = Config::getInstance();
+
+            self::migrateBrandingConfig($config);
+            self::migratePrivacyManagerConfig($config, new PrivacyManagerConfig());
+
+            $config->forceSave();
+
         } catch (\Exception $e) {
             throw new UpdaterErrorException($e->getMessage());
         }
     }
 
-    private static function migrateBrandingConfigToDatabase()
+    private static function migrateBrandingConfig(Config $config)
     {
-        $config = Config::getInstance();
+        $useCustomLogo = self::getValueAndDelete($config, 'branding', 'use_custom_logo');
+
+        $customLogo = new CustomLogo();
+        $useCustomLogo ? $customLogo->enable() : $customLogo->disable();
+    }
 
-        $branding = $config->branding;
+    private static function migratePrivacyManagerConfig(Config $oldConfig, PrivacyManagerConfig $newConfig)
+    {
+        $ipVisitEnrichment   = self::getValueAndDelete($oldConfig, 'Tracker', 'use_anonymized_ip_for_visit_enrichment');
+        $ipAddressMarkLength = self::getValueAndDelete($oldConfig, 'Tracker', 'ip_address_mask_length');
 
-        if (!empty($branding) && array_key_exists('use_custom_logo', $branding)) {
-            $useCustomLogo = $branding['use_custom_logo'];
+        if (null !== $ipVisitEnrichment) {
+            $newConfig->useAnonymizedIpForVisitEnrichment = $ipVisitEnrichment;
+        }
+        if (null !== $ipAddressMarkLength) {
+            $newConfig->ipAddressMaskLength = $ipAddressMarkLength;
+        }
+    }
 
-            $customLogo = new CustomLogo();
-            $useCustomLogo ? $customLogo->enable() : $customLogo->disable();
+    private static function getValueAndDelete(Config $config, $section, $key)
+    {
+        if (!$config->$section || !array_key_exists($key, $config->$section)) {
+            return null;
         }
 
-        $config->branding = array();
-        $config->forceSave();
+        $values = $config->$section;
+        $value  = $values[$key];
+        unset($values[$key]);
+
+        $config->$section = $values;
+
+        return $value;
     }
 }
diff --git a/plugins/PrivacyManager/Config.php b/plugins/PrivacyManager/Config.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e5c0d51566319f7f9ff909196e37c3223916a07
--- /dev/null
+++ b/plugins/PrivacyManager/Config.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\PrivacyManager;
+
+use Piwik\Option;
+use Piwik\Tracker\Cache;
+
+/**
+ * @property bool $doNotTrackEnabled    Enable / Disable Do Not Track {@see DoNotTrackHeaderChecker}
+ * @property bool $ipAnonymizerEnabled  Enable / Disable IP Anonymizer {@see IPAnonymizer}
+ * @property bool $useAnonymizedIpForVisitEnrichment Set this setting to 0 to let plugins use the full
+ *                                      non-anonymized IP address when enriching visitor information.
+ *                                      When set to 1, by default, Geo Location via geoip and Provider reverse name lookups
+ *                                      will use the anonymized IP address when anonymization is enabled.
+ * @property int  $ipAddressMaskLength  Anonymize a visitor's IP address after testing for "Ip exclude"
+ *                                      This value is the level of anonymization Piwik will use; if the IP
+ *                                      anonymization is deactivated, this value is ignored. For IPv4/IPv6 addresses,
+ *                                      valid values are the number of octets in IP address to mask (from 0 to 4).
+ *                                      For IPv6 addresses 0..4 means that 0, 64, 80, 104 or all bits are masked.
+ */
+class Config
+{
+    private $properties = array(
+        'useAnonymizedIpForVisitEnrichment' => array('type' => 'boolean', 'default' => true),
+        'ipAddressMaskLength'               => array('type' => 'integer', 'default' => 1),
+        'doNotTrackEnabled'                 => array('type' => 'boolean', 'default' => false),
+        'ipAnonymizerEnabled'               => array('type' => 'boolean', 'default' => false),
+    );
+
+    public function __set($name, $value)
+    {
+        if (!array_key_exists($name, $this->properties)) {
+            throw new \Exception(sprintf('Property %s does not exist', $name));
+        }
+
+        $this->set($name, $value, $this->properties[$name]);
+    }
+
+    public function __get($name)
+    {
+        if (!array_key_exists($name, $this->properties)) {
+            throw new \Exception(sprintf('Property %s does not exist', $name));
+        }
+
+        return $this->getFromTrackerCache($name, $this->properties[$name]);
+    }
+
+    private function prefix($optionName)
+    {
+        return 'PrivacyManager.' . $optionName;
+    }
+
+    private function getFromTrackerCache($name, $config)
+    {
+        $name  = $this->prefix($name);
+        $cache = Cache::getCacheGeneral();
+
+        if (array_key_exists($name, $cache)) {
+
+            $value = $cache[$name];
+            settype($value, $config['type']);
+            return $value;
+        }
+
+        return $config['default'];
+    }
+
+    private function getFromOption($name, $config)
+    {
+        $name  = $this->prefix($name);
+        $value = Option::get($name);
+
+        if (false !== $value) {
+            settype($value, $config['type']);
+        } else {
+            $value = $config['default'];
+        }
+
+        return $value;
+    }
+
+    private function set($name, $value, $config)
+    {
+        if ('boolean' == $config['type']) {
+            $value = $value ? '1' : '0';
+        } else {
+            settype($value, $config['type']);
+        }
+
+        Option::set($this->prefix($name), $value);
+        Cache::clearCacheGeneral();
+    }
+
+    public function setTrackerCacheGeneral($cacheContent)
+    {
+        foreach ($this->properties as $name => $config) {
+            $cacheContent[$this->prefix($name)] = $this->getFromOption($name, $config);
+        }
+
+        return $cacheContent;
+    }
+
+}
diff --git a/plugins/PrivacyManager/Controller.php b/plugins/PrivacyManager/Controller.php
index bda1c080b1ea381cbbeec8877a8cdce7493a5109..0ea3dffefd922def572a39fc1ec403c9118d1871 100644
--- a/plugins/PrivacyManager/Controller.php
+++ b/plugins/PrivacyManager/Controller.php
@@ -9,7 +9,7 @@
 namespace Piwik\Plugins\PrivacyManager;
 
 use Piwik\Common;
-use Piwik\Config;
+use Piwik\Config as PiwikConfig;
 use Piwik\Date;
 use Piwik\Db;
 use Piwik\MetricsFormatter;
@@ -39,11 +39,9 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
             switch (Common::getRequestVar('form')) {
                 case("formMaskLength"):
                     $this->handlePluginState(Common::getRequestVar("anonymizeIPEnable", 0));
-                    $trackerConfig = Config::getInstance()->Tracker;
-                    $trackerConfig['ip_address_mask_length'] = Common::getRequestVar("maskLength", 1);
-                    $trackerConfig['use_anonymized_ip_for_visit_enrichment'] = Common::getRequestVar("useAnonymizedIpForVisitEnrichment", 1);
-                    Config::getInstance()->Tracker = $trackerConfig;
-                    Config::getInstance()->forceSave();
+                    $privacyConfig = new Config();
+                    $privacyConfig->ipAddressMaskLength = Common::getRequestVar("maskLength", 1);
+                    $privacyConfig->useAnonymizedIpForVisitEnrichment = Common::getRequestVar("useAnonymizedIpForVisitEnrichment", 1);
                     break;
 
                 case("formDeleteSettings"):
@@ -91,15 +89,14 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
         $settings['delete_reports_enable'] = Common::getRequestVar("deleteReportsEnable", 0);
         $deleteReportsOlderThan = Common::getRequestVar("deleteReportsOlderThan", 3);
         $settings['delete_reports_older_than'] = $deleteReportsOlderThan < 3 ? 3 : $deleteReportsOlderThan;
-        $settings['delete_reports_keep_basic_metrics'] = Common::getRequestVar("deleteReportsKeepBasic", 0);
-        $settings['delete_reports_keep_day_reports'] = Common::getRequestVar("deleteReportsKeepDay", 0);
-        $settings['delete_reports_keep_week_reports'] = Common::getRequestVar("deleteReportsKeepWeek", 0);
-        $settings['delete_reports_keep_month_reports'] = Common::getRequestVar("deleteReportsKeepMonth", 0);
-        $settings['delete_reports_keep_year_reports'] = Common::getRequestVar("deleteReportsKeepYear", 0);
-        $settings['delete_reports_keep_range_reports'] = Common::getRequestVar("deleteReportsKeepRange", 0);
+        $settings['delete_reports_keep_basic_metrics']   = Common::getRequestVar("deleteReportsKeepBasic", 0);
+        $settings['delete_reports_keep_day_reports']     = Common::getRequestVar("deleteReportsKeepDay", 0);
+        $settings['delete_reports_keep_week_reports']    = Common::getRequestVar("deleteReportsKeepWeek", 0);
+        $settings['delete_reports_keep_month_reports']   = Common::getRequestVar("deleteReportsKeepMonth", 0);
+        $settings['delete_reports_keep_year_reports']    = Common::getRequestVar("deleteReportsKeepYear", 0);
+        $settings['delete_reports_keep_range_reports']   = Common::getRequestVar("deleteReportsKeepRange", 0);
         $settings['delete_reports_keep_segment_reports'] = Common::getRequestVar("deleteReportsKeepSegments", 0);
-
-        $settings['delete_logs_max_rows_per_query'] = PrivacyManager::DEFAULT_MAX_ROWS_PER_QUERY;
+        $settings['delete_logs_max_rows_per_query']      = PiwikConfig::getInstance()->Deletelogs['delete_logs_max_rows_per_query'];
 
         return $settings;
     }
@@ -130,7 +127,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
             $view->anonymizeIP = $this->getAnonymizeIPInfo();
             $view->dntSupport = DoNotTrackHeaderChecker::isActive();
             $view->canDeleteLogActions = Db::isLockPrivilegeGranted();
-            $view->dbUser = Config::getInstance()->database['username'];
+            $view->dbUser = PiwikConfig::getInstance()->database['username'];
             $view->deactivateNonce = Nonce::getNonce(self::DEACTIVATE_DNT_NONCE);
             $view->activateNonce   = Nonce::getNonce(self::ACTIVATE_DNT_NONCE);
         }
@@ -179,7 +176,7 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
             $settings = PrivacyManager::getPurgeDataSettings();
         }
 
-        $doDatabaseSizeEstimate = Config::getInstance()->Deletelogs['enable_auto_database_size_estimate'];
+        $doDatabaseSizeEstimate = PiwikConfig::getInstance()->Deletelogs['enable_auto_database_size_estimate'];
 
         // determine the DB size & purged DB size
         $metadataProvider = new MySQLMetadataProvider();
@@ -230,10 +227,10 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
         Piwik::checkUserHasSuperUserAccess();
         $anonymizeIP = array();
 
-        $trackerConfig = Config::getInstance()->Tracker;
+        $privacyConfig = new Config();
         $anonymizeIP["enabled"] = IpAnonymizer::isActive();
-        $anonymizeIP["maskLength"] = $trackerConfig['ip_address_mask_length'];
-        $anonymizeIP["useAnonymizedIpForVisitEnrichment"] = $trackerConfig['use_anonymized_ip_for_visit_enrichment'];
+        $anonymizeIP["maskLength"] = $privacyConfig->ipAddressMaskLength;
+        $anonymizeIP["useAnonymizedIpForVisitEnrichment"] = $privacyConfig->useAnonymizedIpForVisitEnrichment;
 
         return $anonymizeIP;
     }
diff --git a/plugins/PrivacyManager/DoNotTrackHeaderChecker.php b/plugins/PrivacyManager/DoNotTrackHeaderChecker.php
index a139f0b93ce9b8db714394c4186b359ced0c5ca0..0b20f323839af05f31c8861adce2528243badc3c 100644
--- a/plugins/PrivacyManager/DoNotTrackHeaderChecker.php
+++ b/plugins/PrivacyManager/DoNotTrackHeaderChecker.php
@@ -11,8 +11,6 @@ namespace Piwik\Plugins\PrivacyManager;
 use Piwik\Common;
 use Piwik\Tracker\IgnoreCookie;
 use Piwik\Tracker\Request;
-use Piwik\Tracker\Cache;
-use Piwik\Option;
 
 /**
  * Excludes visits where user agent's request contains either:
@@ -23,14 +21,12 @@ use Piwik\Option;
  */
 class DoNotTrackHeaderChecker
 {
-    const OPTION_NAME = "PrivacyManager.doNotTrackEnabled";
-
     /**
      * Checks for DoNotTrack headers and if found, sets `$exclude` to `true`.
      */
     public function checkHeaderInTracker(&$exclude)
     {
-        if (!$this->isActiveInTracker()
+        if (!$this->isActive()
             || $exclude
         ) {
             return;
@@ -60,31 +56,13 @@ class DoNotTrackHeaderChecker
         }
     }
 
-    /**
-     * Returns true if DoNotTrack header checking is enabled. This function is called by the
-     * Tracker.
-     */
-    private function isActiveInTracker()
-    {
-        $cache = Cache::getCacheGeneral();
-        return !empty($cache[self::OPTION_NAME]);
-    }
-
-    /**
-     * Caches the status of DoNotTrack checking (whether it is enabled or not).
-     */
-    public function setTrackerCacheGeneral(&$cacheContent)
-    {
-        $cacheContent[self::OPTION_NAME] = Option::get(self::OPTION_NAME);
-    }
-
     /**
      * Deactivates DoNotTrack header checking. This function will not be called by the Tracker.
      */
     public static function deactivate()
     {
-        Option::set(self::OPTION_NAME, 0);
-        Cache::clearCacheGeneral();
+        $config = new Config();
+        $config->doNotTrackEnabled = false;
     }
 
     /**
@@ -92,8 +70,8 @@ class DoNotTrackHeaderChecker
      */
     public static function activate()
     {
-        Option::set(self::OPTION_NAME, 1);
-        Cache::clearCacheGeneral();
+        $config = new Config();
+        $config->doNotTrackEnabled = true;
     }
 
     /**
@@ -103,7 +81,7 @@ class DoNotTrackHeaderChecker
      */
     public static function isActive()
     {
-        $active = Option::get(self::OPTION_NAME);
-        return !empty($active);
+        $config = new Config();
+        return $config->doNotTrackEnabled;
     }
 }
diff --git a/plugins/PrivacyManager/IPAnonymizer.php b/plugins/PrivacyManager/IPAnonymizer.php
index bf639e08c72eeb7b2bff5b922050b2942a69429a..9bff7c14d6d294c9db244747b9d683a21989e92c 100644
--- a/plugins/PrivacyManager/IPAnonymizer.php
+++ b/plugins/PrivacyManager/IPAnonymizer.php
@@ -9,19 +9,13 @@
 namespace Piwik\Plugins\PrivacyManager;
 
 use Piwik\Common;
-use Piwik\Config;
 use Piwik\IP;
-use Piwik\Tracker\Cache;
-use Piwik\Option;
 
 /**
  * Anonymize visitor IP addresses to comply with the privacy laws/guidelines in countries, such as Germany.
- *
  */
 class IPAnonymizer
 {
-    const OPTION_NAME = "PrivacyManager.ipAnonymizerEnabled";
-
     /**
      * Internal function to mask portions of the visitor IP address
      *
@@ -58,33 +52,17 @@ class IPAnonymizer
      */
     public function setVisitorIpAddress(&$ip)
     {
-
-        if (!$this->isActiveInTracker()) {
+        if (!$this->isActive()) {
             Common::printDebug("Visitor IP was _not_ anonymized: ". IP::N2P($ip));
             return;
         }
 
         $originalIp = $ip;
-        $ip = self::applyIPMask($ip, Config::getInstance()->Tracker['ip_address_mask_length']);
-        Common::printDebug("Visitor IP (was: ". IP::N2P($originalIp) .") has been anonymized: ". IP::N2P($ip));
-    }
 
-    /**
-     * Returns true if IP anonymization is enabled. This function is called by the
-     * Tracker.
-     */
-    private function isActiveInTracker()
-    {
-        $cache = Cache::getCacheGeneral();
-        return !empty($cache[self::OPTION_NAME]);
-    }
+        $privacyConfig = new Config();
 
-    /**
-     * Caches the status of IP anonymization (whether it is enabled or not).
-     */
-    public function setTrackerCacheGeneral(&$cacheContent)
-    {
-        $cacheContent[self::OPTION_NAME] = Option::get(self::OPTION_NAME);
+        $ip = self::applyIPMask($ip, $privacyConfig->ipAddressMaskLength);
+        Common::printDebug("Visitor IP (was: ". IP::N2P($originalIp) .") has been anonymized: ". IP::N2P($ip));
     }
 
     /**
@@ -92,8 +70,8 @@ class IPAnonymizer
      */
     public static function deactivate()
     {
-        Option::set(self::OPTION_NAME, 0);
-        Cache::clearCacheGeneral();
+        $privacyConfig = new Config();
+        $privacyConfig->ipAnonymizerEnabled = false;
     }
 
     /**
@@ -101,8 +79,8 @@ class IPAnonymizer
      */
     public static function activate()
     {
-        Option::set(self::OPTION_NAME, 1);
-        Cache::clearCacheGeneral();
+        $privacyConfig = new Config();
+        $privacyConfig->ipAnonymizerEnabled = true;
     }
 
     /**
@@ -112,7 +90,7 @@ class IPAnonymizer
      */
     public static function isActive()
     {
-        $active = Option::get(self::OPTION_NAME);
-        return !empty($active);
+        $privacyConfig = new Config();
+        return $privacyConfig->ipAnonymizerEnabled;
     }
 }
diff --git a/plugins/PrivacyManager/PrivacyManager.php b/plugins/PrivacyManager/PrivacyManager.php
index 4dc3013df5936971bd00c75a9b4da098a47a1e3a..d6908a61cd4bb835f3a868353607816982123860 100644
--- a/plugins/PrivacyManager/PrivacyManager.php
+++ b/plugins/PrivacyManager/PrivacyManager.php
@@ -10,12 +10,11 @@ namespace Piwik\Plugins\PrivacyManager;
 
 use Exception;
 use Piwik\Common;
-use Piwik\Config;
+use Piwik\Config as PiwikConfig;
 use Piwik\DataTable\DataTableInterface;
 use Piwik\Date;
 use Piwik\Db;
 use Piwik\Menu\MenuAdmin;
-
 use Piwik\Metrics;
 use Piwik\Option;
 use Piwik\Period\Range;
@@ -23,7 +22,6 @@ use Piwik\Period;
 use Piwik\Piwik;
 use Piwik\Plugins\Goals\Archiver;
 use Piwik\ScheduledTask;
-use Piwik\ScheduledTime\Daily;
 use Piwik\ScheduledTime;
 use Piwik\Site;
 use Piwik\Tracker\GoalManager;
@@ -45,23 +43,23 @@ class PrivacyManager extends \Piwik\Plugin
     const OPTION_LAST_DELETE_PIWIK_LOGS = "lastDelete_piwik_logs";
     const OPTION_LAST_DELETE_PIWIK_REPORTS = 'lastDelete_piwik_reports';
     const OPTION_LAST_DELETE_PIWIK_LOGS_INITIAL = "lastDelete_piwik_logs_initial";
-    const DEFAULT_MAX_ROWS_PER_QUERY = 100000;
-
-    // default config options for data purging feature
-    public static $defaultPurgeDataOptions = array(
-        'delete_logs_enable'                   => 0,
-        'delete_logs_schedule_lowest_interval' => 7,
-        'delete_logs_older_than'               => 180,
-        'delete_logs_max_rows_per_query'       => self::DEFAULT_MAX_ROWS_PER_QUERY,
-        'delete_reports_enable'                => 0,
-        'delete_reports_older_than'            => 12,
-        'delete_reports_keep_basic_metrics'    => 1,
-        'delete_reports_keep_day_reports'      => 0,
-        'delete_reports_keep_week_reports'     => 0,
-        'delete_reports_keep_month_reports'    => 1,
-        'delete_reports_keep_year_reports'     => 1,
-        'delete_reports_keep_range_reports'    => 0,
-        'delete_reports_keep_segment_reports'  => 0,
+
+    // options for data purging feature array[configName => configSection]
+    public static $purgeDataOptions = array(
+        'delete_logs_enable'                   => 'Deletelogs',
+        'delete_logs_schedule_lowest_interval' => 'Deletelogs',
+        'delete_logs_older_than'               => 'Deletelogs',
+        'delete_logs_max_rows_per_query'       => 'Deletelogs',
+        'enable_auto_database_size_estimate'   => 'Deletelogs',
+        'delete_reports_enable'                => 'Deletereports',
+        'delete_reports_older_than'            => 'Deletereports',
+        'delete_reports_keep_basic_metrics'    => 'Deletereports',
+        'delete_reports_keep_day_reports'      => 'Deletereports',
+        'delete_reports_keep_week_reports'     => 'Deletereports',
+        'delete_reports_keep_month_reports'    => 'Deletereports',
+        'delete_reports_keep_year_reports'     => 'Deletereports',
+        'delete_reports_keep_range_reports'    => 'Deletereports',
+        'delete_reports_keep_segment_reports'  => 'Deletereports',
     );
 
     private $dntChecker = null;
@@ -152,8 +150,8 @@ class PrivacyManager extends \Piwik\Plugin
 
     public function setTrackerCacheGeneral(&$cacheContent)
     {
-        $this->ipAnonymizer->setTrackerCacheGeneral($cacheContent);
-        $this->dntChecker->setTrackerCacheGeneral($cacheContent);
+        $config       = new Config();
+        $cacheContent = $config->setTrackerCacheGeneral($cacheContent);
     }
 
     public function getScheduledTasks(&$tasks)
@@ -195,37 +193,20 @@ class PrivacyManager extends \Piwik\Plugin
         $settings = array();
 
         // load settings from ini config
-        try {
-            $oldSettings = array(
-                'enable_auto_database_size_estimate',
-
-                // backwards compatibility: load old values in ini config if present
-                'delete_logs_enable',
-                'delete_logs_schedule_lowest_interval',
-                'delete_logs_older_than',
-            );
-
-            $deleteLogsSettings = Config::getInstance()->Deletelogs;
-            foreach ($oldSettings as $settingName) {
-                $settings[$settingName] = $deleteLogsSettings[$settingName];
-            }
-        } catch (Exception $e) {
-            // ignore
+        $config = PiwikConfig::getInstance();
+        foreach (self::$purgeDataOptions as $configKey => $configSection) {
+            $settings[$configKey] = $config->$configSection[$configKey];
+        }
+
+        if (!Controller::isDataPurgeSettingsEnabled()) {
+            return $settings;
         }
 
         // load the settings for the data purging settings
-        foreach (self::$defaultPurgeDataOptions as $optionName => $defaultValue) {
-            $value = Option::get($optionName);
+        foreach (self::$purgeDataOptions as $configName => $configSection) {
+            $value = Option::get($configName);
             if ($value !== false) {
-                $settings[$optionName] = $value;
-            } else {
-                // if the option hasn't been set/created, use the default value
-                if (!isset($settings[$optionName])) {
-                    $settings[$optionName] = $defaultValue;
-                }
-
-                // option is not saved in the DB, so save it now
-                Option::set($optionName, $settings[$optionName]);
+                $settings[$configName] = $value;
             }
         }
 
@@ -239,9 +220,9 @@ class PrivacyManager extends \Piwik\Plugin
      */
     public static function savePurgeDataSettings($settings)
     {
-        foreach (self::$defaultPurgeDataOptions as $optionName => $defaultValue) {
-            if (isset($settings[$optionName])) {
-                Option::set($optionName, $settings[$optionName]);
+        foreach (self::$purgeDataOptions as $configName => $configSection) {
+            if (isset($settings[$configName])) {
+                Option::set($configName, $settings[$configName]);
             }
         }
     }
diff --git a/plugins/Provider/Provider.php b/plugins/Provider/Provider.php
index fc737e51583597ea905c0afbae7f4be58fda0f03..4e9b2c62cfb21a5c1fb2c90ace97fdae4075f541 100644
--- a/plugins/Provider/Provider.php
+++ b/plugins/Provider/Provider.php
@@ -19,6 +19,7 @@ use Piwik\IP;
 use Piwik\Menu\MenuMain;
 use Piwik\Piwik;
 use Piwik\Plugin\ViewDataTable;
+use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
 use Piwik\WidgetsList;
 
 /**
@@ -115,7 +116,8 @@ class Provider extends \Piwik\Plugin
             return;
         }
 
-        $ip = IP::N2P(Config::getInstance()->Tracker['use_anonymized_ip_for_visit_enrichment'] == 1 ? $visitorInfo['location_ip'] : $request->getIp());
+        $privacyConfig = new PrivacyManagerConfig();
+        $ip = IP::N2P($privacyConfig->useAnonymizedIpForVisitEnrichment ? $visitorInfo['location_ip'] : $request->getIp());
 
         // In case the IP was anonymized, we should not continue since the DNS reverse lookup will fail and this will slow down tracking
         if (substr($ip, -2, 2) == '.0') {
diff --git a/plugins/SecurityInfo b/plugins/SecurityInfo
index 2d1f5e5a70ddcf5e7a88514c07b9e0ef501051ef..cd98a60c785ce56b45e4d142e9af3a470619a60b 160000
--- a/plugins/SecurityInfo
+++ b/plugins/SecurityInfo
@@ -1 +1 @@
-Subproject commit 2d1f5e5a70ddcf5e7a88514c07b9e0ef501051ef
+Subproject commit cd98a60c785ce56b45e4d142e9af3a470619a60b
diff --git a/plugins/TasksTimetable b/plugins/TasksTimetable
index 2646ac6b7856fc46e20a0213a5467cd6cd7c7313..f6e252d5dc5e3cf004263f7450c2ca55bd2c5a71 160000
--- a/plugins/TasksTimetable
+++ b/plugins/TasksTimetable
@@ -1 +1 @@
-Subproject commit 2646ac6b7856fc46e20a0213a5467cd6cd7c7313
+Subproject commit f6e252d5dc5e3cf004263f7450c2ca55bd2c5a71
diff --git a/plugins/TreemapVisualization b/plugins/TreemapVisualization
index 19978cb7cd926ec0fba111ce257b8f0450f34ce8..2cb15300a88f7ff2a1fc27ef633a1a1f4d5fef09 160000
--- a/plugins/TreemapVisualization
+++ b/plugins/TreemapVisualization
@@ -1 +1 @@
-Subproject commit 19978cb7cd926ec0fba111ce257b8f0450f34ce8
+Subproject commit 2cb15300a88f7ff2a1fc27ef633a1a1f4d5fef09
diff --git a/plugins/UserCountry/UserCountry.php b/plugins/UserCountry/UserCountry.php
index dcfadff81bb338d43477dd7464b17e6f4786c3d6..d74bde1e34e6687034103cfbc1d97436816ae295 100644
--- a/plugins/UserCountry/UserCountry.php
+++ b/plugins/UserCountry/UserCountry.php
@@ -17,9 +17,9 @@ use Piwik\Menu\MenuMain;
 use Piwik\Piwik;
 use Piwik\Plugin\ViewDataTable;
 use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
-
 use Piwik\Plugins\UserCountry\LocationProvider;
 use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
+use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
 use Piwik\Url;
 use Piwik\WidgetsList;
 
@@ -83,7 +83,9 @@ class UserCountry extends \Piwik\Plugin
     {
         require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php";
 
-        $ipAddress = IP::N2P(Config::getInstance()->Tracker['use_anonymized_ip_for_visit_enrichment'] == 1 ? $visitorInfo['location_ip'] : $request->getIp());
+        $privacyConfig = new PrivacyManagerConfig();
+
+        $ipAddress = IP::N2P($privacyConfig->useAnonymizedIpForVisitEnrichment ? $visitorInfo['location_ip'] : $request->getIp());
         $userInfo = array(
             'lang' => $visitorInfo['location_browser_lang'],
             'ip' => $ipAddress
diff --git a/plugins/VisitorGenerator b/plugins/VisitorGenerator
index 6cd5e94ca5cca57ed5132b9f929d7a952e41041e..0e0066e5358aea60026b8f53bd7a33e854dbb67a 160000
--- a/plugins/VisitorGenerator
+++ b/plugins/VisitorGenerator
@@ -1 +1 @@
-Subproject commit 6cd5e94ca5cca57ed5132b9f929d7a952e41041e
+Subproject commit 0e0066e5358aea60026b8f53bd7a33e854dbb67a
diff --git a/tests/PHPUnit/Integration/Plugins/PrivacyManagerConfigTest.php b/tests/PHPUnit/Integration/Plugins/PrivacyManagerConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c63f6b18f5434a551e0c60c8618b3c566f22c13c
--- /dev/null
+++ b/tests/PHPUnit/Integration/Plugins/PrivacyManagerConfigTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+use \Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
+use \Piwik\Option;
+
+/**
+ * Class Plugins_SitesManagerTest
+ *
+ * @group Plugins
+ */
+class Plugins_PrivacyManagerConfigTest extends DatabaseTestCase
+{
+    /**
+     * @var PrivacyManagerConfig
+     */
+    private $config;
+
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->config = new PrivacyManagerConfig();
+    }
+
+    public function test_useAnonymizedIpForVisitEnrichment()
+    {
+        $this->assertTrue($this->config->useAnonymizedIpForVisitEnrichment);
+
+        $this->config->useAnonymizedIpForVisitEnrichment = false;
+
+        $this->assertFalse($this->config->useAnonymizedIpForVisitEnrichment);
+
+        $this->config->useAnonymizedIpForVisitEnrichment = true;
+
+        $this->assertTrue($this->config->useAnonymizedIpForVisitEnrichment);
+    }
+
+    public function test_doNotTrackEnabled()
+    {
+        $this->assertFalse($this->config->doNotTrackEnabled);
+
+        $this->config->doNotTrackEnabled = true;
+
+        $this->assertTrue($this->config->doNotTrackEnabled);
+
+        $this->config->doNotTrackEnabled = false;
+
+        $this->assertFalse($this->config->doNotTrackEnabled);
+    }
+
+    public function test_ipAnonymizerEnabled()
+    {
+        $this->assertFalse($this->config->ipAnonymizerEnabled);
+
+        $this->config->ipAnonymizerEnabled = true;
+
+        $this->assertTrue($this->config->ipAnonymizerEnabled);
+    }
+
+    public function test_ipAddressMaskLength()
+    {
+        $this->assertSame(1, $this->config->ipAddressMaskLength);
+
+        $this->config->ipAddressMaskLength = '19';
+
+        $this->assertSame(19, $this->config->ipAddressMaskLength);
+    }
+
+    public function test_setTrackerCacheContent()
+    {
+        $content = $this->config->setTrackerCacheGeneral(array('existingEntry' => 'test'));
+
+        $expected = array(
+            'existingEntry' => 'test',
+            'PrivacyManager.ipAddressMaskLength' => 1,
+            'PrivacyManager.ipAnonymizerEnabled' => false,
+            'PrivacyManager.doNotTrackEnabled'   => false,
+            'PrivacyManager.useAnonymizedIpForVisitEnrichment' => true,
+        );
+
+        $this->assertEquals($expected, $content);
+    }
+
+    public function test_setTrackerCacheContent_ShouldGetValuesFromConfig()
+    {
+        Option::set('PrivacyManager.ipAddressMaskLength', '232');
+
+        $content = $this->config->setTrackerCacheGeneral(array('existingEntry' => 'test'));
+
+        $this->assertEquals(232, $content['PrivacyManager.ipAddressMaskLength']);
+    }
+
+}
diff --git a/tests/PHPUnit/UI b/tests/PHPUnit/UI
index abd6aff5abe8582bf69a6afd2a7cdaf583a55295..ba9eecdcc8be1a0a3114c99e9810b9b98ff15afb 160000
--- a/tests/PHPUnit/UI
+++ b/tests/PHPUnit/UI
@@ -1 +1 @@
-Subproject commit abd6aff5abe8582bf69a6afd2a7cdaf583a55295
+Subproject commit ba9eecdcc8be1a0a3114c99e9810b9b98ff15afb