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];
+
+      if (++counter == INT_MAX)
+        counter = INT_MAX / 2;
+
+      sprintf (name, "$internal%d", counter);
+      var = dict_create_var (internal_dict, name, width);
+      if (var != NULL)
+        {
+          set_var_case_index (var, case_idx);
+          return var;
+        }
+    }
+}
+
+/* Destroys VAR, which must have been created with
+   dict_create_internal_var(). */
+void
+dict_destroy_internal_var (struct variable *var)
+{
+  if (var != NULL)
+    {
+      dict_delete_var (internal_dict, var);
 
+      /* Destroy internal_dict if it has no variables left, just so that
+         valgrind --leak-check --show-reachable won't show internal_dict. */
+      if (dict_get_var_cnt (internal_dict) == 0)
+        {
+          dict_destroy (internal_dict);
+          internal_dict = NULL;
+        }
+    }
+}
 
 void dict_set_attributes (struct dictionary *, const struct attrset *);
 bool dict_has_attributes (const struct dictionary *);
 
-
+/* Data encoding. */
 void dict_set_encoding (struct dictionary *d, const char *enc);
 const char *dict_get_encoding (const struct dictionary *d);
 
+/* Internal variables. */
+struct variable *dict_create_internal_var (int case_idx, int width);
+void dict_destroy_internal_var (struct variable *);
 
 /* Functions to be called upon dictionary changes. */
 struct dict_callbacks
 
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
   return new_var;
 }
 
-/* Create a variable of the specified WIDTH to be used for
-   internal calculations only.  The variable is assigned a unique
-   dictionary index and a case index of CASE_IDX. */
-struct variable *
-var_create_internal (int case_idx, int width)
-{
-  struct variable *v = var_create ("$internal", width);
-  struct vardict_info vdi;
-  static int counter = INT_MAX / 2;
-
-  vdi.dict = NULL;
-  vdi.case_index = case_idx;
-  vdi.dict_index = counter++;
-  if (counter == INT_MAX)
-    counter = INT_MAX / 2;
-
-  var_set_vardict (v, &vdi);
-
-  return v;
-}
-
 /* Destroys variable V.
    V must not belong to a dictionary.  If it does, use
    dict_delete_var instead. */
 {
   if (v != NULL)
     {
-      if (var_has_vardict (v))
-       {
-         const struct vardict_info *vdi = var_get_vardict (v);
-         assert (vdi->dict == NULL);
-       }
+      assert (!var_has_vardict (v));
       mv_destroy (&v->miss);
       cat_stored_values_destroy (v->obs_vals);
       var_clear_short_names (v);
 {
   assert (vardict->dict_index >= 0);
   assert (vardict->case_index >= 0);
+  assert (vardict->dict != NULL);
   v->vardict = *vardict;
 }
 
 
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 struct variable *var_create (const char *name, int width);
 struct variable *var_clone (const struct variable *);
 void var_destroy (struct variable *);
-struct variable *var_create_internal (int case_idx, int width);
-
 
 /* Variable names. */
 #define VAR_NAME_LEN 64 /* Maximum length of variable name, in bytes. */
 
       else if (iter->function == SD)
         moments1_destroy (iter->moments);
 
-      var_destroy (iter->subject);
-      var_destroy (iter->weight);
+      dict_destroy_internal_var (iter->subject);
+      dict_destroy_internal_var (iter->weight);
 
       free (iter);
     }
             proto = caseproto_add_width (proto, 0);
 
            if ( ! iter->subject)
-             iter->subject = var_create_internal (0, 0);
+             iter->subject = dict_create_internal_var (0, 0);
 
            if ( ! iter->weight)
-             iter->weight = var_create_internal (1, 0);
+             iter->weight = dict_create_internal_var (1, 0);
 
             subcase_init_var (&ordering, iter->subject, SC_ASCEND);
            iter->writer = sort_create_writer (&ordering, proto);
 
 /* Pspp - a program for statistical analysis.
-   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
   struct wilcoxon_state *ws = xcalloc (sizeof (*ws), t2s->n_pairs);
   const struct variable *weight = dict_get_weight (dict);
-  struct variable *weightx = var_create_internal (WEIGHT_IDX, 0);
+  struct variable *weightx = dict_create_internal_var (WEIGHT_IDX, 0);
   struct caseproto *proto;
 
   input =
       struct subcase ordering;
       variable_pair *vp = &t2s->pairs[i];
 
-      ws[i].sign = var_create_internal (0, 0);
-      ws[i].absdiff = var_create_internal (1, 0);
+      ws[i].sign = dict_create_internal_var (0, 0);
+      ws[i].absdiff = dict_create_internal_var (1, 0);
 
       r = casereader_create_filter_missing (r, *vp, 2,
                                            exclude,
 
   casereader_destroy (input);
 
-  var_destroy (weightx);
+  dict_destroy_internal_var (weightx);
 
   show_ranks_box (ws, t2s, dict);
   show_tests_box (ws, t2s, exact, timer);
 
   for (i = 0 ; i < t2s->n_pairs; ++i )
     {
-      var_destroy (ws[i].sign);
-      var_destroy (ws[i].absdiff);
+      dict_destroy_internal_var (ws[i].sign);
+      dict_destroy_internal_var (ws[i].absdiff);
     }
 
   free (ws);
 
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include <config.h>
 #include <assert.h>
+#include <data/dictionary.h>
 #include <data/value.h>
 #include <data/variable.h>
 #include <gl/unistr.h>
              width += var_get_width (vars[i]);
            }
        }
-      result->intr = var_create_internal (0, width);
+      result->intr = dict_create_internal_var (0, width);
     }
 
   return result;
 }
 void interaction_variable_destroy (struct interaction_variable *iv)
 {
-  var_destroy (iv->intr);
+  dict_destroy_internal_var (iv->intr);
   free (iv->members);
   free (iv);
 }