+ mrset_destroy (mrset);
+ dict->mrsets[i] = dict->mrsets[--dict->n_mrsets];
+ }
+ else
+ i++;
+ }
+}
+\f
+/* Returns D's attribute set. The caller may examine or modify
+ the attribute set, but must not destroy it. Destroying D or
+ calling dict_set_attributes for D will also destroy D's
+ attribute set. */
+struct attrset *
+dict_get_attributes (const struct dictionary *d)
+{
+ return CONST_CAST (struct attrset *, &d->attributes);
+}
+
+/* Replaces D's attributes set by a copy of ATTRS. */
+void
+dict_set_attributes (struct dictionary *d, const struct attrset *attrs)
+{
+ attrset_destroy (&d->attributes);
+ attrset_clone (&d->attributes, attrs);
+}
+
+/* Returns true if D has at least one attribute in its attribute
+ set, false if D's attribute set is empty. */
+bool
+dict_has_attributes (const struct dictionary *d)
+{
+ return attrset_count (&d->attributes) > 0;
+}
+
+/* Called from variable.c to notify the dictionary that some property of
+ the variable has changed */
+void
+dict_var_changed (const struct variable *v)
+{
+ if ( var_has_vardict (v))
+ {
+ const struct vardict_info *vardict = var_get_vardict (v);
+ struct dictionary *d = vardict->dict;
+
+ if ( NULL == d)
+ return;
+
+ if (d->changed ) d->changed (d, d->changed_data);
+ if ( d->callbacks && d->callbacks->var_changed )
+ d->callbacks->var_changed (d, var_get_dict_index (v), d->cb_data);
+ }
+}
+
+
+/* Called from variable.c to notify the dictionary that the variable's width
+ has changed */
+void
+dict_var_resized (const struct variable *v, int old_width)
+{
+ if ( var_has_vardict (v))
+ {
+ const struct vardict_info *vardict = var_get_vardict (v);
+ struct dictionary *d;
+
+ d = vardict->dict;
+
+ if (d->changed) d->changed (d, d->changed_data);
+
+ invalidate_proto (d);
+ if ( d->callbacks && d->callbacks->var_resized )
+ d->callbacks->var_resized (d, var_get_dict_index (v), old_width,
+ d->cb_data);
+ }
+}
+
+/* Called from variable.c to notify the dictionary that the variable's display width
+ has changed */
+void
+dict_var_display_width_changed (const struct variable *v)
+{
+ if ( var_has_vardict (v))
+ {
+ const struct vardict_info *vardict = var_get_vardict (v);
+ struct dictionary *d;
+
+ d = vardict->dict;
+
+ if (d->changed) d->changed (d, d->changed_data);
+ if ( d->callbacks && d->callbacks->var_display_width_changed )
+ d->callbacks->var_display_width_changed (d, var_get_dict_index (v), d->cb_data);
+ }
+}
+\f
+/* Dictionary used to contain "internal variables". */
+static struct dictionary *internal_dict;
+
+/* Create a variable of the specified WIDTH to be used for internal
+ calculations only. The variable is assigned case index CASE_IDX. */
+struct variable *
+dict_create_internal_var (int case_idx, int width)
+{
+ if (internal_dict == NULL)
+ internal_dict = dict_create ();
+
+ for (;;)
+ {
+ static int counter = INT_MAX / 2;
+ struct variable *var;
+ char name[64];