diff --git handlers/views_handler_relationship_groupwise_max.inc handlers/views_handler_relationship_groupwise_max.inc
new file mode 100644
index 0000000..b135af7
--- /dev/null
+++ handlers/views_handler_relationship_groupwise_max.inc
@@ -0,0 +1,304 @@
+<?php
+// $Id$
+/*
+ * @file
+ * Relationship for groupwise maximum handler.
+ */
+
+/**
+ * Relationship handler that allows a groupwise maximum of the linked in table. 
+ * For a definition, see: 
+ * http://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html
+ * In lay terms, instead of joining to get all matching records in the linked 
+ * table, we get only one record, a 'representative record' picked according
+ * to a given criterion.
+ * 
+ * Example:
+ * Suppose we have a term view that gives us the terms: Horse, Cat, Aardvark.
+ * We wish to show for each term the most recent node of that term.
+ * What we want is some kind of relationship from term to node.
+ * But a regular relationship will give us all the nodes for each term, 
+ * giving the view multiple rows per term. What we want is just one 
+ * representative node per term, the node that is the 'best' in some way:
+ * eg, the most recent, the most commented on, the first in alphabetical order.
+ * 
+ * This handler gives us that kind of relationship from term to node.
+ * The method of choosing the 'best' implemented with a sort
+ * that the user selects in the relationship settings. 
+ * 
+ * So if we want our term view to show the most commented node for each term, 
+ * add the relationship and in its options, pick the 'Comment count' sort.
+ * 
+ * Relationship definition
+ *  - 'outer field': The outer field to substitute into the correlated subquery.
+ *       This must be the full field name, not the alias. 
+ *       Eg: 'term_data.tid'.
+ *  - 'argument table',
+ *    'argument field': These options define a views argument that the subquery
+ *     must add to itself to filter by the main view.
+ *     Example: the main view shows terms, this handler is being used to get to
+ *     the nodes base table. Your argument must be 'term_node', 'tid', as this 
+ *     is the argument that should be added to a node view to filter on terms.
+ * 
+ * A note on performance:
+ * This relationship uses a correlated subquery, which is expensive.
+ * Subsequent versions of this handler could also implement the alternative way 
+ * of doing this, with a join -- though this looks like it could be pretty messy
+ * to implement. This is also an expensive method, so providing both methods and
+ * allowing the user to choose which one works fastest for their data might be 
+ * the best way.
+ * If your use of this relationship handler is likely to result in large 
+ * data sets, you might want to consider storing statistics in a separate table,
+ * in the same way as node_comment_statistics.
+ */
+class views_handler_relationship_groupwise_max extends views_handler_relationship {
+
+  /**
+   * Defines default values for options.
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['subquery_sort'] = array('default' => array(NULL)); // TODO: Correct structure?
+    $options['subquery_order'] = array('default' => 'DESC'); // Descending more useful.
+    $options['subquery_regenerate'] = array('default' => FALSE);
+    $options['subquery_view'] = array('default' => FALSE);
+    $options['subquery_namespace'] = array('default' => FALSE);
+
+    return $options;
+  }
+
+  /**
+   * Extends the relationship's basic options, allowing the user to pick
+   * a sort and an order for it.
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    // Get the sorts that apply to our base.
+    $sorts = views_fetch_fields($this->definition['base'], 'sort');    
+    foreach ($sorts as $sort_id => $sort) {
+      $options[$sort_id] = "$sort[group]: $sort[title]";
+    }
+
+    $form['subquery_sort'] = array(
+      '#type' => 'select',
+      '#title' => t('Representative sort criterion'),
+      '#default_value' => $this->options['subquery_sort'],
+      '#options' => $options,
+      '#description' => theme('advanced_help_topic', 'views', 'relationship-representative') .
+      t('This sort determines how the representative item is chosen. Eg, to show the most recent node for each term in a term view, select "Node: Post date".'),
+    );
+
+    $form['subquery_order'] = array(
+      '#type' => 'radios',
+      '#title' => t('Representative sort order'),
+      '#options' => array('ASC' => t('Ascending'), 'DESC' => t('Descending')),
+      '#default_value' => $this->options['subquery_order'],
+    ); 
+
+    $form['subquery_namespace'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Subquery namespace'),
+      '#default_value' => $this->options['subquery_namespace'],
+    ); 
+
+    
+    // WIP: This stuff doens't work yet: namespacing issues.
+    // A list of suitable views to pick one as the subview.   
+    $views = array('' => '<none>');
+    $all_views = views_get_all_views();   
+    foreach ($all_views as $view) {
+      // Only get views that are suitable:
+      // - base must the base that our relationship joins towards
+      // - must have fields.
+      if ($view->base_table == $this->definition['base'] && !empty($view->display['default']->display_options['fields'])) {
+        // TODO: check the field is the correct sort?
+        // or let users hang themselves at this stage and check later?
+        if ($view->type == 'Default') {
+          $views[t('Default Views')][$view->name] = $view->name;
+        }
+        else {
+          $views[t('Existing Views')][$view->name] = $view->name;
+        }
+      }
+    }
+
+    $form['subquery_view'] = array(
+      '#type' => 'select',
+      '#title' => t('Representative view'),
+      '#default_value' => $this->options['subquery_view'],
+      '#options' => $views,
+      '#description' => t('Advanced. Use another view to generate the relationship subquery. This allows you to use filtering and more than one sort. If you pick a view here, the sort options above are ignored. Your view must have the ID of its base as its only field, and should have some kind of sorting.'),
+    ); 
+
+    $form['subquery_regenerate'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Generate subquery each time view is run.'),
+      '#default_value' => $this->options['subquery_regenerate'],
+      '#description' => t('Will re-generate the subquery for this relationship every time the view is run, instead of only when these options are saved. Use for testing if you are making changes elsewhere. WARNING: seriously impairs performance.'),
+    );
+  } 
+
+  /**
+   * Perform any necessary changes to the form values prior to storage.
+   * There is no need for this function to actually store the data.
+   *
+   * Generate the subquery string when the user submits the options, and store 
+   * it. This saves the expense of generating it when the view is run.
+   */
+  function options_submit($form, &$form_state) { 
+    // Get the new user options from the form values.
+    $new_options = $form_state['values']['options'];   
+    $subquery = $this->left_query($new_options);
+    // Add the subquery string to the options we're about to store.
+    $this->options['subquery_string'] = $subquery;
+  }
+
+  /**
+   * Helper function to create a pseudo view with a namespace added.
+   */
+  function view_aliased() {
+    views_include('view');
+    $view = new view();
+    $view->vid = 'new'; // @todo: what's this?
+    $view->base_table = $this->definition['base'];
+    $view->add_display('default');
+    return $view;
+  }
+  /**
+   * Generate a subquery given the user options, as set in the options. 
+   * These are passed in rather than picked up from the object because we 
+   * generate the subquery when the options are saved, rather than when the view
+   * is run. This saves considerable time.
+   *
+   * @param $options
+   *   An array of options:
+   *    - subquery_sort: the id of a views sort.
+   *    - subquery_order: either ASC or DESC.
+   * @return
+   *    The subquery SQL string, ready for use in the main query.
+   */
+  function left_query($options) {
+
+    // Either load another view, or create one on the fly.
+    if ($options['subquery_view']) {
+      // We don't use views_get_view because we want our own class of view.
+      views_include('view');      
+      $temp_view = view::load($options['subquery_view']);
+
+      // Remove all fields from default display
+      unset($temp_view->display['default']->display_options['fields']);
+    }
+    else {
+      // Create a new view object on the fly.
+      // We use this to generate a query from the chosen sort.
+      $temp_view = $this->view_aliased();
+      
+      // Add the sort from the options to the default display.
+      $sort = $options['subquery_sort'];
+      list($sort_table, $sort_field) = explode('.', $sort);
+      $sort_options = array('order' => $options['subquery_order']);
+      $temp_view->add_item('default', 'sort', $sort_table, $sort_field, $sort_options);
+    }
+    $temp_view->namespace = (!empty($options['subquery_namespace'])) ? '_'. $options['subquery_namespace'] : '_INNER';
+   
+    // The value we add here does nothing, but doing this adds the right tables 
+    // and puts in a WHERE clause with a placeholder we can grab later.
+    $temp_view->args[] = '**CORRELATED**';
+
+    // Add the base table ID field.
+    $views_data = views_fetch_data($this->definition['base']);
+    $base_field = $views_data['table']['base']['field'];
+    $temp_view->add_item('default', 'field', $this->definition['base'], $this->definition['field']);
+
+    // Add the correct argument for our relationship's base
+    // ie ehe 'how to get back to base' argument.
+    // The relationship definition tells us which one to use.
+    $temp_view->add_item(
+      'default', 
+      'argument', 
+      $this->definition['argument table'], // eg 'term_node', 
+      $this->definition['argument field'] //  eg 'tid'
+    );
+
+    // Build the view. The creates the query object and produces the query 
+    // string but does not run any queries.
+    $temp_view->build();
+    
+    // Now collect the query SQL string..
+
+    $subquery = $temp_view->build_info['query'];
+
+    // We need to prevent the last %d placeholder from getting replaced with an
+    // argument value, because it's the one that needs to get the outer
+    // reference field.
+    // Replacing the %d with %dd protects it.
+    $subquery = preg_replace('/%d(?!.*%d.*)/', '%%d', $subquery);
+
+    // Get the arguments from the view build info.
+    $args = $temp_view->build_info['query_args'];  
+ 
+    // Replace the placeholders with the arguments.
+    _db_query_callback($args, TRUE);
+
+    $subquery = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $subquery);
+
+    // Add in the outer field.
+    $subquery = preg_replace('/%d/', $this->definition['outer field'], $subquery);
+
+    // The query we get doesn't include the LIMIT.
+    // TODO: Is there a better way than adding it by hand?
+    $subquery .= ' LIMIT 1';
+        
+    return $subquery;
+  }
+
+  /**
+   * Called to implement a relationship in a query.
+   * This is mostly a copy of our parent's query() except for this bit with
+   * the join class.
+   */
+  function query() {
+    // Figure out what base table this relationship brings to the party.
+    $table_data = views_fetch_data($this->definition['base']);
+    $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field'];
+
+    $this->ensure_my_table();
+
+    $def = $this->definition;
+    $def['table'] = $this->definition['base'];
+    $def['field'] = $base_field;
+    $def['left_table'] = $this->table_alias;
+    $def['left_field'] = $this->field;
+    if (!empty($this->options['required'])) {
+      $def['type'] = 'INNER';
+    }
+    
+    if ($this->options['subquery_regenerate']) {
+      // For testing only, regenerate the subquery each time.
+      $def['left_query'] = $this->left_query($this->options);     
+    }
+    else {
+      // Get the stored subquery SQL string.
+      $def['left_query'] = $this->options['subquery_string'];
+    }
+
+    if (!empty($def['join_handler']) && class_exists($def['join_handler'])) {
+      $join = new $def['join_handler'];
+    }
+    else {
+      $join = new views_join_subquery();
+    }
+
+    $join->definition = $def;
+    $join->construct();
+    $join->adjusted = TRUE;
+
+    // use a short alias for this:
+    $alias = $def['table'] . '_' . $this->table;
+
+    $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship);
+  }
+}
+
diff --git modules/comment.views.inc modules/comment.views.inc
index ea82d1c..8b3c0ce 100644
--- modules/comment.views.inc
+++ modules/comment.views.inc
@@ -89,6 +89,25 @@ function comment_views_data() {
     ),
   );
 
