public static void collectFreeVariables(Stella_Object self, List collection, List quantifiedvars, List beenthere) {
    { Surrogate testValue000 = Stella_Object.safePrimaryType(self);

      if (Surrogate.subtypeOfP(testValue000, Logic.SGT_LOGIC_PATTERN_VARIABLE)) {
        { PatternVariable self000 = ((PatternVariable)(self));

          if ((!quantifiedvars.memberP(self000)) &&
              (!collection.memberP(self000))) {
            collection.insertLast(self000);
          }
        }
      }
      else if (Surrogate.subtypeOfP(testValue000, Logic.SGT_LOGIC_PROPOSITION)) {
        { Proposition self000 = ((Proposition)(self));

          if (!(beenthere.memberP(self000))) {
            { Keyword testValue001 = self000.kind;

              if ((testValue001 == Logic.KWD_FORALL) ||
                  (testValue001 == Logic.KWD_EXISTS)) {
                { PatternVariable v = null;
                  Vector vector000 = ((Vector)(KeyValueList.dynamicSlotValue(self000.dynamicSlots, Logic.SYM_LOGIC_IO_VARIABLES, null)));
                  int index000 = 0;
                  int length000 = vector000.length();

                  for (;index000 < length000; index000 = index000 + 1) {
                    v = ((PatternVariable)((vector000.theArray)[index000]));
                    quantifiedvars.insert(v);
                  }
                }
              }
              else {
              }
            }
            beenthere.insert(self000);
            { Stella_Object arg = null;
              Vector vector001 = self000.arguments;
              int index001 = 0;
              int length001 = vector001.length();

              for (;index001 < length001; index001 = index001 + 1) {
                arg = (vector001.theArray)[index001];
                Logic.collectFreeVariables(arg, collection, quantifiedvars, beenthere);
              }
            }
          }
        }
      }
      else if (Surrogate.subtypeOfP(testValue000, Logic.SGT_LOGIC_DESCRIPTION)) {
        { Description self000 = ((Description)(self));

          { PatternVariable v = null;
            Vector vector002 = self000.ioVariables;
            int index002 = 0;
            int length002 = vector002.length();

            for (;index002 < length002; index002 = index002 + 1) {
              v = ((PatternVariable)((vector002.theArray)[index002]));
              quantifiedvars.insert(v);
            }
          }
          { PatternVariable v = null;
            Cons iter000 = Description.topLevelExistentialVariables(self000);

            for (;!(iter000 == Stella.NIL); iter000 = iter000.rest) {
              v = ((PatternVariable)(iter000.value));
              quantifiedvars.insert(v);
            }
          }
          Logic.collectFreeVariables(self000.proposition, collection, quantifiedvars, beenthere);
        }
      }
      else {
      }
    }
  }