Index: src/jaxme/org/apache/ws/jaxme/JMElement.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/JMElement.java,v
retrieving revision 1.2
diff -u -r1.2 JMElement.java
--- src/jaxme/org/apache/ws/jaxme/JMElement.java	16 Feb 2004 23:39:48 -0000	1.2
+++ src/jaxme/org/apache/ws/jaxme/JMElement.java	5 Aug 2005 20:56:45 -0000
@@ -12,7 +12,6 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
-
  */
 package org.apache.ws.jaxme;
 
Index: src/jaxme/org/apache/ws/jaxme/generator/sg/SimpleTypeSG.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/generator/sg/SimpleTypeSG.java,v
retrieving revision 1.7
diff -u -r1.7 SimpleTypeSG.java
--- src/jaxme/org/apache/ws/jaxme/generator/sg/SimpleTypeSG.java	7 May 2005 19:42:27 -0000	1.7
+++ src/jaxme/org/apache/ws/jaxme/generator/sg/SimpleTypeSG.java	5 Aug 2005 20:56:45 -0000
@@ -155,4 +155,14 @@
    * "set" method <code>pMethod</code>.</p>
    */
   public void addValidation(JavaMethod pMethod, DirectAccessible pValue) throws SAXException;
+
+	/** Returns, whether the simple type is an instance of
+	 * <code>xs:id</code>.
+	 */
+	public boolean isXsId();
+
+	/** Returns, whether the simple type is an instance of
+	 * <code>xs:idref</code>.
+	 */
+	public boolean isXsIdRef();
 }
Index: src/jaxme/org/apache/ws/jaxme/generator/sg/impl/ccsg/HandlerSGImpl.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/generator/sg/impl/ccsg/HandlerSGImpl.java,v
retrieving revision 1.4
diff -u -r1.4 HandlerSGImpl.java
--- src/jaxme/org/apache/ws/jaxme/generator/sg/impl/ccsg/HandlerSGImpl.java	30 Jul 2005 21:05:15 -0000	1.4
+++ src/jaxme/org/apache/ws/jaxme/generator/sg/impl/ccsg/HandlerSGImpl.java	5 Aug 2005 20:56:46 -0000
@@ -17,11 +17,13 @@
 
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import javax.xml.bind.ValidationEvent;
 import javax.xml.namespace.QName;
 
+import org.apache.ws.jaxme.IDREF;
 import org.apache.ws.jaxme.ValidationEvents;
 import org.apache.ws.jaxme.generator.sg.AttributeSG;
 import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
@@ -29,6 +31,7 @@
 import org.apache.ws.jaxme.generator.sg.TypeSG;
 import org.apache.ws.jaxme.generator.types.StringSG;
 import org.apache.ws.jaxme.js.DirectAccessible;
+import org.apache.ws.jaxme.js.JavaInnerClass;
 import org.apache.ws.jaxme.js.JavaMethod;
 import org.apache.ws.jaxme.js.JavaQName;
 import org.apache.ws.jaxme.js.JavaQNameImpl;
@@ -36,6 +39,7 @@
 import org.apache.ws.jaxme.js.LocalJavaField;
 import org.apache.ws.jaxme.js.TypedValue;
 import org.apache.ws.jaxme.js.impl.TypedValueImpl;
+import org.apache.ws.jaxme.xs.xml.XsQName;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 
@@ -52,6 +56,7 @@
 	private DirectAccessible paramResult;
 	private DirectAccessible paramQName;
 	private DirectAccessible paramAttrs;
