diff --git a/modules/statistics/config-templates/module_statistics.php b/modules/statistics/config-templates/module_statistics.php
index be25afef584a4056a660af20f5fc1e4d76347614..cda18ab6e3e53be9250f5e795b39749b3b6e938c 100644
--- a/modules/statistics/config-templates/module_statistics.php
+++ b/modules/statistics/config-templates/module_statistics.php
@@ -140,19 +140,28 @@ $config = array (
 		),
 	),
 	'statrules' => array(
-// 		'sloratio' => array(
-// 			'name' 		=> 'SSO to SLO ratio',
-// 			'descr'		=> 'ratio',
-// 		
-// 			'type' => 'ratio',
-// 			
-// 			'action' 	=> 'saml20-idp-SSO',
-// 			'col'		=> 6,				// Service Provider EntityID
-// 			'fieldPresentation' => array(
-// 				'class' => 'statistics:Entity',
-// 				'config' => 'saml20-sp-remote',
-// 			),
-// 		),
+		'sloratio' => array(
+			'name' 		=> 'SLO to SSO ratio',
+			'descr'		=> 'Comparison of the number of Single Log-Out compared to Single Sign-On. Graph shows how many logouts where initiated for each Single Sign-On.',
+			'type' => 'calculated',
+			'presenter' => 'statistics:Ratio',
+			'ref' => array('slo', 'sso'),
+			'fieldPresentation' => array(
+				'class' => 'statistics:Entity',
+				'config' => 'saml20-sp-remote',
+			),
+		),
+		'ssomulti' => array(
+			'name' 		=> 'Requests per session',
+			'descr'		=> 'Number of SSO request pairs exchanged between IdP and SP within the same IdP session. A high number indicates that the session at the SP is timing out faster than at the IdP.',
+			'type' => 'calculated',
+			'presenter' => 'statistics:Ratio',
+			'ref' => array('sso', 'ssofirst'),
+			'fieldPresentation' => array(
+				'class' => 'statistics:Entity',
+				'config' => 'saml20-sp-remote',
+			),
+		),
 		'sso' => array(
 			'name' 		=> 'SSO to service',
 			'descr'		=> 'The number of logins at a Service Provider.',
@@ -194,8 +203,8 @@ $config = array (
 			),
 		),
 		'slo' => array(
-			'name' 		=> 'Logout',
-			'descr'		=> 'The number of initated Sinlge Logout.',
+			'name' 		=> 'SLO initiated from service',
+			'descr'		=> 'The number of initated Sinlge Logout from each of the service providers.',
 			'action' 	=> 'saml20-idp-SLO',
 			'col'		=> 7,				// Service Provider EntityID that initiated the logout.
 			'fieldPresentation' => array(
@@ -223,7 +232,6 @@ $config = array (
 				'config' => 'saml20-sp-remote',
 			),
 		),
-		
 	),
 
 );
