diff --git a/config/vufind/sitemap.ini b/config/vufind/sitemap.ini
index 68b542cef29a921965e9f2ed5fb75b8c24dbf4cf..1783849fa04546e376579eae143e682f3386cb48 100644
--- a/config/vufind/sitemap.ini
+++ b/config/vufind/sitemap.ini
@@ -34,6 +34,15 @@ fileName       = sitemap
 ;    sitemap. See http://sitemaps.org/protocol.php#location for details.
 fileLocation   = /tmp
 
+;  This setting controls which index or indices are used to generate the sitemap.
+;    Each value in the array should be a comma-separated pair, with the first
+;    value being the name of the search backend for accessing the index, and the
+;    second value being a relative path to insert between the base URL and the
+;    record ID in order to generate a link. If this setting is omitted, the
+;    default will be "Solr,/Record/"
+index[] = "Solr,/Record/"
+;index[] = "SolrAuth,/Authority/Record?id="
+
 ; The SitemapIndex Section contains settings affecting the generation of
 ;   a sitemap index file which groups multiple sitemap files. The sitemap
 ;   index file will contain absolute URLs to the individual sitemap files.
diff --git a/languages/en-gb.ini b/languages/en-gb.ini
index 66f061b9f226e3bbcda99b5644c8c87a81c883b8..e97fca18dc868b12304cddca65335613c5637154 100644
--- a/languages/en-gb.ini
+++ b/languages/en-gb.ini
@@ -682,6 +682,7 @@ summon_database_recommendations = "You may find additional resources here:"
 Supplied by Amazon = "Supplied by Amazon"
 Switch view to = "Switch view to"
 switchquery_intro = "You may be able to get more results by adjusting your search query."
+switchquery_lowercasebools = "If you are trying to use Boolean operators, they must be ALL CAPS"
 switchquery_unwantedbools = "The words AND, OR and NOT may confuse the search; try adding quotes"
 switchquery_unwantedquotes = "Removing quotes may allow a broader search"
 switchquery_wildcard = "Adding a wildcard symbol may retrieve word variants"
diff --git a/languages/en.ini b/languages/en.ini
index f8c6368e2d8c2c06f8ff85e332665115dfa26859..2b9aa0cf1dc0912df3d18d4cbda2eb5d20e74288 100644
--- a/languages/en.ini
+++ b/languages/en.ini
@@ -682,6 +682,7 @@ summon_database_recommendations = "You may find additional resources here:"
 Supplied by Amazon = "Supplied by Amazon"
 Switch view to = "Switch view to"
 switchquery_intro = "You may be able to get more results by adjusting your search query."
+switchquery_lowercasebools = "If you are trying to use Boolean operators, they must be ALL CAPS"
 switchquery_unwantedbools = "The words AND, OR and NOT may confuse the search; try adding quotes"
 switchquery_unwantedquotes = "Removing quotes may allow a broader search"
 switchquery_wildcard = "Adding a wildcard symbol may retrieve word variants"
diff --git a/module/VuFind/src/VuFind/Recommend/SwitchQuery.php b/module/VuFind/src/VuFind/Recommend/SwitchQuery.php
index bdf882a0a52af458cd5bda20d0c7e07bf4879e8c..0b4e8907ee32df3177ca7425f4080d1ae7b0c2a8 100644
--- a/module/VuFind/src/VuFind/Recommend/SwitchQuery.php
+++ b/module/VuFind/src/VuFind/Recommend/SwitchQuery.php
@@ -160,6 +160,30 @@ class SwitchQuery implements RecommendInterface
         }
     }
 
+    /**
+     * Does the query contain lowercase boolean operators that should be uppercased?
+     *
+     * @param string $query Query to check
+     *
+     * @return string|bool
+     */
+    protected function checkLowercaseBools($query)
+    {
+        // This test only applies if booleans are case-sensitive and there is a
+        // capitalizaton method available:
+        $qb = $this->getQueryBuilder();
+        if (!$qb || !isset($qb->caseSensitiveBooleans)
+            || !is_callable(array($qb, 'capitalizeBooleans'))
+            || !$qb->caseSensitiveBooleans
+        ) {
+            return false;
+        }
+
+        // Try to capitalize booleans, return new query if a change is found:
+        $newQuery = $qb->capitalizeBooleans($query);
+        return ($query == $newQuery) ? false : $newQuery;
+    }
+
     /**
      * Does the query contain terms that are being treated as boolean operators,
      * perhaps unintentionally?
diff --git a/module/VuFind/src/VuFind/Sitemap.php b/module/VuFind/src/VuFind/Sitemap.php
index bef5a8d8792bbcdf821a98be29d4a54b71e376d6..5cf0fac7031d8995f5f7a7d117542dadb3cbbb16 100644
--- a/module/VuFind/src/VuFind/Sitemap.php
+++ b/module/VuFind/src/VuFind/Sitemap.php
@@ -26,7 +26,8 @@
  * @link     http://www.vufind.org  Main Page
  */
 namespace VuFind;
