abstract sclass DynObjectTable extends DynModule {
  new L data;
  
  transient JTable table;
  transient F1 itemToMap;
  transient VF1 defaultAction;
  transient bool debug, fieldsInOrder = true, withSearcher;
  transient TableSearcher searcher;
  transient L onListChanged;
  transient Set hideFields;
  transient bool useStruct = false; // possible breaking change for older modules
  
  start {
    itemToMap = func(A a) -> Map {
      if (a instanceof S) ret litorderedmap("" := (S) a);
      Map map = humanizeKeys(fieldsInOrder ? objectToMap_inOrder_withoutFields(a, hideFields) : objectToMap(a));
      if (!useStruct) map = mapValues strOrEmpty(map);
      ret map;
    };
    onChange(r updateTable);
  }
  
  void addCountToName {
    onListChanged = addDyn_sync(onListChanged, r addCountToNameNow);
    addCountToNameNow();
  }
  
  void addCountToNameNow() enter {
    setModuleName(programTitle() + " (" + count() + ")");
  }
  
  visualize {
    L