diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 73685d986aca65d1e5eeadb4067be76ea0f04feb..807e8f236b0675dbc34a5b912ac70ddbf64ca5fc 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -480,6 +480,11 @@ $config = array(
                     $sm->get('VuFind\Http')->createClient()
                 );
             },
+            'VuFindTheme\Tools' => function ($sm) {
+                return new \VuFind\Theme\Tools(
+                    realpath(__DIR__ . '/../../../themes')
+                );
+            }
         ),
         'invokables' => array(
             'VuFind\AuthManager' => 'VuFind\Auth\Manager',
diff --git a/module/VuFind/src/VuFind/Controller/CoverController.php b/module/VuFind/src/VuFind/Controller/CoverController.php
index 258b30e70dae3f9b84627fd4f4b05dd099db9ac2..be9ff970d686d21bd7cbbea8cdec73f7981095de 100644
--- a/module/VuFind/src/VuFind/Controller/CoverController.php
+++ b/module/VuFind/src/VuFind/Controller/CoverController.php
@@ -52,6 +52,7 @@ class CoverController extends AbstractBase
         if (!$this->loader) {
             $this->loader = new Loader(
                 ConfigReader::getConfig(),
+                $this->getServiceLocator()->get('VuFindTheme\Tools'),
                 $this->getServiceLocator()->get('VuFind\Http')->createClient(),
                 $this->getServiceLocator()->get('VuFind\CacheManager')->getCacheDir()
             );
diff --git a/module/VuFind/src/VuFind/Cover/Loader.php b/module/VuFind/src/VuFind/Cover/Loader.php
index a537484ae7f457ff035ebd488e978107487bf0d7..54602746257c597f1c887a09f3087c809529d467 100644
--- a/module/VuFind/src/VuFind/Cover/Loader.php
+++ b/module/VuFind/src/VuFind/Cover/Loader.php
@@ -27,8 +27,7 @@
  * @link     http://vufind.org/wiki/use_of_external_content Wiki
  */
 namespace VuFind\Cover;
-use VuFind\Code\ISBN, VuFind\Theme\Tools as ThemeTools, Zend\Log\LoggerInterface,
-    ZendService\Amazon\Amazon;
+use VuFind\Code\ISBN, Zend\Log\LoggerInterface, ZendService\Amazon\Amazon;
 
 /**
  * Book Cover Generator
@@ -119,17 +118,27 @@ class Loader implements \Zend\Log\LoggerAwareInterface
      */
     protected $logger = false;
 
+    /**
+     * Theme tools
+     *
+     * @var \VuFind\Theme\Tools
+     */
+    protected $themeTools;
+
     /**
      * Constructor
      *
      * @param \Zend\Config\Config $config  VuFind configuration
+     * @param \VuFind\Theme\Tools $theme   VuFind theme tools
      * @param \Zend\Http\Client   $client  HTTP client
      * @param string              $baseDir Directory to store downloaded images
      * (set to system temp dir if not otherwise specified)
      */
-    public function __construct($config, \Zend\Http\Client $client, $baseDir = null)
-    {
+    public function __construct($config, \VuFind\Theme\Tools $theme,
+        \Zend\Http\Client $client, $baseDir = null
+    ) {
         $this->config = $config;
+        $this->themeTools = $theme;
         $this->client = $client;
         $this->baseDir = rtrim(
             is_null($baseDir) ? sys_get_temp_dir() : $baseDir, '\\/'
@@ -335,7 +344,7 @@ class Loader implements \Zend\Log\LoggerAwareInterface
         foreach ($formats as $format) {
             $filenames[] =  $path . $format;
         }
-        $fileMatch = ThemeTools::findContainingTheme($filenames, true);
+        $fileMatch = $this->themeTools->findContainingTheme($filenames, true);
         return empty($fileMatch) ? false : $fileMatch;
     }
 
diff --git a/module/VuFind/src/VuFind/Theme/Initializer.php b/module/VuFind/src/VuFind/Theme/Initializer.php
index 009e837efee1837d950ea9ea1ffe18382aa0e03c..d076af647a3d0f55f6ec6b0ac30285512a13e53f 100644
--- a/module/VuFind/src/VuFind/Theme/Initializer.php
+++ b/module/VuFind/src/VuFind/Theme/Initializer.php
@@ -55,29 +55,25 @@ class Initializer
      *
      * @param Config   $config Configuration object
      * @param MvcEvent $event  Zend MVC Event object
-     * @param string   $tools  Name of Tools class
      */
-    public function __construct(Config $config, MvcEvent $event,
-        string $tools = null
-    ) {
-        // If no tools class name was passed in, use a default:
-        if (is_null($tools)) {
-            $tools = 'VuFind\Theme\Tools';
-        }
-
+    public function __construct(Config $config, MvcEvent $event)
+    {
+        // Store parameters:
         $this->config = $config;
         $this->event = $event;
-        $this->baseDir = call_user_func(array($tools, 'getBaseDir'));
 
         // Grab the service manager for convenience:
         $this->serviceManager = $this->event->getApplication()->getServiceManager();
 
+        // Get base directory from tools object:
+        $tools = $this->serviceManager->get('VuFindTheme\Tools');
+        $this->baseDir = $tools->getBaseDir();
+
         // Grab the resource manager for tracking CSS, JS, etc.:
-        $this->resourceContainer
-            = call_user_func(array($tools, 'getResourceContainer'));
+        $this->resourceContainer = $tools->getResourceContainer();
 
         // Set up a session namespace for storing theme settings:
-        $this->session = call_user_func(array($tools, 'getPersistenceContainer'));
+        $this->session = $tools->getPersistenceContainer();
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/Theme/Root/Helper/HeadLink.php b/module/VuFind/src/VuFind/Theme/Root/Helper/HeadLink.php
index f4be64e333837169700079ff63b684ad37130d34..1296432d8618706d1d0f5225b85df549c7ed2817 100644
--- a/module/VuFind/src/VuFind/Theme/Root/Helper/HeadLink.php
+++ b/module/VuFind/src/VuFind/Theme/Root/Helper/HeadLink.php
@@ -26,7 +26,8 @@
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
 namespace VuFind\Theme\Root\Helper;
-use VuFind\Theme\Tools as ThemeTools;
+use Zend\ServiceManager\ServiceLocatorInterface,
+    Zend\ServiceManager\ServiceLocatorAwareInterface;
 
 /**
  * Head link view helper (extended for VuFind's theme system)
@@ -38,7 +39,50 @@ use VuFind\Theme\Tools as ThemeTools;
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
 class HeadLink extends \Zend\View\Helper\HeadLink
+    implements ServiceLocatorAwareInterface
 {
+    /**
+     * Service locator
+     *
+     * @var ServiceLocatorInterface
+     */
+    protected $serviceLocator;
+
+    /**
+     * Set the service locator.
+     *
+     * @param ServiceLocatorInterface $serviceLocator Locator to register
+     *
+     * @return AbstractServiceLocator
+     */
+    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
+    {
+        // The service locator passed in here is a Zend\View\HelperPluginManager;
+        // we want to pull out the main Zend\ServiceManager\ServiceManager.
+        $this->serviceLocator = $serviceLocator->getServiceLocator();
+        return $this;
+    }
+
+    /**
+     * Get the service locator.
+     *
+     * @return \Zend\ServiceManager\ServiceLocatorInterface
+     */
+    public function getServiceLocator()
+    {
+        return $this->serviceLocator;
+    }
+
+    /**
+     * Get the theme tools.
+     *
+     * @return \VuFind\Theme\Tools
+     */
+    public function getThemeTools()
+    {
+        return $this->getServiceLocator()->get('VuFindTheme\Tools');
+    }
+
     /**
      * Create HTML link element from data item
      *
@@ -50,7 +94,7 @@ class HeadLink extends \Zend\View\Helper\HeadLink
     {
         // Normalize href to account for themes, then call the parent class:
         $relPath = 'css/' . $item->href;
-        $currentTheme = ThemeTools::findContainingTheme($relPath);
+        $currentTheme = $this->getThemeTools()->findContainingTheme($relPath);
 
         if (!empty($currentTheme)) {
             $urlHelper = $this->getView()->plugin('url');
diff --git a/module/VuFind/src/VuFind/Theme/Root/Helper/HeadScript.php b/module/VuFind/src/VuFind/Theme/Root/Helper/HeadScript.php
index 36269252ad932fb0fb7c7560e75dfbc87c36a999..6be44c7999c37ee3e5810a29a0cec823c34cd1f0 100644
--- a/module/VuFind/src/VuFind/Theme/Root/Helper/HeadScript.php
+++ b/module/VuFind/src/VuFind/Theme/Root/Helper/HeadScript.php
@@ -26,7 +26,8 @@
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
 namespace VuFind\Theme\Root\Helper;
-use VuFind\Theme\Tools as ThemeTools;
+use Zend\ServiceManager\ServiceLocatorInterface,
+    Zend\ServiceManager\ServiceLocatorAwareInterface;
 
 /**
  * Head script view helper (extended for VuFind's theme system)
@@ -38,7 +39,50 @@ use VuFind\Theme\Tools as ThemeTools;
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
 class HeadScript extends \Zend\View\Helper\HeadScript
+    implements ServiceLocatorAwareInterface
 {
+    /**
+     * Service locator
+     *
+     * @var ServiceLocatorInterface
+     */
+    protected $serviceLocator;
+
+    /**
+     * Set the service locator.
+     *
+     * @param ServiceLocatorInterface $serviceLocator Locator to register
+     *
+     * @return AbstractServiceLocator
+     */
+    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
+    {
+        // The service locator passed in here is a Zend\View\HelperPluginManager;
+        // we want to pull out the main Zend\ServiceManager\ServiceManager.
+        $this->serviceLocator = $serviceLocator->getServiceLocator();
+        return $this;
+    }
+
+    /**
+     * Get the service locator.
+     *
+     * @return \Zend\ServiceManager\ServiceLocatorInterface
+     */
+    public function getServiceLocator()
+    {
+        return $this->serviceLocator;
+    }
+
+    /**
+     * Get the theme tools.
+     *
+     * @return \VuFind\Theme\Tools
+     */
+    public function getThemeTools()
+    {
+        return $this->getServiceLocator()->get('VuFindTheme\Tools');
+    }
+
     /**
      * Create script HTML
      *
@@ -54,7 +98,7 @@ class HeadScript extends \Zend\View\Helper\HeadScript
         // Normalize href to account for themes:
         if (!empty($item->attributes['src'])) {
             $relPath = 'js/' . $item->attributes['src'];
-            $currentTheme = ThemeTools::findContainingTheme($relPath);
+            $currentTheme = $this->getThemeTools()->findContainingTheme($relPath);
 
             if (!empty($currentTheme)) {
                 $urlHelper = $this->getView()->plugin('url');
diff --git a/module/VuFind/src/VuFind/Theme/Root/Helper/HeadThemeResources.php b/module/VuFind/src/VuFind/Theme/Root/Helper/HeadThemeResources.php
index 5847e91ce9438843c9d6c9f4a7a24bf2f87a9875..9e623f6a31d620aaf5d8ae814c7e53bd4da62560 100644
--- a/module/VuFind/src/VuFind/Theme/Root/Helper/HeadThemeResources.php
+++ b/module/VuFind/src/VuFind/Theme/Root/Helper/HeadThemeResources.php
@@ -26,8 +26,7 @@
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
 namespace VuFind\Theme\Root\Helper;
-use VuFind\Theme\Tools as ThemeTools,
-    Zend\View\Helper\AbstractHelper;
+use Zend\View\Helper\AbstractHelper;
 
 /**
  * View helper for loading theme-related resources in the header.
@@ -38,8 +37,18 @@ use VuFind\Theme\Tools as ThemeTools,
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     http://vufind.org/wiki/building_a_recommendations_module Wiki
  */
-class HeadThemeResources extends AbstractHelper
+class HeadThemeResources extends AbstractServiceLocator
 {
+    /**
+     * Get the theme tools.
+     *
+     * @return \VuFind\Theme\Tools
+     */
+    public function getThemeTools()
+    {
+        return $this->getServiceLocator()->get('VuFindTheme\Tools');
+    }
+
     /**
      * Set up header items based on contents of theme resource container.
      *
@@ -47,7 +56,7 @@ class HeadThemeResources extends AbstractHelper
      */
     public function __invoke()
     {
-        $resourceContainer = ThemeTools::getResourceContainer();
+        $resourceContainer = $this->getThemeTools()->getResourceContainer();
 
         // Set up encoding:
         $headMeta = $this->getView()->plugin('headmeta');
diff --git a/module/VuFind/src/VuFind/Theme/Root/Helper/ImageLink.php b/module/VuFind/src/VuFind/Theme/Root/Helper/ImageLink.php
index ffb815d5589f719d9f4bd298b46bec5d842df897..395b1639b257dc3fb7ad144dbc0e3c9a2e727477 100644
--- a/module/VuFind/src/VuFind/Theme/Root/Helper/ImageLink.php
+++ b/module/VuFind/src/VuFind/Theme/Root/Helper/ImageLink.php
@@ -26,8 +26,7 @@
  * @link     http://www.vufind.org  Main Page
  */
 namespace VuFind\Theme\Root\Helper;
-use VuFind\Theme\Tools as ThemeTools,
-    Zend\View\Helper\AbstractHelper;
+use Zend\View\Helper\AbstractHelper;
 
 /**
  * Image link view helper (extended for VuFind's theme system)
@@ -38,8 +37,18 @@ use VuFind\Theme\Tools as ThemeTools,
  * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
  * @link     http://www.vufind.org  Main Page
  */
-class ImageLink extends AbstractHelper
+class ImageLink extends AbstractServiceLocator
 {
+    /**
+     * Get the theme tools.
+     *
+     * @return \VuFind\Theme\Tools
+     */
+    public function getThemeTools()
+    {
+        return $this->getServiceLocator()->get('VuFindTheme\Tools');
+    }
+
     /**
      * Returns an image path according the configured theme
      *
@@ -51,7 +60,7 @@ class ImageLink extends AbstractHelper
     {
         // Normalize href to account for themes:
         $relPath = 'images/' . $image;
-        $currentTheme = ThemeTools::findContainingTheme($relPath);
+        $currentTheme = $this->getThemeTools()->findContainingTheme($relPath);
 
         if (is_null($currentTheme)) {
             return null;
diff --git a/module/VuFind/src/VuFind/Theme/Tools.php b/module/VuFind/src/VuFind/Theme/Tools.php
index 60c71a4a651e276c56317e72b93117674b0c5285..782f506bf2cccb0319c87f19f6982c092f9a1ff1 100644
--- a/module/VuFind/src/VuFind/Theme/Tools.php
+++ b/module/VuFind/src/VuFind/Theme/Tools.php
@@ -39,29 +39,58 @@ use Zend\Session\Container as SessionContainer;
  */
 class Tools
 {
+    /**
+     * Base directory for theme files
+     *
+     * @var string
+     */
+    protected $baseDir;
+
+    /**
+     * Resource container
+     *
+     * @var ResourceContainer
+     */
+    protected $resourceContainer;
+
+    /**
+     * Session (persistence) container
+     *
+     * @var SessionContainer
+     */
+    protected $sessionContainer;
+
+    /**
+     * Constructor
+     *
+     * @param string $baseDir Base directory for theme files.
+     */
+    public function __construct($baseDir)
+    {
+        $this->baseDir = $baseDir;
+        $this->resourceContainer = new ResourceContainer();
+        $this->sessionContainer = new SessionContainer('Theme');
+    }
+
     /**
      * Get the base directory for themes.
      *
      * @return string
      */
-    public static function getBaseDir()
+    public function getBaseDir()
     {
-        return APPLICATION_PATH . '/themes';
+        return $this->baseDir;
     }
 
     /**
      * Get the container used for handling public resources for themes
      * (CSS, JS, etc.)
      *
-     * @return Context
+     * @return ResourceContainer
      */
-    public static function getResourceContainer()
+    public function getResourceContainer()
     {
-        static $container = false;
-        if (!$container) {
-            $container = new ResourceContainer();
-        }
-        return $container;
+        return $this->resourceContainer;
     }
 
     /**
@@ -70,13 +99,9 @@ class Tools
      *
      * @return SessionContainer
      */
-    public static function getPersistenceContainer()
+    public function getPersistenceContainer()
     {
-        static $container = false;
-        if (!$container) {
-            $container = new SessionContainer('Theme');
-        }
-        return $container;
+        return $this->sessionContainer;
     }
 
     /**
@@ -90,10 +115,10 @@ class Tools
      *
      * @return string
      */
-    public static function findContainingTheme($relativePath, $returnFile = false)
+    public function findContainingTheme($relativePath, $returnFile = false)
     {
-        $session = static::getPersistenceContainer();
-        $basePath = static::getBaseDir();
+        $session = $this->getPersistenceContainer();
+        $basePath = $this->getBaseDir();
         $allPaths = is_array($relativePath)
             ? $relativePath : array($relativePath);