diff --git a/modules/statistics/lib/Aggregator.php b/modules/statistics/lib/Aggregator.php
index 27ec2980c9f14b875adb2cb51ce05bf41d8b834c..2fe726ebef14a1da090939a266bb889e8c21b405 100644
--- a/modules/statistics/lib/Aggregator.php
+++ b/modules/statistics/lib/Aggregator.php
@@ -138,7 +138,11 @@ class sspmod_statistics_Aggregator {
 			
 			// Iterate all the statrules from config.
 			foreach ($this->statrules AS $rulename => $rule) {
-			
+				
+				$type = 'aggregate';
+				if (array_key_exists('type', $rule)) $type = $rule['type'];
+				if ($type !== 'aggregate') continue;
+				
 				foreach($this->timeres AS $tres => $tresconfig ) {
 			
 					// echo 'Comparing action: [' . $rule['action'] . '] with [' . $action . ']' . "\n";
diff --git a/modules/statistics/lib/RatioDataset.php b/modules/statistics/lib/RatioDataset.php
new file mode 100644
index 0000000000000000000000000000000000000000..b83c12b0386bfe7c6dfb93ac4678c784785b5288
--- /dev/null
+++ b/modules/statistics/lib/RatioDataset.php
@@ -0,0 +1,85 @@
+<?php
+/*
+ * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_statistics_RatioDataset extends sspmod_statistics_StatDataset {
+
+	
+	public function aggregateSummary() {
+		/**
+		 * Aggregate summary table from dataset. To be used in the table view.
+		 */
+		$this->summary = array(); 
+		$noofvalues = array();
+		foreach($this->results AS $slot => $res) {
+			foreach ($res AS $key => $value) {
+				if (array_key_exists($key, $this->summary)) {
+					$this->summary[$key] += $value;
+					if ($value > 0) 
+						$noofvalues[$key]++;
+				} else {
+					$this->summary[$key] = $value;
+					if ($value > 0) 
+						$noofvalues[$key] = 1;
+					else 
+						$noofvalues[$key] = 0;
+				}
+			}
+		}
+		
+		foreach($this->summary AS $key => $val) {
+			$this->summary[$key] = $this->divide($this->summary[$key], $noofvalues[$key]);
+		}
+		
+		asort($this->summary);
+		$this->summary = array_reverse($this->summary, TRUE);
+		// echo '<pre>'; print_r($summaryDataset); exit;
+	}
+	
+	private function ag($k, $a) {
+		if (array_key_exists($k, $a)) return $a[$k];
+		return 0;
+	}
+	
+	private function divide($v1, $v2) {
+		if ($v2 == 0) return 0;
+		return ($v1 / $v2);
+	}
+	
+	public function combine($result1, $result2) {
+
+		
+		$combined = array();
+		
+		foreach($result2 AS $tick => $val) {
+			$combined[$tick] = array();
+			foreach($val AS $index => $num) {
+				$combined[$tick][$index] = $this->divide( 
+					$this->ag($index, $result1[$tick]),
+					$this->ag($index, $result2[$tick])
+				);
+			}
+			
+		}
+		
+		// echo('<pre>');
+		// echo('combine 1 ');
+		// print_r($result1);
+		// echo('combine 2 ');
+		// print_r($result2); 
+		// echo('combineed ');
+		// print_r($combined); 
+		// 
+		// exit;
+		
+		return $combined;
+	}
+	
+	public function getPieData() {
+		return NULL;
+	}
+
+}
+
diff --git a/modules/statistics/lib/Ruleset.php b/modules/statistics/lib/Ruleset.php
index 24fe6c2f0be203f55f11f38a6abff8bee763ea2e..4833a66b316a5f0a9929ae67e2b5bef562368923 100644
--- a/modules/statistics/lib/Ruleset.php
+++ b/modules/statistics/lib/Ruleset.php
@@ -47,11 +47,12 @@ class sspmod_statistics_Ruleset {
 		/*
 		 * Create array with information about available rules..
 		 */
+		$this->availrules = array_keys($statrules);
 		$available_rules = array();
-		foreach ($this->available AS $key => $av) {
+		foreach ($this->availrules AS $key) {
 			$available_rules[$key] = array('name' => $statrules[$key]['name'], 'descr' => $statrules[$key]['descr']);
 		}
-		$this->availrules = array_keys($available_rules);
+		// echo('<pre>'); print_r($available_rules); exit;
 		$this->availrulenames = $available_rules;
 		
 	}
@@ -81,7 +82,9 @@ class sspmod_statistics_Ruleset {
 		$rule = $this->resolveSelectedRule($preferRule);
 		$statrulesConfig = $this->statconfig->getConfigItem('statrules');
 		$statruleConfig = $statrulesConfig->getConfigItem($rule);
-		$statrule = new sspmod_statistics_StatRule($this->statconfig, $statruleConfig, $rule, $this->available[$rule]);
+		
+		$presenterClass = SimpleSAML_Module::resolveClass($statruleConfig->getValue('presenter', 'statistics:BaseRule'), 'Statistics_Rulesets');
+		$statrule = new $presenterClass($this->statconfig, $statruleConfig, $rule, $this->available);
 		return $statrule;
 	}
 
diff --git a/modules/statistics/lib/StatDataset.php b/modules/statistics/lib/StatDataset.php
index e1eccfd802128ee3fd21cb9bff86580e90d5ffe5..8ed2f094b8f05cb8a177ae75845956af2334781d 100644
--- a/modules/statistics/lib/StatDataset.php
+++ b/modules/statistics/lib/StatDataset.php
@@ -6,21 +6,21 @@
  */
 class sspmod_statistics_StatDataset {
 
-	private $statconfig;
-	private $ruleconfig;
-	private $timeresconfig;
-	private $ruleid;
+	protected $statconfig;
+	protected $ruleconfig;
+	protected $timeresconfig;
+	protected $ruleid;
 
-	private $fileslot;
-	private $timeres;
+	protected $fileslot;
+	protected $timeres;
 	
-	private $delimiter;
-	private $results;
-	private $summary;
-	private $max;
+	protected $delimiter;
+	protected $results;
+	protected $summary;
+	protected $max;
 	
-	private $datehandlerFile;
-	private $datehandlerTick;
+	protected $datehandlerFile;
+	protected $datehandlerTick;
 	
 	/**
 	 * Constructor
@@ -294,19 +294,29 @@ class sspmod_statistics_StatDataset {
 	public function loadData() {
 
 		$statdir = $this->statconfig->getValue('statdir');
+		$resarray = array();
+		$rules = SimpleSAML_Utilities::arrayize($this->ruleid);
+		foreach($rules AS $rule) {
+			// Get file and extract results.
+			$resultFileName = $statdir . '/' . $rule . '-' . $this->timeres . '-'. $this->fileslot . '.stat';
+			if (!file_exists($resultFileName))
+				throw new Exception('Aggregated statitics file [' . $resultFileName . '] not found.');
+			if (!is_readable($resultFileName))
+				throw new Exception('Could not read statitics file [' . $resultFileName . ']. Bad file permissions?');
+			$resultfile = file_get_contents($resultFileName);
+			$newres = unserialize($resultfile);
+			if (empty($newres))
+				throw new Exception('Aggregated statistics in file [' . $resultFileName . '] was empty.');
+			$resarray[] = $newres;
+		}
 
-		// Get file and extract results.
-		$resultFileName = $statdir . '/' . $this->ruleid . '-' . $this->timeres . '-'. $this->fileslot . '.stat';
-		if (!file_exists($resultFileName))
-			throw new Exception('Aggregated statitics file [' . $resultFileName . '] not found.');
-		if (!is_readable($resultFileName))
-			throw new Exception('Could not read statitics file [' . $resultFileName . ']. Bad file permissions?');
-		$resultfile = file_get_contents($resultFileName);
-		$this->results = unserialize($resultfile);
-		if (empty($this->results))
-			throw new Exception('Aggregated statistics in file [' . $resultFileName . '] was empty.');
-			
-		// echo('<pre>'); print_r($this->results); exit;
+		$combined = $resarray[0];
+		if(count($resarray) > 1) {
+			for($i = 1; $i < count($resarray); $i++) {
+				$combined = $this->combine($combined, $resarray[$i]);
+			}
+		}
+		$this->results = $combined;
 	}
 
 }
diff --git a/modules/statistics/lib/StatRule.php b/modules/statistics/lib/Statistics/Rulesets/BaseRule.php
similarity index 89%
rename from modules/statistics/lib/StatRule.php
rename to modules/statistics/lib/Statistics/Rulesets/BaseRule.php
index c5e17b4f893ba14929e1afd8ce4d27babd991e66..5e7e2c8f17b8f6d5fd659cb83baf3e14c23b4e59 100644
--- a/modules/statistics/lib/StatRule.php
+++ b/modules/statistics/lib/Statistics/Rulesets/BaseRule.php
@@ -4,13 +4,13 @@
  * @package simpleSAMLphp
  * @version $Id$
  */
-class sspmod_statistics_StatRule {
+class sspmod_statistics_Statistics_Rulesets_BaseRule {
+
+	protected $statconfig;
+	protected $ruleconfig;
+	protected $ruleid;
+	protected $available;
 
-	private $statconfig;
-	private $ruleconfig;
-	private $ruleid;
-	private $available;
-	// private $datehandler;
 	/**
 	 * Constructor
 	 */
@@ -20,10 +20,9 @@ class sspmod_statistics_StatRule {
 		$this->statconfig = $statconfig;
 		$this->ruleconfig = $ruleconfig;
 		$this->ruleid = $ruleid;
-		$this->available = $available;
-	
-		// $this->datehandlerFile = $datehandler;
-		// $this->datehandlerTick = $datehandler;
+		
+		$this->available = NULL;
+		if (array_key_exists($ruleid, $available)) $this->available = $available[$ruleid];	
 	}
 	
 	public function getRuleID() {
@@ -67,7 +66,7 @@ class sspmod_statistics_StatRule {
 		return $available_times;
 	}
 
-	private function resolveTimeRes($preferTimeRes) {
+	protected function resolveTimeRes($preferTimeRes) {
 		$timeresavailable = array_keys($this->available);
 		$timeres = $timeresavailable[0];
 
@@ -78,7 +77,7 @@ class sspmod_statistics_StatRule {
 		return $timeres;
 	}
 	
-	private function resolveFileSlot($timeres, $preferTime) {
+	protected function resolveFileSlot($timeres, $preferTime) {
 
 		// Get which time (fileslot) to use.. First get a default, which is the most recent one.
 		$fileslot = $this->available[$timeres][count($this->available[$timeres])-1];
diff --git a/modules/statistics/lib/Statistics/Rulesets/Ratio.php b/modules/statistics/lib/Statistics/Rulesets/Ratio.php
new file mode 100644
index 0000000000000000000000000000000000000000..94095ef2e66c2a7c4916c57f2073ff7293df0c09
--- /dev/null
+++ b/modules/statistics/lib/Statistics/Rulesets/Ratio.php
@@ -0,0 +1,65 @@
+<?php
+/*
+ * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class sspmod_statistics_Statistics_Rulesets_Ratio extends sspmod_statistics_Statistics_Rulesets_BaseRule {
+
+	protected $refrule1;
+	protected $refrule2;
+	
+	/**
+	 * Constructor
+	 */
+	public function __construct($statconfig, $ruleconfig, $ruleid, $available) {
+		assert('$statconfig instanceof SimpleSAML_Configuration');
+		assert('$ruleconfig instanceof SimpleSAML_Configuration');
+		
+		parent::__construct($statconfig, $ruleconfig, $ruleid, $available);
+		
+		$refNames = $this->ruleconfig->getArray('ref');
+		
+		$statrulesConfig = $this->statconfig->getConfigItem('statrules');
+		
+		$statruleConfig1 = $statrulesConfig->getConfigItem($refNames[0]);
+		$statruleConfig2 = $statrulesConfig->getConfigItem($refNames[1]);
+		
+		$this->refrule1 = new sspmod_statistics_Statistics_Rulesets_BaseRule($this->statconfig, $statruleConfig1, $refNames[0], $available);
+		$this->refrule2 = new sspmod_statistics_Statistics_Rulesets_BaseRule($this->statconfig, $statruleConfig2, $refNames[1], $available);
+	}
+	
+	public function availableTimeRes() {
+		return $this->refrule1->availableTimeRes();
+	}
+	
+	public function availableFileSlots($timeres) {
+		return $this->refrule1->availableFileSlots($timeres);
+	}
+
+	protected function resolveTimeRes($preferTimeRes) {
+		return $this->refrule1->resolveTimeRes($preferTimeRes);
+	}
+	
+	protected function resolveFileSlot($timeres, $preferTime) {
+		return $this->refrule1->resolveFileSlot($timeres, $preferTime);
+	}
+	
+	
+	public function getTimeNavigation($timeres, $preferTime) {
+		return $this->refrule1->getTimeNavigation($timeres, $preferTime);
+	}
+	
+	public function getDataSet($preferTimeRes, $preferTime) {
+		$timeres = $this->resolveTimeRes($preferTimeRes);
+		$fileslot = $this->resolveFileSlot($timeres, $preferTime);
+		
+		$refNames = $this->ruleconfig->getArray('ref');
+		
+		$dataset = new sspmod_statistics_RatioDataset($this->statconfig, $this->ruleconfig, $refNames, $timeres, $fileslot);
+		return $dataset;
+	}
+	
+
+}
+
diff --git a/modules/statistics/templates/statistics-tpl.php b/modules/statistics/templates/statistics-tpl.php
index 7b8e08cb75c5307f7e1c1d1a28bb86523cec188b..e6d342eb14262dc599a6c4ba6fc0e0d34d2fd157 100644
--- a/modules/statistics/templates/statistics-tpl.php
+++ b/modules/statistics/templates/statistics-tpl.php
@@ -234,8 +234,9 @@ echo '</div>'; # end graph content.
 $classint = array('odd', 'even'); $i = 0;
 echo '<div id="table" class="tabset_content">';
 
-echo('<img src="' . $this->data['pieimgurl'] . '" />');
-
+if (isset($this->data['pieimgurl'])) {
+	echo('<img src="' . $this->data['pieimgurl'] . '" />');
+}
 echo '<table class="tableview"><tr><th class="value">Value</th><th class="category">Data range</th>';
 
 foreach ( $this->data['summaryDataset'] as $key => $value ) {
diff --git a/modules/statistics/www/showstats.php b/modules/statistics/www/showstats.php
index 20ef8c4c83fbab8496e5e62e2840804ff61101bb..a46882b04f72813480c5c98d24c273254238901c 100644
--- a/modules/statistics/www/showstats.php
+++ b/modules/statistics/www/showstats.php
@@ -111,7 +111,9 @@ SimpleSAML_Module::callHooks('htmlinject', $hookinfo);
 $t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics-tpl.php');
 $t->data['header'] = 'stat';
 $t->data['imgurl'] = $grapher->show($axis['axis'], $axis['axispos'], $datasets, $max);
-$t->data['pieimgurl'] = $grapher->showPie( $dataset->getDelimiterPresentationPie(), $piedata);
+if (isset($piedata)) {
+	$t->data['pieimgurl'] = $grapher->showPie( $dataset->getDelimiterPresentationPie(), $piedata);
+}
 $t->data['available.rules'] = $ruleset->availableRulesNames();
 $t->data['available.times'] = $statrule->availableFileSlots($timeres);
 $t->data['available.timeres'] = $statrule->availableTimeRes();