+ input = case_unshare_and_resize (input, car->proto);
+ case_data_rw_idx (input, caseproto_get_n_widths (car->proto) - 1)->f
+ = car->mean_rank;
+ car->prev_value = value;
+ return input;
+}
+
+
+\f
+
+struct consolidator
+{
+ const struct variable *key;
+ const struct variable *weight;
+ double cc;
+ double prev_cc;
+
+ casenumber n;
+ struct casereader *clone;
+ struct caseproto *proto;
+ int direction;
+};
+
+static bool
+uniquify (const struct ccase *c, void *aux)
+{
+ struct consolidator *cdr = aux;
+ const union value *current_value = case_data (c, cdr->key);
+ const int key_width = var_get_width (cdr->key);
+ const double weight = cdr->weight ? case_data (c, cdr->weight)->f : 1.0;
+ const struct ccase *next_case = casereader_peek (cdr->clone, cdr->n + 1);
+ int dir = 0;
+
+ cdr->n ++;
+ cdr->cc += weight;
+
+ if ( NULL == next_case)
+ goto end;
+
+ dir = value_compare_3way (case_data (next_case, cdr->key),
+ current_value, key_width);
+ if ( dir != 0 )
+ {
+ /* Insist that the data are sorted */
+ assert (cdr->direction == 0 || dir == cdr->direction);
+ cdr->direction = dir;
+ goto end;
+ }
+
+ return false;
+
+ end:
+ cdr->prev_cc = cdr->cc;
+ cdr->cc = 0;
+ return true;
+}
+
+
+
+static struct ccase *
+consolodate_weight (struct ccase *input, void *aux)
+{
+ struct consolidator *cdr = aux;
+ struct ccase *c;
+
+ if (cdr->weight)
+ {
+ c = case_unshare (input);
+ case_data_rw (c, cdr->weight)->f = cdr->prev_cc;
+ }
+ else
+ {
+ c = case_unshare_and_resize (input, cdr->proto);
+ case_data_rw_idx (c, caseproto_get_n_widths (cdr->proto) - 1)->f = cdr->prev_cc;
+ }
+
+ return c;