diff --git a/bin/build-release.sh b/bin/build-release.sh
index 7b34442bdaa4196ef899d2827dc484a12f22208e..b2a7d89de7f4f9f75e13104fc520d0c137ac755d 100755
--- a/bin/build-release.sh
+++ b/bin/build-release.sh
@@ -65,6 +65,7 @@ php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-
 php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-oauth
 php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-radius
 php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-riak
+php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-statistics
 
 cd $TARGET
 npm install
diff --git a/composer.json b/composer.json
index 5bef068eb96365c118092dcbf28f0d48fb892a95..8d6989139e427327f9177c4936cc7fa938f3a974 100644
--- a/composer.json
+++ b/composer.json
@@ -65,6 +65,7 @@
         "simplesamlphp/simplesamlphp-module-oauth": "^1.0",
         "simplesamlphp/simplesamlphp-module-radius": "^1.0.0",
         "simplesamlphp/simplesamlphp-module-riak": "^1.0.0",
+        "simplesamlphp/simplesamlphp-module-statistics": "^1.0.0",
         "symfony/routing": "^3.4 || ^4.0",
         "symfony/http-foundation": "^3.4 || ^4.0",
         "symfony/config": "^3.4 || ^4.0",
diff --git a/modules/statistics/bin/loganalyzer.php b/modules/statistics/bin/loganalyzer.php
deleted file mode 100755
index 81e3d698a13114d12706d41086b83df988cc8d12..0000000000000000000000000000000000000000
--- a/modules/statistics/bin/loganalyzer.php
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-// This is the base directory of the SimpleSAMLphp installation
-$baseDir = dirname(dirname(dirname(dirname(__FILE__))));
-
-// Add library autoloader.
-require_once($baseDir.'/lib/_autoload.php');
-
-// Initialize the configuration.
-$configdir = \SimpleSAML\Utils\Config::getConfigDir();
-\SimpleSAML\Configuration::setConfigDir($configdir);
-\SimpleSAML\Utils\Time::initTimezone();
-
-$progName = array_shift($argv);
-$debug = false;
-$dryrun = false;
-
-foreach ($argv as $a) {
-    if (strlen($a) === 0) {
-        continue;
-    }
-    if (strpos($a, '=') !== false) {
-        $p = strpos($a, '=');
-        $v = substr($a, $p + 1);
-        $a = substr($a, 0, $p);
-    } else {
-        $v = null;
-    }
-
-    // Map short options to long options.
-    $shortOptMap = ['-d' => '--debug'];
-    if (array_key_exists($a, $shortOptMap)) {
-        $a = $shortOptMap[$a];
-    }
-    switch ($a) {
-        case '--help':
-            printHelp();
-            exit(0);
-        case '--debug':
-            $debug = true;
-            break;
-        case '--dry-run':
-            $dryrun = true;
-            break;
-        default:
-            echo 'Unknown option: '.$a."\n";
-            echo 'Please run `'.$progName.' --help` for usage information.'."\n";
-            exit(1);
-    }
-}
-
-$aggregator = new \SimpleSAML\Module\statistics\Aggregator(true);
-$aggregator->dumpConfig();
-$aggregator->debugInfo();
-$results = $aggregator->aggregate($debug);
-$aggregator->debugInfo();
-
-if (!$dryrun) {
-    $aggregator->store($results);
-}
-
-foreach ($results as $slot => $val) {
-    foreach ($val as $sp => $no) {
-        echo $sp." ".count($no)." - ";
-    }
-    echo "\n";
-}
-
-
-/**
- * This function prints the help output.
- * @return void
- */
-function printHelp()
-{
-    global $progName;
-
-    echo <<<END
-Usage: $progName [options]
-
-This program parses and aggregates SimpleSAMLphp log files.
-
-Options:
- -d, --debug			Used when configuring the log file syntax. See doc.
- --dry-run			Aggregate but do not store the results.
-END;
-}
diff --git a/modules/statistics/bin/logcleaner.php b/modules/statistics/bin/logcleaner.php
deleted file mode 100755
index 18432cf3852050d251fa8ba061bb6b611f2cd997..0000000000000000000000000000000000000000
--- a/modules/statistics/bin/logcleaner.php
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-// This is the base directory of the SimpleSAMLphp installation
-$baseDir = dirname(dirname(dirname(dirname(__FILE__))));
-
-// Add library autoloader.
-require_once($baseDir.'/lib/_autoload.php');
-
-// Initialize the configuration.
-$configdir = \SimpleSAML\Utils\Config::getConfigDir();
-\SimpleSAML\Configuration::setConfigDir($configdir);
-
-$progName = array_shift($argv);
-$debug = false;
-$dryrun = false;
-$output = '/tmp/simplesamlphp-new.log';
-$infile = null;
-
-foreach ($argv as $a) {
-    if (strlen($a) === 0) {
-        continue;
-    }
-    if (strpos($a, '=') !== false) {
-        $p = strpos($a, '=');
-        $v = substr($a, $p + 1);
-        $a = substr($a, 0, $p);
-    } else {
-        $v = null;
-    }
-
-    // Map short options to long options.
-    $shortOptMap = ['-d' => '--debug'];
-    if (array_key_exists($a, $shortOptMap)) {
-        $a = $shortOptMap[$a];
-    }
-
-    switch ($a) {
-        case '--help':
-            printHelp();
-            exit(0);
-        case '--debug':
-            $debug = true;
-            break;
-        case '--dry-run':
-            $dryrun = true;
-            break;
-        case '--infile':
-            $infile = $v;
-            break;
-        case '--outfile':
-            $output = $v;
-            break;
-        default:
-            echo 'Unknown option: '.$a."\n";
-            echo 'Please run `'.$progName.' --help` for usage information.'."\n";
-            exit(1);
-    }
-}
-
-$cleaner = new \SimpleSAML\Module\statistics\LogCleaner($infile);
-$cleaner->dumpConfig();
-$todelete = $cleaner->clean($debug);
-
-echo "Cleaning these trackIDs: ".join(', ', $todelete)."\n";
-
-if (!$dryrun) {
-    $cleaner->store($todelete, $output);
-}
-
-/**
- * This function prints the help output.
- * @return void
- */
-function printHelp()
-{
-    global $progName;
-
-    echo <<<END
-Usage: $progName [options]
-
-This program cleans logs. This script is experimental. Do not run it unless you have talked to Andreas about it. 
-The script deletes log lines related to sessions that produce more than 200 lines.
-
-Options:
-	-d, --debug			Used when configuring the log file syntax. See doc.
-	--dry-run			Aggregate but do not store the results.
-	--infile			File input.
-	--outfile			File to output the results.
-
-END;
-}
diff --git a/modules/statistics/config-templates/module_statistics.php b/modules/statistics/config-templates/module_statistics.php
deleted file mode 100644
index 9e186dc2908f65297a74825e8c03e830fee1fe84..0000000000000000000000000000000000000000
--- a/modules/statistics/config-templates/module_statistics.php
+++ /dev/null
@@ -1,190 +0,0 @@
-<?php
-/*
- * The configuration of SimpleSAMLphp statistics package
- */
-
-$config = [
-    // Authentication & authorization for statistics
-
-    // Whether the statistics require authentication before use.
-    'protected' => false,
-
-    // The authentication source that should be used.
-    'auth' => 'admin',
-
-    // Alternative 1: List of allowed users.
-    //'useridattr' => 'eduPersonPrincipalName',
-    //'allowedUsers' => array('andreas@uninett.no', 'ola.normann@sp.example.org'),
-
-    // Alternative 2: External ACL list.
-    //'acl' => 'adminlist',
-
-    'default' => 'sso',
-
-    'statdir' => '/tmp/stats/',
-    'inputfile' => '/var/log/simplesamlphp.stat',
-    'offset' => 60 * 60 * 2 + 60 * 60 * 24 * 3, // Two hours offset to match epoch and norwegian winter time.
-
-    'datestart' => 1,
-    'datelength' => 15,
-    'offsetspan' => 21,
-
-    // Dimensions on graph from Google Charts in pixels...
-    'dimension.x' => 800,
-    'dimension.y' => 350,
-
-    /*
-     * Do you want to generate statistics using the cron module? If so, specify which cron tag to use.
-     * Examples: daily, weekly
-     * To not run statistics in cron, set value to
-     *     'cron_tag' => null,
-     */
-    'cron_tag' => 'daily',
-
-    /*
-     * Set max running time for this script. This is also controlled by max_execution_time in php.ini
-     * and is set to 30 sec by default. Your web server can have other timeout configurations that may
-     * also interrupt PHP execution. Apache has a Timeout directive and IIS has a
-     * CGI timeout function. Both default to 300 seconds.
-     */
-    'time_limit' => 300,
-
-    'timeres' => [
-        'day' => [
-            'name' => 'Day',
-            'slot'              => 60 * 15, // Slots of 15 minutes
-            'fileslot'          => 60 * 60 * 24, // One day (24 hours) file slots
-            'axislabelint'      => 6 * 4, // Number of slots per label. 4 per hour *6 = 6 hours
-            'dateformat-period' => 'j. M', //  4. Mars
-            'dateformat-intra'  => 'j. M H:i', //  4. Mars 12:30
-        ],
-        'week' => [
-            'name' => 'Week',
-            'slot'              => 60 * 60, // Slots of one hour
-            'fileslot'          => 60 * 60 * 24 * 7, // 7 days of data in each file
-            'axislabelint'      => 24, // Number of slots per label. 24 is one each day
-            'dateformat-period' => 'j. M', //  4. Mars
-            'dateformat-intra'  => 'j. M H:i', //  4. Mars 12:30
-        ],
-        'month' => [
-            'name' => 'Month',
-            'slot'              => 60 * 60 * 24, // Slots of one day
-            'fileslot'          => 60 * 60 * 24 * 30, // 30 days of data in each file
-            'axislabelint'      => 7, // Number of slots per label. 7 days => 1 week
-            'dateformat-period' => 'j. M Y H:i', //  4. Mars 12:30
-            'dateformat-intra'  => 'j. M', //  4. Mars
-        ],
-        'monthaligned' => [
-            'name'              => 'AlignedMonth',
-            'slot'              => 60 * 60 * 24, // Slots of one day
-            'fileslot'          => null, // 30 days of data in each file
-            'customDateHandler' => 'month',
-            'axislabelint'      => 7, // Number of slots per label. 7 days => 1 week
-            'dateformat-period' => 'j. M Y H:i', //  4. Mars 12:30
-            'dateformat-intra'  => 'j. M', //  4. Mars
-        ],
-        'days180' => [
-            'name'              => '180 days',
-            'slot'              => 60 * 60 * 24, // Slots of 1 day (24 hours)
-            'fileslot'          => 60 * 60 * 24 * 180, // 80 days of data in each file
-            'axislabelint'      => 30, // Number of slots per label. 7 days => 1 week
-            'dateformat-period' => 'j. M', //  4. Mars
-            'dateformat-intra'  => 'j. M', //  4. Mars
-        ],
-    ],
-
-    'statrules' => [
-        'sloratio' => [
-            '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'          => ['slo', 'sso'],
-            'fieldPresentation' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-        'ssomulti' => [
-            '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'          => ['sso', 'ssofirst'],
-            'fieldPresentation' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-        'sso' => [
-            'name'         => 'SSO to service',
-            'descr'        => 'The number of logins at a Service Provider.',
-            'action'       => 'saml20-idp-SSO',
-            'col'          => 6, // Service Provider EntityID
-            'fieldPresentation' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-        'ssofirst' => [
-            'name'         => 'SSO-first to service',
-            'descr'        => 'The number of logins at a Service Provider.',
-            'action'       => 'saml20-idp-SSO-first',
-            'col'          => 6, // Service Provider EntityID
-            'fieldPresentation' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-        'slo' => [
-            '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' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-        'consent' => [
-            'name'         => 'Consent',
-            'descr'        => 'Consent statistics. Everytime a user logs in to a service an entry is logged for'.
-                ' one of three states: consent was found, consent was not found or consent storage was not available.',
-            'action'       => 'consent',
-            'col'          => 6,
-            'fieldPresentation' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-        'consentresponse' => [
-            'name'         => 'Consent response',
-            'descr'        => 'Consent response statistics. Everytime a user accepts consent,'.
-                ' it is logged whether the user selected to remember the consent to next time.',
-            'action'       => 'consentResponse',
-            'col'          => 6,
-            'fieldPresentation' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-        'slopages' => [
-            'name'         => 'SLO iframe pages',
-            'descr'        => 'The varioust IFrame SLO pages a user visits',
-            'action'       => 'slo-iframe',
-            'col'          => 6, // Page the user visits.
-        ],
-        'slofail' => [
-            'name'         => 'Failed iframe IdP-init SLOs',
-            'descr'        => 'The number of logout failures from various SPs',
-            'action'       => 'slo-iframe-fail',
-            'col'          => 6, // Service Provider EntityID that wasn't logged out.
-            'fieldPresentation' => [
-                'class'    => 'statistics:Entity',
-                'config'   => 'saml20-sp-remote',
-            ],
-        ],
-    ],
-];
diff --git a/modules/statistics/default-disable b/modules/statistics/default-disable
deleted file mode 100644
index fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f..0000000000000000000000000000000000000000
--- a/modules/statistics/default-disable
+++ /dev/null
@@ -1,3 +0,0 @@
-This file indicates that the default state of this module
-is disabled. To enable, create a file named enable in the
-same directory as this file.
diff --git a/modules/statistics/dictionaries/statistics.definition.json b/modules/statistics/dictionaries/statistics.definition.json
deleted file mode 100644
index 065b7b4d386391ae247300b09bd6c249172ea039..0000000000000000000000000000000000000000
--- a/modules/statistics/dictionaries/statistics.definition.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "link_statistics": {
-    "en": "Show statistics"
-  },
-  "link_statistics_metadata": {
-    "en": "Show statistics metadata"
-  }
-}
\ No newline at end of file
diff --git a/modules/statistics/dictionaries/statistics.translation.json b/modules/statistics/dictionaries/statistics.translation.json
deleted file mode 100644
index 7a4adb1eac0e76cc9c663a958a925be135ca316f..0000000000000000000000000000000000000000
--- a/modules/statistics/dictionaries/statistics.translation.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "link_statistics": {
-    "es": "Mostrar estadĂ­sticas",
-    "no": "Vis statistikker",
-    "nn": "Vis statistikkar",
-    "ca": "Mostra les estadĂ­stiques"
-  },
-  "link_statistics_metadata": {
-    "es": "Mostrar metadatos de las estadĂ­sticas",
-    "no": "Vis metadata om statistikker",
-    "nn": "Vis metadata om statistikkar",
-    "ca": "Mostra les estadĂ­stiques de les metadades"
-  }
-}
diff --git a/modules/statistics/docs/statistics.md b/modules/statistics/docs/statistics.md
deleted file mode 100644
index 07d7e40c44f997347b688da3fb30a36e70a6d907..0000000000000000000000000000000000000000
--- a/modules/statistics/docs/statistics.md
+++ /dev/null
@@ -1,129 +0,0 @@
-The SimpleSAMLphp statistics module
-===================================
-
-
-<!-- 
-	This file is written in Markdown syntax. 
-	For more information about how to use the Markdown syntax, read here:
-	http://daringfireball.net/projects/markdown/syntax
--->
-
-  * Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
-
-
-## Configure your logs
-
-It's recommended to use syslog for logging, then a separate log level is
-dedicated to statistics. You need to get all statistics log entries
-in one log file. Here is how I do it in syslog.conf:
-
-    # SimpleSAMLphp logging
-    local5.*                        /var/log/simplesamlphp.log
-    # Notice level is reserved for statistics only...
-    local5.=notice                  /var/log/simplesamlphp.stat
-
-Then make sure you have configured this correctly such that you
-have one log file like this:
-
-    # ls -la /var/log/simplesamlphp.stat
-    -rw-r--r-- 1 root root 76740 Nov 15 13:37 /var/log/simplesamlphp.stat
-
-With content that looks like this:
-
-    # tail /var/log/simplesamlphp.stat
-    Nov 15 12:01:49 www1 simplesamlphp-foodle[31960]: 5 STAT [77013b4b6e] saml20-sp-SSO urn:mace:feide.no:services:no.feide.foodle sam.feide.no andreas@uninett.no
-    Nov 15 13:01:14 www1 simplesamlphp-openwiki[2247]: 5 STAT [50292b9d04] saml20-sp-SSO urn:mace:feide.no:services:no.feide.openwikicore sam.feide.no NA
-    Nov 15 13:16:39 www1 simplesamlphp-openwiki[2125]: 5 STAT [3493d5d87f] saml20-sp-SSO urn:mace:feide.no:services:no.feide.openwikicore sam.feide.no NA
-    Nov 15 13:37:27 www1 simplesamlphp-foodle[3146]: 5 STAT [77013b4b6e] AUTH-login-admin OK
-
-Here you can see that I collect statistics in one file for several installations. You could easily separate each instance of SimpleSAMLphp into separate files (your preference).
-
-## Configure the statistics module
-
-First enable the statistics module, as you enable any other module:
-
-    cd modules/statistics
-    touch enable
-
-Then take the configuration template:
-
-    cp modules/statistics/config-templates/*.php config/
-
-Configure the path of the log file:
-
-    'inputfile' => '/var/log/simplesamlphp.stat',
-
-Make sure the stat dir is writable. SimpleSAMLphp will write data here:
-
-    'statdir' => '/var/lib/simplesamlphp/stats/',
-
-### Configuring the syntax of the logfile
-
-Syslog uses different date formats on different environments, so you need to do some manual tweaking to make sure that SimpleSAMLphp knows how to interpret the logs.
-
-There are three parameter values you need to make sure are correct.
-
-	'datestart'  => 1,
-	'datelength' => 15,
-	'offsetspan' => 21,
-
-The first `datestart` is 1 when the date starts from the beginning of the line. The `datelength` parameter tells how many characters long the date is.
-
-The `offsetspan` parameter shows on which character the first column starts, such that the STAT keyword becomes column number 3.
-
-Use the `loganalyzer` script with the `--debug` parameter to debug whether your configuration is correct. If not, then it easy to see what is wrong, for example if the STAT keyword is not in column 3.
-
-Here is some example output:
-
-
-	$ cd modules/statistics/bin
-	$ ./loganalyzer.php --debug
-	Statistics directory   : /var/lib/simplesamlphp/stats/
-	Input file             : /Users/andreas/Desktop/simplesamlphp.log
-	Offset                 : 4237200
-	----------------------------------------
-	Log line: Feb 11 11:32:57 moria-app1 syslog_moria-app1[6630]: 5 STAT [2d41ee3f1e] AUTH-login-admin Failed
-	Date parse [Feb 11 11:32:57] to [Wed, 11 Feb 09 11:32:57 +0100]
-	Array
-	(
-		[0] => moria-app1
-		[1] => syslog_moria-app1[6630]:
-		[2] => 5
-		[3] => STAT
-		[4] => [2d41ee3f1e]
-		[5] => AUTH-login-admin
-		[6] => Failed
-	)
-
-In the debug output, please verify four things:
-
- 1. That the first field in the date parse line contains all the characters that are part of the timestamp, compared with the log line on the line above.
- 2. Verify that the second field in the date parse line is correct: corresponding to the input timestamp.
- 3. That the first `[0]` field contains all the characters from the first column.
- 4. That column `[3]` is STAT.
-
-
-### Setup cron
-
-You also should setup the cron module:
-
-    cd modules/cron
-    touch enable
-
-### Alternative to using the cron module
-
-As an alternative to using the cron module you can run the
-script `statistics/bin/loganalyzer.php` manually.
-
-## Presentation of the statistics
-
-At the Installation page there will be a link "show statistics", go there and if SimpleSAMLphp finds the statistics files in the `statdir` generated from cron or the script you will see statistics. Enjoy.
-
-Support
--------
-
-If you need help to make this work, or want to discuss SimpleSAMLphp with other users of the software, you are fortunate: Around SimpleSAMLphp there is a great Open source community, and you are welcome to join! The forums are open for you to ask questions, contribute answers other further questions, request improvements or contribute with code or plugins of your own.
-
--  [SimpleSAMLphp homepage](http://simplesamlphp.org)
--  [List of all available SimpleSAMLphp documentation](http://simplesamlphp.org/docs/stable/)
--  [Join the SimpleSAMLphp user's mailing list](http://simplesamlphp.org/lists)
diff --git a/modules/statistics/hooks/hook_configpage.php b/modules/statistics/hooks/hook_configpage.php
deleted file mode 100644
index 36853ed2d1f986e979fced5601c7f01c9c2eada3..0000000000000000000000000000000000000000
--- a/modules/statistics/hooks/hook_configpage.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-
-/**
- * Hook to add the statistics module to the config page.
- *
- * @param \SimpleSAML\XHTML\Template &$template The template that we should alter in this hook.
- * @return void
- */
-function statistics_hook_configpage(\SimpleSAML\XHTML\Template &$template)
-{
-    $template->data['links']['statistics'] = [
-        'href' => SimpleSAML\Module::getModuleURL('statistics/showstats.php'),
-        'text' => \SimpleSAML\Locale\Translate::noop('Show statistics'),
-    ];
-    $template->data['links']['statisticsmeta'] = [
-        'href' => SimpleSAML\Module::getModuleURL('statistics/statmeta.php'),
-        'text' => \SimpleSAML\Locale\Translate::noop('Show statistics metadata'),
-    ];
-    $template->getLocalization()->addModuleDomain('statistics');
-}
diff --git a/modules/statistics/hooks/hook_cron.php b/modules/statistics/hooks/hook_cron.php
deleted file mode 100644
index f0de516faf163b78c5e35004807c743ebc5705aa..0000000000000000000000000000000000000000
--- a/modules/statistics/hooks/hook_cron.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * Hook to run a cron job.
- *
- * @param array &$croninfo  Output
- * @return void
- */
-function statistics_hook_cron(&$croninfo)
-{
-    assert(is_array($croninfo));
-    assert(array_key_exists('summary', $croninfo));
-    assert(array_key_exists('tag', $croninfo));
-
-    $statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
-
-    if (is_null($statconfig->getValue('cron_tag', null))) {
-        return;
-    }
-    if ($statconfig->getValue('cron_tag', null) !== $croninfo['tag']) {
-        return;
-    }
-
-    $maxtime = $statconfig->getInteger('time_limit', null);
-    if ($maxtime) {
-        set_time_limit($maxtime);
-    }
-
-    try {
-        $aggregator = new \SimpleSAML\Module\statistics\Aggregator();
-        $results = $aggregator->aggregate();
-        if (empty($results)) {
-            \SimpleSAML\Logger::notice('Output from statistics aggregator was empty.');
-        } else {
-            $aggregator->store($results);
-        }
-    } catch (\Exception $e) {
-        $message = 'Loganalyzer threw exception: '.$e->getMessage();
-        \SimpleSAML\Logger::warning($message);
-        $croninfo['summary'][] = $message;
-    }
-}
diff --git a/modules/statistics/hooks/hook_frontpage.php b/modules/statistics/hooks/hook_frontpage.php
deleted file mode 100644
index bb4e934179a781a213bd886286916190f09b0d6d..0000000000000000000000000000000000000000
--- a/modules/statistics/hooks/hook_frontpage.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * Hook to add the modinfo module to the frontpage.
- *
- * @param array &$links  The links on the frontpage, split into sections.
- * @return void
- */
-function statistics_hook_frontpage(&$links)
-{
-    assert(is_array($links));
-    assert(array_key_exists('links', $links));
-
-    $links['config']['statistics'] = [
-        'href' => SimpleSAML\Module::getModuleURL('statistics/showstats.php'),
-        'text' => '{statistics:statistics:link_statistics}',
-    ];
-    $links['config']['statisticsmeta'] = [
-        'href' => SimpleSAML\Module::getModuleURL('statistics/statmeta.php'),
-        'text' => '{statistics:statistics:link_statistics_metadata}',
-        'shorttext' => ['en' => 'Statistics metadata', 'no' => 'Statistikk metadata'],
-    ];
-}
-
diff --git a/modules/statistics/hooks/hook_sanitycheck.php b/modules/statistics/hooks/hook_sanitycheck.php
deleted file mode 100644
index 398266ca83659c455404a9856f6264a651971e11..0000000000000000000000000000000000000000
--- a/modules/statistics/hooks/hook_sanitycheck.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * Hook to do sanity checks
- *
- * @param array &$hookinfo  hookinfo
- * @return void
- */
-function statistics_hook_sanitycheck(&$hookinfo)
-{
-    assert(is_array($hookinfo));
-    assert(array_key_exists('errors', $hookinfo));
-    assert(array_key_exists('info', $hookinfo));
-
-    try {
-        $statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
-    } catch (Exception $e) {
-        $hookinfo['errors'][] = '[statistics] Could not get configuration: '.$e->getMessage();
-        return;
-    }
-
-    $statdir = $statconfig->getValue('statdir');
-    $inputfile = $statconfig->getValue('inputfile');
-
-    if (file_exists($statdir)) {
-        $hookinfo['info'][] = '[statistics] Statistics dir ['.$statdir.'] exists';
-        if (is_writable($statdir)) {
-            $hookinfo['info'][] = '[statistics] Statistics dir ['.$statdir.'] is writable';
-        } else {
-            $hookinfo['errors'][] = '[statistics] Statistics dir ['.$statdir.'] is not writable';
-        }
-    } else {
-        $hookinfo['errors'][] = '[statistics] Statistics dir ['.$statdir.'] does not exist';
-    }
-
-    if (file_exists($inputfile)) {
-        $hookinfo['info'][] = '[statistics] Input file ['.$inputfile.'] exists';
-    } else {
-        $hookinfo['errors'][] = '[statistics] Input file ['.$inputfile.'] does not exist';
-    }
-}
diff --git a/modules/statistics/lib/AccessCheck.php b/modules/statistics/lib/AccessCheck.php
deleted file mode 100644
index 8750714415e647f8e7550c21e3e6ae1c477c06e8..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/AccessCheck.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/**
- * Class implementing the access checker function for the statistics module.
- *
- * @package SimpleSAMLphp
- */
-class AccessCheck
-{
-    /**
-     * Check that the user has access to the statistics.
-     * If the user doesn't have access, send the user to the login page.
-     *
-     * @param \SimpleSAML\Configuration $statconfig
-     * @return void
-     * @throws \Exception
-     * @throws \SimpleSAML\Error\Exception
-     */
-    public static function checkAccess(\SimpleSAML\Configuration $statconfig)
-    {
-        $protected = $statconfig->getBoolean('protected', false);
-        $authsource = $statconfig->getString('auth', null);
-        $allowedusers = $statconfig->getValue('allowedUsers', null);
-        $useridattr = $statconfig->getString('useridattr', 'eduPersonPrincipalName');
-
-        $acl = $statconfig->getValue('acl', null);
-        if ($acl !== null && !is_string($acl) && !is_array($acl)) {
-            throw new \SimpleSAML\Error\Exception('Invalid value for \'acl\'-option. Should be an array or a string.');
-        }
-
-        if (!$protected) {
-            return;
-        }
-
-        if (\SimpleSAML\Utils\Auth::isAdmin()) {
-            // User logged in as admin. OK.
-            \SimpleSAML\Logger::debug('Statistics auth - logged in as admin, access granted');
-            return;
-        }
-
-        if (!isset($authsource)) {
-            // If authsource is not defined, init admin login.
-            \SimpleSAML\Utils\Auth::requireAdmin();
-        }
-
-        // We are using an authsource for login.
-
-        $as = new \SimpleSAML\Auth\Simple($authsource);
-        $as->requireAuth();
-
-        // User logged in with auth source.
-        \SimpleSAML\Logger::debug('Statistics auth - valid login with auth source ['.$authsource.']');
-
-        // Retrieving attributes
-        $attributes = $as->getAttributes();
-
-        if (!empty($allowedusers)) {
-            // Check if userid exists
-            if (!isset($attributes[$useridattr][0])) {
-                throw new \Exception('User ID is missing');
-            }
-
-            // Check if userid is allowed access..
-            if (in_array($attributes[$useridattr][0], $allowedusers, true)) {
-                \SimpleSAML\Logger::debug(
-                    'Statistics auth - User granted access by user ID ['.$attributes[$useridattr][0].']'
-                );
-                return;
-            }
-            \SimpleSAML\Logger::debug(
-                'Statistics auth - User denied access by user ID ['.$attributes[$useridattr][0].']'
-            );
-        } else {
-            \SimpleSAML\Logger::debug('Statistics auth - no allowedUsers list.');
-        }
-
-        if (!is_null($acl)) {
-            $acl = new \SimpleSAML\Module\core\ACL($acl);
-            if ($acl->allows($attributes)) {
-                \SimpleSAML\Logger::debug('Statistics auth - allowed access by ACL.');
-                return;
-            }
-            \SimpleSAML\Logger::debug('Statistics auth - denied access by ACL.');
-        } else {
-            \SimpleSAML\Logger::debug('Statistics auth - no ACL configured.');
-        }
-        throw new \SimpleSAML\Error\Exception('Access denied to the current user.');
-    }
-}
diff --git a/modules/statistics/lib/Aggregator.php b/modules/statistics/lib/Aggregator.php
deleted file mode 100644
index dc311d4d4d4c8eb66365261f9a62d5577f298050..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/Aggregator.php
+++ /dev/null
@@ -1,372 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class Aggregator
-{
-    /** @var \SimpleSAML\Configuration */
-    private $statconfig;
-
-    /** @var string */
-    private $statdir;
-
-    /** @var string */
-    private $inputfile;
-
-    /** @var array */
-    private $statrules;
-
-    /** @var int */
-    private $offset;
-
-    /** @var array|null */
-    private $metadata = null;
-
-    /** @var bool */
-    private $fromcmdline;
-
-    /** @var int */
-    private $starttime;
-
-    /** @var array */
-    private $timeres;
-
-
-    /**
-     * Constructor
-     *
-     * @param bool $fromcmdline
-     */
-    public function __construct($fromcmdline = false)
-    {
-        $this->fromcmdline = $fromcmdline;
-        $this->statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
-
-        $this->statdir = $this->statconfig->getValue('statdir');
-        $this->inputfile = $this->statconfig->getValue('inputfile');
-        $this->statrules = $this->statconfig->getValue('statrules');
-        $this->timeres = $this->statconfig->getValue('timeres');
-        $this->offset = $this->statconfig->getValue('offset', 0);
-
-        $this->starttime = time();
-    }
-
-
-    /**
-     * @return void
-     */
-    public function dumpConfig()
-    {
-        echo 'Statistics directory   : '.$this->statdir."\n";
-        echo 'Input file             : '.$this->inputfile."\n";
-        echo 'Offset                 : '.$this->offset."\n";
-    }
-
-
-    /**
-     * @return void
-     */
-    public function debugInfo()
-    {
-        echo 'Memory usage           : '.number_format(memory_get_usage() / 1048576, 2)." MB\n"; // 1024*1024=1048576
-    }
-
-
-    /**
-     * @return void
-     */
-    public function loadMetadata()
-    {
-        $filename = $this->statdir.'/.stat.metadata';
-        $metadata = null;
-        if (file_exists($filename)) {
-            $metadata = unserialize(file_get_contents($filename));
-        }
-        $this->metadata = $metadata;
-    }
-
-
-    /**
-     * @return array|null
-     */
-    public function getMetadata()
-    {
-        return $this->metadata;
-    }
-
-
-    /**
-     * @return void
-     */
-    public function saveMetadata()
-    {
-        $this->metadata['time'] = time() - $this->starttime;
-        $this->metadata['memory'] = memory_get_usage();
-        $this->metadata['lastrun'] = time();
-
-        $filename = $this->statdir.'/.stat.metadata';
-        file_put_contents($filename, serialize($this->metadata), LOCK_EX);
-    }
-
-
-    /**
-     * @param bool $debug
-     * @return array
-     * @throws \Exception
-     */
-    public function aggregate($debug = false)
-    {
-        $this->loadMetadata();
-
-        if (!is_dir($this->statdir)) {
-            throw new \Exception('Statistics module: output dir do not exists ['.$this->statdir.']');
-        }
-
-        if (!file_exists($this->inputfile)) {
-            throw new \Exception('Statistics module: input file do not exists ['.$this->inputfile.']');
-        }
-
-        $file = fopen($this->inputfile, 'r');
-
-        if ($file === false) {
-            throw new \Exception('Statistics module: unable to open file ['.$this->inputfile.']');
-        }
-
-        $logparser = new LogParser(
-            $this->statconfig->getValue('datestart', 0),
-            $this->statconfig->getValue('datelength', 15),
-            $this->statconfig->getValue('offsetspan', 44)
-        );
-        $datehandler = [
-            'default' => new DateHandler($this->offset),
-            'month' => new  DateHandlerMonth($this->offset),
-        ];
-
-        $notBefore = 0;
-        $lastRead = 0;
-        $lastlinehash = '-';
-
-        if (isset($this->metadata)) {
-            $notBefore = $this->metadata['notBefore'];
-            $lastlinehash = $this->metadata['lastlinehash'];
-        }
-
-        $lastlogline = 'sdfsdf';
-        $lastlineflip = false;
-        $results = [];
-
-        $i = 0;
-        // Parse through log file, line by line
-        while (!feof($file)) {
-            $logline = fgets($file, 4096);
-
-            // Continue if STAT is not found on line
-            if (!preg_match('/STAT/', $logline)) {
-                continue;
-            }
-
-            $i++;
-            $lastlogline = $logline;
-
-            // Parse log, and extract epoch time and rest of content.
-            $epoch = $logparser->parseEpoch($logline);
-            $content = $logparser->parseContent($logline);
-            $action = trim($content[5]);
-
-            if ($this->fromcmdline && ($i % 10000) == 0) {
-                echo "Read line ".$i."\n";
-            }
-
-            if ($debug) {
-                echo "----------------------------------------\n";
-                echo 'Log line: '.$logline."\n";
-                echo 'Date parse ['.substr($logline, 0, $this->statconfig->getValue('datelength', 15)).
-                    '] to ['.date(DATE_RFC822, $epoch).']'."\n";
-                echo htmlentities(print_r($content, true));
-                if ($i >= 13) {
-                    exit;
-                }
-            }
-
-            if ($epoch > $lastRead) {
-                $lastRead = $epoch;
-            }
-
-            if ($epoch === $notBefore) {
-                if (!$lastlineflip) {
-                    if (sha1($logline) === $lastlinehash) {
-                        $lastlineflip = true;
-                    }
-                    continue;
-                }
-            }
-
-            if ($epoch < $notBefore) {
-                continue;
-            }
-
-            // 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) {
-                    $dh = 'default';
-                    if (isset($tresconfig['customDateHandler'])) {
-                        $dh = $tresconfig['customDateHandler'];
-                    }
-
-                    $timeslot = $datehandler['default']->toSlot($epoch, $tresconfig['slot']);
-                    $fileslot = $datehandler[$dh]->toSlot($epoch, $tresconfig['fileslot']);
-
-                    if (isset($rule['action']) && ($action !== $rule['action'])) {
-                        continue;
-                    }
-
-                    $difcol = self::getDifCol($content, $rule['col']);
-
-                    if (!isset($results[$rulename][$tres][$fileslot][$timeslot]['_'])) {
-                        $results[$rulename][$tres][$fileslot][$timeslot]['_'] = 0;
-                    }
-                    if (!isset($results[$rulename][$tres][$fileslot][$timeslot][$difcol])) {
-                        $results[$rulename][$tres][$fileslot][$timeslot][$difcol] = 0;
-                    }
-
-                    $results[$rulename][$tres][$fileslot][$timeslot]['_']++;
-                    $results[$rulename][$tres][$fileslot][$timeslot][$difcol]++;
-                }
-            }
-        }
-        $this->metadata['notBefore'] = $lastRead;
-        $this->metadata['lastline'] = $lastlogline;
-        $this->metadata['lastlinehash'] = sha1($lastlogline);
-        return $results;
-    }
-
-
-    /**
-     * @param array $content
-     * @param mixed $colrule
-     * @return string
-     */
-    private static function getDifCol($content, $colrule)
-    {
-        if (is_int($colrule)) {
-            return trim($content[$colrule]);
-        } elseif (is_array($colrule)) {
-            $difcols = [];
-            foreach ($colrule as $cr) {
-                $difcols[] = trim($content[$cr]);
-            }
-            return join('|', $difcols);
-        } else {
-            return 'NA';
-        }
-    }
-
-
-    /**
-     * @param mixed $previous
-     * @param array $newdata
-     * @return array
-     */
-    private function cummulateData($previous, $newdata)
-    {
-        $dataset = [];
-        foreach (func_get_args() as $item) {
-            foreach ($item as $slot => $dataarray) {
-                if (!array_key_exists($slot, $dataset)) {
-                    $dataset[$slot] = [];
-                }
-                foreach ($dataarray as $key => $data) {
-                    if (!array_key_exists($key, $dataset[$slot])) {
-                        $dataset[$slot][$key] = 0;
-                    }
-                    $dataset[$slot][$key] += $data;
-                }
-            }
-        }
-        return $dataset;
-    }
-
-
-    /**
-     * @param array $results
-     * @return void
-     */
-    public function store($results)
-    {
-        $datehandler = [
-            'default' => new DateHandler($this->offset),
-            'month' => new DateHandlerMonth($this->offset),
-        ];
-
-        // Iterate the first level of results, which is per rule, as defined in the config.
-        foreach ($results as $rulename => $timeresdata) {
-            // Iterate over time resolutions
-            foreach ($timeresdata as $tres => $resres) {
-                $dh = 'default';
-                if (isset($this->timeres[$tres]['customDateHandler'])) {
-                    $dh = $this->timeres[$tres]['customDateHandler'];
-                }
-
-                $filenos = array_keys($resres);
-                $lastfile = $filenos[count($filenos) - 1];
-
-                // Iterate the second level of results, which is the fileslot.
-                foreach ($resres as $fileno => $fileres) {
-                    // Slots that have data.
-                    $slotlist = array_keys($fileres);
-
-                    // The last slot.
-                    $maxslot = $slotlist[count($slotlist) - 1];
-
-                    // Get start and end slot number within the file, based on the fileslot.
-                    $start = (int) $datehandler['default']->toSlot(
-                        $datehandler[$dh]->fromSlot($fileno, $this->timeres[$tres]['fileslot']),
-                        $this->timeres[$tres]['slot']
-                    );
-                    $end = (int) $datehandler['default']->toSlot(
-                        $datehandler[$dh]->fromSlot($fileno + 1, $this->timeres[$tres]['fileslot']),
-                        $this->timeres[$tres]['slot']
-                    );
-
-                    // Fill in missing entries and sort file results
-                    $filledresult = [];
-                    for ($slot = $start; $slot < $end; $slot++) {
-                        if (array_key_exists($slot, $fileres)) {
-                            $filledresult[$slot] = $fileres[$slot];
-                        } else {
-                            if ($lastfile == $fileno && $slot > $maxslot) {
-                                $filledresult[$slot] = ['_' => null];
-                            } else {
-                                $filledresult[$slot] = ['_' => 0];
-                            }
-                        }
-                    }
-
-                    $filename = $this->statdir.'/'.$rulename.'-'.$tres.'-'.$fileno.'.stat';
-                    if (file_exists($filename)) {
-                        $previousData = unserialize(file_get_contents($filename));
-                        $filledresult = $this->cummulateData($previousData, $filledresult);
-                    }
-
-                    // store file
-                    file_put_contents($filename, serialize($filledresult), LOCK_EX);
-                }
-            }
-        }
-        $this->saveMetadata();
-    }
-}
diff --git a/modules/statistics/lib/DateHandler.php b/modules/statistics/lib/DateHandler.php
deleted file mode 100644
index 17534e2d688b476d9b3592e969334523f38b46c0..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/DateHandler.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/**
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class DateHandler
-{
-    /** @var int */
-    protected $offset;
-
-    /**
-     * Constructor
-     *
-     * @param int $offset Date offset
-     */
-    public function __construct($offset)
-    {
-        $this->offset = $offset;
-    }
-
-
-    /**
-     * @param int $timestamp
-     * @return int
-     */
-    protected function getDST($timestamp)
-    {
-        if (idate('I', $timestamp)) {
-            return 3600;
-        }
-        return 0;
-    }
-
-
-    /**
-     * @param int $epoch
-     * @param int $slotsize
-     * @return float
-     */
-    public function toSlot($epoch, $slotsize)
-    {
-        $dst = $this->getDST($epoch);
-        return floor(($epoch + $this->offset + $dst) / $slotsize);
-    }
-
-
-    /**
-     * @param int $slot
-     * @param int $slotsize
-     * @return int
-     */
-    public function fromSlot($slot, $slotsize)
-    {
-        $temp = $slot * $slotsize - $this->offset;
-        $dst = $this->getDST($temp);
-        return $slot * $slotsize - $this->offset - $dst;
-    }
-
-
-    /**
-     * @param int $epoch
-     * @param string $dateformat
-     * @return string
-     */
-    public function prettyDateEpoch($epoch, $dateformat)
-    {
-        return date($dateformat, $epoch);
-    }
-
-
-    /**
-     * @param int $slot
-     * @param int $slotsize
-     * @param string $dateformat
-     * @return string
-     */
-    public function prettyDateSlot($slot, $slotsize, $dateformat)
-    {
-        return $this->prettyDateEpoch($this->fromSlot($slot, $slotsize), $dateformat);
-    }
-
-
-    /**
-     * @param int $from
-     * @param int $to
-     * @param int $slotsize
-     * @param string $dateformat
-     * @return string
-     */
-    public function prettyHeader($from, $to, $slotsize, $dateformat)
-    {
-        $text = $this->prettyDateSlot($from, $slotsize, $dateformat);
-        $text .= ' to ';
-        $text .= $this->prettyDateSlot($to, $slotsize, $dateformat);
-        return $text;
-    }
-}
diff --git a/modules/statistics/lib/DateHandlerMonth.php b/modules/statistics/lib/DateHandlerMonth.php
deleted file mode 100644
index 4404c44e14396e2d14429f7b27a516efda4b64c4..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/DateHandlerMonth.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class DateHandlerMonth extends DateHandler
-{
-    /**
-     * Constructor
-     *
-     * @param integer $offset Date offset
-     */
-    public function __construct($offset)
-    {
-        $this->offset = $offset;
-    }
-
-
-    /**
-     * @param int $epoch
-     * @param int $slotsize
-     * @return int
-     */
-    public function toSlot($epoch, $slotsize)
-    {
-        $dsttime = $this->getDST($epoch) + $epoch;
-        $parsed = getdate($dsttime);
-        $slot = (($parsed['year'] - 2000) * 12) + $parsed['mon'] - 1;
-        return $slot;
-    }
-
-
-    /**
-     * @param int $slot
-     * @param int $slotsize
-     * @return int
-     */
-    public function fromSlot($slot, $slotsize)
-    {
-        $month = ($slot % 12);
-        $year = 2000 + intval(floor($slot / 12));
-        return mktime(0, 0, 0, $month + 1, 1, $year);
-    }
-
-
-    /**
-     * @param int $from
-     * @param int $to
-     * @param int $slotsize
-     * @param string $dateformat
-     * @return string
-     */
-    public function prettyHeader($from, $to, $slotsize, $dateformat)
-    {
-        $month = ($from % 12) + 1;
-        $year = 2000 + intval(floor($from / 12));
-        return $year.'-'.$month;
-    }
-}
diff --git a/modules/statistics/lib/Graph/GoogleCharts.php b/modules/statistics/lib/Graph/GoogleCharts.php
deleted file mode 100644
index 22f4e9993039cbc0de09b2dbd4632a82564d1f3b..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/Graph/GoogleCharts.php
+++ /dev/null
@@ -1,199 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics\Graph;
-
-/*
- * \SimpleSAML\Module\statistics\Graph\GoogleCharts will help you to create a Google Chart
- * using the Google Charts API.
- *
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class GoogleCharts
-{
-    /**
-     * @var integer
-     */
-    private $x;
-
-    /**
-     * @var integer
-     */
-    private $y;
-
-    /**
-     * Constructor.
-     *
-     * Takes dimension of graph as parameters. X and Y.
-     *
-     * @param integer $x    X dimension. Default 800.
-     * @param integer $y    Y dimension. Default 350.
-     */
-    public function __construct($x = 800, $y = 350)
-    {
-        $this->x = $x;
-        $this->y = $y;
-    }
-
-
-    /**
-     * @param array $axis
-     * @return string
-     */
-    private function encodeaxis($axis)
-    {
-        return join('|', $axis);
-    }
-
-    /**
-     * t:10.0,58.0,95.0
-     * @param array $datasets
-     * @return string
-     */
-    private function encodedata($datasets)
-    {
-        $setstr = [];
-        foreach ($datasets as $dataset) {
-            $setstr[] = self::extEncode($dataset);
-        }
-        return 'e:'.join(',', $setstr);
-    }
-
-
-    /**
-     * @param array $values
-     * @return string
-     */
-    public static function extEncode($values) // $max = 4095, $min = 0
-    {
-        $extended_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.';
-        $chardata = '';
-        $delta = 4095;
-        $size = (strlen($extended_table));
-
-        foreach ($values as $k => $v) {
-            if ($v >= 0 && $v <= 100) {
-                $first = substr($extended_table, intval(($delta * $v / 100) / $size), 1);
-                $second = substr($extended_table, intval(($delta * $v / 100) % $size), 1);
-                $chardata .= "$first$second";
-            } else {
-                $chardata .= '__'; // Value out of max range;
-            }
-        }
-        return $chardata;
-    }
-
-
-    /**
-     * Generate a Google Charts URL which points to a generated image.
-     * More documentation on Google Charts here:
-     *   http://code.google.com/apis/chart/
-     *
-     * @param array $axis        Axis
-     * @param array $axispos       Axis positions
-     * @param array $datasets    Datasets values
-     * @param array $maxes         Max value. Will be the topmost value on the Y-axis.
-     * @return string
-     */
-    public function show($axis, $axispos, $datasets, $maxes)
-    {
-        $labeld = '&chxt=x,y'.'&chxr=0,0,1|1,0,'.$maxes[0];
-        if (count($datasets) > 1) {
-            if (count($datasets) !== count($maxes)) {
-                throw new \Exception('Incorrect number of max calculations for graph plotting.');
-            }
-            $labeld = '&chxt=x,y,r'.'&chxr=0,0,1|1,0,'.$maxes[0].'|2,0,'.$maxes[1];
-        }
-
-        $url = 'https://chart.apis.google.com/chart?'.
-            // Dimension of graph. Default is 800x350
-            'chs='.$this->x.'x'.$this->y.
-
-            // Dateset values
-            '&chd='.$this->encodedata($datasets).
-
-            // Fill area...
-            '&chco=ff5c00,cca600'.
-            '&chls=1,1,0|1,6,3'.
-
-            // chart type is linechart
-            '&cht=lc'.
-            $labeld.
-            '&chxl=0:|'.$this->encodeaxis($axis).#.$'|1:||top'.
-            '&chxp=0,'.join(',', $axispos).
-            '&chg='.(2400 / (count($datasets[0]) - 1)).',-1,3,3'; // lines
-
-        return $url;
-    }
-
-
-    /**
-     * @param array $axis
-     * @param array $datasets
-     * @return string
-     */
-    public function showPie($axis, $datasets)
-    {
-        $url = 'https://chart.apis.google.com/chart?'.
-
-        // Dimension of graph. Default is 800x350
-        'chs='.$this->x.'x'.$this->y.
-
-        // Dateset values.
-        '&chd='.$this->encodedata([$datasets]).
-
-        // chart type is linechart
-        '&cht=p'.
-
-        '&chl='.$this->encodeaxis($axis);
-
-        return $url;
-    }
-
-
-    /**
-     * Takes a input value, and generates a value that suits better as a max
-     * value on the Y-axis. In example 37.6 will not make a good max value, instead
-     * it will return 40. It will always return an equal or larger number than it gets
-     * as input.
-     *
-     * Here is some test code:
-     * <code>
-     *      $foo = array(
-     *          0, 2, 2.3, 2.6, 6, 10, 15, 98, 198, 256, 487, 563, 763, 801, 899, 999, 987, 198234.485, 283746
-     *      );
-     *      foreach ($foo as $f) {
-     *          echo '<p>'.$f.' => '.\SimpleSAML\Module\statistics\Graph\GoogleCharts::roof($f);
-     *      }
-     * </code>
-     *
-     * @param int $max    Input value.
-     * @return int
-     */
-    public static function roof($max)
-    {
-        $mul = 1;
-
-        if ($max < 1) {
-            return 1;
-        }
-
-        $t = intval(ceil($max));
-        while ($t > 100) {
-            $t /= 10;
-            $mul *= 10;
-        }
-
-        $maxGridLines = 10;
-        $candidates = [1, 2, 5, 10, 20, 25, 50, 100];
-
-        foreach ($candidates as $c) {
-            if ($t / $c < $maxGridLines) {
-                $tick_y = $c * $mul;
-                $target_top = intval(ceil($max / $tick_y) * $tick_y);
-                return $target_top;
-            }
-        }
-        return 1;
-    }
-}
diff --git a/modules/statistics/lib/LogCleaner.php b/modules/statistics/lib/LogCleaner.php
deleted file mode 100644
index ee20e18bf457c8d5a37b2caa110cb8192d5b5cb5..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/LogCleaner.php
+++ /dev/null
@@ -1,201 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/**
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class LogCleaner
-{
-    /** @var \SimpleSAML\Configuration */
-    private $statconfig;
-
-    /** @var string */
-    private $statdir;
-
-    /** @var string */
-    private $inputfile;
-
-    /** @var array */
-    private $statrules;
-
-    /** @var int */
-    private $offset;
-
-
-    /**
-     * Constructor
-     *
-     * @param string|null $inputfile
-     */
-    public function __construct($inputfile = null)
-    {
-        $this->statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
-
-        $this->statdir = $this->statconfig->getValue('statdir');
-        $this->inputfile = $this->statconfig->getValue('inputfile');
-        $this->statrules = $this->statconfig->getValue('statrules');
-        $this->offset = $this->statconfig->getValue('offset', 0);
-
-        if (isset($inputfile)) {
-            $this->inputfile = $inputfile;
-        }
-    }
-
-
-    /**
-     * @return void
-     */
-    public function dumpConfig()
-    {
-        echo 'Statistics directory   : '.$this->statdir."\n";
-        echo 'Input file             : '.$this->inputfile."\n";
-        echo 'Offset                 : '.$this->offset."\n";
-    }
-
-
-    /**
-     * @param bool $debug
-     * @return array
-     * @throws \Exception
-     */
-    public function clean($debug = false)
-    {
-        if (!is_dir($this->statdir)) {
-            throw new \Exception('Statistics module: output dir do not exists ['.$this->statdir.']');
-        }
-
-        if (!file_exists($this->inputfile)) {
-            throw new \Exception('Statistics module: input file do not exists ['.$this->inputfile.']');
-        }
-
-        $file = fopen($this->inputfile, 'r');
-
-        $logparser = new LogParser(
-            $this->statconfig->getValue('datestart', 0),
-            $this->statconfig->getValue('datelength', 15),
-            $this->statconfig->getValue('offsetspan', 44)
-        );
-
-        $sessioncounter = [];
-
-        $i = 0;
-        // Parse through log file, line by line
-        while (!feof($file)) {
-            $logline = fgets($file, 4096);
-
-            // Continue if STAT is not found on line
-            if (!preg_match('/STAT/', $logline)) {
-                continue;
-            }
-            $i++;
-
-            // Parse log, and extract epoch time and rest of content.
-            $epoch = $logparser->parseEpoch($logline);
-            $content = $logparser->parseContent($logline);
-
-            if (($i % 10000) == 0) {
-                echo "Read line ".$i."\n";
-            }
-
-            $trackid = $content[4];
-
-            if (!isset($sessioncounter[$trackid])) {
-                $sessioncounter[$trackid] = 0;
-            }
-            $sessioncounter[$trackid]++;
-
-            if ($debug) {
-                echo "----------------------------------------\n";
-                echo 'Log line: '.$logline."\n";
-                echo 'Date parse ['.substr($logline, 0, $this->statconfig->getValue('datelength', 15)).
-                    '] to ['.date(DATE_RFC822, $epoch).']'."\n";
-                echo htmlentities(print_r($content, true));
-                if ($i >= 13) {
-                    exit;
-                }
-            }
-        }
-
-        $histogram = [];
-        foreach ($sessioncounter as $trackid => $sc) {
-            if (!isset($histogram[$sc])) {
-                $histogram[$sc] = 0;
-            }
-            $histogram[$sc]++;
-        }
-        ksort($histogram);
-
-        $todelete = [];
-        foreach ($sessioncounter as $trackid => $sc) {
-            if ($sc > 200) {
-                $todelete[] = $trackid;
-            }
-        }
-
-        return $todelete;
-    }
-
-
-    /**
-     * @param array $todelete
-     * @param string $outputfile
-     * @return void
-     * @throws \Exceeption
-     */
-    public function store($todelete, $outputfile)
-    {
-        echo "Preparing to delete [".count($todelete)."] trackids\n";
-
-        if (!is_dir($this->statdir)) {
-            throw new \Exception('Statistics module: output dir do not exists ['.$this->statdir.']');
-        }
-
-        if (!file_exists($this->inputfile)) {
-            throw new \Exception('Statistics module: input file do not exists ['.$this->inputfile.']');
-        }
-
-        $file = fopen($this->inputfile, 'r');
-
-        // Open the output file in a way that guarantees that we will not overwrite a random file.
-        if (file_exists($outputfile)) {
-            // Delete existing output file.
-            unlink($outputfile);
-        }
-        $outfile = fopen($outputfile, 'x'); // Create the output file
-
-        $logparser = new LogParser(
-            $this->statconfig->getValue('datestart', 0),
-            $this->statconfig->getValue('datelength', 15),
-            $this->statconfig->getValue('offsetspan', 44)
-        );
-
-        $i = 0;
-        // Parse through log file, line by line
-        while (!feof($file)) {
-            $logline = fgets($file, 4096);
-
-            // Continue if STAT is not found on line.
-            if (!preg_match('/STAT/', $logline)) {
-                continue;
-            }
-            $i++;
-
-            $content = $logparser->parseContent($logline);
-
-            if (($i % 10000) == 0) {
-                echo "Read line ".$i."\n";
-            }
-
-            $trackid = $content[4];
-            if (in_array($trackid, $todelete, true)) {
-                continue;
-            }
-
-            fputs($outfile, $logline);
-        }
-        fclose($file);
-        fclose($outfile);
-    }
-}
diff --git a/modules/statistics/lib/LogParser.php b/modules/statistics/lib/LogParser.php
deleted file mode 100644
index 0516b7f24934f26afbe23bd8a9682ea0f4232c7a..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/LogParser.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-
-class LogParser
-{
-    /**
-     * @var integer
-     */
-    private $datestart;
-
-    /**
-     * @var integer
-     */
-    private $datelength;
-
-    /**
-     * @var integer
-     */
-    private $offset;
-
-    /**
-     * Constructor
-     *
-     * @param integer $datestart   At which char is the date starting
-     * @param integer $datelength  How many characters is the date (on the b
-     * @param integer $offset      At which char is the rest of the entries starting
-     */
-    public function __construct($datestart, $datelength, $offset)
-    {
-        $this->datestart = $datestart;
-        $this->datelength = $datelength;
-        $this->offset = $offset;
-    }
-
-
-    /**
-     * @param string $line
-     *
-     * @return integer
-     */
-    public function parseEpoch($line)
-    {
-        $epoch = strtotime(substr($line, 0, $this->datelength));
-        if ($epoch > time() + 2678400) {
-            // 60 * 60 * 24 * 31 = 2678400
-            /*
-             * More than a month in the future - probably caused by
-             * the log files missing the year.
-             * We will therefore subtrackt one year.
-             */
-            $hour = intval(gmdate('H', $epoch));
-            $minute = intval(gmdate('i', $epoch));
-            $second = intval(gmdate('s', $epoch));
-            $month = intval(gmdate('n', $epoch));
-            $day = intval(gmdate('j', $epoch));
-            $year = intval(gmdate('Y', $epoch)) - 1;
-            $epoch = gmmktime($hour, $minute, $second, $month, $day, $year);
-        }
-        return $epoch;
-    }
-
-
-    /**
-     * @param string $line
-     *
-     * @return array
-     */
-    public function parseContent($line)
-    {
-        $contentstr = substr($line, $this->offset);
-        $content = explode(' ', $contentstr);
-        return $content;
-    }
-}
diff --git a/modules/statistics/lib/RatioDataset.php b/modules/statistics/lib/RatioDataset.php
deleted file mode 100644
index eaed4652402b2cdd884943847cbc37527d09c1a1..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/RatioDataset.php
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/**
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class RatioDataset extends StatDataset
-{
-    /**
-     * @return void
-     */
-    public function aggregateSummary()
-    {
-        /**
-         * Aggregate summary table from dataset. To be used in the table view.
-         */
-        $this->summary = [];
-        $noofvalues = [];
-        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);
-    }
-
-
-    /**
-     * @param string $k
-     * @param array $a
-     * @return int
-     */
-    private function ag($k, $a)
-    {
-        if (array_key_exists($k, $a)) {
-            return $a[$k];
-        }
-        return 0;
-    }
-
-
-    /**
-     * @param int $v1
-     * @param int $v2
-     * @return int|float
-     */
-    private function divide($v1, $v2)
-    {
-        if ($v2 == 0) {
-            return 0;
-        }
-        return ($v1 / $v2);
-    }
-
-
-    /**
-     * @param array $result1
-     * @param array $result2
-     * @return array
-     */
-    public function combine($result1, $result2)
-    {
-        $combined = [];
-
-        foreach ($result2 as $tick => $val) {
-            $combined[$tick] = [];
-            foreach ($val as $index => $num) {
-                $combined[$tick][$index] = $this->divide(
-                    $this->ag($index, $result1[$tick]),
-                    $this->ag($index, $result2[$tick])
-                );
-            }
-        }
-        return $combined;
-    }
-
-
-    /**
-     * @return null
-     */
-    public function getPieData()
-    {
-        return null;
-    }
-}
diff --git a/modules/statistics/lib/Ruleset.php b/modules/statistics/lib/Ruleset.php
deleted file mode 100644
index 361ba994062bdbe4eb744609cd127b85aba73728..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/Ruleset.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class Ruleset
-{
-    /** \SimpleSAML\Configuration */
-    private $statconfig;
-
-    /** @var array */
-    private $availrulenames;
-
-    /** @var array */
-    private $availrules;
-
-    /** @var array */
-    private $available;
-
-
-    /**
-     * Constructor
-     *
-     * @param \SimpleSAML\Configuration $statconfig
-     */
-    public function __construct($statconfig)
-    {
-        $this->statconfig = $statconfig;
-        $this->init();
-    }
-
-
-    /**
-     * @return void
-     */
-    private function init()
-    {
-        $statdir = $this->statconfig->getValue('statdir');
-        $statrules = $this->statconfig->getValue('statrules');
-        $timeres = $this->statconfig->getValue('timeres');
-
-        /*
-         * Walk through file lists, and get available [rule][fileslot]...
-         */
-        if (!is_dir($statdir)) {
-            throw new \Exception('Statisics output directory ['.$statdir.'] does not exist.');
-        }
-        $filelist = scandir($statdir);
-        $this->available = [];
-        foreach ($filelist as $file) {
-            if (preg_match('/([a-z0-9_]+)-([a-z0-9_]+)-([0-9]+)\.stat/', $file, $matches)) {
-                if (array_key_exists($matches[1], $statrules)) {
-                    if (array_key_exists($matches[2], $timeres)) {
-                        $this->available[$matches[1]][$matches[2]][] = $matches[3];
-                    }
-                }
-            }
-        }
-        if (empty($this->available)) {
-            throw new \Exception('No aggregated statistics files found in ['.$statdir.']');
-        }
-
-        /*
-         * Create array with information about available rules..
-         */
-        $this->availrules = array_keys($statrules);
-        $available_rules = [];
-        foreach ($this->availrules as $key) {
-            $available_rules[$key] = ['name' => $statrules[$key]['name'], 'descr' => $statrules[$key]['descr']];
-        }
-        $this->availrulenames = $available_rules;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function availableRules()
-    {
-        return $this->availrules;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function availableRulesNames()
-    {
-        return $this->availrulenames;
-    }
-
-
-    /**
-     * Resolve which rule is selected. Taking user preference and checks if it exists.
-     *
-     * @param array|null $preferRule
-     * @return array|null
-     */
-    private function resolveSelectedRule($preferRule = null)
-    {
-        $rule = $this->statconfig->getString('default', $this->availrules[0]);
-        if (!empty($preferRule)) {
-            if (in_array($preferRule, $this->availrules, true)) {
-                $rule = $preferRule;
-            }
-        }
-        return $rule;
-    }
-
-
-    /**
-     * @param array|null $preferRule
-     * @return \SimpleSAML\Module\statistics\Statistics\Rulesets\BaseRule
-     */
-    public function getRule($preferRule)
-    {
-        $rule = $this->resolveSelectedRule($preferRule);
-        $statrulesConfig = $this->statconfig->getConfigItem('statrules');
-        $statruleConfig = $statrulesConfig->getConfigItem($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
deleted file mode 100644
index 5183f12db4b19d3c1a192a992b6edaba835cd326..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/StatDataset.php
+++ /dev/null
@@ -1,405 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-/**
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class StatDataset
-{
-    /** @var \SimpleSAML\Configuration */
-    protected $statconfig;
-
-    /** @var \SimpleSAML\Configuration */
-    protected $ruleconfig;
-
-    /** @var \SimpleSAML\Configuration */
-    protected $timeresconfig;
-
-    /** @var string */
-    protected $ruleid;
-
-    /** @var int */
-    protected $fileslot;
-
-    /** @var string */
-    protected $timeres;
-
-    /** @var string */
-    protected $delimiter;
-
-    /** @var array */
-    protected $results;
-
-    /** @var array */
-    protected $summary;
-
-    /** @var int */
-    protected $max;
-
-    /** @var \SimpleSAML\Module\statistics\DateHandler */
-    protected $datehandlerFile;
-
-    /** @var \SimpleSAML\Module\statistics\DateHandler */
-    protected $datehandlerTick;
-
-
-    /**
-     * Constructor
-     *
-     * @param \SimpleSAML\Configuration $statconfig
-     * @param \SimpleSAML\Configuration $ruleconfig
-     * @param string $ruleid
-     * @param string $timeres
-     * @param int $fileslot
-     */
-    public function __construct($statconfig, $ruleconfig, $ruleid, $timeres, $fileslot)
-    {
-        assert($statconfig instanceof \SimpleSAML\Configuration);
-        assert($ruleconfig instanceof \SimpleSAML\Configuration);
-        $this->statconfig = $statconfig;
-        $this->ruleconfig = $ruleconfig;
-
-        $timeresconfigs = $statconfig->getConfigItem('timeres');
-        $this->timeresconfig = $timeresconfigs->getConfigItem($timeres);
-
-        $this->ruleid = $ruleid;
-        $this->fileslot = $fileslot;
-        $this->timeres = $timeres;
-
-        $this->delimiter = '_';
-        $this->max = 0;
-
-        $this->datehandlerTick = new DateHandler($this->statconfig->getValue('offset', 0));
-        if ($this->timeresconfig->getValue('customDateHandler', 'default') === 'month') {
-            $this->datehandlerFile = new DateHandlerMonth(0);
-        } else {
-            $this->datehandlerFile = $this->datehandlerTick;
-        }
-
-        $this->loadData();
-    }
-
-
-    /**
-     * @return int
-     */
-    public function getFileSlot()
-    {
-        return $this->fileslot;
-    }
-
-
-    /**
-     * @return string
-     */
-    public function getTimeRes()
-    {
-        return $this->timeres;
-    }
-
-
-    /**
-     * @param string $delimiter
-     * @return void
-     */
-    public function setDelimiter($delimiter = '_')
-    {
-        if (empty($delimiter)) {
-            $delimiter = '_';
-        }
-        $this->delimiter = $delimiter;
-    }
-
-
-    /**
-     * @return string|null
-     */
-    public function getDelimiter()
-    {
-        if ($this->delimiter === '_') {
-            return null;
-        }
-        return $this->delimiter;
-    }
-
-
-    /**
-     * @return void
-     */
-    public function calculateMax()
-    {
-        $maxvalue = 0;
-        foreach ($this->results as $slot => &$res) {
-            if (!array_key_exists($this->delimiter, $res)) {
-                $res[$this->delimiter] = 0;
-            }
-            $maxvalue = max($res[$this->delimiter], $maxvalue);
-        }
-        $this->max = Graph\GoogleCharts::roof($maxvalue);
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getDebugData()
-    {
-        $debugdata = [];
-
-        $slotsize = $this->timeresconfig->getValue('slot');
-        $dateformat_intra = $this->timeresconfig->getValue('dateformat-intra');
-
-        foreach ($this->results as $slot => &$res) {
-            $debugdata[$slot] = [
-                $this->datehandlerTick->prettyDateSlot($slot, $slotsize, $dateformat_intra),
-                $res[$this->delimiter]
-            ];
-        }
-        return $debugdata;
-    }
-
-
-    /**
-     * @return void
-     */
-    public function aggregateSummary()
-    {
-        // aggregate summary table from dataset. To be used in the table view
-        $this->summary = [];
-        foreach ($this->results as $slot => $res) {
-            foreach ($res as $key => $value) {
-                if (array_key_exists($key, $this->summary)) {
-                    $this->summary[$key] += $value;
-                } else {
-                    $this->summary[$key] = $value;
-                }
-            }
-        }
-        asort($this->summary);
-        $this->summary = array_reverse($this->summary, true);
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getTopDelimiters()
-    {
-        // create a list of delimiter keys that has the highest total summary in this period
-        $topdelimiters = [];
-        $maxdelimiters = 4;
-        $i = 0;
-        foreach ($this->summary as $key => $value) {
-            if ($key !== '_') {
-                $topdelimiters[] = $key;
-            }
-            if ($i++ >= $maxdelimiters) {
-                break;
-            }
-        }
-        return $topdelimiters;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function availDelimiters()
-    {
-        $availDelimiters = [];
-        foreach ($this->summary as $key => $value) {
-            $availDelimiters[$key] = 1;
-        }
-        return array_keys($availDelimiters);
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getPieData()
-    {
-        $piedata = [];
-        $sum = 0;
-        $topdelimiters = $this->getTopDelimiters();
-
-        foreach ($topdelimiters as $td) {
-            $sum += $this->summary[$td];
-            $piedata[] = number_format(100 * $this->summary[$td] / $this->summary['_'], 2);
-        }
-        $piedata[] = number_format(100 - 100 * ($sum / $this->summary['_']), 2);
-        return $piedata;
-    }
-
-
-    /**
-     * @return int
-     */
-    public function getMax()
-    {
-        return $this->max;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getSummary()
-    {
-        return $this->summary;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getResults()
-    {
-        return $this->results;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getAxis()
-    {
-        $slotsize = $this->timeresconfig->getValue('slot');
-        $dateformat_intra = $this->timeresconfig->getValue('dateformat-intra');
-        $axislabelint = $this->timeresconfig->getValue('axislabelint');
-
-        $axis = [];
-        $axispos = [];
-        $xentries = count($this->results);
-        $lastslot = 0;
-        $i = 0;
-
-        foreach ($this->results as $slot => $res) {
-            // check if there should be an axis here...
-            if ($slot % $axislabelint == 0) {
-                $axis[] = $this->datehandlerTick->prettyDateSlot($slot, $slotsize, $dateformat_intra);
-                $axispos[] = (($i) / ($xentries - 1));
-            }
-            $lastslot = $slot;
-            $i++;
-        }
-
-        $axis[] = $this->datehandlerTick->prettyDateSlot($lastslot + 1, $slotsize, $dateformat_intra);
-
-        return ['axis' => $axis, 'axispos' => $axispos];
-    }
-
-
-    /**
-     * Walk through dataset to get percent values from max into dataset[].
-     * @return array
-     */
-    public function getPercentValues()
-    {
-        $i = 0;
-        $dataset = [];
-        foreach ($this->results as $slot => $res) {
-            if (array_key_exists($this->delimiter, $res)) {
-                if ($res[$this->delimiter] === null) {
-                    $dataset[] = -1;
-                } else {
-                    $dataset[] = number_format(100 * $res[$this->delimiter] / $this->max, 2);
-                }
-            } else {
-                $dataset[] = '0';
-            }
-            $i++;
-        }
-
-        return $dataset;
-    }
-
-
-    /**
-     * @return array
-     * @throws \Exception
-     */
-    public function getDelimiterPresentation()
-    {
-        $config = \SimpleSAML\Configuration::getInstance();
-        $t = new \SimpleSAML\XHTML\Template($config, 'statistics:statistics.tpl.php');
-
-        $availdelimiters = $this->availDelimiters();
-
-        // create a delimiter presentation filter for this rule...
-        if ($this->ruleconfig->hasValue('fieldPresentation')) {
-            $fieldpresConfig = $this->ruleconfig->getConfigItem('fieldPresentation');
-            $classname = \SimpleSAML\Module::resolveClass(
-                $fieldpresConfig->getValue('class'),
-                'Statistics\FieldPresentation'
-            );
-            if (!class_exists($classname)) {
-                throw new \Exception('Could not find field presentation plugin ['.$classname.']: No class found');
-            }
-            $presentationHandler = new $classname($availdelimiters, $fieldpresConfig->getValue('config'), $t);
-
-            return $presentationHandler->getPresentation();
-        }
-
-        return [];
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getDelimiterPresentationPie()
-    {
-        $topdelimiters = $this->getTopDelimiters();
-        $delimiterPresentation = $this->getDelimiterPresentation();
-
-        $pieaxis = [];
-        foreach ($topdelimiters as $key) {
-            $keyName = $key;
-            if (array_key_exists($key, $delimiterPresentation)) {
-                $keyName = $delimiterPresentation[$key];
-            }
-            $pieaxis[] = $keyName;
-        }
-        $pieaxis[] = 'Others';
-        return $pieaxis;
-    }
-
-
-    /**
-     * @return void
-     */
-    public function loadData()
-    {
-        $statdir = $this->statconfig->getValue('statdir');
-        $resarray = [];
-        $rules = \SimpleSAML\Utils\Arrays::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;
-        }
-
-        $combined = $resarray[0];
-        $count = count($resarray);
-        if ($count > 1) {
-            for ($i = 1; $i < $count; $i++) {
-                $combined = $this->combine($combined, $resarray[$i]);
-            }
-        }
-        $this->results = $combined;
-    }
-}
diff --git a/modules/statistics/lib/Statistics/FieldPresentation/Base.php b/modules/statistics/lib/Statistics/FieldPresentation/Base.php
deleted file mode 100644
index 8f0bd99c0086446922df494cace9df608e0151ca..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/Statistics/FieldPresentation/Base.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics\Statistics\FieldPresentation;
-
-class Base
-{
-    /** @var array */
-    protected $fields;
-
-    /** @var \SimpleSAML\XHTML\Template */
-    protected $template;
-
-    /** @var string */
-    protected $config;
-
-
-    /**
-     * @param array $fields
-     * @param string $config
-     * @param \SimpleSAML\XHTML\Template $template
-     */
-    public function __construct($fields, $config, $template)
-    {
-        $this->fields = $fields;
-        $this->template = $template;
-        $this->config = $config;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function getPresentation()
-    {
-        return ['_' => 'Total'];
-    }
-}
diff --git a/modules/statistics/lib/Statistics/FieldPresentation/Entity.php b/modules/statistics/lib/Statistics/FieldPresentation/Entity.php
deleted file mode 100644
index df88c8e4f710e6d97958cd2c41a2f5e71d99bdab..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/Statistics/FieldPresentation/Entity.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics\Statistics\FieldPresentation;
-
-class Entity extends Base
-{
-    /**
-     * @return array
-     */
-    public function getPresentation()
-    {
-        $mh = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
-        $metadata = $mh->getList($this->config);
-
-        $translation = ['_' => 'All services'];
-        foreach ($this->fields as $field) {
-            if (array_key_exists($field, $metadata)) {
-                if (array_key_exists('name', $metadata[$field])) {
-                    $translation[$field] = $this->template->t($metadata[$field]['name']);
-                }
-            }
-        }
-        return $translation;
-    }
-}
diff --git a/modules/statistics/lib/Statistics/Rulesets/BaseRule.php b/modules/statistics/lib/Statistics/Rulesets/BaseRule.php
deleted file mode 100644
index 77c3a20513b1bdff5eeb3c70732b2a165e25b4a8..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/Statistics/Rulesets/BaseRule.php
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics\Statistics\Rulesets;
-
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class BaseRule
-{
-    /** @var \SimpleSAML\Configuration */
-    protected $statconfig;
-
-    /** @var \SimpleSAML\Configuration */
-    protected $ruleconfig;
-
-    /** @var string */
-    protected $ruleid;
-
-    /** @var array|null */
-    protected $available = null;
-
-    /**
-     * Constructor
-     *
-     * @param \SimpleSAML\Configuration $statconfig
-     * @param \SimpleSAML\Configuration $ruleconfig
-     * @param string $ruleid
-     * @param array $available
-     */
-    public function __construct($statconfig, $ruleconfig, $ruleid, $available)
-    {
-        assert($statconfig instanceof \SimpleSAML\Configuration);
-        assert($ruleconfig instanceof \SimpleSAML\Configuration);
-        $this->statconfig = $statconfig;
-        $this->ruleconfig = $ruleconfig;
-        $this->ruleid = $ruleid;
-
-        if (array_key_exists($ruleid, $available)) {
-            $this->available = $available[$ruleid];
-        }
-    }
-
-
-    /**
-     * @return string
-     */
-    public function getRuleID()
-    {
-        return $this->ruleid;
-    }
-
-
-    /**
-     * @return array
-     */
-    public function availableTimeRes()
-    {
-        $timeresConfigs = $this->statconfig->getValue('timeres');
-        $available_times = [];
-        foreach ($timeresConfigs as $tres => $tresconfig) {
-            if (array_key_exists($tres, $this->available)) {
-                $available_times[$tres] = $tresconfig['name'];
-            }
-        }
-        return $available_times;
-    }
-
-
-    /**
-     * @param string $timeres
-     * @return array
-     */
-    public function availableFileSlots($timeres)
-    {
-        $timeresConfigs = $this->statconfig->getValue('timeres');
-        $timeresConfig = $timeresConfigs[$timeres];
-
-        if (isset($timeresConfig['customDateHandler']) && $timeresConfig['customDateHandler'] == 'month') {
-            $datehandler = new \SimpleSAML\Module\statistics\DateHandlerMonth(0);
-        } else {
-            $datehandler = new \SimpleSAML\Module\statistics\DateHandler($this->statconfig->getValue('offset', 0));
-        }
-
-        /*
-         * Get list of avaiable times in current file (rule)
-         */
-        $available_times = [];
-        foreach ($this->available[$timeres] as $slot) {
-            $available_times[$slot] = $datehandler->prettyHeader(
-                $slot,
-                $slot + 1,
-                $timeresConfig['fileslot'],
-                $timeresConfig['dateformat-period']
-            );
-        }
-        return $available_times;
-    }
-
-
-    /**
-     * @param string $preferTimeRes
-     * @return string
-     */
-    protected function resolveTimeRes($preferTimeRes)
-    {
-        $timeresavailable = array_keys($this->available);
-        $timeres = $timeresavailable[0];
-
-        // Then check if the user have provided one that is valid
-        if (in_array($preferTimeRes, $timeresavailable, true)) {
-            $timeres = $preferTimeRes;
-        }
-        return $timeres;
-    }
-
-
-    /**
-     * @param string $timeres
-     * @param string $preferTime
-     * @return int
-     */
-    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];
-        // Then check if the user have provided one.
-        if (in_array($preferTime, $this->available[$timeres], true)) {
-            $fileslot = $preferTime;
-        }
-        return $fileslot;
-    }
-
-
-    /**
-     * @param string $timeres
-     * @param string $preferTime
-     * @return array
-     */
-    public function getTimeNavigation($timeres, $preferTime)
-    {
-        $fileslot = $this->resolveFileSlot($timeres, $preferTime);
-
-        // Extract previous and next time slots...
-        $available_times_prev = null;
-        $available_times_next = null;
-
-        $timeslots = array_values($this->available[$timeres]);
-        sort($timeslots, SORT_NUMERIC);
-        $timeslotindex = array_flip($timeslots);
-
-        if ($timeslotindex[$fileslot] > 0) {
-            $available_times_prev = $timeslots[$timeslotindex[$fileslot] - 1];
-        }
-        if ($timeslotindex[$fileslot] < (count($timeslotindex) - 1)) {
-            $available_times_next = $timeslots[$timeslotindex[$fileslot] + 1];
-        }
-        return ['prev' => $available_times_prev, 'next' => $available_times_next];
-    }
-
-
-    /**
-     * @param string $preferTimeRes
-     * @param string $preferTime
-     * @return \SimpleSAML\Module\statistics\StatDataset
-     */
-    public function getDataSet($preferTimeRes, $preferTime)
-    {
-        $timeres = $this->resolveTimeRes($preferTimeRes);
-        $fileslot = $this->resolveFileSlot($timeres, $preferTime);
-        $dataset = new \SimpleSAML\Module\statistics\StatDataset(
-            $this->statconfig,
-            $this->ruleconfig,
-            $this->ruleid,
-            $timeres,
-            $fileslot
-        );
-        return $dataset;
-    }
-}
diff --git a/modules/statistics/lib/Statistics/Rulesets/Ratio.php b/modules/statistics/lib/Statistics/Rulesets/Ratio.php
deleted file mode 100644
index ed3a6eb9936ae85fa5e72fbc1a92ef7f8474fda2..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/Statistics/Rulesets/Ratio.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics\Statistics\Rulesets;
-
-/*
- * @author Andreas Ă…kre Solberg <andreas.solberg@uninett.no>
- * @package SimpleSAMLphp
- */
-class Ratio extends BaseRule
-{
-    /** @var \SimpleSAML\Module\statistics\Statistics\Rulesets\BaseRule $refrule1 */
-    protected $refrule1;
-
-    /** @var \SimpleSAML\Module\statistics\Statistics\Rulesets\BaseRule $refrule2 */
-    protected $refrule2;
-
-
-    /**
-     * Constructor
-     *
-     * @param \SimpleSAML\Configuration $statconfig
-     * @param \SimpleSAML\Configuration $ruleconfig
-     * @param string $ruleid
-     * @param array $available
-     */
-    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 BaseRule($this->statconfig, $statruleConfig1, $refNames[0], $available);
-        $this->refrule2 = new BaseRule($this->statconfig, $statruleConfig2, $refNames[1], $available);
-    }
-
-
-    /**
-     * @return array
-     */
-    public function availableTimeRes()
-    {
-        return $this->refrule1->availableTimeRes();
-    }
-
-
-    /**
-     * @param string $timeres
-     * @return array
-     */
-    public function availableFileSlots($timeres)
-    {
-        return $this->refrule1->availableFileSlots($timeres);
-    }
-
-
-    /**
-     * @param string $preferTimeRes
-     * @return string
-     */
-    protected function resolveTimeRes($preferTimeRes)
-    {
-        return $this->refrule1->resolveTimeRes($preferTimeRes);
-    }
-
-
-    /**
-     * @param string $timeres
-     * @param string $preferTime
-     * @return int
-     */
-    protected function resolveFileSlot($timeres, $preferTime)
-    {
-        return $this->refrule1->resolveFileSlot($timeres, $preferTime);
-    }
-
-
-    /**
-     * @param string $timeres
-     * @param string $preferTime
-     * @return array
-     */
-    public function getTimeNavigation($timeres, $preferTime)
-    {
-        return $this->refrule1->getTimeNavigation($timeres, $preferTime);
-    }
-
-
-    /**
-     * @param string $preferTimeRes
-     * @param string $preferTime
-     * @return \SimpleSAML\Module\statistics\RatioDataset
-     */
-    public function getDataSet($preferTimeRes, $preferTime)
-    {
-        $timeres = $this->resolveTimeRes($preferTimeRes);
-        $fileslot = $this->resolveFileSlot($timeres, $preferTime);
-
-        $refNames = $this->ruleconfig->getArray('ref');
-
-        $dataset = new \SimpleSAML\Module\statistics\RatioDataset(
-            $this->statconfig,
-            $this->ruleconfig,
-            $refNames,
-            $timeres,
-            $fileslot
-        );
-        return $dataset;
-    }
-}
diff --git a/modules/statistics/lib/StatisticsController.php b/modules/statistics/lib/StatisticsController.php
deleted file mode 100644
index 5110307931100cd267eaef95f91fb1163459a42f..0000000000000000000000000000000000000000
--- a/modules/statistics/lib/StatisticsController.php
+++ /dev/null
@@ -1,240 +0,0 @@
-<?php
-
-namespace SimpleSAML\Module\statistics;
-
-use SimpleSAML\HTTP\RunnableResponse;
-use SimpleSAML\Locale\Translate;
-use SimpleSAML\Utils\HTTP;
-use Symfony\Component\HttpFoundation\Request;
-
-/**
- * Controller class for the statistics module.
- *
- * This class serves the statistics views available in the module.
- *
- * @package SimpleSAML\Module\admin
- */
-class StatisticsController
-{
-    /** @var \SimpleSAML\Configuration */
-    protected $config;
-
-    /** @var \SimpleSAML\Configuration */
-    protected $moduleConfig;
-
-    /** @var \SimpleSAML\Session */
-    protected $session;
-
-
-    /**
-     * StatisticsController constructor.
-     *
-     * @param \SimpleSAML\Configuration $config The configuration to use.
-     * @param \SimpleSAML\Session $session The current user session.
-     */
-    public function __construct(\SimpleSAML\Configuration $config, \SimpleSAML\Session $session)
-    {
-        $this->config = $config;
-        $this->moduleConfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
-        $this->session = $session;
-    }
-
-
-    /**
-     * Display statistics metadata.
-     *
-     * @param Request $request The current request.
-     *
-     * @return \SimpleSAML\XHTML\Template
-     */
-    public function metadata(Request $request)
-    {
-        \SimpleSAML\Module\statistics\AccessCheck::checkAccess($this->moduleConfig);
-
-        $aggr = new \SimpleSAML\Module\statistics\Aggregator();
-        $aggr->loadMetadata();
-        $metadata = $aggr->getMetadata();
-
-        if ($metadata !== null) {
-            if (in_array('lastrun', $metadata, true)) {
-                $metadata['lastrun'] = date('l jS \of F Y H:i:s', $metadata['lastrun']);
-            }
-            if (in_array('notBefore', $metadata, true)) {
-                $metadata['notBefore'] = date('l jS \of F Y H:i:s', $metadata['notBefore']);
-            }
-            if (in_array('memory', $metadata, true)) {
-                $metadata['memory'] = number_format($metadata['memory'] / (1024 * 1024), 2);
-            }
-        }
-
-        $t = new \SimpleSAML\XHTML\Template($this->config, 'statistics:statmeta.twig');
-        $t->data = [
-            'metadata' => $metadata,
-        ];
-
-        return $t;
-    }
-
-
-    /**
-     * Display the main admin page.
-     *
-     * @return \SimpleSAML\XHTML\Template
-     */
-    public function main(Request $request)
-    {
-        \SimpleSAML\Module\statistics\AccessCheck::checkAccess($this->moduleConfig);
-
-        /*
-         * Check input parameters
-         */
-        $preferRule = $request->query->get('rule');
-        $preferRule2 = $request->query->get('rule2');
-        if ($preferRule2 === '_') {
-            $preferRule2 = null;
-        }
-
-        $preferTime = $request->query->get('time');
-        $preferTimeRes = $request->query->get('res');
-        $delimiter = $request->query->get('delimiler');
-
-        /*
-         * Create statistics data.
-         */
-        $ruleset = new \SimpleSAML\Module\statistics\Ruleset($this->moduleConfig);
-        $statrule = $ruleset->getRule($preferRule);
-        $rule = $statrule->getRuleID();
-
-        /*
-         * Prepare template.
-         */
-        $t = new \SimpleSAML\XHTML\Template($this->config, 'statistics:statistics.twig');
-        $t->data = [
-            'delimiter' => $delimiter,
-            'pageid' => 'statistics',
-            'header' => 'stat',
-            'available_rules' => $ruleset->availableRulesNames(),
-            'selected_rule' => $rule,
-            'selected_rule2' => $preferRule2,
-        ];
-
-        try {
-            $dataset = $statrule->getDataset($preferTimeRes, $preferTime);
-            $dataset->setDelimiter($delimiter);
-            $dataset->aggregateSummary();
-            $dataset->calculateMax();
-        } catch (\Exception $e) {
-            $t->data['error'] = "No data available";
-            return $t;
-        }
-
-        $delimiter = $dataset->getDelimiter();
-        $timeres = $dataset->getTimeRes();
-        $fileslot = $dataset->getFileslot();
-        $timeNavigation = $statrule->getTimeNavigation($timeres, $preferTime);
-        $piedata = $dataset->getPieData();
-        $datasets = [$dataset->getPercentValues()];
-        $axis = $dataset->getAxis();
-        $maxes = [$dataset->getMax()];
-
-        $t->data['selected_rule'] = $rule;
-        $t->data['selected_time'] = $fileslot;
-        $t->data['selected_timeres'] = $timeres;
-        $t->data['post_d'] = $this->getBaseURL($t, 'post', 'd');
-        if (isset($preferRule2)) {
-            $statrule = $ruleset->getRule($preferRule2);
-            try {
-                $dataset2 = $statrule->getDataset($preferTimeRes, $preferTime);
-                $dataset2->aggregateSummary();
-                $dataset2->calculateMax();
-                $datasets[] = $dataset2->getPercentValues();
-                $maxes[] = $dataset2->getMax();
-
-                if ($request->query->get('format') === 'csv') {
-                    header('Content-type: text/csv');
-                    header('Content-Disposition: attachment; filename="simplesamlphp-data.csv"');
-                    $data = $dataset->getDebugData();
-                    foreach ($data as $de) {
-                        if (isset($de[1])) {
-                            echo '"'.$de[0].'",'.$de[1]."\n";
-                        }
-                    }
-                    exit;
-                } else {
-                    $t->data['error'] = 'Export format not supported';
-                    return $t;
-                }
-            } catch (\Exception $e) {
-                $t->data['error'] = "No data available to compare";
-                return $t;
-            }
-        }
-
-        $dimx = $this->moduleConfig->getValue('dimension.x', 800);
-        $dimy = $this->moduleConfig->getValue('dimension.y', 350);
-        $grapher = new \SimpleSAML\Module\statistics\Graph\GoogleCharts($dimx, $dimy);
-        $t->data['imgurl'] = $grapher->show($axis['axis'], $axis['axispos'], $datasets, $maxes);
-
-        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();
-        $t->data['available_times_prev'] = $timeNavigation['prev'];
-        $t->data['available_times_next'] = $timeNavigation['next'];
-        $t->data['current_rule'] = $t->data['available_rules'][$rule];
-        $t->data['selected_rule2'] = $preferRule2;
-        $t->data['selected_delimiter'] = $delimiter;
-        $t->data['debugdata'] = $dataset->getDebugData();
-        $t->data['results'] = $dataset->getResults();
-        $t->data['summaryDataset'] = $dataset->getSummary();
-        $t->data['topdelimiters'] = $dataset->getTopDelimiters();
-        $t->data['post_rule'] = $this->getBaseURL($t, 'post', 'rule');
-        $t->data['post_rule2'] = $this->getBaseURL($t, 'post', 'rule2');
-        $t->data['post_res'] = $this->getBaseURL($t, 'post', 'res');
-        $t->data['post_time'] = $this->getBaseURL($t, 'post', 'time');
-        $t->data['get_times_prev'] = $this->getBaseURL($t, 'get', 'time', $t->data['available_times_prev']);
-        $t->data['get_times_next'] = $this->getBaseURL($t, 'get', 'time', $t->data['available_times_next']);
-        $t->data['availdelimiters'] = $dataset->availDelimiters();
-        $t->data['delimiterPresentation'] = $dataset->getDelimiterPresentation();
-
-        return $t;
-    }
-
-
-    /**
-     * @param \SimpleSAML\XHTML\Template $t
-     * @param string $type
-     * @param string|null $key
-     * @param string|null $value
-     * @return string|array
-     */
-    private function getBaseURL($t, $type = 'get', $key = null, $value = null)
-    {
-        $vars = [
-            'rule' => $t->data['selected_rule'],
-            'time' => $t->data['selected_time'],
-            'res' => $t->data['selected_timeres'],
-        ];
-        if (isset($t->data['selected_delimiter'])) {
-            $vars['d'] = $t->data['selected_delimiter'];
-        }
-        if (!empty($t->data['selected_rule2']) && $t->data['selected_rule2'] !== '_') {
-            $vars['rule2'] = $t->data['selected_rule2'];
-        }
-        if (isset($key)) {
-            if (isset($vars[$key])) {
-                unset($vars[$key]);
-            }
-            if (isset($value)) {
-                $vars[$key] = $value;
-            }
-        }
-        if ($type === 'get') {
-            return \SimpleSAML\Module::getModuleURL("statistics/showstats.php").'?'.http_build_query($vars, '', '&amp;');
-        }
-        return $vars;
-    }
-}
diff --git a/modules/statistics/locales/en/LC_MESSAGES/statistics.po b/modules/statistics/locales/en/LC_MESSAGES/statistics.po
deleted file mode 100644
index 8dee6fd55264775750189843f14e237e88acbaad..0000000000000000000000000000000000000000
--- a/modules/statistics/locales/en/LC_MESSAGES/statistics.po
+++ /dev/null
@@ -1,11 +0,0 @@
-msgid "{statistics:statistics:link_statistics"
-msgstr "Show statistics"
-
-msgid "{statistics:statistics:link_statistics_metadata"
-msgstr "Show statistics metadata"
-
-msgid "Show statistics"
-msgstr "Show statistics"
-
-msgid "Show statistics metadata"
-msgstr "Show statistics metadata"
\ No newline at end of file
diff --git a/modules/statistics/locales/es/LC_MESSAGES/statistics.po b/modules/statistics/locales/es/LC_MESSAGES/statistics.po
deleted file mode 100644
index 871d8251855b584a8b9cd1ca95dbefa1d609d383..0000000000000000000000000000000000000000
--- a/modules/statistics/locales/es/LC_MESSAGES/statistics.po
+++ /dev/null
@@ -1,11 +0,0 @@
-msgid "{statistics:statistics:link_statistics"
-msgstr "Mostrar estadĂ­sticas"
-
-msgid "{statistics:statistics:link_statistics_metadata"
-msgstr "Mostrar metadatos de las estadĂ­sticas"
-
-msgid "Show statistics"
-msgstr "Mostrar estadĂ­sticas"
-
-msgid "Show statistics metadata"
-msgstr "Mostrar metadatos de las estadĂ­sticas"
\ No newline at end of file
diff --git a/modules/statistics/locales/nb/LC_MESSAGES/statistics.po b/modules/statistics/locales/nb/LC_MESSAGES/statistics.po
deleted file mode 100644
index f6704778553d62d21ebc32a90d3c96a3593b49e4..0000000000000000000000000000000000000000
--- a/modules/statistics/locales/nb/LC_MESSAGES/statistics.po
+++ /dev/null
@@ -1,11 +0,0 @@
-msgid "{statistics:statistics:link_statistics"
-msgstr "Vis statistikker"
-
-msgid "{statistics:statistics:link_statistics_metadata"
-msgstr "Vis metadata om statistikker"
-
-msgid "Show statistics"
-msgstr "Vis statistikker"
-
-msgid "Show statistics metadata"
-msgstr "Vis metadata om statistikker"
diff --git a/modules/statistics/locales/nn/LC_MESSAGES/statistics.po b/modules/statistics/locales/nn/LC_MESSAGES/statistics.po
deleted file mode 100644
index 6fb2e3bf4f2e2957a2d28865fd8edc67d895de9e..0000000000000000000000000000000000000000
--- a/modules/statistics/locales/nn/LC_MESSAGES/statistics.po
+++ /dev/null
@@ -1,11 +0,0 @@
-msgid "{statistics:statistics:link_statistics"
-msgstr "Vis statistikkar"
-
-msgid "{statistics:statistics:link_statistics_metadata"
-msgstr "Vis metadata om statistikkar"
-
-msgid "Show statistics"
-msgstr "Vis statistikkar"
-
-msgid "Show statistics metadata"
-msgstr "Vis metadata om statistikkar"
diff --git a/modules/statistics/routes.yaml b/modules/statistics/routes.yaml
deleted file mode 100644
index e0fa51ae9eb9da5b20f34cd9c79824bad3d14bf1..0000000000000000000000000000000000000000
--- a/modules/statistics/routes.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-statistics-main:
-    path:       /
-    defaults:   { _controller: 'SimpleSAML\Module\statistics\StatisticsController::main' }
-statistics-metadata:
-    path:       /metadata
-    defaults:   { _controller: 'SimpleSAML\Module\statistics\StatisticsController::metadata' }
diff --git a/modules/statistics/templates/statistics.tpl.php b/modules/statistics/templates/statistics.tpl.php
deleted file mode 100644
index 7abe9bb7e10c0c1419d72def205596a0b7c8aeff..0000000000000000000000000000000000000000
--- a/modules/statistics/templates/statistics.tpl.php
+++ /dev/null
@@ -1,233 +0,0 @@
-<?php
-$this->data['header'] = 'SimpleSAMLphp Statistics';
-
-$this->data['jquery'] = ['core' => true, 'ui' => true, 'css' => true];
-
-$this->data['head'] = '<link rel="stylesheet" type="text/css" href="'.
-    SimpleSAML\Module::getModuleURL("statistics/assets/css/statistics.css").'" />'."\n";
-$this->data['head'] .= '<script type="text/javascript" src="'.
-    SimpleSAML\Module::getModuleURL("statistics/assets/js/statistics.js").'"></script>'."\n";
-
-$this->includeAtTemplateBase('includes/header.php');
-
-echo '<h1>'.$this->data['available.rules'][$this->data['selected.rule']]['name'].'</h1>';
-echo '<p>'.$this->data['available.rules'][$this->data['selected.rule']]['descr'].'</p>';
-
-// Report settings
-echo '<table class="selecttime">';
-echo '<tr><td class="selecttime_icon"><img src="'.SimpleSAML\Utils\HTTP::getBaseURL().
-    'resources/icons/crystal_project/kchart.32x32.png" alt="Report settings" /></td>';
-
-// Select report
-echo '<td>';
-echo '<form action="#">';
-
-foreach ($this->data['post_rule'] as $k => $v) {
-    echo '<input type="hidden" name="'.$k.'" value="'.htmlspecialchars($v).'" />'."\n";
-}
-
-if (!empty($this->data['available_rules'])) {
-    echo '<select onchange="submit();" name="rule">';
-    foreach ($this->data['available_rules'] as $key => $rule) {
-        if ($key === $this->data['selected_rule']) {
-            echo '<option selected="selected" value="'.$key.'">'.$rule['name'].'</option>';
-        } else {
-            echo '<option value="'.$key.'">'.$rule['name'].'</option>';
-        }
-    }
-    echo '</select>';
-}
-echo '</form></td>';
-
-// Select delimiter
-echo '<td class="td_right">';
-echo '<form action="#">';
-
-foreach ($this->data['post_d'] as $k => $v) {
-    echo '<input type="hidden" name="'.$k.'" value="'.htmlspecialchars($v).'" />'."\n";
-}
-
-if (!empty($this->data['availdelimiters'])) {
-    echo '<select onchange="submit();" name="d">';
-    foreach ($this->data['availdelimiters'] as $key => $delim) {
-        $delimName = $delim;
-        if (array_key_exists($delim, $this->data['delimiterPresentation'])) {
-            $delimName = $this->data['delimiterPresentation'][$delim];
-        }
-
-        if ($key == '_') {
-            echo '<option value="_">Total</option>';
-        } elseif (isset($_REQUEST['d']) && $delim == $_REQUEST['d']) {
-            echo '<option selected="selected" value="'.htmlspecialchars($delim).'">'.
-                htmlspecialchars($delimName).'</option>';
-        } else {
-            echo '<option  value="'.htmlspecialchars($delim).'">'.htmlspecialchars($delimName).'</option>';
-        }
-    }
-    echo '</select>';
-}
-echo '</form></td></tr>';
-
-echo '</table>';
-
-// End report settings
-
-
-// Select time and date
-echo '<table class="selecttime">';
-echo '<tr><td class="selecttime_icon"><img src="'.SimpleSAML\Utils\HTTP::getBaseURL().
-    'resources/icons/crystal_project/date.32x32.png" alt="Select date and time" /></td>';
-
-if (isset($this->data['available_times_prev'])) {
-    echo '<td><a href="'.$this->data['get_times_prev'].'">« Previous</a></td>';
-} else {
-    echo '<td class="selecttime_link_grey">« Previous</td>';
-}
-
-echo '<td class="td_right">';
-echo '<form action="#">';
-
-foreach ($this->data['post_res'] as $k => $v) {
-    echo '<input type="hidden" name="'.$k.'" value="'.htmlspecialchars($v).'" />'."\n";
-}
-
-if (!empty($this->data['available_timeres'])) {
-    echo '<select onchange="submit();" name="res">';
-    foreach ($this->data['available_timeres'] as $key => $timeresname) {
-        if ($key == $this->data['selected_timeres']) {
-            echo '<option selected="selected" value="'.$key.'">'.$timeresname.'</option>';
-        } else {
-            echo '<option  value="'.$key.'">'.$timeresname.'</option>';
-        }
-    }
-    echo '</select>';
-}
-echo '</form></td>';
-
-echo '<td class="td_left">';
-echo '<form action="#">';
-
-foreach ($this->data['post_time'] as $k => $v) {
-    echo '<input type="hidden" name="'.$k.'" value="'.htmlspecialchars($v).'" />'."\n";
-}
-
-if (!empty($this->data['available_times'])) {
-    echo '<select onchange="submit();" name="time">';
-    foreach ($this->data['available_times'] as $key => $timedescr) {
-        if ($key == $this->data['selected_time']) {
-            echo '<option selected="selected" value="'.$key.'">'.$timedescr.'</option>';
-        } else {
-            echo '<option  value="'.$key.'">'.$timedescr.'</option>';
-        }
-    }
-    echo '</select>';
-}
-echo '</form></td>';
-
-if (isset($this->data['available_times_next'])) {
-    echo '<td class="td_right td_next_right"><a href="'.$this->data['get_times_next'].'">Next »</a></td>';
-} else {
-    echo '<td class="td_right selecttime_link_grey td_next_right">Next »</td>';
-}
-
-echo '</tr></table>';
-echo '<div id="tabdiv">';
-if (!empty($this->data['results'])) {
-    echo '<ul class="tabset_tabs">
-       <li><a href="#graph">Graph</a></li>
-       <li><a href="#table">Summary table</a></li>
-       <li><a href="#debug">Time serie</a></li>
-    </ul>';
-    echo '
-
-    <div id="graph" class="tabset_content">';
-
-    echo '<img src="'.htmlspecialchars($this->data['imgurl']).'" alt="Graph" />';
-
-    echo '<form action="#">';
-    echo '<p class="p_right">Compare with total from this dataset ';
-
-    foreach ($this->data['post_rule2'] as $k => $v) {
-        echo '<input type="hidden" name="'.$k.'" value="'.htmlspecialchars($v).'" />'."\n";
-    }
-
-    echo '<select onchange="submit();" name="rule2">';
-    echo '	<option value="_">None</option>';
-    foreach ($this->data['available_rules'] as $key => $rule) {
-        if ($key === $this->data['selected_rule2']) {
-            echo '<option selected="selected" value="'.$key.'">'.$rule['name'].'</option>';
-        } else {
-            echo '<option value="'.$key.'">'.$rule['name'].'</option>';
-        }
-    }
-    echo '</select></p></form>';
-
-    echo '</div>'; // end graph content.
-
-    /**
-     * Handle table view - - - - - -
-     */
-    $classint = ['odd', 'even'];
-    $i = 0;
-    echo '<div id="table" class="tabset_content">';
-
-    if (isset($this->data['pieimgurl'])) {
-        echo '<img src="'.$this->data['pieimgurl'].'" alt="Pie chart" />';
-    }
-    echo '<table class="tableview"><tr><th class="value">Value</th><th class="category">Data range</th></tr>';
-
-    foreach ($this->data['summaryDataset'] as $key => $value) {
-        $clint = $classint[$i++ % 2];
-
-        $keyName = $key;
-        if (array_key_exists($key, $this->data['delimiterPresentation'])) {
-            $keyName = $this->data['delimiterPresentation'][$key];
-        }
-
-        if ($key === '_') {
-            echo '<tr class="total '.$clint.'"><td  class="value">'.
-                $value.'</td><td class="category">'.$keyName.'</td></tr>';
-        } else {
-            echo '<tr class="'.$clint.'"><td  class="value">'.$value.
-                '</td><td class="category">'.$keyName.'</td></tr>';
-        }
-    }
-
-    echo '</table></div>';
-    //  - - - - - - - End table view - - - - - - -
-
-    echo '<div id="debug" >';
-    echo '<table class="timeseries">';
-    echo '<tr><th>Time</th><th>Total</th>';
-    foreach ($this->data['topdelimiters'] as $key) {
-        $keyName = $key;
-        if (array_key_exists($key, $this->data['delimiterPresentation'])) {
-            $keyName = $this->data['delimiterPresentation'][$key];
-        }
-        echo'<th>'.$keyName.'</th>';
-    }
-    echo '</tr>';
-
-    $i = 0;
-    foreach ($this->data['debugdata'] as $slot => $dd) {
-        echo '<tr class="'.((++$i % 2) == 0 ? 'odd' : 'even').'">';
-        echo '<td>'.$dd[0].'</td>';
-        echo '<td class="datacontent">'.$dd[1].'</td>';
-
-        foreach ($this->data['topdelimiters'] as $key) {
-            echo '<td class="datacontent">'.(array_key_exists($key, $this->data['results'][$slot]) ?
-                $this->data['results'][$slot][$key] : '&nbsp;').'</td>';
-        }
-        echo '</tr>';
-    }
-    echo '</table>';
-
-
-    echo '</div>'; // End debug tab content
-} else {
-    echo '<h4 align="center">'.$this->data['error'].'</h4>';
-    echo '<p align="center"><a href="showstats.php">Clear selection</a></p>';
-}
-echo '</div>'; // End tab div
-
-$this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/statistics/templates/statistics.twig b/modules/statistics/templates/statistics.twig
deleted file mode 100644
index fa6559e3afe8e4c4931230c0d84404ab07a88dc0..0000000000000000000000000000000000000000
--- a/modules/statistics/templates/statistics.twig
+++ /dev/null
@@ -1,226 +0,0 @@
-{% set pagetitle = 'SimpleSAMLphp Statistics'|trans %}
-{% extends "base.twig" %}
-
-{% block preload %}
-    <link href="/{{ baseurlpath }}module.php/statistics/assets/css/statistics.css" rel="stylesheet">
-    <link rel="stylesheet" media="screen" href="/{{ baseurlpath }}resources/uitheme1.8/jquery-ui.css">
-{% endblock %}
-
-{% block postload %}
-<script src="/{{ baseurlpath }}resources/jquery-1.8.js"></script>
-<script src="/{{ baseurlpath }}resources/jquery-ui-1.8.js"></script>
-<script src="/{{ baseurlpath }}module.php/statistics/assets/js/statistics.js"></script>
-{% endblock %}
-
-{% block content %}
-    <h1>{{ current_rule.name }}</h1>
-    <p>{{ current_rule.descr }}</p>
-
-    <table class="selecttime">
-        <tr>
-            <td class="selecttime_icon">
-                <i class="fa fa-pie-chart"></i>
-            </td>
-            <td>
-                <form action="#">
-                    {% for key, value in post_rule %}
-                    <input type="hidden" name="{{ key|escape('html') }}" value="{{ value|escape('html') }}">
-                    {% endfor %}
-                    <select onchange="submit();" name="rule">
-                    {% for key, rule in available_rules %}
-                        {% if key == selected_rule %}
-                        <option selected="selected" value="{{ key }}">{{ rule.name }}</option>
-                        {% else %}
-                        <option value="{{ key }}">{{ rule.name }}</option>
-                        {% endif %}
-                    {% endfor %}
-                    </select>
-                </form>
-            </td>
-            <td class="td_right">
-                <form action="#">
-                    {% for key, value in post_d %}
-                    <input type="hidden" name="{{ key|escape('html') }}" value="{{ value|escape('html') }}">
-                    {% endfor %}
-                    {% if availdelimiters %}
-                    <select onchange="submit();" name="d">
-                    {% for key, delim in availdelimiters %}
-                        {% set delimName = delim %}
-
-                        {% if delimiterPresentation[delim] is defined %}
-                        {% set delimName = delimiterPresentation[delim] %}
-                        {% endif %}
-
-                        {% if key == "_" %}
-                        <option value="_">Total</option>
-                        {% elseif request_d is defined and delim == request_d %}
-                        <option selected="selected" value="{{ delim|escape('html') }}">{{ delimName|escape('html') }}</option>
-                        {% else %}
-                        <option value="{{ delim|escape('html') }}">{{ delimName|escape('html') }}</option>
-                        {% endif %}
-                    {% endfor %}
-                    </select>
-                    {% endif %}
-                </form>
-            </td>
-        </tr>
-    </table>
-
-    <table class="selecttime">
-        <tr>
-            <td class="selecttime_icon">
-                <i class="fa fa-calendar"></i>
-            </td>
-            {% if available_times_prev %}
-            <td><a href="{{ get_times_prev }}">&laquo; Previous</a></td>
-            {% else %}
-            <td class="selecttime_link_grey">&laquo; Previous</td>
-            {% endif %}
-            <td class="td_right">
-                <form action="#">
-                    {% for key, value in post_res %}
-                    <input type="hidden" name="{{ key|escape('html') }}" value="{{ value|escape('html') }}">
-                    {% endfor %}
-                    {% if available_timeres %}
-                    <select onchange="submit();" name="res">
-                    {% for key, timeresname in available_timeres %}
-                        {% if key == selected_timeres %}
-                        <option selected="selected" value="{{ key }}">{{ timeresname }}</option>
-                        {% else %}
-                        <option value="{{ key }}">{{ timeresname }}</option>
-                        {% endif %}
-                    {% endfor %}
-                    </select>
-                    {% endif %}
-                </form>
-            </td>
-            <td class="td_left">
-                <form action="#">
-                    {% for key, value in post_time %}
-                    <input type="hidden" name="{{ key|escape('html') }}" value="{{ value|escape('html') }}">
-                    {% endfor %}
-                    {% if available_times %}
-                    <select onchange="submit();" name=time>
-                    {% for key, timedescr in available_times %}
-                        {% if key == selected_time %}
-                        <option selected="selected" value="{{ key }}">{{ timedescr }}</option>
-                        {% else %}
-                        <option value="{{ key }}">{{ timedescr }}</option>
-                        {% endif%}
-                    {% endfor %}
-                    </select>
-                    {% endif %}
-                </form>
-            </td>
-            {% if available_times_next %}
-                <td class="td_right td_next_right"><a href="{{ get_times_next }}">Next &raquo;</a></td>
-            {% else %}
-                <td class="td_right selecttime_link_grey">Next &raquo;</td>
-            {% endif %}
-        </tr>
-    </table>
-
-    <div id="tabdiv">
-    {% if results %}
-        <ul class="tabset_tabs">
-            <li class="tab-link current" data-tab="graph"><a href="#graph">Graph</a></li>
-            <li class="tab-link" data-tab="table"><a href="#table">Summary table</a></li>
-            <li class="tab-link" data-tab="debug"><a href="#debug">Time serie</a></li>
-        </ul>
-
-        <div id="graph" class="tabset_content current">
-            <img src="{{ imgurl }}" alt="Graph" />
-            <form action="#">
-                <p class="p_right">Compare with total from this dataset
-                <select onchange="submit();" name="rule2">
-                    <option value="_">None</option>
-                    {% for key, rule in available_rules %}
-                    {% if key == selected_rule2 %}
-                    <option selected="selected" value="{{ key }}">{{ rule.name }}</option>
-                    {% else %}
-                    <option value="{{ key }}">{{ rule.name }}</option>
-                    {% endif %}
-                    {% endfor %}
-                </select>
-                </p>
-            </form>
-        </div>
-
-        <div id="table" class="tabset_content">
-            {% if pieimgurl is defined %}
-            <img src="{{ pieimgurl }}" alt="Pie chart" />
-            {% endif %}
-
-            <table class="tableview">
-                <tr>
-                    <th class="value">Value</th>
-                    <th class="category">Data range</th>
-                </tr>
-                {% for key, value in summaryDataset %}
-                {% if loop.index0 is even %}
-                    {% set class = 'even' %}
-                {% else %}
-                    {% set class = 'odd' %}
-                {% endif %}
-
-                {% set keyName = key %}
-                {% if delimiterPresentation[key] is defined %}
-                {% set keyName = delimiterPresentation[key] %}
-                {% endif %}
-
-                {% if key == "_" %}
-                <tr class="total {{ class }}">
-                    <td class="value">{{ value }}</td>
-                    <td class="category">{{ keyName }}</td>
-                </tr>
-                {% else %}
-                <tr class="{{ class }}">
-                    <td class="value">{{ value }}</td>
-                    <td class="category">{{ keyName }}</td>
-                </tr>
-                {% endif %}
-                {% endfor %}
-            </table>
-        </div>
-
-        <div id="debug" class="tabset_content">
-            <table class="timeseries">
-                <tr>
-                    <th>Time</th>
-                    <th>Total</th>
-                    {% for key, value in topdelimiters %}
-                    {% set keyName = value %}
-                    {% if delimiterPresentation[value] is defined %}
-                        {% set keyName = delimiterPresentation[value] %}
-                    {% endif %}
-                    <th>{{ keyName }}</th>
-                    {% endfor %}
-                </tr>
-                {% for slot, dd in debugdata %}
-
-                {% if loop.index0 is even %}
-                    {% set class = 'even' %}
-                {% else %}
-                    {% set class = 'odd' %}
-                {% endif %}
-
-                <tr class="{{ class }}">
-                    <td>{{ dd[0] }}</td>
-                    <td class="datacontent">{{ dd[1] }}</td>
-                    {% for key, value in topdelimiters %}
-                    {% if results[slot] is defined %}
-                    <td class="datacontent">{{ results[slot][value] }}</td>
-                    {% else %}
-                    <td class="datacontent">&nbsp;</td>
-                    {% endif %}
-                    {% endfor %}
-                </tr>
-                {% endfor %}
-            </table>
-        </div>
-    {% else %}
-        <h4 align="center">{{ error }}</h4>
-        <p align="center"><a href="showstats.php">Clear selection</a></p>
-    {% endif %}
-    </div>
-{% endblock %}
diff --git a/modules/statistics/templates/statmeta.tpl.php b/modules/statistics/templates/statmeta.tpl.php
deleted file mode 100644
index 324b4e0c5c2ad26a0abf5e3b3c2ee82d98ec3a0b..0000000000000000000000000000000000000000
--- a/modules/statistics/templates/statmeta.tpl.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-$this->data['header'] = 'SimpleSAMLphp Statistics Metadata';
-$this->data['head'] = '<link rel="stylesheet" type="text/css" href="'.
-    SimpleSAML\Module::getModuleURL("statistics/assets/css/statistics.css").'" />';
-$this->includeAtTemplateBase('includes/header.php');
-
-echo '<table id="statmeta">' ;
-
-if (isset($this->data['metadata'])) {
-    $metadata = $this->data['metadata'];
-
-    if (isset($metadata['lastrun'])) {
-        echo '<tr><td>Aggregator last run at</td><td>'.$metadata['lastrun'].'</td></tr>';
-    }
-
-    if (isset($metadata['notBefore'])) {
-        echo '<tr><td>Aggregated data until</td><td>'.$metadata['notBefore'].'</td></tr>';
-    }
-
-    if (isset($metadata['memory'])) {
-        echo '<tr><td>Memory usage</td><td>'.$metadata['memory'].' MB'.'</td></tr>';
-    }
-
-    if (isset($metadata['time'])) {
-        echo '<tr><td>Execution time</td><td>'.$metadata['time'].' seconds'.'</td></tr>';
-    }
-
-    if (isset($metadata['lastlinehash'])) {
-        echo '<tr><td>SHA1 of last processed logline</td><td>'.$metadata['lastlinehash'].'</td></tr>';
-    }
-
-    if (isset($metadata['lastline'])) {
-        echo '<tr><td>Last processed logline</td><td>'.$metadata['lastline'].'</td></tr>';
-    }
-} else {
-    echo '<tr><td>No metadata found</td></tr>';
-}
-
-echo '</table>';
-echo '<p>[ <a href="'.SimpleSAML\Module::getModuleURL("statistics/showstats.php").'">Show statistics</a> ] </p>';
-
-$this->includeAtTemplateBase('includes/footer.php');
diff --git a/modules/statistics/templates/statmeta.twig b/modules/statistics/templates/statmeta.twig
deleted file mode 100644
index 100a8c886c134e64200ac56ce1382b1f0674821b..0000000000000000000000000000000000000000
--- a/modules/statistics/templates/statmeta.twig
+++ /dev/null
@@ -1,40 +0,0 @@
-{% set pagetitle = 'SimpleSAMLphp Statistics Metadata'|trans %}
-{% extends "base.twig" %}
-
-{% block preload %}
-    <link href="/{{ baseurlpath }}modules.php/statistics/assets/css/statistics.css" rel="stylesheet">
-{% endblock %}
-
-{% block content %}
-    <h2>{{ pagetitle }}</h2>
-    <table id="statmeta">
-    {% if metadata is defined %}
-        {% if metadata.lastrun is defined %}
-            <tr><td>Aggregator last run at</td><td>{{ metadata.lastrun|date }}</td></tr>
-        {% endif %}
-
-        {% if metadata.notBefore is defined %}
-            <tr><td>Aggregated data until</td><td>{{ metadata.notBefore|date }}</td></tr>
-        {% endif %}
-
-        {% if metadata.memory is defined %}
-            <tr><td>Memory usage</td><td>{{ metadata.memory }} MB</td></tr>
-        {% endif %}
-
-        {% if metadata.memory is defined %}
-            <tr><td>Execution time</td><td>{{ metadata.time }} seconds</td></tr>
-        {% endif %}
-
-        {% if metadata.memory is defined %}
-            <tr><td>SHA1 of last processed logline</td><td>{{ metadata.lastlinehash }}</td></tr>
-        {% endif %}
-
-        {% if metadata.memory is defined %}
-            <tr><td>Last processed logline</td><td>{{ metadata.lastline }}</td></tr>
-        {% endif %}
-    {% else %}
-        <tr><td>No metadata found</td></tr>
-    {% endif %}
-    </table>
-    <p>[ <a href="/{{ baseurlpath }}module.php/statistics/showstats.php">Show statistics</a> ]</p>
-{% endblock %}
diff --git a/modules/statistics/www/assets/css/statistics.css b/modules/statistics/www/assets/css/statistics.css
deleted file mode 100644
index 4d0d163d600681ffe26fa34cee7cd7cbd9505bc4..0000000000000000000000000000000000000000
--- a/modules/statistics/www/assets/css/statistics.css
+++ /dev/null
@@ -1,127 +0,0 @@
-@media all {
-    div#content {
-        margin: .4em ! important;
-    }
-
-    .tableview {
-        border-collapse: collapse;
-        border: 1px solid #ccc;
-        margin: 1em;
-        width: 80%;
-    }
-
-    .tableview th, .tableview td {
-        border: 1px solid #ccc;
-        padding: 0px 5px;
-    }
-
-    .tableview th {
-        background: #e5e5e5;
-    }
-
-    .tableview tr.total td {
-        color: #500; font-weight: bold;
-    }
-
-    .tableview tr.even td {
-        background: #f5f5f5;
-        border-top: 1px solid #e0e0e0;
-        border-bottom: 1px solid #e0e0e0;
-    }
-
-    .tableview th.value, .tableview td.value {
-        text-align: right;
-    }
-
-    table.timeseries tr.odd td {
-        background-color: #f4f4f4;
-    }
-
-    table.timeseries td {
-        padding-right: 2em; border: 1px solid #ccc
-    }
-
-    td.datacontent {
-        text-align: right;
-    }
-
-    table.selecttime {
-        width: 100%;
-        border: 1px solid #ccc;
-        background: #eee;
-        margin: 1px 0px; padding: 0px;
-    }
-
-    td.selecttime_icon {
-        width: 50px;
-        padding: 0px;
-    }
-
-    td.selecttime_icon img {
-        margin: 0px;
-    }
-
-    td.selecttime_link_grey {
-        color: #ccc;
-    }
-
-    td.td_right {
-        text-align: right;
-    }
-    td.td_next_right {
-        padding-right: 4px;
-    }
-    td.td_left {
-        text-align: left;
-    }
-
-    p.p_right {
-        text-align: right;
-    }
-
-    form {
-        display: inline;
-    }
-
-    table#statmeta {
-        width: 100%;
-    }
-
-    ul.tabset_tabs {
-        margin: 0px;
-        padding: 0px;
-        list-style: none;
-    }
-
-    ul.tabset_tabs li {
-        background: none;
-        color: #222;
-        display: inline-block;
-        padding: 10px 15px;
-        cursor: pointer;
-    }
-
-    ul.tabset_tabs li.current {
-        background: #ededed;
-        color: #222;
-    }
-
-    .tabset_content {
-        display: none;
-        background: #ededed;
-        padding: 15px;
-    }
-
-    .tabset_content.current {
-        display: inherit;
-    }
-
-    #graph img {
-        max-width: 77%;
-        height: auto;
-    }
-    #table img {
-        max-width: 77%;
-        height: auto;
-    }
-}
diff --git a/modules/statistics/www/assets/js/statistics.js b/modules/statistics/www/assets/js/statistics.js
deleted file mode 100644
index 54a72551d90bc1b501e5c2d01f0b83879af7efcc..0000000000000000000000000000000000000000
--- a/modules/statistics/www/assets/js/statistics.js
+++ /dev/null
@@ -1,8 +0,0 @@
-$(document).ready(function () {
-    $("#tabdiv").tabs();
-    $('ul.tabset_tabs li').click(
-        function () {
-            $("html, body").animate({ scrollTop: 0 }, "slow");
-        }
-    )
-});
diff --git a/modules/statistics/www/showstats.php b/modules/statistics/www/showstats.php
deleted file mode 100644
index 544a9c4f7a851a15b223db6fa099bc5446e0418d..0000000000000000000000000000000000000000
--- a/modules/statistics/www/showstats.php
+++ /dev/null
@@ -1,190 +0,0 @@
-<?php
-
-$config = \SimpleSAML\Configuration::getInstance();
-$statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
-$session = \SimpleSAML\Session::getSessionFromRequest();
-$t = new \SimpleSAML\XHTML\Template($config, 'statistics:statistics.tpl.php');
-
-\SimpleSAML\Module\statistics\AccessCheck::checkAccess($statconfig);
-
-/*
- * Check input parameters
- */
-$preferRule = null;
-$preferRule2 = null;
-$preferTime = null;
-$preferTimeRes = null;
-$delimiter = null;
-
-if (array_key_exists('rule', $_REQUEST)) {
-    $preferRule = $_REQUEST['rule'];
-}
-if (array_key_exists('rule2', $_REQUEST)) {
-    $preferRule2 = $_REQUEST['rule2'];
-}
-if (array_key_exists('time', $_REQUEST)) {
-    $preferTime = $_REQUEST['time'];
-}
-if (array_key_exists('res', $_REQUEST)) {
-    $preferTimeRes = $_REQUEST['res'];
-}
-if (array_key_exists('d', $_REQUEST)) {
-    $delimiter = $_REQUEST['d'];
-    $t->data['request_d'] = $delimiter;
-}
-
-if ($preferRule2 === '_') {
-    $preferRule2 = null;
-}
-
-/*
- * Create statistics data.
- */
-$ruleset = new \SimpleSAML\Module\statistics\Ruleset($statconfig);
-$statrule = $ruleset->getRule($preferRule);
-$rule = $statrule->getRuleID();
-
-$t->data['pageid'] = 'statistics';
-$t->data['header'] = 'stat';
-$t->data['available_rules'] = $ruleset->availableRulesNames();
-$t->data['selected_rule'] = $rule;
-$t->data['selected_rule2'] = $preferRule2;
-
-try {
-    $dataset = $statrule->getDataset($preferTimeRes, $preferTime);
-    $dataset->setDelimiter($delimiter);
-    $dataset->aggregateSummary();
-    $dataset->calculateMax();
-
-    if (array_key_exists('output', $_REQUEST) && $_REQUEST['output'] === 'csv') {
-        header('Content-type: text/csv');
-        header('Content-Disposition: attachment; filename="simplesamlphp-data.csv"');
-        $data = $dataset->getDebugData();
-        foreach ($data as $de) {
-            if (isset($de[1])) {
-                echo '"'.$de[0].'",'.$de[1]."\n";
-            }
-        }
-        exit;
-    }
-} catch (\Exception $e) {
-    $t->data['error'] = "No data available";
-    $t->show();
-    exit;
-}
-
-$delimiter = $dataset->getDelimiter();
-
-$timeres = $dataset->getTimeRes();
-$fileslot = $dataset->getFileslot();
-
-$timeNavigation = $statrule->getTimeNavigation($timeres, $preferTime);
-
-$piedata = $dataset->getPieData();
-
-$datasets = [];
-$datasets[] = $dataset->getPercentValues();
-
-$axis = $dataset->getAxis();
-
-$maxes = [];
-
-$maxes[] = $dataset->getMax();
-
-$t->data['selected_time'] = $fileslot;
-$t->data['selected_timeres'] = $timeres;
-$t->data['post_d'] = getBaseURL($t, 'post', 'd');
-
-if (isset($preferRule2)) {
-    $statrule = $ruleset->getRule($preferRule2);
-    try {
-        $dataset2 = $statrule->getDataset($preferTimeRes, $preferTime);
-        $dataset2->aggregateSummary();
-        $dataset2->calculateMax();
-
-        $datasets[] = $dataset2->getPercentValues();
-        $maxes[] = $dataset2->getMax();
-    } catch (\Exception $e) {
-        $t->data['error'] = "No data available to compare";
-        $t->show();
-        exit;
-    }
-}
-
-$dimx = $statconfig->getValue('dimension.x', 800);
-$dimy = $statconfig->getValue('dimension.y', 350);
-$grapher = new \SimpleSAML\Module\statistics\Graph\GoogleCharts($dimx, $dimy);
-
-$t->data['imgurl'] = $grapher->show($axis['axis'], $axis['axispos'], $datasets, $maxes);
-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();
-$t->data['available_times_prev'] = $timeNavigation['prev'];
-$t->data['available_times_next'] = $timeNavigation['next'];
-
-$t->data['current_rule'] = $t->data['available_rules'][$rule];
-
-$t->data['selected_rule'] = $rule;
-$t->data['selected_rule2'] = $preferRule2;
-$t->data['selected_delimiter'] = $delimiter;
-
-$t->data['debugdata'] = $dataset->getDebugData();
-$t->data['results'] = $dataset->getResults();
-$t->data['summaryDataset'] = $dataset->getSummary();
-$t->data['topdelimiters'] = $dataset->getTopDelimiters();
-
-$t->data['post_rule'] = getBaseURL($t, 'post', 'rule');
-$t->data['post_rule2'] = getBaseURL($t, 'post', 'rule2');
-$t->data['post_res'] = getBaseURL($t, 'post', 'res');
-$t->data['post_time'] = getBaseURL($t, 'post', 'time');
-$t->data['get_times_prev'] = getBaseURL($t, 'get', 'time', $t->data['available_times_prev']);
-$t->data['get_times_next'] = getBaseURL($t, 'get', 'time', $t->data['available_times_next']);
-
-$t->data['availdelimiters'] = $dataset->availDelimiters();
-$t->data['delimiterPresentation'] = $dataset->getDelimiterPresentation();
-
-$t->data['jquery'] = ['core' => false, 'ui' => true, 'css' => true];
-
-$t->show();
-
-
-/**
- * @param \SimpleSAML\XHTML\Template $t
- * @param string $type
- * @param string|null $key
- * @param string|null $value
- * @return string|array
- */
-function getBaseURL($t, $type = 'get', $key = null, $value = null)
-{
-    $vars = [
-        'rule' => $t->data['selected_rule'],
-        'time' => $t->data['selected_time'],
-        'res' => $t->data['selected_timeres'],
-    ];
-    if (isset($t->data['selected_delimiter'])) {
-        $vars['d'] = $t->data['selected_delimiter'];
-    }
-    if (!empty($t->data['selected_rule2']) && $t->data['selected_rule2'] !== '_') {
-        $vars['rule2'] = $t->data['selected_rule2'];
-    }
-
-    if (isset($key)) {
-        if (isset($vars[$key])) {
-            unset($vars[$key]);
-        }
-        if (isset($value)) {
-            $vars[$key] = $value;
-        }
-    }
-
-    if ($type === 'get') {
-        return \SimpleSAML\Module::getModuleURL("statistics/showstats.php").'?'.http_build_query($vars, '', '&amp;');
-    }
-
-    return $vars;
-}
diff --git a/modules/statistics/www/statmeta.php b/modules/statistics/www/statmeta.php
deleted file mode 100644
index dd252bb26e1b66f21b21e5c63ca3b9067be4c8c3..0000000000000000000000000000000000000000
--- a/modules/statistics/www/statmeta.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-$config = \SimpleSAML\Configuration::getInstance();
-$statconfig = \SimpleSAML\Configuration::getConfig('module_statistics.php');
-
-\SimpleSAML\Module\statistics\AccessCheck::checkAccess($statconfig);
-
-$aggr = new \SimpleSAML\Module\statistics\Aggregator();
-$aggr->loadMetadata();
-$metadata = $aggr->getMetadata();
-
-$t = new \SimpleSAML\XHTML\Template($config, 'statistics:statmeta.tpl.php');
-
-if ($metadata !== null) {
-    if (in_array('lastrun', $metadata, true)) {
-        $metadata['lastrun'] = date('l jS \of F Y H:i:s', $metadata['lastrun']);
-    }
-    if (in_array('notBefore', $metadata, true)) {
-        $metadata['notBefore'] = date('l jS \of F Y H:i:s', $metadata['notBefore']);
-    }
-    if (in_array('memory', $metadata, true)) {
-        $metadata['memory'] = number_format($metadata['memory'] / (1024 * 1024), 2);
-    }
-    $t->data['metadata'] = $metadata;
-}
-
-$t->show();