+  $data['comments']['cid_plain'] = array(
+    'title' => t('CID - Plain'),
+    'help' => t('The comment ID of the field. Does not add additional fields.'),
+    'real field' => 'cid',
+    'field' => array(
+      'handler' => 'views_handler_field',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_numeric',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument',
+    ),
+  );
+
+
   // name (of comment author)
   $data['comments']['name'] = array(
     'title' => t('Author'),
@@ -311,6 +330,9 @@ function comment_views_data() {
       'handler' => 'views_handler_relationship',
       'label' => t('Node'),
     ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_numeric',
+    ),
   );
 
   $data['comments']['uid'] = array(
diff --git modules/node.views.inc modules/node.views.inc
index 4a037fb..c6e4a73 100644
--- modules/node.views.inc
+++ modules/node.views.inc
@@ -671,6 +671,24 @@ function node_views_data() {
       'handler' => 'views_handler_filter_history_user_timestamp',
     ),
   );
+
+  // ----------------------------------------------------------------------
+  // Representative relationships
+  $data['node']['cid_representative'] = array(
+    'relationship' => array(
+      'real field' => 'cid',
+      'title' => t('Representative comment'),
+      'label'  => t('Representative comment'),
+      'help' => t('Obtains a single representative comment for each node, acccording to a chosen sort criterion, or by embedding a comment view.'),
+      'handler' => 'views_handler_relationship_groupwise_max',
+      'base'   => 'comments',
+      'field'  => 'cid_plain',
+      'outer field' => 'node.nid',
+      'argument table' => 'comments',
+      'argument field' =>  'nid',
+    ),
+  );
+
   return $data;
 }
 
