]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
Dependency analysis for XML-schemas consisting of multiple files
authorMarko Luukkainen <marko.luukkainen@vtt.fi>
Mon, 20 Mar 2017 12:52:48 +0000 (14:52 +0200)
committerMarko Luukkainen <marko.luukkainen@vtt.fi>
Mon, 20 Mar 2017 12:52:48 +0000 (14:52 +0200)
refs #6985

Change-Id: I4462e565f49233faee581bdbfe2529bc158255a7

org.simantics.xml.sax/src/org/simantics/xml/sax/ImporterGenerator.java
org.simantics.xml.sax/src/org/simantics/xml/sax/OntologyGenerator.java
org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConverter.java

index 3d137cf33b7357cba1decc999bc3e32852c419ea..f1076b80bda639560696b04eff3a3db08c896466 100644 (file)
-package org.simantics.xml.sax;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.PrintWriter;\r
-import java.io.StringWriter;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import javax.xml.namespace.QName;\r
-\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-import org.simantics.xml.sax.SchemaConversionBase.Inheritance;\r
-import org.simantics.xml.sax.SchemaConversionBase.InheritanceType;\r
-import org.simantics.xml.sax.SchemaConversionBase.RefType;\r
-import org.simantics.xml.sax.SchemaConversionBase.TypeEntry;\r
-import org.simantics.xml.sax.SchemaObject.ObjectType;\r
-import org.simantics.xml.sax.configuration.AttributeComposition;\r
-import org.simantics.xml.sax.configuration.IDProvider;\r
-import org.simantics.xml.sax.configuration.IDReference;\r
-import org.simantics.xml.sax.configuration.UnrecognizedChildElement;\r
-import org.w3._2001.xmlschema.Annotated;\r
-import org.w3._2001.xmlschema.Attribute;\r
-import org.w3._2001.xmlschema.AttributeGroup;\r
-import org.w3._2001.xmlschema.ComplexType;\r
-import org.w3._2001.xmlschema.Element;\r
-import org.w3._2001.xmlschema.LocalComplexType;\r
-import org.w3._2001.xmlschema.LocalSimpleType;\r
-import org.w3._2001.xmlschema.NamedAttributeGroup;\r
-import org.w3._2001.xmlschema.NamedGroup;\r
-import org.w3._2001.xmlschema.Restriction;\r
-import org.w3._2001.xmlschema.SimpleType;\r
-\r
-public class ImporterGenerator extends JavaGenerator{\r
-       \r
-       public ImporterGenerator(SchemaConverter converter, SchemaConversionBase base) {\r
-               super(converter, base);\r
-       }\r
-       \r
-       public void createParser() throws IOException {\r
-               \r
-               String parserPackagePostfix = "_elem";\r
-               String importerClassPostfix = "Importer";\r
-               String parserClassPostfix = "Parser";\r
-               elementPackageName = name+parserPackagePostfix;\r
-               \r
-               importParserDir= new File(converter.getParserDir().getAbsolutePath()+"/"+elementPackageName);\r
-               if (!importParserDir.exists())\r
-                       importParserDir.mkdirs();\r
-               \r
-               base.handle(this);\r
-               // Create Importer class\r
-               File importerFile = new File(converter.getParserDir().getAbsolutePath()+"/"+name+importerClassPostfix+".java");\r
-               PrintWriter mainWriter = createFile(importerFile);\r
-               mainWriter.println("package " + converter.getPluginName() +";");\r
-               mainWriter.println();\r
-               mainWriter.println("import java.io.File;");\r
-               mainWriter.println("import org.simantics.db.Session;");\r
-               mainWriter.println("import org.simantics.xml.sax.base.AbstractImporter;");\r
-               mainWriter.println();\r
-               mainWriter.println("public class " + name + importerClassPostfix+" extends AbstractImporter {");\r
-               mainWriter.println();\r
-               mainWriter.println("   public " + name + importerClassPostfix+"(Session session, File file)  {");\r
-               mainWriter.println("      super(session, file, new "+name + parserClassPostfix+"());");\r
-               mainWriter.println("   }");\r
-               mainWriter.println();\r
-               mainWriter.println("}");\r
-               \r
-               mainWriter.println();\r
-               mainWriter.flush();\r
-               mainWriter.close();\r
-               \r
-               // Create Parser class\r
-               File parserFile = new File(converter.getParserDir().getAbsolutePath()+"/"+name+parserClassPostfix+".java");\r
-               mainWriter = createFile(parserFile);\r
-               mainWriter.println("package " + converter.getPluginName() +";");\r
-               mainWriter.println();\r
-               mainWriter.println("import org.simantics.xml.sax.base.XMLParser;");\r
-               mainWriter.println();\r
-               mainWriter.println("public class " + name + parserClassPostfix+" extends XMLParser {");\r
-               mainWriter.println();\r
-               mainWriter.println("   public " + name + parserClassPostfix+"()  {");\r
-               if (schema.getTargetNamespace() != null)\r
-               mainWriter.println("      setSchemaURI(\""+schema.getTargetNamespace()+"\");");\r
-               for (String s : ruleClassNames) {\r
-               mainWriter.println("      add(new "+s+"());");\r
-               }\r
-               mainWriter.println("   }");\r
-               mainWriter.println("}");\r
-               \r
-               mainWriter.println();\r
-               mainWriter.flush();\r
-               mainWriter.close();\r
-       }\r
-       \r
-       @Override\r
-       public void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) {\r
-       }\r
-       \r
-       @Override\r
-       public void handle(SchemaObject parent, NamedGroup attribute) {\r
-               // TODO Auto-generated method stub\r
-       }\r
-       \r
-       @Override\r
-       public void handleComplexType(SchemaObject complexTypeObj) {\r
-               ComplexType topLevelComplexType = complexTypeObj.getComplexType();\r
-               \r
-               String name = getName(complexTypeObj);\r
-               \r
-               //if (topLevelComplexType.getName().equals("LocalizedText"))\r
-               //if (topLevelComplexType.getName().equals("Reference"))\r
-//             if (topLevelComplexType.getName().equals("NodeIdAlias"))\r
-//                     System.out.println();\r
-               \r
-               String className = name;//"_"+name;\r
-               \r
-               FileWriter fw = new FileWriter();\r
-               try {\r
-                       fw.writer = createFile(new File(importParserDir.getAbsolutePath()+"/"+className+".java"));\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               writers.put(complexTypeObj, fw);\r
-               \r
-               Inheritance inheritance = this.base.getInheritance(complexTypeObj);\r
-               \r
-               provider = this.base.getIDProvider(topLevelComplexType);\r
-               List<IDReference> references = this.base.getIDReferences(topLevelComplexType);\r
-               UnrecognizedChildElement unknownChildElement = this.base.getUnknown(topLevelComplexType);\r
-\r
-               List<String> intrerfaces = new ArrayList<String>();\r
-               if (references.size() > 0)\r
-                       intrerfaces.add("org.simantics.xml.sax.base.IDReferenceParser");\r
-               if (unknownChildElement != null)\r
-                       intrerfaces.add("org.simantics.xml.sax.base.UnrecognizedElementParser");\r
-               \r
-               createClassHeader(fw.writer, false);\r
-               writeClass(fw.writer,false, null, className, inheritance.baseClass, intrerfaces);\r
-                       \r
-               writeIDProvider(fw.writer);\r
-       \r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public Resource create(WriteGraph graph, ParserElement element) throws DatabaseException{");\r
-               fw.writer.println("      Layer0 L0 = Layer0.getInstance(graph);");\r
-               fw.writer.println("      "+getOntologyImport());\r
-               fw.writer.println("      Resource res = graph.newResource();");\r
-               fw.writer.println("      graph.claim(res, L0.InstanceOf, "+ontShort+name+");");\r
-               fw.writer.println("      return res;");\r
-               fw.writer.println("   }");\r
-               fw.writer.println();\r
-               \r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public boolean connectParent(WriteGraph graph, ParserElement parent, ParserElement element) throws DatabaseException{");\r
-               fw.writer.println("      "+getOntologyImport());\r
-               fw.writer.println("      graph.claim(parent.getData(), "+this.ontShort+getName(complexTypeObj,"has")+", element.getData());");\r
-               fw.writer.println("      return true;");\r
-               fw.writer.println("   }");\r
-               fw.writer.println();\r
-                               \r
-               StringWriter stringWriter = new StringWriter();\r
-               fw.delayedWriter = new PrintWriter(stringWriter);\r
-               StringWriter stringWriter2 = new StringWriter();\r
-               fw.delayedWriter2 = new PrintWriter(stringWriter2);\r
-               \r
-               fw.writer.println("   public " + className + "() {");\r
-               fw.writer.println("      super();");\r
-               \r
-               this.base.handleComplexTypeExtension(complexTypeObj);\r
-               \r
-               fw.writer.println("   }");\r
-               \r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public boolean connectChild(WriteGraph graph, ParserElement element, ParserElement child) throws DatabaseException{");\r
-               fw.writer.println("      "+getOntologyImport());\r
-               \r
-               if (stringWriter.getBuffer().length() > 0) {\r
-                       fw.writer.write(stringWriter.toString());\r
-               }\r
-               if (inheritance.type == InheritanceType.ComplexType) {\r
-               fw.writer.println("      return super.connectChild(graph,element,child);");\r
-               }else{\r
-               fw.writer.println("      return false;");\r
-               }\r
-               fw.writer.println("   }");\r
-               fw.writer.println();\r
-               \r
-               if (stringWriter2.getBuffer().length() > 0) {\r
-                       fw.writer.write(stringWriter2.toString());\r
-               }\r
-               \r
-               stringWriter = null;\r
-               fw.delayedWriter.close();\r
-               fw.delayedWriter=null;\r
-               stringWriter2 = null;\r
-               fw.delayedWriter2.close();\r
-               fw.delayedWriter2 = null;\r
-               \r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public void configure(WriteGraph graph, Deque<ParserElement> parents, ParserElement element) throws DatabaseException {");\r
-               if (inheritance.type == InheritanceType.ComplexType) {\r
-               fw.writer.println("             super.configure(graph,parents,element);");\r
-               }\r
-               fw.writer.println("        "+getOntologyImport());\r
-               \r
-               this.base.handleComplexTypeAttributes(complexTypeObj);\r
-               this.base.handleExtensionAttributes(complexTypeObj);\r
-               \r
-               fw.writer.println("   }");\r
-               \r
-               if (inheritance.type == InheritanceType.AtomicType) {\r
-               fw.writer.println();\r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public void configure(WriteGraph graph, ParserElement element, java.lang.String string) throws DatabaseException {");\r
-               fw.writer.println("      graph.claimValue(element.getData(), "+getValueGetter(inheritance.atomicType,"string")+", "+inheritance.atomicType.binding+");");\r
-               fw.writer.println("   }");\r
-               }\r
-               \r
-               writeIDReferences(fw.writer,name, references);\r
-               writeUnknownChild(fw.writer,name,unknownChildElement);\r
-               \r
-               fw.writer.println("}");\r
-               fw.writer.println();\r
-               fw.writer.flush();\r
-               fw.writer.close();\r
-               fw.writer = null;\r
-               writers.remove(complexTypeObj);\r
-               provider = null;\r
-       }\r
-       \r
-       @Override\r
-       public void createReferenceIndicator(SchemaObject parent, RefType referenceType, String refName, String objectName, String primaryClassName, String secondaryClassName, boolean useElementList, boolean useOriginalList) {\r
-               FileWriter fw = getWriter(parent);\r
-               if (referenceType == RefType.Type) {\r
-               // create internal class for handling the element and child attachment\r
-               secondaryClassName = getName(parent) +"_" +objectName;\r
-               fw.writer.println("        addParser(\""+ objectName +"\", "+secondaryClassName+".class);");\r
-               fw.delayedWriter2.println("   public static class " + secondaryClassName +" extends " + primaryClassName +"{");\r
-               fw.delayedWriter2.println("      public "+ secondaryClassName +"(){");\r
-               fw.delayedWriter2.println("      }");\r
-               fw.delayedWriter2.println("   }");\r
-               } else { // referenceType == RefType.Reference\r
-               fw.writer.println("        addParser("+primaryClassName+".class);");\r
-               if (!primaryClassName.equals(secondaryClassName))\r
-               fw.writer.println("        addParser("+secondaryClassName+".class);");\r
-               }\r
-               \r
-               fw.delayedWriter.println("         if (child.getElementParser() instanceof "+secondaryClassName+"){");\r
-               fw.delayedWriter.println("            graph.claim(element.getData(), "+ontShort+getName(parent)+"_has"+refName + ", child.getData());");\r
-               if (useElementList) {\r
-\r
-               // element type specific list\r
-               fw.delayedWriter.println("            {");\r
-               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List);");\r
-               fw.delayedWriter.println("               if (list == null) {");\r
-               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List,list);");\r
-               fw.delayedWriter.println("               } else {");\r
-               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("               }");\r
-               fw.delayedWriter.println("            }");\r
-               }\r
-               if (useOriginalList) {\r
-               // generic list\r
-               fw.delayedWriter.println("            {");\r
-               fw.delayedWriter.println("               XMLResource XML = XMLResource.getInstance(graph);");\r
-               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(), XML.hasOriginalElementList);");\r
-               fw.delayedWriter.println("               if (list == null) {");\r
-               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("                  graph.claim(element.getData(), XML.hasOriginalElementList,list);");\r
-               fw.delayedWriter.println("               } else {");\r
-               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("               }");\r
-               fw.delayedWriter.println("            }");\r
-               }\r
-               \r
-               fw.delayedWriter.println("            return true;");\r
-               fw.delayedWriter.println("         }");\r
-       }\r
-       \r
-       @Override\r
-       protected void createPrimitiveIndicator(SchemaObject parent, String refName, String binding) {\r
-               FileWriter fw = getWriter(parent);\r
-               fw.writer.println("        addParser(\""+ refName +"\", "+getName(parent) +"_" +refName+".class);");\r
-               \r
-               fw.delayedWriter2.println("   public static class " + getName(parent) +"_" +refName+" extends org.simantics.xml.sax.base.ValueElementParser {");\r
-               fw.delayedWriter2.println("      public "+ getName(parent) +"_" +refName +"(){");\r
-               fw.delayedWriter2.println("           super(\""+refName+"\"," +this.ontologyClassName+".URIs."+getName(parent) + "_has"+refName+", "+binding+");");\r
-               fw.delayedWriter2.println("       }");\r
-               fw.delayedWriter2.println("   }");\r
-       }\r
-       \r
-       @Override\r
-       protected void createElementIndicator(SchemaObject parent, boolean useElementList, String refName, String className, boolean useOriginalList) {\r
-               FileWriter fw = getWriter(parent);\r
-               //if (!reference)\r
-               fw.writer.println("        addParser(\""+ refName +"\", "+className+".class);");\r
-//             else\r
-//             fw.writer.println("        addParser("+className+".class);");\r
-               \r
-               fw.delayedWriter.println("         if (child.getElementParser() instanceof "+className+"){");\r
-               fw.delayedWriter.println("            graph.claim(element.getData(), "+ontShort+getName(parent)+"_has"+refName + ", child.getData());");\r
-               if (useElementList) {\r
-\r
-               // element type specific list\r
-               fw.delayedWriter.println("            {");\r
-               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List);");\r
-               fw.delayedWriter.println("               if (list == null) {");\r
-               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List,list);");\r
-               fw.delayedWriter.println("               } else {");\r
-               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("               }");\r
-               fw.delayedWriter.println("            }");\r
-               }\r
-               if (useOriginalList) {\r
-               // generic list\r
-               fw.delayedWriter.println("            {");\r
-               fw.delayedWriter.println("               XMLResource XML = XMLResource.getInstance(graph);");\r
-               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(), XML.hasOriginalElementList);");\r
-               fw.delayedWriter.println("               if (list == null) {");\r
-               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("                  graph.claim(element.getData(), XML.hasOriginalElementList,list);");\r
-               fw.delayedWriter.println("               } else {");\r
-               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");\r
-               fw.delayedWriter.println("               }");\r
-               fw.delayedWriter.println("            }");\r
-               }\r
-               \r
-               fw.delayedWriter.println("            return true;");\r
-               fw.delayedWriter.println("         }");\r
-       }\r
-       \r
-       @Override\r
-       public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {          \r
-               // generates overriding method that allows parsing any element\r
-               FileWriter fw = getWriter(parent);\r
-               fw.delayedWriter2.println("   @Override");\r
-               fw.delayedWriter2.println("   public Class<? extends org.simantics.xml.sax.base.XMLElementParser> getParser(java.util.Map<java.lang.String,org.simantics.xml.sax.base.XMLElementParser> parsers, ParserElement element, ParserElement child) {");\r
-               fw.delayedWriter2.println("      Class<? extends org.simantics.xml.sax.base.XMLElementParser> parserClass = super.getParser(parsers, element, child);");\r
-               fw.delayedWriter2.println("      if (parserClass != null) return parserClass;");\r
-               fw.delayedWriter2.println("      org.simantics.xml.sax.base.XMLElementParser parser = parsers.get(child.getQName());");\r
-               fw.delayedWriter2.println("      if (parser != null) return parser.getClass();");\r
-               fw.delayedWriter2.println("      return null;");\r
-               fw.delayedWriter2.println("   }");\r
-       }\r
-\r
-       @Override       \r
-       public void handle(SchemaObject parent, Attribute attribute) {\r
-               if (parent == null)\r
-                       return;\r
-               String name = attribute.getName();\r
-               QName primitiveType = attribute.getType();\r
-               SimpleType simpleType = attribute.getSimpleType();\r
-               QName ref = attribute.getRef();\r
-               \r
-               String relationName;\r
-               String attrName;\r
-               if (name != null) {\r
-                       attrName = name;\r
-                       relationName = ontShort+"has"+name;\r
-                       if (parent != null)\r
-                               relationName = ontShort+getName(parent)+"_has"+name;\r
-               }\r
-               else if (ref != null && parent != null) {\r
-                       attrName = ref.getLocalPart();\r
-                       relationName = ontShort+getName(parent)+"_has"+ref.getLocalPart();\r
-                       \r
-                       Attribute referred = this.base.getRefAttribute(ref);\r
-                       if (referred != null) {\r
-                               primitiveType = referred.getType();\r
-                               simpleType = referred.getSimpleType();\r
-                       }\r
-                       \r
-               } else {\r
-                       throw new RuntimeException();\r
-               }\r
-               boolean isReference = false;\r
-               if (provider!= null && provider.getAttribute().getName().equals(attrName))\r
-                       isReference = true;\r
-               \r
-               FileWriter fw = getWriter(parent);\r
-               if (primitiveType != null) {\r
-                       \r
-                       //String binding = getBindingFromPrimitiveType(primitiveType);\r
-                       TypeEntry binding = this.base.getTypeEntry(primitiveType);\r
-                       \r
-                       if (binding != null) {\r
-                               writeAttribute(fw, attrName, relationName, binding, isReference);\r
-                               return;\r
-                   } else {\r
-                       if (simpleType == null) {\r
-                               SchemaObject simpleTypeObj = this.base.getSimpleType(primitiveType);//this.base.simpleTypeName.get(primitiveType.getLocalPart());\r
-                               if (simpleTypeObj != null)\r
-                                       simpleType = simpleTypeObj.getSimpleType();\r
-                       }       \r
-                   }\r
-               } \r
-               if (simpleType != null) {\r
-                       org.w3._2001.xmlschema.List list = simpleType.getList();\r
-                       if (list != null) {\r
-                               TypeEntry binding = this.base.getTypeEntry(new QName(SchemaConversionBase.SCHEMA_NS, "string"));\r
-                               writeAttribute(fw, attrName, relationName, binding, isReference);\r
-                       } else {\r
-                               Restriction restriction = simpleType.getRestriction();\r
-                               if (restriction == null)\r
-                                       throw new RuntimeException("Cannot resolve type for Attribute " + attrName + " -> " + primitiveType.getLocalPart()+ ", SimpleType restriction is unset");\r
-                               QName base = restriction.getBase();\r
-                               \r
-                               \r
-                               //String binding = getBindingFromPrimitiveType(base);\r
-                               TypeEntry binding = this.base.getTypeEntry(base);\r
-                               writeAttribute(fw, attrName, relationName, binding, isReference);\r
-                       }\r
-               } else {\r
-                       // TODO : using default String attribute should be configured with rules.\r
-                       //throw new RuntimeException("Cannot resolve type for Attribute " + attrName + " -> " + primitiveType.getLocalPart());\r
-                       fw.writer.println("    //FIXME: Cannot resolve type for Attribute " + attrName + " Using default type String");\r
-                       //writeAttribute(fw, attrName, relationName, "STRING", isReference);\r
-                       writeAttribute(fw, attrName, relationName, this.base.getTypeEntry("string"), isReference);\r
-               }\r
-       }\r
-       \r
-       private void writeAttribute(FileWriter fw, String attrName, String relationName, TypeEntry binding, boolean isReference) {\r
-               fw.writer.println("      {");\r
-               fw.writer.println("         Attribute a = element.getAttribute(\"" +attrName+"\");");\r
-               fw.writer.println("         if (a != null) {");\r
-               fw.writer.println("            graph.claimLiteral(element.getData(),"+relationName+","+getValueGetterMethod(binding,"a")+", "+binding.binding+");");\r
-               if (isReference)\r
-               fw.writer.println("            idProviderValue = a.getValue();");       \r
-               fw.writer.println("         }");\r
-               fw.writer.println("      }");\r
-       }\r
-       \r
-       @Override\r
-       public void handleAttributes(SchemaObject simpleTypeObj) {\r
-               SchemaObject parent = simpleTypeObj.getParent();\r
-               FileWriter fw = getWriter(parent);\r
-               \r
-               SimpleType simpleType = simpleTypeObj.getSimpleType();\r
-               Restriction restriction = simpleType.getRestriction();\r
-               if (restriction == null)\r
-                       throw new RuntimeException("Cannot resolve type for Element " + getName(parent));\r
-               QName base = restriction.getBase();\r
-               \r
-               \r
-               //String binding = getBindingFromPrimitiveType(base);\r
-               TypeEntry binding = this.base.getTypeEntry(base);\r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public void configure(WriteGraph graph, ParserElement element, java.lang.String value) throws DatabaseException {");\r
-               //fw.writer.println("      graph.claimValue(element.getData(),"+getValueGetter(binding)+", Bindings."+binding+");");\r
-               fw.writer.println("      graph.claimValue(element.getData(),"+getValueGetter(binding)+", "+binding.binding +");");\r
-               fw.writer.println("   }");\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void handle(SchemaObject parent, AttributeGroup attribute) {\r
-               if (parent != null) {\r
-                       FileWriter fw = getWriter(parent);\r
-                       NamedAttributeGroup group = this.base.getAttributeGroup(attribute.getRef());\r
-                       fw.writer.println(commentTag+"    AttributeGroup " + group.getName());\r
-                       SchemaObject obj = new SchemaObject(parent,attribute);\r
-                       for (Annotated annotated : group.getAttributeOrAttributeGroup()) {\r
-                               if (annotated instanceof Attribute) {\r
-                                       //handle("AttributeGroups_"+group.getName(),(Attribute)annotated);\r
-                                       handle(obj,(Attribute)annotated);\r
-                               } else if (annotated instanceof AttributeGroup) {\r
-                                       //handle("AttributeGroups_"+group.getName(),(AttributeGroup)annotated);\r
-                                       handle(obj,(AttributeGroup)annotated);\r
-                               }\r
-                       }\r
-                       //dd\r
-                       if(true)\r
-                               System.out.println();\r
-                       fw.writer.println(commentTag+"    End of AttributeGroup " + group.getName());\r
-               }\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {\r
-               FileWriter fw = getWriter(parent);\r
-               QName type = new QName(SchemaConversionBase.CONVERSION_NS, composition.getType());\r
-               String arrayBinding = this.base.getBindingFromPrimitiveType(type);\r
-               String javaType = this.base.getJavaTypeFromPrimitiveType(type);\r
-               String name = composition.getName();\r
-               \r
-               String relationName;\r
-               if (name != null) {\r
-                       relationName = ontShort+"has"+name;\r
-                       if (parent != null)\r
-                               relationName = ontShort+getName(parent)+"_has"+name;\r
-               } else {\r
-                       throw new RuntimeException();\r
-               }\r
-               \r
-               fw.writer.println("      {");\r
-               int i = 0;\r
-               for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute())\r
-               fw.writer.println("         Attribute a"+(i++)+" = element.getAttribute(\"" +a.getName()+"\");");\r
-               fw.writer.print  ("         "+javaType + " value = new "+javaType+"{");\r
-               i = 0;\r
-               // FIXME : handle optional attributes properly.\r
-               for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {\r
-                       Attribute attribute = ((Attribute)attributes.getRight(a));\r
-                       //QName atype = getBaseType(attribute);\r
-                       QName atype = this.base.getPrimitiveType(attribute);\r
-                       String defaultValue = attribute.getDefault();\r
-                       if (defaultValue == null)\r
-                           defaultValue = this.base.getDefaultValue(atype);\r
-                               \r
-                       //String binding = getBindingFromPrimitiveType(atype);\r
-                       TypeEntry binding = this.base.getTypeEntry(atype);\r
-                       if (i > 0)\r
-                               fw.writer.print(",");\r
-                       if (defaultValue != null)\r
-                               fw.writer.print("a"+(i)+"!= null ? "+ getValueGetterMethod(binding,"a"+(i++)) + " : " +defaultValue);\r
-                       else\r
-                               fw.writer.print(getValueGetterMethod(binding,"a"+(i++)));\r
-               }\r
-               fw.writer.println("};");\r
-               fw.writer.println("         graph.claimLiteral(element.getData(),"+relationName+", value, "+arrayBinding+");");\r
-               fw.writer.println("      }");\r
-               \r
-       }\r
-       \r
-       \r
-       \r
-       \r
-       \r
-\r
-       \r
-       IDProvider provider;\r
-       @Override\r
-       public void handleElement(SchemaObject elementObj)  {\r
-               Element element = elementObj.getElement();\r
-               \r
-               String name = getName(elementObj);//topLevelElement.getName();\r
-               String className = name;\r
-               \r
-               FileWriter fw = new FileWriter();\r
-               try {\r
-                       fw.writer = createFile(new File(importParserDir.getAbsolutePath()+"/"+className+".java"));\r
-               } catch (IOException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
-               writers.put(elementObj, fw);\r
-               boolean isList = false;\r
-               \r
-               Inheritance inheritance = this.base.getInheritance(elementObj); \r
-               \r
-               provider = this.base.getIDProvider(element);\r
-               List<IDReference> references = this.base.getIDReferences(element);\r
-               UnrecognizedChildElement unknownChildElement = this.base.getUnknown(element);\r
-\r
-               List<String> intrerfaces = new ArrayList<String>();\r
-               if (references.size() > 0)\r
-                       intrerfaces.add("org.simantics.xml.sax.base.IDReferenceParser");\r
-               if (unknownChildElement != null)\r
-                       intrerfaces.add("org.simantics.xml.sax.base.UnrecognizedElementParser");\r
-\r
-               createClassHeader(fw.writer, isList);\r
-               writeClass(fw.writer,false, element.getName(), className, inheritance.baseClass, intrerfaces);\r
-               writeIDProvider(fw.writer);\r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public Resource create(WriteGraph graph, ParserElement element) throws DatabaseException{");\r
-               fw.writer.println("      Layer0 L0 = Layer0.getInstance(graph);");\r
-               fw.writer.println("      "+getOntologyImport());\r
-               if (!isList) {\r
-               fw.writer.println("      Resource res = graph.newResource();");\r
-               fw.writer.println("      graph.claim(res, L0.InstanceOf, "+ontShort+name+");");\r
-               } else {\r
-               fw.writer.println("      Resource res = ListUtils.create(graph, "+ontShort+name+", Collections.EMPTY_LIST);");\r
-               }\r
-               fw.writer.println("      return res;");\r
-               fw.writer.println("   }");\r
-               fw.writer.println();\r
-               \r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public boolean connectParent(WriteGraph graph, ParserElement parent, ParserElement element) throws DatabaseException{");\r
-               fw.writer.println("      "+getOntologyImport());\r
-               fw.writer.println("      graph.claim(parent.getData(), "+this.ontShort+getName(elementObj,"has")+", element.getData());");\r
-               fw.writer.println("      return true;");\r
-               fw.writer.println("   }");\r
-               fw.writer.println();\r
-               \r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public void configure(WriteGraph graph, Deque<ParserElement> parents, ParserElement element) throws DatabaseException {");\r
-               if (inheritance.type == InheritanceType.ComplexType) {\r
-               fw.writer.println("             super.configure(graph,parents,element);");\r
-               }\r
-               fw.writer.println("        "+getOntologyImport());\r
-               \r
-               LocalComplexType complexType = element.getComplexType();\r
-               LocalSimpleType simpleType = element.getSimpleType();\r
-               \r
-               if (complexType != null) {\r
-                       SchemaObject obj = this.base.getComplexType(complexType);\r
-                       this.base.handleElementComplexTypeAttributes(obj);\r
-               } \r
-               fw.writer.println("   }");\r
-               \r
-               if (inheritance.type == InheritanceType.AtomicType) {\r
-               fw.writer.println();\r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public void configure(WriteGraph graph, ParserElement element, java.lang.String string) throws DatabaseException {");\r
-               fw.writer.println("      graph.claimValue(element.getData(), "+getValueGetter(inheritance.atomicType,"string")+", "+inheritance.atomicType.binding+");");\r
-               fw.writer.println("   }");\r
-               }\r
-//             if (simpleType != null) {\r
-//                     SchemaObject obj = simpleTypes.get(simpleType);\r
-//                     handleElementSimpleTypeAttributes(obj);\r
-//             }\r
-               \r
-               \r
-               StringWriter stringWriter = new StringWriter();\r
-               fw.delayedWriter = new PrintWriter(stringWriter);\r
-               StringWriter stringWriter2 = new StringWriter();\r
-               fw.delayedWriter2 = new PrintWriter(stringWriter2);\r
-               \r
-               fw.writer.println("   public " + className + "() {");\r
-               fw.writer.println("      super();");\r
-               \r
-               if (complexType != null) {\r
-                       SchemaObject obj = this.base.getComplexType(complexType);\r
-                       this.base.handleComplexTypeExtension(obj);\r
-               } else if (simpleType != null) {\r
-                       \r
-               }\r
-               \r
-               fw.writer.println("   }");\r
-               \r
-               fw.writer.println("   @Override");\r
-               fw.writer.println("   public boolean connectChild(WriteGraph graph, ParserElement element, ParserElement child) throws DatabaseException{");\r
-               fw.writer.println("      "+getOntologyImport());\r
-               \r
-               if (stringWriter.getBuffer().length() > 0) {\r
-                       fw.writer.write(stringWriter.toString());\r
-               }\r
-               if (inheritance.type == InheritanceType.ComplexType) {\r
-               fw.writer.println("      return super.connectChild(graph,element,child);");     \r
-               } else {\r
-               fw.writer.println("      return false;");\r
-               }\r
-               fw.writer.println("   }");\r
-               fw.writer.println();\r
-               \r
-               if (stringWriter2.getBuffer().length() > 0) {\r
-                       fw.writer.write(stringWriter2.toString());\r
-               }\r
-               \r
-               stringWriter = null;\r
-               fw.delayedWriter.close();\r
-               fw.delayedWriter = null;\r
-               stringWriter2 = null;\r
-               fw.delayedWriter2.close();\r
-               fw.delayedWriter2 = null;\r
-               \r
-               writeIDReferences(fw.writer,name, references);\r
-               writeUnknownChild(fw.writer,name,unknownChildElement);\r
-\r
-               fw.writer.println("}");\r
-               fw.writer.println();\r
-               fw.writer.flush();\r
-               fw.writer.close();\r
-               fw.writer = null;\r
-               writers.remove(elementObj);\r
-               provider = null;\r
-               \r
-               ruleClassNames.add(converter.getPluginName()+"."+elementPackageName+"."+name);\r
-       }\r
-\r
-       \r
-       private void writeIDProvider(PrintWriter writer) {\r
-               if (provider != null) {\r
-               writer.println("   java.lang.String idProviderValue = null;");\r
-               writer.println();\r
-               writer.println("   @Override");\r
-               writer.println("   public java.lang.String getID() {");\r
-               writer.println("        java.lang.String s = idProviderValue;");\r
-               writer.println("        idProviderValue = null;");\r
-               writer.println("        return s;");\r
-               writer.println("   }");\r
-               writer.println();\r
-               if (provider.getPriority() != null) {\r
-               writer.println("   @Override");\r
-               writer.println("   public int idPriority() {");\r
-               writer.println("        return " + provider.getPriority().intValue()+";");\r
-               writer.println("   }"); \r
-               }\r
-               }\r
-       }\r
-       \r
-       private void writeIDReferences(PrintWriter writer,String name, List<IDReference> references) {\r
-               if (references.size() > 0) {\r
-               writer.println("   @Override");\r
-               writer.println("   public boolean connectReferences(WriteGraph graph, ParserElement element, java.util.Map<java.lang.String, ParserElement> map) throws DatabaseException {");\r
-               writer.println("      "+getOntologyImport());\r
-               writer.println("      boolean result = true;");\r
-               for (IDReference ref : references) {\r
-               writer.println("      {");\r
-               writer.println("         Attribute a = element.getAttribute(\"" + ref.getIDSource().getName() +"\");");\r
-               writer.println("         if (a != null) {");\r
-               writer.println("            ParserElement refEle = map.get(a.value);");\r
-               writer.println("            if (refEle != null) {");\r
-               writer.println("               Resource ref = refEle.getData();");\r
-               writer.println("               graph.claim(element.getData(), "+ontShort+name+"_"+ref.getReference().getName()+", ref);");\r
-               writer.println("            } else {");\r
-               writer.println("               result = false;");\r
-               writer.println("            }");\r
-               writer.println("         }");\r
-               writer.println("      }");\r
-               }\r
-               writer.println("      return result;");\r
-               writer.println("   }");\r
-               writer.println();\r
-               }\r
-       }\r
-       \r
-       private void writeUnknownChild(PrintWriter writer,String name, UnrecognizedChildElement unknownChildElement) {\r
-               if (unknownChildElement == null)\r
-                       return;\r
-               \r
-               writer.println("   @Override");\r
-               writer.println("   public void configureChild(WriteGraph graph, Deque<ParserElement> parents, ParserElement element, ParserElement child) throws DatabaseException {");\r
-               writer.println("    " + unknownChildElement.getJavaMethod());\r
-               writer.println("   }");\r
-               writer.println();\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public String getBaseClass(ObjectType type) {\r
-               return "org.simantics.xml.sax.base.XMLElementNamedChildParserBase";\r
-       }\r
-       \r
-       protected void createClassHeader(PrintWriter writer, boolean isList) {\r
-               writer.println("package " + converter.getPluginName() +"."+elementPackageName+";");\r
-               writer.println();\r
-               writer.println("import java.util.Deque;");\r
-               writer.println("import org.simantics.databoard.Bindings;");\r
-               writer.println("import org.simantics.db.Resource;");\r
-               writer.println("import org.simantics.db.WriteGraph;");\r
-               writer.println("import org.simantics.db.exception.DatabaseException;");\r
-               writer.println("import org.simantics.xml.sax.base.Attribute;");\r
-               writer.println("import org.simantics.xml.sax.base.ParserElement;");\r
-               writer.println("import org.simantics.xml.sax.ontology.XMLResource;");\r
-               if (!isList) {\r
-               writer.println("import org.simantics.layer0.Layer0;");\r
-           } else {\r
-           writer.println("import java.util.Collections;");\r
-               writer.println("import org.simantics.db.common.utils.ListUtils;");\r
-               }\r
-               writer.println();\r
-       }\r
-       \r
-}\r
+package org.simantics.xml.sax;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.simantics.utils.datastructures.BijectionMap;
+import org.simantics.xml.sax.SchemaConversionBase.Inheritance;
+import org.simantics.xml.sax.SchemaConversionBase.InheritanceType;
+import org.simantics.xml.sax.SchemaConversionBase.RefType;
+import org.simantics.xml.sax.SchemaConversionBase.TypeEntry;
+import org.simantics.xml.sax.SchemaObject.ObjectType;
+import org.simantics.xml.sax.configuration.AttributeComposition;
+import org.simantics.xml.sax.configuration.IDProvider;
+import org.simantics.xml.sax.configuration.IDReference;
+import org.simantics.xml.sax.configuration.UnrecognizedChildElement;
+import org.w3._2001.xmlschema.Annotated;
+import org.w3._2001.xmlschema.Attribute;
+import org.w3._2001.xmlschema.AttributeGroup;
+import org.w3._2001.xmlschema.ComplexType;
+import org.w3._2001.xmlschema.Element;
+import org.w3._2001.xmlschema.LocalComplexType;
+import org.w3._2001.xmlschema.LocalSimpleType;
+import org.w3._2001.xmlschema.NamedAttributeGroup;
+import org.w3._2001.xmlschema.NamedGroup;
+import org.w3._2001.xmlschema.Restriction;
+import org.w3._2001.xmlschema.SimpleType;
+
+public class ImporterGenerator extends JavaGenerator{
+       
+       public ImporterGenerator(SchemaConverter converter, SchemaConversionBase base) {
+               super(converter, base);
+       }
+       
+       public void createParser() throws IOException {
+               
+               String parserPackagePostfix = "_elem";
+               String importerClassPostfix = "Importer";
+               String parserClassPostfix = "Parser";
+               elementPackageName = name+parserPackagePostfix;
+               
+               importParserDir= new File(converter.getParserDir().getAbsolutePath()+"/"+elementPackageName);
+               if (!importParserDir.exists())
+                       importParserDir.mkdirs();
+               
+               base.handle(this);
+               // Create Importer class
+               File importerFile = new File(converter.getParserDir().getAbsolutePath()+"/"+name+importerClassPostfix+".java");
+               PrintWriter mainWriter = createFile(importerFile);
+               mainWriter.println("package " + converter.getPluginName() +";");
+               mainWriter.println();
+               mainWriter.println("import java.io.File;");
+               mainWriter.println("import org.simantics.db.Session;");
+               mainWriter.println("import org.simantics.xml.sax.base.AbstractImporter;");
+               mainWriter.println();
+               mainWriter.println("public class " + name + importerClassPostfix+" extends AbstractImporter {");
+               mainWriter.println();
+               mainWriter.println("   public " + name + importerClassPostfix+"(Session session, File file)  {");
+               mainWriter.println("      super(session, file, new "+name + parserClassPostfix+"());");
+               mainWriter.println("   }");
+               mainWriter.println();
+               mainWriter.println("}");
+               
+               mainWriter.println();
+               mainWriter.flush();
+               mainWriter.close();
+               
+               // Create Parser class
+               File parserFile = new File(converter.getParserDir().getAbsolutePath()+"/"+name+parserClassPostfix+".java");
+               mainWriter = createFile(parserFile);
+               mainWriter.println("package " + converter.getPluginName() +";");
+               mainWriter.println();
+               mainWriter.println("import org.simantics.xml.sax.base.XMLParser;");
+               mainWriter.println();
+               mainWriter.println("public class " + name + parserClassPostfix+" extends XMLParser {");
+               mainWriter.println();
+               mainWriter.println("   public " + name + parserClassPostfix+"()  {");
+               if (schema.getTargetNamespace() != null)
+               mainWriter.println("      setSchemaURI(\""+schema.getTargetNamespace()+"\");");
+               for (String s : ruleClassNames) {
+               mainWriter.println("      add(new "+s+"());");
+               }
+               mainWriter.println("   }");
+               mainWriter.println("}");
+               
+               mainWriter.println();
+               mainWriter.flush();
+               mainWriter.close();
+       }
+       
+       @Override
+       public void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) {
+       }
+       
+       @Override
+       public void handle(SchemaObject parent, NamedGroup attribute) {
+               // TODO Auto-generated method stub
+       }
+       
+       @Override
+       public void handleComplexType(SchemaObject complexTypeObj) {
+               ComplexType topLevelComplexType = complexTypeObj.getComplexType();
+               
+               String name = getName(complexTypeObj);
+               
+               //if (topLevelComplexType.getName().equals("LocalizedText"))
+               //if (topLevelComplexType.getName().equals("Reference"))
+//             if (topLevelComplexType.getName().equals("NodeIdAlias"))
+//                     System.out.println();
+               
+               String className = name;//"_"+name;
+               
+               FileWriter fw = new FileWriter();
+               try {
+                       fw.writer = createFile(new File(importParserDir.getAbsolutePath()+"/"+className+".java"));
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+               writers.put(complexTypeObj, fw);
+               
+               Inheritance inheritance = this.base.getInheritance(complexTypeObj);
+               
+               provider = this.base.getIDProvider(topLevelComplexType);
+               List<IDReference> references = this.base.getIDReferences(topLevelComplexType);
+               UnrecognizedChildElement unknownChildElement = this.base.getUnknown(topLevelComplexType);
+
+               List<String> intrerfaces = new ArrayList<String>();
+               if (references.size() > 0)
+                       intrerfaces.add("org.simantics.xml.sax.base.IDReferenceParser");
+               if (unknownChildElement != null)
+                       intrerfaces.add("org.simantics.xml.sax.base.UnrecognizedElementParser");
+               
+               createClassHeader(fw.writer, false);
+               writeClass(fw.writer,false, null, className, inheritance.baseClass, intrerfaces);
+                       
+               writeIDProvider(fw.writer);
+       
+               fw.writer.println("   @Override");
+               fw.writer.println("   public Resource create(WriteGraph graph, ParserElement element) throws DatabaseException{");
+               fw.writer.println("      Layer0 L0 = Layer0.getInstance(graph);");
+               fw.writer.println("      "+getOntologyImport());
+               fw.writer.println("      Resource res = graph.newResource();");
+               fw.writer.println("      graph.claim(res, L0.InstanceOf, "+ontShort+name+");");
+               fw.writer.println("      return res;");
+               fw.writer.println("   }");
+               fw.writer.println();
+               
+               fw.writer.println("   @Override");
+               fw.writer.println("   public boolean connectParent(WriteGraph graph, ParserElement parent, ParserElement element) throws DatabaseException{");
+               fw.writer.println("      "+getOntologyImport());
+               fw.writer.println("      graph.claim(parent.getData(), "+this.ontShort+getName(complexTypeObj,"has")+", element.getData());");
+               fw.writer.println("      return true;");
+               fw.writer.println("   }");
+               fw.writer.println();
+                               
+               StringWriter stringWriter = new StringWriter();
+               fw.delayedWriter = new PrintWriter(stringWriter);
+               StringWriter stringWriter2 = new StringWriter();
+               fw.delayedWriter2 = new PrintWriter(stringWriter2);
+               
+               fw.writer.println("   public " + className + "() {");
+               fw.writer.println("      super();");
+               
+               this.base.handleComplexTypeExtension(complexTypeObj);
+               
+               fw.writer.println("   }");
+               
+               fw.writer.println("   @Override");
+               fw.writer.println("   public boolean connectChild(WriteGraph graph, ParserElement element, ParserElement child) throws DatabaseException{");
+               fw.writer.println("      "+getOntologyImport());
+               
+               if (stringWriter.getBuffer().length() > 0) {
+                       fw.writer.write(stringWriter.toString());
+               }
+               if (inheritance.type == InheritanceType.ComplexType) {
+               fw.writer.println("      return super.connectChild(graph,element,child);");
+               }else{
+               fw.writer.println("      return false;");
+               }
+               fw.writer.println("   }");
+               fw.writer.println();
+               
+               if (stringWriter2.getBuffer().length() > 0) {
+                       fw.writer.write(stringWriter2.toString());
+               }
+               
+               stringWriter = null;
+               fw.delayedWriter.close();
+               fw.delayedWriter=null;
+               stringWriter2 = null;
+               fw.delayedWriter2.close();
+               fw.delayedWriter2 = null;
+               
+               fw.writer.println("   @Override");
+               fw.writer.println("   public void configure(WriteGraph graph, Deque<ParserElement> parents, ParserElement element) throws DatabaseException {");
+               if (inheritance.type == InheritanceType.ComplexType) {
+               fw.writer.println("             super.configure(graph,parents,element);");
+               }
+               fw.writer.println("        "+getOntologyImport());
+               
+               this.base.handleComplexTypeAttributes(complexTypeObj);
+               this.base.handleExtensionAttributes(complexTypeObj);
+               
+               fw.writer.println("   }");
+               
+               if (inheritance.type == InheritanceType.AtomicType) {
+               fw.writer.println();
+               fw.writer.println("   @Override");
+               fw.writer.println("   public void configure(WriteGraph graph, ParserElement element, java.lang.String string) throws DatabaseException {");
+               fw.writer.println("      graph.claimValue(element.getData(), "+getValueGetter(inheritance.atomicType,"string")+", "+inheritance.atomicType.binding+");");
+               fw.writer.println("   }");
+               }
+               
+               writeIDReferences(fw.writer,name, references);
+               writeUnknownChild(fw.writer,name,unknownChildElement);
+               
+               fw.writer.println("}");
+               fw.writer.println();
+               fw.writer.flush();
+               fw.writer.close();
+               fw.writer = null;
+               writers.remove(complexTypeObj);
+               provider = null;
+       }
+       
+       @Override
+       public void createReferenceIndicator(SchemaObject parent, RefType referenceType, String refName, String objectName, String primaryClassName, String secondaryClassName, boolean useElementList, boolean useOriginalList) {
+               FileWriter fw = getWriter(parent);
+               if (referenceType == RefType.Type) {
+               // create internal class for handling the element and child attachment
+               secondaryClassName = getName(parent) +"_" +objectName;
+               fw.writer.println("        addParser(\""+ objectName +"\", "+secondaryClassName+".class);");
+               fw.delayedWriter2.println("   public static class " + secondaryClassName +" extends " + primaryClassName +"{");
+               fw.delayedWriter2.println("      public "+ secondaryClassName +"(){");
+               fw.delayedWriter2.println("      }");
+               fw.delayedWriter2.println("   }");
+               } else { // referenceType == RefType.Reference
+               fw.writer.println("        addParser("+primaryClassName+".class);");
+               if (!primaryClassName.equals(secondaryClassName))
+               fw.writer.println("        addParser("+secondaryClassName+".class);");
+               }
+               
+               fw.delayedWriter.println("         if (child.getElementParser() instanceof "+secondaryClassName+"){");
+               fw.delayedWriter.println("            graph.claim(element.getData(), "+ontShort+getName(parent)+"_has"+refName + ", child.getData());");
+               if (useElementList) {
+
+               // element type specific list
+               fw.delayedWriter.println("            {");
+               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List);");
+               fw.delayedWriter.println("               if (list == null) {");
+               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List,list);");
+               fw.delayedWriter.println("               } else {");
+               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("               }");
+               fw.delayedWriter.println("            }");
+               }
+               if (useOriginalList) {
+               // generic list
+               fw.delayedWriter.println("            {");
+               fw.delayedWriter.println("               XMLResource XML = XMLResource.getInstance(graph);");
+               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(), XML.hasOriginalElementList);");
+               fw.delayedWriter.println("               if (list == null) {");
+               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("                  graph.claim(element.getData(), XML.hasOriginalElementList,list);");
+               fw.delayedWriter.println("               } else {");
+               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("               }");
+               fw.delayedWriter.println("            }");
+               }
+               
+               fw.delayedWriter.println("            return true;");
+               fw.delayedWriter.println("         }");
+       }
+       
+       @Override
+       protected void createPrimitiveIndicator(SchemaObject parent, String refName, String binding) {
+               FileWriter fw = getWriter(parent);
+               fw.writer.println("        addParser(\""+ refName +"\", "+getName(parent) +"_" +refName+".class);");
+               
+               fw.delayedWriter2.println("   public static class " + getName(parent) +"_" +refName+" extends org.simantics.xml.sax.base.ValueElementParser {");
+               fw.delayedWriter2.println("      public "+ getName(parent) +"_" +refName +"(){");
+               fw.delayedWriter2.println("           super(\""+refName+"\"," +this.ontologyClassName+".URIs."+getName(parent) + "_has"+refName+", "+binding+");");
+               fw.delayedWriter2.println("       }");
+               fw.delayedWriter2.println("   }");
+       }
+       
+       @Override
+       protected void createElementIndicator(SchemaObject parent, boolean useElementList, String refName, String className, boolean useOriginalList) {
+               FileWriter fw = getWriter(parent);
+               //if (!reference)
+               fw.writer.println("        addParser(\""+ refName +"\", "+className+".class);");
+//             else
+//             fw.writer.println("        addParser("+className+".class);");
+               
+               fw.delayedWriter.println("         if (child.getElementParser() instanceof "+className+"){");
+               fw.delayedWriter.println("            graph.claim(element.getData(), "+ontShort+getName(parent)+"_has"+refName + ", child.getData());");
+               if (useElementList) {
+
+               // element type specific list
+               fw.delayedWriter.println("            {");
+               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List);");
+               fw.delayedWriter.println("               if (list == null) {");
+               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("                  graph.claim(element.getData(),"+ontShort+getName(parent)+"_has"+refName + "List,list);");
+               fw.delayedWriter.println("               } else {");
+               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("               }");
+               fw.delayedWriter.println("            }");
+               }
+               if (useOriginalList) {
+               // generic list
+               fw.delayedWriter.println("            {");
+               fw.delayedWriter.println("               XMLResource XML = XMLResource.getInstance(graph);");
+               fw.delayedWriter.println("               Resource list = graph.getPossibleObject(element.getData(), XML.hasOriginalElementList);");
+               fw.delayedWriter.println("               if (list == null) {");
+               fw.delayedWriter.println("                  list = org.simantics.db.common.utils.ListUtils.create(graph, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("                  graph.claim(element.getData(), XML.hasOriginalElementList,list);");
+               fw.delayedWriter.println("               } else {");
+               fw.delayedWriter.println("                  org.simantics.db.common.utils.ListUtils.insertBack(graph, list, java.util.Collections.singletonList(child.getData()));");
+               fw.delayedWriter.println("               }");
+               fw.delayedWriter.println("            }");
+               }
+               
+               fw.delayedWriter.println("            return true;");
+               fw.delayedWriter.println("         }");
+       }
+       
+       @Override
+       public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {          
+               // generates overriding method that allows parsing any element
+               FileWriter fw = getWriter(parent);
+               fw.delayedWriter2.println("   @Override");
+               fw.delayedWriter2.println("   public Class<? extends org.simantics.xml.sax.base.XMLElementParser> getParser(java.util.Map<java.lang.String,org.simantics.xml.sax.base.XMLElementParser> parsers, ParserElement element, ParserElement child) {");
+               fw.delayedWriter2.println("      Class<? extends org.simantics.xml.sax.base.XMLElementParser> parserClass = super.getParser(parsers, element, child);");
+               fw.delayedWriter2.println("      if (parserClass != null) return parserClass;");
+               fw.delayedWriter2.println("      org.simantics.xml.sax.base.XMLElementParser parser = parsers.get(child.getQName());");
+               fw.delayedWriter2.println("      if (parser != null) return parser.getClass();");
+               fw.delayedWriter2.println("      return null;");
+               fw.delayedWriter2.println("   }");
+       }
+
+       @Override       
+       public void handle(SchemaObject parent, Attribute attribute) {
+               if (parent == null)
+                       return;
+               String name = attribute.getName();
+               QName primitiveType = attribute.getType();
+               SimpleType simpleType = attribute.getSimpleType();
+               QName ref = attribute.getRef();
+               
+               String relationName;
+               String attrName;
+               if (name != null) {
+                       attrName = name;
+                       relationName = ontShort+"has"+name;
+                       if (parent != null)
+                               relationName = ontShort+getName(parent)+"_has"+name;
+               }
+               else if (ref != null && parent != null) {
+                       attrName = ref.getLocalPart();
+                       relationName = ontShort+getName(parent)+"_has"+ref.getLocalPart();
+                       
+                       Attribute referred = this.base.getRefAttribute(ref);
+                       if (referred != null) {
+                               primitiveType = referred.getType();
+                               simpleType = referred.getSimpleType();
+                       }
+                       
+               } else {
+                       throw new RuntimeException();
+               }
+               boolean isReference = false;
+               if (provider!= null && provider.getAttribute().getName().equals(attrName))
+                       isReference = true;
+               
+               FileWriter fw = getWriter(parent);
+               if (primitiveType != null) {
+                       
+                       //String binding = getBindingFromPrimitiveType(primitiveType);
+                       TypeEntry binding = this.base.getTypeEntry(primitiveType);
+                       
+                       if (binding != null) {
+                               writeAttribute(fw, attrName, relationName, binding, isReference);
+                               return;
+                   } else {
+                       if (simpleType == null) {
+                               SchemaObject simpleTypeObj = this.base.getSimpleType(primitiveType);//this.base.simpleTypeName.get(primitiveType.getLocalPart());
+                               if (simpleTypeObj != null)
+                                       simpleType = simpleTypeObj.getSimpleType();
+                       }       
+                   }
+               } 
+               if (simpleType != null) {
+                       org.w3._2001.xmlschema.List list = simpleType.getList();
+                       if (list != null) {
+                               TypeEntry binding = this.base.getTypeEntry(new QName(SchemaConversionBase.SCHEMA_NS, "string"));
+                               writeAttribute(fw, attrName, relationName, binding, isReference);
+                       } else {
+//                             Restriction restriction = simpleType.getRestriction();
+//                             if (restriction == null)
+//                                     throw new RuntimeException("Cannot resolve type for Attribute " + attrName + " -> " + primitiveType.getLocalPart()+ ", SimpleType restriction is unset");
+//                             QName base = restriction.getBase();
+                               QName base = this.base.getSimpleTypeBase(simpleType);
+                               
+                               
+                               //String binding = getBindingFromPrimitiveType(base);
+                               TypeEntry binding = this.base.getTypeEntry(base);
+                               writeAttribute(fw, attrName, relationName, binding, isReference);
+                       }
+               } else {
+                       // TODO : using default String attribute should be configured with rules.
+                       //throw new RuntimeException("Cannot resolve type for Attribute " + attrName + " -> " + primitiveType.getLocalPart());
+                       fw.writer.println("    //FIXME: Cannot resolve type for Attribute " + attrName + " Using default type String");
+                       //writeAttribute(fw, attrName, relationName, "STRING", isReference);
+                       writeAttribute(fw, attrName, relationName, this.base.getTypeEntry("string"), isReference);
+               }
+       }
+       
+       private void writeAttribute(FileWriter fw, String attrName, String relationName, TypeEntry binding, boolean isReference) {
+               fw.writer.println("      {");
+               fw.writer.println("         Attribute a = element.getAttribute(\"" +attrName+"\");");
+               fw.writer.println("         if (a != null) {");
+               fw.writer.println("            graph.claimLiteral(element.getData(),"+relationName+","+getValueGetterMethod(binding,"a")+", "+binding.binding+");");
+               if (isReference)
+               fw.writer.println("            idProviderValue = a.getValue();");       
+               fw.writer.println("         }");
+               fw.writer.println("      }");
+       }
+       
+       @Override
+       public void handleAttributes(SchemaObject simpleTypeObj) {
+               SchemaObject parent = simpleTypeObj.getParent();
+               FileWriter fw = getWriter(parent);
+               
+               SimpleType simpleType = simpleTypeObj.getSimpleType();
+               Restriction restriction = simpleType.getRestriction();
+               if (restriction == null)
+                       throw new RuntimeException("Cannot resolve type for Element " + getName(parent));
+               QName base = restriction.getBase();
+               
+               
+               //String binding = getBindingFromPrimitiveType(base);
+               TypeEntry binding = this.base.getTypeEntry(base);
+               fw.writer.println("   @Override");
+               fw.writer.println("   public void configure(WriteGraph graph, ParserElement element, java.lang.String value) throws DatabaseException {");
+               //fw.writer.println("      graph.claimValue(element.getData(),"+getValueGetter(binding)+", Bindings."+binding+");");
+               fw.writer.println("      graph.claimValue(element.getData(),"+getValueGetter(binding)+", "+binding.binding +");");
+               fw.writer.println("   }");
+               
+       }
+       
+       @Override
+       public void handle(SchemaObject parent, AttributeGroup attribute) {
+               if (parent != null) {
+                       FileWriter fw = getWriter(parent);
+                       NamedAttributeGroup group = this.base.getAttributeGroup(attribute.getRef());
+                       fw.writer.println(commentTag+"    AttributeGroup " + group.getName());
+                       SchemaObject obj = new SchemaObject(parent,attribute);
+                       for (Annotated annotated : group.getAttributeOrAttributeGroup()) {
+                               if (annotated instanceof Attribute) {
+                                       //handle("AttributeGroups_"+group.getName(),(Attribute)annotated);
+                                       handle(obj,(Attribute)annotated);
+                               } else if (annotated instanceof AttributeGroup) {
+                                       //handle("AttributeGroups_"+group.getName(),(AttributeGroup)annotated);
+                                       handle(obj,(AttributeGroup)annotated);
+                               }
+                       }
+                       //dd
+                       if(true)
+                               System.out.println();
+                       fw.writer.println(commentTag+"    End of AttributeGroup " + group.getName());
+               }
+               
+       }
+       
+       @Override
+       public void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
+               FileWriter fw = getWriter(parent);
+               QName type = new QName(SchemaConversionBase.CONVERSION_NS, composition.getType());
+               String arrayBinding = this.base.getBindingFromPrimitiveType(type);
+               String javaType = this.base.getJavaTypeFromPrimitiveType(type);
+               String name = composition.getName();
+               
+               String relationName;
+               if (name != null) {
+                       relationName = ontShort+"has"+name;
+                       if (parent != null)
+                               relationName = ontShort+getName(parent)+"_has"+name;
+               } else {
+                       throw new RuntimeException();
+               }
+               
+               fw.writer.println("      {");
+               int i = 0;
+               for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute())
+               fw.writer.println("         Attribute a"+(i++)+" = element.getAttribute(\"" +a.getName()+"\");");
+               fw.writer.print  ("         "+javaType + " value = new "+javaType+"{");
+               i = 0;
+               // FIXME : handle optional attributes properly.
+               for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {
+                       Attribute attribute = ((Attribute)attributes.getRight(a));
+                       //QName atype = getBaseType(attribute);
+                       QName atype = this.base.getPrimitiveType(attribute);
+                       String defaultValue = attribute.getDefault();
+                       if (defaultValue == null)
+                           defaultValue = this.base.getDefaultValue(atype);
+                               
+                       //String binding = getBindingFromPrimitiveType(atype);
+                       TypeEntry binding = this.base.getTypeEntry(atype);
+                       if (i > 0)
+                               fw.writer.print(",");
+                       if (defaultValue != null)
+                               fw.writer.print("a"+(i)+"!= null ? "+ getValueGetterMethod(binding,"a"+(i++)) + " : " +defaultValue);
+                       else
+                               fw.writer.print(getValueGetterMethod(binding,"a"+(i++)));
+               }
+               fw.writer.println("};");
+               fw.writer.println("         graph.claimLiteral(element.getData(),"+relationName+", value, "+arrayBinding+");");
+               fw.writer.println("      }");
+               
+       }
+       
+       
+       
+       
+       
+
+       
+       IDProvider provider;
+       @Override
+       public void handleElement(SchemaObject elementObj)  {
+               Element element = elementObj.getElement();
+               
+               String name = getName(elementObj);//topLevelElement.getName();
+               String className = name;
+               
+               FileWriter fw = new FileWriter();
+               try {
+                       fw.writer = createFile(new File(importParserDir.getAbsolutePath()+"/"+className+".java"));
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+               writers.put(elementObj, fw);
+               boolean isList = false;
+               
+               Inheritance inheritance = this.base.getInheritance(elementObj); 
+               
+               provider = this.base.getIDProvider(element);
+               List<IDReference> references = this.base.getIDReferences(element);
+               UnrecognizedChildElement unknownChildElement = this.base.getUnknown(element);
+
+               List<String> intrerfaces = new ArrayList<String>();
+               if (references.size() > 0)
+                       intrerfaces.add("org.simantics.xml.sax.base.IDReferenceParser");
+               if (unknownChildElement != null)
+                       intrerfaces.add("org.simantics.xml.sax.base.UnrecognizedElementParser");
+
+               createClassHeader(fw.writer, isList);
+               writeClass(fw.writer,false, element.getName(), className, inheritance.baseClass, intrerfaces);
+               writeIDProvider(fw.writer);
+               fw.writer.println("   @Override");
+               fw.writer.println("   public Resource create(WriteGraph graph, ParserElement element) throws DatabaseException{");
+               fw.writer.println("      Layer0 L0 = Layer0.getInstance(graph);");
+               fw.writer.println("      "+getOntologyImport());
+               if (!isList) {
+               fw.writer.println("      Resource res = graph.newResource();");
+               fw.writer.println("      graph.claim(res, L0.InstanceOf, "+ontShort+name+");");
+               } else {
+               fw.writer.println("      Resource res = ListUtils.create(graph, "+ontShort+name+", Collections.EMPTY_LIST);");
+               }
+               fw.writer.println("      return res;");
+               fw.writer.println("   }");
+               fw.writer.println();
+               
+               fw.writer.println("   @Override");
+               fw.writer.println("   public boolean connectParent(WriteGraph graph, ParserElement parent, ParserElement element) throws DatabaseException{");
+               fw.writer.println("      "+getOntologyImport());
+               fw.writer.println("      graph.claim(parent.getData(), "+this.ontShort+getName(elementObj,"has")+", element.getData());");
+               fw.writer.println("      return true;");
+               fw.writer.println("   }");
+               fw.writer.println();
+               
+               fw.writer.println("   @Override");
+               fw.writer.println("   public void configure(WriteGraph graph, Deque<ParserElement> parents, ParserElement element) throws DatabaseException {");
+               if (inheritance.type == InheritanceType.ComplexType) {
+               fw.writer.println("             super.configure(graph,parents,element);");
+               }
+               fw.writer.println("        "+getOntologyImport());
+               
+               LocalComplexType complexType = element.getComplexType();
+               LocalSimpleType simpleType = element.getSimpleType();
+               
+               if (complexType != null) {
+                       SchemaObject obj = this.base.getComplexType(complexType);
+                       this.base.handleElementComplexTypeAttributes(obj);
+               } 
+               fw.writer.println("   }");
+               
+               if (inheritance.type == InheritanceType.AtomicType) {
+               fw.writer.println();
+               fw.writer.println("   @Override");
+               fw.writer.println("   public void configure(WriteGraph graph, ParserElement element, java.lang.String string) throws DatabaseException {");
+               fw.writer.println("      graph.claimValue(element.getData(), "+getValueGetter(inheritance.atomicType,"string")+", "+inheritance.atomicType.binding+");");
+               fw.writer.println("   }");
+               }
+//             if (simpleType != null) {
+//                     SchemaObject obj = simpleTypes.get(simpleType);
+//                     handleElementSimpleTypeAttributes(obj);
+//             }
+               
+               
+               StringWriter stringWriter = new StringWriter();
+               fw.delayedWriter = new PrintWriter(stringWriter);
+               StringWriter stringWriter2 = new StringWriter();
+               fw.delayedWriter2 = new PrintWriter(stringWriter2);
+               
+               fw.writer.println("   public " + className + "() {");
+               fw.writer.println("      super();");
+               
+               if (complexType != null) {
+                       SchemaObject obj = this.base.getComplexType(complexType);
+                       this.base.handleComplexTypeExtension(obj);
+               } else if (simpleType != null) {
+                       
+               }
+               
+               fw.writer.println("   }");
+               
+               fw.writer.println("   @Override");
+               fw.writer.println("   public boolean connectChild(WriteGraph graph, ParserElement element, ParserElement child) throws DatabaseException{");
+               fw.writer.println("      "+getOntologyImport());
+               
+               if (stringWriter.getBuffer().length() > 0) {
+                       fw.writer.write(stringWriter.toString());
+               }
+               if (inheritance.type == InheritanceType.ComplexType) {
+               fw.writer.println("      return super.connectChild(graph,element,child);");     
+               } else {
+               fw.writer.println("      return false;");
+               }
+               fw.writer.println("   }");
+               fw.writer.println();
+               
+               if (stringWriter2.getBuffer().length() > 0) {
+                       fw.writer.write(stringWriter2.toString());
+               }
+               
+               stringWriter = null;
+               fw.delayedWriter.close();
+               fw.delayedWriter = null;
+               stringWriter2 = null;
+               fw.delayedWriter2.close();
+               fw.delayedWriter2 = null;
+               
+               writeIDReferences(fw.writer,name, references);
+               writeUnknownChild(fw.writer,name,unknownChildElement);
+
+               fw.writer.println("}");
+               fw.writer.println();
+               fw.writer.flush();
+               fw.writer.close();
+               fw.writer = null;
+               writers.remove(elementObj);
+               provider = null;
+               
+               ruleClassNames.add(converter.getPluginName()+"."+elementPackageName+"."+name);
+       }
+
+       
+       private void writeIDProvider(PrintWriter writer) {
+               if (provider != null) {
+               writer.println("   java.lang.String idProviderValue = null;");
+               writer.println();
+               writer.println("   @Override");
+               writer.println("   public java.lang.String getID() {");
+               writer.println("        java.lang.String s = idProviderValue;");
+               writer.println("        idProviderValue = null;");
+               writer.println("        return s;");
+               writer.println("   }");
+               writer.println();
+               if (provider.getPriority() != null) {
+               writer.println("   @Override");
+               writer.println("   public int idPriority() {");
+               writer.println("        return " + provider.getPriority().intValue()+";");
+               writer.println("   }"); 
+               }
+               }
+       }
+       
+       private void writeIDReferences(PrintWriter writer,String name, List<IDReference> references) {
+               if (references.size() > 0) {
+               writer.println("   @Override");
+               writer.println("   public boolean connectReferences(WriteGraph graph, ParserElement element, java.util.Map<java.lang.String, ParserElement> map) throws DatabaseException {");
+               writer.println("      "+getOntologyImport());
+               writer.println("      boolean result = true;");
+               for (IDReference ref : references) {
+               writer.println("      {");
+               writer.println("         Attribute a = element.getAttribute(\"" + ref.getIDSource().getName() +"\");");
+               writer.println("         if (a != null) {");
+               writer.println("            ParserElement refEle = map.get(a.value);");
+               writer.println("            if (refEle != null) {");
+               writer.println("               Resource ref = refEle.getData();");
+               writer.println("               graph.claim(element.getData(), "+ontShort+name+"_"+ref.getReference().getName()+", ref);");
+               writer.println("            } else {");
+               writer.println("               result = false;");
+               writer.println("            }");
+               writer.println("         }");
+               writer.println("      }");
+               }
+               writer.println("      return result;");
+               writer.println("   }");
+               writer.println();
+               }
+       }
+       
+       private void writeUnknownChild(PrintWriter writer,String name, UnrecognizedChildElement unknownChildElement) {
+               if (unknownChildElement == null)
+                       return;
+               
+               writer.println("   @Override");
+               writer.println("   public void configureChild(WriteGraph graph, Deque<ParserElement> parents, ParserElement element, ParserElement child) throws DatabaseException {");
+               writer.println("    " + unknownChildElement.getJavaMethod());
+               writer.println("   }");
+               writer.println();
+               
+       }
+       
+       @Override
+       public String getBaseClass(ObjectType type) {
+               return "org.simantics.xml.sax.base.XMLElementNamedChildParserBase";
+       }
+       
+       protected void createClassHeader(PrintWriter writer, boolean isList) {
+               writer.println("package " + converter.getPluginName() +"."+elementPackageName+";");
+               writer.println();
+               writer.println("import java.util.Deque;");
+               writer.println("import org.simantics.databoard.Bindings;");
+               writer.println("import org.simantics.db.Resource;");
+               writer.println("import org.simantics.db.WriteGraph;");
+               writer.println("import org.simantics.db.exception.DatabaseException;");
+               writer.println("import org.simantics.xml.sax.base.Attribute;");
+               writer.println("import org.simantics.xml.sax.base.ParserElement;");
+               writer.println("import org.simantics.xml.sax.ontology.XMLResource;");
+               if (!isList) {
+               writer.println("import org.simantics.layer0.Layer0;");
+           } else {
+           writer.println("import java.util.Collections;");
+               writer.println("import org.simantics.db.common.utils.ListUtils;");
+               }
+               writer.println();
+       }
+       
+}
index 2de5908f48374a85667f66ba1443f5465b56cd6e..6e4355876ff4c7f58e5a38162fdec8db4e3dac78 100644 (file)
-package org.simantics.xml.sax;\r
-\r
-import java.io.FileNotFoundException;\r
-import java.io.PrintWriter;\r
-import java.io.StringWriter;\r
-import java.util.ArrayList;\r
-import java.util.LinkedHashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import javax.xml.namespace.QName;\r
-\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-import org.simantics.xml.sax.SchemaConversionBase.Inheritance;\r
-import org.simantics.xml.sax.SchemaConversionBase.InheritanceType;\r
-import org.simantics.xml.sax.SchemaConversionBase.RefType;\r
-import org.simantics.xml.sax.SchemaObject.ObjectType;\r
-import org.simantics.xml.sax.configuration.AttributeComposition;\r
-import org.simantics.xml.sax.configuration.IDReference;\r
-import org.w3._2001.xmlschema.Annotated;\r
-import org.w3._2001.xmlschema.Attribute;\r
-import org.w3._2001.xmlschema.AttributeGroup;\r
-import org.w3._2001.xmlschema.Element;\r
-import org.w3._2001.xmlschema.LocalComplexType;\r
-import org.w3._2001.xmlschema.LocalSimpleType;\r
-import org.w3._2001.xmlschema.NamedAttributeGroup;\r
-import org.w3._2001.xmlschema.NamedGroup;\r
-import org.w3._2001.xmlschema.Restriction;\r
-import org.w3._2001.xmlschema.Schema;\r
-import org.w3._2001.xmlschema.SimpleType;\r
-\r
-//public class OntologyGenerator extends SchemaConversionBase {\r
-public class OntologyGenerator implements SchemaConversionComponent {\r
-       SchemaConversionBase base;\r
-       \r
-       public OntologyGenerator(SchemaConverter converter, SchemaConversionBase base) {\r
-               this.base = base;\r
-               this.converter = converter;\r
-               this.schema = base.schema;\r
-               this.ontologyUri = base.ontologyURI;\r
-               this.className = base.className;                \r
-       }\r
-\r
-       String ontRoot = "ONT.";\r
-       String commentTag = "//";\r
-       \r
-       Schema schema;\r
-       String ontologyUri;\r
-       String className;\r
-       \r
-       SchemaConverter converter;\r
-       \r
-       PrintWriter writer = null;\r
-       \r
-       public void createOntology() throws FileNotFoundException {\r
-               StringWriter stringWriter = null;\r
-               if (converter.getOntologyFile() == null) {\r
-                       stringWriter = new StringWriter();\r
-                       writer = new PrintWriter(stringWriter);\r
-               } else {\r
-                       writer = new PrintWriter(converter.getOntologyFile());\r
-               }\r
-       \r
-               handle();\r
-               \r
-               writer.flush();\r
-               writer.close();\r
-               if (stringWriter != null)\r
-                       System.out.println(stringWriter.toString());\r
-       }\r
-       \r
-       protected void handle() {\r
-               ontRoot = converter.shortName;\r
-\r
-               for (String s : converter.getHeader()) {\r
-                       writer.println(commentTag + " " + s);   \r
-               }\r
-               writer.println();\r
-               writer.println("L0 = <http://www.simantics.org/Layer0-1.1>");\r
-               writer.println("XML = <http://www.simantics.org/XML-1.0>");\r
-               writer.println();\r
-               writer.println(ontRoot + " = <" + ontologyUri +"> : L0.Ontology");\r
-               writer.println("   @L0.new");\r
-               writer.println("   L0.HasResourceClass \"" + className +"\"");\r
-               writer.println();\r
-               writer.println();\r
-               \r
-               ontRoot += ".";\r
-               writer.println(ontRoot+"ComplexTypes : L0.Library");\r
-               writer.println(ontRoot+"AttributeGroups : L0.Library");\r
-               writer.println();\r
-               writer.println(commentTag + " Interpreted from schema");\r
-               writer.println();\r
-                       \r
-               base.handle(this);\r
-       }\r
-               \r
-       protected String getType(QName qtype) {\r
-               String ontType = base.getL0TypeFromPrimitiveType(qtype);\r
-               if (ontType != null)\r
-                       return ontType;\r
-               else if (base.isComplexTypeRef(qtype.getLocalPart()))\r
-                       return ontRoot+getComplexTypePrefix()+qtype.getLocalPart();\r
-               else if (base.isSimpleTypeRef(qtype.getLocalPart()))\r
-                       return ontRoot+qtype.getLocalPart();\r
-               else if (base.isElementRef(qtype.getLocalPart()))\r
-                       return ontRoot+qtype.getLocalPart();\r
-               else if (qtype.getPrefix() != null && qtype.getPrefix().length() > 0) {\r
-                       return ontRoot+qtype.getPrefix()+qtype.getLocalPart();\r
-               }\r
-               throw new RuntimeException("Reference to unknown type " + qtype.getLocalPart());\r
-       }\r
-       \r
-       public String getComplexTypePrefix() {\r
-               return "ComplexTypes.";\r
-       }\r
-       \r
-       public String getAttributeGroupPrefix() {\r
-               return "AttributeGroups.";\r
-       }\r
-       \r
-       public void handleChoice(SchemaObject parent, SchemaElement indicator, java.util.List<SchemaElement> elements, String name) {\r
-               boolean single = true;\r
-               for (SchemaElement e : elements) {\r
-                       if (e.getRestriction().many()) {\r
-                               single = false;\r
-                               break;\r
-                       }\r
-               }\r
-               String relationName = getName(parent)+".has"+name;\r
-               writer.print(relationName);\r
-               \r
-               List<String> types = new ArrayList<String>();\r
-               for (SchemaElement e : elements) {\r
-                       Element localElement = e.getElement();\r
-                       QName refType = null;\r
-                       String type = null;\r
-                       \r
-                       if (localElement.getName() != null) {\r
-                               refType = localElement.getType();\r
-                               type = base.getL0TypeFromPrimitiveType(refType);        \r
-                       } else if (localElement.getRef() != null) {\r
-                               refType = localElement.getRef();\r
-                               type = base.getL0TypeFromPrimitiveType(refType);\r
-                       }\r
-                       if (type == null) {\r
-                               SchemaObject obj = base.getWithName(refType);\r
-                               types.add(getName(obj,"has"));\r
-                       } \r
-               }\r
-               if (types.size() > 0) {\r
-                       for (String type : types) {\r
-                               writer.print(" <R " + type);\r
-                       }\r
-               } else {\r
-                       writer.print(" <R XML.hasElement");\r
-               }\r
-               \r
-               writer.println();\r
-               \r
-               for (SchemaElement e : elements) {\r
-                       Element localElement = e.getElement();\r
-                       QName refType = null;\r
-                       String type = null;\r
-                       if (localElement.getName() != null) {\r
-                               refType = localElement.getType();\r
-                               type = getType(refType);        \r
-                       } else if (localElement.getRef() != null) {\r
-                               refType = localElement.getRef();\r
-                               type = getType(refType);\r
-                       }\r
-                       if (type != null) {\r
-                               writer.println("   --> " + type);\r
-                       }\r
-               }\r
-               if (!single) {\r
-                       writer.println(ontRoot+name+ "List <T XML.ElementList");\r
-                       if (types.size() == 0) {\r
-                       writer.println(relationName+ "List <R XML.hasElementList : L0.FunctionalRelation");\r
-                       } else {\r
-                               writer.print(relationName+ "List");\r
-                               for (String type : types) {\r
-                                       writer.print(" <R " + type+"List");\r
-                               }\r
-                               writer.println(" : L0.FunctionalRelation");\r
-                       }\r
-                       writer.println("   --> " + ontRoot+name+"List");\r
-               }\r
-       };\r
-       \r
-       \r
-       \r
-       @Override\r
-       public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType) {\r
-               if (refType != refType.Element) {\r
-                       QName referenceType = null;\r
-                       if (refType == RefType.Type) {\r
-                               referenceType = element.getElement().getType();\r
-                               //refName = element.getElement().getName()\r
-                               SchemaObject eObj = base.getElement(element.getElement());//base.elements.get(element.getElement());\r
-                               if (refName == null)\r
-                                       refName = eObj.getName();\r
-                       } else {\r
-                               referenceType = element.getElement().getRef();\r
-                               if (refName == null)\r
-                                       refName = referenceType.getLocalPart();\r
-                       }\r
-                       String type = base.getL0TypeFromPrimitiveType(referenceType);\r
-                       SchemaObject obj = null;\r
-                       if (type == null) {\r
-                               obj = base.getWithName(referenceType);\r
-                               \r
-                               writer.println(getName(parent)+".has"+refName + " <R " +  getName(obj,"has"));\r
-                               writer.println("   --> " + getName(obj));\r
-                       } else {\r
-                               writer.println(getName(parent)+".has"+refName + " <R XML.hasElement");\r
-                               writer.println("   --> " + getType(referenceType));\r
-                       }\r
-                       \r
-                       if (base.useElementList(parent, indicator,element, refType == RefType.Reference, refName, referenceType)) {\r
-                               \r
-                               if (type == null) {\r
-                                       writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");\r
-                                       writer.println(getName(parent)+".has"+refName + "List <R " +  getName(obj,"has")+"List : L0.FunctionalRelation");\r
-                               } else {\r
-                                       writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");\r
-                                       writer.println(getName(parent)+".has"+refName + "List <R XML.hasElementList : L0.FunctionalRelation");  \r
-                               }\r
-                       }\r
-               } else {\r
-                       Element attrs = element.getElement();\r
-                       SchemaObject obj = base.getWithObj(parent, attrs);\r
-                       if (refName == null)\r
-                               refName = obj.getName();\r
-                       \r
-                       writer.println(getName(parent)+".has"+refName + " <R " + getName(obj,"has"));\r
-                       writer.println("   --> " + getName(obj));\r
-                       if (base.useElementList(parent, indicator,element, false, refName, new QName(obj.getName()))) {\r
-                               writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");\r
-                               writer.println(getName(parent)+".has"+refName + "List <R " +  getName(obj,"has")+"List : L0.FunctionalRelation");\r
-                       }\r
-               }\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void handle(SchemaObject parent, NamedGroup attribute) {\r
-               // TODO Auto-generated method stub\r
-               \r
-       }\r
-               \r
-       @Override\r
-       public void handle(SchemaObject parent, Attribute attribute) {\r
-               String name = attribute.getName();\r
-               QName primitiveType = attribute.getType();\r
-               LocalSimpleType simpleType = attribute.getSimpleType();\r
-               QName ref = attribute.getRef();\r
-               \r
-               String relationName;\r
-               String relationType;\r
-               if (name != null) {\r
-                       relationName = ontRoot+"has"+name;\r
-                       if (parent != null)\r
-                               relationName = getName(parent)+".has"+name;\r
-                       relationType = "XML.hasAttribute";\r
-               }\r
-               else if (ref != null && parent != null) {\r
-                       relationName = getName(parent)+".has"+ref.getLocalPart();\r
-                       relationType = ontRoot+"has"+ref.getLocalPart();\r
-               } else {\r
-                       throw new RuntimeException();\r
-               }\r
-               boolean id = false;\r
-               String ontType = null;\r
-               if (primitiveType != null) {\r
-                       ontType = base.getL0TypeFromPrimitiveType(primitiveType);\r
-                       if (ontType != null) {\r
-                               id = base.getTypeEntry(primitiveType).id;\r
-                               if (id)\r
-                                       relationType = "XML.hasID";\r
-                       } else {\r
-                               \r
-                       }\r
-               } else if (simpleType != null){\r
-                       Restriction restriction = simpleType.getRestriction();\r
-                       if (restriction == null || simpleType.getUnion() != null || simpleType.getName() != null || simpleType.getId() != null)\r
-                               throw new RuntimeException();\r
-                       QName base = restriction.getBase();\r
-                       \r
-                       \r
-                       ontType = this.base.getL0TypeFromPrimitiveType(base);\r
-                       \r
-//                     for (Object facetWrap : restriction.getFacets()) {\r
-//                             JAXBElement<?> element = (JAXBElement<?>)facetWrap;\r
-//                             QName elementName = element.getName();\r
-//                             Facet facet = (Facet)element.getValue();        \r
-//                     }\r
-               }\r
-                       \r
-               \r
-               \r
-               writer.println(relationName+ " <R " + relationType + ": L0.FunctionalRelation");\r
-               if (id) {\r
-                       // no need to add range restriction\r
-               } else if (ontType != null) {\r
-                       writer.println("   --> " + ontType);\r
-               } else if (primitiveType != null) {\r
-                       writer.println("   <R "+ontRoot+"has"+primitiveType.getLocalPart());\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void handleAttributes(SchemaObject simpleTypeObj) {\r
-//             SchemaObject parent = simpleTypeObj.getParent();\r
-//             SimpleType simpleType = simpleTypeObj.getSimpleType();\r
-//             Restriction restriction = simpleType.getRestriction();\r
-//             QName base = restriction.getBase();\r
-//             String ontType = getL0TypeFromPrimitiveType(base);\r
-       }\r
-       \r
-       @Override\r
-       public void handle(SchemaObject parent, AttributeGroup attributeGroup) {\r
-               if (parent == null) {\r
-                       NamedAttributeGroup group = (NamedAttributeGroup)attributeGroup;\r
-                       writer.println(ontRoot+getAttributeGroupPrefix()+group.getName()+ " <T XML.AttributeGroup");\r
-                       SchemaObject obj = new SchemaObject(parent,attributeGroup);\r
-                       for (Annotated annotated : group.getAttributeOrAttributeGroup()) {\r
-                               if (annotated instanceof Attribute) {\r
-                                       //handle(getAttributeGroupPrefix()+group.getName(),(Attribute)annotated);\r
-                                       handle(obj,(Attribute)annotated);\r
-                               } else if (annotated instanceof AttributeGroup) {\r
-                                       handle(obj,(AttributeGroup)annotated);\r
-                                       //throw new RuntimeException("Cannot handle nested attribute groups");\r
-                               }\r
-                       }\r
-               } else {\r
-                       writer.println(getName(parent) +" L0.Inherits " + ontRoot + getAttributeGroupPrefix() + attributeGroup.getRef().getLocalPart());\r
-               }\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {\r
-               Attribute compositionAttribute = new Attribute();\r
-               compositionAttribute.setName(composition.getName());\r
-               QName type = new QName(SchemaConversionBase.CONVERSION_NS, composition.getType());\r
-               compositionAttribute.setType(type);\r
-               handle(parent, compositionAttribute);\r
-       }\r
-       \r
-       @Override\r
-       public void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) {\r
-               SimpleType simpleType = simpleTypeObj.getSimpleType();\r
-               String name = simpleType.getName();\r
-               \r
-               org.w3._2001.xmlschema.List list = simpleType.getList();\r
-               if (list != null) {\r
-                       // TODO : process restriction in lists\r
-                       String relationName = ontRoot+"has"+name;\r
-                       if (parent != null)\r
-                               relationName = getName(parent)+".has"+name;\r
-                       writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");\r
-                       \r
-                       String ontType = base.getL0Type(new QName(SchemaConversionBase.SCHEMA_NS, "string"));\r
-                       writer.println("   --> " + ontType);\r
-               } else {\r
-                       String relationName = ontRoot+"has"+name;\r
-                       if (parent != null)\r
-                               relationName = getName(parent)+".has"+name;\r
-                       \r
-                       writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");\r
-                       \r
-                       QName base = this.base.getSimpleTypeBase(simpleType);\r
-                       Inheritance inheritance = new Inheritance("");\r
-                       this.base.getAtomicTypeInheritance(base, inheritance);\r
-                       if (inheritance.atomicType == null)\r
-                               throw new RuntimeException("Could not locate atomic type for SimpleType " + simpleType.getName());\r
-                       writer.println("   --> " + inheritance.atomicType.l0Type);\r
-                       \r
-//                     Restriction restriction = simpleType.getRestriction();\r
-//                     if (restriction != null) {\r
-//                             \r
-//                             QName base = restriction.getBase();\r
-//                             String ontType = getL0Type(base);\r
-//                             writer.println("   --> " + ontType);\r
-//                     } else if (simpleType.getId() != null) {\r
-//                             throw new RuntimeException(simpleType.getName() + " restriction error");\r
-//                     } else if (simpleType.getUnion() != null) {\r
-//                             Union union = simpleType.getUnion();\r
-//                             String ontType = null;\r
-//                             if (union.getMemberTypes().size() > 0) {\r
-//                                     for (QName type : union.getMemberTypes()) {\r
-//                                             String sType = null;\r
-//                                             TypeEntry entry = getTypeEntry(type);\r
-//                                             if (entry == null) {\r
-//                                                     SchemaObject obj = simpleTypeName.get(type.getLocalPart());\r
-//                                                     Inheritance inheritance = new Inheritance("");\r
-//                                                     getAtomicTypeInheritance(type, obj, inheritance);\r
-//                                                     sType = inheritance.atomicType.l0Type;\r
-//                                             } else {\r
-//                                                     sType = entry.l0Type;\r
-//                                             }\r
-//                                             if (ontType == null)\r
-//                                                     ontType = sType;\r
-//                                             else if (!ontType.equals(sType))\r
-//                                                     throw new RuntimeException(simpleType.getName() + " union has incompatible member types");\r
-//                                     }\r
-//                             } else {\r
-//                                     if (union.getSimpleType().size() == 0)\r
-//                                             throw new RuntimeException(simpleType.getName() + " union error");\r
-//                                     for (SimpleType s : union.getSimpleType()) {\r
-//                                             if (restriction == null)\r
-//                                                     restriction = s.getRestriction();\r
-//                                             else  {\r
-//                                                     Restriction r = s.getRestriction();\r
-//                                                     if (!r.getBase().equals(restriction.getBase()))\r
-//                                                             throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");\r
-//                                             }\r
-//                                     }\r
-//                                     QName base = restriction.getBase();\r
-//                                     ontType = getL0Type(base);\r
-//                             }\r
-//                             writer.println("   --> " + ontType);\r
-//                     } else {\r
-//                             throw new RuntimeException(simpleType.getName() + " restriction error");\r
-//                     }\r
-                       \r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void handleComplexType(SchemaObject topLevelComplexType) {\r
-               String name = getName(topLevelComplexType);\r
-//             if (topLevelComplexType.getName().equals("Reference"))\r
-//                     System.out.println();\r
-               \r
-               String relationName = getName(topLevelComplexType,"has");//ontRoot+"has"+name;\r
-               \r
-               writer.println(relationName+ " <R XML.hasComplexType");\r
-               writer.println(relationName+ "List <R XML.hasElementList");\r
-               //writer.println("   --> " + ontRoot+getComplexTypePrefix()+name);\r
-               writer.println("   --> " + name);\r
-               writer.println();\r
-//             String baseType = "XML.ComplexType";\r
-//\r
-//             QName base = getComplexTypeBase(topLevelComplexType.getComplexType());\r
-//             if (base != null) {\r
-//                     baseType = getType(base);\r
-//             }\r
-//             base = getSimpleTypeBase(topLevelComplexType.getSimpleType());\r
-//             if (base != null) {\r
-//                     baseType = getType(base);\r
-//             }\r
-               Inheritance inheritance = base.getInheritance(topLevelComplexType);\r
-               \r
-//             writer.println(name+ " <T "+baseType);\r
-               \r
-               if(inheritance.type == InheritanceType.AtomicType) {\r
-                       writer.println(name+ " <T "+inheritance.baseClass + " <T "+inheritance.atomicType.l0Type);\r
-               } else {\r
-                       writer.println(name+ " <T "+inheritance.baseClass);\r
-               }\r
-//             if (!baseType.equals(inheritance.baseClass))\r
-//                     System.out.println();\r
-               //super.handleComplexType(topLevelComplexType);\r
-               base.handleComplexTypeAttributes(topLevelComplexType);\r
-               base.handleComplexTypeExtension(topLevelComplexType);\r
-               base.handleExtensionAttributes(topLevelComplexType);\r
-               writer.println();\r
-       }\r
-       \r
-       @Override\r
-       public void handleElement(SchemaObject elementObj) {\r
-               Element element = elementObj.getElement();\r
-               String name = getName(elementObj);//element.getName();\r
-               \r
-               if ("Text".equals(name))\r
-                       System.out.println();\r
-               \r
-               String type = "XML.Element";\r
-               Set<String> types = new LinkedHashSet<String>();\r
-               if (element.getType() != null) {\r
-                       types.add(getType(element.getType()));\r
-               }\r
-               QName base = this.base.getElementBase(element);\r
-               if (base != null) {\r
-                       if (base.getNamespaceURI().equals(SchemaConversionBase.SCHEMA_NS)) {\r
-                               String l0Type = this.base.getL0Type(base);\r
-                               if (l0Type == null)\r
-                                       throw new RuntimeException("Cannot get L0 type for " + base.getLocalPart());\r
-                               types.add(l0Type);\r
-                       } else if (this.base.isElementRef(base.getLocalPart()))\r
-                               types.add(ontRoot+base.getLocalPart());\r
-                       else\r
-                               types.add(ontRoot+getComplexTypePrefix()+base.getLocalPart());\r
-               }\r
-               QName substitution = element.getSubstitutionGroup();\r
-               if (substitution != null) {\r
-                       if (this.base.isElementRef(substitution.getLocalPart()))\r
-                               types.add(ontRoot+substitution.getLocalPart());\r
-                       else\r
-                               types.add( ontRoot+getComplexTypePrefix()+substitution.getLocalPart());\r
-               }\r
-               for (String t : types) {\r
-                       type += " <T " + t;\r
-               }\r
-\r
-               String relationName =  getName(elementObj,"has");//ontRoot+"has"+name;\r
-//             if (elementObj.getParent() != null) {\r
-//                     //relationName = ontRoot+getComplexTypePrefix()+"has"+name.substring(getComplexTypePrefix().length());\r
-//                     relationName = ontRoot+getName(elementObj.getParent()) + "has"+element.getName();\r
-//             }\r
-               writer.println(relationName+ " <R XML.hasElement");\r
-               writer.println(relationName+ "List <R XML.hasElementList");\r
-               \r
-               writer.println(name+ " <T "+type);\r
-               \r
-               LocalComplexType complexType = element.getComplexType();\r
-               LocalSimpleType simpleType = element.getSimpleType();\r
-               \r
-               if (complexType != null) {\r
-                       SchemaObject complexTypeObj = this.base.getComplexType(complexType);\r
-                       this.base.handleElementComplexTypeAttributes(complexTypeObj);\r
-                       this.base.handleComplexTypeExtension(complexTypeObj);\r
-               } else if (simpleType != null) {\r
-                       SchemaObject simpleTypeObj = this.base.getSimpleType(simpleType);\r
-                       this.base.handleElementSimpleTypeAttributes(simpleTypeObj);\r
-               }\r
-               \r
-               List<IDReference> references = this.base.getIDReferences(element);\r
-       \r
-               for (IDReference ref : references) {\r
-                       writer.println(name+"."+ref.getReference().getName()+ " <R XML.hasReference");\r
-               }\r
-               \r
-               writer.println();\r
-       }\r
-       \r
-       @Override\r
-       public String getBaseClass(ObjectType type) {\r
-               if (type == ObjectType.ELEMENT)\r
-                       return "XML.Element";\r
-               if (type == ObjectType.COMPLEX_TYPE)\r
-                       return "XML.ComplexType";\r
-               throw new RuntimeException("ObjectType " + type + " has no base class");\r
-       }\r
-       \r
-       @Override\r
-       public String getName(SchemaObject obj) {\r
-               if (obj.getParent() == null) {\r
-                       switch (obj.getType()) {\r
-                       case COMPLEX_TYPE:\r
-                               return ontRoot+getComplexTypePrefix()+obj.getName();\r
-                       case ELEMENT:\r
-                               return ontRoot+obj.getName();\r
-                       case ATTRIBUTE_GROUP:\r
-                               return ontRoot+getAttributeGroupPrefix()+obj.getName();\r
-                       case SIMPLE_TYPE:\r
-                               return ontRoot+obj.getName();\r
-                       }\r
-               } else {\r
-                       SchemaObject o = obj;\r
-                       SchemaObject prev = null;\r
-                       String name = "";\r
-                       while (o != null){\r
-                               if (o.getName() != null)\r
-                                       name = o.getName()+"."+name;\r
-                               prev = o;\r
-                               o = o.getParent();\r
-                       }\r
-                       name = name.substring(0, name.length()-1);\r
-                       switch (prev.getType()) {\r
-                       case COMPLEX_TYPE:\r
-                               return ontRoot+getComplexTypePrefix()+name;\r
-                       case ELEMENT:\r
-                               return ontRoot+name;\r
-                       case ATTRIBUTE_GROUP:\r
-                               return ontRoot+getAttributeGroupPrefix()+name;\r
-                       case SIMPLE_TYPE:\r
-                               return ontRoot+name;\r
-                       }\r
-               }\r
-               throw new RuntimeException();\r
-               \r
-       }\r
-       \r
-       public String getName(SchemaObject obj, String rel) {\r
-               if (obj.getParent() == null) {\r
-                       switch (obj.getType()) {\r
-                       case COMPLEX_TYPE:\r
-                               return ontRoot+getComplexTypePrefix()+rel+obj.getName();\r
-                       case ELEMENT:\r
-                               return ontRoot+rel+obj.getName();\r
-                       case ATTRIBUTE_GROUP:\r
-                               return ontRoot+getAttributeGroupPrefix()+rel+obj.getName();\r
-                       case SIMPLE_TYPE:\r
-                               return ontRoot+rel+obj.getName();\r
-                       }\r
-               } else {\r
-                       SchemaObject o = obj;\r
-                       SchemaObject prev = null;\r
-                       String name = "";\r
-                       while (o != null){\r
-                               if (o.getName() != null)\r
-                                       name = o.getName()+"."+name;\r
-                               prev = o;\r
-                               o = o.getParent();\r
-                       }\r
-                       name = name.substring(0, name.length()-1);\r
-                       switch (prev.getType()) {\r
-                       case COMPLEX_TYPE:\r
-                               return ontRoot+getComplexTypePrefix()+rel+name;\r
-                       case ELEMENT:\r
-                               return ontRoot+rel+name;\r
-                       case ATTRIBUTE_GROUP:\r
-                               return ontRoot+getAttributeGroupPrefix()+rel+name;\r
-                       case SIMPLE_TYPE:\r
-                               return ontRoot+rel+name;\r
-                       }\r
-               }\r
-               throw new RuntimeException();\r
-               \r
-       }\r
-       \r
-       \r
-}\r
+package org.simantics.xml.sax;
+
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.simantics.utils.datastructures.BijectionMap;
+import org.simantics.xml.sax.SchemaConversionBase.Inheritance;
+import org.simantics.xml.sax.SchemaConversionBase.InheritanceType;
+import org.simantics.xml.sax.SchemaConversionBase.RefType;
+import org.simantics.xml.sax.SchemaObject.ObjectType;
+import org.simantics.xml.sax.configuration.AttributeComposition;
+import org.simantics.xml.sax.configuration.IDReference;
+import org.w3._2001.xmlschema.Annotated;
+import org.w3._2001.xmlschema.Attribute;
+import org.w3._2001.xmlschema.AttributeGroup;
+import org.w3._2001.xmlschema.Element;
+import org.w3._2001.xmlschema.LocalComplexType;
+import org.w3._2001.xmlschema.LocalSimpleType;
+import org.w3._2001.xmlschema.NamedAttributeGroup;
+import org.w3._2001.xmlschema.NamedGroup;
+import org.w3._2001.xmlschema.Restriction;
+import org.w3._2001.xmlschema.Schema;
+import org.w3._2001.xmlschema.SimpleType;
+
+//public class OntologyGenerator extends SchemaConversionBase {
+public class OntologyGenerator implements SchemaConversionComponent {
+       SchemaConversionBase base;
+       
+       public OntologyGenerator(SchemaConverter converter, SchemaConversionBase base) {
+               this.base = base;
+               this.converter = converter;
+               this.schema = base.schema;
+               this.ontologyUri = base.ontologyURI;
+               this.className = base.className;                
+       }
+
+       String ontRoot = "ONT.";
+       String commentTag = "//";
+       
+       Schema schema;
+       String ontologyUri;
+       String className;
+       
+       SchemaConverter converter;
+       
+       PrintWriter writer = null;
+       
+       public void createOntology() throws FileNotFoundException {
+               StringWriter stringWriter = null;
+               if (converter.getOntologyFile() == null) {
+                       stringWriter = new StringWriter();
+                       writer = new PrintWriter(stringWriter);
+               } else {
+                       writer = new PrintWriter(converter.getOntologyFile());
+               }
+       
+               handle();
+               
+               writer.flush();
+               writer.close();
+               if (stringWriter != null)
+                       System.out.println(stringWriter.toString());
+       }
+       
+       protected void handle() {
+               ontRoot = converter.shortName;
+
+               for (String s : converter.getHeader()) {
+                       writer.println(commentTag + " " + s);   
+               }
+               writer.println();
+               writer.println("L0 = <http://www.simantics.org/Layer0-1.1>");
+               writer.println("XML = <http://www.simantics.org/XML-1.0>");
+               writer.println();
+               if (converter.isPrimary()) {
+               writer.println(ontRoot + " = <" + ontologyUri +"> : L0.Ontology");
+               writer.println("   @L0.new");
+               writer.println("   L0.HasResourceClass \"" + className +"\"");
+               } else {
+               writer.println(ontRoot + " = <" + ontologyUri +">");
+               }
+               writer.println();
+               writer.println();
+               
+               ontRoot += ".";
+               writer.println(ontRoot+"ComplexTypes : L0.Library");
+               writer.println(ontRoot+"AttributeGroups : L0.Library");
+               writer.println();
+               writer.println(commentTag + " Interpreted from schema");
+               writer.println();
+                       
+               base.handle(this);
+       }
+               
+       protected String getType(QName qtype) {
+               String ontType = base.getL0TypeFromPrimitiveType(qtype);
+               if (ontType != null)
+                       return ontType;
+               else if (base.isComplexTypeRef(qtype.getLocalPart()))
+                       return ontRoot+getComplexTypePrefix()+qtype.getLocalPart();
+               else if (base.isSimpleTypeRef(qtype.getLocalPart()))
+                       return ontRoot+qtype.getLocalPart();
+               else if (base.isElementRef(qtype.getLocalPart()))
+                       return ontRoot+qtype.getLocalPart();
+               else if (qtype.getPrefix() != null && qtype.getPrefix().length() > 0) {
+                       return ontRoot+qtype.getPrefix()+qtype.getLocalPart();
+               }
+               throw new RuntimeException("Reference to unknown type " + qtype.getLocalPart());
+       }
+       
+       public String getComplexTypePrefix() {
+               return "ComplexTypes.";
+       }
+       
+       public String getAttributeGroupPrefix() {
+               return "AttributeGroups.";
+       }
+       
+       public void handleChoice(SchemaObject parent, SchemaElement indicator, java.util.List<SchemaElement> elements, String name) {
+               boolean single = true;
+               for (SchemaElement e : elements) {
+                       if (e.getRestriction().many()) {
+                               single = false;
+                               break;
+                       }
+               }
+               String relationName = getName(parent)+".has"+name;
+               writer.print(relationName);
+               
+               List<String> types = new ArrayList<String>();
+               for (SchemaElement e : elements) {
+                       Element localElement = e.getElement();
+                       QName refType = null;
+                       String type = null;
+                       
+                       if (localElement.getName() != null) {
+                               refType = localElement.getType();
+                               type = base.getL0TypeFromPrimitiveType(refType);        
+                       } else if (localElement.getRef() != null) {
+                               refType = localElement.getRef();
+                               type = base.getL0TypeFromPrimitiveType(refType);
+                       }
+                       if (type == null) {
+                               SchemaObject obj = base.getWithName(refType);
+                               types.add(getName(obj,"has"));
+                       } 
+               }
+               if (types.size() > 0) {
+                       for (String type : types) {
+                               writer.print(" <R " + type);
+                       }
+               } else {
+                       writer.print(" <R XML.hasElement");
+               }
+               
+               writer.println();
+               
+               for (SchemaElement e : elements) {
+                       Element localElement = e.getElement();
+                       QName refType = null;
+                       String type = null;
+                       if (localElement.getName() != null) {
+                               refType = localElement.getType();
+                               type = getType(refType);        
+                       } else if (localElement.getRef() != null) {
+                               refType = localElement.getRef();
+                               type = getType(refType);
+                       }
+                       if (type != null) {
+                               writer.println("   --> " + type);
+                       }
+               }
+               if (!single) {
+                       writer.println(ontRoot+name+ "List <T XML.ElementList");
+                       if (types.size() == 0) {
+                       writer.println(relationName+ "List <R XML.hasElementList : L0.FunctionalRelation");
+                       } else {
+                               writer.print(relationName+ "List");
+                               for (String type : types) {
+                                       writer.print(" <R " + type+"List");
+                               }
+                               writer.println(" : L0.FunctionalRelation");
+                       }
+                       writer.println("   --> " + ontRoot+name+"List");
+               }
+       };
+       
+       
+       
+       @Override
+       public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType) {
+               if (refType != refType.Element) {
+                       QName referenceType = null;
+                       if (refType == RefType.Type) {
+                               referenceType = element.getElement().getType();
+                               //refName = element.getElement().getName()
+                               SchemaObject eObj = base.getElement(element.getElement());//base.elements.get(element.getElement());
+                               if (refName == null)
+                                       refName = eObj.getName();
+                       } else {
+                               referenceType = element.getElement().getRef();
+                               if (refName == null)
+                                       refName = referenceType.getLocalPart();
+                       }
+                       String type = base.getL0TypeFromPrimitiveType(referenceType);
+                       SchemaObject obj = null;
+                       if (type == null) {
+                               obj = base.getWithName(referenceType);
+                               
+                               writer.println(getName(parent)+".has"+refName + " <R " +  getName(obj,"has"));
+                               writer.println("   --> " + getName(obj));
+                       } else {
+                               writer.println(getName(parent)+".has"+refName + " <R XML.hasElement");
+                               writer.println("   --> " + getType(referenceType));
+                       }
+                       
+                       if (base.useElementList(parent, indicator,element, refType == RefType.Reference, refName, referenceType)) {
+                               
+                               if (type == null) {
+                                       writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
+                                       writer.println(getName(parent)+".has"+refName + "List <R " +  getName(obj,"has")+"List : L0.FunctionalRelation");
+                               } else {
+                                       writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
+                                       writer.println(getName(parent)+".has"+refName + "List <R XML.hasElementList : L0.FunctionalRelation");  
+                               }
+                       }
+               } else {
+                       Element attrs = element.getElement();
+                       SchemaObject obj = base.getWithObj(parent, attrs);
+                       if (refName == null)
+                               refName = obj.getName();
+                       
+                       writer.println(getName(parent)+".has"+refName + " <R " + getName(obj,"has"));
+                       writer.println("   --> " + getName(obj));
+                       if (base.useElementList(parent, indicator,element, false, refName, new QName(obj.getName()))) {
+                               writer.println(getName(parent)+"."+refName + "List <T XML.ElementList");
+                               writer.println(getName(parent)+".has"+refName + "List <R " +  getName(obj,"has")+"List : L0.FunctionalRelation");
+                       }
+               }
+               
+       }
+       
+       @Override
+       public void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {
+               
+       }
+       
+       @Override
+       public void handle(SchemaObject parent, NamedGroup attribute) {
+               // TODO Auto-generated method stub
+               
+       }
+               
+       @Override
+       public void handle(SchemaObject parent, Attribute attribute) {
+               String name = attribute.getName();
+               QName primitiveType = attribute.getType();
+               LocalSimpleType simpleType = attribute.getSimpleType();
+               QName ref = attribute.getRef();
+               
+               String relationName;
+               String relationType;
+               if (name != null) {
+                       relationName = ontRoot+"has"+name;
+                       if (parent != null)
+                               relationName = getName(parent)+".has"+name;
+                       relationType = "XML.hasAttribute";
+               }
+               else if (ref != null && parent != null) {
+                       relationName = getName(parent)+".has"+ref.getLocalPart();
+                       relationType = ontRoot+"has"+ref.getLocalPart();
+               } else {
+                       throw new RuntimeException();
+               }
+               boolean id = false;
+               String ontType = null;
+               if (primitiveType != null) {
+                       ontType = base.getL0TypeFromPrimitiveType(primitiveType);
+                       if (ontType != null) {
+                               id = base.getTypeEntry(primitiveType).id;
+                               if (id)
+                                       relationType = "XML.hasID";
+                       } else {
+                               
+                       }
+               } else if (simpleType != null){
+//                     Restriction restriction = simpleType.getRestriction();
+//                     if (restriction == null || simpleType.getUnion() != null || simpleType.getName() != null || simpleType.getId() != null)
+//                             throw new RuntimeException();
+//                     QName base = restriction.getBase();
+                       QName base = this.base.getSimpleTypeBase(simpleType);
+                       
+                       
+                       ontType = this.base.getL0TypeFromPrimitiveType(base);
+                       
+//                     for (Object facetWrap : restriction.getFacets()) {
+//                             JAXBElement<?> element = (JAXBElement<?>)facetWrap;
+//                             QName elementName = element.getName();
+//                             Facet facet = (Facet)element.getValue();        
+//                     }
+               }
+                       
+               
+               
+               writer.println(relationName+ " <R " + relationType + ": L0.FunctionalRelation");
+               if (id) {
+                       // no need to add range restriction
+               } else if (ontType != null) {
+                       writer.println("   --> " + ontType);
+               } else if (primitiveType != null) {
+                       writer.println("   <R "+ontRoot+"has"+primitiveType.getLocalPart());
+               }
+       }
+       
+       @Override
+       public void handleAttributes(SchemaObject simpleTypeObj) {
+//             SchemaObject parent = simpleTypeObj.getParent();
+//             SimpleType simpleType = simpleTypeObj.getSimpleType();
+//             Restriction restriction = simpleType.getRestriction();
+//             QName base = restriction.getBase();
+//             String ontType = getL0TypeFromPrimitiveType(base);
+       }
+       
+       @Override
+       public void handle(SchemaObject parent, AttributeGroup attributeGroup) {
+               if (parent == null) {
+                       NamedAttributeGroup group = (NamedAttributeGroup)attributeGroup;
+                       writer.println(ontRoot+getAttributeGroupPrefix()+group.getName()+ " <T XML.AttributeGroup");
+                       SchemaObject obj = new SchemaObject(parent,attributeGroup);
+                       for (Annotated annotated : group.getAttributeOrAttributeGroup()) {
+                               if (annotated instanceof Attribute) {
+                                       //handle(getAttributeGroupPrefix()+group.getName(),(Attribute)annotated);
+                                       handle(obj,(Attribute)annotated);
+                               } else if (annotated instanceof AttributeGroup) {
+                                       handle(obj,(AttributeGroup)annotated);
+                                       //throw new RuntimeException("Cannot handle nested attribute groups");
+                               }
+                       }
+               } else {
+                       writer.println(getName(parent) +" L0.Inherits " + ontRoot + getAttributeGroupPrefix() + attributeGroup.getRef().getLocalPart());
+               }
+               
+       }
+       
+       @Override
+       public void handleAttributeComposition(SchemaObject parent, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
+               Attribute compositionAttribute = new Attribute();
+               compositionAttribute.setName(composition.getName());
+               QName type = new QName(SchemaConversionBase.CONVERSION_NS, composition.getType());
+               compositionAttribute.setType(type);
+               handle(parent, compositionAttribute);
+       }
+       
+       @Override
+       public void handleSimpleType(SchemaObject parent, SchemaObject simpleTypeObj) {
+               SimpleType simpleType = simpleTypeObj.getSimpleType();
+               String name = simpleType.getName();
+               
+               org.w3._2001.xmlschema.List list = simpleType.getList();
+               if (list != null) {
+                       // TODO : process restriction in lists
+                       String relationName = ontRoot+"has"+name;
+                       if (parent != null)
+                               relationName = getName(parent)+".has"+name;
+                       writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");
+                       
+                       String ontType = base.getL0Type(new QName(SchemaConversionBase.SCHEMA_NS, "string"));
+                       writer.println("   --> " + ontType);
+               } else {
+                       String relationName = ontRoot+"has"+name;
+                       if (parent != null)
+                               relationName = getName(parent)+".has"+name;
+                       
+                       writer.println(relationName+ " <R XML.hasAttribute : L0.FunctionalRelation");
+                       
+                       QName base = this.base.getSimpleTypeBase(simpleType);
+                       Inheritance inheritance = new Inheritance("");
+                       this.base.getAtomicTypeInheritance(base, inheritance);
+                       if (inheritance.atomicType == null)
+                               throw new RuntimeException("Could not locate atomic type for SimpleType " + simpleType.getName());
+                       writer.println("   --> " + inheritance.atomicType.l0Type);
+                       
+//                     Restriction restriction = simpleType.getRestriction();
+//                     if (restriction != null) {
+//                             
+//                             QName base = restriction.getBase();
+//                             String ontType = getL0Type(base);
+//                             writer.println("   --> " + ontType);
+//                     } else if (simpleType.getId() != null) {
+//                             throw new RuntimeException(simpleType.getName() + " restriction error");
+//                     } else if (simpleType.getUnion() != null) {
+//                             Union union = simpleType.getUnion();
+//                             String ontType = null;
+//                             if (union.getMemberTypes().size() > 0) {
+//                                     for (QName type : union.getMemberTypes()) {
+//                                             String sType = null;
+//                                             TypeEntry entry = getTypeEntry(type);
+//                                             if (entry == null) {
+//                                                     SchemaObject obj = simpleTypeName.get(type.getLocalPart());
+//                                                     Inheritance inheritance = new Inheritance("");
+//                                                     getAtomicTypeInheritance(type, obj, inheritance);
+//                                                     sType = inheritance.atomicType.l0Type;
+//                                             } else {
+//                                                     sType = entry.l0Type;
+//                                             }
+//                                             if (ontType == null)
+//                                                     ontType = sType;
+//                                             else if (!ontType.equals(sType))
+//                                                     throw new RuntimeException(simpleType.getName() + " union has incompatible member types");
+//                                     }
+//                             } else {
+//                                     if (union.getSimpleType().size() == 0)
+//                                             throw new RuntimeException(simpleType.getName() + " union error");
+//                                     for (SimpleType s : union.getSimpleType()) {
+//                                             if (restriction == null)
+//                                                     restriction = s.getRestriction();
+//                                             else  {
+//                                                     Restriction r = s.getRestriction();
+//                                                     if (!r.getBase().equals(restriction.getBase()))
+//                                                             throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");
+//                                             }
+//                                     }
+//                                     QName base = restriction.getBase();
+//                                     ontType = getL0Type(base);
+//                             }
+//                             writer.println("   --> " + ontType);
+//                     } else {
+//                             throw new RuntimeException(simpleType.getName() + " restriction error");
+//                     }
+                       
+               }
+       }
+       
+       @Override
+       public void handleComplexType(SchemaObject topLevelComplexType) {
+               String name = getName(topLevelComplexType);
+//             if (topLevelComplexType.getName().equals("Reference"))
+//                     System.out.println();
+               
+               String relationName = getName(topLevelComplexType,"has");//ontRoot+"has"+name;
+               
+               writer.println(relationName+ " <R XML.hasComplexType");
+               writer.println(relationName+ "List <R XML.hasElementList");
+               //writer.println("   --> " + ontRoot+getComplexTypePrefix()+name);
+               writer.println("   --> " + name);
+               writer.println();
+//             String baseType = "XML.ComplexType";
+//
+//             QName base = getComplexTypeBase(topLevelComplexType.getComplexType());
+//             if (base != null) {
+//                     baseType = getType(base);
+//             }
+//             base = getSimpleTypeBase(topLevelComplexType.getSimpleType());
+//             if (base != null) {
+//                     baseType = getType(base);
+//             }
+               Inheritance inheritance = base.getInheritance(topLevelComplexType);
+               
+//             writer.println(name+ " <T "+baseType);
+               
+               if(inheritance.type == InheritanceType.AtomicType) {
+                       writer.println(name+ " <T "+inheritance.baseClass + " <T "+inheritance.atomicType.l0Type);
+               } else {
+                       writer.println(name+ " <T "+inheritance.baseClass);
+               }
+//             if (!baseType.equals(inheritance.baseClass))
+//                     System.out.println();
+               //super.handleComplexType(topLevelComplexType);
+               base.handleComplexTypeAttributes(topLevelComplexType);
+               base.handleComplexTypeExtension(topLevelComplexType);
+               base.handleExtensionAttributes(topLevelComplexType);
+               writer.println();
+       }
+       
+       @Override
+       public void handleElement(SchemaObject elementObj) {
+               Element element = elementObj.getElement();
+               String name = getName(elementObj);//element.getName();
+               
+               if ("Text".equals(name))
+                       System.out.println();
+               
+               String type = "XML.Element";
+               Set<String> types = new LinkedHashSet<String>();
+               if (element.getType() != null) {
+                       types.add(getType(element.getType()));
+               }
+               QName base = this.base.getElementBase(element);
+               if (base != null) {
+                       if (base.getNamespaceURI().equals(SchemaConversionBase.SCHEMA_NS)) {
+                               String l0Type = this.base.getL0Type(base);
+                               if (l0Type == null)
+                                       throw new RuntimeException("Cannot get L0 type for " + base.getLocalPart());
+                               types.add(l0Type);
+                       } else if (this.base.isElementRef(base.getLocalPart()))
+                               types.add(ontRoot+base.getLocalPart());
+                       else
+                               types.add(ontRoot+getComplexTypePrefix()+base.getLocalPart());
+               }
+               QName substitution = element.getSubstitutionGroup();
+               if (substitution != null) {
+                       if (this.base.isElementRef(substitution.getLocalPart()))
+                               types.add(ontRoot+substitution.getLocalPart());
+                       else
+                               types.add( ontRoot+getComplexTypePrefix()+substitution.getLocalPart());
+               }
+               for (String t : types) {
+                       type += " <T " + t;
+               }
+
+               String relationName =  getName(elementObj,"has");//ontRoot+"has"+name;
+//             if (elementObj.getParent() != null) {
+//                     //relationName = ontRoot+getComplexTypePrefix()+"has"+name.substring(getComplexTypePrefix().length());
+//                     relationName = ontRoot+getName(elementObj.getParent()) + "has"+element.getName();
+//             }
+               writer.println(relationName+ " <R XML.hasElement");
+               writer.println(relationName+ "List <R XML.hasElementList");
+               
+               writer.println(name+ " <T "+type);
+               
+               LocalComplexType complexType = element.getComplexType();
+               LocalSimpleType simpleType = element.getSimpleType();
+               
+               if (complexType != null) {
+                       SchemaObject complexTypeObj = this.base.getComplexType(complexType);
+                       this.base.handleElementComplexTypeAttributes(complexTypeObj);
+                       this.base.handleComplexTypeExtension(complexTypeObj);
+               } else if (simpleType != null) {
+                       SchemaObject simpleTypeObj = this.base.getSimpleType(simpleType);
+                       this.base.handleElementSimpleTypeAttributes(simpleTypeObj);
+               }
+               
+               List<IDReference> references = this.base.getIDReferences(element);
+       
+               for (IDReference ref : references) {
+                       writer.println(name+"."+ref.getReference().getName()+ " <R XML.hasReference");
+               }
+               
+               writer.println();
+       }
+       
+       @Override
+       public String getBaseClass(ObjectType type) {
+               if (type == ObjectType.ELEMENT)
+                       return "XML.Element";
+               if (type == ObjectType.COMPLEX_TYPE)
+                       return "XML.ComplexType";
+               throw new RuntimeException("ObjectType " + type + " has no base class");
+       }
+       
+       @Override
+       public String getName(SchemaObject obj) {
+               if (obj.getParent() == null) {
+                       switch (obj.getType()) {
+                       case COMPLEX_TYPE:
+                               return ontRoot+getComplexTypePrefix()+obj.getName();
+                       case ELEMENT:
+                               return ontRoot+obj.getName();
+                       case ATTRIBUTE_GROUP:
+                               return ontRoot+getAttributeGroupPrefix()+obj.getName();
+                       case SIMPLE_TYPE:
+                               return ontRoot+obj.getName();
+                       }
+               } else {
+                       SchemaObject o = obj;
+                       SchemaObject prev = null;
+                       String name = "";
+                       while (o != null){
+                               if (o.getName() != null)
+                                       name = o.getName()+"."+name;
+                               prev = o;
+                               o = o.getParent();
+                       }
+                       name = name.substring(0, name.length()-1);
+                       switch (prev.getType()) {
+                       case COMPLEX_TYPE:
+                               return ontRoot+getComplexTypePrefix()+name;
+                       case ELEMENT:
+                               return ontRoot+name;
+                       case ATTRIBUTE_GROUP:
+                               return ontRoot+getAttributeGroupPrefix()+name;
+                       case SIMPLE_TYPE:
+                               return ontRoot+name;
+                       }
+               }
+               throw new RuntimeException();
+               
+       }
+       
+       public String getName(SchemaObject obj, String rel) {
+               if (obj.getParent() == null) {
+                       switch (obj.getType()) {
+                       case COMPLEX_TYPE:
+                               return ontRoot+getComplexTypePrefix()+rel+obj.getName();
+                       case ELEMENT:
+                               return ontRoot+rel+obj.getName();
+                       case ATTRIBUTE_GROUP:
+                               return ontRoot+getAttributeGroupPrefix()+rel+obj.getName();
+                       case SIMPLE_TYPE:
+                               return ontRoot+rel+obj.getName();
+                       }
+               } else {
+                       SchemaObject o = obj;
+                       SchemaObject prev = null;
+                       String name = "";
+                       while (o != null){
+                               if (o.getName() != null)
+                                       name = o.getName()+"."+name;
+                               prev = o;
+                               o = o.getParent();
+                       }
+                       name = name.substring(0, name.length()-1);
+                       switch (prev.getType()) {
+                       case COMPLEX_TYPE:
+                               return ontRoot+getComplexTypePrefix()+rel+name;
+                       case ELEMENT:
+                               return ontRoot+rel+name;
+                       case ATTRIBUTE_GROUP:
+                               return ontRoot+getAttributeGroupPrefix()+rel+name;
+                       case SIMPLE_TYPE:
+                               return ontRoot+rel+name;
+                       }
+               }
+               throw new RuntimeException();
+               
+       }
+       
+       
+}
index 2bca88d64f5dfd666fee38f5d5cdf6a956fc4e84..1e13951da7d8f522c47558e872534da51a474fb4 100644 (file)
-package org.simantics.xml.sax;\r
-\r
-import java.util.ArrayDeque;\r
-import java.util.ArrayList;\r
-import java.util.Deque;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import javax.xml.bind.JAXBElement;\r
-import javax.xml.namespace.QName;\r
-\r
-import org.simantics.utils.datastructures.BijectionMap;\r
-import org.simantics.xml.sax.SchemaElement.ElementType;\r
-import org.simantics.xml.sax.SchemaObject.ObjectType;\r
-import org.simantics.xml.sax.configuration.AttributeComposition;\r
-import org.simantics.xml.sax.configuration.Configuration;\r
-import org.simantics.xml.sax.configuration.IDProvider;\r
-import org.simantics.xml.sax.configuration.IDReference;\r
-import org.simantics.xml.sax.configuration.OrderedChild;\r
-import org.simantics.xml.sax.configuration.Rename;\r
-import org.simantics.xml.sax.configuration.UnrecognizedChildElement;\r
-import org.w3._2001.xmlschema.All;\r
-import org.w3._2001.xmlschema.Annotated;\r
-import org.w3._2001.xmlschema.Any;\r
-import org.w3._2001.xmlschema.Attribute;\r
-import org.w3._2001.xmlschema.AttributeGroup;\r
-import org.w3._2001.xmlschema.ComplexContent;\r
-import org.w3._2001.xmlschema.ComplexType;\r
-import org.w3._2001.xmlschema.Element;\r
-import org.w3._2001.xmlschema.ExplicitGroup;\r
-import org.w3._2001.xmlschema.ExtensionType;\r
-import org.w3._2001.xmlschema.GroupRef;\r
-import org.w3._2001.xmlschema.LocalElement;\r
-import org.w3._2001.xmlschema.NamedAttributeGroup;\r
-import org.w3._2001.xmlschema.NamedGroup;\r
-import org.w3._2001.xmlschema.OpenAttrs;\r
-import org.w3._2001.xmlschema.RealGroup;\r
-import org.w3._2001.xmlschema.Restriction;\r
-import org.w3._2001.xmlschema.Schema;\r
-import org.w3._2001.xmlschema.SimpleContent;\r
-import org.w3._2001.xmlschema.SimpleType;\r
-import org.w3._2001.xmlschema.TopLevelAttribute;\r
-import org.w3._2001.xmlschema.TopLevelComplexType;\r
-import org.w3._2001.xmlschema.TopLevelElement;\r
-import org.w3._2001.xmlschema.TopLevelSimpleType;\r
-import org.w3._2001.xmlschema.Union;\r
-\r
-public final class SchemaConversionBase {\r
-       \r
-       protected Schema schema;\r
-       protected SchemaConverter converter;\r
-       protected SchemaConversionComponent component;\r
-       protected Configuration configuration;\r
-       \r
-       public static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";\r
-       public static final String CONVERSION_NS = "http://www.simantics.org/Layer0";\r
-       \r
-       protected Map<String,Map<String,TypeEntry>> typeMap;\r
-       \r
-       protected String ontologyURI;\r
-       protected String className;\r
-       \r
-       public SchemaConversionBase(SchemaConverter converter, String ontologyUri, String className) {\r
-               this.converter = converter;\r
-               this.configuration = converter.getConfiguration();\r
-               this.ontologyURI = ontologyUri;\r
-               this.className = className;\r
-               \r
-               initTypes();\r
-       }\r
-       \r
-       protected void initTypes() {\r
-               typeMap = new HashMap<String, Map<String,TypeEntry>>();\r
-               Map<String,TypeEntry> schemaTypes = new HashMap<String, SchemaConversionBase.TypeEntry>();\r
-               typeMap.put(SCHEMA_NS, schemaTypes);\r
-               Map<String,TypeEntry> l0Types = new HashMap<String, SchemaConversionBase.TypeEntry>();\r
-               typeMap.put(CONVERSION_NS, l0Types);\r
-               \r
-               schemaTypes.put("string",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
-               schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
-               schemaTypes.put("token",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
-               schemaTypes.put("ID",                   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","","",true));\r
-               schemaTypes.put("IDREF",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
-               schemaTypes.put("Name",                 new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
-               schemaTypes.put("NCName",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));\r
-               schemaTypes.put("date",                 new TypeEntry("XML.Date",                       "org.simantics.xml.sax.base.datatypes.literal.Date.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Date", "","org.simantics.xml.sax.base.datatypes.literal.Date.parseDate(",")","(",").toString()"));\r
-               schemaTypes.put("time",                 new TypeEntry("XML.Time",                       "org.simantics.xml.sax.base.datatypes.literal.Time.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Time", "","org.simantics.xml.sax.base.datatypes.literal.Time.parseTime(",")","(",").toString()"));\r
-               schemaTypes.put("dateTime",             new TypeEntry("XML.DateTime",           "org.simantics.xml.sax.base.datatypes.literal.DateTime.BINDING", "org.simantics.xml.sax.base.datatypes.literal.DateTime", "","org.simantics.xml.sax.base.datatypes.literal.DateTime.parseDateTime(",")","(",").toString()"));\r
-               schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "Bindings.STRING", "java.lang.String", "","","","",""));\r
-               schemaTypes.put("double",               new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));\r
-               schemaTypes.put("float",                new TypeEntry("L0.Float",                       "Bindings.FLOAT",  "float",  "java.lang.Float.NaN","java.lang.Float.parseFloat(",")","java.lang.Float.toString(",")"));\r
-               schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));\r
-               schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "Bindings.BOOLEAN", "boolean", "false","java.lang.Boolean.parseBoolean(",")","java.lang.Boolean.toString(",")"));\r
-               schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));\r
-               schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));\r
-               schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));\r
-               schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));\r
-               schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));\r
-               schemaTypes.put("base64Binary", new TypeEntry("L0.ByteArray",           "Bindings.BYTE_ARRAY", "byte[]", "new byte[0]","",".getBytes(org.simantics.databoard.util.binary.UTF8.CHARSET)","new java.lang.String(",", org.simantics.databoard.util.binary.UTF8.CHARSET)"));\r
-               \r
-               l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "Bindings.DOUBLE_ARRAY", "double[]", null,null,null,"java.lang.Double.toString(",")"));\r
-               l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "Bindings.STRING_ARRAY", "string[]", null,null,null,"",""));\r
-       }\r
-       \r
-       protected TypeEntry getTypeEntry(QName type) {\r
-               Map<String,TypeEntry> types = typeMap.get(type.getNamespaceURI());\r
-               if (types == null)\r
-                       return null;\r
-               TypeEntry entry = types.get(type.getLocalPart());\r
-               return entry;\r
-       }\r
-       protected TypeEntry getTypeEntry(String type) {\r
-               for (Map<String,TypeEntry> types : typeMap.values()) {\r
-                       TypeEntry entry = types.get(type);\r
-                       if (entry != null)\r
-                               return entry;\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected String getL0TypeFromPrimitiveType(QName primitiveType) {\r
-               TypeEntry entry = getTypeEntry(primitiveType);\r
-               if (entry == null)\r
-                       return null;\r
-               return entry.l0Type;\r
-       }\r
-       \r
-       protected String getL0Type(QName primitiveType) {\r
-               String type = getL0TypeFromPrimitiveType(primitiveType);\r
-               if (type != null)\r
-                       return type;\r
-               SchemaObject simpleTypeObj = simpleTypeName.get(primitiveType.getLocalPart());\r
-               if (simpleTypeObj == null)\r
-                       return null;\r
-               SimpleType simpleType = simpleTypeObj.getSimpleType();\r
-               while (simpleType != null) {\r
-                       QName base = simpleType.getRestriction().getBase();\r
-                       if (base != null)\r
-                               return getL0Type(base);\r
-                       simpleType = simpleType.getRestriction().getSimpleType();\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected String getBindingFromPrimitiveType(QName primitiveType) {\r
-               TypeEntry entry = getTypeEntry(primitiveType);\r
-               if (entry == null)\r
-                       return null;\r
-               return entry.binding;\r
-       }\r
-       \r
-       protected String getJavaTypeFromPrimitiveType(QName primitiveType) {\r
-               TypeEntry entry = getTypeEntry(primitiveType);\r
-               if (entry == null)\r
-                       return null;\r
-               return entry.javaType;\r
-       }\r
-       \r
-       \r
-       public void init(Schema schema) {       \r
-               this.schema = schema;\r
-               \r
-               preload();\r
-       }\r
-       \r
-       public void handle(SchemaConversionComponent component) {\r
-               this.component = component;\r
-               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
-                       if (attrs instanceof TopLevelAttribute) {\r
-                               handle((TopLevelAttribute)attrs);\r
-                               \r
-                       } else if (attrs instanceof TopLevelComplexType) {\r
-                               handleComplexType(complexTypes.get(attrs));\r
-                       } else if (attrs instanceof TopLevelElement) {\r
-                               handleElement(elements.get(attrs));\r
-                       } else if (attrs instanceof TopLevelSimpleType) {\r
-                               handleSimpleType(simpleTypes.get(attrs));\r
-                       } else if (attrs instanceof NamedAttributeGroup) {\r
-                               handle((NamedAttributeGroup)attrs);\r
-                       } else if (attrs instanceof NamedGroup) {\r
-                               handle((NamedGroup)attrs);\r
-                       } else {\r
-                               System.out.println(attrs.getClass().getName());\r
-                       }\r
-               }\r
-       }\r
-       \r
-       private Map<String,SchemaObject> elementName = new HashMap<>();\r
-       private Map<String,SchemaObject> complexTypeName = new HashMap<>();\r
-       private Map<String,SchemaObject> simpleTypeName = new HashMap<>();\r
-       private Map<String,SchemaObject> modelGroupName = new HashMap<>();\r
-       private Map<Element,SchemaObject> elements = new HashMap<>();\r
-       private Map<ComplexType,SchemaObject> complexTypes = new HashMap<>();\r
-       private Map<SimpleType,SchemaObject> simpleTypes = new HashMap<>();\r
-       private Map<NamedGroup,SchemaObject> modelGroups = new HashMap<>();\r
-       \r
-       private SchemaObject _getWithName(QName name) {\r
-               SchemaObject obj = elementName.get(name.getLocalPart());\r
-               if (obj == null)\r
-                       obj = complexTypeName.get(name.getLocalPart());\r
-               if (obj == null)\r
-                       obj = simpleTypeName.get(name.getLocalPart());\r
-               return obj;\r
-       }\r
-       \r
-       protected SchemaObject getWithName(QName name) {\r
-               SchemaObject obj = _getWithName(name);\r
-               if (obj != null)\r
-                       return obj;\r
-               if (name.getNamespaceURI() != null) {\r
-                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
-                               if (sc.base != null) {\r
-                                       obj = sc.base._getWithName(name);\r
-                                       if (obj != null) {\r
-                                               return obj;\r
-                                       }\r
-                               }\r
-                       }               \r
-               }\r
-               return null;\r
-       }\r
-       \r
-       private NamedAttributeGroup _getAttributeGroup(QName name) {\r
-               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
-                       if (attrs instanceof NamedAttributeGroup) {\r
-                               NamedAttributeGroup group = (NamedAttributeGroup)attrs;\r
-                               if (group.getName().equals(name.getLocalPart()))\r
-                                       return group;\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-\r
-       public NamedAttributeGroup getAttributeGroup(QName name) {\r
-               NamedAttributeGroup group = _getAttributeGroup(name);\r
-               if (group != null)\r
-                       return group;\r
-               if (name.getNamespaceURI() != null) {\r
-                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
-                               if (sc.base != null) {\r
-                                       group = sc.base._getAttributeGroup(name);\r
-                                       if (group != null) {\r
-                                               return group;\r
-                                       }\r
-                               }\r
-                       }       \r
-               }\r
-               return null;\r
-       }\r
-       \r
-       private SchemaObject _getElement(QName name) {\r
-               return elementName.get(name.getLocalPart());\r
-       }\r
-       \r
-       protected SchemaObject getElement(QName name) {\r
-               SchemaObject obj = _getElement(name);\r
-               if (obj != null)\r
-                       return obj;\r
-               if (name.getNamespaceURI() != null) {\r
-                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
-                               if (sc.base != null) {\r
-                                       obj = sc.base._getElement(name);\r
-                                       if (obj != null) {\r
-                                               return obj;\r
-                                       }\r
-                               }\r
-                       }               \r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected SchemaObject getElement(Element element) {\r
-               return elements.get(element);\r
-       }\r
-       \r
-       \r
-       private SchemaObject _getComplexType(QName name) {\r
-               return complexTypeName.get(name.getLocalPart());\r
-       }\r
-       \r
-       protected SchemaObject getComplexType(QName name) {\r
-               SchemaObject obj = _getComplexType(name);\r
-               if (obj != null)\r
-                       return obj;\r
-               if (name.getNamespaceURI() != null) {\r
-                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
-                               if (sc.base != null) {\r
-                                       obj = sc.base._getComplexType(name);\r
-                                       if (obj != null) {\r
-                                               return obj;\r
-                                       }\r
-                               }\r
-                       }               \r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected SchemaObject getComplexType(ComplexType complexType) {\r
-               return complexTypes.get(complexType);\r
-       }\r
-       \r
-       private SchemaObject _getSimpleType(QName name) {\r
-               return simpleTypeName.get(name.getLocalPart());\r
-       }\r
-       \r
-       protected SchemaObject getSimpleType(QName name) {\r
-               SchemaObject obj = _getSimpleType(name);\r
-               if (obj != null)\r
-                       return obj;\r
-               if (name.getNamespaceURI() != null) {\r
-                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {\r
-                               if (sc.base != null) {\r
-                                       obj = sc.base._getSimpleType(name);\r
-                                       if (obj != null) {\r
-                                               return obj;\r
-                                       }\r
-                               }\r
-                       }               \r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected SchemaObject getSimpleType(SimpleType simpleType) {\r
-               return simpleTypes.get(simpleType);\r
-       }\r
-       \r
-       protected SchemaObject getWithObj(SchemaObject referrer, OpenAttrs attrs) {\r
-               // FIXME : this method cannot handle references to other schemas.\r
-               SchemaObject obj = null;\r
-               if (attrs instanceof Element)\r
-                       obj = elements.get(attrs);\r
-               else if (attrs instanceof ComplexType)\r
-                       obj = complexTypes.get(attrs);\r
-               else if (attrs instanceof SimpleType) \r
-                       obj = simpleTypes.get(attrs);\r
-               if (obj == null){\r
-                       throw new RuntimeException("Cannot locate referred object " + attrs + " when handling " + referrer.getName());\r
-               }\r
-               return obj;\r
-       }\r
-       \r
-       private void preload() {\r
-               Deque<SchemaObject> stack = new ArrayDeque<SchemaObject>();\r
-               //stack.addAll(schema.getSimpleTypeOrComplexTypeOrGroup());\r
-               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
-                       if (attrs instanceof Element) {\r
-                               Element element = (Element)attrs;\r
-                               SchemaObject obj = new SchemaObject(element);\r
-                               obj.setRename(getRename(element));\r
-                               stack.push(obj);\r
-                       } else if (attrs instanceof ComplexType) {\r
-                               ComplexType complexType = (ComplexType)attrs;\r
-                               SchemaObject obj = new SchemaObject(complexType);\r
-                               obj.setRename(getRename(complexType));\r
-                               stack.push(obj);\r
-                       } else if (attrs instanceof SimpleType) {\r
-                               SimpleType simpleType = (SimpleType)attrs;\r
-                               SchemaObject obj = new SchemaObject(simpleType);\r
-                               stack.push(obj);\r
-                       }  else if (attrs instanceof Attribute) {\r
-                               // Attributes are not cached\r
-                       } else if (attrs instanceof AttributeGroup) {\r
-                               // Attribute groups are not cached\r
-                       } else if (attrs instanceof NamedGroup) {\r
-                               NamedGroup group = (NamedGroup)attrs;\r
-                               SchemaObject obj = new SchemaObject(group);\r
-                               stack.push(obj);\r
-                       } else {\r
-                               System.out.println(attrs.getClass().getName());\r
-                       }\r
-               }\r
-               \r
-               while (!stack.isEmpty()) {\r
-                       SchemaObject object = stack.pop();\r
-                       switch (object.getType()) {\r
-                       case COMPLEX_TYPE:{\r
-                               ComplexType ct = object.getComplexType();\r
-                               if (ct.getName() != null && ct.getName().length() > 0 && ct instanceof TopLevelComplexType)\r
-                                       complexTypeName.put(ct.getName(), object);\r
-                               complexTypes.put(ct, object);\r
-                               if (ct.getChoice() != null) {\r
-                                       preload(object,ct.getChoice(), stack);\r
-                               }\r
-                               if (ct.getSequence() != null) {\r
-                                       preload(object,ct.getSequence(), stack);\r
-                               }\r
-                               if (ct.getAll() != null) {\r
-                                       preload(object,ct.getAll(), stack);\r
-                               }\r
-                               if (ct.getGroup() != null)\r
-                                       throw new RuntimeException("Groups not supported");\r
-                               if (ct.getComplexContent() != null) {\r
-                                       ComplexContent cc = ct.getComplexContent();\r
-                                       ExtensionType extensionType = cc.getExtension();\r
-                                       if (extensionType != null) {\r
-                                               if (extensionType.getChoice() != null) {\r
-                                                       preload(object,extensionType.getChoice(), stack);\r
-                                               }\r
-                                               if (extensionType.getSequence()!= null) {\r
-                                                       preload(object,extensionType.getSequence(), stack);\r
-                                               }\r
-                                               if (extensionType.getAll()!= null) {\r
-                                                       preload(object,extensionType.getAll(), stack);\r
-                                               }\r
-                                               if (extensionType.getGroup() != null)\r
-                                                       throw new RuntimeException("Groups not supported");\r
-                                       }\r
-                               }\r
-                               if (ct.getSimpleContent() != null) {\r
-                                       SimpleContent cc = ct.getSimpleContent();\r
-                                       ExtensionType extensionType = cc.getExtension();\r
-                                       if (extensionType != null) {\r
-                                               if (extensionType.getChoice() != null) {\r
-                                                       preload(object,extensionType.getChoice(), stack);\r
-                                               }\r
-                                               if (extensionType.getSequence()!= null) {\r
-                                                       preload(object,extensionType.getSequence(), stack);\r
-                                               }\r
-                                               if (extensionType.getAll()!= null) {\r
-                                                       preload(object,extensionType.getAll(), stack);\r
-                                               }\r
-                                               if (extensionType.getGroup() != null)\r
-                                                       throw new RuntimeException("Groups not supported");\r
-                                       }\r
-                               }\r
-                               break;\r
-                       } \r
-                       case ELEMENT:{\r
-                               Element e = object.getElement();\r
-                               if (e instanceof TopLevelElement)\r
-                                       elementName.put(e.getName(), object);\r
-                               elements.put(e, object);\r
-                               if (e.getComplexType() != null)\r
-                                       stack.push(new SchemaObject(object,e.getComplexType()));\r
-                               if (e.getSimpleType() != null)\r
-                                       stack.push(new SchemaObject(object,e.getSimpleType()));\r
-                               break;\r
-                       } \r
-                       case SIMPLE_TYPE:{\r
-                               SimpleType e = object.getSimpleType();\r
-                               if (e instanceof TopLevelSimpleType)\r
-                                       simpleTypeName.put(e.getName(), object);\r
-                               simpleTypes.put(e, object);\r
-                               break;\r
-                       } \r
-                       case MODEL_GROUP:{\r
-                               NamedGroup e = object.getModelGroup();\r
-                               modelGroupName.put(e.getName(), object);\r
-                               modelGroups.put(e, object);\r
-                               break;\r
-                       }\r
-                       }\r
-               } // while\r
-       }\r
-       \r
-       private void preload(SchemaObject parent,ExplicitGroup eg, Deque<SchemaObject> stack) {\r
-               for (Object o : eg.getParticle()) {\r
-                       if (o instanceof JAXBElement<?>) {\r
-                               JAXBElement<?> element = (JAXBElement<?>)o;\r
-                               Object elemValue = element.getValue();\r
-                               if (elemValue instanceof Element) {\r
-                                       SchemaObject obj = new SchemaObject(parent,(Element)elemValue);\r
-                                       obj.setRename(getRename((Element)elemValue));\r
-                                       stack.add(obj);\r
-                               } else if (elemValue instanceof ExplicitGroup) {\r
-                                       preload(parent,(ExplicitGroup)elemValue, stack);\r
-                               } else if (elemValue instanceof RealGroup) {\r
-                                       preload(parent,(RealGroup)elemValue, stack);\r
-                               } else {\r
-                                       throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
-                               }\r
-                       } else if (o instanceof Any){\r
-                               \r
-                       } else {\r
-                               throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());\r
-                       }\r
-               }\r
-       }\r
-       \r
-       private void preload(SchemaObject parent, RealGroup eg, Deque<SchemaObject> stack) {\r
-               System.out.println(eg); \r
-               if (eg instanceof NamedGroup) {\r
-                       SchemaObject obj = new SchemaObject(parent,(NamedGroup)eg);\r
-                       stack.add(obj);\r
-               }\r
-       }\r
-\r
-       \r
-       protected void handle(TopLevelAttribute topLevelAttribute) {\r
-               handle(null, topLevelAttribute);\r
-       }\r
-       \r
-       protected void handleSimpleType(SchemaObject topLevelSimpleType) {\r
-               handleSimpleType(null,topLevelSimpleType);\r
-       }\r
-       \r
-       protected void handle(NamedAttributeGroup namedAttributeGroup){\r
-               handle(null, namedAttributeGroup);\r
-       }\r
-       \r
-       protected void handle(NamedGroup namedAttributeGroup){\r
-               handle(null, namedAttributeGroup);\r
-       }\r
-       \r
-       protected QName getComplexTypeBase(ComplexType complexType) {\r
-               if (complexType == null)\r
-                       return null;\r
-               ComplexContent complexContent = complexType.getComplexContent();\r
-               if (complexContent != null) {\r
-                       ExtensionType extensionType = complexContent.getExtension();\r
-                       if (extensionType != null) {\r
-                               QName type = extensionType.getBase();\r
-                               return type;\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected QName getSimpleTypeBase(SimpleType simpleType) {\r
-//             if (simpleType == null)\r
-//                     return null;\r
-//             return simpleType.getRestriction().getBase();\r
-               \r
-               Restriction restriction = simpleType.getRestriction();\r
-               if (restriction != null) {\r
-                       QName base = restriction.getBase();\r
-                       return base;\r
-               } else if (simpleType.getId() != null) {\r
-                       throw new RuntimeException(simpleType.getName() + " restriction error");\r
-               } else if (simpleType.getUnion() != null) {\r
-                       Union union = simpleType.getUnion();\r
-                       if (union.getMemberTypes().size() > 0) {\r
-                               QName base = null;\r
-                               for (QName type : union.getMemberTypes()) {\r
-                                       QName sType = null;\r
-                                       TypeEntry entry = getTypeEntry(type);\r
-                                       if (entry == null) {\r
-                                               SchemaObject obj = simpleTypeName.get(type.getLocalPart());\r
-                                               if (obj == null)\r
-                                                       throw new RuntimeException(simpleType.getName() + " union has unresolved reference " + type.getLocalPart());\r
-                                               sType = getSimpleTypeBase(obj.getSimpleType());\r
-                                       } else {\r
-                                               sType = type;\r
-                                       }\r
-                                       if (base == null)\r
-                                               base = sType;\r
-                                       else if (!base.equals(sType)) {\r
-                                               //FIXME : throw new RuntimeException(simpleType.getName() + " union has incompatible member types");\r
-                                               // fall back to string. \r
-                                               base = new QName(SCHEMA_NS, "string");\r
-                                               \r
-                                       }\r
-                               }\r
-                               return base;\r
-                       } else {\r
-                               if (union.getSimpleType().size() == 0)\r
-                                       throw new RuntimeException(simpleType.getName() + " union error");\r
-                               for (SimpleType s : union.getSimpleType()) {\r
-                                       if (restriction == null)\r
-                                               restriction = s.getRestriction();\r
-                                       else  {\r
-                                               Restriction r = s.getRestriction();\r
-                                               if (!r.getBase().equals(restriction.getBase()))\r
-                                                       throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");\r
-                                       }\r
-                               }\r
-                               QName base = restriction.getBase();\r
-                               return base;\r
-                       }\r
-               } else if (simpleType.getList() != null) {\r
-                       // FIXME: callers cannot get the information that we have a list.\r
-                       org.w3._2001.xmlschema.List list = simpleType.getList();\r
-                       return list.getItemType();\r
-               } else {\r
-                       throw new RuntimeException(simpleType.getName() + " restriction error");\r
-               }\r
-       }\r
-       \r
-       protected QName getElementBase(Element element) {\r
-               ComplexType complexType = element.getComplexType();\r
-               SimpleType simpleType = element.getSimpleType();\r
-               if (complexType != null)\r
-                       return getComplexTypeBase(complexType);\r
-               if (simpleType != null) {\r
-                       return getSimpleTypeBase(simpleType);\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       private void handleAttributes(SchemaObject complexType, List<Annotated> attributeOrAttributeGroup) {\r
-               //name = getComplexTypePrefix()+complexType.getName()\r
-               \r
-               Set<Annotated> handled = handleAttributeCompositions(complexType,attributeOrAttributeGroup);\r
-               for (Annotated annotated : attributeOrAttributeGroup) {\r
-                       if (handled.contains(annotated))\r
-                               continue;\r
-                       if (annotated instanceof Attribute) {\r
-                               handle(complexType,(Attribute)annotated);\r
-                       } else if (annotated instanceof AttributeGroup){\r
-                               handle(complexType,(AttributeGroup)annotated);\r
-                               //comment("AttributeGroup " + ((AttributeGroup)annotated).getRef().getLocalPart());\r
-                       } else {\r
-                               throw new RuntimeException();\r
-                       }\r
-               }\r
-       }\r
-       \r
-       protected void handleAttributes(SchemaObject simpleTypeObj) {\r
-               component.handleAttributes(simpleTypeObj);\r
-       }\r
-       \r
-       protected void handleExtensionAttributes(SchemaObject complexType) {\r
-               ComplexContent complexContent = complexType.getComplexType().getComplexContent();\r
-               if (complexContent != null) {\r
-                       ExtensionType extensionType = complexContent.getExtension();\r
-                       if (extensionType != null) {\r
-                               handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());\r
-                       }\r
-               }\r
-               SimpleContent simpleContent = complexType.getComplexType().getSimpleContent();\r
-               if (simpleContent != null) {\r
-                       ExtensionType extensionType = simpleContent.getExtension();\r
-                       if (extensionType != null) {\r
-                               handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());\r
-                       }\r
-               }\r
-       }\r
-       \r
-       \r
-       \r
-       protected void handleComplexTypeAttributes(SchemaObject complexType) {          \r
-               handleAttributes(complexType,complexType.getComplexType().getAttributeOrAttributeGroup());\r
-       }\r
-       \r
-       protected void handleElementComplexTypeAttributes(SchemaObject complexType) {\r
-               if (complexType != null) {\r
-                       handleComplexTypeAttributes(complexType);\r
-                       handleExtensionAttributes(complexType);\r
-               }\r
-       }\r
-       \r
-       protected void handleElementSimpleTypeAttributes(SchemaObject simpleType) {\r
-               if (simpleType != null) {\r
-                       handleAttributes(simpleType);\r
-               }\r
-       }\r
-       \r
-       protected Set<Annotated> handleAttributeCompositions(SchemaObject obj, List<Annotated> attributeOrAttributeGroup) {\r
-               \r
-               Set<Annotated> handled = new HashSet<Annotated>();\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof AttributeComposition) {\r
-                               AttributeComposition composition = (AttributeComposition)e.getValue();\r
-                               if (composition.getAttribute().size() < 2)\r
-                                       throw new RuntimeException("Attribute Composition is not valid");\r
-                               BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> map = new BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated>();\r
-                               for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {\r
-                                       for (Annotated annotated : attributeOrAttributeGroup) {\r
-                                               if (annotated instanceof Attribute) {\r
-                                                       Attribute attribute = (Attribute)annotated;\r
-                                                       QName type = getBaseType(attribute);\r
-                                                       if (a.getName().equals(attribute.getName()) && type != null && a.getType().equals(type.getLocalPart())) {\r
-                                                               map.map(a, attribute);\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                               }\r
-                               if (composition.getAttribute().size() == map.size()) {\r
-                                       handled.addAll(map.getRightSet());\r
-                                       handleAttributeComposition(obj, composition, map);      \r
-                               }\r
-                       }\r
-               }\r
-               return handled;\r
-       }\r
-       \r
-       protected QName getBaseType(Attribute attribute) {\r
-               if (attribute.getType() != null)\r
-                       return attribute.getType();\r
-               if (attribute.getRef() != null)\r
-                       return attribute.getRef();\r
-               SimpleType simpleType = attribute.getSimpleType();\r
-               if (simpleType != null) {\r
-                       Restriction restriction = simpleType.getRestriction();\r
-                       if (restriction != null)\r
-                               if (restriction.getBase() != null)\r
-                                       return restriction.getBase();\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected QName getPrimitiveType(Attribute attribute) {\r
-               QName type = getBaseType(attribute);\r
-               String b = getBindingFromPrimitiveType(type);\r
-               while (b==null && type != null) {\r
-                       SchemaObject baseType = simpleTypeName.get(type.getLocalPart());\r
-                       if (baseType != null) {\r
-                               Restriction restriction = baseType.getSimpleType().getRestriction();\r
-                               if (restriction != null)\r
-                                       if (restriction.getBase() != null) {\r
-                                               type = restriction.getBase();\r
-                                               b = getBindingFromPrimitiveType(type);\r
-                                       }\r
-                       }\r
-               }\r
-               return type;\r
-       }\r
-       \r
-       protected Attribute getRefAttribute(QName ref) {\r
-               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {\r
-                       if (attrs instanceof TopLevelAttribute) {\r
-                               TopLevelAttribute attribute = (TopLevelAttribute)attrs;\r
-                               if (attribute.getName().equals(ref.getLocalPart()))\r
-                                       return attribute;\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       //protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);\r
-       protected void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {\r
-               component.handleAttributeComposition(obj, composition, attributes);\r
-       }\r
-       \r
-       \r
-       \r
-       \r
-       protected void handleComplexType(SchemaObject complexType) {\r
-//             handleComplexTypeAttributes(complexType);\r
-//             handleComplexTypeExtension(complexType);\r
-//             handleExtensionAttributes(complexType);\r
-               component.handleComplexType(complexType);\r
-       }\r
-       \r
-       protected void handleElement(SchemaObject topLevelElement) {\r
-//             LocalComplexType complexType = topLevelElement.getElement().getComplexType();\r
-//             \r
-//             if (complexType != null) {\r
-//                     SchemaObject complextTypeObj = complexTypes.get(complexType);\r
-//                     handleElementComplexTypeAttributes(complextTypeObj);\r
-//                     handleComplexTypeExtension(complextTypeObj);\r
-//             }       \r
-               component.handleElement(topLevelElement);\r
-       }\r
-       \r
-       protected enum RefType{Element,Reference,Type};\r
-       \r
-       protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType) {\r
-               component.handleIndicator(parent, indicator, element, refName, refType);\r
-       }\r
-       protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {\r
-               component.handleIndicator(parent, indicator, any);\r
-       }\r
-       protected void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements) {\r
-               //component.handle(parent, indicator, elements);\r
-               if (indicator.getType() == SchemaElement.ElementType.SEQUENCE || (indicator.getType() == SchemaElement.ElementType.CHOICE && indicator.getRestriction().many())) {\r
-                       for (SchemaElement e : elements) {\r
-                               handle(parent, indicator, e);\r
-                       }\r
-               } else if (indicator.getType() == SchemaElement.ElementType.CHOICE) {\r
-                       String name = getChoiceName(elements);\r
-                       component.handleChoice(parent, indicator, elements, name);\r
-               }\r
-       }\r
-       \r
-       protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {\r
-               handle(parent, new SchemaElement(eg, indicator));\r
-       }\r
-       \r
-       protected void handle(SchemaObject parent, SchemaElement indicator) {\r
-               \r
-               \r
-               List<SchemaElement> elements = new ArrayList<SchemaElement>();\r
-               List<SchemaElement> choices = new ArrayList<SchemaElement>();\r
-               List<SchemaElement> sequences = new ArrayList<SchemaElement>();\r
-               List<SchemaElement> alls = new ArrayList<SchemaElement>();\r
-               List<SchemaElement> anys = new ArrayList<SchemaElement>();\r
-               List<SchemaElement> groups = new ArrayList<SchemaElement>();\r
-               \r
-               for (Object o : indicator.getGroup().getParticle()) {\r
-                       if (o instanceof JAXBElement<?>) {\r
-                               JAXBElement<?> element = (JAXBElement<?>)o;\r
-                               Object elemValue = element.getValue();\r
-                               if (elemValue instanceof LocalElement) {\r
-                                       LocalElement localElement = (LocalElement)elemValue;\r
-                                       elements.add(new SchemaElement(indicator,localElement, ElementType.ELEMENT));\r
-                               } else if (elemValue instanceof All) {\r
-                                       alls.add(new SchemaElement(indicator,(All)elemValue, ElementType.ALL));\r
-                               } else if (elemValue instanceof ExplicitGroup) {\r
-                                       QName qname = element.getName();\r
-                                       if ("choice".equals(qname.getLocalPart())) {\r
-                                               choices.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.CHOICE));\r
-                                       } else if ("sequence".equals(qname.getLocalPart())) {\r
-                                               sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));\r
-                                       }\r
-                               } else if (elemValue instanceof RealGroup) {\r
-                                       if (elemValue instanceof GroupRef) {\r
-                                               groups.add(new SchemaElement(indicator,(GroupRef)elemValue, ElementType.GROUP_REF));\r
-                                       } else if (elemValue instanceof NamedGroup) {\r
-                                               groups.add(new SchemaElement(indicator,(NamedGroup)elemValue, ElementType.NAMED_GROUP));\r
-                                       } else {\r
-                                               throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
-                                       }\r
-                               } else {\r
-                                       throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());\r
-                               }\r
-                       } else if (o instanceof Any){\r
-                               anys.add(new SchemaElement(indicator,(Any)o, ElementType.ANY));\r
-                       } else {\r
-                               throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());\r
-                       }\r
-               }\r
-               \r
-               if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0 && groups.size() == 0) {\r
-                       return;\r
-               }\r
-               \r
-               if (indicator.getType() == SchemaElement.ElementType.SEQUENCE) {\r
-                       if (indicator.getRestriction().single()) {\r
-                               if (elements.size() > 0) {\r
-                                       for (SchemaElement e : sequences) {\r
-                                               handle(parent, e);\r
-                                       }\r
-                                       for (SchemaElement c : choices) {\r
-                                               handle(parent, c);\r
-                                       }\r
-                                       \r
-                                       for (SchemaElement c : alls) {\r
-                                               handle(parent, c);\r
-                                       }\r
-                                       \r
-                                       for (SchemaElement c : groups) {\r
-                                               handle(parent, c);\r
-                                       }\r
-                                       handle(parent, indicator, elements);\r
-                                       for (SchemaElement a : anys) {\r
-                                               handleIndicator(parent, indicator, a);\r
-                                       }\r
-                               } else {\r
-                                       if (sequences.size() > 0) {\r
-                                               throw new RuntimeException("Cannot handle Sequence with inner Sequences");\r
-                                       }\r
-                                       for (SchemaElement c : choices) {\r
-                                               handle(parent, c);\r
-                                       }\r
-                                       for (SchemaElement a : anys) {\r
-                                               handleIndicator(parent, indicator, a);\r
-                                       }\r
-                                       for (SchemaElement c : groups) {\r
-                                               handle(parent, c);\r
-                                       }\r
-                               }\r
-                       } else {\r
-                               if (choices.size() == 1 && sequences.size() == 0 && alls.size() == 0 && groups.size() == 0) {\r
-                                       // special case: handle lone choice inside sequence with maxOccurs > 1 \r
-                                       SchemaElement choice = choices.get(0);\r
-                                       // move multiplicity restrictions to choice\r
-                                       if (indicator.getRestriction().max == -1 || (choice.getRestriction().max > 0 && indicator.getRestriction().max > choice.getRestriction().max))\r
-                                               choice.getRestriction().max = indicator.getRestriction().max;\r
-                                       if (indicator.getRestriction().min == 0 || choice.getRestriction().min > indicator.getRestriction().min)\r
-                                               choice.getRestriction().min = indicator.getRestriction().min;\r
-                                       handle(parent, choice, elements);\r
-                                       return;\r
-                               }\r
-                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {\r
-                                       throw new RuntimeException("Cannot handle Sequence with inner ExplicitGroups");\r
-                               }\r
-                               handle(parent, indicator, elements);\r
-                               for (SchemaElement a : anys) {\r
-                                       handleIndicator(parent, indicator, a);\r
-                               }\r
-                       }\r
-               \r
-               } else if (indicator.getType() == SchemaElement.ElementType.CHOICE){\r
-                       if (indicator.getRestriction().single()) {\r
-                               if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0 || groups.size() > 0) {\r
-                                       throw new RuntimeException("Cannot handle Choice that contains something else than Elements");\r
-                               }\r
-                               handle(parent, indicator, elements);\r
-                               \r
-                       } else {\r
-                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {\r
-                                       throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");\r
-                               }\r
-                               handle(parent, indicator,  elements);\r
-                               for (SchemaElement a : anys) {\r
-                                       handleIndicator(parent, indicator, a);\r
-                               }\r
-                       }\r
-               } else if (indicator.getType() == ElementType.ALL) {\r
-                       if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0  || groups.size() > 0) {\r
-                               throw new RuntimeException("Cannot handle All that contains something else than Elements");\r
-                       }\r
-                       if (!indicator.getRestriction().single()) {\r
-                               throw new RuntimeException("All indicator must have maxOccurs=1");\r
-                       }\r
-                       handle(parent, indicator, elements);\r
-               }\r
-       }\r
-       \r
-       \r
-       protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element) {\r
-               Element localElement = element.getElement();\r
-               if (localElement.getName() != null) {\r
-                       SchemaObject eObj = elements.get(localElement); \r
-                       QName refType = localElement.getType();\r
-                       if (refType != null)\r
-                               handleIndicator(parent, indicator, element, null, RefType.Type);\r
-                       else {\r
-                               handleElement(eObj);\r
-                               handleIndicator(parent, indicator, element, null, RefType.Element);\r
-                       }\r
-               } else if (localElement.getRef() != null) {\r
-                       handleIndicator(parent, indicator,element, null, RefType.Reference);\r
-               }\r
-       }\r
-       \r
-       protected String getElementName(Element localElement) {\r
-               if (localElement.getName() != null) {\r
-                       String refName = localElement.getName();\r
-                       QName refType = localElement.getType();\r
-                       if (refType != null)\r
-                               return refName;\r
-               } else if (localElement.getRef() != null) {\r
-                       QName refType = localElement.getRef();\r
-                       if (refType != null)\r
-                               return refType.getLocalPart();\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       protected String getChoiceName(List<SchemaElement> elements) {\r
-               if (elements.size() == 1) {\r
-                       return getElementName(elements.get(0).getElement());\r
-               }\r
-               List<String> names = new ArrayList<String>();\r
-               for (SchemaElement e : elements) {\r
-                       String name = getElementName(e.getElement());\r
-                       if (name != null)\r
-                               names.add(name);\r
-               }\r
-               String name = "";\r
-               for (int i = 0; i < names.size(); i++) {\r
-                       if (i == 0)\r
-                               name = names.get(i);\r
-                       else\r
-                               name += "Or"+names.get(i);\r
-               }\r
-               return name;\r
-       }\r
-               \r
-       protected void handle(SchemaObject parent, Attribute attribute) {\r
-               component.handle(parent, attribute);\r
-       }\r
-       protected void handle(SchemaObject parent, AttributeGroup attribute) {\r
-               component.handle(parent, attribute);\r
-       }\r
-       protected void handle(SchemaObject parent, NamedGroup attribute){\r
-               component.handle(parent, attribute);\r
-       };\r
-       \r
-       protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {\r
-               component.handleSimpleType(parent, simpleType);\r
-       }\r
-       \r
-       \r
-       \r
-       protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {\r
-               ComplexType complexType = complexTypeObj.getComplexType();\r
-               if (complexType != null) {\r
-                       if (complexType.getChoice() != null)\r
-                               handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);\r
-                       if (complexType.getSequence() != null)\r
-                               handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
-                       if (complexType.getAll() != null)\r
-                               handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);\r
-                       if (complexType.getGroup() != null)\r
-                               throw new RuntimeException("Groups not supported");\r
-                       ComplexContent complexContent = complexType.getComplexContent();\r
-                       if (complexContent != null) {\r
-                               ExtensionType extensionType = complexContent.getExtension();\r
-                               if (extensionType != null) {\r
-                                       if (extensionType.getChoice() != null) {\r
-                                               handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);\r
-                                       }\r
-                                       if (extensionType.getSequence()!= null) {\r
-                                               handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);\r
-                                       }\r
-                                       if (extensionType.getAll()!= null) {\r
-                                               handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);\r
-                                       }\r
-                                       if (extensionType.getGroup() != null) {\r
-                                               throw new RuntimeException("Groups not supported");\r
-                                       }\r
-                               }\r
-                       }\r
-//                     SimpleContent simpleContent = complexType.getSimpleContent();\r
-//                     if (simpleContent != null) {\r
-//                             ExtensionType extensionType = simpleContent.getExtension();\r
-//                     }\r
-               }\r
-       }\r
-       \r
-       \r
-       public boolean isElementRef(String ref) {\r
-               return elementName.containsKey(ref);\r
-       }\r
-       \r
-       public boolean isComplexTypeRef(String ref) {\r
-               return complexTypeName.containsKey(ref);\r
-       }\r
-       \r
-       public boolean isSimpleTypeRef(String ref) {\r
-               return simpleTypeName.containsKey(ref);\r
-       }\r
-       \r
-       public IDProvider getIDProvider(Element element) {\r
-               List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof IDProvider) {\r
-                               IDProvider ref = (IDProvider)e.getValue();\r
-                               org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
-                               if (element2 != null) {\r
-                                       if (element.getName().equals(element2.getName()))\r
-                                               idProviders.add(ref);\r
-                               }\r
-                               \r
-                       }\r
-               }\r
-               if (idProviders.size() == 0)\r
-                       return null;\r
-               if (idProviders.size() > 1)\r
-                       throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
-               return idProviders.get(0);\r
-       }\r
-       \r
-       public IDProvider getIDProvider(ComplexType complexType) {\r
-               List<IDProvider> idProviders = new ArrayList<IDProvider>(2);\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof IDProvider) {\r
-                               IDProvider ref = (IDProvider)e.getValue();\r
-                               org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
-                               if (complexType2 != null) {\r
-                                       if (complexType.getName().equals(complexType2.getName()))\r
-                                               idProviders.add(ref);\r
-                               }\r
-\r
-                       }\r
-               }\r
-               if (idProviders.size() == 0)\r
-                       return null;\r
-               if (idProviders.size() > 1)\r
-                       throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");\r
-               return idProviders.get(0);\r
-       }\r
-       \r
-       public List<IDReference> getIDReferences(Element element) {\r
-               List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof IDReference) {\r
-                               IDReference ref = (IDReference)e.getValue();\r
-                               org.simantics.xml.sax.configuration.Element element2 = ref.getElement();\r
-                               if (element2 != null) {\r
-                                       if (element.getName().equals(element2.getName()))\r
-                                               idReferences.add(ref);\r
-                               }\r
-                       }\r
-               }\r
-               return idReferences;\r
-       }\r
-       \r
-       public List<IDReference> getIDReferences(ComplexType complexType) {\r
-               List<IDReference> idReferences = new ArrayList<IDReference>(2);\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof IDReference) {\r
-                               IDReference ref = (IDReference)e.getValue();\r
-                               org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();\r
-                               if (complexType2 != null) {\r
-                                       if (complexType.getName().equals(complexType2.getName()))\r
-                                               idReferences.add(ref);\r
-                               }\r
-                       }\r
-               }\r
-               return idReferences;\r
-       }\r
-       \r
-       public UnrecognizedChildElement getUnknown(ComplexType complexType) {\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof UnrecognizedChildElement) {\r
-                               UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();\r
-                               org.simantics.xml.sax.configuration.ComplexType complexType2 = rule.getComplexType();\r
-                               if (complexType2 != null) {\r
-                                       if (complexType.getName().equals(complexType2.getName()))\r
-                                               return rule;\r
-                               }\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public UnrecognizedChildElement getUnknown(Element element) {\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof UnrecognizedChildElement) {\r
-                               UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();\r
-                               org.simantics.xml.sax.configuration.Element element2 = rule.getElement();\r
-                               if (element2 != null) {\r
-                                       if (element.getName().equals(element2.getName()))\r
-                                               return rule;\r
-                               }\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public Rename getRename(Attribute element) {\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof Rename) {\r
-                               Rename rule = (Rename)e.getValue();\r
-                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);\r
-                               if (!(ref instanceof org.simantics.xml.sax.configuration.Attribute))\r
-                                       continue;\r
-                               org.simantics.xml.sax.configuration.Attribute element2 = (org.simantics.xml.sax.configuration.Attribute)ref;\r
-                               if (element2.getName().equals(element.getName())) {\r
-                                       return rule;\r
-                               }\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public Rename getRename(ComplexType element) {\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof Rename) {\r
-                               Rename rule = (Rename)e.getValue();\r
-                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);\r
-                               if (!(ref instanceof org.simantics.xml.sax.configuration.ComplexType))\r
-                                       continue;\r
-                               org.simantics.xml.sax.configuration.ComplexType element2 = (org.simantics.xml.sax.configuration.ComplexType)ref;\r
-                               if (element2.getName().equals(element.getName())) {\r
-                                       return rule;\r
-                               }\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-       \r
-       public Rename getRename(Element element) {\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof Rename) {\r
-                               Rename rule = (Rename)e.getValue();\r
-                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);\r
-                               if (!(ref instanceof org.simantics.xml.sax.configuration.Element))\r
-                                       continue;\r
-                               org.simantics.xml.sax.configuration.Element element2 = (org.simantics.xml.sax.configuration.Element)ref;\r
-                               if (element2.getName().equals(element.getName())) {\r
-                                       return rule;\r
-                               }\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-        \r
-       \r
-       public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {\r
-               if (parent.getName() == null)\r
-                       parent = parent.getParent();\r
-               if (parent.getName().contains("PipingNetworkSegment"))\r
-                       System.out.println();\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof OrderedChild) {\r
-                               OrderedChild oc = (OrderedChild)e.getValue();\r
-                               org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
-                               org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
-                               org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
-                               if (!oc.getType().equals("original"))\r
-                                       continue;\r
-                               boolean match = false;\r
-                               if (element2 != null) {\r
-                                       if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
-                                               match = true;\r
-                                       }\r
-                               } else if (complexType != null) {\r
-                                       if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
-                                               match = true;\r
-                                       }\r
-                                       \r
-                               }\r
-                               if (match) {\r
-                                       if (child != null) {\r
-                                               if (matchChild(child, ref, refType)) {\r
-                                                       if (oc.getValue().equals("disable"))\r
-                                                               return false;\r
-                                                       else return true;\r
-                                               }\r
-                                       } else { \r
-                                               if (oc.getValue().equals("disable"))\r
-                                                       return false;\r
-                                               return true;\r
-                                       }\r
-                                       \r
-                               }\r
-                       }\r
-               }\r
-               return indicator.order();\r
-       }\r
-       \r
-       public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {\r
-               if (parent.getName() == null)\r
-                       parent = parent.getParent();\r
-               if (parent.getName() == "PipingNetworkSegment")\r
-                       System.out.println();\r
-               for (JAXBElement<?> e : configuration.getConversionRule()) {\r
-                       if (e.getValue() instanceof OrderedChild) {\r
-                               OrderedChild oc = (OrderedChild)e.getValue();\r
-                               org.simantics.xml.sax.configuration.Element element2 = oc.getElement();\r
-                               org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();\r
-                               org.simantics.xml.sax.configuration.Element child = oc.getChild();\r
-                               if (!oc.getType().equals("child"))\r
-                                       continue;\r
-                               boolean match = false;\r
-                               if (element2 != null) {\r
-                                       if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {\r
-                                               match = true;\r
-                                       }\r
-                               } else if (complexType != null) {\r
-                                       if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {\r
-                                               match = true;\r
-                                       }\r
-                                       \r
-                               }\r
-                               if (match) {\r
-                                       if (child != null) {\r
-                                               if (matchChild(child, refName, refType)) {\r
-                                                       if (oc.getValue().equals("disable"))\r
-                                                               return false;\r
-                                                       else return true;\r
-                                               }\r
-                                       } else {\r
-                                               if (oc.getValue().equals("disable"))\r
-                                                       return false;\r
-                                               return true;\r
-                                       }\r
-                                       \r
-                               }\r
-                       }\r
-               }\r
-               return element.many() && element.order();\r
-       }\r
-       \r
-       private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {\r
-               if (refType != null && refType.getLocalPart().equals(child.getName()))\r
-                       return true;\r
-               if (refName != null && refName.equals(child.getName()))\r
-                       return true;\r
-               return false;\r
-       }\r
-       \r
-       public static class TypeEntry {\r
-               String l0Type;\r
-               String binding;\r
-               String javaType;\r
-               String defaultValue;\r
-               boolean id;\r
-               String getterPrefix;\r
-               String getterPostfix;\r
-               String stringPrefix;\r
-               String stringPostfix;\r
-               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix) {\r
-                       super();\r
-                       this.l0Type = l0Type;\r
-                       this.binding = binding;\r
-                       this.javaType = javaType;\r
-                       this.defaultValue = defaultValue;\r
-                       this.id = false;\r
-                       this.getterPrefix = getterPrefix;\r
-                       this.getterPostfix = getterPostfix;\r
-                       this.stringPrefix = stringPrefix;\r
-                       this.stringPostfix = stringPostfix;\r
-               }\r
-               \r
-               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix, boolean id) {\r
-                       super();\r
-                       this.l0Type = l0Type;\r
-                       this.binding = binding;\r
-                       this.javaType = javaType;\r
-                       this.defaultValue = defaultValue;\r
-                       this.id = id;\r
-                       this.getterPrefix = getterPrefix;\r
-                       this.getterPostfix = getterPostfix;\r
-                       this.stringPrefix = stringPrefix;\r
-                       this.stringPostfix = stringPostfix;\r
-               }\r
-               \r
-               public String getValueGetterMethod(String name) {\r
-                       return getterPrefix + name + ".getValue()"+getterPostfix;\r
-               }\r
-               public String getValueGetter(String name) {\r
-                       return getterPrefix + name+getterPostfix;\r
-               }\r
-               public String getValueGetter()\r
-               {\r
-                       return getValueGetter("value");\r
-               }\r
-               \r
-               public String getToString(String name) {\r
-                       return stringPrefix +"("+javaType+")"+name+stringPostfix;\r
-               }\r
-               \r
-               public String getElementToString(String name) {\r
-                       return stringPrefix + name+stringPostfix;\r
-               }\r
-               \r
-       }\r
-       \r
-       public enum InheritanceType{ComplexType,AtomicType,None};\r
-       \r
-       public static class Inheritance {\r
-               public String baseClass;\r
-               public InheritanceType type;\r
-               public TypeEntry atomicType;\r
-               \r
-               public Inheritance(String baseClass) {\r
-                       this.baseClass = baseClass;\r
-                       this.type = InheritanceType.None;\r
-               }\r
-       }\r
-       \r
-       public String getComplexTypePrefix() {\r
-               return component.getComplexTypePrefix();\r
-       }\r
-       public String getAttributeGroupPrefix() {\r
-               return component.getAttributeGroupPrefix();\r
-       }\r
-       public String getName(SchemaObject obj) {\r
-               return component.getName(obj);\r
-       }\r
-       public String getBaseClass(ObjectType type) {\r
-               return component.getBaseClass(type);\r
-       }\r
-       \r
-       \r
-       \r
-       public Inheritance getInheritance(SchemaObject topLevelObj) {\r
-               Inheritance inheritance = null;\r
-               if (topLevelObj.getType() == ObjectType.ELEMENT) {\r
-                       Element topLevelElement = topLevelObj.getElement();\r
-                       inheritance = new Inheritance(getBaseClass(ObjectType.ELEMENT));\r
-                       if (topLevelElement.getType() != null) {\r
-                               QName type = topLevelElement.getType();\r
-                               if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
-                                       SchemaObject obj = complexTypeName.get(type.getLocalPart());\r
-       //                              if (obj == null)\r
-       //                                      obj = simpleTypeName.get(type.getLocalPart());\r
-                                       if (obj != null) {\r
-                                               inheritance.baseClass = getName(obj);\r
-                                               inheritance.type = InheritanceType.ComplexType;\r
-                                       }\r
-                               } else {\r
-                                       TypeEntry entry = getTypeEntry(type);\r
-                                       if (entry != null) {\r
-                                               inheritance.type = InheritanceType.AtomicType;\r
-                                               inheritance.atomicType = entry;\r
-                                       }\r
-                               }\r
-                       }\r
-                       if (inheritance.type == InheritanceType.None) {\r
-                               QName type = getElementBase(topLevelElement);\r
-                               if (type != null) {\r
-                                       if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
-                                               SchemaObject obj = getWithName(type);\r
-                                               inheritance.baseClass = getName(obj);\r
-                                               inheritance.type = InheritanceType.ComplexType;\r
-                                       } else {\r
-                                               TypeEntry entry = getTypeEntry(type);\r
-                                               if (entry != null) {\r
-                                                       inheritance.type = InheritanceType.AtomicType;\r
-                                                       inheritance.atomicType = entry;\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-                       if (inheritance.type == InheritanceType.None) {\r
-                               QName type = topLevelElement.getSubstitutionGroup();\r
-                               if (type != null) {\r
-                                       if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
-                                               SchemaObject obj = getWithName(type);\r
-                                               inheritance.baseClass = getName(obj);\r
-                                               inheritance.type = InheritanceType.ComplexType;\r
-                                       } else {\r
-                                               TypeEntry entry = getTypeEntry(type);\r
-                                               if (entry != null) {\r
-                                                       inheritance.type = InheritanceType.AtomicType;\r
-                                                       inheritance.atomicType = entry;\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-               } else if (topLevelObj.getType() == ObjectType.COMPLEX_TYPE) {\r
-                       ComplexType complexType = topLevelObj.getComplexType();\r
-                       QName type = getComplexTypeBase(complexType);\r
-                       inheritance = new Inheritance(getBaseClass(ObjectType.COMPLEX_TYPE));\r
-                       if (type != null && !type.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) {\r
-                               SchemaObject obj = complexTypeName.get(type.getLocalPart());\r
-                               if (obj != null) {\r
-                                       inheritance.baseClass = getName(obj);\r
-                                       inheritance.type = InheritanceType.ComplexType;\r
-                               }\r
-                       }\r
-                       SimpleContent simpleContent = complexType.getSimpleContent();\r
-                       if (simpleContent != null) {\r
-                               ExtensionType extensionType = simpleContent.getExtension();\r
-                               if (extensionType != null) {\r
-                                       type = extensionType.getBase();\r
-                                       getAtomicTypeInheritance(type, inheritance);\r
-                               }\r
-                       }\r
-               }\r
-               \r
-               return inheritance;\r
-       }       \r
-       /**\r
-        * Goes through chain of SimpleTypes until locates Atomic Type (type defined in XML schema). \r
-        * @param type\r
-        * @param topLevelObj\r
-        * @param inheritance\r
-        */\r
-       public void getAtomicTypeInheritance(QName type, Inheritance inheritance) {\r
-               if (!type.getNamespaceURI().equals(SCHEMA_NS)) {\r
-                       SchemaObject obj = getWithName(type);\r
-                       System.out.println();\r
-                       if (obj.getType() != ObjectType.SIMPLE_TYPE)\r
-                               throw new RuntimeException("SimpleContent does not use SimpleType definition");\r
-                       SimpleType simpleType = obj.getSimpleType();\r
-                       type = getSimpleTypeBase(simpleType);\r
-                       getAtomicTypeInheritance(type, inheritance);\r
-               } else {\r
-                       TypeEntry entry = getTypeEntry(type);\r
-                       if (entry != null) {\r
-                               inheritance.type = InheritanceType.AtomicType;\r
-                               inheritance.atomicType = entry;\r
-                       }\r
-               }\r
-       }\r
-       \r
-       public String getDefaultValue(QName atype) {\r
-               Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());\r
-               if (types == null)\r
-                       return null;\r
-               TypeEntry entry =  types.get(atype.getLocalPart());\r
-               if (entry == null)\r
-                       return null;\r
-               return entry.defaultValue;\r
-       }\r
-\r
-}\r
+package org.simantics.xml.sax;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
+
+import org.simantics.utils.datastructures.BijectionMap;
+import org.simantics.xml.sax.SchemaElement.ElementType;
+import org.simantics.xml.sax.SchemaObject.ObjectType;
+import org.simantics.xml.sax.configuration.AttributeComposition;
+import org.simantics.xml.sax.configuration.Configuration;
+import org.simantics.xml.sax.configuration.IDProvider;
+import org.simantics.xml.sax.configuration.IDReference;
+import org.simantics.xml.sax.configuration.OrderedChild;
+import org.simantics.xml.sax.configuration.Rename;
+import org.simantics.xml.sax.configuration.UnrecognizedChildElement;
+import org.w3._2001.xmlschema.All;
+import org.w3._2001.xmlschema.Annotated;
+import org.w3._2001.xmlschema.Any;
+import org.w3._2001.xmlschema.Attribute;
+import org.w3._2001.xmlschema.AttributeGroup;
+import org.w3._2001.xmlschema.ComplexContent;
+import org.w3._2001.xmlschema.ComplexType;
+import org.w3._2001.xmlschema.Element;
+import org.w3._2001.xmlschema.ExplicitGroup;
+import org.w3._2001.xmlschema.ExtensionType;
+import org.w3._2001.xmlschema.GroupRef;
+import org.w3._2001.xmlschema.LocalElement;
+import org.w3._2001.xmlschema.NamedAttributeGroup;
+import org.w3._2001.xmlschema.NamedGroup;
+import org.w3._2001.xmlschema.OpenAttrs;
+import org.w3._2001.xmlschema.RealGroup;
+import org.w3._2001.xmlschema.Restriction;
+import org.w3._2001.xmlschema.Schema;
+import org.w3._2001.xmlschema.SimpleContent;
+import org.w3._2001.xmlschema.SimpleType;
+import org.w3._2001.xmlschema.TopLevelAttribute;
+import org.w3._2001.xmlschema.TopLevelComplexType;
+import org.w3._2001.xmlschema.TopLevelElement;
+import org.w3._2001.xmlschema.TopLevelSimpleType;
+import org.w3._2001.xmlschema.Union;
+
+public final class SchemaConversionBase {
+       
+       protected Schema schema;
+       protected SchemaConverter converter;
+       protected SchemaConversionComponent component;
+       protected Configuration configuration;
+       
+       public static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
+       public static final String CONVERSION_NS = "http://www.simantics.org/Layer0";
+       
+       protected Map<String,Map<String,TypeEntry>> typeMap;
+       
+       protected String ontologyURI;
+       protected String className;
+       
+       public SchemaConversionBase(SchemaConverter converter, String ontologyUri, String className) {
+               this.converter = converter;
+               this.configuration = converter.getConfiguration();
+               this.ontologyURI = ontologyUri;
+               this.className = className;
+               
+               initTypes();
+       }
+       
+       protected void initTypes() {
+               typeMap = new HashMap<String, Map<String,TypeEntry>>();
+               Map<String,TypeEntry> schemaTypes = new HashMap<String, SchemaConversionBase.TypeEntry>();
+               typeMap.put(SCHEMA_NS, schemaTypes);
+               Map<String,TypeEntry> l0Types = new HashMap<String, SchemaConversionBase.TypeEntry>();
+               typeMap.put(CONVERSION_NS, l0Types);
+               
+               schemaTypes.put("string",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("NMTOKEN",              new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("token",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("ID",                   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","","",true));
+               schemaTypes.put("IDREF",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("Name",                 new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("NCName",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("date",                 new TypeEntry("XML.Date",                       "org.simantics.xml.sax.base.datatypes.literal.Date.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Date", "","org.simantics.xml.sax.base.datatypes.literal.Date.parseDate(",")","(",").toString()"));
+               schemaTypes.put("time",                 new TypeEntry("XML.Time",                       "org.simantics.xml.sax.base.datatypes.literal.Time.BINDING", "org.simantics.xml.sax.base.datatypes.literal.Time", "","org.simantics.xml.sax.base.datatypes.literal.Time.parseTime(",")","(",").toString()"));
+               schemaTypes.put("dateTime",             new TypeEntry("XML.DateTime",           "org.simantics.xml.sax.base.datatypes.literal.DateTime.BINDING", "org.simantics.xml.sax.base.datatypes.literal.DateTime", "","org.simantics.xml.sax.base.datatypes.literal.DateTime.parseDateTime(",")","(",").toString()"));
+               schemaTypes.put("gYearMonth",   new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("gYear",                new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("gMonth",               new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("gMonthDay",    new TypeEntry("L0.String",                      "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("anyURI",               new TypeEntry("L0.URI",                         "Bindings.STRING", "java.lang.String", "","","","",""));
+               schemaTypes.put("double",               new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));
+               schemaTypes.put("float",                new TypeEntry("L0.Float",                       "Bindings.FLOAT",  "float",  "java.lang.Float.NaN","java.lang.Float.parseFloat(",")","java.lang.Float.toString(",")"));
+               schemaTypes.put("decimal",              new TypeEntry("L0.Double",                      "Bindings.DOUBLE", "double", "java.lang.Double.NaN","java.lang.Double.parseDouble(",")","java.lang.Double.toString(",")"));
+               schemaTypes.put("boolean",              new TypeEntry("L0.Boolean",                     "Bindings.BOOLEAN", "boolean", "false","java.lang.Boolean.parseBoolean(",")","java.lang.Boolean.toString(",")"));
+               schemaTypes.put("integer",              new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("positiveInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("nonPositiveInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("nonNegativeInteger", new TypeEntry("L0.Integer",       "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("negativeInteger", new TypeEntry("L0.Integer",          "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("unsignedInt",  new TypeEntry("L0.Integer",             "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("int",                  new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("short",                new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("unsignedShort",new TypeEntry("L0.Integer",                     "Bindings.INTEGER", "int", "0","java.lang.Integer.parseInt(",")","java.lang.Integer.toString(",")"));
+               schemaTypes.put("byte",                 new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));
+               schemaTypes.put("unsignedByte", new TypeEntry("L0.Byte",                        "Bindings.BYTE", "byte", "0","java.lang.Byte.parseByte(",")","java.lang.Byte.toString(",")"));
+               schemaTypes.put("long",                 new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));
+               schemaTypes.put("unsignedLong", new TypeEntry("L0.Long",                        "Bindings.LONG", "long", "0","java.lang.Long.parseLong(",")","java.lang.Long.toString(",")"));
+               schemaTypes.put("base64Binary", new TypeEntry("L0.ByteArray",           "Bindings.BYTE_ARRAY", "byte[]", "new byte[0]","",".getBytes(org.simantics.databoard.util.binary.UTF8.CHARSET)","new java.lang.String(",", org.simantics.databoard.util.binary.UTF8.CHARSET)"));
+               
+               l0Types.put("doubleArray",              new TypeEntry("L0.DoubleArray",  "Bindings.DOUBLE_ARRAY", "double[]", null,null,null,"java.lang.Double.toString(",")"));
+               l0Types.put("stringArray",              new TypeEntry("L0.StringArray",  "Bindings.STRING_ARRAY", "string[]", null,null,null,"",""));
+       }
+       
+       protected TypeEntry getTypeEntry(QName type) {
+               Map<String,TypeEntry> types = typeMap.get(type.getNamespaceURI());
+               if (types == null)
+                       return null;
+               TypeEntry entry = types.get(type.getLocalPart());
+               return entry;
+       }
+       protected TypeEntry getTypeEntry(String type) {
+               for (Map<String,TypeEntry> types : typeMap.values()) {
+                       TypeEntry entry = types.get(type);
+                       if (entry != null)
+                               return entry;
+               }
+               return null;
+       }
+       
+       protected String getL0TypeFromPrimitiveType(QName primitiveType) {
+               TypeEntry entry = getTypeEntry(primitiveType);
+               if (entry == null)
+                       return null;
+               return entry.l0Type;
+       }
+       
+       protected String getL0Type(QName primitiveType) {
+               String type = getL0TypeFromPrimitiveType(primitiveType);
+               if (type != null)
+                       return type;
+               SchemaObject simpleTypeObj = simpleTypeName.get(primitiveType.getLocalPart());
+               if (simpleTypeObj == null)
+                       return null;
+               SimpleType simpleType = simpleTypeObj.getSimpleType();
+               while (simpleType != null) {
+                       QName base = simpleType.getRestriction().getBase();
+                       if (base != null)
+                               return getL0Type(base);
+                       simpleType = simpleType.getRestriction().getSimpleType();
+               }
+               return null;
+       }
+       
+       protected String getBindingFromPrimitiveType(QName primitiveType) {
+               TypeEntry entry = getTypeEntry(primitiveType);
+               if (entry == null)
+                       return null;
+               return entry.binding;
+       }
+       
+       protected String getJavaTypeFromPrimitiveType(QName primitiveType) {
+               TypeEntry entry = getTypeEntry(primitiveType);
+               if (entry == null)
+                       return null;
+               return entry.javaType;
+       }
+       
+       
+       public void init(Schema schema) {       
+               this.schema = schema;
+               
+               preload();
+       }
+       
+       public void handle(SchemaConversionComponent component) {
+               this.component = component;
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
+                       if (attrs instanceof TopLevelAttribute) {
+                               handle((TopLevelAttribute)attrs);
+                               
+                       } else if (attrs instanceof TopLevelComplexType) {
+                               handleComplexType(complexTypes.get(attrs));
+                       } else if (attrs instanceof TopLevelElement) {
+                               handleElement(elements.get(attrs));
+                       } else if (attrs instanceof TopLevelSimpleType) {
+                               handleSimpleType(simpleTypes.get(attrs));
+                       } else if (attrs instanceof NamedAttributeGroup) {
+                               handle((NamedAttributeGroup)attrs);
+                       } else if (attrs instanceof NamedGroup) {
+                               handle((NamedGroup)attrs);
+                       } else {
+                               System.out.println(attrs.getClass().getName());
+                       }
+               }
+       }
+       
+       private Map<String,SchemaObject> elementName = new HashMap<>();
+       private Map<String,SchemaObject> complexTypeName = new HashMap<>();
+       private Map<String,SchemaObject> simpleTypeName = new HashMap<>();
+       private Map<String,SchemaObject> modelGroupName = new HashMap<>();
+       private Map<Element,SchemaObject> elements = new HashMap<>();
+       private Map<ComplexType,SchemaObject> complexTypes = new HashMap<>();
+       private Map<SimpleType,SchemaObject> simpleTypes = new HashMap<>();
+       private Map<NamedGroup,SchemaObject> modelGroups = new HashMap<>();
+       
+       private SchemaObject _getWithName(QName name) {
+               SchemaObject obj = elementName.get(name.getLocalPart());
+               if (obj == null)
+                       obj = complexTypeName.get(name.getLocalPart());
+               if (obj == null)
+                       obj = simpleTypeName.get(name.getLocalPart());
+               return obj;
+       }
+       
+       protected SchemaObject getWithName(QName name) {
+               SchemaObject obj = _getWithName(name);
+               if (obj != null)
+                       return obj;
+               if (name.getNamespaceURI() != null) {
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
+                               if (sc.base != null) {
+                                       obj = sc.base._getWithName(name);
+                                       if (obj != null) {
+                                               return obj;
+                                       }
+                               }
+                       }               
+               }
+               return null;
+       }
+       
+       private NamedAttributeGroup _getAttributeGroup(QName name) {
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
+                       if (attrs instanceof NamedAttributeGroup) {
+                               NamedAttributeGroup group = (NamedAttributeGroup)attrs;
+                               if (group.getName().equals(name.getLocalPart()))
+                                       return group;
+                       }
+               }
+               return null;
+       }
+
+       public NamedAttributeGroup getAttributeGroup(QName name) {
+               NamedAttributeGroup group = _getAttributeGroup(name);
+               if (group != null)
+                       return group;
+               if (name.getNamespaceURI() != null) {
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
+                               if (sc.base != null) {
+                                       group = sc.base._getAttributeGroup(name);
+                                       if (group != null) {
+                                               return group;
+                                       }
+                               }
+                       }       
+               }
+               return null;
+       }
+       
+       private SchemaObject _getElement(QName name) {
+               return elementName.get(name.getLocalPart());
+       }
+       
+       protected SchemaObject getElement(QName name) {
+               SchemaObject obj = _getElement(name);
+               if (obj != null)
+                       return obj;
+               if (name.getNamespaceURI() != null) {
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
+                               if (sc.base != null) {
+                                       obj = sc.base._getElement(name);
+                                       if (obj != null) {
+                                               return obj;
+                                       }
+                               }
+                       }               
+               }
+               return null;
+       }
+       
+       protected SchemaObject getElement(Element element) {
+               return elements.get(element);
+       }
+       
+       
+       private SchemaObject _getComplexType(QName name) {
+               return complexTypeName.get(name.getLocalPart());
+       }
+       
+       protected SchemaObject getComplexType(QName name) {
+               SchemaObject obj = _getComplexType(name);
+               if (obj != null)
+                       return obj;
+               if (name.getNamespaceURI() != null) {
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
+                               if (sc.base != null) {
+                                       obj = sc.base._getComplexType(name);
+                                       if (obj != null) {
+                                               return obj;
+                                       }
+                               }
+                       }               
+               }
+               return null;
+       }
+       
+       protected SchemaObject getComplexType(ComplexType complexType) {
+               return complexTypes.get(complexType);
+       }
+       
+       private SchemaObject _getSimpleType(QName name) {
+               return simpleTypeName.get(name.getLocalPart());
+       }
+       
+       protected SchemaObject getSimpleType(QName name) {
+               SchemaObject obj = _getSimpleType(name);
+               if (obj != null)
+                       return obj;
+               if (name.getNamespaceURI() != null) {
+                       for (SchemaConverter sc : converter.getConverter(name.getNamespaceURI())) {
+                               if (sc.base != null) {
+                                       obj = sc.base._getSimpleType(name);
+                                       if (obj != null) {
+                                               return obj;
+                                       }
+                               }
+                       }               
+               }
+               return null;
+       }
+       
+       protected SchemaObject getSimpleType(SimpleType simpleType) {
+               return simpleTypes.get(simpleType);
+       }
+       
+       protected SchemaObject getWithObj(SchemaObject referrer, OpenAttrs attrs) {
+               // FIXME : this method cannot handle references to other schemas.
+               SchemaObject obj = null;
+               if (attrs instanceof Element)
+                       obj = elements.get(attrs);
+               else if (attrs instanceof ComplexType)
+                       obj = complexTypes.get(attrs);
+               else if (attrs instanceof SimpleType) 
+                       obj = simpleTypes.get(attrs);
+               if (obj == null){
+                       throw new RuntimeException("Cannot locate referred object " + attrs + " when handling " + referrer.getName());
+               }
+               return obj;
+       }
+       
+       private void preload() {
+               Deque<SchemaObject> stack = new ArrayDeque<SchemaObject>();
+               //stack.addAll(schema.getSimpleTypeOrComplexTypeOrGroup());
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
+                       if (attrs instanceof Element) {
+                               Element element = (Element)attrs;
+                               SchemaObject obj = new SchemaObject(element);
+                               obj.setRename(getRename(element));
+                               stack.push(obj);
+                       } else if (attrs instanceof ComplexType) {
+                               ComplexType complexType = (ComplexType)attrs;
+                               SchemaObject obj = new SchemaObject(complexType);
+                               obj.setRename(getRename(complexType));
+                               stack.push(obj);
+                       } else if (attrs instanceof SimpleType) {
+                               SimpleType simpleType = (SimpleType)attrs;
+                               SchemaObject obj = new SchemaObject(simpleType);
+                               stack.push(obj);
+                       }  else if (attrs instanceof Attribute) {
+                               // Attributes are not cached
+                       } else if (attrs instanceof AttributeGroup) {
+                               // Attribute groups are not cached
+                       } else if (attrs instanceof NamedGroup) {
+                               NamedGroup group = (NamedGroup)attrs;
+                               SchemaObject obj = new SchemaObject(group);
+                               stack.push(obj);
+                       } else {
+                               System.out.println(attrs.getClass().getName());
+                       }
+               }
+               
+               while (!stack.isEmpty()) {
+                       SchemaObject object = stack.pop();
+                       switch (object.getType()) {
+                       case COMPLEX_TYPE:{
+                               ComplexType ct = object.getComplexType();
+                               if (ct.getName() != null && ct.getName().length() > 0 && ct instanceof TopLevelComplexType)
+                                       complexTypeName.put(ct.getName(), object);
+                               complexTypes.put(ct, object);
+                               if (ct.getChoice() != null) {
+                                       preload(object,ct.getChoice(), stack);
+                               }
+                               if (ct.getSequence() != null) {
+                                       preload(object,ct.getSequence(), stack);
+                               }
+                               if (ct.getAll() != null) {
+                                       preload(object,ct.getAll(), stack);
+                               }
+                               if (ct.getGroup() != null)
+                                       throw new RuntimeException("Groups not supported");
+                               if (ct.getComplexContent() != null) {
+                                       ComplexContent cc = ct.getComplexContent();
+                                       ExtensionType extensionType = cc.getExtension();
+                                       if (extensionType != null) {
+                                               if (extensionType.getChoice() != null) {
+                                                       preload(object,extensionType.getChoice(), stack);
+                                               }
+                                               if (extensionType.getSequence()!= null) {
+                                                       preload(object,extensionType.getSequence(), stack);
+                                               }
+                                               if (extensionType.getAll()!= null) {
+                                                       preload(object,extensionType.getAll(), stack);
+                                               }
+                                               if (extensionType.getGroup() != null) {
+                                                       throw new RuntimeException("Groups not supported");
+                                                       //preload(object,extensionType.getGroup(), stack);
+                                               }
+                                       }
+                               }
+                               if (ct.getSimpleContent() != null) {
+                                       SimpleContent cc = ct.getSimpleContent();
+                                       ExtensionType extensionType = cc.getExtension();
+                                       if (extensionType != null) {
+                                               if (extensionType.getChoice() != null) {
+                                                       preload(object,extensionType.getChoice(), stack);
+                                               }
+                                               if (extensionType.getSequence()!= null) {
+                                                       preload(object,extensionType.getSequence(), stack);
+                                               }
+                                               if (extensionType.getAll()!= null) {
+                                                       preload(object,extensionType.getAll(), stack);
+                                               }
+                                               if (extensionType.getGroup() != null)
+                                                       throw new RuntimeException("Groups not supported");
+                                       }
+                               }
+                               break;
+                       } 
+                       case ELEMENT:{
+                               Element e = object.getElement();
+                               if (e instanceof TopLevelElement)
+                                       elementName.put(e.getName(), object);
+                               elements.put(e, object);
+                               if (e.getComplexType() != null)
+                                       stack.push(new SchemaObject(object,e.getComplexType()));
+                               if (e.getSimpleType() != null)
+                                       stack.push(new SchemaObject(object,e.getSimpleType()));
+                               break;
+                       } 
+                       case SIMPLE_TYPE:{
+                               SimpleType e = object.getSimpleType();
+                               if (e instanceof TopLevelSimpleType)
+                                       simpleTypeName.put(e.getName(), object);
+                               simpleTypes.put(e, object);
+                               break;
+                       } 
+                       case MODEL_GROUP:{
+                               NamedGroup e = object.getModelGroup();
+                               modelGroupName.put(e.getName(), object);
+                               modelGroups.put(e, object);
+                               break;
+                       }
+                       }
+               } // while
+       }
+       
+       private void preload(SchemaObject parent,ExplicitGroup eg, Deque<SchemaObject> stack) {
+               for (Object o : eg.getParticle()) {
+                       if (o instanceof JAXBElement<?>) {
+                               JAXBElement<?> element = (JAXBElement<?>)o;
+                               Object elemValue = element.getValue();
+                               if (elemValue instanceof Element) {
+                                       SchemaObject obj = new SchemaObject(parent,(Element)elemValue);
+                                       obj.setRename(getRename((Element)elemValue));
+                                       stack.add(obj);
+                               } else if (elemValue instanceof ExplicitGroup) {
+                                       preload(parent,(ExplicitGroup)elemValue, stack);
+                               } else if (elemValue instanceof RealGroup) {
+                                       preload(parent,(RealGroup)elemValue, stack);
+                               } else {
+                                       throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
+                               }
+                       } else if (o instanceof Any){
+                               
+                       } else {
+                               throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());
+                       }
+               }
+       }
+       
+       private void preload(SchemaObject parent, RealGroup eg, Deque<SchemaObject> stack) {
+               System.out.println(eg); 
+               if (eg instanceof NamedGroup) {
+                       SchemaObject obj = new SchemaObject(parent,(NamedGroup)eg);
+                       stack.add(obj);
+               }
+       }
+
+       
+       protected void handle(TopLevelAttribute topLevelAttribute) {
+               handle(null, topLevelAttribute);
+       }
+       
+       protected void handleSimpleType(SchemaObject topLevelSimpleType) {
+               handleSimpleType(null,topLevelSimpleType);
+       }
+       
+       protected void handle(NamedAttributeGroup namedAttributeGroup){
+               handle(null, namedAttributeGroup);
+       }
+       
+       protected void handle(NamedGroup namedAttributeGroup){
+               handle(null, namedAttributeGroup);
+       }
+       
+       protected QName getComplexTypeBase(ComplexType complexType) {
+               if (complexType == null)
+                       return null;
+               ComplexContent complexContent = complexType.getComplexContent();
+               if (complexContent != null) {
+                       ExtensionType extensionType = complexContent.getExtension();
+                       if (extensionType != null) {
+                               QName type = extensionType.getBase();
+                               return type;
+                       }
+               }
+               return null;
+       }
+       
+       protected QName getSimpleTypeBase(SimpleType simpleType) {
+//             if (simpleType == null)
+//                     return null;
+//             return simpleType.getRestriction().getBase();
+               
+               Restriction restriction = simpleType.getRestriction();
+               if (restriction != null) {
+                       QName base = restriction.getBase();
+                       return base;
+               } else if (simpleType.getId() != null) {
+                       throw new RuntimeException(simpleType.getName() + " restriction error");
+               } else if (simpleType.getUnion() != null) {
+                       Union union = simpleType.getUnion();
+                       if (union.getMemberTypes().size() > 0) {
+                               QName base = null;
+                               for (QName type : union.getMemberTypes()) {
+                                       QName sType = null;
+                                       TypeEntry entry = getTypeEntry(type);
+                                       if (entry == null) {
+                                               //SchemaObject obj = simpleTypeName.get(type.getLocalPart());
+                                               SchemaObject obj = getSimpleType(type);
+                                               if (obj == null)
+                                                       throw new RuntimeException(simpleType.getName() + " union has unresolved reference " + type.getLocalPart());
+                                               sType = getSimpleTypeBase(obj.getSimpleType());
+                                       } else {
+                                               sType = type;
+                                       }
+                                       if (base == null)
+                                               base = sType;
+                                       else if (!base.equals(sType)) {
+                                               //FIXME : throw new RuntimeException(simpleType.getName() + " union has incompatible member types");
+                                               // fall back to string. 
+                                               base = new QName(SCHEMA_NS, "string");
+                                               
+                                       }
+                               }
+                               return base;
+                       } else {
+                               if (union.getSimpleType().size() == 0)
+                                       throw new RuntimeException(simpleType.getName() + " union error");
+                               for (SimpleType s : union.getSimpleType()) {
+                                       if (restriction == null)
+                                               restriction = s.getRestriction();
+                                       else  {
+                                               Restriction r = s.getRestriction();
+                                               if (!r.getBase().equals(restriction.getBase())) {
+                                                       Inheritance rI = new Inheritance("");
+                                                       getAtomicTypeInheritance(r.getBase(), rI);
+                                                       Inheritance restI = new Inheritance("");
+                                                       getAtomicTypeInheritance(restriction.getBase(), restI);
+                                                       if (!rI.atomicType.l0Type.equals(restI.atomicType.l0Type))
+                                                               throw new RuntimeException(simpleType.getName() + " union has incompatible restriction bases");
+                                               }
+                                       }
+                               }
+                               QName base = restriction.getBase();
+                               return base;
+                       }
+               } else if (simpleType.getList() != null) {
+                       // FIXME: callers cannot get the information that we have a list.
+                       org.w3._2001.xmlschema.List list = simpleType.getList();
+                       return list.getItemType();
+               } else {
+                       throw new RuntimeException(simpleType.getName() + " restriction error");
+               }
+       }
+       
+       protected QName getElementBase(Element element) {
+               ComplexType complexType = element.getComplexType();
+               SimpleType simpleType = element.getSimpleType();
+               if (complexType != null)
+                       return getComplexTypeBase(complexType);
+               if (simpleType != null) {
+                       return getSimpleTypeBase(simpleType);
+               }
+               return null;
+       }
+       
+       private void handleAttributes(SchemaObject complexType, List<Annotated> attributeOrAttributeGroup) {
+               //name = getComplexTypePrefix()+complexType.getName()
+               
+               Set<Annotated> handled = handleAttributeCompositions(complexType,attributeOrAttributeGroup);
+               for (Annotated annotated : attributeOrAttributeGroup) {
+                       if (handled.contains(annotated))
+                               continue;
+                       if (annotated instanceof Attribute) {
+                               handle(complexType,(Attribute)annotated);
+                       } else if (annotated instanceof AttributeGroup){
+                               handle(complexType,(AttributeGroup)annotated);
+                               //comment("AttributeGroup " + ((AttributeGroup)annotated).getRef().getLocalPart());
+                       } else {
+                               throw new RuntimeException();
+                       }
+               }
+       }
+       
+       protected void handleAttributes(SchemaObject simpleTypeObj) {
+               component.handleAttributes(simpleTypeObj);
+       }
+       
+       protected void handleExtensionAttributes(SchemaObject complexType) {
+               ComplexContent complexContent = complexType.getComplexType().getComplexContent();
+               if (complexContent != null) {
+                       ExtensionType extensionType = complexContent.getExtension();
+                       if (extensionType != null) {
+                               handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());
+                       }
+               }
+               SimpleContent simpleContent = complexType.getComplexType().getSimpleContent();
+               if (simpleContent != null) {
+                       ExtensionType extensionType = simpleContent.getExtension();
+                       if (extensionType != null) {
+                               handleAttributes(complexType, extensionType.getAttributeOrAttributeGroup());
+                       }
+               }
+       }
+       
+       
+       
+       protected void handleComplexTypeAttributes(SchemaObject complexType) {          
+               handleAttributes(complexType,complexType.getComplexType().getAttributeOrAttributeGroup());
+       }
+       
+       protected void handleElementComplexTypeAttributes(SchemaObject complexType) {
+               if (complexType != null) {
+                       handleComplexTypeAttributes(complexType);
+                       handleExtensionAttributes(complexType);
+               }
+       }
+       
+       protected void handleElementSimpleTypeAttributes(SchemaObject simpleType) {
+               if (simpleType != null) {
+                       handleAttributes(simpleType);
+               }
+       }
+       
+       protected Set<Annotated> handleAttributeCompositions(SchemaObject obj, List<Annotated> attributeOrAttributeGroup) {
+               
+               Set<Annotated> handled = new HashSet<Annotated>();
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof AttributeComposition) {
+                               AttributeComposition composition = (AttributeComposition)e.getValue();
+                               if (composition.getAttribute().size() < 2)
+                                       throw new RuntimeException("Attribute Composition is not valid");
+                               BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> map = new BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated>();
+                               for (org.simantics.xml.sax.configuration.Attribute a : composition.getAttribute()) {
+                                       for (Annotated annotated : attributeOrAttributeGroup) {
+                                               if (annotated instanceof Attribute) {
+                                                       Attribute attribute = (Attribute)annotated;
+                                                       QName type = getBaseType(attribute);
+                                                       if (a.getName().equals(attribute.getName()) && type != null && a.getType().equals(type.getLocalPart())) {
+                                                               map.map(a, attribute);
+                                                       }
+                                               }
+                                       }
+                               }
+                               if (composition.getAttribute().size() == map.size()) {
+                                       handled.addAll(map.getRightSet());
+                                       handleAttributeComposition(obj, composition, map);      
+                               }
+                       }
+               }
+               return handled;
+       }
+       
+       protected QName getBaseType(Attribute attribute) {
+               if (attribute.getType() != null)
+                       return attribute.getType();
+               if (attribute.getRef() != null)
+                       return attribute.getRef();
+               SimpleType simpleType = attribute.getSimpleType();
+               if (simpleType != null) {
+                       Restriction restriction = simpleType.getRestriction();
+                       if (restriction != null)
+                               if (restriction.getBase() != null)
+                                       return restriction.getBase();
+               }
+               return null;
+       }
+       
+       protected QName getPrimitiveType(Attribute attribute) {
+               QName type = getBaseType(attribute);
+               String b = getBindingFromPrimitiveType(type);
+               while (b==null && type != null) {
+                       SchemaObject baseType = simpleTypeName.get(type.getLocalPart());
+                       if (baseType != null) {
+                               Restriction restriction = baseType.getSimpleType().getRestriction();
+                               if (restriction != null)
+                                       if (restriction.getBase() != null) {
+                                               type = restriction.getBase();
+                                               b = getBindingFromPrimitiveType(type);
+                                       }
+                       }
+               }
+               return type;
+       }
+       
+       protected Attribute getRefAttribute(QName ref) {
+               for (OpenAttrs attrs : schema.getSimpleTypeOrComplexTypeOrGroup()) {
+                       if (attrs instanceof TopLevelAttribute) {
+                               TopLevelAttribute attribute = (TopLevelAttribute)attrs;
+                               if (attribute.getName().equals(ref.getLocalPart()))
+                                       return attribute;
+                       }
+               }
+               return null;
+       }
+       
+       //protected abstract void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes);
+       protected void handleAttributeComposition(SchemaObject obj, AttributeComposition composition, BijectionMap<org.simantics.xml.sax.configuration.Attribute, Annotated> attributes) {
+               component.handleAttributeComposition(obj, composition, attributes);
+       }
+       
+       
+       
+       
+       protected void handleComplexType(SchemaObject complexType) {
+//             handleComplexTypeAttributes(complexType);
+//             handleComplexTypeExtension(complexType);
+//             handleExtensionAttributes(complexType);
+               component.handleComplexType(complexType);
+       }
+       
+       protected void handleElement(SchemaObject topLevelElement) {
+//             LocalComplexType complexType = topLevelElement.getElement().getComplexType();
+//             
+//             if (complexType != null) {
+//                     SchemaObject complextTypeObj = complexTypes.get(complexType);
+//                     handleElementComplexTypeAttributes(complextTypeObj);
+//                     handleComplexTypeExtension(complextTypeObj);
+//             }       
+               component.handleElement(topLevelElement);
+       }
+       
+       protected enum RefType{Element,Reference,Type};
+       
+       protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement element, String refName, RefType refType) {
+               component.handleIndicator(parent, indicator, element, refName, refType);
+       }
+       protected void handleIndicator(SchemaObject parent, SchemaElement indicator, SchemaElement any) {
+               component.handleIndicator(parent, indicator, any);
+       }
+       protected void handle(SchemaObject parent, SchemaElement indicator, List<SchemaElement> elements) {
+               //component.handle(parent, indicator, elements);
+               if (indicator.getType() == SchemaElement.ElementType.SEQUENCE || (indicator.getType() == SchemaElement.ElementType.CHOICE && indicator.getRestriction().many())) {
+                       for (SchemaElement e : elements) {
+                               handle(parent, indicator, e);
+                       }
+               } else if (indicator.getType() == SchemaElement.ElementType.CHOICE) {
+                       String name = getChoiceName(elements);
+                       component.handleChoice(parent, indicator, elements, name);
+               }
+       }
+       
+       protected void handle(SchemaObject parent, ExplicitGroup eg, SchemaElement.ElementType indicator) {
+               handle(parent, new SchemaElement(eg, indicator));
+       }
+       
+       protected void handle(SchemaObject parent, GroupRef eg, SchemaElement.ElementType indicator) {
+               handle(parent, new SchemaElement(eg, indicator));
+       }
+       
+       protected void handle(SchemaObject parent, SchemaElement indicator) {
+               
+               
+               List<SchemaElement> elements = new ArrayList<SchemaElement>();
+               List<SchemaElement> choices = new ArrayList<SchemaElement>();
+               List<SchemaElement> sequences = new ArrayList<SchemaElement>();
+               List<SchemaElement> alls = new ArrayList<SchemaElement>();
+               List<SchemaElement> anys = new ArrayList<SchemaElement>();
+               List<SchemaElement> groups = new ArrayList<SchemaElement>();
+               
+               for (Object o : indicator.getGroup().getParticle()) {
+                       if (o instanceof JAXBElement<?>) {
+                               JAXBElement<?> element = (JAXBElement<?>)o;
+                               Object elemValue = element.getValue();
+                               if (elemValue instanceof LocalElement) {
+                                       LocalElement localElement = (LocalElement)elemValue;
+                                       elements.add(new SchemaElement(indicator,localElement, ElementType.ELEMENT));
+                               } else if (elemValue instanceof All) {
+                                       alls.add(new SchemaElement(indicator,(All)elemValue, ElementType.ALL));
+                               } else if (elemValue instanceof ExplicitGroup) {
+                                       QName qname = element.getName();
+                                       if ("choice".equals(qname.getLocalPart())) {
+                                               choices.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.CHOICE));
+                                       } else if ("sequence".equals(qname.getLocalPart())) {
+                                               sequences.add(new SchemaElement(indicator,(ExplicitGroup)elemValue, ElementType.SEQUENCE));
+                                       }
+                               } else if (elemValue instanceof RealGroup) {
+                                       if (elemValue instanceof GroupRef) {
+                                               groups.add(new SchemaElement(indicator,(GroupRef)elemValue, ElementType.GROUP_REF));
+                                       } else if (elemValue instanceof NamedGroup) {
+                                               groups.add(new SchemaElement(indicator,(NamedGroup)elemValue, ElementType.NAMED_GROUP));
+                                       } else {
+                                               throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
+                                       }
+                               } else {
+                                       throw new RuntimeException("Unknown ExplicitGroup element " + elemValue.getClass().getName());
+                               }
+                       } else if (o instanceof Any){
+                               anys.add(new SchemaElement(indicator,(Any)o, ElementType.ANY));
+                       } else {
+                               throw new RuntimeException("Unknown ExplicitGroup reference " + o.getClass().getName());
+                       }
+               }
+               
+               if (elements.size() == 0 && choices.size() == 0 && sequences.size() == 0 && alls.size() == 0 && anys.size() == 0 && groups.size() == 0) {
+                       return;
+               }
+               
+               if (indicator.getType() == SchemaElement.ElementType.SEQUENCE) {
+                       if (indicator.getRestriction().single()) {
+                               if (elements.size() > 0) {
+                                       for (SchemaElement e : sequences) {
+                                               handle(parent, e);
+                                       }
+                                       for (SchemaElement c : choices) {
+                                               handle(parent, c);
+                                       }
+                                       
+                                       for (SchemaElement c : alls) {
+                                               handle(parent, c);
+                                       }
+                                       
+                                       for (SchemaElement c : groups) {
+                                               handle(parent, c);
+                                       }
+                                       handle(parent, indicator, elements);
+                                       for (SchemaElement a : anys) {
+                                               handleIndicator(parent, indicator, a);
+                                       }
+                               } else {
+                                       if (sequences.size() > 0) {
+                                               throw new RuntimeException("Cannot handle Sequence with inner Sequences");
+                                       }
+                                       for (SchemaElement c : choices) {
+                                               handle(parent, c);
+                                       }
+                                       for (SchemaElement a : anys) {
+                                               handleIndicator(parent, indicator, a);
+                                       }
+                                       for (SchemaElement c : groups) {
+                                               handle(parent, c);
+                                       }
+                               }
+                       } else {
+                               if (choices.size() == 1 && sequences.size() == 0 && alls.size() == 0 && groups.size() == 0) {
+                                       // special case: handle lone choice inside sequence with maxOccurs > 1 
+                                       SchemaElement choice = choices.get(0);
+                                       // move multiplicity restrictions to choice
+                                       if (indicator.getRestriction().max == -1 || (choice.getRestriction().max > 0 && indicator.getRestriction().max > choice.getRestriction().max))
+                                               choice.getRestriction().max = indicator.getRestriction().max;
+                                       if (indicator.getRestriction().min == 0 || choice.getRestriction().min > indicator.getRestriction().min)
+                                               choice.getRestriction().min = indicator.getRestriction().min;
+                                       handle(parent, choice, elements);
+                                       return;
+                               }
+                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {
+                                       throw new RuntimeException("Cannot handle Sequence with inner ExplicitGroups");
+                               }
+                               handle(parent, indicator, elements);
+                               for (SchemaElement a : anys) {
+                                       handleIndicator(parent, indicator, a);
+                               }
+                       }
+               
+               } else if (indicator.getType() == SchemaElement.ElementType.CHOICE){
+                       if (indicator.getRestriction().single()) {
+                               if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0 || groups.size() > 0) {
+                                       throw new RuntimeException("Cannot handle Choice that contains something else than Elements");
+                                       //System.out.println("Cannot handle Choice that contains something else than Elements");
+                                       //return;
+                               }
+                               handle(parent, indicator, elements);
+                               
+                       } else {
+                               if (sequences.size() > 0 || choices.size() > 0 || alls.size() > 0 || groups.size() > 0) {
+                                       throw new RuntimeException("Cannot handle Choice with inner ExplicitGroups");
+                                       //System.out.println("Cannot handle Choice with inner ExplicitGroups");
+                                       //return;
+                               }
+                               handle(parent, indicator,  elements);
+                               for (SchemaElement a : anys) {
+                                       handleIndicator(parent, indicator, a);
+                               }
+                       }
+               } else if (indicator.getType() == ElementType.ALL) {
+                       if (sequences.size()> 0 || choices.size() > 0 || alls.size() > 0 || anys.size() > 0  || groups.size() > 0) {
+                               throw new RuntimeException("Cannot handle All that contains something else than Elements");
+                       }
+                       if (!indicator.getRestriction().single()) {
+                               throw new RuntimeException("All indicator must have maxOccurs=1");
+                       }
+                       handle(parent, indicator, elements);
+               }
+       }
+       
+       
+       protected void handle(SchemaObject parent, SchemaElement indicator, SchemaElement element) {
+               Element localElement = element.getElement();
+               if (localElement.getName() != null) {
+                       SchemaObject eObj = elements.get(localElement); 
+                       QName refType = localElement.getType();
+                       if (refType != null)
+                               handleIndicator(parent, indicator, element, null, RefType.Type);
+                       else {
+                               handleElement(eObj);
+                               handleIndicator(parent, indicator, element, null, RefType.Element);
+                       }
+               } else if (localElement.getRef() != null) {
+                       handleIndicator(parent, indicator,element, null, RefType.Reference);
+               }
+       }
+       
+       protected String getElementName(Element localElement) {
+               if (localElement.getName() != null) {
+                       String refName = localElement.getName();
+                       QName refType = localElement.getType();
+                       if (refType != null)
+                               return refName;
+               } else if (localElement.getRef() != null) {
+                       QName refType = localElement.getRef();
+                       if (refType != null)
+                               return refType.getLocalPart();
+               }
+               return null;
+       }
+       
+       protected String getChoiceName(List<SchemaElement> elements) {
+               if (elements.size() == 1) {
+                       return getElementName(elements.get(0).getElement());
+               }
+               List<String> names = new ArrayList<String>();
+               for (SchemaElement e : elements) {
+                       String name = getElementName(e.getElement());
+                       if (name != null)
+                               names.add(name);
+               }
+               String name = "";
+               for (int i = 0; i < names.size(); i++) {
+                       if (i == 0)
+                               name = names.get(i);
+                       else
+                               name += "Or"+names.get(i);
+               }
+               return name;
+       }
+               
+       protected void handle(SchemaObject parent, Attribute attribute) {
+               component.handle(parent, attribute);
+       }
+       protected void handle(SchemaObject parent, AttributeGroup attribute) {
+               component.handle(parent, attribute);
+       }
+       protected void handle(SchemaObject parent, NamedGroup attribute){
+               component.handle(parent, attribute);
+       };
+       
+       protected void handleSimpleType(SchemaObject parent, SchemaObject simpleType) {
+               component.handleSimpleType(parent, simpleType);
+       }
+       
+       
+       
+       protected void handleComplexTypeExtension(SchemaObject complexTypeObj) {
+               ComplexType complexType = complexTypeObj.getComplexType();
+               if (complexType != null) {
+                       if (complexType.getChoice() != null)
+                               handle(complexTypeObj, complexType.getChoice(), SchemaElement.ElementType.CHOICE);
+                       if (complexType.getSequence() != null)
+                               handle(complexTypeObj, complexType.getSequence(), SchemaElement.ElementType.SEQUENCE);
+                       if (complexType.getAll() != null)
+                               handle(complexTypeObj, complexType.getAll(), SchemaElement.ElementType.ALL);
+                       if (complexType.getGroup() != null)
+                               throw new RuntimeException("Groups not supported");
+                       ComplexContent complexContent = complexType.getComplexContent();
+                       if (complexContent != null) {
+                               ExtensionType extensionType = complexContent.getExtension();
+                               if (extensionType != null) {
+                                       if (extensionType.getChoice() != null) {
+                                               handle(complexTypeObj, extensionType.getChoice(), SchemaElement.ElementType.CHOICE);
+                                       }
+                                       if (extensionType.getSequence()!= null) {
+                                               handle(complexTypeObj, extensionType.getSequence(), SchemaElement.ElementType.SEQUENCE);
+                                       }
+                                       if (extensionType.getAll()!= null) {
+                                               handle(complexTypeObj, extensionType.getAll(), SchemaElement.ElementType.ALL);
+                                       }
+                                       if (extensionType.getGroup() != null) {
+                                               throw new RuntimeException("Groups not supported");
+                                               //handle(complexTypeObj, extensionType.getGroup(), SchemaElement.ElementType.GROUP_REF);
+                                       }
+                               }
+                       }
+//                     SimpleContent simpleContent = complexType.getSimpleContent();
+//                     if (simpleContent != null) {
+//                             ExtensionType extensionType = simpleContent.getExtension();
+//                     }
+               }
+       }
+       
+       
+       public boolean isElementRef(String ref) {
+               return elementName.containsKey(ref);
+       }
+       
+       public boolean isComplexTypeRef(String ref) {
+               return complexTypeName.containsKey(ref);
+       }
+       
+       public boolean isSimpleTypeRef(String ref) {
+               return simpleTypeName.containsKey(ref);
+       }
+       
+       public IDProvider getIDProvider(Element element) {
+               List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof IDProvider) {
+                               IDProvider ref = (IDProvider)e.getValue();
+                               org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
+                               if (element2 != null) {
+                                       if (element.getName().equals(element2.getName()))
+                                               idProviders.add(ref);
+                               }
+                               
+                       }
+               }
+               if (idProviders.size() == 0)
+                       return null;
+               if (idProviders.size() > 1)
+                       throw new RuntimeException("Element " + element.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
+               return idProviders.get(0);
+       }
+       
+       public IDProvider getIDProvider(ComplexType complexType) {
+               List<IDProvider> idProviders = new ArrayList<IDProvider>(2);
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof IDProvider) {
+                               IDProvider ref = (IDProvider)e.getValue();
+                               org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
+                               if (complexType2 != null) {
+                                       if (complexType.getName().equals(complexType2.getName()))
+                                               idProviders.add(ref);
+                               }
+
+                       }
+               }
+               if (idProviders.size() == 0)
+                       return null;
+               if (idProviders.size() > 1)
+                       throw new RuntimeException("Element " + complexType.getName() + " contains " + idProviders.size() + " id provider rules, only one is allowed.");
+               return idProviders.get(0);
+       }
+       
+       public List<IDReference> getIDReferences(Element element) {
+               List<IDReference> idReferences = new ArrayList<IDReference>(2);
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof IDReference) {
+                               IDReference ref = (IDReference)e.getValue();
+                               org.simantics.xml.sax.configuration.Element element2 = ref.getElement();
+                               if (element2 != null) {
+                                       if (element.getName().equals(element2.getName()))
+                                               idReferences.add(ref);
+                               }
+                       }
+               }
+               return idReferences;
+       }
+       
+       public List<IDReference> getIDReferences(ComplexType complexType) {
+               List<IDReference> idReferences = new ArrayList<IDReference>(2);
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof IDReference) {
+                               IDReference ref = (IDReference)e.getValue();
+                               org.simantics.xml.sax.configuration.ComplexType complexType2 = ref.getComplexType();
+                               if (complexType2 != null) {
+                                       if (complexType.getName().equals(complexType2.getName()))
+                                               idReferences.add(ref);
+                               }
+                       }
+               }
+               return idReferences;
+       }
+       
+       public UnrecognizedChildElement getUnknown(ComplexType complexType) {
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof UnrecognizedChildElement) {
+                               UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
+                               org.simantics.xml.sax.configuration.ComplexType complexType2 = rule.getComplexType();
+                               if (complexType2 != null) {
+                                       if (complexType.getName().equals(complexType2.getName()))
+                                               return rule;
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       public UnrecognizedChildElement getUnknown(Element element) {
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof UnrecognizedChildElement) {
+                               UnrecognizedChildElement rule = (UnrecognizedChildElement)e.getValue();
+                               org.simantics.xml.sax.configuration.Element element2 = rule.getElement();
+                               if (element2 != null) {
+                                       if (element.getName().equals(element2.getName()))
+                                               return rule;
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       public Rename getRename(Attribute element) {
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof Rename) {
+                               Rename rule = (Rename)e.getValue();
+                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
+                               if (!(ref instanceof org.simantics.xml.sax.configuration.Attribute))
+                                       continue;
+                               org.simantics.xml.sax.configuration.Attribute element2 = (org.simantics.xml.sax.configuration.Attribute)ref;
+                               if (element2.getName().equals(element.getName())) {
+                                       return rule;
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       public Rename getRename(ComplexType element) {
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof Rename) {
+                               Rename rule = (Rename)e.getValue();
+                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
+                               if (!(ref instanceof org.simantics.xml.sax.configuration.ComplexType))
+                                       continue;
+                               org.simantics.xml.sax.configuration.ComplexType element2 = (org.simantics.xml.sax.configuration.ComplexType)ref;
+                               if (element2.getName().equals(element.getName())) {
+                                       return rule;
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       public Rename getRename(Element element) {
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof Rename) {
+                               Rename rule = (Rename)e.getValue();
+                               Object ref = rule.getElementOrComplexTypeOrAttribute().get(0);
+                               if (!(ref instanceof org.simantics.xml.sax.configuration.Element))
+                                       continue;
+                               org.simantics.xml.sax.configuration.Element element2 = (org.simantics.xml.sax.configuration.Element)ref;
+                               if (element2.getName().equals(element.getName())) {
+                                       return rule;
+                               }
+                       }
+               }
+               return null;
+       }
+        
+       
+       public boolean useOriginalList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String ref, QName refType) {
+               if (parent.getName() == null)
+                       parent = parent.getParent();
+               if (parent.getName().contains("PipingNetworkSegment"))
+                       System.out.println();
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof OrderedChild) {
+                               OrderedChild oc = (OrderedChild)e.getValue();
+                               org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
+                               org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
+                               org.simantics.xml.sax.configuration.Element child = oc.getChild();
+                               if (!oc.getType().equals("original"))
+                                       continue;
+                               boolean match = false;
+                               if (element2 != null) {
+                                       if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
+                                               match = true;
+                                       }
+                               } else if (complexType != null) {
+                                       if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
+                                               match = true;
+                                       }
+                                       
+                               }
+                               if (match) {
+                                       if (child != null) {
+                                               if (matchChild(child, ref, refType)) {
+                                                       if (oc.getValue().equals("disable"))
+                                                               return false;
+                                                       else return true;
+                                               }
+                                       } else { 
+                                               if (oc.getValue().equals("disable"))
+                                                       return false;
+                                               return true;
+                                       }
+                                       
+                               }
+                       }
+               }
+               return indicator.order();
+       }
+       
+       public boolean useElementList(SchemaObject parent, SchemaElement indicator, SchemaElement element,  boolean reference, String refName, QName refType) {
+               if (parent.getName() == null)
+                       parent = parent.getParent();
+               if (parent.getName() == "PipingNetworkSegment")
+                       System.out.println();
+               for (JAXBElement<?> e : configuration.getConversionRule()) {
+                       if (e.getValue() instanceof OrderedChild) {
+                               OrderedChild oc = (OrderedChild)e.getValue();
+                               org.simantics.xml.sax.configuration.Element element2 = oc.getElement();
+                               org.simantics.xml.sax.configuration.ComplexType complexType = oc.getComplexType();
+                               org.simantics.xml.sax.configuration.Element child = oc.getChild();
+                               if (!oc.getType().equals("child"))
+                                       continue;
+                               boolean match = false;
+                               if (element2 != null) {
+                                       if (parent.getType() == ObjectType.ELEMENT && parent.getName().equals(element2.getName())) {
+                                               match = true;
+                                       }
+                               } else if (complexType != null) {
+                                       if (parent.getType() == ObjectType.COMPLEX_TYPE && parent.getName() != null && parent.getName().equals(complexType.getName())) {
+                                               match = true;
+                                       }
+                                       
+                               }
+                               if (match) {
+                                       if (child != null) {
+                                               if (matchChild(child, refName, refType)) {
+                                                       if (oc.getValue().equals("disable"))
+                                                               return false;
+                                                       else return true;
+                                               }
+                                       } else {
+                                               if (oc.getValue().equals("disable"))
+                                                       return false;
+                                               return true;
+                                       }
+                                       
+                               }
+                       }
+               }
+               return element.many() && element.order();
+       }
+       
+       private boolean matchChild(org.simantics.xml.sax.configuration.Element child, String refName, QName refType) {
+               if (refType != null && refType.getLocalPart().equals(child.getName()))
+                       return true;
+               if (refName != null && refName.equals(child.getName()))
+                       return true;
+               return false;
+       }
+       
+       public static class TypeEntry {
+               String l0Type;
+               String binding;
+               String javaType;
+               String defaultValue;
+               boolean id;
+               String getterPrefix;
+               String getterPostfix;
+               String stringPrefix;
+               String stringPostfix;
+               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix) {
+                       super();
+                       this.l0Type = l0Type;
+                       this.binding = binding;
+                       this.javaType = javaType;
+                       this.defaultValue = defaultValue;
+                       this.id = false;
+                       this.getterPrefix = getterPrefix;
+                       this.getterPostfix = getterPostfix;
+                       this.stringPrefix = stringPrefix;
+                       this.stringPostfix = stringPostfix;
+               }
+               
+               public TypeEntry(String l0Type, String binding, String javaType, String defaultValue, String getterPrefix, String getterPostfix, String stringPrefix, String stringPostfix, boolean id) {
+                       super();
+                       this.l0Type = l0Type;
+                       this.binding = binding;
+                       this.javaType = javaType;
+                       this.defaultValue = defaultValue;
+                       this.id = id;
+                       this.getterPrefix = getterPrefix;
+                       this.getterPostfix = getterPostfix;
+                       this.stringPrefix = stringPrefix;
+                       this.stringPostfix = stringPostfix;
+               }
+               
+               public String getValueGetterMethod(String name) {
+                       return getterPrefix + name + ".getValue()"+getterPostfix;
+               }
+               public String getValueGetter(String name) {
+                       return getterPrefix + name+getterPostfix;
+               }
+               public String getValueGetter()
+               {
+                       return getValueGetter("value");
+               }
+               
+               public String getToString(String name) {
+                       return stringPrefix +"("+javaType+")"+name+stringPostfix;
+               }
+               
+               public String getElementToString(String name) {
+                       return stringPrefix + name+stringPostfix;
+               }
+               
+       }
+       
+       public enum InheritanceType{ComplexType,AtomicType,None};
+       
+       public static class Inheritance {
+               public String baseClass;
+               public InheritanceType type;
+               public TypeEntry atomicType;
+               
+               public Inheritance(String baseClass) {
+                       this.baseClass = baseClass;
+                       this.type = InheritanceType.None;
+               }
+       }
+       
+       public String getComplexTypePrefix() {
+               return component.getComplexTypePrefix();
+       }
+       public String getAttributeGroupPrefix() {
+               return component.getAttributeGroupPrefix();
+       }
+       public String getName(SchemaObject obj) {
+               return component.getName(obj);
+       }
+       public String getBaseClass(ObjectType type) {
+               return component.getBaseClass(type);
+       }
+       
+       
+       
+       public Inheritance getInheritance(SchemaObject topLevelObj) {
+               Inheritance inheritance = null;
+               if (topLevelObj.getType() == ObjectType.ELEMENT) {
+                       Element topLevelElement = topLevelObj.getElement();
+                       inheritance = new Inheritance(getBaseClass(ObjectType.ELEMENT));
+                       if (topLevelElement.getType() != null) {
+                               QName type = topLevelElement.getType();
+                               if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
+                                       SchemaObject obj = complexTypeName.get(type.getLocalPart());
+       //                              if (obj == null)
+       //                                      obj = simpleTypeName.get(type.getLocalPart());
+                                       if (obj != null) {
+                                               inheritance.baseClass = getName(obj);
+                                               inheritance.type = InheritanceType.ComplexType;
+                                       }
+                               } else {
+                                       TypeEntry entry = getTypeEntry(type);
+                                       if (entry != null) {
+                                               inheritance.type = InheritanceType.AtomicType;
+                                               inheritance.atomicType = entry;
+                                       }
+                               }
+                       }
+                       if (inheritance.type == InheritanceType.None) {
+                               QName type = getElementBase(topLevelElement);
+                               if (type != null) {
+                                       if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
+                                               SchemaObject obj = getWithName(type);
+                                               inheritance.baseClass = getName(obj);
+                                               inheritance.type = InheritanceType.ComplexType;
+                                       } else {
+                                               TypeEntry entry = getTypeEntry(type);
+                                               if (entry != null) {
+                                                       inheritance.type = InheritanceType.AtomicType;
+                                                       inheritance.atomicType = entry;
+                                               }
+                                       }
+                               }
+                       }
+                       if (inheritance.type == InheritanceType.None) {
+                               QName type = topLevelElement.getSubstitutionGroup();
+                               if (type != null) {
+                                       if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
+                                               SchemaObject obj = getWithName(type);
+                                               inheritance.baseClass = getName(obj);
+                                               inheritance.type = InheritanceType.ComplexType;
+                                       } else {
+                                               TypeEntry entry = getTypeEntry(type);
+                                               if (entry != null) {
+                                                       inheritance.type = InheritanceType.AtomicType;
+                                                       inheritance.atomicType = entry;
+                                               }
+                                       }
+                               }
+                       }
+               } else if (topLevelObj.getType() == ObjectType.COMPLEX_TYPE) {
+                       ComplexType complexType = topLevelObj.getComplexType();
+                       QName type = getComplexTypeBase(complexType);
+                       inheritance = new Inheritance(getBaseClass(ObjectType.COMPLEX_TYPE));
+                       if (type != null && !type.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) {
+                               SchemaObject obj = complexTypeName.get(type.getLocalPart());
+                               if (obj != null) {
+                                       inheritance.baseClass = getName(obj);
+                                       inheritance.type = InheritanceType.ComplexType;
+                               }
+                       }
+                       SimpleContent simpleContent = complexType.getSimpleContent();
+                       if (simpleContent != null) {
+                               ExtensionType extensionType = simpleContent.getExtension();
+                               if (extensionType != null) {
+                                       type = extensionType.getBase();
+                                       getAtomicTypeInheritance(type, inheritance);
+                               }
+                       }
+               }
+               
+               return inheritance;
+       }       
+       /**
+        * Goes through chain of SimpleTypes until locates Atomic Type (type defined in XML schema). 
+        * @param type
+        * @param topLevelObj
+        * @param inheritance
+        */
+       public void getAtomicTypeInheritance(QName type, Inheritance inheritance) {
+               if (!type.getNamespaceURI().equals(SCHEMA_NS)) {
+                       SchemaObject obj = getWithName(type);
+                       if (obj.getType() != ObjectType.SIMPLE_TYPE)
+                               throw new RuntimeException("SimpleContent does not use SimpleType definition");
+                       SimpleType simpleType = obj.getSimpleType();
+                       type = getSimpleTypeBase(simpleType);
+                       getAtomicTypeInheritance(type, inheritance);
+               } else {
+                       TypeEntry entry = getTypeEntry(type);
+                       if (entry != null) {
+                               inheritance.type = InheritanceType.AtomicType;
+                               inheritance.atomicType = entry;
+                       }
+               }
+       }
+       
+       public String getDefaultValue(QName atype) {
+               Map<String,TypeEntry> types = typeMap.get(atype.getNamespaceURI());
+               if (types == null)
+                       return null;
+               TypeEntry entry =  types.get(atype.getLocalPart());
+               if (entry == null)
+                       return null;
+               return entry.defaultValue;
+       }
+
+}
index ed11c14cd7ad762f9cb4ffc81b49db92ad1387ef..1b2b3722606832c8f55fc62cc7c082e97cc1eab6 100644 (file)
-package org.simantics.xml.sax;\r
-\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.ArrayList;\r
-import java.util.Date;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import javax.xml.bind.JAXBContext;\r
-import javax.xml.bind.JAXBElement;\r
-import javax.xml.bind.JAXBException;\r
-import javax.xml.bind.Unmarshaller;\r
-\r
-import org.simantics.utils.datastructures.MapList;\r
-import org.simantics.xml.sax.configuration.Configuration;\r
-import org.w3._2001.xmlschema.Annotation;\r
-import org.w3._2001.xmlschema.Import;\r
-import org.w3._2001.xmlschema.Include;\r
-import org.w3._2001.xmlschema.OpenAttrs;\r
-import org.w3._2001.xmlschema.Schema;\r
-\r
-/**\r
- * This file is developed for XMpLant / Proteus schema conversion is not able to handle all XML Schema definitions.\r
- * \r
- * @author mlmarko\r
- *\r
- */\r
-public class SchemaConverter {\r
-       \r
-       File outputPlugin;\r
-       File schemaFile;\r
-       File conversionFile;\r
-       File ontologyFile;\r
-       File parserDir;\r
-       Schema schema;\r
-       Configuration configuration;\r
-       \r
-       String pluginName;\r
-       \r
-       private String[] header;\r
-       \r
-       boolean createPGraph = true;\r
-       boolean createImporter = true;\r
-       boolean createExporter = true;\r
-       \r
-       private List<SchemaConverter> parent = new ArrayList<>();\r
-       private List<SchemaConverter> subConverters = new ArrayList<>();\r
-       private Map<String,SchemaConverter> fileMap;\r
-       private MapList<String,SchemaConverter> schemaNSMap;\r
-       private MapList<String,SchemaConverter> shortNameMap;\r
-       \r
-       String schemaNs;\r
-       String ontologyUri;\r
-       String className;\r
-       String name;\r
-       String shortName;\r
-       \r
-       SchemaConversionBase base;\r
-       \r
-       private ManualSchemaFileImport fileImport;\r
-       \r
-       public SchemaConverter(File schemaFile, File conversionFile, File outputPlugin) throws IOException {\r
-               this(null,schemaFile,conversionFile,outputPlugin);\r
-       }\r
-       \r
-       public SchemaConverter(SchemaConverter parent,File schemaFile, File conversionFile, File outputPlugin) throws IOException {\r
-               \r
-               this.outputPlugin = outputPlugin;\r
-               this.schemaFile = schemaFile;\r
-               this.conversionFile = conversionFile;\r
-               \r
-               pluginName = outputPlugin.getName();\r
-               String packageParts[] = pluginName.split("\\.");\r
-               String outputLoc = outputPlugin.getAbsolutePath();\r
-               outputLoc += "/src";\r
-               for (String s : packageParts)\r
-                       outputLoc += "/"+s;\r
-               String outputGraph = outputPlugin.getAbsolutePath();\r
-               outputGraph += "/graph";\r
-               outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";\r
-               \r
-               \r
-               this.ontologyFile = new File(outputGraph);\r
-               this.parserDir = new File(outputLoc);\r
-               \r
-               if (parent != null) {\r
-                       this.parent.add(parent);\r
-                       parent.subConverters.add(this);\r
-               } else {\r
-                       fileMap = new HashMap<>();\r
-                       schemaNSMap = new MapList<>();\r
-                       shortNameMap = new MapList<>();\r
-               }\r
-               getRoot().fileMap.put(schemaFile.getAbsolutePath(), this);\r
-       }\r
-       \r
-       public List<SchemaConverter> getConverter(String schemaNS) {\r
-               return getRoot().schemaNSMap.getValues(schemaNS);\r
-       }\r
-       \r
-       public void setFileImport(ManualSchemaFileImport fileImport) {\r
-               this.fileImport = fileImport;\r
-       }\r
-\r
-       \r
-       public void setCreateExporter(boolean createExporter) {\r
-               this.createExporter = createExporter;\r
-       }\r
-       \r
-       public void setCreateImporter(boolean createImporter) {\r
-               this.createImporter = createImporter;\r
-       }\r
-       \r
-       public void setCreatePGraph(boolean createPGraph) {\r
-               this.createPGraph = createPGraph;\r
-       }\r
-       \r
-       protected SchemaConverter createSubConverter(String location) throws JAXBException, IOException {\r
-               File directory = schemaFile.getParentFile();\r
-               File schemaFile = new File(directory.getAbsolutePath()+File.separator+location);\r
-               if (!schemaFile.exists()) {\r
-                       if (getRoot().fileImport != null) {\r
-                               schemaFile = getRoot().fileImport.getFileForLocation(location);\r
-                       }\r
-                       if (!schemaFile.exists())\r
-                               throw new FileNotFoundException(schemaFile.getAbsolutePath());\r
-               }\r
-               SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));\r
-               if (subConverter == null) {\r
-                       subConverter = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);\r
-                       subConverter.createPGraph = this.createPGraph;\r
-                       subConverter.createImporter = this.createImporter;\r
-                       subConverter.createExporter = this.createExporter;\r
-               } else {\r
-                       subConverter.parent.add(this);\r
-               }\r
-               return subConverter;\r
-       }\r
-       \r
-       protected SchemaConverter getRoot() {\r
-               SchemaConverter s = this;\r
-               while (s.parent.size() > 0)\r
-                       s = s.parent.get(0);\r
-               return s;\r
-       }\r
-       \r
-       public void convert() throws JAXBException, IOException {\r
-               \r
-               init();\r
-               doConvert();\r
-       }\r
-       \r
-       boolean init = false;\r
-       \r
-       protected void assignShortName() {\r
-               shortName = name.substring(0, 3).toUpperCase();\r
-               SchemaConverter root = getRoot();\r
-               if (!root.shortNameMap.containsKey(shortName)) {\r
-                       root.shortNameMap.add(shortName, this);\r
-                       return;\r
-               } else {\r
-                       SchemaConverter sc = root.shortNameMap.getValues(shortName).get(0);\r
-                       if (sc.schemaNs.equals(schemaNs)) {\r
-                               root.shortNameMap.add(shortName, this);\r
-                               return;\r
-                       }\r
-               }\r
-               int i = 1;\r
-               while (true) {\r
-                       String n = shortName+i;\r
-                       if (!root.shortNameMap.containsKey(n)) {\r
-                               shortName = n;\r
-                               root.shortNameMap.add(shortName, this);\r
-                               return;\r
-                       } else {\r
-                               SchemaConverter sc = root.shortNameMap.getValues(n).get(0);\r
-                               if (sc.schemaNs.equals(schemaNs)) {\r
-                                       shortName = n;\r
-                                       root.shortNameMap.add(shortName, this);\r
-                                       return;\r
-                               }\r
-                       }\r
-                       i++;\r
-               }\r
-       }\r
-       \r
-       protected void init() throws IOException, JAXBException {\r
-               if (init)\r
-                       return;\r
-               init = true;\r
-               JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");\r
-               Unmarshaller u = jc.createUnmarshaller();\r
-               //u.setSchema(schema);\r
-        InputStream fileStream = new FileInputStream(schemaFile);\r
-               schema = (Schema)u.unmarshal(fileStream);\r
-               \r
-               if (conversionFile != null) {\r
-                       jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");\r
-                       u = jc.createUnmarshaller();\r
-                       fileStream = new FileInputStream(conversionFile);\r
-                       configuration = (Configuration)((JAXBElement<?>)u.unmarshal(fileStream)).getValue();\r
-               } else {\r
-                       configuration = new Configuration();\r
-               }\r
-               \r
-               header = new String[4];\r
-               header[0] = "Generated with org.simantics.xml.sax XML schema converter";\r
-               header[1] = "";\r
-               header[2] = "File " + schemaFile.getAbsolutePath();\r
-               header[3] = "Date " + new Date().toString();\r
-               \r
-               schemaNs = schema.getTargetNamespace();\r
-               ontologyUri = schemaNs;\r
-               if (ontologyUri == null) {\r
-                       ontologyUri = getSchemaFile().getName();\r
-                       \r
-                       int index = ontologyUri.lastIndexOf(".");\r
-                       if (index > 0)\r
-                               ontologyUri = ontologyUri.substring(0, index);\r
-               } \r
-               ontologyUri = ontologyUri.replaceAll(" ", "_");\r
-               String parts[] = ontologyUri.split("/");\r
-               name = parts[parts.length-1];\r
-               name = name.replaceAll("\\.", "_");\r
-               if (!ontologyUri.startsWith("http://"))\r
-                       ontologyUri = "http://" + ontologyUri.replaceAll("/", "_");\r
-               else\r
-                       ontologyUri = "http://" + ontologyUri.substring("http://".length()).replaceAll("/", "_");\r
-               \r
-               String version = schema.getVersion();\r
-               if (version == null)\r
-                       version = "1.0";\r
-               ontologyUri +="-"+ version;\r
-\r
-               \r
-               className = getPluginName() + "." + name;\r
-               assignShortName();\r
-               if (schemaNs != null)\r
-                       getRoot().schemaNSMap.add(schemaNs, this);\r
-               \r
-               \r
-               for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {\r
-                       if (attrs instanceof Import) {\r
-                               Import imp = (Import)attrs;\r
-                               String location = imp.getSchemaLocation();\r
-                               SchemaConverter sc = createSubConverter(location);\r
-                               sc.init();\r
-                       } else if (attrs instanceof Include) {\r
-                               Include inc = (Include)attrs;\r
-                               String location = inc.getSchemaLocation();\r
-                               SchemaConverter sc = createSubConverter(location);\r
-                               sc.init();\r
-                       } else if (attrs instanceof Annotation) {\r
-                               \r
-                       } else {\r
-                               throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");\r
-                       }\r
-               }\r
-       }\r
-       \r
-       protected void doConvert() throws IOException, JAXBException {\r
-               if (!ontologyFile.exists()) {\r
-                       ontologyFile.getParentFile().mkdirs();\r
-                       ontologyFile.createNewFile();\r
-               }\r
-               if (!parserDir.exists())\r
-                       parserDir.mkdirs();\r
-               \r
-               for (SchemaConverter sc : subConverters)\r
-                       sc.doConvert();\r
-               \r
-               base = new SchemaConversionBase(this,ontologyUri,className);\r
-               base.init(schema);\r
-               \r
-               if (createPGraph) {\r
-                       OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);\r
-                       ontologyGenerator.createOntology();\r
-               }\r
-               if (createImporter) {\r
-                       ImporterGenerator importerGenerator = new ImporterGenerator(this,base);\r
-                       importerGenerator.createParser();\r
-               }\r
-               if (createExporter) {\r
-                       ExporterGenerator exporterGenerator = new ExporterGenerator(this,base);\r
-                       exporterGenerator.createParser();\r
-               }\r
-               base.component = null;\r
-       }\r
-       \r
-       public File getOntologyFile() {\r
-               return ontologyFile;\r
-       }\r
-       public File getParserDir() {\r
-               return parserDir;\r
-       }\r
-       \r
-       public Schema getSchema() {\r
-               return schema;\r
-       }\r
-       \r
-       public File getSchemaFile() {\r
-               return schemaFile;\r
-       }\r
-       \r
-       public String getPluginName() {\r
-               return pluginName;\r
-       }\r
-       \r
-       public String[] getHeader() {\r
-               return header;\r
-       }\r
-       \r
-       public Configuration getConfiguration() {\r
-               return configuration;\r
-       }\r
-\r
-\r
-}\r
+package org.simantics.xml.sax;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.simantics.utils.datastructures.MapList;
+import org.simantics.xml.sax.configuration.Configuration;
+import org.w3._2001.xmlschema.Annotation;
+import org.w3._2001.xmlschema.Import;
+import org.w3._2001.xmlschema.Include;
+import org.w3._2001.xmlschema.OpenAttrs;
+import org.w3._2001.xmlschema.Schema;
+
+/**
+ * This file is developed for XMpLant / Proteus schema conversion is not able to handle all XML Schema definitions.
+ * 
+ * @author mlmarko
+ *
+ */
+public class SchemaConverter {
+       
+       File outputPlugin;
+       File schemaFile;
+       File conversionFile;
+       File ontologyFile;
+       File parserDir;
+       Schema schema;
+       Configuration configuration;
+       
+       String pluginName;
+       
+       private String[] header;
+       
+       boolean createPGraph = true;
+       boolean createImporter = true;
+       boolean createExporter = true;
+       
+       private List<SchemaConverter> parent = new ArrayList<>();
+       private List<SchemaConverter> subConverters = new ArrayList<>();
+       private Map<String,SchemaConverter> fileMap;
+       private MapList<String,SchemaConverter> schemaNSMap;
+       private MapList<String,SchemaConverter> shortNameMap;
+       
+       String schemaNs;
+       String ontologyUri;
+       String className;
+       String name;
+       String shortName;
+       
+       SchemaConversionBase base;
+       
+       private ManualSchemaFileImport fileImport;
+       
+       public SchemaConverter(File schemaFile, File conversionFile, File outputPlugin) throws IOException {
+               this(null,schemaFile,conversionFile,outputPlugin);
+       }
+       
+       public SchemaConverter(SchemaConverter parent,File schemaFile, File conversionFile, File outputPlugin) throws IOException {
+               
+               this.outputPlugin = outputPlugin;
+               this.schemaFile = schemaFile;
+               this.conversionFile = conversionFile;
+               
+               pluginName = outputPlugin.getName();
+               String packageParts[] = pluginName.split("\\.");
+               String outputLoc = outputPlugin.getAbsolutePath();
+               outputLoc += "/src";
+               for (String s : packageParts)
+                       outputLoc += "/"+s;
+               String outputGraph = outputPlugin.getAbsolutePath();
+               outputGraph += "/graph";
+               outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";
+               
+               
+               this.ontologyFile = new File(outputGraph);
+               this.parserDir = new File(outputLoc);
+               
+               if (parent != null) {
+                       this.parent.add(parent);
+                       parent.subConverters.add(this);
+               } else {
+                       fileMap = new HashMap<>();
+                       schemaNSMap = new MapList<>();
+                       shortNameMap = new MapList<>();
+               }
+               getRoot().fileMap.put(schemaFile.getAbsolutePath(), this);
+       }
+       
+       public List<SchemaConverter> getConverter(String schemaNS) {
+               return getRoot().schemaNSMap.getValues(schemaNS);
+       }
+       
+       public void setFileImport(ManualSchemaFileImport fileImport) {
+               this.fileImport = fileImport;
+       }
+
+       
+       public void setCreateExporter(boolean createExporter) {
+               this.createExporter = createExporter;
+       }
+       
+       public void setCreateImporter(boolean createImporter) {
+               this.createImporter = createImporter;
+       }
+       
+       public void setCreatePGraph(boolean createPGraph) {
+               this.createPGraph = createPGraph;
+       }
+       
+       protected SchemaConverter createSubConverter(String location) throws JAXBException, IOException {
+               File directory = schemaFile.getParentFile();
+               File schemaFile = new File(directory.getAbsolutePath()+File.separator+location);
+               if (!schemaFile.exists()) {
+                       if (getRoot().fileImport != null) {
+                               schemaFile = getRoot().fileImport.getFileForLocation(location);
+                       }
+                       if (!schemaFile.exists())
+                               throw new FileNotFoundException(schemaFile.getAbsolutePath());
+               }
+               SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));
+               if (subConverter == null) {
+                       subConverter = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);
+                       subConverter.createPGraph = this.createPGraph;
+                       subConverter.createImporter = this.createImporter;
+                       subConverter.createExporter = this.createExporter;
+               } else {
+                       subConverter.parent.add(this);
+               }
+               return subConverter;
+       }
+       
+       protected SchemaConverter getRoot() {
+               SchemaConverter s = this;
+               if (s.fileMap != null)
+                       return s;
+               while (s.parent.size() > 0) {
+                       s = s.parent.get(0);
+                       if (s.fileMap != null)
+                               return s;
+               }
+               return s;
+       }
+       
+       public void convert() throws JAXBException, IOException {
+               
+               init();
+               doConvert();
+       }
+       
+       boolean init = false;
+       
+       protected void assignShortName() {
+               shortName = name.substring(0, 3).toUpperCase();
+               SchemaConverter root = getRoot();
+               if (!root.shortNameMap.containsKey(shortName)) {
+                       root.shortNameMap.add(shortName, this);
+                       return;
+               } else {
+                       SchemaConverter sc = root.shortNameMap.getValues(shortName).get(0);
+                       if (sc.schemaNs.equals(schemaNs)) {
+                               root.shortNameMap.add(shortName, this);
+                               return;
+                       }
+               }
+               int i = 1;
+               while (true) {
+                       String n = shortName+i;
+                       if (!root.shortNameMap.containsKey(n)) {
+                               shortName = n;
+                               root.shortNameMap.add(shortName, this);
+                               return;
+                       } else {
+                               SchemaConverter sc = root.shortNameMap.getValues(n).get(0);
+                               if (sc.schemaNs.equals(schemaNs)) {
+                                       shortName = n;
+                                       root.shortNameMap.add(shortName, this);
+                                       return;
+                               }
+                       }
+                       i++;
+               }
+       }
+       
+       protected void init() throws IOException, JAXBException {
+               if (init)
+                       return;
+               init = true;
+               JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");
+               Unmarshaller u = jc.createUnmarshaller();
+               //u.setSchema(schema);
+        InputStream fileStream = new FileInputStream(schemaFile);
+               schema = (Schema)u.unmarshal(fileStream);
+               
+               if (conversionFile != null) {
+                       jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");
+                       u = jc.createUnmarshaller();
+                       fileStream = new FileInputStream(conversionFile);
+                       configuration = (Configuration)((JAXBElement<?>)u.unmarshal(fileStream)).getValue();
+               } else {
+                       configuration = new Configuration();
+               }
+               
+               header = new String[4];
+               header[0] = "Generated with org.simantics.xml.sax XML schema converter";
+               header[1] = "";
+               header[2] = "File " + schemaFile.getAbsolutePath().replaceAll(Matcher.quoteReplacement("\\"), "/");
+               header[3] = "Date " + new Date().toString();
+               
+               schemaNs = schema.getTargetNamespace();
+               ontologyUri = schemaNs;
+               if (ontologyUri == null) {
+                       ontologyUri = getSchemaFile().getName();
+                       
+                       int index = ontologyUri.lastIndexOf(".");
+                       if (index > 0)
+                               ontologyUri = ontologyUri.substring(0, index);
+               } 
+               ontologyUri = ontologyUri.replaceAll(" ", "_");
+               String parts[] = ontologyUri.split("/");
+               for (int i = parts.length-1; i >= 0; i--) {
+                       name = parts[i];
+                       if (!Character.isDigit(name.charAt(0)))
+                               break;
+               }
+               if (name == null) {
+                       throw new JAXBException("Could not resolve proper name for schema " + ontologyUri);
+               }
+               
+               
+               name = name.replaceAll("\\.", "_");
+               if (!ontologyUri.startsWith("http://"))
+                       ontologyUri = "http://" + ontologyUri.replaceAll("/", "_");
+               else
+                       ontologyUri = "http://" + ontologyUri.substring("http://".length()).replaceAll("/", "_");
+               
+               String version = schema.getVersion();
+               if (version == null)
+                       version = "1.0";
+               ontologyUri +="-"+ version;
+
+               
+               className = getPluginName() + "." + name;
+               assignShortName();
+               if (schemaNs != null)
+                       getRoot().schemaNSMap.add(schemaNs, this);
+               
+               
+               for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {
+                       if (attrs instanceof Import) {
+                               Import imp = (Import)attrs;
+                               String location = imp.getSchemaLocation();
+                               SchemaConverter sc = createSubConverter(location);
+                               sc.init();
+                       } else if (attrs instanceof Include) {
+                               Include inc = (Include)attrs;
+                               String location = inc.getSchemaLocation();
+                               SchemaConverter sc = createSubConverter(location);
+                               sc.init();
+                       } else if (attrs instanceof Annotation) {
+                               
+                       } else {
+                               throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");
+                       }
+               }
+       }
+       
+       protected void doConvert() throws IOException, JAXBException {
+               if (!ontologyFile.exists()) {
+                       ontologyFile.getParentFile().mkdirs();
+                       ontologyFile.createNewFile();
+               }
+               if (!parserDir.exists())
+                       parserDir.mkdirs();
+               
+               for (SchemaConverter sc : subConverters)
+                       sc.doConvert();
+               
+               base = new SchemaConversionBase(this,ontologyUri,className);
+               base.init(schema);
+               
+               if (createPGraph) {
+                       OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);
+                       ontologyGenerator.createOntology();
+               }
+               if (createImporter) {
+                       ImporterGenerator importerGenerator = new ImporterGenerator(this,base);
+                       importerGenerator.createParser();
+               }
+               if (createExporter) {
+                       ExporterGenerator exporterGenerator = new ExporterGenerator(this,base);
+                       exporterGenerator.createParser();
+               }
+               base.component = null;
+       }
+       
+       public File getOntologyFile() {
+               return ontologyFile;
+       }
+       public File getParserDir() {
+               return parserDir;
+       }
+       
+       public Schema getSchema() {
+               return schema;
+       }
+       
+       public File getSchemaFile() {
+               return schemaFile;
+       }
+       
+       public String getPluginName() {
+               return pluginName;
+       }
+       
+       public String[] getHeader() {
+               return header;
+       }
+       
+       public Configuration getConfiguration() {
+               return configuration;
+       }
+       
+       public boolean isPrimary() {
+               return getRoot().schemaNSMap.getValues(schemaNs).indexOf(this) == 0;
+       }
+
+
+}