diff --git a/module/VuFind/src/VuFind/Controller/AbstractBase.php b/module/VuFind/src/VuFind/Controller/AbstractBase.php
index acf9804ce14eda9bb922e30cb1b6a178ad57f5ae..5cce5450db9439d40d675f6dae9987bd5e36e369 100644
--- a/module/VuFind/src/VuFind/Controller/AbstractBase.php
+++ b/module/VuFind/src/VuFind/Controller/AbstractBase.php
@@ -531,4 +531,87 @@ class AbstractBase extends AbstractActionController
         $tagSetting = isset($config->Social->tags) ? $config->Social->tags : true;
         return $tagSetting && $tagSetting !== 'disabled';
     }
+
+    /**
+     * Store a referer (if appropriate) to keep post-login redirect pointing
+     * to an appropriate location. This is used when the user clicks the
+     * log in link from an arbitrary page or when a password is mistyped;
+     * separate logic is used for storing followup information when VuFind
+     * forces the user to log in from another context.
+     *
+     * @return void
+     */
+    protected function setFollowupUrlToReferer()
+    {
+        // Get the referer -- if it's empty, there's nothing to store!
+        $referer = $this->getRequest()->getServer()->get('HTTP_REFERER');
+        if (empty($referer)) {
+            return;
+        }
+        $refererNorm = $this->normalizeUrlForComparison($referer);
+
+        // If the referer lives outside of VuFind, don't store it! We only
+        // want internal post-login redirects.
+        $baseUrl = $this->getServerUrl('home');
+        $baseUrlNorm = $this->normalizeUrlForComparison($baseUrl);
+        if (0 !== strpos($refererNorm, $baseUrlNorm)) {
+            return;
+        }
+
+        // If the referer is the MyResearch/Home action, it probably means
+        // that the user is repeatedly mistyping their password. We should
+        // ignore this and instead rely on any previously stored referer.
+        $myResearchHomeUrl = $this->getServerUrl('myresearch-home');
+        $mrhuNorm = $this->normalizeUrlForComparison($myResearchHomeUrl);
+        if ($mrhuNorm === $refererNorm) {
+            return;
+        }
+
+        // If we got this far, we want to store the referer:
+        $this->followup()->store(array(), $referer);
+    }
+
+    /**
+     * Normalize the referer URL so that inconsistencies in protocol and trailing
+     * slashes do not break comparisons.
+     *
+     * @param string $url URL to normalize
+     *
+     * @return string
+     */
+    protected function normalizeUrlForComparison($url)
+    {
+        $parts = explode('://', $url, 2);
+        return trim(end($parts), '/');
+    }
+
+    /**
+     * Retrieve a referer to keep post-login redirect pointing
+     * to an appropriate location.
+     * Unset the followup before returning.
+     *
+     * @return string
+     */
+    protected function getFollowupUrl()
+    {
+        $followup = $this->followup()->retrieve();
+        // followups aren't used in lightboxes.
+        if (isset($followup->url) && !$this->inLightbox()) {
+            return $followup->url;
+        }
+        return '';
+    }
+
+    /**
+     * Sometimes we need to unset the followup to trigger default behaviors
+     *
+     * @return void
+     */
+    protected function clearFollowupUrl()
+    {
+        $followup = $this->followup()->retrieve();
+        if (isset($followup->url)) {
+            unset($followup->url);
+        }
+    }
 }
diff --git a/module/VuFind/src/VuFind/Controller/AbstractRecord.php b/module/VuFind/src/VuFind/Controller/AbstractRecord.php
index 4e7181120880bab1864e5abc8394785f094ba8ec..4f57e2e8c4ff943db77c027d04f95b64534f0b41 100644
--- a/module/VuFind/src/VuFind/Controller/AbstractRecord.php
+++ b/module/VuFind/src/VuFind/Controller/AbstractRecord.php
@@ -258,14 +258,9 @@ class AbstractRecord extends AbstractBase
         $this->flashMessenger()->setNamespace('info')
             ->addMessage('bulk_save_success');
 
-        // Grab the followup namespace so we know where to send the user next:
-        $followup = new SessionContainer($this->searchClassId . 'SaveFollowup');
-        $url = isset($followup->url) ? (string)$followup->url : false;
-        if (!empty($url)) {
-            // Clear followup URL in session -- we're done with it now:
-            unset($followup->url);
-
-            // Redirect!
+        // redirect to followup url saved in saveAction
+        if ($url = $this->getFollowupUrl()) {
+            $this->clearFollowupUrl();
             return $this->redirect()->toUrl($url);
         }
 
@@ -300,13 +295,15 @@ class AbstractRecord extends AbstractBase
         // ProcessSave action (to get back to where we came from after saving).
         // We shouldn't save follow-up information if it points to the Save
         // screen or the "create list" screen, as this causes confusing workflows;
-        // in these cases, we will simply default to pushing the user to record view.
-        $followup = new SessionContainer($this->searchClassId . 'SaveFollowup');
+        // in these cases, we will simply push the user to record view
+        // by unsetting the followup and relying on default behavior in processSave.
         $referer = $this->getRequest()->getServer()->get('HTTP_REFERER');
         if (substr($referer, -5) != '/Save'
             && stripos($referer, 'MyResearch/EditList/NEW') === false
         ) {
-            $followup->url = $referer;
+            $this->setFollowupUrlToReferer();
+        } else {
+            $this->clearFollowupUrl();
         }
 
         // Retrieve the record driver:
@@ -684,4 +681,4 @@ class AbstractRecord extends AbstractBase
         $view->setTemplate($ajax ? 'record/ajaxtab' : 'record/view');
         return $view;
     }
