diff --git a/core/Archive.php b/core/Archive.php
index ebe0516a294dbed5c4e1dbdb7e3893a833e02845..4f4717f0918a37edb18ba755c112e7a761c93dba 100644
--- a/core/Archive.php
+++ b/core/Archive.php
@@ -41,7 +41,6 @@
  */
 class Piwik_Archive
 {
-    const FLAG_ALL_WEBSITES_REQUESTED = 'all';
     /**
      * When saving DataTables in the DB, we sometimes replace the columns name by these IDs so we save up lots of bytes
      * Eg. INDEX_NB_UNIQ_VISITORS is an integer: 4 bytes, but 'nb_uniq_visitors' is 16 bytes at least
@@ -103,6 +102,8 @@ class Piwik_Archive
     const INDEX_GOAL_ECOMMERCE_REVENUE_DISCOUNT = 7;
     const INDEX_GOAL_ECOMMERCE_ITEMS = 8;
 
+    const REQUEST_ALL_WEBSITES_FLAG = 'all';
+
     public static function getVisitsMetricNames()
     {
         $names = array();
@@ -308,7 +309,7 @@ class Piwik_Archive
             $allPeriods = array($oPeriod);
         }
         $segment = new Piwik_Segment($segment, $websiteIds);
-        $idSiteIsAll = $idSites == self::FLAG_ALL_WEBSITES_REQUESTED;
+        $idSiteIsAll = $idSites == self::REQUEST_ALL_WEBSITES_FLAG;
         return Piwik_Archive::factory($segment, $allPeriods, $websiteIds, $idSiteIsAll);
     }
 
@@ -516,7 +517,7 @@ class Piwik_Archive
             return $result;
         }
         
-        $archiveData = Piwik_DataAccess_Archiver::getArchiveData($archiveIds, $archiveNames, $archiveDataType, $idSubtable);
+        $archiveData = Piwik_DataAccess_ArchiveSelector::getArchiveData($archiveIds, $archiveNames, $archiveDataType, $idSubtable);
         foreach ($archiveData as $row) {
             // values are grouped by idsite (site ID), date1-date2 (date range), then name (field name)
             $idSite = $row['idsite'];
@@ -669,7 +670,7 @@ class Piwik_Archive
      */
     private function cacheArchiveIdsWithoutLaunching($plugins)
     {
-        $idarchivesByReport = Piwik_DataAccess_Archiver::getArchiveIds(
+        $idarchivesByReport = Piwik_DataAccess_ArchiveSelector::getArchiveIds(
             $this->params->getIdSites(), $this->params->getPeriods(), $this->params->getSegment(), $plugins);
         
         // initialize archive ID cache for each report
diff --git a/core/ArchiveProcessor.php b/core/ArchiveProcessor.php
index 9791735d0e0f077bd6b447855e94116f61268043..c475177ee13e96a140c785f2642d968e7f7eb7b4 100644
--- a/core/ArchiveProcessor.php
+++ b/core/ArchiveProcessor.php
@@ -10,21 +10,8 @@
  */
 
 /**
- * The ArchiveProcessor module is a module that reads the Piwik logs from the DB and
- * compute all the reports, which are then stored in the database.
- *
  * The ArchiveProcessor class is used by the Archive object to make sure the given Archive is processed and available in the DB.
  *
- * A record in the Database for a given report is defined by
- * - idarchive    = unique ID that is associated to all the data of this archive (idsite+period+date)
- * - idsite        = the ID of the website
- * - date1        = starting day of the period
- * - date2        = ending day of the period
- * - period    = integer that defines the period (day/week/etc.). @see period::getId()
- * - ts_archived = timestamp when the archive was processed (UTC)
- * - name        = the name of the report (ex: uniq_visitors or search_keywords_by_search_engines)
- * - value        = the actual data
- *
  * @package Piwik
  * @subpackage Piwik_ArchiveProcessor
  */
@@ -74,13 +61,6 @@ abstract class Piwik_ArchiveProcessor
      */
     protected $tableArchiveBlob;
 
-    /**
-     * Minimum timestamp looked at for processed archives
-     *
-     * @var int
-     */
-    protected $minDatetimeArchiveProcessedUTC = false;
-
     /**
      * Is the current archive temporary. ie.
      * - today
@@ -88,13 +68,35 @@ abstract class Piwik_ArchiveProcessor
      */
     protected $temporaryArchive;
 
+    protected $logAggregator = null;
+
     /**
-     * This methods reads the subperiods if necessary,
-     * and computes the archive of the current period.
+     * @var int Number of visits cached as early as possible
      */
-    abstract protected function compute();
+    protected $visitsMetricCached = false;
 
-    abstract protected function aggregateCoreVisitsMetrics();
+    /**
+     * @var int Number of visits with conversions, cached when selecting
+     */
+    protected $convertedVisitsMetricCached = false;
+
+    /**
+     * Site of the current archive
+     * Can be accessed by plugins (that is why it's public)
+     *
+     * @var Piwik_Site
+     */
+    private $site = null;
+
+    /**
+     * @var Piwik_Period
+     */
+    private $period = null;
+
+    /**
+     * @var Piwik_Segment
+     */
+    private $segment = null;
 
     public function __construct(Piwik_Period $period, Piwik_Site $site, Piwik_Segment $segment)
     {
@@ -103,65 +105,146 @@ abstract class Piwik_ArchiveProcessor
         $this->segment = $segment;
     }
 
-    protected $logAggregator = null;
-
     /**
      * @return Piwik_DataAccess_LogAggregator
      */
     public function getLogAggregator()
     {
-        if(empty($this->logAggregator)) {
-            $this->logAggregator = new Piwik_DataAccess_LogAggregator(  $this->getPeriod()->getDateStart(), $this->getPeriod()->getDateEnd(),
-                $this->getSite(), $this->getSegment() );
+        if (empty($this->logAggregator)) {
+            $this->logAggregator = new Piwik_DataAccess_LogAggregator($this->getPeriod()->getDateStart(), $this->getPeriod()->getDateEnd(),
+                $this->getSite(), $this->getSegment());
         }
         return $this->logAggregator;
     }
 
+    public function preProcessArchive($requestedPlugin, $enforceProcessCoreMetricsOnly = false)
+    {
+        $this->idArchive = false;
+
+        $this->setRequestedPlugin($requestedPlugin);
+
+        if (!$enforceProcessCoreMetricsOnly) {
+            $this->idArchive = $this->loadExistingArchiveIdFromDb($requestedPlugin);
+            if ($this->isArchivingForcedToTrigger()) {
+                $this->idArchive = false;
+                $this->setNumberOfVisits(false);
+            }
+            if (!empty($this->idArchive)) {
+                return $this->idArchive;
+            }
+
+            $visitsNotKnownYet = $this->getNumberOfVisits() === false;
+
+            $createAnotherArchiveForVisitsSummary = !$this->doesRequestedPluginIncludeVisitsSummary($requestedPlugin) && $visitsNotKnownYet;
+
+            if ($createAnotherArchiveForVisitsSummary) {
+                // recursive archive creation in case we create another separate one, for VisitsSummary core metrics
+                // We query VisitsSummary here, as it is needed in the call below ($this->getNumberOfVisits() > 0)
+                $requestedPlugin = $this->getRequestedPlugin();
+                $this->preProcessArchive('VisitsSummary', $pleaseProcessCoreMetricsOnly = true);
+                $this->setRequestedPlugin($requestedPlugin);
+                if ($this->getNumberOfVisits() === false) {
+                    throw new Exception("preProcessArchive() is expected to set number of visits to a numeric value.");
+                }
+            }
+        }
+
+        return $this->computeNewArchive($requestedPlugin, $enforceProcessCoreMetricsOnly);
+    }
+
+    public function setRequestedPlugin($plugin)
+    {
+        $this->requestedPlugin = $plugin;
+    }
+
     /**
-     * Returns the minimum archive processed datetime to look at
-     *
-     * @return string Datetime string, or false if must look at any archive available
+     * Returns the idArchive if the archive is available in the database for the requested plugin.
+     * Returns false if the archive needs to be processed.
      *
-     * @public for tests
+     * @return int|false
      */
-    public function getMinTimeArchivedProcessed()
+    protected function loadExistingArchiveIdFromDb($requestedPlugin)
     {
+        $minDatetimeArchiveProcessedUTC = $this->getMinTimeArchivedProcessed();
         $site = $this->getSite();
-        $segment = $this->getSegment();
         $period = $this->getPeriod();
-        $dateStart = $this->getDateStart();
-        $dateEnd = $this->getDateEnd();
+        $segment = $this->getSegment();
+        $numericTableName = $this->getTableArchiveNumericName();
 
+        $idAndVisits = Piwik_DataAccess_ArchiveSelector::getArchiveIdAndVisits($numericTableName, $site, $period, $segment, $minDatetimeArchiveProcessedUTC, $requestedPlugin);
+        if (!$idAndVisits) {
+            return false;
+        }
+        list($idArchive, $visits, $visitsConverted) = $idAndVisits;
+        $this->setNumberOfVisits($visits, $visitsConverted);
+        return $idArchive;
+    }
+
+    protected static function determineIfArchivePermanent(Piwik_Date $dateEnd)
+    {
         $now = time();
         $endTimestampUTC = strtotime($dateEnd->getDateEndUTC());
         if ($endTimestampUTC <= $now) {
             // - if the period we are looking for is finished, we look for a ts_archived that
             //   is greater than the last day of the archive
-            $this->temporaryArchive = false;
             return $endTimestampUTC;
         }
+        return false;
+    }
 
-        $this->temporaryArchive = true;
-
-        $minimumArchiveTime = $now - Piwik_ArchiveProcessor_Rules::getTodayArchiveTimeToLive();
+    /**
+     * Returns the minimum archive processed datetime to look at
+     *
+     * @return string Datetime string, or false if must look at any archive available
+     *
+     * @public for tests
+     */
+    public function getMinTimeArchivedProcessed()
+    {
 
-        $isArchivingDisabled = Piwik_ArchiveProcessor_Rules::isArchivingDisabledFor($segment, $period->getLabel());
+        $endDateTimestamp = self::determineIfArchivePermanent($this->getDateEnd());
+        $isArchiveTemporary = ($endDateTimestamp === false);
+        $this->temporaryArchive = $isArchiveTemporary;
 
-        if ($isArchivingDisabled) {
-            if ($endTimestampUTC > $now
-                && $period->getNumberOfSubperiods() == 0
-                && $dateStart->getTimestamp() <= $now
-            ) {
-                $minimumArchiveTime = false;
-            } else {
-                // However, if archiving is disabled for this request, we shall
-                // accept any archive that was processed today after 00:00:01 this morning
-                $timezone = $site->getTimezone();
-                $minimumArchiveTime = Piwik_Date::factory(Piwik_Date::factory('now', $timezone)->getDateStartUTC())->setTimezone($timezone)->getTimestamp();
-            }
+        if($endDateTimestamp) {
+            // Permanent archive
+            return $endDateTimestamp;
         }
+        // Temporary archive
+        return Piwik_ArchiveProcessor_Rules::getMinTimeProcessedForTemporaryArchive($this->getDateStart(), $this->getPeriod(), $this->getSegment(), $this->getSite());
+    }
+
+    /**
+     * @return Piwik_Date
+     */
+    public function getDateStart()
+    {
+        return $this->getPeriod()->getDateStart()->setTimezone($this->getSite()->getTimezone());
+    }
 
-        return $minimumArchiveTime;
+    /**
+     * @return Piwik_Date
+     */
+    public function getDateEnd()
+    {
+        return $this->getPeriod()->getDateEnd()->setTimezone($this->getSite()->getTimezone());
+    }
+
+    /**
+     * A flag mechanism to store whether
+     * @param $visitsMetricCached
+     * @param bool $convertedVisitsMetricCached
+     */
+    protected function setNumberOfVisits($visitsMetricCached, $convertedVisitsMetricCached = false)
+    {
+        if (empty($visitsMetricCached)) {
+            $visitsMetricCached = 0;
+        }
+        if (empty($convertedVisitsMetricCached)) {
+            $convertedVisitsMetricCached = 0;
+        }
+        $this->visitsMetricCached = (int)$visitsMetricCached;
+        $this->convertedVisitsMetricCached = (int)$convertedVisitsMetricCached;
     }
 
     protected function isArchivingForcedToTrigger()
@@ -176,39 +259,9 @@ abstract class Piwik_ArchiveProcessor
         return Piwik_Config::getInstance()->Debug[$debugSetting];
     }
 
-    public function preProcessArchive($requestedPlugin, $enforceProcessCoreMetricsOnly = false)
+    public function getNumberOfVisits()
     {
-        $this->idArchive = false;
-
-        $this->setRequestedPlugin($requestedPlugin);
-
-        if( !$enforceProcessCoreMetricsOnly ) {
-            $this->idArchive = $this->loadExistingArchiveIdFromDb($requestedPlugin);
-            if ($this->isArchivingForcedToTrigger()) {
-                $this->idArchive = false;
-                $this->setNumberOfVisits(false);
-            }
-            if (!empty($this->idArchive)) {
-                return $this->idArchive;
-            }
-
-            $visitsNotKnownYet = $this->getNumberOfVisits() === false;
-
-            $createAnotherArchiveForVisitsSummary = !$this->doesRequestedPluginIncludeVisitsSummary($requestedPlugin) && $visitsNotKnownYet;
-
-            if ($createAnotherArchiveForVisitsSummary) {
-                // recursive archive creation in case we create another separate one, for VisitsSummary core metrics
-                // We query VisitsSummary here, as it is needed in the call below ($this->getNumberOfVisits() > 0)
-                $requestedPlugin = $this->getRequestedPlugin();
-                $this->preProcessArchive('VisitsSummary', $pleaseProcessCoreMetricsOnly = true);
-                $this->setRequestedPlugin($requestedPlugin);
-                if($this->getNumberOfVisits() === false) {
-                    throw new Exception("preProcessArchive() is expected to set number of visits to a numeric value.");
-                }
-            }
-        }
-
-        return $this->computeNewArchive($requestedPlugin, $enforceProcessCoreMetricsOnly);
+        return $this->visitsMetricCached;
     }
 
     protected function doesRequestedPluginIncludeVisitsSummary($requestedPlugin)
@@ -226,11 +279,9 @@ abstract class Piwik_ArchiveProcessor
      */
     protected function computeNewArchive($requestedPlugin, $enforceProcessCoreMetricsOnly)
     {
-        if (!Piwik_DataAccess_Archiver::getArchiveProcessorLock($this->getSite()->getId(), $this->getPeriod(), $this->getSegment())) {
-            Piwik::log('SELECT GET_LOCK(?, 1) FAILED to acquire lock. Proceeding anyway...');
-        }
+        Piwik_DataAccess_ArchiveSelector::getArchiveProcessorLock($this->getSite()->getId(), $this->getPeriod(), $this->getSegment());
 
-        $this->idArchive = Piwik_DataAccess_Archiver::allocateNewArchiveId($this->getTableArchiveNumericName(), $this->getSite()->getId());
+        $this->idArchive = Piwik_DataAccess_ArchiveSelector::allocateNewArchiveId($this->getTableArchiveNumericName(), $this->getSite()->getId());
 
         $doneFlag = Piwik_ArchiveProcessor_Rules::getDoneStringFlagFor($this->getSegment(), $this->getPeriod()->getLabel(), $requestedPlugin);
         $this->insertNumericRecord($doneFlag, Piwik_ArchiveProcessor::DONE_ERROR);
@@ -250,19 +301,7 @@ abstract class Piwik_ArchiveProcessor
             }
         }
 
-        $temporary = 'definitive archive';
-        if ($this->isArchiveTemporary()) {
-            $temporary = 'temporary archive';
-        }
-        Piwik::log(sprintf("'%s, idSite = %d (%s), segment '%s', report = '%s', UTC datetime [%s -> %s]",
-            $this->getPeriod()->getLabel(),
-            $this->getSite()->getId(),
-            $temporary,
-            $this->getSegment()->getString(),
-            $requestedPlugin,
-            $this->getDateStart()->getDateStartUTC(),
-            $this->getDateEnd()->getDateEndUTC()
-        ));
+        $this->logStatus($requestedPlugin);
 
         if ($this->getNumberOfVisits() > 0
             && !$enforceProcessCoreMetricsOnly
@@ -270,7 +309,7 @@ abstract class Piwik_ArchiveProcessor
             $this->compute();
         }
 
-        Piwik_DataAccess_Archiver::deletePreviousArchiveStatus($this->getTableArchiveNumericName(), $doneFlag, $this->getIdArchive());
+        Piwik_DataAccess_ArchiveSelector::deletePreviousArchiveStatus($this->getTableArchiveNumericName(), $doneFlag, $this->getIdArchive());
 
         $flag = Piwik_ArchiveProcessor::DONE_OK;
         if ($this->isArchiveTemporary()) {
@@ -278,77 +317,54 @@ abstract class Piwik_ArchiveProcessor
         }
         $this->insertNumericRecord($doneFlag, $flag);
 
-        Piwik_DataAccess_Archiver::releaseArchiveProcessorLock($this->getSite()->getId(), $this->getPeriod(), $this->getSegment());
+        Piwik_DataAccess_ArchiveSelector::releaseArchiveProcessorLock($this->getSite()->getId(), $this->getPeriod(), $this->getSegment());
 
         return $this->idArchive;
     }
 
-    /**
-     * Returns the name of the numeric table where the archive numeric values are stored
-     *
-     * @return string
-     */
-    public function getTableArchiveNumericName()
-    {
-        if (empty($this->tableArchiveNumeric)) {
-            $this->tableArchiveNumeric = new Piwik_TablePartitioning_Monthly('archive_numeric');
-            $this->tableArchiveNumeric->setTimestamp($this->getPeriod()->getDateStart()->getTimestamp());
-        }
-        return $this->tableArchiveNumeric->getTableName();
-    }
+    abstract protected function aggregateCoreVisitsMetrics();
 
     /**
-     * Returns the name of the blob table where the archive blob values are stored
-     *
-     * @return string
+     * @param $requestedPlugin
      */
-    public function getTableArchiveBlobName()
+    protected function logStatus($requestedPlugin)
     {
-        if (empty($this->tableArchiveBlob)) {
-            $this->tableArchiveBlob = new Piwik_TablePartitioning_Monthly('archive_blob');
-            $this->tableArchiveBlob->setTimestamp($this->getPeriod()->getDateStart()->getTimestamp());
+        $temporary = 'definitive archive';
+        if ($this->isArchiveTemporary()) {
+            $temporary = 'temporary archive';
         }
-        return $this->tableArchiveBlob->getTableName();
-    }
-
-    public function setRequestedPlugin($plugin)
-    {
-        $this->requestedPlugin = $plugin;
+        Piwik::log(sprintf("'%s, idSite = %d (%s), segment '%s', report = '%s', UTC datetime [%s -> %s]",
+            $this->getPeriod()->getLabel(),
+            $this->getSite()->getId(),
+            $temporary,
+            $this->getSegment()->getString(),
+            $requestedPlugin,
+            $this->getDateStart()->getDateStartUTC(),
+            $this->getDateEnd()->getDateEndUTC()
+        ));
     }
 
-    protected function getRequestedPlugin()
+    public function isArchiveTemporary()
     {
-        return $this->requestedPlugin;
+        return $this->temporaryArchive;
     }
 
-    protected $visitsMetricCached = false;
-    protected $convertedVisitsMetricCached = false;
-
     /**
-     * A flag mechanism to store whether
-     * @param $visitsMetricCached
-     * @param bool $convertedVisitsMetricCached
+     * This methods reads the subperiods if necessary,
+     * and computes the archive of the current period.
      */
-    protected function setNumberOfVisits($visitsMetricCached, $convertedVisitsMetricCached = false)
-    {
-        if (empty($visitsMetricCached)) {
-            $visitsMetricCached = 0;
-        }
-        if (empty($convertedVisitsMetricCached)) {
-            $convertedVisitsMetricCached = 0;
-        }
-        $this->visitsMetricCached = (int)$visitsMetricCached;
-        $this->convertedVisitsMetricCached = (int)$convertedVisitsMetricCached;
-    }
+    abstract protected function compute();
 
-    public function getNumberOfVisits()
+    public function getNumberOfVisitsConverted()
     {
-        return $this->visitsMetricCached;
+        return $this->convertedVisitsMetricCached;
     }
 
-    public function getNumberOfVisitsConverted()
+    public function insertNumericRecords($numericRecords)
     {
-        return $this->convertedVisitsMetricCached;
+        foreach ($numericRecords as $name => $value) {
+            $this->insertNumericRecord($name, $value);
+        }
     }
 
     /**
@@ -361,13 +377,6 @@ abstract class Piwik_ArchiveProcessor
         return $this->insertRecord($name, $value);
     }
 
-    public function insertNumericRecords($numericRecords)
-    {
-        foreach ($numericRecords as $name => $value) {
-            $this->insertNumericRecord($name, $value);
-        }
-    }
-
     /**
      * @param string $name
      * @param string|array $values
@@ -441,21 +450,6 @@ abstract class Piwik_ArchiveProcessor
         return true;
     }
 
-    protected function getInsertRecordBind()
-    {
-        return array($this->getIdArchive(),
-                     $this->getSite()->getId(),
-                     $this->getPeriod()->getDateStart()->toString('Y-m-d'),
-                     $this->getPeriod()->getDateEnd()->toString('Y-m-d'),
-                     $this->getPeriod()->getId(),
-                     date("Y-m-d H:i:s"));
-    }
-
-    protected function getInsertFields()
-    {
-        return array('idarchive', 'idsite', 'date1', 'date2', 'period', 'ts_archived', 'name', 'value');
-    }
-
     /**
      * Inserts a record in the right table (either NUMERIC or BLOB)
      *
@@ -466,7 +460,7 @@ abstract class Piwik_ArchiveProcessor
      */
     protected function insertRecord($name, $value)
     {
-        if($this->isRecordZero($name, $value)) {
+        if ($this->isRecordZero($name, $value)) {
             return;
         }
 
@@ -481,6 +475,7 @@ abstract class Piwik_ArchiveProcessor
         $bindSql[] = $name;
         $bindSql[] = $value;
         Piwik_Query($query, $bindSql);
+        return true;
     }
 
     /**
@@ -504,73 +499,56 @@ abstract class Piwik_ArchiveProcessor
     }
 
     /**
-     * Returns the idArchive if the archive is available in the database for the requested plugin.
-     * Returns false if the archive needs to be processed.
+     * Returns the name of the numeric table where the archive numeric values are stored
      *
-     * @return int|false
+     * @return string
      */
-    protected function loadExistingArchiveIdFromDb($requestedPlugin)
+    public function getTableArchiveNumericName()
     {
-        $minDatetimeArchiveProcessedUTC = $this->getMinTimeArchivedProcessed();
-        $site = $this->getSite();
-        $period = $this->getPeriod();
-        $segment = $this->getSegment();
-        $numericTableName = $this->getTableArchiveNumericName();
-
-        $idAndVisits = Piwik_DataAccess_Archiver::getArchiveIdAndVisits($numericTableName, $site, $period, $segment, $minDatetimeArchiveProcessedUTC, $requestedPlugin);
-        if (!$idAndVisits) {
-            return false;
+        if (empty($this->tableArchiveNumeric)) {
+            $this->tableArchiveNumeric = new Piwik_TablePartitioning_Monthly('archive_numeric');
+            $this->tableArchiveNumeric->setTimestamp($this->getPeriod()->getDateStart()->getTimestamp());
         }
-        list($idArchive, $visits, $visitsConverted) = $idAndVisits;
-        $this->setNumberOfVisits($visits, $visitsConverted);
-        return $idArchive;
+        return $this->tableArchiveNumeric->getTableName();
     }
 
-    /**
-     * Whether the specified plugin's reports should be archived
-     * @param string $pluginName
-     * @return bool
-     */
-    public function shouldProcessReportsForPlugin($pluginName)
+    public function getPeriod()
     {
-        if (Piwik_ArchiveProcessor_Rules::shouldProcessReportsAllPlugins($this->getSegment(), $this->getPeriod()->getLabel())) {
-            return true;
-        }
-        // If any other segment, only process if the requested report belong to this plugin
-        $pluginBeingProcessed = $this->getRequestedPlugin();
-        if ($pluginBeingProcessed == $pluginName) {
-            return true;
-        }
-        if (!Piwik_PluginsManager::getInstance()->isPluginLoaded($pluginBeingProcessed)) {
-            return true;
-        }
-        return false;
+        return $this->period;
     }
 
     /**
-     * Site of the current archive
-     * Can be accessed by plugins (that is why it's public)
+     * Returns the name of the blob table where the archive blob values are stored
      *
-     * @var Piwik_Site
+     * @return string
      */
-    private $site = null;
+    public function getTableArchiveBlobName()
+    {
+        if (empty($this->tableArchiveBlob)) {
+            $this->tableArchiveBlob = new Piwik_TablePartitioning_Monthly('archive_blob');
+            $this->tableArchiveBlob->setTimestamp($this->getPeriod()->getDateStart()->getTimestamp());
+        }
+        return $this->tableArchiveBlob->getTableName();
+    }
 
-    /**
-     * @var Piwik_Period
-     */
-    private $period = null;
+    protected function getInsertFields()
+    {
+        return array('idarchive', 'idsite', 'date1', 'date2', 'period', 'ts_archived', 'name', 'value');
+    }
 
-    /**
-     * @var Piwik_Segment
-     */
-    private $segment = null;
+    protected function getInsertRecordBind()
+    {
+        return array($this->getIdArchive(),
+                     $this->getSite()->getId(),
+                     $this->getPeriod()->getDateStart()->toString('Y-m-d'),
+                     $this->getPeriod()->getDateEnd()->toString('Y-m-d'),
+                     $this->getPeriod()->getId(),
+                     date("Y-m-d H:i:s"));
+    }
 
-    /**
-     * @return Piwik_Segment
-     */
-    public function getSegment()
+    public function getIdArchive()
     {
-        return $this->segment;
+        return $this->idArchive;
     }
 
     /**
@@ -581,34 +559,37 @@ abstract class Piwik_ArchiveProcessor
         return $this->site;
     }
 
-    public function getPeriod()
-    {
-        return $this->period;
-    }
-
     /**
-     * @return Piwik_Date
+     * Whether the specified plugin's reports should be archived
+     * @param string $pluginName
+     * @return bool
      */
-    public function getDateEnd()
+    public function shouldProcessReportsForPlugin($pluginName)
     {
-        return $this->getPeriod()->getDateEnd()->setTimezone($this->getSite()->getTimezone());
+        if (Piwik_ArchiveProcessor_Rules::shouldProcessReportsAllPlugins($this->getSegment(), $this->getPeriod()->getLabel())) {
+            return true;
+        }
+        // If any other segment, only process if the requested report belong to this plugin
+        $pluginBeingProcessed = $this->getRequestedPlugin();
+        if ($pluginBeingProcessed == $pluginName) {
+            return true;
+        }
+        if (!Piwik_PluginsManager::getInstance()->isPluginLoaded($pluginBeingProcessed)) {
+            return true;
+        }
+        return false;
     }
 
     /**
-     * @return Piwik_Date
+     * @return Piwik_Segment
      */
-    public function getDateStart()
-    {
-        return $this->getPeriod()->getDateStart()->setTimezone($this->getSite()->getTimezone());
-    }
-
-    public function isArchiveTemporary()
+    public function getSegment()
     {
-        return $this->temporaryArchive;
+        return $this->segment;
     }
 
-    public function getIdArchive()
+    protected function getRequestedPlugin()
     {
-        return $this->idArchive;
+        return $this->requestedPlugin;
     }
 }
diff --git a/core/ArchiveProcessor/Rules.php b/core/ArchiveProcessor/Rules.php
index 5817dc5519766a3f92704df15e075834d6f2e8ab..942f21420e9e3a57e8fa152877534a12aed6caf5 100644
--- a/core/ArchiveProcessor/Rules.php
+++ b/core/ArchiveProcessor/Rules.php
@@ -8,6 +8,7 @@ class Piwik_ArchiveProcessor_Rules
 
     const OPTION_TODAY_ARCHIVE_TTL = 'todayArchiveTimeToLive';
     const OPTION_BROWSER_TRIGGER_ARCHIVING = 'enableBrowserTriggerArchiving';
+
     static public function isBrowserTriggerEnabled()
     {
         $browserArchivingEnabled = Piwik_GetOption(self::OPTION_BROWSER_TRIGGER_ARCHIVING);
@@ -16,6 +17,7 @@ class Piwik_ArchiveProcessor_Rules
         }
         return (bool)Piwik_Config::getInstance()->General['enable_browser_archiving_triggering'];
     }
+
     public static function getTodayArchiveTimeToLive()
     {
         $timeToLive = Piwik_GetOption(self::OPTION_TODAY_ARCHIVE_TTL);
@@ -93,7 +95,6 @@ class Piwik_ArchiveProcessor_Rules
         return $isArchivingDisabled;
     }
 
-
     /**
      * Returns the name of the archive field used to tell the status of an archive, (ie,
      * whether the archive was created successfully or not).
@@ -176,15 +177,13 @@ class Piwik_ArchiveProcessor_Rules
             else {
                 $purgeArchivesOlderThan = Piwik_Date::factory('today')->getDateTime();
             }
-            Piwik_DataAccess_Archiver::purgeOutdatedArchives($numericTable, $blobTable, $purgeArchivesOlderThan);
-
+            Piwik_DataAccess_ArchiveSelector::purgeOutdatedArchives($numericTable, $blobTable, $purgeArchivesOlderThan);
             // these tables will be OPTIMIZEd daily in a scheduled task, to claim lost space
         } else {
             Piwik::log("Purging temporary archives: skipped.");
         }
     }
 
-
     public static function setTodayArchiveTimeToLive($timeToLiveSeconds)
     {
         $timeToLiveSeconds = (int)$timeToLiveSeconds;
@@ -193,4 +192,27 @@ class Piwik_ArchiveProcessor_Rules
         }
         Piwik_SetOption(self::OPTION_TODAY_ARCHIVE_TTL, $timeToLiveSeconds, $autoload = true);
     }
+
+    static public function getMinTimeProcessedForTemporaryArchive(Piwik_Date $dateStart, Piwik_Period $period, Piwik_Segment $segment,
+                                                       Piwik_Site $site)
+    {
+        $now = time();
+        $minimumArchiveTime = $now - Piwik_ArchiveProcessor_Rules::getTodayArchiveTimeToLive();
+
+        $isArchivingDisabled = Piwik_ArchiveProcessor_Rules::isArchivingDisabledFor($segment, $period->getLabel());
+        if ($isArchivingDisabled) {
+            if ($period->getNumberOfSubperiods() == 0
+                && $dateStart->getTimestamp() <= $now
+            ) {
+                $minimumArchiveTime = false;
+            } else {
+                // However, if archiving is disabled for this request, we shall
+                // accept any archive that was processed today after 00:00:01 this morning
+                $timezone = $site->getTimezone();
+                $minimumArchiveTime = Piwik_Date::factory(Piwik_Date::factory('now', $timezone)->getDateStartUTC())->setTimezone($timezone)->getTimestamp();
+            }
+        }
+        return $minimumArchiveTime;
+    }
+
 }
\ No newline at end of file
diff --git a/core/DataAccess/Archiver.php b/core/DataAccess/ArchiveSelector.php
similarity index 94%
rename from core/DataAccess/Archiver.php
rename to core/DataAccess/ArchiveSelector.php
index 005bef11ab9b7bd0bff0208c36158614034ecb86..98937fe9f801a622290f8064e410e88591c9cc87 100644
--- a/core/DataAccess/Archiver.php
+++ b/core/DataAccess/ArchiveSelector.php
@@ -11,8 +11,19 @@
 
 /**
  * Data Access object used to query archives, create new archives, and insert data for them.
+ *
+ * A record in the Database for a given report is defined by
+ * - idarchive     = unique ID that is associated to all the data of this archive (idsite+period+date)
+ * - idsite        = the ID of the website
+ * - date1         = starting day of the period
+ * - date2         = ending day of the period
+ * - period        = integer that defines the period (day/week/etc.). @see period::getId()
+ * - ts_archived   = timestamp when the archive was processed (UTC)
+ * - name          = the name of the report (ex: uniq_visitors or search_keywords_by_search_engines)
+ * - value         = the actual data (a numeric value, or a blob of compressed serialized data)
+ *
  */
-class Piwik_DataAccess_Archiver
+class Piwik_DataAccess_ArchiveSelector
 {
     const NB_VISITS_RECORD_LOOKED_UP = "nb_visits";
     const NB_VISITS_CONVERTED_RECORD_LOOKED_UP = "nb_visits_converted";
@@ -58,8 +69,12 @@ class Piwik_DataAccess_Archiver
      */
     static public function getArchiveProcessorLock($idsite, $period, $segment)
     {
+
         $lockName = self::getArchiveProcessorLockName($idsite, $period, $segment);
-        return Piwik_GetDbLock($lockName, $maxRetries = 30);
+        $result = Piwik_GetDbLock($lockName, $maxRetries = 30);
+        if(!$result) {
+            Piwik::log('SELECT GET_LOCK(?, 1) FAILED to acquire lock. Proceeding anyway...');
+        }
     }
 
     /**
@@ -169,7 +184,9 @@ class Piwik_DataAccess_Archiver
     protected static function getVisitsMetricsFromResults($idArchive, $idArchiveVisitsSummary, $results)
     {
         $visits = $visitsConverted = false;
-        if($idArchiveVisitsSummary !== false) {
+
+        $archiveWithVisitsMetricsWasFound = ($idArchiveVisitsSummary !== false);
+        if($archiveWithVisitsMetricsWasFound) {
             $visits = $visitsConverted = 0;
         }
         foreach ($results as $result) {
diff --git a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
index 61062e2f5016e1543807bd6c9f51c29d747964ce..7488f019ffc7e7d5c91107145e26b17e8a976492 100644
--- a/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
+++ b/tests/PHPUnit/Integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
@@ -168,6 +168,7 @@
 		<name>Visitor ID</name>
 		<segment>visitorId</segment>
 		<acceptedValues>34c31e04394bdc63 - any 16 Hexadecimal chars ID, which can be fetched using the Tracking API function getVisitorId()</acceptedValues>
+		<permission>1</permission>
 	</row>
 	<row>
 		<type>dimension</type>