diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index a43dc88f4100dd4310f3d78fa7548d9e69eb5966..6aa0d939510973efb20ea739860be418309efcb6 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -138,6 +138,31 @@ $config = array(
             'result-scroller' => 'VuFind\Controller\Plugin\ResultScroller',
         )
     ),
+    'ils_driver_plugin_manager' => array(
+        'abstract_factories' => array('VuFind\ILS\Driver\PluginFactory'),
+        'invokables' => array(
+            'aleph' => 'VuFind\ILS\Driver\Aleph',
+            'amicus' => 'VuFind\ILS\Driver\Amicus',
+            'daia' => 'VuFind\ILS\Driver\DAIA',
+            'demo' => 'VuFind\ILS\Driver\Demo',
+            'evergreen' => 'VuFind\ILS\Driver\Evergreen',
+            'horizon' => 'VuFind\ILS\Driver\Horizon',
+            'horizonxmlapi' => 'VuFind\ILS\Driver\HorizonXMLAPI',
+            'innovative' => 'VuFind\ILS\Driver\Innovative',
+            'koha' => 'VuFind\ILS\Driver\Koha',
+            'newgenlib' => 'VuFind\ILS\Driver\NewGenLib',
+            'noils' => 'VuFind\ILS\Driver\NoILS',
+            'pica' => 'VuFind\ILS\Driver\PICA',
+            'sample' => 'VuFind\ILS\Driver\Sample',
+            'symphony' => 'VuFind\ILS\Driver\Symphony',
+            'unicorn' => 'VuFind\ILS\Driver\Unicorn',
+            'virtua' => 'VuFind\ILS\Driver\Virtua',
+            'voyager' => 'VuFind\ILS\Driver\Voyager',
+            'voyagerrestful' => 'VuFind\ILS\Driver\VoyagerRestful',
+            'xcncip' => 'VuFind\ILS\Driver\XCNCIP',
+            'xcncip2' => 'VuFind\ILS\Driver\XCNCIP2',
+        ),
+    ),
     'recommend_plugin_manager' => array(
         'abstract_factories' => array('VuFind\Recommend\PluginFactory'),
         'invokables' => array(
diff --git a/module/VuFind/src/VuFind/Bootstrap.php b/module/VuFind/src/VuFind/Bootstrap.php
index 99b1257c46d87d746fd01b81e6e3a2a77000ea5f..0f1a5135b42299a3f8febf07a828def83dfb059d 100644
--- a/module/VuFind/src/VuFind/Bootstrap.php
+++ b/module/VuFind/src/VuFind/Bootstrap.php
@@ -90,11 +90,13 @@ class Bootstrap
         $config = $app->getConfig();
 
         // Use naming conventions to set up a bunch of services based on namespace:
-        $namespaces = array('Auth', 'Autocomplete', 'Recommend', 'Session');
+        $namespaces = array(
+            'Auth', 'Autocomplete', 'ILS\Driver', 'Recommend', 'Session'
+        );
         foreach ($namespaces as $ns) {
-            $serviceName = $ns . 'PluginManager';
+            $serviceName = str_replace('\\', '', $ns) . 'PluginManager';
             $className = 'VuFind\\' . $ns . '\PluginManager';
-            $configKey = strtolower($ns) . '_plugin_manager';
+            $configKey = strtolower(str_replace('\\', '_', $ns)) . '_plugin_manager';
             $service = new $className(
                 new ServiceManagerConfig($config[$configKey])
             );
@@ -109,6 +111,9 @@ class Bootstrap
         $manager = new \VuFind\Search\Manager($config['search_manager']);
         $manager->setServiceLocator($serviceManager);
         $serviceManager->setService('SearchManager', $manager);
+
+        // TODO: factor out static connection manager.
+        \VuFind\Connection\Manager::setServiceLocator($serviceManager);
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/Connection/Manager.php b/module/VuFind/src/VuFind/Connection/Manager.php
index ff8231da477aa65883e9185c2ea77ab53a649192..cdd6d0b3559e1f505b56f5a20e39b270cbf80dc1 100644
--- a/module/VuFind/src/VuFind/Connection/Manager.php
+++ b/module/VuFind/src/VuFind/Connection/Manager.php
@@ -27,7 +27,8 @@
  */
 namespace VuFind\Connection;
 
-use VuFind\Config\Reader as ConfigReader, VuFind\ILS\Connection as ILSConnection;
+use VuFind\Config\Reader as ConfigReader, VuFind\ILS\Connection as ILSConnection,
+    Zend\ServiceManager\ServiceLocatorInterface;
 
 /**
  * Central class for connecting to resources used by VuFind.
@@ -40,6 +41,20 @@ use VuFind\Config\Reader as ConfigReader, VuFind\ILS\Connection as ILSConnection
  */
 class Manager
 {
+    protected static $serviceLocator;
+
+    /**
+     * Set the service locator.
+     *
+     * @param ServiceLocatorInterface $serviceLocator Locator to register
+     *
+     * @return void
+     */
+    public static function setServiceLocator(ServiceLocatorInterface $serviceLocator)
+    {
+        self::$serviceLocator = $serviceLocator;
+    }
+
     /**
      * Connect to the catalog.
      *
@@ -52,7 +67,10 @@ class Manager
         // remember the old connection and return that instead of starting over.
         static $catalog = false;
         if ($catalog === false) {
+            $config = ConfigReader::getConfig();
             $catalog = new ILSConnection();
+            $catalog->setServiceLocator(self::$serviceLocator);
+            $catalog->setConfig($config->Catalog);
         }
 
         return $catalog;
diff --git a/module/VuFind/src/VuFind/ILS/Connection.php b/module/VuFind/src/VuFind/ILS/Connection.php
index adec157af0f6e7c943a9cc3cc69ad55fffb77513..0ffca7c867ba415281ffbcded37c05efdc2e983d 100644
--- a/module/VuFind/src/VuFind/ILS/Connection.php
+++ b/module/VuFind/src/VuFind/ILS/Connection.php
@@ -30,7 +30,9 @@
  * @link     http://vufind.org/wiki/building_an_ils_driver Wiki
  */
 namespace VuFind\ILS;
-use VuFind\Config\Reader as ConfigReader, VuFind\Exception\ILS as ILSException;
+use VuFind\Config\Reader as ConfigReader, VuFind\Exception\ILS as ILSException,
+    Zend\ServiceManager\ServiceLocatorAwareInterface,
+    Zend\ServiceManager\ServiceLocatorInterface;
 
 /**
  * Catalog Connection Class
@@ -48,52 +50,78 @@ use VuFind\Config\Reader as ConfigReader, VuFind\Exception\ILS as ILSException;
 class Connection
 {
     /**
-     * The class of the appropriate driver.
+     * Has the driver been initialized yet?
      *
-     * @var string
+     * @var bool
      */
-    protected $driverClass;
+    protected $driverInitialized = false;
 
     /**
      * The object of the appropriate driver.
      *
      * @var object
      */
-    protected $driver = false;
+    protected $driver;
 
     /**
-     * Constructor
+     * The service locator
      *
-     * @throws ILSException
+     * @var ServiceLocatorInterface
+     */
+    protected $serviceLocator;
+
+    /**
+     * ILS configuration
+     *
+     * @var \Zend\Config\Config
      */
-    public function __construct()
+    protected $config;
+
+    /**
+     * Set the configuration of the connection.
+     *
+     * @param \Zend\Config\Config $config Configuration representing the [Catalog]
+     * section of config.ini
+     *
+     * @return void
+     */
+    public function setConfig($config)
     {
-        $config = ConfigReader::getConfig();
-        if (!isset($config->Catalog->driver)) {
+        $this->config = $config;
+
+        if (!isset($config->driver)) {
             throw new ILSException('ILS driver setting missing.');
         }
-        $class = 'VuFind\ILS\Driver\\' . $config->Catalog->driver;
-        if (!class_exists($class)) {
+        $driverManager = $this->getServiceLocator()->get('ILSDriverPluginManager');
+        $service = $config->driver;
+        if (!$driverManager->has($service)) {
             // Don't throw ILSException here -- we don't want this to be
             // treated as a login problem; it's more serious than that!
-            throw new \Exception('ILS driver missing: ' . $class);
+            throw new \Exception('ILS driver missing: ' . $service);
         }
-        $this->driverClass = $class;
+        $this->driver = $driverManager->get($service);
 
         // If we're configured to fail over to the NoILS driver, we need
         // to test if the main driver is working.
-        if (isset($config->Catalog->loadNoILSOnFailure)
-            && $config->Catalog->loadNoILSOnFailure
-        ) {
+        if (isset($config->loadNoILSOnFailure) && $config->loadNoILSOnFailure) {
             try {
                 $this->getDriver();
             } catch (\Exception $e) {
-                $this->driver = false;
-                $this->driverClass = 'VuFind\ILS\Driver\NoILS';
+                $this->driver = $driverManager->get('NoILS');
             }
         }
     }
 
+    /**
+     * Get class name of the driver object.
+     *
+     * @return string
+     */
+    public function getDriverClass()
+    {
+        return get_class($this->driver);
+    }
+
     /**
      * Get access to the driver object.
      *
@@ -102,10 +130,10 @@ class Connection
      */
     public function getDriver()
     {
-        if (!$this->driver) {
-            $this->driver = new $this->driverClass;
+        if (!$this->driverInitialized) {
             $this->driver->setConfig($this->getDriverConfig());
             $this->driver->init();
+            $this->driverInitialized = true;
         }
         return $this->driver;
     }
@@ -120,7 +148,7 @@ class Connection
     public function getDriverConfig()
     {
         // Determine config file name based on class name:
-        $parts = explode('\\', $this->driverClass);
+        $parts = explode('\\', $this->getDriverClass());
         $configFile = end($parts) . '.ini';
         $configFilePath = ConfigReader::getConfigPath($configFile);
         return file_exists($configFilePath)
@@ -141,7 +169,7 @@ class Connection
     public function checkFunction($function)
     {
         // Extract the configuration from the driver if available:
-        $functionConfig = method_exists($this->driverClass, 'getConfig')
+        $functionConfig = method_exists($this->getDriverClass(), 'getConfig')
             ? $this->getDriver()->getConfig($function) : false;
 
         // See if we have a corresponding check method to analyze the response:
@@ -170,7 +198,7 @@ class Connection
         $response = false;
 
         if ($this->getHoldsMode() != "none"
-            && method_exists($this->driverClass, 'placeHold')
+            && method_exists($this->getDriverClass(), 'placeHold')
             && isset($functionConfig['HMACKeys'])
         ) {
             $response = array('function' => "placeHold");
@@ -182,7 +210,7 @@ class Connection
             if (isset($functionConfig['extraHoldFields'])) {
                 $response['extraHoldFields'] = $functionConfig['extraHoldFields'];
             }
-        } else if (method_exists($this->driverClass, 'getHoldLink')) {
+        } else if (method_exists($this->getDriverClass(), 'getHoldLink')) {
             $response = array('function' => "getHoldLink");
         }
         return $response;
@@ -203,14 +231,13 @@ class Connection
     protected function checkMethodcancelHolds($functionConfig)
     {
         $response = false;
-        $config = ConfigReader::getConfig();
 
-        if ($config->Catalog->cancel_holds_enabled == true
-            && method_exists($this->driverClass, 'cancelHolds')
+        if ($this->config->cancel_holds_enabled == true
+            && method_exists($this->getDriverClass(), 'cancelHolds')
         ) {
             $response = array('function' => "cancelHolds");
-        } else if ($config->Catalog->cancel_holds_enabled == true
-            && method_exists($this->driverClass, 'getCancelHoldLink')
+        } else if ($this->config->cancel_holds_enabled == true
+            && method_exists($this->getDriverClass(), 'getCancelHoldLink')
         ) {
             $response = array('function' => "getCancelHoldLink");
         }
@@ -231,14 +258,13 @@ class Connection
     protected function checkMethodRenewals($functionConfig)
     {
         $response = false;
-        $config = ConfigReader::getConfig();
 
-        if ($config->Catalog->renewals_enabled == true
-            && method_exists($this->driverClass, 'renewMyItems')
+        if ($this->config->renewals_enabled == true
+            && method_exists($this->getDriverClass(), 'renewMyItems')
         ) {
             $response = array('function' => "renewMyItems");
-        } else if ($config->Catalog->renewals_enabled == true
-            && method_exists($this->driverClass, 'renewMyItemsLink')
+        } else if ($this->config->renewals_enabled == true
+            && method_exists($this->getDriverClass(), 'renewMyItemsLink')
         ) {
             $response = array('function' => "renewMyItemsLink");
         }
@@ -259,7 +285,7 @@ class Connection
      */
     public function checkRequestIsValid($id, $data, $patron)
     {
-        $method = array($this->driverClass, 'checkRequestIsValid');
+        $method = array($this->getDriverClass(), 'checkRequestIsValid');
         if (is_callable($method)) {
             return $this->getDriver()->checkRequestIsValid($id, $data, $patron);
         }
@@ -294,8 +320,8 @@ class Connection
     public function getOfflineMode()
     {
         // Graceful degradation -- return false if no method supported.
-        return method_exists($this->driverClass, 'getOfflineMode') ?
-            $this->getDriver()->getOfflineMode() : false;
+        return method_exists($this->getDriverClass(), 'getOfflineMode')
+            ? $this->getDriver()->getOfflineMode() : false;
     }
 
     /**
@@ -324,8 +350,8 @@ class Connection
     public function hasHoldings($id)
     {
         // Graceful degradation -- return true if no method supported.
-        return method_exists($this->driverClass, 'hasHoldings') ?
-            $this->getDriver()->hasHoldings($id) : true;
+        return method_exists($this->getDriverClass(), 'hasHoldings')
+            ? $this->getDriver()->hasHoldings($id) : true;
     }
 
     /**
@@ -338,8 +364,8 @@ class Connection
     public function loginIsHidden()
     {
         // Graceful degradation -- return false if no method supported.
-        return method_exists($this->driverClass, 'loginIsHidden') ?
-            $this->getDriver()->loginIsHidden() : false;
+        return method_exists($this->getDriverClass(), 'loginIsHidden')
+            ? $this->getDriver()->loginIsHidden() : false;
     }
 
     /**
@@ -354,11 +380,34 @@ class Connection
      */
     public function __call($methodName, $params)
     {
-        if (is_callable(array($this->driverClass, $methodName))) {
+        if (is_callable(array($this->getDriverClass(), $methodName))) {
             return call_user_func_array(
                 array($this->getDriver(), $methodName), $params
             );
         }
         throw new ILSException('Cannot call method: ' . $methodName);
     }
+
+    /**
+     * Set the service locator.
+     *
+     * @param ServiceLocatorInterface $serviceLocator Locator to register
+     *
+     * @return Connection
+     */
+    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
+    {
+        $this->serviceLocator = $serviceLocator;
+        return $this;
+    }
+
+    /**
+     * Get the service locator.
+     *
+     * @return \Zend\ServiceManager\ServiceLocatorInterface
+     */
+    public function getServiceLocator()
+    {
+        return $this->serviceLocator;
+    }
 }
diff --git a/module/VuFind/src/VuFind/ILS/Driver/PluginFactory.php b/module/VuFind/src/VuFind/ILS/Driver/PluginFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..a92408cda50fa63d6ca8f84ab4ace266c3d10819
--- /dev/null
+++ b/module/VuFind/src/VuFind/ILS/Driver/PluginFactory.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * ILS driver plugin factory
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2010.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  ILS_Drivers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/creating_a_session_handler Wiki
+ */
+namespace VuFind\ILS\Driver;
+
+/**
+ * ILS driver plugin factory
+ *
+ * @category VuFind2
+ * @package  ILS_Drivers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/creating_a_session_handler Wiki
+ */
+class PluginFactory extends \VuFind\ServiceManager\AbstractPluginFactory
+{
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->defaultNamespace = 'VuFind\ILS\Driver';
+    }
+}
\ No newline at end of file
diff --git a/module/VuFind/src/VuFind/ILS/Driver/PluginManager.php b/module/VuFind/src/VuFind/ILS/Driver/PluginManager.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac27f6cb1628f200910b8a5b4be892d9ff58044e
--- /dev/null
+++ b/module/VuFind/src/VuFind/ILS/Driver/PluginManager.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * ILS driver plugin manager
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2010.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  ILS_Drivers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/creating_a_session_handler Wiki
+ */
+namespace VuFind\ILS\Driver;
+
+/**
+ * ILS driver plugin manager
+ *
+ * @category VuFind2
+ * @package  ILS_Drivers
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org/wiki/creating_a_session_handler Wiki
+ */
+class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager
+{
+    /**
+     * Return the name of the base class or interface that plug-ins must conform
+     * to.
+     *
+     * @return string
+     */
+    protected function getExpectedInterface()
+    {
+        return 'VuFind\ILS\Driver\DriverInterface';
+    }
+}
\ No newline at end of file