]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConversionBase.java
Dependency analysis for XML-schemas consisting of multiple files
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConversionBase.java
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;
+       }
+
+}