diff --git a/securepages.module b/securepages.module
index 47695d5..d977c58 100644
--- a/securepages.module
+++ b/securepages.module
@@ -1,5 +1,5 @@
 <?php
-// $Id$
+// $Id: securepages.module,v 1.15.2.28 2011/02/23 14:41:39 gordon Exp $
 /**
  * @file
  * Provide method of creating allowing certain pages to only viewable from
@@ -37,9 +37,6 @@ function securepages_boot() {
     return;
   }
 
-  if (!isset($_SESSION['securepages_redirect'])) {
-    securepages_redirect();
-  }
 }
 
 /**
@@ -50,16 +47,7 @@ function securepages_init() {
     return;
   }
 
-  /**
-   * If we have redirected in the hook_boot(). Then don't try to redirect
-   * again. This will prevent a loop
-   */
-  if (!isset($_SESSION['securepages_redirect'])) {
-    securepages_redirect();
-  }
-  else {
-    unset($_SESSION['securepages_redirect']);
-  }
+  securepages_redirect();
 }
 
 /**
@@ -107,12 +95,12 @@ function securepages_form_alter(&$form, &$form_state, $form_id) {
     }
     $path = drupal_get_normal_path($path);
     $query = drupal_query_string_encode($query);
-    $page_match = securepages_match($path);
-    if ($page_match && !securepages_is_secure()) {
-      $form['#action'] = securepages_url($path, array('query' => $query, 'secure' => TRUE));
-    }
-    elseif ($page_match === 0 && securepages_is_secure() && variable_get('securepages_switch', FALSE)) {
-      $form['#action'] = securepages_url($path, array('query' => $query, 'secure' => FALSE));
+
+    $target_scheme = securepages_target_scheme($path);
+    
+    if ($target_scheme) {
+      $secure = ($target_scheme == 'https');
+      $form['#action'] = securepages_url($path, array('query' => $query, 'secure' => $secure));
     }
   }
 }
@@ -126,12 +114,11 @@ function securepages_link_alter(&$links, $node) {
   }
   foreach ($links as $module => $link) {
     if ($link['href'] && securepages_can_alter_url($link['href'])) {
-      $page_match = securepages_match($link['href']);
-      if ($page_match && !securepages_is_secure()) {
-        $links[$module]['href'] = securepages_url($link['href'], array('secure' => TRUE));
-      }
-      elseif ($page_match === 0 && securepages_is_secure() && variable_get('securepages_switch', FALSE)) {
-        $links[$module]['href'] = securepages_url($link['href'], array('secure' => FALSE));
+      $target_scheme = securepages_target_scheme($link['href']);
+      
+      if ($target_scheme) {
+        $secure = ($target_scheme == 'https');
+        $links[$module]['href'] = securepages_url($link['href'], array('secure' => $secure));
       }
     }
   }
@@ -140,22 +127,22 @@ function securepages_link_alter(&$links, $node) {
 /**
  * Check the current page and see if we need to redirect to the secure or
  * insecure version of the page.
+ * @param $path The path whose target scheme we need to determine.
  */
 function securepages_redirect() {
-  global $base_url;
-  $path = isset($_GET['q']) ? $_GET['q'] : '';
-  $page_match = securepages_match($path);
-
   if ($_POST) {
     // If something has been posted to here then ignore the rules.
   }
-  elseif ($page_match && !securepages_is_secure()) {
-    securepages_goto(TRUE);
-  }
-  elseif ($page_match === 0 && securepages_is_secure() && variable_get('securepages_switch', FALSE)) {
-    securepages_goto(FALSE);
+  else {
+    $path = isset($_GET['q']) ? $_GET['q'] : '';
+    $target_scheme = securepages_target_scheme($path);
+    
+    if ($target_scheme) {
+      securepages_switch_scheme($target_scheme);
+      return ;
+    }
   }
-
+  
   // Correct the base_url so that everything comes from https.
   if (securepages_is_secure()) {
     $base_url = securepages_baseurl();
@@ -163,24 +150,25 @@ function securepages_redirect() {
 }
 
 /**
- * securepage_goto()
- *
- * Redirects the current page to the secure or insecure version.
- *
- * @param $secure
- *  Determine which version of the set to move to.
+ * Redirect the user to the appropriate scheme.
+ * @param $target_scheme The scheme to switch to; only 'https' and 'http' are accepted.  If any other value is passed, no action is taken.
  */
-function securepages_goto($secure) {
+function securepages_switch_scheme($target_scheme) {
   global $base_root;
+  
+  if (($target_scheme != 'http') && ($target_scheme != 'https')) {
+    return ;
+  }
+
+  $secure = ($target_scheme == 'https');
 
-  $_SESSION['securepages_redirect'] = TRUE;
   $path = !empty($_REQUEST['q']) ? $_REQUEST['q'] : '';
   $query = count($_GET) > 1 ? securepages_get_query($_GET) : NULL;
   $url = securepages_url($path, array('query' => $query, 'secure' => $secure));
 
-  if (function_exists('module_invoke_all')) {
-    foreach (module_implements('exit') as $module) {
-      if ($module != 'devel') {
+  if(function_exists('module_invoke_all')) {
+    foreach(module_implements('exit') as $module) {
+      if($module != 'devel') {
         module_invoke($module, 'exit');
       }
     }
@@ -188,52 +176,113 @@ function securepages_goto($secure) {
   else {
     bootstrap_invoke_all('exit');
   }
-  header('Location: '. $url);
-
+  
+  header('Location: '.$url);
+  
   // Make sure the cache is clear so that the next page will not pick up a cached version.
-  cache_clear_all($base_root . request_uri(), 'cache_page');
+  cache_clear_all($base_root . request_uri(), 'cache_page');  
   exit();
 }
 
 /**
- * securepages_match()
- *
- * check the page past and see if it should be secure or insecure.
- *
- * @param $path
- *  the page of the page to check.
- *
- * @return
- *  0 - page should be insecure.
- *  1 - page should be secure.
- *  NULL - do not change page.
+ * Determine the target scheme we should switch to, or that no switch should occur.
+ * @param $path The path whose target scheme we need to determine.
+ * @return 'https' if the path should be switched to https; 'http' if the path should be switched to http; NULL if no switch should occur. 
  */
-function securepages_match($path) {
-  /**
-   * Check to see if the page matches the current settings
-   */
-  $secure = variable_get('securepages_secure', 1);
+function securepages_target_scheme($path) {
+  $should_be_secure = _securepages_should_be_secure($path);
+  $is_secure = securepages_is_secure();
+  $switch_back_to_http = variable_get('securepages_switch', FALSE);
+  
+  if ($should_be_secure && !$is_secure) {
+    return 'https';
+  }
+  else if (!$should_be_secure && $is_secure && $switch_back_to_http ) {
+    return 'http';
+  }
+  
+  return NULL;
+}
+
+/**
+ * Determine whether or not the specified path should be secure.
+ * @param $path The path to examine for secure mode required.
+ * @return TRUE if the path should be secure, FALSE otherwise.
+ */
+function _securepages_should_be_secure($path) {
   $pages = variable_get('securepages_pages', "node/add*\nnode/*/edit\nuser/*\nadmin*");
   $ignore = variable_get('securepages_ignore', "*/autocomplete/*\n*/ajax/*");
+  $matching_pages_should_be_secure = variable_get('securepages_secure', 1);
 
   if ($ignore) {
     $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($ignore, '/')) .')$/';
     if (preg_match($regexp, $path)) {
-      return securepages_is_secure() ? 1 : 0;
+      return (bool) securepages_is_secure();
     }
   }
+
+  $page_matches = FALSE;
   if ($pages) {
+    $path_matches = FALSE;
+    $alias_matches = FALSE;
+
     $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($pages, '/')) .')$/';
-    $result = preg_match($regexp, $path);
-    if (function_exists('drupal_get_path_alias')) {
-      $path_alias = drupal_get_path_alias($path);
-      $result |= preg_match($regexp, $path_alias);
+    $path_matches = preg_match($regexp, $path);
+    
+    if (!$path_matches) {
+      if (function_exists('drupal_get_path_alias')) {
+        $alias = drupal_get_path_alias($path);
+        $alias_matches = preg_match($regexp, $alias);
+      }
     }
-    return !($secure xor $result) ? 1 : 0;
+
+    $page_matches = $path_matches || $alias_matches;
+  }
+
+  if (!$page_matches) {
+    $path_matches = FALSE;
+    $alias_matches = FALSE;
+
+    $path_matches = securepages_invoke_should_be_secure($path);
+
+    if (!$path_matches) {
+      if (function_exists('drupal_get_path_alias')) {
+        $alias = drupal_get_path_alias($path);
+        $alias_matches = securepages_invoke_should_be_secure($alias); 
+      }
+    }
+
+    $page_matches = $path_matches || $alias_matches;
+  }
+
+  if ($matching_pages_should_be_secure) {
+    return $page_matches;
   }
   else {
-    return;
+    return !$page_matches;
+  }
+}
+
+/**
+ * Invoke the securepages_should_be_secure hook on all available modules.
+ * @param $path The path to examine for secure mode required.
+ * @return TRUE if at least one module wants the path to be secure, FALSE otherwise.
+ */
+function securepages_invoke_should_be_secure($path) {
+  if (!function_exists('module_list')) {
+    return FALSE;
   }
+
+  foreach (module_list(TRUE, FALSE) as $module) {
+    $function = $module . '_securepages_should_be_secure';
+    if (function_exists($function)) {
+      if ($function($path)) {
+        return TRUE;
+      }
+    }
+  }
+
+  return FALSE;
 }
 
 /**
@@ -441,4 +490,4 @@ function securepages_can_alter_url($url) {
   }
 
   return TRUE;
-}
\ No newline at end of file
+}
