+/* Returns true if performing VM on dictionary D would not cause
+ problems such as duplicate variable names. Returns false
+ otherwise, and issues an error message. */
+static int
+validate_var_modification (const struct dictionary *d,
+ const struct var_modification *vm)
+{
+ /* Variable reordering can't be a problem, so we don't simulate
+ it. Variable renaming can cause duplicate names, but
+ dropping variables can eliminate them, so we simulate both
+ of those. */
+ struct variable **all_vars;
+ struct variable **keep_vars;
+ struct variable **drop_vars;
+ size_t all_cnt, keep_cnt, drop_cnt;
+
+ struct var_renaming *var_renaming;
+ int valid;
+ size_t i;
+
+ /* All variables, in index order. */
+ dict_get_vars (d, &all_vars, &all_cnt, 0);
+
+ /* Drop variables, in index order. */
+ drop_cnt = vm->drop_cnt;
+ drop_vars = xmalloc (drop_cnt * sizeof *drop_vars);
+ memcpy (drop_vars, vm->drop_vars, drop_cnt * sizeof *drop_vars);
+ sort (drop_vars, drop_cnt, sizeof *drop_vars,
+ compare_variables_given_ordering, &forward_positional_ordering);
+
+ /* Keep variables, in index order. */
+ keep_cnt = all_cnt - drop_cnt;
+ keep_vars = xmalloc (keep_cnt * sizeof *keep_vars);
+ if (set_difference (all_vars, all_cnt,
+ drop_vars, drop_cnt,
+ sizeof *all_vars,
+ keep_vars,
+ compare_variables_given_ordering,
+ &forward_positional_ordering) != keep_cnt)
+ assert (0);
+
+ /* Copy variables into var_renaming array. */
+ var_renaming = xmalloc (keep_cnt * sizeof *var_renaming);
+ for (i = 0; i < keep_cnt; i++)