diff --git a/config/vufind/WorldCat.ini b/config/vufind/WorldCat.ini
index 5736b5782a0374e513d6a76404f35587fd774dfb..f027431e6c39bd7ef4fc3f52a0166ae798bd57d0 100644
--- a/config/vufind/WorldCat.ini
+++ b/config/vufind/WorldCat.ini
@@ -54,4 +54,3 @@ Title       = sort_title
 next_prev_navigation = false
 
 related[] = "WorldCatSimilar"
-related[] = "WorldCatEditions"
diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index dc6a0de2f0519147d72c9ac7336c0a2d17e24861..406d90ff98fd475e459024ced7f8f203ff21cedb 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -727,25 +727,14 @@ pw               = "Password"
 ;apiId        = myAccessId
 ;apiKey       = mySecretKey
 
-; WorldCat is Optional.  Worldcat offers extra features such as "Other Editions"
-; and the WorldCat searching.
+; This section must be filled in if you plan to use the optional WorldCat
+; search module. Otherwise, it may be ignored.
 ;[WorldCat]
 ;Your WorldCat search API key
-;apiKey          = ApiKey
+;apiKey          = "long-search-api-key-goes-here"
 ;Your holdings symbol (usually a three-letter code) - used for excluding your
 ; institution's holdings from the search results.
 ;OCLCCode        = MYCODE
-; Your worldcat xID Affiliate ID - used for Other Editions feature
-;id              = myAccount
-; If you have increased your OCLC xID daily limits using the token method,
-; fill in those credentials here.
-; note: xOCLCNUM uses the xISBN token/secret
-;xISBN_token = myToken
-;xISBN_secret = mySecret
-; As of 2014-09, although not specified by OCLC's documentation, the xISSN call
-; does not work if you have not also specified your affiliate ID.
-;xISSN_token = myToken
-;xISSN_secret = mySecret
 
 ; DPLA key -- uncomment and fill in to use DPLATerms recommendations (see also
 ; searches.ini).
@@ -1119,13 +1108,9 @@ hide_holdings[] = "World Wide Web"
 ; record view page.
 ;
 ; Available options:
-;    Editions - Alternate editions (in the Solr index) based on WorldCat lookup
 ;    Similar - Similarity based on Solr lookup
-;    WorldCatEditions - Alternate editions (in the WorldCat index) based on WorldCat
-;        lookup
 ;    WorldCatSimilar - Similarity based on WorldCat lookup
 related[] = "Similar"
-related[] = "Editions"
 
 ; This setting controls which citations are available; set to true for all supported
 ; options (default); set to false to disable citations; set to a comma-separated list
diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 247c4dfbfe8877f84d915da6e79e4bcefcff717a..9081341123c844b671703443586dac7271551a9a 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -494,11 +494,13 @@ $config = [
             'related' => [
                 'abstract_factories' => ['VuFind\Related\PluginFactory'],
                 'factories' => [
-                    'editions' => 'VuFind\Related\Factory::getEditions',
                     'similar' => 'VuFind\Related\Factory::getSimilar',
-                    'worldcateditions' => 'VuFind\Related\Factory::getWorldCatEditions',
                     'worldcatsimilar' => 'VuFind\Related\Factory::getWorldCatSimilar',
                 ],
+                'invokables' => [
+                    'editions' => 'VuFind\Related\Deprecated',
+                    'worldcateditions' => 'VuFind\Related\Deprecated',
+                ],
             ],
             'resolver_driver' => [
                 'abstract_factories' => ['VuFind\Resolver\Driver\PluginFactory'],
diff --git a/module/VuFind/src/VuFind/Config/Upgrade.php b/module/VuFind/src/VuFind/Config/Upgrade.php
index 4b0d9189e03452de73a9976363ec344725e913e1..e778de4cdcddee4ab97ca3f7b6eed5ddec0f428d 100644
--- a/module/VuFind/src/VuFind/Config/Upgrade.php
+++ b/module/VuFind/src/VuFind/Config/Upgrade.php
@@ -565,7 +565,7 @@ class Upgrade
             }
         }
 
