public static Description instantiateExternalVariables(Description self, KeyValueMap bindings) {
    if (!(bindings.emptyP())) {
      { Object old$Evaluationmode$000 = Logic.$EVALUATIONMODE$.get();
        Object old$Queryiterator$000 = Logic.$QUERYITERATOR$.get();

        try {
          Native.setSpecial(Logic.$EVALUATIONMODE$, Logic.KWD_DESCRIPTION);
          Native.setSpecial(Logic.$QUERYITERATOR$, null);
          { Description description = Description.newDescription();

            { Stella_Object var = null;
              Stella_Object binding = null;
              DictionaryIterator iter000 = ((DictionaryIterator)(bindings.allocateIterator()));

              while (iter000.nextP()) {
                var = iter000.key;
                binding = iter000.value;
                bindings.insertAt(var, Logic.evaluateTerm(binding));
              }
            }
            description.ioVariables = self.ioVariables.copy();
            { PatternVariable var = null;
              Vector vector000 = self.ioVariables;
              int index000 = 0;
              int length000 = vector000.length();

              for (;index000 < length000; index000 = index000 + 1) {
                var = ((PatternVariable)((vector000.theArray)[index000]));
                bindings.insertAt(var, var);
              }
            }
            { PatternVariable var = null;
              Vector vector001 = ((Vector)(KeyValueList.dynamicSlotValue(self.dynamicSlots, Logic.SYM_LOGIC_EXTERNAL_VARIABLES, null)));
              int index001 = 0;
              int length001 = vector001.length();

              for (;index001 < length001; index001 = index001 + 1) {
                var = ((PatternVariable)((vector001.theArray)[index001]));
                if (bindings.lookup(var) == null) {
                  bindings.insertAt(var, var);
                }
              }
            }
            { PatternVariable var = null;
              Vector vector002 = self.internalVariables;
              int index002 = 0;
              int length002 = vector002.length();

              for (;index002 < length002; index002 = index002 + 1) {
                var = ((PatternVariable)((vector002.theArray)[index002]));
                bindings.insertAt(var, var);
              }
            }
            description.proposition = Proposition.inheritProposition(self.proposition, bindings);
            return (Description.finishBuildingDescription(description, true, Logic.KWD_TOP_LEVEL));
          }

        } finally {
          Logic.$QUERYITERATOR$.set(old$Queryiterator$000);
          Logic.$EVALUATIONMODE$.set(old$Evaluationmode$000);
        }
      }
    }
    return (self);
  }