[jboss-svn-commits] JBoss Common SVN: r3947 - in jbossxb/trunk/src/main/java/org/jboss/xb: binding/sunday/unmarshalling/impl/runtime and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jan 22 06:24:13 EST 2010


Author: alex.loubyansky at jboss.com
Date: 2010-01-22 06:24:12 -0500 (Fri, 22 Jan 2010)
New Revision: 3947

Added:
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AbstractPosition.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandlerFactory.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementPosition.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/NonElementPosition.java
Removed:
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/position/
Modified:
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandler.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/DefaultHandlers.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SimpleTypeBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TermBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
   jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtCharactersHandler.java
   jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
Log:
type-specific CharactersHandler implementations for the XSD built-in types, removed Position and PositionFactory interface switching to AbstractPosition as the base class and referencing properties directly instead of getters/setters inside position class hierarchy

Added: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AbstractPosition.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AbstractPosition.java	                        (rev 0)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AbstractPosition.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -0,0 +1,211 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, 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 javax.xml.namespace.QName;
+
+import org.jboss.logging.Logger;
+import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.UnmarshallingContextImpl;
+import org.xml.sax.Attributes;
+
+/**
+ * A AbstractPosition.
+ * 
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractPosition
+{
+   protected static Logger log = Logger.getLogger(AbstractPosition.class);
+   protected static boolean trace;
+   
+   public static void resetTrace()
+   {
+      trace = log.isTraceEnabled();
+   }
+   
+   protected PositionStack stack;
+   protected final QName qName;
+   protected ParticleBinding particle;
+   protected ParticleHandler handler;
+   protected TypeBinding parentType;
+   protected Object o;
+   protected Object repeatableParticleValue;
+   protected RepeatableParticleHandler repeatableHandler;
+   protected boolean ended;
+   protected int occurrence;
+
+   protected AbstractPosition previous;
+   protected AbstractPosition next;
+   private AbstractPosition notSkippedParent;
+
+   protected AbstractPosition(QName qName, ParticleBinding particle)
+   {
+      if (particle == null)
+         throw new IllegalArgumentException("Null particle");
+      
+      if(qName == null)
+         throw new IllegalArgumentException("Null qName");
+      this.qName = qName;
+
+      this.particle = particle;
+      this.occurrence = 1;
+   }
+
+   public void setStack(PositionStack stack)
+   {
+      this.stack = stack;
+   }
+
+   public ParticleBinding getParticle()
+   {
+      return particle;
+   }
+
+   public AbstractPosition getPrevious()
+   {
+      return previous;
+   }
+
+   public Object getRepeatableParticleValue()
+   {
+      return repeatableParticleValue;
+   }
+
+   public Object getValue()
+   {
+      return o;
+   }
+
+   public boolean isEnded()
+   {
+      return ended;
+   }
+
+   public boolean isElement()
+   {
+      return false;
+   }
+
+   public void endRepeatableParticle()
+   {
+      if (trace)
+         log.trace(" end repeatable " + particle.getTerm());
+      repeatableHandler.endRepeatableParticle(previous.o, repeatableParticleValue, qName, particle, previous.particle);
+      repeatableParticleValue = null;
+      repeatableHandler = null;
+   }
+
+   public abstract void endParticle();
+   
+   public abstract void characters(char[] ch, int start, int length);
+   
+   public abstract ElementPosition startParticle(QName startName, Attributes atts);
+
+   protected void initValue(Attributes atts)
+   {
+      if(handler == null)
+         handler = getHandler();
+      Object parent = previous == null ? null : previous.o;
+      o = handler.startParticle(parent, qName, particle, atts, stack.getNamespaceRegistry());
+   }
+
+   protected void startRepeatableParticle()
+   {
+      if(trace)
+         log.trace(" start repeatable " + particle.getTerm());
+
+      RepeatableParticleHandler repeatableHandler = particle.getTerm().getRepeatableHandler();
+      // the way it is now it's never null
+      Object repeatableContainer = repeatableHandler.startRepeatableParticle(previous.o, qName, particle);
+      if(repeatableContainer != null)
+      {
+         if(this.repeatableParticleValue != null)
+            throw new IllegalStateException("Previous repeatable particle hasn't been ended yet!");
+         this.repeatableParticleValue = repeatableContainer;
+         this.repeatableHandler = repeatableHandler;
+      }
+   }
+
+   protected AbstractPosition notSkippedParent()
+   {
+      if(notSkippedParent != null)
+         return notSkippedParent;
+      
+      AbstractPosition position = previous;
+      AbstractPosition wildcardPosition = null;
+      while(position != null)
+      {
+         ParticleBinding particle = position.particle;
+         if(!particle.getTerm().isSkip() || position.repeatableParticleValue != null)
+         {
+            notSkippedParent = position;
+            return position;
+         }
+         else if(wildcardPosition != null)
+         {
+            notSkippedParent = wildcardPosition;
+            return wildcardPosition;
+         }
+
+         if(particle.getTerm().isWildcard())
+            wildcardPosition = position;
+         position = position.previous;
+      }
+      notSkippedParent = wildcardPosition;
+      return wildcardPosition;
+   }
+
+   protected void setParent(AbstractPosition parentPosition, ParticleHandler handler)
+   {
+      if(repeatableParticleValue != null)
+      {
+         repeatableHandler.addTermValue(repeatableParticleValue, o, qName, particle, parentPosition.particle, handler);
+      }
+      else if(parentPosition.repeatableParticleValue == null || !parentPosition.particle.getTerm().isSkip())
+      {
+         TermBeforeSetParentCallback beforeSetParent = particle.getTerm().getBeforeSetParentCallback();
+         if(beforeSetParent != null)
+         {
+            UnmarshallingContextImpl ctx = stack.getContext();
+            ctx.parent = parentPosition.o;
+            ctx.particle = particle;
+            ctx.parentParticle = notSkippedParent().particle;
+            o = beforeSetParent.beforeSetParent(o, ctx);
+            ctx.clear();
+         }
+         
+         handler.setParent(parentPosition.o, o, qName, particle, parentPosition.particle);
+      }
+      else
+         parentPosition.repeatableHandler.addTermValue(
+               parentPosition.repeatableParticleValue,
+               o, qName, particle,
+               parentPosition.particle, handler);
+   }
+
+   protected abstract ParticleHandler getHandler();
+   
+   protected abstract void repeatForChild(Attributes atts);
+   
+   protected abstract AbstractPosition nextPosition(QName startName, Attributes atts);
+}

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/AllBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -27,8 +27,6 @@
 import java.util.Collection;
 import javax.xml.namespace.QName;
 import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.sunday.unmarshalling.position.NonElementPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
 import org.xml.sax.Attributes;
 
 
@@ -79,12 +77,12 @@
       return elements.values();
    }
 
-   public Position newPosition(QName qName, Attributes attrs, ParticleBinding allParticle)
+   public AbstractPosition newPosition(QName qName, Attributes attrs, ParticleBinding allParticle)
    {
       ParticleBinding particle = elements.get(qName);
       if(particle != null)
       {
-         Position next = particle.getTerm().newPosition(qName, attrs, particle);
+         AbstractPosition next = particle.getTerm().newPosition(qName, attrs, particle);
          return new AllPosition(qName, allParticle, next);
       }
 
@@ -99,18 +97,18 @@
    
    private final class AllPosition extends NonElementPosition
    {
-      private AllPosition(QName name, ParticleBinding particle, Position next)
+      private AllPosition(QName name, ParticleBinding particle, AbstractPosition next)
       {
          super(name, particle, next);
       }
 
-      public Position nextPosition(QName qName, Attributes atts)
+      public AbstractPosition nextPosition(QName qName, Attributes atts)
       {
          ParticleBinding particle = elements.get(qName);
          if(particle != null)
          {
             next = particle.getTerm().newPosition(qName, atts, particle);
-            next.setPrevious(this);
+            next.previous = this;
             // TODO occurrence is not used here ++occurrence;
             return this;
          }

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandler.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandler.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandler.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -53,6 +53,17 @@
    {
    };
 
+   protected UnmarshalCharactersHandler unmarshalHandler = DEFAULT_UNMARSHAL_HANDLER;
+   
+   public CharactersHandler()
+   {
+   }
+   
+   public CharactersHandler(UnmarshalCharactersHandler unmarshalHandler)
+   {
+      this.unmarshalHandler = unmarshalHandler;
+   }
+   
    public Object unmarshalEmpty(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx, ValueMetaData valueMetaData)
    {
       if(typeBinding.isIgnoreEmptyString())
@@ -74,67 +85,90 @@
 
    public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx, ValueMetaData valueMetaData, String value)
    {
-      Object o;
-      QName typeQName = typeBinding.getQName();
-      TypeBinding itemType = typeBinding.getItemType();
-      if(itemType != null)
+      return unmarshalHandler.unmarshal(qName, typeBinding, nsCtx, valueMetaData, value);
+   }
+
+   public void setValue(QName qName, ElementBinding element, Object owner, Object value)
+   {
+   }
+   
+   public static interface UnmarshalCharactersHandler
+   {
+      Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx, ValueMetaData valueMetaData, String value);
+   }
+
+   public static class DefaultUnmarshalCharactersHandler implements UnmarshalCharactersHandler
+   {
+      public Object unmarshal(QName name, TypeBinding typeBinding, NamespaceContext nsCtx, ValueMetaData valueMetaData, String value)
       {
-         QName itemTypeQName = itemType.getQName();
-         ValueAdapter adapter = itemType.getValueAdapter();
-         
-         if(itemTypeQName == null || !Constants.NS_XML_SCHEMA.equals(itemTypeQName.getNamespaceURI()))
+         Object o;
+         QName typeQName = typeBinding.getQName();
+         TypeBinding itemType = typeBinding.getItemType();
+         if(itemType != null)
          {
+            QName itemTypeQName = itemType.getQName();
+            ValueAdapter adapter = itemType.getValueAdapter();
+            
+            if(itemTypeQName == null || !Constants.NS_XML_SCHEMA.equals(itemTypeQName.getNamespaceURI()))
+            {
+               if(adapter == null)
+                  throw new JBossXBRuntimeException(
+                        "Only list types with item type from " + Constants.NS_XML_SCHEMA +
+                        " namespace are supported currently."
+                     );
+               else
+                  itemTypeQName = Constants.QNAME_STRING;
+            }
+            
             if(adapter == null)
-               throw new JBossXBRuntimeException(
-                     "Only list types with item type from " + Constants.NS_XML_SCHEMA +
-                     " namespace are supported currently."
-                  );
+               adapter = ValueAdapter.NOOP;
+
+            List<?> list = SimpleTypeBindings.unmarshalList(itemTypeQName.getLocalPart(), value, nsCtx, adapter);
+            if (typeBinding.getSchemaBinding().isUnmarshalListsToArrays())
+            {
+               if (list.isEmpty())
+               {
+                  Class<?> compType = SimpleTypeBindings.classForType(itemTypeQName.getLocalPart(), true);
+                  o = Array.newInstance(compType, 0);
+               }
+               else
+               {
+                  Class<?> compType = list.get(0).getClass();
+                  o = list.toArray((Object[]) Array.newInstance(compType, list.size()));
+               }
+            }
             else
-               itemTypeQName = Constants.QNAME_STRING;
+            {
+               o = list;
+            }
          }
-         
-         if(adapter == null)
-            adapter = ValueAdapter.NOOP;
-
-         List<?> list = SimpleTypeBindings.unmarshalList(itemTypeQName.getLocalPart(), value, nsCtx, adapter);
-         if (typeBinding.getSchemaBinding().isUnmarshalListsToArrays())
+         else if(typeQName != null && Constants.NS_XML_SCHEMA.equals(typeQName.getNamespaceURI()))
          {
-            if (list.isEmpty())
+            try
             {
-               Class<?> compType = SimpleTypeBindings.classForType(itemTypeQName.getLocalPart(), true);
-               o = Array.newInstance(compType, 0);
+               o = SimpleTypeBindings.unmarshal(typeQName.getLocalPart(), value, nsCtx);
             }
-            else
+            catch (IllegalStateException e)
             {
-               Class<?> compType = list.get(0).getClass();
-               o = list.toArray((Object[]) Array.newInstance(compType, list.size()));
+               throw new JBossXBRuntimeException("Characters are not allowed here", e);
             }
          }
          else
          {
-            o = list;
+            TypeBinding baseType = typeBinding.getBaseType();
+            o = (baseType == null ? value : unmarshal(name, baseType, nsCtx, valueMetaData, value));
          }
+         return o;
       }
-      else if(typeQName != null && Constants.NS_XML_SCHEMA.equals(typeQName.getNamespaceURI()))
-      {
-         try
-         {
-            o = SimpleTypeBindings.unmarshal(typeQName.getLocalPart(), value, nsCtx);
-         }
-         catch (IllegalStateException e)
-         {
-            throw new JBossXBRuntimeException("Characters are not allowed here", e);
-         }
-      }
-      else
-      {
-         TypeBinding baseType = typeBinding.getBaseType();
-         o = (baseType == null ? value : unmarshal(qName, baseType, nsCtx, valueMetaData, value));
-      }
-      return o;
    }
-
-   public void setValue(QName qName, ElementBinding element, Object owner, Object value)
+   
+   public static final UnmarshalCharactersHandler NOOP_UNMARSHAL_HANDLER = new UnmarshalCharactersHandler()
    {
-   }
+      public Object unmarshal(QName name, TypeBinding typeBinding, NamespaceContext nsCtx, ValueMetaData valueMetaData, String value)
+      {
+         return value;
+      }      
+   };
+   
+   public static final UnmarshalCharactersHandler DEFAULT_UNMARSHAL_HANDLER = new DefaultUnmarshalCharactersHandler();
 }

Added: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandlerFactory.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandlerFactory.java	                        (rev 0)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/CharactersHandlerFactory.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -0,0 +1,35 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, 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;
+
+/**
+ * A HandlersFactory.
+ * 
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public interface CharactersHandlerFactory
+{
+   CharactersHandler newCharactersHandler();
+   
+   CharactersHandler newCharactersHandler(CharactersHandler.UnmarshalCharactersHandler unmarshalHandler);
+}

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ChoiceBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -27,8 +27,6 @@
 import java.util.Collection;
 import javax.xml.namespace.QName;
 
-import org.jboss.xb.binding.sunday.unmarshalling.position.NonElementPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
 import org.xml.sax.Attributes;
 
 
@@ -72,12 +70,12 @@
       return choices;
    }
 
-   public Position newPosition(QName qName, Attributes attrs, ParticleBinding choiceParticle)
+   public AbstractPosition newPosition(QName qName, Attributes attrs, ParticleBinding choiceParticle)
    {
       for(int i = 0; i < choices.size(); ++i)
       {
          ParticleBinding particle = (ParticleBinding)choices.get(i);
-         Position next = particle.getTerm().newPosition(qName, attrs, particle);
+         AbstractPosition next = particle.getTerm().newPosition(qName, attrs, particle);
          if(next != null)
             return new ChoicePosition(qName, choiceParticle, next);
       }
@@ -93,12 +91,12 @@
    
    private final class ChoicePosition extends NonElementPosition
    {
-      private ChoicePosition(QName name, ParticleBinding particle, Position next)
+      private ChoicePosition(QName name, ParticleBinding particle, AbstractPosition next)
       {
          super(name, particle, next);
       }
 
-      public Position nextPosition(QName qName, Attributes atts)
+      public AbstractPosition nextPosition(QName qName, Attributes atts)
       {
          if(trace)
          {
@@ -117,11 +115,11 @@
 
                if (next != null)
                {
-                  next.setPrevious(this);
+                  next.previous = this;
                   ++occurrence;
 
                   o = handler.endParticle(o, qName, particle);
-                  if(previous.getValue() != null)
+                  if(previous.o != null)
                      setParent(previous, handler);
                   initValue(atts);
 

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/DefaultHandlers.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/DefaultHandlers.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/DefaultHandlers.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -23,6 +23,7 @@
 
 import javax.xml.namespace.QName;
 
+import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler.UnmarshalCharactersHandler;
 import org.jboss.xb.binding.sunday.unmarshalling.impl.runtime.RtAttributeHandler;
 import org.jboss.xb.binding.sunday.unmarshalling.impl.runtime.RtCharactersHandler;
 import org.jboss.xb.binding.sunday.unmarshalling.impl.runtime.RtElementHandler;
@@ -53,8 +54,21 @@
 
    public static AttributeHandler ATTRIBUTE_HANDLER = RtAttributeHandler.INSTANCE;
 
-   public static CharactersHandler CHARACTERS_HANDLER = RtCharactersHandler.INSTANCE;
+   public static CharactersHandlerFactory CHARACTERS_HANDLER_FACTORY = new CharactersHandlerFactory()
+   {
+      public CharactersHandler newCharactersHandler()
+      {
+         return RtCharactersHandler.INSTANCE;
+      }
 
+      public CharactersHandler newCharactersHandler(UnmarshalCharactersHandler unmarshalHandler)
+      {
+         return new RtCharactersHandler(unmarshalHandler);
+      }
+   };
+   
+   //public static CharactersHandler CHARACTERS_HANDLER = RtCharactersHandler.INSTANCE;
+
    public static ParticleHandler XOP_HANDLER = new XOPElementHandler();
    
    public static RepeatableParticleHandler REPEATABLE_HANDLER = NoopRepeatableParticleHandler.INSTANCE;

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -33,8 +33,6 @@
 import org.jboss.xb.binding.metadata.ValueMetaData;
 import org.jboss.xb.binding.JBossXBRuntimeException;
 import org.jboss.xb.binding.sunday.marshalling.TermBeforeMarshallingCallback;
-import org.jboss.xb.binding.sunday.unmarshalling.position.ElementPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
 import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
 import org.xml.sax.Attributes;
 
@@ -80,6 +78,13 @@
       return typeBinding;
    }
 
+   public void setType(TypeBinding type)
+   {
+      if(type == null)
+         throw new IllegalArgumentException("The type cannot be null: " + qName);
+      this.typeBinding = type;
+   }
+
    public void pushInterceptor(ElementInterceptor interceptor)
    {
       switch(interceptors.size())
@@ -211,7 +216,7 @@
       return "element(" + qName + ", type=" + typeBinding.getQName() + ")";
    }
 
-   public Position newPosition(QName name, Attributes attrs, ParticleBinding particle)
+   public ElementPosition newPosition(QName name, Attributes attrs, ParticleBinding particle)
    {
       if(!qName.equals(name))
          return null;

Added: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementPosition.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementPosition.java	                        (rev 0)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/ElementPosition.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -0,0 +1,617 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, 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.Collections;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.jboss.util.StringPropertyReplacer;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.NamespaceRegistry;
+import org.jboss.xb.binding.metadata.CharactersMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.UnmarshallingContextImpl;
+import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
+import org.xml.sax.Attributes;
+
+/**
+ * A ElementPosition.
+ * 
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public class ElementPosition extends AbstractPosition
+{
+   private ParticleBinding nonXsiParticle;
+   private boolean ignoreCharacters;
+   private StringBuffer textContent;
+   private Boolean indentation;
+   private boolean ignorableCharacters = true;
+
+   private Object[] interceptorObjects;
+
+   public ElementPosition(QName qName, ParticleBinding particle)
+   {
+      super(qName, particle);
+   }
+
+   public boolean isElement()
+   {
+      return true;
+   }
+
+   public 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.setLength(0);
+      
+      indentation = null;
+      ignorableCharacters = true;
+      
+      if(nonXsiParticle != null)
+         particle = nonXsiParticle;
+   }
+   
+   public ParticleBinding getNonXsiParticle()
+   {
+      return nonXsiParticle;
+   }
+   
+   public void setNonXsiParticle(ParticleBinding nonXsiParticle)
+   {
+      this.nonXsiParticle = nonXsiParticle;
+   }
+   
+   public boolean isIgnoreCharacters()
+   {
+      return ignoreCharacters;
+   }
+   
+   public void setIgnoreCharacters(boolean ignoreCharacters)
+   {
+      this.ignoreCharacters = ignoreCharacters;
+   }
+   
+   public StringBuffer getTextContent()
+   {
+      return this.textContent;
+   }
+
+   public AbstractPosition nextPosition(QName startName, Attributes atts)
+   {
+      if (ended) // this is about repeating itself
+      {
+         if (!qName.equals(startName))
+         {
+            if (repeatableParticleValue != null)
+               endRepeatableParticle();
+            return null;
+         }
+
+         if (particle.isRepeatable())
+         {
+            if (particle.isOccurrenceAllowed(occurrence + 1))
+            {
+               reset();
+               ++occurrence;
+               return this;
+            }
+            else if (repeatableParticleValue != null)
+               endRepeatableParticle();
+            return null;
+         }
+
+         // it's not repeatable but it re-appeared
+         // it probably has a repeatable parent
+         reset();
+         previous.repeatForChild(atts);
+         occurrence = 1;
+         if(next != null)
+         {
+            next.previous = null;
+            next = null;
+         }
+         return this;
+      }
+      
+      // this is locating the next child
+      ElementBinding element = (ElementBinding) particle.getTerm();
+      TypeBinding parentType = element.getType();
+      ParticleBinding typeParticle = parentType.getParticle();
+      ModelGroupBinding modelGroup = typeParticle == null ? null : (ModelGroupBinding) typeParticle.getTerm();
+      if (modelGroup == null)
+      {
+         if (startName.equals(Constants.QNAME_XOP_INCLUDE))
+         {
+            SchemaBinding schema = element.getSchema();
+            TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
+            if (anyUriType == null)
+               log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
+
+            ElementBinding parentElement = (ElementBinding) particle.getTerm();
+            parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
+
+            flushIgnorableCharacters();
+            handler = DefaultHandlers.XOP_HANDLER;
+            ignoreCharacters = true;
+            initValue(null);
+
+            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(parentType, schema.getXopUnmarshaller()));
+
+            ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
+            next = new ElementPosition(startName, new ParticleBinding(xopInclude));
+            next.stack = stack;
+            next.previous = this;
+            return next;
+         }
+
+         QName typeName = parentType.getQName();
+         throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) + " type of element "
+               + qName + " should be complex and contain " + startName + " as a child element.");
+      }
+
+      if (next != null)
+      {
+         if (particle.isOccurrenceAllowed(occurrence + 1))
+         {
+            // this increase is actually ahead of its time, it may fail to locate the element
+            // but in the current impl it doesn't matter
+            ++occurrence;
+         }
+         else
+         {
+            throw new JBossXBRuntimeException(startName + " cannot appear in this position. Expected content of "
+                  + qName + " is " + modelGroup);
+         }
+      }
+
+      next = modelGroup.newPosition(startName, atts, typeParticle);
+      if (next == null)
+         throw new JBossXBRuntimeException(startName + " not found as a child of " + qName + " in " + modelGroup);
+
+      next.previous = this;
+      
+      flushIgnorableCharacters();
+
+      AbstractPosition nextPosition = next;
+      while (nextPosition.next != null)
+      {
+         if (nextPosition.particle.isRepeatable())
+            nextPosition.startRepeatableParticle();
+
+         nextPosition.stack = stack;
+         nextPosition.initValue(atts);
+         nextPosition.parentType = parentType;
+         nextPosition = nextPosition.next;
+      }
+
+      nextPosition.stack = stack;
+      nextPosition.parentType = parentType;
+      return (ElementPosition) nextPosition;
+   }
+
+   public void characters(char[] ch, int start, int length)
+   {
+      ElementBinding e = (ElementBinding) particle.getTerm();
+
+      // collect characters only if they are allowed content
+      if(e.getType().isTextContentAllowed())
+      {
+         if(indentation != Boolean.FALSE)
+         {
+            if(e.getType().isSimple())
+            {
+               // simple content is not analyzed
+               indentation = Boolean.FALSE;
+               ignorableCharacters = false;
+            }
+            else if(e.getSchema() != null && !e.getSchema().isIgnoreWhitespacesInMixedContent())
+            {
+               indentation = Boolean.FALSE;
+               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)
+                  {
+                     indentation = Boolean.TRUE;
+                  }
+                  else if (!Character.isWhitespace(ch[i]))
+                  {
+                     indentation = Boolean.FALSE;
+                     ignorableCharacters = false;
+                     break;
+                  }
+               }
+            }
+         }
+         
+         if (textContent == null)
+            textContent = new StringBuffer();
+         textContent.append(ch, start, length);
+      }
+   }
+   
+   public void endParticle()
+   {
+      ElementBinding element = (ElementBinding) particle.getTerm();
+      TypeBinding type = element.getType();
+      
+      List<ElementInterceptor> interceptors = null;
+      List<ElementInterceptor> localInterceptors = null;
+      if(interceptorObjects != null)
+      {
+         interceptors = element.getInterceptors();
+         localInterceptors = parentType == null ? Collections.<ElementInterceptor>emptyList() : parentType.getInterceptors(qName);
+      }
+
+      if(o != SundayContentHandler.NIL)
+      {
+         //
+         // characters
+         //
+
+         flushIgnorableCharacters();
+
+         TypeBinding charType = type.getSimpleType();
+         if(charType == null)
+            charType = type;
+
+         CharactersHandler charHandler = 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 = this.textContent == null ? "" : this.textContent.toString();
+         if(textContent.length() > 0 || charHandler != null && !type.isIgnoreEmptyString())
+         {
+            String dataContent;
+            SchemaBinding schema = element.getSchema();
+            if(textContent.length() == 0)
+            {
+               dataContent = null;
+            }
+            else
+            {
+               dataContent = textContent;
+               if(schema != null && schema.isReplacePropertyRefs())
+                  dataContent = StringPropertyReplacer.replaceProperties(dataContent);
+               
+               if(element.isNormalizeSpace())
+                  dataContent = dataContent.trim();
+            }
+
+            Object unmarshalled;
+
+            if(charHandler == null)
+            {
+               if(!type.isSimple() &&
+                  schema != null &&
+                  schema.isStrictSchema()
+                  && !element.isSkip())
+               {
+                  throw new JBossXBRuntimeException("Element " +
+                     qName +
+                     " 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(qName, charType, stack.getNamespaceRegistry(), valueMetaData) :
+                  charHandler.unmarshal(qName, charType, stack.getNamespaceRegistry(), 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)
+                  {
+                     UnmarshallingContextImpl ctx = stack.getContext();
+                     ctx.parent = o;
+                     ctx.particle = particle;
+                     ctx.parentParticle = notSkippedParent().particle;
+                     unmarshalled = beforeSetParent.beforeSetParent(unmarshalled, ctx);
+                     ctx.clear();
+                  }
+                  
+                  charHandler.setValue(qName, element, o, unmarshalled);
+               }
+            }
+
+            if(interceptorObjects != null)
+            {
+               NamespaceRegistry nsRegistry = stack.getNamespaceRegistry();
+               int ioIndex = 0;
+               for (int i = interceptors.size() - 1; i >= 0; --i)
+               {
+                  ElementInterceptor interceptor = interceptors.get(i);
+                  interceptor.characters(interceptorObjects[ioIndex++], qName, type, nsRegistry, dataContent);
+               }
+
+               for (int i = localInterceptors.size() - 1; i >= 0; --i)
+               {
+                  ElementInterceptor interceptor = localInterceptors.get(i);
+                  interceptor.characters(interceptorObjects[ioIndex++], qName, type, nsRegistry, dataContent);
+               }
+            }
+         }
+      }
+      else
+      {
+         o = null;
+      }
+
+      //
+      // endElement
+      //
+
+      o = handler.endParticle(o, qName, particle);
+
+      if(interceptorObjects != null && !interceptors.isEmpty())
+      {
+         int ioIndex = 0;
+         for (int i = interceptors.size() - 1; i >= 0; --i)
+         {
+            ElementInterceptor interceptor = interceptors.get(i);
+            interceptorObjects[ioIndex] = interceptor.endElement(interceptorObjects[ioIndex++], qName, type);
+         }
+      }
+      
+      //
+      // setParent
+      //
+
+      if(interceptorObjects == null)
+      {
+         AbstractPosition notSkippedParent = notSkippedParent();
+         if (notSkippedParent != null)
+         {
+            ParticleBinding parentParticle = notSkippedParent.particle;
+            TermBinding parentTerm = parentParticle.getTerm();
+
+            if (notSkippedParent.o != null)
+            {
+               ParticleHandler handler = this.handler;
+               if (parentTerm.isWildcard())
+               {
+                  ParticleHandler wh = ((WildcardBinding) parentTerm).getWildcardHandler();
+                  if (wh != null)
+                     handler = wh;
+               }
+               setParent(notSkippedParent, handler);
+            }
+            else if (parentTerm.isWildcard())
+            {
+               // the parent has anyType, so it gets the value of its child
+               AbstractPosition parentPos = previous;
+               parentPos.o = o;
+               while(!parentPos.isElement())
+               {
+                  parentPos = parentPos.getPrevious();
+                  parentPos.o = o;
+               }
+
+               if (trace)
+                  log.trace("Value of " + qName + " " + o + " is promoted as the value of its parent element.");
+            }
+         }
+      }
+      else
+      {
+         int ioIndex = 0;
+         for(int i = interceptors.size() - 1; i >= 0; --i)
+         {
+            ElementInterceptor interceptor = interceptors.get(i);
+            Object parent = interceptorObjects[ioIndex++];
+            interceptor.add(parent, o, qName);
+            o = parent;
+         }
+
+         for(int i = localInterceptors.size() - 1; i >= 0; --i)
+         {
+            ElementInterceptor interceptor = localInterceptors.get(i);
+            Object parent = interceptorObjects[ioIndex++];
+            interceptor.add(parent, o, qName);
+            o = parent;
+         }
+      }
+      
+      ended = true;
+   }
+   
+   public ElementPosition startParticle(QName startName, Attributes atts)
+   {
+      return (ElementPosition) nextPosition(startName, atts);
+   }
+
+   public void repeatForChild(Attributes atts)
+   {
+      throw new JBossXBRuntimeException("Failed to repeat parent for non-repeatable element: "
+            + "repeatable parent expected to be a model group but got element "
+            + qName);
+   }
+
+   public void push(Attributes atts)
+   {
+      ElementBinding element = (ElementBinding) particle.getTerm();
+
+      // TODO xsi:type support should be implemented in a better way
+      String xsiType = atts.getValue(Constants.NS_XML_SCHEMA_INSTANCE, "type");
+      if (xsiType != null)
+      {
+         if (trace)
+            log.trace(element.getQName() + " uses xsi:type " + xsiType);
+
+         if (nonXsiParticle == null)
+            nonXsiParticle = particle;
+
+         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 = stack.getNamespaceRegistry().getNamespaceURI(xsiTypePrefix);
+         QName xsiTypeQName = new QName(xsiTypeNs, xsiTypeLocal);
+
+         SchemaBinding schemaBinding = element.getSchema();
+         TypeBinding xsiTypeBinding = schemaBinding.getType(xsiTypeQName);
+         if (xsiTypeBinding == null)
+         {
+            throw new JBossXBRuntimeException("Type binding not found for type " + xsiTypeQName
+                  + " specified with xsi:type for element " + qName);
+         }
+
+         ElementBinding xsiElement = new ElementBinding(schemaBinding, qName, xsiTypeBinding);
+         xsiElement.setRepeatableHandler(element.getRepeatableHandler());
+
+         particle = new ParticleBinding(xsiElement, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded());
+      }
+
+      if (occurrence == 1 && particle.isRepeatable())
+         startRepeatableParticle();
+
+      TypeBinding type = element.getType();
+      if (type == null)
+         throw new JBossXBRuntimeException("No type for element " + element);
+
+      handler = type.getHandler();
+      if (handler == null)
+         handler = DefaultHandlers.ELEMENT_HANDLER;
+
+      Object parent = previous == null ? null : previous.o;
+
+      if(parentType != null)
+      {
+         List<ElementInterceptor> interceptors = parentType.getInterceptors(qName);
+         if(!interceptors.isEmpty())
+         {
+            NamespaceRegistry nsRegistry = stack.getNamespaceRegistry();
+            interceptorObjects = new Object[interceptors.size() + element.getInterceptors().size()];
+            // objects are written to the array in the reversed order to optimize endParticle iterations
+            int ioIndex = interceptorObjects.length - 1;
+            for(ElementInterceptor i : interceptors)
+            {
+               parent = i.startElement(parent, qName, type);
+               i.attributes(parent, qName, type, atts, nsRegistry);
+               interceptorObjects[ioIndex--] = parent;
+            }
+         }
+      }
+      
+      if(!element.getInterceptors().isEmpty())
+      {
+         NamespaceRegistry nsRegistry = stack.getNamespaceRegistry();
+         int ioIndex;
+         if(interceptorObjects == null)
+         {
+            interceptorObjects = new Object[element.getInterceptors().size()];
+            ioIndex = interceptorObjects.length - 1;
+         }
+         else
+            ioIndex = element.getInterceptors().size() - 1;
+         for(ElementInterceptor i : element.getInterceptors())
+         {
+            parent = i.startElement(parent, qName, type);
+            i.attributes(parent, qName, type, atts, nsRegistry);
+            interceptorObjects[ioIndex--] = parent;
+         }
+      }
+
+      String nil = atts.getValue(Constants.NS_XML_SCHEMA_INSTANCE, "nil");
+      if (nil == null || !("1".equals(nil) || "true".equals(nil)))
+         initValue(atts);
+      else
+         o = SundayContentHandler.NIL;
+   }
+   
+   private void flushIgnorableCharacters()
+   {
+      if(textContent == null)
+         return;
+
+      if(indentation == Boolean.TRUE || ignorableCharacters)
+      {
+         if(trace)
+            log.trace("ignored characters: " + ((ElementBinding) particle.getTerm()).getQName() + " '" + textContent + "'");
+         textContent = null;
+         indentation = null;
+      }
+   }
+   
+   @Override
+   protected ParticleHandler getHandler()
+   {
+      return DefaultHandlers.ELEMENT_HANDLER;
+   }
+}
\ No newline at end of file

Added: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/NonElementPosition.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/NonElementPosition.java	                        (rev 0)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/NonElementPosition.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -0,0 +1,116 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, 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 javax.xml.namespace.QName;
+
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.xml.sax.Attributes;
+
+/**
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class NonElementPosition extends AbstractPosition
+{
+   protected NonElementPosition(QName name, ParticleBinding particle, AbstractPosition next)
+   {
+      super(name, particle);
+      this.particle = particle;
+      this.next = next;
+      next.previous = this;
+   }
+
+   public boolean isElement()
+   {
+      return false;
+   }
+
+   public void characters(char[] ch, int start, int length)
+   {
+   }
+   
+   
+   public void endParticle()
+   {
+      if(ended)
+         throw new JBossXBRuntimeException("The position has already been ended!");
+      
+      o = handler.endParticle(o, qName, particle);
+      ended = true;
+      
+      if(previous.o != null)
+         setParent(previous, handler);
+      
+      if(repeatableParticleValue != null)
+         endRepeatableParticle();
+   }
+
+   public void repeatForChild(Attributes atts)
+   {
+      if(ended)
+         throw new JBossXBRuntimeException("The position has already been ended!");
+
+      o = handler.endParticle(o, qName, particle);
+
+      // model group should always have parent particle
+      AbstractPosition parentPosition = notSkippedParent();
+      if(parentPosition.o != null)
+         setParent(parentPosition, handler);
+
+      // if it is repeatable then this is the repeatable parent
+      if(!particle.isRepeatable())
+         previous.repeatForChild(atts);
+      
+      initValue(atts);
+   }
+   
+   public ElementPosition startParticle(QName startName, Attributes atts)
+   {
+      if (nextPosition(startName, atts) == null)
+         return null;
+
+      // push all except the last one
+      AbstractPosition nextPosition = next;
+      while (nextPosition.next != null)
+      {
+         if (nextPosition.particle.isRepeatable())
+            nextPosition.startRepeatableParticle();
+
+         nextPosition.stack = stack;
+         nextPosition.initValue(atts);
+         nextPosition.parentType = parentType;
+         nextPosition = nextPosition.next;
+      }
+
+      nextPosition.stack = stack;
+      nextPosition.parentType = parentType;
+      return (ElementPosition) nextPosition;
+   }
+
+   protected void nextNotFound()
+   {
+      endParticle();
+      next = null;
+      occurrence = 0;
+   }
+}
\ No newline at end of file

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -21,19 +21,26 @@
   */
 package org.jboss.xb.binding.sunday.unmarshalling;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.Set;
 
