diff --git a/core/Archive.php b/core/Archive.php
index 5492c1b4a8d7a12d47330e8caccb9948e2c5044b..42690fb37955948f44ca772c35fe2f4f68ef6848 100644
--- a/core/Archive.php
+++ b/core/Archive.php
@@ -12,9 +12,14 @@
 /**
  * The archive object is used to query specific data for a day or a period of statistics for a given website.
  *
+ * Limitations:
+ * - If you query w/ a range period, you can only query for ONE at a time.
+ * - If you query w/ a non-range period, you can query for multiple periods, but they must
+ *   all be of the same type (ie, day, week, month, year).
+ * 
  * Example:
  * <pre>
- *        $archive = Piwik_Archive::build($idSite = 1, $period = 'week', '2008-03-08' );
+ *        $archive = Piwik_Archive::build($idSite = 1, $period = 'week', '2008-03-08');
  *        $dataTable = $archive->getDataTable('Provider_hostnameExt');
  *        $dataTable->queueFilter('ReplaceColumnNames');
  *        return $dataTable;
@@ -22,17 +27,19 @@
  *
  * Example bis:
  * <pre>
- *        $archive = Piwik_Archive::build($idSite = 3, $period = 'day', $date = 'today' );
+ *        $archive = Piwik_Archive::build($idSite = 3, $period = 'day', $date = 'today');
  *        $nbVisits = $archive->getNumeric('nb_visits');
  *        return $nbVisits;
  * </pre>
  *
  * If the requested statistics are not yet processed, Archive uses ArchiveProcessing to archive the statistics.
- *
+ * 
+ * TODO: create ticket for this: when building archives, should use each site's timezone (ONLY FOR 'now'). 
+ * 
  * @package Piwik
  * @subpackage Piwik_Archive
  */