-        // Warn the user about deprecated WorldCat setting:
+        // Warn the user about deprecated WorldCat settings:
         if (isset($newConfig['WorldCat']['LimitCodes'])) {
             unset($newConfig['WorldCat']['LimitCodes']);
             $this->addWarning(
@@ -573,6 +573,29 @@ class Upgrade
                 . ' removed.'
             );
         }
+        $badKeys
+            = ['id', 'xISBN_token', 'xISBN_secret', 'xISSN_token', 'xISSN_secret'];
+        foreach ($badKeys as $key) {
+            if (isset($newConfig['WorldCat'][$key])) {
+                unset($newConfig['WorldCat'][$key]);
+                $this->addWarning(
+                    'The [WorldCat] ' . $key . ' setting is no longer used and'
+                    . ' has been removed.'
+                );
+            }
+        }
+        if (isset($newConfig['Record']['related'])
+            && in_array('Editions', $newConfig['Record']['related'])
+        ) {
+            $newConfig['Record']['related'] = array_diff(
+                $newConfig['Record']['related'], ['Editions']
+            );
+            $this->addWarning(
+                'The Editions related record module is no longer '
+                . 'supported due to OCLC\'s xID API shutdown.'
+                . ' It has been removed from your settings.'
+            );
+        }
 
         // Upgrade Google Options:
         if (isset($newConfig['Content']['GoogleOptions'])
@@ -1081,6 +1104,21 @@ class Upgrade
             $this->newConfigs['WorldCat.ini'][$section] = $new;
         }
 
+        // Deal with deprecated related record module.
+        $newConfig = & $this->newConfigs['WorldCat.ini'];
+        if (isset($newConfig['Record']['related'])
+            && in_array('WorldCatEditions', $newConfig['Record']['related'])
+        ) {
+            $newConfig['Record']['related'] = array_diff(
+                $newConfig['Record']['related'], ['WorldCatEditions']
+            );
+            $this->addWarning(
+                'The WorldCatEditions related record module is no longer '
+                . 'supported due to OCLC\'s xID API shutdown.'
+                . ' It has been removed from your settings.'
+            );
+        }
+
         // save the file
         $this->saveModifiedConfig('WorldCat.ini');
     }
diff --git a/module/VuFind/src/VuFind/Connection/WorldCatUtils.php b/module/VuFind/src/VuFind/Connection/WorldCatUtils.php
index dfec2f27ca57e318d5b6672f2a9a840f995756ca..6b08b282242bd545a6fc491dca9204d523a44271 100644
--- a/module/VuFind/src/VuFind/Connection/WorldCatUtils.php
+++ b/module/VuFind/src/VuFind/Connection/WorldCatUtils.php
@@ -118,151 +118,6 @@ class WorldCatUtils implements \Zend\Log\LoggerAwareInterface
         return null;
     }
 