-use VuFindSearch\Backend\Solr\Backend, Zend\Config\Config;
+use VuFindSearch\Backend\Solr\Backend, VuFind\Search\BackendManager,
+    Zend\Config\Config;
 
 /**
  * Class for generating sitemaps
@@ -40,11 +41,11 @@ use VuFindSearch\Backend\Solr\Backend, Zend\Config\Config;
 class Sitemap
 {
     /**
-     * Search backend from which to retrieve record IDs.
+     * Search backend manager.
      *
-     * @var Backend
+     * @var BackendManager
      */
-    protected $backend;
+    protected $backendManager;
 
     /**
      * Base URL for site
@@ -54,11 +55,11 @@ class Sitemap
     protected $baseUrl;
 
     /**
-     * Base URL for record
+     * Settings specifying which backends to index.
      *
-     * @var string
+     * @var array
      */
-    protected $resultUrl;
+    protected $backendSettings;
 
     /**
      * Sitemap configuration (sitemap.ini)
@@ -105,16 +106,29 @@ class Sitemap
     /**
      * Constructor
      *
-     * @param Backend $backend Search backend
-     * @param string  $baseUrl VuFind base URL
-     * @param Config  $config  Sitemap configuration settings
+     * @param BackendManager $bm      Search backend
+     * @param string         $baseUrl VuFind base URL
+     * @param Config         $config  Sitemap configuration settings
      */