-abstract class Piwik_Archive
+class Piwik_Archive
 {
     /**
      * When saving DataTables in the DB, we sometimes replace the columns name by these IDs so we save up lots of bytes
@@ -185,86 +192,230 @@ abstract class Piwik_Archive
 
     const LABEL_ECOMMERCE_CART = 'ecommerceAbandonedCart';
     const LABEL_ECOMMERCE_ORDER = 'ecommerceOrder';
-
+    
     /**
-     * Website Piwik_Site
-     *
-     * @var Piwik_Site
+     * The list of site IDs to query archive data for.
+     * 
+     * @var array
      */
-    protected $site = null;
-
+    private $siteIds;
+    
+    /**
+     * The list of Piwik_Period's to query archive data for.
+     * 
+     * @var array
+     */
+    private $periods;
+    
     /**
-     * Segment applied to the visits set
+     * Segment applied to the visits set.
+     * 
      * @var Piwik_Segment
      */
-    protected $segment = false;
+    private $segment;
+    
+    /**
+     * List of archive IDs for the sites, periods and segment we are querying with.
+     * Archive IDs are indexed by done flag and period, ie:
+     * 
+     * array(
+     *     'done.Referers' => array(
+     *         '2010-01-01' => 1,
+     *         '2010-01-02' => 2,
+     *     ),
+     *     'done.VisitsSummary' => array(
+     *         '2010-01-01' => 3,
+     *         '2010-01-02' => 4,
+     *     ),
+     * )
+     * 
+     * or,
+     * 
+     * array(
+     *     'done.all' => array(
+     *         '2010-01-01' => 1,
+     *         '2010-01-02' => 2
+     *     )
+     * )
+     * 
+     * @var array
+     */
+    private $idarchives = array();
+    
+    /**
+     * If set to true, the result of all get functions (ie, getNumeric, getBlob, etc.)
+     * will be indexed by the site ID, even if we're only querying data for one site.
+     * 
+     * @var bool
+     */
+    private $forceIndexedBySite;
+    
+    /**
+     * If set to true, the result of all get functions (ie, getNumeric, getBlob, etc.)
+     * will be indexed by the period, even if we're only querying data for one period.
+     * 
+     * @var bool
+     */
+    private $forceIndexedByDate;
+    
+    /**
+     * Data Access Layer object.
+     * 
+     * @var Piwik_DataAccess_ArchiveQuery
+     */
+    private $dataAccess;
+    
+    /**
+     * Cache of Piwik_ArchiveProcessing instances used when launching the archiving
+     * process.
+     * 
+     * @var array
+     */
+    private $processingCache = array();
+    
+    /**
+     * Constructor.
+     * 
+     * @param array|int $siteIds List of site IDs to query data for.
+     * @param array|Piwik_Period $periods List of periods to query data for.
+     * @param Piwik_Segment $segment The segment used to narrow the visits set.
+     * @param bool $forceIndexedBySite Whether to force index the result of a query by site ID.
+     * @param bool $forceIndexedByDate Whether to force index the result of a query by period.
+     */
+    public function __construct($siteIds, $periods, Piwik_Segment $segment, $forceIndexedBySite = false,
+                                  $forceIndexedByDate = false)
+    {
+        $this->siteIds = $this->getAsNonEmptyArray($siteIds, 'siteIds');
+        
+        $periods = $this->getAsNonEmptyArray($periods, 'periods');
+        $this->periods = array();
+        foreach ($periods as $period) {
+            $this->periods[$period->getRangeString()] = $period;
+        }
+        
+        $this->segment = $segment;
+        $this->forceIndexedBySite = $forceIndexedBySite;
+        $this->forceIndexedByDate = $forceIndexedByDate;
+        $this->dataAccess = new Piwik_DataAccess_ArchiveQuery();
+    }
+    
+    /**
+     * Destructor.
+     */
+    public function __destruct()
+    {
+        $this->periods = null;
+        $this->siteIds = null;
+        $this->segment = null;
+        $this->idarchives = array();
+        $this->processingCache = array();
+    }
+    
+    /**
+     * Returns the IDs of sites we are querying archive data for.
+     * 
+     * @return array
+     */
+    public function getSiteIds()
+    {
+        return $this->siteIds;
+    }
+    
+    /**
+     * Returns the periods we are querying archive data for.
+     * 
+     * @return array
+     */
+    public function getPeriods()
+    {
+        return $this->periods;
+    }
+    
+    /**
+     * Returns the segment used to limit the visit set.
+     * 
+     * @return Piwik_Segment|null
+     */
+    public function getSegment()
+    {
+        return $this->segment;
+    }
 
     /**
-     * Builds an Archive object or returns the same archive if previously built.
+     * Builds an Archive object using query parameter values.
      *
-     * @param int|string $idSite                 integer, or comma separated list of integer
-     * @param string $period                 'week' 'day' etc.
-     * @param Piwik_Date|string $strDate                'YYYY-MM-DD' or magic keywords 'today' @see Piwik_Date::factory()
-     * @param bool|string $segment                Segment definition - defaults to false for Backward Compatibility
-     * @param bool|string $_restrictSitesToLogin  Used only when running as a scheduled task
+     * @param int|string $idSite Integer, or comma separated list of integer site IDs.
+     * @param string $period 'day', 'week', 'month', 'year' or 'range'
+     * @param Piwik_Date|string $strDate 'YYYY-MM-DD', magic keywords (ie, 'today'; @see Piwik_Date::factory())
+     *                                   or date range (ie, 'YYYY-MM-DD,YYYY-MM-DD').
+     * @param false|string $segment Segment definition - defaults to false for backward compatibility.
+     * @param false|string $_restrictSitesToLogin Used only when running as a scheduled task.
      * @return Piwik_Archive
      */
     public static function build($idSite, $period, $strDate, $segment = false, $_restrictSitesToLogin = false)
     {
-        if ($idSite === 'all') {
-            $sites = Piwik_SitesManager_API::getInstance()->getSitesIdWithAtLeastViewAccess($_restrictSitesToLogin);
-        } else {
-            $sites = Piwik_Site::getIdSitesFromIdSitesString($idSite);
-        }
-
-        if (!($segment instanceof Piwik_Segment)) {
-            $segment = new Piwik_Segment($segment, $idSite);
+        $forceIndexedBySite = false;
+        $forceIndexedByDate = false;
+        
+        // determine site IDs to query from
+        if (is_array($idSite)
+            || $idSite == 'all'
+        ) {
+            $forceIndexedBySite = true;
         }
-
-        // idSite=1,3 or idSite=all
-        if ($idSite === 'all'
-            || is_array($idSite)
-            || count($sites) > 1
+        $sites = Piwik_Site::getIdSitesFromIdSitesString($idSite, $_restrictSitesToLogin);
+        
+        // if a period date string is detected: either 'last30', 'previous10' or 'YYYY-MM-DD,YYYY-MM-DD'
+        if (is_string($strDate)
+            && self::isMultiplePeriod($strDate, $period)
         ) {
-            $archive = new Piwik_Archive_Array_IndexedBySite($sites, $period, $strDate, $segment, $_restrictSitesToLogin);
-        } // if a period date string is detected: either 'last30', 'previous10' or 'YYYY-MM-DD,YYYY-MM-DD'
-        elseif (is_string($strDate) && self::isMultiplePeriod($strDate, $period)) {
-            $oSite = new Piwik_Site($idSite);
-            $archive = new Piwik_Archive_Array_IndexedByDate($oSite, $period, $strDate, $segment);
-        } // case we request a single archive
-        else {
-            $oSite = new Piwik_Site($idSite);
+            $oPeriod = new Piwik_Period_Range($period, $strDate);
+            $allPeriods = $oPeriod->getSubperiods();
+            $forceIndexedByDate = true;
+        } else {
+            if (count($sites) == 1) {
+                $oSite = new Piwik_Site($sites[0]);
+            } else {
+                $oSite = null;
+            }
+            
             $oPeriod = Piwik_Archive::makePeriodFromQueryParams($oSite, $period, $strDate);
-
-            $archive = new Piwik_Archive_Single();
-            $archive->setPeriod($oPeriod);
-            $archive->setSite($oSite);
-            $archive->setSegment($segment);
+            $allPeriods = array($oPeriod);
         }
-        return $archive;
+        
+        return new Piwik_Archive(
+            $sites, $allPeriods, new Piwik_Segment($segment, $sites), $forceIndexedBySite, $forceIndexedByDate);
     }
 
     /**
      * Creates a period instance using a Piwik_Site instance and two strings describing
      * the period & date.
      *
-     * @param Piwik_Site $site
+     * @param Piwik_Site|null $site
      * @param string $strPeriod The period string: day, week, month, year, range
      * @param string $strDate The date or date range string.
      * @return Piwik_Period
      */
     public static function makePeriodFromQueryParams($site, $strPeriod, $strDate)
     {
-        $tz = $site->getTimezone();
+        if ($site === null) {
+            $tz = 'UTC';
+        } else {
+            $tz = $site->getTimezone();
+        }
 
         if ($strPeriod == 'range') {
             $oPeriod = new Piwik_Period_Range('range', $strDate, $tz, Piwik_Date::factory('today', $tz));
         } else {
             $oDate = $strDate;
             if (!($strDate instanceof Piwik_Date)) {
-                if ($strDate == 'now' || $strDate == 'today') {
+                if ($strDate == 'now'
+                    || $strDate == 'today'
+                ) {
                     $strDate = date('Y-m-d', Piwik_Date::factory('now', $tz)->getTimestamp());
-                } elseif ($strDate == 'yesterday' || $strDate == 'yesterdaySameTime') {
+                } elseif ($strDate == 'yesterday'
+                          || $strDate == 'yesterdaySameTime'
+                ) {
                     $strDate = date('Y-m-d', Piwik_Date::factory('now', $tz)->subDay(1)->getTimestamp());
                 }
                 $oDate = Piwik_Date::factory($strDate);
@@ -275,62 +426,196 @@ abstract class Piwik_Archive
 
         return $oPeriod;
     }
-
-    abstract public function prepareArchive();
-
+    
     /**
-     * Returns the value of the element $name from the current archive
+     * Returns the value of the element $name from the current archive 
      * The value to be returned is a numeric value and is stored in the archive_numeric_* tables
      *
-     * @param string $name  For example Referers_distinctKeywords
-     * @return float|int|false  False if no value with the given name
+     * @param string|array $names One or more archive names, eg, 'nb_visits', 'Referers_distinctKeywords',
+     *                            etc.
+     * @return numeric|array|false False if no value with the given name, numeric if only one site
+     *                             and date and we're not forcing an index, and array if multiple
+     *                             sites/dates are queried.
      */
-    abstract public function getNumeric($name);
-
+    public function getNumeric($names)
+    {
+        $data = $this->get($names, 'numeric');
+        
+        $resultIndices = $this->getResultIndices();
+        $result = $data->getArray($resultIndices);
+        
+        // if only one metric is returned, just return it as a numeric value
+        if (empty($resultIndices)
+            && count($result) <= 1
+        ) {
+            $result = (float)reset($result); // convert to float in case $result is empty
+        }
+        
+        return $result;
+    }
+    
     /**
-     * Returns the value of the element $name from the current archive
-     *
-     * The value to be returned is a blob value and is stored in the archive_numeric_* tables
-     *
+     * Returns the value of the elements in $names from the current archive.
+     * 
+     * The value to be returned is a blob value and is stored in the archive_blob_* tables.
+     * 
      * It can return anything from strings, to serialized PHP arrays or PHP objects, etc.
      *
-     * @param string $name  For example Referers_distinctKeywords
-     * @return mixed  False if no value with the given name
+     * @param string|array $names One or more archive names, eg, 'Referers_keywordBySearchEngine'.
+     * @return string|array|false False if no value with the given name, numeric if only one site
+     *                            and date and we're not forcing an index, and array if multiple
+     *                            sites/dates are queried.
      */
-    abstract public function getBlob($name);
-
+    public function getBlob($names, $idSubtable = null)
+    {
+        $data = $this->get($names, 'blob', $idSubtable);
+        return $data->getArray($this->getResultIndices());
+    }
+    
     /**
-     *
-     * @param $fields
-     * @return Piwik_DataTable
+     * Returns the numeric values of the elements in $names as a DataTable.
+     * 
+     * Note: Every DataTable instance returned will have at most one row in it.
+     * 
+     * @param string|array $names One or more archive names, eg, 'nb_visits', 'Referers_distinctKeywords',
+     *                            etc.
+     * @return Piwik_DataTable|false False if no value with the given names. Based on the number
+     *                               of sites/periods, the result can be a DataTable_Array, which
+     *                               contains DataTable instances.
      */
-    abstract public function getDataTableFromNumeric($fields);
+    public function getDataTableFromNumeric($names)
+    {
+        $data = $this->get($names, 'numeric');
+        return $data->getDataTable($this->getResultIndices());
+    }
 
     /**
      * This method will build a dataTable from the blob value $name in the current archive.
+     * 
+     * For example $name = 'Referers_searchEngineByKeyword' will return a
+     * Piwik_DataTable containing all the keywords. If a $idSubtable is given, the method
+     * will return the subTable of $name. If 'all' is supplied for $idSubtable every subtable
+     * will be returned.
+     * 
+     * @param string $name The name of the record to get.
+     * @param int|string|null $idSubtable The subtable ID (if any) or 'all' if requesting every datatable.
+     * @return Piwik_DataTable|false
+     */
+    public function getDataTable($name, $idSubtable = null)
+    {
+        $data = $this->get($name, 'blob', $idSubtable);
+        return $data->getDataTable($this->getResultIndices());
+    }
+    
+    /**
+     * Same as getDataTable() except that it will also load in memory all the subtables
+     * for the DataTable $name. You can then access the subtables by using the
+     * Piwik_DataTable_Manager::getTable() function.
      *
-     * For example $name = 'Referers_searchEngineByKeyword' will return a  Piwik_DataTable containing all the keywords
-     * If a idSubTable is given, the method will return the subTable of $name
-     *
-     * @param string $name
-     * @param int $idSubTable or null if requesting the parent table
+     * @param string $name The name of the record to get.
+     * @param int|string|null $idSubtable The subtable ID (if any) or 'all' if requesting every datatable.
+     * @param bool $addMetadataSubtableId Whether to add the DB subtable ID as metadata to each datatable,
+     *                                    or not.
      * @return Piwik_DataTable
-     * @throws exception If the value cannot be found
      */
-    abstract public function getDataTable($name, $idSubTable = null);
+    public function getDataTableExpanded($name, $idSubtable = null, $addMetadataSubtableId = true)
+    {
+        $data = $this->get($name, 'blob', 'all');
+        return $data->getExpandedDataTable($this->getResultIndices(), $idSubtable, $addMetadataSubtableId);
+    }
+    
+    /**
+     * Returns true if we shouldn't launch the archiving process and false if we should.
+     * 
+     * @return bool
+     */
+    public function isArchivingDisabled()
+    {
+        return Piwik_ArchiveProcessing::isArchivingDisabledFor($this->segment, $this->getPeriodLabel());
+    }
 
     /**
-     * Same as getDataTable() except that it will also load in memory
-     * all the subtables for the DataTable $name.
-     * You can then access the subtables by using the Piwik_DataTable_Manager getTable()
+     * Returns true if Segmentation is allowed for this user
      *
-     * @param string $name
-     * @param int|null $idSubTable  null if requesting the parent table
-     * @return Piwik_DataTable
+     * @return bool
      */
-    abstract public function getDataTableExpanded($name, $idSubTable = null);
+    public static function isSegmentationEnabled()
+    {
+        return !Piwik::isUserIsAnonymous()
+            || Piwik_Config::getInstance()->General['anonymous_user_enable_use_segments_API'];
+    }
 
+    /**
+     * Indicate if $dateString and $period correspond to multiple periods
+     *
+     * @static
+     * @param  $dateString
+     * @param  $period
+     * @return boolean
+     */
+    public static function isMultiplePeriod($dateString, $period)
+    {
+        return (preg_match('/^(last|previous){1}([0-9]*)$/D', $dateString, $regs)
+            || Piwik_Period_Range::parseDateRange($dateString))
+            && $period != 'range';
+    }
 
+    /**
+     * Indicate if $idSiteString corresponds to multiple sites.
+     *
+     * @param string $idSiteString
+     * @return bool
+     */
+    public static function isMultipleSites($idSiteString)
+    {
+        return $idSiteString == 'all' || strpos($idSiteString, ',') !== false;
+    }
+    
+    /**
+     * Returns the report names for a list of metric/record names.
+     * 
+     * @see getRequestedReport
+     * 
+     * @param array $archiveNames
+     */
+    public function getRequestedReports($archiveNames)
+    {
+        $result = array();
+        foreach ($archiveNames as $name) {
+            $result[] = self::getRequestedReport($name);
+        }
+        return array_unique($result);
+    }
+    
+    /**
+     * Returns the report name for a metric/record name.
+     * 
+     * A report name has the following format: {$pluginName}_{$reportId}, eg. VisitFrequency_Metrics.
+     * The report ID is not used anywhere in Piwik.
+     */
+    public static function getRequestedReport($archiveName)
+    {
+        // Core metrics are always processed in Core, for the requested date/period/segment
+        if (in_array($archiveName, Piwik_ArchiveProcessing::getCoreMetrics())
+            || $archiveName == 'max_actions'
+        ) {
+            return 'VisitsSummary_CoreMetrics';
+        }
+        // VisitFrequency metrics don't follow the same naming convention (HACK) 
+        else if(strpos($archiveName, '_returning') > 0
+            // ignore Goal_visitor_returning_1_1_nb_conversions 
+            && strpos($archiveName, 'Goal_') === false
+        ) {
+            return 'VisitFrequency_Metrics';
+        }
+        // Goal_* metrics are processed by the Goals plugin (HACK)
+        else if(strpos($archiveName, 'Goal_') === 0) {
+            return 'Goals_Metrics';
+        } else {
+            return $archiveName;
+        }
+    }
+    
     /**
      * Helper - Loads a DataTable from the Archive.
      * Optionally loads the table recursively,
@@ -363,98 +648,337 @@ abstract class Piwik_Archive
 
         return $dataTable;
     }
-
-    protected function formatNumericValue($value)
+    
+    /**
+     * Queries archive tables for data and returns the result.
+     */
+    private function get($archiveNames, $archiveDataType, $idSubtable = null)
     {
-        // If there is no dot, we return as is
-        // Note: this could be an integer bigger than 32 bits
-        if (strpos($value, '.') === false) {
-            if ($value === false) {
-                return 0;
+        if (!is_array($archiveNames)) {
+            $archiveNames = array($archiveNames);
+        }
+        
+        // apply idSubtable
+        if ($idSubtable !== null
+            && $idSubtable != 'all'
+        ) {
+            foreach ($archiveNames as &$name) {
+                $name .= "_$idSubtable";
             }
-            return (float)$value;
         }
-
-        // Round up the value with 2 decimals
-        // we cast the result as float because returns false when no visitors
-        $value = round((float)$value, 2);
-        return $value;
-    }
-
-    public function getSegment()
-    {
-        return $this->segment;
+        
+        $result = new Piwik_Archive_DataCollection(
+            $archiveNames, $archiveDataType, $this->siteIds, $this->periods, $defaultRow = null);
+        
+        $archiveIds = $this->getArchiveIds($archiveNames);
+        if (empty($archiveIds)) {
+            return $result;
+        }
+        
+        $archiveData = $this->dataAccess->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'];
+            $periodStr = $row['date1'].",".$row['date2'];
+            
+            if ($archiveDataType == 'numeric') {
+                $value = $this->formatNumericValue($row['value']);
+            } else {
+                $value = $this->uncompress($row['value']);
+                $result->addMetadata($idSite, $periodStr, 'ts_archived', $row['ts_archived']);
+            }
+            
+            $resultRow = &$result->get($idSite, $periodStr);
+            $resultRow[$row['name']] = $value;
+        }
+        
+        return $result;
     }
-
-    public function setSegment(Piwik_Segment $segment)
+    
+    /**
+     * Returns archive IDs for the sites, periods and archive names that are being
+     * queried. This function will use the idarchive cache if it has the right data,
+     * query archive tables for IDs w/o launching archiving, or launch archiving and
+     * get the idarchive from Piwik_ArchiveProcessing instances.
+     */
+    private function getArchiveIds($archiveNames)
     {
-        $this->segment = $segment;
+        $requestedReports = $this->getRequestedReports($archiveNames);
+        
+        // figure out which archives haven't been processed (if an archive has been processed,
+        // then we have the archive IDs in $this->idarchives)
+        $doneFlags = array();
+        $archiveGroups = array();
+        foreach ($requestedReports as $report) {
+            $doneFlag = Piwik_ArchiveProcessing::getDoneStringFlagFor(
+                $this->segment, $this->getPeriodLabel(), $report);
+            
+            $doneFlags[$doneFlag] = true;
+            if (!isset($this->idarchives[$doneFlag])) {
+                $archiveGroups[] = $this->getArchiveGroupOfReport($report);
+            }
+        }
+        
+        $archiveGroups = array_unique($archiveGroups);
+        
+        // cache id archives for plugins we haven't processed yet
+        if (!empty($archiveGroups)) {
+            if (!$this->isArchivingDisabled()) {
+                $this->cacheArchiveIdsAfterLaunching($archiveGroups, $requestedReports);
+            } else {
+                $this->cacheArchiveIdsWithoutLaunching($requestedReports);
+            }
+        }
+        
+        // order idarchives by the table month they belong to
+        $idArchivesByMonth = array();
+        foreach (array_keys($doneFlags) as $doneFlag) {
+            if (empty($this->idarchives[$doneFlag])) {
+                continue;
+            }
+            
+            foreach ($this->idarchives[$doneFlag] as $dateRange => $idarchives) {
+                foreach ($idarchives as $id) {
+                    $idArchivesByMonth[$dateRange][] = $id;
+                }
+            }
+        }
+        
+        return $idArchivesByMonth;
     }
-
+    
     /**
-     * Sets the site
-     *
-     * @param Piwik_Site $site
+     * Gets the IDs of the archives we're querying for and stores them in $this->archives.
+     * This function will launch the archiving process for each period/site/plugin if 
+     * metrics/reports have not been calculated/archived already.
+     * 
+     * @param array $archiveGroups @see getArchiveGroupOfReport
+     * @param array $requestedReports @see getRequestedReport
      */
-    public function setSite(Piwik_Site $site)
+    private function cacheArchiveIdsAfterLaunching($archiveGroups, $requestedReports)
     {
-        $this->site = $site;
+        $today = Piwik_Date::today();
+        
+        // for every individual query permutation, launch the archiving process and get the archive ID
+        foreach ($this->periods as $period) {
+            $periodStr = $period->getRangeString();
+            
+            $twoDaysBeforePeriod = $period->getDateStart()->subDay(2);
+            $twoDaysAfterPeriod = $period->getDateEnd()->addDay(2);
+            
+            foreach ($this->siteIds as $idSite) {
+                $site = new Piwik_Site($idSite);
+                
+                // if the END of the period is BEFORE the website creation date
+                // we already know there are no stats for this period
+                // we add one day to make sure we don't miss the day of the website creation
+                if ($twoDaysAfterPeriod->isEarlier($site->getCreationDate())) {
+                    $archiveDesc = $this->getArchiveDescriptor($idSite, $period);
+                    Piwik::log("Archive $archiveDesc skipped, archive is before the website was created.");
+                    continue;
+                }
+        
+                // if the starting date is in the future we know there is no visit
+                if ($twoDaysBeforePeriod->isLater($today)) {
+                    $archiveDesc = $this->getArchiveDescriptor($idSite, $period);
+                    Piwik::log("Archive $archiveDesc skipped, archive is after today.");
+                    continue;
+                }
+                
+                // prepare the ArchiveProcessing instance
+                $processing = $this->getArchiveProcessingInstance($period);
+                $processing->setSite($site);
+                $processing->setPeriod($period);
+                $processing->setSegment($this->segment);
+                
+                $processing->isThereSomeVisits = null;
+                
+                // process for each requested report as well
+                foreach ($archiveGroups as $pluginOrAll) {
+                    if ($pluginOrAll == 'all') {
+                        $pluginOrAll = $this->getPluginForReport(reset($requestedReports));
+                    }
+                    $report = $pluginOrAll.'_reportsAndMetrics';
+                    
+                    $doneFlag = Piwik_ArchiveProcessing::getDoneStringFlagFor(
+                        $this->segment, $period->getLabel(), $report);
+                    $this->initializeArchiveIdCache($doneFlag);
+                    
+                    $processing->init();
+                    $processing->setRequestedReport($report);
+                    
+                    // launch archiving if the requested data hasn't been archived
+                    $idArchive = $processing->loadArchive();
+                    if (empty($idArchive)) {
+                        $processing->launchArchiving();
+                        $idArchive = $processing->getIdArchive();
+                    }
+                    
+                    if (!$processing->isThereSomeVisits()) {
+                        continue;
+                    }
+                    
+                    $this->idarchives[$doneFlag][$periodStr][] = $idArchive;
+                }
+            }
+        }
     }
-
+    
     /**
-     * Gets the site
-     *
-     * @return Piwik_Site
+     * Gets the IDs of the archives we're querying for and stores them in $this->archives.
+     * This function will not launch the archiving process (and is thus much, much faster
+     * than cacheArchiveIdsAfterLaunching).
+     * 
+     * @param array $requestedReports @see getRequestedReport
      */
-    public function getSite()
+    private function cacheArchiveIdsWithoutLaunching($requestedReports)
     {
-        return $this->site;
+        $periodType = $this->getPeriodLabel();
+        
+        $idarchivesByReport = $this->dataAccess->getArchiveIds(
+            $this->siteIds, $this->periods, $this->segment, $requestedReports);
+        
+        // initialize archive ID cache for each report
+        foreach ($requestedReports as $report) {
+            $doneFlag = Piwik_ArchiveProcessing::getDoneStringFlagFor($this->segment, $periodType, $report);
+            $this->initializeArchiveIdCache($doneFlag);
+        }
+       
+        foreach ($idarchivesByReport as $doneFlag => $idarchivesByDate) {
+            foreach ($idarchivesByDate as $dateRange => $idarchives) {
+                foreach ($idarchives as $idarchive) {
+                    $this->idarchives[$doneFlag][$dateRange][] = $idarchive;
+                }
+            }
+        }
     }
-
+    
     /**
-     * Returns the Id site associated with this archive
-     *
-     * @return int
+     * Returns an ArchiveProcessing instance that should be used for a specific
+     * period.
+     * 
+     * @param Piwik_Period $period
      */
-    public function getIdSite()
+    private function getArchiveProcessingInstance($period)
+    {
+        $label = $period->getLabel();
+        if (!isset($this->processingCache[$label])) {
+            $this->processingCache[$label] = Piwik_ArchiveProcessing::factory($label);
+        }
+        return $this->processingCache[$label];
+    }
+    
+    private function getPeriodLabel()
     {
-        return $this->site->getId();
+        return reset($this->periods)->getLabel();
     }
-
+    
     /**
-     * Returns true if Segmentation is allowed for this user
-     *
-     * @return bool
+     * Returns an array describing what metadata to use when indexing a query result.
+     * For use with Piwik_Archive_DataCollection.
+     * 
+     * @return array
      */
-    public static function isSegmentationEnabled()
+    private function getResultIndices()
     {
-        return !Piwik::isUserIsAnonymous()
-            || Piwik_Config::getInstance()->General['anonymous_user_enable_use_segments_API'];
+        $indices = array();
+        
+        if (count($this->siteIds) > 1
+            || $this->forceIndexedBySite
+        ) {
+            $indices['site'] = 'idSite';
+        }
+        
+        if (count($this->periods) > 1
+            || $this->forceIndexedByDate
+        ) {
+            $indices['period'] = 'date';
+        }
+        
+        return $indices;
     }
 
+    private function formatNumericValue($value)
+    {
+        // If there is no dot, we return as is
+        // Note: this could be an integer bigger than 32 bits
+        if (strpos($value, '.') === false) {
+            if ($value === false) {
+                return 0;
+            }
+            return (float)$value;
+        }
+
+        // Round up the value with 2 decimals
+        // we cast the result as float because returns false when no visitors
+        return round((float)$value, 2);
+    }
+    
+    private function getArchiveDescriptor($idSite, $period)
+    {
+        return "site $idSite, {$period->getLabel()} ({$period->getPrettyString()})";
+    }
+    
+    private function uncompress($data)
+    {
+        return @gzuncompress($data);
+    }
+    
+    private function getAsNonEmptyArray($array, $paramName)
+    {
+        if (!is_array($array)) {
+            $array = array($array);
+        }
+        
+        if (empty($array)) {
+            throw new Exception("Piwik_Archive::__construct: \$$paramName is empty.");
+        }
+        
+        return $array;
+    }
+    
     /**
-     * Indicate if $dateString and $period correspond to multiple periods
-     *
-     * @static
-     * @param  $dateString
-     * @param  $period
-     * @return boolean
+     * Initializes the archive ID cache ($this->idarchives) for a particular 'done' flag.
+     * 
+     * It is necessary that each archive ID caching function call this method for each
+     * unique 'done' flag it encounters, since the getArchiveIds function determines
+     * whether archiving should be launched based on whether $this->idarchives has a
+     * an entry for a specific 'done' flag.
+     * 
+     * If this function is not called, then periods with no visits will not add
+     * entries to the cache. If the archive is used again, SQL will be executed to
+     * try and find the archive IDs even though we know there are none.
      */
-    public static function isMultiplePeriod($dateString, $period)
+    private function initializeArchiveIdCache($doneFlag)
     {
-        return (preg_match('/^(last|previous){1}([0-9]*)$/D', $dateString, $regs)
-            || Piwik_Period_Range::parseDateRange($dateString))
-            && $period != 'range';
+        if (!isset($this->idarchives[$doneFlag])) {
+            $this->idarchives[$doneFlag] = array();
+        }
     }
-
+    
     /**
-     * Indicate if $idSiteString corresponds to multiple sites.
-     *
-     * @param string $idSiteString
-     * @return bool
+     * Returns the archiving group identifier of a report.
+     * 
+     * More than one plugin can be called at once. In such a case we don't want to
+     * launch archiving three times for three plugins if doing it once is enough,
+     * so getArchiveIds makes sure to get the archive group of all reports.
+     * 
+     * If the period isn't a range, then all plugins' archiving code is executed.
+     * If the period is a range, then archiving code is executed individually for
+     * each plugin.
      */
-    public static function isMultipleSites($idSiteString)
+    private function getArchiveGroupOfReport($report)
     {
-        return $idSiteString == 'all' || strpos($idSiteString, ',') !== false;
+        if ($this->getPeriodLabel() != 'range') {
+            return 'all';
+        }
+        
+        return $this->getPluginForReport($report);
+    }
+    
+    private function getPluginForReport($report)
+    {
+        $parts = explode('_', $report);
+        return $parts[0];
     }
 }
diff --git a/core/Archive/Array.php b/core/Archive/Array.php
deleted file mode 100644
index 896cc1e17ca550fe8a88e721b92c101954b5608f..0000000000000000000000000000000000000000
--- a/core/Archive/Array.php
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- * @category Piwik
- * @package Piwik
- */
-
-/**
- * Piwik_Archive_Array is used to store multiple archives,
- * for example one archive for a given day for each Piwik website
- *
- * @package Piwik
- * @subpackage Piwik_Archive
- */
-abstract class Piwik_Archive_Array extends Piwik_Archive
-{
-    /**
-     * This array contains one Piwik_Archive per entry in the period
-     *
-     * @var Piwik_Archive[]
-     */
-    protected $archives = array();
-
-    abstract protected function getIndexName();
-
-    abstract protected function getDataTableLabelValue($archive);
-
-    /**
-     * Destructor
-     */
-    public function __destruct()
-    {
-        foreach ($this->archives as $archive) {
-            destroy($archive);
-        }
-        $this->archives = array();
-    }
-
-    /**
-     * Prepares each archive in the array
-     */
-    public function prepareArchive()
-    {
-        foreach ($this->archives as $archive) {
-            $archive->prepareArchive();
-        }
-    }
-
-    /**
-     * Returns a newly created Piwik_DataTable_Array.
-     *
-     * @return Piwik_DataTable_Array
-     */
-    protected function getNewDataTableArray()
-    {
-        $table = new Piwik_DataTable_Array();
-        $table->setKeyName($this->getIndexName());
-        return $table;
-    }
-
-    /**
-     * Returns a DataTable_Array containing numeric values
-     * of the element $name from the archives in this Archive_Array.
-     *
-     * @param string $name  Name of the mysql table field to load eg. Referers_distinctKeywords
-     * @return Piwik_DataTable_Array  containing the requested numeric value for each Archive
-     */
-    public function getNumeric($name)
-    {
-        $table = $this->getNewDataTableArray();
-
-        foreach ($this->archives as $archive) {
-            $numeric = $archive->getNumeric($name);
-            $subTable = $archive->makeDataTable($isSimple = true);
-            $subTable->addRowsFromArray(array($numeric));
-            $table->addTable($subTable, $this->getDataTableLabelValue($archive));
-        }
-
-        return $table;
-    }
-
-    /**
-     * Returns a DataTable_Array containing values
-     * of the element $name from the archives in this Archive_Array.
-     *
-     * The value to be returned are blob values (stored in the archive_numeric_* tables in the DB).     *
-     * It can return anything from strings, to serialized PHP arrays or PHP objects, etc.
-     *
-     * @param string $name  Name of the mysql table field to load eg. Referers_keywordBySearchEngine
-     * @return Piwik_DataTable_Array  containing the requested blob values for each Archive
-     */
-    public function getBlob($name)
-    {
-        $table = $this->getNewDataTableArray();
-
-        foreach ($this->archives as $archive) {
-            $blob = $archive->getBlob($name);
-            $subTable = $archive->makeNewDataTable($isSimple = true);
-            $subTable->addRowsFromArray(array('blob' => $blob));
-            $table->addTable($subTable, $this->getDataTableLabelValue($archive));
-        }
-        return $table;
-    }
-
-    /**
-     * Given a BLOB field name (eg. 'Referers_searchEngineByKeyword'), it will return a Piwik_DataTable_Array
-     * which is an array of Piwik_DataTable, ordered by chronological order
-     *
-     * @param string $name        Name of the mysql table field to load
-     * @param int $idSubTable  optional idSubDataTable
-     * @return Piwik_DataTable_Array
-     * @throws Exception  If the value cannot be found
-     */
-    public function getDataTable($name, $idSubTable = null)
-    {
-        $table = $this->getNewDataTableArray();
-        foreach ($this->archives as $archive) {
-            $subTable = $archive->getDataTable($name, $idSubTable);
-            $table->addTable($subTable, $this->getDataTableLabelValue($archive));
-        }
-        return $table;
-    }
-
-
-    /**
-     * Same as getDataTable() except that it will also load in memory
-     * all the subtables for the DataTable $name.
-     * You can then access the subtables by using the Piwik_DataTable_Manager::getInstance()->getTable($idSubTable);
-     *
-     * @param string $name        Name of the mysql table field to load
-     * @param int $idSubTable  optional idSubDataTable
-     * @return Piwik_DataTable_Array
-     */
-    public function getDataTableExpanded($name, $idSubTable = null)
-    {
-        $table = $this->getNewDataTableArray();
-        foreach ($this->archives as $archive) {
-            $subTable = $archive->getDataTableExpanded($name, $idSubTable);
-            $table->addTable($subTable, $this->getDataTableLabelValue($archive));
-        }
-        return $table;
-    }
-}
diff --git a/core/Archive/Array/IndexedByDate.php b/core/Archive/Array/IndexedByDate.php
deleted file mode 100644
index 9a59712d4a91bc2be629c96ee7cee00c96d87db8..0000000000000000000000000000000000000000
--- a/core/Archive/Array/IndexedByDate.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- * @category Piwik
- * @package Piwik
- */
-
-/**
- * @package Piwik
- * @subpackage Piwik_Archive
- */
-class Piwik_Archive_Array_IndexedByDate extends Piwik_Archive_Array
-{
-    /**
-     * Builds an array of Piwik_Archive of a given date range
-     *
-     * @param Piwik_Site $oSite
-     * @param string $strPeriod eg. 'day' 'week' etc.
-     * @param string $strDate A date range, eg. 'last10', 'previous5' or 'YYYY-MM-DD,YYYY-MM-DD'
-     * @param Piwik_Segment $segment
-     */
-    public function __construct(Piwik_Site $oSite, $strPeriod, $strDate, Piwik_Segment $segment)
-    {
-        $rangePeriod = new Piwik_Period_Range($strPeriod, $strDate, $oSite->getTimezone());
-        foreach ($rangePeriod->getSubperiods() as $subPeriod) {
-            $startDate = $subPeriod->getDateStart();
-            $archive = Piwik_Archive::build($oSite->getId(), $strPeriod, $startDate, $segment->getString());
-            $archive->setSegment($segment);
-            $this->archives[] = $archive;
-        }
-        $this->setSite($oSite);
-    }
-
-    /**
-     * @return string
-     */
-    protected function getIndexName()
-    {
-        return 'date';
-    }
-
-    /**
-     * @param Piwik_Archive $archive
-     * @return mixed
-     */
-    protected function getDataTableLabelValue($archive)
-    {
-        return $archive->getPrettyDate();
-    }
-
-    /**
-     * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Array
-     * which is an array of Piwik_DataTable_Simple, ordered by chronological order
-     *
-     * @param array|string $fields  array( fieldName1, fieldName2, ...)  Names of the mysql table fields to load
-     * @return Piwik_DataTable_Array
-     */
-    public function getDataTableFromNumeric($fields)
-    {
-        $inNames = Piwik_Common::getSqlStringFieldsArray($fields);
-
-        // we select in different shots
-        // one per distinct table (case we select last 300 days, maybe we will  select from 10 different tables)
-        $queries = array();
-        foreach ($this->archives as $archive) {
-            $archive->setRequestedReport(is_string($fields) ? $fields : current($fields));
-            $archive->prepareArchive();
-            if (!$archive->isThereSomeVisits) {
-                continue;
-            }
-
-            $table = $archive->archiveProcessing->getTableArchiveNumericName();
-
-            // for every query store IDs
-            $queries[$table][] = $archive->getIdArchive();
-        }
-        // we select the requested value
-        $db = Zend_Registry::get('db');
-
-        // date => array( 'field1' =>X, 'field2'=>Y)
-        // date2 => array( 'field1' =>X2, 'field2'=>Y2)
-
-        $arrayValues = array();
-        foreach ($queries as $table => $aIds) {
-            $inIds = implode(', ', array_filter($aIds));
-            if (empty($inIds)) {
-                // Probable timezone configuration error, i.e., mismatch between PHP and MySQL server.
-                continue;
-            }
-
-            $sql = "SELECT value, name, date1 as startDate
-					FROM $table
-					WHERE idarchive IN ( $inIds )
-					AND name IN ( $inNames )
-					ORDER BY date1, name";
-            $values = $db->fetchAll($sql, $fields);
-            foreach ($values as $value) {
-                $timestamp = Piwik_Date::factory($value['startDate'])->getTimestamp();
-                $arrayValues[$timestamp][$value['name']] = $this->formatNumericValue($value['value']);
-            }
-        }
-
-        $contentArray = array();
-        // we add empty tables so that every requested date has an entry, even if there is nothing
-        // example: <result date="2007-01-01" />
-        $archiveByTimestamp = array();
-        foreach ($this->archives as $archive) {
-            $timestamp = $archive->getTimestampStartDate();
-            $archiveByTimestamp[$timestamp] = $archive;
-            $contentArray[$timestamp]['table'] = $archive->makeDataTable($simple = true);
-            $contentArray[$timestamp]['prettyDate'] = $archive->getPrettyDate();
-        }
-
-        foreach ($arrayValues as $timestamp => $aNameValues) {
-            // undefined in some edge/unknown cases see http://dev.piwik.org/trac/ticket/2578
-            if (isset($contentArray[$timestamp]['table'])) {
-                $contentArray[$timestamp]['table']->addRowsFromArray($aNameValues);
-            }
-        }
-
-        $tableArray = $this->getNewDataTableArray();
-        foreach ($contentArray as $timestamp => $aData) {
-            $tableArray->addTable($aData['table'], $aData['prettyDate']);
-        }
-        return $tableArray;
-    }
-}
diff --git a/core/Archive/Array/IndexedBySite.php b/core/Archive/Array/IndexedBySite.php
deleted file mode 100644
index 1ac9ff682a995eecf5aa79012e139ad16f660c02..0000000000000000000000000000000000000000
--- a/core/Archive/Array/IndexedBySite.php
+++ /dev/null
@@ -1,266 +0,0 @@
-<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- * @category Piwik
- * @package Piwik
- */
-
-/**
- * @package Piwik
- * @subpackage Piwik_Archive
- */
-class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array
-{
-    /**
-     * Used to cache the name of the table that holds the data this archive.
-     *
-     * This will only be used if the archives held by this instance are instances of
-     * Piwik_Archive_Single.
-     */
-    private $tableName = null;
-
-    /**
-     * @param array $sites      array of siteIds
-     * @param string $strPeriod  eg. 'day' 'week' etc.
-     * @param string $strDate    A date range, eg. 'last10', 'previous5' or 'YYYY-MM-DD,YYYY-MM-DD'
-     * @param Piwik_Segment $segment
-     * @param string $_restrictSitesToLogin
-     */
-    function __construct($sites, $strPeriod, $strDate, Piwik_Segment $segment, $_restrictSitesToLogin)
-    {
-        foreach ($sites as $idSite) {
-            $archive = Piwik_Archive::build($idSite, $strPeriod, $strDate, $segment, $_restrictSitesToLogin);
-            $this->archives[$idSite] = $archive;
-        }
-        ksort($this->archives);
-    }
-
-    /**
-     * @return string
-     */
-    protected function getIndexName()
-    {
-        return 'idSite';
-    }
-
-    /**
-     * @param Piwik_Archive $archive
-     * @return mixed
-     */
-    protected function getDataTableLabelValue($archive)
-    {
-        return $archive->getIdSite();
-    }
-
-    /**
-     * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Array
-     * ordered by idsite
-     *
-     * @param array|string $fields  array( fieldName1, fieldName2, ...)  Names of the mysql table fields to load
-     * @return Piwik_DataTable_Array
-     */
-    public function getDataTableFromNumeric($fields)
-    {
-        $tableArray = $this->getNewDataTableArray();
-        if ($this->getFirstArchive() instanceof Piwik_Archive_Single) {
-            $values = $this->getValues($fields);
-            foreach ($this->archives as $idSite => $archive) {
-                $table = $archive->makeDataTable($isSimple = true);
-                if (array_key_exists($idSite, $values)) {
-                    $table->addRowsFromArray($values[$idSite]);
-                }
-                $tableArray->addTable($table, $idSite);
-            }
-        } elseif ($this->getFirstArchive() instanceof Piwik_Archive_Array) {
-            foreach ($this->archives as $idSite => $archive) {
-                $tableArray->addTable($archive->getDataTableFromNumeric($fields), $idSite);
-            }
-        }
-
-        return $tableArray;
-    }
-
-    /**
-     * Returns the values of the requested fields
-     *
-     * @param array $fields
-     * @return array
-     */
-    private function getValues($fields)
-    {
-        // Creating the default array, to ensure consistent order
-        $defaultValues = array();
-        foreach ($fields as $field) {
-            $defaultValues[$field] = null;
-        }
-
-        $arrayValues = array();
-        foreach ($this->loadValuesFromDB($fields) as $value) {
-            if (!isset($arrayValues[$value['idsite']])) {
-                $arrayValues[$value['idsite']] = $defaultValues;
-            }
-            $arrayValues[$value['idsite']][$value['name']] = $this->formatNumericValue($value['value']);
-        }
-        return $arrayValues;
-    }
-
-    /**
-     * @param $fields
-     * @return array|array  (one row in the array per row fetched in the DB)
-     */
-    private function loadValuesFromDB($fields)
-    {
-        $requestedMetrics = is_string($fields) ? array($fields) : $fields;
-        $inNames = Piwik_Common::getSqlStringFieldsArray($fields);
-
-        // get the archive ids
-        if (!$this->getFirstArchive()->isArchivingDisabled()) {
-            $archiveIds = $this->getArchiveIdsAfterLaunching($requestedMetrics);
-        } else {
-            $archiveIds = $this->getArchiveIdsWithoutLaunching($requestedMetrics);
-        }
-
-        $archiveIds = implode(', ', array_filter($archiveIds));
-
-        // if no archive ids are found, avoid executing any SQL queries
-        if (empty($archiveIds)) {
-            return array();
-        }
-
-        // select archive data
-        $sql = "SELECT value, name, idarchive, idsite
-								FROM {$this->getNumericTableName()}
-								WHERE idarchive IN ( $archiveIds )
-									AND name IN ( $inNames )";
-
-        return Piwik_FetchAll($sql, $fields);
-    }
-
-    /**
-     * Returns the first archive in the list
-     *
-     * @return Piwik_Archive
-     */
-    private function getFirstArchive()
-    {
-        return reset($this->archives);
-    }
-
-    /**
-     * Gets the archive id of every Single archive this archive holds. This method
-     * will launch the archiving process if appropriate.
-     *
-     * @param array $metrics  The requested archive metrics.
-     * @throws Exception
-     * @return array
-     */
-    private function getArchiveIdsAfterLaunching($metrics)
-    {
-        // collect the individual report names for the requested metrics
-        $reports = array();
-        foreach ($metrics as $metric) {
-            $report = Piwik_Archive_Single::getRequestedReportFor($metric);
-            $reports[$report] = $metric;
-        }
-
-        // process archives for each individual report
-        $archiveIds = array();
-        foreach ($reports as $report => $metric) {
-            // prepare archives (this will launch archiving when appropriate)
-            foreach ($this->archives as $archive) {
-                // NOTE: Piwik_Archive_Single expects a metric here, not a report
-                $archive->setRequestedReport($metric);
-                $archive->prepareArchive();
-            }
-
-            // collect archive ids for archives that have visits
-            foreach ($this->archives as $archive) {
-                if (!$archive->isThereSomeVisits) {
-                    continue;
-                }
-
-                $archiveIds[] = $archive->getIdArchive();
-
-                if ($this->getNumericTableName() != $archive->archiveProcessing->getTableArchiveNumericName()) {
-                    throw new Exception("Piwik_Archive_Array_IndexedBySite::getDataTableFromNumeric() algorithm won't work if data is stored in different tables");
-                }
-            }
-        }
-
-        return $archiveIds;
-    }
-
-    /**
-     * Gets the archive id of every Single archive this archive holds. This method
-     * will not launch the archiving process.
-     *
-     * @param array $metrics  The requested archive metrics.
-     * @return array
-     */
-    private function getArchiveIdsWithoutLaunching($metrics)
-    {
-        $firstArchive = $this->getFirstArchive();
-        $segment = $firstArchive->getSegment();
-        $period = $firstArchive->getPeriod();
-
-        // the flags used to tell how the archiving process for a specific archive was completed,
-        // if it was completed
-        $doneFlags = array();
-        foreach ($metrics as $metric) {
-            $done = Piwik_ArchiveProcessing::getDoneStringFlagFor($segment, $period, $metric);
-            $donePlugins = Piwik_ArchiveProcessing::getDoneStringFlagFor($segment, $period, $metric, true);
-
-            $doneFlags[$done] = $done;
-            $doneFlags[$donePlugins] = $donePlugins;
-        }
-
-        $allDoneFlags = "'" . implode("','", $doneFlags) . "'";
-
-        // create the SQL to query every archive ID
-        $nameCondition = "(name IN ($allDoneFlags)) AND
-						  (value = '" . Piwik_ArchiveProcessing::DONE_OK . "' OR
-						   value = '" . Piwik_ArchiveProcessing::DONE_OK_TEMPORARY . "')";
-
-        $sql = "SELECT idsite,
-		               MAX(idarchive) AS idarchive
-		          FROM " . $this->getNumericTableName() . "
-		         WHERE date1 = ?
-		           AND date2 = ?
-		           AND period = ?
-		           AND $nameCondition
-		           AND idsite IN (" . implode(',', array_keys($this->archives)) . ")
-		      GROUP BY idsite";
-
-        $bind = array($period->getDateStart()->toString('Y-m-d'),
-                      $period->getDateEnd()->toString('Y-m-d'),
-                      $period->getId());
-
-        // execute the query and process the results.
-        $archiveIds = array();
-        foreach (Piwik_FetchAll($sql, $bind) as $row) {
-            $archiveIds[] = $row['idarchive'];
-        }
-
-        return $archiveIds;
-    }
-
-    /**
-     * Gets the name of the database table that holds the numeric archive data for
-     * this archive.
-     *
-     * @return string
-     */
-    private function getNumericTableName()
-    {
-        if (is_null($this->tableName)) {
-            $table = Piwik_ArchiveProcessing::makeNumericArchiveTable($this->getFirstArchive()->getPeriod());
-            $this->tableName = $table->getTableName();
-        }
-
-        return $this->tableName;
-    }
-}
diff --git a/core/Archive/DataCollection.php b/core/Archive/DataCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..4313fadd1c28e6080921ff8dd7abaa790ada4d41
--- /dev/null
+++ b/core/Archive/DataCollection.php
@@ -0,0 +1,326 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+/**
+ * This class is used to hold and transform archive data for the Piwik_Archive class.
+ * 
+ * Archive data is loaded into an instance of this type, can be indexed by archive
+ * metadata (such as the site ID, period string, etc.), and can be transformed into
+ * Piwik_DataTable and Piwik_DataTable_Array instances.
+ */
+class Piwik_Archive_DataCollection
+{
+    /**
+     * The archive data, indexed first by site ID and then by period date range. Eg,
+     * 
+     * array(
+     *     '0' => array(
+     *         array(
+     *             '2012-01-01,2012-01-01' => array(...),
+     *             '2012-01-02,2012-01-02' => array(...),
+     *         )
+     *     ),
+     *     '1' => array(
+     *         array(
+     *             '2012-01-01,2012-01-01' => array(...),
+     *         )
+     *     )
+     * )
+     * 
+     * Archive data can be either a numeric value or a serialized string blob. Every
+     * piece of archive data is associated by it's archive name. For example,
+     * the array(...) above could look like:
+     * 
+     * array(
+     *    'nb_visits' => 1,
+     *    'nb_actions' => 2
+     * )
+     * 
+     * There is a special element '_metadata' in data rows that holds values treated
+     * as DataTable metadata.
+     */
+    private $data = array();
+    
+    /**
+     * The whole list of metric/record names that were used in the archive query.
+     * 
+     * @var array
+     */
+    private $dataNames;
+    
+    /**
+     * The type of data that was queried for (ie, "blob" or "numeric").
+     * 
+     * @var string
+     */
+    private $dataType;
+    
+    /**
+     * The default values to use for each metric/record name that's being queried
+     * for.
+     * 
+     * @var array
+     */
+    private $defaultRow;
+    
+    /**
+     * The list of all site IDs that were queried for.
+     * 
+     * @var array
+     */
+    private $sitesId;
+    
+    /**
+     * The list of all periods that were queried for. Each period is associated with
+     * the period's range string. Eg,
+     * 
+     * array(
+     *     '2012-01-01,2012-01-31' => new Piwik_Period(...),
+     *     '2012-02-01,2012-02-28' => new Piwik_Period(...),
+     * )
+     * 
+     * @var array
+     */
+    private $periods;
+    
+    /**
+     * Constructor.
+     * 
+     * @param array $dataNames @see $this->dataNames
+     * @param string $dataType @see $this->dataType
+     * @param array $sitesId @see $this->sitesId
+     * @param array $periods @see $this->periods
+     * @param array $defaultRow @see $this->defaultRow
+     */
+    public function __construct($dataNames, $dataType, $sitesId, $periods, $defaultRow = null)
+    {
+        $this->dataNames = $dataNames;
+        $this->dataType = $dataType;
+        
+        if ($defaultRow === null) {
+            $defaultRow = array_fill_keys($dataNames, 0);
+        }
+        $this->sitesId = $sitesId;
+        $this->periods = $periods;
+        $this->defaultRow = $defaultRow;
+    }
+    
+    /**
+     * Returns a reference to the data for a specific site & period. If there is
+     * no data for the given site ID & period, it is set to the default row.
+     * 
+     * @param int $idSite
+     * @param string $period eg, '2012-01-01,2012-01-31'
+     */
+    public function &get($idSite, $period)
+    {
+        if (!isset($this->data[$idSite][$period])) {
+            $this->data[$idSite][$period] = $this->defaultRow;
+        }
+        return $this->data[$idSite][$period];
+    }
+    
+    /**
+     * Adds a new metadata to the data for specific site & period. If there is no
+     * data for the given site ID & period, it is set to the default row.
+     * 
+     * Note: Site ID and period range string are two special types of metadata. Since
+     * the data stored in this class is indexed by site & period, this metadata is not
+     * stored in individual data rows.
+     * 
+     * @param int $idSite
+     * @param string $period eg, '2012-01-01,2012-01-31'
+     * @param string $name The metadata name.
+     * @param mixed $value The metadata name.
+     */
+    public function addMetadata($idSite, $period, $name, $value)
+    {
+        $row = &$this->get($idSite, $period);
+        $row['_metadata'][$name] = $value;
+    }
+    
+    /**
+     * Returns archive data as an array indexed by metadata.
+     * 
+     * @param array $resultIndices An array mapping metadata names to pretty labels
+     *                             for them. Each archive data row will be indexed
+     *                             by the metadata specified here.
+     *                             
+     *                             Eg, array('site' => 'idSite', 'period' => 'Date')
+     * @return array
+     */
+    public function getArray($resultIndices)
+    {
+        $indexKeys = array_keys($resultIndices);
+        
+        $result = $this->createEmptyIndex($indexKeys);
+        foreach ($this->data as $idSite => $rowsByPeriod) {
+            foreach ($rowsByPeriod as $period => $row) {
+                $indexRowKeys = $this->getRowKeys($indexKeys, $row, $idSite, $period);
+                
+                $this->setIndexRow($result, $indexRowKeys, $row);
+            }
+        }
+        return $result;
+    }
+    
+    /**
+     * Returns archive data as a DataTable indexed by metadata. Indexed data will
+     * be represented by Piwik_DataTable_Array instances.
+     * 
+     * @param array $resultIndices An array mapping metadata names to pretty labels
+     *                             for them. Each archive data row will be indexed
+     *                             by the metadata specified here.
+     *                             
+     *                             Eg, array('site' => 'idSite', 'period' => 'Date')
+     * @return Piwik_DataTable|Piwik_DataTable_Array
+     */
+    public function getDataTable($resultIndices)
+    {
+        $dataTableFactory = new Piwik_Archive_DataTableFactory(
+            $this->dataNames, $this->dataType, $this->sitesId, $this->periods, $this->defaultRow);
+        
+        $index = $this->getArray($resultIndices);
+        return $dataTableFactory->make($index, $resultIndices);
+    }
+    
+    /**
+     * Returns archive data as a DataTable indexed by metadata. Indexed data will
+     * be represented by Piwik_DataTable_Array instances. Each DataTable will have
+     * its subtable IDs set.
+     * 
+     * This function will only work if blob data was loaded and only one record
+     * was loaded (not including subtables of the record).
+     * 
+     * @param array $resultIndices An array mapping metadata names to pretty labels
+     *                             for them. Each archive data row will be indexed
+     *                             by the metadata specified here.
+     *                             
+     *                             Eg, array('site' => 'idSite', 'period' => 'Date')
+     * @param int $idSubtable The subtable to return.
+     * @param bool $addMetadataSubtableId Whether to add the DB subtable ID as metadata
+     *                                    to each datatable, or not.
+     */
+    public function getExpandedDataTable($resultIndices, $idSubtable = null, $addMetadataSubtableId = false)
+    {
+        if ($this->dataType != 'blob') {
+            throw new Exception("Piwik_Archive_DataCollection: cannot call getExpandedDataTable with "
+                               . "{$this->dataType} data types. Only works with blob data.");
+        }
+        
+        if (count($this->dataNames) !== 1) {
+            throw new Exception("Piwik_Archive_DataCollection: cannot call getExpandedDataTable with "
+                               . "more than one record.");
+        }
+        
+        $dataTableFactory = new Piwik_Archive_DataTableFactory(
+            $this->dataNames, 'blob', $this->sitesId, $this->periods, $this->defaultRow);
+        $dataTableFactory->expandDataTable($addMetadataSubtableId);
+        $dataTableFactory->useSubtable($idSubtable);
+        
+        $index = $this->getArray($resultIndices);
+        return $dataTableFactory->make($index, $resultIndices);
+    }
+    
+    /**
+     * Returns metadata for a data row.
+     * 
+     * @param array $data The data row.
+     */
+    public static function getDataRowMetadata($data)
+    {
+        if (isset($data['_metadata'])) {
+            return $data['_metadata'];
+        } else {
+            return array();
+        }
+    }
+    
+    /**
+     * Removes all table metadata from a data row.
+     * 
+     * @param array $data The data row.
+     */
+    public static function removeMetadataFromDataRow(&$data)
+    {
+        unset($data['_metadata']);
+    }
+    
+    /**
+     * Creates an empty index using a list of metadata names. If the 'site' and/or
+     * 'period' metadata names are supplied, empty rows are added for every site/period
+     * that was queried for.
+     * 
+     * @param array $indexKeys List of metadata names to index archive data by.
+     * @return array
+     */
+    private function createEmptyIndex($indexKeys)
+    {
+        $result = array();
+        
+        if (!empty($indexKeys)) {
+            $index = array_shift($indexKeys);
+            if ($index == 'site') {
+                foreach ($this->sitesId as $idSite) {
+                    $result[$idSite] = $this->createEmptyIndex($indexKeys);
+                }
+            } else if ($index == 'period') {
+                foreach ($this->periods as $period => $periodObject) {
+                    $result[$period] = $this->createEmptyIndex($indexKeys);
+                }
+            }
+        }
+        
+        return $result;
+    }
+    
+    /**
+     * Sets a row in an index by the index keys of the row.
+     */
+    private function setIndexRow(&$result, $keys, $row)
+    {
+        $keyCount = count($keys);
+        
+        if ($keyCount > 1) {
+            $firstKey = array_shift($keys);
+            $this->setIndexRow($result[$firstKey], $keys, $row);
+        } else if ($keyCount == 1) {
+            $result[reset($keys)] = $row;
+        } else {
+            $result = $row;
+        }
+    }
+    
+    /**
+     * Returns the index keys for a row based on a set of metadata names.
+     * 
+     * @param array $metadataNames
+     * @param array $row
+     * @param int $idSite The site ID for the row (needed since site ID is not
+     *                    stored as metadata).
+     * @param string $period eg, '2012-01-01,2012-01-31'. The period for the
+     *                       row (needed since period is not stored as metadata).
+     */
+    private function getRowKeys($metadataNames, $row, $idSite, $period)
+    {
+        $result = array();
+        foreach ($metadataNames as $name) {
+            if ($name == 'site') {
+                $result['site'] = $idSite;
+            } else if ($name == 'period') {
+                $result['period'] = $period;
+            } else if (isset($row['_metadata'][$name])) {
+                $result[$name] = $row['_metadata'][$name];
+            }
+        }
+        return $result;
+    }
+}
diff --git a/core/Archive/DataTableFactory.php b/core/Archive/DataTableFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..6333545380de63220115fe181a33f71ea8d23e0c
--- /dev/null
+++ b/core/Archive/DataTableFactory.php
@@ -0,0 +1,363 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+/**
+ * Creates a Piwik_DataTable or Piwik_DataTable_Array instance based on an array
+ * index created by Piwik_Archive_DataCollection.
+ * 
+ * This class is only used by Piwik_Archive_DataCollection.
+ */
+class Piwik_Archive_DataTableFactory
+{
+    /**
+     * @see Piwik_Archive_DataCollection::$dataNames.
+     */
+    private $dataNames;
+    
+    /**
+     * @see Piwik_Archive_DataCollection::$dataType.
+     */
+    private $dataType;
+    
+    /**
+     * Whether to expand the DataTables that're created or not. Expanding a DataTable
+     * means creating DataTables using subtable blobs and correctly setting the subtable
+     * IDs of all DataTables.
+     * 
+     * @var bool
+     */
+    private $expandDataTable = false;
+    
+    /**
+     * Whether to add the subtable ID used in the database to the in-memory DataTables
+     * as metadata or not.
+     * 
+     * @var bool
+     */
+    private $addMetadataSubtableId = false;
+    
+    /**
+     * @see Piwik_Archive_DataCollection::$sitesId.
+     */
+    private $sitesId;
+    
+    /**
+     * @see Piwik_Archive_DataCollection::$periods.
+     */
+    private $periods;
+    
+    /**
+     * The ID of the subtable to create a DataTable for. Only relevant for blob data.
+     * 
+     * @var int|null
+     */
+    private $idSubtable = null;
+    
+    /**
+     * @see Piwik_Archive_DataCollection::$defaultRow.
+     */
+    private $defaultRow;
+    
+    /**
+     * Constructor.
+     */
+    public function __construct($dataNames, $dataType, $sitesId, $periods, $defaultRow)
+    {
+        $this->dataNames = $dataNames;
+        $this->dataType = $dataType;
+        $this->sitesId = $sitesId;
+        $this->periods = $periods;
+        $this->defaultRow = $defaultRow;
+    }
+    
+    /**
+     * Tells the factory instance to expand the DataTables that are created by
+     * creating subtables and setting the subtable IDs of rows w/ subtables correctly.
+     * 
+     * @param bool $addMetadataSubtableId Whether to add the subtable ID used in the
+     *                                    database to the in-memory DataTables as
+     *                                    metadata or not.
+     */
+    public function expandDataTable($addMetadataSubtableId = false)
+    {
+        $this->expandDataTable = true;
+        $this->addMetadataSubtableId = $addMetadataSubtableId;
+    }
+    
+    /**
+     * Tells the factory instance to create a DataTable using a blob with the
+     * supplied subtable ID.
+     * 
+     * @param int $idSubtable An in-database subtable ID.
+     */
+    public function useSubtable($idSubtable)
+    {
+        if (count($this->dataNames) !== 1) {
+            throw new Exception("Piwik_Archive_DataTableFactory: Getting subtables for multiple records in one"
+                               . " archive query is not currently supported.");
+        }
+        
+        $this->idSubtable = $idSubtable;
+    }
+    
+    /**
+     * Creates a Piwik_DataTable|Piwik_DataTable_Array instance using an index of
+     * archive data.
+     * 
+     * @param array $index @see Piwik_Archive_DataCollection
+     * @param array $resultIndices an array mapping metadata names with pretty metadata
+     *                             labels.
+     * @return Piwik_DataTable|Piwik_DataTable_Array
+     */
+    public function make($index, $resultIndices)
+    {
+        if (empty($resultIndices)) {
+            // for numeric data, if there's no index (and thus only 1 site & period in the query),
+            // we want to display every queried metric name
+            if (empty($index)
+                && $this->dataType == 'numeric'
+            ) {
+                $index = $this->defaultRow;
+            }
+            
+            $dataTable = $this->createDataTable($index, $keyMetadata = array());
+        } else {
+            $dataTable = $this->createDataTableArrayFromIndex($index, $resultIndices);
+        }
+        
+        $this->transformMetadata($dataTable);
+        return $dataTable;
+    }
+
+    /**
+     * Creates a Piwik_DataTable|Piwik_DataTable_Array instance using an array
+     * of blobs.
+     * 
+     * If only one record is being queried, a single DataTable will
+     * be returned. Otherwise, a DataTable_Array is returned that indexes
+     * DataTables by record name.
+     * 
+     * If expandDataTable was called, and only one record is being queried,
+     * the created DataTable's subtables will be expanded.
+     * 
+     * @param array $blobRow
+     * @return Piwik_DataTable|Piwik_DataTable_Array
+     */
+    private function makeFromBlobRow($blobRow)
+    {
+        if ($blobRow === false) {
+            return new Piwik_DataTable();
+        }
+        
+        if (count($this->dataNames) === 1) {
+            return $this->makeDataTableFromSingleBlob($blobRow);
+        } else {
+            return $this->makeIndexedByRecordNameDataTable($blobRow);
+        }
+    }
+    
+    /**
+     * Creates a DataTable for one record from an archive data row.
+     * 
+     * @see makeFromBlobRow
+     * 
+     * @param array $blobRow
+     * @return Piwik_DataTable
+     */
+    private function makeDataTableFromSingleBlob($blobRow)
+    {
+        $recordName = reset($this->dataNames);
+        if ($this->idSubtable !== null) {
+            $recordName .= '_' . $this->idSubtable;
+        }
+        
+        if (!empty($blobRow[$recordName])) {
+            $table = Piwik_DataTable::fromSerializedArray($blobRow[$recordName]);
+        } else {
+            $table = new Piwik_DataTable();
+        }
+        
+        // set table metadata
+        $table->metadata = Piwik_Archive_DataCollection::getDataRowMetadata($blobRow);
+        
+        if ($this->expandDataTable) {
+            $table->enableRecursiveFilters();
+            $this->setSubtables($table, $blobRow);
+        }
+        
+        return $table;
+    }
+    
+    /**
+     * Creates a DataTable for every record in an archive data row and puts them
+     * in a DataTable_Array instance.
+     * 
+     * @param array $blobRow
+     * @return Piwik_DataTable_Array
+     */
+    private function makeIndexedByRecordNameDataTable($blobRow)
+    {
+        $table = new Piwik_DataTable_Array();
+        $table->setKeyName('recordName');
+        
+        $tableMetadata = Piwik_Archive_DataCollection::getDataRowMetadata($blobRow);
+        
+        foreach ($blobRow as $name => $blob) {
+            $newTable = Piwik_DataTable::fromSerializedArray($blob);
+            $newTable->metadata = $tableMetadata;
+            
+            $table->addTable($newTable, $name);
+        }
+        
+        return $table;
+    }
+    
+    /**
+     * Creates a Piwik_DataTable_Array from an array index.
+     * 
+     * @param array $index @see Piwik_Archive_DataCollection
+     * @param array $resultIndices @see make
+     * @param array $keyMetadata The metadata to add to the table when it's created.
+     */
+    private function createDataTableArrayFromIndex($index, $resultIndices, $keyMetadata = array())
+    {
+        $resultIndexLabel = reset($resultIndices);
+        $resultIndex = key($resultIndices);
+        
+        array_shift($resultIndices);
+        
+        $result = new Piwik_DataTable_Array();
+        $result->setKeyName($resultIndexLabel);
+        
+        foreach ($index as $label => $value) {
+            $keyMetadata[$resultIndex] = $label;
+            
+            if (empty($resultIndices)) {
+                $newTable = $this->createDataTable($value, $keyMetadata);
+            } else {
+                $newTable = $this->createDataTableArrayFromIndex($value, $resultIndices, $keyMetadata);
+            }
+            
+            $result->addTable($newTable, $this->prettifyIndexLabel($resultIndex, $label));
+        }
+        
+        return $result;
+    }
+    
+    /**
+     * Creates a Piwik_DataTable instance from an index row.
+     * 
+     * @param array|false $data An archive data row.
+     * @param array $keyMetadata The metadata to add to the table(s) when created.
+     * @return Piwik_DataTable|Piwik_DataTable_Array
+     */
+    private function createDataTable($data, $keyMetadata)
+    {
+        if ($this->dataType == 'blob') {
+            $result = $this->makeFromBlobRow($data);
+        } else {
+            $table = new Piwik_DataTable_Simple();
+            
+            if (!empty($data)) {
+                $table->metadata = Piwik_Archive_DataCollection::getDataRowMetadata($data);
+                
+                Piwik_Archive_DataCollection::removeMetadataFromDataRow($data);
+                
+                $table->addRow(new Piwik_DataTable_Row(array(Piwik_DataTable_Row::COLUMNS => $data)));
+            }
+            
+            $result = $table;
+        }
+        
+        if (!isset($keyMetadata['site'])) {
+            $keyMetadata['site'] = reset($this->sitesId);
+        }
+        
+        if (!isset($keyMetadata['period'])) {
+            reset($this->periods);
+            $keyMetadata['period'] = key($this->periods);
+        }
+        
+        // Note: $result can be a DataTable_Array
+        $result->filter(function ($table) use ($keyMetadata) {
+            foreach ($keyMetadata as $name => $value) {
+                $table->setMetadata($name, $value);
+            }
+        });
+        
+        return $result;
+    }
+    
+    /**
+     * Creates DataTables from $dataTable's subtable blobs (stored in $blobRow) and sets
+     * the subtable IDs of each DataTable row.
+     * 
+     * @param Piwik_DataTable $dataTable
+     * @param array $blobRow An array associating record names (w/ subtable if applicable)
+     *                       with blob values. This should hold every subtable blob for
+     *                       the loaded DataTable.
+     */
+    private function setSubtables($dataTable, $blobRow)
+    {
+        $dataName = reset($this->dataNames);
+        
+        foreach ($dataTable->getRows() as $row) {
+            $sid = $row->getIdSubDataTable();
+            if ($sid === null) {
+                continue;
+            }
+            
+            $blobName = $dataName."_".$sid;
+            if (isset($blobRow[$blobName])) {
+                $subtable = Piwik_DataTable::fromSerializedArray($blobRow[$blobName]);
+                $this->setSubtables($subtable, $blobRow);
+                
+                // we edit the subtable ID so that it matches the newly table created in memory
+                // NB: we dont overwrite the datatableid in the case we are displaying the table expanded.
+                if ($this->addMetadataSubtableId) {
+                    // this will be written back to the column 'idsubdatatable' just before rendering,
+                    // see Renderer/Php.php
+                    $row->addMetadata('idsubdatatable_in_db', $row->getIdSubDataTable());
+                }
+                
+                $row->setSubtable($subtable);
+            }
+        }
+    }
+    
+    /**
+     * Converts site IDs and period string ranges into Piwik_Site instances and
+     * Piwik_Period instances in DataTable metadata.
+     */
+    private function transformMetadata($table)
+    {
+        $periods = $this->periods;
+        $table->filter(function ($table) use($periods) {
+            $table->metadata['site'] = new Piwik_Site($table->metadata['site']);
+            $table->metadata['period'] = $periods[$table->metadata['period']];
+        });
+    }
+    
+    /**
+     * Returns the pretty version of an index label.
+     * 
+     * @param string $labelType eg, 'site', 'period', etc.
+     * @param string $label eg, '0', '1', '2012-01-01,2012-01-31', etc.
+     * @return string
+     */
+    private function prettifyIndexLabel($labelType, $label)
+    {
+        if ($labelType == 'period') { // prettify period labels
+            return $this->periods[$label]->getPrettyString();
+        }
+        return $label;
+    }
+}
diff --git a/core/Archive/Single.php b/core/Archive/Single.php
deleted file mode 100644
index 3e805d4a98db13c933b1899b16e6ac931f5ee9de..0000000000000000000000000000000000000000
--- a/core/Archive/Single.php
+++ /dev/null
@@ -1,632 +0,0 @@
-<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- *
- * @category Piwik
- * @package Piwik
- */
-
-/**
- * Piwik_Archive_Single is used to store the data of a single archive,
- * for example the statistics for the 'day' '2008-02-21' for the website idSite '2'
- *
- * @package Piwik
- * @subpackage Piwik_Archive
- */
-class Piwik_Archive_Single extends Piwik_Archive
-{
-    /**
-     * The Piwik_ArchiveProcessing object used to check that the archive is available
-     * and launch the processing if the archive was not yet processed
-     *
-     * @var Piwik_ArchiveProcessing
-     */
-    public $archiveProcessing = null;
-
-    /**
-     * @var bool Set to true if the archive has at least 1 visit
-     */
-    public $isThereSomeVisits = null;
-
-    /**
-     * Period of this Archive
-     *
-     * @var Piwik_Period
-     */
-    protected $period = null;
-
-    /**
-     * Set to true will activate numeric value caching for this archive.
-     *
-     * @var bool
-     */
-    protected $cacheEnabledForNumeric = true;
-
-    /**
-     * Array of cached numeric values, used to make requests faster
-     * when requesting the same value again and again
-     *
-     * @var array of numeric
-     */
-    protected $numericCached = array();
-
-    /**
-     * Array of cached blob, used to make requests faster when requesting the same blob again and again
-     *
-     * @var array of mixed
-     */
-    protected $blobCached = array();
-
-    /**
-     * idarchive of this Archive in the database
-     *
-     * @var int
-     */
-    protected $idArchive = null;
-
-    /**
-     * name of requested report
-     *
-     * @var string
-     */
-    protected $requestedReport = null;
-
-    /**
-     * Flag set to true once the archive has been checked (when we make sure it is archived)
-     *
-     * @var bool
-     */
-    protected $alreadyChecked = array();
-
-    protected function clearCache()
-    {
-        foreach ($this->blobCached as $name => $blob) {
-            $this->freeBlob($name);
-        }
-        $this->blobCached = array();
-    }
-
-    public function __destruct()
-    {
-        $this->clearCache();
-    }
-
-    /**
-     * Returns the blob cache. For testing.
-     *
-     * @return array
-     */
-    public function getBlobCache()
-    {
-        return $this->blobCached;
-    }
-
-    /**
-     * Returns the pretty date of this Archive, eg. 'Thursday 20th March 2008'
-     *
-     * @return string
-     */
-    public function getPrettyDate()
-    {
-        return $this->period->getPrettyString();
-    }
-
-    /**
-     * Returns the idarchive of this Archive used to index this archive in the DB
-     *
-     * @throws Exception
-     * @return int
-     */
-    public function getIdArchive()
-    {
-        if (is_null($this->idArchive)) {
-            throw new Exception("idArchive is null");
-        }
-        return $this->idArchive;
-    }
-
-    /**
-     * Set the period
-     *
-     * @param Piwik_Period $period
-     */
-    public function setPeriod(Piwik_Period $period)
-    {
-        $this->period = $period;
-    }
-
-    public function getPeriod()
-    {
-        return $this->period;
-    }
-
-    /**
-     * Returns the timestamp of the first date in the period for this Archive.
-     * This is used to sort archives by date when working on a Archive_Array
-     *
-     * @return int Unix timestamp
-     */
-    public function getTimestampStartDate()
-    {
-        if (!is_null($this->archiveProcessing)) {
-            $timestamp = $this->archiveProcessing->getTimestampStartDate();
-            if (!empty($timestamp)) {
-                return $timestamp;
-            }
-        }
-        return $this->period->getDateStart()->getTimestamp();
-    }
-
-    /**
-     * Prepares the archive. Gets the idarchive from the ArchiveProcessing.
-     *
-     * This will possibly launch the archiving process if the archive was not available.
-     * @return bool
-     */
-    public function prepareArchive()
-    {
-        $archiveJustProcessed = false;
-
-
-        $periodString = $this->period->getLabel();
-        $plugin = Piwik_ArchiveProcessing::getPluginBeingProcessed($this->getRequestedReport());
-
-        $cacheKey = 'all';
-        if ($periodString == 'range') {
-            $cacheKey = $plugin;
-        }
-        if (!isset($this->alreadyChecked[$cacheKey])) {
-            $this->isThereSomeVisits = false;
-            $this->alreadyChecked[$cacheKey] = true;
-            $dayString = $this->period->getPrettyString();
-            $logMessage = sprintf("%s (%s), plugin %s", $periodString, $dayString, $plugin);
-            // if the END of the period is BEFORE the website creation date
-            // we already know there are no stats for this period
-            // we add one day to make sure we don't miss the day of the website creation
-            if ($this->period->getDateEnd()->addDay(2)->isEarlier($this->site->getCreationDate())) {
-                Piwik::log(sprintf("Archive %s skipped, archive is before the website was created.", $logMessage));
-                return;
-            }
-
-            // if the starting date is in the future we know there is no visit
-            if ($this->period->getDateStart()->subDay(2)->isLater(Piwik_Date::today())) {
-                Piwik::log(sprintf("Archive %s skipped, archive is after today.", $logMessage));
-                return;
-            }
-
-            // we make sure the archive is available for the given date
-            $periodLabel = $this->period->getLabel();
-            $this->archiveProcessing = Piwik_ArchiveProcessing::factory($periodLabel);
-            $this->archiveProcessing->setSite($this->site);
-            $this->archiveProcessing->setPeriod($this->period);
-            $this->archiveProcessing->setSegment($this->segment);
-
-            $this->archiveProcessing->init();
-
-            $this->archiveProcessing->setRequestedReport($this->getRequestedReport());
-
-            $archivingDisabledArchiveNotProcessed = false;
-            $idArchive = $this->archiveProcessing->loadArchive();
-            if (empty($idArchive)) {
-                if ($this->archiveProcessing->isArchivingDisabled()) {
-                    $archivingDisabledArchiveNotProcessed = true;
-                    $logMessage = sprintf("Archiving disabled, for %s", $logMessage);
-                } else {
-                    Piwik::log(sprintf("Processing %s, not archived yet...", $logMessage));
-                    $archiveJustProcessed = true;
-
-                    // Process the reports
-                    $this->archiveProcessing->launchArchiving();
-
-                    $idArchive = $this->archiveProcessing->getIdArchive();
-                    $logMessage = sprintf("Processed %d, for %s", $idArchive, $logMessage);
-                }
-            } else {
-                $logMessage = sprintf("Already processed, fetching idArchive = %d (idSite=%d), for %s", $idArchive, $this->site->getId(), $logMessage);
-            }
-            Piwik::log(sprintf("%s, Visits = %d", $logMessage, $this->archiveProcessing->getNumberOfVisits()));
-            $this->isThereSomeVisits = !$archivingDisabledArchiveNotProcessed
-                && $this->archiveProcessing->isThereSomeVisits();
-            $this->idArchive = $idArchive;
-        }
-        return $archiveJustProcessed;
-    }
-
-    /**
-     * Returns a value from the current archive with the name = $name
-     * Method used by getNumeric or getBlob
-     *
-     * @param string $name
-     * @param string $typeValue     numeric|blob
-     * @param string|bool $archivedDate  Value to store date of archive info in. If false, not stored.
-     * @return mixed|bool  false if no result
-     */
-    protected function get($name, $typeValue = 'numeric', &$archivedDate = false)
-    {
-        $this->setRequestedReport($name);
-        $this->prepareArchive();
-
-        // values previously "get" and now cached
-        if ($typeValue == 'numeric'
-            && $this->cacheEnabledForNumeric
-            && isset($this->numericCached[$name])
-        ) {
-            return $this->numericCached[$name];
-        }
-
-        // During archiving we prefetch the blobs recursively
-        // and we get them faster from memory after
-        if ($typeValue == 'blob'
-            && isset($this->blobCached[$name])
-        ) {
-            return $this->blobCached[$name];
-        }
-
-        if ($name == 'idarchive') {
-            return $this->idArchive;
-        }
-
-        if (!$this->isThereSomeVisits) {
-            return false;
-        }
-
-        // select the table to use depending on the type of the data requested
-        switch ($typeValue) {
-            case 'blob':
-                $table = $this->archiveProcessing->getTableArchiveBlobName();
-                break;
-
-            case 'numeric':
-            default:
-                $table = $this->archiveProcessing->getTableArchiveNumericName();
-                break;
-        }
-
-        $db = Zend_Registry::get('db');
-        $row = $db->fetchRow("SELECT value, ts_archived
-								FROM $table
-								WHERE idarchive = ? AND name = ?",
-            array($this->idArchive, $name)
-        );
-
-        $value = $tsArchived = false;
-        if (is_array($row)) {
-            $value = $row['value'];
-            $tsArchived = $row['ts_archived'];
-        }
-
-        if ($archivedDate !== false) {
-            $archivedDate = $tsArchived;
-        }
-
-        if ($value === false) {
-            if ($typeValue == 'numeric'
-                && $this->cacheEnabledForNumeric
-            ) {
-                $this->numericCached[$name] = false;
-            }
-            return $value;
-        }
-
-        // uncompress when selecting from the BLOB table
-        if ($typeValue == 'blob' && $db->hasBlobDataType()) {
-            $value = $this->uncompress($value);
-        }
-
-        if ($typeValue == 'numeric'
-            && $this->cacheEnabledForNumeric
-        ) {
-            $this->numericCached[$name] = $value;
-        }
-        return $value;
-    }
-
-
-    /**
-     * This method loads in memory all the subtables for the main table called $name.
-     * You have to give it the parent table $dataTableToLoad so we can lookup the sub tables ids to load.
-     *
-     * If $addMetadataSubtableId set to true, it will add for each row a 'metadata' called 'databaseSubtableId'
-     *  containing the child ID of the subtable  associated to this row.
-     *
-     * @param string $name
-     * @param Piwik_DataTable $dataTableToLoad
-     * @param bool $addMetadataSubtableId
-     */
-    public function loadSubDataTables($name, Piwik_DataTable $dataTableToLoad, $addMetadataSubtableId = false)
-    {
-        // we have to recursively load all the subtables associated to this table's rows
-        // and update the subtableID so that it matches the newly instanciated table
-        foreach ($dataTableToLoad->getRows() as $row) {
-            $subTableID = $row->getIdSubDataTable();
-
-            if ($subTableID !== null) {
-                $subDataTableLoaded = $this->getDataTable($name, $subTableID);
-
-                $row->setSubtable($subDataTableLoaded);
-
-                $this->loadSubDataTables($name, $subDataTableLoaded, $addMetadataSubtableId);
-
-                // we edit the subtable ID so that it matches the newly table created in memory
-                // NB: we dont overwrite the datatableid in the case we are displaying the table expanded.
-                if ($addMetadataSubtableId) {
-                    // this will be written back to the column 'idsubdatatable' just before rendering, see Renderer/Php.php
-                    $row->addMetadata('idsubdatatable_in_db', $row->getIdSubDataTable());
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Free the blob cache memory array
-     * @param $name
-     */
-    public function freeBlob($name)
-    {
-        unset($this->blobCached[$name]);
-        $this->blobCached[$name] = null;
-    }
-
-    protected function uncompress($data)
-    {
-        return @gzuncompress($data);
-    }
-
-    /**
-     * Fetches all blob fields name_* at once for the current archive for performance reasons.
-     *
-     * @param string  $name
-     *
-     * @return void
-     */
-    public function preFetchBlob($name)
-    {
-        $this->setRequestedReport($name);
-        $this->prepareArchive();
-        if (!$this->isThereSomeVisits) {
-            return;
-        }
-
-        $tableBlob = $this->archiveProcessing->getTableArchiveBlobName();
-
-        $db = Zend_Registry::get('db');
-        $hasBlobs = $db->hasBlobDataType();
-
-        // select blobs w/ name like "$name_[0-9]+" w/o using RLIKE
-        $nameEnd = strlen($name) + 2;
-        $query = $db->query("SELECT value, name
-								FROM $tableBlob
-								WHERE idarchive = ?
-									AND (name = ? OR
-											(name LIKE ? AND SUBSTRING(name, $nameEnd, 1) >= '0'
-														 AND SUBSTRING(name, $nameEnd, 1) <= '9') )",
-            array($this->idArchive, $name, $name . '%')
-        );
-
-        while ($row = $query->fetch()) {
-            $value = $row['value'];
-            $name = $row['name'];
-
-            if ($hasBlobs) {
-                $this->blobCached[$name] = $this->uncompress($value);
-                if ($this->blobCached[$name] === false) {
-                    //throw new Exception("Error gzuncompress $name ");
-                }
-            } else {
-                $this->blobCached[$name] = $value;
-            }
-        }
-    }
-
-    /**
-     * Returns a numeric value from this Archive, with the name '$name'
-     *
-     * @param string $name
-     * @return int|float
-     */
-    public function getNumeric($name)
-    {
-        return $this->formatNumericValue($this->get($name, 'numeric'));
-    }
-
-
-    /**
-     * Returns a blob value from this Archive, with the name '$name'
-     * Blob values are all values except int and float.
-     *
-     * @param string $name
-     * @return mixed
-     */
-    public function getBlob($name)
-    {
-        return $this->get($name, 'blob');
-    }
-
-    /**
-     * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Simple
-     * containing one row per field name.
-     *
-     * For example $fields = array(    'max_actions',
-     *                        'nb_uniq_visitors',
-     *                        'nb_visits',
-     *                        'nb_actions',
-     *                        'sum_visit_length',
-     *                        'bounce_count',
-     *                        'nb_visits_converted'
-     *                    );
-     *
-     * @param string|array $fields Name or array of names of Archive fields
-     *
-     * @return Piwik_DataTable_Simple
-     */
-    public function getDataTableFromNumeric($fields)
-    {
-        if (!is_array($fields)) {
-            $fields = array($fields);
-        }
-
-        $values = array();
-        foreach ($fields as $field) {
-            $values[$field] = $this->getNumeric($field);
-        }
-
-        $table = new Piwik_DataTable_Simple();
-        $table->addRowsFromArray($values);
-        return $table;
-    }
-
-    /**
-     * Returns a DataTable that has the name '$name' from the current Archive.
-     * If $idSubTable is specified, returns the subDataTable called '$name_$idSubTable'
-     *
-     * @param string $name
-     * @param int $idSubTable  optional id SubDataTable
-     * @return Piwik_DataTable
-     */
-    public function getDataTable($name, $idSubTable = null)
-    {
-        if (!is_null($idSubTable)) {
-            $name .= sprintf("_%s", $idSubTable);
-        }
-
-        $this->setRequestedReport($name);
-
-        $data = $this->get($name, 'blob', $tsArchived);
-
-        $table = $this->makeDataTable();
-
-        if ($data !== false) {
-            $table->addRowsFromSerializedArray($data);
-            $table->setMetadata(Piwik_DataTable::ARCHIVED_DATE_METADATA_NAME, $tsArchived);
-        }
-        if ($data === false
-            && $idSubTable !== null
-        ) {
-            // This is not expected, but somehow happens in some unknown cases and very rarely.
-            // Do not throw error in this case
-            //throw new Exception("not expected");
-            return new Piwik_DataTable();
-        }
-
-        return $table;
-    }
-
-    /**
-     * Creates a new DataTable with some metadata set. Sets the following metadata:
-     * - 'site' => Piwik_Site instance for this archive
-     * - 'period' => Piwik_Period instance for this archive
-     * - 'timestamp' => the timestamp of the first date in this archive
-     *
-     * @param bool $isSimple Whether the DataTable should be a DataTable_Simple
-     *                       instance or not.
-     * @return Piwik_DataTable
-     */
-    public function makeDataTable($isSimple = false)
-    {
-        if ($isSimple) {
-            $result = new Piwik_DataTable_Simple();
-        } else {
-            $result = new Piwik_DataTable();
-        }
-
-        $result->setMetadata('site', $this->getSite());
-        $result->setMetadata('period', $this->getPeriod());
-        $result->setMetadata('timestamp', $this->getTimestampStartDate());
-
-        return $result;
-    }
-
-    public function setRequestedReport($requestedReport)
-    {
-        $this->requestedReport = $requestedReport;
-    }
-
-    /**
-     * Returns the report (the named collection of metrics) this Archive instance is
-     * currently going to query/process.
-     *
-     * @return string
-     */
-    protected function getRequestedReport()
-    {
-        return self::getRequestedReportFor($this->requestedReport);
-    }
-
-    /**
-     * Returns the name of the report (the named collection of metrics) that contains the
-     * specified metric.
-     *
-     * @param string $metric The metric whose report is being requested. If this does
-     *                       not belong to a known report, its assumed to be the report
-     *                       itself.
-     * @return string
-     */
-    public static function getRequestedReportFor($metric)
-    {
-        // Core metrics are always processed in Core, for the requested date/period/segment
-        if (in_array($metric, Piwik_ArchiveProcessing::getCoreMetrics())
-            || $metric == 'max_actions'
-        ) {
-            return 'VisitsSummary_CoreMetrics';
-        }
-        // VisitFrequency metrics don't follow the same naming convention (HACK)
-        if (strpos($metric, '_returning') > 0
-            // ignore Goal_visitor_returning_1_1_nb_conversions
-            && strpos($metric, 'Goal_') === false
-        ) {
-            return 'VisitFrequency_Metrics';
-        }
-        // Goal_* metrics are processed by the Goals plugin (HACK)
-        if (strpos($metric, 'Goal_') === 0) {
-            return 'Goals_Metrics';
-        }
-        // Actions metrics are processed by the Actions plugin (HACK) (3RD HACK IN FACT) (YES, THIS IS TOO MUCH HACKING)
-        // (FIXME PLEASE).
-        if (in_array($metric, Piwik_Archive::$actionsMetrics)) {
-            return 'Actions_Metrics';
-        }
-        return $metric;
-    }
-
-    /**
-     * Returns a DataTable that has the name '$name' from the current Archive.
-     * Also loads in memory all subDataTable for this DataTable.
-     *
-     * For example, if $name = 'Referers_keywordBySearchEngine' it will load all DataTable
-     *  named 'Referers_keywordBySearchEngine_*' and they will be set as subDataTable to the
-     *  rows. You can then go through the rows
-     *        $rows = DataTable->getRows();
-     *  and for each row request the subDataTable (in this case the DataTable of the keywords for each search engines)
-     *        $idSubTable = $row->getIdSubDataTable();
-     *        $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable);
-     *
-     * @param string $name
-     * @param int $idSubTable  Optional subDataTable to load instead of loading the parent DataTable
-     * @return Piwik_DataTable
-     */
-    public function getDataTableExpanded($name, $idSubTable = null)
-    {
-        $this->preFetchBlob($name);
-        $dataTableToLoad = $this->getDataTable($name, $idSubTable);
-        $this->loadSubDataTables($name, $dataTableToLoad, $addMetadataSubtableId = true);
-        $dataTableToLoad->enableRecursiveFilters();
-        $this->freeBlob($name);
-        return $dataTableToLoad;
-    }
-
-    /**
-     * Returns true if Piwik can launch the archiving process for this archive,
-     * false if otherwise.
-     *
-     * @return bool
-     */
-    public function isArchivingDisabled()
-    {
-        return Piwik_ArchiveProcessing::isArchivingDisabledFor($this->segment, $this->period);
-    }
-}
diff --git a/core/ArchiveProcessing.php b/core/ArchiveProcessing.php
index 18acd71b1ab1271f51c5eb857fff1431f52fd8c8..31af7e1047fd7928b4abef1d863c9ff35b3e5853 100644
--- a/core/ArchiveProcessing.php
+++ b/core/ArchiveProcessing.php
@@ -507,7 +507,7 @@ abstract class Piwik_ArchiveProcessing
     public function getDoneStringFlag($flagArchiveAsAllPlugins = false)
     {
         return self::getDoneStringFlagFor(
-            $this->getSegment(), $this->period, $this->getRequestedReport(), $flagArchiveAsAllPlugins);
+            $this->getSegment(), $this->period->getLabel(), $this->getRequestedReport(), $flagArchiveAsAllPlugins);
     }
 
     /**
@@ -515,15 +515,15 @@ abstract class Piwik_ArchiveProcessing
      * whether the archive was created successfully or not).
      *
      * @param Piwik_Segment $segment
-     * @param Piwik_Period $period
+     * @param string $periodLabel
      * @param string $requestedReport
      * @param bool $flagArchiveAsAllPlugins
      * @return string
      */
-    public static function getDoneStringFlagFor($segment, $period, $requestedReport, $flagArchiveAsAllPlugins = false)
+    public static function getDoneStringFlagFor($segment, $periodLabel, $requestedReport, $flagArchiveAsAllPlugins = false)
     {
         $segmentHash = $segment->getHash();
-        if (!self::shouldProcessReportsAllPluginsFor($segment, $period)) {
+        if (!self::shouldProcessReportsAllPluginsFor($segment, $periodLabel)) {
             $pluginProcessed = self::getPluginBeingProcessed($requestedReport);
             if (!Piwik_PluginsManager::getInstance()->isPluginLoaded($pluginProcessed)
                 || $flagArchiveAsAllPlugins
@@ -583,10 +583,10 @@ abstract class Piwik_ArchiveProcessing
         }
         $this->insertNumericRecord($done, $flag);
     }
-
+    
     /**
      * Returns the name of the numeric table where the archive numeric values are stored
-     *
+     * 
      * @return string
      */
     public function getTableArchiveNumericName()
@@ -639,7 +639,7 @@ abstract class Piwik_ArchiveProcessing
         $this->requestedReport = $requestedReport;
     }
 
-    protected function getRequestedReport()
+    public function getRequestedReport()
     {
         return $this->requestedReport;
     }
@@ -957,15 +957,15 @@ abstract class Piwik_ArchiveProcessing
      */
     public function isArchivingDisabled()
     {
-        return self::isArchivingDisabledFor($this->getSegment(), $this->period);
+        return self::isArchivingDisabledFor($this->getSegment(), $this->period->getLabel());
     }
 
-    public static function isArchivingDisabledFor($segment, $period)
+    public static function isArchivingDisabledFor($segment, $periodLabel)
     {
-        if ($period->getLabel() == 'range') {
+        if ($periodLabel == 'range') {
             return false;
         }
-        $processOneReportOnly = !self::shouldProcessReportsAllPluginsFor($segment, $period);
+        $processOneReportOnly = !self::shouldProcessReportsAllPluginsFor($segment, $periodLabel);
         $isArchivingDisabled = !self::isRequestAuthorizedToArchive();
 
         if ($processOneReportOnly) {
@@ -1003,17 +1003,17 @@ abstract class Piwik_ArchiveProcessing
      */
     protected function shouldProcessReportsAllPlugins($segment, $period)
     {
-        return self::shouldProcessReportsAllPluginsFor($segment, $period);
+        return self::shouldProcessReportsAllPluginsFor($segment, $period->getLabel());
     }
 
     /**
      * @param Piwik_Segment $segment
-     * @param Piwik_Period $period
+     * @param string $period
      * @return bool
      */
-    protected static function shouldProcessReportsAllPluginsFor($segment, $period)
+    protected static function shouldProcessReportsAllPluginsFor($segment, $periodLabel)
     {
-        if ($segment->isEmpty() && $period->getLabel() != 'range') {
+        if ($segment->isEmpty() && $periodLabel != 'range') {
             return true;
         }
 
diff --git a/core/ArchiveProcessing/Day.php b/core/ArchiveProcessing/Day.php
index 75b48bde5c9012998b98f300f5a7c748935f27a8..96a630a93a7dddf55c2fd790332285c5803996e4 100644
--- a/core/ArchiveProcessing/Day.php
+++ b/core/ArchiveProcessing/Day.php
@@ -126,11 +126,7 @@ class Piwik_ArchiveProcessing_Day extends Piwik_ArchiveProcessing
      */
     private function redirectRequestToVisitsSummary()
     {
-        $archive = new Piwik_Archive_Single();
-        $archive->setSite($this->site);
-        $archive->setPeriod($this->period);
-        $archive->setSegment($this->getSegment());
-        $archive->setRequestedReport('VisitsSummary');
+        $archive = new Piwik_Archive($this->site->getId(), $this->period, $this->getSegment());
 
         $nbVisits = $archive->getNumeric('nb_visits');
         $this->isThereSomeVisits = $nbVisits > 0;
diff --git a/core/ArchiveProcessing/Period.php b/core/ArchiveProcessing/Period.php
index 6d3de2e6f6e7a47be0f7d36adb786a0fdcd337b8..840f5b5c97491cde97ec884a2c220f4ac325d8d2 100644
--- a/core/ArchiveProcessing/Period.php
+++ b/core/ArchiveProcessing/Period.php
@@ -34,7 +34,42 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
     /**
      * @var Piwik_Archive_Single[]
      */
-    public $archives = array();
+    //public $archives = array();
+    
+    public $archive = null;
+    
+    /**
+     * Set the period
+     *
+     * @param Piwik_Period $period
+     */
+    public function setPeriod( Piwik_Period $period ) 
+    {
+        parent::setPeriod($period);
+        $this->resetSubperiodArchiveQuery();
+    }
+    
+    /**
+     * Sets the segment.
+     * 
+     * @param Piwik_Segment $segment
+     */
+    public function setSegment( Piwik_Segment $segment) 
+    {
+        parent::setSegment($segment);
+        $this->resetSubperiodArchiveQuery();
+    }
+    
+    /**
+     * Set the site
+     *
+     * @param Piwik_Site $site
+     */
+    public function setSite( Piwik_Site $site )
+    {
+        parent::setSite($site);
+        $this->resetSubperiodArchiveQuery();
+    }
 
     /**
      * Sums all values for the given field names $aNames over the period
@@ -78,52 +113,72 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
             $aNames = array($aNames);
         }
 
-        // fetch the numeric values and apply the operation on them
-        $results = array();
-        foreach ($this->archives as $id => $archive) {
-            foreach ($aNames as $name) {
-                if (!isset($results[$name])) {
-                    $results[$name] = 0;
-                }
-                if ($name == 'nb_uniq_visitors') continue;
-
-                $valueToSum = $archive->getNumeric($name);
-
-                if ($valueToSum !== false) {
-                    switch ($operationToApply) {
-                        case 'sum':
-                            $results[$name] += $valueToSum;
-                            break;
-                        case 'max':
-                            $results[$name] = max($results[$name], $valueToSum);
-                            break;
-                        case 'min':
-                            $results[$name] = min($results[$name], $valueToSum);
-                            break;
-                        default:
-                            throw new Exception("Operation not applicable.");
-                            break;
-                    }
+        // remove nb_uniq_visitors if present
+        foreach ($aNames as $i => $name) {
+            if ($name == 'nb_uniq_visitors') {
+                $results['nb_uniq_visitors'] = 0;
+                unset($aNames[$i]);
+                
+                break;
+            }
+        }
+        
+        // data will be array mapping each period w/ result row for period
+        $data = $this->archive->getNumeric($aNames);
+        foreach ($data as $dateRange => $row) {
+            foreach ($row as $name => $value) {
+                switch ($operationToApply) {
+                    case 'sum':
+                        if (!isset($results[$name])) {
+                            $results[$name] = 0;
+                        }
+                        
+                        $results[$name] += $value;
+                        break;
+                    case 'max':
+                        if (!isset($results[$name])) {
+                            $results[$name] = 0;
+                        }
+                        
+                        $results[$name] = max($results[$name], $value);
+                        break;
+                    case 'min':
+                        if (!isset($results[$name])) {
+                            $results[$name] = $value;
+                        }
+                        
+                        $results[$name] = min($results[$name], $value);
+                        break;
+                    default:
+                        throw new Exception("Operation not applicable.");
+                        break;
                 }
             }
         }
-
+        
+        // set default for metrics that weren't found
+        foreach ($aNames as $name) {
+            if (!isset($results[$name])) {
+                $results[$name] = 0;
+            }
+        }
+        
         if (!Piwik::isUniqueVisitorsEnabled($this->period->getLabel())) {
             unset($results['nb_uniq_visitors']);
         }
-
-        foreach ($results as $name => $value) {
+        
+        foreach($results as $name => $value) {
             if ($name == 'nb_uniq_visitors') {
-                $value = (float)$this->computeNbUniqVisitors();
+                $value = (float) $this->computeNbUniqVisitors();
             }
             $this->insertRecord($name, $value);
         }
-
+        
         // if asked for only one field to sum
         if (count($results) == 1) {
-            return $results[$name];
+            return reset($results);
         }
-
+        
         // returns the array of records once summed
         return $results;
     }
@@ -200,23 +255,24 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
     protected function getRecordDataTableSum($name, $invalidSummedColumnNameToRenamedName, &$columnAggregationOperations = null)
     {
         $table = new Piwik_DataTable();
-        
-        if (is_array($columnAggregationOperations)) {
+        if ($columnAggregationOperations !== null) {
             $table->setColumnAggregationOperations($columnAggregationOperations);
         }
         
-        foreach ($this->archives as $archive) {
-            $archive->preFetchBlob($name);
-            $datatableToSum = $archive->getDataTable($name);
-            $archive->loadSubDataTables($name, $datatableToSum);
+        $data = $this->archive->getDataTableExpanded($name, $idSubTable = null, $addMetadataSubtableId = false);
+        foreach ($data->getArray() as $dateRange => $datatableToSum)
+        {
             $table->addDataTable($datatableToSum);
-            $archive->freeBlob($name);
         }
-
-        if (is_null($invalidSummedColumnNameToRenamedName)) {
+        
+        unset($data);
+        
+        if(is_null($invalidSummedColumnNameToRenamedName))
+        {
             $invalidSummedColumnNameToRenamedName = self::$invalidSummedColumnNameToRenamedName;
         }
-        foreach ($invalidSummedColumnNameToRenamedName as $oldName => $newName) {
+        foreach($invalidSummedColumnNameToRenamedName as $oldName => $newName)
+        {
             $table->renameColumn($oldName, $newName);
         }
         return $table;
@@ -228,25 +284,20 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
     }
 
     /**
-     * Returns the ID of the archived subperiods.
-     *
-     * @return array  Array of the idArchive of the subperiods
+     * Returns an archive instance that can be used to query for data in each
+     * subperiod of the period we're archiving data for.
+     * 
+     * @return Piwik_Archive
      */
     protected function loadSubperiodsArchive()
     {
-        $periods = array();
-
-        // we first compute every subperiod of the archive
-        foreach ($this->period->getSubperiods() as $period) {
-            $archivePeriod = new Piwik_Archive_Single();
-            $archivePeriod->setSite($this->site);
-            $archivePeriod->setPeriod($period);
-            $archivePeriod->setSegment($this->getSegment());
-            $archivePeriod->setRequestedReport($this->getRequestedReport());
-
-            $periods[] = $archivePeriod;
-        }
-        return $periods;
+        return new Piwik_Archive(
+            array($this->site->getId()),
+            $this->period->getSubperiods(),
+            $this->getSegment(),
+            $forceIndexedBySite = false,
+            $forceIndexedByDate = true
+        );
     }
 
     /**
@@ -266,8 +317,9 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
 
     protected function loadSubPeriods()
     {
-        if (empty($this->archives)) {
-            $this->archives = $this->loadSubperiodsArchive();
+        if(is_null($this->archive))
+        {
+            $this->archive = $this->loadSubperiodsArchive();
         }
     }
 
@@ -290,18 +342,21 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
             $record = $this->archiveNumericValuesSum($toSum);
             $this->archiveNumericValuesMax('max_actions');
 
-            $nbVisitsConverted = $record['nb_visits_converted'];
-            $nbVisits = $record['nb_visits'];
+            if (!isset($record['nb_visits'])) {
+                $nbVisits = $nbVisitsConverted = 0;
+            } else {
+                $nbVisitsConverted = $record['nb_visits_converted'];
+                $nbVisits = $record['nb_visits'];
+            }
         } else {
-            $archive = new Piwik_Archive_Single();
-            $archive->setSite($this->site);
-            $archive->setPeriod($this->period);
-            $archive->setSegment($this->getSegment());
-
-            $nbVisits = $archive->getNumeric('nb_visits');
-            $nbVisitsConverted = 0;
-            if ($nbVisits > 0) {
-                $nbVisitsConverted = $archive->getNumeric('nb_visits_converted');
+            $archive = new Piwik_Archive($this->site->getId(), $this->period, $this->getSegment());
+
+            $metrics = $archive->getNumeric(array('nb_visits', 'nb_visits_converted'));
+            if (!isset($metrics['nb_visits'])) {
+                $nbVisits = $nbVisitsConverted = 0;
+            } else {
+                $nbVisits = $metrics['nb_visits'];
+                $nbVisitsConverted = $metrics['nb_visits_converted'];
             }
         }
 
@@ -324,8 +379,8 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
         $select = "count(distinct log_visit.idvisitor) as nb_uniq_visitors";
         $from = "log_visit";
         $where = "log_visit.visit_last_action_time >= ?
-	    		AND log_visit.visit_last_action_time <= ? 
-	    		AND log_visit.idsite = ?";
+                AND log_visit.visit_last_action_time <= ? 
+                AND log_visit.idsite = ?";
 
         $bind = array($this->getStartDatetimeUTC(), $this->getEndDatetimeUTC(), $this->idsite);
 
@@ -344,14 +399,8 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
 
         $numericTable = $this->tableArchiveNumeric->getTableName();
         self::doPurgeOutdatedArchives($numericTable, $this->isArchiveTemporary());
-
-        if (!isset($this->archives)) {
-            return;
-        }
-        foreach ($this->archives as $archive) {
-            destroy($archive);
-        }
-        $this->archives = array();
+        
+        $this->resetSubperiodArchiveQuery();
     }
 
     const FLAG_TABLE_PURGED = 'lastPurge_';
@@ -397,12 +446,12 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
                 $purgeArchivesOlderThan = Piwik_Date::factory('today')->getDateTime();
             }
             $result = Piwik_FetchAll("
-				SELECT idarchive
-				FROM $numericTable
-				WHERE name LIKE 'done%'
-					AND ((  value = " . Piwik_ArchiveProcessing::DONE_OK_TEMPORARY . "
-						    AND ts_archived < ?)
-						 OR value = " . Piwik_ArchiveProcessing::DONE_ERROR . ")",
+                SELECT idarchive
+                FROM $numericTable
+                WHERE name LIKE 'done%'
+                    AND ((  value = " . Piwik_ArchiveProcessing::DONE_OK_TEMPORARY . "
+                            AND ts_archived < ?)
+                         OR value = " . Piwik_ArchiveProcessing::DONE_ERROR . ")",
                 array($purgeArchivesOlderThan)
             );
 
@@ -412,9 +461,9 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
                     $idArchivesToDelete[] = $row['idarchive'];
                 }
                 $query = "DELETE
-    						FROM %s
-    						WHERE idarchive IN (" . implode(',', $idArchivesToDelete) . ")
-    						";
+                            FROM %s
+                            WHERE idarchive IN (" . implode(',', $idArchivesToDelete) . ")
+                            ";
 
                 Piwik_Query(sprintf($query, $numericTable));
 
@@ -430,9 +479,9 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
             // and would take up unecessary space
             $yesterday = Piwik_Date::factory('yesterday')->getDateTime();
             $query = "DELETE
-    					FROM %s
-    					WHERE period = ?
-    						AND ts_archived < ?";
+                        FROM %s
+                        WHERE period = ?
+                            AND ts_archived < ?";
             $bind = array(Piwik::$idPeriods['range'], $yesterday);
             Piwik::log("Purging Custom Range archives: done [ purged archives older than $yesterday from $blobTable and $numericTable ]");
 
@@ -449,4 +498,12 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
             Piwik::log("Purging temporary archives: skipped.");
         }
     }
-}
\ No newline at end of file
+    
+    private function resetSubperiodArchiveQuery()
+    {
+        if ($this->archive !== null) {
+            destroy($this->archive);
+            $this->archive = null;
+        }
+    }
+}
diff --git a/core/DataAccess/ArchiveQuery.php b/core/DataAccess/ArchiveQuery.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca3fbbd0e59be8076557b6eb19c0ca6eb0f0bdbb
--- /dev/null
+++ b/core/DataAccess/ArchiveQuery.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+
+/**
+ * Data Access object used to query archive data.
+ */
+class Piwik_DataAccess_ArchiveQuery
+{
+    /**
+     * Queries and returns archive IDs for a set of sites, periods, and a segment.
+     * 
+     * @param array $siteIds
+     * @param array $periods
+     * @param Piwik_Segment|null $segment
+     * @param array $requestedReports
+     * @return array Archive IDs are grouped by archive name and period range, ie,
+     *               array(
+     *                   'VisitsSummary.done' => array(
+     *                       '2010-01-01' => array(1,2,3)
+     *                   )
+     *               )
+     */
+    public function getArchiveIds($siteIds, $periods, $segment, $requestedReports)
+    {
+        $periodType = reset($periods)->getLabel();
+        
+        $getArchiveIdsSql = "SELECT idsite, name, date1, date2, MAX(idarchive) as idarchive
+                               FROM %s
+                              WHERE period = ?
+                                AND %s
+                                AND ".$this->getNameCondition($requestedReports, $segment, $periodType)."
+                                AND idsite IN (".implode(',', $siteIds).")
+                           GROUP BY idsite, date1, date2";
+        
+        // for every month within the archive query, select from numeric table
+        $result = array();
+        foreach ($this->getPeriodsByTableMonth($periods) as $tableMonth => $periods) {
+            $firstPeriod = reset($periods);
+            $table = Piwik_Common::prefixTable("archive_numeric_$tableMonth");
+            
+            Piwik_TablePartitioning_Monthly::createArchiveTablesIfAbsent($firstPeriod);
+            
+            // if looking for a range archive. NOTE: we assume there's only one period if its a range.
+            $bind = array($firstPeriod->getId());
+            if ($firstPeriod instanceof Piwik_Period_Range) {
+                $dateCondition = "date1 = ? AND date2 = ?";
+                $bind[] = $firstPeriod->getDateStart()->toString('Y-m-d');
+                $bind[] = $firstPeriod->getDateEnd()->toString('Y-m-d');
+            } else { // if looking for a normal period
+                $dateStrs = array();
+                foreach ($periods as $period) {
+                    $dateStrs[] = $period->getDateStart()->toString('Y-m-d');
+                }
+                
+                $dateCondition = "date1 IN ('".implode("','", $dateStrs)."')";
+            }
+            
+            $sql = sprintf($getArchiveIdsSql, $table, $dateCondition);
+            
+            // get the archive IDs
+            foreach (Piwik_FetchAll($sql, $bind) as $row) {
+                $archiveName = $row['name'];
+                $dateStr = $row['date1'].",".$row['date2'];
+                
+                $result[$archiveName][$dateStr][] = $row['idarchive'];
+            }
+        }
+        
+        return $result;
+    }
+    
+    /**
+     * Queries and returns archive data using a set of archive IDs.
+     * 
+     * @param array $archiveIds The IDs of the archives to get data from.
+     * @param array $archiveNames The names of the data to retrieve (ie, nb_visits,
+     *                            nb_actions, etc.)
+     * @param string $archiveDataType The archive data type (either, 'blob' or 'numeric').
+     * @param string|null $idSubtable The subtable to retrieve ('all' for all subtables).
+     */
+    public function getArchiveData($archiveIds, $archiveNames, $archiveDataType, $idSubtable)
+    {
+        $archiveTableType = 'archive_'.$archiveDataType;
+        
+        // create the SQL to select archive data
+        $inNames = Piwik_Common::getSqlStringFieldsArray($archiveNames);
+        if ($idSubtable == 'all') {
+            $name = reset($archiveNames);
+            
+            // select blobs w/ name like "$name_[0-9]+" w/o using RLIKE
+            $nameEnd = strlen($name) + 2;
+            $getValuesSql = "SELECT value, name, idsite, date1, date2, ts_archived
+                                FROM %s
+                                WHERE idarchive IN (%s)
+                                  AND (name = ? OR
+                                            (name LIKE ? AND SUBSTRING(name, $nameEnd, 1) >= '0'
+                                                         AND SUBSTRING(name, $nameEnd, 1) <= '9') )";
+            $bind = array($name, $name.'%');
+        } else {
+            $getValuesSql = "SELECT name, value, idsite, date1, date2, ts_archived
+                               FROM %s
+                              WHERE idarchive IN (%s)
+                                AND name IN ($inNames)";
+            $bind = array_values($archiveNames);
+        }
+        
+        // get data from every table we're querying
+        $rows = array();
+        foreach ($archiveIds as $period => $ids) {
+            $tableMonth = $this->getTableMonthFromDateRange($period);
+            
+            $table = Piwik_Common::prefixTable($archiveTableType."_".$tableMonth);
+            $sql = sprintf($getValuesSql, $table, implode(',', $ids));
+            
+            foreach (Piwik_FetchAll($sql, $bind) as $row) {
+                $rows[] = $row;
+            }
+        }
+        
+        return $rows;
+    }
+    
+    /**
+     * Returns the SQL condition used to find successfully completed archives that
+     * this instance is querying for.
+     * 
+     * @param array $requestedReports @see getRequestedReport
+     * @return string
+     */
+    private function getNameCondition($requestedReports, $segment, $periodType)
+    {
+        // the flags used to tell how the archiving process for a specific archive was completed,
+        // if it was completed
+        $doneFlags = array();
+        foreach ($requestedReports as $report) {
+            $done = Piwik_ArchiveProcessing::getDoneStringFlagFor($segment, $periodType, $report);
+            $donePlugins = Piwik_ArchiveProcessing::getDoneStringFlagFor($segment, $periodType, $report, true);
+            
+            $doneFlags[$done] = $done;
+            $doneFlags[$donePlugins] = $donePlugins;
+        }
+
+        $allDoneFlags = "'".implode("','", $doneFlags)."'";
+        
+        // create the SQL to find archives that are DONE
+        return "(name IN ($allDoneFlags)) AND
+                (value = '".Piwik_ArchiveProcessing::DONE_OK."' OR
+                 value = '".Piwik_ArchiveProcessing::DONE_OK_TEMPORARY."')";
+    }
+    
+    /**
+     * Returns the periods of the archives this instance is querying for grouped by
+     * by year & month.
+     * 
+     * @return array The result will be an array of Piwik_Period instances, where each
+     *               instance is associated w/ a string describing the year and month,
+     *               eg, 2012_01. The format is the same format used in archive database
+     *               table names.
+     */
+    private function getPeriodsByTableMonth($periods)
+    {
+        $result = array();
+        foreach ($periods as $period) {
+            $tableMonth = $period->getDateStart()->toString('Y_m');
+            $result[$tableMonth][] = $period;
+        }
+        return $result;
+    }
+    
+    /**
+     * Returns the table & month that an archive for a specific date range is stored
+     * in.
+     * 
+     * @param string $dateRange eg, "2012-01-01,2012-01-02"
+     * @return string eg, "2012_01"
+     */
+    private function getTableMonthFromDateRange($dateRange)
+    {
+        return str_replace('-', '_', substr($dateRange, 0, 7));
+    }
+}
diff --git a/core/DataTable.php b/core/DataTable.php
index b5e2064980e0a6d368235d9e882c723312d6e926..ca38047bd98833c51b6a947d644e6fd749001035 100644
--- a/core/DataTable.php
+++ b/core/DataTable.php
@@ -369,11 +369,17 @@ class Piwik_DataTable
     /**
      * Apply a filter to this datatable
      *
-     * @param string $className   Class name, eg. "Sort" or "Piwik_DataTable_Filter_Sort"
+     * @param string|Closure $className   Class name, eg. "Sort" or "Piwik_DataTable_Filter_Sort".
+     *                                    If this variable is a closure, it will get executed immediately.
      * @param array $parameters  Array of parameters to the filter, eg. array('nb_visits', 'asc')
      */
     public function filter($className, $parameters = array())
     {
+        if ($className instanceof Closure) {
+            $className($this);
+            return;
+        }
+        
         if (!class_exists($className, false)) {
             $className = "Piwik_DataTable_Filter_" . $className;
         }
@@ -1491,4 +1497,16 @@ class Piwik_DataTable
         return $this->columnAggregationOperations;
     }
     
+    /**
+     * Creates a new DataTable instance from a serialize()'d array of rows.
+     * 
+     * @param string $data
+     * @return Piwik_DataTable
+     */
+    public static function fromSerializedArray($data)
+    {
+        $result = new Piwik_DataTable();
+        $result->addRowsFromSerializedArray($data);
+        return $result;
+    }
 }
diff --git a/core/DataTable/Manager.php b/core/DataTable/Manager.php
index 3fff1bcc2daa2cd357b1609d5d0d551860511516..b6baa899d69ea231df5b14ce850a833731aace2a 100644
--- a/core/DataTable/Manager.php
+++ b/core/DataTable/Manager.php
@@ -39,7 +39,7 @@ class Piwik_DataTable_Manager
      *
      * @var array
      */
-    protected $tables = array();
+    private $tables = array();
 
     /**
      * Id of the next inserted table id in the Manager
diff --git a/core/DataTable/Renderer/Rss.php b/core/DataTable/Renderer/Rss.php
index 60f11ca13e71712dedbc0238746b40a32e95b09e..a9e6376455e54de6a2e636d30852d60f12b421df 100644
--- a/core/DataTable/Renderer/Rss.php
+++ b/core/DataTable/Renderer/Rss.php
@@ -66,7 +66,7 @@ class Piwik_DataTable_Renderer_Rss extends Piwik_DataTable_Renderer
         $out = "";
         $moreRecentFirst = array_reverse($table->getArray(), true);
         foreach ($moreRecentFirst as $date => $subtable) {
-            $timestamp = $subtable->getMetadata('timestamp');
+            $timestamp = $subtable->getMetadata('period')->getDateStart()->getTimestamp();
             $site = $subtable->getMetadata('site');
 
             $pudDate = date('r', $timestamp);
diff --git a/core/Period.php b/core/Period.php
index 6e6d4cf4d6818360f3f749ee2ce0c80d26f5c085..b004f1731a5012eec8f9e94badc3bdbdf525158a 100644
--- a/core/Period.php
+++ b/core/Period.php
@@ -265,4 +265,9 @@ abstract class Piwik_Period
     abstract public function getLocalizedShortString();
 
     abstract public function getLocalizedLongString();
+    
+    public function getRangeString()
+    {
+        return $this->getDateStart()->toString("Y-m-d").",".$this->getDateEnd()->toString("Y-m-d");
+    }
 }
diff --git a/core/Site.php b/core/Site.php
index ae62ae0519c4b78a3d42962f662a584a0b792d7c..53a939256b6ce589b50f39479c1408fccca3580f 100644
--- a/core/Site.php
+++ b/core/Site.php
@@ -204,12 +204,13 @@ class Piwik_Site
      * Checks the given string for valid site ids and returns them as an array
      *
      * @param string $ids comma separated idSite list
+     * @param false|string $_restrictSitesToLogin Used only when running as a scheduled task.
      * @return array of valid integer
      */
-    static public function getIdSitesFromIdSitesString($ids)
+    static public function getIdSitesFromIdSitesString($ids, $_restrictSitesToLogin = false)
     {
         if ($ids === 'all') {
-            return Piwik_SitesManager_API::getInstance()->getSitesIdWithAtLeastViewAccess();
+            return Piwik_SitesManager_API::getInstance()->getSitesIdWithAtLeastViewAccess($_restrictSitesToLogin);
         }
 
         if (!is_array($ids)) {
diff --git a/core/TablePartitioning.php b/core/TablePartitioning.php
index 40bcec40d090a793f1b3ed014e81c2a65aedb703..b3341940bac47679da8b90cfbc5adf3cfc350b37 100644
--- a/core/TablePartitioning.php
+++ b/core/TablePartitioning.php
@@ -97,6 +97,9 @@ abstract class Piwik_TablePartitioning
  */
 class Piwik_TablePartitioning_Monthly extends Piwik_TablePartitioning
 {
+    private static $blobArchiveTable = null;
+    private static $numericArchiveTable = null;
+    
     public function __construct($tableName)
     {
         parent::__construct($tableName);
@@ -107,24 +110,29 @@ class Piwik_TablePartitioning_Monthly extends Piwik_TablePartitioning
         $config = Piwik_Config::getInstance();
         return $config->database['tables_prefix'] . $this->tableName . "_" . date("Y_m", $this->timestamp);
     }
-
-}
-
-/**
- *
- * @package Piwik
- * @subpackage Piwik_TablePartitioning
- */
-class Piwik_TablePartitioning_Daily extends Piwik_TablePartitioning
-{
-    public function __construct($tableName)
+    
+    /**
+     * Creates archive_blob & archive_numeric tables for a period if they don't
+     * already exist.
+     * 
+     * @param Piwik_Period $periodInMonth
+     */
+    public static function createArchiveTablesIfAbsent($periodInMonth)
     {
-        parent::__construct($tableName);
+        $timestamp = $periodInMonth->getDateStart()->getTimestamp();
+        
+        self::$blobArchiveTable->setTimestamp($timestamp);
+        self::$blobArchiveTable->getTableName();
+        
+        self::$numericArchiveTable->setTimestamp($timestamp);
+        self::$numericArchiveTable->getTableName();
     }
-
-    protected function generateTableName()
+    
+    public static function init()
     {
-        $config = Piwik_Config::getInstance();
-        return $config->database['tables_prefix'] . $this->tableName . "_" . date("Y_m_d", $this->timestamp);
+        self::$blobArchiveTable = new Piwik_TablePartitioning_Monthly('archive_blob');
+        self::$numericArchiveTable = new Piwik_TablePartitioning_Monthly('archive_numeric');
     }
 }
+
+Piwik_TablePartitioning_Monthly::init();
diff --git a/plugins/Goals/API.php b/plugins/Goals/API.php
index aea16ad70e68b0b52f18efd68c9acaa9e0dbc37c..ad58ec431040cfaa311b4f205835715e873c50ca 100644
--- a/plugins/Goals/API.php
+++ b/plugins/Goals/API.php
@@ -210,6 +210,7 @@ class Piwik_Goals_API
         }
         $archive = Piwik_Archive::build($idSite, $period, $date);
         $dataTable = $archive->getDataTable($recordNameFinal);
+        
         $dataTable->filter('Sort', array(Piwik_Archive::INDEX_ECOMMERCE_ITEM_REVENUE));
         $dataTable->queueFilter('ReplaceColumnNames');
         $dataTable->queueFilter('ReplaceSummaryRowLabel');
@@ -428,7 +429,7 @@ class Piwik_Goals_API
     {
         Piwik::checkUserHasViewAccess($idSite);
         $archive = Piwik_Archive::build($idSite, $period, $date, $segment);
-        $dataTable = $archive->getNumeric($toFetch);
+        $dataTable = $archive->getDataTableFromNumeric($toFetch);
         return $dataTable;
     }
 
diff --git a/plugins/MultiSites/API.php b/plugins/MultiSites/API.php
index b6b0a4d1ae2ae52d1ff4d1adc6a0755dae2eb80c..5aba1c4764d85efd65ce1fd14026aaabdcab530c 100755
--- a/plugins/MultiSites/API.php
+++ b/plugins/MultiSites/API.php
@@ -218,7 +218,9 @@ class Piwik_MultiSites_API
         ) {
             $dataTable = $dataTable->mergeChildren();
         } else {
-            if (!$dataTable instanceof Piwik_DataTable_Array) {
+            if (!$dataTable instanceof Piwik_DataTable_Array
+                && $dataTable->getRowsCount() > 0
+            ) {
                 $firstDataTableRow = $dataTable->getFirstRow();
                 $firstDataTableRow->setColumn('label', $sites);
             }
diff --git a/plugins/UserSettings/API.php b/plugins/UserSettings/API.php
index e438b96b2f5724d5ac0a4cb59d8fdcc8533a895d..dd3820fff729412498f6162f636912887188bbf5 100644
--- a/plugins/UserSettings/API.php
+++ b/plugins/UserSettings/API.php
@@ -171,7 +171,7 @@ class Piwik_UserSettings_API
         $dataTable = $this->getDataTable('UserSettings_plugin', $idSite, $period, $date, $segment);
         $browserTypes = $this->getDataTable('UserSettings_browserType', $idSite, $period, $date, $segment);
         $archive = Piwik_Archive::build($idSite, $period, $date, $segment);
-        $visitsSums = $archive->getNumeric('nb_visits');
+        $visitsSums = $archive->getDataTableFromNumeric('nb_visits');
 
         // check whether given tables are arrays
         if ($dataTable instanceof Piwik_DataTable_Array) {
@@ -179,9 +179,9 @@ class Piwik_UserSettings_API
             $browserTypesArray = $browserTypes->getArray();
             $visitSumsArray = $visitsSums->getArray();
         } else {
-            $tableArray = Array($dataTable);
-            $browserTypesArray = Array($browserTypes);
-            $visitSumsArray = Array($visitsSums);
+            $tableArray = array($dataTable);
+            $browserTypesArray = array($browserTypes);
+            $visitSumsArray = array($visitsSums);
         }
 
         // walk through the results and calculate the percentage
@@ -198,7 +198,11 @@ class Piwik_UserSettings_API
             foreach ($visitSumsArray AS $k => $visits) {
                 if ($k == $key) {
                     if (is_object($visits)) {
-                        $visitsSumTotal = (float)$visits->getFirstRow()->getColumn(0);
+                        if ($visits->getRowsCount() == 0) {
+                            $visitsSumTotal = 0;
+                        } else {
+                            $visitsSumTotal = (float)$visits->getFirstRow()->getColumn('nb_visits');
+                        }
                     } else {
                         $visitsSumTotal = (float)$visits;
                     }
diff --git a/plugins/VisitTime/API.php b/plugins/VisitTime/API.php
index 3da0646fb7f94e13eaf3b103bb280e3c20f21be3..973a8d3dd850b02ccf88f8199211345a1e861583 100644
--- a/plugins/VisitTime/API.php
+++ b/plugins/VisitTime/API.php
@@ -85,6 +85,7 @@ class Piwik_VisitTime_API
         $dataTable = $archive->getDataTableFromNumeric($metrics)->mergeChildren();
 
         // if there's no data for this report, don't bother w/ anything else
+        // TODO: with changes to getDataTableFromNumeric, this code would have to check if every row has 0 column values. is it really necessary? (assuming no for now)
         if ($dataTable->getRowsCount() == 0) {
             return $dataTable;
         }
diff --git a/plugins/VisitsSummary/API.php b/plugins/VisitsSummary/API.php
index 0864c517b50b30b8e65a0016736408d3da78ff8c..9221d941bdd0e6deeb03f5239e258ffc666caa33 100644
--- a/plugins/VisitsSummary/API.php
+++ b/plugins/VisitsSummary/API.php
@@ -100,7 +100,7 @@ class Piwik_VisitsSummary_API
     {
         Piwik::checkUserHasViewAccess($idSite);
         $archive = Piwik_Archive::build($idSite, $period, $date, $segment);
-        $dataTable = $archive->getNumeric($toFetch);
+        $dataTable = $archive->getDataTableFromNumeric($toFetch);
         return $dataTable;
     }
 
@@ -142,8 +142,9 @@ class Piwik_VisitsSummary_API
     public function getSumVisitsLengthPretty($idSite, $period, $date, $segment = false)
     {
         $table = $this->getSumVisitsLength($idSite, $period, $date, $segment);
-        if ($table instanceof Piwik_DataTable_Array) {
-            $table->filter('ColumnCallbackReplace', array(0, array('Piwik', 'getPrettyTimeFromSeconds')));
+        if (is_object($table)) {
+            $table->filter('ColumnCallbackReplace',
+                array('sum_visit_length', array('Piwik', 'getPrettyTimeFromSeconds')));
         } else {
             $table = Piwik::getPrettyTimeFromSeconds($table);
         }
diff --git a/tests/PHPUnit/Core/TablePartitioningTest.php b/tests/PHPUnit/Core/TablePartitioningTest.php
index 9626b7aceb5d05e9cc91491a9629af9fce76376c..8c8695f18418ed8a213e70907883f3bec771401f 100644
--- a/tests/PHPUnit/Core/TablePartitioningTest.php
+++ b/tests/PHPUnit/Core/TablePartitioningTest.php
@@ -67,26 +67,4 @@ class TablePartitioningTest extends DatabaseTestCase
         $this->assertEquals($tablename, $p->getTableName());
         $this->assertEquals($tablename, (string)$p->__toString());
     }
-
-    /**
-     * test daily
-     * @group Core
-     * @group TablePartitioning
-     */
-    public function testDailyPartition()
-    {
-        $tableName = 'archive_numeric';
-        $p = new Piwik_TablePartitioning_Daily($tableName);
-        $timestamp = strtotime("10 September 2000");
-        $suffixShouldBe = "_2000_09_10";
-        $prefixTables = Piwik_Config::getInstance()->database['tables_prefix'];
-        $tablename = $prefixTables . $tableName . $suffixShouldBe;
-
-        $p->setTimestamp($timestamp);
-
-        $allTablesInstalled = Piwik::getTablesInstalled();
-        $this->assertContains($tablename, $allTablesInstalled);
-        $this->assertEquals($tablename, $p->getTableName());
-        $this->assertEquals($tablename, (string)$p->__toString());
-    }
 }
diff --git a/tests/PHPUnit/Integration/OneVisitorTwoVisitsTest.php b/tests/PHPUnit/Integration/OneVisitorTwoVisitsTest.php
index b0c86868c371fc72c4098d640146784a1d3a81a6..5288a22df997925d512a2087262f6d86f175de40 100755
--- a/tests/PHPUnit/Integration/OneVisitorTwoVisitsTest.php
+++ b/tests/PHPUnit/Integration/OneVisitorTwoVisitsTest.php
@@ -163,8 +163,7 @@ class Test_Piwik_Integration_OneVisitorTwoVisits extends IntegrationTestCase
     public function testArchiveSinglePreFetchBlob()
     {
         $archive = Piwik_Archive::build(self::$fixture->idSite, 'day', self::$fixture->dateTime);
-        $archive->preFetchBlob('Actions_actions');
-        $cache = $archive->getBlobCache();
+        $cache = $archive->getBlob('Actions_actions', 'all');
 
         $foundSubtable = false;
 
@@ -179,6 +178,27 @@ class Test_Piwik_Integration_OneVisitorTwoVisits extends IntegrationTestCase
 
         $this->assertTrue($foundSubtable, "Actions_actions subtable was not loaded");
     }
+    
+    /**
+     * Test that restricting the number of sites to those viewable to another login
+     * works when building an archive query object.
+     * 
+     * @group        Integration
+     * @group        OneVisitorTwoVisits
+     */
+    public function testArchiveSitesWhenRestrictingToLogin()
+    {
+        try
+        {
+            Piwik_Archive::build(
+                'all', 'day', self::$fixture->dateTime, $segment = false, $_restrictToLogin = 'anotherLogin');
+            $this->fail("Restricting sites to invalid login did not return 0 sites.");
+        }
+        catch (Exception $ex)
+        {
+            // pass
+        }
+    }
 }
 
 Test_Piwik_Integration_OneVisitorTwoVisits::$fixture = new Test_Piwik_Fixture_OneVisitorTwoVisits();
diff --git a/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml b/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml
index 95d827565af399ae453ec26bc9cfd1dc9d1fbe3f..8a400626b7f1bab2510a3b83fc2018e05976c213 100755
--- a/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_ImportLogs__MultiSites.getAll_month.xml
@@ -17,10 +17,11 @@
 		<nb_visits>1</nb_visits>
 		<nb_actions>1</nb_actions>
 		<nb_pageviews>1</nb_pageviews>
-		<revenue />
+		<revenue>0</revenue>
 		<visits_evolution>100%</visits_evolution>
 		<actions_evolution>100%</actions_evolution>
 		<pageviews_evolution>100%</pageviews_evolution>
+		<revenue_evolution>0%</revenue_evolution>
 		<idsite>2</idsite>
 	</row>
 </result>
\ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_ImportLogs__VisitTime.getByDayOfWeek_month.xml b/tests/PHPUnit/Integration/expected/test_ImportLogs__VisitTime.getByDayOfWeek_month.xml
index 0202a80040eb8065ec5f110b53f19a43608b683b..a95e7420bbcb06603e1db356f72264e654d7b38e 100755
--- a/tests/PHPUnit/Integration/expected/test_ImportLogs__VisitTime.getByDayOfWeek_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_ImportLogs__VisitTime.getByDayOfWeek_month.xml
@@ -13,38 +13,41 @@
 	<row>
 		<label>Wednesday</label>
 		<nb_visits>2</nb_visits>
-		<bounce_count>2</bounce_count>
-		<nb_actions>2</nb_actions>
 		<nb_uniq_visitors>2</nb_uniq_visitors>
+		<nb_actions>2</nb_actions>
+		<sum_visit_length>0</sum_visit_length>
+		<bounce_count>2</bounce_count>
 		<nb_visits_converted>2</nb_visits_converted>
 		<day_of_week>3</day_of_week>
 	</row>
 	<row>
 		<label>Thursday</label>
 		<nb_visits>9</nb_visits>
-		<bounce_count>9</bounce_count>
-		<nb_actions>9</nb_actions>
 		<nb_uniq_visitors>9</nb_uniq_visitors>
+		<nb_actions>9</nb_actions>
+		<sum_visit_length>0</sum_visit_length>
+		<bounce_count>9</bounce_count>
 		<nb_visits_converted>9</nb_visits_converted>
 		<day_of_week>4</day_of_week>
 	</row>
 	<row>
 		<label>Friday</label>
 		<nb_visits>6</nb_visits>
-		<bounce_count>6</bounce_count>
-		<nb_actions>6</nb_actions>
 		<nb_uniq_visitors>6</nb_uniq_visitors>
+		<nb_actions>6</nb_actions>
+		<sum_visit_length>0</sum_visit_length>
+		<bounce_count>6</bounce_count>
 		<nb_visits_converted>6</nb_visits_converted>
 		<day_of_week>5</day_of_week>
 	</row>
 	<row>
 		<label>Saturday</label>
 		<nb_visits>9</nb_visits>
-		<bounce_count>7</bounce_count>
-		<nb_actions>12</nb_actions>
 		<nb_uniq_visitors>9</nb_uniq_visitors>
-		<nb_visits_converted>7</nb_visits_converted>
+		<nb_actions>12</nb_actions>
 		<sum_visit_length>305</sum_visit_length>
+		<bounce_count>7</bounce_count>
+		<nb_visits_converted>7</nb_visits_converted>
 		<day_of_week>6</day_of_week>
 	</row>
 	<row>
diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__VisitTime.getByDayOfWeek_day.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__VisitTime.getByDayOfWeek_day.xml
index 7052ae2d51c987c541eeee1d36ab7502691284bd..e715309206aa884f75ec89101c9caf6342393ebb 100755
--- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__VisitTime.getByDayOfWeek_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits__VisitTime.getByDayOfWeek_day.xml
@@ -28,11 +28,11 @@
 	<row>
 		<label>Saturday</label>
 		<nb_visits>2</nb_visits>
-		<bounce_count>1</bounce_count>
-		<nb_actions>8</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
-		<nb_visits_converted>2</nb_visits_converted>
+		<nb_actions>8</nb_actions>
 		<sum_visit_length>1621</sum_visit_length>
+		<bounce_count>1</bounce_count>
+		<nb_visits_converted>2</nb_visits_converted>
 		<day_of_week>6</day_of_week>
 	</row>
 	<row>
diff --git a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__VisitTime.getByDayOfWeek_day.xml b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__VisitTime.getByDayOfWeek_day.xml
index 02907424a5aba03a257787004373c2fdf0bd8ca9..7b035b01889ba7f9cd6bff712e55d9d4f77a7357 100755
--- a/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__VisitTime.getByDayOfWeek_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_OneVisitorTwoVisits_withCookieSupport__VisitTime.getByDayOfWeek_day.xml
@@ -28,11 +28,11 @@
 	<row>
 		<label>Saturday</label>
 		<nb_visits>2</nb_visits>
-		<bounce_count>1</bounce_count>
-		<nb_actions>9</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
-		<nb_visits_converted>2</nb_visits_converted>
+		<nb_actions>9</nb_actions>
 		<sum_visit_length>1621</sum_visit_length>
+		<bounce_count>1</bounce_count>
+		<nb_visits_converted>2</nb_visits_converted>
 		<day_of_week>6</day_of_week>
 	</row>
 	<row>
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_day.xml
index 9b8feaf636335731f828d8cb78d27906b5a0b44c..50967fa121934a7928087c590996439a92a18493 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_day.xml
@@ -45,26 +45,26 @@
 	</columns>
 	<reportData>
 		<result prettyDate="Sunday 3 January 2010">
-			<nb_keywords>3</nb_keywords>
 			<nb_pageviews>4</nb_pageviews>
-			<nb_searches>5</nb_searches>
 			<nb_uniq_pageviews>3</nb_uniq_pageviews>
-			<avg_time_generation>0s</avg_time_generation>
 			<nb_downloads>0</nb_downloads>
 			<nb_uniq_downloads>0</nb_uniq_downloads>
 			<nb_outlinks>0</nb_outlinks>
 			<nb_uniq_outlinks>0</nb_uniq_outlinks>
-		</result>
-		<result prettyDate="Monday 4 January 2010">
+			<nb_searches>5</nb_searches>
 			<nb_keywords>3</nb_keywords>
-			<nb_searches>3</nb_searches>
 			<avg_time_generation>0s</avg_time_generation>
+		</result>
+		<result prettyDate="Monday 4 January 2010">
 			<nb_pageviews>0</nb_pageviews>
 			<nb_uniq_pageviews>0</nb_uniq_pageviews>
 			<nb_downloads>0</nb_downloads>
 			<nb_uniq_downloads>0</nb_uniq_downloads>
 			<nb_outlinks>0</nb_outlinks>
 			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>3</nb_searches>
+			<nb_keywords>3</nb_keywords>
+			<avg_time_generation>0s</avg_time_generation>
 		</result>
 		<result prettyDate="Tuesday 5 January 2010" />
 		<result prettyDate="Wednesday 6 January 2010" />
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_month.xml
index 924bf9decca4006ffddcdb51def4dba8c97363a9..eb8cbeec952c4c13fde7b9a6c3273d19d5abf434 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_Actions.get_firstSite_lastN__API.getProcessedReport_month.xml
@@ -45,15 +45,15 @@
 	</columns>
 	<reportData>
 		<result prettyDate="2010, January">
-			<nb_keywords>5</nb_keywords>
 			<nb_pageviews>4</nb_pageviews>
-			<nb_searches>8</nb_searches>
 			<nb_uniq_pageviews>3</nb_uniq_pageviews>
-			<avg_time_generation>0s</avg_time_generation>
 			<nb_downloads>0</nb_downloads>
 			<nb_uniq_downloads>0</nb_uniq_downloads>
 			<nb_outlinks>0</nb_outlinks>
 			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>8</nb_searches>
+			<nb_keywords>5</nb_keywords>
+			<avg_time_generation>0s</avg_time_generation>
 		</result>
 		<result prettyDate="2010, February" />
 		<result prettyDate="2010, March" />
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_day.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_day.xml
index dfa32df4694ddeb978ceb77940292b89614f155d..13c2a7e8ac538e1924f52c9bba9691560f6457fb 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_day.xml
@@ -2,15 +2,25 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01-03">
-			<nb_keywords>3</nb_keywords>
 			<nb_pageviews>4</nb_pageviews>
-			<nb_searches>5</nb_searches>
 			<nb_uniq_pageviews>3</nb_uniq_pageviews>
+			<nb_downloads>0</nb_downloads>
+			<nb_uniq_downloads>0</nb_uniq_downloads>
+			<nb_outlinks>0</nb_outlinks>
+			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>5</nb_searches>
+			<nb_keywords>3</nb_keywords>
 			<avg_time_generation>0</avg_time_generation>
 		</result>
 		<result date="2010-01-04">
-			<nb_keywords>3</nb_keywords>
+			<nb_pageviews>0</nb_pageviews>
+			<nb_uniq_pageviews>0</nb_uniq_pageviews>
+			<nb_downloads>0</nb_downloads>
+			<nb_uniq_downloads>0</nb_uniq_downloads>
+			<nb_outlinks>0</nb_outlinks>
+			<nb_uniq_outlinks>0</nb_uniq_outlinks>
 			<nb_searches>3</nb_searches>
+			<nb_keywords>3</nb_keywords>
 			<avg_time_generation>0</avg_time_generation>
 		</result>
 		<result date="2010-01-05" />
@@ -21,10 +31,14 @@
 	</result>
 	<result idSite="2">
 		<result date="2010-01-03">
-			<nb_keywords>3</nb_keywords>
 			<nb_pageviews>2</nb_pageviews>
-			<nb_searches>3</nb_searches>
 			<nb_uniq_pageviews>2</nb_uniq_pageviews>
+			<nb_downloads>0</nb_downloads>
+			<nb_uniq_downloads>0</nb_uniq_downloads>
+			<nb_outlinks>0</nb_outlinks>
+			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>3</nb_searches>
+			<nb_keywords>3</nb_keywords>
 			<avg_time_generation>0</avg_time_generation>
 		</result>
 		<result date="2010-01-04" />
@@ -38,6 +52,12 @@
 		<result date="2010-01-03">
 			<nb_pageviews>3</nb_pageviews>
 			<nb_uniq_pageviews>3</nb_uniq_pageviews>
+			<nb_downloads>0</nb_downloads>
+			<nb_uniq_downloads>0</nb_uniq_downloads>
+			<nb_outlinks>0</nb_outlinks>
+			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>0</nb_searches>
+			<nb_keywords>0</nb_keywords>
 			<avg_time_generation>0</avg_time_generation>
 		</result>
 		<result date="2010-01-04" />
diff --git a/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_month.xml b/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_month.xml
index 56b93eb2579fd6a4124b03f41a9f527262c9b1f2..d0789131088f8443b2d4dea083eb7b1484ea4ade 100644
--- a/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_SiteSearch_AllSites__Actions.get_month.xml
@@ -2,10 +2,14 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01">
-			<nb_keywords>5</nb_keywords>
 			<nb_pageviews>4</nb_pageviews>
-			<nb_searches>8</nb_searches>
 			<nb_uniq_pageviews>3</nb_uniq_pageviews>
+			<nb_downloads>0</nb_downloads>
+			<nb_uniq_downloads>0</nb_uniq_downloads>
+			<nb_outlinks>0</nb_outlinks>
+			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>8</nb_searches>
+			<nb_keywords>5</nb_keywords>
 			<avg_time_generation>0</avg_time_generation>
 		</result>
 		<result date="2010-02" />
@@ -17,10 +21,14 @@
 	</result>
 	<result idSite="2">
 		<result date="2010-01">
-			<nb_keywords>3</nb_keywords>
 			<nb_pageviews>2</nb_pageviews>
-			<nb_searches>3</nb_searches>
 			<nb_uniq_pageviews>2</nb_uniq_pageviews>
+			<nb_downloads>0</nb_downloads>
+			<nb_uniq_downloads>0</nb_uniq_downloads>
+			<nb_outlinks>0</nb_outlinks>
+			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>3</nb_searches>
+			<nb_keywords>3</nb_keywords>
 			<avg_time_generation>0</avg_time_generation>
 		</result>
 		<result date="2010-02" />
@@ -34,6 +42,12 @@
 		<result date="2010-01">
 			<nb_pageviews>3</nb_pageviews>
 			<nb_uniq_pageviews>3</nb_uniq_pageviews>
+			<nb_downloads>0</nb_downloads>
+			<nb_uniq_downloads>0</nb_uniq_downloads>
+			<nb_outlinks>0</nb_outlinks>
+			<nb_uniq_outlinks>0</nb_uniq_outlinks>
+			<nb_searches>0</nb_searches>
+			<nb_keywords>0</nb_keywords>
 			<avg_time_generation>0</avg_time_generation>
 		</result>
 		<result date="2010-02" />
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml
index 122c2f44602679dca6915e49a8bc76a9fe4ef145..d7dfbaef5a120118a7c2ee23a16a8a0ea288e7a2 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_day.xml
@@ -6,7 +6,7 @@
 		<nb_actions>1</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
 		<bounce_count>1</bounce_count>
-		<sum_visit_length />
+		<sum_visit_length>0</sum_visit_length>
 		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml
index 4930a5c39611c07916fe2f167d86b812fe185bf5..1b25e82b0f9c48e1dc7adf8e3c159a4f8f7fca95 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_month.xml
@@ -17,7 +17,7 @@
 		<nb_visits>1</nb_visits>
 		<nb_actions>3</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
-		<bounce_count />
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>2</sum_visit_length>
 		<max_actions>3</max_actions>
 		<bounce_rate>0%</bounce_rate>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml
index 122c2f44602679dca6915e49a8bc76a9fe4ef145..d7dfbaef5a120118a7c2ee23a16a8a0ea288e7a2 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_week.xml
@@ -6,7 +6,7 @@
 		<nb_actions>1</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
 		<bounce_count>1</bounce_count>
-		<sum_visit_length />
+		<sum_visit_length>0</sum_visit_length>
 		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml
index bf6186ee738d79eaa17348db3a0ea4a37dbd3e11..acce1ab816ce12905df10d12059cdf05f9465a94 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_disabledAfter__VisitsSummary.get_year.xml
@@ -15,7 +15,7 @@
 		<nb_visits>1</nb_visits>
 		<nb_actions>3</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
-		<bounce_count />
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>2</sum_visit_length>
 		<max_actions>3</max_actions>
 		<bounce_rate>0%</bounce_rate>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml
index 122c2f44602679dca6915e49a8bc76a9fe4ef145..d7dfbaef5a120118a7c2ee23a16a8a0ea288e7a2 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_day.xml
@@ -6,7 +6,7 @@
 		<nb_actions>1</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
 		<bounce_count>1</bounce_count>
-		<sum_visit_length />
+		<sum_visit_length>0</sum_visit_length>
 		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml
index 4930a5c39611c07916fe2f167d86b812fe185bf5..1b25e82b0f9c48e1dc7adf8e3c159a4f8f7fca95 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_month.xml
@@ -17,7 +17,7 @@
 		<nb_visits>1</nb_visits>
 		<nb_actions>3</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
-		<bounce_count />
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>2</sum_visit_length>
 		<max_actions>3</max_actions>
 		<bounce_rate>0%</bounce_rate>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml
index 122c2f44602679dca6915e49a8bc76a9fe4ef145..d7dfbaef5a120118a7c2ee23a16a8a0ea288e7a2 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_week.xml
@@ -6,7 +6,7 @@
 		<nb_actions>1</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
 		<bounce_count>1</bounce_count>
-		<sum_visit_length />
+		<sum_visit_length>0</sum_visit_length>
 		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml
index bf6186ee738d79eaa17348db3a0ea4a37dbd3e11..acce1ab816ce12905df10d12059cdf05f9465a94 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_ArchivingDisabled_enabled__VisitsSummary.get_year.xml
@@ -15,7 +15,7 @@
 		<nb_visits>1</nb_visits>
 		<nb_actions>3</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
-		<bounce_count />
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>2</sum_visit_length>
 		<max_actions>3</max_actions>
 		<bounce_rate>0%</bounce_rate>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml
index fef0db55eb71cedb022fb350b1742f40a69a1089..cd5e731d32e4e69ed4d1be5714d6c5680f2dbda6 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml
@@ -61,10 +61,10 @@
 		<result prettyDate="Sunday 3 January 2010">
 			<row>
 				<label>Site 1</label>
+				<nb_visits>1</nb_visits>
+				<nb_actions>1</nb_actions>
 				<nb_pageviews>2</nb_pageviews>
 				<revenue>$ 10</revenue>
-				<nb_actions>1</nb_actions>
-				<nb_visits>1</nb_visits>
 				<visits_evolution>100%</visits_evolution>
 				<actions_evolution>100%</actions_evolution>
 				<pageviews_evolution>100%</pageviews_evolution>
@@ -80,14 +80,14 @@
 		<result prettyDate="Monday 4 January 2010">
 			<row>
 				<label>Site 1</label>
-				<nb_pageviews>1</nb_pageviews>
-				<nb_actions>2</nb_actions>
 				<nb_visits>1</nb_visits>
+				<nb_actions>2</nb_actions>
+				<nb_pageviews>1</nb_pageviews>
+				<revenue>$ 0</revenue>
 				<visits_evolution>0%</visits_evolution>
 				<actions_evolution>100%</actions_evolution>
 				<pageviews_evolution>-50%</pageviews_evolution>
 				<revenue_evolution>-100%</revenue_evolution>
-				<revenue>$ 0</revenue>
 				<nb_conversions>0</nb_conversions>
 				<nb_conversions_evolution>0</nb_conversions_evolution>
 				<orders>0</orders>
@@ -97,14 +97,14 @@
 			</row>
 			<row>
 				<label>Site 2</label>
-				<nb_pageviews>3</nb_pageviews>
-				<nb_actions>3</nb_actions>
 				<nb_visits>1</nb_visits>
+				<nb_actions>3</nb_actions>
+				<nb_pageviews>3</nb_pageviews>
+				<revenue>$ 0</revenue>
 				<visits_evolution>100%</visits_evolution>
 				<actions_evolution>100%</actions_evolution>
 				<pageviews_evolution>100%</pageviews_evolution>
-				<revenue>$ 0</revenue>
-				<revenue_evolution>0</revenue_evolution>
+				<revenue_evolution>0%</revenue_evolution>
 				<nb_conversions>0</nb_conversions>
 				<nb_conversions_evolution>0</nb_conversions_evolution>
 				<orders>0</orders>
@@ -116,10 +116,10 @@
 		<result prettyDate="Tuesday 5 January 2010">
 			<row>
 				<label>Site 1</label>
+				<nb_visits>1</nb_visits>
+				<nb_actions>5</nb_actions>
 				<nb_pageviews>5</nb_pageviews>
 				<revenue>$ 5</revenue>
-				<nb_actions>5</nb_actions>
-				<nb_visits>1</nb_visits>
 				<visits_evolution>0%</visits_evolution>
 				<actions_evolution>150%</actions_evolution>
 				<pageviews_evolution>400%</pageviews_evolution>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml
index 5fee61a930f3affbe39b1a7eda0692f95b524743..f5ea6177e50476c018dd1552a39948f7c7dd9c5b 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml
@@ -10,5 +10,6 @@
 		<nb_conversions>1</nb_conversions>
 		<nb_visits_converted>1</nb_visits_converted>
 		<conversion_rate>100</conversion_rate>
+		<revenue>0</revenue>
 	</result>
 </results>
\ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_day.xml
index 122c2f44602679dca6915e49a8bc76a9fe4ef145..d7dfbaef5a120118a7c2ee23a16a8a0ea288e7a2 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_day.xml
@@ -6,7 +6,7 @@
 		<nb_actions>1</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
 		<bounce_count>1</bounce_count>
-		<sum_visit_length />
+		<sum_visit_length>0</sum_visit_length>
 		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_month.xml
index 4930a5c39611c07916fe2f167d86b812fe185bf5..1b25e82b0f9c48e1dc7adf8e3c159a4f8f7fca95 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__VisitsSummary.get_month.xml
@@ -17,7 +17,7 @@
 		<nb_visits>1</nb_visits>
 		<nb_actions>3</nb_actions>
 		<nb_visits_converted>1</nb_visits_converted>
-		<bounce_count />
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>2</sum_visit_length>
 		<max_actions>3</max_actions>
 		<bounce_rate>0%</bounce_rate>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml
index eefd33ca1bb1184d82b2ea4321589a17416f2096..72a701359a32208bf4ffcb51053d39a42bdeb615 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml
@@ -3,10 +3,10 @@
 	<result date="2010-01-03">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>1</nb_visits>
+			<nb_actions>1</nb_actions>
 			<nb_pageviews>2</nb_pageviews>
 			<revenue>10</revenue>
-			<nb_actions>1</nb_actions>
-			<nb_visits>1</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -17,9 +17,10 @@
 	<result date="2010-01-04">
 		<row>
 			<label>Site 1</label>
-			<nb_pageviews>1</nb_pageviews>
-			<nb_actions>2</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>2</nb_actions>
+			<nb_pageviews>1</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>0%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>-50%</pageviews_evolution>
@@ -28,22 +29,24 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
 	<result date="2010-01-05">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>1</nb_visits>
+			<nb_actions>5</nb_actions>
 			<nb_pageviews>5</nb_pageviews>
 			<revenue>5</revenue>
-			<nb_actions>5</nb_actions>
-			<nb_visits>1</nb_visits>
 			<visits_evolution>0%</visits_evolution>
 			<actions_evolution>150%</actions_evolution>
 			<pageviews_evolution>400%</pageviews_evolution>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml
index 879bd15096faf1143f1633356121d321d73920a3..0e8c2139487d13992bd3d9dc076d8a891c4f5284 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml
@@ -3,10 +3,10 @@
 	<result date="2010-01">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>3</nb_visits>
+			<nb_actions>8</nb_actions>
 			<nb_pageviews>8</nb_pageviews>
 			<revenue>15</revenue>
-			<nb_actions>8</nb_actions>
-			<nb_visits>3</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -15,12 +15,14 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml
index ac0858dd811f9c41de826aee436a6b4c25823931..b36fe1bf7c36f472d9b1bb84d9b59ab1c9fd1e92 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml
@@ -3,10 +3,10 @@
 	<result date="From 2009-12-28 to 2010-01-03">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>1</nb_visits>
+			<nb_actions>1</nb_actions>
 			<nb_pageviews>2</nb_pageviews>
 			<revenue>10</revenue>
-			<nb_actions>1</nb_actions>
-			<nb_visits>1</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -17,10 +17,10 @@
 	<result date="From 2010-01-04 to 2010-01-10">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>2</nb_visits>
+			<nb_actions>7</nb_actions>
 			<nb_pageviews>6</nb_pageviews>
 			<revenue>5</revenue>
-			<nb_actions>7</nb_actions>
-			<nb_visits>2</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>600%</actions_evolution>
 			<pageviews_evolution>200%</pageviews_evolution>
@@ -29,12 +29,14 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml
index a56856f4eb4172b2d1fa9fa35d19133e87cf2774..f5989031af7fdf134ee31476c44803a49933b08b 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml
@@ -3,10 +3,10 @@
 	<result date="2010">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>3</nb_visits>
+			<nb_actions>8</nb_actions>
 			<nb_pageviews>8</nb_pageviews>
 			<revenue>15</revenue>
-			<nb_actions>8</nb_actions>
-			<nb_visits>3</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -15,12 +15,14 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml
index eefd33ca1bb1184d82b2ea4321589a17416f2096..72a701359a32208bf4ffcb51053d39a42bdeb615 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml
@@ -3,10 +3,10 @@
 	<result date="2010-01-03">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>1</nb_visits>
+			<nb_actions>1</nb_actions>
 			<nb_pageviews>2</nb_pageviews>
 			<revenue>10</revenue>
-			<nb_actions>1</nb_actions>
-			<nb_visits>1</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -17,9 +17,10 @@
 	<result date="2010-01-04">
 		<row>
 			<label>Site 1</label>
-			<nb_pageviews>1</nb_pageviews>
-			<nb_actions>2</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>2</nb_actions>
+			<nb_pageviews>1</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>0%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>-50%</pageviews_evolution>
@@ -28,22 +29,24 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
 	<result date="2010-01-05">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>1</nb_visits>
+			<nb_actions>5</nb_actions>
 			<nb_pageviews>5</nb_pageviews>
 			<revenue>5</revenue>
-			<nb_actions>5</nb_actions>
-			<nb_visits>1</nb_visits>
 			<visits_evolution>0%</visits_evolution>
 			<actions_evolution>150%</actions_evolution>
 			<pageviews_evolution>400%</pageviews_evolution>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml
index 879bd15096faf1143f1633356121d321d73920a3..0e8c2139487d13992bd3d9dc076d8a891c4f5284 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml
@@ -3,10 +3,10 @@
 	<result date="2010-01">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>3</nb_visits>
+			<nb_actions>8</nb_actions>
 			<nb_pageviews>8</nb_pageviews>
 			<revenue>15</revenue>
-			<nb_actions>8</nb_actions>
-			<nb_visits>3</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -15,12 +15,14 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml
index ac0858dd811f9c41de826aee436a6b4c25823931..b36fe1bf7c36f472d9b1bb84d9b59ab1c9fd1e92 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml
@@ -3,10 +3,10 @@
 	<result date="From 2009-12-28 to 2010-01-03">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>1</nb_visits>
+			<nb_actions>1</nb_actions>
 			<nb_pageviews>2</nb_pageviews>
 			<revenue>10</revenue>
-			<nb_actions>1</nb_actions>
-			<nb_visits>1</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -17,10 +17,10 @@
 	<result date="From 2010-01-04 to 2010-01-10">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>2</nb_visits>
+			<nb_actions>7</nb_actions>
 			<nb_pageviews>6</nb_pageviews>
 			<revenue>5</revenue>
-			<nb_actions>7</nb_actions>
-			<nb_visits>2</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>600%</actions_evolution>
 			<pageviews_evolution>200%</pageviews_evolution>
@@ -29,12 +29,14 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml
index a56856f4eb4172b2d1fa9fa35d19133e87cf2774..f5989031af7fdf134ee31476c44803a49933b08b 100755
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml
@@ -3,10 +3,10 @@
 	<result date="2010">
 		<row>
 			<label>Site 1</label>
+			<nb_visits>3</nb_visits>
+			<nb_actions>8</nb_actions>
 			<nb_pageviews>8</nb_pageviews>
 			<revenue>15</revenue>
-			<nb_actions>8</nb_actions>
-			<nb_visits>3</nb_visits>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
@@ -15,12 +15,14 @@
 		</row>
 		<row>
 			<label>Site 2</label>
-			<nb_pageviews>3</nb_pageviews>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_pageviews>3</nb_pageviews>
+			<revenue>0</revenue>
 			<visits_evolution>100%</visits_evolution>
 			<actions_evolution>100%</actions_evolution>
 			<pageviews_evolution>100%</pageviews_evolution>
+			<revenue_evolution>0%</revenue_evolution>
 			<idsite>2</idsite>
 		</row>
 	</result>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_day.xml
index 2b01191d5b7787e8fd4fb4230508bb12c9dcaeb7..7780723708da30e1b8a069f5041153c5d754f1eb 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_day.xml
@@ -4,9 +4,9 @@
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
 		<nb_actions>1</nb_actions>
-		<nb_visits_converted />
+		<nb_visits_converted>0</nb_visits_converted>
 		<bounce_count>1</bounce_count>
-		<sum_visit_length />
+		<sum_visit_length>0</sum_visit_length>
 		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_month.xml
index e51d617dda11352cf831e09182aa45e7a32ecd91..6460d1334f77e2837dea394bf9ba0e8973122d6a 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_NotLastNPeriods__VisitsSummary.get_month.xml
@@ -4,7 +4,7 @@
 		<nb_uniq_visitors>2</nb_uniq_visitors>
 		<nb_visits>3</nb_visits>
 		<nb_actions>8</nb_actions>
-		<nb_visits_converted />
+		<nb_visits_converted>0</nb_visits_converted>
 		<bounce_count>1</bounce_count>
 		<sum_visit_length>1262</sum_visit_length>
 		<max_actions>5</max_actions>
@@ -16,8 +16,8 @@
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
 		<nb_actions>3</nb_actions>
-		<nb_visits_converted />
-		<bounce_count />
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>1</sum_visit_length>
 		<max_actions>3</max_actions>
 		<bounce_rate>0%</bounce_rate>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml
index 8b436753e0b60ec5b689952a7f100a8221570f65..09624ef0d27e703e29ce2f69b69ed76173de88e0 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml
@@ -43,9 +43,9 @@
 		<result prettyDate="Sunday 3 January 2010" />
 		<result prettyDate="Monday 4 January 2010" />
 		<result prettyDate="Tuesday 5 January 2010">
-			<nb_actions_returning>5</nb_actions_returning>
 			<nb_uniq_visitors_returning>1</nb_uniq_visitors_returning>
 			<nb_visits_returning>1</nb_visits_returning>
+			<nb_actions_returning>5</nb_actions_returning>
 			<bounce_rate_returning>0%</bounce_rate_returning>
 			<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 			<avg_time_on_site_returning>00:15:01</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml
index 1d83cf9ccc5c9e200c5e380875a3dd0effeec174..86f02442e8b5367df914952fbbf750fec0411528 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml
@@ -43,28 +43,28 @@
 	</columns>
 	<reportData>
 		<result prettyDate="Sunday 3 January 2010">
-			<max_actions>1</max_actions>
-			<nb_actions>1</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>1</nb_actions>
+			<max_actions>1</max_actions>
 			<bounce_rate>100%</bounce_rate>
 			<nb_actions_per_visit>1</nb_actions_per_visit>
 			<avg_time_on_site>00:00:00</avg_time_on_site>
 		</result>
 		<result prettyDate="Monday 4 January 2010">
-			<max_actions>2</max_actions>
-			<nb_actions>2</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>2</nb_actions>
+			<max_actions>2</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>2</nb_actions_per_visit>
 			<avg_time_on_site>00:06:01</avg_time_on_site>
 		</result>
 		<result prettyDate="Tuesday 5 January 2010">
-			<max_actions>5</max_actions>
-			<nb_actions>5</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>5</nb_actions>
+			<max_actions>5</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>5</nb_actions_per_visit>
 			<avg_time_on_site>00:15:01</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_day.xml
index b40dd75842a7f381c68b5bd8e948e31a484554fd..a5a307b7063ea9ad24160ccc2d95730bfc9ae82f 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_day.xml
@@ -4,11 +4,13 @@
 		<result date="2010-01-03" />
 		<result date="2010-01-04" />
 		<result date="2010-01-05">
-			<max_actions_returning>5</max_actions_returning>
-			<nb_actions_returning>5</nb_actions_returning>
 			<nb_uniq_visitors_returning>1</nb_uniq_visitors_returning>
 			<nb_visits_returning>1</nb_visits_returning>
+			<nb_actions_returning>5</nb_actions_returning>
+			<max_actions_returning>5</max_actions_returning>
 			<sum_visit_length_returning>901</sum_visit_length_returning>
+			<bounce_count_returning>0</bounce_count_returning>
+			<nb_visits_converted_returning>0</nb_visits_converted_returning>
 			<bounce_rate_returning>0%</bounce_rate_returning>
 			<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 			<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_month.xml
index ca1b4d4aea51c511edca4428656c085879af1e7c..fe8d7166c8fecace3ac95bda03421cf27d149859 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_month.xml
@@ -2,10 +2,12 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01">
-			<max_actions_returning>5</max_actions_returning>
-			<nb_actions_returning>5</nb_actions_returning>
 			<nb_visits_returning>1</nb_visits_returning>
+			<nb_actions_returning>5</nb_actions_returning>
+			<max_actions_returning>5</max_actions_returning>
 			<sum_visit_length_returning>901</sum_visit_length_returning>
+			<bounce_count_returning>0</bounce_count_returning>
+			<nb_visits_converted_returning>0</nb_visits_converted_returning>
 			<bounce_rate_returning>0%</bounce_rate_returning>
 			<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 			<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_week.xml
index 39b8f32ae771d94fe2c77e74b89b1577e797ab2f..a34b5c88f0ced307792534b1300002d0e7474048 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_week.xml
@@ -3,10 +3,12 @@
 	<result idSite="1">
 		<result date="From 2009-12-28 to 2010-01-03" />
 		<result date="From 2010-01-04 to 2010-01-10">
-			<max_actions_returning>5</max_actions_returning>
-			<nb_actions_returning>5</nb_actions_returning>
 			<nb_visits_returning>1</nb_visits_returning>
+			<nb_actions_returning>5</nb_actions_returning>
+			<max_actions_returning>5</max_actions_returning>
 			<sum_visit_length_returning>901</sum_visit_length_returning>
+			<bounce_count_returning>0</bounce_count_returning>
+			<nb_visits_converted_returning>0</nb_visits_converted_returning>
 			<bounce_rate_returning>0%</bounce_rate_returning>
 			<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 			<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_year.xml
index c7f6af556374977afd4aa34f8d09c1ee9fcf9636..85c2b048ab78b9407a50043745156ff2147dccfe 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitFrequency.get_year.xml
@@ -2,10 +2,12 @@
 <results>
 	<result idSite="1">
 		<result date="2010">
-			<max_actions_returning>5</max_actions_returning>
-			<nb_actions_returning>5</nb_actions_returning>
 			<nb_visits_returning>1</nb_visits_returning>
+			<nb_actions_returning>5</nb_actions_returning>
+			<max_actions_returning>5</max_actions_returning>
 			<sum_visit_length_returning>901</sum_visit_length_returning>
+			<bounce_count_returning>0</bounce_count_returning>
+			<nb_visits_converted_returning>0</nb_visits_converted_returning>
 			<bounce_rate_returning>0%</bounce_rate_returning>
 			<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 			<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_day.xml
index 4133f81ce5413c0f13ae6d7173696660f5b147af..dcd5c5b81efcaccb17bf8de045abe7977b08610d 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_day.xml
@@ -2,31 +2,37 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01-03">
-			<bounce_count>1</bounce_count>
-			<max_actions>1</max_actions>
-			<nb_actions>1</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>1</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>1</bounce_count>
+			<sum_visit_length>0</sum_visit_length>
+			<max_actions>1</max_actions>
 			<bounce_rate>100%</bounce_rate>
 			<nb_actions_per_visit>1</nb_actions_per_visit>
 			<avg_time_on_site>0</avg_time_on_site>
 		</result>
 		<result date="2010-01-04">
-			<max_actions>2</max_actions>
-			<nb_actions>2</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>2</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>361</sum_visit_length>
+			<max_actions>2</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>2</nb_actions_per_visit>
 			<avg_time_on_site>361</avg_time_on_site>
 		</result>
 		<result date="2010-01-05">
-			<max_actions>5</max_actions>
-			<nb_actions>5</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>5</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>901</sum_visit_length>
+			<max_actions>5</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>5</nb_actions_per_visit>
 			<avg_time_on_site>901</avg_time_on_site>
@@ -39,11 +45,13 @@
 	<result idSite="2">
 		<result date="2010-01-03" />
 		<result date="2010-01-04">
-			<max_actions>3</max_actions>
-			<nb_actions>3</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>1</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>3</nb_actions_per_visit>
 			<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_month.xml
index e4c2a93ef9140b6eac0209bb717dc63b6ae3a8c4..8075487234f03f52bd377dce4f148ada019bdbde 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_month.xml
@@ -2,12 +2,13 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01">
-			<bounce_count>1</bounce_count>
-			<max_actions>5</max_actions>
-			<nb_actions>8</nb_actions>
 			<nb_uniq_visitors>2</nb_uniq_visitors>
 			<nb_visits>3</nb_visits>
+			<nb_actions>8</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>1</bounce_count>
 			<sum_visit_length>1262</sum_visit_length>
+			<max_actions>5</max_actions>
 			<bounce_rate>33%</bounce_rate>
 			<nb_actions_per_visit>2.7</nb_actions_per_visit>
 			<avg_time_on_site>421</avg_time_on_site>
@@ -21,11 +22,13 @@
 	</result>
 	<result idSite="2">
 		<result date="2010-01">
-			<max_actions>3</max_actions>
-			<nb_actions>3</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>1</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>3</nb_actions_per_visit>
 			<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_week.xml
index 33acb7218df00e899d42cb05cbaf8eacee17291a..55d33219e13396a6981678d8ec1b5b30b1609fc1 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_week.xml
@@ -2,21 +2,25 @@
 <results>
 	<result idSite="1">
 		<result date="From 2009-12-28 to 2010-01-03">
-			<bounce_count>1</bounce_count>
-			<max_actions>1</max_actions>
-			<nb_actions>1</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>1</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>1</bounce_count>
+			<sum_visit_length>0</sum_visit_length>
+			<max_actions>1</max_actions>
 			<bounce_rate>100%</bounce_rate>
 			<nb_actions_per_visit>1</nb_actions_per_visit>
 			<avg_time_on_site>0</avg_time_on_site>
 		</result>
 		<result date="From 2010-01-04 to 2010-01-10">
-			<max_actions>5</max_actions>
-			<nb_actions>7</nb_actions>
 			<nb_uniq_visitors>2</nb_uniq_visitors>
 			<nb_visits>2</nb_visits>
+			<nb_actions>7</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>1262</sum_visit_length>
+			<max_actions>5</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>3.5</nb_actions_per_visit>
 			<avg_time_on_site>631</avg_time_on_site>
@@ -30,11 +34,13 @@
 	<result idSite="2">
 		<result date="From 2009-12-28 to 2010-01-03" />
 		<result date="From 2010-01-04 to 2010-01-10">
-			<max_actions>3</max_actions>
-			<nb_actions>3</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>1</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>3</nb_actions_per_visit>
 			<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_year.xml
index eb45008e28e1fd4104fd389fab8ee4dbe801c95a..e947da042bf6ddac51619cf941545665aa15e70e 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays__VisitsSummary.get_year.xml
@@ -2,11 +2,12 @@
 <results>
 	<result idSite="1">
 		<result date="2010">
-			<bounce_count>1</bounce_count>
-			<max_actions>5</max_actions>
-			<nb_actions>8</nb_actions>
 			<nb_visits>3</nb_visits>
+			<nb_actions>8</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>1</bounce_count>
 			<sum_visit_length>1262</sum_visit_length>
+			<max_actions>5</max_actions>
 			<bounce_rate>33%</bounce_rate>
 			<nb_actions_per_visit>2.7</nb_actions_per_visit>
 			<avg_time_on_site>421</avg_time_on_site>
@@ -20,10 +21,12 @@
 	</result>
 	<result idSite="2">
 		<result date="2010">
-			<max_actions>3</max_actions>
-			<nb_actions>3</nb_actions>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
+			<nb_visits_converted>0</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>1</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>3</nb_actions_per_visit>
 			<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_day.xml
index bf273ff429d17043123a1617db72079bc313689b..99df3c9513a3f3749e6b861ffa5c43d6d66f1aca 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_day.xml
@@ -3,11 +3,13 @@
 	<result date="2010-01-03" />
 	<result date="2010-01-04" />
 	<result date="2010-01-05">
-		<max_actions_returning>5</max_actions_returning>
-		<nb_actions_returning>5</nb_actions_returning>
 		<nb_uniq_visitors_returning>1</nb_uniq_visitors_returning>
 		<nb_visits_returning>1</nb_visits_returning>
+		<nb_actions_returning>5</nb_actions_returning>
+		<max_actions_returning>5</max_actions_returning>
 		<sum_visit_length_returning>901</sum_visit_length_returning>
+		<bounce_count_returning>0</bounce_count_returning>
+		<nb_visits_converted_returning>0</nb_visits_converted_returning>
 		<bounce_rate_returning>0%</bounce_rate_returning>
 		<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 		<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_month.xml
index bedaee43c4656d0671bf44e4e01e3542aed6a816..9ffb889bca0de2b8062a62579d035b02198fa129 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_month.xml
@@ -1,10 +1,12 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="2010-01">
-		<max_actions_returning>5</max_actions_returning>
-		<nb_actions_returning>5</nb_actions_returning>
 		<nb_visits_returning>1</nb_visits_returning>
+		<nb_actions_returning>5</nb_actions_returning>
+		<max_actions_returning>5</max_actions_returning>
 		<sum_visit_length_returning>901</sum_visit_length_returning>
+		<bounce_count_returning>0</bounce_count_returning>
+		<nb_visits_converted_returning>0</nb_visits_converted_returning>
 		<bounce_rate_returning>0%</bounce_rate_returning>
 		<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 		<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_week.xml
index 011231d299bdf3ea997ca31ed00cdb0437b37c7c..a4059459f221274d20af27fd3ec32735b54048d2 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_week.xml
@@ -2,10 +2,12 @@
 <results>
 	<result date="From 2009-12-28 to 2010-01-03" />
 	<result date="From 2010-01-04 to 2010-01-10">
-		<max_actions_returning>5</max_actions_returning>
-		<nb_actions_returning>5</nb_actions_returning>
 		<nb_visits_returning>1</nb_visits_returning>
+		<nb_actions_returning>5</nb_actions_returning>
+		<max_actions_returning>5</max_actions_returning>
 		<sum_visit_length_returning>901</sum_visit_length_returning>
+		<bounce_count_returning>0</bounce_count_returning>
+		<nb_visits_converted_returning>0</nb_visits_converted_returning>
 		<bounce_rate_returning>0%</bounce_rate_returning>
 		<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 		<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_year.xml
index ee9bc5d62b3bc1bfcf89fc5e8d1d98ca936df923..4e65e0053ad1bacfc0b75dcd50f39990a627052e 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitFrequency.get_year.xml
@@ -1,10 +1,12 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="2010">
-		<max_actions_returning>5</max_actions_returning>
-		<nb_actions_returning>5</nb_actions_returning>
 		<nb_visits_returning>1</nb_visits_returning>
+		<nb_actions_returning>5</nb_actions_returning>
+		<max_actions_returning>5</max_actions_returning>
 		<sum_visit_length_returning>901</sum_visit_length_returning>
+		<bounce_count_returning>0</bounce_count_returning>
+		<nb_visits_converted_returning>0</nb_visits_converted_returning>
 		<bounce_rate_returning>0%</bounce_rate_returning>
 		<nb_actions_per_visit_returning>5</nb_actions_per_visit_returning>
 		<avg_time_on_site_returning>901</avg_time_on_site_returning>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_day.xml
index be1c6c3f05ac45a47812055866bd1fdc9d447098..34107feaf911144e73b1efc114702d46062ec111 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_day.xml
@@ -1,31 +1,37 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="2010-01-03">
-		<bounce_count>1</bounce_count>
-		<max_actions>1</max_actions>
-		<nb_actions>1</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>1</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>1</bounce_count>
+		<sum_visit_length>0</sum_visit_length>
+		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
 		<avg_time_on_site>0</avg_time_on_site>
 	</result>
 	<result date="2010-01-04">
-		<max_actions>2</max_actions>
-		<nb_actions>2</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>2</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>361</sum_visit_length>
+		<max_actions>2</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>2</nb_actions_per_visit>
 		<avg_time_on_site>361</avg_time_on_site>
 	</result>
 	<result date="2010-01-05">
-		<max_actions>5</max_actions>
-		<nb_actions>5</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>5</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>901</sum_visit_length>
+		<max_actions>5</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>5</nb_actions_per_visit>
 		<avg_time_on_site>901</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_month.xml
index 97dcf9402dbd054b6af7c7d21c23834f1c65687a..7b3d2ad59053152579dd35a13791a6960d90c7e3 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_month.xml
@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="2010-01">
-		<bounce_count>1</bounce_count>
-		<max_actions>5</max_actions>
-		<nb_actions>8</nb_actions>
 		<nb_uniq_visitors>2</nb_uniq_visitors>
 		<nb_visits>3</nb_visits>
+		<nb_actions>8</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>1</bounce_count>
 		<sum_visit_length>1262</sum_visit_length>
+		<max_actions>5</max_actions>
 		<bounce_rate>33%</bounce_rate>
 		<nb_actions_per_visit>2.7</nb_actions_per_visit>
 		<avg_time_on_site>421</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_week.xml
index 2dc43c8ba74e22478ffea6d5420e30edf9ab35b2..ecb5834c991fd4862ff0752b1188d5f8bf45c1e7 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_week.xml
@@ -1,21 +1,25 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="From 2009-12-28 to 2010-01-03">
-		<bounce_count>1</bounce_count>
-		<max_actions>1</max_actions>
-		<nb_actions>1</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>1</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>1</bounce_count>
+		<sum_visit_length>0</sum_visit_length>
+		<max_actions>1</max_actions>
 		<bounce_rate>100%</bounce_rate>
 		<nb_actions_per_visit>1</nb_actions_per_visit>
 		<avg_time_on_site>0</avg_time_on_site>
 	</result>
 	<result date="From 2010-01-04 to 2010-01-10">
-		<max_actions>5</max_actions>
-		<nb_actions>7</nb_actions>
 		<nb_uniq_visitors>2</nb_uniq_visitors>
 		<nb_visits>2</nb_visits>
+		<nb_actions>7</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>1262</sum_visit_length>
+		<max_actions>5</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>3.5</nb_actions_per_visit>
 		<avg_time_on_site>631</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_year.xml b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_year.xml
index 11f73e549fb3c2cf32210b933f8438773ac3eb85..d4bc70826ef8ed52d3fa34bde7ebfd8b21fdba69 100644
--- a/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_year.xml
+++ b/tests/PHPUnit/Integration/expected/test_TwoVisitors_twoWebsites_differentDays_idSiteOne___VisitsSummary.get_year.xml
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="2010">
-		<bounce_count>1</bounce_count>
-		<max_actions>5</max_actions>
-		<nb_actions>8</nb_actions>
 		<nb_visits>3</nb_visits>
+		<nb_actions>8</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>1</bounce_count>
 		<sum_visit_length>1262</sum_visit_length>
+		<max_actions>5</max_actions>
 		<bounce_rate>33%</bounce_rate>
 		<nb_actions_per_visit>2.7</nb_actions_per_visit>
 		<avg_time_on_site>421</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldAppear__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldAppear__VisitsSummary.get_month.xml
index 111231042c6c6bd77171538aa2dd68e84b7c15e5..960470df27e39d634957dfa6942469b3cb8fcbfd 100644
--- a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldAppear__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldAppear__VisitsSummary.get_month.xml
@@ -1,22 +1,26 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="2010-01">
-		<max_actions>4</max_actions>
-		<nb_actions>4</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>4</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>1</sum_visit_length>
+		<max_actions>4</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>4</nb_actions_per_visit>
 		<avg_time_on_site>1</avg_time_on_site>
 	</result>
 	<result date="2010-02" />
 	<result date="2010-03">
-		<max_actions>6</max_actions>
-		<nb_actions>6</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>6</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>1</sum_visit_length>
+		<max_actions>6</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>6</nb_actions_per_visit>
 		<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldNotAppear__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldNotAppear__VisitsSummary.get_month.xml
index e10145445478d071a3c097b49c071ee6a14c4715..a0bc7a3d907d5cfa7ac6c2248bfd5437c747c439 100644
--- a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldNotAppear__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite1_OldReportsShouldNotAppear__VisitsSummary.get_month.xml
@@ -3,11 +3,13 @@
 	<result date="2010-01" />
 	<result date="2010-02" />
 	<result date="2010-03">
-		<max_actions>6</max_actions>
-		<nb_actions>6</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>6</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>1</sum_visit_length>
+		<max_actions>6</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>6</nb_actions_per_visit>
 		<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldAppear__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldAppear__VisitsSummary.get_month.xml
index a5a594c64796c876d7072417c5c1d3d634b61f8e..caa4caae0595407f401cfb91214586e4bc265394 100644
--- a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldAppear__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldAppear__VisitsSummary.get_month.xml
@@ -1,11 +1,13 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
 	<result date="2009-10">
-		<max_actions>5</max_actions>
-		<nb_actions>5</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>5</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>361</sum_visit_length>
+		<max_actions>5</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>5</nb_actions_per_visit>
 		<avg_time_on_site>361</avg_time_on_site>
@@ -13,11 +15,13 @@
 	<result date="2009-11" />
 	<result date="2009-12" />
 	<result date="2010-01">
-		<max_actions>6</max_actions>
-		<nb_actions>6</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>6</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>1</sum_visit_length>
+		<max_actions>6</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>6</nb_actions_per_visit>
 		<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldNotAppear__VisitsSummary.get_month.xml b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldNotAppear__VisitsSummary.get_month.xml
index 9f536d593769bffe7a25b30643a831df63be1198..be23d67bf27e156ce7eb25ab0bc7874c63efdc48 100644
--- a/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldNotAppear__VisitsSummary.get_month.xml
+++ b/tests/PHPUnit/Integration/expected/test_VisitsInPast_InvalidateOldReportsWebsite2_OldReportsShouldNotAppear__VisitsSummary.get_month.xml
@@ -4,11 +4,13 @@
 	<result date="2009-11" />
 	<result date="2009-12" />
 	<result date="2010-01">
-		<max_actions>6</max_actions>
-		<nb_actions>6</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
 		<nb_visits>1</nb_visits>
+		<nb_actions>6</nb_actions>
+		<nb_visits_converted>0</nb_visits_converted>
+		<bounce_count>0</bounce_count>
 		<sum_visit_length>1</sum_visit_length>
+		<max_actions>6</max_actions>
 		<bounce_rate>0%</bounce_rate>
 		<nb_actions_per_visit>6</nb_actions_per_visit>
 		<avg_time_on_site>1</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__VisitTime.getByDayOfWeek_day.xml b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__VisitTime.getByDayOfWeek_day.xml
index 06100d0440340bfdc992ee9f4fefda94bfcdcf01..e9de54454b39bb2b5e7a8ca0e97a77f5a6d25d66 100755
--- a/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__VisitTime.getByDayOfWeek_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_ecommerceOrderWithItems__VisitTime.getByDayOfWeek_day.xml
@@ -8,10 +8,11 @@
 	<row>
 		<label>Tuesday</label>
 		<nb_visits>3</nb_visits>
-		<nb_actions>13</nb_actions>
 		<nb_uniq_visitors>1</nb_uniq_visitors>
-		<nb_visits_converted>2</nb_visits_converted>
+		<nb_actions>13</nb_actions>
 		<sum_visit_length>5403</sum_visit_length>
+		<bounce_count>0</bounce_count>
+		<nb_visits_converted>2</nb_visits_converted>
 		<day_of_week>2</day_of_week>
 	</row>
 	<row>
diff --git a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_day.xml b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_day.xml
index c908c9a75de925061fd59c6a5dde6d4d81c4e63b..106f23f16bb7dddc98ac7def1dd2c59d64a48127 100644
--- a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_day.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
-	<result date="2009-01-04">0s</result>
-	<result date="2009-01-05">0s</result>
-	<result date="2009-01-06">0s</result>
-	<result date="2009-01-07">0s</result>
-	<result date="2009-01-08">0s</result>
-	<result date="2009-01-09">0s</result>
-	<result date="2009-01-10">0s</result>
+	<result date="2009-01-04" />
+	<result date="2009-01-05" />
+	<result date="2009-01-06" />
+	<result date="2009-01-07" />
+	<result date="2009-01-08" />
+	<result date="2009-01-09" />
+	<result date="2009-01-10" />
 </results>
\ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_week.xml b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_week.xml
index 1f731a8248b9e8dba6b3bf7c067163ab4e77f5c1..5cfb246edc18a6da402cb45044dfaf1ad20e25bc 100644
--- a/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_noVisit_PeriodIsLast__VisitsSummary.getSumVisitsLengthPretty_week.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <results>
-	<result date="From 2008-12-29 to 2009-01-04">0s</result>
-	<result date="From 2009-01-05 to 2009-01-11">0s</result>
-	<result date="From 2009-01-12 to 2009-01-18">0s</result>
-	<result date="From 2009-01-19 to 2009-01-25">0s</result>
-	<result date="From 2009-01-26 to 2009-02-01">0s</result>
-	<result date="From 2009-02-02 to 2009-02-08">0s</result>
-	<result date="From 2009-02-09 to 2009-02-15">0s</result>
+	<result date="From 2008-12-29 to 2009-01-04" />
+	<result date="From 2009-01-05 to 2009-01-11" />
+	<result date="From 2009-01-12 to 2009-01-18" />
+	<result date="From 2009-01-19 to 2009-01-25" />
+	<result date="From 2009-01-26 to 2009-02-01" />
+	<result date="From 2009-02-02 to 2009-02-08" />
+	<result date="From 2009-02-09 to 2009-02-15" />
 </results>
\ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml b/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml
index 34dab4179a09f19baf72321982a7dd1455b127d7..6cba58af76b07f209e3fa4807961a2ae5cb52e0d 100755
--- a/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml
@@ -5,10 +5,11 @@
 		<nb_visits>2</nb_visits>
 		<nb_actions>3</nb_actions>
 		<nb_pageviews>3</nb_pageviews>
-		<revenue />
+		<revenue>0</revenue>
 		<visits_evolution>0%</visits_evolution>
 		<actions_evolution>0%</actions_evolution>
 		<pageviews_evolution>0%</pageviews_evolution>
+		<revenue_evolution>0%</revenue_evolution>
 		<idsite>1</idsite>
 	</row>
 </result>
\ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml b/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml
index 7ad506794e1a50c297869e01ff93af7537d1226b..124352434cfc6bc9fc6d342482da89988fad4d51 100755
--- a/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml
+++ b/tests/PHPUnit/Integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml
@@ -5,7 +5,7 @@
 		<nb_visits>6</nb_visits>
 		<nb_actions>9</nb_actions>
 		<nb_pageviews>9</nb_pageviews>
-		<revenue />
+		<revenue>0</revenue>
 		<idsite>1</idsite>
 	</row>
 	<row>
@@ -13,7 +13,7 @@
 		<nb_visits>2</nb_visits>
 		<nb_actions>2</nb_actions>
 		<nb_pageviews>2</nb_pageviews>
-		<revenue />
+		<revenue>0</revenue>
 		<idsite>2</idsite>
 	</row>
 </result>
\ No newline at end of file
diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml
index 5f71e55e2dcc9cd6a082f369c0619c5d7a88072f..af699f57c029c2365d9fae946765be69e24f1c86 100644
--- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml
@@ -2,13 +2,13 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01-03">
-			<bounce_count>2</bounce_count>
-			<max_actions>4</max_actions>
-			<nb_actions>6</nb_actions>
 			<nb_uniq_visitors>2</nb_uniq_visitors>
 			<nb_visits>3</nb_visits>
+			<nb_actions>6</nb_actions>
 			<nb_visits_converted>2</nb_visits_converted>
+			<bounce_count>2</bounce_count>
 			<sum_visit_length>722</sum_visit_length>
+			<max_actions>4</max_actions>
 			<bounce_rate>67%</bounce_rate>
 			<nb_actions_per_visit>2</nb_actions_per_visit>
 			<avg_time_on_site>241</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml
index f4c4d277b9384317335d72f2c587db9fb4c5d4ac..af0e5b623478c50bdd3fd55395da2c042bb3b188 100644
--- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml
@@ -2,13 +2,13 @@
 <results>
 	<result idSite="1">
 		<result date="From 2009-12-28 to 2010-01-03">
-			<bounce_count>2</bounce_count>
-			<max_actions>4</max_actions>
-			<nb_actions>6</nb_actions>
 			<nb_uniq_visitors>2</nb_uniq_visitors>
 			<nb_visits>3</nb_visits>
+			<nb_actions>6</nb_actions>
 			<nb_visits_converted>2</nb_visits_converted>
+			<bounce_count>2</bounce_count>
 			<sum_visit_length>722</sum_visit_length>
+			<max_actions>4</max_actions>
 			<bounce_rate>67%</bounce_rate>
 			<nb_actions_per_visit>2</nb_actions_per_visit>
 			<avg_time_on_site>241</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_day.xml
index 36155923470a7c3157020db80a8dfd514ee45568..fed5186aaa135d2993544aa229108a521a103c3a 100644
--- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_day.xml
@@ -2,13 +2,13 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01-03">
-			<bounce_count>2</bounce_count>
-			<max_actions>3</max_actions>
-			<nb_actions>5</nb_actions>
 			<nb_uniq_visitors>2</nb_uniq_visitors>
 			<nb_visits>3</nb_visits>
+			<nb_actions>5</nb_actions>
 			<nb_visits_converted>2</nb_visits_converted>
+			<bounce_count>2</bounce_count>
 			<sum_visit_length>725</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>67%</bounce_rate>
 			<nb_actions_per_visit>1.7</nb_actions_per_visit>
 			<avg_time_on_site>242</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_week.xml
index dea7c5b5df0d519ed18ee0d10953d44705efc87c..15d181149326df4397458a9a9735b11c66a6feff 100644
--- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchALL_noGoalData__VisitsSummary.get_week.xml
@@ -2,13 +2,13 @@
 <results>
 	<result idSite="1">
 		<result date="From 2009-12-28 to 2010-01-03">
-			<bounce_count>2</bounce_count>
-			<max_actions>3</max_actions>
-			<nb_actions>5</nb_actions>
 			<nb_uniq_visitors>2</nb_uniq_visitors>
 			<nb_visits>3</nb_visits>
+			<nb_actions>5</nb_actions>
 			<nb_visits_converted>2</nb_visits_converted>
+			<bounce_count>2</bounce_count>
 			<sum_visit_length>725</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>67%</bounce_rate>
 			<nb_actions_per_visit>1.7</nb_actions_per_visit>
 			<avg_time_on_site>242</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_day.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_day.xml
index d6f61bf5f7b564a1cb0d8643a9441d8547bed153..1eecbb155e722c14442e5a165b4e6cbd4b3d8ffc 100644
--- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_day.xml
+++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_day.xml
@@ -2,12 +2,13 @@
 <results>
 	<result idSite="1">
 		<result date="2010-01-03">
-			<max_actions>3</max_actions>
-			<nb_actions>3</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
 			<nb_visits_converted>1</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>364</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>3</nb_actions_per_visit>
 			<avg_time_on_site>364</avg_time_on_site>
diff --git a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_week.xml b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_week.xml
index 4e252528ca4a3d6191eee13af59168e5c3922b7e..48f2d04f2d81093dc9dd731a3768f41cc4a8a868 100644
--- a/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_week.xml
+++ b/tests/PHPUnit/Integration/expected/test_twoVisitsWithCustomVariables_segmentMatchVisitorType__VisitsSummary.get_week.xml
@@ -2,12 +2,13 @@
 <results>
 	<result idSite="1">
 		<result date="From 2009-12-28 to 2010-01-03">
-			<max_actions>3</max_actions>
-			<nb_actions>3</nb_actions>
 			<nb_uniq_visitors>1</nb_uniq_visitors>
 			<nb_visits>1</nb_visits>
+			<nb_actions>3</nb_actions>
 			<nb_visits_converted>1</nb_visits_converted>
+			<bounce_count>0</bounce_count>
 			<sum_visit_length>364</sum_visit_length>
+			<max_actions>3</max_actions>
 			<bounce_rate>0%</bounce_rate>
 			<nb_actions_per_visit>3</nb_actions_per_visit>
 			<avg_time_on_site>364</avg_time_on_site>
diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php
index 30595ef8edc906451886c8917d38770449f09f23..881d5e182f6ebc7ee54de592b7134be74fa786a4 100755
--- a/tests/PHPUnit/IntegrationTestCase.php
+++ b/tests/PHPUnit/IntegrationTestCase.php
@@ -248,6 +248,7 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase
         'Annotations',
         'SegmentEditor',
         'UserCountry.getLocationFromIP',
+        'Dashboard'
     );
 
     const DEFAULT_USER_PASSWORD = 'nopass';