-    /**
-     * Get the WorldCat ID from the config file.
-     *
-     * @return string
-     */
-    protected function getWorldCatId()
-    {
-        return isset($this->config->id) ? $this->config->id : false;
-    }
-
-    /**
-     * Build a url to use in querying OCLC's xID service.
-     *
-     * @param string $base      base url with no querystring
-     * @param string $tokenVar  config file variable holding the token
-     * @param string $secretVar config file variable holding the secret
-     * @param string $format    data format for api response
-     *
-     * @return string
-     */
-    protected function buildXIdUrl($base, $tokenVar, $secretVar, $format)
-    {
-        $token = isset($this->config->$tokenVar)
-            ? $this->config->$tokenVar : false;
-        $secret = isset($this->config->$secretVar)
-            ? $this->config->$secretVar : false;
-        $querystr = '?method=getEditions&format=' . $format;
-        if ($token && $secret) {
-            $hash = md5($base . '|' . $this->ip . '|' . $secret);
-            $querystr .= '&token=' . $token . '&hash=' . $hash;
-        } if ($wcId = $this->getWorldCatId()) {
-            $querystr .= '&ai=' . urlencode($wcId);
-        }
-        $base .= $querystr;
-        return $base;
-    }
-
-    /**
-     * Retrieve results from the index using the XISBN service.
-     *
-     * @param string $isbn ISBN of main record
-     *
-     * @return array       ISBNs for related items (may be empty).
-     */
-    public function getXISBN($isbn)
-    {
-        // Build URL
-        $base = 'http://xisbn.worldcat.org/webservices/xid/isbn/' .
-                urlencode(is_array($isbn) ? $isbn[0] : $isbn);
-        $url = $this->buildXIdUrl($base, 'xISBN_token', 'xISBN_secret', 'json');
-
-        // Print Debug code
-        $this->debug("XISBN: $url");
-        $response = json_decode($this->retrieve($url));
-
-        // Fetch results
-        $isbns = [];
-        if (isset($response->list)) {
-            foreach ($response->list as $line) {
-                // Filter out non-ISBN characters and validate the length of
-                // whatever is left behind; this will prevent us from treating
-                // error messages like "invalidId" or "overlimit" as ISBNs.
-                $isbn = preg_replace(
-                    '/[^0-9xX]/', '', isset($line->isbn[0]) ? $line->isbn[0] : ''
-                );
-                if (strlen($isbn) >= 10) {
-                    $isbns[] = $isbn;
-                }
-            }
-        }
-        return $isbns;
-    }
-
-    /**
-     * Retrieve results from the index using the XOCLCNUM service.
-     *
-     * @param string $oclc OCLC number of main record
-     *
-     * @return array       ISBNs for related items (may be empty).
-     */
-    public function getXOCLCNUM($oclc)
-    {
-        // Build URL
-        $base = 'http://xisbn.worldcat.org/webservices/xid/oclcnum/' .
-                urlencode(is_array($oclc) ? $oclc[0] : $oclc);
-        $url = $this->buildXIdUrl($base, 'xISBN_token', 'xISBN_secret', 'json');
-
-        // Print Debug code
-        $this->debug("XOCLCNUM: $url");
-        $response = json_decode($this->retrieve($url));
-
-        // Fetch results
-        $results = [];
-        if (isset($response->list)) {
-            foreach ($response->list as $line) {
-                $values = isset($line->oclcnum) ? $line->oclcnum : [];
-                foreach ($values as $data) {
-                    // Filter out non-numeric characters and validate the length of
-                    // whatever is left behind; this will prevent us from treating
-                    // error messages like "invalidId" or "overlimit" as ISBNs.
-                    $current = preg_replace('/[^0-9]/', '', $data);
-                    if (!empty($current)) {
-                        $results[] = $current;
-                    }
-                }
-            }
-        }
-
-        return array_unique($results);
-    }
-
-    /**
-     * Retrieve results from the index using the XISSN service.
-     *
-     * @param string $issn ISSN of main record
-     *
-     * @return array       ISSNs for related items (may be empty).
-     */
-    public function getXISSN($issn)
-    {
-        // Build URL
-        $base = 'http://xissn.worldcat.org/webservices/xid/issn/' .
-                urlencode(is_array($issn) ? $issn[0] : $issn);
-        $url = $this->buildXIdUrl($base, 'xISSN_token', 'xISSN_secret', 'xml');
-
-        // Print Debug code
-        $this->debug("XISSN: $url");
-
-        // Fetch results
-        $issns = [];
-        $xml = $this->retrieve($url);
-        if (!empty($xml)) {
-            $data = simplexml_load_string($xml);
-            if (!empty($data) && isset($data->group->issn)
-                && count($data->group->issn) > 0
-            ) {
-                foreach ($data->group->issn as $issn) {
-                    $issns[] = (string)$issn;
-                }
-            }
-        }
-
-        return $issns;
-    }
-
     /**
      * Support function for getIdentitiesQuery(); is the provided name component
      * worth considering as a first or last name?
diff --git a/module/VuFind/src/VuFind/Related/Deprecated.php b/module/VuFind/src/VuFind/Related/Deprecated.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b630c34eed7fe0b8976a41c4eb49b80f9e5242b
--- /dev/null
+++ b/module/VuFind/src/VuFind/Related/Deprecated.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Deprecated Related Records Module - used to replace legacy modules that no
+ * longer function due to, for example, external APIs that have been shut down.
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2015.
+ *
+ * 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  Related_Records
+ * @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/vufind2:building_a_related_record_module Wiki
+ */
+namespace VuFind\Related;
+
+/**
+ * Deprecated Related Records Module - used to replace legacy modules that no
+ * longer function due to, for example, external APIs that have been shut down.
+ *
+ * @category VuFind2
+ * @package  Related_Records
+ * @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/vufind2:building_a_related_record_module Wiki
+ */
+class Deprecated implements RelatedInterface
+{
+    /**
+     * Establishes base settings for making recommendations.
+     *
+     * @param string                            $settings Settings from config.ini
+     * @param \VuFind\RecordDriver\AbstractBase $driver   Record driver object
+     *
+     * @return void
+     */
+    public function init($settings, $driver)
+    {
+    }
+}
\ No newline at end of file
diff --git a/module/VuFind/src/VuFind/Related/Editions.php b/module/VuFind/src/VuFind/Related/Editions.php
deleted file mode 100644
index eeeaf989d1ce7b5aaa340260290b0830f0ad0c3f..0000000000000000000000000000000000000000
--- a/module/VuFind/src/VuFind/Related/Editions.php
+++ /dev/null
@@ -1,170 +0,0 @@
-<?php
-/**
- * Related Records: WorldCat-based editions list (Solr results)
- *
- * PHP version 5
- *
- * Copyright (C) Villanova University 2009.
- *
- * 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  Related_Records
- * @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/vufind2:building_a_related_record_module Wiki
- */
-namespace VuFind\Related;
-
-/**
- * Related Records: WorldCat-based editions list (Solr results)
- *
- * @category VuFind2
- * @package  Related_Records
- * @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/vufind2:building_a_related_record_module Wiki
- */
-class Editions implements RelatedInterface
-{
-    /**
-     * Related editions
-     *
-     * @var array
-     */
-    protected $results = [];
-
-    /**
-     * Results plugin manager
-     *
-     * @var \VuFind\Search\Results\PluginManager
-     */
-    protected $resultsManager;
-
-    /**
-     * WorldCat utilities
-     *
-     * @var \VuFind\Connection\WorldCatUtils
-     */
-    protected $wcUtils;
-
-    /**
-     * Maximum limit
-     *
-     * @var int
-     */
-    protected $maxLimit;
-
-    /**
-     * Constructor
-     *
-     * @param \VuFind\Search\Results\PluginManager $results  Results plugin manager
-     * @param \VuFind\Connection\WorldCatUtils     $wcUtils  WorldCat utils object
-     * @param int                                  $maxLimit The maximum number of
-     * results to look up in Solr; set to -1 to use the "max boolean clauses" limit.
-     */
-    public function __construct(\VuFind\Search\Results\PluginManager $results,
-        \VuFind\Connection\WorldCatUtils $wcUtils, $maxLimit = -1
-    ) {
-        $this->resultsManager = $results;
-        $this->wcUtils = $wcUtils;
-        $this->maxLimit = $maxLimit;
-    }
-
-    /**
-     * Establishes base settings for making recommendations.
-     *
-     * @param string                            $settings Settings from config.ini
-     * @param \VuFind\RecordDriver\AbstractBase $driver   Record driver object
-     *
-     * @return void
-     */
-    public function init($settings, $driver)
-    {
-        // If we have query parts, we should try to find related records:
-        $parts = $this->getQueryParts($driver);
-        if (!empty($parts)) {
-            // Limit the number of parts based on the boolean clause limit:
-            $result = $this->resultsManager->get('Solr');
-            $params = $result->getParams();
-            $params->getOptions()->spellcheckEnabled(false);
-            $limit = $params->getQueryIDLimit();
-            if ($this->maxLimit > 0 && $limit > $this->maxLimit) {
-                $limit = $this->maxLimit;
-            }
-            if (count($parts) > $limit) {
-                $parts = array_slice($parts, 0, $limit);
-            }
-
-            // Assemble the query parts and filter out current record if it comes
-            // from the Solr index.:
-            $query = '(' . implode(' OR ', $parts) . ')';
-            if ($driver->getResourceSource() == 'VuFind') {
-                $query .= ' NOT id:"' . addcslashes($driver->getUniqueID(), '"')
-                    . '"';
-            }
-
-            // Perform the search and return either results or an error:
-            $params->setLimit(5);
-            $params->setOverrideQuery($query);
-            $this->results = $result->getResults();
-        }
-    }
-
-    /**
-     * Get an array of Record Driver objects representing other editions of the one
-     * passed to the constructor.
-     *
-     * @return array
-     */
-    public function getResults()
-    {
-        return $this->results;
-    }
-
-    /**
-     * Try to build an array of OCLC Number, ISBN or ISSN-based sub-queries by
-     * using OCLC X-services against a record driver object.
-     *
-     * @param \VuFind\RecordDriver\AbstractBase $driver Record driver object
-     *
-     * @return array
-     */
-    protected function getQueryParts($driver)
-    {
-        $parts = [];
-        $oclcNum = $driver->tryMethod('getCleanOCLCNum');
-        if (!empty($oclcNum)) {
-            $oclcList = $this->wcUtils->getXOCLCNUM($oclcNum);
-            foreach ($oclcList as $current) {
-                $parts[] = "oclc_num:" . $current;
-            }
-        }
-        $isbn = $driver->tryMethod('getCleanISBN');
-        if (!empty($isbn)) {
-            $isbnList = $this->wcUtils->getXISBN($isbn);
-            foreach ($isbnList as $current) {
-                $parts[] = 'isbn:' . $current;
-            }
-        }
-        $issn = $driver->tryMethod('getCleanISSN');
-        if (!empty($issn)) {
-            $issnList = $this->wcUtils->getXISSN($issn);
-            foreach ($issnList as $current) {
-                $parts[] = 'issn:' . $current;
-            }
-        }
-        return $parts;
-    }
-}
\ No newline at end of file
diff --git a/module/VuFind/src/VuFind/Related/WorldCatEditions.php b/module/VuFind/src/VuFind/Related/WorldCatEditions.php
deleted file mode 100644
index fa2e864a2115751bc038c7c1ba6188f0eca4fefc..0000000000000000000000000000000000000000
--- a/module/VuFind/src/VuFind/Related/WorldCatEditions.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?php
-/**
- * Related Records: WorldCat-based editions list (WorldCat results)
- *
- * PHP version 5
- *
- * Copyright (C) Villanova University 2009.
- *
- * 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  Related_Records
- * @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/vufind2:building_a_related_record_module Wiki
- */
-namespace VuFind\Related;
-
-/**
- * Related Records: WorldCat-based editions list (WorldCat results)
- *
- * @category VuFind2
- * @package  Related_Records
- * @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/vufind2:building_a_related_record_module Wiki
- */
-class WorldCatEditions extends Editions
-{
-    /**
-     * Establishes base settings for making recommendations.
-     *
-     * @param string                            $settings Settings from config.ini
-     * @param \VuFind\RecordDriver\AbstractBase $driver   Record driver object
-     *
-     * @return void
-     */
-    public function init($settings, $driver)
-    {
-        // If we have query parts, we should try to find related records:
-        $parts = $this->getQueryParts($driver);
-        if (!empty($parts)) {
-            // Assemble the query parts and filter out current record if it comes
-            // from the Solr index.:
-            $query = '(' . implode(' or ', $parts) . ')';
-            if ($driver->getResourceSource() == 'WorldCat') {
-                $query .= ' not srw.no all ' . $driver->getUniqueID();
-            }
-
-            // Perform the search and save results:
-            $result = $this->resultsManager->get('WorldCat');
-            $params = $result->getParams();
-            $params->setLimit(5);
-            $params->setOverrideQuery($query);
-            $this->results = $result->getResults();
-        }
-    }
-
-    /**
-     * Try to build an array of OCLC Number, ISBN or ISSN-based sub-queries by
-     * using OCLC X-services against a record driver object.
-     *
-     * @param \VuFind\RecordDriver\AbstractBase $driver Record driver object
-     *
-     * @return array
-     */
-    protected function getQueryParts($driver)
-    {
-        $parts = [];
-        $oclcNum = $driver->tryMethod('getCleanOCLCNum');
-        if (!empty($oclcNum)) {
-            $oclcList = $this->wcUtils->getXOCLCNUM($oclcNum);
-            if (!empty($oclcList)) {
-                $parts[] = '(srw.no any "' . implode(' ', $oclcList) . '")';
-            }
-        }
-        $isbn = $driver->tryMethod('getCleanISBN');
-        if (!empty($isbn)) {
-            $isbnList = $this->wcUtils->getXISBN($isbn);
-            if (!empty($isbnList)) {
-                $parts[] = '(srw.bn any "' . implode(' ', $isbnList) . '")';
-            }
-        }
-        $issn = $driver->tryMethod('getCleanISSN');
-        if (!empty($issn)) {
-            $issnList = $this->wcUtils->getXISSN($issn);
-            if (!empty($issnList)) {
-                $parts[] = '(srw.sn any "' . implode(' ', $issnList) . '")';
-            }
-        }
-        return $parts;
-    }
-}
diff --git a/module/VuFind/tests/fixtures/configs/xid/WorldCat.ini b/module/VuFind/tests/fixtures/configs/xid/WorldCat.ini
new file mode 100644
index 0000000000000000000000000000000000000000..7757a57019723db20fa98c53c3dfde59241cee58
--- /dev/null
+++ b/module/VuFind/tests/fixtures/configs/xid/WorldCat.ini
@@ -0,0 +1,3 @@
+[Record]
+related[] = "WorldCatSimilar"
+related[] = "WorldCatEditions"
\ No newline at end of file
diff --git a/module/VuFind/tests/fixtures/configs/xid/config.ini b/module/VuFind/tests/fixtures/configs/xid/config.ini
new file mode 100644
index 0000000000000000000000000000000000000000..f27b6d6e2c4f0947d5098cb97019a1035276cff6
--- /dev/null
+++ b/module/VuFind/tests/fixtures/configs/xid/config.ini
@@ -0,0 +1,11 @@
+[Record]
+related[] = "Similar"
+related[] = "Editions"
+
+[WorldCat]
+apiKey = foo
+id = bar
+xISBN_token = myToken1
+xISBN_secret = mySecret1
+xISSN_token = myToken2
+xISSN_secret = mySecret2
diff --git a/module/VuFind/tests/fixtures/worldcat/xisbn b/module/VuFind/tests/fixtures/worldcat/xisbn
deleted file mode 100644
index d57a21bb8d5e9a3270729b5cbff1892f993bcd6c..0000000000000000000000000000000000000000
Binary files a/module/VuFind/tests/fixtures/worldcat/xisbn and /dev/null differ
diff --git a/module/VuFind/tests/fixtures/worldcat/xissn b/module/VuFind/tests/fixtures/worldcat/xissn
deleted file mode 100644
index 6d6fb1e36abdcb6878e188a71790b2c616b9d03c..0000000000000000000000000000000000000000
--- a/module/VuFind/tests/fixtures/worldcat/xissn
+++ /dev/null
@@ -1,18 +0,0 @@
-HTTP/1.1 200 OK
-Server: Apache-Coyote/1.1
-Content-Type: text/xml;charset=UTF-8
-Content-Length: 1817
-Date: Fri, 12 Sep 2014 17:17:29 GMT
-Connection: close
-
-<?xml version="1.0" encoding="UTF-8"?> 
-<rsp xmlns="http://worldcat.org/xid/issn/" stat="ok">
-      <group  rel="this"  >
-      <issn  form="JC"   oclcnum="27999397 614775952 828258510"   title="The New York times" publisher="Ann Arbor, MI : University Microfilms"            issnl="0362-4331" >1542-667X</issn>
-<issn  form="JD"   oclcnum="848189732 869683812 34107580 819006198 475400139"   rawcoverage="Print began with vol. 6, no. 1868 (Sept. 14, 1857)." title="The New York times on the Web" publisher="New York, N.Y. : New York Times"            issnl="0362-4331" >1553-8095</issn>
-<issn  form="JB"   oclcnum="185495447 173336391 798566583 855519714 862776474 436637822 799670030 875826368 715521852 611398715 721108740 477255725 871183240 757341285 1760220 433669505 783915798 783922118 760532692 793841904 719164751 474217043 809570612 184852924 423444534 760046843 863161983 2414466 802634886"   rawcoverage="v. 1-   Jan./Mar. 1913-" title="The New York times index" publisher="New York, New York Times Co"            issnl="0147-538X" >0147-538X</issn>
-<issn  form="JB"   oclcnum="858481778 289500397 858131820 772652747 798923343 423444554 315567303 812136736 612271274 473828002 503228989 872186574 427348605 850514978 762018412 367767356 436627352 757371407 174295982 433738063 638670150 137342435 62313540 652207512 13446366 22436204 25127357 746941922 5657581 612958371 875973682 801785886 1645522 647946096 243424919 773494446 486812086 848537359 472456118 613508528 530930573 719926643 823513770 641015517 802636502 811616918 173858512 474808737 643839034 219854517 42957207 433689829 637645077 440842696"   rawcoverage="Vol. 6, no. 1868 (Sept. 14, 1857)-" title="The New York times" publisher="New-York N.Y. : H.J. Raymond &amp; Co"            issnl="0362-4331" >0362-4331</issn>
- 
-</group>
- 
-</rsp>
diff --git a/module/VuFind/tests/fixtures/worldcat/xoclcnum b/module/VuFind/tests/fixtures/worldcat/xoclcnum
deleted file mode 100644
index db2f0c1b14f61bf4815a06fe0c70243bed581f98..0000000000000000000000000000000000000000
Binary files a/module/VuFind/tests/fixtures/worldcat/xoclcnum and /dev/null differ
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
index f40bfeb617a59c574332a2667f77229b92e64135..71074a340da512d47289905462e3063deb6087fe 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
@@ -90,22 +90,34 @@ class UpgradeTest extends \VuFindTest\Unit\TestCase
         // Prior to 2.4, we expect exactly one warning about using a deprecated
         // theme:
         if ((float)$version < 1.3) {
-            $this->assertEquals(1, count($warnings));
+            $this->assertEquals(2, count($warnings));
+            $this->assertEquals(
+                'The Editions related record module is no longer '
+                . 'supported due to OCLC\'s xID API shutdown.'
+                . ' It has been removed from your settings.',
+                $warnings[0]
+            );
             $this->assertEquals(
                 "WARNING: This version of VuFind does not support "
                 . "the default theme.  Your config.ini [Site] theme setting "
                 . "has been reset to the default: bootprint3.  You may need to "
                 . "reimplement your custom theme.",
-                $warnings[0]
+                $warnings[1]
             );
         } else if ((float)$version < 2.4) {
-            $this->assertEquals(1, count($warnings));
+            $this->assertEquals(2, count($warnings));
+            $this->assertEquals(
+                'The Editions related record module is no longer '
+                . 'supported due to OCLC\'s xID API shutdown.'
+                . ' It has been removed from your settings.',
+                $warnings[0]
+            );
             $this->assertEquals(
                 "WARNING: This version of VuFind does not support "
                 . "the blueprint theme.  Your config.ini [Site] theme setting "
                 . "has been reset to the default: bootprint3.  You may need to "
                 . "reimplement your custom theme.",
-                $warnings[0]
+                $warnings[1]
             );
         } else {
             $this->assertEquals(0, count($warnings));
@@ -269,6 +281,35 @@ class UpgradeTest extends \VuFindTest\Unit\TestCase
         );
     }
 
