[jboss-svn-commits] JBoss Common SVN: r2490 - in jbossxb/tags: jbossxb-1.0.0.CR11 and 8 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Aug 15 07:51:10 EDT 2007


Author: alex.loubyansky at jboss.com
Date: 2007-08-15 07:51:08 -0400 (Wed, 15 Aug 2007)
New Revision: 2490

Added:
   jbossxb/tags/jbossxb-1.0.0.CR11/
   jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml
Removed:
   jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
   jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java
Log:
[maven-scm] copy for tag jbossxb-1.0.0.CR11

Copied: jbossxb/tags/jbossxb-1.0.0.CR11 (from rev 2419, jbossxb/branches/1_0)

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml
===================================================================
--- jbossxb/branches/1_0/pom.xml	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,142 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <parent>
-    <groupId>jboss</groupId>
-    <artifactId>jboss-parent</artifactId>
-    <version>1</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>jboss.jbossxb</groupId>
-  <artifactId>jbossxb</artifactId>
-  <packaging>jar</packaging>
-  <version>1.0.0.SNAPSHOT</version>
-  <name>JBoss XML Binding</name>
-  <url>http://www.jboss.org</url>
-  <description>JBoss XML Binding</description>
-  <licenses>
-   <license>
-      <name>lgpl</name>
-      <url>http://repository.jboss.com/licenses/lgpl.txt</url>
-   </license>
-  </licenses>
-  <organization>
-    <name>JBoss Inc.</name>
-    <url>http://www.jboss.org</url>
-  </organization>
- 
-  <repositories>
-    <repository>
-      <id>jboss</id>
-      <name>JBoss Inc. Repository</name>
-      <layout>default</layout>
-      <url>http://repository.jboss.com/maven2/</url>
-      <snapshots>
-        <enabled>true</enabled>
-      </snapshots>
-    </repository>
-  </repositories>
-  
-  <build>
-    <finalName>jboss-xml-binding</finalName>
-    <plugins>
-      <!-- define how we want compilation to take place
-        here, we accept most of the defaults but say that we want the
-        optimization flag set, and define the source and target to be 1.4,
-        these setting will be inherited by child projects -->
-      <plugin>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>2.0</version>
-        <configuration>
-          <optimize>true</optimize>
-          <source>1.4</source>
-          <target>1.4</target>
-        </configuration>
-      </plugin>  
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <printSummary>true</printSummary>
-          <disableXmlReport>false</disableXmlReport>
-          <testFailureIgnore>true</testFailureIgnore>
-          <includes>
-            <include>**/**TestCase.java</include>
-          </includes>
-          <forkMode>pertest</forkMode> <!-- required to correctly run the PojoServer tests -->
-        </configuration>
-      </plugin>    
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-report-plugin</artifactId>
-      </plugin>    
-    </plugins>
-  </build>
-
-  <dependencies>
-    <dependency>
-      <groupId>jboss.logging</groupId>
-      <artifactId>jboss-logging-spi</artifactId>
-      <version>1.0</version>
-    </dependency>
-    <dependency>
-      <groupId>jboss.logging.log4j</groupId>
-      <artifactId>jboss-logging-log4j</artifactId>
-      <version>1.0</version>
-    </dependency>
-    <dependency>
-      <groupId>jboss.common.core</groupId>
-      <artifactId>jboss-common-core</artifactId>
-      <version>1.0</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>oswego-concurrent</groupId>
-      <artifactId>concurrent</artifactId>
-      <version>1.3.4</version>
-      <scope>compile</scope>
-    </dependency> 
-    <dependency>
-      <groupId>apache-slide</groupId>
-      <artifactId>webdavlib</artifactId>
-      <version>2.0</version>
-      <scope>compile</scope>
-    </dependency> 
-    <dependency>
-      <groupId>sun-jaf</groupId>
-      <artifactId>activation</artifactId>
-      <version>1.0.2</version>
-      <scope>compile</scope>
-    </dependency> 
-    <dependency>
-      <groupId>apache-xerces</groupId>
-      <artifactId>xercesImpl</artifactId>
-      <version>2.7.1</version>
-      <scope>compile</scope>
-    </dependency>     
-    <dependency>
-      <groupId>wutka-dtdparser</groupId>
-      <artifactId>dtdparser121</artifactId>
-      <version>1.2.1</version>
-      <scope>compile</scope>
-    </dependency>         
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.1</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>jboss.jboss-test</groupId>
-      <artifactId>jboss-test</artifactId>
-      <version>1.0.0.CR1</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>  
-  <distributionManagement>
-    <repository>
-      <id>cvs-file-repository</id>
-      <!-- Set maven.cvs.root in your settings.xml -->
-      <url>file://${maven.cvs.root}</url>
-    </repository>
-  </distributionManagement>
-</project>
-

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml (from rev 2489, jbossxb/branches/1_0/pom.xml)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,155 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.jboss</groupId>
+    <artifactId>jboss-parent</artifactId>
+    <version>3</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>jbossxb</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0.0.CR11</version>
+  <name>JBoss XML Binding</name>
+  <url>http://www.jboss.org</url>
+  <description>JBoss XML Binding</description>
+  <licenses>
+   <license>
+      <name>lgpl</name>
+      <url>http://repository.jboss.com/licenses/lgpl.txt</url>
+   </license>
+  </licenses>
+  <organization>
+    <name>JBoss Inc.</name>
+    <url>http://www.jboss.org</url>
+  </organization>
+
+  <scm>
+    <connection>scm:svn:https://svn.jboss.org/repos/common/jbossxb/tags/jbossxb-1.0.0.CR11</connection>
+  </scm>
+ 
+  <repositories>
+    <repository>
+      <id>jboss</id>
+      <name>JBoss Inc. Repository</name>
+      <layout>default</layout>
+      <url>http://repository.jboss.com/maven2/</url>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+    <repository>
+      <id>snapshots.jboss.org</id>
+      <name>JBoss Snapshot Repository</name>
+      <layout>default</layout>
+      <url>http://snapshots.jboss.org/maven2/</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+  
+  <build>
+    <finalName>jboss-xml-binding</finalName>
+    <plugins>
+      <!-- define how we want compilation to take place
+        here, we accept most of the defaults but say that we want the
+        optimization flag set, and define the source and target to be 1.4,
+        these setting will be inherited by child projects -->
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.0</version>
+        <configuration>
+          <optimize>true</optimize>
+          <source>1.4</source>
+          <target>1.4</target>
+        </configuration>
+      </plugin>  
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <printSummary>true</printSummary>
+          <disableXmlReport>false</disableXmlReport>
+          <testFailureIgnore>true</testFailureIgnore>
+          <includes>
+            <include>**/**TestCase.java</include>
+          </includes>
+          <forkMode>pertest</forkMode> <!-- required to correctly run the PojoServer tests -->
+        </configuration>
+      </plugin>    
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <artifactId>maven-release-plugin</artifactId>
+        <configuration>
+          <tagBase>https://svn.jboss.org/repos/common/jbossxb/tags</tagBase>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>jboss.logging</groupId>
+      <artifactId>jboss-logging-spi</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>jboss.logging.log4j</groupId>
+      <artifactId>jboss-logging-log4j</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>jboss.common.core</groupId>
+      <artifactId>jboss-common-core</artifactId>
+      <version>1.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>apache-slide</groupId>
+      <artifactId>webdavlib</artifactId>
+      <version>2.0</version>
+      <scope>compile</scope>
+    </dependency> 
+    <dependency>
+      <groupId>sun-jaf</groupId>
+      <artifactId>activation</artifactId>
+      <version>1.0.2</version>
+      <scope>compile</scope>
+    </dependency> 
+    <dependency>
+      <groupId>apache-xerces</groupId>
+      <artifactId>xercesImpl</artifactId>
+      <version>2.7.1</version>
+      <scope>compile</scope>
+    </dependency>     
+    <dependency>
+      <groupId>wutka-dtdparser</groupId>
+      <artifactId>dtdparser121</artifactId>
+      <version>1.2.1</version>
+      <scope>compile</scope>
+    </dependency>         
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>jboss.jboss-test</groupId>
+      <artifactId>jboss-test</artifactId>
+      <version>1.0.0.CR1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>  
+  <distributionManagement>
+    <repository>
+      <id>cvs-file-repository</id>
+      <!-- Set maven.cvs.root in your settings.xml -->
+      <url>file://${maven.cvs.root}</url>
+    </repository>
+  </distributionManagement>
+</project>
\ No newline at end of file

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/Content.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,393 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding;
-
-import java.io.StringWriter;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ArrayList;
-import org.jboss.logging.Logger;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-
-/**
- * An instance of this class represents XML content.
- * It is populated on unmarshalling with org.jboss.xb.binding.ContentPopulator and used
- * to implement content navigation in object model factories.
- * And on marshalling, first, an instance of this class is created and then it
- * is serialized into XML content with org.jboss.xb.binding.ContentWriter.
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class Content
-{
-   private static Logger log = Logger.getLogger(Content.class);
-
-   private List content = new ArrayList();
-   private final boolean trace = log.isTraceEnabled();
-
-   // Public
-
-   public String getChildContent(String namespaceURI, String qName)
-   {
-      StartElement current = ((StartElement)content.get(index));
-
-      boolean lookingForStart = true;
-      StartElement start = null;
-      boolean childFound = false;
-      StringBuffer value = new StringBuffer();
-
-      int i = index + 1;
-      Object next = content.get(i++);
-      while(!current.isMyEnd(next))
-      {
-         if(lookingForStart)
-         {
-            if(next instanceof StartElement)
-            {
-               start = (StartElement)next;
-               lookingForStart = false;
-
-               if(qName.equals(start.qName) &&
-                  (namespaceURI == null ? start.namespaceURI == null : namespaceURI.equals(start.namespaceURI)))
-               {
-                  childFound = true;
-               }
-            }
-         }
-         else if(next instanceof EndElement)
-         {
-            if(start.isMyEnd(next))
-            {
-               if(childFound)
-               {
-                  break;
-               }
-               else
-               {
-                  lookingForStart = true;
-               }
-            }
-         }
-         else if(childFound && next instanceof Characters)
-         {
-            Characters chars = (Characters)next;
-            value.append(chars.ch, chars.start, chars.length);
-         }
-         next = content.get(i++);
-      }
-      return value.toString().trim();
-   }
-
-   public void handleContent(ContentHandler handler) throws SAXException
-   {
-      handler.startDocument();
-
-      for(Iterator i = content.iterator(); i.hasNext();)
-      {
-         Object item = i.next();
-         if(item instanceof StartElement)
-         {
-            StartElement start = (StartElement)item;
-            handler.startElement(start.namespaceURI, start.localName, start.qName, start.attrs);
-         }
-         else if(item instanceof EndElement)
-         {
-            EndElement end = (EndElement)item;
-            handler.endElement(end.namespaceURI, end.localName, end.qName);
-         }
-         else if(item instanceof Characters)
-         {
-            Characters ch = (Characters)item;
-            handler.characters(ch.ch, ch.start, ch.length);
-         }
-         else if(item instanceof StartPrefixMapping)
-         {
-/*
-            if(trace)
-            {
-               StartPrefixMapping startPrefix = (StartPrefixMapping)item;
-               log.trace("start prefix mapping: " + startPrefix.prefix + "=" + startPrefix.uri);
-            }
-*/
-         }
-         else if(item instanceof EndPrefixMapping)
-         {
-/*
-            if(trace)
-            {
-               EndPrefixMapping endPrefix = (EndPrefixMapping)item;
-               log.trace("end prefix mapping: " + endPrefix.prefix);
-            }
-*/
-         }
-         else
-         {
-            throw new IllegalStateException("Unexpected element type: " + item);
-         }
-      }
-
-      handler.endDocument();
-   }
-
-   public String toString()
-   {
-      StringWriter writer = new StringWriter();
-      try
-      {
-         ContentWriter contentWriter = new ContentWriter(writer, true);
-         handleContent(contentWriter);
-      }
-      catch(SAXException e)
-      {
-         writer.write(e.getMessage());
-      }
-      return writer.getBuffer().toString();
-   }
-
-   // Methods that populate the content
-
-   public void startDocument()
-   {
-      content.clear();
-   }
-
-   public void endDocument()
-   {
-   }
-
-   public void startPrefixMapping(String prefix, String uri)
-   {
-      StartPrefixMapping node = new StartPrefixMapping(prefix, uri);
-      content.add(node);
-   }
-
-   public void endPrefixMapping(String prefix)
-   {
-      EndPrefixMapping node = new EndPrefixMapping(prefix);
-      content.add(node);
-   }
-
-   public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
-   {
-      StartElement startElement = new StartElement(namespaceURI, localName, qName, atts);
-      content.add(startElement);
-
-      if(trace)
-      {
-         log.trace("startElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName + ", attrs=" + atts);
-      }
-   }
-
-   public void endElement(String namespaceURI, String localName, String qName)
-   {
-      EndElement endElement = new EndElement(namespaceURI, localName, qName);
-      content.add(endElement);
-
-      if(trace)
-      {
-         log.trace("endElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName);
-      }
-   }
-
-   public void characters(char[] ch, int start, int length)
-   {
-      Characters characters = new Characters(ch, start, length);
-      // ignore whitespace-only characters
-      if(characters.toString().trim().length() > 0)
-      {
-         content.add(characters);
-
-         if(trace)
-         {
-            log.trace("characters> " + characters);
-         }
-      }
-   }
-
-   // Methods that navigate through the content
-
-   private int index;
-
-   public void append(Content content)
-   {
-      for(Iterator i = content.content.iterator(); i.hasNext();)
-      {
-         this.content.add(i.next());
-      }
-   }
-
-   // Inner
-
-   private static interface Node
-   {
-   }
-
-   public static class Characters
-      implements Node
-   {
-      private final char[] ch;
-      private final int start;
-      private final int length;
-
-      public Characters(char[] ch, int start, int length)
-      {
-         /*
-         this.ch = ch;
-         this.start = start;
-         this.length = length;
-         */
-         this.ch = new char[length];
-         System.arraycopy(ch, start, this.ch, 0, length);
-         this.start = 0;
-         this.length = length;
-      }
-
-      public String toString()
-      {
-         return String.valueOf(ch, start, length);
-      }
-   }
-
-   public static class EndElement
-      implements Node
-   {
-      private final String namespaceURI;
-      private final String localName;
-      private final String qName;
-
-      public EndElement(String namespaceURI, String localName, String qName)
-      {
-         this.namespaceURI = namespaceURI;
-         this.localName = localName;
-         this.qName = qName;
-      }
-
-      public String toString()
-      {
-         return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
-      }
-   }
-
-   public static class StartElement
-      implements Node
-   {
-      private final String namespaceURI;
-      private final String localName;
-      private final String qName;
-      private final Attributes attrs;
-
-      public StartElement(String namespaceURI, String localName, String qName, Attributes attrs)
-      {
-         this.namespaceURI = namespaceURI;
-         this.localName = localName;
-         this.qName = qName;
-         this.attrs = new AttributesImpl(attrs);
-      }
-
-      public boolean isMyEnd(Object element)
-      {
-         boolean itis = false;
-         if(element instanceof EndElement)
-         {
-            EndElement end = (EndElement)element;
-            itis = (namespaceURI == null ? end.namespaceURI == null : namespaceURI.equals(end.namespaceURI))
-               && qName.equals(end.qName);
-         }
-         return itis;
-      }
-
-      public String toString()
-      {
-         return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
-      }
-   }
-
-   public static class StartPrefixMapping
-      implements Node
-   {
-      public final String prefix;
-      public final String uri;
-
-      public StartPrefixMapping(String prefix, String uri)
-      {
-         this.prefix = prefix;
-         this.uri = uri;
-      }
-
-      public void read(ObjectModelBuilder builder)
-      {
-         builder.startPrefixMapping(prefix, uri);
-      }
-
-      public boolean equals(Object o)
-      {
-         if(this == o)
-         {
-            return true;
-         }
-         if(!(o instanceof StartPrefixMapping))
-         {
-            return false;
-         }
-
-         final StartPrefixMapping startPrefixMapping = (StartPrefixMapping)o;
-
-         if(prefix != null ? !prefix.equals(startPrefixMapping.prefix) : startPrefixMapping.prefix != null)
-         {
-            return false;
-         }
-         if(uri != null ? !uri.equals(startPrefixMapping.uri) : startPrefixMapping.uri != null)
-         {
-            return false;
-         }
-
-         return true;
-      }
-
-      public int hashCode()
-      {
-         int result;
-         result = (prefix != null ? prefix.hashCode() : 0);
-         result = 29 * result + (uri != null ? uri.hashCode() : 0);
-         return result;
-      }
-   }
-
-   public static class EndPrefixMapping
-      implements Node
-   {
-      public final String prefix;
-
-      public EndPrefixMapping(String prefix)
-      {
-         this.prefix = prefix;
-      }
-
-      public void read(ObjectModelBuilder builder)
-      {
-         builder.endPrefixMapping(prefix);
-      }
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java (from rev 2434, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/Content.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,393 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding;
+
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import org.jboss.logging.Logger;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * An instance of this class represents XML content.
+ * It is populated on unmarshalling with org.jboss.xb.binding.ContentPopulator and used
+ * to implement content navigation in object model factories.
+ * And on marshalling, first, an instance of this class is created and then it
+ * is serialized into XML content with org.jboss.xb.binding.ContentWriter.
+ *
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class Content
+{
+   private static Logger log = Logger.getLogger(Content.class);
+
+   private List content = new ArrayList();
+   private final boolean trace = log.isTraceEnabled();
+
+   // Public
+
+   public String getChildContent(String namespaceURI, String qName)
+   {
+      StartElement current = ((StartElement)content.get(index));
+
+      boolean lookingForStart = true;
+      StartElement start = null;
+      boolean childFound = false;
+      StringBuffer value = new StringBuffer();
+
+      int i = index + 1;
+      Object next = content.get(i++);
+      while(!current.isMyEnd(next))
+      {
+         if(lookingForStart)
+         {
+            if(next instanceof StartElement)
+            {
+               start = (StartElement)next;
+               lookingForStart = false;
+
+               if(qName.equals(start.qName) &&
+                  (namespaceURI == null ? start.namespaceURI == null : namespaceURI.equals(start.namespaceURI)))
+               {
+                  childFound = true;
+               }
+            }
+         }
+         else if(next instanceof EndElement)
+         {
+            if(start.isMyEnd(next))
+            {
+               if(childFound)
+               {
+                  break;
+               }
+               else
+               {
+                  lookingForStart = true;
+               }
+            }
+         }
+         else if(childFound && next instanceof Characters)
+         {
+            Characters chars = (Characters)next;
+            value.append(chars.ch, chars.start, chars.length);
+         }
+         next = content.get(i++);
+      }
+      return value.toString().trim();
+   }
+
+   public void handleContent(ContentHandler handler) throws SAXException
+   {
+      handler.startDocument();
+
+      for(Iterator i = content.iterator(); i.hasNext();)
+      {
+         Object item = i.next();
+         if(item instanceof StartElement)
+         {
+            StartElement start = (StartElement)item;
+            handler.startElement(start.namespaceURI, start.localName, start.qName, start.attrs);
+         }
+         else if(item instanceof EndElement)
+         {
+            EndElement end = (EndElement)item;
+            handler.endElement(end.namespaceURI, end.localName, end.qName);
+         }
+         else if(item instanceof Characters)
+         {
+            Characters ch = (Characters)item;
+            handler.characters(ch.ch, ch.start, ch.length);
+         }
+         else if(item instanceof StartPrefixMapping)
+         {
+/*
+            if(trace)
+            {
+               StartPrefixMapping startPrefix = (StartPrefixMapping)item;
+               log.trace("start prefix mapping: " + startPrefix.prefix + "=" + startPrefix.uri);
+            }
+*/
+         }
+         else if(item instanceof EndPrefixMapping)
+         {
+/*
+            if(trace)
+            {
+               EndPrefixMapping endPrefix = (EndPrefixMapping)item;
+               log.trace("end prefix mapping: " + endPrefix.prefix);
+            }
+*/
+         }
+         else
+         {
+            throw new IllegalStateException("Unexpected element type: " + item);
+         }
+      }
+
+      handler.endDocument();
+   }
+
+   public String toString()
+   {
+      StringWriter writer = new StringWriter();
+      try
+      {
+         ContentWriter contentWriter = new ContentWriter(writer, true);
+         handleContent(contentWriter);
+      }
+      catch(SAXException e)
+      {
+         writer.write(e.getMessage());
+      }
+      return writer.getBuffer().toString();
+   }
+
+   // Methods that populate the content
+
+   public void startDocument()
+   {
+      content.clear();
+   }
+
+   public void endDocument()
+   {
+   }
+
+   public void startPrefixMapping(String prefix, String uri)
+   {
+      StartPrefixMapping node = new StartPrefixMapping(prefix, uri);
+      content.add(node);
+   }
+
+   public void endPrefixMapping(String prefix)
+   {
+      EndPrefixMapping node = new EndPrefixMapping(prefix);
+      content.add(node);
+   }
+
+   public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
+   {
+      StartElement startElement = new StartElement(namespaceURI, localName, qName, atts);
+      content.add(startElement);
+
+      if(trace)
+      {
+         log.trace("startElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName + ", attrs=" + atts);
+      }
+   }
+
+   public void endElement(String namespaceURI, String localName, String qName)
+   {
+      EndElement endElement = new EndElement(namespaceURI, localName, qName);
+      content.add(endElement);
+
+      if(trace)
+      {
+         log.trace("endElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName);
+      }
+   }
+
+   public void characters(char[] ch, int start, int length)
+   {
+      Characters characters = new Characters(ch, start, length);
+      // DON'T ignore whitespace-only characters
+      //if(characters.toString().trim().length() > 0)
+      //{
+         content.add(characters);
+
+         if(trace)
+         {
+            log.trace("characters> " + characters);
+         }
+      //}
+   }
+
+   // Methods that navigate through the content
+
+   private int index;
+
+   public void append(Content content)
+   {
+      for(Iterator i = content.content.iterator(); i.hasNext();)
+      {
+         this.content.add(i.next());
+      }
+   }
+
+   // Inner
+
+   private static interface Node
+   {
+   }
+
+   public static class Characters
+      implements Node
+   {
+      private final char[] ch;
+      private final int start;
+      private final int length;
+
+      public Characters(char[] ch, int start, int length)
+      {
+         /*
+         this.ch = ch;
+         this.start = start;
+         this.length = length;
+         */
+         this.ch = new char[length];
+         System.arraycopy(ch, start, this.ch, 0, length);
+         this.start = 0;
+         this.length = length;
+      }
+
+      public String toString()
+      {
+         return String.valueOf(ch, start, length);
+      }
+   }
+
+   public static class EndElement
+      implements Node
+   {
+      private final String namespaceURI;
+      private final String localName;
+      private final String qName;
+
+      public EndElement(String namespaceURI, String localName, String qName)
+      {
+         this.namespaceURI = namespaceURI;
+         this.localName = localName;
+         this.qName = qName;
+      }
+
+      public String toString()
+      {
+         return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
+      }
+   }
+
+   public static class StartElement
+      implements Node
+   {
+      private final String namespaceURI;
+      private final String localName;
+      private final String qName;
+      private final Attributes attrs;
+
+      public StartElement(String namespaceURI, String localName, String qName, Attributes attrs)
+      {
+         this.namespaceURI = namespaceURI;
+         this.localName = localName;
+         this.qName = qName;
+         this.attrs = new AttributesImpl(attrs);
+      }
+
+      public boolean isMyEnd(Object element)
+      {
+         boolean itis = false;
+         if(element instanceof EndElement)
+         {
+            EndElement end = (EndElement)element;
+            itis = (namespaceURI == null ? end.namespaceURI == null : namespaceURI.equals(end.namespaceURI))
+               && qName.equals(end.qName);
+         }
+         return itis;
+      }
+
+      public String toString()
+      {
+         return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
+      }
+   }
+
+   public static class StartPrefixMapping
+      implements Node
+   {
+      public final String prefix;
+      public final String uri;
+
+      public StartPrefixMapping(String prefix, String uri)
+      {
+         this.prefix = prefix;
+         this.uri = uri;
+      }
+
+      public void read(ObjectModelBuilder builder)
+      {
+         builder.startPrefixMapping(prefix, uri);
+      }
+
+      public boolean equals(Object o)
+      {
+         if(this == o)
+         {
+            return true;
+         }
+         if(!(o instanceof StartPrefixMapping))
+         {
+            return false;
+         }
+
+         final StartPrefixMapping startPrefixMapping = (StartPrefixMapping)o;
+
+         if(prefix != null ? !prefix.equals(startPrefixMapping.prefix) : startPrefixMapping.prefix != null)
+         {
+            return false;
+         }
+         if(uri != null ? !uri.equals(startPrefixMapping.uri) : startPrefixMapping.uri != null)
+         {
+            return false;
+         }
+
+         return true;
+      }
+
+      public int hashCode()
+      {
+         int result;
+         result = (prefix != null ? prefix.hashCode() : 0);
+         result = 29 * result + (uri != null ? uri.hashCode() : 0);
+         return result;
+      }
+   }
+
+   public static class EndPrefixMapping
+      implements Node
+   {
+      public final String prefix;
+
+      public EndPrefixMapping(String prefix)
+      {
+         this.prefix = prefix;
+      }
+
+      public void read(ObjectModelBuilder builder)
+      {
+         builder.endPrefixMapping(prefix);
+      }
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,557 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding;
-
-import org.xml.sax.Attributes;
-import org.jboss.logging.Logger;
-import org.jboss.xb.binding.parser.JBossXBParser;
-import org.apache.xerces.xs.XSTypeDefinition;
-
-import javax.xml.namespace.QName;
-import javax.xml.namespace.NamespaceContext;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
-import java.util.StringTokenizer;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ArrayList;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * An instance of this class translates SAX events into org.jboss.xml.binding.GenericObjectModelFactory calls
- * such as newChild, addChild and setValue.
- * WARN: this implementation is not thread-safe!
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class ObjectModelBuilder
-   implements UnmarshallingContext, JBossXBParser.ContentHandler
-{
-   /**
-    * logger
-    */
-   private static final Logger log = Logger.getLogger(ObjectModelBuilder.class);
-
-   /**
-    * The object that represents an ignored by the object model factory XML element, i.e. the factory returned null
-    * from its newChild method
-    */
-   private static final Object IGNORED = new Object();
-
-   /**
-    * The root of the unmarshalled object graph
-    */
-   private Object root;
-
-   /**
-    * the stack of all the objects including IGNORED
-    */
-   private Stack all = new StackImpl();
-
-   /**
-    * the stack of only accepted objects (all - IGNORED)
-    */
-   private Stack accepted = new StackImpl();
-
-   private GenericObjectModelFactory curFactory;
-   private String curNameSwitchingFactory;
-   private String curNsSwitchingFactory;
-   private Stack nameSwitchingFactory;
-   private Stack nsSwitchingFactory;
-
-   /**
-    * default object model factory
-    */
-   private GenericObjectModelFactory defaultFactory;
-
-   /**
-    * factories mapped to namespace URIs
-    */
-   private Map factoriesToNs = Collections.EMPTY_MAP;
-
-   /**
-    * NamespaceContext implementation
-    */
-   private final NamespaceRegistry nsRegistry = new NamespaceRegistry();
-
-   private XSTypeDefinition currentType;
-
-   private boolean trace = log.isTraceEnabled();
-
-   // Public
-
-   public void mapFactoryToNamespace(ObjectModelFactory factory, String namespaceUri)
-   {
-      if(factoriesToNs == Collections.EMPTY_MAP)
-      {
-         factoriesToNs = new HashMap();
-      }
-      factoriesToNs.put(namespaceUri, getGenericObjectModelFactory(factory));
-   }
-
-   public void init(ObjectModelFactory defaultFactory, Object root)
-   {
-      this.defaultFactory = getGenericObjectModelFactory(defaultFactory);
-      all.clear();
-      accepted.clear();
-      this.root = root;
-   }
-
-   public void pushFactory(String namespaceURI, String localName, GenericObjectModelFactory factory)
-   {
-      if(curNsSwitchingFactory != null)
-      {
-         if(nsSwitchingFactory == null)
-         {
-            nsSwitchingFactory = new StackImpl();
-            nameSwitchingFactory = new StackImpl();
-         }
-         nsSwitchingFactory.push(curNsSwitchingFactory);
-         nameSwitchingFactory.push(curNameSwitchingFactory);
-      }
-      curNsSwitchingFactory = namespaceURI;
-      curNameSwitchingFactory = localName;
-      curFactory = factory;
-   }
-
-   public void popFactory()
-   {
-      if(nsSwitchingFactory == null || nsSwitchingFactory.isEmpty())
-      {
-         curNameSwitchingFactory = null;
-         curNsSwitchingFactory = null;
-      }
-      else
-      {
-         curNameSwitchingFactory = (String)nameSwitchingFactory.pop();
-         curNsSwitchingFactory = (String)nsSwitchingFactory.pop();
-      }
-
-      curFactory = getFactory(curNsSwitchingFactory);
-   }
-
-   // UnmarshallingContext implementation
-
-   public Iterator getNamespaceURIs()
-   {
-      return nsRegistry.getRegisteredURIs();
-   }
-
-   public NamespaceContext getNamespaceContext()
-   {
-      return nsRegistry;
-   }
-
-   /**
-    * Construct a QName from a value
-    *
-    * @param value A value that is of the form [prefix:]localpart
-    */
-   public QName resolveQName(String value)
-   {
-      StringTokenizer st = new StringTokenizer(value, ":");
-      if(st.countTokens() == 1)
-         return new QName(value);
-
-      if(st.countTokens() != 2)
-         throw new IllegalArgumentException("Illegal QName: " + value);
-
-      String prefix = st.nextToken();
-      String local = st.nextToken();
-      String nsURI = nsRegistry.getNamespaceURI(prefix);
-      if (nsURI == null)
-         throw new IllegalStateException("Cannot obtain namespace URI for prefix: " + prefix);
-
-      return new QName(nsURI, local, prefix);
-   }
-
-   public String getChildContent(String namespaceURI, String qName)
-   {
-      // todo reimplement later
-      throw new UnsupportedOperationException();
-      //return content.getChildContent(namespaceURI, qName);
-   }
-
-   public XSTypeDefinition getType()
-   {
-      return currentType;
-   }
-
-   // Public
-
-   public void startPrefixMapping(String prefix, String uri)
-   {
-      nsRegistry.addPrefixMapping(prefix, uri);
-   }
-
-   public void endPrefixMapping(String prefix)
-   {
-      nsRegistry.removePrefixMapping(prefix);
-   }
-
-   public void processingInstruction(String target, String data)
-   {
-      if(!"jbossxb".equals(target))
-      {
-         return;
-      }
-
-      int i = data.indexOf("factory=\"");
-      if(i != -1)
-      {
-         int end = data.indexOf('\"', i + 9);
-         if(end == -1)
-         {
-            throw new JBossXBRuntimeException(
-               "Property 'factory' is not terminated with '\"' in processing instruction: " + data
-            );
-         }
-
-         String factoryProp = data.substring(i + 9, end);
-         Class factoryCls;
-         try
-         {
-            factoryCls = Thread.currentThread().getContextClassLoader().loadClass(factoryProp);
-         }
-         catch(ClassNotFoundException e)
-         {
-            throw new JBossXBRuntimeException("Failed to load factory class : " + e.getMessage(), e);
-         }
-
-         ObjectModelFactory factory;
-         try
-         {
-            factory = (ObjectModelFactory)factoryCls.newInstance();
-         }
-         catch(Exception e)
-         {
-            throw new JBossXBRuntimeException("Failed to instantiate factory " + factoryProp + ": " + e.getMessage(),
-               e
-            );
-         }
-
-         i = data.indexOf("ns=\"");
-         if(i == -1)
-         {
-            throw new JBossXBRuntimeException(
-               "Property 'ns' not found in factory mapping processing instruction: " + data
-            );
-         }
-
-         end = data.indexOf("\"", i + 4);
-         if(end == -1)
-         {
-            throw new JBossXBRuntimeException(
-               "Property 'ns' is not terminated with '\"' in processing instruction: " + data
-            );
-         }
-
-         String nsProp = data.substring(i + 4, end);
-         mapFactoryToNamespace(factory, nsProp);
-      }
-      else
-      {
-         throw new JBossXBRuntimeException(
-            "Unexpected data in processing instruction: target=" + target + ", data=" + data
-         );
-      }
-   }
-
-   public Object getRoot()
-   {
-      if(!all.isEmpty())
-      {
-         popAll();
-         popAccepted();
-      }
-      return root;
-   }
-
-   public void startElement(String namespaceURI,
-                            String localName,
-                            String qName,
-                            Attributes atts,
-                            XSTypeDefinition type)
-   {
-      Object parent = accepted.isEmpty() ? root : peekAccepted();
-
-      // todo currentType assignment
-      currentType = type;
-
-      Object element;
-      if(!namespaceURI.equals(curNsSwitchingFactory))
-      {
-         GenericObjectModelFactory newFactory = getFactory(namespaceURI);
-         if(newFactory != curFactory)
-         {
-            element = newFactory.newRoot(parent, this, namespaceURI, localName, atts);
-         }
-         else
-         {
-            element = newFactory.newChild(parent, this, namespaceURI, localName, atts);
-         }
-
-         // still have to push since curNsSwitchingFactory needs to be updated to prevent
-         // newRoot calls for the children
-         pushFactory(namespaceURI, localName, newFactory);
-      }
-      else
-      {
-         element = curFactory.newChild(parent, this, namespaceURI, localName, atts);
-      }
-
-      if(element == null)
-      {
-         pushAll(IGNORED);
-
-         if(trace)
-         {
-            log.trace("ignored " + namespaceURI + ':' + qName);
-         }
-      }
-      else
-      {
-         pushAll(element);
-         pushAccepted(element);
-
-         if(trace)
-         {
-            log.trace("accepted " + namespaceURI + ':' + qName);
-         }
-      }
-   }
-
-   public void endElement(String namespaceURI, String localName, String qName)
-   {
-      AllElement element = popAll();
-
-      if(!accepted.isEmpty())
-      {
-         Object acceptedElement = peekAccepted();
-         if(element.characters != null && element.characters.length() > 0)
-         {
-            String characters = element.characters.toString().trim();
-            if(characters.length() > 0)
-            {
-               curFactory.setValue(acceptedElement, this, namespaceURI, localName, characters);
-            }
-         }
-      }
-
-      if(localName.equals(curNameSwitchingFactory) && namespaceURI.equals(curNsSwitchingFactory))
-      {
-         popFactory();
-      }
-
-      if(element.element != IGNORED)
-      {
-         popAccepted();
-         Object parent = (accepted.isEmpty() ? null : peekAccepted());
-
-         if(parent != null)
-         {
-            curFactory.addChild(parent, element.element, this, namespaceURI, localName);
-         }
-         else
-         {
-            root = curFactory.completeRoot(element.element, this, namespaceURI, localName);
-         }
-      }
-   }
-
-   public void characters(char[] ch, int start, int length)
-   {
-      if(!accepted.isEmpty())
-      {
-         String str = String.valueOf(ch, start, length);
-         AllElement allElement = peekAll();
-         if(allElement.characters == null)
-         {
-            allElement.characters = new StringBuffer(str);
-         }
-         else
-         {
-            allElement.characters.append(str);
-         }
-      }
-   }
-
-   // Private
-
-   private GenericObjectModelFactory getFactory(String namespaceUri)
-   {
-      GenericObjectModelFactory factory = (GenericObjectModelFactory)factoriesToNs.get(namespaceUri);
-      if(factory == null)
-      {
-         factory = defaultFactory;
-      }
-      return factory;
-   }
-
-   static Object invokeFactory(Object factory, Method method, Object[] args)
-   {
-      try
-      {
-         return method.invoke(factory, args);
-      }
-      catch(InvocationTargetException e)
-      {
-         Throwable te = e.getCause();
-         if(te instanceof RuntimeException)
-         {
-            throw (RuntimeException)te;
-         }
-
-         String msg = "Failed to invoke method " + method + ", factory=" + factory;
-         log.error(msg, e.getTargetException());
-
-         IllegalStateException ise = new IllegalStateException(msg);
-         ise.initCause(te);
-         throw ise;
-      }
-      catch(Exception e)
-      {
-         String msg = "Failed to invoke method " + method.getName() + ", factory=" + factory;
-         log.error(msg, e);
-         IllegalStateException ise = new IllegalStateException(msg);
-         ise.initCause(e);
-         throw ise;
-      }
-   }
-
-   static Method getMethodForElement(Object factory, String name, Class[] params)
-   {
-      Method method = null;
-      try
-      {
-         method = factory.getClass().getMethod(name, params);
-      }
-      catch(NoSuchMethodException e)
-      {
-      }
-      catch(SecurityException e)
-      {
-         throw e;
-      }
-
-      return method;
-   }
-
-   static final GenericObjectModelFactory getGenericObjectModelFactory(ObjectModelFactory factory)
-   {
-      if(!(factory instanceof GenericObjectModelFactory))
-      {
-         factory = new DelegatingObjectModelFactory(factory);
-      }
-      return factory instanceof GenericObjectModelFactory ?
-         (GenericObjectModelFactory)factory :
-         new DelegatingObjectModelFactory(factory);
-   }
-
-   private void pushAccepted(Object o)
-   {
-      accepted.push(o);
-   }
-
-   private Object popAccepted()
-   {
-      return accepted.pop();
-   }
-
-   private Object peekAccepted()
-   {
-      return accepted.peek();
-   }
-
-   private void pushAll(Object o)
-   {
-      all.push(new AllElement(o));
-   }
-
-   private AllElement popAll()
-   {
-      return (AllElement)all.pop();
-   }
-
-   private AllElement peekAll()
-   {
-      return (AllElement)all.peek();
-   }
-
-   private static final class AllElement
-   {
-      public final Object element;
-      public StringBuffer characters;
-
-      public AllElement(Object element)
-      {
-         this.element = element;
-      }
-   }
-
-   private static interface Stack
-   {
-      void clear();
-
-      void push(Object o);
-
-      Object pop();
-
-      Object peek();
-
-      boolean isEmpty();
-   }
-
-   private static class StackImpl
-      implements Stack
-   {
-      private List list = new ArrayList();
-
-      public void clear()
-      {
-         list.clear();
-      }
-
-      public void push(Object o)
-      {
-         list.add(o);
-      }
-
-      public Object pop()
-      {
-         return list.remove(list.size() - 1);
-      }
-
-      public Object peek()
-      {
-         return list.get(list.size() - 1);
-      }
-
-      public boolean isEmpty()
-      {
-         return list.isEmpty();
-      }
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,577 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding;
+
+import org.xml.sax.Attributes;
+import org.jboss.logging.Logger;
+import org.jboss.xb.binding.parser.JBossXBParser;
+import org.apache.xerces.xs.XSTypeDefinition;
+
+import javax.xml.namespace.QName;
+import javax.xml.namespace.NamespaceContext;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.StringTokenizer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * An instance of this class translates SAX events into org.jboss.xml.binding.GenericObjectModelFactory calls
+ * such as newChild, addChild and setValue.
+ * WARN: this implementation is not thread-safe!
+ *
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class ObjectModelBuilder
+   implements UnmarshallingContext, JBossXBParser.ContentHandler
+{
+   /**
+    * logger
+    */
+   private static final Logger log = Logger.getLogger(ObjectModelBuilder.class);
+
+   /**
+    * The object that represents an ignored by the object model factory XML element, i.e. the factory returned null
+    * from its newChild method
+    */
+   private static final Object IGNORED = new Object();
+
+   /**
+    * The root of the unmarshalled object graph
+    */
+   private Object root;
+
+   /**
+    * the stack of all the objects including IGNORED
+    */
+   private Stack all = new StackImpl();
+
+   /**
+    * the stack of only accepted objects (all - IGNORED)
+    */
+   private Stack accepted = new StackImpl();
+
+   private GenericObjectModelFactory curFactory;
+   private String curNameSwitchingFactory;
+   private String curNsSwitchingFactory;
+   private Stack nameSwitchingFactory;
+   private Stack nsSwitchingFactory;
+
+   /**
+    * default object model factory
+    */
+   private GenericObjectModelFactory defaultFactory;
+
+   /**
+    * factories mapped to namespace URIs
+    */
+   private Map factoriesToNs = Collections.EMPTY_MAP;
+
+   /**
+    * NamespaceContext implementation
+    */
+   private final NamespaceRegistry nsRegistry = new NamespaceRegistry();
+
+   // whether text content should be trimmed before it is set
+   private boolean trimTextContent = true; //  for backwards compatibility
+
+   private XSTypeDefinition currentType;
+
+   private boolean trace = log.isTraceEnabled();
+
+   // Public
+
+   public void mapFactoryToNamespace(ObjectModelFactory factory, String namespaceUri)
+   {
+      if(factoriesToNs == Collections.EMPTY_MAP)
+      {
+         factoriesToNs = new HashMap();
+      }
+      factoriesToNs.put(namespaceUri, getGenericObjectModelFactory(factory));
+   }
+
+   public void init(ObjectModelFactory defaultFactory, Object root)
+   {
+      this.defaultFactory = getGenericObjectModelFactory(defaultFactory);
+      all.clear();
+      accepted.clear();
+      this.root = root;
+   }
+
+   public void pushFactory(String namespaceURI, String localName, GenericObjectModelFactory factory)
+   {
+      if(curNsSwitchingFactory != null)
+      {
+         if(nsSwitchingFactory == null)
+         {
+            nsSwitchingFactory = new StackImpl();
+            nameSwitchingFactory = new StackImpl();
+         }
+         nsSwitchingFactory.push(curNsSwitchingFactory);
+         nameSwitchingFactory.push(curNameSwitchingFactory);
+      }
+      curNsSwitchingFactory = namespaceURI;
+      curNameSwitchingFactory = localName;
+      curFactory = factory;
+   }
+
+   public void popFactory()
+   {
+      if(nsSwitchingFactory == null || nsSwitchingFactory.isEmpty())
+      {
+         curNameSwitchingFactory = null;
+         curNsSwitchingFactory = null;
+      }
+      else
+      {
+         curNameSwitchingFactory = (String)nameSwitchingFactory.pop();
+         curNsSwitchingFactory = (String)nsSwitchingFactory.pop();
+      }
+
+      curFactory = getFactory(curNsSwitchingFactory);
+   }
+
+   // UnmarshallingContext implementation
+
+   public Iterator getNamespaceURIs()
+   {
+      return nsRegistry.getRegisteredURIs();
+   }
+
+   public NamespaceContext getNamespaceContext()
+   {
+      return nsRegistry;
+   }
+
+   public boolean isTrimTextContent()
+   {
+      return trimTextContent;
+   }
+   
+   public void setTrimTextContent(boolean trimTextContent)
+   {
+      this.trimTextContent = trimTextContent;
+   }   
+
+   /**
+    * Construct a QName from a value
+    *
+    * @param value A value that is of the form [prefix:]localpart
+    */
+   public QName resolveQName(String value)
+   {
+      StringTokenizer st = new StringTokenizer(value, ":");
+      if(st.countTokens() == 1)
+         return new QName(value);
+
+      if(st.countTokens() != 2)
+         throw new IllegalArgumentException("Illegal QName: " + value);
+
+      String prefix = st.nextToken();
+      String local = st.nextToken();
+      String nsURI = nsRegistry.getNamespaceURI(prefix);
+      if (nsURI == null)
+         throw new IllegalStateException("Cannot obtain namespace URI for prefix: " + prefix);
+
+      return new QName(nsURI, local, prefix);
+   }
+
+   public String getChildContent(String namespaceURI, String qName)
+   {
+      // todo reimplement later
+      throw new UnsupportedOperationException();
+      //return content.getChildContent(namespaceURI, qName);
+   }
+
+   public XSTypeDefinition getType()
+   {
+      return currentType;
+   }
+
+   // Public
+
+   public void startPrefixMapping(String prefix, String uri)
+   {
+      nsRegistry.addPrefixMapping(prefix, uri);
+   }
+
+   public void endPrefixMapping(String prefix)
+   {
+      nsRegistry.removePrefixMapping(prefix);
+   }
+
+   public void processingInstruction(String target, String data)
+   {
+      if(!"jbossxb".equals(target))
+      {
+         return;
+      }
+
+      int i = data.indexOf("factory=\"");
+      if(i != -1)
+      {
+         int end = data.indexOf('\"', i + 9);
+         if(end == -1)
+         {
+            throw new JBossXBRuntimeException(
+               "Property 'factory' is not terminated with '\"' in processing instruction: " + data
+            );
+         }
+
+         String factoryProp = data.substring(i + 9, end);
+         Class factoryCls;
+         try
+         {
+            factoryCls = Thread.currentThread().getContextClassLoader().loadClass(factoryProp);
+         }
+         catch(ClassNotFoundException e)
+         {
+            throw new JBossXBRuntimeException("Failed to load factory class : " + e.getMessage(), e);
+         }
+
+         ObjectModelFactory factory;
+         try
+         {
+            factory = (ObjectModelFactory)factoryCls.newInstance();
+         }
+         catch(Exception e)
+         {
+            throw new JBossXBRuntimeException("Failed to instantiate factory " + factoryProp + ": " + e.getMessage(),
+               e
+            );
+         }
+
+         i = data.indexOf("ns=\"");
+         if(i == -1)
+         {
+            throw new JBossXBRuntimeException(
+               "Property 'ns' not found in factory mapping processing instruction: " + data
+            );
+         }
+
+         end = data.indexOf("\"", i + 4);
+         if(end == -1)
+         {
+            throw new JBossXBRuntimeException(
+               "Property 'ns' is not terminated with '\"' in processing instruction: " + data
+            );
+         }
+
+         String nsProp = data.substring(i + 4, end);
+         mapFactoryToNamespace(factory, nsProp);
+      }
+      else
+      {
+         throw new JBossXBRuntimeException(
+            "Unexpected data in processing instruction: target=" + target + ", data=" + data
+         );
+      }
+   }
+
+   public Object getRoot()
+   {
+      if(!all.isEmpty())
+      {
+         popAll();
+         popAccepted();
+      }
+      return root;
+   }
+
+   public void startElement(String namespaceURI,
+                            String localName,
+                            String qName,
+                            Attributes atts,
+                            XSTypeDefinition type)
+   {
+      Object parent = accepted.isEmpty() ? root : peekAccepted();
+
+      // todo currentType assignment
+      currentType = type;
+
+      Object element;
+      if(!namespaceURI.equals(curNsSwitchingFactory))
+      {
+         GenericObjectModelFactory newFactory = getFactory(namespaceURI);
+         if(newFactory != curFactory)
+         {
+            element = newFactory.newRoot(parent, this, namespaceURI, localName, atts);
+         }
+         else
+         {
+            element = newFactory.newChild(parent, this, namespaceURI, localName, atts);
+         }
+
+         // still have to push since curNsSwitchingFactory needs to be updated to prevent
+         // newRoot calls for the children
+         pushFactory(namespaceURI, localName, newFactory);
+      }
+      else
+      {
+         element = curFactory.newChild(parent, this, namespaceURI, localName, atts);
+      }
+
+      if(element == null)
+      {
+         pushAll(IGNORED);
+
+         if(trace)
+         {
+            log.trace("ignored " + namespaceURI + ':' + qName);
+         }
+      }
+      else
+      {
+         pushAll(element);
+         pushAccepted(element);
+
+         if(trace)
+         {
+            log.trace("accepted " + namespaceURI + ':' + qName);
+         }
+      }
+   }
+
+   public void endElement(String namespaceURI, String localName, String qName)
+   {
+      AllElement element = popAll();
+
+      if(!accepted.isEmpty())
+      {
+         Object acceptedElement = peekAccepted();
+         if(element.characters != null && element.characters.length() > 0)
+         {
+            if(trimTextContent)
+            {
+               String characters = element.characters.toString().trim();
+               if (characters.length() > 0)
+               {
+                  curFactory.setValue(acceptedElement, this, namespaceURI, localName, characters);
+               }
+            }
+            else
+            {
+               curFactory.setValue(acceptedElement, this, namespaceURI, localName, element.characters.toString());
+            }
+         }
+      }
+
+      if(localName.equals(curNameSwitchingFactory) && namespaceURI.equals(curNsSwitchingFactory))
+      {
+         popFactory();
+      }
+
+      if(element.element != IGNORED)
+      {
+         popAccepted();
+         Object parent = (accepted.isEmpty() ? null : peekAccepted());
+
+         if(parent != null)
+         {
+            curFactory.addChild(parent, element.element, this, namespaceURI, localName);
+         }
+         else
+         {
+            root = curFactory.completeRoot(element.element, this, namespaceURI, localName);
+         }
+      }
+   }
+
+   public void characters(char[] ch, int start, int length)
+   {
+      if(!accepted.isEmpty())
+      {
+         String str = String.valueOf(ch, start, length);
+         AllElement allElement = peekAll();
+         if(allElement.characters == null)
+         {
+            allElement.characters = new StringBuffer(str);
+         }
+         else
+         {
+            allElement.characters.append(str);
+         }
+      }
+   }
+
+   // Private
+
+   private GenericObjectModelFactory getFactory(String namespaceUri)
+   {
+      GenericObjectModelFactory factory = (GenericObjectModelFactory)factoriesToNs.get(namespaceUri);
+      if(factory == null)
+      {
+         factory = defaultFactory;
+      }
+      return factory;
+   }
+
+   static Object invokeFactory(Object factory, Method method, Object[] args)
+   {
+      try
+      {
+         return method.invoke(factory, args);
+      }
+      catch(InvocationTargetException e)
+      {
+         Throwable te = e.getCause();
+         if(te instanceof RuntimeException)
+         {
+            throw (RuntimeException)te;
+         }
+
+         String msg = "Failed to invoke method " + method + ", factory=" + factory;
+         log.error(msg, e.getTargetException());
+
+         IllegalStateException ise = new IllegalStateException(msg);
+         ise.initCause(te);
+         throw ise;
+      }
+      catch(Exception e)
+      {
+         String msg = "Failed to invoke method " + method.getName() + ", factory=" + factory;
+         log.error(msg, e);
+         IllegalStateException ise = new IllegalStateException(msg);
+         ise.initCause(e);
+         throw ise;
+      }
+   }
+
+   static Method getMethodForElement(Object factory, String name, Class[] params)
+   {
+      Method method = null;
+      try
+      {
+         method = factory.getClass().getMethod(name, params);
+      }
+      catch(NoSuchMethodException e)
+      {
+      }
+      catch(SecurityException e)
+      {
+         throw e;
+      }
+
+      return method;
+   }
+
+   static final GenericObjectModelFactory getGenericObjectModelFactory(ObjectModelFactory factory)
+   {
+      if(!(factory instanceof GenericObjectModelFactory))
+      {
+         factory = new DelegatingObjectModelFactory(factory);
+      }
+      return factory instanceof GenericObjectModelFactory ?
+         (GenericObjectModelFactory)factory :
+         new DelegatingObjectModelFactory(factory);
+   }
+
+   private void pushAccepted(Object o)
+   {
+      accepted.push(o);
+   }
+
+   private Object popAccepted()
+   {
+      return accepted.pop();
+   }
+
+   private Object peekAccepted()
+   {
+      return accepted.peek();
+   }
+
+   private void pushAll(Object o)
+   {
+      all.push(new AllElement(o));
+   }
+
+   private AllElement popAll()
+   {
+      return (AllElement)all.pop();
+   }
+
+   private AllElement peekAll()
+   {
+      return (AllElement)all.peek();
+   }
+
+   private static final class AllElement
+   {
+      public final Object element;
+      public StringBuffer characters;
+
+      public AllElement(Object element)
+      {
+         this.element = element;
+      }
+   }
+
+   private static interface Stack
+   {
+      void clear();
+
+      void push(Object o);
+
+      Object pop();
+
+      Object peek();
+
+      boolean isEmpty();
+   }
+
+   private static class StackImpl
+      implements Stack
+   {
+      private List list = new ArrayList();
+
+      public void clear()
+      {
+         list.clear();
+      }
+
+      public void push(Object o)
+      {
+         list.add(o);
+      }
+
+      public Object pop()
+      {
+         return list.remove(list.size() - 1);
+      }
+
+      public Object peek()
+      {
+         return list.get(list.size() - 1);
+      }
+
+      public boolean isEmpty()
+      {
+         return list.isEmpty();
+      }
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,67 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding;
-
-import org.apache.xerces.xs.XSTypeDefinition;
-
-import javax.xml.namespace.QName;
-import javax.xml.namespace.NamespaceContext;
-import java.util.Iterator;
-
-/**
- * An interface for content navigation. At the moment it has only one method to get child's content.
- * But it could also implement XPath navigation.
- *
- * @version <tt>$Revision$</tt>
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- */
-public interface UnmarshallingContext
-{
-   /** Construct a QName from a value
-    * @param value A value that is of the form [prefix:]localpart
-    */
-   QName resolveQName(String value);
-
-   /**
-    * @return  all the known namespace URIs
-    */
-   Iterator getNamespaceURIs();
-
-   /**
-    * @return  NamespaceContext instance
-    */
-   NamespaceContext getNamespaceContext();
-
-   /**
-    * Returns child's content.
-    * todo consider deprecating this method
-    * @param namespaceURI
-    * @param qName
-    * @return
-    */
-   String getChildContent(String namespaceURI, String qName);
-
-   /**
-    * @return current element's type definition or null if this info is not available
-    */
-   XSTypeDefinition getType();
-}
\ No newline at end of file

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,79 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding;
+
+import org.apache.xerces.xs.XSTypeDefinition;
+
+import javax.xml.namespace.QName;
+import javax.xml.namespace.NamespaceContext;
+import java.util.Iterator;
+
+/**
+ * An interface for content navigation. At the moment it has only one method to get child's content.
+ * But it could also implement XPath navigation.
+ *
+ * @version <tt>$Revision$</tt>
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ */
+public interface UnmarshallingContext
+{
+   /** Construct a QName from a value
+    * @param value A value that is of the form [prefix:]localpart
+    */
+   QName resolveQName(String value);
+
+   /**
+    * @return  all the known namespace URIs
+    */
+   Iterator getNamespaceURIs();
+
+   /**
+    * @return  NamespaceContext instance
+    */
+   NamespaceContext getNamespaceContext();
+
+   /** 
+    * @return true if the text content passed to the setValue(...) method
+    * is automatically trimmed (the default).
+    */
+   boolean isTrimTextContent();
+   
+   /**
+    * Should the text content be automatically trimmed before setValue(...) is called.
+    * @param trimTextContent
+    */
+   void setTrimTextContent(boolean trimTextContent);
+
+   /**
+    * Returns child's content.
+    * todo consider deprecating this method
+    * @param namespaceURI
+    * @param qName
+    * @return
+    */
+   String getChildContent(String namespaceURI, String qName);
+
+   /**
+    * @return current element's type definition or null if this info is not available
+    */
+   XSTypeDefinition getType();
+}
\ No newline at end of file

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,128 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.introspection;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.util.Map;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision: $</tt>
- */
-public class ClassInfo
-{
-   private static final Object FIELD_INFO_NA = new Object();
-   private final Class type;
-   private Map fields = new ConcurrentHashMap();
-   private boolean introspected;
-
-   public ClassInfo(Class cls)
-   {
-      this.type = cls;
-   }
-
-   public Class getType()
-   {
-      return type;
-   }
-
-   /**
-    * @param name     the name of the field
-    * @param required if true never returns null (if the FieldInfo is not available, an exception will be thrown).
-    *                 If false and FieldInfo is not available then null will be returned.
-    * @return an instance of FieldInfo or null
-    */
-   public FieldInfo getFieldInfo(String name, boolean required)
-   {
-      Object o = fields.get(name);
-      if(o == null)
-      {
-         FieldInfo fieldInfo = FieldInfo.getFieldInfo(this, name);
-         if(fieldInfo == null)
-         {
-            fields.put(name, FIELD_INFO_NA);
-         }
-         else
-         {
-            return fieldInfo;
-         }
-      }
-      else if(o != FIELD_INFO_NA)
-      {
-         return (FieldInfo)o;
-      }
-
-      if(required)
-      {
-         throw new JBossXBRuntimeException(
-            "Failed to find read method or field for property '" + name + "' in " + type
-         );
-      }
-
-      return null;
-   }
-
-   void addFieldInfo(FieldInfo fieldInfo)
-   {
-      fields.put(fieldInfo.getName(), fieldInfo);
-   }
-
-   FieldInfo introspect(String name)
-   {
-      if(introspected)
-      {
-         return null;
-      }
-
-      try
-      {
-         BeanInfo info = java.beans.Introspector.getBeanInfo(type);
-         PropertyDescriptor[] props = info.getPropertyDescriptors();
-         if(props != null)
-         {
-            for(int i = 0; i < props.length; ++i)
-            {
-               PropertyDescriptor prop = props[i];
-               Method readMethod = prop.getReadMethod();
-               // todo: there are issues with null readMethod, e.g. scale in BigDecimal...
-               if(readMethod != null)
-               {
-                  Method writeMethod = prop.getWriteMethod();
-                  FieldInfo fieldInfo = new FieldInfo(type, prop.getName(), readMethod, writeMethod);
-                  addFieldInfo(fieldInfo);
-               }
-            }
-         }
-      }
-      catch(IntrospectionException e)
-      {
-      }
-
-      introspected = true;
-      return getFieldInfo(name, false);
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java (from rev 2482, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,129 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.introspection;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.xb.binding.JBossXBRuntimeException;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: $</tt>
+ */
+public class ClassInfo
+{
+   private static final Object FIELD_INFO_NA = new Object();
+   private final Class type;
+   private Map fields = new ConcurrentHashMap();
+   private boolean introspected;
+
+   public ClassInfo(Class cls)
+   {
+      this.type = cls;
+   }
+
+   public Class getType()
+   {
+      return type;
+   }
+
+   /**
+    * @param name     the name of the field
+    * @param required if true never returns null (if the FieldInfo is not available, an exception will be thrown).
+    *                 If false and FieldInfo is not available then null will be returned.
+    * @return an instance of FieldInfo or null
+    */
+   public FieldInfo getFieldInfo(String name, boolean required)
+   {
+      Object o = fields.get(name);
+      if(o == null)
+      {
+         FieldInfo fieldInfo = FieldInfo.getFieldInfo(this, name);
+         if(fieldInfo == null)
+         {
+            fields.put(name, FIELD_INFO_NA);
+         }
+         else
+         {
+            return fieldInfo;
+         }
+      }
+      else if(o != FIELD_INFO_NA)
+      {
+         return (FieldInfo)o;
+      }
+
+      if(required)
+      {
+         throw new JBossXBRuntimeException(
+            "Failed to find read method or field for property '" + name + "' in " + type
+         );
+      }
+
+      return null;
+   }
+
+   void addFieldInfo(FieldInfo fieldInfo)
+   {
+      fields.put(fieldInfo.getName(), fieldInfo);
+   }
+
+   FieldInfo introspect(String name)
+   {
+      if(introspected)
+      {
+         return null;
+      }
+
+      try
+      {
+         BeanInfo info = java.beans.Introspector.getBeanInfo(type);
+         PropertyDescriptor[] props = info.getPropertyDescriptors();
+         if(props != null)
+         {
+            for(int i = 0; i < props.length; ++i)
+            {
+               PropertyDescriptor prop = props[i];
+               Method readMethod = prop.getReadMethod();
+               // todo: there are issues with null readMethod, e.g. scale in BigDecimal...
+               if(readMethod != null)
+               {
+                  Method writeMethod = prop.getWriteMethod();
+                  FieldInfo fieldInfo = new FieldInfo(type, prop.getName(), readMethod, writeMethod);
+                  addFieldInfo(fieldInfo);
+               }
+            }
+         }
+      }
+      catch(IntrospectionException e)
+      {
+      }
+
+      introspected = true;
+      return getFieldInfo(name, false);
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,174 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.introspection;
-
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.lang.ref.WeakReference;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.util.NoopMap;
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision: $</tt>
- */
-public class ClassInfos
-{
-   private static Map classloaderCache = new WeakHashMap();
-
-   /**
-    * Disables caching of ClassInfo's. Already cached ClassInfo's will be lost after
-    * the method returns.
-    */
-   public static void disableCache()
-   {
-      synchronized(classloaderCache)
-      {
-         classloaderCache = NoopMap.INSTANCE;
-      }
-   }
-
-   /**
-    * Enables caching of ClassInfo's unless caching is already enabled.
-    */
-   public static void enableCache()
-   {
-      synchronized(classloaderCache)
-      {
-         if(!isCacheEnabled())
-         {
-            classloaderCache = new WeakHashMap();
-         }
-      }
-   }
-
-   /**
-    * @return true if caching is enabled, false otherwise.
-    */
-   public static boolean isCacheEnabled()
-   {
-      synchronized(classloaderCache)
-      {
-         return classloaderCache != NoopMap.INSTANCE;
-      }
-   }
-
-   /**
-    * Flushes all the cached ClassInfo's.
-    */
-   public static void flushCache()
-   {
-      synchronized(classloaderCache)
-      {
-         classloaderCache.clear();
-      }
-   }
-
-   /**
-    * Evicts ClassInfo for a specific class.
-    * @param cls  fully qualified class name of the class
-    */
-   public static void flushCache(String cls)
-   {
-      ClassLoader cl = Thread.currentThread().getContextClassLoader();
-      Map classLoaderCache = getClassLoaderCache(cl);
-      classLoaderCache.remove(cls);
-   }
-
-   /**
-    * Evicts ClassInfo for a specific class.
-    * @param cls  the class to remove the ClassInfo for
-    */
-   public static void flushCache(Class cls)
-   {
-      Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
-      classLoaderCache.remove(cls.getName());
-   }
-
-   public static ClassInfo getClassInfo(Class cls)
-   {
-      Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
-
-      WeakReference weak = (WeakReference)classLoaderCache.get(cls.getName());
-      if(weak != null)
-      {
-         Object result = weak.get();
-         if(result != null)
-         {
-            return (ClassInfo)result;
-         }
-      }
-
-      ClassInfo clsInfo = new ClassInfo(cls);
-      weak = new WeakReference(clsInfo);
-      classLoaderCache.put(cls.getName(), weak);
-      return clsInfo;
-   }
-
-   public static ClassInfo getClassInfo(String name, boolean required)
-   {
-      ClassLoader cl = Thread.currentThread().getContextClassLoader();
-      Map classLoaderCache = getClassLoaderCache(cl);
-
-      WeakReference weak = (WeakReference)classLoaderCache.get(name);
-      if(weak != null)
-      {
-         Object result = weak.get();
-         if(result != null)
-         {
-            return (ClassInfo)result;
-         }
-      }
-
-      try
-      {
-         ClassInfo clsInfo = new ClassInfo(cl.loadClass(name));
-         weak = new WeakReference(clsInfo);
-         classLoaderCache.put(name, weak);
-         return clsInfo;
-      }
-      catch(ClassNotFoundException e)
-      {
-         if(required)
-         {
-            throw new JBossXBRuntimeException("Failed to load class " + name);
-         }
-      }
-
-      return null;
-   }
-
-   private static Map getClassLoaderCache(ClassLoader cl)
-   {
-      synchronized(classloaderCache)
-      {
-         Map result = (Map) classloaderCache.get(cl);
-         if (result == null)
-         {
-            result = new ConcurrentHashMap();
-            classloaderCache.put(cl, result);
-         }
-         return result;
-      }
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java (from rev 2482, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,175 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.introspection;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.util.NoopMap;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: $</tt>
+ */
+public class ClassInfos
+{
+   private static Map classloaderCache = new WeakHashMap();
+
+   /**
+    * Disables caching of ClassInfo's. Already cached ClassInfo's will be lost after
+    * the method returns.
+    */
+   public static void disableCache()
+   {
+      synchronized(classloaderCache)
+      {
+         classloaderCache = NoopMap.INSTANCE;
+      }
+   }
+
+   /**
+    * Enables caching of ClassInfo's unless caching is already enabled.
+    */
+   public static void enableCache()
+   {
+      synchronized(classloaderCache)
+      {
+         if(!isCacheEnabled())
+         {
+            classloaderCache = new WeakHashMap();
+         }
+      }
+   }
+
+   /**
+    * @return true if caching is enabled, false otherwise.
+    */
+   public static boolean isCacheEnabled()
+   {
+      synchronized(classloaderCache)
+      {
+         return classloaderCache != NoopMap.INSTANCE;
+      }
+   }
+
+   /**
+    * Flushes all the cached ClassInfo's.
+    */
+   public static void flushCache()
+   {
+      synchronized(classloaderCache)
+      {
+         classloaderCache.clear();
+      }
+   }
+
+   /**
+    * Evicts ClassInfo for a specific class.
+    * @param cls  fully qualified class name of the class
+    */
+   public static void flushCache(String cls)
+   {
+      ClassLoader cl = Thread.currentThread().getContextClassLoader();
+      Map classLoaderCache = getClassLoaderCache(cl);
+      classLoaderCache.remove(cls);
+   }
+
+   /**
+    * Evicts ClassInfo for a specific class.
+    * @param cls  the class to remove the ClassInfo for
+    */
+   public static void flushCache(Class cls)
+   {
+      Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
+      classLoaderCache.remove(cls.getName());
+   }
+
+   public static ClassInfo getClassInfo(Class cls)
+   {
+      Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
+
+      WeakReference weak = (WeakReference)classLoaderCache.get(cls.getName());
+      if(weak != null)
+      {
+         Object result = weak.get();
+         if(result != null)
+         {
+            return (ClassInfo)result;
+         }
+      }
+
+      ClassInfo clsInfo = new ClassInfo(cls);
+      weak = new WeakReference(clsInfo);
+      classLoaderCache.put(cls.getName(), weak);
+      return clsInfo;
+   }
+
+   public static ClassInfo getClassInfo(String name, boolean required)
+   {
+      ClassLoader cl = Thread.currentThread().getContextClassLoader();
+      Map classLoaderCache = getClassLoaderCache(cl);
+
+      WeakReference weak = (WeakReference)classLoaderCache.get(name);
+      if(weak != null)
+      {
+         Object result = weak.get();
+         if(result != null)
+         {
+            return (ClassInfo)result;
+         }
+      }
+
+      try
+      {
+         ClassInfo clsInfo = new ClassInfo(cl.loadClass(name));
+         weak = new WeakReference(clsInfo);
+         classLoaderCache.put(name, weak);
+         return clsInfo;
+      }
+      catch(ClassNotFoundException e)
+      {
+         if(required)
+         {
+            throw new JBossXBRuntimeException("Failed to load class " + name);
+         }
+      }
+
+      return null;
+   }
+
+   private static Map getClassLoaderCache(ClassLoader cl)
+   {
+      synchronized(classloaderCache)
+      {
+         Map result = (Map) classloaderCache.get(cl);
+         if (result == null)
+         {
+            result = new ConcurrentHashMap();
+            classloaderCache.put(cl, result);
+         }
+         return result;
+      }
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,384 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.parser.sax;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.lang.reflect.Method;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import org.jboss.logging.Logger;
-import org.jboss.util.JBossStringBuilder;
-import org.jboss.util.xml.JBossEntityResolver;
-import org.jboss.xb.binding.JBossXBException;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.parser.JBossXBParser;
-import org.xml.sax.Attributes;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.XMLReader;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class SaxJBossXBParser
-   implements JBossXBParser
-{
-   private static final Logger log = Logger.getLogger(SaxJBossXBParser.class);
-
-   private static final SAXParserFactory saxFactory = SAXParserFactory.newInstance();
-   static
-   {
-      saxFactory.setValidating(true);
-      saxFactory.setNamespaceAware(true);
-      enableXInclude();
-   }
-
-   private final XMLReader reader;
-   private JBossXBParser.ContentHandler contentHandler;
-   private DelegatingContentHandler delegateHandler;
-   private boolean trace;
-
-   /**
-    * Enables XInclude if the saxFactory supports it.<p>
-    * 
-    * NOTE: Checks the real factory class, not the JAXP interface.
-    */
-   private static void enableXInclude()
-   {
-      try
-      {
-         Class clazz = saxFactory.getClass();
-         Method method = clazz.getMethod("setXIncludeAware", new Class[] { Boolean.TYPE });
-         method.invoke(saxFactory, new Object[] { Boolean.TRUE });
-      }
-      catch (Exception e)
-      {
-         log.trace("Not setting XIncludeAware", e);
-      }
-   }
-   
-   public SaxJBossXBParser()
-      throws JBossXBException
-   {
-      SAXParser parser;
-      try
-      {
-         parser = saxFactory.newSAXParser();
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBException("Failed to create a new SAX parser", e);
-      }
-
-      try
-      {
-         reader = parser.getXMLReader();
-      }
-      catch(SAXException e1)
-      {
-         throw new JBossXBRuntimeException("Failed to get parser's XMLReader", e1);
-      }
-
-      delegateHandler = new DelegatingContentHandler();
-      reader.setContentHandler(delegateHandler);
-      reader.setErrorHandler(MetaDataErrorHandler.INSTANCE);
-      reader.setEntityResolver(new JBossEntityResolver());
-
-/*
-      setFeature(Unmarshaller.VALIDATION, true);
-      setFeature(Unmarshaller.SCHEMA_VALIDATION, true);
-      setFeature(Unmarshaller.SCHEMA_FULL_CHECKING, true);
-      setFeature(Unmarshaller.DYNAMIC_VALIDATION, true);
-      setFeature(Unmarshaller.NAMESPACES, true);
-*/
-   }
-
-   // JBossXBParser implementation
-
-   public void setEntityResolver(EntityResolver entityResolver)
-      throws JBossXBException
-   {
-      reader.setEntityResolver(entityResolver);
-   }
-
-   public void setProperty(String name, Object value)
-   {
-      try
-      {
-         reader.setProperty(name, value);
-      }
-      catch(SAXException e)
-      {
-         throw new JBossXBRuntimeException("Failed to set property on the XML reader", e);
-      }
-   }
-
-   public void setFeature(String name, boolean value)
-   {
-      try
-      {
-         reader.setFeature(name, value);
-      }
-      catch(SAXException e)
-      {
-         throw new JBossXBRuntimeException("Failed to set feature on the XMLReader", e);
-      }
-   }
-
-   public void parse(String systemId, ContentHandler handler) throws JBossXBException
-   {
-      this.contentHandler = handler;
-      trace = log.isTraceEnabled();
-      try
-      {
-         reader.parse(systemId);
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBException("Failed to parse source: " + getLocationAsString(systemId), e);
-      }
-   }
-
-   public void parse(InputStream is, ContentHandler handler) throws JBossXBException
-   {
-      this.contentHandler = handler;
-      trace = log.isTraceEnabled();
-      try
-      {
-         reader.parse(new InputSource(is));
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
-      }
-   }
-
-   public void parse(Reader reader, ContentHandler handler) throws JBossXBException
-   {
-      this.contentHandler = handler;
-      trace = log.isTraceEnabled();
-      try
-      {
-         this.reader.parse(new InputSource(reader));
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
-      }
-   }
-
-   public String getLocationAsString(String fileName)
-   {
-      Locator locator = delegateHandler.getDocumentLocator();
-      if (locator == null)
-         return fileName;
-      else
-      {
-         JBossStringBuilder buffer = new JBossStringBuilder();
-         String id = locator.getSystemId();
-         if (id == null)
-            id = locator.getPublicId();
-         buffer.append(id).append('@');
-         buffer.append(locator.getLineNumber());
-         buffer.append(',');
-         buffer.append(locator.getColumnNumber());
-         return buffer.toString();
-      }
-   }
-
-   // Inner
-
-   private final class DelegatingContentHandler
-      implements org.xml.sax.ContentHandler
-   {
-      Locator locator;
-      
-      public void endDocument()
-      {
-      }
-
-      public void startDocument()
-      {
-      }
-
-      public void characters(char ch[], int start, int length)
-      {
-         // todo look at this later
-         // do not notify content handler if these are just whitespaces
-         int i = start;
-         while(i < start + length)
-         {
-            if(!Character.isWhitespace(ch[i++]))
-            {
-               contentHandler.characters(ch, start, length);
-               break;
-            }
-         }
-      }
-
-      public void ignorableWhitespace(char ch[], int start, int length)
-      {
-      }
-
-      public void endPrefixMapping(String prefix)
-      {
-         contentHandler.endPrefixMapping(prefix);
-      }
-
-      public void skippedEntity(String name)
-      {
-      }
-
-      public Locator getDocumentLocator()
-      {
-         return locator;
-      }
-      
-      public void setDocumentLocator(Locator locator)
-      {
-         this.locator = locator;
-      }
-
-      public void processingInstruction(String target, String data)
-      {
-         contentHandler.processingInstruction(target, data);
-      }
-
-      public void startPrefixMapping(String prefix, String uri)
-      {
-         contentHandler.startPrefixMapping(prefix, uri);
-      }
-
-      public void endElement(String namespaceURI, String localName, String qName)
-      {
-         String name = null;
-         if(trace)
-         {
-            if(localName.length() == 0)
-            {
-               name = qName;
-            }
-            else
-            {
-               name = namespaceURI + ':' + localName;
-            }
-            log.trace("Enter endElement " + name);
-         }
-         try
-         {
-            contentHandler.endElement(namespaceURI, localName, qName);
-         }
-         finally
-         {
-            if(trace)
-            {
-               log.trace("Exit endElement  " + name);
-            }
-         }
-      }
-
-      public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
-      {
-         String name = null;
-         if(trace)
-         {
-            if(localName.length() == 0)
-            {
-               name = qName;
-            }
-            else
-            {
-               name = namespaceURI + ':' + localName;
-            }
-            log.trace("Enter startElement " + name);
-         }
-         try
-         {
-            contentHandler.startElement(namespaceURI, localName, qName, atts, null);
-         }
-         finally
-         {
-            if(trace)
-            {
-               log.trace("Exit startElement  " + name);
-            }
-         }
-      }
-   }
-
-   private static final class MetaDataErrorHandler
-      implements ErrorHandler
-   {
-      public static final ErrorHandler INSTANCE = new MetaDataErrorHandler();
-
-      public void warning(SAXParseException exception)
-      {
-         log.warn(formatMessage(exception));
-      }
-
-      public void error(SAXParseException exception)
-         throws SAXException
-      {
-         throw new SAXException(formatMessage(exception));
-      }
-
-      public void fatalError(SAXParseException exception)
-         throws SAXException
-      {
-         throw new SAXException(formatMessage(exception));
-      }
-
-      public String formatMessage(SAXParseException exception)
-      {
-         StringBuffer buffer = new StringBuffer(50);
-         buffer.append(exception.getMessage()).append(" @ ");
-         String location = exception.getPublicId();
-         if(location != null)
-         {
-            buffer.append(location);
-         }
-         else
-         {
-            location = exception.getSystemId();
-            if(location != null)
-            {
-               buffer.append(location);
-            }
-            else
-            {
-               buffer.append("*unknown*");
-            }
-         }
-         buffer.append('[');
-         buffer.append(exception.getLineNumber()).append(',');
-         buffer.append(exception.getColumnNumber()).append(']');
-         return buffer.toString();
-      }
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,385 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.parser.sax;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Method;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.jboss.logging.Logger;
+import org.jboss.util.JBossStringBuilder;
+import org.jboss.util.xml.JBossEntityResolver;
+import org.jboss.xb.binding.JBossXBException;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.parser.JBossXBParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class SaxJBossXBParser
+   implements JBossXBParser
+{
+   private static final Logger log = Logger.getLogger(SaxJBossXBParser.class);
+
+   private static final SAXParserFactory saxFactory = SAXParserFactory.newInstance();
+   static
+   {
+      saxFactory.setValidating(true);
+      saxFactory.setNamespaceAware(true);
+      enableXInclude();
+   }
+
+   private final XMLReader reader;
+   private JBossXBParser.ContentHandler contentHandler;
+   private DelegatingContentHandler delegateHandler;
+   private boolean trace;
+
+   /**
+    * Enables XInclude if the saxFactory supports it.<p>
+    * 
+    * NOTE: Checks the real factory class, not the JAXP interface.
+    */
+   private static void enableXInclude()
+   {
+      try
+      {
+         Class clazz = saxFactory.getClass();
+         Method method = clazz.getMethod("setXIncludeAware", new Class[] { Boolean.TYPE });
+         method.invoke(saxFactory, new Object[] { Boolean.TRUE });
+      }
+      catch (Exception e)
+      {
+         log.trace("Not setting XIncludeAware", e);
+      }
+   }
+   
+   public SaxJBossXBParser()
+      throws JBossXBException
+   {
+      SAXParser parser;
+      try
+      {
+         parser = saxFactory.newSAXParser();
+      }
+      catch(Exception e)
+      {
+         throw new JBossXBException("Failed to create a new SAX parser", e);
+      }
+
+      try
+      {
+         reader = parser.getXMLReader();
+      }
+      catch(SAXException e1)
+      {
+         throw new JBossXBRuntimeException("Failed to get parser's XMLReader", e1);
+      }
+
+      delegateHandler = new DelegatingContentHandler();
+      reader.setContentHandler(delegateHandler);
+      reader.setErrorHandler(MetaDataErrorHandler.INSTANCE);
+      reader.setEntityResolver(new JBossEntityResolver());
+
+/*
+      setFeature(Unmarshaller.VALIDATION, true);
+      setFeature(Unmarshaller.SCHEMA_VALIDATION, true);
+      setFeature(Unmarshaller.SCHEMA_FULL_CHECKING, true);
+      setFeature(Unmarshaller.DYNAMIC_VALIDATION, true);
+      setFeature(Unmarshaller.NAMESPACES, true);
+*/
+   }
+
+   // JBossXBParser implementation
+
+   public void setEntityResolver(EntityResolver entityResolver)
+      throws JBossXBException
+   {
+      reader.setEntityResolver(entityResolver);
+   }
+
+   public void setProperty(String name, Object value)
+   {
+      try
+      {
+         reader.setProperty(name, value);
+      }
+      catch(SAXException e)
+      {
+         throw new JBossXBRuntimeException("Failed to set property on the XML reader", e);
+      }
+   }
+
+   public void setFeature(String name, boolean value)
+   {
+      try
+      {
+         reader.setFeature(name, value);
+      }
+      catch(SAXException e)
+      {
+         throw new JBossXBRuntimeException("Failed to set feature on the XMLReader", e);
+      }
+   }
+
+   public void parse(String systemId, ContentHandler handler) throws JBossXBException
+   {
+      this.contentHandler = handler;
+      trace = log.isTraceEnabled();
+      try
+      {
+         reader.parse(systemId);
+      }
+      catch(Exception e)
+      {
+e.printStackTrace();
+         throw new JBossXBException("Failed to parse source: " + getLocationAsString(systemId), e);
+      }
+   }
+
+   public void parse(InputStream is, ContentHandler handler) throws JBossXBException
+   {
+      this.contentHandler = handler;
+      trace = log.isTraceEnabled();
+      try
+      {
+         reader.parse(new InputSource(is));
+      }
+      catch(Exception e)
+      {
+         throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
+      }
+   }
+
+   public void parse(Reader reader, ContentHandler handler) throws JBossXBException
+   {
+      this.contentHandler = handler;
+      trace = log.isTraceEnabled();
+      try
+      {
+         this.reader.parse(new InputSource(reader));
+      }
+      catch(Exception e)
+      {
+         throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
+      }
+   }
+
+   public String getLocationAsString(String fileName)
+   {
+      Locator locator = delegateHandler.getDocumentLocator();
+      if (locator == null)
+         return fileName;
+      else
+      {
+         JBossStringBuilder buffer = new JBossStringBuilder();
+         String id = locator.getSystemId();
+         if (id == null)
+            id = locator.getPublicId();
+         buffer.append(id).append('@');
+         buffer.append(locator.getLineNumber());
+         buffer.append(',');
+         buffer.append(locator.getColumnNumber());
+         return buffer.toString();
+      }
+   }
+
+   // Inner
+
+   private final class DelegatingContentHandler
+      implements org.xml.sax.ContentHandler
+   {
+      Locator locator;
+      
+      public void endDocument()
+      {
+      }
+
+      public void startDocument()
+      {
+      }
+
+      public void characters(char ch[], int start, int length)
+      {
+         // todo look at this later
+         // do not notify content handler if these are just whitespaces
+         //int i = start;
+         //while(i < start + length)
+         //{
+         //   if(!Character.isWhitespace(ch[i++]))
+         //   {
+               contentHandler.characters(ch, start, length);
+         //      break;
+         //   }
+         //}
+      }
+
+      public void ignorableWhitespace(char ch[], int start, int length)
+      {
+      }
+
+      public void endPrefixMapping(String prefix)
+      {
+         contentHandler.endPrefixMapping(prefix);
+      }
+
+      public void skippedEntity(String name)
+      {
+      }
+
+      public Locator getDocumentLocator()
+      {
+         return locator;
+      }
+      
+      public void setDocumentLocator(Locator locator)
+      {
+         this.locator = locator;
+      }
+
+      public void processingInstruction(String target, String data)
+      {
+         contentHandler.processingInstruction(target, data);
+      }
+
+      public void startPrefixMapping(String prefix, String uri)
+      {
+         contentHandler.startPrefixMapping(prefix, uri);
+      }
+
+      public void endElement(String namespaceURI, String localName, String qName)
+      {
+         String name = null;
+         if(trace)
+         {
+            if(localName.length() == 0)
+            {
+               name = qName;
+            }
+            else
+            {
+               name = namespaceURI + ':' + localName;
+            }
+            log.trace("Enter endElement " + name);
+         }
+         try
+         {
+            contentHandler.endElement(namespaceURI, localName, qName);
+         }
+         finally
+         {
+            if(trace)
+            {
+               log.trace("Exit endElement  " + name);
+            }
+         }
+      }
+
+      public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
+      {
+         String name = null;
+         if(trace)
+         {
+            if(localName.length() == 0)
+            {
+               name = qName;
+            }
+            else
+            {
+               name = namespaceURI + ':' + localName;
+            }
+            log.trace("Enter startElement " + name);
+         }
+         try
+         {
+            contentHandler.startElement(namespaceURI, localName, qName, atts, null);
+         }
+         finally
+         {
+            if(trace)
+            {
+               log.trace("Exit startElement  " + name);
+            }
+         }
+      }
+   }
+
+   private static final class MetaDataErrorHandler
+      implements ErrorHandler
+   {
+      public static final ErrorHandler INSTANCE = new MetaDataErrorHandler();
+
+      public void warning(SAXParseException exception)
+      {
+         log.warn(formatMessage(exception));
+      }
+
+      public void error(SAXParseException exception)
+         throws SAXException
+      {
+         throw new SAXException(formatMessage(exception));
+      }
+
+      public void fatalError(SAXParseException exception)
+         throws SAXException
+      {
+         throw new SAXException(formatMessage(exception));
+      }
+
+      public String formatMessage(SAXParseException exception)
+      {
+         StringBuffer buffer = new StringBuffer(50);
+         buffer.append(exception.getMessage()).append(" @ ");
+         String location = exception.getPublicId();
+         if(location != null)
+         {
+            buffer.append(location);
+         }
+         else
+         {
+            location = exception.getSystemId();
+            if(location != null)
+            {
+               buffer.append(location);
+            }
+            else
+            {
+               buffer.append("*unknown*");
+            }
+         }
+         buffer.append('[');
+         buffer.append(exception.getLineNumber()).append(',');
+         buffer.append(exception.getColumnNumber()).append(']');
+         return buffer.toString();
+      }
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,437 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.sunday.unmarshalling;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.xml.namespace.QName;
-
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
-import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
-import org.jboss.xb.binding.metadata.PackageMetaData;
-import org.jboss.xb.util.DomCharactersHandler;
-import org.jboss.xb.util.DomLocalMarshaller;
-import org.jboss.xb.util.DomParticleHandler;
-
-
-/**
- * A SchemaBinding is a collection of binding objects (TypeBinding,
- * ChoiceBinding, ElementBinding, ModelGroupBinding, SequenceBinding, WildcardBinding)
- * for a single namespace keyed by the QNames of the schema components.
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class SchemaBinding
-{
-   private static final ValueAdapter DATE_ADAPTER = new ValueAdapter()
-   {
-      public Object cast(Object o, Class c)
-      {
-         if (o != null && java.util.Date.class.isAssignableFrom(c))
-         {
-            o = ((java.util.Calendar) o).getTime();
-         }
-         return o;
-      }
-   };
-
-   /** The namespaces Set<String> */
-   private Set namespaces = Collections.EMPTY_SET;
-   /** Map<QName, TypeBinding> for simple/complex types */
-   private Map types = new HashMap();
-   /** Map<QName, ParticleBinding> for */
-   private Map elements = new HashMap();
-   /** The default package information */
-   private PackageMetaData packageMetaData;
-   /** Schema resolver to use for foreign namespaces */
-   private SchemaBindingResolver schemaResolver;
-   /** Must all content have a valid binding */
-   private boolean strictSchema = true;
-   /** Should child elements be ignored if they don't map to a parent field */
-   private boolean ignoreUnresolvedFieldOrClass = true;
-   /** Should '_' be considered as a word separator or part of Java identifier */
-   private boolean ignoreLowLine = true;
-   /** Should ${x} references be replaced with x system property */
-   private boolean replacePropertyRefs = true;
-   /** Should list xml types be unmarshalled as arrays */
-   private boolean unmarshalListsToArrays;
-   /** Should the default no-arg ctor be used to create the java instance */
-   private boolean useNoArgCtorIfFound;
-   /** The default property name to use for simple content bindings */
-   private String simpleContentProperty = "value";
-
-   /** default XOP unmarshaller */
-   private XOPUnmarshaller xopUnmarshaller;
-   /** default XOP marshaller */
-   private XOPMarshaller xopMarshaller;
-
-   public SchemaBinding()
-   {
-      addType(new SimpleTypeBinding(Constants.QNAME_ANYSIMPLETYPE));
-      addType(new SimpleTypeBinding(Constants.QNAME_STRING));
-      addType(new SimpleTypeBinding(Constants.QNAME_BOOLEAN));
-      addType(new SimpleTypeBinding(Constants.QNAME_DECIMAL));
-      addType(new SimpleTypeBinding(Constants.QNAME_FLOAT));
-      addType(new SimpleTypeBinding(Constants.QNAME_DOUBLE));
-      addType(new SimpleTypeBinding(Constants.QNAME_DURATION));
-      addType(new SimpleTypeBinding(Constants.QNAME_DATETIME, DATE_ADAPTER));
-      addType(new SimpleTypeBinding(Constants.QNAME_TIME, DATE_ADAPTER));
-      addType(new SimpleTypeBinding(Constants.QNAME_DATE, DATE_ADAPTER));
-      addType(new SimpleTypeBinding(Constants.QNAME_GYEARMONTH));
-      addType(new SimpleTypeBinding(Constants.QNAME_GYEAR));
-      addType(new SimpleTypeBinding(Constants.QNAME_GMONTHDAY));
-      addType(new SimpleTypeBinding(Constants.QNAME_GDAY));
-      addType(new SimpleTypeBinding(Constants.QNAME_GMONTH));
-      addType(new SimpleTypeBinding(Constants.QNAME_HEXBINARY));
-      addType(new SimpleTypeBinding(Constants.QNAME_BASE64BINARY));
-      addType(new SimpleTypeBinding(Constants.QNAME_ANYURI));
-      addType(new SimpleTypeBinding(Constants.QNAME_QNAME));
-      addType(new SimpleTypeBinding(Constants.QNAME_NOTATION));
-      addType(new SimpleTypeBinding(Constants.QNAME_NORMALIZEDSTRING));
-      addType(new SimpleTypeBinding(Constants.QNAME_TOKEN));
-      addType(new SimpleTypeBinding(Constants.QNAME_LANGUAGE));
-      addType(new SimpleTypeBinding(Constants.QNAME_NMTOKEN));
-      addType(new SimpleTypeBinding(Constants.QNAME_NMTOKENS));
-      addType(new SimpleTypeBinding(Constants.QNAME_NAME));
-      addType(new SimpleTypeBinding(Constants.QNAME_NCNAME));
-      addType(new SimpleTypeBinding(Constants.QNAME_ID));
-      addType(new SimpleTypeBinding(Constants.QNAME_IDREF));
-      addType(new SimpleTypeBinding(Constants.QNAME_IDREFS));
-      addType(new SimpleTypeBinding(Constants.QNAME_ENTITY));
-      addType(new SimpleTypeBinding(Constants.QNAME_ENTITIES));
-      addType(new SimpleTypeBinding(Constants.QNAME_INTEGER));
-      addType(new SimpleTypeBinding(Constants.QNAME_NONPOSITIVEINTEGER));
-      addType(new SimpleTypeBinding(Constants.QNAME_NEGATIVEINTEGER));
-      addType(new SimpleTypeBinding(Constants.QNAME_LONG));
-      addType(new SimpleTypeBinding(Constants.QNAME_INT));
-      addType(new SimpleTypeBinding(Constants.QNAME_SHORT));
-      addType(new SimpleTypeBinding(Constants.QNAME_BYTE));
-      addType(new SimpleTypeBinding(Constants.QNAME_NONNEGATIVEINTEGER));
-      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDLONG));
-      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDINT));
-      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDSHORT));
-      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDBYTE));
-      addType(new SimpleTypeBinding(Constants.QNAME_POSITIVEINTEGER));
-   }
-
-   /**
-    * Get the namespaces.
-    * 
-    * @return the namespaces.
-    */
-   public Set getNamespaces()
-   {
-      return namespaces;
-   }
-
-   /**
-    * Set the namespaces.
-    * 
-    * @param namespaces the namespaces.
-    * @throws IllegalArgumentException for null spaces
-    */
-   public void setNamespaces(Set namespaces)
-   {
-      if (namespaces == null)
-         throw new IllegalArgumentException("Null namespaces");
-      this.namespaces = namespaces;
-   }
-
-   public TypeBinding getType(QName qName)
-   {
-      return (TypeBinding)types.get(qName);
-   }
-
-   public void addType(TypeBinding type)
-   {
-      QName qName = type.getQName();
-      if(qName == null)
-      {
-         throw new JBossXBRuntimeException("Global type must have a name.");
-      }
-      types.put(qName, type);
-   }
-
-   public ElementBinding getElement(QName name)
-   {
-      ParticleBinding particle = (ParticleBinding)elements.get(name);
-      ElementBinding element = (ElementBinding)(particle == null ? null : particle.getTerm());
-      return element;
-   }
-
-   public ParticleBinding getElementParticle(QName name)
-   {
-      return (ParticleBinding)elements.get(name);
-   }
-
-   public void addElement(ElementBinding element)
-   {
-      ParticleBinding particle = new ParticleBinding(element);
-      elements.put(element.getQName(), particle);
-   }
-
-   public ElementBinding addElement(QName name, TypeBinding type)
-   {
-      ElementBinding element = new ElementBinding(this, name, type);
-      addElement(element);
-      return element;
-   }
-
-   public Iterator getElements()
-   {
-      return new Iterator()
-      {
-         private Iterator particleIterator = elements.values().iterator();
-
-         public boolean hasNext()
-         {
-            return particleIterator.hasNext();
-         }
-
-         public Object next()
-         {
-            ParticleBinding particle = (ParticleBinding)particleIterator.next();
-            return particle.getTerm();
-         }
-
-         public void remove()
-         {
-            throw new UnsupportedOperationException("remove is not implemented.");
-         }
-      };
-   }
-
-   public Iterator getElementParticles()
-   {
-      return elements.values().iterator();
-   }
-
-   public Iterator getTypes()
-   {
-      return Collections.unmodifiableCollection(types.values()).iterator();
-   }
-
-   public PackageMetaData getPackageMetaData()
-   {
-      return packageMetaData;
-   }
-
-   public void setPackageMetaData(PackageMetaData packageMetaData)
-   {
-      this.packageMetaData = packageMetaData;
-   }
-
-   public SchemaBindingResolver getSchemaResolver()
-   {
-      return schemaResolver;
-   }
-
-   public void setSchemaResolver(SchemaBindingResolver schemaResolver)
-   {
-      this.schemaResolver = schemaResolver;
-   }
-
-   public boolean isStrictSchema()
-   {
-      return strictSchema;
-   }
-
-   /**
-    * If strict-schema is true then all the elements and attributes in XML content being parsed must be bound
-    * in this instance of SchemaBinding (except attributes from xmlns and xsi namespaces),
-    * otherwise a runtime exception is thrown. The default value for this property is true.
-    */
-   public void setStrictSchema(boolean strictSchema)
-   {
-      this.strictSchema = strictSchema;
-   }
-
-   public boolean isIgnoreUnresolvedFieldOrClass()
-   {
-      return ignoreUnresolvedFieldOrClass;
-   }
-
-   /**
-    * If a field is not found in the parent class to set child value on or
-    * a class an element is bound to
-    * an exception will be thrown if this property is false. Otherwise,
-    * the process will just go on (the default for now).
-    */
-   public void setIgnoreUnresolvedFieldOrClass(boolean ignoreUnresolvedFieldOrClass)
-   {
-      this.ignoreUnresolvedFieldOrClass = ignoreUnresolvedFieldOrClass;
-   }
-
-   public boolean isReplacePropertyRefs()
-   {
-      return replacePropertyRefs;
-   }
-   /**
-    *
-    * @param flag
-    */
-   public void setReplacePropertyRefs(boolean flag)
-   {
-      this.replacePropertyRefs = flag;
-   }
-
-   public boolean isIgnoreLowLine()
-   {
-      return ignoreLowLine;
-   }
-
-   /**
-    * Where '_' should be considered as a word separator or a part of the Java identifier
-    * when mapping XML names to Java identifiers.
-    */
-   public void setIgnoreLowLine(boolean ignoreLowLine)
-   {
-      this.ignoreLowLine = ignoreLowLine;
-   }
-
-   public boolean isUnmarshalListsToArrays()
-   {
-      return unmarshalListsToArrays;
-   }
-
-   /**
-    * Should list xml types be unmarshalled as arrays
-    * @param unmarshalListsToArrays
-    */
-   public void setUnmarshalListsToArrays(boolean unmarshalListsToArrays)
-   {
-      this.unmarshalListsToArrays = unmarshalListsToArrays;
-   }
-
-   public boolean isUseNoArgCtorIfFound()
-   {
-      return useNoArgCtorIfFound;
-   }
-
-   /**
-    * Should the default no-arg ctor be used to create the java instance
-    * @param useNoArgCtorIfFound
-    */
-   public void setUseNoArgCtorIfFound(boolean useNoArgCtorIfFound)
-   {
-      this.useNoArgCtorIfFound = useNoArgCtorIfFound;
-   }
-
-   public String getSimpleContentProperty()
-   {
-      return simpleContentProperty;
-   }
-
-   /**
-    * Set the default property name to use for simple content bindings
-    * @param simpleContentProperty
-    */
-   public void setSimpleContentProperty(String simpleContentProperty)
-   {
-      this.simpleContentProperty = simpleContentProperty;
-   }
-
-   /**
-    * @return  schema default XOP unmarshaller
-    */
-   public XOPUnmarshaller getXopUnmarshaller()
-   {
-      return xopUnmarshaller;
-   }
-
-   /**
-    * @param xopUnmarshaller  schema default XOP unmarshaller
-    */
-   public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
-   {
-      this.xopUnmarshaller = xopUnmarshaller;
-   }
-
-   /**
-    * @return schema default XOP marshaller
-    */
-   public XOPMarshaller getXopMarshaller()
-   {
-      return xopMarshaller;
-   }
-
-   /**
-    * @param xopMarshaller  schema default XOP marshaller
-    */
-   public void setXopMarshaller(XOPMarshaller xopMarshaller)
-   {
-      this.xopMarshaller = xopMarshaller;
-   }
-
-   public void setUnresolvedContentBoundToDOM(boolean toDom)
-   {
-      TypeBinding type = getType(Constants.QNAME_ANYTYPE);
-      if(type == null)
-      {
-         // ignore, there is no use of the anyType in the schema
-         return;
-         //throw new JBossXBRuntimeException("anyType is not bound.");
-      }
-
-      WildcardBinding wildcard = type.getWildcard();
-      if(toDom)
-      {
-         wildcard.setUnresolvedCharactersHandler(DomCharactersHandler.INSTANCE);
-         wildcard.setUnresolvedElementHandler(DomParticleHandler.INSTANCE);
-         wildcard.setUnresolvedMarshaller(DomLocalMarshaller.INSTANCE);
-      }
-      else
-      {
-         wildcard.setUnresolvedCharactersHandler(null);
-         wildcard.setUnresolvedElementHandler(null);
-         wildcard.setUnresolvedMarshaller(null);
-      }
-   }
-   
-   public boolean isUnresolvedContentBoundToDOM()
-   {
-      TypeBinding type = getType(Constants.QNAME_ANYTYPE);
-      if(type == null)
-      {
-         // there is no use of the anyType in the schema
-         return false;
-         //throw new JBossXBRuntimeException("anyType is not bound.");
-      }
-
-      WildcardBinding wildcard = type.getWildcard();
-      return wildcard.getUnresolvedCharactersHandler() instanceof DomCharactersHandler
-      && wildcard.getUnresolvedElementHandler() instanceof DomParticleHandler
-      && wildcard.getUnresolvedMarshaller() instanceof DomLocalMarshaller;
-   }
-
-   void addElementParticle(ParticleBinding particle)
-   {
-      ElementBinding element = (ElementBinding)particle.getTerm();
-      elements.put(element.getQName(), particle);
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,452 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.sunday.unmarshalling;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
+import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
+import org.jboss.xb.binding.metadata.PackageMetaData;
+import org.jboss.xb.util.DomCharactersHandler;
+import org.jboss.xb.util.DomLocalMarshaller;
+import org.jboss.xb.util.DomParticleHandler;
+
+
+/**
+ * A SchemaBinding is a collection of binding objects (TypeBinding,
+ * ChoiceBinding, ElementBinding, ModelGroupBinding, SequenceBinding, WildcardBinding)
+ * for a single namespace keyed by the QNames of the schema components.
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class SchemaBinding
+{
+   private static final ValueAdapter DATE_ADAPTER = new ValueAdapter()
+   {
+      public Object cast(Object o, Class c)
+      {
+         if (o != null && java.util.Date.class.isAssignableFrom(c))
+         {
+            o = ((java.util.Calendar) o).getTime();
+         }
+         return o;
+      }
+   };
+
+   /** The namespaces Set<String> */
+   private Set namespaces = Collections.EMPTY_SET;
+   /** Map<QName, TypeBinding> for simple/complex types */
+   private Map types = new HashMap();
+   /** Map<QName, ParticleBinding> for */
+   private Map elements = new HashMap();
+   /** The default package information */
+   private PackageMetaData packageMetaData;
+   /** Schema resolver to use for foreign namespaces */
+   private SchemaBindingResolver schemaResolver;
+   /** Must all content have a valid binding */
+   private boolean strictSchema = true;
+   /** Should child elements be ignored if they don't map to a parent field */
+   private boolean ignoreUnresolvedFieldOrClass = true;
+   /** Should '_' be considered as a word separator or part of Java identifier */
+   private boolean ignoreLowLine = true;
+   /** Should ${x} references be replaced with x system property */
+   private boolean replacePropertyRefs = true;
+   /** Should list xml types be unmarshalled as arrays */
+   private boolean unmarshalListsToArrays;
+   /** Should the default no-arg ctor be used to create the java instance */
+   private boolean useNoArgCtorIfFound;
+   /** The default property name to use for simple content bindings */
+   private String simpleContentProperty = "value";
+
+   /** if all the characters in the mixed content are whitespaces
+    *  should they be considered indentation and ignored?
+    *  the default is true for the backwards compatibility */
+   private boolean ignoreWhitespacesInMixedContent = true;
+
+   /** default XOP unmarshaller */
+   private XOPUnmarshaller xopUnmarshaller;
+   /** default XOP marshaller */
+   private XOPMarshaller xopMarshaller;
+
+   public SchemaBinding()
+   {
+      addType(new SimpleTypeBinding(Constants.QNAME_ANYSIMPLETYPE));
+      addType(new SimpleTypeBinding(Constants.QNAME_STRING));
+      addType(new SimpleTypeBinding(Constants.QNAME_BOOLEAN));
+      addType(new SimpleTypeBinding(Constants.QNAME_DECIMAL));
+      addType(new SimpleTypeBinding(Constants.QNAME_FLOAT));
+      addType(new SimpleTypeBinding(Constants.QNAME_DOUBLE));
+      addType(new SimpleTypeBinding(Constants.QNAME_DURATION));
+      addType(new SimpleTypeBinding(Constants.QNAME_DATETIME, DATE_ADAPTER));
+      addType(new SimpleTypeBinding(Constants.QNAME_TIME, DATE_ADAPTER));
+      addType(new SimpleTypeBinding(Constants.QNAME_DATE, DATE_ADAPTER));
+      addType(new SimpleTypeBinding(Constants.QNAME_GYEARMONTH));
+      addType(new SimpleTypeBinding(Constants.QNAME_GYEAR));
+      addType(new SimpleTypeBinding(Constants.QNAME_GMONTHDAY));
+      addType(new SimpleTypeBinding(Constants.QNAME_GDAY));
+      addType(new SimpleTypeBinding(Constants.QNAME_GMONTH));
+      addType(new SimpleTypeBinding(Constants.QNAME_HEXBINARY));
+      addType(new SimpleTypeBinding(Constants.QNAME_BASE64BINARY));
+      addType(new SimpleTypeBinding(Constants.QNAME_ANYURI));
+      addType(new SimpleTypeBinding(Constants.QNAME_QNAME));
+      addType(new SimpleTypeBinding(Constants.QNAME_NOTATION));
+      addType(new SimpleTypeBinding(Constants.QNAME_NORMALIZEDSTRING));
+      addType(new SimpleTypeBinding(Constants.QNAME_TOKEN));
+      addType(new SimpleTypeBinding(Constants.QNAME_LANGUAGE));
+      addType(new SimpleTypeBinding(Constants.QNAME_NMTOKEN));
+      addType(new SimpleTypeBinding(Constants.QNAME_NMTOKENS));
+      addType(new SimpleTypeBinding(Constants.QNAME_NAME));
+      addType(new SimpleTypeBinding(Constants.QNAME_NCNAME));
+      addType(new SimpleTypeBinding(Constants.QNAME_ID));
+      addType(new SimpleTypeBinding(Constants.QNAME_IDREF));
+      addType(new SimpleTypeBinding(Constants.QNAME_IDREFS));
+      addType(new SimpleTypeBinding(Constants.QNAME_ENTITY));
+      addType(new SimpleTypeBinding(Constants.QNAME_ENTITIES));
+      addType(new SimpleTypeBinding(Constants.QNAME_INTEGER));
+      addType(new SimpleTypeBinding(Constants.QNAME_NONPOSITIVEINTEGER));
+      addType(new SimpleTypeBinding(Constants.QNAME_NEGATIVEINTEGER));
+      addType(new SimpleTypeBinding(Constants.QNAME_LONG));
+      addType(new SimpleTypeBinding(Constants.QNAME_INT));
+      addType(new SimpleTypeBinding(Constants.QNAME_SHORT));
+      addType(new SimpleTypeBinding(Constants.QNAME_BYTE));
+      addType(new SimpleTypeBinding(Constants.QNAME_NONNEGATIVEINTEGER));
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDLONG));
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDINT));
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDSHORT));
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDBYTE));
+      addType(new SimpleTypeBinding(Constants.QNAME_POSITIVEINTEGER));
+   }
+
+   /**
+    * Get the namespaces.
+    * 
+    * @return the namespaces.
+    */
+   public Set getNamespaces()
+   {
+      return namespaces;
+   }
+
+   /**
+    * Set the namespaces.
+    * 
+    * @param namespaces the namespaces.
+    * @throws IllegalArgumentException for null spaces
+    */
+   public void setNamespaces(Set namespaces)
+   {
+      if (namespaces == null)
+         throw new IllegalArgumentException("Null namespaces");
+      this.namespaces = namespaces;
+   }
+
+   public TypeBinding getType(QName qName)
+   {
+      return (TypeBinding)types.get(qName);
+   }
+
+   public void addType(TypeBinding type)
+   {
+      QName qName = type.getQName();
+      if(qName == null)
+      {
+         throw new JBossXBRuntimeException("Global type must have a name.");
+      }
+      types.put(qName, type);
+   }
+
+   public ElementBinding getElement(QName name)
+   {
+      ParticleBinding particle = (ParticleBinding)elements.get(name);
+      ElementBinding element = (ElementBinding)(particle == null ? null : particle.getTerm());
+      return element;
+   }
+
+   public ParticleBinding getElementParticle(QName name)
+   {
+      return (ParticleBinding)elements.get(name);
+   }
+
+   public void addElement(ElementBinding element)
+   {
+      ParticleBinding particle = new ParticleBinding(element);
+      elements.put(element.getQName(), particle);
+   }
+
+   public ElementBinding addElement(QName name, TypeBinding type)
+   {
+      ElementBinding element = new ElementBinding(this, name, type);
+      addElement(element);
+      return element;
+   }
+
+   public Iterator getElements()
+   {
+      return new Iterator()
+      {
+         private Iterator particleIterator = elements.values().iterator();
+
+         public boolean hasNext()
+         {
+            return particleIterator.hasNext();
+         }
+
+         public Object next()
+         {
+            ParticleBinding particle = (ParticleBinding)particleIterator.next();
+            return particle.getTerm();
+         }
+
+         public void remove()
+         {
+            throw new UnsupportedOperationException("remove is not implemented.");
+         }
+      };
+   }
+
+   public Iterator getElementParticles()
+   {
+      return elements.values().iterator();
+   }
+
+   public Iterator getTypes()
+   {
+      return Collections.unmodifiableCollection(types.values()).iterator();
+   }
+
+   public PackageMetaData getPackageMetaData()
+   {
+      return packageMetaData;
+   }
+
+   public void setPackageMetaData(PackageMetaData packageMetaData)
+   {
+      this.packageMetaData = packageMetaData;
+   }
+
+   public SchemaBindingResolver getSchemaResolver()
+   {
+      return schemaResolver;
+   }
+
+   public void setSchemaResolver(SchemaBindingResolver schemaResolver)
+   {
+      this.schemaResolver = schemaResolver;
+   }
+
+   public boolean isStrictSchema()
+   {
+      return strictSchema;
+   }
+
+   /**
+    * If strict-schema is true then all the elements and attributes in XML content being parsed must be bound
+    * in this instance of SchemaBinding (except attributes from xmlns and xsi namespaces),
+    * otherwise a runtime exception is thrown. The default value for this property is true.
+    */
+   public void setStrictSchema(boolean strictSchema)
+   {
+      this.strictSchema = strictSchema;
+   }
+
+   public boolean isIgnoreUnresolvedFieldOrClass()
+   {
+      return ignoreUnresolvedFieldOrClass;
+   }
+
+   /**
+    * If a field is not found in the parent class to set child value on or
+    * a class an element is bound to
+    * an exception will be thrown if this property is false. Otherwise,
+    * the process will just go on (the default for now).
+    */
+   public void setIgnoreUnresolvedFieldOrClass(boolean ignoreUnresolvedFieldOrClass)
+   {
+      this.ignoreUnresolvedFieldOrClass = ignoreUnresolvedFieldOrClass;
+   }
+
+   public boolean isReplacePropertyRefs()
+   {
+      return replacePropertyRefs;
+   }
+   /**
+    *
+    * @param flag
+    */
+   public void setReplacePropertyRefs(boolean flag)
+   {
+      this.replacePropertyRefs = flag;
+   }
+
+   public boolean isIgnoreLowLine()
+   {
+      return ignoreLowLine;
+   }
+
+   /**
+    * Where '_' should be considered as a word separator or a part of the Java identifier
+    * when mapping XML names to Java identifiers.
+    */
+   public void setIgnoreLowLine(boolean ignoreLowLine)
+   {
+      this.ignoreLowLine = ignoreLowLine;
+   }
+
+   public boolean isUnmarshalListsToArrays()
+   {
+      return unmarshalListsToArrays;
+   }
+
+   /**
+    * Should list xml types be unmarshalled as arrays
+    * @param unmarshalListsToArrays
+    */
+   public void setUnmarshalListsToArrays(boolean unmarshalListsToArrays)
+   {
+      this.unmarshalListsToArrays = unmarshalListsToArrays;
+   }
+
+   public boolean isUseNoArgCtorIfFound()
+   {
+      return useNoArgCtorIfFound;
+   }
+
+   /**
+    * Should the default no-arg ctor be used to create the java instance
+    * @param useNoArgCtorIfFound
+    */
+   public void setUseNoArgCtorIfFound(boolean useNoArgCtorIfFound)
+   {
+      this.useNoArgCtorIfFound = useNoArgCtorIfFound;
+   }
+
+   public String getSimpleContentProperty()
+   {
+      return simpleContentProperty;
+   }
+
+   /**
+    * Set the default property name to use for simple content bindings
+    * @param simpleContentProperty
+    */
+   public void setSimpleContentProperty(String simpleContentProperty)
+   {
+      this.simpleContentProperty = simpleContentProperty;
+   }
+
+   /**
+    * @return  schema default XOP unmarshaller
+    */
+   public XOPUnmarshaller getXopUnmarshaller()
+   {
+      return xopUnmarshaller;
+   }
+
+   /**
+    * @param xopUnmarshaller  schema default XOP unmarshaller
+    */
+   public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
+   {
+      this.xopUnmarshaller = xopUnmarshaller;
+   }
+
+   /**
+    * @return schema default XOP marshaller
+    */
+   public XOPMarshaller getXopMarshaller()
+   {
+      return xopMarshaller;
+   }
+
+   /**
+    * @param xopMarshaller  schema default XOP marshaller
+    */
+   public void setXopMarshaller(XOPMarshaller xopMarshaller)
+   {
+      this.xopMarshaller = xopMarshaller;
+   }
+
+   public void setUnresolvedContentBoundToDOM(boolean toDom)
+   {
+      TypeBinding type = getType(Constants.QNAME_ANYTYPE);
+      if(type == null)
+      {
+         // ignore, there is no use of the anyType in the schema
+         return;
+         //throw new JBossXBRuntimeException("anyType is not bound.");
+      }
+
+      WildcardBinding wildcard = type.getWildcard();
+      if(toDom)
+      {
+         wildcard.setUnresolvedCharactersHandler(DomCharactersHandler.INSTANCE);
+         wildcard.setUnresolvedElementHandler(DomParticleHandler.INSTANCE);
+         wildcard.setUnresolvedMarshaller(DomLocalMarshaller.INSTANCE);
+      }
+      else
+      {
+         wildcard.setUnresolvedCharactersHandler(null);
+         wildcard.setUnresolvedElementHandler(null);
+         wildcard.setUnresolvedMarshaller(null);
+      }
+   }
+   
+   public boolean isUnresolvedContentBoundToDOM()
+   {
+      TypeBinding type = getType(Constants.QNAME_ANYTYPE);
+      if(type == null)
+      {
+         // there is no use of the anyType in the schema
+         return false;
+         //throw new JBossXBRuntimeException("anyType is not bound.");
+      }
+
+      WildcardBinding wildcard = type.getWildcard();
+      return wildcard.getUnresolvedCharactersHandler() instanceof DomCharactersHandler
+      && wildcard.getUnresolvedElementHandler() instanceof DomParticleHandler
+      && wildcard.getUnresolvedMarshaller() instanceof DomLocalMarshaller;
+   }
+
+   public boolean isIgnoreWhitespacesInMixedContent()
+   {
+      return ignoreWhitespacesInMixedContent;
+   }
+   
+   public void setIgnoreWhitespacesInMixedContent(boolean value)
+   {
+      this.ignoreWhitespacesInMixedContent = value;
+   }
+
+   void addElementParticle(ParticleBinding particle)
+   {
+      ElementBinding element = (ElementBinding)particle.getTerm();
+      elements.put(element.getQName(), particle);
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,1291 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.sunday.unmarshalling;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.ListIterator;
-import javax.xml.namespace.QName;
-import org.apache.xerces.xs.XSTypeDefinition;
-import org.jboss.logging.Logger;
-import org.jboss.util.StringPropertyReplacer;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.GenericValueContainer;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.NamespaceRegistry;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.group.ValueList;
-import org.jboss.xb.binding.group.ValueListHandler;
-import org.jboss.xb.binding.group.ValueListInitializer;
-import org.jboss.xb.binding.introspection.FieldInfo;
-import org.jboss.xb.binding.metadata.CharactersMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.parser.JBossXBParser;
-import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
-import org.xml.sax.Attributes;
-
-/**
- * ContentHandler that is used as a sandbox for JBXB-76
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class SundayContentHandler
-   implements JBossXBParser.ContentHandler
-{
-   private final static Logger log = Logger.getLogger(SundayContentHandler.class);
-
-   private final static Object NIL = new Object();
-
-   private final SchemaBinding schema;
-   private final SchemaBindingResolver schemaResolver;
-
-   private final StackImpl stack = new StackImpl();
-
-   private Object root;
-   private NamespaceRegistry nsRegistry = new NamespaceRegistry();
-
-   private ParticleHandler defParticleHandler = DefaultHandlers.ELEMENT_HANDLER;
-
-   private UnmarshallingContextImpl ctx = new UnmarshallingContextImpl();
-
-   private final boolean trace = log.isTraceEnabled();
-
-   public SundayContentHandler(SchemaBinding schema)
-   {
-      this.schema = schema;
-      this.schemaResolver = null;
-   }
-
-   public SundayContentHandler(SchemaBindingResolver schemaResolver)
-   {
-      this.schemaResolver = schemaResolver;
-      this.schema = null;
-   }
-
-   public void characters(char[] ch, int start, int length)
-   {
-      StackItem stackItem = stack.peek();
-      if(stackItem.cursor == null)
-      {
-         if(stackItem.textContent == null)
-         {
-            stackItem.textContent = new StringBuffer();
-         }
-         stackItem.textContent.append(ch, start, length);
-      }
-   }
-
-   public void endElement(String namespaceURI, String localName, String qName)
-   {
-      ElementBinding elementBinding = null;
-      QName endName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
-      StackItem item;
-      while(true)
-      {
-         item = stack.peek();
-         if(item.cursor == null)
-         {
-            if(item.ended)
-            {
-               pop();
-               if(item.particle.isRepeatable())
-               {
-                  endRepeatableParticle(item.particle);
-               }
-            }
-            else
-            {
-               elementBinding = (ElementBinding)item.particle.getTerm();
-               item.ended = true;
-               break;
-            }
-         }
-         else
-         {
-            if(!item.ended) // could be ended if it's a choice
-            {
-               endParticle(item, endName, 1);
-            }
-
-            ParticleBinding currentParticle = item.cursor.getCurrentParticle();
-            TermBinding term = currentParticle.getTerm();
-            if(term.isWildcard() && currentParticle.isRepeatable())
-            {
-               endRepeatableParticle(currentParticle);
-            }
-
-            pop();
-            if(item.particle.isRepeatable())
-            {
-               endRepeatableParticle(item.particle);
-            }
-         }
-      }
-
-      if(elementBinding == null)
-      {
-         throw new JBossXBRuntimeException("Failed to endElement " + qName + ": binding not found");
-      }
-
-      if(!elementBinding.getQName().equals(endName))
-      {
-         throw new JBossXBRuntimeException("Failed to end element " +
-            new QName(namespaceURI, localName) +
-            ": element on the stack is " + elementBinding.getQName()
-         );
-      }
-
-      endElement();
-   }
-
-   public void startElement(String namespaceURI,
-                            String localName,
-                            String qName,
-                            Attributes atts,
-                            XSTypeDefinition xercesType)
-   {
-      QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
-      ParticleBinding particle = null;
-      ParticleHandler handler = null;
-      boolean repeated = false;
-      boolean repeatedParticle = false;
-      StackItem item = null;
-      ModelGroupBinding.Cursor cursor = null; // used only when particle is a wildcard
-      SchemaBinding schemaBinding = schema;
-
-      if(stack.isEmpty())
-      {
-         if(schemaBinding != null)
-         {
-            particle = schemaBinding.getElementParticle(startName);
-         }
-         else if(schemaResolver != null)
-         {
-            String schemaLocation = atts == null ? null : Util.getSchemaLocation(atts, namespaceURI);
-            schemaBinding = schemaResolver.resolve(namespaceURI, null, schemaLocation);
-            if(schemaBinding != null)
-            {
-               particle = schemaBinding.getElementParticle(startName);
-            }
-            else
-            {
-               throw new JBossXBRuntimeException("Failed to resolve schema nsURI=" + namespaceURI + " location=" + schemaLocation);
-            }
-         }
-         else
-         {
-            throw new JBossXBRuntimeException("Neither schema binding nor schema binding resolver is available!");
-         }
-      }
-      else
-      {
-         while(!stack.isEmpty())
-         {
-            item = stack.peek();
-            if(item.cursor == null)
-            {
-               TermBinding term = item.particle.getTerm();
-               ElementBinding element = (ElementBinding)term;
-               if(item.ended)
-               {
-                  if(element.getQName().equals(startName))
-                  {
-                     particle = item.particle;
-                     repeated = true;
-                     item.reset();
-
-                     if(!particle.isRepeatable())
-                     {
-                        endRepeatableParent(startName);
-                     }
-                  }
-                  else
-                  {
-                     pop();                     
-                     if(item.particle.isRepeatable())
-                     {
-                        endRepeatableParticle(item.particle);
-                     }
-                     continue;
-                  }
-               }
-               else
-               {
-                  ParticleBinding typeParticle = element.getType().getParticle();
-                  ModelGroupBinding modelGroup = typeParticle == null ?
-                     null :
-                     (ModelGroupBinding)typeParticle.getTerm();
-                  if(modelGroup == null)
-                  {
-                     if(startName.equals(Constants.QNAME_XOP_INCLUDE))
-                     {
-                        TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
-                        if(anyUriType == null)
-                        {
-                           log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
-                        }
-
-                        TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
-                        xopIncludeType.setSchemaBinding(schema);
-                        xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
-                        xopIncludeType.setHandler(new XOPIncludeHandler(element.getType(), schema.getXopUnmarshaller()));
-
-                        ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
-
-                        particle = new ParticleBinding(xopInclude);
-
-                        ElementBinding parentElement = (ElementBinding) item.particle.getTerm();
-                        parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
-
-                        item.handler = DefaultHandlers.XOP_HANDLER;
-                        item.ignoreCharacters = true;
-                        item.o = item.handler.startParticle(stack.peek().o, startName, stack.peek().particle, null, nsRegistry);
-                        break;
-                     }
-
-                     QName typeName = element.getType().getQName();
-                     throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
-                        " type of element " +
-                        element.getQName() +
-                        " should be complex and contain " + startName + " as a child element."
-                     );
-                  }
-
-                  cursor = modelGroup.newCursor(typeParticle);
-                  List newCursors = cursor.startElement(startName, atts);
-                  if(newCursors.isEmpty())
-                  {
-                     throw new JBossXBRuntimeException(startName +
-                        " not found as a child of " +
-                        ((ElementBinding)term).getQName()
-                     );
-                  }
-                  else
-                  {
-                     Object o = item.o;
-                     // push all except the last one
-                     for(int i = newCursors.size() - 1; i >= 0; --i)
-                     {
-                        cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
-
-                        ParticleBinding modelGroupParticle = cursor.getParticle();
-                        if(modelGroupParticle.isRepeatable())
-                        {
-                           startRepeatableParticle(startName, modelGroupParticle);
-                        }
-
-                        handler = getHandler(modelGroupParticle);
-                        o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                        push(cursor, o, handler);
-                     }
-                     particle = cursor.getCurrentParticle();
-                  }
-               }
-               break;
-            }
-            else
-            {
-               cursor = item.cursor;
-               if(cursor == null)
-               {
-                  throw new JBossXBRuntimeException("No cursor for " + startName);
-               }
-
-               // todo review
-               if(!item.ended && cursor.isPositioned() && cursor.getParticle().getTerm() instanceof ChoiceBinding)
-               {
-                  endParticle(item, startName, 1);
-                  if(!item.particle.isRepeatable()) // this is for repeatable choices that should stay on the stack
-                  {
-                     pop();
-                  }
-                  continue;
-               }
-
-               //int prevOccurence = cursor.getOccurence();
-               ParticleBinding prevParticle = cursor.isPositioned() ? cursor.getCurrentParticle() : null;
-               List newCursors = cursor.startElement(startName, atts);
-               if(newCursors.isEmpty())
-               {
-                  if(!item.ended) // this is for choices
-                  {
-                     endParticle(item, startName, 1);
-                  }
-                  pop();
-               }
-               else
-               {
-                  if(item.ended) // for repeatable choices
-                  {
-                     if(!item.particle.isRepeatable())
-                     {
-                        throw new JBossXBRuntimeException("The particle expected to be repeatable but it's not: " + item.particle.getTerm());
-                     }
-                     item.reset();
-                     
-                     handler = getHandler(item.particle);
-                     item.o = handler.startParticle(stack.peek(1).o, startName, item.particle, atts, nsRegistry);
-                  }
-                  
-                  ParticleBinding curParticle = cursor.getCurrentParticle();
-                  if(curParticle != prevParticle)
-                  {
-                     if(prevParticle != null && prevParticle.isRepeatable() && prevParticle.getTerm().isModelGroup())
-                     {
-                        endRepeatableParticle(prevParticle);
-                     }
-
-                     if(newCursors.size() > 1 && curParticle.isRepeatable())
-                     {
-                        startRepeatableParticle(startName, curParticle);
-                     }
-                  }
-                  else
-                  {
-                     repeatedParticle = true;
-                  }
-
-                  // push all except the last one
-                  Object o = item.o;
-                  for(int i = newCursors.size() - 2; i >= 0; --i)
-                  {
-                     cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
-
-                     ParticleBinding modelGroupParticle = cursor.getParticle();
-                     handler = getHandler(modelGroupParticle);
-                     o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
-                     push(cursor, o, handler);
-                  }
-                  cursor = (ModelGroupBinding.Cursor)newCursors.get(0);
-                  particle = cursor.getCurrentParticle();
-                  break;
-               }
-            }
-         }
-      }
-
-      Object o = null;
-      if(particle != null)
-      {
-         Object parent = stack.isEmpty() ? null :
-            (repeated ? stack.peek(1).o : stack.peek().o);
-         if(particle.getTerm() instanceof WildcardBinding)
-         {
-            /*
-            WildcardBinding wildcard = (WildcardBinding)particle.getTerm();
-            ElementBinding element = wildcard.getElement(startName, atts);
-            */
-            ElementBinding element = cursor.getElement();
-            if(element == null)
-            {
-               throw new JBossXBRuntimeException("Failed to resolve element " +
-                  startName + " for wildcard."
-               );
-            }
-
-            if(!repeatedParticle && particle.isRepeatable())
-            {
-               startRepeatableParticle(startName, particle);
-            }
-            particle = new ParticleBinding(element/*, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded()*/);
-         }
-
-         ElementBinding element = (ElementBinding)particle.getTerm();
-
-         // todo xsi:type support should be implemented in a better way
-         String xsiType = atts.getValue("xsi:type");
-         if(xsiType != null)
-         {
-            if(trace)
-            {
-               log.trace(element.getQName() + " uses xsi:type " + xsiType);
-            }
-
-            String xsiTypePrefix;
-            String xsiTypeLocal;
-            int colon = xsiType.indexOf(':');
-            if(colon == -1)
-            {
-               xsiTypePrefix = "";
-               xsiTypeLocal = xsiType;
-            }
-            else
-            {
-               xsiTypePrefix = xsiType.substring(0, colon);
-               xsiTypeLocal = xsiType.substring(colon + 1);
-            }
-
-            String xsiTypeNs = nsRegistry.getNamespaceURI(xsiTypePrefix);
-            QName xsiTypeQName = new QName(xsiTypeNs, xsiTypeLocal);
-
-            TypeBinding xsiTypeBinding = schemaBinding.getType(xsiTypeQName);
-            if(xsiTypeBinding == null)
-            {
-               throw new JBossXBRuntimeException("Type binding not found for type " +
-                  xsiTypeQName +
-                  " specified with xsi:type for element " + startName
-               );
-            }
-
-            element = new ElementBinding(schemaBinding, startName, xsiTypeBinding);
-            particle =
-               new ParticleBinding(element,
-                  particle.getMinOccurs(),
-                  particle.getMaxOccurs(),
-                  particle.getMaxOccursUnbounded()
-               );
-         }
-
-         if(!repeated && particle.isRepeatable())
-         {
-            startRepeatableParticle(startName, particle);
-         }
-
-         TypeBinding type = element.getType();
-         if(type == null)
-         {
-            throw new JBossXBRuntimeException("No type for element " + element);
-         }
-
-         handler = type.getHandler();
-         if(handler == null)
-         {
-            handler = defParticleHandler;
-         }
-
-         List interceptors = element.getInterceptors();
-         if(!interceptors.isEmpty())
-         {
-            if (repeated)
-            {
-               pop();
-            }
-
-            for (int i = 0; i < interceptors.size(); ++i)
-            {
-               ElementInterceptor interceptor = (ElementInterceptor) interceptors.get(i);
-               parent = interceptor.startElement(parent, startName, type);
-               push(startName, particle, parent, handler);
-               interceptor.attributes(parent, startName, type, atts, nsRegistry);
-            }
-
-            if (repeated)
-            {
-               // to have correct endRepeatableParticle calls
-               stack.push(item);
-            }
-         }
-
-         String nil = atts.getValue("xsi:nil");
-         if(nil == null || !("1".equals(nil) || "true".equals(nil)))
-         {
-            o = handler.startParticle(parent, startName, particle, atts, nsRegistry);
-         }
-         else
-         {
-            o = NIL;
-         }
-      }
-      else
-      {
-         ElementBinding parentBinding = null;
-         if(!stack.isEmpty())
-         {
-            ParticleBinding stackParticle = repeated ? stack.peek(1).particle : stack.peek().particle;
-            if(stackParticle != null)
-            {
-               parentBinding = (ElementBinding)stackParticle.getTerm();
-            }
-         }
-
-         if(parentBinding != null && parentBinding.getSchema() != null)
-         {
-            schemaBinding = parentBinding.getSchema();
-         }
-
-         String msg = "Element " +
-            startName +
-            " is not bound " +
-            (parentBinding == null ? "as a global element." : "in type " + parentBinding.getType().getQName());
-         if(schemaBinding != null && schemaBinding.isStrictSchema())
-         {
-            throw new JBossXBRuntimeException(msg);
-         }
-         else if(trace)
-         {
-            log.trace(msg);
-         }
-      }
-
-      if(repeated)
-      {
-         item.o = o;
-         // in case of collection of abstract types
-         item.particle = particle;
-      }
-      else
-      {
-         push(startName, particle, o, handler);
-      }
-   }
-
-   private ParticleHandler getHandler(ParticleBinding modelGroupParticle)
-   {
-      ParticleHandler handler = ((ModelGroupBinding)modelGroupParticle.getTerm()).getHandler();
-      return handler == null ? defParticleHandler : handler;
-   }
-
-   private void endRepeatableParent(QName startName)
-   {
-      int parentPos = 1;
-      StackItem parentItem;
-      ParticleBinding parentParticle = null;
-      while(true)
-      {
-         parentItem = stack.peek(parentPos);
-         if(parentItem.cursor == null)
-         {
-            throw new JBossXBRuntimeException(
-               "Failed to start " + startName +
-               ": the element is not repeatable, repeatable parent expected to be a model group but got element " +
-               ((ElementBinding)parentItem.particle.getTerm()).getQName()
-            );
-         }
-
-         parentParticle = parentItem.particle;
-         if(parentParticle.isRepeatable())
-         {
-            break;
-         }
-
-         endParticle(parentItem, startName, ++parentPos);
-      }
-
-      if(!parentParticle.isRepeatable())
-      {
-         StringBuffer msg = new StringBuffer();
-
-         StackItem item = stack.peek();
-         ParticleBinding currentParticle = item.particle;
-         msg.append("Failed to start ").append(startName).append(": ")
-            .append(currentParticle.getTerm())
-            .append(" is not repeatable.")
-            .append(" Its parent ")
-            .append(parentParticle.getTerm())
-            .append(" expected to be repeatable!")
-            .append("\ncurrent stack: ");
-
-         for(int i = stack.size() - 1; i >= 0; --i)
-         {
-            item = stack.peek(i);
-            ParticleBinding particle = item.particle;
-            TermBinding term = particle.getTerm();
-            if(term.isModelGroup())
-            {
-               if(term instanceof SequenceBinding)
-               {
-                  msg.append("sequence");
-               }
-               else if(term instanceof ChoiceBinding)
-               {
-                  msg.append("choice");
-               }
-               else
-               {
-                  msg.append("all");
-               }
-            }
-            else if(term.isWildcard())
-            {
-               msg.append("wildcard");
-            }
-            else
-            {
-               msg.append(((ElementBinding)term).getQName());
-            }
-            msg.append("\\");
-         }
-
-         throw new JBossXBRuntimeException(msg.toString());
-      }
-
-      // todo startName is wrong here
-      endParticle(parentItem, startName, parentPos + 1);
-
-      parentItem = stack.peek(parentPos + 1);
-      while(parentPos > 0)
-      {
-         StackItem item = stack.peek(parentPos--);
-         ParticleHandler handler = getHandler(item.particle);
-         item.reset();
-         item.o = handler.startParticle(parentItem.o, startName, item.particle, null, nsRegistry);
-         parentItem = item;
-      }
-   }
-
-   private void startRepeatableParticle(QName startName, ParticleBinding particle)
-   {
-      //System.out.println(" start repeatable (" + stack.size() + "): " + particle.getTerm());
-      
-      TermBinding term = particle.getTerm();
-      if(term.isSkip())
-      {
-         return;
-      }
-      
-      StackItem item = stack.peek();
-      if(item.o != null &&
-            !(item.o instanceof GenericValueContainer) &&
-            term.getAddMethodMetaData() == null &&
-            term.getMapEntryMetaData() == null &&
-            term.getPutMethodMetaData() == null)
-      {
-         ValueListHandler handler = ValueListHandler.FACTORY.lazy(item.o);
-         Class cls = item.o.getClass();
-         item.repeatableParticleValue = new ValueListInitializer().newValueList(handler, cls);
-      }
-   }
-
-   private void endRepeatableParticle(ParticleBinding particle)
-   {
-      //System.out.println(" end repeatable (" + stack.size() + "): " + particle.getTerm());
-
-      StackItem item = stack.peek();
-      ValueList valueList = item.repeatableParticleValue;
-      if(valueList != null)
-      {
-         item.repeatableParticleValue = null;
-         if(valueList.size() == 0)
-         {
-            return;
-         }
-            
-         if(particle.getTerm().isWildcard())
-         {
-            ParticleHandler handler = ((WildcardBinding)particle.getTerm()).getWildcardHandler();
-            if(handler == null)
-            {
-               handler = defParticleHandler;
-            }
-
-            // that's not good. some elements can be handled as "unresolved" and some as "resolved"
-            QName qName = valueList.getValue(0).qName;
-            Collection col = new ArrayList();
-            for(int i = 0; i < valueList.size(); ++i)
-            {
-               col.add(valueList.getValue(i).value);
-            }
-            StackItem parentItem = stack.peek(1);
-            handler.setParent(parentItem.o, col, qName, particle, parentItem.particle);
-         }
-         else
-         {
-            valueList.getHandler().newInstance(particle, valueList);
-         }
-      }
-   }
-
-   private void endParticle(StackItem item, QName qName, int parentStackPos)
-   {
-      if(item.ended)
-      {
-         throw new JBossXBRuntimeException(item.particle.getTerm() + " has already been ended.");
-      }
-
-      ParticleBinding modelGroupParticle = item.particle;
-      ParticleHandler handler = item.handler;//getHandler(modelGroupParticle);
-
-      Object o;
-      if(item.o instanceof ValueList && !modelGroupParticle.getTerm().isSkip())
-      {
-         if(trace)
-         {
-            log.trace("endParticle " + modelGroupParticle.getTerm() + " valueList");
-         }
-         ValueList valueList = (ValueList)item.o;
-         o = valueList.getHandler().newInstance(modelGroupParticle, valueList);
-      }
-      else
-      {
-         o = handler.endParticle(item.o, qName, modelGroupParticle);
-      }
-
-      item.ended = true;
-
-      // model group should always have parent particle
-      item = (StackItem)stack.peek(parentStackPos);
-      if(item.o != null)
-      {
-         ParticleBinding parentParticle = getParentParticle();//item.particle;
-         if(parentParticle == null)
-         {
-            parentParticle = item.particle;
-         }
-         setParent(handler,
-               item.repeatableParticleValue == null ? item.o : item.repeatableParticleValue,
-               o, qName, modelGroupParticle, parentParticle);
-      }
-   }
-
-   public void startPrefixMapping(String prefix, String uri)
-   {
-      nsRegistry.addPrefixMapping(prefix, uri);
-   }
-
-   public void endPrefixMapping(String prefix)
-   {
-      nsRegistry.removePrefixMapping(prefix);
-   }
-
-   public void processingInstruction(String target, String data)
-   {
-   }
-
-   public Object getRoot()
-   {
-      return root;
-   }
-
-   // Private
-
-   private ParticleBinding getParentParticle()
-   {
-      ListIterator iter = stack.prevIterator();
-      while(iter.hasPrevious())
-      {
-         StackItem prev = (StackItem)iter.previous();
-         ParticleBinding peeked = prev.particle;
-
-         TermBinding term = peeked.getTerm();
-         if(!term.isSkip())
-         {
-            return peeked;
-         }
-      }
-      return null;
-   }
-
-   private void endElement()
-   {
-      StackItem item = stack.peek();
-      Object o = item.o;
-      ParticleBinding particle = item.particle;
-      
-      ElementBinding element = (ElementBinding)particle.getTerm();
-      QName endName = element.getQName();
-      TypeBinding type = element.getType();
-      List interceptors = element.getInterceptors();
-      int interceptorsTotal = interceptors.size();
-
-      if(o != NIL)
-      {
-         //
-         // characters
-         //
-
-         TypeBinding charType = type.getSimpleType();
-         if(charType == null)
-         {
-            charType = type;
-         }
-
-         CharactersHandler charHandler = item.ignoreCharacters ? null : charType.getCharactersHandler();
-
-         /**
-          * If there is text content then unmarshal it and set.
-          * If there is no text content and the type is simple and
-          * its characters handler is not null then unmarshal and set.
-          * If the type is complex and there is no text data then the unmarshalled value
-          * of the empty text content is assumed to be null
-          * (in case of simple types that's not always true and depends on nillable attribute).
-          */
-         String textContent = item.textContent == null ? "" : item.textContent.toString();
-         if(textContent.length() > 0 || charHandler != null && type.isSimple())
-         {
-            String dataContent;
-            SchemaBinding schema = element.getSchema();
-            if(textContent.length() == 0)
-            {
-               dataContent = null;
-            }
-            else
-            {
-               dataContent = textContent.toString();
-               if(schema != null && schema.isReplacePropertyRefs())
-               {
-                  dataContent = StringPropertyReplacer.replaceProperties(dataContent);
-               }
-            }
-
-            Object unmarshalled;
-
-            if(charHandler == null)
-            {
-               if(!type.isSimple() &&
-                  schema != null &&
-                  schema.isStrictSchema()
-                  // todo this isSkip() doesn't look nice here
-                  && !element.isSkip())
-               {
-                  throw new JBossXBRuntimeException("Element " +
-                     endName +
-                     " with type binding " +
-                     type.getQName() +
-                     " does not include text content binding: " + dataContent
-                  );
-               }
-               unmarshalled = dataContent;
-            }
-            else
-            {
-               ValueMetaData valueMetaData = element.getValueMetaData();
-               if(valueMetaData == null)
-               {
-                  CharactersMetaData charactersMetaData = type.getCharactersMetaData();
-                  if(charactersMetaData != null)
-                  {
-                     valueMetaData = charactersMetaData.getValue();
-                  }
-               }
-
-               // todo valueMetaData is available from type
-               unmarshalled = dataContent == null ?
-                  charHandler.unmarshalEmpty(endName, charType, nsRegistry, valueMetaData) :
-                  charHandler.unmarshal(endName, charType, nsRegistry, valueMetaData, dataContent);
-            }
-
-            if(unmarshalled != null)
-            {
-               // if startElement returned null, we use characters as the object for this element
-               if(o == null)
-               {
-                  o = unmarshalled;
-               }
-               else if(charHandler != null)
-               {
-                  TermBeforeSetParentCallback beforeSetParent = charType.getBeforeSetParentCallback();
-                  if(beforeSetParent != null)
-                  {
-                     ctx.parent = o;
-                     ctx.particle = particle;
-                     ctx.parentParticle = getParentParticle();
-                     unmarshalled = beforeSetParent.beforeSetParent(unmarshalled, ctx);
-                     ctx.clear();
-                  }
-
-                  if(o instanceof ValueList)
-                  {
-                     ValueList valueList = (ValueList)o;
-                     if(type.isSimple())
-                     {
-                        valueList.getInitializer().addTermValue(endName,
-                           particle,
-                           charHandler,
-                           valueList,
-                           unmarshalled,
-                           null
-                        );
-                     }
-                     else
-                     {
-                        valueList.getInitializer().addTextValue(endName,
-                           particle,
-                           charHandler,
-                           valueList,
-                           unmarshalled
-                        );
-                     }
-                  }
-                  else
-                  {
-                     charHandler.setValue(endName, element, o, unmarshalled);
-                  }
-               }
-            }
-
-            for(int i = interceptorsTotal - 1; i >= 0; --i)
-            {
-               ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-               interceptor.characters(((StackItem)stack.peek(interceptorsTotal - i)).o,
-                  endName, type, nsRegistry, dataContent
-               );
-            }
-         }
-      }
-      else
-      {
-         o = null;
-      }
-
-      //
-      // endElement
-      //
-
-      StackItem parentItem = stack.size() == 1 ? null : stack.peek(1);
-      Object parent = parentItem == null ? null : parentItem.o;
-      ParticleHandler handler = stack.peek().handler;
-      
-      if(o instanceof ValueList && !particle.getTerm().isSkip())
-      {
-         if(trace)
-         {
-            log.trace("endParticle " + endName + " valueList");
-         }
-         ValueList valueList = (ValueList)o;
-         o = valueList.getHandler().newInstance(particle, valueList);
-      }
-      else
-      {
-         o = handler.endParticle(o, endName, particle);
-      }
-
-      for(int i = interceptorsTotal - 1; i >= 0; --i)
-      {
-         ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-         interceptor.endElement(((StackItem)stack.peek(interceptorsTotal - i)).o, endName, type);
-      }
-
-      //
-      // setParent
-      //
-
-      if(interceptorsTotal == 0)
-      {
-         ParticleBinding parentParticle = getParentParticle();
-         boolean hasWildcard = false;
-         ParticleHandler wildcardHandler = null;
-
-         if (parentParticle != null && parentParticle.getTerm().isElement())
-         {
-            WildcardBinding wildcard = ((ElementBinding) parentParticle.getTerm()).getType().getWildcard();
-            if (wildcard != null)
-            {
-               hasWildcard = true;
-               wildcardHandler = wildcard.getWildcardHandler();
-            }
-         }
-
-         if(parent != null)
-         {
-            /*if(o == null)
-            {
-               throw new JBossXBRuntimeException(endName + " is null!");
-            } */
-            if(wildcardHandler != null)
-            {
-               setParent(wildcardHandler,
-                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
-                     o, endName, particle, parentParticle);
-            }
-            else
-            {
-               setParent(handler,
-                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
-                     o, endName, particle, parentParticle);
-            }
-         }
-         else if(parentParticle != null && hasWildcard && stack.size() > 1)
-         {
-            // the parent has anyType, so it gets the value of its child
-            ListIterator iter = stack.prevIterator();
-            while(iter.hasPrevious())
-            {
-               StackItem peeked = (StackItem)iter.previous();
-               peeked.o = o;
-               if(peeked.cursor == null)
-               {
-                  break;
-               }
-            }
-
-            if(trace)
-            {
-               log.trace("Value of " + endName + " " + o + " is promoted as the value of its parent element.");
-            }
-         }
-      }
-      else
-      {
-         StackItem popped = pop();
-         for(int i = interceptorsTotal - 1; i >= 0; --i)
-         {
-            ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
-            parent = pop().o;
-            interceptor.add(parent, o, endName);
-            o = parent;
-         }
-         // need to have correst endRepeatableParticle events
-         stack.push(popped);
-      }
-
-      if(stack.size() == 1)
-      {
-         root = o;
-         stack.clear();
-      }
-   }
-
-   private void setParent(ParticleHandler handler,
-                          Object parent,
-                          Object o,
-                          QName endName,
-                          ParticleBinding particle,
-                          ParticleBinding parentParticle)
-   {
-      TermBeforeSetParentCallback beforeSetParent = particle.getTerm().getBeforeSetParentCallback();
-      if(beforeSetParent != null)
-      {
-         ctx.parent = parent;
-         ctx.particle = particle;
-         ctx.parentParticle = parentParticle;
-         o = beforeSetParent.beforeSetParent(o, ctx);
-         ctx.clear();
-      }
-
-      if(parent instanceof ValueList /*&& !particle.getTerm().isSkip()*/)
-      {
-         if(parent == o)
-         {            
-            return;
-         }
-         ValueList valueList = (ValueList)parent;
-         valueList.getInitializer().addTermValue(endName, particle, handler, valueList, o, parentParticle);
-      }
-      else
-      {
-         handler.setParent(parent, o, endName, particle, parentParticle);
-      }
-   }
-
-   private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler)
-   {
-      StackItem item = new StackItem(particle, o, handler);
-      stack.push(item);
-      if(trace)
-      {
-         Object binding = null;
-         if(particle != null)
-         {
-            binding = particle.getTerm();
-         }
-         log.trace("pushed " + qName + "=" + o + ", binding=" + binding);
-      }
-   }
-
-   private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
-   {
-      StackItem item = new StackItem(cursor, o, handler);
-      stack.push(item);
-      if(trace)
-      {
-         log.trace("pushed cursor " + cursor + ", o=" + o);
-      }
-   }
-
-   private StackItem pop()
-   {
-      StackItem item = stack.pop();
-      if(trace)
-      {
-         if(item.cursor == null)
-         {
-            log.trace("poped " + ((ElementBinding)item.particle.getTerm()).getQName() + "=" + item.particle);
-         }
-         else
-         {
-            log.trace("poped " + item.cursor.getCurrentParticle().getTerm());
-         }
-      }
-      return item;
-   }
-
-   // Inner
-
-   private static class StackItem
-   {
-      final ModelGroupBinding.Cursor cursor;
-      ParticleBinding particle;
-      ParticleHandler handler;
-      boolean ignoreCharacters;
-      Object o;
-      ValueList repeatableParticleValue;
-      StringBuffer textContent;
-      boolean ended;
-
-      public StackItem(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
-      {
-         if (cursor == null)
-            throw new IllegalArgumentException("Null cursor");
-         // this is modelgroup particle
-         this.cursor = cursor;
-         this.particle = cursor.getParticle();
-         this.o = o;
-         this.handler = handler;
-      }
-
-      public StackItem(ParticleBinding particle, Object o, ParticleHandler handler)
-      {
-         if (particle == null)
-            throw new IllegalArgumentException("Null particle");
-         // this is element particle
-         this.cursor = null;
-         this.particle = particle;
-         this.o = o;
-         this.handler = handler;
-      }
-
-      void reset()
-      {
-         if(!ended)
-         {
-            throw new JBossXBRuntimeException(
-               "Attempt to reset a particle that has already been reset: " + particle.getTerm()
-            );
-         }
-
-         ended = false;
-         o = null;
-         if(textContent != null)
-         {
-            textContent.delete(0, textContent.length());
-         }
-      }
-   }
-
-   static class StackImpl
-   {
-      private List list = new ArrayList();
-
-      public void clear()
-      {
-         list.clear();
-      }
-
-      public void push(Object o)
-      {
-         list.add(o);
-      }
-
-      public StackItem pop()
-      {
-         return (StackItem)list.remove(list.size() - 1);
-      }
-
-      public ListIterator prevIterator()
-      {
-         return list.listIterator(list.size() - 1);
-      }
-
-      public StackItem peek()
-      {
-         return (StackItem)list.get(list.size() - 1);
-      }
-
-      public StackItem peek(int i)
-      {
-         return (StackItem)list.get(list.size() - 1 - i);
-      }
-
-      public boolean isEmpty()
-      {
-         return list.isEmpty();
-      }
-
-      public int size()
-      {
-         return list.size();
-      }
-   }
-
-   private class UnmarshallingContextImpl implements UnmarshallingContext
-   {
-      Object parent;
-      ParticleBinding particle;
-      ParticleBinding parentParticle;
-      
-      public Object getParentValue()
-      {
-         return parent;
-      }
-      
-      public ParticleBinding getParticle()
-      {
-         return particle;
-      }
-      
-      public ParticleBinding getParentParticle()
-      {
-         return parentParticle;
-      }
-      
-      public String resolvePropertyName()
-      {
-         TermBinding term = particle.getTerm();
-         PropertyMetaData propertyMetaData = term.getPropertyMetaData();
-         String prop = propertyMetaData == null ? null : propertyMetaData.getName();
-         
-         if(prop != null)
-         {
-            return prop;
-         }
-         
-         if(term.isElement())
-         {
-            QName name = ((ElementBinding)term).getQName();
-            prop = Util.xmlNameToFieldName(name.getLocalPart(), term.getSchema().isIgnoreLowLine());
-         }
-         
-         return prop;
-      }
-
-      public Class resolvePropertyType()
-      {
-         if(parent == null)
-         {
-            return null;
-         }
-         
-         String prop = resolvePropertyName();
-         if(prop != null)
-         {      
-            FieldInfo fieldInfo = FieldInfo.getFieldInfo(parent.getClass(), prop, false);
-            if (fieldInfo != null)
-            {
-               return fieldInfo.getType();
-            }
-         }
-         return null;
-      }
-      
-      // private
-      
-      void clear()
-      {
-         ctx.parent = null;
-         ctx.particle = null;
-         ctx.parentParticle = null;
-      }
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,1407 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.sunday.unmarshalling;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+import javax.xml.namespace.QName;
+import org.apache.xerces.xs.XSTypeDefinition;
+import org.jboss.logging.Logger;
+import org.jboss.util.StringPropertyReplacer;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.GenericValueContainer;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.NamespaceRegistry;
+import org.jboss.xb.binding.Util;
+import org.jboss.xb.binding.group.ValueList;
+import org.jboss.xb.binding.group.ValueListHandler;
+import org.jboss.xb.binding.group.ValueListInitializer;
+import org.jboss.xb.binding.introspection.FieldInfo;
+import org.jboss.xb.binding.metadata.CharactersMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.parser.JBossXBParser;
+import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
+import org.xml.sax.Attributes;
+
+/**
+ * ContentHandler that is used as a sandbox for JBXB-76
+ *
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class SundayContentHandler
+   implements JBossXBParser.ContentHandler
+{
+   private final static Logger log = Logger.getLogger(SundayContentHandler.class);
+
+   private final static Object NIL = new Object();
+
+   private final SchemaBinding schema;
+   private final SchemaBindingResolver schemaResolver;
+
+   private final StackImpl stack = new StackImpl();
+
+   private Object root;
+   private NamespaceRegistry nsRegistry = new NamespaceRegistry();
+
+   private ParticleHandler defParticleHandler = DefaultHandlers.ELEMENT_HANDLER;
+
+   private UnmarshallingContextImpl ctx = new UnmarshallingContextImpl();
+
+   private final boolean trace = log.isTraceEnabled();
+
+   public SundayContentHandler(SchemaBinding schema)
+   {
+      this.schema = schema;
+      this.schemaResolver = null;
+   }
+
+   public SundayContentHandler(SchemaBindingResolver schemaResolver)
+   {
+      this.schemaResolver = schemaResolver;
+      this.schema = null;
+   }
+
+   public void characters(char[] ch, int start, int length)
+   {
+      StackItem stackItem = stack.peek();
+      if(stackItem.cursor != null)
+      {
+         return;
+      }
+
+      ElementBinding e = (ElementBinding) stackItem.particle.getTerm();
+/*      if(!stackItem.ended && e.getType().isTextContentAllowed())
+      {
+         int i = start;
+         while (i < start + length)
+         {
+            if(ch[i] == 0x0a)
+            {
+               stackItem.indentation = true;
+            }
+            else
+            {
+               if (ch[i] == ' ' || ch[i] == 0x0d)
+               {
+               }
+               else
+               {
+                  stackItem.indentation = false;
+                  break;
+               }
+            }
+            ++i;
+         }
+
+         if(!stackItem.indentation)
+         {
+            if (stackItem.textContent == null)
+            {
+               stackItem.textContent = new StringBuffer();
+            }
+            stackItem.textContent.append(ch, start, length);
+         }
+      }
+*/
+      // if current is ended the characters belong to its parent
+      if(stackItem.ended)
+      {
+         int i = 0;
+         do
+         {
+            stackItem = stack.peek(++i);
+         }
+         while(stackItem.cursor != null && i < stack.size());
+         
+         e = (ElementBinding) stackItem.particle.getTerm();
+      }
+
+      // collect characters only if they are allowed content
+      if(e.getType().isTextContentAllowed())
+      {
+         if(stackItem.indentation != Boolean.FALSE)
+         {
+            if(e.getType().isSimple())
+            {
+               // simple content is not analyzed
+               stackItem.indentation = Boolean.FALSE;
+               stackItem.ignorableCharacters = false;
+            }
+            else if(e.getSchema() != null && !e.getSchema().isIgnoreWhitespacesInMixedContent())
+            {
+               stackItem.indentation = Boolean.FALSE;
+               stackItem.ignorableCharacters = false;
+            }
+            else
+            {
+               // the indentation is currently defined as whitespaces with next line characters
+               // this should probably be externalized in the form of a filter or something
+               for (int i = start; i < start + length; ++i)
+               {
+                  if(ch[i] == 0x0a)
+                  {
+                     stackItem.indentation = Boolean.TRUE;
+                  }
+                  else if (!Character.isWhitespace(ch[i]))
+                  {
+                     stackItem.indentation = Boolean.FALSE;
+                     stackItem.ignorableCharacters = false;
+                     break;
+                  }
+               }
+            }
+         }
+         
+         if (stackItem.textContent == null)
+         {
+            stackItem.textContent = new StringBuffer();
+         }
+         stackItem.textContent.append(ch, start, length);
+      }
+   }
+
+   public void endElement(String namespaceURI, String localName, String qName)
+   {
+      ElementBinding elementBinding = null;
+      QName endName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
+      StackItem item;
+      while(true)
+      {
+         item = stack.peek();
+         if(item.cursor == null)
+         {
+            if(item.ended)
+            {
+               pop();
+               if(item.particle.isRepeatable())
+               {
+                  endRepeatableParticle(item.particle);
+               }
+            }
+            else
+            {
+               elementBinding = (ElementBinding)item.particle.getTerm();
+               item.ended = true;
+               break;
+            }
+         }
+         else
+         {
+            if(!item.ended) // could be ended if it's a choice
+            {
+               endParticle(item, endName, 1);
+            }
+
+            ParticleBinding currentParticle = item.cursor.getCurrentParticle();
+            TermBinding term = currentParticle.getTerm();
+            if(term.isWildcard() && currentParticle.isRepeatable())
+            {
+               endRepeatableParticle(currentParticle);
+            }
+
+            pop();
+            if(item.particle.isRepeatable())
+            {
+               endRepeatableParticle(item.particle);
+            }
+         }
+      }
+
+      if(elementBinding == null)
+      {
+         throw new JBossXBRuntimeException("Failed to endElement " + qName + ": binding not found");
+      }
+
+      if(!elementBinding.getQName().equals(endName))
+      {
+         throw new JBossXBRuntimeException("Failed to end element " +
+            new QName(namespaceURI, localName) +
+            ": element on the stack is " + elementBinding.getQName()
+         );
+      }
+
+      endElement();
+   }
+
+   public void startElement(String namespaceURI,
+                            String localName,
+                            String qName,
+                            Attributes atts,
+                            XSTypeDefinition xercesType)
+   {
+      QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
+      ParticleBinding particle = null;
+      ParticleHandler handler = null;
+      boolean repeated = false;
+      boolean repeatedParticle = false;
+      StackItem item = null;
+      ModelGroupBinding.Cursor cursor = null; // used only when particle is a wildcard
+      SchemaBinding schemaBinding = schema;
+
+      if(stack.isEmpty())
+      {
+         if(schemaBinding != null)
+         {
+            particle = schemaBinding.getElementParticle(startName);
+         }
+         else if(schemaResolver != null)
+         {
+            String schemaLocation = atts == null ? null : Util.getSchemaLocation(atts, namespaceURI);
+            schemaBinding = schemaResolver.resolve(namespaceURI, null, schemaLocation);
+            if(schemaBinding != null)
+            {
+               particle = schemaBinding.getElementParticle(startName);
+            }
+            else
+            {
+               throw new JBossXBRuntimeException("Failed to resolve schema nsURI=" + namespaceURI + " location=" + schemaLocation);
+            }
+         }
+         else
+         {
+            throw new JBossXBRuntimeException("Neither schema binding nor schema binding resolver is available!");
+         }
+      }
+      else
+      {
+         while(!stack.isEmpty())
+         {
+            item = stack.peek();
+            if(item.cursor == null)
+            {
+               TermBinding term = item.particle.getTerm();
+               ElementBinding element = (ElementBinding)term;
+               if(item.ended)
+               {
+                  if(element.getQName().equals(startName))
+                  {
+                     particle = item.particle;
+                     repeated = true;
+                     item.reset();
+
+                     if(!particle.isRepeatable())
+                     {
+                        endRepeatableParent(startName);
+                     }
+                  }
+                  else
+                  {
+                     pop();                     
+                     if(item.particle.isRepeatable())
+                     {
+                        endRepeatableParticle(item.particle);
+                     }
+                     continue;
+                  }
+               }
+               else
+               {
+                  ParticleBinding typeParticle = element.getType().getParticle();
+                  ModelGroupBinding modelGroup = typeParticle == null ?
+                     null :
+                     (ModelGroupBinding)typeParticle.getTerm();
+                  if(modelGroup == null)
+                  {
+                     if(startName.equals(Constants.QNAME_XOP_INCLUDE))
+                     {
+                        TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
+                        if(anyUriType == null)
+                        {
+                           log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
+                        }
+
+                        TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
+                        xopIncludeType.setSchemaBinding(schema);
+                        xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
+                        xopIncludeType.setHandler(new XOPIncludeHandler(element.getType(), schema.getXopUnmarshaller()));
+
+                        ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
+
+                        particle = new ParticleBinding(xopInclude);
+
+                        ElementBinding parentElement = (ElementBinding) item.particle.getTerm();
+                        parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
+
+                        flushIgnorableCharacters();
+                        item.handler = DefaultHandlers.XOP_HANDLER;
+                        item.ignoreCharacters = true;
+                        item.o = item.handler.startParticle(stack.peek().o, startName, stack.peek().particle, null, nsRegistry);
+                        break;
+                     }
+
+                     QName typeName = element.getType().getQName();
+                     throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
+                        " type of element " +
+                        element.getQName() +
+                        " should be complex and contain " + startName + " as a child element."
+                     );
+                  }
+
+                  cursor = modelGroup.newCursor(typeParticle);
+                  List newCursors = cursor.startElement(startName, atts);
+                  if(newCursors.isEmpty())
+                  {
+                     throw new JBossXBRuntimeException(startName +
+                        " not found as a child of " +
+                        ((ElementBinding)term).getQName()
+                     );
+                  }
+                  else
+                  {
+                     flushIgnorableCharacters();
+
+                     Object o = item.o;
+                     // push all except the last one
+                     for(int i = newCursors.size() - 1; i >= 0; --i)
+                     {
+                        cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
+
+                        ParticleBinding modelGroupParticle = cursor.getParticle();
+                        if(modelGroupParticle.isRepeatable())
+                        {
+                           startRepeatableParticle(startName, modelGroupParticle);
+                        }
+
+                        handler = getHandler(modelGroupParticle);
+                        o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
+                        push(cursor, o, handler);
+                     }
+                     particle = cursor.getCurrentParticle();
+                  }
+               }
+               break;
+            }
+            else
+            {
+               cursor = item.cursor;
+               if(cursor == null)
+               {
+                  throw new JBossXBRuntimeException("No cursor for " + startName);
+               }
+
+               // todo review
+               if(!item.ended && cursor.isPositioned() && cursor.getParticle().getTerm() instanceof ChoiceBinding)
+               {
+                  endParticle(item, startName, 1);
+                  if(!item.particle.isRepeatable()) // this is for repeatable choices that should stay on the stack
+                  {
+                     pop();
+                  }
+                  continue;
+               }
+
+               //int prevOccurence = cursor.getOccurence();
+               ParticleBinding prevParticle = cursor.isPositioned() ? cursor.getCurrentParticle() : null;
+               List newCursors = cursor.startElement(startName, atts);
+               if(newCursors.isEmpty())
+               {
+                  if(!item.ended) // this is for choices
+                  {
+                     endParticle(item, startName, 1);
+                  }
+                  pop();
+               }
+               else
+               {
+                  if(item.ended) // for repeatable choices
+                  {
+                     if(!item.particle.isRepeatable())
+                     {
+                        throw new JBossXBRuntimeException("The particle expected to be repeatable but it's not: " + item.particle.getTerm());
+                     }
+                     item.reset();
+                     
+                     handler = getHandler(item.particle);
+                     item.o = handler.startParticle(stack.peek(1).o, startName, item.particle, atts, nsRegistry);
+                  }
+                  
+                  ParticleBinding curParticle = cursor.getCurrentParticle();
+                  if(curParticle != prevParticle)
+                  {
+                     if(prevParticle != null && prevParticle.isRepeatable() && prevParticle.getTerm().isModelGroup())
+                     {
+                        endRepeatableParticle(prevParticle);
+                     }
+
+                     if(newCursors.size() > 1 && curParticle.isRepeatable())
+                     {
+                        startRepeatableParticle(startName, curParticle);
+                     }
+                  }
+                  else
+                  {
+                     repeatedParticle = true;
+                  }
+
+                  // push all except the last one
+                  Object o = item.o;
+                  for(int i = newCursors.size() - 2; i >= 0; --i)
+                  {
+                     cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
+
+                     ParticleBinding modelGroupParticle = cursor.getParticle();
+                     handler = getHandler(modelGroupParticle);
+                     o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
+                     push(cursor, o, handler);
+                  }
+                  cursor = (ModelGroupBinding.Cursor)newCursors.get(0);
+                  particle = cursor.getCurrentParticle();
+                  break;
+               }
+            }
+         }
+      }
+
+      Object o = null;
+      if(particle != null)
+      {
+         Object parent = stack.isEmpty() ? null :
+            (repeated ? stack.peek(1).o : stack.peek().o);
+         if(particle.getTerm() instanceof WildcardBinding)
+         {
+            /*
+            WildcardBinding wildcard = (WildcardBinding)particle.getTerm();
+            ElementBinding element = wildcard.getElement(startName, atts);
+            */
+            ElementBinding element = cursor.getElement();
+            if(element == null)
+            {
+               throw new JBossXBRuntimeException("Failed to resolve element " +
+                  startName + " for wildcard."
+               );
+            }
+
+            if(!repeatedParticle && particle.isRepeatable())
+            {
+               startRepeatableParticle(startName, particle);
+            }
+            particle = new ParticleBinding(element/*, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded()*/);
+         }
+
+         ElementBinding element = (ElementBinding)particle.getTerm();
+
+         // todo xsi:type support should be implemented in a better way
+         String xsiType = atts.getValue("xsi:type");
+         if(xsiType != null)
+         {
+            if(trace)
+            {
+               log.trace(element.getQName() + " uses xsi:type " + xsiType);
+            }
+
+            String xsiTypePrefix;
+            String xsiTypeLocal;
+            int colon = xsiType.indexOf(':');
+            if(colon == -1)
+            {
+               xsiTypePrefix = "";
+               xsiTypeLocal = xsiType;
+            }
+            else
+            {
+               xsiTypePrefix = xsiType.substring(0, colon);
+               xsiTypeLocal = xsiType.substring(colon + 1);
+            }
+
+            String xsiTypeNs = nsRegistry.getNamespaceURI(xsiTypePrefix);
+            QName xsiTypeQName = new QName(xsiTypeNs, xsiTypeLocal);
+
+            TypeBinding xsiTypeBinding = schemaBinding.getType(xsiTypeQName);
+            if(xsiTypeBinding == null)
+            {
+               throw new JBossXBRuntimeException("Type binding not found for type " +
+                  xsiTypeQName +
+                  " specified with xsi:type for element " + startName
+               );
+            }
+
+            element = new ElementBinding(schemaBinding, startName, xsiTypeBinding);
+            particle =
+               new ParticleBinding(element,
+                  particle.getMinOccurs(),
+                  particle.getMaxOccurs(),
+                  particle.getMaxOccursUnbounded()
+               );
+         }
+
+         if(!repeated && particle.isRepeatable())
+         {
+            startRepeatableParticle(startName, particle);
+         }
+
+         TypeBinding type = element.getType();
+         if(type == null)
+         {
+            throw new JBossXBRuntimeException("No type for element " + element);
+         }
+
+         handler = type.getHandler();
+         if(handler == null)
+         {
+            handler = defParticleHandler;
+         }
+
+         List interceptors = element.getInterceptors();
+         if(!interceptors.isEmpty())
+         {
+            if (repeated)
+            {
+               pop();
+            }
+
+            for (int i = 0; i < interceptors.size(); ++i)
+            {
+               ElementInterceptor interceptor = (ElementInterceptor) interceptors.get(i);
+               parent = interceptor.startElement(parent, startName, type);
+               push(startName, particle, parent, handler);
+               interceptor.attributes(parent, startName, type, atts, nsRegistry);
+            }
+
+            if (repeated)
+            {
+               // to have correct endRepeatableParticle calls
+               stack.push(item);
+            }
+         }
+
+         String nil = atts.getValue("xsi:nil");
+         if(nil == null || !("1".equals(nil) || "true".equals(nil)))
+         {
+            o = handler.startParticle(parent, startName, particle, atts, nsRegistry);
+         }
+         else
+         {
+            o = NIL;
+         }
+      }
+      else
+      {
+         ElementBinding parentBinding = null;
+         if(!stack.isEmpty())
+         {
+            ParticleBinding stackParticle = repeated ? stack.peek(1).particle : stack.peek().particle;
+            if(stackParticle != null)
+            {
+               parentBinding = (ElementBinding)stackParticle.getTerm();
+            }
+         }
+
+         if(parentBinding != null && parentBinding.getSchema() != null)
+         {
+            schemaBinding = parentBinding.getSchema();
+         }
+
+         String msg = "Element " +
+            startName +
+            " is not bound " +
+            (parentBinding == null ? "as a global element." : "in type " + parentBinding.getType().getQName());
+         if(schemaBinding != null && schemaBinding.isStrictSchema())
+         {
+            throw new JBossXBRuntimeException(msg);
+         }
+         else if(trace)
+         {
+            log.trace(msg);
+         }
+      }
+
+      if(repeated)
+      {
+         item.o = o;
+         // in case of collection of abstract types
+         item.particle = particle;
+      }
+      else
+      {
+         push(startName, particle, o, handler);
+      }
+   }
+
+   private ParticleHandler getHandler(ParticleBinding modelGroupParticle)
+   {
+      ParticleHandler handler = ((ModelGroupBinding)modelGroupParticle.getTerm()).getHandler();
+      return handler == null ? defParticleHandler : handler;
+   }
+
+   private void endRepeatableParent(QName startName)
+   {
+      int parentPos = 1;
+      StackItem parentItem;
+      ParticleBinding parentParticle = null;
+      while(true)
+      {
+         parentItem = stack.peek(parentPos);
+         if(parentItem.cursor == null)
+         {
+            throw new JBossXBRuntimeException(
+               "Failed to start " + startName +
+               ": the element is not repeatable, repeatable parent expected to be a model group but got element " +
+               ((ElementBinding)parentItem.particle.getTerm()).getQName()
+            );
+         }
+
+         parentParticle = parentItem.particle;
+         if(parentParticle.isRepeatable())
+         {
+            break;
+         }
+
+         endParticle(parentItem, startName, ++parentPos);
+      }
+
+      if(!parentParticle.isRepeatable())
+      {
+         StringBuffer msg = new StringBuffer();
+
+         StackItem item = stack.peek();
+         ParticleBinding currentParticle = item.particle;
+         msg.append("Failed to start ").append(startName).append(": ")
+            .append(currentParticle.getTerm())
+            .append(" is not repeatable.")
+            .append(" Its parent ")
+            .append(parentParticle.getTerm())
+            .append(" expected to be repeatable!")
+            .append("\ncurrent stack: ");
+
+         for(int i = stack.size() - 1; i >= 0; --i)
+         {
+            item = stack.peek(i);
+            ParticleBinding particle = item.particle;
+            TermBinding term = particle.getTerm();
+            if(term.isModelGroup())
+            {
+               if(term instanceof SequenceBinding)
+               {
+                  msg.append("sequence");
+               }
+               else if(term instanceof ChoiceBinding)
+               {
+                  msg.append("choice");
+               }
+               else
+               {
+                  msg.append("all");
+               }
+            }
+            else if(term.isWildcard())
+            {
+               msg.append("wildcard");
+            }
+            else
+            {
+               msg.append(((ElementBinding)term).getQName());
+            }
+            msg.append("\\");
+         }
+
+         throw new JBossXBRuntimeException(msg.toString());
+      }
+
+      // todo startName is wrong here
+      endParticle(parentItem, startName, parentPos + 1);
+
+      parentItem = stack.peek(parentPos + 1);
+      while(parentPos > 0)
+      {
+         StackItem item = stack.peek(parentPos--);
+         ParticleHandler handler = getHandler(item.particle);
+         item.reset();
+         item.o = handler.startParticle(parentItem.o, startName, item.particle, null, nsRegistry);
+         parentItem = item;
+      }
+   }
+
+   private void startRepeatableParticle(QName startName, ParticleBinding particle)
+   {
+      //System.out.println(" start repeatable (" + stack.size() + "): " + particle.getTerm());
+      
+      TermBinding term = particle.getTerm();
+      if(term.isSkip())
+      {
+         return;
+      }
+      
+      StackItem item = stack.peek();
+      if(item.o != null &&
+            !(item.o instanceof GenericValueContainer) &&
+            term.getAddMethodMetaData() == null &&
+            term.getMapEntryMetaData() == null &&
+            term.getPutMethodMetaData() == null)
+      {
+         ValueListHandler handler = ValueListHandler.FACTORY.lazy(item.o);
+         Class cls = item.o.getClass();
+         item.repeatableParticleValue = new ValueListInitializer().newValueList(handler, cls);
+      }
+   }
+
+   private void endRepeatableParticle(ParticleBinding particle)
+   {
+      //System.out.println(" end repeatable (" + stack.size() + "): " + particle.getTerm());
+
+      StackItem item = stack.peek();
+      ValueList valueList = item.repeatableParticleValue;
+      if(valueList != null)
+      {
+         item.repeatableParticleValue = null;
+         if(valueList.size() == 0)
+         {
+            return;
+         }
+            
+         if(particle.getTerm().isWildcard())
+         {
+            ParticleHandler handler = ((WildcardBinding)particle.getTerm()).getWildcardHandler();
+            if(handler == null)
+            {
+               handler = defParticleHandler;
+            }
+
+            // that's not good. some elements can be handled as "unresolved" and some as "resolved"
+            QName qName = valueList.getValue(0).qName;
+            Collection col = new ArrayList();
+            for(int i = 0; i < valueList.size(); ++i)
+            {
+               col.add(valueList.getValue(i).value);
+            }
+            StackItem parentItem = stack.peek(1);
+            handler.setParent(parentItem.o, col, qName, particle, parentItem.particle);
+         }
+         else
+         {
+            valueList.getHandler().newInstance(particle, valueList);
+         }
+      }
+   }
+
+   private void endParticle(StackItem item, QName qName, int parentStackPos)
+   {
+      if(item.ended)
+      {
+         throw new JBossXBRuntimeException(item.particle.getTerm() + " has already been ended.");
+      }
+
+      ParticleBinding modelGroupParticle = item.particle;
+      ParticleHandler handler = item.handler;//getHandler(modelGroupParticle);
+
+      Object o;
+      if(item.o instanceof ValueList && !modelGroupParticle.getTerm().isSkip())
+      {
+         if(trace)
+         {
+            log.trace("endParticle " + modelGroupParticle.getTerm() + " valueList");
+         }
+         ValueList valueList = (ValueList)item.o;
+         o = valueList.getHandler().newInstance(modelGroupParticle, valueList);
+      }
+      else
+      {
+         o = handler.endParticle(item.o, qName, modelGroupParticle);
+      }
+
+      item.ended = true;
+
+      // model group should always have parent particle
+      item = (StackItem)stack.peek(parentStackPos);
+      if(item.o != null)
+      {
+         ParticleBinding parentParticle = getParentParticle();//item.particle;
+         if(parentParticle == null)
+         {
+            parentParticle = item.particle;
+         }
+         setParent(handler,
+               item.repeatableParticleValue == null ? item.o : item.repeatableParticleValue,
+               o, qName, modelGroupParticle, parentParticle);
+      }
+   }
+
+   public void startPrefixMapping(String prefix, String uri)
+   {
+      nsRegistry.addPrefixMapping(prefix, uri);
+   }
+
+   public void endPrefixMapping(String prefix)
+   {
+      nsRegistry.removePrefixMapping(prefix);
+   }
+
+   public void processingInstruction(String target, String data)
+   {
+   }
+
+   public Object getRoot()
+   {
+      return root;
+   }
+
+   // Private
+
+   private void flushIgnorableCharacters()
+   {
+      StackItem stackItem = stack.peek();
+      if(stackItem.cursor != null || stackItem.textContent == null)
+      {
+         return;
+      }
+
+      if(stackItem.indentation == Boolean.TRUE || stackItem.ignorableCharacters)
+      {
+         if(log.isTraceEnabled())
+         {
+            log.trace("ignored characters: " + ((ElementBinding) stackItem.particle.getTerm()).getQName() + " '"
+               + stackItem.textContent + "'");
+         }
+         stackItem.textContent = null;
+         stackItem.indentation = null;
+      }
+   }
+
+   private ParticleBinding getParentParticle()
+   {
+      ListIterator iter = stack.prevIterator();
+      while(iter.hasPrevious())
+      {
+         StackItem prev = (StackItem)iter.previous();
+         ParticleBinding peeked = prev.particle;
+
+         TermBinding term = peeked.getTerm();
+         if(!term.isSkip())
+         {
+            return peeked;
+         }
+      }
+      return null;
+   }
+
+   private void endElement()
+   {
+      StackItem item = stack.peek();
+      Object o = item.o;
+      ParticleBinding particle = item.particle;
+      
+      ElementBinding element = (ElementBinding)particle.getTerm();
+      QName endName = element.getQName();
+      TypeBinding type = element.getType();
+      List interceptors = element.getInterceptors();
+      int interceptorsTotal = interceptors.size();
+
+      if(o != NIL)
+      {
+         //
+         // characters
+         //
+
+         flushIgnorableCharacters();
+
+         TypeBinding charType = type.getSimpleType();
+         if(charType == null)
+         {
+            charType = type;
+         }
+
+         CharactersHandler charHandler = item.ignoreCharacters ? null : charType.getCharactersHandler();
+
+         /**
+          * If there is text content then unmarshal it and set.
+          * If there is no text content and the type is simple and
+          * its characters handler is not null then unmarshal and set.
+          * If the type is complex and there is no text data then the unmarshalled value
+          * of the empty text content is assumed to be null
+          * (in case of simple types that's not always true and depends on nillable attribute).
+          */
+         String textContent = item.textContent == null ? "" : item.textContent.toString();
+         if(textContent.length() > 0 || charHandler != null && type.isSimple())
+         {
+            String dataContent;
+            SchemaBinding schema = element.getSchema();
+            if(textContent.length() == 0)
+            {
+               dataContent = null;
+            }
+            else
+            {
+               dataContent = textContent.toString();
+               if(schema != null && schema.isReplacePropertyRefs())
+               {
+                  dataContent = StringPropertyReplacer.replaceProperties(dataContent);
+               }
+            }
+
+            Object unmarshalled;
+
+            if(charHandler == null)
+            {
+               if(!type.isSimple() &&
+                  schema != null &&
+                  schema.isStrictSchema()
+                  // todo this isSkip() doesn't look nice here
+                  && !element.isSkip())
+               {
+                  throw new JBossXBRuntimeException("Element " +
+                     endName +
+                     " with type binding " +
+                     type.getQName() +
+                     " does not include text content binding: " + dataContent
+                  );
+               }
+               unmarshalled = dataContent;
+            }
+            else
+            {
+               ValueMetaData valueMetaData = element.getValueMetaData();
+               if(valueMetaData == null)
+               {
+                  CharactersMetaData charactersMetaData = type.getCharactersMetaData();
+                  if(charactersMetaData != null)
+                  {
+                     valueMetaData = charactersMetaData.getValue();
+                  }
+               }
+
+               // todo valueMetaData is available from type
+               unmarshalled = dataContent == null ?
+                  charHandler.unmarshalEmpty(endName, charType, nsRegistry, valueMetaData) :
+                  charHandler.unmarshal(endName, charType, nsRegistry, valueMetaData, dataContent);
+            }
+
+            if(unmarshalled != null)
+            {
+               // if startElement returned null, we use characters as the object for this element
+               if(o == null)
+               {
+                  o = unmarshalled;
+               }
+               else if(charHandler != null)
+               {
+                  TermBeforeSetParentCallback beforeSetParent = charType.getBeforeSetParentCallback();
+                  if(beforeSetParent != null)
+                  {
+                     ctx.parent = o;
+                     ctx.particle = particle;
+                     ctx.parentParticle = getParentParticle();
+                     unmarshalled = beforeSetParent.beforeSetParent(unmarshalled, ctx);
+                     ctx.clear();
+                  }
+
+                  if(o instanceof ValueList)
+                  {
+                     ValueList valueList = (ValueList)o;
+                     if(type.isSimple())
+                     {
+                        valueList.getInitializer().addTermValue(endName,
+                           particle,
+                           charHandler,
+                           valueList,
+                           unmarshalled,
+                           null
+                        );
+                     }
+                     else
+                     {
+                        valueList.getInitializer().addTextValue(endName,
+                           particle,
+                           charHandler,
+                           valueList,
+                           unmarshalled
+                        );
+                     }
+                  }
+                  else
+                  {
+                     charHandler.setValue(endName, element, o, unmarshalled);
+                  }
+               }
+            }
+
+            for(int i = interceptorsTotal - 1; i >= 0; --i)
+            {
+               ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
+               interceptor.characters(((StackItem)stack.peek(interceptorsTotal - i)).o,
+                  endName, type, nsRegistry, dataContent
+               );
+            }
+         }
+      }
+      else
+      {
+         o = null;
+      }
+
+      //
+      // endElement
+      //
+
+      StackItem parentItem = stack.size() == 1 ? null : stack.peek(1);
+      Object parent = parentItem == null ? null : parentItem.o;
+      ParticleHandler handler = stack.peek().handler;
+      
+      if(o instanceof ValueList && !particle.getTerm().isSkip())
+      {
+         if(trace)
+         {
+            log.trace("endParticle " + endName + " valueList");
+         }
+         ValueList valueList = (ValueList)o;
+         o = valueList.getHandler().newInstance(particle, valueList);
+      }
+      else
+      {
+         o = handler.endParticle(o, endName, particle);
+      }
+
+      for(int i = interceptorsTotal - 1; i >= 0; --i)
+      {
+         ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
+         interceptor.endElement(((StackItem)stack.peek(interceptorsTotal - i)).o, endName, type);
+      }
+
+      //
+      // setParent
+      //
+
+      if(interceptorsTotal == 0)
+      {
+         ParticleBinding parentParticle = getParentParticle();
+         boolean hasWildcard = false;
+         ParticleHandler wildcardHandler = null;
+
+         if (parentParticle != null && parentParticle.getTerm().isElement())
+         {
+            WildcardBinding wildcard = ((ElementBinding) parentParticle.getTerm()).getType().getWildcard();
+            if (wildcard != null)
+            {
+               hasWildcard = true;
+               wildcardHandler = wildcard.getWildcardHandler();
+            }
+         }
+
+         if(parent != null)
+         {
+            /*if(o == null)
+            {
+               throw new JBossXBRuntimeException(endName + " is null!");
+            } */
+            if(wildcardHandler != null)
+            {
+               setParent(wildcardHandler,
+                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
+                     o, endName, particle, parentParticle);
+            }
+            else
+            {
+               setParent(handler,
+                     parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
+                     o, endName, particle, parentParticle);
+            }
+         }
+         else if(parentParticle != null && hasWildcard && stack.size() > 1)
+         {
+            // the parent has anyType, so it gets the value of its child
+            ListIterator iter = stack.prevIterator();
+            while(iter.hasPrevious())
+            {
+               StackItem peeked = (StackItem)iter.previous();
+               peeked.o = o;
+               if(peeked.cursor == null)
+               {
+                  break;
+               }
+            }
+
+            if(trace)
+            {
+               log.trace("Value of " + endName + " " + o + " is promoted as the value of its parent element.");
+            }
+         }
+      }
+      else
+      {
+         StackItem popped = pop();
+         for(int i = interceptorsTotal - 1; i >= 0; --i)
+         {
+            ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
+            parent = pop().o;
+            interceptor.add(parent, o, endName);
+            o = parent;
+         }
+         // need to have correst endRepeatableParticle events
+         stack.push(popped);
+      }
+
+      if(stack.size() == 1)
+      {
+         root = o;
+         stack.clear();
+      }
+   }
+
+   private void setParent(ParticleHandler handler,
+                          Object parent,
+                          Object o,
+                          QName endName,
+                          ParticleBinding particle,
+                          ParticleBinding parentParticle)
+   {
+      TermBeforeSetParentCallback beforeSetParent = particle.getTerm().getBeforeSetParentCallback();
+      if(beforeSetParent != null)
+      {
+         ctx.parent = parent;
+         ctx.particle = particle;
+         ctx.parentParticle = parentParticle;
+         o = beforeSetParent.beforeSetParent(o, ctx);
+         ctx.clear();
+      }
+
+      if(parent instanceof ValueList /*&& !particle.getTerm().isSkip()*/)
+      {
+         if(parent == o)
+         {            
+            return;
+         }
+         ValueList valueList = (ValueList)parent;
+         valueList.getInitializer().addTermValue(endName, particle, handler, valueList, o, parentParticle);
+      }
+      else
+      {
+         handler.setParent(parent, o, endName, particle, parentParticle);
+      }
+   }
+
+   private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler)
+   {
+      StackItem item = new StackItem(particle, o, handler);
+      stack.push(item);
+      if(trace)
+      {
+         Object binding = null;
+         if(particle != null)
+         {
+            binding = particle.getTerm();
+         }
+         log.trace("pushed " + qName + "=" + o + ", binding=" + binding);
+      }
+   }
+
+   private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
+   {
+      StackItem item = new StackItem(cursor, o, handler);
+      stack.push(item);
+      if(trace)
+      {
+         log.trace("pushed cursor " + cursor + ", o=" + o);
+      }
+   }
+
+   private StackItem pop()
+   {
+      StackItem item = stack.pop();
+      if(trace)
+      {
+         if(item.cursor == null)
+         {
+            log.trace("poped " + ((ElementBinding)item.particle.getTerm()).getQName() + "=" + item.particle);
+         }
+         else
+         {
+            log.trace("poped " + item.cursor.getCurrentParticle().getTerm());
+         }
+      }
+      return item;
+   }
+
+   // Inner
+
+   private static class StackItem
+   {
+      final ModelGroupBinding.Cursor cursor;
+      ParticleBinding particle;
+      ParticleHandler handler;
+      boolean ignoreCharacters;
+      Object o;
+      ValueList repeatableParticleValue;
+      StringBuffer textContent;
+      Boolean indentation;
+      boolean ignorableCharacters = true;
+      boolean ended;
+
+      public StackItem(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
+      {
+         if (cursor == null)
+            throw new IllegalArgumentException("Null cursor");
+         // this is modelgroup particle
+         this.cursor = cursor;
+         this.particle = cursor.getParticle();
+         this.o = o;
+         this.handler = handler;
+      }
+
+      public StackItem(ParticleBinding particle, Object o, ParticleHandler handler)
+      {
+         if (particle == null)
+            throw new IllegalArgumentException("Null particle");
+         // this is element particle
+         this.cursor = null;
+         this.particle = particle;
+         this.o = o;
+         this.handler = handler;
+      }
+
+      void reset()
+      {
+         if(!ended)
+         {
+            throw new JBossXBRuntimeException(
+               "Attempt to reset a particle that has already been reset: " + particle.getTerm()
+            );
+         }
+
+         ended = false;
+         o = null;
+         if(textContent != null)
+         {
+            textContent.delete(0, textContent.length());
+         }
+
+         indentation = null;
+         ignorableCharacters = true;
+      }
+   }
+
+   static class StackImpl
+   {
+      private List list = new ArrayList();
+
+      public void clear()
+      {
+         list.clear();
+      }
+
+      public void push(Object o)
+      {
+         list.add(o);
+      }
+
+      public StackItem pop()
+      {
+         return (StackItem)list.remove(list.size() - 1);
+      }
+
+      public ListIterator prevIterator()
+      {
+         return list.listIterator(list.size() - 1);
+      }
+
+      public StackItem peek()
+      {
+         return (StackItem)list.get(list.size() - 1);
+      }
+
+      public StackItem peek(int i)
+      {
+         return (StackItem)list.get(list.size() - 1 - i);
+      }
+
+      public boolean isEmpty()
+      {
+         return list.isEmpty();
+      }
+
+      public int size()
+      {
+         return list.size();
+      }
+   }
+
+   private class UnmarshallingContextImpl implements UnmarshallingContext
+   {
+      Object parent;
+      ParticleBinding particle;
+      ParticleBinding parentParticle;
+      
+      public Object getParentValue()
+      {
+         return parent;
+      }
+      
+      public ParticleBinding getParticle()
+      {
+         return particle;
+      }
+      
+      public ParticleBinding getParentParticle()
+      {
+         return parentParticle;
+      }
+      
+      public String resolvePropertyName()
+      {
+         TermBinding term = particle.getTerm();
+         PropertyMetaData propertyMetaData = term.getPropertyMetaData();
+         String prop = propertyMetaData == null ? null : propertyMetaData.getName();
+         
+         if(prop != null)
+         {
+            return prop;
+         }
+         
+         if(term.isElement())
+         {
+            QName name = ((ElementBinding)term).getQName();
+            prop = Util.xmlNameToFieldName(name.getLocalPart(), term.getSchema().isIgnoreLowLine());
+         }
+         
+         return prop;
+      }
+
+      public Class resolvePropertyType()
+      {
+         if(parent == null)
+         {
+            return null;
+         }
+         
+         String prop = resolvePropertyName();
+         if(prop != null)
+         {      
+            FieldInfo fieldInfo = FieldInfo.getFieldInfo(parent.getClass(), prop, false);
+            if (fieldInfo != null)
+            {
+               return fieldInfo.getType();
+            }
+         }
+         return null;
+      }
+      
+      // private
+      
+      void clear()
+      {
+         ctx.parent = null;
+         ctx.particle = null;
+         ctx.parentParticle = null;
+      }
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,630 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.sunday.unmarshalling;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-
-import org.jboss.xb.binding.metadata.AddMethodMetaData;
-import org.jboss.xb.binding.metadata.CharactersMetaData;
-import org.jboss.xb.binding.metadata.ClassMetaData;
-import org.jboss.xb.binding.metadata.MapEntryMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.sunday.marshalling.TermBeforeMarshallingCallback;
-import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
-import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
-import org.xml.sax.Attributes;
-import org.xml.sax.helpers.AttributesImpl;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class TypeBinding
-{
-   protected QName qName;
-   /** Map<QName, AttributeBinding>  */
-   private Map attrs = Collections.EMPTY_MAP;
-   private ParticleHandler handler;//todo default handler is now in SundayContentHandler.
-   //private ParticleHandler handler = DefaultHandlers.ELEMENT_HANDLER;
-   private CharactersHandler charactersHandler;
-   private ClassMetaData classMetaData;
-   private ValueMetaData valueMetaData;
-   private PropertyMetaData propertyMetaData;
-   private MapEntryMetaData mapEntryMetaData;
-   private SchemaBinding schemaBinding; // todo it's optional for now...
-   private TypeBinding baseType;
-   private boolean skip;
-   private CharactersMetaData charMetaData;
-   private AddMethodMetaData addMethodMetaData;
-   private ValueAdapter valueAdapter = ValueAdapter.NOOP;
-   private TermBeforeMarshallingCallback beforeMarshallingCallback;
-   private TermBeforeSetParentCallback beforeSetParentCallback;
-   private Boolean startElementCreatesObject;
-   private Boolean simple;
-
-   private WildcardBinding wildcard;
-   private ParticleBinding particle;
-
-   private List patternValues;
-   private List enumValues;
-   private TypeBinding itemType; // the type is a list type with this item type
-   private TypeBinding simpleType;
-
-   private XOPUnmarshaller xopUnmarshaller;
-   private XOPMarshaller xopMarshaller;
-
-   public TypeBinding()
-   {
-      this.qName = null;
-   }
-
-   public TypeBinding(QName qName)
-   {
-      //this(qName, (CharactersHandler)null);
-      this(qName, DefaultHandlers.CHARACTERS_HANDLER);
-   }
-
-   public TypeBinding(CharactersHandler charactersHandler)
-   {
-      this(null, charactersHandler);
-   }
-
-   public TypeBinding(QName qName, CharactersHandler charactersHandler)
-   {
-      this.qName = qName;
-      this.charactersHandler = charactersHandler;
-   }
-
-   public TypeBinding(QName qName, TypeBinding baseType)
-   {
-      this(qName, baseType.charactersHandler);
-
-      if(baseType.particle != null)
-      {
-         // todo
-         this.particle = baseType.particle;
-      }
-
-      this.attrs = new HashMap(baseType.attrs);
-      this.classMetaData = baseType.classMetaData;
-      this.valueMetaData = baseType.valueMetaData;
-      this.propertyMetaData = baseType.propertyMetaData;
-      this.mapEntryMetaData = baseType.mapEntryMetaData;
-      this.schemaBinding = baseType.schemaBinding;
-      this.baseType = baseType;
-
-      if(!baseType.isStartElementCreatesObject())
-      {
-         this.handler = baseType.handler;
-      }
-   }
-
-   public QName getQName()
-   {
-      return qName;
-   }
-
-   public ElementBinding getElement(QName name)
-   {
-      return getElement(name, true);
-   }
-
-   private ElementBinding getElement(QName name, boolean ignoreWildcards)
-   {
-      ElementBinding element = null;
-      if(particle != null)
-      {
-         ModelGroupBinding modelGroup = (ModelGroupBinding)particle.getTerm();
-         element = modelGroup.newCursor(particle).getElement(name, null, ignoreWildcards);
-      }
-
-      if(element == null && !ignoreWildcards && wildcard != null)
-      {
-         element = wildcard.getElement(name, null);
-      }
-      return element;
-   }
-
-   public void addParticle(ParticleBinding particle)
-   {
-      ModelGroupBinding modelGroup;
-      if(this.particle == null)
-      {
-         modelGroup = new AllBinding(schemaBinding);
-         this.particle = new ParticleBinding(modelGroup);
-      }
-      else
-      {
-         modelGroup = (ModelGroupBinding)this.particle.getTerm();
-      }
-      modelGroup.addParticle(particle);
-   }
-
-   public void addElement(ElementBinding element)
-   {
-      addElement(element, 1, false);
-   }
-
-   public void addElement(ElementBinding element, int minOccurs, boolean unbounded)
-   {
-      ParticleBinding particle = new ParticleBinding(element);
-      particle.setMinOccurs(minOccurs);
-      particle.setMaxOccursUnbounded(unbounded);
-      addParticle(particle);
-   }
-
-   public ElementBinding addElement(QName name, TypeBinding type)
-   {
-      return addElement(name, type, 1, false);
-   }
-
-   public ElementBinding addElement(QName name, TypeBinding type, int minOccurs, boolean unbounded)
-   {
-      ElementBinding el = new ElementBinding(schemaBinding, name, type);
-      addElement(el, minOccurs, unbounded);
-      return el;
-   }
-
-   public void addGroup(Map group)
-   {
-      for(Iterator i = group.entrySet().iterator(); i.hasNext();)
-      {
-         Map.Entry entry = (Map.Entry)i.next();
-         QName name = (QName)entry.getKey();
-         TypeBinding type = (TypeBinding)entry.getValue();
-         addElement(name, type);
-      }
-   }
-
-   public AttributeBinding getAttribute(QName qName)
-   {
-      return (AttributeBinding)attrs.get(qName);
-   }
-
-   /**
-    * Go through the type attributes to see if there are any with defaults
-    * that do not appears in the attrs list.
-    *
-    * @param attrs - the attributes seen in the document
-    * @return a possibly augmented list that includes unspecified attributes
-    *    with default values.
-    */
-   public Attributes expandWithDefaultAttributes(Attributes attrs)
-   {
-      if(this.attrs.size() == 0)
-      {
-         return attrs;
-      }
-
-      // Map<QName, AttributeBinding>
-      HashMap attrsNotSeen = new HashMap(this.attrs);
-      for(int n = 0; n < attrs.getLength(); n ++)
-      {
-         QName name = new QName(attrs.getURI(n), attrs.getLocalName(n));
-         attrsNotSeen.remove(name);
-      }
-
-      Attributes expandedAttrs = attrs;
-      if( attrsNotSeen.size() > 0 )
-      {
-         AttributesImpl tmp = new AttributesImpl(attrs);
-         Iterator iter = attrsNotSeen.entrySet().iterator();
-         while( iter.hasNext() )
-         {
-            Map.Entry entry = (Map.Entry) iter.next();
-            QName name = (QName) entry.getKey();
-            AttributeBinding binding = (AttributeBinding) entry.getValue();
-            String constraint = binding.getDefaultConstraint();
-            if( constraint != null )
-            {
-               // the Javadoc for Attributes.getType(i) says:
-               // "The attribute type is one of the strings
-               // "CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
-               // or "NOTATION" (always in upper case)."
-               tmp.addAttribute(name.getNamespaceURI(), name.getLocalPart(),
-                  name.toString(), "CDATA", constraint);
-            }
-         }
-         expandedAttrs = tmp;
-      }
-
-      return expandedAttrs;
-   }
-
-   public AttributeBinding addAttribute(QName name, TypeBinding type, AttributeHandler handler)
-   {
-      AttributeBinding attr = new AttributeBinding(schemaBinding, name, type, handler);
-      addAttribute(attr);
-      return attr;
-   }
-
-   public void addAttribute(AttributeBinding attr)
-   {
-      switch(attrs.size())
-      {
-         case 0:
-            attrs = Collections.singletonMap(attr.getQName(), attr);
-            break;
-         case 1:
-            attrs = new HashMap(attrs);
-         default:
-            attrs.put(attr.getQName(), attr);
-      }
-   }
-
-   public Collection getAttributes()
-   {
-      return attrs.values();
-   }
-
-   public CharactersHandler getCharactersHandler()
-   {
-      return charactersHandler;
-   }
-
-   /**
-    * This method will create a new simple type binding with the passed in characters handler
-    * and set this simple type as the simple type of the complex type the method was invoked on.
-    * @param charactersHandler
-    */
-   public void setSimpleType(CharactersHandler charactersHandler)
-   {
-      setSimpleType(new TypeBinding(charactersHandler));
-   }
-
-   public TypeBinding getSimpleType()
-   {
-      return simpleType;
-   }
-
-   public void setSimpleType(TypeBinding simpleType)
-   {
-      this.simpleType = simpleType;
-   }
-
-   public void setHandler(ParticleHandler handler)
-   {
-      this.handler = handler;
-   }
-
-   public ParticleHandler getHandler()
-   {
-      return handler;
-   }
-
-   public void pushInterceptor(QName qName, ElementInterceptor interceptor)
-   {
-      ElementBinding el = getElement(qName);
-      if(el == null)
-      {
-         el = addElement(qName, new TypeBinding());
-      }
-      el.pushInterceptor(interceptor);
-   }
-
-   public TypeBinding getBaseType()
-   {
-      return baseType;
-   }
-
-   public void setBaseType(TypeBinding baseType)
-   {
-      this.baseType = baseType;
-   }
-
-   public boolean isSimple()
-   {
-      return simple == null ? particle == null && attrs.isEmpty() : simple.booleanValue();
-   }
-
-   public void setSimple(boolean simple)
-   {
-      this.simple = simple ? Boolean.TRUE : Boolean.FALSE;
-   }
-
-   public ClassMetaData getClassMetaData()
-   {
-      return classMetaData;
-   }
-
-   public void setClassMetaData(ClassMetaData classMetaData)
-   {
-      this.classMetaData = classMetaData;
-   }
-
-   public SchemaBinding getSchemaBinding()
-   {
-      return schemaBinding;
-   }
-
-   public void setSchemaBinding(SchemaBinding schemaBinding)
-   {
-      this.schemaBinding = schemaBinding;
-   }
-
-   public void setValueMetaData(ValueMetaData valueMetaData)
-   {
-      this.valueMetaData = valueMetaData;
-   }
-
-   public ValueMetaData getValueMetaData()
-   {
-      return valueMetaData;
-   }
-
-   public PropertyMetaData getPropertyMetaData()
-   {
-      return propertyMetaData;
-   }
-
-   public void setPropertyMetaData(PropertyMetaData propertyMetaData)
-   {
-      this.propertyMetaData = propertyMetaData;
-   }
-
-   public MapEntryMetaData getMapEntryMetaData()
-   {
-      return mapEntryMetaData;
-   }
-
-   public void setMapEntryMetaData(MapEntryMetaData mapEntryMetaData)
-   {
-      this.mapEntryMetaData = mapEntryMetaData;
-   }
-
-   public void setSkip(boolean skip)
-   {
-      this.skip = skip;
-   }
-
-   public boolean isSkip()
-   {
-      return skip;
-   }
-
-   public CharactersMetaData getCharactersMetaData()
-   {
-      return charMetaData;
-   }
-
-   public void setCharactersMetaData(CharactersMetaData charMetaData)
-   {
-      this.charMetaData = charMetaData;
-   }
-
-   public void setAddMethodMetaData(AddMethodMetaData addMethodMetaData)
-   {
-      this.addMethodMetaData = addMethodMetaData;
-   }
-
-   public AddMethodMetaData getAddMethodMetaData()
-   {
-      return addMethodMetaData;
-   }
-
-   public ValueAdapter getValueAdapter()
-   {
-      return valueAdapter;
-   }
-
-   public void setValueAdapter(ValueAdapter valueAdapter)
-   {
-      this.valueAdapter = valueAdapter;
-   }
-
-   public boolean isStartElementCreatesObject()
-   {
-      return startElementCreatesObject == null ?
-         particle != null || !attrs.isEmpty() : startElementCreatesObject.booleanValue();
-   }
-
-   public void setStartElementCreatesObject(boolean startElementCreatesObject)
-   {
-      this.startElementCreatesObject = startElementCreatesObject ? Boolean.TRUE : Boolean.FALSE;
-   }
-
-   private boolean initializedWildcard;
-   public WildcardBinding getWildcard()
-   {
-      if(initializedWildcard)
-      {
-         return wildcard;
-      }
-      
-      if(particle != null)
-      {
-         wildcard = getWildcard(particle.getTerm());
-         initializedWildcard = true;
-      }
-      
-      return wildcard;
-   }
-
-   public ParticleBinding getParticle()
-   {
-      return particle;
-   }
-
-   public void setParticle(ParticleBinding particle)
-   {
-      this.particle = particle;
-   }
-
-   public List getLexicalPattern()
-   {
-      return patternValues;
-   }
-
-   public void addLexicalPattern(String patternValue)
-   {
-      if(patternValues == null)
-      {
-         patternValues = Collections.singletonList(patternValue);
-      }
-      else
-      {
-         if(patternValues.size() == 1)
-         {
-            patternValues = new ArrayList(patternValues);
-         }
-         patternValues.add(patternValue);
-      }
-   }
-
-   public List getLexicalEnumeration()
-   {
-      return enumValues;
-   }
-
-   public void addEnumValue(String value)
-   {
-      if(enumValues == null)
-      {
-         enumValues = Collections.singletonList(value);
-      }
-      else
-      {
-         if(enumValues.size() == 1)
-         {
-            enumValues = new ArrayList(enumValues);
-         }
-         enumValues.add(value);
-      }
-   }
-
-   public void setItemType(TypeBinding itemType)
-   {
-      this.itemType = itemType;
-   }
-
-   public TypeBinding getItemType()
-   {
-      return itemType;
-   }
-
-   public XOPUnmarshaller getXopUnmarshaller()
-   {
-      return xopUnmarshaller == null ?
-         (schemaBinding == null ? null : schemaBinding.getXopUnmarshaller()) : xopUnmarshaller;
-   }
-
-   public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
-   {
-      this.xopUnmarshaller = xopUnmarshaller;
-   }
-
-   public XOPMarshaller getXopMarshaller()
-   {
-      return xopMarshaller == null ?
-         (schemaBinding == null ? null : schemaBinding.getXopMarshaller()) : xopMarshaller;
-   }
-
-   public void setXopMarshaller(XOPMarshaller xopMarshaller)
-   {
-      this.xopMarshaller = xopMarshaller;
-   }
-
-   public boolean hasOnlyXmlMimeAttributes()
-   {
-      if(attrs.isEmpty())
-      {
-         return false;
-      }
-      else
-      {
-         Iterator iter = attrs.keySet().iterator();
-         while(iter.hasNext())
-         {
-            QName qName = (QName)iter.next();
-            if(!Constants.NS_XML_MIME.equals(qName.getNamespaceURI()))
-            {
-               return false;
-            }
-         }
-      }
-      return true;
-   }
-
-   public void setBeforeMarshallingCallback(TermBeforeMarshallingCallback marshallingHandler)
-   {
-      this.beforeMarshallingCallback = marshallingHandler;
-   }
-
-   public TermBeforeMarshallingCallback getBeforeMarshallingCallback()
-   {
-      return beforeMarshallingCallback;
-   }
-
-   public void setBeforeSetParentCallback(TermBeforeSetParentCallback beforeSetParent)
-   {
-      this.beforeSetParentCallback = beforeSetParent;
-   }
-
-   public TermBeforeSetParentCallback getBeforeSetParentCallback()
-   {
-      return beforeSetParentCallback;
-   }
-
-   public String toString()
-   {
-      return super.toString() + "[" + qName + "]";
-   }
-
-   private static WildcardBinding getWildcard(TermBinding term)
-   {
-      if(term.isWildcard())
-      {
-         return (WildcardBinding) term;
-      }     
-      
-      if(term.isModelGroup())
-      {
-         ModelGroupBinding group = (ModelGroupBinding) term;
-         for(Iterator i = group.getParticles().iterator(); i.hasNext();)
-         {
-            term = ((ParticleBinding)i.next()).getTerm();
-            if(term.isWildcard())
-            {
-               return (WildcardBinding)term;
-            }
-            else if(term.isModelGroup())
-            {
-               WildcardBinding wc = getWildcard(term);
-               if (wc != null)
-                  return wc;
-            }
-         }
-      }
-      
-      return null;
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,635 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.sunday.unmarshalling;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.jboss.xb.binding.metadata.AddMethodMetaData;
+import org.jboss.xb.binding.metadata.CharactersMetaData;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.metadata.MapEntryMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.sunday.marshalling.TermBeforeMarshallingCallback;
+import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
+import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class TypeBinding
+{
+   protected QName qName;
+   /** Map<QName, AttributeBinding>  */
+   private Map attrs = Collections.EMPTY_MAP;
+   private ParticleHandler handler;//todo default handler is now in SundayContentHandler.
+   //private ParticleHandler handler = DefaultHandlers.ELEMENT_HANDLER;
+   private CharactersHandler charactersHandler;
+   private ClassMetaData classMetaData;
+   private ValueMetaData valueMetaData;
+   private PropertyMetaData propertyMetaData;
+   private MapEntryMetaData mapEntryMetaData;
+   private SchemaBinding schemaBinding; // todo it's optional for now...
+   private TypeBinding baseType;
+   private boolean skip;
+   private CharactersMetaData charMetaData;
+   private AddMethodMetaData addMethodMetaData;
+   private ValueAdapter valueAdapter = ValueAdapter.NOOP;
+   private TermBeforeMarshallingCallback beforeMarshallingCallback;
+   private TermBeforeSetParentCallback beforeSetParentCallback;
+   private Boolean startElementCreatesObject;
+   private Boolean simple;
+
+   private WildcardBinding wildcard;
+   private ParticleBinding particle;
+
+   private List patternValues;
+   private List enumValues;
+   private TypeBinding itemType; // the type is a list type with this item type
+   private TypeBinding simpleType;
+
+   private XOPUnmarshaller xopUnmarshaller;
+   private XOPMarshaller xopMarshaller;
+
+   public TypeBinding()
+   {
+      this.qName = null;
+   }
+
+   public TypeBinding(QName qName)
+   {
+      //this(qName, (CharactersHandler)null);
+      this(qName, DefaultHandlers.CHARACTERS_HANDLER);
+   }
+
+   public TypeBinding(CharactersHandler charactersHandler)
+   {
+      this(null, charactersHandler);
+   }
+
+   public TypeBinding(QName qName, CharactersHandler charactersHandler)
+   {
+      this.qName = qName;
+      this.charactersHandler = charactersHandler;
+   }
+
+   public TypeBinding(QName qName, TypeBinding baseType)
+   {
+      this(qName, baseType.charactersHandler);
+
+      if(baseType.particle != null)
+      {
+         // todo
+         this.particle = baseType.particle;
+      }
+
+      this.attrs = new HashMap(baseType.attrs);
+      this.classMetaData = baseType.classMetaData;
+      this.valueMetaData = baseType.valueMetaData;
+      this.propertyMetaData = baseType.propertyMetaData;
+      this.mapEntryMetaData = baseType.mapEntryMetaData;
+      this.schemaBinding = baseType.schemaBinding;
+      this.baseType = baseType;
+
+      if(!baseType.isStartElementCreatesObject())
+      {
+         this.handler = baseType.handler;
+      }
+   }
+
+   public QName getQName()
+   {
+      return qName;
+   }
+
+   public ElementBinding getElement(QName name)
+   {
+      return getElement(name, true);
+   }
+
+   private ElementBinding getElement(QName name, boolean ignoreWildcards)
+   {
+      ElementBinding element = null;
+      if(particle != null)
+      {
+         ModelGroupBinding modelGroup = (ModelGroupBinding)particle.getTerm();
+         element = modelGroup.newCursor(particle).getElement(name, null, ignoreWildcards);
+      }
+
+      if(element == null && !ignoreWildcards && wildcard != null)
+      {
+         element = wildcard.getElement(name, null);
+      }
+      return element;
+   }
+
+   public void addParticle(ParticleBinding particle)
+   {
+      ModelGroupBinding modelGroup;
+      if(this.particle == null)
+      {
+         modelGroup = new AllBinding(schemaBinding);
+         this.particle = new ParticleBinding(modelGroup);
+      }
+      else
+      {
+         modelGroup = (ModelGroupBinding)this.particle.getTerm();
+      }
+      modelGroup.addParticle(particle);
+   }
+
+   public void addElement(ElementBinding element)
+   {
+      addElement(element, 1, false);
+   }
+
+   public void addElement(ElementBinding element, int minOccurs, boolean unbounded)
+   {
+      ParticleBinding particle = new ParticleBinding(element);
+      particle.setMinOccurs(minOccurs);
+      particle.setMaxOccursUnbounded(unbounded);
+      addParticle(particle);
+   }
+
+   public ElementBinding addElement(QName name, TypeBinding type)
+   {
+      return addElement(name, type, 1, false);
+   }
+
+   public ElementBinding addElement(QName name, TypeBinding type, int minOccurs, boolean unbounded)
+   {
+      ElementBinding el = new ElementBinding(schemaBinding, name, type);
+      addElement(el, minOccurs, unbounded);
+      return el;
+   }
+
+   public void addGroup(Map group)
+   {
+      for(Iterator i = group.entrySet().iterator(); i.hasNext();)
+      {
+         Map.Entry entry = (Map.Entry)i.next();
+         QName name = (QName)entry.getKey();
+         TypeBinding type = (TypeBinding)entry.getValue();
+         addElement(name, type);
+      }
+   }
+
+   public AttributeBinding getAttribute(QName qName)
+   {
+      return (AttributeBinding)attrs.get(qName);
+   }
+
+   /**
+    * Go through the type attributes to see if there are any with defaults
+    * that do not appears in the attrs list.
+    *
+    * @param attrs - the attributes seen in the document
+    * @return a possibly augmented list that includes unspecified attributes
+    *    with default values.
+    */
+   public Attributes expandWithDefaultAttributes(Attributes attrs)
+   {
+      if(this.attrs.size() == 0)
+      {
+         return attrs;
+      }
+
+      // Map<QName, AttributeBinding>
+      HashMap attrsNotSeen = new HashMap(this.attrs);
+      for(int n = 0; n < attrs.getLength(); n ++)
+      {
+         QName name = new QName(attrs.getURI(n), attrs.getLocalName(n));
+         attrsNotSeen.remove(name);
+      }
+
+      Attributes expandedAttrs = attrs;
+      if( attrsNotSeen.size() > 0 )
+      {
+         AttributesImpl tmp = new AttributesImpl(attrs);
+         Iterator iter = attrsNotSeen.entrySet().iterator();
+         while( iter.hasNext() )
+         {
+            Map.Entry entry = (Map.Entry) iter.next();
+            QName name = (QName) entry.getKey();
+            AttributeBinding binding = (AttributeBinding) entry.getValue();
+            String constraint = binding.getDefaultConstraint();
+            if( constraint != null )
+            {
+               // the Javadoc for Attributes.getType(i) says:
+               // "The attribute type is one of the strings
+               // "CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
+               // or "NOTATION" (always in upper case)."
+               tmp.addAttribute(name.getNamespaceURI(), name.getLocalPart(),
+                  name.toString(), "CDATA", constraint);
+            }
+         }
+         expandedAttrs = tmp;
+      }
+
+      return expandedAttrs;
+   }
+
+   public AttributeBinding addAttribute(QName name, TypeBinding type, AttributeHandler handler)
+   {
+      AttributeBinding attr = new AttributeBinding(schemaBinding, name, type, handler);
+      addAttribute(attr);
+      return attr;
+   }
+
+   public void addAttribute(AttributeBinding attr)
+   {
+      switch(attrs.size())
+      {
+         case 0:
+            attrs = Collections.singletonMap(attr.getQName(), attr);
+            break;
+         case 1:
+            attrs = new HashMap(attrs);
+         default:
+            attrs.put(attr.getQName(), attr);
+      }
+   }
+
+   public Collection getAttributes()
+   {
+      return attrs.values();
+   }
+
+   public CharactersHandler getCharactersHandler()
+   {
+      return charactersHandler;
+   }
+
+   /**
+    * This method will create a new simple type binding with the passed in characters handler
+    * and set this simple type as the simple type of the complex type the method was invoked on.
+    * @param charactersHandler
+    */
+   public void setSimpleType(CharactersHandler charactersHandler)
+   {
+      setSimpleType(new TypeBinding(charactersHandler));
+   }
+
+   public TypeBinding getSimpleType()
+   {
+      return simpleType;
+   }
+
+   public void setSimpleType(TypeBinding simpleType)
+   {
+      this.simpleType = simpleType;
+   }
+
+   public void setHandler(ParticleHandler handler)
+   {
+      this.handler = handler;
+   }
+
+   public ParticleHandler getHandler()
+   {
+      return handler;
+   }
+
+   public void pushInterceptor(QName qName, ElementInterceptor interceptor)
+   {
+      ElementBinding el = getElement(qName);
+      if(el == null)
+      {
+         el = addElement(qName, new TypeBinding());
+      }
+      el.pushInterceptor(interceptor);
+   }
+
+   public TypeBinding getBaseType()
+   {
+      return baseType;
+   }
+
+   public void setBaseType(TypeBinding baseType)
+   {
+      this.baseType = baseType;
+   }
+
+   public boolean isSimple()
+   {
+      return simple == null ? particle == null && attrs.isEmpty() : simple.booleanValue();
+   }
+
+   public void setSimple(boolean simple)
+   {
+      this.simple = simple ? Boolean.TRUE : Boolean.FALSE;
+   }
+
+   public boolean isTextContentAllowed()
+   {
+      return simpleType != null || isSimple();
+   }
+
+   public ClassMetaData getClassMetaData()
+   {
+      return classMetaData;
+   }
+
+   public void setClassMetaData(ClassMetaData classMetaData)
+   {
+      this.classMetaData = classMetaData;
+   }
+
+   public SchemaBinding getSchemaBinding()
+   {
+      return schemaBinding;
+   }
+
+   public void setSchemaBinding(SchemaBinding schemaBinding)
+   {
+      this.schemaBinding = schemaBinding;
+   }
+
+   public void setValueMetaData(ValueMetaData valueMetaData)
+   {
+      this.valueMetaData = valueMetaData;
+   }
+
+   public ValueMetaData getValueMetaData()
+   {
+      return valueMetaData;
+   }
+
+   public PropertyMetaData getPropertyMetaData()
+   {
+      return propertyMetaData;
+   }
+
+   public void setPropertyMetaData(PropertyMetaData propertyMetaData)
+   {
+      this.propertyMetaData = propertyMetaData;
+   }
+
+   public MapEntryMetaData getMapEntryMetaData()
+   {
+      return mapEntryMetaData;
+   }
+
+   public void setMapEntryMetaData(MapEntryMetaData mapEntryMetaData)
+   {
+      this.mapEntryMetaData = mapEntryMetaData;
+   }
+
+   public void setSkip(boolean skip)
+   {
+      this.skip = skip;
+   }
+
+   public boolean isSkip()
+   {
+      return skip;
+   }
+
+   public CharactersMetaData getCharactersMetaData()
+   {
+      return charMetaData;
+   }
+
+   public void setCharactersMetaData(CharactersMetaData charMetaData)
+   {
+      this.charMetaData = charMetaData;
+   }
+
+   public void setAddMethodMetaData(AddMethodMetaData addMethodMetaData)
+   {
+      this.addMethodMetaData = addMethodMetaData;
+   }
+
+   public AddMethodMetaData getAddMethodMetaData()
+   {
+      return addMethodMetaData;
+   }
+
+   public ValueAdapter getValueAdapter()
+   {
+      return valueAdapter;
+   }
+
+   public void setValueAdapter(ValueAdapter valueAdapter)
+   {
+      this.valueAdapter = valueAdapter;
+   }
+
+   public boolean isStartElementCreatesObject()
+   {
+      return startElementCreatesObject == null ?
+         particle != null || !attrs.isEmpty() : startElementCreatesObject.booleanValue();
+   }
+
+   public void setStartElementCreatesObject(boolean startElementCreatesObject)
+   {
+      this.startElementCreatesObject = startElementCreatesObject ? Boolean.TRUE : Boolean.FALSE;
+   }
+
+   private boolean initializedWildcard;
+   public WildcardBinding getWildcard()
+   {
+      if(initializedWildcard)
+      {
+         return wildcard;
+      }
+      
+      if(particle != null)
+      {
+         wildcard = getWildcard(particle.getTerm());
+         initializedWildcard = true;
+      }
+      
+      return wildcard;
+   }
+
+   public ParticleBinding getParticle()
+   {
+      return particle;
+   }
+
+   public void setParticle(ParticleBinding particle)
+   {
+      this.particle = particle;
+   }
+
+   public List getLexicalPattern()
+   {
+      return patternValues;
+   }
+
+   public void addLexicalPattern(String patternValue)
+   {
+      if(patternValues == null)
+      {
+         patternValues = Collections.singletonList(patternValue);
+      }
+      else
+      {
+         if(patternValues.size() == 1)
+         {
+            patternValues = new ArrayList(patternValues);
+         }
+         patternValues.add(patternValue);
+      }
+   }
+
+   public List getLexicalEnumeration()
+   {
+      return enumValues;
+   }
+
+   public void addEnumValue(String value)
+   {
+      if(enumValues == null)
+      {
+         enumValues = Collections.singletonList(value);
+      }
+      else
+      {
+         if(enumValues.size() == 1)
+         {
+            enumValues = new ArrayList(enumValues);
+         }
+         enumValues.add(value);
+      }
+   }
+
+   public void setItemType(TypeBinding itemType)
+   {
+      this.itemType = itemType;
+   }
+
+   public TypeBinding getItemType()
+   {
+      return itemType;
+   }
+
+   public XOPUnmarshaller getXopUnmarshaller()
+   {
+      return xopUnmarshaller == null ?
+         (schemaBinding == null ? null : schemaBinding.getXopUnmarshaller()) : xopUnmarshaller;
+   }
+
+   public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
+   {
+      this.xopUnmarshaller = xopUnmarshaller;
+   }
+
+   public XOPMarshaller getXopMarshaller()
+   {
+      return xopMarshaller == null ?
+         (schemaBinding == null ? null : schemaBinding.getXopMarshaller()) : xopMarshaller;
+   }
+
+   public void setXopMarshaller(XOPMarshaller xopMarshaller)
+   {
+      this.xopMarshaller = xopMarshaller;
+   }
+
+   public boolean hasOnlyXmlMimeAttributes()
+   {
+      if(attrs.isEmpty())
+      {
+         return false;
+      }
+      else
+      {
+         Iterator iter = attrs.keySet().iterator();
+         while(iter.hasNext())
+         {
+            QName qName = (QName)iter.next();
+            if(!Constants.NS_XML_MIME.equals(qName.getNamespaceURI()))
+            {
+               return false;
+            }
+         }
+      }
+      return true;
+   }
+
+   public void setBeforeMarshallingCallback(TermBeforeMarshallingCallback marshallingHandler)
+   {
+      this.beforeMarshallingCallback = marshallingHandler;
+   }
+
+   public TermBeforeMarshallingCallback getBeforeMarshallingCallback()
+   {
+      return beforeMarshallingCallback;
+   }
+
+   public void setBeforeSetParentCallback(TermBeforeSetParentCallback beforeSetParent)
+   {
+      this.beforeSetParentCallback = beforeSetParent;
+   }
+
+   public TermBeforeSetParentCallback getBeforeSetParentCallback()
+   {
+      return beforeSetParentCallback;
+   }
+
+   public String toString()
+   {
+      return super.toString() + "[" + qName + "]";
+   }
+
+   private static WildcardBinding getWildcard(TermBinding term)
+   {
+      if(term.isWildcard())
+      {
+         return (WildcardBinding) term;
+      }     
+      
+      if(term.isModelGroup())
+      {
+         ModelGroupBinding group = (ModelGroupBinding) term;
+         for(Iterator i = group.getParticles().iterator(); i.hasNext();)
+         {
+            term = ((ParticleBinding)i.next()).getTerm();
+            if(term.isWildcard())
+            {
+               return (WildcardBinding)term;
+            }
+            else if(term.isModelGroup())
+            {
+               WildcardBinding wc = getWildcard(term);
+               if (wc != null)
+                  return wc;
+            }
+         }
+      }
+      
+      return null;
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,1521 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.sunday.unmarshalling;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.ListIterator;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-
-import javax.xml.namespace.QName;
-
-import org.apache.xerces.xs.StringList;
-import org.apache.xerces.xs.XSAnnotation;
-import org.apache.xerces.xs.XSAttributeDeclaration;
-import org.apache.xerces.xs.XSAttributeUse;
-import org.apache.xerces.xs.XSComplexTypeDefinition;
-import org.apache.xerces.xs.XSConstants;
-import org.apache.xerces.xs.XSElementDeclaration;
-import org.apache.xerces.xs.XSModel;
-import org.apache.xerces.xs.XSModelGroup;
-import org.apache.xerces.xs.XSModelGroupDefinition;
-import org.apache.xerces.xs.XSNamedMap;
-import org.apache.xerces.xs.XSObjectList;
-import org.apache.xerces.xs.XSParticle;
-import org.apache.xerces.xs.XSSimpleTypeDefinition;
-import org.apache.xerces.xs.XSTerm;
-import org.apache.xerces.xs.XSTypeDefinition;
-import org.apache.xerces.xs.XSWildcard;
-import org.jboss.logging.Logger;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
-import org.jboss.xb.binding.metadata.AddMethodMetaData;
-import org.jboss.xb.binding.metadata.CharactersMetaData;
-import org.jboss.xb.binding.metadata.ClassMetaData;
-import org.jboss.xb.binding.metadata.MapEntryMetaData;
-import org.jboss.xb.binding.metadata.PackageMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.PutMethodMetaData;
-import org.jboss.xb.binding.metadata.SchemaMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.metadata.XsdAnnotation;
-import org.jboss.xb.binding.metadata.XsdAppInfo;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class XsdBinder
-{
-   static final Logger log = Logger.getLogger(XsdBinder.class);
-
-   /**
-    * Creates a new instance of the binder the user can use to tune
-    * configuration before parsing the XSD.
-    * 
-    * @return  a new instance of the XsdBinder
-    */
-   public static XsdBinder newInstance()
-   {
-     return new XsdBinder();
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd url/uri.
-    *
-    * @param xsdUrl
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(String xsdUrl)
-   {
-      DefaultSchemaResolver resolver = new DefaultSchemaResolver();
-      resolver.setBaseURI(xsdUrl);
-      return bind(xsdUrl, resolver);
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd url/uri.
-    *
-    * @param xsdUrl
-    * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
-    *                 and also will be set on the returned instance of SchemaBinding
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(String xsdUrl, SchemaBindingResolver resolver)
-   {
-      XSModel model = Util.loadSchema(xsdUrl, resolver);
-      return bind(model, resolver);
-   }
-
-   public static SchemaBinding bind(InputStream xsdStream, String encoding)
-   {
-      return bind(xsdStream, encoding, new DefaultSchemaResolver());
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd stream.
-    *
-    * @param xsdStream - the xsd InputStream
-    * @param encoding  - optional stream encoding
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI)
-   {
-      return bind(xsdStream, encoding, baseURI, true);
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd stream.
-    *
-    * @param xsdStream - the xsd InputStream
-    * @param encoding  - optional stream encoding
-    * @param processAnnotations - process annotations
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI, boolean processAnnotations)
-   {
-      DefaultSchemaResolver resolver = new DefaultSchemaResolver();
-      resolver.setBaseURI(baseURI);
-      return bind(xsdStream, encoding, resolver, processAnnotations);
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd stream.
-    *
-    * @param xsdStream - the xsd InputStream
-    * @param encoding  - optional stream encoding
-    * @param resolver  the resolver will be used to resolve imported schemas in the schema being loaded
-    *                  and also will be set on the returned instance of SchemaBinding
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver)
-   {
-      return bind(xsdStream, encoding, resolver, true);
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd stream.
-    *
-    * @param xsdStream - the xsd InputStream
-    * @param encoding  - optional stream encoding
-    * @param resolver  the resolver will be used to resolve imported schemas in the schema being loaded
-    *                  and also will be set on the returned instance of SchemaBinding
-    * @param processAnnotations whether to process annotations
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver, boolean processAnnotations)
-   {
-      XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
-      return bind(model, resolver, processAnnotations);
-   }
-
-   public static SchemaBinding bind(Reader xsdReader, String encoding)
-   {
-      return bind(xsdReader, encoding, new DefaultSchemaResolver());
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd reader.
-    *
-    * @param xsdReader - xsd reader
-    * @param encoding  - optional reader encoding
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(Reader xsdReader, String encoding, String baseURI)
-   {
-      DefaultSchemaResolver resolver = new DefaultSchemaResolver();
-      resolver.setBaseURI(baseURI);
-      return bind(xsdReader, encoding, resolver);
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd reader.
-    *
-    * @param xsdReader - xsd reader
-    * @param encoding  - optional reader encoding
-    * @param resolver  the resolver will be used to resolve imported schemas in the schema being loaded
-    *                  and also will be set on the returned instance of SchemaBinding
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(Reader xsdReader, String encoding, SchemaBindingResolver resolver)
-   {
-      XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
-      return bind(model, resolver);
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd string.
-    *
-    * @param xsd      - xsd string
-    * @param encoding - optional string encoding
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(String xsd, String encoding)
-   {
-      return bind(xsd, encoding, new DefaultSchemaResolver());
-   }
-
-   /**
-    * Create a SchemaBinding from and xsd string.
-    *
-    * @param xsd      - xsd string
-    * @param encoding - optional string encoding
-    * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
-    *                 and also will be set on the returned instance of SchemaBinding
-    * @return SchemaBinding mapping
-    */
-   public static SchemaBinding bind(String xsd, String encoding, SchemaBindingResolver resolver)
-   {
-      XSModel model = Util.loadSchema(xsd, encoding);
-      return bind(model, resolver);
-   }
-
-   public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver)
-   {
-      return bind(model,resolver, true);
-   }
-
-   public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver, boolean processAnnotations)
-   {
-      XsdBinder binder = new XsdBinder();
-      binder.setProcessAnnotations(processAnnotations);
-      binder.setSchemaResolver(resolver);
-      return binder.parse(model);
-   }
-
-   /**
-    * @param schema schema binding the type should be added to
-    * @param type   type definition to be bound
-    * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
-    *             It will be removed when anonymous type binding in JBossWS is implemented properly.
-    *             No one else should use this method.</i>
-    *
-    *             <p>This method binds a type definition and adds it as a global type to the passed in schema binding.
-    */
-   public static void bindType(SchemaBinding schema, XSTypeDefinition type)
-   {
-      TypeBinding typeBinding = bindType(new Context(schema), type);
-      schema.addType(typeBinding);
-   }
-
-   /**
-    * @param schema             schema binding the type should be added to
-    * @param element            element declaration to be bound
-    * @param minOccurs
-    * @param maxOccurs
-    * @param maxOccursUnbounded
-    * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
-    *             It will be removed when anonymous type binding in JBossWS is implemented properly.
-    *             No one else should use this method.</i>
-    *
-    *             <p>This method binds an element declaration and adds it as a global element to the passed in schema binding.
-    */
-   public static void bindElement(SchemaBinding schema,
-                                  XSElementDeclaration element,
-                                  int minOccurs,
-                                  int maxOccurs,
-                                  boolean maxOccursUnbounded)
-   {
-      ParticleBinding particle = bindElement(new Context(schema),
-         element,
-         minOccurs,
-         maxOccurs,
-         maxOccursUnbounded
-      );
-      schema.addElementParticle(particle);
-   }
-
-   // Exposed attributes
-   
-   private boolean processAnnotations = true;
-   private SchemaBindingResolver resolver;
-   private boolean simpleContentWithIdAsSimpleType = true;
-   private boolean unresolvedContentBoundToDOM = true;
-   
-   // Internal attributes
-   
-   private boolean trace = log.isTraceEnabled();
-   private final SchemaBinding schema;
-   private SharedElements sharedElements = new SharedElements();
-   private final List typeGroupStack = new ArrayList();
-
-   // Ctors
-   
-   private XsdBinder()
-   {
-      this(new SchemaBinding());
-   }
-
-   private XsdBinder(SchemaBinding schema)
-   {
-      this.schema = schema;
-   }
-
-   // Public
-   
-   public void setProcessAnnotations(boolean processAnnotations)
-   {
-      this.processAnnotations = processAnnotations;
-   }
-
-   public boolean isProcessAnnotations()
-   {
-      return processAnnotations;
-   }
-
-   public void setSchemaResolver(SchemaBindingResolver resolver)
-   {
-      this.resolver = resolver;
-   }
-
-   public SchemaBindingResolver getSchemaResolver()
-   {
-      return resolver;
-   }
-
-   public void setSimpleContentWithIdAsSimpleType(boolean simpleContentWithIdAsSimpleType)
-   {
-      this.simpleContentWithIdAsSimpleType = simpleContentWithIdAsSimpleType;
-   }
-
-   public boolean isSimpleContentWithIdAsSimpleType()
-   {
-      return simpleContentWithIdAsSimpleType;
-   }
-
-   public void setUnresolvedContentBoundToDOM(boolean toDOM)
-   {
-      this.unresolvedContentBoundToDOM = toDOM;      
-   }
-   
-   public boolean isUnresolvedContentBoundToDOM()
-   {
-      return this.unresolvedContentBoundToDOM;
-   }
-   
-   public SchemaBinding parse(String xsdUrl)
-   {
-      if(resolver == null)
-      {
-         resolver = new DefaultSchemaResolver();
-      }
-
-      XSModel model = Util.loadSchema(xsdUrl, resolver);
-      return parse(model);
-   }
-   
-   public SchemaBinding parse(InputStream xsdStream, String encoding)
-   {
-      if(resolver == null)
-      {
-         resolver = new DefaultSchemaResolver();
-      }
-
-      XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
-      return parse(model);
-   }
-   
-   public SchemaBinding parse(Reader xsdReader, String encoding)
-   {
-      if(resolver == null)
-      {
-         resolver = new DefaultSchemaResolver();
-      }
-  
-      XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
-      return parse(model);
-   }
-
-
-   // Private
-
-   public SchemaBinding parse(XSModel model)
-   {
-      Context ctx = new Context();
-      ctx.processAnnotations = processAnnotations;
-      SchemaBinding schema = ctx.schema;
-      schema.setSchemaResolver(resolver);
-
-      // read annotations. for now just log the ones that are going to be used
-      if (ctx.processAnnotations)
-      {
-         XSObjectList annotations = model.getAnnotations();
-         if (ctx.trace)
-         {
-            log.trace("started binding schema " + schema);
-            log.trace("Schema annotations: " + annotations.getLength());
-         }
-
-         for(int i = 0; i < annotations.getLength(); ++i)
-         {
-            XSAnnotation annotation = (XSAnnotation)annotations.item(i);
-            XsdAnnotation an = XsdAnnotation.unmarshal(annotation.getAnnotationString());
-            XsdAppInfo appinfo = an.getAppInfo();
-            if(appinfo != null)
-            {
-               SchemaMetaData schemaBindings = appinfo.getSchemaMetaData();
-               if(schemaBindings != null)
-               {
-                  // Get the ignoreUnresolvedFieldOrClass
-                  schema.setIgnoreUnresolvedFieldOrClass(schemaBindings.isIgnoreUnresolvedFieldOrClass());
-                  // Get the ignoreUnresolvedFieldOrClass
-                  schema.setReplacePropertyRefs(schemaBindings.isReplacePropertyRefs());
-                  // Get the default package
-                  PackageMetaData packageMetaData = schemaBindings.getPackage();
-                  if(packageMetaData != null)
-                  {
-                     if (ctx.trace)
-                        log.trace("schema default package: " + packageMetaData.getName());
-                     schema.setPackageMetaData(packageMetaData);
-                  }
-               }
-            }
-         }
-      }
-
-      StringList namespaceList = model.getNamespaces();
-      Set namespaces = new LinkedHashSet(namespaceList.getLength());
-      for (int i = 0; i < namespaceList.getLength(); ++i)
-         namespaces.add(namespaceList.item(i));
-      schema.setNamespaces(namespaces);
-      
-      XSNamedMap groups = model.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
-      if (ctx.trace)
-         log.trace("Model groups: " + groups.getLength());
-      for(int i = 0; i < groups.getLength(); ++i)
-      {
-         XSModelGroupDefinition groupDef = (XSModelGroupDefinition)groups.item(i);
-         bindGlobalGroup(groupDef.getModelGroup(), ctx.sharedElements);
-      }
-
-      XSNamedMap types = model.getComponents(XSConstants.TYPE_DEFINITION);
-      if (ctx.trace)
-         log.trace("Model types: " + types.getLength());
-      for(int i = 0; i < types.getLength(); ++i)
-      {
-         XSTypeDefinition type = (XSTypeDefinition)types.item(i);
-         if(!Constants.NS_XML_SCHEMA.equals(type.getNamespace()))
-         {
-            bindType(ctx, type);
-         }
-      }
-
-      XSNamedMap elements = model.getComponents(XSConstants.ELEMENT_DECLARATION);
-      if (ctx.trace)
-         log.trace("Model elements: " + types.getLength());
-      for(int i = 0; i < elements.getLength(); ++i)
-      {
-         XSElementDeclaration element = (XSElementDeclaration)elements.item(i);
-         bindElement(ctx, element, 1, 0, false);
-      }
-
-      schema.setUnresolvedContentBoundToDOM(true);
-
-      if (ctx.trace)
-      {
-         log.trace("finished binding schema " + schema);
-      }
-
-      return schema;
-   }
-
-   private static TypeBinding bindType(Context ctx, XSTypeDefinition type)
-   {
-      TypeBinding binding;
-      switch(type.getTypeCategory())
-      {
-         case XSTypeDefinition.SIMPLE_TYPE:
-            binding = bindSimpleType(ctx, (XSSimpleTypeDefinition)type);
-            break;
-         case XSTypeDefinition.COMPLEX_TYPE:
-            binding = bindComplexType(ctx, (XSComplexTypeDefinition)type);
-            break;
-         default:
-            throw new JBossXBRuntimeException("Unexpected type category: " + type.getTypeCategory());
-      }
-      return binding;
-   }
-
-   private static TypeBinding bindSimpleType(Context ctx, XSSimpleTypeDefinition type)
-   {
-      QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
-      TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
-      if(binding != null)
-      {
-         return binding;
-      }
-
-      if(ctx.trace)
-      {
-         log.trace("binding simple type " + typeName);
-      }
-
-      XSTypeDefinition baseTypeDef = type.getBaseType();
-      TypeBinding baseType = baseTypeDef == null ? null : bindType(ctx, baseTypeDef);
-
-      binding = baseType == null ? new TypeBinding(typeName) : new TypeBinding(typeName, baseType);
-
-      StringList strList = type.getLexicalPattern();
-      if(strList != null && strList.getLength() > 0)
-      {
-         for(int i = 0; i < strList.getLength(); ++i)
-         {
-            binding.addLexicalPattern(strList.item(i));
-         }
-      }
-
-      strList = type.getLexicalEnumeration();
-      if(strList != null && strList.getLength() > 0)
-      {
-         for(int i = 0; i < strList.getLength(); ++i)
-         {
-            binding.addEnumValue(strList.item(i));
-         }
-      }
-
-      if(type.getItemType() != null)
-      {
-         TypeBinding itemType = bindSimpleType(ctx, type.getItemType());
-         binding.setItemType(itemType);
-      }
-
-      if(typeName != null)
-      {
-         ctx.schema.addType(binding);
-      }
-
-      if(ctx.trace)
-      {
-         String msg = typeName == null ? "bound simple anonymous type" : "bound simple type " + typeName;
-         if(baseType != null)
-         {
-            msg += " inherited binding metadata from " + baseType.getQName();
-         }
-         log.trace(msg);
-      }
-
-      // customize binding with annotations
-      if(ctx.processAnnotations)
-      {
-         XSObjectList annotations = type.getAnnotations();
-         if(annotations != null)
-         {
-            if(ctx.trace)
-            {
-               log.trace(typeName + " annotations " + annotations.getLength());
-            }
-            for(int i = 0; i < annotations.getLength(); ++i)
-            {
-               XSAnnotation an = (XSAnnotation)annotations.item(i);
-               XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
-               XsdAppInfo appInfo = xsdAn.getAppInfo();
-               if(appInfo != null)
-               {
-                  ClassMetaData classMetaData = appInfo.getClassMetaData();
-                  if(classMetaData != null)
-                  {
-                     if(ctx.trace)
-                     {
-                        log.trace("simple type " +
-                           type.getName() +
-                           ": impl=" +
-                           classMetaData.getImpl());
-                     }
-                     binding.setClassMetaData(classMetaData);
-                  }
-
-                  ValueMetaData valueMetaData = appInfo.getValueMetaData();
-                  if(valueMetaData != null)
-                  {
-                     if(ctx.trace)
-                     {
-                        log.trace("simple type " +
-                           type.getName() +
-                           ": unmarshalMethod=" +
-                           valueMetaData.getUnmarshalMethod() +
-                           ", marshalMethod=" +
-                           valueMetaData.getMarshalMethod());
-                     }
-                     binding.setValueMetaData(valueMetaData);
-                  }
-               }
-            }
-         }
-      }
-
-      binding.setSchemaBinding(ctx.schema);
-
-      return binding;
-   }
-
-   private static TypeBinding bindComplexType(Context ctx, XSComplexTypeDefinition type)
-   {
-      QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
-      TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
-      if(binding != null)
-      {
-         return binding;
-      }
-
-      XSTypeDefinition baseTypeDef = type.getBaseType();
-      // anyType is the parent of all the types, even the parent of itself according to xerces :)
-      TypeBinding baseType = null;
-      if(baseTypeDef != null && !Constants.QNAME_ANYTYPE.equals(typeName))
-      {
-         baseType = bindType(ctx, baseTypeDef);
-         // sometimes binding the base type can lead to another request
-         // to bind the type being bound here
-         if(typeName != null)
-         {
-            binding = ctx.schema.getType(typeName);
-            if(binding != null)
-            {
-               return binding;
-            }
-         }
-      }
-
-      if (ctx.trace)
-         log.trace("binding complex " + (typeName == null ? "anonymous type" : "type " + typeName));
-
-      binding = new TypeBinding(typeName);
-      binding.setBaseType(baseType);
-      binding.setStartElementCreatesObject(true);
-      binding.setSimple(false);
-
-      if(type.getSimpleType() != null)
-      {
-         TypeBinding simpleType = bindSimpleType(ctx, type.getSimpleType());
-         binding.setSimpleType(simpleType);
-      }
-      else if(type.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED)
-      {
-         TypeBinding stringType = ctx.schema.getType(Constants.QNAME_STRING);
-         if(stringType == null)
-         {
-            throw new JBossXBRuntimeException("xsd:string has not been bound yet!");
-         }
-         binding.setSimpleType(stringType);
-      }
-
-      if(typeName != null)
-      {
-         ctx.schema.addType(binding);
-      }
-
-      binding.setSchemaBinding(ctx.schema);
-
-      XSObjectList attrs = type.getAttributeUses();
-      if (ctx.trace)
-         log.trace(typeName + " attributes " + attrs.getLength());
-      for(int i = 0; i < attrs.getLength(); ++i)
-      {
-         XSAttributeUse attr = (XSAttributeUse)attrs.item(i);
-         bindAttributes(ctx, binding, attr);
-      }
-
-      // customize binding with xsd annotations
-      if (ctx.processAnnotations)
-      {
-         XSObjectList annotations = type.getAnnotations();
-         if(annotations != null)
-         {
-            if (ctx.trace)
-               log.trace(typeName + " annotations " + annotations.getLength());
-            for(int i = 0; i < annotations.getLength(); ++i)
-            {
-               XSAnnotation an = (XSAnnotation)annotations.item(i);
-               XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
-               XsdAppInfo appInfo = xsdAn.getAppInfo();
-               if(appInfo != null)
-               {
-                  ClassMetaData classMetaData = appInfo.getClassMetaData();
-                  if(classMetaData != null)
-                  {
-                     if (ctx.trace)
-                     {
-                        log.trace("complex type " +
-                           type.getName() +
-                           ": impl=" +
-                           classMetaData.getImpl()
-                        );
-                     }
-                     binding.setClassMetaData(classMetaData);
-                  }
-
-                  CharactersMetaData charactersMetaData = appInfo.getCharactersMetaData();
-                  if(charactersMetaData != null)
-                  {
-                     if (ctx.trace)
-                     {
-                        PropertyMetaData propertyMetaData = charactersMetaData.getProperty();
-                        if(propertyMetaData != null)
-                        {
-                           log.trace("complex type " +
-                              type.getName() +
-                              ": characters bound to " + propertyMetaData.getName()
-                           );
-                        }
-
-                        ValueMetaData valueMetaData = charactersMetaData.getValue();
-                        if(valueMetaData != null)
-                        {
-                           log.trace("complex type " +
-                              type.getName() +
-                              ": characters unmarshalMethod=" +
-                              valueMetaData.getUnmarshalMethod() +
-                              ", marshalMethod=" + valueMetaData.getMarshalMethod()
-                           );
-                        }
-
-                        boolean mapEntryKey = appInfo.isMapEntryKey();
-                        if(mapEntryKey)
-                        {
-                           log.trace("complex type " +
-                              type.getName() +
-                              ": characters are bound as a key in a map entry"
-                           );
-                        }
-
-                        boolean mapEntryValue = appInfo.isMapEntryValue();
-                        if(mapEntryValue)
-                        {
-                           log.trace("complex type " +
-                              type.getName() +
-                              ": characters are bound as a value in a map entry"
-                           );
-                        }
-                     }
-                     binding.setCharactersMetaData(charactersMetaData);
-                  }
-
-                  MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
-                  if(mapEntryMetaData != null)
-                  {
-                     if (ctx.trace)
-                     {
-                        log.trace("complex type " +
-                           type.getName() +
-                           " is bound to a map entry: impl=" +
-                           mapEntryMetaData.getImpl() +
-                           ", getKeyMethod=" +
-                           mapEntryMetaData.getGetKeyMethod() +
-                           ", setKeyMethod=" +
-                           mapEntryMetaData.getSetKeyMethod() +
-                           ", getValueMethod=" +
-                           mapEntryMetaData.getGetValueMethod() +
-                           ", setValueMethod=" +
-                           mapEntryMetaData.getSetValueMethod() +
-                           ", valueType=" +
-                           mapEntryMetaData.getValueType() +
-                           ", nonNullValue=" + mapEntryMetaData.isNonNullValue()
-                        );
-                     }
-
-                     if(classMetaData != null)
-                     {
-                        throw new JBossXBRuntimeException("Illegal binding: both jbxb:class and jbxb:mapEntry are specified for complex type " +
-                           type.getName()
-                        );
-                     }
-                     binding.setMapEntryMetaData(mapEntryMetaData);
-                  }
-
-                  boolean skip = appInfo.isSkip();
-                  if(skip)
-                  {
-                     if (ctx.trace)
-                     {
-                        log.trace("complex type " +
-                           type.getName() +
-                           ": elements of this type will be skipped; their attrs, character content " +
-                           "and elements will be set the parent."
-                        );
-                     }
-                     binding.setSkip(skip);
-                  }
-
-                  PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
-                  if(propertyMetaData != null)
-                  {
-                     if (ctx.trace)
-                     {
-                        log.trace("complex type " +
-                           type.getName() +
-                           ": the content of elements of this type is bound to property " + propertyMetaData.getName()
-                        );
-                     }
-                     binding.setPropertyMetaData(propertyMetaData);
-                  }
-
-                  AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
-                  if(addMethodMetaData != null)
-                  {
-                     if (ctx.trace)
-                     {
-                        log.trace("complex type " +
-                           type.getName() +
-                           ": elements of this type will be added to parent objects with addMethod=" +
-                           addMethodMetaData.getMethodName() + ", valueType=" + addMethodMetaData.getValueType()
-                        );
-                     }
-                     binding.setAddMethodMetaData(addMethodMetaData);
-                  }
-               }
-            }
-         }
-      }
-
-      XSParticle particle = type.getParticle();
-      if(particle != null)
-      {
-         ctx.pushType(binding);
-         bindParticle(ctx, particle);
-         ctx.popType();
-      }
-
-      if(binding.hasOnlyXmlMimeAttributes())
-      {
-         addXOPInclude(binding, ctx.schema);
-      }
-
-      if(ctx.trace)
-      {
-         log.trace(typeName == null ? "bound complex anonymous type" : "bound complex type " + typeName);
-      }
-
-      return binding;
-   }
-
-   private static void bindAttributes(Context ctx, TypeBinding type, XSAttributeUse attrUse)
-   {
-      XSAttributeDeclaration attr = attrUse.getAttrDeclaration();
-      QName attrName = new QName(attr.getNamespace(), attr.getName());
-
-      if (ctx.trace)
-      {
-         log.trace("binding attribute " + attrName + " for " + type.getQName() + ", required=" + attrUse.getRequired());
-      }
-
-      XSSimpleTypeDefinition attrType = attr.getTypeDefinition();
-      TypeBinding typeBinding = bindSimpleType(ctx, attrType);
-      AttributeBinding binding = type.addAttribute(attrName, typeBinding, DefaultHandlers.ATTRIBUTE_HANDLER);
-      binding.setRequired(attrUse.getRequired());
-      if(attrUse.getConstraintType() == XSConstants.VC_DEFAULT)
-      {
-         // Associate the default value with the binding
-         binding.setDefaultConstraint(attrUse.getConstraintValue());
-      }
-
-      if (ctx.processAnnotations)
-      {
-         XSAnnotation an = attr.getAnnotation();
-         if(an != null)
-         {
-            if (ctx.trace)
-            {
-               log.trace(attrName + " attribute annotation");
-            }
-
-            XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
-            XsdAppInfo appInfo = xsdAn.getAppInfo();
-            if(appInfo != null)
-            {
-               PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
-               if(propertyMetaData != null)
-               {
-                  binding.setPropertyMetaData(propertyMetaData);
-               }
-
-               boolean mapEntryKey = appInfo.isMapEntryKey();
-               if(mapEntryKey)
-               {
-                  binding.setMapEntryKey(mapEntryKey);
-               }
-
-               boolean mapEntryValue = appInfo.isMapEntryValue();
-               if(mapEntryValue)
-               {
-                  binding.setMapEntryValue(mapEntryValue);
-               }
-            }
-         }
-      }
-
-
-      if (ctx.trace)
-      {
-         String msg = "bound attribute " + attrName;
-
-         if(binding.getPropertyMetaData() != null)
-         {
-            msg += " property=" +
-               binding.getPropertyMetaData().getName() +
-               ", collectionType=" + binding.getPropertyMetaData().getCollectionType();
-         }
-         else if(binding.isMapEntryKey())
-         {
-            msg += "bound as a key in a map entry";
-         }
-         else if(binding.isMapEntryValue())
-         {
-            msg += "bound as a value in a map entry";
-         }
-         else
-         {
-            msg += " type=" + attrType.getName() + ", owner type=" + type.getQName();
-         }
-
-         if(binding.getDefaultConstraint() != null)
-         {
-            msg += ", default=" + binding.getDefaultConstraint();
-         }
-
-         log.trace(msg);
-      }
-   }
-
-   private static void bindParticle(Context ctx, XSParticle particle)
-   {
-      XSTerm term = particle.getTerm();
-      switch(term.getType())
-      {
-         case XSConstants.MODEL_GROUP:
-            XSModelGroup modelGroup = (XSModelGroup)term;
-            // todo: investigate this
-            if(modelGroup.getParticles().getLength() > 0)
-            {
-               ModelGroupBinding groupBinding;
-               switch(modelGroup.getCompositor())
-               {
-                  case XSModelGroup.COMPOSITOR_ALL:
-                     groupBinding = new AllBinding(ctx.schema);
-                     break;
-                  case XSModelGroup.COMPOSITOR_CHOICE:
-                     groupBinding = new ChoiceBinding(ctx.schema);
-                     break;
-                  case XSModelGroup.COMPOSITOR_SEQUENCE:
-                     groupBinding = new SequenceBinding(ctx.schema);
-                     break;
-                  default:
-                     throw new JBossXBRuntimeException("Unexpected model group: " + modelGroup.getCompositor());
-               }
-
-               ParticleBinding particleBinding = new ParticleBinding(groupBinding);
-               particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
-               particleBinding.setMinOccurs(particle.getMinOccurs());
-               particleBinding.setMaxOccurs(particle.getMaxOccurs());
-
-               if (ctx.trace)
-               {
-                  log.trace("created model group " + groupBinding);
-               }
-
-               if (ctx.processAnnotations)
-               {
-                  XSAnnotation annotation = modelGroup.getAnnotation();
-                  if(annotation != null)
-                  {
-                     customizeTerm(annotation, groupBinding, ctx.trace);
-                  }
-               }
-
-               Object o = ctx.peekTypeOrGroup();
-               if(o instanceof ModelGroupBinding)
-               {
-                  ModelGroupBinding parentGroup = (ModelGroupBinding)o;
-                  parentGroup.addParticle(particleBinding);
-                  if (ctx.trace)
-                  {
-                     log.trace("added " + groupBinding + " to " + parentGroup);
-                  }
-               }
-               else if(o instanceof TypeBinding)
-               {
-                  TypeBinding typeBinding = (TypeBinding)o;
-                  typeBinding.setParticle(particleBinding);
-                  if (ctx.trace)
-                  {
-                     log.trace("added " + groupBinding + " to type " + typeBinding.getQName());
-                  }
-               }
-
-               ctx.pushModelGroup(groupBinding);
-               bindModelGroup(ctx, modelGroup);
-               ctx.popModelGroup();
-            }
-            break;
-         case XSConstants.WILDCARD:
-            bindWildcard(ctx, particle);
-            break;
-         case XSConstants.ELEMENT_DECLARATION:
-            bindElement(ctx,
-               (XSElementDeclaration)term,
-               particle.getMinOccurs(),
-               particle.getMaxOccurs(),
-               particle.getMaxOccursUnbounded()
-            );
-            break;
-         default:
-            throw new IllegalStateException("Unexpected term type: " + term.getType());
-      }
-   }
-
-   private static void bindWildcard(Context ctx, XSParticle particle)
-   {
-      WildcardBinding binding = new WildcardBinding(ctx.schema);
-
-      ModelGroupBinding group = (ModelGroupBinding)ctx.peekTypeOrGroup();
-      ParticleBinding particleBinding = new ParticleBinding(binding);
-      particleBinding.setMaxOccurs(particle.getMaxOccurs());
-      particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
-      particleBinding.setMinOccurs(particle.getMinOccurs());
-      group.addParticle(particleBinding);
-
-      XSWildcard wildcard = (XSWildcard)particle.getTerm();
-      if(wildcard.getName() != null)
-      {
-         binding.setQName(new QName(wildcard.getNamespace(), wildcard.getName()));
-      }
-
-      binding.setProcessContents(wildcard.getProcessContents());
-
-      if (ctx.processAnnotations)
-      {
-         XSAnnotation annotation = wildcard.getAnnotation();
-         if(annotation != null)
-         {
-            customizeTerm(annotation, binding, ctx.trace);
-         }
-      }
-   }
-
-   private static ParticleBinding bindElement(Context ctx,
-                                              XSElementDeclaration elementDec,
-                                              int minOccurs,
-                                              int maxOccurs,
-                                              boolean maxOccursUnbounded)
-   {
-      QName qName = new QName(elementDec.getNamespace(), elementDec.getName());
-
-      ModelGroupBinding parentGroup = (ModelGroupBinding)ctx.peekTypeOrGroup();
-
-      boolean global = elementDec.getScope() == XSConstants.SCOPE_GLOBAL;
-      ElementBinding element = ctx.schema.getElement(qName);
-      ParticleBinding particle;
-      if(global && element != null)
-      {
-         particle = new ParticleBinding(element);
-         if(parentGroup != null)
-         {
-            parentGroup.addParticle(particle);
-         }
-
-         particle.setMinOccurs(minOccurs);
-         if(maxOccursUnbounded)
-         {
-            particle.setMaxOccursUnbounded(maxOccursUnbounded);
-         }
-         else
-         {
-            particle.setMaxOccurs(maxOccurs);
-         }
-
-         return particle;
-      }
-
-      TypeBinding type = null;
-
-      boolean shared = ctx.sharedElements.isShared(elementDec);
-      if(shared)
-      {
-         type = ctx.sharedElements.getTypeBinding(elementDec);
-      }
-
-      if(type == null)
-      {
-         type = bindType(ctx, elementDec.getTypeDefinition());
-         if(shared)
-         {
-            ctx.sharedElements.setTypeBinding(elementDec, type);
-         }
-      }
-
-      element = new ElementBinding(ctx.schema, qName, type);
-      element.setNillable(elementDec.getNillable());
-      particle = new ParticleBinding(element);
-      particle.setMinOccurs(minOccurs);
-      particle.setMaxOccurs(maxOccurs);
-      particle.setMaxOccursUnbounded(maxOccursUnbounded);
-      if(global)
-      {
-         ctx.schema.addElementParticle(particle);
-      }
-
-      if(parentGroup != null)
-      {
-         parentGroup.addParticle(particle);
-         if (ctx.trace)
-         {
-            log.trace("Element " + element.getQName() + " added to " + parentGroup);
-         }
-      }
-
-      if (ctx.trace)
-      {
-         TypeBinding parentType = ctx.peekType();
-         log.trace("element: name=" +
-            qName +
-            ", type=" +
-            type.getQName() +
-            ", repeatable=" +
-            particle.isRepeatable() +
-            ", nillable=" +
-            element.isNillable() +
-            ", minOccurs=" + minOccurs +
-            ", maxOccurs=" + (maxOccursUnbounded ? "unbounded" : "" + maxOccurs) +
-            ", " + (global ? "global scope" : " owner type=" + parentType.getQName())
-         );
-      }
-
-      // customize element with annotations
-      if (ctx.processAnnotations)
-      {
-         XSAnnotation an = elementDec.getAnnotation();
-         if(an != null)
-         {
-            customizeTerm(an, element, ctx.trace);
-         }
-      }
-      return particle;
-   }
-
-   private static void bindModelGroup(Context ctx, XSModelGroup modelGroup)
-   {
-      XSObjectList particles = modelGroup.getParticles();
-      for(int i = 0; i < particles.getLength(); ++i)
-      {
-         XSParticle particle = (XSParticle)particles.item(i);
-         bindParticle(ctx, particle);
-      }
-   }
-
-   // Private
-
-   private static void addXOPInclude(TypeBinding binding, SchemaBinding schema)
-   {
-      binding.setHandler(DefaultHandlers.XOP_HANDLER);
-      if(binding.getParticle() != null)
-      {
-         throw new JBossXBRuntimeException(
-            "XOP optimizable type has a particle which is unexpected, please, open a JIRA issue!"
-         );
-      }
-
-      TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
-      if(anyUriType == null)
-      {
-         log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
-      }
-
-      TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
-      xopIncludeType.setSchemaBinding(schema);
-      xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
-      xopIncludeType.setHandler(new XOPIncludeHandler(binding));
-
-      ElementBinding xopInclude = new ElementBinding(schema, new QName(Constants.NS_XOP_INCLUDE, "Include"), xopIncludeType);
-
-      ParticleBinding particleBinding = new ParticleBinding(xopInclude);
-      particleBinding.setMinOccurs(0);
-
-      binding.addParticle(particleBinding);
-   }
-
-   private static void customizeTerm(XSAnnotation an, TermBinding term, boolean trace)
-   {
-      XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
-      XsdAppInfo appInfo = xsdAn.getAppInfo();
-      if(appInfo != null)
-      {
-         Boolean skip = null;
-
-         ClassMetaData classMetaData = appInfo.getClassMetaData();
-         if(classMetaData != null)
-         {
-            if (trace)
-            {
-               String msg;
-               if(term.isModelGroup())
-               {
-                  msg = term + " bound to ";
-               }
-               else if(term.isWildcard())
-               {
-                  msg = " wildcard bound to ";
-               }
-               else
-               {
-                  msg = "element: name=" + ((ElementBinding)term).getQName() + ", class=";
-               }
-
-               msg += classMetaData.getImpl();
-               log.trace(msg);
-            }
-            term.setClassMetaData(classMetaData);
-            skip = Boolean.FALSE;
-         }
-
-         PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
-         if(propertyMetaData != null)
-         {
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term + " " : "element: name=" +
-                  ((ElementBinding)term).getQName() + ", ";
-               msg += " property=" +
-                  propertyMetaData.getName() +
-                  ", collectionType=" + propertyMetaData.getCollectionType();
-               log.trace(msg);
-            }
-            term.setPropertyMetaData(propertyMetaData);
-         }
-
-         MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
-         if(mapEntryMetaData != null)
-         {
-            if(propertyMetaData != null)
-            {
-               String msg = "A term can be bound either as a property or as a map" +
-                  " entry but not both: " +
-                  (term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
-               throw new JBossXBRuntimeException(msg);
-            }
-
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
-                  ((ElementBinding)term).getQName();
-
-               msg += " is bound to a map entry: impl=" +
-                  mapEntryMetaData.getImpl() +
-                  ", getKeyMethod=" +
-                  mapEntryMetaData.getGetKeyMethod() +
-                  ", setKeyMethod=" +
-                  mapEntryMetaData.getSetKeyMethod() +
-                  ", getValueMethod=" +
-                  mapEntryMetaData.getGetValueMethod() +
-                  ", setValueMethod=" +
-                  mapEntryMetaData.getSetValueMethod() +
-                  ", valueType=" +
-                  mapEntryMetaData.getValueType() +
-                  ", nonNullValue=" + mapEntryMetaData.isNonNullValue();
-               log.trace(msg);
-            }
-
-            if(classMetaData != null)
-            {
-               String msg = "Invalid customization: both jbxb:class and jbxb:mapEntry are specified for term " +
-                  (term.isWildcard() || term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
-               throw new JBossXBRuntimeException(msg);
-            }
-            term.setMapEntryMetaData(mapEntryMetaData);
-            skip = Boolean.FALSE;
-         }
-
-         PutMethodMetaData putMethodMetaData = appInfo.getPutMethodMetaData();
-         if(putMethodMetaData != null)
-         {
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
-                  ((ElementBinding)term).getQName() + ",";
-
-               msg += " putMethod=" +
-                  putMethodMetaData.getName() +
-                  ", keyType=" +
-                  putMethodMetaData.getKeyType() +
-                  ", valueType=" + putMethodMetaData.getValueType();
-               log.trace(msg);
-            }
-            term.setPutMethodMetaData(putMethodMetaData);
-         }
-
-         AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
-         if(addMethodMetaData != null)
-         {
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
-                  ((ElementBinding)term).getQName() + ",";
-               msg += " addMethod=" +
-                  addMethodMetaData.getMethodName() +
-                  ", valueType=" +
-                  addMethodMetaData.getValueType() +
-                  ", isChildType=" + addMethodMetaData.isChildType();
-               log.trace(msg);
-            }
-            term.setAddMethodMetaData(addMethodMetaData);
-         }
-
-         ValueMetaData valueMetaData = appInfo.getValueMetaData();
-         if(valueMetaData != null)
-         {
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element " +
-                  ((ElementBinding)term).getQName();
-               msg += ": unmarshalMethod=" + valueMetaData.getUnmarshalMethod();
-               log.trace(msg);
-            }
-            term.setValueMetaData(valueMetaData);
-         }
-
-         boolean mapEntryKey = appInfo.isMapEntryKey();
-         if(mapEntryKey)
-         {
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
-                  ((ElementBinding)term).getQName();
-               msg += ": is bound to a key in a map entry";
-               log.trace(msg);
-            }
-            term.setMapEntryKey(mapEntryKey);
-            skip = Boolean.FALSE;
-         }
-
-         boolean mapEntryValue = appInfo.isMapEntryValue();
-         if(mapEntryValue)
-         {
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
-                  ((ElementBinding)term).getQName();
-               msg += ": is bound to a value in a map entry";
-               log.trace(msg);
-            }
-            term.setMapEntryValue(mapEntryValue);
-            skip = Boolean.FALSE;
-         }
-
-         boolean skipAnnotation = appInfo.isSkip();
-         if(skip != null)
-         {
-            term.setSkip(skip);
-         }
-         else if(skipAnnotation)
-         {
-            if (trace)
-            {
-               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
-                  ((ElementBinding)term).getQName();
-               msg += ": will be skipped, it's attributes, character content and children will be set on the parent";
-               log.trace(msg);
-            }
-            term.setSkip(skipAnnotation ? Boolean.TRUE : Boolean.FALSE);
-         }
-      }
-   }
-
-   private static void bindGlobalGroup(XSModelGroup group, SharedElements sharedElements)
-   {
-      XSObjectList particles = group.getParticles();
-      for(int j = 0; j < particles.getLength(); ++j)
-      {
-         XSParticle particle = (XSParticle)particles.item(j);
-         XSTerm term = particle.getTerm();
-         switch(term.getType())
-         {
-            case XSConstants.ELEMENT_DECLARATION:
-               XSElementDeclaration element = ((XSElementDeclaration)term);
-               sharedElements.add(element);
-               break;
-            case XSConstants.WILDCARD:
-               // todo is it actually possible?
-               break;
-            case XSConstants.MODEL_GROUP:
-               bindGlobalGroup((XSModelGroup)term, sharedElements);
-         }
-      }
-   }
-
-
-   // Inner
-
-   private static final class SharedElements
-   {
-      private Map elements = Collections.EMPTY_MAP;
-
-      public void add(XSElementDeclaration element)
-      {
-         switch(elements.size())
-         {
-            case 0:
-               elements = Collections.singletonMap(element, null);
-               break;
-            case 1:
-               elements = new HashMap(elements);
-            default:
-               elements.put(element, null);
-         }
-      }
-
-      public boolean isShared(XSElementDeclaration element)
-      {
-         return elements.containsKey(element);
-      }
-
-      public TypeBinding getTypeBinding(XSElementDeclaration element)
-      {
-         return (TypeBinding)elements.get(element);
-      }
-
-      public void setTypeBinding(XSElementDeclaration element, TypeBinding type)
-      {
-         switch(elements.size())
-         {
-            case 0:
-               elements = Collections.singletonMap(element, type);
-               break;
-            case 1:
-               elements = new HashMap(elements);
-            default:
-               elements.put(element, type);
-         }
-      }
-   }
-
-   private static final class Context
-   {
-      public final SchemaBinding schema;
-      public SharedElements sharedElements = new SharedElements();
-      public boolean processAnnotations = true;
-      public boolean trace = log.isTraceEnabled();
-      private final List typeGroupStack = new ArrayList();
-
-      public Context()
-      {
-         this(new SchemaBinding());
-      }
-
-      public Context(SchemaBinding schema)
-      {
-         this.schema = schema;
-      }
-
-      public void popType()
-      {
-         Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
-         if(!(o instanceof TypeBinding))
-         {
-            throw new JBossXBRuntimeException("Should have poped type binding but got " + o);
-         }
-      }
-
-      public void pushType(TypeBinding binding)
-      {
-         typeGroupStack.add(binding);
-      }
-
-      public void popModelGroup()
-      {
-         Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
-         if(!(o instanceof ModelGroupBinding))
-   {
-            throw new JBossXBRuntimeException("Should have poped model group binding but got " + o);
-         }
-      }
-
-      public void pushModelGroup(ModelGroupBinding binding)
-      {
-         typeGroupStack.add(binding);
-      }
-
-      public Object peekTypeOrGroup()
-      {
-         return typeGroupStack.isEmpty() ? null : typeGroupStack.get(typeGroupStack.size() - 1);
-      }
-
-      public TypeBinding peekType()
-      {
-         TypeBinding binding = null;
-         for(ListIterator i = typeGroupStack.listIterator(typeGroupStack.size()); i.hasPrevious();)
-         {
-            Object o = i.previous();
-            if(o instanceof TypeBinding)
-            {
-               binding = (TypeBinding)o;
-               break;
-            }
-         }
-         return binding;
-      }
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,1542 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.sunday.unmarshalling;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.ListIterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xerces.xs.StringList;
+import org.apache.xerces.xs.XSAnnotation;
+import org.apache.xerces.xs.XSAttributeDeclaration;
+import org.apache.xerces.xs.XSAttributeUse;
+import org.apache.xerces.xs.XSComplexTypeDefinition;
+import org.apache.xerces.xs.XSConstants;
+import org.apache.xerces.xs.XSElementDeclaration;
+import org.apache.xerces.xs.XSModel;
+import org.apache.xerces.xs.XSModelGroup;
+import org.apache.xerces.xs.XSModelGroupDefinition;
+import org.apache.xerces.xs.XSNamedMap;
+import org.apache.xerces.xs.XSObjectList;
+import org.apache.xerces.xs.XSParticle;
+import org.apache.xerces.xs.XSSimpleTypeDefinition;
+import org.apache.xerces.xs.XSTerm;
+import org.apache.xerces.xs.XSTypeDefinition;
+import org.apache.xerces.xs.XSWildcard;
+import org.jboss.logging.Logger;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.Util;
+import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
+import org.jboss.xb.binding.metadata.AddMethodMetaData;
+import org.jboss.xb.binding.metadata.CharactersMetaData;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.metadata.MapEntryMetaData;
+import org.jboss.xb.binding.metadata.PackageMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.PutMethodMetaData;
+import org.jboss.xb.binding.metadata.SchemaMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.metadata.XsdAnnotation;
+import org.jboss.xb.binding.metadata.XsdAppInfo;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class XsdBinder
+{
+   static final Logger log = Logger.getLogger(XsdBinder.class);
+
+   /**
+    * Creates a new instance of the binder the user can use to tune
+    * configuration before parsing the XSD.
+    * 
+    * @return  a new instance of the XsdBinder
+    */
+   public static XsdBinder newInstance()
+   {
+     return new XsdBinder();
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd url/uri.
+    *
+    * @param xsdUrl
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(String xsdUrl)
+   {
+      DefaultSchemaResolver resolver = new DefaultSchemaResolver();
+      resolver.setBaseURI(xsdUrl);
+      return bind(xsdUrl, resolver);
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd url/uri.
+    *
+    * @param xsdUrl
+    * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
+    *                 and also will be set on the returned instance of SchemaBinding
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(String xsdUrl, SchemaBindingResolver resolver)
+   {
+      XSModel model = Util.loadSchema(xsdUrl, resolver);
+      return bind(model, resolver);
+   }
+
+   public static SchemaBinding bind(InputStream xsdStream, String encoding)
+   {
+      return bind(xsdStream, encoding, new DefaultSchemaResolver());
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd stream.
+    *
+    * @param xsdStream - the xsd InputStream
+    * @param encoding  - optional stream encoding
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI)
+   {
+      return bind(xsdStream, encoding, baseURI, true);
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd stream.
+    *
+    * @param xsdStream - the xsd InputStream
+    * @param encoding  - optional stream encoding
+    * @param processAnnotations - process annotations
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI, boolean processAnnotations)
+   {
+      DefaultSchemaResolver resolver = new DefaultSchemaResolver();
+      resolver.setBaseURI(baseURI);
+      return bind(xsdStream, encoding, resolver, processAnnotations);
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd stream.
+    *
+    * @param xsdStream - the xsd InputStream
+    * @param encoding  - optional stream encoding
+    * @param resolver  the resolver will be used to resolve imported schemas in the schema being loaded
+    *                  and also will be set on the returned instance of SchemaBinding
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver)
+   {
+      return bind(xsdStream, encoding, resolver, true);
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd stream.
+    *
+    * @param xsdStream - the xsd InputStream
+    * @param encoding  - optional stream encoding
+    * @param resolver  the resolver will be used to resolve imported schemas in the schema being loaded
+    *                  and also will be set on the returned instance of SchemaBinding
+    * @param processAnnotations whether to process annotations
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver, boolean processAnnotations)
+   {
+      XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
+      return bind(model, resolver, processAnnotations);
+   }
+
+   public static SchemaBinding bind(Reader xsdReader, String encoding)
+   {
+      return bind(xsdReader, encoding, new DefaultSchemaResolver());
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd reader.
+    *
+    * @param xsdReader - xsd reader
+    * @param encoding  - optional reader encoding
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(Reader xsdReader, String encoding, String baseURI)
+   {
+      DefaultSchemaResolver resolver = new DefaultSchemaResolver();
+      resolver.setBaseURI(baseURI);
+      return bind(xsdReader, encoding, resolver);
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd reader.
+    *
+    * @param xsdReader - xsd reader
+    * @param encoding  - optional reader encoding
+    * @param resolver  the resolver will be used to resolve imported schemas in the schema being loaded
+    *                  and also will be set on the returned instance of SchemaBinding
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(Reader xsdReader, String encoding, SchemaBindingResolver resolver)
+   {
+      XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
+      return bind(model, resolver);
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd string.
+    *
+    * @param xsd      - xsd string
+    * @param encoding - optional string encoding
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(String xsd, String encoding)
+   {
+      return bind(xsd, encoding, new DefaultSchemaResolver());
+   }
+
+   /**
+    * Create a SchemaBinding from and xsd string.
+    *
+    * @param xsd      - xsd string
+    * @param encoding - optional string encoding
+    * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
+    *                 and also will be set on the returned instance of SchemaBinding
+    * @return SchemaBinding mapping
+    */
+   public static SchemaBinding bind(String xsd, String encoding, SchemaBindingResolver resolver)
+   {
+      XSModel model = Util.loadSchema(xsd, encoding);
+      return bind(model, resolver);
+   }
+
+   public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver)
+   {
+      return bind(model,resolver, true);
+   }
+
+   public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver, boolean processAnnotations)
+   {
+      XsdBinder binder = new XsdBinder();
+      binder.setProcessAnnotations(processAnnotations);
+      binder.setSchemaResolver(resolver);
+      return binder.parse(model);
+   }
+
+   /**
+    * @param schema schema binding the type should be added to
+    * @param type   type definition to be bound
+    * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
+    *             It will be removed when anonymous type binding in JBossWS is implemented properly.
+    *             No one else should use this method.</i>
+    *
+    *             <p>This method binds a type definition and adds it as a global type to the passed in schema binding.
+    */
+   public static void bindType(SchemaBinding schema, XSTypeDefinition type)
+   {
+      TypeBinding typeBinding = bindType(new Context(schema), type);
+      schema.addType(typeBinding);
+   }
+
+   /**
+    * @param schema             schema binding the type should be added to
+    * @param element            element declaration to be bound
+    * @param minOccurs
+    * @param maxOccurs
+    * @param maxOccursUnbounded
+    * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
+    *             It will be removed when anonymous type binding in JBossWS is implemented properly.
+    *             No one else should use this method.</i>
+    *
+    *             <p>This method binds an element declaration and adds it as a global element to the passed in schema binding.
+    */
+   public static void bindElement(SchemaBinding schema,
+                                  XSElementDeclaration element,
+                                  int minOccurs,
+                                  int maxOccurs,
+                                  boolean maxOccursUnbounded)
+   {
+      ParticleBinding particle = bindElement(new Context(schema),
+         element,
+         minOccurs,
+         maxOccurs,
+         maxOccursUnbounded
+      );
+      schema.addElementParticle(particle);
+   }
+
+   // Exposed attributes
+   
+   private boolean processAnnotations = true;
+   private SchemaBindingResolver resolver;
+   private boolean simpleContentWithIdAsSimpleType = true;
+   private boolean unresolvedContentBoundToDOM = true;
+   
+   // Internal attributes
+   
+   private boolean trace = log.isTraceEnabled();
+   private final SchemaBinding schema;
+   private SharedElements sharedElements = new SharedElements();
+   private final List typeGroupStack = new ArrayList();
+
+   // Ctors
+   
+   private XsdBinder()
+   {
+      this(new SchemaBinding());
+   }
+
+   private XsdBinder(SchemaBinding schema)
+   {
+      this.schema = schema;
+   }
+
+   // Public
+   
+   public void setProcessAnnotations(boolean processAnnotations)
+   {
+      this.processAnnotations = processAnnotations;
+   }
+
+   public boolean isProcessAnnotations()
+   {
+      return processAnnotations;
+   }
+
+   public void setSchemaResolver(SchemaBindingResolver resolver)
+   {
+      this.resolver = resolver;
+   }
+
+   public SchemaBindingResolver getSchemaResolver()
+   {
+      return resolver;
+   }
+
+   public void setSimpleContentWithIdAsSimpleType(boolean simpleContentWithIdAsSimpleType)
+   {
+      this.simpleContentWithIdAsSimpleType = simpleContentWithIdAsSimpleType;
+   }
+
+   public boolean isSimpleContentWithIdAsSimpleType()
+   {
+      return simpleContentWithIdAsSimpleType;
+   }
+
+   public void setUnresolvedContentBoundToDOM(boolean toDOM)
+   {
+      this.unresolvedContentBoundToDOM = toDOM;      
+   }
+   
+   public boolean isUnresolvedContentBoundToDOM()
+   {
+      return this.unresolvedContentBoundToDOM;
+   }
+   
+   public SchemaBinding parse(String xsdUrl)
+   {
+      if(resolver == null)
+      {
+         resolver = new DefaultSchemaResolver();
+      }
+
+      XSModel model = Util.loadSchema(xsdUrl, resolver);
+      return parse(model);
+   }
+   
+   public SchemaBinding parse(InputStream xsdStream, String encoding)
+   {
+      if(resolver == null)
+      {
+         resolver = new DefaultSchemaResolver();
+      }
+
+      XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
+      return parse(model);
+   }
+   
+   public SchemaBinding parse(Reader xsdReader, String encoding)
+   {
+      if(resolver == null)
+      {
+         resolver = new DefaultSchemaResolver();
+      }
+  
+      XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
+      return parse(model);
+   }
+
+
+   // Private
+
+   public SchemaBinding parse(XSModel model)
+   {
+      Context ctx = new Context();
+      ctx.processAnnotations = processAnnotations;
+      ctx.simpleContentWithIdAsSimpleType = simpleContentWithIdAsSimpleType;
+      SchemaBinding schema = ctx.schema;
+      schema.setSchemaResolver(resolver);
+
+      // read annotations. for now just log the ones that are going to be used
+      if (ctx.processAnnotations)
+      {
+         XSObjectList annotations = model.getAnnotations();
+         if (ctx.trace)
+         {
+            log.trace("started binding schema " + schema);
+            log.trace("Schema annotations: " + annotations.getLength());
+         }
+
+         for(int i = 0; i < annotations.getLength(); ++i)
+         {
+            XSAnnotation annotation = (XSAnnotation)annotations.item(i);
+            XsdAnnotation an = XsdAnnotation.unmarshal(annotation.getAnnotationString());
+            XsdAppInfo appinfo = an.getAppInfo();
+            if(appinfo != null)
+            {
+               SchemaMetaData schemaBindings = appinfo.getSchemaMetaData();
+               if(schemaBindings != null)
+               {
+                  // Get the ignoreUnresolvedFieldOrClass
+                  schema.setIgnoreUnresolvedFieldOrClass(schemaBindings.isIgnoreUnresolvedFieldOrClass());
+                  // Get the ignoreUnresolvedFieldOrClass
+                  schema.setReplacePropertyRefs(schemaBindings.isReplacePropertyRefs());
+                  // Get the default package
+                  PackageMetaData packageMetaData = schemaBindings.getPackage();
+                  if(packageMetaData != null)
+                  {
+                     if (ctx.trace)
+                        log.trace("schema default package: " + packageMetaData.getName());
+                     schema.setPackageMetaData(packageMetaData);
+                  }
+               }
+            }
+         }
+      }
+
+      StringList namespaceList = model.getNamespaces();
+      Set namespaces = new LinkedHashSet(namespaceList.getLength());
+      for (int i = 0; i < namespaceList.getLength(); ++i)
+         namespaces.add(namespaceList.item(i));
+      schema.setNamespaces(namespaces);
+      
+      XSNamedMap groups = model.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
+      if (ctx.trace)
+         log.trace("Model groups: " + groups.getLength());
+      for(int i = 0; i < groups.getLength(); ++i)
+      {
+         XSModelGroupDefinition groupDef = (XSModelGroupDefinition)groups.item(i);
+         bindGlobalGroup(groupDef.getModelGroup(), ctx.sharedElements);
+      }
+
+      XSNamedMap types = model.getComponents(XSConstants.TYPE_DEFINITION);
+      if (ctx.trace)
+         log.trace("Model types: " + types.getLength());
+      for(int i = 0; i < types.getLength(); ++i)
+      {
+         XSTypeDefinition type = (XSTypeDefinition)types.item(i);
+         if(!Constants.NS_XML_SCHEMA.equals(type.getNamespace()))
+         {
+            bindType(ctx, type);
+         }
+      }
+
+      XSNamedMap elements = model.getComponents(XSConstants.ELEMENT_DECLARATION);
+      if (ctx.trace)
+         log.trace("Model elements: " + types.getLength());
+      for(int i = 0; i < elements.getLength(); ++i)
+      {
+         XSElementDeclaration element = (XSElementDeclaration)elements.item(i);
+         bindElement(ctx, element, 1, 0, false);
+      }
+
+      schema.setUnresolvedContentBoundToDOM(true);
+
+      if (ctx.trace)
+      {
+         log.trace("finished binding schema " + schema);
+      }
+
+      return schema;
+   }
+
+   private static TypeBinding bindType(Context ctx, XSTypeDefinition type)
+   {
+      TypeBinding binding;
+      switch(type.getTypeCategory())
+      {
+         case XSTypeDefinition.SIMPLE_TYPE:
+            binding = bindSimpleType(ctx, (XSSimpleTypeDefinition)type);
+            break;
+         case XSTypeDefinition.COMPLEX_TYPE:
+            binding = bindComplexType(ctx, (XSComplexTypeDefinition)type);
+            break;
+         default:
+            throw new JBossXBRuntimeException("Unexpected type category: " + type.getTypeCategory());
+      }
+      return binding;
+   }
+
+   private static TypeBinding bindSimpleType(Context ctx, XSSimpleTypeDefinition type)
+   {
+      QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
+      TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
+      if(binding != null)
+      {
+         return binding;
+      }
+
+      if(ctx.trace)
+      {
+         log.trace("binding simple type " + typeName);
+      }
+
+      XSTypeDefinition baseTypeDef = type.getBaseType();
+      TypeBinding baseType = baseTypeDef == null ? null : bindType(ctx, baseTypeDef);
+
+      binding = baseType == null ? new TypeBinding(typeName) : new TypeBinding(typeName, baseType);
+
+      StringList strList = type.getLexicalPattern();
+      if(strList != null && strList.getLength() > 0)
+      {
+         for(int i = 0; i < strList.getLength(); ++i)
+         {
+            binding.addLexicalPattern(strList.item(i));
+         }
+      }
+
+      strList = type.getLexicalEnumeration();
+      if(strList != null && strList.getLength() > 0)
+      {
+         for(int i = 0; i < strList.getLength(); ++i)
+         {
+            binding.addEnumValue(strList.item(i));
+         }
+      }
+
+      if(type.getItemType() != null)
+      {
+         TypeBinding itemType = bindSimpleType(ctx, type.getItemType());
+         binding.setItemType(itemType);
+      }
+
+      if(typeName != null)
+      {
+         ctx.schema.addType(binding);
+      }
+
+      if(ctx.trace)
+      {
+         String msg = typeName == null ? "bound simple anonymous type" : "bound simple type " + typeName;
+         if(baseType != null)
+         {
+            msg += " inherited binding metadata from " + baseType.getQName();
+         }
+         log.trace(msg);
+      }
+
+      // customize binding with annotations
+      if(ctx.processAnnotations)
+      {
+         XSObjectList annotations = type.getAnnotations();
+         if(annotations != null)
+         {
+            if(ctx.trace)
+            {
+               log.trace(typeName + " annotations " + annotations.getLength());
+            }
+            for(int i = 0; i < annotations.getLength(); ++i)
+            {
+               XSAnnotation an = (XSAnnotation)annotations.item(i);
+               XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+               XsdAppInfo appInfo = xsdAn.getAppInfo();
+               if(appInfo != null)
+               {
+                  ClassMetaData classMetaData = appInfo.getClassMetaData();
+                  if(classMetaData != null)
+                  {
+                     if(ctx.trace)
+                     {
+                        log.trace("simple type " +
+                           type.getName() +
+                           ": impl=" +
+                           classMetaData.getImpl());
+                     }
+                     binding.setClassMetaData(classMetaData);
+                  }
+
+                  ValueMetaData valueMetaData = appInfo.getValueMetaData();
+                  if(valueMetaData != null)
+                  {
+                     if(ctx.trace)
+                     {
+                        log.trace("simple type " +
+                           type.getName() +
+                           ": unmarshalMethod=" +
+                           valueMetaData.getUnmarshalMethod() +
+                           ", marshalMethod=" +
+                           valueMetaData.getMarshalMethod());
+                     }
+                     binding.setValueMetaData(valueMetaData);
+                  }
+               }
+            }
+         }
+      }
+
+      binding.setSchemaBinding(ctx.schema);
+
+      return binding;
+   }
+
+   private static TypeBinding bindComplexType(Context ctx, XSComplexTypeDefinition type)
+   {
+      QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
+      TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
+      if(binding != null)
+      {
+         return binding;
+      }
+
+      XSTypeDefinition baseTypeDef = type.getBaseType();
+      // anyType is the parent of all the types, even the parent of itself according to xerces :)
+      TypeBinding baseType = null;
+      if(baseTypeDef != null && !Constants.QNAME_ANYTYPE.equals(typeName))
+      {
+         baseType = bindType(ctx, baseTypeDef);
+         // sometimes binding the base type can lead to another request
+         // to bind the type being bound here
+         if(typeName != null)
+         {
+            binding = ctx.schema.getType(typeName);
+            if(binding != null)
+            {
+               return binding;
+            }
+         }
+      }
+
+      if (ctx.trace)
+         log.trace("binding complex " + (typeName == null ? "anonymous type" : "type " + typeName));
+
+      binding = new TypeBinding(typeName);
+      binding.setBaseType(baseType);
+      binding.setStartElementCreatesObject(true);
+      binding.setSimple(false);
+
+      if(type.getSimpleType() != null)
+      {
+         TypeBinding simpleType = bindSimpleType(ctx, type.getSimpleType());
+         binding.setSimpleType(simpleType);
+      }
+      else if(type.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED)
+      {
+         TypeBinding stringType = ctx.schema.getType(Constants.QNAME_STRING);
+         if(stringType == null)
+         {
+            throw new JBossXBRuntimeException("xsd:string has not been bound yet!");
+         }
+         binding.setSimpleType(stringType);
+      }
+
+      if(typeName != null)
+      {
+         ctx.schema.addType(binding);
+      }
+
+      binding.setSchemaBinding(ctx.schema);
+
+      XSObjectList attrs = type.getAttributeUses();
+      if (ctx.trace)
+         log.trace(typeName + " attributes " + attrs.getLength());
+
+      boolean hasOnlyIdAttrs = true;
+      for(int i = 0; i < attrs.getLength(); ++i)
+      {
+         XSAttributeUse attr = (XSAttributeUse)attrs.item(i);
+         AttributeBinding attrBinding = bindAttributes(ctx, binding, attr);
+         if(hasOnlyIdAttrs && !Constants.QNAME_ID.equals(attrBinding.getType().getQName()))
+         {
+            hasOnlyIdAttrs = false;
+         }
+      }
+
+      // customize binding with xsd annotations
+      if (ctx.processAnnotations)
+      {
+         XSObjectList annotations = type.getAnnotations();
+         if(annotations != null)
+         {
+            if (ctx.trace)
+               log.trace(typeName + " annotations " + annotations.getLength());
+            for(int i = 0; i < annotations.getLength(); ++i)
+            {
+               XSAnnotation an = (XSAnnotation)annotations.item(i);
+               XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+               XsdAppInfo appInfo = xsdAn.getAppInfo();
+               if(appInfo != null)
+               {
+                  ClassMetaData classMetaData = appInfo.getClassMetaData();
+                  if(classMetaData != null)
+                  {
+                     if (ctx.trace)
+                     {
+                        log.trace("complex type " +
+                           type.getName() +
+                           ": impl=" +
+                           classMetaData.getImpl()
+                        );
+                     }
+                     binding.setClassMetaData(classMetaData);
+                  }
+
+                  CharactersMetaData charactersMetaData = appInfo.getCharactersMetaData();
+                  if(charactersMetaData != null)
+                  {
+                     if (ctx.trace)
+                     {
+                        PropertyMetaData propertyMetaData = charactersMetaData.getProperty();
+                        if(propertyMetaData != null)
+                        {
+                           log.trace("complex type " +
+                              type.getName() +
+                              ": characters bound to " + propertyMetaData.getName()
+                           );
+                        }
+
+                        ValueMetaData valueMetaData = charactersMetaData.getValue();
+                        if(valueMetaData != null)
+                        {
+                           log.trace("complex type " +
+                              type.getName() +
+                              ": characters unmarshalMethod=" +
+                              valueMetaData.getUnmarshalMethod() +
+                              ", marshalMethod=" + valueMetaData.getMarshalMethod()
+                           );
+                        }
+
+                        boolean mapEntryKey = appInfo.isMapEntryKey();
+                        if(mapEntryKey)
+                        {
+                           log.trace("complex type " +
+                              type.getName() +
+                              ": characters are bound as a key in a map entry"
+                           );
+                        }
+
+                        boolean mapEntryValue = appInfo.isMapEntryValue();
+                        if(mapEntryValue)
+                        {
+                           log.trace("complex type " +
+                              type.getName() +
+                              ": characters are bound as a value in a map entry"
+                           );
+                        }
+                     }
+                     binding.setCharactersMetaData(charactersMetaData);
+                  }
+
+                  MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
+                  if(mapEntryMetaData != null)
+                  {
+                     if (ctx.trace)
+                     {
+                        log.trace("complex type " +
+                           type.getName() +
+                           " is bound to a map entry: impl=" +
+                           mapEntryMetaData.getImpl() +
+                           ", getKeyMethod=" +
+                           mapEntryMetaData.getGetKeyMethod() +
+                           ", setKeyMethod=" +
+                           mapEntryMetaData.getSetKeyMethod() +
+                           ", getValueMethod=" +
+                           mapEntryMetaData.getGetValueMethod() +
+                           ", setValueMethod=" +
+                           mapEntryMetaData.getSetValueMethod() +
+                           ", valueType=" +
+                           mapEntryMetaData.getValueType() +
+                           ", nonNullValue=" + mapEntryMetaData.isNonNullValue()
+                        );
+                     }
+
+                     if(classMetaData != null)
+                     {
+                        throw new JBossXBRuntimeException("Illegal binding: both jbxb:class and jbxb:mapEntry are specified for complex type " +
+                           type.getName()
+                        );
+                     }
+                     binding.setMapEntryMetaData(mapEntryMetaData);
+                  }
+
+                  boolean skip = appInfo.isSkip();
+                  if(skip)
+                  {
+                     if (ctx.trace)
+                     {
+                        log.trace("complex type " +
+                           type.getName() +
+                           ": elements of this type will be skipped; their attrs, character content " +
+                           "and elements will be set the parent."
+                        );
+                     }
+                     binding.setSkip(skip);
+                  }
+
+                  PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
+                  if(propertyMetaData != null)
+                  {
+                     if (ctx.trace)
+                     {
+                        log.trace("complex type " +
+                           type.getName() +
+                           ": the content of elements of this type is bound to property " + propertyMetaData.getName()
+                        );
+                     }
+                     binding.setPropertyMetaData(propertyMetaData);
+                  }
+
+                  AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
+                  if(addMethodMetaData != null)
+                  {
+                     if (ctx.trace)
+                     {
+                        log.trace("complex type " +
+                           type.getName() +
+                           ": elements of this type will be added to parent objects with addMethod=" +
+                           addMethodMetaData.getMethodName() + ", valueType=" + addMethodMetaData.getValueType()
+                        );
+                     }
+                     binding.setAddMethodMetaData(addMethodMetaData);
+                  }
+               }
+            }
+         }
+      }
+
+      XSParticle particle = type.getParticle();
+      if(particle != null)
+      {
+         ctx.pushType(binding);
+         bindParticle(ctx, particle);
+         ctx.popType();
+      }
+
+      if(binding.getClassMetaData() == null &&
+            ctx.simpleContentWithIdAsSimpleType &&
+            particle == null && hasOnlyIdAttrs)
+      {
+         binding.setStartElementCreatesObject(false);System.out.println("no object for " + binding.getQName());
+      }
+      else
+      {
+         binding.setStartElementCreatesObject(true);
+      }
+
+      if(binding.hasOnlyXmlMimeAttributes())
+      {
+         addXOPInclude(binding, ctx.schema);
+      }
+
+      if(ctx.trace)
+      {
+         log.trace(typeName == null ? "bound complex anonymous type" : "bound complex type " + typeName);
+      }
+
+      return binding;
+   }
+
+   private static AttributeBinding bindAttributes(Context ctx, TypeBinding type, XSAttributeUse attrUse)
+   {
+      XSAttributeDeclaration attr = attrUse.getAttrDeclaration();
+      QName attrName = new QName(attr.getNamespace(), attr.getName());
+
+      if (ctx.trace)
+      {
+         log.trace("binding attribute " + attrName + " for " + type.getQName() + ", required=" + attrUse.getRequired());
+      }
+
+      XSSimpleTypeDefinition attrType = attr.getTypeDefinition();
+      TypeBinding typeBinding = bindSimpleType(ctx, attrType);
+      AttributeBinding binding = type.addAttribute(attrName, typeBinding, DefaultHandlers.ATTRIBUTE_HANDLER);
+      binding.setRequired(attrUse.getRequired());
+      if(attrUse.getConstraintType() == XSConstants.VC_DEFAULT)
+      {
+         // Associate the default value with the binding
+         binding.setDefaultConstraint(attrUse.getConstraintValue());
+      }
+
+      if (ctx.processAnnotations)
+      {
+         XSAnnotation an = attr.getAnnotation();
+         if(an != null)
+         {
+            if (ctx.trace)
+            {
+               log.trace(attrName + " attribute annotation");
+            }
+
+            XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+            XsdAppInfo appInfo = xsdAn.getAppInfo();
+            if(appInfo != null)
+            {
+               PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
+               if(propertyMetaData != null)
+               {
+                  binding.setPropertyMetaData(propertyMetaData);
+               }
+
+               boolean mapEntryKey = appInfo.isMapEntryKey();
+               if(mapEntryKey)
+               {
+                  binding.setMapEntryKey(mapEntryKey);
+               }
+
+               boolean mapEntryValue = appInfo.isMapEntryValue();
+               if(mapEntryValue)
+               {
+                  binding.setMapEntryValue(mapEntryValue);
+               }
+            }
+         }
+      }
+
+
+      if (ctx.trace)
+      {
+         String msg = "bound attribute " + attrName;
+
+         if(binding.getPropertyMetaData() != null)
+         {
+            msg += " property=" +
+               binding.getPropertyMetaData().getName() +
+               ", collectionType=" + binding.getPropertyMetaData().getCollectionType();
+         }
+         else if(binding.isMapEntryKey())
+         {
+            msg += "bound as a key in a map entry";
+         }
+         else if(binding.isMapEntryValue())
+         {
+            msg += "bound as a value in a map entry";
+         }
+         else
+         {
+            msg += " type=" + attrType.getName() + ", owner type=" + type.getQName();
+         }
+
+         if(binding.getDefaultConstraint() != null)
+         {
+            msg += ", default=" + binding.getDefaultConstraint();
+         }
+
+         log.trace(msg);
+      }
+
+      return binding;
+   }
+
+   private static void bindParticle(Context ctx, XSParticle particle)
+   {
+      XSTerm term = particle.getTerm();
+      switch(term.getType())
+      {
+         case XSConstants.MODEL_GROUP:
+            XSModelGroup modelGroup = (XSModelGroup)term;
+            // todo: investigate this
+            if(modelGroup.getParticles().getLength() > 0)
+            {
+               ModelGroupBinding groupBinding;
+               switch(modelGroup.getCompositor())
+               {
+                  case XSModelGroup.COMPOSITOR_ALL:
+                     groupBinding = new AllBinding(ctx.schema);
+                     break;
+                  case XSModelGroup.COMPOSITOR_CHOICE:
+                     groupBinding = new ChoiceBinding(ctx.schema);
+                     break;
+                  case XSModelGroup.COMPOSITOR_SEQUENCE:
+                     groupBinding = new SequenceBinding(ctx.schema);
+                     break;
+                  default:
+                     throw new JBossXBRuntimeException("Unexpected model group: " + modelGroup.getCompositor());
+               }
+
+               ParticleBinding particleBinding = new ParticleBinding(groupBinding);
+               particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
+               particleBinding.setMinOccurs(particle.getMinOccurs());
+               particleBinding.setMaxOccurs(particle.getMaxOccurs());
+
+               if (ctx.trace)
+               {
+                  log.trace("created model group " + groupBinding);
+               }
+
+               if (ctx.processAnnotations)
+               {
+                  XSAnnotation annotation = modelGroup.getAnnotation();
+                  if(annotation != null)
+                  {
+                     customizeTerm(annotation, groupBinding, ctx.trace);
+                  }
+               }
+
+               Object o = ctx.peekTypeOrGroup();
+               if(o instanceof ModelGroupBinding)
+               {
+                  ModelGroupBinding parentGroup = (ModelGroupBinding)o;
+                  parentGroup.addParticle(particleBinding);
+                  if (ctx.trace)
+                  {
+                     log.trace("added " + groupBinding + " to " + parentGroup);
+                  }
+               }
+               else if(o instanceof TypeBinding)
+               {
+                  TypeBinding typeBinding = (TypeBinding)o;
+                  typeBinding.setParticle(particleBinding);
+                  if (ctx.trace)
+                  {
+                     log.trace("added " + groupBinding + " to type " + typeBinding.getQName());
+                  }
+               }
+
+               ctx.pushModelGroup(groupBinding);
+               bindModelGroup(ctx, modelGroup);
+               ctx.popModelGroup();
+            }
+            break;
+         case XSConstants.WILDCARD:
+            bindWildcard(ctx, particle);
+            break;
+         case XSConstants.ELEMENT_DECLARATION:
+            bindElement(ctx,
+               (XSElementDeclaration)term,
+               particle.getMinOccurs(),
+               particle.getMaxOccurs(),
+               particle.getMaxOccursUnbounded()
+            );
+            break;
+         default:
+            throw new IllegalStateException("Unexpected term type: " + term.getType());
+      }
+   }
+
+   private static void bindWildcard(Context ctx, XSParticle particle)
+   {
+      WildcardBinding binding = new WildcardBinding(ctx.schema);
+
+      ModelGroupBinding group = (ModelGroupBinding)ctx.peekTypeOrGroup();
+      ParticleBinding particleBinding = new ParticleBinding(binding);
+      particleBinding.setMaxOccurs(particle.getMaxOccurs());
+      particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
+      particleBinding.setMinOccurs(particle.getMinOccurs());
+      group.addParticle(particleBinding);
+
+      XSWildcard wildcard = (XSWildcard)particle.getTerm();
+      if(wildcard.getName() != null)
+      {
+         binding.setQName(new QName(wildcard.getNamespace(), wildcard.getName()));
+      }
+
+      binding.setProcessContents(wildcard.getProcessContents());
+
+      if (ctx.processAnnotations)
+      {
+         XSAnnotation annotation = wildcard.getAnnotation();
+         if(annotation != null)
+         {
+            customizeTerm(annotation, binding, ctx.trace);
+         }
+      }
+   }
+
+   private static ParticleBinding bindElement(Context ctx,
+                                              XSElementDeclaration elementDec,
+                                              int minOccurs,
+                                              int maxOccurs,
+                                              boolean maxOccursUnbounded)
+   {
+      QName qName = new QName(elementDec.getNamespace(), elementDec.getName());
+
+      ModelGroupBinding parentGroup = (ModelGroupBinding)ctx.peekTypeOrGroup();
+
+      boolean global = elementDec.getScope() == XSConstants.SCOPE_GLOBAL;
+      ElementBinding element = ctx.schema.getElement(qName);
+      ParticleBinding particle;
+      if(global && element != null)
+      {
+         particle = new ParticleBinding(element);
+         if(parentGroup != null)
+         {
+            parentGroup.addParticle(particle);
+         }
+
+         particle.setMinOccurs(minOccurs);
+         if(maxOccursUnbounded)
+         {
+            particle.setMaxOccursUnbounded(maxOccursUnbounded);
+         }
+         else
+         {
+            particle.setMaxOccurs(maxOccurs);
+         }
+
+         return particle;
+      }
+
+      TypeBinding type = null;
+
+      boolean shared = ctx.sharedElements.isShared(elementDec);
+      if(shared)
+      {
+         type = ctx.sharedElements.getTypeBinding(elementDec);
+      }
+
+      if(type == null)
+      {
+         type = bindType(ctx, elementDec.getTypeDefinition());
+         if(shared)
+         {
+            ctx.sharedElements.setTypeBinding(elementDec, type);
+         }
+      }
+
+      element = new ElementBinding(ctx.schema, qName, type);
+      element.setNillable(elementDec.getNillable());
+      particle = new ParticleBinding(element);
+      particle.setMinOccurs(minOccurs);
+      particle.setMaxOccurs(maxOccurs);
+      particle.setMaxOccursUnbounded(maxOccursUnbounded);
+      if(global)
+      {
+         ctx.schema.addElementParticle(particle);
+      }
+
+      if(parentGroup != null)
+      {
+         parentGroup.addParticle(particle);
+         if (ctx.trace)
+         {
+            log.trace("Element " + element.getQName() + " added to " + parentGroup);
+         }
+      }
+
+      if (ctx.trace)
+      {
+         TypeBinding parentType = ctx.peekType();
+         log.trace("element: name=" +
+            qName +
+            ", type=" +
+            type.getQName() +
+            ", repeatable=" +
+            particle.isRepeatable() +
+            ", nillable=" +
+            element.isNillable() +
+            ", minOccurs=" + minOccurs +
+            ", maxOccurs=" + (maxOccursUnbounded ? "unbounded" : "" + maxOccurs) +
+            ", " + (global ? "global scope" : " owner type=" + parentType.getQName())
+         );
+      }
+
+      // customize element with annotations
+      if (ctx.processAnnotations)
+      {
+         XSAnnotation an = elementDec.getAnnotation();
+         if(an != null)
+         {
+            customizeTerm(an, element, ctx.trace);
+         }
+      }
+      return particle;
+   }
+
+   private static void bindModelGroup(Context ctx, XSModelGroup modelGroup)
+   {
+      XSObjectList particles = modelGroup.getParticles();
+      for(int i = 0; i < particles.getLength(); ++i)
+      {
+         XSParticle particle = (XSParticle)particles.item(i);
+         bindParticle(ctx, particle);
+      }
+   }
+
+   // Private
+
+   private static void addXOPInclude(TypeBinding binding, SchemaBinding schema)
+   {
+      binding.setHandler(DefaultHandlers.XOP_HANDLER);
+      if(binding.getParticle() != null)
+      {
+         throw new JBossXBRuntimeException(
+            "XOP optimizable type has a particle which is unexpected, please, open a JIRA issue!"
+         );
+      }
+
+      TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
+      if(anyUriType == null)
+      {
+         log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
+      }
+
+      TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
+      xopIncludeType.setSchemaBinding(schema);
+      xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
+      xopIncludeType.setHandler(new XOPIncludeHandler(binding));
+
+      ElementBinding xopInclude = new ElementBinding(schema, new QName(Constants.NS_XOP_INCLUDE, "Include"), xopIncludeType);
+
+      ParticleBinding particleBinding = new ParticleBinding(xopInclude);
+      particleBinding.setMinOccurs(0);
+
+      binding.addParticle(particleBinding);
+   }
+
+   private static void customizeTerm(XSAnnotation an, TermBinding term, boolean trace)
+   {
+      XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+      XsdAppInfo appInfo = xsdAn.getAppInfo();
+      if(appInfo != null)
+      {
+         Boolean skip = null;
+
+         ClassMetaData classMetaData = appInfo.getClassMetaData();
+         if(classMetaData != null)
+         {
+            if (trace)
+            {
+               String msg;
+               if(term.isModelGroup())
+               {
+                  msg = term + " bound to ";
+               }
+               else if(term.isWildcard())
+               {
+                  msg = " wildcard bound to ";
+               }
+               else
+               {
+                  msg = "element: name=" + ((ElementBinding)term).getQName() + ", class=";
+               }
+
+               msg += classMetaData.getImpl();
+               log.trace(msg);
+            }
+            term.setClassMetaData(classMetaData);
+            skip = Boolean.FALSE;
+         }
+
+         PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
+         if(propertyMetaData != null)
+         {
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term + " " : "element: name=" +
+                  ((ElementBinding)term).getQName() + ", ";
+               msg += " property=" +
+                  propertyMetaData.getName() +
+                  ", collectionType=" + propertyMetaData.getCollectionType();
+               log.trace(msg);
+            }
+            term.setPropertyMetaData(propertyMetaData);
+         }
+
+         MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
+         if(mapEntryMetaData != null)
+         {
+            if(propertyMetaData != null)
+            {
+               String msg = "A term can be bound either as a property or as a map" +
+                  " entry but not both: " +
+                  (term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
+               throw new JBossXBRuntimeException(msg);
+            }
+
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+                  ((ElementBinding)term).getQName();
+
+               msg += " is bound to a map entry: impl=" +
+                  mapEntryMetaData.getImpl() +
+                  ", getKeyMethod=" +
+                  mapEntryMetaData.getGetKeyMethod() +
+                  ", setKeyMethod=" +
+                  mapEntryMetaData.getSetKeyMethod() +
+                  ", getValueMethod=" +
+                  mapEntryMetaData.getGetValueMethod() +
+                  ", setValueMethod=" +
+                  mapEntryMetaData.getSetValueMethod() +
+                  ", valueType=" +
+                  mapEntryMetaData.getValueType() +
+                  ", nonNullValue=" + mapEntryMetaData.isNonNullValue();
+               log.trace(msg);
+            }
+
+            if(classMetaData != null)
+            {
+               String msg = "Invalid customization: both jbxb:class and jbxb:mapEntry are specified for term " +
+                  (term.isWildcard() || term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
+               throw new JBossXBRuntimeException(msg);
+            }
+            term.setMapEntryMetaData(mapEntryMetaData);
+            skip = Boolean.FALSE;
+         }
+
+         PutMethodMetaData putMethodMetaData = appInfo.getPutMethodMetaData();
+         if(putMethodMetaData != null)
+         {
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
+                  ((ElementBinding)term).getQName() + ",";
+
+               msg += " putMethod=" +
+                  putMethodMetaData.getName() +
+                  ", keyType=" +
+                  putMethodMetaData.getKeyType() +
+                  ", valueType=" + putMethodMetaData.getValueType();
+               log.trace(msg);
+            }
+            term.setPutMethodMetaData(putMethodMetaData);
+         }
+
+         AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
+         if(addMethodMetaData != null)
+         {
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
+                  ((ElementBinding)term).getQName() + ",";
+               msg += " addMethod=" +
+                  addMethodMetaData.getMethodName() +
+                  ", valueType=" +
+                  addMethodMetaData.getValueType() +
+                  ", isChildType=" + addMethodMetaData.isChildType();
+               log.trace(msg);
+            }
+            term.setAddMethodMetaData(addMethodMetaData);
+         }
+
+         ValueMetaData valueMetaData = appInfo.getValueMetaData();
+         if(valueMetaData != null)
+         {
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element " +
+                  ((ElementBinding)term).getQName();
+               msg += ": unmarshalMethod=" + valueMetaData.getUnmarshalMethod();
+               log.trace(msg);
+            }
+            term.setValueMetaData(valueMetaData);
+         }
+
+         boolean mapEntryKey = appInfo.isMapEntryKey();
+         if(mapEntryKey)
+         {
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+                  ((ElementBinding)term).getQName();
+               msg += ": is bound to a key in a map entry";
+               log.trace(msg);
+            }
+            term.setMapEntryKey(mapEntryKey);
+            skip = Boolean.FALSE;
+         }
+
+         boolean mapEntryValue = appInfo.isMapEntryValue();
+         if(mapEntryValue)
+         {
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+                  ((ElementBinding)term).getQName();
+               msg += ": is bound to a value in a map entry";
+               log.trace(msg);
+            }
+            term.setMapEntryValue(mapEntryValue);
+            skip = Boolean.FALSE;
+         }
+
+         boolean skipAnnotation = appInfo.isSkip();
+         if(skip != null)
+         {
+            term.setSkip(skip);
+         }
+         else if(skipAnnotation)
+         {
+            if (trace)
+            {
+               String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+                  ((ElementBinding)term).getQName();
+               msg += ": will be skipped, it's attributes, character content and children will be set on the parent";
+               log.trace(msg);
+            }
+            term.setSkip(skipAnnotation ? Boolean.TRUE : Boolean.FALSE);
+         }
+      }
+   }
+
+   private static void bindGlobalGroup(XSModelGroup group, SharedElements sharedElements)
+   {
+      XSObjectList particles = group.getParticles();
+      for(int j = 0; j < particles.getLength(); ++j)
+      {
+         XSParticle particle = (XSParticle)particles.item(j);
+         XSTerm term = particle.getTerm();
+         switch(term.getType())
+         {
+            case XSConstants.ELEMENT_DECLARATION:
+               XSElementDeclaration element = ((XSElementDeclaration)term);
+               sharedElements.add(element);
+               break;
+            case XSConstants.WILDCARD:
+               // todo is it actually possible?
+               break;
+            case XSConstants.MODEL_GROUP:
+               bindGlobalGroup((XSModelGroup)term, sharedElements);
+         }
+      }
+   }
+
+
+   // Inner
+
+   private static final class SharedElements
+   {
+      private Map elements = Collections.EMPTY_MAP;
+
+      public void add(XSElementDeclaration element)
+      {
+         switch(elements.size())
+         {
+            case 0:
+               elements = Collections.singletonMap(element, null);
+               break;
+            case 1:
+               elements = new HashMap(elements);
+            default:
+               elements.put(element, null);
+         }
+      }
+
+      public boolean isShared(XSElementDeclaration element)
+      {
+         return elements.containsKey(element);
+      }
+
+      public TypeBinding getTypeBinding(XSElementDeclaration element)
+      {
+         return (TypeBinding)elements.get(element);
+      }
+
+      public void setTypeBinding(XSElementDeclaration element, TypeBinding type)
+      {
+         switch(elements.size())
+         {
+            case 0:
+               elements = Collections.singletonMap(element, type);
+               break;
+            case 1:
+               elements = new HashMap(elements);
+            default:
+               elements.put(element, type);
+         }
+      }
+   }
+
+   private static final class Context
+   {
+      public final SchemaBinding schema;
+      public SharedElements sharedElements = new SharedElements();
+      public boolean processAnnotations = true;
+      public boolean simpleContentWithIdAsSimpleType = true;
+      public boolean trace = log.isTraceEnabled();
+      private final List typeGroupStack = new ArrayList();
+
+      public Context()
+      {
+         this(new SchemaBinding());
+      }
+
+      public Context(SchemaBinding schema)
+      {
+         this.schema = schema;
+      }
+
+      public void popType()
+      {
+         Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
+         if(!(o instanceof TypeBinding))
+         {
+            throw new JBossXBRuntimeException("Should have poped type binding but got " + o);
+         }
+      }
+
+      public void pushType(TypeBinding binding)
+      {
+         typeGroupStack.add(binding);
+      }
+
+      public void popModelGroup()
+      {
+         Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
+         if(!(o instanceof ModelGroupBinding))
+   {
+            throw new JBossXBRuntimeException("Should have poped model group binding but got " + o);
+         }
+      }
+
+      public void pushModelGroup(ModelGroupBinding binding)
+      {
+         typeGroupStack.add(binding);
+      }
+
+      public Object peekTypeOrGroup()
+      {
+         return typeGroupStack.isEmpty() ? null : typeGroupStack.get(typeGroupStack.size() - 1);
+      }
+
+      public TypeBinding peekType()
+      {
+         TypeBinding binding = null;
+         for(ListIterator i = typeGroupStack.listIterator(typeGroupStack.size()); i.hasPrevious();)
+         {
+            Object o = i.previous();
+            if(o instanceof TypeBinding)
+            {
+               binding = (TypeBinding)o;
+               break;
+            }
+         }
+         return binding;
+      }
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,1445 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.xb.binding.sunday.unmarshalling.impl.runtime;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.Map;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
-import org.jboss.logging.Logger;
-import org.jboss.util.Classes;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.GenericValueContainer;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.SimpleTypeBindings;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.introspection.FieldInfo;
-import org.jboss.xb.binding.group.ValueList;
-import org.jboss.xb.binding.group.ValueListHandler;
-import org.jboss.xb.binding.group.ValueListInitializer;
-import org.jboss.xb.binding.metadata.AddMethodMetaData;
-import org.jboss.xb.binding.metadata.ClassMetaData;
-import org.jboss.xb.binding.metadata.MapEntryMetaData;
-import org.jboss.xb.binding.metadata.PackageMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.PutMethodMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.AttributeHandler;
-import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler;
-import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ParticleHandler;
-import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
-import org.xml.sax.Attributes;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class RtElementHandler
-   implements ParticleHandler
-{
-   private static final Logger log = Logger.getLogger(RtElementHandler.class);
-
-   public static final RtElementHandler INSTANCE = new RtElementHandler();
-   
-   // ParticleHandler impl
-
-   /**
-    * TODO: it seems like for correct type resolution in startParticle
-    * I should take into account the way the object is going to be added
-    * to the parent in setParent (and, hence, do some steps that are done in setParticle).
-    * In setParent then I should reuse the results of what has been done in startParticle.
-    */
-   public Object startParticle(Object parent,
-                               QName elementName,
-                               ParticleBinding particle,
-                               Attributes attrs,
-                               NamespaceContext nsCtx)
-   {
-      TermBinding term = particle.getTerm();
-      Object o = startElement(parent, elementName, particle);
-      if(!term.isModelGroup())
-      {
-         ElementBinding element = (ElementBinding)term;
-         if(o != null)
-         {
-            attrs = element.getType().expandWithDefaultAttributes(attrs);
-            attributes(o, elementName, element, attrs, nsCtx);
-         }
-      }
-      return o;
-   }
-
-   public void setParent(Object parent,
-                         Object o,
-                         QName qName,
-                         ParticleBinding particle,
-                         ParticleBinding parentParticle)
-   {
-      TermBinding term = particle.getTerm();
-      if(term.isSkip())
-      {
-         return;
-      }
-
-      boolean trace = log.isTraceEnabled();
-      if(trace)
-      {
-         log.trace("setParent " + qName + " parent=" + parent + " object=" + o + " term=" + term);
-      }
-
-      TermBinding parentTerm = parentParticle.getTerm();
-
-      if(term.isMapEntryKey())
-      {
-         if(trace)
-         {
-            log.trace("setParent " + qName + " mapKey");
-         }
-
-         if(parent instanceof MapEntry)
-         {
-            MapEntry mapEntry = (MapEntry)parent;
-            mapEntry.setKey(o);
-         }
-         else if(parentTerm != null)
-         {
-            MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
-
-            String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
-            if(getKeyMethodName == null)
-            {
-               getKeyMethodName = "getKey";
-            }
-
-            String setKeyMethodName = mapEntryMetaData.getSetKeyMethod();
-            if(setKeyMethodName == null)
-            {
-               setKeyMethodName = "setKey";
-            }
-
-            Class parentCls = parent.getClass();
-            Method setKeyMethod = getSetMethod(parentCls, getKeyMethodName, setKeyMethodName);
-            invokeSetter(setKeyMethod, parent, o, setKeyMethodName);
-         }
-         else
-         {
-            throw new JBossXBRuntimeException(
-               "Element " +
-               qName +
-               " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
-            );
-         }
-      }
-      else if(term.isMapEntryValue())
-      {
-         if(trace)
-         {
-            log.trace("setParent " + qName + " mapValue");
-         }
-
-         if(parent instanceof MapEntry)
-         {
-            MapEntry mapEntry = (MapEntry)parent;
-            mapEntry.setValue(o);
-         }
-         else if(parentTerm != null)
-         {
-            MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
-            setMapEntryValue(mapEntryMetaData, parent, o);
-         }
-         else
-         {
-            throw new JBossXBRuntimeException(
-               "Element " +
-               qName +
-               " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
-            );
-         }
-      }
-      else
-      {
-         Object owner = parent;
-         if(parent instanceof MapEntry)
-         {
-            if(trace)
-            {
-               log.trace("setParent " + qName + " mapEntry");
-            }
-
-            MapEntry mapEntry = (MapEntry)parent;
-            owner = mapEntry.getValue();
-            if(owner == null)
-            {
-               if(parentTerm == null)
-               {
-                  throw new JBossXBRuntimeException("Binding metadata needed for lazy map entry value instantiation is not available " +
-                     "for parent element of element " +
-                     qName
-                  );
-               }
-
-               MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
-               String valueType = mapEntryMetaData.getValueType();
-               if(valueType == null)
-               {
-                  throw new JBossXBRuntimeException("Element " +
-                     qName +
-                     " is supposed to be bound as map entry value with lazy value instantiation " +
-                     "but value type is not specified in its map entry metadata."
-                  );
-               }
-
-               Class valueCls;
-               try
-               {
-                  valueCls = Thread.currentThread().getContextClassLoader().loadClass(valueType);
-               }
-               catch(ClassNotFoundException e)
-               {
-                  throw new JBossXBRuntimeException(
-                     "Failed to load value type specified in the map entry metadata: " + valueType
-                  );
-               }
-
-               try
-               {
-                  owner = valueCls.newInstance();
-               }
-               catch(Exception e)
-               {
-                  throw new JBossXBRuntimeException(
-                     "Failed to create an instance of value type " + valueType + ": " + e.getMessage()
-                  );
-               }
-
-               setMapEntryValue(mapEntryMetaData, parent, owner);
-            }
-         }
-
-         // the wildcard this element is a content of
-         WildcardBinding wildcard = null;
-         if(parentTerm != null && !parentTerm.isModelGroup())
-         {
-            ElementBinding parentElement = (ElementBinding)parentTerm;
-            TypeBinding parentType = parentElement.getType();
-            wildcard = parentType.getWildcard();
-            // there should be a better way of checking this
-            if(wildcard != null && parentType.getElement(qName) != null)
-            {
-               wildcard = null;
-            }
-         }
-
-         if(tryPut(owner, o, qName, term, trace))
-         {
-         }
-         else if(tryAdd(owner, o, qName, term, wildcard, trace))
-         {
-         }
-         else if (owner instanceof GenericValueContainer)
-         {
-            if (trace)
-            {
-               log.trace("setParent " + qName + " addChild");
-            }
-            ((GenericValueContainer) owner).addChild(qName, o);
-         }
-         else if (owner instanceof Collection)
-         {
-            if (trace)
-            {
-               log.trace("setParent " + qName + " collection.add()");
-            }
-            ((Collection) owner).add(o);
-         }
-         else
-         {
-            PropertyMetaData propertyMetaData = wildcard == null ? null : wildcard.getPropertyMetaData();
-            if (propertyMetaData == null)
-            {
-               propertyMetaData = term.getPropertyMetaData();
-            }
-
-            String propName = null;
-            String colType = null;
-            if (propertyMetaData != null)
-            {
-               propName = propertyMetaData.getName();
-               colType = propertyMetaData.getCollectionType();
-            }
-
-            if (propName == null)
-            {
-               propName = Util.xmlNameToFieldName(qName.getLocalPart(), term.getSchema().isIgnoreLowLine());
-            }
-
-            if (trace)
-            {
-               log.trace("setParent " + qName + " metadata set " + propName);
-            }
-
-            /*if(particle.isRepeatable())
-            {
-               RtUtil.add(owner, o, propName, colType,
-                  term.getSchema().isIgnoreUnresolvedFieldOrClass(),
-                  term.getValueAdapter()
-               );
-            }
-            else
-            {*/
-               RtUtil.set(owner, o, propName, colType,
-                     term.getSchema().isIgnoreUnresolvedFieldOrClass(),
-                     term.getValueAdapter());
-            //}
-         }
-      }
-   }
-
-   public Object endParticle(Object o, QName elementName, ParticleBinding particle)
-   {
-      TermBinding term = particle.getTerm();
-      if(term.isSkip())
-      {
-         return o;
-      }
-
-      boolean trace = log.isTraceEnabled();
-      if(trace)
-      {
-         log.trace("endParticle " + elementName + " object=" + o + " term=" + term);
-      }
-
-      if(o instanceof GenericValueContainer)
-      {
-         try
-         {
-            if(trace)
-            {
-               log.trace("endParticle " + elementName + " instantiate()");
-            }
-            o = ((GenericValueContainer)o).instantiate();
-         }
-         catch(JBossXBRuntimeException e)
-         {
-            throw e;
-         }
-         catch(RuntimeException e)
-         {
-            throw new JBossXBRuntimeException("Container failed to create an instance for " +
-               elementName +
-               ": " + e.getMessage(), e
-            );
-         }
-      }
-
-      return o;
-   }
-
-   // Private
-
-   private Object startElement(Object parent, QName elementName, ParticleBinding particle)
-   {
-      TermBinding term = particle.getTerm();
-      if(term.isSkip())
-      {
-         return parent;
-      }
-
-      boolean trace = log.isTraceEnabled();
-      if(trace)
-      {
-         log.trace("startElement " + elementName + " parent=" + parent + " term=" + term);
-      }
-
-      ClassMetaData classMetaData = term.getClassMetaData();
-      MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
-
-      if(!term.isModelGroup())
-      {
-         TypeBinding type = ((ElementBinding)term).getType();
-         if(!type.isStartElementCreatesObject() ||
-            classMetaData == null && mapEntryMetaData == null && Constants.QNAME_ANYTYPE.equals(type.getQName()))
-         {
-            if(trace)
-            {
-               log.trace("startElement " + elementName + " does not create an object");
-            }
-            return null;
-         }
-      }
-
-      Object o = null;
-
-      // if addMethod is specified, it's probably some collection field
-      // but should not be set as a property. Instead, items are added to it using the addMethod
-      ElementBinding arrayItem = null;
-      if(!term.isModelGroup())
-      {
-         TypeBinding type = ((ElementBinding)term).getType();
-         if(type.getAttributes().isEmpty())
-         {
-            ParticleBinding typeParticle = type.getParticle();
-            ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
-            arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
-
-            // todo refactor later (move it to modelGroup.getArrayItem()?)
-            if(arrayItem != null &&
-               (arrayItem.isSkip() ||
-               arrayItem.getMapEntryMetaData() != null ||
-               arrayItem.getPutMethodMetaData() != null ||
-               arrayItem.getAddMethodMetaData() != null
-               ))
-            {
-               arrayItem = null;
-            }
-         }
-      }
-
-      if(arrayItem != null)
-      {
-         Class wrapperType = null;
-         if(classMetaData != null)
-         {
-            wrapperType = loadClassForTerm(classMetaData.getImpl(),
-               term.getSchema().isIgnoreUnresolvedFieldOrClass(),
-               elementName
-            );
-
-            if(GenericValueContainer.class.isAssignableFrom(wrapperType) ||
-               Collection.class.isAssignableFrom(wrapperType) ||
-               Map.class.isAssignableFrom(wrapperType))
-            {
-               return newInstance(wrapperType, elementName, term.getSchema().isUseNoArgCtorIfFound());
-            }
-         }
-
-         if(wrapperType == null && parent == null)
-         {
-            Class itemType = classForElement(arrayItem, null);
-            if(itemType != null)
-            {
-               if(trace)
-               {
-                  log.trace("startElement " + elementName + " new array " + itemType.getName());
-               }
-               o = GenericValueContainer.FACTORY.array(itemType);
-            }
-         }
-         else
-         {
-            PropertyMetaData propertyMetaData = wrapperType == null ?
-               term.getPropertyMetaData() : arrayItem.getPropertyMetaData();
-
-            String propName;
-            if(propertyMetaData == null)
-            {
-               propName = Util.xmlNameToFieldName(
-                  wrapperType == null ? elementName.getLocalPart() : arrayItem.getQName().getLocalPart(),
-                  term.getSchema().isIgnoreLowLine()
-               );
-            }
-            else
-            {
-               propName = propertyMetaData.getName();
-            }
-
-            if(trace)
-            {
-               log.trace("startElement " + elementName + " property=" + propName);
-            }
-
-            Class parentClass = wrapperType;
-            if(wrapperType == null)
-            {
-               if(parent instanceof GenericValueContainer)
-               {
-                  parentClass = ((GenericValueContainer)parent).getTargetClass();
-               }
-               else if(parent instanceof ValueList)
-               {
-                  parentClass = ((ValueList)parent).getTargetClass();
-               }
-               else
-               {
-                  parentClass = parent.getClass();
-               }
-            }
-
-            Class fieldType;
-            if(parentClass.isArray())
-            {
-               fieldType = parentClass.getComponentType();
-            }
-            else
-            {
-               fieldType = FieldInfo.getFieldInfo(parentClass, propName, true).getType();
-               if(particle.isRepeatable() && fieldType.isArray())
-               {
-                  fieldType = fieldType.getComponentType();
-               }
-            }
-
-            if(fieldType.isArray())
-            {
-               o = GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType.getComponentType());
-            }
-            else if(Collection.class.isAssignableFrom(fieldType))
-            {
-               //System.out.println("GeenericValueContainer.child: " + elementName);
-               o = new ValueListInitializer().newValueList(ValueListHandler.FACTORY.child(), Collection.class);
-               //o = new ArrayList();
-            }
-            else
-            {
-               o = GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType);
-            }
-         }
-      }
-      else
-      {
-         if(mapEntryMetaData != null)
-         {
-            if(mapEntryMetaData.getImpl() != null)
-            {
-               Class cls = loadClassForTerm(mapEntryMetaData.getImpl(),
-                  term.getSchema().isIgnoreUnresolvedFieldOrClass(),
-                  elementName
-               );
-
-               if(trace)
-               {
-                  log.trace("startElement " + elementName + " new map entry " + cls.getName());
-               }
-
-               o = newInstance(cls, elementName, term.getSchema().isUseNoArgCtorIfFound());
-            }
-            else
-            {
-               o = new MapEntry();
-               if(trace)
-               {
-                  log.trace("startElement " + elementName + " new map entry");
-               }
-            }
-
-            if(mapEntryMetaData.isNonNullValue() && mapEntryMetaData.getValueType() != null)
-            {
-               Class mapValueType;
-               try
-               {
-                  mapValueType =
-                     Thread.currentThread().getContextClassLoader().loadClass(mapEntryMetaData.getValueType());
-               }
-               catch(ClassNotFoundException e)
-               {
-                  throw new JBossXBRuntimeException("startElement failed for " +
-                     elementName +
-                     ": failed to load class " +
-                     mapEntryMetaData.getValueType() +
-                     " for map entry value."
-                  );
-               }
-
-               Object value;
-               try
-               {
-                  if(trace)
-                  {
-                     log.trace("startElement " + elementName + " map value type " + mapEntryMetaData.getValueType());
-                  }
-                  value = mapValueType.newInstance();
-               }
-               catch(Exception e)
-               {
-                  throw new JBossXBRuntimeException("startElement failed for " +
-                     elementName +
-                     ": failed to create an instance of " +
-                     mapValueType +
-                     " for map entry value."
-                  );
-               }
-
-               if(o instanceof MapEntry)
-               {
-                  ((MapEntry)o).setValue(value);
-               }
-               else
-               {
-                  String getValueMethodName = mapEntryMetaData.getGetValueMethod();
-                  if(getValueMethodName == null)
-                  {
-                     getValueMethodName = "getValue";
-                  }
-
-                  String setValueMethodName = mapEntryMetaData.getSetValueMethod();
-                  if(setValueMethodName == null)
-                  {
-                     setValueMethodName = "setValue";
-                  }
-
-                  Method getValueMethod;
-                  try
-                  {
-                     getValueMethod = o.getClass().getMethod(getValueMethodName, null);
-                  }
-                  catch(NoSuchMethodException e)
-                  {
-                     throw new JBossXBRuntimeException("getValueMethod=" +
-                        getValueMethodName +
-                        " is not found in map entry " + o.getClass()
-                     );
-                  }
-
-                  Method setValueMethod;
-                  try
-                  {
-                     setValueMethod =
-                        o.getClass().getMethod(setValueMethodName, new Class[]{getValueMethod.getReturnType()});
-                  }
-                  catch(NoSuchMethodException e)
-                  {
-                     throw new JBossXBRuntimeException("setValueMethod=" +
-                        setValueMethodName +
-                        "(" +
-                        getValueMethod.getReturnType().getName() +
-                        " value) is not found in map entry " + o.getClass()
-                     );
-                  }
-
-                  try
-                  {
-                     setValueMethod.invoke(o, new Object[]{value});
-                  }
-                  catch(Exception e)
-                  {
-                     throw new JBossXBRuntimeException("setValueMethod=" +
-                        setValueMethodName +
-                        " failed: owner=" +
-                        o +
-                        ", value=" + value + ", msg=" + e.getMessage(), e
-                     );
-                  }
-               }
-            }
-         }
-         else
-         {
-            // todo: for now we require metadata for model groups to be bound
-            // todo 2: parent.getClass() is not going to work for containers
-            Class parentClass = null;
-            if(parent != null)
-            {
-               if(parent instanceof GenericValueContainer)
-               {
-                  parentClass = ((GenericValueContainer)parent).getTargetClass();
-               }
-               else if(parent instanceof ValueList)
-               {
-                  parentClass = ((ValueList)parent).getTargetClass();
-               }
-               else
-               {
-                  parentClass = parent.getClass();
-               }
-            }
-
-            Class cls;
-            if(term.isModelGroup())
-            {
-               if(classMetaData == null)
-               {
-                  throw new JBossXBRuntimeException(
-                     "Model groups should be annotated with 'class' annotation to be bound."
-                  );
-               }
-               cls = loadClassForTerm(classMetaData.getImpl(),
-                  term.getSchema().isIgnoreUnresolvedFieldOrClass(),
-                  elementName
-               );
-            }
-            else
-            {
-               ElementBinding element = (ElementBinding)term;
-               cls = classForNonArrayItem(element, parentClass);
-               if(cls != null)
-               {
-                  // todo: before that, the type should be checked for required attributes and elements
-                  TypeBinding simpleType = element.getType().getSimpleType();
-                  if(simpleType != null)
-                  {
-                     Class simpleCls = classForSimpleType(simpleType, element.isNillable());
-                     if(cls.equals(simpleCls) ||
-                        cls.isPrimitive() && Classes.getPrimitiveWrapper(cls) == simpleCls ||
-                        simpleCls.isPrimitive() && Classes.getPrimitiveWrapper(simpleCls) == cls)
-                     {
-                        cls = null;
-                     }
-                  }
-               }
-            }
-
-            if(cls != null)
-            {
-               boolean noArgCtor;
-               if(classMetaData == null)
-               {
-                  noArgCtor = term.getSchema().isUseNoArgCtorIfFound();
-               }
-               else
-               {
-                  Boolean termUsesNoArgCtor = classMetaData.isUseNoArgCtor();
-                  noArgCtor = termUsesNoArgCtor == null ?
-                     term.getSchema().isUseNoArgCtorIfFound() : termUsesNoArgCtor.booleanValue();               }
-
-               if(trace)
-               {
-                  log.trace("startElement " + elementName + " new " + cls.getName() + ", noArgCtor=" + noArgCtor);
-               }
-               o = newInstance(cls, elementName, noArgCtor);
-            }
-         }
-      }
-      return o;
-   }
-
-   private void attributes(Object o,
-                           QName elementName,
-                           ElementBinding element,
-                           Attributes attrs,
-                           NamespaceContext nsCtx)
-   {
-      TypeBinding type = element.getType();
-      for(int i = 0; i < attrs.getLength(); ++i)
-      {
-         QName attrName = new QName(attrs.getURI(i), attrs.getLocalName(i));
-         AttributeBinding binding = type.getAttribute(attrName);
-         if(binding != null)
-         {
-            AttributeHandler handler = binding.getHandler();
-            if(handler != null)
-            {
-               Object value = handler.unmarshal(elementName, attrName, binding, nsCtx, attrs.getValue(i));
-               handler.attribute(elementName, attrName, binding, o, value);
-            }
-            else
-            {
-               throw new JBossXBRuntimeException(
-                  "Attribute binding present but has no handler: element=" + elementName + ", attrinute=" + attrName
-               );
-            }
-         }
-         else
-         {
-            if(!Constants.NS_XML_SCHEMA_INSTANCE.equals(attrs.getURI(i)))
-            {
-               CharactersHandler simpleType = type.getCharactersHandler();
-               Object value;
-               if(simpleType == null)
-               {
-                  value = attrs.getValue(i);
-                  RtUtil.set(o, attrName, value, element.getSchema().isIgnoreLowLine());
-               }
-            }
-         }
-      }
-   }
-
-   private boolean tryAdd(Object owner,
-                          Object o,
-                          QName qName,
-                          TermBinding term,
-                          WildcardBinding wildcard,
-                          boolean trace)
-   {
-      AddMethodMetaData addMetaData = wildcard == null ? null : wildcard.getAddMethodMetaData();
-      if(addMetaData == null)
-      {
-         addMetaData = term.getAddMethodMetaData();
-      }
-
-      if(addMetaData == null)
-      {
-         return false;
-      }
-
-      if(trace)
-      {
-         log.trace("setParent " + qName + " add");
-      }
-      invokeAdd(qName, addMetaData, owner, o);
-      return true;
-   }
-
-   private boolean tryPut(Object owner, Object o, QName qName, TermBinding term, boolean trace)
-   {
-      if(term.getPutMethodMetaData() != null ||
-         term.getMapEntryMetaData() != null && owner instanceof Map)
-      {
-         if(trace)
-         {
-            log.trace("setParent " + qName + " mapPut");
-         }
-         invokePut(qName, term, owner, o);
-         return true;
-      }
-      return false;
-   }
-
-   private Class classForElement(ElementBinding element, Class parentClass)
-   {
-      Class cls;
-      TypeBinding type = element.getType();
-      QName typeQName = type.getQName();
-      if(typeQName != null && Constants.NS_XML_SCHEMA.equals(typeQName.getNamespaceURI()))
-      {
-         cls = SimpleTypeBindings.classForType(type.getQName().getLocalPart(), element.isNillable());
-      }
-      else
-      {
-         ElementBinding arrayItem = null;
-         if(!type.isSimple() && type.getAttributes().isEmpty())
-         {
-            ParticleBinding typeParticle = type.getParticle();
-            ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
-            arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
-         }
-
-         if(arrayItem != null)
-         {
-            cls = classForElement(arrayItem, parentClass);
-            // todo: what's the best way to get an array class having the item class
-            cls = Array.newInstance(cls, 0).getClass();
-         }
-         else
-         {
-            cls = classForNonArrayItem(element, parentClass);
-         }
-      }
-      return cls;
-   }
-
-   private static void setMapEntryValue(MapEntryMetaData mapEntryMetaData, Object parent, Object o)
-   {
-      String getValueMethodName = mapEntryMetaData.getGetValueMethod();
-      if(getValueMethodName == null)
-      {
-         getValueMethodName = "getValue";
-      }
-
-      String setValueMethodName = mapEntryMetaData.getSetValueMethod();
-      if(setValueMethodName == null)
-      {
-         setValueMethodName = "setValue";
-      }
-
-      Class parentCls = parent.getClass();
-      Method setValueMethod = getSetMethod(parentCls, getValueMethodName, setValueMethodName);
-      invokeSetter(setValueMethod, parent, o, setValueMethodName);
-   }
-
-   private static void invokeSetter(Method setValueMethod, Object parent, Object o, String setValueMethodName)
-   {
-      try
-      {
-         setValueMethod.invoke(parent, new Object[]{o});
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBRuntimeException("Failed to invoke " +
-            setValueMethodName +
-            " on " +
-            parent +
-            " with parameter " +
-            o +
-            ": " +
-            e.getMessage()
-         );
-      }
-   }
-
-   private static Method getSetMethod(Class cls, String getMethodName, String setMethodName)
-   {
-      Method getKeyMethod;
-      try
-      {
-         getKeyMethod = cls.getMethod(getMethodName, null);
-      }
-      catch(NoSuchMethodException e)
-      {
-         throw new JBossXBRuntimeException("Method " + getMethodName + " not found in " + cls);
-      }
-
-      Method setKeyMethod;
-      try
-      {
-         setKeyMethod = cls.getMethod(setMethodName, new Class[]{getKeyMethod.getReturnType()});
-      }
-      catch(NoSuchMethodException e)
-      {
-         throw new JBossXBRuntimeException("Method " +
-            setMethodName +
-            "(" +
-            getKeyMethod.getReturnType().getName() +
-            " p) not found in " +
-            cls
-         );
-      }
-      return setKeyMethod;
-   }
-
-   private static MapEntryMetaData getMapEntryMetaData(TermBinding term, QName qName)
-   {
-      MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
-      if(mapEntryMetaData == null)
-      {
-         String msg;
-         if(term.isModelGroup())
-         {
-            msg = "Term " +
-               qName +
-               " bound as map entry key or value but map entry metadata is not available for its parent term.";
-         }
-         else
-         {
-            ElementBinding element = (ElementBinding)term;
-            msg = "Element " +
-               qName +
-               " bound as map entry key or value but map entry metadata is not available for its parent element nor its " +
-               (element.getType().getQName() == null ?
-               "annonymous" :
-               element.getType().getQName().toString()
-               ) +
-               " type.";
-         }
-         throw new JBossXBRuntimeException(msg);
-      }
-      return mapEntryMetaData;
-   }
-
-   private static Object newInstance(Class cls, QName elementName, boolean useNoArgCtorIfFound)
-   {
-      Object o;
-      if(cls.isArray())
-      {
-         o = GenericValueContainer.FACTORY.array(cls.getComponentType());
-      }
-      else
-      {
-         Constructor[] ctors = cls.getConstructors();
-         if(ctors.length == 0)
-         {
-            throw new JBossXBRuntimeException(
-               "Class " + cls.getName() + " has no public constructors or the class reflects a primitive type or void"
-            );
-         }
-
-         if(useNoArgCtorIfFound)
-         {
-            try
-            {
-               Constructor ctor = cls.getConstructor(null);
-               o = ctor.newInstance(null);
-            }
-            catch(NoSuchMethodException e)
-            {
-               o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
-            }
-            catch(Exception e)
-            {
-               throw new JBossXBRuntimeException("Failed to create an instance of " +
-                  cls +
-                  " using default constructor for element " +
-                  elementName + ": " + e.getMessage(), e
-               );
-            }
-         }
-         else if(ctors.length > 1 || ctors[0].getParameterTypes().length > 0)
-         {
-            o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
-         }
-         else
-         {
-            try
-            {
-               o = ctors[0].newInstance(null);
-            }
-            catch(Exception e)
-            {
-               throw new JBossXBRuntimeException("Failed to create an instance of " +
-                  cls +
-                  " using default constructor for element " +
-                  elementName + ": " + e.getMessage(), e
-               );
-            }
-         }
-      }
-      return o;
-   }
-
-   private static Class loadClassForTerm(String className,
-                                         boolean ignoreCNFE,
-                                         QName elementName)
-   {
-      if(className == null)
-      {
-         throw new JBossXBRuntimeException("No class for " + elementName);
-      }
-
-      Class cls = null;
-      try
-      {
-         cls = Thread.currentThread().getContextClassLoader().loadClass(className);
-      }
-      catch(ClassNotFoundException e)
-      {
-         if(ignoreCNFE)
-         {
-            if(log.isTraceEnabled())
-            {
-               log.trace("Failed to resolve class for element " +
-                  elementName +
-                  ": " +
-                  className
-               );
-            }
-         }
-         else
-         {
-            throw new JBossXBRuntimeException("Failed to resolve class name for " +
-               elementName +
-               ": " +
-               e.getMessage()
-            );
-         }
-      }
-      return cls;
-   }
-
-   private void invokeAdd(QName qName, AddMethodMetaData addMethodMetaData, Object owner, Object o)
-   {
-      Class valueType = Object.class;
-      if(addMethodMetaData.getValueType() != null)
-      {
-         try
-         {
-            valueType = Thread.currentThread().getContextClassLoader().
-               loadClass(addMethodMetaData.getValueType());
-         }
-         catch(ClassNotFoundException e)
-         {
-            throw new JBossXBRuntimeException("Failed to load value type for addMethod.name=" +
-               addMethodMetaData.getMethodName() +
-               ", valueType=" +
-               addMethodMetaData.getValueType() +
-               ": " + e.getMessage(), e
-            );
-         }
-      }
-      else if(addMethodMetaData.isChildType())
-      {
-         if(o == null)
-         {
-            throw new JBossXBRuntimeException("addMethod=" +
-               addMethodMetaData.getMethodName() +
-               " for element " +
-               qName +
-               " is configured with valueType='child'. The valueType cannot be determined because" +
-               " the child is null"
-            );
-         }
-         valueType = o.getClass();
-      }
-
-      Class ownerClass = owner.getClass();
-      Method addMethod;
-      try
-      {
-         addMethod = ownerClass.getMethod(addMethodMetaData.getMethodName(), new Class[]{valueType});
-      }
-      catch(NoSuchMethodException e)
-      {
-         throw new JBossXBRuntimeException("Failed to find addMethod.name=" +
-            addMethodMetaData.getMethodName() +
-            ", addMethod.valueType=" +
-            valueType.getName() +
-            " in class " +
-            ownerClass.getName() +
-            ": " +
-            e.getMessage(), e
-         );
-      }
-
-      try
-      {
-         addMethod.invoke(owner, new Object[]{o});
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBRuntimeException("setParent failed for " +
-            qName +
-            "=" +
-            o +
-            ": addMethod=" +
-            addMethodMetaData.getMethodName() +
-            " threw an exception for owner=" +
-            owner +
-            ", value=" +
-            o +
-            ": " +
-            e.getMessage(),
-            e
-         );
-      }
-   }
-
-   private void invokePut(QName qName, TermBinding term, Object owner, Object o)
-   {
-      PutMethodMetaData putMethodMetaData = term.getPutMethodMetaData();
-
-      MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
-      if(mapEntryMetaData == null)
-      {
-         throw new JBossXBRuntimeException((putMethodMetaData == null ?
-            "Parent object is an instance of java.util.Map" :
-            "putMethod is specified for element " + qName
-            ) +
-            " but mapEntry is specified for neither element " +
-            qName +
-            " nor it's type."
-         );
-      }
-
-      Class oClass = o.getClass();
-      String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
-      if(getKeyMethodName == null)
-      {
-         getKeyMethodName = "getKey";
-      }
-
-      Method keyMethod;
-      try
-      {
-         keyMethod = oClass.getMethod(getKeyMethodName, null);
-      }
-      catch(NoSuchMethodException e)
-      {
-         throw new JBossXBRuntimeException("setParent failed for " +
-            qName +
-            "=" +
-            o +
-            ": getKeyMethod=" +
-            getKeyMethodName +
-            " not found in " + oClass
-         );
-      }
-
-      Object key;
-      try
-      {
-         key = keyMethod.invoke(o, null);
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBRuntimeException("setParent failed for " +
-            qName +
-            "=" +
-            o +
-            ": getKeyMethod=" +
-            getKeyMethodName +
-            " threw an exception: " + e.getMessage(), e
-         );
-      }
-
-      Class keyType = Object.class;
-      Class valueType = Object.class;
-      String putMethodName = "put";
-      Class ownerClass = owner.getClass();
-
-      if(putMethodMetaData != null)
-      {
-         if(putMethodMetaData.getKeyType() != null)
-         {
-            try
-            {
-               keyType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getKeyType());
-            }
-            catch(ClassNotFoundException e)
-            {
-               throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
-            }
-         }
-
-         if(putMethodMetaData.getValueType() != null)
-         {
-            try
-            {
-               valueType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getValueType());
-            }
-            catch(ClassNotFoundException e)
-            {
-               throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
-            }
-         }
-
-         String name = putMethodMetaData.getName();
-         if(name != null)
-         {
-            putMethodName = name;
-         }
-      }
-
-      Method putMethod;
-      try
-      {
-         putMethod = ownerClass.getMethod(putMethodName, new Class[]{keyType, valueType});
-      }
-      catch(NoSuchMethodException e)
-      {
-         throw new JBossXBRuntimeException("setParent failed for " +
-            qName +
-            "=" +
-            o +
-            ": putMethod=" +
-            putMethodName +
-            "(" + keyType.getName() + " key, " + valueType.getName() + " value) not found in " + ownerClass
-         );
-      }
-
-      Object value = o;
-      String valueMethodName = mapEntryMetaData.getGetValueMethod();
-      if(valueMethodName != null)
-      {
-         Method valueMethod;
-         try
-         {
-            valueMethod = oClass.getMethod(valueMethodName, null);
-         }
-         catch(NoSuchMethodException e)
-         {
-            throw new JBossXBRuntimeException("setParent failed for " +
-               qName +
-               "=" +
-               o +
-               ": getValueMethod=" +
-               mapEntryMetaData.getGetValueMethod() +
-               " not found in " + oClass
-            );
-         }
-
-         try
-         {
-            value = valueMethod.invoke(o, null);
-         }
-         catch(Exception e)
-         {
-            throw new JBossXBRuntimeException("setParent failed for " +
-               qName +
-               "=" +
-               o +
-               ": getValueMethod=" +
-               mapEntryMetaData.getGetValueMethod() +
-               " threw an exception: " + e.getMessage(), e
-            );
-         }
-      }
-      else if(o instanceof MapEntry)
-      {
-         value = ((MapEntry)o).getValue();
-      }
-
-      try
-      {
-         putMethod.invoke(owner, new Object[]{key, value});
-      }
-      catch(Exception e)
-      {
-         throw new JBossXBRuntimeException("setParent failed for " +
-            qName +
-            "=" +
-            o +
-            ": putMethod=" +
-            putMethodName +
-            " threw an exception for owner=" +
-            owner +
-            ", key=" +
-            key +
-            ", value=" +
-            value +
-            ": " +
-            e.getMessage(),
-            e
-         );
-      }
-   }
-
-   private Class classForNonArrayItem(ElementBinding element, Class parentClass)
-   {
-      String clsName;
-
-      // first, class metadata and map entry metadata
-      ClassMetaData clsMetaData = element.getClassMetaData();
-      clsName = clsMetaData == null ? null : clsMetaData.getImpl();
-      if(clsName == null)
-      {
-         MapEntryMetaData mapEntryMetaData = element.getMapEntryMetaData();
-         if(mapEntryMetaData != null)
-         {
-            clsName = mapEntryMetaData.getImpl();
-            if(clsName == null)
-            {
-               clsName = MapEntry.class.getName();
-            }
-         }
-      }
-
-      // second, property metadata and property type
-      if(clsName == null)
-      {
-         if(parentClass == null)
-         {
-            clsName = classFromQName(element);
-         }
-         else
-         {
-            PropertyMetaData propertyMetaData = element.getPropertyMetaData();
-            String propName = propertyMetaData == null ? null : propertyMetaData.getName();
-            if(propName == null)
-            {
-               // if there is add or put method metadata then fallback to XML-name-to-class-name algorithm
-               if(element.getAddMethodMetaData() == null && element.getPutMethodMetaData() == null)
-               {
-                  propName =
-                     Util.xmlNameToFieldName(element.getQName().getLocalPart(), element.getSchema().isIgnoreLowLine());
-               }
-            }
-
-            if(propName != null)
-            {
-               FieldInfo fieldInfo = FieldInfo.getFieldInfo(parentClass, propName, false);
-               Class fieldType = fieldInfo == null ? null : fieldInfo.getType();
-
-               if(fieldType == null ||
-                  Modifier.isAbstract(fieldType.getModifiers()) ||
-                  Modifier.isInterface(fieldType.getModifiers()) ||
-                  fieldType.isArray() ||
-                  Collection.class.isAssignableFrom(fieldType))
-               {
-                  clsName = classFromQName(element);
-               }
-               else
-               {
-                  return fieldType;
-               }
-            }
-         }
-      }
-
-      return loadClassForTerm(clsName, element.getSchema().isIgnoreUnresolvedFieldOrClass(), element.getQName());
-   }
-
-   private String classFromQName(ElementBinding element)
-   {
-      String clsName;
-      QName typeBase = element.getType().getQName();
-      if(typeBase == null)
-      {
-         typeBase = element.getQName();
-      }
-
-      SchemaBinding schema = element.getSchema();
-      PackageMetaData pkgMetaData = schema.getPackageMetaData();
-      if(pkgMetaData == null)
-      {
-         clsName =
-            Util.xmlNameToClassName(typeBase.getNamespaceURI(),
-               typeBase.getLocalPart(),
-               schema.isIgnoreLowLine()
-            );
-      }
-      else
-      {
-         String pkg = pkgMetaData.getName();
-         clsName =
-            pkg == null || pkg.length() == 0 ?
-            Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine()) :
-            pkg + "." + Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine());
-      }
-      return clsName;
-   }
-
-   private static Class classForSimpleType(TypeBinding type, boolean nillable)
-   {
-      ValueMetaData valueMetaData = type.getValueMetaData();
-      if(valueMetaData != null && valueMetaData.getUnmarshalMethod() != null)
-      {
-         return RtUtil.getUnmarshalMethod(type.getQName(), valueMetaData).getReturnType();
-      }
-      else if(type.getClassMetaData() != null && type.getClassMetaData().getImpl() != null)
-      {
-         return RtUtil.loadClass(type.getClassMetaData().getImpl(), true);
-      }
-
-      TypeBinding itemType = type.getItemType();
-      if(itemType != null)
-      {
-         if(type.getSchemaBinding().isUnmarshalListsToArrays())
-         {
-            // todo: nillable not always should be propagated to the item
-            Class itemClass = classForSimpleType(itemType, nillable);
-            return Array.newInstance(itemClass, 0).getClass();
-         }
-         else
-         {
-            return java.util.List.class;
-         }
-      }
-      else
-      {
-         QName qName = type.getQName();
-         if(qName != null && Constants.NS_XML_SCHEMA.equals(qName.getNamespaceURI()))
-         {
-            return SimpleTypeBindings.classForType(qName.getLocalPart(), nillable);
-         }
-         else
-         {
-            TypeBinding baseType = type.getBaseType();
-            if(baseType == null)
-            {
-               throw new JBossXBRuntimeException("Expected a base type here.");
-            }
-
-            return classForSimpleType(baseType, nillable);
-         }
-      }
-   }
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,1465 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.xb.binding.sunday.unmarshalling.impl.runtime;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Map;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import org.jboss.logging.Logger;
+import org.jboss.util.Classes;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.GenericValueContainer;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.SimpleTypeBindings;
+import org.jboss.xb.binding.Util;
+import org.jboss.xb.binding.introspection.FieldInfo;
+import org.jboss.xb.binding.group.ValueList;
+import org.jboss.xb.binding.group.ValueListHandler;
+import org.jboss.xb.binding.group.ValueListInitializer;
+import org.jboss.xb.binding.metadata.AddMethodMetaData;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.metadata.MapEntryMetaData;
+import org.jboss.xb.binding.metadata.PackageMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.PutMethodMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.AttributeHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ParticleHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
+import org.xml.sax.Attributes;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class RtElementHandler
+   implements ParticleHandler
+{
+   private static final Logger log = Logger.getLogger(RtElementHandler.class);
+
+   public static final RtElementHandler INSTANCE = new RtElementHandler();
+   
+   // ParticleHandler impl
+
+   /**
+    * TODO: it seems like for correct type resolution in startParticle
+    * I should take into account the way the object is going to be added
+    * to the parent in setParent (and, hence, do some steps that are done in setParticle).
+    * In setParent then I should reuse the results of what has been done in startParticle.
+    */
+   public Object startParticle(Object parent,
+                               QName elementName,
+                               ParticleBinding particle,
+                               Attributes attrs,
+                               NamespaceContext nsCtx)
+   {
+      TermBinding term = particle.getTerm();
+      Object o = startElement(parent, elementName, particle);
+      if(!term.isModelGroup())
+      {
+         ElementBinding element = (ElementBinding)term;
+         if(o != null)
+         {
+            attrs = element.getType().expandWithDefaultAttributes(attrs);
+            attributes(o, elementName, element, attrs, nsCtx);
+         }
+      }
+      return o;
+   }
+
+   public void setParent(Object parent,
+                         Object o,
+                         QName qName,
+                         ParticleBinding particle,
+                         ParticleBinding parentParticle)
+   {
+      TermBinding term = particle.getTerm();
+      if(term.isSkip())
+      {
+         return;
+      }
+
+      boolean trace = log.isTraceEnabled();
+      if(trace)
+      {
+         log.trace("setParent " + qName + " parent=" + parent + " object=" + o + " term=" + term);
+      }
+
+      TermBinding parentTerm = parentParticle.getTerm();
+
+      if(term.isMapEntryKey())
+      {
+         if(trace)
+         {
+            log.trace("setParent " + qName + " mapKey");
+         }
+
+         if(parent instanceof MapEntry)
+         {
+            MapEntry mapEntry = (MapEntry)parent;
+            mapEntry.setKey(o);
+         }
+         else if(parentTerm != null)
+         {
+            MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
+
+            String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
+            if(getKeyMethodName == null)
+            {
+               getKeyMethodName = "getKey";
+            }
+
+            String setKeyMethodName = mapEntryMetaData.getSetKeyMethod();
+            if(setKeyMethodName == null)
+            {
+               setKeyMethodName = "setKey";
+            }
+
+            Class parentCls = parent.getClass();
+            Method setKeyMethod = getSetMethod(parentCls, getKeyMethodName, setKeyMethodName);
+            invokeSetter(setKeyMethod, parent, o, setKeyMethodName);
+         }
+         else
+         {
+            throw new JBossXBRuntimeException(
+               "Element " +
+               qName +
+               " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
+            );
+         }
+      }
+      else if(term.isMapEntryValue())
+      {
+         if(trace)
+         {
+            log.trace("setParent " + qName + " mapValue");
+         }
+
+         if(parent instanceof MapEntry)
+         {
+            MapEntry mapEntry = (MapEntry)parent;
+            mapEntry.setValue(o);
+         }
+         else if(parentTerm != null)
+         {
+            MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
+            setMapEntryValue(mapEntryMetaData, parent, o);
+         }
+         else
+         {
+            throw new JBossXBRuntimeException(
+               "Element " +
+               qName +
+               " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
+            );
+         }
+      }
+      else
+      {
+         Object owner = parent;
+         if(parent instanceof MapEntry)
+         {
+            if(trace)
+            {
+               log.trace("setParent " + qName + " mapEntry");
+            }
+
+            MapEntry mapEntry = (MapEntry)parent;
+            owner = mapEntry.getValue();
+            if(owner == null)
+            {
+               if(parentTerm == null)
+               {
+                  throw new JBossXBRuntimeException("Binding metadata needed for lazy map entry value instantiation is not available " +
+                     "for parent element of element " +
+                     qName
+                  );
+               }
+
+               MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
+               String valueType = mapEntryMetaData.getValueType();
+               if(valueType == null)
+               {
+                  throw new JBossXBRuntimeException("Element " +
+                     qName +
+                     " is supposed to be bound as map entry value with lazy value instantiation " +
+                     "but value type is not specified in its map entry metadata."
+                  );
+               }
+
+               Class valueCls;
+               try
+               {
+                  valueCls = Thread.currentThread().getContextClassLoader().loadClass(valueType);
+               }
+               catch(ClassNotFoundException e)
+               {
+                  throw new JBossXBRuntimeException(
+                     "Failed to load value type specified in the map entry metadata: " + valueType
+                  );
+               }
+
+               try
+               {
+                  owner = valueCls.newInstance();
+               }
+               catch(Exception e)
+               {
+                  throw new JBossXBRuntimeException(
+                     "Failed to create an instance of value type " + valueType + ": " + e.getMessage()
+                  );
+               }
+
+               setMapEntryValue(mapEntryMetaData, parent, owner);
+            }
+         }
+
+         // the wildcard this element is a content of
+         WildcardBinding wildcard = null;
+         if(parentTerm != null && !parentTerm.isModelGroup())
+         {
+            ElementBinding parentElement = (ElementBinding)parentTerm;
+            TypeBinding parentType = parentElement.getType();
+            wildcard = parentType.getWildcard();
+            // there should be a better way of checking this
+            if(wildcard != null && parentType.getElement(qName) != null)
+            {
+               wildcard = null;
+            }
+         }
+
+         if(tryPut(owner, o, qName, term, trace))
+         {
+         }
+         else if(tryAdd(owner, o, qName, term, wildcard, trace))
+         {
+         }
+         else if (owner instanceof GenericValueContainer)
+         {
+            if (trace)
+            {
+               log.trace("setParent " + qName + " addChild");
+            }
+            ((GenericValueContainer) owner).addChild(qName, o);
+         }
+         else if (owner instanceof Collection)
+         {
+            if (trace)
+            {
+               log.trace("setParent " + qName + " collection.add()");
+            }
+            ((Collection) owner).add(o);
+         }
+         else
+         {
+            PropertyMetaData propertyMetaData = wildcard == null ? null : wildcard.getPropertyMetaData();
+            if (propertyMetaData == null)
+            {
+               propertyMetaData = term.getPropertyMetaData();
+            }
+
+            String propName = null;
+            String colType = null;
+            if (propertyMetaData != null)
+            {
+               propName = propertyMetaData.getName();
+               colType = propertyMetaData.getCollectionType();
+            }
+
+            if (propName == null)
+            {
+               propName = Util.xmlNameToFieldName(qName.getLocalPart(), term.getSchema().isIgnoreLowLine());
+            }
+
+            if (trace)
+            {
+               log.trace("setParent " + qName + " metadata set " + propName);
+            }
+
+            /*if(particle.isRepeatable())
+            {
+               RtUtil.add(owner, o, propName, colType,
+                  term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+                  term.getValueAdapter()
+               );
+            }
+            else
+            {*/
+               RtUtil.set(owner, o, propName, colType,
+                     term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+                     term.getValueAdapter());
+            //}
+         }
+      }
+   }
+
+   public Object endParticle(Object o, QName elementName, ParticleBinding particle)
+   {
+      TermBinding term = particle.getTerm();
+      if(term.isSkip())
+      {
+         return o;
+      }
+
+      boolean trace = log.isTraceEnabled();
+      if(trace)
+      {
+         log.trace("endParticle " + elementName + " object=" + o + " term=" + term);
+      }
+
+      if(o instanceof GenericValueContainer)
+      {
+         try
+         {
+            if(trace)
+            {
+               log.trace("endParticle " + elementName + " instantiate()");
+            }
+            o = ((GenericValueContainer)o).instantiate();
+         }
+         catch(JBossXBRuntimeException e)
+         {
+            throw e;
+         }
+         catch(RuntimeException e)
+         {
+            throw new JBossXBRuntimeException("Container failed to create an instance for " +
+               elementName +
+               ": " + e.getMessage(), e
+            );
+         }
+      }
+
+      return o;
+   }
+
+   // Private
+
+   private Object startElement(Object parent, QName elementName, ParticleBinding particle)
+   {
+      TermBinding term = particle.getTerm();
+      if(term.isSkip())
+      {
+         return parent;
+      }
+
+      boolean trace = log.isTraceEnabled();
+      if(trace)
+      {
+         log.trace("startElement " + elementName + " parent=" + parent + " term=" + term);
+      }
+
+      ClassMetaData classMetaData = term.getClassMetaData();
+      MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
+
+      if(!term.isModelGroup())
+      {
+         TypeBinding type = ((ElementBinding)term).getType();
+         if(type.isSimple() ||
+               classMetaData == null && mapEntryMetaData == null &&
+               (!type.isStartElementCreatesObject() ||
+                     Constants.QNAME_ANYTYPE.equals(type.getQName())))
+         {
+            if(trace)
+            {
+               log.trace("startElement " + elementName + " does not create an object");
+            }
+            return null;
+         }
+      }
+
+      // if addMethod is specified, it's probably some collection field
+      // but should not be set as a property. Instead, items are added to it using the addMethod
+      ElementBinding arrayItem = null;
+      if(!term.isModelGroup())
+      {
+         TypeBinding type = ((ElementBinding)term).getType();
+         if(type.getAttributes().isEmpty())
+         {
+            ParticleBinding typeParticle = type.getParticle();
+            ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
+            arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
+
+            // todo refactor later (move it to modelGroup.getArrayItem()?)
+            if(arrayItem != null &&
+               (arrayItem.isSkip() ||
+               arrayItem.getMapEntryMetaData() != null ||
+               arrayItem.getPutMethodMetaData() != null ||
+               arrayItem.getAddMethodMetaData() != null
+               ))
+            {
+               arrayItem = null;
+            }
+         }
+      }
+
+      if(arrayItem != null)
+      {
+         Class wrapperType = null;
+         if(classMetaData != null)
+         {
+            wrapperType = loadClassForTerm(classMetaData.getImpl(),
+               term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+               elementName
+            );
+
+            if(GenericValueContainer.class.isAssignableFrom(wrapperType) ||
+               Collection.class.isAssignableFrom(wrapperType) ||
+               Map.class.isAssignableFrom(wrapperType))
+            {
+               return newInstance(wrapperType, elementName, term.getSchema().isUseNoArgCtorIfFound());
+            }
+         }
+
+         if(wrapperType == null && parent == null)
+         {
+            Class itemType = classForElement(arrayItem, null);
+            if(itemType != null)
+            {
+               if(trace)
+               {
+                  log.trace("startElement " + elementName + " new array " + itemType.getName());
+               }
+               return GenericValueContainer.FACTORY.array(itemType);
+            }
+         }
+         else
+         {
+            PropertyMetaData propertyMetaData = wrapperType == null ?
+               term.getPropertyMetaData() : arrayItem.getPropertyMetaData();
+
+            String propName;
+            if(propertyMetaData == null)
+            {
+               propName = Util.xmlNameToFieldName(
+                  wrapperType == null ? elementName.getLocalPart() : arrayItem.getQName().getLocalPart(),
+                  term.getSchema().isIgnoreLowLine()
+               );
+            }
+            else
+            {
+               propName = propertyMetaData.getName();
+            }
+
+            if(trace)
+            {
+               log.trace("startElement " + elementName + " property=" + propName);
+            }
+
+            Class parentClass = wrapperType;
+            if(wrapperType == null)
+            {
+               if(parent instanceof GenericValueContainer)
+               {
+                  parentClass = ((GenericValueContainer)parent).getTargetClass();
+               }
+               else if(parent instanceof ValueList)
+               {
+                  parentClass = ((ValueList)parent).getTargetClass();
+               }
+               else
+               {
+                  parentClass = parent.getClass();
+               }
+            }
+
+            Class fieldType = null;
+            if(parentClass.isArray())
+            {
+               fieldType = parentClass.getComponentType();
+            }
+            else
+            {
+               //fieldType = FieldInfo.getFieldInfo(parentClass, propName, true).getType();
+               // this was changed to false because allow overriding of handler.setParent()
+               // with an interceptor.add(). See CollectionOverridePropertyUnitTestCase
+               // In other words, don't treat it as an array wrapper.
+               FieldInfo fieldInfo = FieldInfo.getFieldInfo(parentClass, propName, false);
+               if(fieldInfo != null)
+               {
+                  fieldType = fieldInfo.getType();
+                  if (particle.isRepeatable() && fieldType.isArray())
+                  {
+                     fieldType = fieldType.getComponentType();
+                  }
+               }
+               else if(arrayItem.getInterceptors().isEmpty())
+               {
+                  QName typeName = ((ElementBinding)term).getType().getQName();
+                  throw new JBossXBRuntimeException(
+                        "Couldn't apply 'array wrapper' pattern for element " +
+                        elementName + " of type " +
+                        (typeName == null ? "anonymous" : typeName.toString()) +
+                        ": failed to resolve property " + propName +
+                        " and no interceptors applied to override handler.setParent(...)");
+               }
+            }
+
+            if(fieldType.isArray())
+            {
+               return GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType.getComponentType());
+            }
+            else if(Collection.class.isAssignableFrom(fieldType))
+            {
+               if (wrapperType == null)
+               {
+                  return new ValueListInitializer().newValueList(ValueListHandler.FACTORY.child(), Collection.class);
+                  //o = ArrayList();
+               }
+            }
+            else
+            {
+               return GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType);
+            }
+         }
+      }
+
+      Object o = null;
+         if(mapEntryMetaData != null)
+         {
+            if(mapEntryMetaData.getImpl() != null)
+            {
+               Class cls = loadClassForTerm(mapEntryMetaData.getImpl(),
+                  term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+                  elementName
+               );
+
+               if(trace)
+               {
+                  log.trace("startElement " + elementName + " new map entry " + cls.getName());
+               }
+
+               o = newInstance(cls, elementName, term.getSchema().isUseNoArgCtorIfFound());
+            }
+            else
+            {
+               o = new MapEntry();
+               if(trace)
+               {
+                  log.trace("startElement " + elementName + " new map entry");
+               }
+            }
+
+            if(mapEntryMetaData.isNonNullValue() && mapEntryMetaData.getValueType() != null)
+            {
+               Class mapValueType;
+               try
+               {
+                  mapValueType =
+                     Thread.currentThread().getContextClassLoader().loadClass(mapEntryMetaData.getValueType());
+               }
+               catch(ClassNotFoundException e)
+               {
+                  throw new JBossXBRuntimeException("startElement failed for " +
+                     elementName +
+                     ": failed to load class " +
+                     mapEntryMetaData.getValueType() +
+                     " for map entry value."
+                  );
+               }
+
+               Object value;
+               try
+               {
+                  if(trace)
+                  {
+                     log.trace("startElement " + elementName + " map value type " + mapEntryMetaData.getValueType());
+                  }
+                  value = mapValueType.newInstance();
+               }
+               catch(Exception e)
+               {
+                  throw new JBossXBRuntimeException("startElement failed for " +
+                     elementName +
+                     ": failed to create an instance of " +
+                     mapValueType +
+                     " for map entry value."
+                  );
+               }
+
+               if(o instanceof MapEntry)
+               {
+                  ((MapEntry)o).setValue(value);
+               }
+               else
+               {
+                  String getValueMethodName = mapEntryMetaData.getGetValueMethod();
+                  if(getValueMethodName == null)
+                  {
+                     getValueMethodName = "getValue";
+                  }
+
+                  String setValueMethodName = mapEntryMetaData.getSetValueMethod();
+                  if(setValueMethodName == null)
+                  {
+                     setValueMethodName = "setValue";
+                  }
+
+                  Method getValueMethod;
+                  try
+                  {
+                     getValueMethod = o.getClass().getMethod(getValueMethodName, null);
+                  }
+                  catch(NoSuchMethodException e)
+                  {
+                     throw new JBossXBRuntimeException("getValueMethod=" +
+                        getValueMethodName +
+                        " is not found in map entry " + o.getClass()
+                     );
+                  }
+
+                  Method setValueMethod;
+                  try
+                  {
+                     setValueMethod =
+                        o.getClass().getMethod(setValueMethodName, new Class[]{getValueMethod.getReturnType()});
+                  }
+                  catch(NoSuchMethodException e)
+                  {
+                     throw new JBossXBRuntimeException("setValueMethod=" +
+                        setValueMethodName +
+                        "(" +
+                        getValueMethod.getReturnType().getName() +
+                        " value) is not found in map entry " + o.getClass()
+                     );
+                  }
+
+                  try
+                  {
+                     setValueMethod.invoke(o, new Object[]{value});
+                  }
+                  catch(Exception e)
+                  {
+                     throw new JBossXBRuntimeException("setValueMethod=" +
+                        setValueMethodName +
+                        " failed: owner=" +
+                        o +
+                        ", value=" + value + ", msg=" + e.getMessage(), e
+                     );
+                  }
+               }
+            }
+         }
+         else
+         {
+            // todo: for now we require metadata for model groups to be bound
+            // todo 2: parent.getClass() is not going to work for containers
+            Class parentClass = null;
+            if(parent != null)
+            {
+               if(parent instanceof GenericValueContainer)
+               {
+                  parentClass = ((GenericValueContainer)parent).getTargetClass();
+               }
+               else if(parent instanceof ValueList)
+               {
+                  parentClass = ((ValueList)parent).getTargetClass();
+               }
+               else
+               {
+                  parentClass = parent.getClass();
+               }
+            }
+
+            Class cls;
+            if(term.isModelGroup())
+            {
+               if(classMetaData == null)
+               {
+                  throw new JBossXBRuntimeException(
+                     "Model groups should be annotated with 'class' annotation to be bound."
+                  );
+               }
+               cls = loadClassForTerm(classMetaData.getImpl(),
+                  term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+                  elementName
+               );
+            }
+            else
+            {
+               ElementBinding element = (ElementBinding)term;
+               cls = classForNonArrayItem(element, parentClass);
+               if(cls != null)
+               {
+                  // todo: before that, the type should be checked for required attributes and elements
+                  TypeBinding simpleType = element.getType().getSimpleType();
+                  if(simpleType != null)
+                  {
+                     Class simpleCls = classForSimpleType(simpleType, element.isNillable());
+                     if(cls.equals(simpleCls) ||
+                        cls.isPrimitive() && Classes.getPrimitiveWrapper(cls) == simpleCls ||
+                        simpleCls.isPrimitive() && Classes.getPrimitiveWrapper(simpleCls) == cls)
+                     {
+                        cls = null;
+                     }
+                  }
+               }
+            }
+
+            if(cls != null)
+            {
+               boolean noArgCtor;
+               if(classMetaData == null)
+               {
+                  noArgCtor = term.getSchema().isUseNoArgCtorIfFound();
+               }
+               else
+               {
+                  Boolean termUsesNoArgCtor = classMetaData.isUseNoArgCtor();
+                  noArgCtor = termUsesNoArgCtor == null ?
+                     term.getSchema().isUseNoArgCtorIfFound() : termUsesNoArgCtor.booleanValue();               }
+
+               if(trace)
+               {
+                  log.trace("startElement " + elementName + " new " + cls.getName() + ", noArgCtor=" + noArgCtor);
+               }
+               o = newInstance(cls, elementName, noArgCtor);
+            }
+         }
+
+      return o;
+   }
+
+   private void attributes(Object o,
+                           QName elementName,
+                           ElementBinding element,
+                           Attributes attrs,
+                           NamespaceContext nsCtx)
+   {
+      TypeBinding type = element.getType();
+      for(int i = 0; i < attrs.getLength(); ++i)
+      {
+         QName attrName = new QName(attrs.getURI(i), attrs.getLocalName(i));
+         AttributeBinding binding = type.getAttribute(attrName);
+         if(binding != null)
+         {
+            AttributeHandler handler = binding.getHandler();
+            if(handler != null)
+            {
+               Object value = handler.unmarshal(elementName, attrName, binding, nsCtx, attrs.getValue(i));
+               handler.attribute(elementName, attrName, binding, o, value);
+            }
+            else
+            {
+               throw new JBossXBRuntimeException(
+                  "Attribute binding present but has no handler: element=" + elementName + ", attrinute=" + attrName
+               );
+            }
+         }
+         else
+         {
+            if(!Constants.NS_XML_SCHEMA_INSTANCE.equals(attrs.getURI(i)))
+            {
+               CharactersHandler simpleType = type.getCharactersHandler();
+               Object value;
+               if(simpleType == null)
+               {
+                  value = attrs.getValue(i);
+                  RtUtil.set(o, attrName, value, element.getSchema().isIgnoreLowLine());
+               }
+            }
+         }
+      }
+   }
+
+   private boolean tryAdd(Object owner,
+                          Object o,
+                          QName qName,
+                          TermBinding term,
+                          WildcardBinding wildcard,
+                          boolean trace)
+   {
+      AddMethodMetaData addMetaData = wildcard == null ? null : wildcard.getAddMethodMetaData();
+      if(addMetaData == null)
+      {
+         addMetaData = term.getAddMethodMetaData();
+      }
+
+      if(addMetaData == null)
+      {
+         return false;
+      }
+
+      if(trace)
+      {
+         log.trace("setParent " + qName + " add");
+      }
+      invokeAdd(qName, addMetaData, owner, o);
+      return true;
+   }
+
+   private boolean tryPut(Object owner, Object o, QName qName, TermBinding term, boolean trace)
+   {
+      if(term.getPutMethodMetaData() != null ||
+         term.getMapEntryMetaData() != null && owner instanceof Map)
+      {
+         if(trace)
+         {
+            log.trace("setParent " + qName + " mapPut");
+         }
+         invokePut(qName, term, owner, o);
+         return true;
+      }
+      return false;
+   }
+
+   private Class classForElement(ElementBinding element, Class parentClass)
+   {
+      Class cls;
+      TypeBinding type = element.getType();
+      QName typeQName = type.getQName();
+      if(typeQName != null && Constants.NS_XML_SCHEMA.equals(typeQName.getNamespaceURI()))
+      {
+         cls = SimpleTypeBindings.classForType(type.getQName().getLocalPart(), element.isNillable());
+      }
+      else
+      {
+         ElementBinding arrayItem = null;
+         if(!type.isSimple() && type.getAttributes().isEmpty())
+         {
+            ParticleBinding typeParticle = type.getParticle();
+            ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
+            arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
+         }
+
+         if(arrayItem != null)
+         {
+            cls = classForElement(arrayItem, parentClass);
+            // todo: what's the best way to get an array class having the item class
+            cls = Array.newInstance(cls, 0).getClass();
+         }
+         else
+         {
+            cls = classForNonArrayItem(element, parentClass);
+         }
+      }
+      return cls;
+   }
+
+   private static void setMapEntryValue(MapEntryMetaData mapEntryMetaData, Object parent, Object o)
+   {
+      String getValueMethodName = mapEntryMetaData.getGetValueMethod();
+      if(getValueMethodName == null)
+      {
+         getValueMethodName = "getValue";
+      }
+
+      String setValueMethodName = mapEntryMetaData.getSetValueMethod();
+      if(setValueMethodName == null)
+      {
+         setValueMethodName = "setValue";
+      }
+
+      Class parentCls = parent.getClass();
+      Method setValueMethod = getSetMethod(parentCls, getValueMethodName, setValueMethodName);
+      invokeSetter(setValueMethod, parent, o, setValueMethodName);
+   }
+
+   private static void invokeSetter(Method setValueMethod, Object parent, Object o, String setValueMethodName)
+   {
+      try
+      {
+         setValueMethod.invoke(parent, new Object[]{o});
+      }
+      catch(Exception e)
+      {
+         throw new JBossXBRuntimeException("Failed to invoke " +
+            setValueMethodName +
+            " on " +
+            parent +
+            " with parameter " +
+            o +
+            ": " +
+            e.getMessage()
+         );
+      }
+   }
+
+   private static Method getSetMethod(Class cls, String getMethodName, String setMethodName)
+   {
+      Method getKeyMethod;
+      try
+      {
+         getKeyMethod = cls.getMethod(getMethodName, null);
+      }
+      catch(NoSuchMethodException e)
+      {
+         throw new JBossXBRuntimeException("Method " + getMethodName + " not found in " + cls);
+      }
+
+      Method setKeyMethod;
+      try
+      {
+         setKeyMethod = cls.getMethod(setMethodName, new Class[]{getKeyMethod.getReturnType()});
+      }
+      catch(NoSuchMethodException e)
+      {
+         throw new JBossXBRuntimeException("Method " +
+            setMethodName +
+            "(" +
+            getKeyMethod.getReturnType().getName() +
+            " p) not found in " +
+            cls
+         );
+      }
+      return setKeyMethod;
+   }
+
+   private static MapEntryMetaData getMapEntryMetaData(TermBinding term, QName qName)
+   {
+      MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
+      if(mapEntryMetaData == null)
+      {
+         String msg;
+         if(term.isModelGroup())
+         {
+            msg = "Term " +
+               qName +
+               " bound as map entry key or value but map entry metadata is not available for its parent term.";
+         }
+         else
+         {
+            ElementBinding element = (ElementBinding)term;
+            msg = "Element " +
+               qName +
+               " bound as map entry key or value but map entry metadata is not available for its parent element nor its " +
+               (element.getType().getQName() == null ?
+               "annonymous" :
+               element.getType().getQName().toString()
+               ) +
+               " type.";
+         }
+         throw new JBossXBRuntimeException(msg);
+      }
+      return mapEntryMetaData;
+   }
+
+   private static Object newInstance(Class cls, QName elementName, boolean useNoArgCtorIfFound)
+   {
+      Object o;
+      if(cls.isArray())
+      {
+         o = GenericValueContainer.FACTORY.array(cls.getComponentType());
+      }
+      else
+      {
+         Constructor[] ctors = cls.getConstructors();
+         if(ctors.length == 0)
+         {
+            throw new JBossXBRuntimeException(
+               "Class " + cls.getName() + " has no public constructors or the class reflects a primitive type or void"
+            );
+         }
+
+         if(useNoArgCtorIfFound)
+         {
+            try
+            {
+               Constructor ctor = cls.getConstructor(null);
+               o = ctor.newInstance(null);
+            }
+            catch(NoSuchMethodException e)
+            {
+               o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
+            }
+            catch(Exception e)
+            {
+               throw new JBossXBRuntimeException("Failed to create an instance of " +
+                  cls +
+                  " using default constructor for element " +
+                  elementName + ": " + e.getMessage(), e
+               );
+            }
+         }
+         else if(ctors.length > 1 || ctors[0].getParameterTypes().length > 0)
+         {
+            o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
+         }
+         else
+         {
+            try
+            {
+               o = ctors[0].newInstance(null);
+            }
+            catch(Exception e)
+            {
+               throw new JBossXBRuntimeException("Failed to create an instance of " +
+                  cls +
+                  " using default constructor for element " +
+                  elementName + ": " + e.getMessage(), e
+               );
+            }
+         }
+      }
+      return o;
+   }
+
+   private static Class loadClassForTerm(String className,
+                                         boolean ignoreCNFE,
+                                         QName elementName)
+   {
+      if(className == null)
+      {
+         throw new JBossXBRuntimeException("No class for " + elementName);
+      }
+
+      Class cls = null;
+      try
+      {
+         cls = Thread.currentThread().getContextClassLoader().loadClass(className);
+      }
+      catch(ClassNotFoundException e)
+      {
+         if(ignoreCNFE)
+         {
+            if(log.isTraceEnabled())
+            {
+               log.trace("Failed to resolve class for element " +
+                  elementName +
+                  ": " +
+                  className
+               );
+            }
+         }
+         else
+         {
+            throw new JBossXBRuntimeException("Failed to resolve class name for " +
+               elementName +
+               ": " +
+               e.getMessage()
+            );
+         }
+      }
+      return cls;
+   }
+
+   private void invokeAdd(QName qName, AddMethodMetaData addMethodMetaData, Object owner, Object o)
+   {
+      Class valueType = Object.class;
+      if(addMethodMetaData.getValueType() != null)
+      {
+         try
+         {
+            valueType = Thread.currentThread().getContextClassLoader().
+               loadClass(addMethodMetaData.getValueType());
+         }
+         catch(ClassNotFoundException e)
+         {
+            throw new JBossXBRuntimeException("Failed to load value type for addMethod.name=" +
+               addMethodMetaData.getMethodName() +
+               ", valueType=" +
+               addMethodMetaData.getValueType() +
+               ": " + e.getMessage(), e
+            );
+         }
+      }
+      else if(addMethodMetaData.isChildType())
+      {
+         if(o == null)
+         {
+            throw new JBossXBRuntimeException("addMethod=" +
+               addMethodMetaData.getMethodName() +
+               " for element " +
+               qName +
+               " is configured with valueType='child'. The valueType cannot be determined because" +
+               " the child is null"
+            );
+         }
+         valueType = o.getClass();
+      }
+
+      Class ownerClass = owner.getClass();
+      Method addMethod;
+      try
+      {
+         addMethod = ownerClass.getMethod(addMethodMetaData.getMethodName(), new Class[]{valueType});
+      }
+      catch(NoSuchMethodException e)
+      {
+         throw new JBossXBRuntimeException("Failed to find addMethod.name=" +
+            addMethodMetaData.getMethodName() +
+            ", addMethod.valueType=" +
+            valueType.getName() +
+            " in class " +
+            ownerClass.getName() +
+            ": " +
+            e.getMessage(), e
+         );
+      }
+
+      try
+      {
+         addMethod.invoke(owner, new Object[]{o});
+      }
+      catch(Exception e)
+      {
+         throw new JBossXBRuntimeException("setParent failed for " +
+            qName +
+            "=" +
+            o +
+            ": addMethod=" +
+            addMethodMetaData.getMethodName() +
+            " threw an exception for owner=" +
+            owner +
+            ", value=" +
+            o +
+            ": " +
+            e.getMessage(),
+            e
+         );
+      }
+   }
+
+   private void invokePut(QName qName, TermBinding term, Object owner, Object o)
+   {
+      PutMethodMetaData putMethodMetaData = term.getPutMethodMetaData();
+
+      MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
+      if(mapEntryMetaData == null)
+      {
+         throw new JBossXBRuntimeException((putMethodMetaData == null ?
+            "Parent object is an instance of java.util.Map" :
+            "putMethod is specified for element " + qName
+            ) +
+            " but mapEntry is specified for neither element " +
+            qName +
+            " nor it's type."
+         );
+      }
+
+      Class oClass = o.getClass();
+      String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
+      if(getKeyMethodName == null)
+      {
+         getKeyMethodName = "getKey";
+      }
+
+      Method keyMethod;
+      try
+      {
+         keyMethod = oClass.getMethod(getKeyMethodName, null);
+      }
+      catch(NoSuchMethodException e)
+      {
+         throw new JBossXBRuntimeException("setParent failed for " +
+            qName +
+            "=" +
+            o +
+            ": getKeyMethod=" +
+            getKeyMethodName +
+            " not found in " + oClass
+         );
+      }
+
+      Object key;
+      try
+      {
+         key = keyMethod.invoke(o, null);
+      }
+      catch(Exception e)
+      {
+         throw new JBossXBRuntimeException("setParent failed for " +
+            qName +
+            "=" +
+            o +
+            ": getKeyMethod=" +
+            getKeyMethodName +
+            " threw an exception: " + e.getMessage(), e
+         );
+      }
+
+      Class keyType = Object.class;
+      Class valueType = Object.class;
+      String putMethodName = "put";
+      Class ownerClass = owner.getClass();
+
+      if(putMethodMetaData != null)
+      {
+         if(putMethodMetaData.getKeyType() != null)
+         {
+            try
+            {
+               keyType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getKeyType());
+            }
+            catch(ClassNotFoundException e)
+            {
+               throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
+            }
+         }
+
+         if(putMethodMetaData.getValueType() != null)
+         {
+            try
+            {
+               valueType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getValueType());
+            }
+            catch(ClassNotFoundException e)
+            {
+               throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
+            }
+         }
+
+         String name = putMethodMetaData.getName();
+         if(name != null)
+         {
+            putMethodName = name;
+         }
+      }
+
+      Method putMethod;
+      try
+      {
+         putMethod = ownerClass.getMethod(putMethodName, new Class[]{keyType, valueType});
+      }
+      catch(NoSuchMethodException e)
+      {
+         throw new JBossXBRuntimeException("setParent failed for " +
+            qName +
+            "=" +
+            o +
+            ": putMethod=" +
+            putMethodName +
+            "(" + keyType.getName() + " key, " + valueType.getName() + " value) not found in " + ownerClass
+         );
+      }
+
+      Object value = o;
+      String valueMethodName = mapEntryMetaData.getGetValueMethod();
+      if(valueMethodName != null)
+      {
+         Method valueMethod;
+         try
+         {
+            valueMethod = oClass.getMethod(valueMethodName, null);
+         }
+         catch(NoSuchMethodException e)
+         {
+            throw new JBossXBRuntimeException("setParent failed for " +
+               qName +
+               "=" +
+               o +
+               ": getValueMethod=" +
+               mapEntryMetaData.getGetValueMethod() +
+               " not found in " + oClass
+            );
+         }
+
+         try
+         {
+            value = valueMethod.invoke(o, null);
+         }
+         catch(Exception e)
+         {
+            throw new JBossXBRuntimeException("setParent failed for " +
+               qName +
+               "=" +
+               o +
+               ": getValueMethod=" +
+               mapEntryMetaData.getGetValueMethod() +
+               " threw an exception: " + e.getMessage(), e
+            );
+         }
+      }
+      else if(o instanceof MapEntry)
+      {
+         value = ((MapEntry)o).getValue();
+      }
+
+      try
+      {
+         putMethod.invoke(owner, new Object[]{key, value});
+      }
+      catch(Exception e)
+      {
+         throw new JBossXBRuntimeException("setParent failed for " +
+            qName +
+            "=" +
+            o +
+            ": putMethod=" +
+            putMethodName +
+            " threw an exception for owner=" +
+            owner +
+            ", key=" +
+            key +
+            ", value=" +
+            value +
+            ": " +
+            e.getMessage(),
+            e
+         );
+      }
+   }
+
+   private Class classForNonArrayItem(ElementBinding element, Class parentClass)
+   {
+      String clsName;
+
+      // first, class metadata and map entry metadata
+      ClassMetaData clsMetaData = element.getClassMetaData();
+      clsName = clsMetaData == null ? null : clsMetaData.getImpl();
+      if(clsName == null)
+      {
+         MapEntryMetaData mapEntryMetaData = element.getMapEntryMetaData();
+         if(mapEntryMetaData != null)
+         {
+            clsName = mapEntryMetaData.getImpl();
+            if(clsName == null)
+            {
+               clsName = MapEntry.class.getName();
+            }
+         }
+      }
+
+      // second, property metadata and property type
+      if(clsName == null)
+      {
+         if(parentClass == null)
+         {
+            clsName = classFromQName(element);
+         }
+         else
+         {
+            PropertyMetaData propertyMetaData = element.getPropertyMetaData();
+            String propName = propertyMetaData == null ? null : propertyMetaData.getName();
+            if(propName == null)
+            {
+               // if there is add or put method metadata then fallback to XML-name-to-class-name algorithm
+               if(element.getAddMethodMetaData() == null && element.getPutMethodMetaData() == null)
+               {
+                  propName =
+                     Util.xmlNameToFieldName(element.getQName().getLocalPart(), element.getSchema().isIgnoreLowLine());
+               }
+            }
+
+            if(propName != null)
+            {
+               FieldInfo fieldInfo = FieldInfo.getFieldInfo(parentClass, propName, false);
+               Class fieldType = fieldInfo == null ? null : fieldInfo.getType();
+
+               if(fieldType == null ||
+                  Modifier.isAbstract(fieldType.getModifiers()) ||
+                  Modifier.isInterface(fieldType.getModifiers()) ||
+                  fieldType.isArray() ||
+                  Collection.class.isAssignableFrom(fieldType))
+               {
+                  clsName = classFromQName(element);
+               }
+               else
+               {
+                  return fieldType;
+               }
+            }
+         }
+      }
+
+      return loadClassForTerm(clsName, element.getSchema().isIgnoreUnresolvedFieldOrClass(), element.getQName());
+   }
+
+   private String classFromQName(ElementBinding element)
+   {
+      String clsName;
+      QName typeBase = element.getType().getQName();
+      if(typeBase == null)
+      {
+         typeBase = element.getQName();
+      }
+
+      SchemaBinding schema = element.getSchema();
+      PackageMetaData pkgMetaData = schema.getPackageMetaData();
+      if(pkgMetaData == null)
+      {
+         clsName =
+            Util.xmlNameToClassName(typeBase.getNamespaceURI(),
+               typeBase.getLocalPart(),
+               schema.isIgnoreLowLine()
+            );
+      }
+      else
+      {
+         String pkg = pkgMetaData.getName();
+         clsName =
+            pkg == null || pkg.length() == 0 ?
+            Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine()) :
+            pkg + "." + Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine());
+      }
+      return clsName;
+   }
+
+   private static Class classForSimpleType(TypeBinding type, boolean nillable)
+   {
+      ValueMetaData valueMetaData = type.getValueMetaData();
+      if(valueMetaData != null && valueMetaData.getUnmarshalMethod() != null)
+      {
+         return RtUtil.getUnmarshalMethod(type.getQName(), valueMetaData).getReturnType();
+      }
+      else if(type.getClassMetaData() != null && type.getClassMetaData().getImpl() != null)
+      {
+         return RtUtil.loadClass(type.getClassMetaData().getImpl(), true);
+      }
+
+      TypeBinding itemType = type.getItemType();
+      if(itemType != null)
+      {
+         if(type.getSchemaBinding().isUnmarshalListsToArrays())
+         {
+            // todo: nillable not always should be propagated to the item
+            Class itemClass = classForSimpleType(itemType, nillable);
+            return Array.newInstance(itemClass, 0).getClass();
+         }
+         else
+         {
+            return java.util.List.class;
+         }
+      }
+      else
+      {
+         QName qName = type.getQName();
+         if(qName != null && Constants.NS_XML_SCHEMA.equals(qName.getNamespaceURI()))
+         {
+            return SimpleTypeBindings.classForType(qName.getLocalPart(), nillable);
+         }
+         else
+         {
+            TypeBinding baseType = type.getBaseType();
+            if(baseType == null)
+            {
+               throw new JBossXBRuntimeException("Expected a base type here.");
+            }
+
+            return classForSimpleType(baseType, nillable);
+         }
+      }
+   }
+}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java (from rev 2434, jbossxb/branches/1_0/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,220 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.xml;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import junit.framework.TestSuite;
+
+import org.jboss.xb.binding.ObjectModelFactory;
+import org.jboss.xb.binding.Unmarshaller;
+import org.jboss.xb.binding.UnmarshallerFactory;
+import org.jboss.xb.binding.UnmarshallingContext;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.sunday.marshalling.MarshallerImpl;
+import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.XsdBinder;
+import org.xml.sax.Attributes;
+
+
+/**
+ * IgnorableWhitespaceUnitTestCase.
+ * 
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision$
+ */
+public class IgnorableWhitespaceUnitTestCase extends AbstractJBossXBTest
+{
+   private static final String NS = "http://www.jboss.org/test/xml/simpleContent";
+ 
+   private static final String XSD =
+      "<?xml version='1.0' encoding='UTF-8'?>" +
+      "<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'" +
+      " targetNamespace='http://www.jboss.org/test/xml/simpleContent'" +
+      " xmlns='http://www.jboss.org/test/xml/simpleContent'" +
+      " elementFormDefault='qualified'" +
+      " attributeFormDefault='unqualified'" +
+      " version='1.0'>" +
+      " <xsd:element name='top'>" +
+      "  <xsd:complexType>" +
+      "   <xsd:sequence>" +
+      "    <xsd:element name='string' type='myString' minOccurs='0' maxOccurs='unbounded'/>" +
+      "   </xsd:sequence>" +
+      "  </xsd:complexType>" +
+      " </xsd:element>" +
+      " <xsd:complexType name='myString'>" +
+      "  <xsd:simpleContent>" +
+      "   <xsd:extension base='xsd:string'>" +
+      "    <xsd:attribute name='id' type='xsd:ID'/>" +
+      "   </xsd:extension>" +
+      "  </xsd:simpleContent>" +
+      " </xsd:complexType>" +
+      "</xsd:schema>";
+
+   public static final TestSuite suite()
+   {
+      return new TestSuite(IgnorableWhitespaceUnitTestCase.class);
+   }
+   
+   public IgnorableWhitespaceUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testWhitespaceUnmarshalling() throws Exception
+   {
+      SchemaBinding schema = XsdBinder.bind(new StringReader(XSD), null);
+
+      schema.setIgnoreUnresolvedFieldOrClass(false);
+      schema.setIgnoreWhitespacesInMixedContent(false);
+
+      ClassMetaData classMetaData = new ClassMetaData();
+      classMetaData.setImpl(Top.class.getName());
+      ElementBinding element = schema.getElement(new QName(NS, "top"));
+      assertNotNull(element);
+      element.setClassMetaData(classMetaData);
+      
+      Top top = (Top) unmarshal("IgnorableWhitespaceContent.xml", schema, Top.class);
+      assertNotNull(top.string);
+      assertEquals(2, top.string.size());
+      assertEquals(" ", top.string.get(0));
+      assertEquals("\n      newline, 6 spaces, newline, 3 spaces\n   ", top.string.get(1));
+   }
+
+   public void testWhitespaceMarshalling() throws Exception
+   {
+      SchemaBinding schema = XsdBinder.bind(new StringReader(XSD), null);
+
+      schema.setIgnoreUnresolvedFieldOrClass(false);
+      schema.setIgnoreWhitespacesInMixedContent(false);
+
+      ClassMetaData classMetaData = new ClassMetaData();
+      classMetaData.setImpl(Top.class.getName());
+      ElementBinding element = schema.getElement(new QName(NS, "top"));
+      assertNotNull(element);
+      element.setClassMetaData(classMetaData);
+      
+      Top top = new Top();
+      top.string = new ArrayList();
+      top.string.add(" ");
+      top.string.add("\n      newline, 6 spaces, newline, 3 spaces\n   ");
+      MarshallerImpl marshaller = new MarshallerImpl();
+      StringWriter writer = new StringWriter();
+      marshaller.marshal(schema, null, top, writer);
+      
+      // TODO: the xml diff trims whitespaces...
+      //assertXmlFileContent("IgnorableWhitespaceContent.xml", writer.getBuffer().toString());
+      //System.out.println(writer.getBuffer().toString());
+      
+      Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
+      Object o = unmarshaller.unmarshal(new StringReader(writer.getBuffer().toString()), schema);
+      
+      assertEquals(top, o);
+   }
+
+   public void testObjectModelFactory() throws Exception
+   {
+      String url = findXML("IgnorableWhitespaceContent.xml");
+      
+      ObjectModelFactory omf = new OMF();
+      
+      Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
+      Object o = unmarshaller.unmarshal(url, omf, null);
+      
+      assertNotNull(o);
+      assertTrue(o instanceof Top);
+      Top top = (Top) o;
+      assertEquals(2, top.string.size());
+      assertEquals(" ", top.string.get(0));
+      assertEquals("\n      newline, 6 spaces, newline, 3 spaces\n   ", top.string.get(1));
+
+   }
+   
+   public static final class OMF implements ObjectModelFactory
+   {
+      public Object completeRoot(Object root, UnmarshallingContext ctx, String namespaceURI, String localName)
+      {
+         return root;
+      }
+
+      public Object newRoot(Object root, UnmarshallingContext ctx, String namespaceURI, String localName, Attributes attrs)
+      {
+         ctx.setTrimTextContent(false);
+         return new Top();
+      }
+
+      public void setValue(Top top, UnmarshallingContext ctx, String ns, String name, String value)
+      {
+         if(name.equals("string"))
+         {
+            if(top.string == null)
+            {
+               top.string = new ArrayList();
+            }
+            top.string.add(value);
+         }
+      }
+   }
+
+   public static class Top
+   {
+      public List string;
+
+      public int hashCode()
+      {
+         final int PRIME = 31;
+         int result = 1;
+         result = PRIME * result + ((string == null) ? 0 : string.hashCode());
+         return result;
+      }
+
+      public boolean equals(Object obj)
+      {
+         if (this == obj)
+            return true;
+         if (obj == null)
+            return false;
+         if (getClass() != obj.getClass())
+            return false;
+         final Top other = (Top) obj;
+         if (string == null)
+         {
+            if (other.string != null)
+               return false;
+         }
+         else if (!string.equals(other.string))
+            return false;
+         return true;
+      }
+      
+      public String toString()
+      {
+         return "[top: string=" + string + "]";
+      }
+   }
+}

Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java
===================================================================
--- jbossxb/branches/1_0/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java	2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,119 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.test.xml.pojoserver.metadata;
-
-import java.util.Map;
-import java.util.Iterator;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-
-/**
- * @author Scott.Stark at jboss.org
- * @version $Revision: 37406 $
- */
-public class AbstractFeatureMetaData
-   implements FeatureMetaData
-{
-   /** The description */
-   protected String description;
-
-   /** The generic metadata */
-   protected Map values;
-   
-   // Static --------------------------------------------------------
-   
-   // Constructors --------------------------------------------------
-
-   /**
-    * Create a new meta data
-    */
-   public AbstractFeatureMetaData()
-   {
-   }
-   
-   // Public --------------------------------------------------------
-   
-   /**
-    * Set the description.
-    * 
-    * @param description the description.
-    */
-   public void setDescription(String description)
-   {
-      this.description = description;
-   }
-
-   /**
-    * Set the value.
-    * 
-    * @param key the key to the value
-    * @param value The value to set.
-    */
-   public void setValue(String key, Object value)
-   {
-      if (values == null)
-         values = new ConcurrentReaderHashMap();
-      values.put(key, value);
-   }
-
-   // MetaData implementation ---------------------------------------
-   
-   public String getDescription()
-   {
-      return description;
-   }
-  
-   public Object getValue(String key)
-   {
-      if (values == null)
-         return null;
-      return values.get(key);
-   }
-
-   // MetaDataVisitorNote overrides ----------------------------------
-
-   public void visit(MetaDataVisitor visitor)
-   {
-      visitor.visit(this);
-   }
-   
-   public Iterator getChildren()
-   {
-      return null;
-   }
-   
-   // JBossObject overrides ------------------------------------------
-   
-   public void toString(StringBuffer buffer)
-   {
-      if (description != null)
-         buffer.append("description=").append(description);
-      if (values != null)
-         buffer.append(" values=").append(values);
-   }
-   
-   public void toShortString(StringBuffer buffer)
-   {
-      buffer.append(description);
-   }
-
-}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java (from rev 2482, jbossxb/branches/1_0/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,119 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.test.xml.pojoserver.metadata;
+
+import java.util.Map;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 37406 $
+ */
+public class AbstractFeatureMetaData
+   implements FeatureMetaData
+{
+   /** The description */
+   protected String description;
+
+   /** The generic metadata */
+   protected Map values;
+   
+   // Static --------------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+
+   /**
+    * Create a new meta data
+    */
+   public AbstractFeatureMetaData()
+   {
+   }
+   
+   // Public --------------------------------------------------------
+   
+   /**
+    * Set the description.
+    * 
+    * @param description the description.
+    */
+   public void setDescription(String description)
+   {
+      this.description = description;
+   }
+
+   /**
+    * Set the value.
+    * 
+    * @param key the key to the value
+    * @param value The value to set.
+    */
+   public void setValue(String key, Object value)
+   {
+      if (values == null)
+         values = new ConcurrentHashMap();
+      values.put(key, value);
+   }
+
+   // MetaData implementation ---------------------------------------
+   
+   public String getDescription()
+   {
+      return description;
+   }
+  
+   public Object getValue(String key)
+   {
+      if (values == null)
+         return null;
+      return values.get(key);
+   }
+
+   // MetaDataVisitorNote overrides ----------------------------------
+
+   public void visit(MetaDataVisitor visitor)
+   {
+      visitor.visit(this);
+   }
+   
+   public Iterator getChildren()
+   {
+      return null;
+   }
+   
+   // JBossObject overrides ------------------------------------------
+   
+   public void toString(StringBuffer buffer)
+   {
+      if (description != null)
+         buffer.append("description=").append(description);
+      if (values != null)
+         buffer.append(" values=").append(values);
+   }
+   
+   public void toShortString(StringBuffer buffer)
+   {
+      buffer.append(description);
+   }
+
+}

Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml (from rev 2420, jbossxb/branches/1_0/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml	                        (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml	2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<top xmlns='http://www.jboss.org/test/xml/simpleContent'>
+   <string> </string>
+   <string>
+      newline, 6 spaces, newline, 3 spaces
+   </string>
+</top>




More information about the jboss-svn-commits mailing list