+import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
 
 import org.jboss.xb.binding.Constants;
 import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.JBossXBValueFormatException;
+import org.jboss.xb.binding.SimpleTypeBindings;
 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.binding.metadata.ValueMetaData;
 import org.jboss.xb.util.DomCharactersHandler;
 import org.jboss.xb.util.DomLocalMarshaller;
 import org.jboss.xb.util.DomParticleHandler;
@@ -103,51 +110,464 @@
 
    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));
+      addType(new SimpleTypeBinding(Constants.QNAME_ANYSIMPLETYPE, CharactersHandler.NOOP_UNMARSHAL_HANDLER));
+      addType(new SimpleTypeBinding(Constants.QNAME_STRING, CharactersHandler.NOOP_UNMARSHAL_HANDLER));
+      addType(new SimpleTypeBinding(Constants.QNAME_BOOLEAN, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            if(value.length() == 1)
+            {
+               char c = value.charAt(0);
+               if(c == '1')
+                  return Boolean.TRUE;
+               if(c == '0')
+                  return Boolean.FALSE;
+               throw new JBossXBValueFormatException("An instance of a datatype that is defined as ?boolean? can have the following legal literals" +
+                  " {true, false, 1, 0}. But got: " + value);
+            }
+            else
+               return Boolean.valueOf(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_DECIMAL, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return new BigDecimal(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_FLOAT, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            if("INF".equals(value))
+               return new Float(Float.POSITIVE_INFINITY);
+            else if("-INF".equals(value))
+               return new Float(Float.NEGATIVE_INFINITY);
+            else
+               return Float.valueOf(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_DOUBLE, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            if("INF".equals(value))
+               return new Double(Double.POSITIVE_INFINITY);
+            else if("-INF".equals(value))
+               return new Double(Double.NEGATIVE_INFINITY);
+            else
+               return Double.valueOf(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_DURATION, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {         
+            // todo XS_DURATION
+            throw new IllegalStateException("Recognized but not supported xsdType: " + Constants.QNAME_DURATION);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_DATETIME, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalDateTime(value);
+         }
+      }, DATE_ADAPTER));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_TIME, new CharactersHandler.UnmarshalCharactersHandler(){
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalTime(value);
+         }         
+      }, DATE_ADAPTER));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_DATE, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalDate(value);
+         }         
+      }, DATE_ADAPTER));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_GYEARMONTH, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalGYearMonth(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_GYEAR, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalGYear(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_GMONTHDAY, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalGMonthDay(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_GDAY, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalGDay(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_GMONTH, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalGMonth(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_HEXBINARY, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalHexBinary(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_BASE64BINARY, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalBase64(value);
+         }         
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_ANYURI, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            // anyUri is by default bound to java.net.URI for now. The following is the warning from JAXB2.0:
+            //
+            // Design Note � xs:anyURI is not bound to java.net.URI by default since not all
+            // possible values of xs:anyURI can be passed to the java.net.URI constructor. Using
+            // a global JAXB customization described in Section 7.9, �<javaType>
+            // Declaration", a JAXB user can override the default mapping to map xs:anyURI to
+            // java.net.URI.
+            //
+            try
+            {
+               return new java.net.URI(value);
+            }
+            catch(URISyntaxException e)
+            {
+               throw new JBossXBValueFormatException("Failed to unmarshal anyURI value " + value, e);
+            }
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_QNAME, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalQName(value, nsCtx);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_NOTATION, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_NORMALIZEDSTRING, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            if(SimpleTypeBindings.isNormalizedString(value))
+               return value;
+            else
+               throw new JBossXBValueFormatException("Invalid normalizedString value: " + value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_TOKEN, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            if(SimpleTypeBindings.isValidToken(value))
+               return value;
+            else
+               throw new JBossXBValueFormatException("Invalid token value: " + value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_LANGUAGE, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_NMTOKEN, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_NMTOKENS, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalNMTokens(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_NAME, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_NCNAME, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_ID, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_IDREF, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_IDREFS, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalIdRefs(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_ENTITY, CharactersHandler.NOOP));
+      addType(new SimpleTypeBinding(Constants.QNAME_ENTITIES, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return SimpleTypeBindings.unmarshalIdRefs(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_INTEGER, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return new BigInteger(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_NONPOSITIVEINTEGER, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            BigInteger result = new BigInteger(value);
+            if(BigInteger.ZERO.compareTo(result) < 0)
+               throw new JBossXBValueFormatException("Invalid nonPositiveInteger value: " + value);
+            return result;
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_NEGATIVEINTEGER, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            BigInteger result = new BigInteger(value);
+            if(BigInteger.ZERO.compareTo(result) <= 0)
+               throw new JBossXBValueFormatException("Invalid negativeInteger value: " + value);
+            return result;
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_LONG, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return Long.valueOf(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_INT, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return Integer.valueOf(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_SHORT, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return Short.valueOf(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_BYTE, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            return Byte.valueOf(value);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_NONNEGATIVEINTEGER, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            BigInteger result = new BigInteger(value);
+            if(BigInteger.ZERO.compareTo(result) > 0)
+               throw new JBossXBValueFormatException("Invalid nonNegativeInteger value: " + value);
+            return result;
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDLONG, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            BigInteger d = new BigInteger(value);
+            if(d.doubleValue() < 0 || d.doubleValue() > 18446744073709551615D)
+               throw new JBossXBValueFormatException("Invalid unsignedLong value: " + value);
+            return d;
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDINT, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            long l = Long.parseLong(value);
+            if(l < 0 || l > 4294967295L)
+               throw new JBossXBValueFormatException("Invalid unsignedInt value: " + value);
+            return new Long(l);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDSHORT, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            int i = Integer.parseInt(value);
+            if(i < 0 || i > 65535)
+               throw new JBossXBValueFormatException("Invalid unsignedShort value: " + value);
+            return new Integer(i);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDBYTE, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            short s = Short.parseShort(value);
+            if(s < 0 || s > 255)
+               throw new JBossXBValueFormatException("Invalid unsignedByte value: " + value);
+            return new Short(s);
+         }
+      }));
+      
+      addType(new SimpleTypeBinding(Constants.QNAME_POSITIVEINTEGER, new CharactersHandler.UnmarshalCharactersHandler()
+      {
+         public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx,
+               ValueMetaData valueMetaData, String value)
+         {
+            if (value == null)
+               throw new IllegalArgumentException("Value string cannot be null");
+            BigInteger result = new BigInteger(value);
+            if(BigInteger.ZERO.compareTo((BigInteger)result) >= 0)
+               throw new JBossXBValueFormatException("Invalid positiveInteger value: " + value);
+            return result;
+         }
+      }));
    }
    
    public void addPrefixMapping(String prefix, String ns)

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SequenceBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -27,8 +27,6 @@
 import java.util.Collection;
 import javax.xml.namespace.QName;
 
-import org.jboss.xb.binding.sunday.unmarshalling.position.NonElementPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
 import org.xml.sax.Attributes;
 
 
@@ -81,12 +79,12 @@
       return sequence;
    }
 
-   public Position newPosition(QName qName, Attributes attrs, ParticleBinding seqParticle)
+   public AbstractPosition newPosition(QName qName, Attributes attrs, ParticleBinding seqParticle)
    {
       for(int i = 0; i < sequence.size(); ++i)
       {
          ParticleBinding particle = sequence.get(i);
-         Position next = particle.getTerm().newPosition(qName, attrs, particle);
+         AbstractPosition next = particle.getTerm().newPosition(qName, attrs, particle);
          if(next != null)
             return new SequencePosition(qName, seqParticle, i, next);
          
@@ -107,13 +105,13 @@
    {
       private int pos = -1;
 
-      protected SequencePosition(QName qName, ParticleBinding particle, int pos, Position next)
+      protected SequencePosition(QName qName, ParticleBinding particle, int pos, AbstractPosition next)
       {
          super(qName, particle, next);
          this.pos = pos;
       }
 
-      public Position nextPosition(QName qName, Attributes atts)
+      public AbstractPosition nextPosition(QName qName, Attributes atts)
       {
          if(trace)
          {
@@ -129,7 +127,7 @@
 
             if (next != null)
             {
-               next.setPrevious(this);
+               next.previous = this;
                return this;
             }
 
@@ -150,11 +148,11 @@
 
                if(next != null)
                {
-                  next.setPrevious(this);
+                  next.previous = this;
                   ++occurrence;
 
                   o = handler.endParticle(o, qName, particle);
-                  if(previous.getValue() != null)
+                  if(previous.o != null)
                      setParent(previous, handler);
                   initValue(atts);
 

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SimpleTypeBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SimpleTypeBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SimpleTypeBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -39,23 +39,38 @@
 
    public SimpleTypeBinding(QName qName)
    {
-      super(qName, DefaultHandlers.CHARACTERS_HANDLER);
+      super(qName, DefaultHandlers.CHARACTERS_HANDLER_FACTORY.newCharactersHandler());
       setDefaultHandler();
    }
 
    public SimpleTypeBinding(QName qName, ValueAdapter valueAdapter)
    {
-      super(qName, DefaultHandlers.CHARACTERS_HANDLER);
+      this(qName, DefaultHandlers.CHARACTERS_HANDLER_FACTORY.newCharactersHandler(), valueAdapter);
+   }
+
+   public SimpleTypeBinding(QName qName, CharactersHandler handler, ValueAdapter valueAdapter)
+   {
+      super(qName, handler);
       setDefaultHandler();
       setValueAdapter(valueAdapter);
    }
 
+   public SimpleTypeBinding(QName qName, CharactersHandler.UnmarshalCharactersHandler unmarshalHandler, ValueAdapter valueAdapter)
+   {
+      this(qName, DefaultHandlers.CHARACTERS_HANDLER_FACTORY.newCharactersHandler(unmarshalHandler), valueAdapter);
+   }
+
    public SimpleTypeBinding(QName qName, CharactersHandler simple)
    {
       super(qName, simple);
       setDefaultHandler();
    }
 
+   public SimpleTypeBinding(QName qName, CharactersHandler.UnmarshalCharactersHandler unmarshalHandler)
+   {
+      this(qName, DefaultHandlers.CHARACTERS_HANDLER_FACTORY.newCharactersHandler(unmarshalHandler));
+   }
+
    private void setDefaultHandler()
    {
       setHandler(DefaultHandlers.SIMPLE_HANDLER);

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -35,9 +35,6 @@
 import org.jboss.xb.binding.metadata.PropertyMetaData;
 import org.jboss.xb.binding.parser.JBossXBParser;
 import org.jboss.xb.binding.resolver.MutableSchemaResolver;
-import org.jboss.xb.binding.sunday.unmarshalling.position.AbstractPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.ElementPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
 import org.xml.sax.Attributes;
 
 /**
@@ -56,7 +53,7 @@
    private final SchemaBindingResolver schemaResolver;
    private final SchemaBinding schema;
 
-   private Position head;
+   private AbstractPosition head;
    
    // DTD information frm startDTD
    private String dtdRootName;
@@ -98,7 +95,7 @@
       if(!head.isElement())
          return;
 
-      Position position = head;
+      AbstractPosition position = head;
       // if current is ended the characters belong to its parent
       if(position.isEnded())
       {

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TermBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TermBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TermBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -30,13 +30,13 @@
 import org.jboss.xb.binding.metadata.AddMethodMetaData;
 import org.jboss.xb.binding.metadata.ValueMetaData;
 import org.jboss.xb.binding.sunday.marshalling.TermBeforeMarshallingCallback;
-import org.jboss.xb.binding.sunday.unmarshalling.position.PositionFactory;
+import org.xml.sax.Attributes;
 
 /**
  * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
  * @version <tt>$Revision$</tt>
  */
-public abstract class TermBinding implements PositionFactory
+public abstract class TermBinding
 {
    protected SchemaBinding schema;
    protected QName qName;
@@ -211,4 +211,6 @@
    {
       this.repeatableHandler = repeatableHandler;
    }
+   
+   public abstract AbstractPosition newPosition(QName qName, Attributes attrs, ParticleBinding particle);
 }

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -52,7 +52,7 @@
 {
    protected QName qName;
    /** Map<QName, AttributeBinding>  */
-   private Map<QName, AttributeBinding> attrs = Collections.emptyMap();
+   private Map<QName, AttributeBinding> attrs;
    private AnyAttributeBinding anyAttribute;
    private ParticleHandler handler;//todo default handler is now in SundayContentHandler.
    private CharactersHandler charactersHandler;
@@ -70,7 +70,7 @@
    private TermBeforeSetParentCallback beforeSetParentCallback;
    
    private Boolean startElementCreatesObject;
-   private Boolean simple;
+   private int simple; // 0 - not set, 1 - false, 2 - true
    private Boolean ignoreEmptyString;
 
    private WildcardBinding wildcard;
@@ -97,7 +97,7 @@
    public TypeBinding(QName qName)
    {
       //this(qName, (CharactersHandler)null);
-      this(qName, DefaultHandlers.CHARACTERS_HANDLER);
+      this(qName, DefaultHandlers.CHARACTERS_HANDLER_FACTORY.newCharactersHandler());
    }
 
    public TypeBinding(CharactersHandler charactersHandler)
@@ -121,7 +121,7 @@
          this.particle = baseType.particle;
       }
 
-      this.attrs = new HashMap<QName, AttributeBinding>(baseType.attrs);
+      this.attrs = baseType.attrs == null ? null : new HashMap<QName, AttributeBinding>(baseType.attrs);
       this.classMetaData = baseType.classMetaData;
       this.valueMetaData = baseType.valueMetaData;
       this.propertyMetaData = baseType.propertyMetaData;
@@ -214,7 +214,7 @@
 
    public AttributeBinding getAttribute(QName qName)
    {
-      return attrs.get(qName);
+      return attrs == null ? null : attrs.get(qName);
    }
 
    /**
@@ -227,10 +227,8 @@
     */
    public Attributes expandWithDefaultAttributes(Attributes attrs)
    {
-      if(this.attrs.size() == 0)
-      {
+      if(this.attrs == null)
          return attrs;
-      }
 
       // Map<QName, AttributeBinding>
       HashMap<QName, AttributeBinding> attrsNotSeen = new HashMap<QName, AttributeBinding>(this.attrs);
@@ -275,21 +273,20 @@
 
    public void addAttribute(AttributeBinding attr)
    {
-      switch(attrs.size())
+      if(attrs == null)
       {
-         case 0:
-            attrs = Collections.singletonMap(attr.getQName(), attr);
-            break;
-         case 1:
-            attrs = new HashMap<QName, AttributeBinding>(attrs);
-         default:
-            attrs.put(attr.getQName(), attr);
+         attrs = Collections.singletonMap(attr.getQName(), attr);
+         return;
       }
+      
+      if(attrs.size() == 1)
+         attrs = new HashMap<QName, AttributeBinding>(attrs);         
+      attrs.put(attr.getQName(), attr);
    }
 
    public Collection<AttributeBinding> getAttributes()
    {
-      return attrs.values();
+      return attrs == null ? Collections.<AttributeBinding>emptyList() : attrs.values();
    }
 
    public CharactersHandler getCharactersHandler()
@@ -409,12 +406,12 @@
       // actually, a type can be complex when the particle is null and
       // there are no attributes. But the XsdBinder will set the value of simple
       // to false. This check is for schema bindings created programmatically
-      return simple == null ? particle == null && attrs.isEmpty() : simple.booleanValue();
+      return simple == 0 ? particle == null && attrs == null : simple == 2;
    }
 
    public void setSimple(boolean simple)
    {
-      this.simple = simple ? Boolean.TRUE : Boolean.FALSE;
+      this.simple = simple ? 2 : 1;
    }
 
    public boolean isTextContentAllowed()
@@ -524,7 +521,7 @@
    public boolean isStartElementCreatesObject()
    {
       return startElementCreatesObject == null ?
-         particle != null || !attrs.isEmpty() : startElementCreatesObject.booleanValue();
+         particle != null || attrs != null : startElementCreatesObject;
    }
 
    /**
@@ -538,7 +535,7 @@
     */
    public void setStartElementCreatesObject(boolean startElementCreatesObject)
    {
-      this.startElementCreatesObject = startElementCreatesObject ? Boolean.TRUE : Boolean.FALSE;
+      this.startElementCreatesObject = startElementCreatesObject;
    }
 
    private boolean initializedWildcard;
@@ -644,21 +641,15 @@
 
    public boolean hasOnlyXmlMimeAttributes()
    {
-      if(attrs.isEmpty())
-      {
+      if(attrs == null)
          return false;
-      }
-      else
+
+      Iterator<QName> iter = attrs.keySet().iterator();
+      while(iter.hasNext())
       {
-         Iterator<QName> iter = attrs.keySet().iterator();
-         while(iter.hasNext())
-         {
-            QName qName = iter.next();
-            if(!Constants.NS_XML_MIME.equals(qName.getNamespaceURI()))
-            {
-               return false;
-            }
-         }
+         QName qName = iter.next();
+         if(!Constants.NS_XML_MIME.equals(qName.getNamespaceURI()))
+            return false;
       }
       return true;
    }

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/UnorderedSequenceBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -31,8 +31,6 @@
 import javax.xml.namespace.QName;
 
 import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.sunday.unmarshalling.position.NonElementPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
 import org.xml.sax.Attributes;
 
 /**
@@ -101,7 +99,7 @@
       return allParticles;
    }
 
-   public Position newPosition(QName qName, Attributes attrs, ParticleBinding seqParticle)
+   public AbstractPosition newPosition(QName qName, Attributes attrs, ParticleBinding seqParticle)
    {
       ParticleBinding currentParticle = elementParticles.get(qName);
       if (currentParticle != null)
@@ -110,14 +108,14 @@
 
       for (ParticleBinding particle : groupParticles)
       {
-         Position next = particle.getTerm().newPosition(qName, attrs, particle);
+         AbstractPosition next = particle.getTerm().newPosition(qName, attrs, particle);
          if (next != null)
             return new UnorderedSequencePosition(qName, seqParticle, next);
       }
 
       for (ParticleBinding particle : wildcardParticles)
       {
-         Position next = particle.getTerm().newPosition(qName, attrs, particle);
+         AbstractPosition next = particle.getTerm().newPosition(qName, attrs, particle);
          if (next != null)
             return new UnorderedSequencePosition(qName, seqParticle, next);
       }
@@ -133,12 +131,12 @@
    
    private final class UnorderedSequencePosition extends NonElementPosition
    {
-      private UnorderedSequencePosition(QName name, ParticleBinding particle, Position next)
+      private UnorderedSequencePosition(QName name, ParticleBinding particle, AbstractPosition next)
       {
          super(name, particle, next);
       }
 
-      public Position nextPosition(QName qName, Attributes atts)
+      public AbstractPosition nextPosition(QName qName, Attributes atts)
       {
          if(trace)
          {
@@ -151,7 +149,7 @@
          if (element != null)
          {
             next = element.getTerm().newPosition(qName, atts, element);
-            next.setPrevious(this);
+            next.previous = this;
             // TODO occurrence here is not used ++occurrence;
             if (trace)
                log.trace("found " + qName + " in " + UnorderedSequenceBinding.this);
@@ -164,7 +162,7 @@
             if (next != null)
             {
                //++occurrence;
-               next.setPrevious(this);
+               next.previous = this;
                return this;
             }
          }
@@ -175,7 +173,7 @@
             if (next != null)
             {
                //++occurrence;
-               next.setPrevious(this);
+               next.previous = this;
                return this;
             }
          }

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/WildcardBinding.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -25,8 +25,6 @@
 import org.jboss.xb.binding.JBossXBRuntimeException;
 import org.jboss.xb.binding.ObjectLocalMarshaller;
 import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.sunday.unmarshalling.position.NonElementPosition;
-import org.jboss.xb.binding.sunday.unmarshalling.position.Position;
 import org.xml.sax.Attributes;
 
 /**
@@ -244,13 +242,13 @@
       return element;
    }
 
-   public Position newPosition(QName qName, Attributes attrs, ParticleBinding wildcardParticle)
+   public AbstractPosition newPosition(QName qName, Attributes attrs, ParticleBinding wildcardParticle)
    {
       ElementBinding wildcardContent = getElement(qName, attrs);
       if(wildcardContent != null)
       {
          ParticleBinding particle = new ParticleBinding(wildcardContent);
-         Position next = wildcardContent.newPosition(qName, attrs, particle);
+         AbstractPosition next = wildcardContent.newPosition(qName, attrs, particle);
          return new WildcardPosition(qName, wildcardParticle, next);
       }
       return null;
@@ -298,12 +296,12 @@
    
    private final class WildcardPosition extends NonElementPosition
    {
-      protected WildcardPosition(QName name, ParticleBinding particle, Position next)
+      protected WildcardPosition(QName name, ParticleBinding particle, AbstractPosition next)
       {
          super(name, particle, next);
       }
 
-      public Position nextPosition(QName name, Attributes atts)
+      public AbstractPosition nextPosition(QName name, Attributes atts)
       {
          if (particle.isOccurrenceAllowed(occurrence + 1))
          {
@@ -312,11 +310,11 @@
             {
                ParticleBinding wildcardParticle = new ParticleBinding(wildcardContent);
                next = wildcardContent.newPosition(name, atts, wildcardParticle);
-               next.setPrevious(this);
+               next.previous = this;
                ++occurrence;
 
                o = handler.endParticle(o, qName, particle);
-               if(previous.getValue() != null)
+               if(previous.o != null)
                   setParent(previous, handler);
                //o = initValue(stack.parent().getValue(), atts);
 

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -56,6 +56,7 @@
 import org.jboss.xb.binding.JBossXBRuntimeException;
 import org.jboss.xb.binding.Util;
 import org.jboss.xb.binding.resolver.MultiClassSchemaResolver;
+import org.jboss.xb.binding.sunday.unmarshalling.impl.runtime.RtCharactersHandler;
 import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
 import org.jboss.xb.binding.group.ValueListRepeatableParticleHandler;
 import org.jboss.xb.binding.metadata.AddMethodMetaData;
@@ -531,9 +532,17 @@
 
       XSTypeDefinition baseTypeDef = type.getBaseType();
       TypeBinding baseType = baseTypeDef == null ? null : bindType(baseTypeDef);
+      if(baseType == null)
+      {
+         binding = new TypeBinding(typeName);
+      }
+      else
+      {
+         binding = new TypeBinding(typeName, baseType);
+         if(Constants.NS_XML_SCHEMA.equals(baseTypeDef.getNamespace()))
+            binding.setCharactersHandler(DefaultHandlers.CHARACTERS_HANDLER_FACTORY.newCharactersHandler());
+      }
 
-      binding = baseType == null ? new TypeBinding(typeName) : new TypeBinding(typeName, baseType);
-
       StringList strList = type.getLexicalPattern();
       if(strList != null && strList.getLength() > 0)
       {
@@ -1384,6 +1393,17 @@
                log.trace(msg);
             }
             term.setValueMetaData(valueMetaData);
+            if(term.isElement())
+            {
+               ElementBinding e = (ElementBinding)term;
+               TypeBinding currentType = e.getType();
+               // that's not nice, i.e. creating another type with the same name but not adding it to SchemaBinding
+               // but it would be wrong to do that in case of built-in types
+               TypeBinding newType = new TypeBinding(currentType.getQName(), currentType);
+               CharactersHandler ch = DefaultHandlers.CHARACTERS_HANDLER_FACTORY.newCharactersHandler(RtCharactersHandler.VALUE_METADATA_UNMARSHAL_HANDLER);
+               newType.setCharactersHandler(ch);
+               e.setType(newType);
+            }
          }
 
          boolean mapEntryKey = appInfo.isMapEntryKey();

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtCharactersHandler.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtCharactersHandler.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtCharactersHandler.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -44,85 +44,102 @@
 public class RtCharactersHandler
    extends CharactersHandler
 {
-   public static final RtCharactersHandler INSTANCE = new RtCharactersHandler();
-
-   public Object unmarshal(QName qName,
-                           TypeBinding typeBinding,
-                           NamespaceContext nsCtx,
-                           ValueMetaData valueMetaData,
-                           String value)
+   public static final UnmarshalCharactersHandler VALUE_METADATA_UNMARSHAL_HANDLER = new UnmarshalCharactersHandler()
    {
-      Object unmarshalled = null;
-      if(valueMetaData != null)
+      public Object unmarshal(QName name, TypeBinding typeBinding, NamespaceContext nsCtx, ValueMetaData valueMetaData, String value)
       {
-         Method unmarshalMethod = RtUtil.getUnmarshalMethod(qName, valueMetaData);
+         if(valueMetaData == null)
+            throw new JBossXBRuntimeException("The handler expects non-null valueMetaData: element=" + name
+                  + ", type=" + typeBinding.getQName() + ", value=" + value);
+         Method unmarshalMethod = RtUtil.getUnmarshalMethod(name, valueMetaData);
          Object args[] = unmarshalMethod.getParameterTypes().length == 1 ?
-            new Object[]{value} :
-            new Object[]{value, nsCtx};
-         unmarshalled = RtUtil.invokeUnmarshalMethod(unmarshalMethod, args, qName);
+               new Object[]{value} : new Object[]{value, nsCtx};
+         return RtUtil.invokeUnmarshalMethod(unmarshalMethod, args, name);
       }
-      else
+   };
+   
+   public static final UnmarshalCharactersHandler RT_UNMARSHAL_HANDLER = new DefaultUnmarshalCharactersHandler()
+   {
+      public Object unmarshal(QName qName, TypeBinding typeBinding, NamespaceContext nsCtx, ValueMetaData valueMetaData, String value)
       {
-         unmarshalled = super.unmarshal(qName, typeBinding, nsCtx, valueMetaData, value);
+         Object unmarshalled = null;
+         if (valueMetaData != null)
+         {
+            Method unmarshalMethod = RtUtil.getUnmarshalMethod(qName, valueMetaData);
+            Object args[] = unmarshalMethod.getParameterTypes().length == 1 ? new Object[]
+            {value} : new Object[]
+            {value, nsCtx};
+            unmarshalled = RtUtil.invokeUnmarshalMethod(unmarshalMethod, args, qName);
+         }
+         else
+         {
+            unmarshalled = super.unmarshal(qName, typeBinding, nsCtx, valueMetaData, value);
 
-         if(typeBinding.isSimple())
-         {
-            String clsName = null;
-            boolean failIfNotFound = false;
-            if(typeBinding.getClassMetaData() != null)
+            if (typeBinding.isSimple())
             {
-               clsName = typeBinding.getClassMetaData().getImpl();
-               failIfNotFound = true;
-            }
-            else
-            {
-               QName typeName = typeBinding.getQName();
-               if(typeName != null && !Constants.NS_XML_SCHEMA.equals(typeName.getNamespaceURI()))
+               String clsName = null;
+               boolean failIfNotFound = false;
+               if (typeBinding.getClassMetaData() != null)
                {
-                  boolean ignoreLowLine = typeBinding.getSchemaBinding() != null ?
-                     typeBinding.getSchemaBinding().isIgnoreLowLine() :
-                     true;
-                  clsName =
-                     Util.xmlNameToClassName(typeName.getNamespaceURI(), typeName.getLocalPart(), ignoreLowLine);
+                  clsName = typeBinding.getClassMetaData().getImpl();
+                  failIfNotFound = true;
                }
-            }
-
-            Class<?> cls = clsName == null ? null : RtUtil.loadClass(clsName, failIfNotFound);
-            if(cls != null && !cls.isPrimitive())
-            {
-               // I assume if it doesn't have ctors, there should be static fromValue
-               // method like it is defined for enum types in JAXB2.0
-               // for java5 cls.isEnum() should be used instead
-               if(cls.getConstructors().length == 0)
+               else
                {
-                  Class<?> valueType = unmarshalled.getClass();
-                  // todo: this should be used in combination element.isNillable...
-                  if(Classes.isPrimitiveWrapper(valueType))
+                  QName typeName = typeBinding.getQName();
+                  if (typeName != null && !Constants.NS_XML_SCHEMA.equals(typeName.getNamespaceURI()))
                   {
-                     valueType = Classes.getPrimitive(valueType);
+                     boolean ignoreLowLine = typeBinding.getSchemaBinding() != null ? typeBinding.getSchemaBinding()
+                           .isIgnoreLowLine() : true;
+                     clsName = Util.xmlNameToClassName(typeName.getNamespaceURI(), typeName.getLocalPart(),
+                           ignoreLowLine);
                   }
+               }
 
-                  // it should probably invoke fromValue even if unmarshalled is null
-                  unmarshalled = unmarshalled == null ? null :
-                     RtUtil.invokeUnmarshalMethod(cls, "fromValue", unmarshalled, valueType, nsCtx, qName);
-               }
-               else
+               Class<?> cls = clsName == null ? null : RtUtil.loadClass(clsName, failIfNotFound);
+               if (cls != null && !cls.isPrimitive())
                {
-                  throw new JBossXBRuntimeException("This case is not yet supported (create a feature request): " +
-                     "simple type (" +
-                     typeBinding.getQName() +
-                     ") is bound to a class (" +
-                     cls +
-                     ") with optional property metadata with " +
-                     "default value for the property name 'value'."
-                  );
+                  // I assume if it doesn't have ctors, there should be static fromValue
+                  // method like it is defined for enum types in JAXB2.0
+                  // for java5 cls.isEnum() should be used instead
+                  if (cls.getConstructors().length == 0)
+                  {
+                     Class<?> valueType = unmarshalled.getClass();
+                     // todo: this should be used in combination element.isNillable...
+                     if (Classes.isPrimitiveWrapper(valueType))
+                     {
+                        valueType = Classes.getPrimitive(valueType);
+                     }
+
+                     // it should probably invoke fromValue even if unmarshalled is null
+                     unmarshalled = unmarshalled == null ? null : RtUtil.invokeUnmarshalMethod(cls, "fromValue",
+                           unmarshalled, valueType, nsCtx, qName);
+                  }
+                  else
+                  {
+                     throw new JBossXBRuntimeException("This case is not yet supported (create a feature request): "
+                           + "simple type (" + typeBinding.getQName() + ") is bound to a class (" + cls
+                           + ") with optional property metadata with " + "default value for the property name 'value'.");
+                  }
                }
             }
          }
+
+         return unmarshalled;
       }
+   };
+ 
+   public static final RtCharactersHandler INSTANCE = new RtCharactersHandler();
 
-      return unmarshalled;
+   public RtCharactersHandler()
+   {
+      super(RT_UNMARSHAL_HANDLER);
    }
+   
+   public RtCharactersHandler(UnmarshalCharactersHandler unmarshalHandler)
+   {
+      super(unmarshalHandler);
+   }
 
    public void setValue(QName qName, ElementBinding element, Object owner, Object value)
    {

Modified: jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java
===================================================================
--- jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java	2010-01-22 01:52:02 UTC (rev 3946)
+++ jbossxb/trunk/src/main/java/org/jboss/xb/builder/JBossXBNoSchemaBuilder.java	2010-01-22 11:24:12 UTC (rev 3947)
@@ -102,7 +102,6 @@
 import org.jboss.xb.binding.sunday.unmarshalling.AttributeHandler;
 import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler;
 import org.jboss.xb.binding.sunday.unmarshalling.ChoiceBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.DefaultElementHandler;
 import org.jboss.xb.binding.sunday.unmarshalling.DefaultElementInterceptor;
 import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
 import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
@@ -869,7 +868,7 @@
       if (root)
       {
          QName qName = generateXmlName(typeInfo, XmlNsForm.QUALIFIED, overrideNamespace, overrideName);
-         typeBinding = new TypeBinding(qName);
+         typeBinding = new TypeBinding(qName, CharactersHandler.NOOP);
       }
       else
       {



More information about the jboss-svn-commits mailing list