+    /**
+     * Test removal of xID settings
+     *
+     * @return void
+     */
+    public function testXidDeprecation()
+    {
+        $upgrader = $this->getUpgrader('xid');
+        $upgrader->run();
+        $results = $upgrader->getNewConfigs();
+        $this->assertEquals(
+            ['Similar'], $results['config.ini']['Record']['related']
+        );
+        $this->assertEquals(
+            ['WorldCatSimilar'], $results['WorldCat.ini']['Record']['related']
+        );
+        $this->assertEquals(['apiKey' => 'foo'], $results['config.ini']['WorldCat']);
+        $expectedWarnings = [
+            'The [WorldCat] id setting is no longer used and has been removed.',
+            'The [WorldCat] xISBN_token setting is no longer used and has been removed.',
+            'The [WorldCat] xISBN_secret setting is no longer used and has been removed.',
+            'The [WorldCat] xISSN_token setting is no longer used and has been removed.',
+            'The [WorldCat] xISSN_secret setting is no longer used and has been removed.',
+            'The Editions related record module is no longer supported due to OCLC\'s xID API shutdown. It has been removed from your settings.',
+            'The WorldCatEditions related record module is no longer supported due to OCLC\'s xID API shutdown. It has been removed from your settings.',
+        ];
+        $this->assertEquals($expectedWarnings, $upgrader->getWarnings());
+    }
+
     /**
      * Test permission upgrade
      *
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Connection/WorldCatUtilsTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Connection/WorldCatUtilsTest.php
index 429795338877c29fcd4a4bd1d5e0ad760cc9f214..89d4a51105044301980be4f472d6fdf57b233172 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Connection/WorldCatUtilsTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Connection/WorldCatUtilsTest.php
@@ -44,48 +44,6 @@ use Zend\Http\Client as HttpClient;
  */
 class WorldCatUtilsTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * Test XISBN processing.
