+ input = casereader_create_filter_missing (input, &rank_var, 1,
+ exclude_values, NULL, output);
+ input = casereader_create_filter_weight (input, dict, NULL, output);
+
+ casereader_split (input, &pass1, &pass2);
+
+ /* Pass 1: Get total group weight. */
+ for (; (c = casereader_read (pass1)) != NULL; case_unref (c))
+ w += dict_get_case_weight (dict, c, NULL);
+ casereader_destroy (pass1);
+
+ /* Pass 2: Do ranking. */
+ tie_grouper = casegrouper_create_vars (pass2, &rank_var, 1);
+ while (casegrouper_get_next_group (tie_grouper, &pass2_1))
+ {
+ struct casereader *pass2_2;
+ double cc_1 = cc;
+ double tw = 0.0;
+ int i;
+
+ pass2_2 = casereader_clone (pass2_1);
+ taint_propagate (casereader_get_taint (pass2_2),
+ casewriter_get_taint (output));
+
+ /* Pass 2.1: Sum up weight for tied cases. */
+ for (; (c = casereader_read (pass2_1)) != NULL; case_unref (c))
+ tw += dict_get_case_weight (dict, c, NULL);
+ cc += tw;
+ casereader_destroy (pass2_1);
+
+ /* Pass 2.2: Rank tied cases. */
+ while ((c = casereader_read (pass2_2)) != NULL)
+ {
+ c = case_unshare (c);
+ for (i = 0; i < n_rank_specs; ++i)
+ {
+ const struct variable *dst_var = rs[i].destvars[dest_idx];
+ double *dst_value = &case_data_rw (c, dst_var)->f;
+ *dst_value = rank_func[rs[i].rfunc] (tw, cc, cc_1, tie_group, w);
+ }
+ casewriter_write (output, c);
+ }
+ casereader_destroy (pass2_2);
+
+ tie_group++;
+ }
+ casegrouper_destroy (tie_grouper);
+}
+
+/* Transformation function to enumerate all the cases */
+static int
+create_resort_key (void *key_var_, struct ccase **cc, casenumber case_num)
+{
+ struct variable *key_var = key_var_;
+
+ *cc = case_unshare (*cc);
+ case_data_rw (*cc, key_var)->f = case_num;
+
+ return TRNS_CONTINUE;
+}
+
+
+/* Create and return a new variable in which to store the ranks of SRC_VAR
+ accoring to the rank function F.
+ VNAME is the name of the variable to be created.
+ If VNAME is NULL, then a name will be automatically chosen.
+ */
+static struct variable *
+create_rank_variable (struct dictionary *dict, enum RANK_FUNC f,
+ const struct variable *src_var,
+ const char *vname)
+{
+ int i;
+ struct variable *var = NULL;
+ char name[SHORT_NAME_LEN + 1];
+
+ if ( vname )
+ var = dict_create_var(dict, vname, 0);
+
+ if ( NULL == var )
+ {
+ snprintf (name, SHORT_NAME_LEN + 1, "%c%s",
+ function_name[f][0], var_get_name (src_var));
+
+ var = dict_create_var(dict, name, 0);
+ }
+
+ i = 1;
+ while( NULL == var )