diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index 28737c58e35e49feec943e59bc7c5ee964fe4090..e2a9fdbc1cf29657dba19a436c2a26c361d543f4 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -198,7 +198,7 @@ class SimpleSAML_Configuration implements \SimpleSAML\Utils\ClearableState
 
 
     /**
-     * Load a configuration file from a configuration set.XM
+     * Load a configuration file from a configuration set.
      *
      * @param string $filename The name of the configuration file.
      * @param string $configSet The configuration set. Optional, defaults to 'simplesaml'.
diff --git a/tests/Utils/ClearStateTestCase.php b/tests/Utils/ClearStateTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..701dba29f95beb7b5e2d92063c8f071980ed313d
--- /dev/null
+++ b/tests/Utils/ClearStateTestCase.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace SimpleSAML\Test\Utils;
+
+include(dirname(__FILE__) . '/StateClearer.php');
+
+/**
+ * A base SSP test case that takes care of removing global state prior to test runs
+ */
+class ClearStateTestCase extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Used for managing and clearing state
+     * @var StateClearer
+     */
+    protected static $stateClearer;
+
+    public static function setUpBeforeClass()
+    {
+        if (!self::$stateClearer) {
+            self::$stateClearer = new StateClearer();
+            self::$stateClearer->backupGlobals();
+        }
+    }
+
+
+    protected function setUp()
+    {
+        self::clearState();
+    }
+
+    public static function tearDownAfterClass()
+    {
+        self::clearState();
+    }
+
+
+    /**
+     * Clear any SSP global state to reduce spill over between tests.
+     */
+    public static function clearState()
+    {
+        self::$stateClearer->clearGlobals();
+        self::$stateClearer->clearSSPState();
+    }
+}
diff --git a/tests/Utils/ClearStateTestListener.php b/tests/Utils/ClearStateTestListener.php
deleted file mode 100644
index 7a92fac854cac816e3fac5e70f9ce00ae2c0bc98..0000000000000000000000000000000000000000
--- a/tests/Utils/ClearStateTestListener.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-namespace SimpleSAML\Test\Utils;
-
-use PHPUnit_Framework_Test;
-use PHPUnit_Framework_TestSuite;
-
-/**
- * A PHPUnit test listener that attempts to clear global state and cached SSP configuration between test run
- */
-class ClearStateTestListener extends \PHPUnit_Framework_BaseTestListener
-{
-
-    /**
-     * Global state to restore between test runs
-     * @var array
-     */
-    private static $backups = array();
-
-    /**
-     * Class that implement \SimpleSAML\Utils\ClearableState and should have clearInternalState called between tests
-     * @var array
-     */
-    private static $clearableState = array('SimpleSAML_Configuration');
-
-    /**
-     * Variables
-     * @var array
-     */
-    private static $vars_to_unset = array('SIMPLESAMLPHP_CONFIG_DIR');
-
-    public function __construct()
-    {
-        // Backup any state that is needed as part of processing, so we can restore it later.
-        // TODO: phpunit's backupGlobals = false, yet we are trying to do a similar thing here. Is that an issue?
-        if (!self::$backups) {
-            self::$backups['$_COOKIE'] = $_COOKIE;
-            self::$backups['$_ENV'] = $_ENV;
-            self::$backups['$_FILES'] = $_FILES;
-            self::$backups['$_GET'] = $_GET;
-            self::$backups['$_POST'] = $_POST;
-            self::$backups['$_SERVER'] = $_SERVER;
-            self::$backups['$_SESSION'] = isset($_SESSION) ? $_SESSION : array();
-            self::$backups['$_REQUEST'] = $_REQUEST;
-        }
-    }
-
-    /**
-     * Clear any state needed prior to a test file running
-     */
-    public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
-    {
-        // TODO: decide how to handle tests that want to set suite level settings with setUpBeforeClass()
-    }
-
-    /**
-     * Clear any state needed prior to a test case
-     * @param PHPUnit_Framework_Test $test
-     */
-    public function startTest(PHPUnit_Framework_Test $test)
-    {
-        $_COOKIE = self::$backups['$_COOKIE'];
-        $_ENV = self::$backups['$_ENV'];
-        $_FILES = self::$backups['$_FILES'];
-        $_GET = self::$backups['$_GET'];
-        $_POST = self::$backups['$_POST'];
-        $_SERVER = self::$backups['$_SERVER'];
-        $_SESSION = self::$backups['$_SESSION'];
-        $_REQUEST = self::$backups['$_REQUEST'];
-
-        foreach (self::$clearableState as $var) {
-            $var::clearInternalState();
-        }
-
-        foreach (self::$vars_to_unset as $var) {
-            putenv($var);
-        }
-    }
-}
diff --git a/tests/Utils/ReduceSpillOverTest.php b/tests/Utils/ReduceSpillOverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c1022209bb38225ad37e6042e82001b2d274839
--- /dev/null
+++ b/tests/Utils/ReduceSpillOverTest.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace SimpleSAML\Test\Utils;
+
+/**
+ * Test that ensures state doesn't spill over between tests
+ * @package SimpleSAML\Test\Utils
+ */
+class ReduceSpillOverTest extends ClearStateTestCase
+{
+
+    /**
+     * Set some global state
+     */
+    public function testSetState()
+    {
+        $_SERVER['QUERY_STRING'] = 'a=b';
+        \SimpleSAML_Configuration::loadFromArray(array('a' => 'b'), '[ARRAY]', 'simplesaml');
+        $this->assertEquals('b', \SimpleSAML_Configuration::getInstance()->getString('a'));
+        putenv('SIMPLESAMLPHP_CONFIG_DIR=' . __DIR__);
+    }
+
+    /**
+     * Confirm global state removed prior to next test
+     */
+    public function testStateRemoved()
+    {
+
+        $this->assertArrayNotHasKey('QUERY_STRING', $_SERVER);
+        $this->assertFalse(getenv('SIMPLESAMLPHP_CONFIG_DIR'));
+        try {
+            \SimpleSAML_Configuration::getInstance();
+            $this->fail('Expected config configured in other tests to no longer be valid');
+        } catch (\SimpleSAML\Error\ConfigurationError $error) {
+            // Expected error
+        }
+    }
+}
diff --git a/tests/Utils/StateClearer.php b/tests/Utils/StateClearer.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d074d5b1a861a0b1e149a6fa1cf5ee94183352e
--- /dev/null
+++ b/tests/Utils/StateClearer.php
@@ -0,0 +1,76 @@
+<?php
+namespace SimpleSAML\Test\Utils;
+
+/**
+ * A helper class to aid in clearing global state that is set during SSP tests
+ */
+class StateClearer
+{
+
+    /**
+     * Global state to restore between test runs
+     * @var array
+     */
+    private $backups = array();
+
+    /**
+     * Class that implement \SimpleSAML\Utils\ClearableState and should have clearInternalState called between tests
+     * @var array
+     */
+    private $clearableState = array('SimpleSAML_Configuration');
+
+    /**
+     * Environmental variables to unset
+     * @var array
+     */
+    private $vars_to_unset = array('SIMPLESAMLPHP_CONFIG_DIR');
+
+    public function backupGlobals()
+    {
+        // Backup any state that is needed as part of processing, so we can restore it later.
+        // TODO: phpunit's backupGlobals = false, yet we are trying to do a similar thing here. Is that an issue?
+        $this->backups['$_COOKIE'] = $_COOKIE;
+        $this->backups['$_ENV'] = $_ENV;
+        $this->backups['$_FILES'] = $_FILES;
+        $this->backups['$_GET'] = $_GET;
+        $this->backups['$_POST'] = $_POST;
+        $this->backups['$_SERVER'] = $_SERVER;
+        $this->backups['$_SESSION'] = isset($_SESSION) ? $_SESSION : array();
+        $this->backups['$_REQUEST'] = $_REQUEST;
+    }
+
+
+    /**
+     * Clear any global state.
+     */
+    public function clearGlobals()
+    {
+        if (!empty($this->backups)) {
+            $_COOKIE = $this->backups['$_COOKIE'];
+            $_ENV = $this->backups['$_ENV'];
+            $_FILES = $this->backups['$_FILES'];
+            $_GET = $this->backups['$_GET'];
+            $_POST = $this->backups['$_POST'];
+            $_SERVER = $this->backups['$_SERVER'];
+            $_SESSION = $this->backups['$_SESSION'];
+            $_REQUEST = $this->backups['$_REQUEST'];
+        } else {
+            //TODO: what should this behavior be?
+        }
+    }
+
+    /**
+     * Clear any SSP specific state, such as SSP enviormental variables or cached internals.
+     */
+    public function clearSSPState()
+    {
+
+        foreach ($this->clearableState as $var) {
+            $var::clearInternalState();
+        }
+
+        foreach ($this->vars_to_unset as $var) {
+            putenv($var);
+        }
+    }
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ec9274b9b08c126d52bc3286c5b9c877eed2a4e
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,7 @@
+<?php
+
+$projectRoot = dirname(__DIR__);
+require_once($projectRoot . '/vendor/autoload.php');
+
+// Current SSP autoloader can't resolve classes from the tests folder.
+include($projectRoot . '/tests/Utils/ClearStateTestCase.php');
diff --git a/tools/phpunit/phpunit.xml b/tools/phpunit/phpunit.xml
index 4d455eb109e4b9f0a281d085f3ef739fbb84c16b..b82bc2077bff517bf5f5c806da56498b6bf68133 100644
--- a/tools/phpunit/phpunit.xml
+++ b/tools/phpunit/phpunit.xml
@@ -8,7 +8,7 @@
          processIsolation="false"
          stopOnFailure="false"
          syntaxCheck="false"
-         bootstrap="./../../vendor/autoload.php">
+         bootstrap="./../../tests/bootstrap.php">
     <testsuites>
         <testsuite name="Unit tests">
             <directory>./../../tests/</directory>
@@ -31,8 +31,4 @@
         <log type="coverage-html" target="build/coverage" title="PHP Coveralls" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70"/>
         <log type="coverage-clover" target="build/logs/clover.xml"/>
     </logging>
-    <listeners>
-        <listener class="\SimpleSAML\Test\Utils\ClearStateTestListener" file="./tests/Utils/ClearStateTestListener.php">
-        </listener>
-    </listeners>
 </phpunit>