sclass BEAUtils { Map> beaClasses = calcBEAClasses(); Map> beaClasses() { ret beaClasses if null = calcBEAClasses(); } // e.g. "Input" => BInput Map> calcBEAClasses() { ret ciMapToKeys(c -> dropPrefix("B", shortClassName(c)), listMinusItem(BEAObject, myNonAbstractClassesImplementing(BEAObject))); } Class defaultCustomClass(BEAObject o) { ret beaClasses().get(o.type()); } A migrateConceptToClass(Class c, BEAObject in) { A out = unlisted(c); for (S field : conceptFields(in)) try { continue if eq(field, "type"); cset(out, field, cget(in, field)); // TODO: check Ref types } catch e { fail("Can't convert field " + field, e); } ret out; } BEAObject autoMigrate(BEAObject o) { pcall { Class targetClass = defaultCustomClass(o); printVars_str(+o, +targetClass); if (targetClass != null && targetClass != _getClass(o)) ret replaceConceptAndUpdateRefs(o, migrateConceptToClass(targetClass, o)); } ret o; } }