diff --git a/lib/SimpleSAML/Auth/BWC.php b/lib/SimpleSAML/Auth/BWC.php
new file mode 100644
index 0000000000000000000000000000000000000000..538ca90443220f23dbcb55cb6c8d16f88681a325
--- /dev/null
+++ b/lib/SimpleSAML/Auth/BWC.php
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * Helper class for backwards compatibility with old-style authentication sources.
+ *
+ * Provides the same interface as Auth_Simple.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class SimpleSAML_Auth_BWC extends SimpleSAML_Auth_Simple {
+
+	/**
+	 * Our authentication handler.
+	 *
+	 * @var string
+	 */
+	private $auth;
+
+
+	/**
+	 * Our authority.
+	 *
+	 * @var string
+	 */
+	private $authority;
+
+
+	/**
+	 * Initialize a backwards-compatibility authsource for the given authentication page and authority.
+	 *
+	 * @param string $auth  The authentication page.
+	 * @param string|NULL $authority  The authority we should validate the login against.
+	 */
+	public function __construct($auth, $authority) {
+		assert('is_string($auth)');
+		assert('is_string($authority) || is_null($authority)');
+
+		if ($authority === NULL) {
+			$candidates = array(
+				'auth/login-admin.php' => 'login-admin',
+				'auth/login-cas-ldap.php' => 'login-cas-ldap',
+				'auth/login-ldapmulti.php' => 'login-ldapmulti',
+				'auth/login-radius.php' => 'login-radius',
+				'auth/login-tlsclient.php' => 'tlsclient',
+				'auth/login-wayf-ldap.php' => 'login-wayf-ldap',
+				'auth/login.php' => 'login',
+			);
+			if (!isset($candidates[$auth])) {
+				throw new SimpleSAML_Error_Exception('You must provide an authority when using ' . $auth);
+			}
+			$authority = $candidates[$auth];
+		}
+
+		$this->auth = $auth;
+		$this->authority = $authority;
+
+		parent::__construct($authority);
+	}
+
+
+	/**
+	 * Start a login operation.
+	 *
+	 * @param array $params  Various options to the authentication request.
+	 */
+	public function login(array $params = array()) {
+
+		if (array_key_exists('KeepPost', $params)) {
+			$keepPost = (bool)$params['KeepPost'];
+		} else {
+			$keepPost = TRUE;
+		}
+
+		if (!isset($params['ReturnTo']) && !isset($params['ReturnCallback'])) {
+			$params['ReturnTo'] = SimpleSAML_Utilities::selfURL();
+		}
+
+		if (isset($params['ReturnTo']) && $keepPost && $_SERVER['REQUEST_METHOD'] === 'POST') {
+			$params['ReturnTo'] = SimpleSAML_Utilities::createPostRedirectLink($params['ReturnTo'], $_POST);
+		}
+
+		$session = SimpleSAML_Session::getInstance();
+
+		$authnRequest = array(
+			'IsPassive' => isset($params['isPassive']) ? $params['isPassive'] : FALSE,
+			'ForceAuthn' => isset($params['ForceAuthn']) ? $params['ForceAuthn'] : FALSE,
+			'core:State' => $params,
+			'core:prevSession' => $session->getAuthData($this->authority, 'AuthnInstant'),
+			'core:authority' => $this->authority,
+		);
+
+		if (isset($params['saml:RequestId'])) {
+			$authnRequest['RequestID'] = $params['saml:RequestId'];
+		}
+		if (isset($params['SPMetadata']['entityid'])) {
+			$authnRequest['Issuer'] = $params['SPMetadata']['entityid'];
+		}
+		if (isset($params['saml:RelayState'])) {
+			$authnRequest['RelayState'] = $params['saml:RelayState'];
+		}
+		if (isset($params['saml:IDPList'])) {
+			$authnRequest['IDPList'] = $params['saml:IDPList'];
+		}
+
+		$authId = SimpleSAML_Utilities::generateID();
+		$session->setAuthnRequest('saml2', $authId, $authnRequest);
+
+		$relayState = SimpleSAML_Module::getModuleURL('core/bwc_resumeauth.php', array('RequestID' => $authId));
+
+		$config = SimpleSAML_Configuration::getInstance();
+		$authurl = '/' . $config->getBaseURL() . $this->auth;
+		SimpleSAML_Utilities::redirect($authurl, array(
+			'RelayState' => $relayState,
+			'AuthId' => $authId,
+			'protocol' => 'saml2',
+		));
+	}
+
+
+	/**
+	 * Start a logout operation.
+	 *
+	 * @param string|NULL $url  The url the user should be redirected to after logging out.
+	 *                          Defaults to the current page.
+	 */
+	public function logout($url = NULL) {
+
+		if ($url === NULL) {
+			$url = SimpleSAML_Utilities::selfURL();
+		}
+
+		$session = SimpleSAML_Session::getInstance();
+		if (!$session->isValid($this->authority)) {
+			/* Not authenticated to this authentication source. */
+			SimpleSAML_Utilities::redirect($url);
+			assert('FALSE');
+		}
+
+		if ($this->authority === 'saml2') {
+			$config = SimpleSAML_Configuration::getInstance();
+			SimpleSAML_Utilities::redirect('/' . $config->getBaseURL() . 'saml2/sp/initSLO.php',
+				array('RelayState' => $url)
+			);
+		}
+
+		$session->doLogout($this->authority);
+
+		SimpleSAML_Utilities::redirect($url);
+	}
+
+}
diff --git a/modules/core/www/bwc_resumeauth.php b/modules/core/www/bwc_resumeauth.php
new file mode 100644
index 0000000000000000000000000000000000000000..5da50c3dccb85e0d00b43a7a264a5b792956a81c
--- /dev/null
+++ b/modules/core/www/bwc_resumeauth.php
@@ -0,0 +1,31 @@
+<?php
+
+if (!isset($_REQUEST['RequestID'])) {
+	throw new SimpleSAML_Error_BadRequest('Missing required URL parameter.');
+}
+
+/* Backwards-compatibility with old authentication pages. */
+$session = SimpleSAML_Session::getInstance();
+$requestcache = $session->getAuthnRequest('saml2', (string)$_REQUEST['RequestID']);
+if (!$requestcache) {
+	throw new Exception('Could not retrieve cached RequestID = ' . $authId);
+}
+
+$authority = $requestcache['core:authority'];
+
+$state = $requestcache['core:State'];
+
+if ($requestcache['ForceAuthn'] && $requestcache['core:prevSession'] === $session->getAuthData($authority, 'AuthnInstant')) {
+	throw new Exception('ForceAuthn set, but timestamp not updated.');
+}
+
+if (isset($state['ReturnTo'])) {
+	SimpleSAML_Utilities::redirect($state['ReturnTo']);
+}
+
+foreach ($session->getAuthState($authority) as $k => $v) {
+	$state[$k] = $v;
+}
+
+call_user_func($state['ReturnCallback'], $state);
+assert('FALSE');