+	private JavaInnerClass idrefImplClass;
 
 	protected HandlerSGImpl(ComplexTypeSG pType, JavaSource pJs) {
 		ctSG = pType;
@@ -116,6 +121,7 @@
 		
 		JavaQName resultType = ctSG.getClassContext().getXMLInterfaceName();
 		LocalJavaField result = jm.newJavaField(resultType);
+		result.setFinal(true);
 		result.addLine("(", resultType, ") result");
 
 		Set uris = createSetOfExplicitURIs(myAttributes);
@@ -138,9 +144,40 @@
 				
 				jm.addIf(firstInNamespace, JavaSource.getQuoted(attr.getName().getLocalName()), ".equals(", pLocalName, ")");
 				firstInNamespace = false;
-				createSimpleTypeConversion(jm, myAttributes[i].getTypeSG(), pValue,
-										   "@" + myAttributes[i].getName(),
-										   attr.getPropertySG(), result);
+				if ("http://www.w3.org/2001/XMLSchema".equals(typeName.getNamespaceURI())) {
+					if ("ID".equals(typeName.getLocalName())) {
+						jm.addLine("getHandler().addId(", pValue, ", ", result, ");");
+					} else if ("IDREF".equals(typeName.getLocalName())) {
+						idref = true;
+						try {
+							// FIXME how to make method parameter 'pValue' final, to avoid this temp variable?
+							LocalJavaField idField = jm.newJavaField(String.class);
+							idField.setFinal(true);
+							idField.addLine(pValue, ";");
+
+							// FIXME how to properly create anonymous innner class?
+							LocalJavaField idrefField = jm.newJavaField(IDREF.class, "idref");
+							idrefField.addLine("new ", IDREF.class, "() {");
+							idrefField.addLine("  public void validate(", Map.class, " pIds) throws ", SAXException.class, " {");
+							idrefField.addLine("    Object o = pIds.get(", idField, ");");
+							idrefField.addLine("    if (o != null) {");
+							idrefField.addLine("      ", result, ".", attr.getPropertySG().getXMLSetMethodName(), "(", "o", ");");
+							idrefField.addLine("    } else {");
+							idrefField.addLine("      throw new ", SAXException.class, "(", JavaSource.getQuoted("ID attribute '"), " + ", idField, " + ", JavaSource.getQuoted("' is not unique"), ");");
+							idrefField.addLine("    }");
+							idrefField.addLine("  }");
+							idrefField.addLine("};");
+							jm.addLine("getHandler().addIdref(", idrefField, ");");
+						} catch (Exception e) {
+							e.printStackTrace();
+						}
+					}
+				}
+				if (!idref) {
+					createSimpleTypeConversion(jm, myAttributes[i].getTypeSG(), pValue,
+											   "@" + myAttributes[i].getName(),
+											   attr.getPropertySG(), result);
+				}
 				jm.addLine("return;");
 			}
 			if (!firstInNamespace) {
Index: src/jaxme/org/apache/ws/jaxme/generator/types/IDREFSG.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/generator/types/IDREFSG.java,v
retrieving revision 1.2
diff -u -r1.2 IDREFSG.java
--- src/jaxme/org/apache/ws/jaxme/generator/types/IDREFSG.java	16 Feb 2004 23:39:51 -0000	1.2
+++ src/jaxme/org/apache/ws/jaxme/generator/types/IDREFSG.java	5 Aug 2005 20:56:47 -0000
@@ -17,17 +17,70 @@
 package org.apache.ws.jaxme.generator.types;
 
 import org.apache.ws.jaxme.generator.sg.SGFactory;
+import org.apache.ws.jaxme.generator.sg.SGlet;
 import org.apache.ws.jaxme.generator.sg.SchemaSG;
+import org.apache.ws.jaxme.generator.sg.SimpleTypeSG;
+import org.apache.ws.jaxme.js.DirectAccessible;
+import org.apache.ws.jaxme.js.JavaMethod;
+import org.apache.ws.jaxme.js.JavaQName;
+import org.apache.ws.jaxme.js.JavaQNameImpl;
+import org.apache.ws.jaxme.js.JavaSource;
+import org.apache.ws.jaxme.js.LocalJavaField;
+import org.apache.ws.jaxme.js.TypedValue;
+import org.apache.ws.jaxme.js.impl.TypedValueImpl;
 import org.apache.ws.jaxme.xs.XSType;
 import org.xml.sax.SAXException;
 
 /**
  * @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
  */
-public class IDREFSG extends StringSG {
-  /** <p>Creates a new instance of IDREFSG.</p>
-   */
-  public IDREFSG(SGFactory pFactory, SchemaSG pSchema, XSType pType) throws SAXException {
-    super(pFactory, pSchema, pType);
-  }
+public class IDREFSG extends SimpleTypeSGImpl {
+	private static final JavaQName OBJECT_TYPE = JavaQNameImpl.getInstance(Object.class);
+
+	/** <p>Creates a new instance of IDREFSG.</p>
+	 */
+	public IDREFSG(SGFactory pFactory, SchemaSG pSchema, XSType pType) throws SAXException {
+		super(pFactory, pSchema, pType);
+	}
+
+	public JavaQName getRuntimeType(SimpleTypeSG pController) { return OBJECT_TYPE; }
+	public boolean isCausingParseConversionEvent(SimpleTypeSG pController) { return false; }
+
+	public TypedValue getCastFromString(SimpleTypeSG pController, JavaMethod pMethod, Object pValue, Object pData) throws SAXException {
+	    return new TypedValueImpl(null, OBJECT_TYPE);
+	}
+
+	public TypedValue getCastToString(SimpleTypeSG pController, JavaMethod pMethod, Object pValue, DirectAccessible pData) throws SAXException {
+		LocalJavaField s = pMethod.newJavaField(String.class);
+		pMethod.addIf(pValue, " == null");
+		pMethod.addLine(s, " = null;");
+		pMethod.addElse();
+		pMethod.addLine(s, " = getIdAttribute(", pData, ", ", pValue, ");");
+		pMethod.addIf(s, " == null");
+		pMethod.addThrowNew(IllegalStateException.class,
+							JavaSource.getQuoted("ID attribute not set"));
+		pMethod.addEndIf();
+		pMethod.addEndIf();
+		return s;
+	}
+
+	public TypedValue getCastFromString(SimpleTypeSG pController, String pValue) throws SAXException {
+		throw new IllegalStateException("Unable to resolve ID's at compile time.");
+	}
+
+	public void forAllValues(SimpleTypeSG pController, JavaMethod pMethod, Object pValue, SGlet pSGlet) throws SAXException {
+	    pSGlet.generate(pMethod, pValue);
+	}
+
+	public void forAllNonNullValues(SimpleTypeSG pController, JavaMethod pMethod, Object pValue, SGlet pSGlet) throws SAXException {
+	    LocalJavaField f = pMethod.newJavaField(OBJECT_TYPE);
+	    f.addLine(pValue);
+	    pMethod.addIf(f, " != null");
+	    pSGlet.generate(pMethod, pValue);
+	    pMethod.addEndIf();
+	}
+
+	public Object getEqualsCheck(SimpleTypeSG pController, JavaMethod pMethod, Object pValue1, Object pValue2) throws SAXException {
+	    return new Object[]{pValue1, ".equals(", pValue2, ")"};
+	}
 }
Index: src/jaxme/org/apache/ws/jaxme/generator/types/IDSG.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/generator/types/IDSG.java,v
retrieving revision 1.2
diff -u -r1.2 IDSG.java
--- src/jaxme/org/apache/ws/jaxme/generator/types/IDSG.java	16 Feb 2004 23:39:51 -0000	1.2
+++ src/jaxme/org/apache/ws/jaxme/generator/types/IDSG.java	5 Aug 2005 20:56:47 -0000
@@ -18,19 +18,20 @@
 
 import org.apache.ws.jaxme.generator.sg.SGFactory;
 import org.apache.ws.jaxme.generator.sg.SchemaSG;
+import org.apache.ws.jaxme.generator.sg.SimpleTypeSG;
 import org.apache.ws.jaxme.xs.XSType;
 import org.xml.sax.SAXException;
 
 
-/**
- * @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
+/** Implementation of {@link org.apache.ws.jaxme.generator.sg.SimpleTypeSG}
+ * for <code>xs:id</code>.
  */
 public class IDSG extends StringSG {
+	/** Creates a new instance of IDSG.
+	 */
+	public IDSG(SGFactory pFactory, SchemaSG pSchema, XSType pType) throws SAXException {
+		super(pFactory, pSchema, pType);
+	}
 
-  /** <p>Creates a new instance of IDSG.</p>
-   */
-  public IDSG(SGFactory pFactory, SchemaSG pSchema, XSType pType) throws SAXException {
-    super(pFactory, pSchema, pType);
-  }
-
+	public boolean isXsId(SimpleTypeSG pController) { return true; }
 }
Index: src/jaxme/org/apache/ws/jaxme/generator/types/SimpleTypeSGImpl.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/generator/types/SimpleTypeSGImpl.java,v
retrieving revision 1.4
diff -u -r1.4 SimpleTypeSGImpl.java
--- src/jaxme/org/apache/ws/jaxme/generator/types/SimpleTypeSGImpl.java	7 May 2005 19:42:26 -0000	1.4
+++ src/jaxme/org/apache/ws/jaxme/generator/types/SimpleTypeSGImpl.java	5 Aug 2005 20:56:47 -0000
@@ -56,6 +56,8 @@
   public boolean isAtomic(SimpleTypeSG pController) { return false; }
   public boolean isList(SimpleTypeSG pController) { return false; }
   public boolean isUnion(SimpleTypeSG pController) { return false; }
+  public boolean isXsId(SimpleTypeSG pController) { return false; }
+  public boolean isXsIdRef(SimpleTypeSG pController) { return false; }
   public boolean hasSetMethod(SimpleTypeSG pController) { return true; }
   public void setNullable(SimpleTypeSG pController, boolean pNullable) {
     setNullable(pNullable);
Index: src/jaxme/org/apache/ws/jaxme/impl/JMSAXDriver.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/impl/JMSAXDriver.java,v
retrieving revision 1.1
diff -u -r1.1 JMSAXDriver.java
--- src/jaxme/org/apache/ws/jaxme/impl/JMSAXDriver.java	10 Mar 2005 10:14:03 -0000	1.1
+++ src/jaxme/org/apache/ws/jaxme/impl/JMSAXDriver.java	5 Aug 2005 20:56:47 -0000
@@ -28,6 +28,10 @@
 	 */
 	public AttributesImpl getAttributes(JMSAXDriverController pController, Object pObject) throws SAXException;
 
+	/** Returns the objects ID attribute, if any, or null.
+	 */
+	public String getIdAttribute(JMSAXDriverController pController, Object pObject) throws SAXException;
+
 	/** Creates the objects content into SAX events, which
 	 * are being fired into the given content handler.
 	 */
Index: src/jaxme/org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java
===================================================================
RCS file: /home/cvs/ws-jaxme/src/jaxme/org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java,v
retrieving revision 1.9
diff -u -r1.9 JMUnmarshallerHandlerImpl.java
--- src/jaxme/org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java	30 Jun 2005 08:16:13 -0000	1.9
+++ src/jaxme/org/apache/ws/jaxme/impl/JMUnmarshallerHandlerImpl.java	5 Aug 2005 20:56:48 -0000
@@ -17,7 +17,10 @@
 package org.apache.ws.jaxme.impl;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import javax.xml.bind.DatatypeConverterInterface;
 import javax.xml.bind.JAXBException;
@@ -28,6 +31,7 @@
 import javax.xml.bind.helpers.ValidationEventLocatorImpl;
 import javax.xml.namespace.QName;
 
+import org.apache.ws.jaxme.IDREF;
 import org.apache.ws.jaxme.JMManager;
 import org.apache.ws.jaxme.JMUnmarshaller;
 import org.apache.ws.jaxme.JMUnmarshallerHandler;
@@ -74,6 +78,8 @@
     private final StringBuffer sb = new StringBuffer();
 	private Observer observer;
 	private Object result;
+	private final Map idMap = new HashMap();
+	private final List idrefs = new ArrayList();
 
     public int getLevel() { return level; }
 
@@ -131,6 +137,10 @@
     }
 
     public void endDocument() throws SAXException {
+    	for (Iterator i = idrefs.iterator(); i.hasNext();) {
+			IDREF idref = (IDREF) i.next();
+			idref.validate(idMap);
+		}
     }
 
     public void startPrefixMapping(String pPrefix, String pURI) throws SAXException {
@@ -394,4 +404,24 @@
 			state = STATE_GROUP;
 		}
 	}
+	
+	/**
+	 * @param id XML ID attribute of JAXB object
+	 * @param jaxbObject the JAXB object
+	 * @throws SAXException if duplicate ID
+	 */
+	public void addId(String id, Object jaxbObject) throws SAXException {
+		if (idMap.containsKey(id)) {
+			throw new SAXException("ID '" + id + "' is not unique");
+		}
+		idMap.put(id, jaxbObject);
+	}
+	
+	/**
+	 * @param idref
+	 */
+	public void addIdref(IDREF idref) {
+		idrefs.add(idref);
+	}
+	
 }
