Index: trunk/lib/App.inc.php
===================================================================
--- trunk/lib/App.inc.php	(revision 550)
+++ trunk/lib/App.inc.php	(revision 551)
@@ -1346,9 +1346,9 @@
         // Get URL from stored boomerang. Allow non specific URL if ID not valid.
         if ($this->validBoomerangURL($id, true)) {
-            if (isset($id) && isset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$id])) {
-                $url = $_SESSION['_app'][$this->_ns]['boomerang']['url'][$id];
+            if (isset($id) && isset($_SESSION['_app'][$this->_ns]['boomerang'][$id])) {
+                $url = $_SESSION['_app'][$this->_ns]['boomerang'][$id]['url'];
                 $this->logMsg(sprintf('dieBoomerangURL(%s) found: %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
             } else {
-                $url = end($_SESSION['_app'][$this->_ns]['boomerang']['url']);
+                $url = end($_SESSION['_app'][$this->_ns]['boomerang'])['url'];
                 $this->logMsg(sprintf('dieBoomerangURL(%s) using: %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
             }
@@ -1366,7 +1366,8 @@
         }
 
-        // A redirection will never happen immediately twice.
-        // Set the time so ensure this doesn't happen.
-        $_SESSION['_app'][$this->_ns]['boomerang']['time'] = time();
+        // A redirection will never happen immediately twice. Set the time so we can ensure this doesn't happen.
+        $_SESSION['_app'][$this->_ns]['boomerang_last_redirect_time'] = time();
+
+        // Do it.
         $this->dieURL($url, $carry_args);
     }
@@ -1392,10 +1393,10 @@
             $url = preg_replace(array('/([&?])boomerang=[^&?]+[&?]?/', '/[&?]$/'), array('$1', ''), $url);
 
-            if (isset($_SESSION['_app'][$this->_ns]['boomerang']['url']) && is_array($_SESSION['_app'][$this->_ns]['boomerang']['url']) && !empty($_SESSION['_app'][$this->_ns]['boomerang']['url'])) {
+            if (isset($_SESSION['_app'][$this->_ns]['boomerang']) && is_array($_SESSION['_app'][$this->_ns]['boomerang']) && !empty($_SESSION['_app'][$this->_ns]['boomerang'])) {
                 // If the ID=>URL pair currently exists in the boomerang array, delete.
-                foreach (array_keys($_SESSION['_app'][$this->_ns]['boomerang']['url'], $url) as $existing_key) {
-                    if ($existing_key == $id) {
+                foreach (array_keys($_SESSION['_app'][$this->_ns]['boomerang']) as $existing_id) {
+                    if ($existing_id === $id) {
                         $this->logMsg(sprintf('Found and deleting existing ID=>URL pair: %s=>%s', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
-                        unset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$existing_key]);
+                        unset($_SESSION['_app'][$this->_ns]['boomerang'][$existing_id]);
                     }
                 }
@@ -1403,8 +1404,15 @@
 
             if (isset($id)) {
-                $_SESSION['_app'][$this->_ns]['boomerang']['url'][$id] = $url;
+                $_SESSION['_app'][$this->_ns]['boomerang'][$id] = array(
+                    'url' => $url,
+                    'added_time' => time(),
+                );
             } else {
-                $_SESSION['_app'][$this->_ns]['boomerang']['url'][] = $url;
-            }
+                $_SESSION['_app'][$this->_ns]['boomerang'][] = array(
+                    'url' => $url,
+                    'added_time' => time(),
+                );
+            }
+
             $this->logMsg(sprintf('setBoomerangURL(%s): %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
             return true;
@@ -1428,11 +1436,11 @@
 
         if (isset($id)) {
-            if (isset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$id])) {
-                return $_SESSION['_app'][$this->_ns]['boomerang']['url'][$id];
+            if (isset($_SESSION['_app'][$this->_ns]['boomerang'][$id])) {
+                return $_SESSION['_app'][$this->_ns]['boomerang'][$id]['url'];
             } else {
                 return '';
             }
-        } else if (is_array($_SESSION['_app'][$this->_ns]['boomerang']['url'])) {
-            return end($_SESSION['_app'][$this->_ns]['boomerang']['url']);
+        } else if (is_array($_SESSION['_app'][$this->_ns]['boomerang']) && !empty($_SESSION['_app'][$this->_ns]['boomerang'])) {
+            return end($_SESSION['_app'][$this->_ns]['boomerang'])['url'];
         } else {
             return false;
@@ -1452,9 +1460,9 @@
         }
 
-        if (isset($id) && isset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$id])) {
+        if (isset($id) && isset($_SESSION['_app'][$this->_ns]['boomerang'][$id])) {
             $url = $this->getBoomerangURL($id);
-            unset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$id]);
-        } else if (is_array($_SESSION['_app'][$this->_ns]['boomerang']['url'])) {
-            $url = array_pop($_SESSION['_app'][$this->_ns]['boomerang']['url']);
+            unset($_SESSION['_app'][$this->_ns]['boomerang'][$id]);
+        } else if (is_array($_SESSION['_app'][$this->_ns]['boomerang'])) {
+            $url = array_pop($_SESSION['_app'][$this->_ns]['boomerang'])['url'];
         }
         $this->logMsg(sprintf('deleteBoomerangURL(%s): %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
@@ -1474,28 +1482,24 @@
         }
 
-        if (!isset($_SESSION['_app'][$this->_ns]['boomerang']['url'])) {
+        if (!isset($_SESSION['_app'][$this->_ns]['boomerang'])) {
             $this->logMsg(sprintf('validBoomerangURL(%s) no boomerang URL set.', $id), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
 
-        // Time is the time stamp of a boomerangURL redirection, or setting of a boomerangURL.
-        // a boomerang redirection will always occur at least several seconds after the last boomerang redirect
-        // or a boomerang being set.
-        $boomerang_time = isset($_SESSION['_app'][$this->_ns]['boomerang']['time']) ? $_SESSION['_app'][$this->_ns]['boomerang']['time'] : 0;
-
         $url = '';
-        if (isset($id) && isset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$id])) {
-            $url = $_SESSION['_app'][$this->_ns]['boomerang']['url'][$id];
+        if (isset($id) && isset($_SESSION['_app'][$this->_ns]['boomerang'][$id])) {
+            $url = $_SESSION['_app'][$this->_ns]['boomerang'][$id]['url'];
+            $added_time = $_SESSION['_app'][$this->_ns]['boomerang'][$id]['added_time'];
         } else if (!isset($id) || $use_nonspecificboomerang) {
             // Use non specific boomerang if available.
-            $url = end($_SESSION['_app'][$this->_ns]['boomerang']['url']);
-        }
-
-        $this->logMsg(sprintf('validBoomerangURL(%s) testing: %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
-
-        if ('' == $url) {
+            $url = end($_SESSION['_app'][$this->_ns]['boomerang'])['url'];
+            $added_time = end($_SESSION['_app'][$this->_ns]['boomerang'])['added_time'];
+        }
+
+        if ('' == trim($url)) {
             $this->logMsg(sprintf('validBoomerangURL(%s) not valid, empty!', $id), LOG_DEBUG, __FILE__, __LINE__);
             return false;
         }
+
         if ($url == absoluteMe()) {
             // The URL we are directing to is the current page.
@@ -1503,12 +1507,18 @@
             return false;
         }
-        if ($boomerang_time >= (time() - 2)) {
+
+        // Last redirect time is the time stamp of the last boomerangURL redirection, if any. A boomerang redirection should always occur at least several seconds after the last boomerang redirect (time it takes to load a page and receive user interaction).
+        $boomerang_last_redirect_time = isset($_SESSION['_app'][$this->_ns]['boomerang_last_redirect_time']) ? $_SESSION['_app'][$this->_ns]['boomerang_last_redirect_time'] : null;
+        if (isset($boomerang_last_redirect_time) && $boomerang_last_redirect_time >= (time() - 2)) {
             // Last boomerang direction was less than 2 seconds ago.
-            $this->logMsg(sprintf('validBoomerangURL(%s) not valid, boomerang_time too short: %s seconds', $id, time() - $boomerang_time), LOG_DEBUG, __FILE__, __LINE__);
-            return false;
-        }
-        if ($boomerang_time < (time() - 72000)) {
-            // Last boomerang direction was more than 20 minutes ago.
-            $this->logMsg(sprintf('validBoomerangURL(%s) not valid, boomerang_time too long: %s seconds', $id, time() - $boomerang_time), LOG_DEBUG, __FILE__, __LINE__);
+            $this->logMsg(sprintf('validBoomerangURL(%s) not valid, boomerang_last_redirect_time too short: %s seconds', $id, time() - $boomerang_last_redirect_time), LOG_DEBUG, __FILE__, __LINE__);
+            return false;
+        }
+
+        if (isset($added_time) && $added_time < (time() - 72000)) {
+            // Last boomerang direction was more than 20 hours ago.
+            $this->logMsg(sprintf('validBoomerangURL(%s) not valid, added_time too old: %s seconds', $id, time() - $added_time), LOG_DEBUG, __FILE__, __LINE__);
+            // Delete this defunct boomerang.
+            $this->deleteBoomerangURL($id);
             return false;
         }
