diff -rupN original/prev_next/prev_next.module new/prev_next/prev_next.module
--- original/prev_next/prev_next.module	2010-05-17 17:54:07.000000000 +0100
+++ new/prev_next/prev_next.module	2010-09-09 19:41:44.000000000 +0100
@@ -519,9 +519,27 @@ function prev_next_nodeapi(&$node, $op) 
 }
 
 /*
+ * Callable API function to get the next/prev pager
+ */
+function prev_next_pager(&$node, $pager_options) {
+  
+  // call hook_prev_next_pager
+  foreach (module_implements('prev_next_pager') as $module) {
+    $function = $module . '_prev_next_pager';
+    $ret = $function($node, $pager_options);
+    if ($ret !== FALSE) {
+      // If the function returns FALSE, keep trying other methods
+      return $ret;
+    }
+  }
+  
+}
+/*
  * Callable API function to get the next/prev nid of a given nid
  */
 function prev_next_nid($nid, $op = 'next') {
+  
+  // call prev_next_nid
   foreach (module_implements('prev_next_nid') as $module) {
     $function = $module . '_prev_next_nid';
     $ret = $function($nid, $op);
diff -rupN original/prev_next/prev_next_views.module new/prev_next/prev_next_views.module
--- original/prev_next/prev_next_views.module	2010-05-17 17:54:07.000000000 +0100
+++ new/prev_next/prev_next_views.module	2010-09-09 19:54:06.000000000 +0100
@@ -1,32 +1,161 @@
 <?php
 // $Id: prev_next_views.module,v 1.1.2.2 2010/05/17 16:54:07 jcnventura Exp $
 
+// static class avoids need for globals
+class prev_next_views {
+  static $registered_node_ids;
+  static $session_was_registered = false;
+  
+  /*
+   *  register session nodes
+   * 
+   */
+  static function register_session_nodes(&$nids) {
+    
+    // cache the view node array
+    $_SESSION['prev_next_views'] = $nids;
+    
+    // cache the view uri 
+    $uri = request_uri();
+   
+    $_SESSION['prev_next_views_view_uri'] = $uri;
+     
+    self::$session_was_registered = true;
+    
+  }
+  /*
+   * register_node_access
+   * 
+   * register access to a node
+   * 
+   */
+  static function register_node_access(&$node) {
+    
+    if (!isset(self::$registered_node_ids)) {
+      self::$registered_node_ids = array();
+    }
+    
+    self::$registered_node_ids[] = $node->nid;
+  }
+  
+  /*
+   * 
+   *  clean_up
+   *  
+   *  if the node registry shows that we have not accessed any of the registered nodes
+   *  in the current request then we can clear the session variable.
+   */
+  static function clean_up() {
+
+    // if we have just registered the session we don't want to scavenge it
+    if (self::$session_was_registered) return;
+    
+    if (!isset($_SESSION['prev_next_views'])) return;
+          
+    if (isset(self::$registered_node_ids)) {
+      foreach (self::$registered_node_ids as $nid) {
+        if (array_search($nid, $_SESSION['prev_next_views']) !== FALSE) {
+          return;
+        }  
+      }
+    }
+    
+    unset($_SESSION['prev_next_views']);
+    unset($_SESSION['prev_next_views_view_uri']);
+   
+  }
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function prev_next_views_theme($existing, $type, $theme, $path) {
+
+  return array(
+    'prev_next_views_node' => array(
+      'arguments' => array('node' => null, 'link_text' => null),
+    ),
+    'prev_next_views_pager' => array(
+      'arguments' => array('pager' => null),
+    )
+  );
+}
+
 /**
  * Implementation of hook_prev_next_nid().
+ * 
+ * Rturn FALSE to use the default implementation
  */
 function prev_next_views_prev_next_nid($nid, $op = 'next') {
-  if (isset($_SESSION['prev_next_views'])) {
-    // There's a prev_next views list stored for this session
-    $index = array_search($nid, $_SESSION['prev_next_views']);
-    if ($index !== FALSE) {
-      // This node is part of the prev_next list, so return the appropriate node
-      $ret = $index;
-      if ($op == 'prev') {
-        $ret--;
-      }
-      elseif ($op == 'next') {
-        $ret++;
-      }
+  $index = prev_next_views_node_index($nid, $op);
+  if ($index === FALSE) return 0;
+  
+  return $_SESSION['prev_next_views'][$index];
+}
 
-      if (($ret >= 0) && ($ret < count($_SESSION['prev_next_views']))) {
-        return $_SESSION['prev_next_views'][$ret];
-      }
-      else {
-        // First or last element of the view
-        return 0;
-      }
-    }
+/*
+ * 
+ * prev_next_views_node_count()
+ * 
+ */
+function prev_next_views_node_count()
+{
+  if (isset($_SESSION['prev_next_views'])) {
+    return count($_SESSION['prev_next_views']);  
   }
+  
+  return FALSE;
+}
+/*
+ * 
+ * prev_next_views_node_index()
+ * 
+ * Returns a valid node index or FALSE
+ */
+function prev_next_views_node_index($nid, $op = 'next')
+{
+  if (!isset($_SESSION['prev_next_views'])) return FALSE;
+  
+  $node_count = prev_next_views_node_count();
+
+  // There's a prev_next views list stored for this session
+  $index = array_search($nid, $_SESSION['prev_next_views']);
+  if ($index === FALSE) return FALSE;
+  
+  // This node is part of the prev_next list, so return the appropriate node
+  $ret = $index;
+  switch ($op) {
+
+    case 'first':
+      if ($ret == 0) return FALSE;  // first node selected
+      $ret = 0;
+      break;
+    
+    case 'prev':
+      $ret--;
+      break;
+    
+    case 'current':
+      break;
+      
+    case 'next':
+      $ret++;
+      break;
+      
+    case 'last':
+      if ($ret == ($node_count - 1)) return FALSE;  // last node selected
+      $ret = count($_SESSION['prev_next_views']) - 1;
+      break;
+      
+    default:
+      return FALSE;
+      
+  }
+
+  if (($ret >= 0) && ($ret < $node_count)) {
+   return $ret;
+  } 
+  
   return FALSE;
 }
 
@@ -63,12 +192,22 @@ function prev_next_views_menu() {
  * Implementation of hook_nodeapi().
  */
 function prev_next_views_nodeapi(&$node, $op) {
-  if (isset($_SESSION['prev_next_views']) && (array_search($node->nid, $_SESSION['prev_next_views']) === FALSE)) {
-    // The current node is no longer part of the views results, so forget about it
-    unset($_SESSION['prev_next_views']);
+  switch ($op) {
+      /*
+       * node view
+       */
+    case 'view':
+        prev_next_views::register_node_access($node);
+    break;
   }
 }
 
+/**
+ * Implementation of hook_exit().
+ */
+function prev_next_views_exit($destination = NULL) {
+  prev_next_views::clean_up();
+}
 
 /**
  * Implementation of hook_views_api().
@@ -85,6 +224,7 @@ function prev_next_views_views_api() {
  */
 function prev_next_views_views_pre_execute(&$view) {
   if (in_array($view->name, variable_get('prev_next_views_enabled', array()))) {
+    
     $query = db_rewrite_sql($view->build_info['query'], $view->base_table, $view->base_field, array('view' => &$view));
     $args = $view->build_info['query_args'];
 
@@ -94,6 +234,184 @@ function prev_next_views_views_pre_execu
       $nids[] = $item['nid'];
     }
 
-    $_SESSION['prev_next_views'] = $nids;
+    // register the session nodes
+    prev_next_views::register_session_nodes($nids);
   }
+
 }
+
+/*
+ * 
+ * theme_prev_next_views_node()
+ * 
+ */
+function theme_prev_next_views_node($node, $link_text) {
+  if (!isset($node) || !isset($link_text)) return NULL;
+  
+  $nid = $node->nid;
+  
+  $options = array(
+        'attributes' => array('class' => 'thumbnail'),
+        'html'  => TRUE,
+      );
+      
+  switch($node->type) {
+    
+    // For image nodes only
+    case 'image':
+      // This is an image node, get the thumbnail
+      $html = l(image_display($node, 'thumbnail'), "node/$nid", $options);
+      $html .= l($link_text, "node/$nid", array('html' => TRUE));
+      return $html;
+  
+    // For video nodes only
+    case 'video':
+      foreach ($node->files as $fid => $file) {
+        $html  = '<img src="' . base_path() . $file->filepath;
+        $html .= '" alt="' . $node->title;
+        $html .= '" title="' . $node->title;
+        $html .= '" class="image image-thumbnail" />';
+        $img_html = l($html, "node/$nid", $options);
+        $text_html = l($link_text, "node/$nid", array('html' => TRUE));
+        return $img_html . $text_html;
+      }
+      
+    default:
+      $html .= l($link_text, "node/$nid", array('html' => TRUE));
+      return $html;
+  }
+}
+
+/*
+ * 
+ * theme_prev_next_views_pager()
+ * 
+ */
+function theme_prev_next_views_pager(&$pager) {
+ 
+  $first_link = $pager['first'];
+  $prev_link = $pager['prev'];
+  $current = $pager['current'];
+  $next_link = $pager['next'];
+  $last_link = $pager['last'];
+  $view_link = $pager['view_url'];
+  
+  $list = '';
+  
+  // utilise similar CSS to views pager 
+  if (isset($first_link)) {
+    $list .= '<li class="pager-first first">'.$first_link.'</li>';
+  }
+  if (isset($prev_link)) {  
+    $list .= '<li class="pager-previous prev">'.$prev_link.'</li>';
+  }
+  if (isset($current)) {  
+    $list .= '<li class="pager-item current">'.$current.'</li>';
+  }
+  if (isset($next_link)) {
+    $list .= '<li class="pager-next">'.$next_link.'</li>';
+  }
+  if (isset($last_link)) {
+    $list .= '<li class="pager-last last">'.$last_link.'</li>';
+  }
+  
+  if (strlen($list) > 0) {
+    $list = '<ul class="pager main">'.$list.'</ul>';
+  } else {
+    unset($list);
+  }
+  
+  if (isset($list) || isset($view_link)) {
+    // theme final output
+    $html = '<div class="prev-next-pager">';
+    
+    if (isset($view_link)) {
+      $html .= '<ul class="pager aux"><li class="pager-back">'.$view_link.'</li></ul>';
+    }
+    
+    if (isset($list)) {
+      $html .= $list;
+    }
+    
+    $html .= "</div>";
+  }
+  
+  return $html;
+ }
+/**
+ * Implementation of hook_prev_next_pager().
+ * 
+ * Return FALSE to use the default implementation.
+ * 
+ */
+function prev_next_views_prev_next_pager(&$node, $pager_options) {
+
+  $parts = array();
+  
+  // get the pager parts
+  foreach ($pager_options as $key => $options) {
+    $text = $options['text'];
+    $part = prev_next_views_pager_part($node, $key, $text);
+    if (isset($part)) {  
+      $parts[$key] = $part;
+    }
+  }
+  
+  if (count($parts) == 0) return NULL;
+  
+  return theme("prev_next_views_pager", $parts);
+}
+
+/*
+ * 
+ * prev_next_views_pager_part()
+ * 
+ */
+function prev_next_views_pager_part($node, $part = 'next', $text = "") {
+  global $base_url;
+  
+  if (!function_exists('prev_next_nid')) {
+    return NULL;
+  }
+  
+  switch($part) {
+    case 'first':
+    case 'prev':
+    case 'next':
+    case 'last':
+      $n_nid = prev_next_nid($node->nid, $part);
+      break;
+    
+    case 'current':
+      $index = prev_next_views_node_index($node->nid, $part);
+      if ($index === false) return NULL;
+      $node_count = prev_next_views_node_count();
+      if ($node_count === false) return NULL;
+      
+      $index++;
+      $link_text = $index.t(' of ').$node_count;
+      return $link_text;
+      
+    case 'view_url';
+      if (!isset($_SESSION['prev_next_views_view_uri'])) {
+        return NULL;
+      }
+      
+      // link to the original view url.
+      // this is a complete url so do not use l() or url() as % encoding may break it
+      $uri = $_SESSION['prev_next_views_view_uri'];
+      $url = $base_url.$uri;
+      return '<a href="'.$url.'">'.$text.'</a>';
+      
+    default:
+      return NULL;
+  }
+  
+  if ($n_nid == 0) return NULL;
+  
+  // theme the node
+  $n_node = node_load($n_nid);
+  return theme("prev_next_views_node", $n_node, $text);
+
+}
+
