please include function myInnerClasses.

static abstract class DynModule {
  S name, toolTip;
  PersistableThrowable _error;
  Map<S, Collection<S>> mechLists;
  Map<S, Bool> _persistenceInfo;
  
  transient O _host;
  transient Map timers = newWeakHashMap(); // all kinds of resources actually; value is closer helper
  transient Set<AutoCloseable> _resources = synchroHashSet();
  transient Lock lock; // set by stem
  transient bool persistOnChangedField = true;
  transient int changeCount;
  transient O changeCountSync = new O;
  transient L onChange;
  transient bool verboseTimers;
  transient ReliableSingleThread rstUpdate;
  transient Set<S> componentFieldsToKeep;
  transient Map<S, O> transientGeneralMap = synchroHashMap();
  transient Q q; // module command queue
  
  *() {
    dm_initErrorHandling();
    setMainDesktopPane((JDesktopPane) getCreatorOpt('desktop));
  }
  
  bool isVisible() { ret isTrue(getOpt(_host, 'visible)); }
  
  S moduleName() { ret name; }
  
  void setModuleName(S name) {
    S oldName = this.name;
    if (!eq(name, oldName)) {
      this.name = name;
      possiblyInternalFrameTitle(vis(), name);
      vmBus_send('moduleNameChange, this, oldName, name);
    }
  }
  
  void setModuleToolTip(S toolTip) {
    this.toolTip = toolTip;
  }
  
  JComponent vis() {
    ret (JComponent) getOpt(_host, 'vis);
  }
  
  <A extends AutoCloseable> A ownResource(A a) {
    if (a != null)
      _resources.add(a);
    ret a;
  }
  
  <A> A ownTimer(A timer) {
    if (timer instanceof AutoCloseable) ownResource((AutoCloseable) timer);
    ownTimer(timer, f cancelTimerOrInterruptThread);
    ret timer;
  }
  
  void ownTimer(O timer, O closerHelper) {
    timers.put(timer, closerHelper);
  }
  
  void singleTimer(java.util.Timer timer) {
    stopAllTimers();
    ownTimer(timer);
  }
  
  void stopAllTimers() {
    for (AutoCloseable resource : getAndClearList(_resources)) {
      if (verboseTimers)
        print("Releasing resource: " + resource);
      pcall { resource.close(); }
    }
      
    for (O timer, closerHelper : getAndClearMap(timers)) {
      if (verboseTimers)
        print("Stopping timer: " + closerHelper + " / " + timer);
      pcallFInRealOrMyMC(this, closerHelper, timer);
    }
  }
  
  void cleanMeUp_dynModule {
    stopAllTimers();
  }
  
  void persistMe {
    synchronized(changeCountSync) { ++changeCount; }
    pcallFAll(onChange); callOpt(_host, '_change);
    updateMe();
  }
  
  void _change { persistMe(); }
  void change { persistMe(); }
  
  void updateMe {
    rstUpdate().trigger();
  }
  
  void changeAndUpdate { _change(); updateMe(); }
  
  bool setField(S name, O value) enter {
    {
      // lock lock; // this leads to too many problems
      pcall { // some really weird classes fail on equals() (BCEL JavaClass, I'm looking at you)
        if (eq(get(this, name), value)) false;
      }
      set(this, name, value);
    } // releasing lock before calling _change()!
    if (persistOnChangedField && !isFalse(mapGet(_persistenceInfo, name)))
      _change();
    true;
  }
  
  <A> A setFieldAndReturn(S name, A value) {
    setField(name, value);
    ret value;
  }
  
  bool setFields(O... params) {
    bool change = false;
    for (int i = 0; i < l(params); i += 2)
      if (setField((S) params[i], params[i+1])) change = true;
    ret change;
  }
  
  void start {
    if (hasMethod_onTypes(this, 'onTopInput, S))
      dm_onTopInput_q(voidfunc(S s) { call(module(), 'onTopInput, s) });
  }
  
  void revisualize {
    call(creator(), 'revisualizeModule, _host);
  }
  
  AutoCloseable enter() {
    please include function dm_currentModule.
    AutoCloseable c = tempSetThreadLocal(dm_currentModule_value, new WeakReference(this));
    fO realMC = getMainClass(this);
    if (realMC != mc()) {
      c = combineAutoCloseables(tempInterceptPrint(func(S s) -> bool {
        ret false with call(realMC, 'print, s);
      }), c);
      c = combineAutoCloseables(tempSetTL(realMC_tl(), realMC), c);
    }
    ret c;
  }
  
  AutoCloseable enterAndLock() {
    ret combineAutoCloseables(enter(), tempLock(lock));
  }
  
  bool setError(Throwable e) {
    setField(_error := persistableThrowable(e));
    true;
  }
  
  void clearError {
    setField(_error := null);
  }
  
  void onChange(Runnable r) {
    lock lock;
    if (onChange == null) onChange = synchroList();
    addIfNotThere(onChange, r);
  }
  
  void onChangeAndNow(Runnable r) {
    onChange(r);
    callF(r);
  }
  
  void onChangeAndNow(JComponent c, O r) {
    main.onChangeAndNow(c, r);
  }

  void update() {}
  
  void unvisualize() {
    zeroAllFieldsOfTypeExcept(this, Component, componentFieldsToKeep);
  }
  
  L<AbstractAction> menuItems() {
    null;
  }
  
  void enhanceFrame(Container f) {
    ifndef NoMenuItems
    internalFramePopupMenuFromActions_threaded(f, menuItems());
    endifndef
    ifndef NoSwitchableFields
    S switchableFields = callOpt(this, 'switchableFields);
    for (S field : splitAtSpace(switchableFields)) {
      Class type = fieldType(this, field);
      if (eq(bool.class, type))
        dm_boolFieldMenuItem(f, field);
      else if (eq(int.class, type))
        dm_intFieldMenuItem(f, field);
      else if (eq(double.class, type))
        dm_doubleFieldMenuItem(f, field);
    }
    endifndef
  }
  
  // assume this is called in start(), so no locking
  ReliableSingleThread rstUpdate() {
    if (rstUpdate == null) rstUpdate = dm_rst(this, r enter { update(); });
    ret rstUpdate;
  }
  
  Q q() enter {
    if (q == null) {
      lock lock;
      if (q == null) q = dm_startQ();
    }
    ret q;
  }
  
  <A> A withUpdate(A a) {
    rstUpdate().trigger();
    ret a;
  }
  
  DynModule module() { this; }
  
  JComponent visualize() {
    ret dm_noVisualisation();
  }
}

static void _registerTimer(java.util.Timer timer) {
  _registerTimer_original(timer);
  dm_currentModule().ownTimer(timer);
}