AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.OBJECT_KEY, ObjectKeyNd.PROPERTIES
AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.PROPERTIES, PropertyNd.NESTED_MAP, NestedMapNd.OBJECT_KEY, NestedMapNd.MAPPINGS, NestedMappingNd.NESTED_MAP, ObjectTypeNd.OBJECT_KEY, ObjectKeyNd.PROPERTIES
    private void emitMapping() {        m_ast.traverse(new Node.Switch() {                public void onIdentifier(IdentifierNd id) {                    ObjectTypeNd ot =                        (ObjectTypeNd) id.getParent().getParent();                    ObjectMap om = m_root.getObjectMap			(m_symbols.getEmitted(ot));                    Role role = (Role) m_symbols.getEmitted(ot).getProperty                        (id.getName());                    if (role == null) {                        m_errors.fatal                            (id, "no such property: " + id.getName());                    } else {                        if (role.isCollection()) {                            m_errors.fatal                                (id, "collections cannot be keys: " +                                 id.getName());                        } else {                            om.getKeyProperties().add(role);                            role.setNullable(false);                        }                    }                }            }, new Node.IncludeFilter(new Node.Field[] {                AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.OBJECT_KEY,                ObjectKeyNd.PROPERTIES            }));	m_ast.traverse(new Node.Switch() {		public void onAssociation(AssociationNd assn) {		    if (assn.getProperties().size() == 0) {			return;		    }		    PropertyNd one = assn.getRoleOne();		    PropertyNd two = assn.getRoleTwo();		    ObjectType ot = m_symbols.getEmitted(linkName(assn));		    ObjectMap om = m_root.getObjectMap(ot);		    Collection keys = om.getKeyProperties();		    Role pone = (Role) ot.getProperty(one.getName().getName());		    Role ptwo = (Role) ot.getProperty(two.getName().getName());                    Link lone = (Link)                        ptwo.getType().getProperty(pone.getName());                    Link ltwo = (Link)                        pone.getType().getProperty(ptwo.getName());		    keys.add(ptwo);		    keys.add(pone);		    if (one.getMapping() != null) {			emitMapping(pone, (JoinPathNd) one.getMapping(), 1, 2);			emitMapping(pone.getReverse(),				    (JoinPathNd) two.getMapping(), 0, 1);                        emitMapping(ltwo, (JoinPathNd) two.getMapping(), 0, 2);		    } else {			om.addMapping(new Static(Path.get(pone.getName())));                        ObjectMap oneom = m_root.getObjectMap(pone.getType());                        oneom.addMapping                            (new Static                             (Path.get(pone.getReverse().getName())));                        oneom.addMapping(new Static(Path.get(ltwo.getName())));		    }		    if (two.getMapping() != null) {			emitMapping(ptwo, (JoinPathNd) two.getMapping(), 1, 2);			emitMapping(ptwo.getReverse(),				    (JoinPathNd) one.getMapping(), 0, 1);                        emitMapping(lone, (JoinPathNd) one.getMapping(), 0, 2);		    } else {			om.addMapping(new Static(Path.get(ptwo.getName())));                        ObjectMap twoom = m_root.getObjectMap(ptwo.getType());                        twoom.addMapping			    (new Static			     (Path.get(ptwo.getReverse().getName())));                        twoom.addMapping(new Static(Path.get(lone.getName())));		    }		    String[] paths = new String[] { pone.getName(),						    ptwo.getName() };		    for (int i = 0; i < paths.length; i++) {			Mapping m = om.getMapping(Path.get(paths[i]));			if (m.getTable() != null) {			    om.setTable(m.getTable());			    break;			}		    }		}	    });        m_ast.traverse(new Node.Switch() {                public void onProperty(PropertyNd pn) {                    Role prop = (Role) getEmitted(pn);                    if (prop == null) { return; }                    ObjectMap om = m_root.getObjectMap(prop.getContainer());                    if (om == null) { return; }                    Object mapping = pn.getMapping();                    if (mapping == null) {                        Path p = Path.get(prop.getName());                        om.addMapping(new Static(p));                    } else if (mapping instanceof ColumnNd) {                        emitMapping(prop, (ColumnNd) mapping);                    } else if (mapping instanceof JoinPathNd) {                        emitMapping(prop, (JoinPathNd) mapping);                    } else {                        emitMapping(prop, (QualiasNd) mapping);                    }                    if (!m_root.hasObjectMap(prop.getType())) {                        Mapping m = om.getMapping(prop);                        if (m != null) {                            m.setMap(new ObjectMap(prop.getType()));                        }                    }                    // auto generate reverse way for one-way composites                    if (pn.isComposite()                        && pn.getParent() instanceof ObjectTypeNd) {                        if (mapping == null) {                            m_errors.fatal                                (pn, "one-way composite must have metadata");                        } else {                            Role rev = prop.getReverse();                            if (mapping instanceof JoinPathNd) {                                emitMapping(rev, (JoinPathNd) mapping, true);                            } else {                                m_errors.fatal(pn, "must have a join path");                            }                        }                    }                }            });        m_ast.traverse(new Node.Switch() {                public void onReferenceKey(ReferenceKeyNd rkn) {                    Column key = lookup(rkn.getCol());                    ObjectMap om = getMap(rkn);                    om.setTable(key.getTable());                }                public void onObjectKey(ObjectKeyNd okn) {                    ObjectMap om = getMap(okn);                    IdentifierNd prop =                        (IdentifierNd) okn.getProperties().iterator().next();                    Mapping m = om.getMapping(Path.get(prop.getName()));                    if (m != null) {                        om.setTable(m.getTable());                    }                }            });	m_ast.traverse(new Node.Switch() {		public void onReferenceKey(ReferenceKeyNd rkn) {		    Column key = lookup(rkn.getCol());		    ObjectMap om = getMap(rkn);		    Column[] cols = new Column[] {key};		    if (key.getTable().getForeignKey(cols) == null) {			ObjectMap sm = om.getSuperMap();			Table table = null;			while (sm != null) {			    table = sm.getTable();			    if (table != null) {				break;			    }			    sm = sm.getSuperMap();			}			if (table == null) {			    throw new IllegalStateException				("unable to find supertable for " +                                 om.getObjectType());			}			fk(cols, table.getPrimaryKey());		    }		}	    });        m_ast.traverse(new Node.Switch() {                public void onPath(PathNd nd) {                    ObjectMap om = m_root.getObjectMap                        (m_symbols.getEmitted                         ((ObjectTypeNd) nd.getParent().getParent()));                    om.addFetchedPath(nd.getPath());                }            }, new Node.IncludeFilter(new Node.Field[] {                AST.FILES, FileNd.OBJECT_TYPES, ObjectTypeNd.AGGRESSIVE_LOAD,                AggressiveLoadNd.PATHS            }));    }