-}
\ No newline at end of file
+}
diff --git a/module/VuFind/src/VuFind/Controller/MyResearchController.php b/module/VuFind/src/VuFind/Controller/MyResearchController.php
index f2778f364c7cb59ff9c8457b0a15edbbdd81eda9..233e5ef0ae6db1529cbf5fc12ee969388faaa78e 100644
--- a/module/VuFind/src/VuFind/Controller/MyResearchController.php
+++ b/module/VuFind/src/VuFind/Controller/MyResearchController.php
@@ -67,56 +67,14 @@ class MyResearchController extends AbstractBase
     }
 
     /**
-     * Store a referer (if appropriate) to keep post-login redirect pointing
-     * to an appropriate location. This is used when the user clicks the
-     * log in link from an arbitrary page or when a password is mistyped;
-     * separate logic is used for storing followup information when VuFind
-     * forces the user to log in from another context.
+     * Maintaining this method for backwards compatibility;
+     * logic moved to parent and method re-named
      *
      * @return void
      */
     protected function storeRefererForPostLoginRedirect()
     {
-        // Get the referer -- if it's empty, there's nothing to store!
-        $referer = $this->getRequest()->getServer()->get('HTTP_REFERER');
-        if (empty($referer)) {
-            return;
-        }
-        $refererNorm = $this->normalizeUrlForComparison($referer);
-
-        // If the referer lives outside of VuFind, don't store it! We only
-        // want internal post-login redirects.
-        $baseUrl = $this->getServerUrl('home');
-        $baseUrlNorm = $this->normalizeUrlForComparison($baseUrl);
-        if (0 !== strpos($refererNorm, $baseUrlNorm)) {
-            return;
-        }
-
-        // If the referer is the MyResearch/Home action, it probably means
-        // that the user is repeatedly mistyping their password. We should
-        // ignore this and instead rely on any previously stored referer.
-        $myResearchHomeUrl = $this->getServerUrl('myresearch-home');
-        $mrhuNorm = $this->normalizeUrlForComparison($myResearchHomeUrl);
-        if ($mrhuNorm === $refererNorm) {
-            return;
-        }
-
-        // If we got this far, we want to store the referer:
-        $this->followup()->store(array(), $referer);
-    }
-
-    /**
-     * Normalize the referer URL so that inconsistencies in protocol and trailing
-     * slashes do not break comparisons.
-     *
-     * @param string $url URL to normalize
-     *
-     * @return string
-     */
-    protected function normalizeUrlForComparison($url)
-    {
-        $parts = explode('://', $url, 2);
-        return trim(end($parts), '/');
+        $this->setFollowupUrlToReferer();
     }
 
     /**
@@ -148,16 +106,13 @@ class MyResearchController extends AbstractBase
 
         // Not logged in?  Force user to log in:
         if (!$this->getAuthManager()->isLoggedIn()) {
-            $this->storeRefererForPostLoginRedirect();
+            $this->setFollowupUrlToReferer();
             return $this->forwardTo('MyResearch', 'Login');
         }
-
-        // Logged in?  Forward user to followup action (if set and not in lightbox)
+        // Logged in?  Forward user to followup action
         // or default action (if no followup provided):
-        $followup = $this->followup()->retrieve();
-        if (isset($followup->url) && !$this->inLightbox()) {
-            $url = $followup->url;
-            unset($followup->url);
+        if ($url = $this->getFollowupUrl()) {
+            $this->clearFollowupUrl();
             return $this->redirect()->toUrl($url);
         }
 
@@ -191,9 +146,9 @@ class MyResearchController extends AbstractBase
         // We may have come in from a lightbox.  In this case, a prior module
         // will not have set the followup information.  We should grab the referer
         // so the user doesn't get lost.
-        $followup = $this->followup()->retrieve();
-        if (!isset($followup->url)) {
-            $followup->url = $this->getRequest()->getServer()->get('HTTP_REFERER');
+        // i.e. if there's already a followup url, keep it; otherwise set one.
+        if (!$this->getFollowupUrl()) {
+            $this->setFollowupUrlToReferer();
         }
 
         // Make view
@@ -260,11 +215,8 @@ class MyResearchController extends AbstractBase
      */
     public function userloginAction()
     {
-        $followup = $this->followup()->retrieve();
-        if (isset($followup->url)) {
-            unset($followup->url);
-        }
-        $this->storeRefererForPostLoginRedirect();
+        $this->clearFollowupUrl();
+        $this->setFollowupUrlToReferer();
         if ($si = $this->getSessionInitiator()) {
             return $this->redirect()->toUrl($si);
         }