public static MemoizationTable newMemoizationTable() {
    {
      MemoizationTable self = null;

      self = new MemoizationTable();
      self.timestamps = Stella.NIL;
      self.currentTimestamp = null;
      self.tableName = null;
      self.hashTable = null;
      return (self);
    }
  }
  public static Cons lookupMemoizedValue(
      MemoizationTable memotable,
      Stella_Object arg1,
      Stella_Object arg2,
      Stella_Object arg3,
      Stella_Object arg4,
      int eqvector) {
    {
      IntegerHashTable hashtable = memotable.hashTable;
      Cons timestamp = null;
      int hashcode = 0;
      Cons entry = Stella.NIL;
      Cons bucket = Stella.NIL;

      if (hashtable == null) {
        hashtable = IntegerHashTable.newIntegerHashTable();
        memotable.hashTable = hashtable;
        memotable.currentTimestamp = Cons.cons(null, Stella.NIL);
      }
      timestamp = memotable.currentTimestamp;
      hashcode = Stella_Object.hashMemoizedArguments(arg1, arg2, arg3, arg4, eqvector);
      bucket = ((Cons) (hashtable.lookup(hashcode)));
      if (bucket != null) {
        if (((Cons) (bucket.value)) == timestamp) {
          entry = Cons.findMemoizedValueEntry(bucket, arg1, arg2, arg3, arg4, eqvector, false);
          if (entry != null) {
            return (entry);
          }
        } else {
          bucket.value = timestamp;
          bucket.rest = Stella.NIL;
        }
      }
      entry = Stella_Object.makeMemoizedValueEntry(null, arg1, arg2, arg3, arg4);
      if (bucket != null) {
        bucket.rest = Cons.cons(entry, bucket.rest);
      } else {
        hashtable.insertAt(hashcode, Cons.cons(timestamp, Cons.cons(entry, Stella.NIL)));
      }
      return (entry);
    }
  }
  public static Stella_Object accessMemoizationTableSlotValue(
      MemoizationTable self, Symbol slotname, Stella_Object value, boolean setvalueP) {
    if (slotname == Stella.SYM_STELLA_HASH_TABLE) {
      if (setvalueP) {
        self.hashTable = ((IntegerHashTable) (value));
      } else {
        value = self.hashTable;
      }
    } else if (slotname == Stella.SYM_STELLA_TABLE_NAME) {
      if (setvalueP) {
        self.tableName = ((Surrogate) (value));
      } else {
        value = self.tableName;
      }
    } else if (slotname == Stella.SYM_STELLA_CURRENT_TIMESTAMP) {
      if (setvalueP) {
        self.currentTimestamp = ((Cons) (value));
      } else {
        value = self.currentTimestamp;
      }
    } else if (slotname == Stella.SYM_STELLA_TIMESTAMPS) {
      if (setvalueP) {
        self.timestamps = ((Cons) (value));
      } else {
        value = self.timestamps;
      }
    } else {
      {
        OutputStringStream stream000 = OutputStringStream.newOutputStringStream();

        stream000.nativeStream.print("`" + slotname + "' is not a valid case option");
        throw ((StellaException)
            (StellaException.newStellaException(stream000.theStringReader()).fillInStackTrace()));
      }
    }
    return (value);
  }