diff --git modules/taxonomy.views.inc modules/taxonomy.views.inc
index ed7e605..bb06ecb 100644
--- modules/taxonomy.views.inc
+++ modules/taxonomy.views.inc
@@ -123,6 +123,17 @@ function taxonomy_views_data() {
       'numeric' => TRUE,
       'skip base' => array('node', 'node_revision'),
     ),
+    'relationship' => array(
+      'title' => t('Representative node'),
+      'label'  => t('Representative node'),
+      'help' => t('Obtains a single representative node for each term, acccording to a chosen sort criterion.'),
+      'handler' => 'views_handler_relationship_groupwise_max',
+      'base'   => 'node',
+      'field'  => 'nid',
+      'outer field' => 'term_data.tid',
+      'argument table' => 'term_node',
+      'argument field' =>  'tid',
+    ),
   );
 
   // Term name field
diff --git modules/user.views.inc modules/user.views.inc
index 318e978..f9a2fd1 100644
--- modules/user.views.inc
+++ modules/user.views.inc
@@ -73,6 +73,22 @@ function user_views_data() {
   );
 
   // uid
+  $data['users']['uid_representative'] = array(
+    'relationship' => array(
+      'real field' => 'uid',
+      'title' => t('Representative node'),
+      'label'  => t('Representative node'),
+      'help' => t('Obtains a single representative node for each user, acccording to a chosen sort criterion.'),
+      'handler' => 'views_handler_relationship_groupwise_max',
+      'base'   => 'node',
+      'field'  => 'nid',
+      'outer field' => 'users.uid',
+      'argument table' => 'users',
+      'argument field' =>  'uid',
+    ),
+  );
+
+  // uid
   $data['users']['uid_current'] = array(
     'real field' => 'uid',
     'title' => t('Current'),