-    public function __construct(Backend $backend, $baseUrl, Config $config)
+    public function __construct(BackendManager $bm, $baseUrl, Config $config)
     {
-        $this->backend = $backend;
+        // Save incoming parameters:
+        $this->backendManager = $bm;
         $this->baseUrl = $baseUrl;
-        $this->resultUrl = $this->baseUrl . '/Record/';
         $this->config = $config;
+
+        // Process backend configuration:
+        $backendConfig = isset($this->config->Sitemap->index)
+            ? $this->config->Sitemap->index : array('Solr,/Record/');
+        $backendConfig = is_callable(array($backendConfig, 'toArray'))
+            ? $backendConfig->toArray() : (array)$backendConfig;
+        $callback = function ($n) {
+            $parts = array_map('trim', explode(',', $n));
+            return array('id' => $parts[0], 'url' => $parts[1]);
+        };
+        $this->backendSettings = array_map($callback, $backendConfig);
+
+        // Store other key config settings:
         $this->frequency = $this->config->Sitemap->frequency;
         $this->countPerPage = $this->config->Sitemap->countPerPage;
         $this->fileStart = $this->config->Sitemap->fileLocation . "/" .
@@ -132,21 +146,59 @@ class Sitemap
      */
     public function generate()
     {
+        // Initialize variable
         $currentPage = 1;
+
+        // Loop through all backends
+        foreach ($this->backendSettings as $current) {
+            $backend = $this->backendManager->get($current['id']);
+            if (!($backend instanceof Backend)) {
+                throw new \Exception('Unsupported backend: ' . get_class($backend));
+            }
+            $recordUrl = $this->baseUrl . $current['url'];
+            $currentPage = $this
+                ->generateForBackend($backend, $recordUrl, $currentPage);
+        }
+
+        // Set-up Sitemap Index
+        $this->buildIndex($currentPage - 1);
+    }
+
+    /**
+     * Get array of warning messages thrown during build.
+     *
+     * @return array
+     */
+    public function getWarnings()
+    {
+        return $this->warnings;
+    }
+
+    /**
+     * Generate sitemap files for a single search backend.
+     *
+     * @param Backend $backend     Search backend
+     * @param string  $recordUrl   Base URL for record links
+     * @param int     $currentPage Sitemap page number to start generating
+     *
+     * @return int                 Next sitemap page number to generate
+     */
+    protected function generateForBackend(Backend $backend, $recordUrl, $currentPage)
+    {
         $last_term = '';
+        $key = $backend->getConnector()->getUniqueKey();
 
         while (true) {
             // Get
-            $currentPageInfo
-                = $this->backend->terms('id', $last_term, $this->countPerPage)
-                    ->getFieldTerms('id');
+            $currentPageInfo = $backend->terms($key, $last_term, $this->countPerPage)
+                ->getFieldTerms($key);
             if (null === $currentPageInfo || count($currentPageInfo) < 1) {
                 break;
             } else {
                 $filename = $this->getFilenameForPage($currentPage);
                 $smf = $this->openSitemapFile($filename, 'urlset');
                 foreach ($currentPageInfo as $item => $count) {
-                    $loc = htmlspecialchars($this->resultUrl . urlencode($item));
+                    $loc = htmlspecialchars($recordUrl . urlencode($item));
                     if (strpos($loc, 'http') === false) {
                         $loc = 'http://'.$loc;
                     }
@@ -160,19 +212,7 @@ class Sitemap
 
             $currentPage++;
         }
-
-        // Set-up Sitemap Index
-        $this->buildIndex($currentPage - 1);
-    }
-
-    /**
-     * Get array of warning messages thrown during build.
-     *
-     * @return array
-     */
-    public function getWarnings()
-    {
-        return $this->warnings;
+        return $currentPage;
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/View/Helper/Root/JsTranslations.php b/module/VuFind/src/VuFind/View/Helper/Root/JsTranslations.php
index c42195ae366fdeb26ffa4bd1b5634b5df8a347cc..d7873423c98692731835086cd878bd0eaf8b0374 100644
--- a/module/VuFind/src/VuFind/View/Helper/Root/JsTranslations.php
+++ b/module/VuFind/src/VuFind/View/Helper/Root/JsTranslations.php
@@ -97,6 +97,6 @@ class JsTranslations extends AbstractHelper
         foreach ($this->strings as $k => $v) {
             $parts[] = $k . ': "' . addslashes($this->transEsc->__invoke($v)) . '"';
         }
-        return $this->varName . ' = {' . implode(',' , $parts) . '};';
+        return $this->varName . ' = {' . implode(',', $parts) . '};';
     }
 }
\ No newline at end of file
diff --git a/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php b/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php
index cc0eb34a96ccea14809b963cb390d972161db18a..d7a050f8ced03abcf54a0151a7998cb4a5062228 100644
--- a/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php
+++ b/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php
@@ -263,11 +263,9 @@ class UtilController extends AbstractBase
     public function sitemapAction()
     {
         // Build sitemap and display appropriate warnings if needed:
-        $backendManager = $this->getServiceLocator()
-            ->get('VuFind\Search\BackendManager');
         $configLoader = $this->getServiceLocator()->get('VuFind\Config');
         $generator = new Sitemap(
-            $backendManager->get('Solr'),
+            $this->getServiceLocator()->get('VuFind\Search\BackendManager'),
             $configLoader->get('config')->Site->url, $configLoader->get('sitemap')
         );
         $generator->generate();
diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php
index e12b974dde2f10f421b7f8f680a346b9e61884bd..1e1f0244318b8a105e7aa2f76f6d487c50db536d 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/Solr/Connector.php
@@ -163,6 +163,16 @@ class Connector
         return $this->map;
     }
 
+    /**
+     * Get unique key.
+     *
+     * @return string
+     */
+    public function getUniqueKey()
+    {
+        return $this->uniqueKey;
+    }
+
     /**
      * Return document specified by id.
      *
diff --git a/themes/blueprint/js/common.js b/themes/blueprint/js/common.js
index 8b4a74d9d13c36fb39151574d1f7130c136e948a..07209f28afc43e4c008b33cdd85b4c5fd0f26543 100644
--- a/themes/blueprint/js/common.js
+++ b/themes/blueprint/js/common.js
@@ -1,4 +1,4 @@
-/*global getLightbox, path*/
+/*global getLightbox, path, vufindString*/
 
 /**
  * Initialize common functions and event handlers.
diff --git a/themes/bootstrap/js/lightbox.js b/themes/bootstrap/js/lightbox.js
index 734cf4f5aabb607035f6d6fd400b7a8fd3094a7e..ef18442d387b4b92dc24fc5a349bc94dfe406d42 100644
--- a/themes/bootstrap/js/lightbox.js
+++ b/themes/bootstrap/js/lightbox.js
@@ -2,6 +2,7 @@
 
 var lastLightboxURL,lastLightboxPOST; // Replacement for empty form actions
 var lightboxShown = false; // is the lightbox deployed?
+var modalXHR; // Used for current in-progress XHR lightbox request
 
 /**********************************/
 /* ====== LIGHTBOX ACTIONS ====== */
@@ -56,7 +57,6 @@ function displayLightboxError(message) {
 /****************************/
 // AJAX the content and put it into a lightbox
 // Callback if necessary
-var modalXHR;
 function getLightboxByUrl(url, post, callback) {
   if(!lightboxShown) {
     $('#modal').modal('show');
@@ -282,10 +282,10 @@ function registerModalForms(modal) {
   });
   $(modal).find('form[name="newList"]').unbind('submit').submit(function(){
     ajaxSubmit($(this), changeModalContent);
-    return false
+    return false;
   });
   $(modal).find('form[name="loginForm"]').unbind('submit')
-    .submit(function(){ajaxLogin(this);return false});
+    .submit(function(){ajaxLogin(this);return false;});
 }
 // Default lightbox behaviour
 // Tell links to open lightboxes