Index: src/test/jaxb/defaults.xsd
===================================================================
RCS file: /home/cvs/ws-jaxme/src/test/jaxb/defaults.xsd,v
retrieving revision 1.3
diff -u -r1.3 defaults.xsd
--- src/test/jaxb/defaults.xsd	27 Apr 2005 06:23:26 -0000	1.3
+++ src/test/jaxb/defaults.xsd	5 Aug 2005 20:56:49 -0000
@@ -79,7 +79,6 @@
 			default="NMTOKENS,NMTOKENS1"/>  		
   		<xs:attribute name="Name" type="xs:Name" default="Name" />
   		<xs:attribute name="NCName" type="xs:NCName" default="NCName" />
-  		<xs:attribute name="IDREF" type="xs:IDREF" default="idvalue0" />
   		<xs:attribute name="integer" type="xs:integer" default="1" />
   		<xs:attribute name="nonPositiveInteger"
   			type="xs:nonPositiveInteger" default="-1" />
Index: src/jaxme/org/apache/ws/jaxme/IDREF.java
===================================================================
RCS file: src/jaxme/org/apache/ws/jaxme/IDREF.java
diff -N src/jaxme/org/apache/ws/jaxme/IDREF.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/jaxme/org/apache/ws/jaxme/IDREF.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2003, 2004  The Apache Software Foundation
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ws.jaxme;
+
+import java.util.Map;
+
+import org.xml.sax.SAXException;
+
+
+/** This class is used for resolving IDREF fields. Whenever the
+ * Unmarshaller finds an instance of IDREF, then it will create
+ * an object, which implements this interface. As soon as the
+ * parser is done (and all ID's are collected), then it will
+ * invoke the method {@link #validate(Map)}.
+ */
+public interface IDREF {
+	/** Called for resolving the ID reference.
+	 * @param pIds the map of IDs->objects
+	 * @throws SAXException if IDREF references non-existing ID
+	 */
+	void validate(Map pIds) throws SAXException;
+}
