* @param body
   * @return Stella_Object
   */
  public static Stella_Object memoize(Cons inputargs, Cons body) {
    { Surrogate memoname = null;
      Symbol memotablevar = Stella.localGensym("MEMO-TABLE");
      Symbol memoentryvar = Stella.localGensym("MEMOIZED-ENTRY");
      Symbol memovaluevar = Stella.localGensym("MEMOIZED-VALUE");
      int nofinputs = inputargs.length();
      PropertyList options = null;
      Stella_Object lookupfunction = null;
      Cons lookuptree = Stella.NIL;
      StandardObject valuetypespec = null;
      boolean alleqP = true;
      int eqvector = 0;

      body = Cons.cons(Stella.NIL, body);
      options = Cons.parseMemoizeOptions(Cons.extractOptions(body, null));
      body = body.rest;
      memoname = ((Surrogate)(options.lookup(Stella.KWD_NAME)));
      if (memoname == null) {
        memoname = Symbol.makeMemoizationTableSurrogate(null);
      }
      { ConsIterator it = inputargs.allocateIterator();
        int index = Stella.NULL_INTEGER;
        int iter000 = 0;

        for (;it.nextP(); iter000 = iter000 + 1) {
          index = iter000;
          { Stella_Object walkedarg = null;
            StandardObject type = null;

            { Object [] caller_MV_returnarray = new Object[1];

              walkedarg = Stella_Object.walkATree(it.value, caller_MV_returnarray);
              type = ((StandardObject)(caller_MV_returnarray[0]));
            }
            if (StandardObject.subTypeSpecOfP(type, Stella.SGT_STELLA_STANDARD_OBJECT) ||
                (StandardObject.subTypeSpecOfP(type, Stella.SGT_STELLA_BOOLEAN_WRAPPER) ||
                 StandardObject.subTypeSpecOfP(type, Stella.SGT_STELLA_BOOLEAN))) {
              if (index < 12) {
                eqvector = (eqvector | ((1 << index)));
              }
            }
            else {
              alleqP = false;
            }
            it.valueSetter(Stella_Object.sysTree(walkedarg, type, new Object[1]));
          }
        }
      }
      lookupfunction = ((options.lookup(Stella.KWD_MAX_VALUES) == null) ? (((nofinputs <= 4) ? Stella.SYM_STELLA_LOOKUP_MEMOIZED_VALUE : Stella.SYM_STELLA_LOOKUP_MEMOIZED_VALUEN)) : (((nofinputs <= 4) ? Stella.SYM_STELLA_LOOKUP_MRU_MEMOIZED_VALUE : Stella.SYM_STELLA_LOOKUP_MRU_MEMOIZED_VALUEN)));
      switch (nofinputs) {
        case 0: 
          { Object old$PrintreadablyP$000 = Stella.$PRINTREADABLYp$.get();

            try {
              Native.setBooleanSpecial(Stella.$PRINTREADABLYp$, true);
              Stella.signalTranslationError();
              if (!(Stella.suppressWarningsP())) {
                Stella.printErrorContext(">> ERROR: ", Stella.STANDARD_ERROR);
                {
                  Stella.STANDARD_ERROR.nativeStream.println();
                  Stella.STANDARD_ERROR.nativeStream.println(" Missing memoization input argument specification.");
                }
;
              }

            } finally {
              Stella.$PRINTREADABLYp$.set(old$PrintreadablyP$000);
            }
          }
          return (Stella_Object.walkDontCallMeTree(body, Stella.SGT_STELLA_OBJECT, new Object[1]));
        case 1: 
          lookuptree = Cons.cons(lookupfunction, Cons.cons(memotablevar, Cons.cons(inputargs.value, Cons.list$(Cons.cons(Stella.SYM_STELLA_MEMOIZED_NULL_VALUE, Cons.cons(Stella.SYM_STELLA_NULL, Cons.cons(Stella.SYM_STELLA_NULL, Cons.cons((alleqP ? IntegerWrapper.wrapInteger(-1) : IntegerWrapper.wrapInteger(eqvector)), Cons.cons(Stella.NIL, Stella.NIL)))))))));
        break;
        case 2: 
          lookuptree = Cons.cons(lookupfunction, Cons.cons(memotablevar, Cons.cons(inputargs.value, Cons.cons(inputargs.rest.value, Cons.list$(Cons.cons(Stella.SYM_STELLA_MEMOIZED_NULL_VALUE, Cons.cons(Stella.SYM_STELLA_NULL, Cons.cons((alleqP ? IntegerWrapper.wrapInteger(-1) : IntegerWrapper.wrapInteger(eqvector)), Cons.cons(Stella.NIL, Stella.NIL)))))))));
        break;
        case 3: 
          lookuptree = Cons.cons(lookupfunction, Cons.cons(memotablevar, Cons.cons(inputargs.value, Cons.cons(inputargs.rest.value, Cons.cons(inputargs.rest.rest.value, Cons.list$(Cons.cons(Stella.SYM_STELLA_MEMOIZED_NULL_VALUE, Cons.cons((alleqP ? IntegerWrapper.wrapInteger(-1) : IntegerWrapper.wrapInteger(eqvector)), Cons.cons(Stella.NIL, Stella.NIL)))))))));
        break;
        case 4: 
          lookuptree = Cons.cons(lookupfunction, Cons.cons(memotablevar, Cons.cons(inputargs.value, Cons.cons(inputargs.rest.value, Cons.cons(inputargs.rest.rest.value, Cons.cons(inputargs.fourth(), Cons.cons((alleqP ? IntegerWrapper.wrapInteger(-1) : IntegerWrapper.wrapInteger(eqvector)), Stella.NIL)))))));
        break;
        default:
          lookuptree = Cons.cons(lookupfunction, Cons.cons(memotablevar, Cons.list$(Cons.cons(Cons.cons(Stella.SYM_STELLA_CONS_LIST, inputargs.concatenate(Stella.NIL, Stella.NIL)), Cons.cons((alleqP ? IntegerWrapper.wrapInteger(-1) : IntegerWrapper.wrapInteger(eqvector)), Cons.cons(Stella.NIL, Stella.NIL))))));
        break;
      }
      valuetypespec = Stella_Object.computeExpressionType(body.value, true);
      return (Cons.list$(Cons.cons(Stella.SYM_STELLA_VRLET, Cons.cons(Cons.list$(Cons.cons(Cons.cons(memotablevar, Cons.list$(Cons.cons(Stella.SYM_STELLA_MEMOIZATION_TABLE, Cons.cons(Stella.SYM_STELLA_NULL, Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Cons.cons(memoentryvar, Cons.list$(Cons.cons(Stella.SYM_STELLA_CONS, Cons.cons(Stella.SYM_STELLA_NULL, Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Cons.cons(memovaluevar, Cons.list$(Cons.cons(Stella.SYM_STELLA_OBJECT, Cons.cons(Stella.SYM_STELLA_NULL, Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_WHEN, Cons.cons(Stella.SYM_STELLA_$MEMOIZATION_ENABLEDp$, Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SETQ, Cons.cons(memotablevar, Cons.cons(Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SURROGATE_VALUE, Cons.cons(memoname, Cons.cons(Stella.NIL, Stella.NIL)))), Stella.NIL), Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_WHEN, Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_NULLp, Cons.cons(memotablevar, Cons.cons(Stella.NIL, Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_INITIALIZE_MEMOIZATION_TABLE, Cons.cons(memoname, Cons.cons(Cons.cons(StringWrapper.wrapString(Native.stringify(options.thePlist)), Stella.NIL), Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SETQ, Cons.cons(memotablevar, Cons.cons(Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SURROGATE_VALUE, Cons.cons(memoname, Cons.cons(Stella.NIL, Stella.NIL)))), Stella.NIL), Stella.NIL)))), Cons.cons(Stella.NIL, Stella.NIL)))))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SETQ, Cons.cons(memoentryvar, Cons.cons(Cons.cons(lookuptree, Stella.NIL), Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SETQ, Cons.cons(memovaluevar, Cons.cons(Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_FIRST, Cons.cons(memoentryvar, Cons.cons(Stella.NIL, Stella.NIL)))), Stella.NIL), Stella.NIL)))), Cons.cons(Stella.NIL, Stella.NIL)))))))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_COND, Cons.cons(Cons.list$(Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_DEFINEDp, Cons.cons(memovaluevar, Cons.cons(Stella.NIL, Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_WHEN, Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_EQLp, Cons.cons(memovaluevar, Cons.cons(Cons.cons(Stella.SYM_STELLA_MEMOIZED_NULL_VALUE, Stella.NIL), Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SETQ, Cons.cons(memovaluevar, Cons.cons(Cons.cons(Stella.SYM_STELLA_NULL, Stella.NIL), Stella.NIL)))), Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Stella.NIL, Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_OTHERWISE, Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SETQ, Cons.cons(memovaluevar, Cons.cons(body.concatenate(Stella.NIL, Stella.NIL), Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_WHEN, Cons.cons(Stella.SYM_STELLA_$MEMOIZATION_ENABLEDp$, Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_SETF, Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_VALUE, Cons.cons(memoentryvar, Cons.cons(Stella.NIL, Stella.NIL)))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_CHOOSE, Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_NULLp, Cons.cons(memovaluevar, Cons.cons(Stella.NIL, Stella.NIL)))), Cons.cons(Stella.SYM_STELLA_MEMOIZED_NULL_VALUE, Cons.cons(memovaluevar, Cons.cons(Stella.NIL, Stella.NIL)))))), Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Stella.NIL, Stella.NIL))))), Cons.cons(Cons.list$(Cons.cons(Stella.SYM_STELLA_CAST, Cons.cons(memovaluevar, Cons.cons(Cons.cons(StandardObject.yieldTypeSpecTree(valuetypespec), Stella.NIL), Stella.NIL)))), Cons.cons(Stella.NIL, Stella.NIL))))))));
    }
  }