-     *
-     * @return void
-     */
-    public function testXISBN()
-    {
-        $client = $this->getClient('xisbn');
-        $result = $client->getXISBN('0140435123');
-        $this->assertEquals(82, count($result));
-        $this->assertTrue(in_array('0140435123', $result));
-        $this->assertTrue(in_array('1848378912', $result));
-    }
-
-    /**
-     * Test XISSN processing.
-     *
-     * @return void
-     */
-    public function testXISSN()
-    {
-        $client = $this->getClient('xissn');
-        $result = $client->getXISSN('0362-4331');
-        $this->assertEquals(4, count($result));
-        $this->assertTrue(in_array('0362-4331', $result));
-        $this->assertTrue(in_array('1542-667X', $result));
-    }
-
-    /**
-     * Test XOCLCNUM processing.
-     *
-     * @return void
-     */
-    public function testXOCLCNUM()
-    {
-        $client = $this->getClient('xoclcnum');
-        $result = $client->getXOCLCNUM('42371494');
-        $this->assertEquals(568, count($result));
-        $this->assertTrue(in_array('42371494', $result));
-        $this->assertTrue(in_array('1710732', $result));
-    }
-
     /**
      * Test related identities
      *
diff --git a/themes/bootstrap3/templates/Related/Deprecated.phtml b/themes/bootstrap3/templates/Related/Deprecated.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..63445d34f9c1ebc4c55c092c9dcf8965c9fd3c66
--- /dev/null
+++ b/themes/bootstrap3/templates/Related/Deprecated.phtml
@@ -0,0 +1,2 @@
+<? /* do nothing -- this module is a placeholder for old deprecated features
+      to prevent legacy configurations from causing fatal errors. */ ?>
\ No newline at end of file
diff --git a/themes/bootstrap3/templates/Related/Editions.phtml b/themes/bootstrap3/templates/Related/Editions.phtml
deleted file mode 100644
index c04b471900944402e1cfc3b79976a84ac24569d1..0000000000000000000000000000000000000000
--- a/themes/bootstrap3/templates/Related/Editions.phtml
+++ /dev/null
@@ -1,18 +0,0 @@
-<? $editions = $this->related->getResults(); if (!empty($editions)): ?>
-  <h4><?=$this->transEsc('Other Editions')?></h4>
-  <ul class="list-group">
-    <? foreach ($editions as $data): ?>
-      <li class="list-group-item">
-        <? $formats = $data->getFormats(); ?>
-        <i class="fa fa-x<? if (count($formats) > 0): ?> fa-<?=preg_replace('/[^a-z0-9]/', '', strtolower($formats[0]))?>" title="<?=$formats[0] ?><? endif; ?>"></i>
-        <a href="<?=$this->recordLink()->getUrl($data)?>"><?=$this->escapeHtml($data->getTitle())?></a>
-        <? $author = $data->getPrimaryAuthor(); if (!empty($author)): ?>
-          <br/><?=$this->transEsc('By')?>: <?=$this->escapeHtml($author);?>
-        <? endif; ?>
-        <? $pubDates = $data->getPublicationDates(); if (!empty($pubDates)): ?>
-          <?=$this->transEsc('Published')?>: (<?=$this->escapeHtml($pubDates[0])?>)
-        <? endif; ?>
-      </li>
-    <? endforeach; ?>
-  </ul>
-<? endif; ?>
\ No newline at end of file