Registry { (@ GeneratedCodeCategory get_generatedCategory(String name) throws ParseException { CodeCategory result = get_category(name); if( ! (result instanceof GeneratedCodeCategory)) throw new ParseException("Not a GeneratedCodeCategory: "+name); return (GeneratedCodeCategory)result; } @) void generateCode(GeneratedCodeCategory category,CmdArgs args) (@ SourceList sources = new SourceList(); generateEntityCode(category,args,sources); if( ! sources.isEmpty()) // initialize a macro table category.expandMakeTemplate(/*macros, */args,sources); @) private void generateEntityCode( GeneratedCodeCategory category, CmdArgs args, SourceList sources) bypassing ParentEntity to Entity { (@ private Registry registry; @) before Registry (@ registry = host; @) before Entity (@ final String entityName = host.get_name().get_value(); if(category.get_keys().intersects(host.get_keys())){ System.out.println(" Generating source for: "+entityName); ExpansionContext context = new ExpansionContext(); host.collectContext(context,category.get_keys()); MacroTable macros = new MacroTable(); registry.addMacros(macros,host); String thisClassName = category.className(host); macros.define("ThisClass",thisClassName); macros.define("ThisClassHeader", category.headerFile(host).toString()); macros.define("ThisClassHeaderKey", thisClassName.toUpperCase()+"_H"); category.expandEntityTemplates(context,macros,args,sources); } @) } } Entity { void collectContext(ExpansionContext context, AccessKeyList keys) to TypeUse { before Entity(@ if(context.get_entity() == null) context.set_entity(host); @) around Method (@ // The buck stops at unqualified Methods :-) if(get_keys().intersects(keys)){ context.add(host); subtraversal.apply(); } @) before TypeUse (@ context.add(host); @) } } ExpansionContext{ (@ Hashtable useMap; @) init (@ useMap = new Hashtable(); methods = new MethodList(); useage = new TypeUseList(); entity = null; @) void add(Method method) (@ get_methods().add(method); @) void add(TypeUse newUse) (@ final String key = newUse.get_typeName().get_value(); TypeUse use = (TypeUse)useMap.get(key); if(use == null){ use = new TypeUse( newUse.get_typeName(), false, newUse.get_type()); useMap.put(key,use); useage.add(use); } if(newUse.get_needHeader()) use.set_needHeader(true); @) } Registry{ void addMacros(MacroTable macros,Entity entity) to CodeCategory { before CodeCategory (@ String name = host.get_macroBaseName(); macros.define(name,host.className(entity)); macros.define(name+"Header",host.headerFile(entity).toString()); @) } }