XmlElementRef(s) and XmlElementDecl validation
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties b/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties
index dcd667c..36f375b 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jaxb_validation.properties
@@ -28,11 +28,23 @@
 XML_ELEMENT__UNSPECIFIED_TYPE = Unspecified XML element type.
 XML_ELEMENT__ILLEGAL_TYPE = XML element type must be a sub-type of ''{0}''.
 
-XML_ELEMENT_REF__NO_REGISTRY = There is no XML registry configured for this package.
-XML_ELEMENT_REF__NO_MATCHING_ELEMENT_DECL = There is no XML element decl in the XML registry matching the namespace ''{0}'' and name ''{1}''.
+XML_ELEMENT_DECL__SUBST_HEAD_NAME_EQUALS_NAME = XML element decl substitution head must not match its XML element.
+XML_ELEMENT_DECL__SUBST_HEAD_NO_MATCHING_ELEMENT_DECL = XML element decl substitution head must match another XML element decl.
 
+XML_ELEMENT_REF__UNSPECIFIED_TYPE = Unspecified XML element ref type.
+XML_ELEMENT_REF__ILLEGAL_TYPE = XML element ref type must be a sub-type of ''{0}''.
+XML_ELEMENT_REF__NO_ROOT_ELEMENT = No root element specified on type ''{0}'' or any of its sub-types.
+XML_ELEMENT_REF__NO_REGISTRY = No XML registry configured for this package.
+XML_ELEMENT_REF__NO_MATCHING_ELEMENT_DECL = No XML element decl in the XML registry matching the namespace ''{0}'' and name ''{1}''.
+
+XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_TYPE = Duplicate type ''{0}'' in XML element refs.
+XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_QNAME = Duplicate element name ''{0}''in XML element refs.
+	
 XML_ELEMENTS__DUPLICATE_XML_ELEMENT_TYPE = Duplicate type ''{0}'' in XML elements.
 XML_ELEMENTS__DUPLICATE_XML_ELEMENT_QNAME = Duplicate element name ''{0}'' in XML elements.
+
+XML_REGISTRY__DUPLICATE_XML_ELEMENT_QNAME = Duplicate XML element decl name ''{0}'' {1}.
+
 XML_IDREF__TYPE_DOES_NOT_CONTAIN_XML_ID =  In order to be used with an XML ID ref, type ''{0}'' must contain a property or field mapped as an XML ID.
 XML_LIST_DEFINED_ON_NON_ARRAY_NON_COLLECTION = Only a collection or array property may be mapped as an XML list.
 MULTIPLE_XML_ANY_ELEMENT_MAPPINGS_DEFINED = Attribute ''{0}'' cannot be mapped as XmlAnyElement because attribute ''{1}'' is already mapped as XmlAnyElement, cannot define multiple XmlAnyElement mappings
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jpt_jaxb_core.properties b/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jpt_jaxb_core.properties
index 064e5cd..14eabf9 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jpt_jaxb_core.properties
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/property_files/jpt_jaxb_core.properties
@@ -26,5 +26,8 @@
 XML_ATTRIBUTE_DESC = XML attribute declaration
 XML_ELEMENT_DESC = XML element declaration
 XML_TYPE_DESC = XML type definition
+SUBSTITUTION_HEAD_DESC = XML element substitution head
+
+XML_ELEMENT_DECL__SCOPE = in the scope of ''{0}''
 
 PREFERENCES_FLUSH_JOB_NAME=Flush Preferences: {0}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbElementFactoryMethod.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbElementFactoryMethod.java
index 2fc90c9..563907c 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbElementFactoryMethod.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbElementFactoryMethod.java
@@ -10,6 +10,7 @@
 package org.eclipse.jpt.jaxb.core.context;
 
 import org.eclipse.jpt.common.core.resource.java.JavaResourceMethod;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
 
 /**
  * Represents a JAXB element factory method  
@@ -25,60 +26,57 @@
  * @since 3.0
  */
 public interface JaxbElementFactoryMethod
-		extends JaxbContextNode {
-
+		extends JavaContextNode {
+	
 	JavaResourceMethod getResourceMethod();
-
+	
 	/**
 	 * Return the method name
 	 */
 	String getName();
-
-	/**
-	 * Corresponds to the XmlElementDecl annotation 'name' element
-	 */
-	String getElementName();
-	void setElementName(String elementName);
-		String ELEMENT_NAME_PROPERTY = "elementName"; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the XmlElementDecl annotation 'defaultValue' element
-	 */
-	String getDefaultValue();
-	void setDefaultValue(String defaultValue);
-		String DEFAULT_VALUE_PROPERTY = "defaultValue"; //$NON-NLS-1$
-		String DEFAULT_DEFAULT_VALUE = "\u0000"; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the XmlElementDecl annotation 'namespace' element
-	 */
-	String getNamespace();
-	void setNamespace(String namespace);
-		String NAMESPACE_PROPERTY = "namespace"; //$NON-NLS-1$
-		String DEFAULT_NAMESPACE = "##default"; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the XmlElementDecl annotation 'substitutionHeadName' element
-	 */
-	String getSubstitutionHeadName();
-	void setSubstitutionHeadName(String substitutionHeadName);
-		String SUBSTIUTION_HEAD_NAME_PROPERTY = "substitutionHeadName"; //$NON-NLS-1$
-		String DEFAULT_SUBSTIUTION_HEAD_NAME = ""; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the XmlElementDecl annotation 'substitutionHeadNamespace' element
-	 */
-	String getSubstitutionHeadNamespace();
-	void setSubstitutionHeadNamespace(String substitutionHeadNamespace);
-		String SUBSTIUTION_HEAD_NAMESPACE_PROPERTY = "substitutionHeadNamespace"; //$NON-NLS-1$
-		String DEFAULT_SUBSTIUTION_HEAD_NAMESPACE = "##default"; //$NON-NLS-1$
-
-
+	
+	
+	// ***** scope *****
+	
 	/**
 	 * Corresponds to the XmlElementDecl annotation 'scope' element
 	 */
+	String SCOPE_PROPERTY = "scope"; //$NON-NLS-1$
+	
 	String getScope();
+	
 	void setScope(String scope);
-		String SCOPE_PROPERTY = "scope"; //$NON-NLS-1$
-		String DEFAULT_SCOPE_CLASS_NAME = "javax.xml.bind.annotation.XmlElementDecl.GLOBAL"; //$NON-NLS-1$
+	
+	String DEFAULT_SCOPE_CLASS_NAME = "javax.xml.bind.annotation.XmlElementDecl.GLOBAL"; //$NON-NLS-1$
+	
+	String getFullyQualifiedScope();
+	
+	/**
+	 * Return true if the scope is default or is specified to be XmlElementDecl.GLOBAL.
+	 */
+	boolean isGlobalScope();
+	
+	
+	// ***** qName *****
+	
+	JaxbQName getQName();
+	
+	
+	// ***** substitution head qName *****
+	
+	JaxbQName getSubstitutionHeadQName();
+	
+	
+	// ***** default value *****
+	
+	/**
+	 * Corresponds to the XmlElementDecl annotation 'defaultValue' element
+	 */
+	String DEFAULT_VALUE_PROPERTY = "defaultValue"; //$NON-NLS-1$
+	
+	String getDefaultValue();
+	
+	void setDefaultValue(String defaultValue);
+	
+	String DEFAULT_DEFAULT_VALUE = "\u0000"; //$NON-NLS-1$	
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java
index f52f029..74331cf 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbPersistentClass.java
@@ -72,6 +72,9 @@
 	 * Return true if 1 or more attributes include the @XmlId annotation
 	 */
 	boolean containsXmlId();
-
-
+	
+	/**
+	 * Return true if this class or a subclass has a root element defined
+	 */
+	boolean hasRootElementInHierarchy();
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbQName.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbQName.java
index 2053baa..5ef4178 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbQName.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/JaxbQName.java
@@ -52,7 +52,7 @@
 	
 	String getSpecifiedName();
 	
-	void setSpecifiedName(String name);	
+	void setSpecifiedName(String name);
 	
 	
 	// ***** validation *****
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlAnyElementMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlAnyElementMapping.java
index 1e2b502..0533b8e 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlAnyElementMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlAnyElementMapping.java
@@ -24,29 +24,62 @@
  */
 public interface XmlAnyElementMapping
 		extends JaxbAttributeMapping, XmlAdaptable {	
-
-
+	
+	// ***** lax *****
+	
 	boolean isLax();
-	boolean isDefaultLax();
-		boolean DEFAULT_LAX = false;
+	
+	String SPECIFIED_LAX_PROPERTY = "specifiedLax"; //$NON-NLS-1$
+	
 	Boolean getSpecifiedLax();
+	
 	void setSpecifiedLax(Boolean specifiedLax);
-		String SPECIFIED_LAX_PROPERTY = "specifiedLax"; //$NON-NLS-1$
-
-	/**************** value *****************/
-
+	
+	boolean isDefaultLax();
+	
+	boolean DEFAULT_LAX = false;
+	
+	
+	// ***** value *****
+	
 	String getValue();
-	String getDefaultValue();
-		String DEFAULT_TYPE_PROPERTY = "defaultValue"; //$NON-NLS-1$
+	
+	String SPECIFIED_VALUE_PROPERTY = "specifiedValue"; //$NON-NLS-1$
+	
 	String getSpecifiedValue();
+	
 	void setSpecifiedValue(String value);
-		String SPECIFIED_VALUE_PROPERTY = "specifiedValue"; //$NON-NLS-1$
-		String DEFAULT_VALUE = "javax.xml.bind.annotation.W3CDomHandler"; //$NON-NLS-1$
-
-	/********** XmlMixed **********/
+	
+	String DEFAULT_TYPE_PROPERTY = "defaultValue"; //$NON-NLS-1$
+	
+	String getDefaultValue();
+	
+	String DEFAULT_VALUE = "javax.xml.bind.annotation.W3CDomHandler"; //$NON-NLS-1$
+	
+	
+	// ***** XmlElementRefs *****
+	
+	XmlElementRefs getXmlElementRefs();
+	
+	
+	// ***** XmlElementWrapper *****
+	
+	String XML_ELEMENT_WRAPPER_PROPERTY = "xmlElementWrapper"; //$NON-NLS-1$
+	
+	XmlElementWrapper getXmlElementWrapper();
+	
+	XmlElementWrapper addXmlElementWrapper();
+	
+	void removeXmlElementWrapper();
+	
+	
+	// ***** XmlMixed *****
+	
+	String XML_MIXED_PROPERTY = "xmlMixed"; //$NON-NLS-1$
+	
 	XmlMixed getXmlMixed();
+	
 	XmlMixed addXmlMixed();
-	void removeXmlMixed();
-		String XML_MIXED_PROPERTY = "xmlMixed"; //$NON-NLS-1$
-
+	
+	void removeXmlMixed();	
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefMapping.java
index c814859..ebce681 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefMapping.java
@@ -24,6 +24,8 @@
 public interface XmlElementRefMapping
 		extends JaxbAttributeMapping, XmlAdaptable {
 	
+	// ***** XmlElementRef *****
+	
 	XmlElementRef getXmlElementRef();
 	
 	
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefs.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefs.java
new file mode 100644
index 0000000..efbc6bd
--- /dev/null
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefs.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ *  Copyright (c) 2011  Oracle. All rights reserved.
+ *  This program and the accompanying materials are made available under the
+ *  terms of the Eclipse Public License v1.0, which accompanies this distribution
+ *  and is available at http://www.eclipse.org/legal/epl-v10.html
+ *  
+ *  Contributors: 
+ *  	Oracle - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.jaxb.core.context;
+
+import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
+
+
+public interface XmlElementRefs
+		extends JavaContextNode {
+	
+	// ***** XmlElementRefs *****
+	
+	String XML_ELEMENT_REFS_LIST = "xmlElementRefs"; //$NON-NLS-1$
+	
+	ListIterable<XmlElementRef> getXmlElementRefs();
+	
+	int getXmlElementRefsSize();
+	
+	XmlElementRef addXmlElementRef(int index);
+	
+	void removeXmlElementRef(int index);
+	
+	void removeXmlElementRef(XmlElementRef xmlElementRef);
+	
+	void moveXmlElementRef(int targetIndex, int sourceIndex);
+	
+	
+	// ***** misc *****
+	
+	/**
+	 * Return all type names that are directly referenced (for purposes of building a JAXB context)
+	 */
+	Iterable<String> getDirectlyReferencedTypeNames();
+}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefsMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefsMapping.java
index 232fe15..1ad02f9 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefsMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/context/XmlElementRefsMapping.java
@@ -9,7 +9,6 @@
  *******************************************************************************/
 package org.eclipse.jpt.jaxb.core.context;
 
-import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
 
 /**
  * Represents a JAXB xml element refs mapping (@XmlElementRefs)
@@ -28,19 +27,7 @@
 	
 	// ***** XmlElementRefs *****
 	
-	String XML_ELEMENT_REFS_LIST = "xmlElementRefs"; //$NON-NLS-1$
-	
-	ListIterable<XmlElementRef> getXmlElementRefs();
-	
-	int getXmlElementRefsSize();
-	
-	XmlElementRef addXmlElementRef(int index);
-	
-	void removeXmlElementRef(int index);
-	
-	void removeXmlElementRef(XmlElementRef xmlElementRef);
-	
-	void moveXmlElementRef(int targetIndex, int sourceIndex);
+	XmlElementRefs getXmlElementRefs();
 	
 	
 	// ***** XmlElementWrapper *****
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/JptJaxbCoreMessages.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/JptJaxbCoreMessages.java
index b7abc42..112a115 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/JptJaxbCoreMessages.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/JptJaxbCoreMessages.java
@@ -36,7 +36,9 @@
 	public static String XML_ATTRIBUTE_DESC;
 	public static String XML_ELEMENT_DESC;
 	public static String XML_TYPE_DESC;
+	public static String SUBSTITUTION_HEAD_DESC;
 	
+	public static String XML_ELEMENT_DECL__SCOPE;
 	
 	
 	private static final String BUNDLE_NAME = "jpt_jaxb_core"; //$NON-NLS-1$
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java
index 410b352..fe52fc0 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/GenericContextRoot.java
@@ -15,7 +15,6 @@
 public class GenericContextRoot
 		extends AbstractJaxbContextRoot {
 	
-	
 	public GenericContextRoot(JaxbProject jaxbProject) {
 		super(jaxbProject);
 	}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaElementQName.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaElementQName.java
index c480813..2a3f118 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaElementQName.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaElementQName.java
@@ -30,8 +30,8 @@
 public abstract class AbstractJavaElementQName
 		extends AbstractJavaQName {
 	
-	public AbstractJavaElementQName(JavaContextNode parent) {
-		super(parent);
+	public AbstractJavaElementQName(JavaContextNode parent, AbstractJavaQName.AnnotationProxy proxy) {
+		super(parent, proxy);
 	}
 	
 		
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaPersistentType.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaPersistentType.java
index 3d9d377..3090619 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaPersistentType.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaPersistentType.java
@@ -334,17 +334,11 @@
 			extends AbstractJavaQName {
 		
 		protected XmlTypeQName(JavaContextNode parent) {
-			super(parent);
+			super(parent, new QNameAnnotationProxy());
 		}
 		
 		
 		@Override
-		protected QNameAnnotation getAnnotation(boolean createIfNull) {
-			// never null
-			return AbstractJavaPersistentType.this.getXmlTypeAnnotation();
-		}
-		
-		@Override
 		public String getDefaultNamespace() {
 			return AbstractJavaPersistentType.this.getJaxbPackage().getNamespace();
 		}
@@ -412,6 +406,16 @@
 			}
 		}
 	}
+		
+		
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			return AbstractJavaPersistentType.this.getXmlTypeAnnotation();
+		}
+	}
 	
 	
 	/**
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaQName.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaQName.java
index e658fe4..e345acf 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaQName.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/AbstractJavaQName.java
@@ -29,15 +29,18 @@
 		extends AbstractJavaContextNode 
 		implements JaxbQName {
 	
+	protected final AnnotationProxy proxy;
+	
 	protected String specifiedNamespace;
 	
 	protected String specifiedName;
 	
 	
-	public AbstractJavaQName(JavaContextNode parent) {
+	public AbstractJavaQName(JavaContextNode parent, AnnotationProxy proxy) {
 		super(parent);
-		this.specifiedNamespace = buildSpecifiedNamespace();
-		this.specifiedName = buildSpecifiedName();
+		this.proxy = proxy;
+		this.specifiedNamespace = getAnnotationNamespace();
+		this.specifiedName = getAnnotationName();
 	}
 	
 	
@@ -46,13 +49,11 @@
 		return (JavaContextNode) super.getParent();
 	}
 	
-	protected abstract QNameAnnotation getAnnotation(boolean createIfNull);
-	
 	@Override
 	public void synchronizeWithResourceModel() {
 		super.synchronizeWithResourceModel();
-		setSpecifiedNamespace_(buildSpecifiedNamespace());
-		setSpecifiedName_(buildSpecifiedName());
+		setSpecifiedNamespace_(getAnnotationNamespace());
+		setSpecifiedName_(getAnnotationName());
 	}
 	
 	
@@ -70,8 +71,8 @@
 	}
 	
 	public void setSpecifiedNamespace(String newSpecifiedNamespace) {
-		getAnnotation(true).setNamespace(newSpecifiedNamespace);
-		this.setSpecifiedNamespace_(newSpecifiedNamespace);
+		setAnnotationNamespace(newSpecifiedNamespace);
+		setSpecifiedNamespace_(newSpecifiedNamespace);
 	}
 	
 	protected void setSpecifiedNamespace_(String newSpecifiedNamespace) {
@@ -80,9 +81,12 @@
 		firePropertyChanged(SPECIFIED_NAMESPACE_PROPERTY, oldNamespace, newSpecifiedNamespace);
 	}
 	
-	protected String buildSpecifiedNamespace() {
-		QNameAnnotation annotation = getAnnotation(false);
-		return annotation == null ? null : annotation.getNamespace();
+	protected void setAnnotationNamespace(String newNamespace) {
+		this.proxy.setNamespace(newNamespace);
+	}
+	
+	protected String getAnnotationNamespace() {
+		return this.proxy.getNamespace();
 	}
 	
 	
@@ -99,7 +103,7 @@
 	}
 	
 	public void setSpecifiedName(String newSpecifiedName) {
-		getAnnotation(true).setName(newSpecifiedName);
+		setAnnotationName(newSpecifiedName);
 		setSpecifiedName_(newSpecifiedName);
 	}
 	
@@ -109,9 +113,12 @@
 		firePropertyChanged(SPECIFIED_NAME_PROPERTY, old, newSpecifiedName);
 	}
 	
-	protected String buildSpecifiedName() {
-		QNameAnnotation annotation = getAnnotation(false);
-		return annotation == null ? null : annotation.getName();
+	protected void setAnnotationName(String newName) {
+		this.proxy.setName(newName);
+	}
+	
+	protected String getAnnotationName() {
+		return this.proxy.getName();
 	}
 	
 	
@@ -125,29 +132,19 @@
 			return result;
 		}
 		
-		if (namespaceTouches(pos, astRoot)) {
+		if (this.proxy.namespaceTouches(pos, astRoot)) {
 			return getNamespaceProposals(filter);
 		}
 		
-		if (nameTouches(pos, astRoot)) {
+		if (this.proxy.nameTouches(pos, astRoot)) {
 			return getNameProposals(filter);
 		}
 		
 		return EmptyIterable.instance();
 	}
 	
-	protected boolean namespaceTouches(int pos, CompilationUnit astRoot) {
-		QNameAnnotation annotation = getAnnotation(false);
-		return (annotation == null) ? false : annotation.namespaceTouches(pos, astRoot);
-	}
-	
 	protected abstract Iterable<String> getNamespaceProposals(Filter<String> filter);
 	
-	protected boolean nameTouches(int pos, CompilationUnit astRoot) {
-		QNameAnnotation annotation = getAnnotation(false);
-		return (annotation == null) ? false : annotation.nameTouches(pos, astRoot);
-	}
-	
 	protected abstract Iterable<String> getNameProposals(Filter<String> filter);
 	
 	
@@ -158,18 +155,16 @@
 		return getParent().getValidationTextRange(astRoot);
 	}
 	
+	protected TextRange getTextRange(TextRange textRange, CompilationUnit astRoot) {
+		return (textRange != null) ? textRange : getParent().getValidationTextRange(astRoot);
+	}
+	
 	public TextRange getNamespaceTextRange(CompilationUnit astRoot) {
-		QNameAnnotation annotation = getAnnotation(false);
-		return (annotation == null) ? null : getTextRange(annotation.getNamespaceTextRange(astRoot), astRoot);
+		return getTextRange(this.proxy.getNamespaceTextRange(astRoot), astRoot);
 	}
 	
 	public TextRange getNameTextRange(CompilationUnit astRoot) {
-		QNameAnnotation annotation = getAnnotation(false);
-		return (annotation == null) ? null : getTextRange(annotation.getNameTextRange(astRoot), astRoot);
-	}
-	
-	protected TextRange getTextRange(TextRange textRange, CompilationUnit astRoot) {
-		return (textRange != null) ? textRange : getParent().getValidationTextRange(astRoot);
+		return getTextRange(this.proxy.getNameTextRange(astRoot), astRoot);
 	}
 	
 	/**
@@ -211,6 +206,74 @@
 				JaxbValidationMessages.QNAME__UNRESOLVED_COMPONENT,
 				new String[] { getReferencedComponentTypeDescription(), getNamespace(), getName() },
 				this,
-				getValidationTextRange(astRoot));
+				getNameTextRange(astRoot));
+	}
+	
+	
+	public interface AnnotationProxy {
+		
+		String getNamespace();
+		
+		void setNamespace(String namespace);
+		
+		boolean namespaceTouches(int pos, CompilationUnit astRoot);
+		
+		TextRange getNamespaceTextRange(CompilationUnit astRoot);
+		
+		String getName();
+		
+		void setName(String name);
+		
+		boolean nameTouches(int pos, CompilationUnit astRoot);
+		
+		TextRange getNameTextRange(CompilationUnit astRoot);
+	}
+	
+	
+	/**
+	 * represents a {@link QNameAnnotation}
+	 */
+	public static abstract class AbstractQNameAnnotationProxy
+			implements AnnotationProxy {
+		
+		protected abstract QNameAnnotation getAnnotation(boolean createIfNull);
+		
+		public String getNamespace() {
+			QNameAnnotation annotation = getAnnotation(false);
+			return annotation == null ? null : annotation.getNamespace();
+		}
+		
+		public void setNamespace(String newSpecifiedNamespace) {
+			getAnnotation(true).setNamespace(newSpecifiedNamespace);
+		}
+		
+		public boolean namespaceTouches(int pos, CompilationUnit astRoot) {
+			QNameAnnotation annotation = getAnnotation(false);
+			return (annotation == null) ? false : annotation.namespaceTouches(pos, astRoot);
+		}
+		
+		public TextRange getNamespaceTextRange(CompilationUnit astRoot) {
+			QNameAnnotation annotation = getAnnotation(false);
+			return (annotation == null) ? null : annotation.getNamespaceTextRange(astRoot);
+		}
+			
+		public String getName() {
+			QNameAnnotation annotation = getAnnotation(false);
+			return annotation == null ? null : annotation.getName();
+		}
+		
+		public void setName(String newSpecifiedName) {
+			getAnnotation(true).setName(newSpecifiedName);
+		}
+		
+		public boolean nameTouches(int pos, CompilationUnit astRoot) {
+			QNameAnnotation annotation = getAnnotation(false);
+			return (annotation == null) ? false : annotation.nameTouches(pos, astRoot);
+		}
+		
+		public TextRange getNameTextRange(CompilationUnit astRoot) {
+			QNameAnnotation annotation = getAnnotation(false);
+			return (annotation == null) ? null : annotation.getNameTextRange(astRoot);
+		}
 	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaElementFactoryMethod.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaElementFactoryMethod.java
index 9b7e10a..e4e5922 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaElementFactoryMethod.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaElementFactoryMethod.java
@@ -9,181 +9,439 @@
  ******************************************************************************/
 package org.eclipse.jpt.jaxb.core.internal.context.java;
 
+import java.util.List;
+import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceMethod;
+import org.eclipse.jpt.common.core.utility.TextRange;
+import org.eclipse.jpt.common.utility.Filter;
+import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.StringTools;
+import org.eclipse.jpt.common.utility.internal.Tools;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
 import org.eclipse.jpt.jaxb.core.context.JaxbElementFactoryMethod;
+import org.eclipse.jpt.jaxb.core.context.JaxbPersistentClass;
+import org.eclipse.jpt.jaxb.core.context.JaxbQName;
 import org.eclipse.jpt.jaxb.core.context.JaxbRegistry;
-import org.eclipse.jpt.jaxb.core.internal.context.AbstractJaxbContextNode;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
+import org.eclipse.jpt.jaxb.core.internal.JptJaxbCoreMessages;
+import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
+import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
 import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
+import org.eclipse.jpt.jaxb.core.resource.java.QNameAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlElementDeclAnnotation;
+import org.eclipse.jpt.jaxb.core.xsd.XsdSchema;
+import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
 
 public class GenericJavaElementFactoryMethod
-		extends AbstractJaxbContextNode
+		extends AbstractJavaContextNode
 		implements JaxbElementFactoryMethod {
 
 	protected final JavaResourceMethod resourceMethod;
-
-	protected String elementName;
-	protected String defaultValue;
-	protected String namespace;
+	
 	protected String scope;
-	protected String substitutionHeadName;
-	protected String substitutionHeadNamespace;
-
+	
+	protected JaxbQName qName;
+	
+	protected JaxbQName substitutionHeadQName;
+	
+	protected String defaultValue;
+	
+	
 	public GenericJavaElementFactoryMethod(JaxbRegistry parent, JavaResourceMethod resourceMethod) {
 		super(parent);
 		this.resourceMethod = resourceMethod;
-		this.elementName = this.getResourceElementName();
+		this.scope = getResourceScope();
+		this.qName = buildQName();
+		this.substitutionHeadQName = buildSubstitutionHeadQName();
 		this.defaultValue = this.getResourceDefaultValue();
-		this.namespace = this.getResourceNamespace();
-		this.scope = this.getResourceScope();
-		this.substitutionHeadName = this.getResourceSubstitutionHeadName();
-		this.substitutionHeadNamespace = this.getResourceSubstitutionHeadNamespace();
 	}
-
+	
+	
+	protected JaxbQName buildQName() {
+		return new XmlElementDeclQName(this);
+	}
+	
+	protected JaxbQName buildSubstitutionHeadQName() {
+		return new XmlElementDeclSubstitutionHeadQName(this);
+	}
+	
+	protected JaxbRegistry getRegistry() {
+		return (JaxbRegistry) getParent();
+	}
+	
 	public JavaResourceMethod getResourceMethod() {
 		return this.resourceMethod;
 	}
-
-	// ********** synchronize/update **********
-
+	
+	protected XmlElementDeclAnnotation getXmlElementDeclAnnotation() {
+		return (XmlElementDeclAnnotation) getResourceMethod().getAnnotation(JAXB.XML_ELEMENT_DECL);
+	}
+	
+	
+	// ***** synchronize/update *****
+	
 	@Override
 	public void synchronizeWithResourceModel() {
 		super.synchronizeWithResourceModel();
-		this.setElementName_(this.getResourceElementName());
-		this.setDefaultValue_(this.getResourceDefaultValue());
-		this.setNamespace_(this.getResourceNamespace());
-		this.setScope_(this.getResourceScope());
-		this.setSubstitutionHeadName_(this.getResourceSubstitutionHeadName());
-		this.setSubstitutionHeadNamespace_(this.getResourceSubstitutionHeadNamespace());
+		setScope_(getResourceScope());
+		this.qName.synchronizeWithResourceModel();
+		this.substitutionHeadQName.synchronizeWithResourceModel();
+		setDefaultValue_(getResourceDefaultValue());
 	}
-
-
-	// ********** xml enum value annotation **********
-
-	protected XmlElementDeclAnnotation getXmlElementDeclAnnotation() {
-		return (XmlElementDeclAnnotation) this.getResourceMethod().getNonNullAnnotation(JAXB.XML_ELEMENT_DECL);
+	
+	@Override
+	public void update() {
+		super.update();
+		this.qName.update();
+		this.substitutionHeadQName.update();
 	}
+	
 
-
-	// ************** JaxbElementFactoryMethod impl ***********
+	// ***** JaxbElementFactoryMethod impl *****
 
 	public String getName() {
 		return this.resourceMethod.getName();
 	}
-
-	// ********** element name **********
-
-	public String getElementName() {
-		return this.elementName;
-	}
-
-	public void setElementName(String elementName) {
-		this.getXmlElementDeclAnnotation().setName(elementName);
-		this.setElementName_(elementName);	
-	}
-
-	protected void setElementName_(String elementName) {
-		String old = this.elementName;
-		this.elementName = elementName;
-		this.firePropertyChanged(ELEMENT_NAME_PROPERTY, old, elementName);
-	}
-
-	protected String getResourceElementName() {
-		return this.getXmlElementDeclAnnotation().getName();
-	}
-
-	public String getDefaultValue() {
-		return this.defaultValue;
-	}
-
-	public void setDefaultValue(String defaultValue) {
-		this.getXmlElementDeclAnnotation().setDefaultValue(defaultValue);
-		this.setDefaultValue_(defaultValue);	
-	}
-
-	protected void setDefaultValue_(String defaultValue) {
-		String old = this.defaultValue;
-		this.defaultValue = defaultValue;
-		this.firePropertyChanged(DEFAULT_VALUE_PROPERTY, old, defaultValue);
-	}
-
-	protected String getResourceDefaultValue() {
-		return this.getXmlElementDeclAnnotation().getDefaultValue();
-	}
-
-	public String getNamespace() {
-		return this.namespace;
-	}
-
-	public void setNamespace(String namespace) {
-		this.getXmlElementDeclAnnotation().setNamespace(namespace);
-		this.setNamespace_(namespace);	
-	}
-
-	protected void setNamespace_(String namespace) {
-		String old = this.namespace;
-		this.namespace = namespace;
-		this.firePropertyChanged(NAMESPACE_PROPERTY, old, namespace);
-	}
-
-	protected String getResourceNamespace() {
-		return this.getXmlElementDeclAnnotation().getNamespace();
-	}
-
+	
+	
+	// ***** scope *****
+	
 	public String getScope() {
 		return this.scope;
 	}
-
-	public void setScope(String scope) {
-		this.getXmlElementDeclAnnotation().setScope(scope);
-		this.setScope_(scope);	
-	}
-
+	
 	protected void setScope_(String scope) {
 		String old = this.scope;
 		this.scope = scope;
-		this.firePropertyChanged(SCOPE_PROPERTY, old, scope);
+		firePropertyChanged(SCOPE_PROPERTY, old, scope);
 	}
-
+	
+	public void setScope(String scope) {
+		getXmlElementDeclAnnotation().setScope(scope);
+		setScope_(scope);	
+	}
+	
 	protected String getResourceScope() {
-		return this.getXmlElementDeclAnnotation().getScope();
+		return getXmlElementDeclAnnotation().getScope();
 	}
-
-	public String getSubstitutionHeadName() {
-		return this.substitutionHeadName;
+	
+	public String getFullyQualifiedScope() {
+		return (this.scope == null) ? DEFAULT_SCOPE_CLASS_NAME : getXmlElementDeclAnnotation().getFullyQualifiedScopeClassName();
 	}
-
-	public void setSubstitutionHeadName(String substitutionHeadName) {
-		this.getXmlElementDeclAnnotation().setSubstitutionHeadName(substitutionHeadName);
-		this.setSubstitutionHeadName_(substitutionHeadName);	
+	
+	public boolean isGlobalScope() {
+		return DEFAULT_SCOPE_CLASS_NAME.equals(getFullyQualifiedScope());
 	}
-
-	protected void setSubstitutionHeadName_(String substitutionHeadName) {
-		String old = this.substitutionHeadName;
-		this.substitutionHeadName = substitutionHeadName;
-		this.firePropertyChanged(SUBSTIUTION_HEAD_NAME_PROPERTY, old, substitutionHeadName);
+	
+	
+	// ***** qname *****
+	
+	public JaxbQName getQName() {
+		return this.qName;
 	}
-
-	protected String getResourceSubstitutionHeadName() {
-		return this.getXmlElementDeclAnnotation().getSubstitutionHeadName();
+	
+	
+	// ***** substitution head qname *****
+	
+	public JaxbQName getSubstitutionHeadQName() {
+		return this.substitutionHeadQName;
 	}
-
-	public String getSubstitutionHeadNamespace() {
-		return this.substitutionHeadNamespace;
+	
+	
+	// ***** default value *****
+	
+	public String getDefaultValue() {
+		return this.defaultValue;
 	}
-
-	public void setSubstitutionHeadNamespace(String substitutionHeadNamespace) {
-		this.getXmlElementDeclAnnotation().setSubstitutionHeadNamespace(substitutionHeadNamespace);
-		this.setSubstitutionHeadNamespace_(substitutionHeadNamespace);	
+	
+	protected void setDefaultValue_(String defaultValue) {
+		String old = this.defaultValue;
+		this.defaultValue = defaultValue;
+		firePropertyChanged(DEFAULT_VALUE_PROPERTY, old, defaultValue);
 	}
-
-	protected void setSubstitutionHeadNamespace_(String substitutionHeadNamespace) {
-		String old = this.substitutionHeadNamespace;
-		this.substitutionHeadNamespace = substitutionHeadNamespace;
-		this.firePropertyChanged(SUBSTIUTION_HEAD_NAMESPACE_PROPERTY, old, substitutionHeadNamespace);
+	
+	public void setDefaultValue(String defaultValue) {
+		getXmlElementDeclAnnotation().setDefaultValue(defaultValue);
+		setDefaultValue_(defaultValue);	
 	}
-
-	protected String getResourceSubstitutionHeadNamespace() {
-		return this.getXmlElementDeclAnnotation().getSubstitutionHeadNamespace();
+	
+	protected String getResourceDefaultValue() {
+		return getXmlElementDeclAnnotation().getDefaultValue();
+	}
+	
+	
+	// ***** content assist *****
+	
+	@Override
+	public Iterable<String> getJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
+		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
+		}
+		
+		result = this.qName.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
+		}
+		
+		result = this.substitutionHeadQName.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
+		}
+		
+		return EmptyIterable.instance();
+	}
+	
+	
+	// ***** validation *****
+	
+	@Override
+	public TextRange getValidationTextRange(CompilationUnit astRoot) {
+		return getXmlElementDeclAnnotation().getTextRange(astRoot);
+	}
+	
+	@Override
+	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+		super.validate(messages, reporter, astRoot);
+		this.qName.validate(messages, reporter, astRoot);
+		this.substitutionHeadQName.validate(messages, reporter, astRoot);
+	}
+	
+	
+	protected class XmlElementDeclQName
+			extends AbstractJavaQName {
+		
+		protected XmlElementDeclQName(JavaContextNode parent) {
+			super(parent, new QNameAnnotationProxy());
+		}
+		
+		
+		@Override
+		public String getDefaultName() {
+			return null;
+		}
+		
+		@Override
+		public String getDefaultNamespace() {
+			return GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getNamespace();
+		}
+		
+		@Override
+		public Iterable<String> getNameProposals(Filter<String> filter) {
+			if (! GenericJavaElementFactoryMethod.this.isGlobalScope()) {
+				String fqScope = GenericJavaElementFactoryMethod.this.getFullyQualifiedScope();
+				JaxbPersistentClass scopeClass = 
+						GenericJavaElementFactoryMethod.this.getJaxbProject().getContextRoot().getPersistentClass(fqScope);
+				if (scopeClass != null) {
+					XsdTypeDefinition xsdType = scopeClass.getXsdTypeDefinition();
+					if (xsdType != null) {
+						return xsdType.getElementNameProposals(getNamespace(), filter, true);
+					}
+				}
+			}
+			
+			XsdSchema xsdSchema = GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getXsdSchema();
+			if (xsdSchema != null) {
+				return xsdSchema.getElementNameProposals(getNamespace(), filter);
+			}
+			
+			return EmptyIterable.instance(); 
+		}
+		
+		@Override
+		public Iterable<String> getNamespaceProposals(Filter<String> filter) {
+			XsdSchema xsdSchema = GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getXsdSchema();
+			return (xsdSchema == null) ? EmptyIterable.<String>instance() : xsdSchema.getNamespaceProposals(filter);
+		}
+		
+		@Override
+		public String getReferencedComponentTypeDescription() {
+			return JptJaxbCoreMessages.XML_ELEMENT_DESC;
+		}
+		
+		@Override
+		protected void validateReference(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+			if (! GenericJavaElementFactoryMethod.this.isGlobalScope()) {
+				String fqScope = GenericJavaElementFactoryMethod.this.getFullyQualifiedScope();
+				JaxbPersistentClass scopeClass = 
+						GenericJavaElementFactoryMethod.this.getJaxbProject().getContextRoot().getPersistentClass(fqScope);
+				if (scopeClass != null) {
+					XsdTypeDefinition xsdType = scopeClass.getXsdTypeDefinition();
+					if (xsdType == null) {
+						return;
+					}
+					
+					if (xsdType.getElement(getNamespace(), getName(), true) == null) {
+						messages.add(getUnresolveSchemaComponentMessage(astRoot));
+					}
+				}
+			}
+			else {
+				XsdSchema xsdSchema = GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getXsdSchema();
+				if (xsdSchema != null) {
+					if (xsdSchema.getElementDeclaration(getNamespace(), getName()) == null) {
+						messages.add(getUnresolveSchemaComponentMessage(astRoot));
+					}
+				}
+			}
+		}
+	}
+	
+	
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			return GenericJavaElementFactoryMethod.this.getXmlElementDeclAnnotation();
+		}
+	}
+	
+	
+	protected class XmlElementDeclSubstitutionHeadQName
+			extends AbstractJavaQName {
+		
+		protected XmlElementDeclSubstitutionHeadQName(JavaContextNode parent) {
+			super(parent, new SubstitutionHeadQNameAnnotationProxy());
+		}
+		
+		
+		@Override
+		public String getDefaultName() {
+			return null;
+		}
+		
+		@Override
+		public String getDefaultNamespace() {
+			return GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getNamespace();
+		}
+		
+		@Override
+		public Iterable<String> getNameProposals(Filter<String> filter) {
+			String fqScope = GenericJavaElementFactoryMethod.this.getFullyQualifiedScope();
+			JaxbPersistentClass scopeClass = 
+					GenericJavaElementFactoryMethod.this.getJaxbProject().getContextRoot().getPersistentClass(fqScope);
+			if (scopeClass != null) {
+				XsdTypeDefinition xsdType = scopeClass.getXsdTypeDefinition();
+				if (xsdType != null) {
+					return xsdType.getElementNameProposals(getNamespace(), filter);
+				}
+			}
+			
+			XsdSchema xsdSchema = GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getXsdSchema();
+			if (xsdSchema != null) {
+				return xsdSchema.getElementNameProposals(getNamespace(), filter);
+			}
+			
+			return EmptyIterable.instance(); 
+		}
+		
+		@Override
+		public Iterable<String> getNamespaceProposals(Filter<String> filter) {
+			XsdSchema xsdSchema = GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getXsdSchema();
+			return (xsdSchema == null) ? EmptyIterable.<String>instance() : xsdSchema.getNamespaceProposals(filter);
+		}
+		
+		@Override
+		public String getReferencedComponentTypeDescription() {
+			return JptJaxbCoreMessages.SUBSTITUTION_HEAD_DESC;
+		}
+		
+		@Override
+		protected void validateName(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+			// need to ignore the unspecified (null) case
+			if ("".equals(getName())) {
+				messages.add(
+						DefaultValidationMessages.buildMessage(
+								IMessage.HIGH_SEVERITY,
+								JaxbValidationMessages.QNAME__MISSING_NAME,
+								new String[] { getReferencedComponentTypeDescription() },
+								this,
+								getNameTextRange(astRoot)));
+			}
+			else if (! StringTools.stringIsEmpty(getName())) {
+				if (Tools.valuesAreEqual(getName(), GenericJavaElementFactoryMethod.this.getQName().getName())) {
+					messages.add(
+							DefaultValidationMessages.buildMessage(
+									IMessage.HIGH_SEVERITY,
+									JaxbValidationMessages.XML_ELEMENT_DECL__SUBST_HEAD_NAME_EQUALS_NAME,
+									this,
+									getNameTextRange(astRoot)));
+				}
+			}
+		}
+	
+		@Override
+		protected void validateReference(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+			XsdSchema xsdSchema = GenericJavaElementFactoryMethod.this.getRegistry().getJaxbPackage().getXsdSchema();
+			if (xsdSchema != null) {
+				if (xsdSchema.getElementDeclaration(getNamespace(), getName()) == null) {
+					messages.add(getUnresolveSchemaComponentMessage(astRoot));
+				}
+			}
+			
+			for (JaxbElementFactoryMethod elementDecl : GenericJavaElementFactoryMethod.this.getRegistry().getElementFactoryMethods()) {
+				if (Tools.valuesAreEqual(getName(), elementDecl.getSubstitutionHeadQName().getName())
+						&& Tools.valuesAreEqual(getNamespace(), elementDecl.getSubstitutionHeadQName().getNamespace())) {
+					return;
+				}
+			}
+			messages.add(
+					DefaultValidationMessages.buildMessage(
+							IMessage.HIGH_SEVERITY,
+							JaxbValidationMessages.XML_ELEMENT_DECL__SUBST_HEAD_NO_MATCHING_ELEMENT_DECL,
+							new String[] { getNamespace(), getName() },
+							this,
+							getValidationTextRange(astRoot)));
+		}
+	}
+	
+	
+	protected class SubstitutionHeadQNameAnnotationProxy 
+			implements AbstractJavaQName.AnnotationProxy {
+		
+		protected XmlElementDeclAnnotation getAnnotation() {
+			return 	GenericJavaElementFactoryMethod.this.getXmlElementDeclAnnotation();
+		}
+		
+		public String getNamespace() {
+			XmlElementDeclAnnotation annotation = getAnnotation();
+			return annotation == null ? null : annotation.getSubstitutionHeadNamespace();
+		}
+		
+		public void setNamespace(String newSpecifiedNamespace) {
+			getAnnotation().setSubstitutionHeadNamespace(newSpecifiedNamespace);
+		}
+		
+		public boolean namespaceTouches(int pos, CompilationUnit astRoot) {
+			XmlElementDeclAnnotation annotation = getAnnotation();
+			return (annotation == null) ? false : annotation.substitutionHeadNamespaceTouches(pos, astRoot);
+		}
+		
+		public TextRange getNamespaceTextRange(CompilationUnit astRoot) {
+			XmlElementDeclAnnotation annotation = getAnnotation();
+			return (annotation == null) ? null : annotation.getSubstitutionHeadNamespaceTextRange(astRoot);
+		}
+		
+		public String getName() {
+			XmlElementDeclAnnotation annotation = getAnnotation();
+			return annotation == null ? null : annotation.getSubstitutionHeadName();
+		}
+		
+		public void setName(String newSpecifiedName) {
+			getAnnotation().setSubstitutionHeadName(newSpecifiedName);
+		}
+		
+		public boolean nameTouches(int pos, CompilationUnit astRoot) {
+			XmlElementDeclAnnotation annotation = getAnnotation();
+			return (annotation == null) ? false : annotation.substitutionHeadNameTouches(pos, astRoot);
+		}
+		
+		public TextRange getNameTextRange(CompilationUnit astRoot) {
+			XmlElementDeclAnnotation annotation = getAnnotation();
+			return (annotation == null) ? null : annotation.getSubstitutionHeadNameTextRange(astRoot);
+		}
 	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java
index e64c8cb..665b432 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaPersistentClass.java
@@ -16,6 +16,7 @@
 import java.util.List;
 import java.util.Map;
 import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jpt.common.core.internal.utility.JDTTools;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceType;
@@ -72,6 +73,9 @@
 	
 	protected JaxbClass superClass;
 	
+	protected boolean hasRootElementInHierarchy_loaded = false;
+	protected boolean hasRootElementInHierarchy = false;
+	
 	protected XmlAccessType defaultAccessType;
 	protected XmlAccessType specifiedAccessType;
 	
@@ -122,14 +126,14 @@
 	@Override
 	public void update() {
 		super.update();
-		super.update();
-		this.setSuperClass(this.buildSuperClass());
-		this.setDefaultAccessType(this.buildDefaultAccessType());
-		this.setDefaultAccessOrder(this.buildDefaultAccessOrder());
+		setSuperClass(buildSuperClass());
+		this.hasRootElementInHierarchy_loaded = false; // triggers that the value must be recalculated on next request
+		setDefaultAccessType(buildDefaultAccessType());
+		setDefaultAccessOrder(buildDefaultAccessOrder());
 		this.xmlAdaptable.update();
 		updateXmlSeeAlso();
 		this.attributesContainer.update();
-		this.updateInheritedAttributes();
+		updateInheritedAttributes();
 	}
 	
 	
@@ -214,6 +218,33 @@
 	}
 	
 	
+	// ***** subClasses *****
+	
+	public boolean hasRootElementInHierarchy() {
+		if (! this.hasRootElementInHierarchy_loaded) {
+			this.hasRootElementInHierarchy = calculateHasRootElementInHierarchy();
+			this.hasRootElementInHierarchy_loaded = true;
+		}
+		return this.hasRootElementInHierarchy;
+	}
+	
+	protected boolean calculateHasRootElementInHierarchy() {
+		if (this.getRootElement() != null) {
+			return true;
+		}
+		
+		for (JaxbPersistentClass persistentClass : getJaxbProject().getContextRoot().getPersistentClasses()) {
+			if (persistentClass.getRootElement() != null
+					&& JDTTools.typeIsSubType(getJaxbProject().getJavaProject(),
+							persistentClass.getFullyQualifiedName(), getFullyQualifiedName())) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	
 	// ********** inheritance **********
 	
 	public Iterable<JaxbClass> getInheritanceHierarchy() {
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaRegistry.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaRegistry.java
index 879ae5f..2210d0d 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaRegistry.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaRegistry.java
@@ -9,16 +9,32 @@
  *******************************************************************************/
 package org.eclipse.jpt.jaxb.core.internal.context.java;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.namespace.QName;
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceMethod;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceType;
 import org.eclipse.jpt.common.core.utility.TextRange;
+import org.eclipse.jpt.common.utility.Filter;
+import org.eclipse.jpt.common.utility.internal.Bag;
+import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.HashBag;
+import org.eclipse.jpt.common.utility.internal.StringTools;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
 import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
 import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot;
 import org.eclipse.jpt.jaxb.core.context.JaxbElementFactoryMethod;
 import org.eclipse.jpt.jaxb.core.context.JaxbRegistry;
+import org.eclipse.jpt.jaxb.core.internal.JptJaxbCoreMessages;
+import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
+import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
 import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlRegistryAnnotation;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
 
 
 public class GenericJavaRegistry
@@ -26,31 +42,32 @@
 		implements JaxbRegistry {
 
 	protected final ElementFactoryMethodContainer elementFactoryMethodContainer;
-
-	private static final String ELEMENT_FACTORY_METHOD_CREATE_PREFIX = "create"; //$NON-NLS-1$
-
+	
+	
 	public GenericJavaRegistry(JaxbContextRoot parent, JavaResourceType resourceType) {
 		super(parent, resourceType);
 		this.elementFactoryMethodContainer = new ElementFactoryMethodContainer();
 	}
-
+	
+	
 	@Override
 	public JavaResourceType getJavaResourceType() {
 		return (JavaResourceType) super.getJavaResourceType();
 	}
 	
 	protected XmlRegistryAnnotation getAnnotation() {
-		return (XmlRegistryAnnotation) getJavaResourceType().getNonNullAnnotation(JAXB.XML_REGISTRY);
+		return (XmlRegistryAnnotation) getJavaResourceType().getAnnotation(JAXB.XML_REGISTRY);
 	}
 	
 	
-	// ********** JaxbType impl **********
+	// ***** JaxbType impl *****
 	
 	public Kind getKind() {
 		return Kind.REGISTRY;
 	}
 	
-	// ********** synchronize/update **********
+	
+	// ***** synchronize/update *****
 	
 	@Override
 	public void synchronizeWithResourceModel() {
@@ -63,19 +80,19 @@
 		super.update();
 		this.elementFactoryMethodContainer.update();
 	}
-
+	
 	public Iterable<JaxbElementFactoryMethod> getElementFactoryMethods() {
 		return this.elementFactoryMethodContainer.getContextElements();
 	}
-
+	
 	public int getElementFactoryMethodsSize() {
 		return this.elementFactoryMethodContainer.getContextElementsSize();
 	}
-
+	
 	private JaxbElementFactoryMethod buildElementFactoryMethod(JavaResourceMethod resourceMethod) {
 		return getFactory().buildJavaElementFactoryMethod(this, resourceMethod);
 	}
-
+	
 	private Iterable<JavaResourceMethod> getResourceElementFactoryMethods() {
 		return new FilteringIterable<JavaResourceMethod>(getJavaResourceType().getMethods()) {
 			@Override
@@ -84,31 +101,42 @@
 			}
 		};
 	}
-
-	//For now we will just check that the method has an @XmlElementDecl annotation.
-	//In the future we could look for methods that are unannotated, but appear
-	//to be element factory methods : begin with create, return type is JAXB element,
-	//1 parameter, etc.
+	
+	// Return methods with XmlElementDecl annotation
 	protected static boolean methodIsElementFactoryMethod(JavaResourceMethod method) {
 		return methodHasXmlElementDeclAnnotation(method);
 	}
-
+	
 	protected static boolean methodHasXmlElementDeclAnnotation(JavaResourceMethod method) {
 		return method.getAnnotation(JAXB.XML_ELEMENT_DECL) != null;
 	}
 	
-	protected static boolean methodStartsWithCreate(JavaResourceMethod method) {
-		return method.getName().startsWith(ELEMENT_FACTORY_METHOD_CREATE_PREFIX);
-	}
-
 	protected static boolean methodReturnTypeIsJAXBElement(JavaResourceMethod method) {
-		return method.typeIsSubTypeOf(JAXB_ELEMENT_TYPE_NAME);
+		return method.typeIsSubTypeOf(JAXB.XML_ELEMENT);
 	}
-
-	protected static final String JAXB_ELEMENT_TYPE_NAME = "javax.xml.bind.JAXBElement"; //$NON-NLS-1$
 	
 	
-	// **************** validation ********************************************
+	// ***** content assist *****
+	
+	 @Override
+	public Iterable<String> getJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
+		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
+		}
+		
+		for (JaxbElementFactoryMethod efm : getElementFactoryMethods()) {
+			result = efm.getJavaCompletionProposals(pos, filter, astRoot);
+				if (! CollectionTools.isEmpty(result)) {
+				return result;
+			}
+		}
+		
+		return EmptyIterable.<String>instance();
+	}
+	
+	
+	// ***** validation *****
 	
 	@Override
 	public TextRange getValidationTextRange(CompilationUnit astRoot) {
@@ -116,29 +144,77 @@
 		return (textRange != null) ? textRange : super.getValidationTextRange(astRoot);
 	}
 	
+	@Override
+	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+		super.validate(messages, reporter, astRoot);
+		
+		validateDuplicateQNames(messages, reporter, astRoot);
+		
+		for (JaxbElementFactoryMethod efm : getElementFactoryMethods()) {
+			efm.validate(messages, reporter, astRoot);
+		}
+	}
+	
+	protected void validateDuplicateQNames(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+		
+		Map<String, Bag<QName>> xmlElementDeclQnames = new HashMap<String, Bag<QName>>();
+		
+		for (JaxbElementFactoryMethod xmlElementDecl : getElementFactoryMethods()) {
+			String elementDeclName = xmlElementDecl.getQName().getName();
+			if (! StringTools.stringIsEmpty(elementDeclName)) {
+				String fqScope = xmlElementDecl.getFullyQualifiedScope();
+				if (xmlElementDeclQnames.get(fqScope) == null) {
+					xmlElementDeclQnames.put(fqScope, new HashBag<QName>());
+				}
+				xmlElementDeclQnames.get(fqScope).add(new QName(xmlElementDecl.getQName().getNamespace(), elementDeclName));
+			}
+		}
+		
+		for (JaxbElementFactoryMethod xmlElementDecl : getElementFactoryMethods()) {
+			String fqScope = xmlElementDecl.getFullyQualifiedScope();
+			String xmlElementNamespace = xmlElementDecl.getQName().getNamespace();
+			String xmlElementName = xmlElementDecl.getQName().getName();
+			if (xmlElementDeclQnames.get(fqScope).count(new QName(xmlElementNamespace, xmlElementName)) > 1) {
+				String scopeDesc = "";
+				if (! JaxbElementFactoryMethod.DEFAULT_SCOPE_CLASS_NAME.equals(fqScope)) {
+					scopeDesc = NLS.bind(JptJaxbCoreMessages.XML_ELEMENT_DECL__SCOPE, fqScope);
+				}
+				messages.add(
+						DefaultValidationMessages.buildMessage(
+								IMessage.HIGH_SEVERITY,
+								JaxbValidationMessages.XML_REGISTRY__DUPLICATE_XML_ELEMENT_QNAME,
+								new String[] { xmlElementName, scopeDesc },
+								xmlElementDecl,
+								xmlElementDecl.getQName().getNameTextRange(astRoot)));
+			}
+		}
+	}
+	
 	
 	/**
 	 * element factory method container adapter
 	 */
 	protected class ElementFactoryMethodContainer
-		extends ContextCollectionContainer<JaxbElementFactoryMethod, JavaResourceMethod>
-	{
+			extends ContextCollectionContainer<JaxbElementFactoryMethod, JavaResourceMethod> {
+		
 		@Override
 		protected String getContextElementsPropertyName() {
-			return ELEMENT_FACTORY_METHODS_COLLECTION;
+			return JaxbRegistry.ELEMENT_FACTORY_METHODS_COLLECTION;
 		}
+		
 		@Override
 		protected JaxbElementFactoryMethod buildContextElement(JavaResourceMethod resourceElement) {
 			return GenericJavaRegistry.this.buildElementFactoryMethod(resourceElement);
 		}
+		
 		@Override
 		protected Iterable<JavaResourceMethod> getResourceElements() {
 			return GenericJavaRegistry.this.getResourceElementFactoryMethods();
 		}
+		
 		@Override
 		protected JavaResourceMethod getResourceElement(JaxbElementFactoryMethod contextElement) {
 			return contextElement.getResourceMethod();
 		}
 	}
-
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientClass.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientClass.java
index c856822..98e1148 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientClass.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaTransientClass.java
@@ -75,7 +75,7 @@
 	// ********** xml transient annotation **********
 
 	protected XmlTransientAnnotation getXmlTransientAnnotation() {
-		return (XmlTransientAnnotation) this.getJavaResourceType().getNonNullAnnotation(JAXB.XML_TRANSIENT);
+		return (XmlTransientAnnotation) this.getJavaResourceType().getAnnotation(JAXB.XML_TRANSIENT);
 	}
 	
 	
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAnyElementMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAnyElementMapping.java
index 2a967a0..ce2f11c 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAnyElementMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAnyElementMapping.java
@@ -9,56 +9,67 @@
  ******************************************************************************/
 package org.eclipse.jpt.jaxb.core.internal.context.java;
 
+import java.util.List;
+import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement;
+import org.eclipse.jpt.common.core.utility.TextRange;
+import org.eclipse.jpt.common.utility.Filter;
+import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyListIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.SingleElementListIterable;
 import org.eclipse.jpt.jaxb.core.MappingKeys;
+import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
 import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
 import org.eclipse.jpt.jaxb.core.context.XmlAdaptable;
 import org.eclipse.jpt.jaxb.core.context.XmlAnyElementMapping;
+import org.eclipse.jpt.jaxb.core.context.XmlElementRef;
+import org.eclipse.jpt.jaxb.core.context.XmlElementRefs;
+import org.eclipse.jpt.jaxb.core.context.XmlElementWrapper;
 import org.eclipse.jpt.jaxb.core.context.XmlJavaTypeAdapter;
 import org.eclipse.jpt.jaxb.core.context.XmlMixed;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
+import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
+import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
 import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlAnyElementAnnotation;
+import org.eclipse.jpt.jaxb.core.resource.java.XmlElementRefAnnotation;
+import org.eclipse.jpt.jaxb.core.resource.java.XmlElementRefsAnnotation;
+import org.eclipse.jpt.jaxb.core.resource.java.XmlElementWrapperAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlJavaTypeAdapterAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlMixedAnnotation;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
 
 public class GenericJavaXmlAnyElementMapping
-	extends AbstractJavaAttributeMapping<XmlAnyElementAnnotation>
-	implements XmlAnyElementMapping
-{
-
+		extends AbstractJavaAttributeMapping<XmlAnyElementAnnotation>
+		implements XmlAnyElementMapping {
+	
 	protected Boolean specifiedLax;
-
+	
 	protected String specifiedValue;
-
-	protected XmlMixed xmlMixed;
-
+	
 	protected final XmlAdaptable xmlAdaptable;
-
-
+	
+	protected final XmlElementRefs xmlElementRefs;
+	
+	protected XmlElementWrapper xmlElementWrapper;
+	
+	protected XmlMixed xmlMixed;
+	
+	
 	public GenericJavaXmlAnyElementMapping(JaxbPersistentAttribute parent) {
 		super(parent);
 		this.specifiedLax = buildSpecifiedLax();
-		this.specifiedValue = this.getResourceValueString();
+		this.specifiedValue = getResourceValueString();
 		this.xmlAdaptable = buildXmlAdaptable();
+		this.xmlElementRefs = buildXmlElementRefs();
+		initializeXmlElementWrapper();
 		this.initializeXmlMixed();			
 	}
-
-	@Override
-	public void synchronizeWithResourceModel() {
-		super.synchronizeWithResourceModel();
-		this.setSpecifiedLax(buildSpecifiedLax());
-		this.setSpecifiedValue_(this.getResourceValueString());
-		this.xmlAdaptable.synchronizeWithResourceModel();
-		this.syncXmlMixed();
-	}
-
-	@Override
-	public void update() {
-		super.update();
-		this.xmlAdaptable.update();
-		this.updateXmlMixed();
-	}
-
+	
+	
 	public String getKey() {
 		return MappingKeys.XML_ANY_ELEMENT_ATTRIBUTE_MAPPING_KEY;
 	}
@@ -67,163 +78,496 @@
 	protected String getAnnotationName() {
 		return JAXB.XML_ANY_ELEMENT;
 	}
-
-
-	//************ lax ***************
-
+	
+	
+	// ***** sync/update *****
+	
+	@Override
+	public void synchronizeWithResourceModel() {
+		super.synchronizeWithResourceModel();
+		setSpecifiedLax_(buildSpecifiedLax());
+		setSpecifiedValue_(getResourceValueString());
+		this.xmlAdaptable.synchronizeWithResourceModel();
+		this.xmlElementRefs.synchronizeWithResourceModel();
+		syncXmlElementWrapper();
+		syncXmlMixed();
+	}
+	
+	@Override
+	public void update() {
+		super.update();
+		this.xmlAdaptable.update();
+		this.xmlElementRefs.update();
+		updateXmlElementWrapper();
+		updateXmlMixed();
+	}
+	
+	
+	// ***** lax *****
+	
 	public boolean isLax() {
-		return (this.getSpecifiedLax() == null) ? this.isDefaultLax() : this.getSpecifiedLax().booleanValue();
+		return (getSpecifiedLax() == null) ? isDefaultLax() : getSpecifiedLax().booleanValue();
 	}
-
-	public boolean isDefaultLax() {
-		return DEFAULT_LAX;
-	}
-
+	
 	public Boolean getSpecifiedLax() {
 		return this.specifiedLax;
 	}
-
+	
 	public void setSpecifiedLax(Boolean newSpecifiedLax) {
-		this.getOrCreateAnnotation().setLax(newSpecifiedLax);
-		this.setSpecifiedLax_(newSpecifiedLax);
+		getOrCreateAnnotation().setLax(newSpecifiedLax);
+		setSpecifiedLax_(newSpecifiedLax);
 	}
-
+	
 	protected void setSpecifiedLax_(Boolean newSpecifiedLax) {
 		Boolean oldLax = this.specifiedLax;
 		this.specifiedLax = newSpecifiedLax;
 		firePropertyChanged(SPECIFIED_LAX_PROPERTY, oldLax, newSpecifiedLax);
 	}
-
+	
 	protected Boolean buildSpecifiedLax() {
 		return getAnnotation().getLax();
 	}
-
-	// ********** value **********
-
+	
+	public boolean isDefaultLax() {
+		return DEFAULT_LAX;
+	}
+	
+	
+	// ***** value *****
+	
 	public String getValue() {
-		return this.getSpecifiedValue() == null ? this.getDefaultValue() : this.getSpecifiedValue();
+		return getSpecifiedValue() == null ? getDefaultValue() : getSpecifiedValue();
 	}
-
-	public String getDefaultValue() {
-		return DEFAULT_VALUE;
-	}
-
+	
 	public String getSpecifiedValue() {
 		return this.specifiedValue;
 	}
-
+	
 	public void setSpecifiedValue(String location) {
-		this.getOrCreateAnnotation().setValue(location);
-		this.setSpecifiedValue_(location);	
+		getOrCreateAnnotation().setValue(location);
+		setSpecifiedValue_(location);	
 	}
-
+	
 	protected void setSpecifiedValue_(String type) {
 		String old = this.specifiedValue;
 		this.specifiedValue = type;
 		this.firePropertyChanged(SPECIFIED_VALUE_PROPERTY, old, type);
 	}
-
+	
 	protected String getResourceValueString() {
 		return getAnnotation().getValue();
 	}
-
-	//****************** XmlJavaTypeAdapter *********************
-
+	
+	public String getDefaultValue() {
+		return DEFAULT_VALUE;
+	}
+	
+	
+	// ***** XmlJavaTypeAdapter *****
+	
+	public XmlJavaTypeAdapter getXmlJavaTypeAdapter() {
+		return this.xmlAdaptable.getXmlJavaTypeAdapter();
+	}
+	
+	public XmlJavaTypeAdapter addXmlJavaTypeAdapter() {
+		return this.xmlAdaptable.addXmlJavaTypeAdapter();
+	}
+	
+	public void removeXmlJavaTypeAdapter() {
+		this.xmlAdaptable.removeXmlJavaTypeAdapter();
+	}
+	
+	protected XmlJavaTypeAdapter buildXmlJavaTypeAdapter(XmlJavaTypeAdapterAnnotation xmlJavaTypeAdapterAnnotation) {
+		return new GenericJavaAttributeXmlJavaTypeAdapter(this, xmlJavaTypeAdapterAnnotation);
+	}
+	
 	public XmlAdaptable buildXmlAdaptable() {
 		return new GenericJavaXmlAdaptable(this, new XmlAdaptable.Owner() {
+			
 			public JavaResourceAnnotatedElement getResource() {
 				return getJavaResourceAttribute();
 			}
+			
 			public XmlJavaTypeAdapter buildXmlJavaTypeAdapter(XmlJavaTypeAdapterAnnotation adapterAnnotation) {
 				return GenericJavaXmlAnyElementMapping.this.buildXmlJavaTypeAdapter(adapterAnnotation);
 			}
+			
 			public void fireXmlAdapterChanged(XmlJavaTypeAdapter oldAdapter, XmlJavaTypeAdapter newAdapter) {
 				GenericJavaXmlAnyElementMapping.this.firePropertyChanged(XML_JAVA_TYPE_ADAPTER_PROPERTY, oldAdapter, newAdapter);
 			}
 		});
 	}
-
-	public XmlJavaTypeAdapter getXmlJavaTypeAdapter() {
-		return this.xmlAdaptable.getXmlJavaTypeAdapter();
+	
+	
+	// ***** XmlElementRefs *****
+	
+	public XmlElementRefs getXmlElementRefs() {
+		return this.xmlElementRefs;
 	}
-
-	public XmlJavaTypeAdapter addXmlJavaTypeAdapter() {
-		return this.xmlAdaptable.addXmlJavaTypeAdapter();
+	
+	protected XmlElementRefs buildXmlElementRefs() {
+		return new GenericJavaXmlElementRefs(this, new XmlElementRefsContext());
 	}
-
-	protected XmlJavaTypeAdapter buildXmlJavaTypeAdapter(XmlJavaTypeAdapterAnnotation xmlJavaTypeAdapterAnnotation) {
-		return new GenericJavaAttributeXmlJavaTypeAdapter(this, xmlJavaTypeAdapterAnnotation);
+	
+	
+	// ***** XmlElementWrapper *****
+	
+	public XmlElementWrapper getXmlElementWrapper() {
+		return this.xmlElementWrapper;
 	}
-
-	public void removeXmlJavaTypeAdapter() {
-		this.xmlAdaptable.removeXmlJavaTypeAdapter();
+	
+	protected void setXmlElementWrapper_(XmlElementWrapper xmlElementWrapper) {
+		XmlElementWrapper oldXmlElementWrapper = this.xmlElementWrapper;
+		this.xmlElementWrapper = xmlElementWrapper;
+		firePropertyChanged(XML_ELEMENT_WRAPPER_PROPERTY, oldXmlElementWrapper, xmlElementWrapper);
 	}
-
-
-	//************  XmlMixed ***************
-
-	public XmlMixed getXmlMixed() {
-		return this.xmlMixed;
-	}
-
-	public XmlMixed addXmlMixed() {
-		if (this.xmlMixed != null) {
+	
+	public XmlElementWrapper addXmlElementWrapper() {
+		if (this.xmlElementWrapper != null) {
 			throw new IllegalStateException();
 		}
-		XmlMixedAnnotation annotation = (XmlMixedAnnotation) this.getJavaResourceAttribute().addAnnotation(JAXB.XML_MIXED);
-
-		XmlMixed xmlMixed = this.buildXmlMixed(annotation);
-		this.setXmlMixed_(xmlMixed);
-		return xmlMixed;
+		XmlElementWrapperAnnotation annotation = 
+				(XmlElementWrapperAnnotation) this.getJavaResourceAttribute().addAnnotation(JAXB.XML_ELEMENT_WRAPPER);
+		XmlElementWrapper xmlElementWrapper = this.buildXmlElementWrapper(annotation);
+		this.setXmlElementWrapper_(xmlElementWrapper);
+		return xmlElementWrapper;
 	}
-
-	protected XmlMixed buildXmlMixed(XmlMixedAnnotation xmlMixedAnnotation) {
-		return new GenericJavaXmlMixed(this, xmlMixedAnnotation);
-	}
-
-	public void removeXmlMixed() {
-		if (this.xmlMixed == null) {
+	
+	public void removeXmlElementWrapper() {
+		if (this.xmlElementWrapper == null) {
 			throw new IllegalStateException();
 		}
-		this.getJavaResourceAttribute().removeAnnotation(JAXB.XML_MIXED);
-		this.setXmlMixed_(null);
+		this.getJavaResourceAttribute().removeAnnotation(JAXB.XML_ELEMENT_WRAPPER);
+		this.setXmlElementWrapper_(null);
 	}
-
-	protected void initializeXmlMixed() {
-		XmlMixedAnnotation annotation = this.getXmlMixedAnnotation();
+	
+	protected XmlElementWrapperAnnotation getXmlElementWrapperAnnotation() {
+		return (XmlElementWrapperAnnotation) this.getJavaResourceAttribute().getAnnotation(JAXB.XML_ELEMENT_WRAPPER);
+	}
+	
+	protected XmlElementWrapper buildXmlElementWrapper(XmlElementWrapperAnnotation xmlElementWrapperAnnotation) {
+		return new GenericJavaXmlElementWrapper(this, xmlElementWrapperAnnotation);
+	}
+	
+	protected void initializeXmlElementWrapper() {
+		XmlElementWrapperAnnotation annotation = this.getXmlElementWrapperAnnotation();
 		if (annotation != null) {
-			this.xmlMixed = this.buildXmlMixed(annotation);
+			this.xmlElementWrapper = this.buildXmlElementWrapper(annotation);
 		}
 	}
-
-	protected XmlMixedAnnotation getXmlMixedAnnotation() {
-		return (XmlMixedAnnotation) this.getJavaResourceAttribute().getAnnotation(JAXB.XML_MIXED);
-	}
-
-	protected void syncXmlMixed() {
-		XmlMixedAnnotation annotation = this.getXmlMixedAnnotation();
+	
+	protected void syncXmlElementWrapper() {
+		XmlElementWrapperAnnotation annotation = this.getXmlElementWrapperAnnotation();
 		if (annotation != null) {
-			if (this.getXmlMixed() != null) {
-				this.getXmlMixed().synchronizeWithResourceModel();
+			if (this.getXmlElementWrapper() != null) {
+				this.getXmlElementWrapper().synchronizeWithResourceModel();
 			}
 			else {
-				this.setXmlMixed_(this.buildXmlMixed(annotation));
+				this.setXmlElementWrapper_(this.buildXmlElementWrapper(annotation));
 			}
 		}
 		else {
-			this.setXmlMixed_(null);
+			this.setXmlElementWrapper_(null);
 		}
 	}
-
-	protected void updateXmlMixed() {
-		if (this.getXmlMixed() != null) {
-			this.getXmlMixed().update();
+	
+	protected void updateXmlElementWrapper() {
+		if (this.getXmlElementWrapper() != null) {
+			this.getXmlElementWrapper().update();
 		}
 	}
-
+	
+	
+	// ***** XmlMixed *****
+	
+	public XmlMixed getXmlMixed() {
+		return this.xmlMixed;
+	}
+	
 	protected void setXmlMixed_(XmlMixed xmlMixed) {
 		XmlMixed oldXmlMixed = this.xmlMixed;
 		this.xmlMixed = xmlMixed;
 		firePropertyChanged(XML_MIXED_PROPERTY, oldXmlMixed, xmlMixed);
 	}
+	
+	public XmlMixed addXmlMixed() {
+		if (this.xmlMixed != null) {
+			throw new IllegalStateException();
+		}
+		XmlMixedAnnotation annotation = (XmlMixedAnnotation) getJavaResourceAttribute().addAnnotation(JAXB.XML_MIXED);
+		
+		XmlMixed xmlMixed = buildXmlMixed(annotation);
+		setXmlMixed_(xmlMixed);
+		return xmlMixed;
+	}
+	
+	public void removeXmlMixed() {
+		if (this.xmlMixed == null) {
+			throw new IllegalStateException();
+		}
+		getJavaResourceAttribute().removeAnnotation(JAXB.XML_MIXED);
+		setXmlMixed_(null);
+	}
+	
+	protected XmlMixedAnnotation getXmlMixedAnnotation() {
+		return (XmlMixedAnnotation) getJavaResourceAttribute().getAnnotation(JAXB.XML_MIXED);
+	}
+	
+	protected XmlMixed buildXmlMixed(XmlMixedAnnotation xmlMixedAnnotation) {
+		return new GenericJavaXmlMixed(this, xmlMixedAnnotation);
+	}
+	
+	protected void initializeXmlMixed() {
+		XmlMixedAnnotation annotation = getXmlMixedAnnotation();
+		if (annotation != null) {
+			this.xmlMixed = buildXmlMixed(annotation);
+		}
+	}
+	
+	protected void syncXmlMixed() {
+		XmlMixedAnnotation annotation = getXmlMixedAnnotation();
+		if (annotation != null) {
+			if (this.xmlMixed != null) {
+				this.xmlMixed.synchronizeWithResourceModel();
+			}
+			else {
+				setXmlMixed_(buildXmlMixed(annotation));
+			}
+		}
+		else {
+			setXmlMixed_(null);
+		}
+	}
+	
+	protected void updateXmlMixed() {
+		if (this.xmlMixed != null) {
+			this.xmlMixed.update();
+		}
+	}
+	
+	
+	// ***** misc *****
+	
+	@Override
+	public Iterable<String> getDirectlyReferencedTypeNames() {
+		return this.xmlElementRefs.getDirectlyReferencedTypeNames();
+	}
+	
+	
+	// ***** content assist *****
+	
+	@Override
+	public Iterable<String> getJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
+		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
+		}
+		
+		result = this.xmlElementRefs.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
+		}
+		
+		if (this.xmlElementWrapper != null) {
+			result = this.xmlElementWrapper.getJavaCompletionProposals(pos, filter, astRoot);
+			if (! CollectionTools.isEmpty(result)) {
+				return result;
+			}
+		}
+		
+		return EmptyIterable.instance();
+	}
+	
+	
+	// ***** validation *****
+	
+	@Override
+	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+		super.validate(messages, reporter, astRoot);
+		
+		this.xmlElementRefs.validate(messages, reporter, astRoot);
+		
+		if (getJavaResourceAttribute().getAnnotation(JAXB.XML_ELEMENT_REFS) != null) {
+			XmlElementRefAnnotation xmlElementRefAnnotation = 
+					(XmlElementRefAnnotation) getJavaResourceAttribute().getAnnotation(JAXB.XML_ELEMENT_REF);
+			if (xmlElementRefAnnotation != null) {
+				messages.add(
+						DefaultValidationMessages.buildMessage(
+								IMessage.HIGH_SEVERITY,
+								JaxbValidationMessages.ATTRIBUTE_MAPPING__UNSUPPORTED_ANNOTATION,
+								new String[] { JAXB.XML_ELEMENT_REF, JAXB.XML_ELEMENT_REFS },
+								getPersistentAttribute(),
+								xmlElementRefAnnotation.getTextRange(astRoot)));
+			}
+		}
+		
+		this.xmlAdaptable.validate(messages, reporter, astRoot);
+		
+		if (this.xmlElementWrapper != null) {
+			this.xmlElementWrapper.validate(messages, reporter, astRoot);
+		}
+		
+		if (this.xmlMixed != null) {
+			this.xmlMixed.validate(messages, reporter, astRoot);
+		}
+	}
+	
+	public class XmlElementRefsContext
+			implements GenericJavaXmlElementRefs.Context {
+		
+		protected XmlElementRefsAnnotation getXmlElementRefsAnnotation() {
+			return (XmlElementRefsAnnotation) GenericJavaXmlAnyElementMapping.this.getJavaResourceAttribute().getAnnotation(JAXB.XML_ELEMENT_REFS);
+		}
+		
+		protected XmlElementRefsAnnotation addXmlElementRefsAnnotation() {
+			return (XmlElementRefsAnnotation) GenericJavaXmlAnyElementMapping.this.getJavaResourceAttribute().addAnnotation(JAXB.XML_ELEMENT_REFS);
+		}
+		
+		protected void removeXmlElementRefsAnnotation() {
+			GenericJavaXmlAnyElementMapping.this.getJavaResourceAttribute().removeAnnotation(JAXB.XML_ELEMENT_REFS);
+		}
+		
+		protected XmlElementRefAnnotation getXmlElementRefAnnotation() {
+			return (XmlElementRefAnnotation) GenericJavaXmlAnyElementMapping.this.getJavaResourceAttribute().getAnnotation(JAXB.XML_ELEMENT_REF);
+		}
+		
+		protected XmlElementRefAnnotation addXmlElementRefAnnotation() {
+			return (XmlElementRefAnnotation) GenericJavaXmlAnyElementMapping.this.getJavaResourceAttribute().addAnnotation(JAXB.XML_ELEMENT_REF);
+		}
+		
+		protected void removeXmlElementRefAnnotation() {
+			GenericJavaXmlAnyElementMapping.this.getJavaResourceAttribute().removeAnnotation(JAXB.XML_ELEMENT_REF);
+		}
+		
+		public ListIterable<XmlElementRefAnnotation> getXmlElementRefAnnotations() {
+			XmlElementRefsAnnotation xmlElementRefsAnnotation = getXmlElementRefsAnnotation();
+			if (xmlElementRefsAnnotation != null) {
+				return xmlElementRefsAnnotation.getXmlElementRefs();
+			}
+			
+			XmlElementRefAnnotation xmlElementRefAnnotation = getXmlElementRefAnnotation();
+			if (xmlElementRefAnnotation != null) {
+				return new SingleElementListIterable(xmlElementRefAnnotation);
+			}
+			
+			return EmptyListIterable.instance();
+		}
+		
+		public XmlElementRefAnnotation addXmlElementRefAnnotation(int index) {
+			XmlElementRefsAnnotation xmlElementRefsAnnotation = getXmlElementRefsAnnotation();
+			if (xmlElementRefsAnnotation != null) {
+				return xmlElementRefsAnnotation.addXmlElementRef(index);
+			}
+			
+			XmlElementRefAnnotation xmlElementRefAnnotation = getXmlElementRefAnnotation();
+			if (xmlElementRefAnnotation != null) {
+				if (index > 1) {
+					throw new IllegalArgumentException(String.valueOf(index));
+				}
+				xmlElementRefsAnnotation = addXmlElementRefsAnnotation();
+				XmlElementRefAnnotation xmlElementRefAnnotationCopy = xmlElementRefsAnnotation.addXmlElementRef(0);
+				xmlElementRefAnnotationCopy.setName(xmlElementRefAnnotation.getName());
+				xmlElementRefAnnotationCopy.setNamespace(xmlElementRefAnnotation.getNamespace());
+				xmlElementRefAnnotationCopy.setRequired(xmlElementRefAnnotation.getRequired());
+				xmlElementRefAnnotationCopy.setType(xmlElementRefAnnotation.getType());
+				
+				removeXmlElementRefAnnotation();
+				
+				return xmlElementRefsAnnotation.addXmlElementRef(index);
+			}
+			
+			if (index > 0) {
+				throw new IllegalArgumentException(String.valueOf(index));
+			}
+			return addXmlElementRefAnnotation();
+		}
+		
+		public void removeXmlElementRefAnnotation(int index) {
+			XmlElementRefsAnnotation xmlElementRefsAnnotation = getXmlElementRefsAnnotation();
+			if (xmlElementRefsAnnotation != null) {
+				xmlElementRefsAnnotation.removeXmlElementRef(index);
+				if (xmlElementRefsAnnotation.getXmlElementRefsSize() == 0) {
+					removeXmlElementRefsAnnotation();
+				}
+				else if (xmlElementRefsAnnotation.getXmlElementRefsSize() == 1) {
+					XmlElementRefAnnotation xmlElementRefAnnotation = CollectionTools.get(xmlElementRefsAnnotation.getXmlElementRefs(), 0);
+					XmlElementRefAnnotation xmlElementRefAnnotationCopy = addXmlElementRefAnnotation();
+					xmlElementRefAnnotationCopy.setName(xmlElementRefAnnotation.getName());
+					xmlElementRefAnnotationCopy.setNamespace(xmlElementRefAnnotation.getNamespace());
+					xmlElementRefAnnotationCopy.setRequired(xmlElementRefAnnotation.getRequired());
+					xmlElementRefAnnotationCopy.setType(xmlElementRefAnnotation.getType());
+					removeXmlElementRefsAnnotation();
+				}
+				return;
+			}
+			
+			XmlElementRefAnnotation xmlElementRefAnnotation = getXmlElementRefAnnotation();
+			if (xmlElementRefAnnotation != null) {
+				if (index != 0) {
+					throw new IllegalArgumentException(String.valueOf(index));
+				}
+				removeXmlElementRefAnnotation();
+				return;
+			}
+			
+			throw new IllegalArgumentException(String.valueOf(index));
+		}
+		
+		public void moveXmlElementRefAnnotation(int targetIndex, int sourceIndex) {
+			if (targetIndex == sourceIndex) {
+				return;
+			}
+			
+			XmlElementRefsAnnotation xmlElementRefsAnnotation = getXmlElementRefsAnnotation();
+			if (xmlElementRefsAnnotation == null) {
+				throw new IllegalArgumentException(String.valueOf(targetIndex) + ", " + String.valueOf(sourceIndex));
+			}
+			xmlElementRefsAnnotation.moveXmlElementRef(targetIndex, sourceIndex);
+		}
+		
+		public XmlElementRef buildXmlElementRef(JavaContextNode parent, XmlElementRefAnnotation annotation) {
+			return new GenericJavaXmlElementRef(parent, new XmlElementRefContext(annotation));
+		}
+		
+		public TextRange getValidationTextRange(CompilationUnit astRoot) {
+			XmlElementRefsAnnotation xmlElementRefsAnnotation = getXmlElementRefsAnnotation();
+			if (xmlElementRefsAnnotation != null) {
+				return xmlElementRefsAnnotation.getTextRange(astRoot);
+			}
+			
+			XmlElementRefAnnotation xmlElementRefAnnotation = getXmlElementRefAnnotation();
+			if (xmlElementRefAnnotation != null) {
+				return xmlElementRefAnnotation.getTextRange(astRoot);
+			}
+			
+			return GenericJavaXmlAnyElementMapping.this.getValidationTextRange(astRoot);
+		}
+	}
+	
+	
+	public class XmlElementRefContext
+			implements GenericJavaXmlElementRef.Context {
+		
+		protected XmlElementRefAnnotation annotation;
+		
+		protected XmlElementRefContext(XmlElementRefAnnotation annotation) {
+			this.annotation = annotation;
+		}
+		
+		public XmlElementRefAnnotation getAnnotation() {
+			return this.annotation;
+		}
+		
+		public JaxbAttributeMapping getAttributeMapping() {
+			return GenericJavaXmlAnyElementMapping.this;
+		}
+		
+		public String getDefaultType() {
+			return null;
+		}
+		
+		public XmlElementWrapper getElementWrapper() {
+			return GenericJavaXmlAnyElementMapping.this.getXmlElementWrapper();
+		}
+	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAttributeMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAttributeMapping.java
index e9dbdf9..6b140c3 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAttributeMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlAttributeMapping.java
@@ -152,7 +152,7 @@
 			extends AbstractJavaQName {
 		
 		protected XmlAttributeQName(JavaContextNode parent) {
-			super(parent);
+			super(parent, new QNameAnnotationProxy());
 		}
 		
 		
@@ -162,16 +162,6 @@
 		}
 		
 		@Override
-		protected QNameAnnotation getAnnotation(boolean createIfNull) {
-			if (createIfNull) {
-				return GenericJavaXmlAttributeMapping.this.getOrCreateAnnotation();
-			}
-			else {
-				return GenericJavaXmlAttributeMapping.this.getAnnotation();
-			}
-		}
-		
-		@Override
 		public String getDefaultName() {
 			return GenericJavaXmlAttributeMapping.this.getPersistentAttribute().getJavaResourceAttribute().getName();
 		}
@@ -206,6 +196,21 @@
 	}
 	
 	
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			if (createIfNull) {
+				return GenericJavaXmlAttributeMapping.this.getOrCreateAnnotation();
+			}
+			else {
+				return GenericJavaXmlAttributeMapping.this.getAnnotation();
+			}
+		}
+	}
+	
+	
 	protected class XmlIDREFContext
 			extends GenericJavaBasicMapping.XmlIDREFContext {
 		
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElement.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElement.java
index dfc403c..0d301bb 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElement.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElement.java
@@ -342,13 +342,9 @@
 			extends AbstractJavaElementQName {
 		
 		protected XmlElementQName(JavaContextNode parent) {
-			super(parent);
+			super(parent, new QNameAnnotationProxy());
 		}
 		
-		@Override
-		protected QNameAnnotation getAnnotation(boolean createIfNull) {
-			return GenericJavaXmlElement.this.getAnnotation(createIfNull);
-		}
 		
 		@Override
 		protected JaxbPersistentAttribute getPersistentAttribute() {
@@ -362,6 +358,16 @@
 	}
 	
 	
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			return GenericJavaXmlElement.this.getAnnotation(createIfNull);
+		}
+	}
+	
+	
 	public interface Context {
 		
 		JaxbAttributeMapping getAttributeMapping();
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRef.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRef.java
index eb3da2a..721c06a 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRef.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRef.java
@@ -194,7 +194,14 @@
 	
 	public Iterable<String> getDirectlyReferencedTypeNames() {
 		// only return the specified type - the default type should already be included
-		return (this.specifiedType == null) ? EmptyIterable.<String>instance() : new SingleElementIterable(getFullyQualifiedType());
+		if (this.specifiedType != null) {
+			String fqType = getFullyQualifiedType();
+			if (! JAXB.JAXB_ELEMENT.equals(fqType)) {
+				return new SingleElementIterable(fqType);
+			}
+		}
+		
+		return EmptyIterable.instance();
 	}
 	
 	
@@ -241,7 +248,7 @@
 			messages.add(
 					DefaultValidationMessages.buildMessage(
 							IMessage.HIGH_SEVERITY,
-							JaxbValidationMessages.XML_ELEMENT__UNSPECIFIED_TYPE,
+							JaxbValidationMessages.XML_ELEMENT_REF__UNSPECIFIED_TYPE,
 							this,
 							getTypeTextRange(astRoot)));
 		}
@@ -253,12 +260,24 @@
 				messages.add(
 						DefaultValidationMessages.buildMessage(
 								IMessage.HIGH_SEVERITY,
-								JaxbValidationMessages.XML_ELEMENT__ILLEGAL_TYPE,
+								JaxbValidationMessages.XML_ELEMENT_REF__ILLEGAL_TYPE,
 								new String[] { attributeBaseType },
 								this,
 								getTypeTextRange(astRoot)));
 								
 			}
+			
+			// if type is a persistent class, check that it or a subclass has a root element specified
+			JaxbPersistentClass persistentClass = getJaxbProject().getContextRoot().getPersistentClass(fqType);
+			if (persistentClass != null && ! persistentClass.hasRootElementInHierarchy()) {
+				messages.add(
+						DefaultValidationMessages.buildMessage(
+								IMessage.HIGH_SEVERITY,
+								JaxbValidationMessages.XML_ELEMENT_REF__NO_ROOT_ELEMENT,
+								new String[] { attributeBaseType },
+								this,
+								getTypeTextRange(astRoot)));
+			}
 		}
 	}
 	
@@ -267,13 +286,9 @@
 			extends AbstractJavaElementQName {
 		
 		protected XmlElementRefQName(JavaContextNode parent) {
-			super(parent);
+			super(parent, new QNameAnnotationProxy());
 		}
 		
-		@Override
-		protected QNameAnnotation getAnnotation(boolean createIfNull) {
-			return GenericJavaXmlElementRef.this.getAnnotation();
-		}
 		
 		@Override
 		protected JaxbPersistentAttribute getPersistentAttribute() {
@@ -354,8 +369,8 @@
 			}
 			
 			for (JaxbElementFactoryMethod elementDecl : registry.getElementFactoryMethods()) {
-				if (Tools.valuesAreEqual(getName(), elementDecl.getElementName())
-						&& Tools.valuesAreEqual(getNamespace(), elementDecl.getNamespace())) {
+				if (Tools.valuesAreEqual(getName(), elementDecl.getQName().getName())
+						&& Tools.valuesAreEqual(getNamespace(), elementDecl.getQName().getNamespace())) {
 					return;
 				}
 			}
@@ -371,6 +386,16 @@
 	}
 	
 	
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			return GenericJavaXmlElementRef.this.getAnnotation();
+		}
+	}
+	
+	
 	public interface Context {
 		
 		JaxbAttributeMapping getAttributeMapping();
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefMapping.java
index 8893cb1..55adfbe 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefMapping.java
@@ -15,6 +15,7 @@
 import org.eclipse.jpt.common.utility.Filter;
 import org.eclipse.jpt.common.utility.internal.CollectionTools;
 import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
 import org.eclipse.jpt.jaxb.core.MappingKeys;
 import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
 import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
@@ -263,6 +264,17 @@
 	}
 	
 	
+	// ***** misc *****
+	
+	@Override
+	public Iterable<String> getDirectlyReferencedTypeNames() {
+		String typeName = this.xmlElementRef.getFullyQualifiedType();
+		return (JAXB.JAXB_ELEMENT.equals(typeName)) ? 
+				EmptyIterable.<String>instance() 
+				: new SingleElementIterable(typeName);
+	}
+	
+	
 	// ***** content assist *****
 	
 	@Override
@@ -298,8 +310,8 @@
 		
 		this.xmlAdaptable.validate(messages, reporter, astRoot);
 		
-		if (this.getXmlElementWrapper() != null) {
-			this.getXmlElementWrapper().validate(messages, reporter, astRoot);
+		if (this.xmlElementWrapper != null) {
+			this.xmlElementWrapper.validate(messages, reporter, astRoot);
 		}
 	}
 	
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefs.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefs.java
new file mode 100644
index 0000000..6f93977
--- /dev/null
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefs.java
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ *  Copyright (c) 2011  Oracle. All rights reserved.
+ *  This program and the accompanying materials are made available under the
+ *  terms of the Eclipse Public License v1.0, which accompanies this distribution
+ *  and is available at http://www.eclipse.org/legal/epl-v10.html
+ *  
+ *  Contributors: 
+ *  	Oracle - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jpt.jaxb.core.internal.context.java;
+
+import java.util.List;
+import javax.xml.namespace.QName;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jpt.common.core.utility.TextRange;
+import org.eclipse.jpt.common.utility.Filter;
+import org.eclipse.jpt.common.utility.internal.Bag;
+import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.HashBag;
+import org.eclipse.jpt.common.utility.internal.StringTools;
+import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
+import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
+import org.eclipse.jpt.jaxb.core.context.XmlElementRef;
+import org.eclipse.jpt.jaxb.core.context.XmlElementRefs;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
+import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
+import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
+import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
+import org.eclipse.jpt.jaxb.core.resource.java.XmlElementRefAnnotation;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
+
+
+public class GenericJavaXmlElementRefs
+		extends AbstractJavaContextNode 
+		implements XmlElementRefs {
+	
+	protected final Context context;
+	
+	protected final XmlElementRefContainer xmlElementRefContainer;
+	
+	
+	public GenericJavaXmlElementRefs(JavaContextNode parent, Context context) {
+		super(parent);
+		this.context = context;
+		this.xmlElementRefContainer = new XmlElementRefContainer();
+	}
+	
+	
+	// ***** sync/update *****
+	
+	@Override
+	public void synchronizeWithResourceModel() {
+		super.synchronizeWithResourceModel();
+		this.xmlElementRefContainer.synchronizeWithResourceModel();
+	}
+	
+	@Override
+	public void update() {
+		super.update();
+		this.xmlElementRefContainer.update();
+	}
+	
+	
+	// ***** xml element refs *****
+	
+	public ListIterable<XmlElementRef> getXmlElementRefs() {
+		return this.xmlElementRefContainer.getContextElements();
+	}
+	
+	public int getXmlElementRefsSize() {
+		return this.xmlElementRefContainer.getContextElementsSize();
+	}
+	
+	public XmlElementRef addXmlElementRef(int index) {
+		XmlElementRefAnnotation annotation = this.context.addXmlElementRefAnnotation(index);
+		return this.xmlElementRefContainer.addContextElement(index, annotation);
+	}
+	
+	public void removeXmlElementRef(int index) {
+		this.context.removeXmlElementRefAnnotation(index);
+		this.xmlElementRefContainer.removeContextElement(index);
+	}
+	
+	public void removeXmlElementRef(XmlElementRef xmlElementRef) {
+		removeXmlElementRef(this.xmlElementRefContainer.indexOfContextElement(xmlElementRef));
+	}
+	
+	public void moveXmlElementRef(int targetIndex, int sourceIndex) {
+		this.context.moveXmlElementRefAnnotation(targetIndex, sourceIndex);
+		this.xmlElementRefContainer.moveContextElement(targetIndex, sourceIndex);
+	}
+	
+	protected XmlElementRef buildXmlElementRef(XmlElementRefAnnotation xmlElementRefAnnotation) {
+		return context.buildXmlElementRef(this, xmlElementRefAnnotation);
+	}
+	
+	protected ListIterable<XmlElementRefAnnotation> getXmlElementRefAnnotations() {
+		return this.context.getXmlElementRefAnnotations();
+	}
+	
+	protected XmlElementRefAnnotation getXmlElementRefAnnotation(XmlElementRef xmlElementRef) {
+		return this.xmlElementRefContainer.getResourceElement(xmlElementRef);
+	}
+	
+	
+	// ***** content assist *****
+	
+	@Override
+	public Iterable<String> getJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
+		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
+		}
+		
+		for (XmlElementRef elementRef : getXmlElementRefs()) {
+			result = elementRef.getJavaCompletionProposals(pos, filter, astRoot);
+			if (! CollectionTools.isEmpty(result)) {
+				return result;
+			}
+		}
+		
+		return EmptyIterable.instance();
+	}
+	
+	
+	// ***** validation *****
+	
+	@Override
+	public TextRange getValidationTextRange(CompilationUnit astRoot) {
+		return this.context.getValidationTextRange(astRoot);
+	}
+	
+	@Override
+	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+		super.validate(messages, reporter, astRoot);
+		
+		validateDuplicateTypesAndQNames(messages, reporter, astRoot);
+		
+		for (XmlElementRef elementRef : getXmlElementRefs()) {
+			elementRef.validate(messages, reporter, astRoot);
+		}
+	}
+	
+	protected void validateDuplicateTypesAndQNames(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+		
+		Bag<String> xmlElementRefTypes = new HashBag<String>();
+		Bag<QName> xmlElementRefQnames = new HashBag<QName>();
+		
+		for (XmlElementRef xmlElementRef : getXmlElementRefs()) {
+			String typeName = xmlElementRef.getFullyQualifiedType();
+			boolean isJaxbElement = JAXB.JAXB_ELEMENT.equals(typeName);
+			if (! isJaxbElement && ! StringTools.stringIsEmpty(typeName)) {
+				xmlElementRefTypes.add(typeName);
+			}
+			String elementRefName = xmlElementRef.getQName().getName();
+			if (isJaxbElement && ! StringTools.stringIsEmpty(elementRefName)) {
+				xmlElementRefQnames.add(new QName(xmlElementRef.getQName().getNamespace(), elementRefName));
+			}
+		}
+		
+		for (XmlElementRef xmlElementRef : getXmlElementRefs()) {
+			String typeName = xmlElementRef.getFullyQualifiedType();
+			boolean isJaxbElement = JAXB.JAXB_ELEMENT.equals(typeName);
+			if (! isJaxbElement && xmlElementRefTypes.count(typeName) > 1) {
+				messages.add(
+						DefaultValidationMessages.buildMessage(
+								IMessage.HIGH_SEVERITY,
+								JaxbValidationMessages.XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_TYPE,
+								new String[] { typeName },
+								xmlElementRef,
+								xmlElementRef.getTypeTextRange(astRoot)));
+			}
+			
+			String xmlElementNamespace = xmlElementRef.getQName().getNamespace();
+			String xmlElementName = xmlElementRef.getQName().getName();
+			if (isJaxbElement && xmlElementRefQnames.count(new QName(xmlElementNamespace, xmlElementName)) > 1) {
+				messages.add(
+						DefaultValidationMessages.buildMessage(
+								IMessage.HIGH_SEVERITY,
+								JaxbValidationMessages.XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_QNAME,
+								new String[] { xmlElementName },
+								xmlElementRef,
+								xmlElementRef.getQName().getNameTextRange(astRoot)));
+			}
+		}
+	}
+	
+	
+	
+	// ***** misc *****
+	
+	public Iterable<String> getDirectlyReferencedTypeNames() {
+		return new CompositeIterable<String>(
+				new TransformationIterable<XmlElementRef, Iterable<String>>(getXmlElementRefs()) {
+					@Override
+					protected Iterable<String> transform(XmlElementRef xmlElementRef) {
+						return xmlElementRef.getDirectlyReferencedTypeNames();
+					}
+				});
+	}
+	
+	
+	
+	protected class XmlElementRefContainer
+			extends ContextListContainer<XmlElementRef, XmlElementRefAnnotation> {
+		
+		@Override
+		protected String getContextElementsPropertyName() {
+			return XmlElementRefs.XML_ELEMENT_REFS_LIST;
+		}
+		
+		@Override
+		protected XmlElementRef buildContextElement(XmlElementRefAnnotation resourceElement) {
+			return GenericJavaXmlElementRefs.this.buildXmlElementRef(resourceElement);
+		}
+		
+		@Override
+		protected ListIterable<XmlElementRefAnnotation> getResourceElements() {
+			return GenericJavaXmlElementRefs.this.getXmlElementRefAnnotations();
+		}
+		
+		@Override
+		protected XmlElementRefAnnotation getResourceElement(XmlElementRef contextElement) {
+			// in this context, there will never be an XmlElementRef without an annotation
+			return contextElement.getAnnotation();
+		}
+	}
+	
+	
+	public interface Context {
+		
+		ListIterable<XmlElementRefAnnotation> getXmlElementRefAnnotations();
+		
+		XmlElementRefAnnotation addXmlElementRefAnnotation(int index);
+		
+		void removeXmlElementRefAnnotation(int index);
+		
+		void moveXmlElementRefAnnotation(int targetIndex, int sourceIndex);
+		
+		XmlElementRef buildXmlElementRef(JavaContextNode parent, XmlElementRefAnnotation annotation);
+		
+		TextRange getValidationTextRange(CompilationUnit astRoot);
+	}
+}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefsMapping.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefsMapping.java
index 03c7923..fa46a33 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefsMapping.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementRefsMapping.java
@@ -9,30 +9,40 @@
  *******************************************************************************/
 package org.eclipse.jpt.jaxb.core.internal.context.java;
 
+import java.util.List;
+import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement;
+import org.eclipse.jpt.common.core.utility.TextRange;
+import org.eclipse.jpt.common.utility.Filter;
+import org.eclipse.jpt.common.utility.internal.CollectionTools;
+import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
 import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
 import org.eclipse.jpt.jaxb.core.MappingKeys;
 import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
 import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
 import org.eclipse.jpt.jaxb.core.context.XmlAdaptable;
 import org.eclipse.jpt.jaxb.core.context.XmlElementRef;
+import org.eclipse.jpt.jaxb.core.context.XmlElementRefs;
 import org.eclipse.jpt.jaxb.core.context.XmlElementRefsMapping;
 import org.eclipse.jpt.jaxb.core.context.XmlElementWrapper;
 import org.eclipse.jpt.jaxb.core.context.XmlJavaTypeAdapter;
 import org.eclipse.jpt.jaxb.core.context.XmlMixed;
+import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
 import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlElementRefAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlElementRefsAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlElementWrapperAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlJavaTypeAdapterAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlMixedAnnotation;
+import org.eclipse.wst.validation.internal.provisional.core.IMessage;
+import org.eclipse.wst.validation.internal.provisional.core.IReporter;
 
 
 public class GenericJavaXmlElementRefsMapping
 		extends AbstractJavaAttributeMapping<XmlElementRefsAnnotation>
 		implements XmlElementRefsMapping {
 	
-	protected final XmlElementRefContainer xmlElementRefContainer;
+	protected final XmlElementRefs xmlElementRefs;
 	
 	protected final XmlAdaptable xmlAdaptable;
 	
@@ -43,7 +53,7 @@
 	
 	public GenericJavaXmlElementRefsMapping(JaxbPersistentAttribute parent) {
 		super(parent);
-		this.xmlElementRefContainer = new XmlElementRefContainer();
+		this.xmlElementRefs = buildXmlElementRefs();
 		this.xmlAdaptable = buildXmlAdaptable();
 		initializeXmlElementWrapper();
 		initializeXmlMixed();			
@@ -65,7 +75,7 @@
 	@Override
 	public void synchronizeWithResourceModel() {
 		super.synchronizeWithResourceModel();
-		this.xmlElementRefContainer.synchronizeWithResourceModel();
+		this.xmlElementRefs.synchronizeWithResourceModel();
 		this.xmlAdaptable.synchronizeWithResourceModel();
 		syncXmlElementWrapper();
 		syncXmlMixed();
@@ -74,52 +84,21 @@
 	@Override
 	public void update() {
 		super.update();
-		this.xmlElementRefContainer.update();
+		this.xmlElementRefs.update();
 		this.xmlAdaptable.update();
 		updateXmlElementWrapper();
 		updateXmlMixed();
 	}
 	
 	
-	// ***** xml element refs *****
+	// ***** XmlElementRefs *****
 	
-	public ListIterable<XmlElementRef> getXmlElementRefs() {
-		return this.xmlElementRefContainer.getContextElements();
+	public XmlElementRefs getXmlElementRefs() {
+		return this.xmlElementRefs;
 	}
 	
-	public int getXmlElementRefsSize() {
-		return this.xmlElementRefContainer.getContextElementsSize();
-	}
-	
-	public XmlElementRef addXmlElementRef(int index) {
-		XmlElementRefAnnotation annotation = getAnnotation().addXmlElementRef(index);
-		return this.xmlElementRefContainer.addContextElement(index, annotation);
-	}
-	
-	public void removeXmlElementRef(int index) {
-		getAnnotation().removeXmlElementRef(index);
-		this.xmlElementRefContainer.removeContextElement(index);
-	}
-	
-	public void removeXmlElementRef(XmlElementRef xmlElementRef) {
-		removeXmlElementRef(this.xmlElementRefContainer.indexOfContextElement(xmlElementRef));
-	}
-	
-	public void moveXmlElementRef(int targetIndex, int sourceIndex) {
-		getAnnotation().moveXmlElementRef(targetIndex, sourceIndex);
-		this.xmlElementRefContainer.moveContextElement(targetIndex, sourceIndex);
-	}
-	
-	protected XmlElementRef buildXmlElementRef(XmlElementRefAnnotation xmlElementRefAnnotation) {
-		return new GenericJavaXmlElementRef(this, new XmlElementRefContext(xmlElementRefAnnotation));
-	}
-	
-	protected ListIterable<XmlElementRefAnnotation> getXmlElementRefAnnotations() {
-		return getAnnotation().getXmlElementRefs();
-	}
-	
-	protected XmlElementRefAnnotation getXmlElementRefAnnotation(XmlElementRef xmlElementRef) {
-		return this.xmlElementRefContainer.getResourceElement(xmlElementRef);
+	protected XmlElementRefs buildXmlElementRefs() {
+		return new GenericJavaXmlElementRefs(this, new XmlElementRefsContext());
 	}
 	
 	
@@ -296,28 +275,88 @@
 	}
 	
 	
-	protected class XmlElementRefContainer
-			extends ContextListContainer<XmlElementRef, XmlElementRefAnnotation> {
-		
-		@Override
-		protected String getContextElementsPropertyName() {
-			return XmlElementRefsMapping.XML_ELEMENT_REFS_LIST;
+	// ***** misc *****
+	
+	@Override
+	public Iterable<String> getDirectlyReferencedTypeNames() {
+		return this.xmlElementRefs.getDirectlyReferencedTypeNames();
+	}
+	
+	
+	// ***** content assist *****
+	
+	@Override
+	public Iterable<String> getJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
+		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
 		}
 		
-		@Override
-		protected XmlElementRef buildContextElement(XmlElementRefAnnotation resourceElement) {
-			return GenericJavaXmlElementRefsMapping.this.buildXmlElementRef(resourceElement);
+		result = this.xmlElementRefs.getJavaCompletionProposals(pos, filter, astRoot);
+		if (! CollectionTools.isEmpty(result)) {
+			return result;
 		}
 		
-		@Override
-		protected ListIterable<XmlElementRefAnnotation> getResourceElements() {
-			return GenericJavaXmlElementRefsMapping.this.getXmlElementRefAnnotations();
+		if (this.xmlElementWrapper != null) {
+			result = this.xmlElementWrapper.getJavaCompletionProposals(pos, filter, astRoot);
+			if (! CollectionTools.isEmpty(result)) {
+				return result;
+			}
 		}
 		
-		@Override
-		protected XmlElementRefAnnotation getResourceElement(XmlElementRef contextElement) {
-			// in the context of this mapping, there will never be an XmlElementRef without an annotation
-			return contextElement.getAnnotation();
+		return EmptyIterable.instance();
+	}
+	
+	
+	// ***** validation *****
+	
+	@Override
+	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
+		super.validate(messages, reporter, astRoot);
+		
+		this.xmlElementRefs.validate(messages, reporter, astRoot);
+		
+		this.xmlAdaptable.validate(messages, reporter, astRoot);
+		
+		if (this.xmlElementWrapper != null) {
+			this.xmlElementWrapper.validate(messages, reporter, astRoot);
+		}
+		
+		if (this.xmlMixed != null) {
+			this.xmlMixed.validate(messages, reporter, astRoot);
+		}
+	}
+	
+	
+	public class XmlElementRefsContext
+			implements GenericJavaXmlElementRefs.Context {
+		
+		protected XmlElementRefsAnnotation getXmlElementRefsAnnotation() {
+			return GenericJavaXmlElementRefsMapping.this.getAnnotation();
+		}
+		
+		public ListIterable<XmlElementRefAnnotation> getXmlElementRefAnnotations() {
+			return getXmlElementRefsAnnotation().getXmlElementRefs();
+		}
+		
+		public XmlElementRefAnnotation addXmlElementRefAnnotation(int index) {
+			return getXmlElementRefsAnnotation().addXmlElementRef(index);
+		}
+		
+		public void removeXmlElementRefAnnotation(int index) {
+			getXmlElementRefsAnnotation().removeXmlElementRef(index);
+		}
+		
+		public void moveXmlElementRefAnnotation(int targetIndex, int sourceIndex) {
+			getXmlElementRefsAnnotation().moveXmlElementRef(targetIndex, sourceIndex);
+		}
+		
+		public XmlElementRef buildXmlElementRef(JavaContextNode parent, XmlElementRefAnnotation annotation) {
+			return new GenericJavaXmlElementRef(parent, new XmlElementRefContext(annotation));
+		}
+		
+		public TextRange getValidationTextRange(CompilationUnit astRoot) {
+			return getXmlElementRefsAnnotation().getTextRange(astRoot);
 		}
 	}
 	
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementWrapper.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementWrapper.java
index 2e88904..8f58b5c 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementWrapper.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlElementWrapper.java
@@ -213,17 +213,11 @@
 			extends AbstractJavaQName {
 		
 		protected XmlElementQName(JavaContextNode parent) {
-			super(parent);
+			super(parent, new QNameAnnotationProxy());
 		}
 		
 		
 		@Override
-		protected QNameAnnotation getAnnotation(boolean createIfNull) {
-			// never null
-			return GenericJavaXmlElementWrapper.this.annotation;
-		}
-		
-		@Override
 		public String getDefaultName() {
 			return "";
 		}
@@ -263,4 +257,14 @@
 			}
 		}
 	}
+	
+	
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			return GenericJavaXmlElementWrapper.this.annotation;
+		}
+	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlRootElement.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlRootElement.java
index e8683ce..d220863 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlRootElement.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlRootElement.java
@@ -124,17 +124,11 @@
 			extends AbstractJavaQName {
 		
 		protected XmlRootElementQName(JavaContextNode parent) {
-			super(parent);
+			super(parent, new QNameAnnotationProxy());
 		}
 		
 		
 		@Override
-		protected QNameAnnotation getAnnotation(boolean createIfNull) {
-			// never null
-			return GenericJavaXmlRootElement.this.annotation;
-		}
-		
-		@Override
 		public String getDefaultNamespace() {
 			return GenericJavaXmlRootElement.this.getPersistentType().getJaxbPackage().getNamespace();
 		}
@@ -197,4 +191,14 @@
 			}
 		}
 	}
+	
+	
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			return GenericJavaXmlRootElement.this.annotation;
+		}
+	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlSchemaType.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlSchemaType.java
index c677791..3526a79 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlSchemaType.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/GenericJavaXmlSchemaType.java
@@ -138,17 +138,11 @@
 			extends AbstractJavaQName {
 		
 		protected XmlSchemaTypeQName(JavaContextNode parent) {
-			super(parent);
+			super(parent, new QNameAnnotationProxy());
 		}
 		
 		
 		@Override
-		protected QNameAnnotation getAnnotation(boolean createIfNull) {
-			// never null
-			return GenericJavaXmlSchemaType.this.annotation;
-		}
-		
-		@Override
 		protected String getReferencedComponentTypeDescription() {
 			return JptJaxbCoreMessages.XML_TYPE_DESC;
 		}
@@ -198,4 +192,14 @@
 			}
 		}
 	}
+	
+	
+	protected class QNameAnnotationProxy 
+			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
+		
+		@Override
+		protected QNameAnnotation getAnnotation(boolean createIfNull) {
+			return GenericJavaXmlSchemaType.this.annotation;
+		}
+	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/JavaXmlAnyElementMappingDefinition.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/JavaXmlAnyElementMappingDefinition.java
index b771d98..b020381 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/JavaXmlAnyElementMappingDefinition.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/context/java/JavaXmlAnyElementMappingDefinition.java
@@ -26,8 +26,11 @@
 		new JavaXmlAnyElementMappingDefinition();
 	
 	private static final String[] SUPPORTING_ANNOTATION_NAMES = {
-			JAXB.XML_JAVA_TYPE_ADAPTER,
-			JAXB.XML_MIXED };
+		JAXB.XML_ELEMENT_REF,
+		JAXB.XML_ELEMENT_REFS,
+		JAXB.XML_ELEMENT_WRAPPER,
+		JAXB.XML_JAVA_TYPE_ADAPTER,
+		JAXB.XML_MIXED };
 	
 	
 	/**
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/NullXmlElementDeclAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/NullXmlElementDeclAnnotation.java
deleted file mode 100644
index 03ccd49..0000000
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/NullXmlElementDeclAnnotation.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 Oracle. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0, which accompanies this distribution
- * and is available at http://www.eclipse.org/legal/epl-v10.html.
- * 
- * Contributors:
- *     Oracle - initial API and implementation
- ******************************************************************************/
-package org.eclipse.jpt.jaxb.core.internal.resource.java;
-
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jpt.common.core.internal.resource.java.NullAnnotation;
-import org.eclipse.jpt.common.core.resource.java.JavaResourceNode;
-import org.eclipse.jpt.common.core.utility.TextRange;
-import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
-import org.eclipse.jpt.jaxb.core.resource.java.XmlElementDeclAnnotation;
-
-/**
- * javax.xml.bind.annotation.XmlElementDecl
- */
-public final class NullXmlElementDeclAnnotation
-	extends NullAnnotation
-	implements XmlElementDeclAnnotation
-{
-	protected NullXmlElementDeclAnnotation(JavaResourceNode parent) {
-		super(parent);
-	}
-
-	public String getAnnotationName() {
-		return JAXB.XML_ELEMENT_DECL;
-	}
-
-	@Override
-	protected XmlElementDeclAnnotation addAnnotation() {
-		return (XmlElementDeclAnnotation) super.addAnnotation();
-	}
-
-
-	// ********** XmlEnumAnnotation implementation **********
-	
-	// ***** name
-	public String getName() {
-		return null;
-	}
-
-	public void setName(String name) {
-		if (name != null) {
-			this.addAnnotation().setName(name);
-		}
-	}
-
-	public TextRange getNameTextRange(CompilationUnit astRoot) {
-		return null;
-	}
-	
-	// ***** namespace
-	public String getNamespace() {
-		return null;
-	}
-
-	public void setNamespace(String namespace) {
-		if (namespace != null) {
-			this.addAnnotation().setNamespace(namespace);
-		}
-	}
-
-	public TextRange getNamespaceTextRange(CompilationUnit astRoot) {
-		return null;
-	}
-	
-	// ***** defaultValue
-	public String getDefaultValue() {
-		return null;
-	}
-
-	public void setDefaultValue(String defaultValue) {
-		if (defaultValue != null) {
-			this.addAnnotation().setDefaultValue(defaultValue);
-		}
-	}
-
-	public TextRange getDefaultValueTextRange(CompilationUnit astRoot) {
-		return null;
-	}
-	
-	// ***** scope
-	public String getScope() {
-		return null;
-	}
-
-	public String getFullyQualifiedScopeClassName() {
-		return null;
-	}
-
-	public void setScope(String scope) {
-		if (scope != null) {
-			this.addAnnotation().setScope(scope);
-		}
-	}
-
-	public TextRange getScopeTextRange(CompilationUnit astRoot) {
-		return null;
-	}
-	
-	// ***** substitutionHeadName
-	public String getSubstitutionHeadName() {
-		return null;
-	}
-
-	public void setSubstitutionHeadName(String substitutionHeadName) {
-		if (substitutionHeadName != null) {
-			this.addAnnotation().setSubstitutionHeadName(substitutionHeadName);
-		}
-	}
-
-	public TextRange getSubstitutionHeadNameTextRange(CompilationUnit astRoot) {
-		return null;
-	}
-	
-	// ***** substitutionHeadNamespace
-	public String getSubstitutionHeadNamespace() {
-		return null;
-	}
-
-	public void setSubstitutionHeadNamespace(String substitutionHeadNamespace) {
-		if (substitutionHeadNamespace != null) {
-			this.addAnnotation().setSubstitutionHeadNamespace(substitutionHeadNamespace);
-		}
-	}
-
-	public TextRange getSubstitutionHeadNamespaceTextRange(CompilationUnit astRoot) {
-		return null;
-	}
-
-}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/XmlElementDeclAnnotationDefinition.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/XmlElementDeclAnnotationDefinition.java
index 7ca1261..cfabd0c 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/XmlElementDeclAnnotationDefinition.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/XmlElementDeclAnnotationDefinition.java
@@ -53,7 +53,7 @@
 	}
 	
 	public Annotation buildNullAnnotation(JavaResourceAnnotatedElement parent) {
-		return new NullXmlElementDeclAnnotation(parent);
+		throw new UnsupportedOperationException();
 	}
 	
 	public Annotation buildAnnotation(JavaResourceAnnotatedElement parent, IAnnotation jdtAnnotation) {
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlElementDeclAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlElementDeclAnnotation.java
index 7c827dd..bf1be28 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlElementDeclAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/binary/BinaryXmlElementDeclAnnotation.java
@@ -21,190 +21,216 @@
  * javax.xml.bind.annotation.XmlElementDecl
  */
 public final class BinaryXmlElementDeclAnnotation
-	extends BinaryAnnotation
-	implements XmlElementDeclAnnotation
-{
-	private String name;
-	private String namespace;
-	private String defaultValue;
+		extends BinaryAnnotation
+		implements XmlElementDeclAnnotation {
+	
 	private String scope;
-	private String substitutionHeadName;
+	private String namespace;
+	private String name;
 	private String substitutionHeadNamespace;
-
-
+	private String substitutionHeadName;
+	private String defaultValue;
+	
+	
 	public BinaryXmlElementDeclAnnotation(JavaResourceAnnotatedElement parent, IAnnotation jdtAnnotation) {
 		super(parent, jdtAnnotation);
-		this.name = this.buildName();
-		this.namespace = this.buildNamespace();
-		this.defaultValue = this.buildDefaultValue();
-		this.scope = this.buildScope();
-		this.substitutionHeadName = this.buildSubstitutionHeadName();
-		this.substitutionHeadNamespace = this.buildSubstitutionHeadNamespace();
+		this.scope = buildScope();
+		this.namespace = buildNamespace();
+		this.name = buildName();
+		this.substitutionHeadNamespace = buildSubstitutionHeadNamespace();
+		this.substitutionHeadName = buildSubstitutionHeadName();
+		this.defaultValue = buildDefaultValue();
 	}
-
+	
+	
 	public String getAnnotationName() {
 		return JAXB.XML_ELEMENT_DECL;
 	}
-
+	
 	@Override
 	public void update() {
 		super.update();
-		this.setName_(this.buildName());
-		this.setNamespace_(this.buildNamespace());
-		this.setDefaultValue_(this.buildDefaultValue());
-		this.setScope_(this.buildScope());
-		this.setSubstitutionHeadName_(this.buildSubstitutionHeadName());
-		this.setSubstitutionHeadNamespace_(this.buildSubstitutionHeadNamespace());
+		setScope_(buildScope());
+		setNamespace_(buildNamespace());
+		setName_(buildName());
+		setSubstitutionHeadNamespace_(buildSubstitutionHeadNamespace());
+		setSubstitutionHeadName_(buildSubstitutionHeadName());
+		setDefaultValue_(buildDefaultValue());
 	}
-
+	
 	@Override
 	public void toString(StringBuilder sb) {
 		sb.append(this.name);
 	}
-
-
-	// ********** XmlElementDeclAnnotation implementation **********
-	// ***** name
-	public String getName() {
-		return this.name;
-	}
-
-	public void setName(String name) {
-		throw new UnsupportedOperationException();
-	}
-
-	private void setName_(String name) {
-		String old = this.name;
-		this.name = name;
-		this.firePropertyChanged(NAME_PROPERTY, old, name);
-	}
-
-	private String buildName() {
-		return (String) this.getJdtMemberValue(JAXB.XML_ELEMENT_DECL__NAME);
-	}
-
-	public TextRange getNameTextRange(CompilationUnit astRoot) {
-		throw new UnsupportedOperationException();
-	}
-
-	// ***** namespace
+	
+	
+	// ***** namespace *****
+	
 	public String getNamespace() {
 		return this.namespace;
 	}
-
+	
 	public void setNamespace(String namespace) {
 		throw new UnsupportedOperationException();
 	}
-
+	
 	private void setNamespace_(String namespace) {
 		String old = this.namespace;
 		this.namespace = namespace;
-		this.firePropertyChanged(NAMESPACE_PROPERTY, old, namespace);
+		firePropertyChanged(NAMESPACE_PROPERTY, old, namespace);
 	}
-
+	
 	private String buildNamespace() {
-		return (String) this.getJdtMemberValue(JAXB.XML_ELEMENT_DECL__NAMESPACE);
+		return (String) getJdtMemberValue(JAXB.XML_ELEMENT_DECL__NAMESPACE);
 	}
-
+	
 	public TextRange getNamespaceTextRange(CompilationUnit astRoot) {
 		throw new UnsupportedOperationException();
 	}
-
-	// ***** default value
-	public String getDefaultValue() {
-		return this.defaultValue;
-	}
-
-	public void setDefaultValue(String defaultValue) {
+	
+	public boolean namespaceTouches(int pos, CompilationUnit astRoot) {
 		throw new UnsupportedOperationException();
 	}
-
-	private void setDefaultValue_(String defaultValue) {
-		String old = this.defaultValue;
-		this.defaultValue = defaultValue;
-		this.firePropertyChanged(DEFAULT_VALUE_PROPERTY, old, defaultValue);
+	
+	
+	// ***** name *****
+	
+	public String getName() {
+		return this.name;
 	}
-
-	private String buildDefaultValue() {
-		return (String) this.getJdtMemberValue(JAXB.XML_ELEMENT_DECL__DEFAULT_VALUE);
-	}
-
-	public TextRange getDefaultValueTextRange(CompilationUnit astRoot) {
+	
+	public void setName(String name) {
 		throw new UnsupportedOperationException();
 	}
-
-	// ***** scope
+	
+	private void setName_(String name) {
+		String old = this.name;
+		this.name = name;
+		firePropertyChanged(NAME_PROPERTY, old, name);
+	}
+	
+	private String buildName() {
+		return (String) getJdtMemberValue(JAXB.XML_ELEMENT_DECL__NAME);
+	}
+	
+	public TextRange getNameTextRange(CompilationUnit astRoot) {
+		throw new UnsupportedOperationException();
+	}
+	
+	public boolean nameTouches(int pos, CompilationUnit astRoot) {
+		throw new UnsupportedOperationException();
+	}
+	
+	
+	// ***** scope *****
+	
 	public String getScope() {
 		return this.scope;
 	}
-
+	
 	public void setScope(String scope) {
 		throw new UnsupportedOperationException();
 	}
-
+	
 	private void setScope_(String scope) {
 		String old = this.scope;
 		this.scope = scope;
-		this.firePropertyChanged(SCOPE_PROPERTY, old, scope);
-		this.firePropertyChanged(FULLY_QUALIFIED_SCOPE_CLASS_NAME_PROPERTY, old, scope);
+		firePropertyChanged(SCOPE_PROPERTY, old, scope);
+		firePropertyChanged(FULLY_QUALIFIED_SCOPE_CLASS_NAME_PROPERTY, old, scope);
 	}
-
+	
 	private String buildScope() {
-		return (String) this.getJdtMemberValue(JAXB.XML_ELEMENT_DECL__SCOPE);
+		return (String) getJdtMemberValue(JAXB.XML_ELEMENT_DECL__SCOPE);
 	}
-
+	
 	public TextRange getScopeTextRange(CompilationUnit astRoot) {
 		throw new UnsupportedOperationException();
 	}
-
-	// ***** fully-qualified scope class name
+	
 	public String getFullyQualifiedScopeClassName() {
 		return this.scope;
 	}
-
-	// ***** substitutionHeadName
-	public String getSubstitutionHeadName() {
-		return this.substitutionHeadName;
-	}
-
-	public void setSubstitutionHeadName(String substitutionHeadName) {
-		throw new UnsupportedOperationException();
-	}
-
-	private void setSubstitutionHeadName_(String substitutionHeadName) {
-		String old = this.substitutionHeadName;
-		this.substitutionHeadName = substitutionHeadName;
-		this.firePropertyChanged(SUBSTITUTION_HEAD_NAME_PROPERTY, old, substitutionHeadName);
-	}
-
-	private String buildSubstitutionHeadName() {
-		return (String) this.getJdtMemberValue(JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAME);
-	}
-
-	public TextRange getSubstitutionHeadNameTextRange(CompilationUnit astRoot) {
-		throw new UnsupportedOperationException();
-	}
-
-	// ***** substitutionHeadNamespace
+	
+	
+	// ***** substitutionHeadNamespace *****
+	
 	public String getSubstitutionHeadNamespace() {
 		return this.substitutionHeadNamespace;
 	}
-
+	
 	public void setSubstitutionHeadNamespace(String substitutionHeadNamespace) {
 		throw new UnsupportedOperationException();
 	}
-
+	
 	private void setSubstitutionHeadNamespace_(String substitutionHeadNamespace) {
 		String old = this.substitutionHeadNamespace;
 		this.substitutionHeadNamespace = substitutionHeadNamespace;
-		this.firePropertyChanged(SUBSTITUTION_HEAD_NAMESPACE_PROPERTY, old, substitutionHeadNamespace);
+		firePropertyChanged(SUBSTITUTION_HEAD_NAMESPACE_PROPERTY, old, substitutionHeadNamespace);
 	}
-
+	
 	private String buildSubstitutionHeadNamespace() {
-		return (String) this.getJdtMemberValue(JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAMESPACE);
+		return (String) getJdtMemberValue(JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAMESPACE);
 	}
-
+	
 	public TextRange getSubstitutionHeadNamespaceTextRange(CompilationUnit astRoot) {
 		throw new UnsupportedOperationException();
 	}
+	
+	public boolean substitutionHeadNamespaceTouches(int pos, CompilationUnit astRoot) {
+		throw new UnsupportedOperationException();
+	}
+	
+	
+	// ***** substitutionHeadName *****
+	
+	public String getSubstitutionHeadName() {
+		return this.substitutionHeadName;
+	}
+	
+	public void setSubstitutionHeadName(String substitutionHeadName) {
+		throw new UnsupportedOperationException();
+	}
+	
+	private void setSubstitutionHeadName_(String substitutionHeadName) {
+		String old = this.substitutionHeadName;
+		this.substitutionHeadName = substitutionHeadName;
+		firePropertyChanged(SUBSTITUTION_HEAD_NAME_PROPERTY, old, substitutionHeadName);
+	}
+	
+	private String buildSubstitutionHeadName() {
+		return (String) getJdtMemberValue(JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAME);
+	}
+	
+	public TextRange getSubstitutionHeadNameTextRange(CompilationUnit astRoot) {
+		throw new UnsupportedOperationException();
+	}
+	
+	public boolean substitutionHeadNameTouches(int pos, CompilationUnit astRoot) {
+		throw new UnsupportedOperationException();
+	}
+	
+	
+	// ***** default value *****
+	
+	public String getDefaultValue() {
+		return this.defaultValue;
+	}
+	
+	public void setDefaultValue(String defaultValue) {
+		throw new UnsupportedOperationException();
+	}
+	
+	private void setDefaultValue_(String defaultValue) {
+		String old = this.defaultValue;
+		this.defaultValue = defaultValue;
+		firePropertyChanged(DEFAULT_VALUE_PROPERTY, old, defaultValue);
+	}
+	
+	private String buildDefaultValue() {
+		return (String) getJdtMemberValue(JAXB.XML_ELEMENT_DECL__DEFAULT_VALUE);
+	}
+	
+	public TextRange getDefaultValueTextRange(CompilationUnit astRoot) {
+		throw new UnsupportedOperationException();
+	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlElementDeclAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlElementDeclAnnotation.java
index a3c3881..92745cb 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlElementDeclAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/resource/java/source/SourceXmlElementDeclAnnotation.java
@@ -31,284 +31,315 @@
  * javax.xml.bind.annotation.XmlElementDecl
  */
 public final class SourceXmlElementDeclAnnotation
-	extends SourceAnnotation
-	implements XmlElementDeclAnnotation
-{
+		extends SourceAnnotation
+		implements XmlElementDeclAnnotation {
+	
 	public static final DeclarationAnnotationAdapter DECLARATION_ANNOTATION_ADAPTER = new SimpleDeclarationAnnotationAdapter(JAXB.XML_ELEMENT_DECL);
-
-	private static final DeclarationAnnotationElementAdapter<String> NAME_ADAPTER = buildNameAdapter();
-	private final AnnotationElementAdapter<String> nameAdapter;
-	private String name;
-
-	private static final DeclarationAnnotationElementAdapter<String> NAMESPACE_ADAPTER = buildNamespaceAdapter();
-	private final AnnotationElementAdapter<String> namespaceAdapter;
-	private String namespace;
-
-	private static final DeclarationAnnotationElementAdapter<String> DEFAULT_VALUE_ADAPTER = buildDefaultValueAdapter();
-	private final AnnotationElementAdapter<String> defaultValueAdapter;
-	private String defaultValue;
-
-	private static final DeclarationAnnotationElementAdapter<String> SCOPE_ADAPTER = buildScopeAdapter();
+	
+	private final DeclarationAnnotationElementAdapter<String> scopeDeclarationAdapter;
 	private final AnnotationElementAdapter<String> scopeAdapter;
 	private String scope;
 	private String fullyQualifiedScopeClassName;
-
-	private static final DeclarationAnnotationElementAdapter<String> SUBSTITUTION_HEAD_NAME_ADAPTER = buildSubstitutionHeadNameAdapter();
-	private final AnnotationElementAdapter<String> substitutionHeadNameAdapter;
-	private String substitutionHeadName;
-
-	private static final DeclarationAnnotationElementAdapter<String> SUBSTITUTION_HEAD_NAMESPACE_ADAPTER = buildSubstitutionHeadNamespaceAdapter();
+	
+	private final DeclarationAnnotationElementAdapter<String> namespaceDeclarationAdapter;
+	private final AnnotationElementAdapter<String> namespaceAdapter;
+	private String namespace;
+	
+	private final DeclarationAnnotationElementAdapter<String> nameDeclarationAdapter;
+	private final AnnotationElementAdapter<String> nameAdapter;
+	private String name;
+	
+	private final DeclarationAnnotationElementAdapter<String> substitutionHeadNamespaceDeclarationAdapter;
 	private final AnnotationElementAdapter<String> substitutionHeadNamespaceAdapter;
 	private String substitutionHeadNamespace;
-
-
+	
+	private final DeclarationAnnotationElementAdapter<String> substitutionHeadNameDeclarationAdapter;
+	private final AnnotationElementAdapter<String> substitutionHeadNameAdapter;
+	private String substitutionHeadName;
+	
+	private final DeclarationAnnotationElementAdapter<String> defaultValueDeclarationAdapter;
+	private final AnnotationElementAdapter<String> defaultValueAdapter;
+	private String defaultValue;
+	
+	
 	// ********** constructors **********
 
 	public SourceXmlElementDeclAnnotation(JavaResourceAnnotatedElement parent, AnnotatedElement annotatedElement) {
 		super(parent, annotatedElement, DECLARATION_ANNOTATION_ADAPTER, new ElementAnnotationAdapter(annotatedElement, DECLARATION_ANNOTATION_ADAPTER));
-		this.nameAdapter = this.buildAnnotationElementAdapter(NAME_ADAPTER);
-		this.namespaceAdapter = this.buildAnnotationElementAdapter(NAMESPACE_ADAPTER);
-		this.defaultValueAdapter = this.buildAnnotationElementAdapter(DEFAULT_VALUE_ADAPTER);
-		this.scopeAdapter = this.buildAnnotationElementAdapter(SCOPE_ADAPTER);
-		this.substitutionHeadNameAdapter = this.buildAnnotationElementAdapter(SUBSTITUTION_HEAD_NAME_ADAPTER);
-		this.substitutionHeadNamespaceAdapter = this.buildAnnotationElementAdapter(SUBSTITUTION_HEAD_NAMESPACE_ADAPTER);
+		this.scopeDeclarationAdapter = buildScopeDeclarationAdapter();
+		this.scopeAdapter = buildAnnotationElementAdapter(this.scopeDeclarationAdapter);
+		this.namespaceDeclarationAdapter = buildNamespaceDeclarationAdapter();
+		this.namespaceAdapter = buildAnnotationElementAdapter(this.namespaceDeclarationAdapter);
+		this.nameDeclarationAdapter = buildNameDeclarationAdapter();
+		this.nameAdapter = buildAnnotationElementAdapter(this.nameDeclarationAdapter);
+		this.substitutionHeadNamespaceDeclarationAdapter = buildSubstitutionHeadNamespaceDeclarationAdapter();
+		this.substitutionHeadNamespaceAdapter = buildAnnotationElementAdapter(this.substitutionHeadNamespaceDeclarationAdapter);
+		this.substitutionHeadNameDeclarationAdapter = buildSubstitutionHeadNameDeclarationAdapter();
+		this.substitutionHeadNameAdapter = buildAnnotationElementAdapter(this.substitutionHeadNameDeclarationAdapter);
+		this.defaultValueDeclarationAdapter = buildDefaultValueDeclarationAdapter();
+		this.defaultValueAdapter = buildAnnotationElementAdapter(this.defaultValueDeclarationAdapter);
 	}
-
+	
+	
 	private AnnotationElementAdapter<String> buildAnnotationElementAdapter(DeclarationAnnotationElementAdapter<String> daea) {
 		return new AnnotatedElementAnnotationElementAdapter<String>(this.annotatedElement, daea);
 	}
+	
+	private DeclarationAnnotationElementAdapter<String> buildScopeDeclarationAdapter() {
+		return buildAnnotationElementAdapter(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__SCOPE, SimpleTypeStringExpressionConverter.instance());
+	}
 
+	private DeclarationAnnotationElementAdapter<String> buildAnnotationElementAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName, ExpressionConverter<String> converter) {
+		return new ConversionDeclarationAnnotationElementAdapter<String>(annotationAdapter, elementName, converter);
+	}
+	
+	private DeclarationAnnotationElementAdapter<String> buildNamespaceDeclarationAdapter() {
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__NAMESPACE);
+	}
+	
+	private DeclarationAnnotationElementAdapter<String> buildNameDeclarationAdapter() {
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__NAME);
+	}
+	
+	private DeclarationAnnotationElementAdapter<String> buildSubstitutionHeadNamespaceDeclarationAdapter() {
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAMESPACE);
+	}
+	
+	private DeclarationAnnotationElementAdapter<String> buildSubstitutionHeadNameDeclarationAdapter() {
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAME);
+	}
+	
+	private DeclarationAnnotationElementAdapter<String> buildDefaultValueDeclarationAdapter() {
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__DEFAULT_VALUE);
+	}
+	
 	public String getAnnotationName() {
 		return JAXB.XML_ELEMENT_DECL;
 	}
-
+	
 	public void initialize(CompilationUnit astRoot) {
-		this.name = this.buildName(astRoot);
-		this.namespace = this.buildNamespace(astRoot);
-		this.defaultValue = this.buildDefaultValue(astRoot);
-		this.scope = this.buildScope(astRoot);
-		this.fullyQualifiedScopeClassName = this.buildFullyQualifiedScopeClassName(astRoot);
-		this.substitutionHeadName = this.buildSubstitutionHeadName(astRoot);
-		this.substitutionHeadNamespace = this.buildSubstitutionHeadNamespace(astRoot);
+		this.scope = buildScope(astRoot);
+		this.fullyQualifiedScopeClassName = buildFullyQualifiedScopeClassName(astRoot);
+		this.namespace = buildNamespace(astRoot);
+		this.name = buildName(astRoot);
+		this.substitutionHeadNamespace = buildSubstitutionHeadNamespace(astRoot);
+		this.substitutionHeadName = buildSubstitutionHeadName(astRoot);
+		this.defaultValue = buildDefaultValue(astRoot);
 	}
-
+	
 	public void synchronizeWith(CompilationUnit astRoot) {
-		this.syncName(this.buildName(astRoot));
-		this.syncNamespace(this.buildNamespace(astRoot));
-		this.syncDefaultValue(this.buildDefaultValue(astRoot));
-		this.syncScope(this.buildScope(astRoot));
-		this.syncFullyQualifiedScopeClassName(this.buildFullyQualifiedScopeClassName(astRoot));
-		this.syncSubstitutionHeadName(this.buildSubstitutionHeadName(astRoot));
-		this.syncSubstitutionHeadNamespace(this.buildSubstitutionHeadNamespace(astRoot));
+		syncScope(buildScope(astRoot));
+		syncFullyQualifiedScopeClassName(buildFullyQualifiedScopeClassName(astRoot));
+		syncNamespace(buildNamespace(astRoot));
+		syncName(buildName(astRoot));
+		syncSubstitutionHeadNamespace(buildSubstitutionHeadNamespace(astRoot));
+		syncSubstitutionHeadName(buildSubstitutionHeadName(astRoot));
+		syncDefaultValue(buildDefaultValue(astRoot));
 	}
-
+	
 	@Override
 	public void toString(StringBuilder sb) {
 		sb.append(this.name);
 	}
-
-
-	// ********** XmlElementDeclAnnotation implementation **********
-
-	// ***** name
-	public String getName() {
-		return this.name;
-	}
-
-	public void setName(String name) {
-		if (this.attributeValueHasChanged(this.name, name)) {
-			this.name = name;
-			this.nameAdapter.setValue(name);
-		}
-	}
-
-	private void syncName(String astName) {
-		String old = this.name;
-		this.name = astName;
-		this.firePropertyChanged(NAME_PROPERTY, old, astName);
-	}
-
-	private String buildName(CompilationUnit astRoot) {
-		return this.nameAdapter.getValue(astRoot);
-	}
-
-	public TextRange getNameTextRange(CompilationUnit astRoot) {
-		return this.getElementTextRange(NAME_ADAPTER, astRoot);
-	}
-
-	// ***** namespace
-	public String getNamespace() {
-		return this.namespace;
-	}
-
-	public void setNamespace(String namespace) {
-		if (this.attributeValueHasChanged(this.namespace, namespace)) {
-			this.namespace = namespace;
-			this.namespaceAdapter.setValue(namespace);
-		}
-	}
-
-	private void syncNamespace(String astNamespace) {
-		String old = this.namespace;
-		this.namespace = astNamespace;
-		this.firePropertyChanged(NAMESPACE_PROPERTY, old, astNamespace);
-	}
-
-	private String buildNamespace(CompilationUnit astRoot) {
-		return this.namespaceAdapter.getValue(astRoot);
-	}
-
-	public TextRange getNamespaceTextRange(CompilationUnit astRoot) {
-		return this.getElementTextRange(NAMESPACE_ADAPTER, astRoot);
-	}
-
-	// ***** defaultValue
-	public String getDefaultValue() {
-		return this.defaultValue;
-	}
-
-	public void setDefaultValue(String defaultValue) {
-		if (this.attributeValueHasChanged(this.defaultValue, defaultValue)) {
-			this.defaultValue = defaultValue;
-			this.defaultValueAdapter.setValue(defaultValue);
-		}
-	}
-
-	private void syncDefaultValue(String astDefaultValue) {
-		String old = this.defaultValue;
-		this.defaultValue = astDefaultValue;
-		this.firePropertyChanged(DEFAULT_VALUE_PROPERTY, old, astDefaultValue);
-	}
-
-	private String buildDefaultValue(CompilationUnit astRoot) {
-		return this.defaultValueAdapter.getValue(astRoot);
-	}
-
-	public TextRange getDefaultValueTextRange(CompilationUnit astRoot) {
-		return this.getElementTextRange(DEFAULT_VALUE_ADAPTER, astRoot);
-	}
-
-	// ***** scope
+	
+	
+	// ***** scope *****
+	
 	public String getScope() {
 		return this.scope;
 	}
-
+	
 	public void setScope(String scope) {
-		if (this.attributeValueHasChanged(this.scope, scope)) {
+		if (attributeValueHasChanged(this.scope, scope)) {
 			this.scope = scope;
 			this.scopeAdapter.setValue(scope);
 		}
 	}
-
+	
 	private void syncScope(String astScope) {
 		String old = this.scope;
 		this.scope = astScope;
-		this.firePropertyChanged(SCOPE_PROPERTY, old, astScope);
+		firePropertyChanged(SCOPE_PROPERTY, old, astScope);
 	}
-
+	
 	private String buildScope(CompilationUnit astRoot) {
 		return this.scopeAdapter.getValue(astRoot);
 	}
-
+	
 	public TextRange getScopeTextRange(CompilationUnit astRoot) {
-		return this.getElementTextRange(SCOPE_ADAPTER, astRoot);
+		return getElementTextRange(this.scopeDeclarationAdapter, astRoot);
 	}
-
-	// ***** fully-qualified scope class name
+	
+	
+	// ***** fully-qualified scope class name *****
+	
 	public String getFullyQualifiedScopeClassName() {
 		return this.fullyQualifiedScopeClassName;
 	}
-
+	
 	private void syncFullyQualifiedScopeClassName(String name) {
 		String old = this.fullyQualifiedScopeClassName;
 		this.fullyQualifiedScopeClassName = name;
-		this.firePropertyChanged(FULLY_QUALIFIED_SCOPE_CLASS_NAME_PROPERTY, old, name);
+		firePropertyChanged(FULLY_QUALIFIED_SCOPE_CLASS_NAME_PROPERTY, old, name);
 	}
-
+	
 	private String buildFullyQualifiedScopeClassName(CompilationUnit astRoot) {
 		return (this.scope == null) ? null : ASTTools.resolveFullyQualifiedName(this.scopeAdapter.getExpression(astRoot));
 	}
-
-	// ***** substitutionHeadName
-	public String getSubstitutionHeadName() {
-		return this.substitutionHeadName;
+	
+	
+	// ***** namespace *****
+	
+	public String getNamespace() {
+		return this.namespace;
 	}
-
-	public void setSubstitutionHeadName(String substitutionHeadName) {
-		if (this.attributeValueHasChanged(this.substitutionHeadName, substitutionHeadName)) {
-			this.substitutionHeadName = substitutionHeadName;
-			this.substitutionHeadNameAdapter.setValue(substitutionHeadName);
+	
+	public void setNamespace(String namespace) {
+		if (attributeValueHasChanged(this.namespace, namespace)) {
+			this.namespace = namespace;
+			this.namespaceAdapter.setValue(namespace);
 		}
 	}
-
-	private void syncSubstitutionHeadName(String astSubstitutionHeadName) {
-		String old = this.substitutionHeadName;
-		this.substitutionHeadName = astSubstitutionHeadName;
-		this.firePropertyChanged(SUBSTITUTION_HEAD_NAME_PROPERTY, old, astSubstitutionHeadName);
+	
+	private void syncNamespace(String astNamespace) {
+		String old = this.namespace;
+		this.namespace = astNamespace;
+		firePropertyChanged(NAMESPACE_PROPERTY, old, astNamespace);
 	}
-
-	private String buildSubstitutionHeadName(CompilationUnit astRoot) {
-		return this.substitutionHeadNameAdapter.getValue(astRoot);
+	
+	private String buildNamespace(CompilationUnit astRoot) {
+		return this.namespaceAdapter.getValue(astRoot);
 	}
-
-	public TextRange getSubstitutionHeadNameTextRange(CompilationUnit astRoot) {
-		return this.getElementTextRange(SUBSTITUTION_HEAD_NAME_ADAPTER, astRoot);
+	
+	public TextRange getNamespaceTextRange(CompilationUnit astRoot) {
+		return getElementTextRange(this.namespaceDeclarationAdapter, astRoot);
 	}
-
-	// ***** substitutionHeadNamespace
+	
+	public boolean namespaceTouches(int pos, CompilationUnit astRoot) {
+		return elementTouches(this.namespaceDeclarationAdapter, pos, astRoot);
+	}
+	
+	
+	// ***** name *****
+	
+	public String getName() {
+		return this.name;
+	}
+	
+	public void setName(String name) {
+		if (attributeValueHasChanged(this.name, name)) {
+			this.name = name;
+			this.nameAdapter.setValue(name);
+		}
+	}
+	
+	private void syncName(String astName) {
+		String old = this.name;
+		this.name = astName;
+		firePropertyChanged(NAME_PROPERTY, old, astName);
+	}
+	
+	private String buildName(CompilationUnit astRoot) {
+		return this.nameAdapter.getValue(astRoot);
+	}
+	
+	public TextRange getNameTextRange(CompilationUnit astRoot) {
+		return getElementTextRange(this.nameDeclarationAdapter, astRoot);
+	}
+	
+	public boolean nameTouches(int pos, CompilationUnit astRoot) {
+		return elementTouches(this.nameDeclarationAdapter, pos, astRoot);
+	}
+	
+	
+	// ***** substitutionHeadNamespace *****
+	
 	public String getSubstitutionHeadNamespace() {
 		return this.substitutionHeadNamespace;
 	}
-
+	
 	public void setSubstitutionHeadNamespace(String substitutionHeadNamespace) {
-		if (this.attributeValueHasChanged(this.substitutionHeadNamespace, substitutionHeadNamespace)) {
+		if (attributeValueHasChanged(this.substitutionHeadNamespace, substitutionHeadNamespace)) {
 			this.substitutionHeadNamespace = substitutionHeadNamespace;
 			this.substitutionHeadNamespaceAdapter.setValue(substitutionHeadNamespace);
 		}
 	}
-
+	
 	private void syncSubstitutionHeadNamespace(String astSubstitutionHeadNamespace) {
 		String old = this.substitutionHeadNamespace;
 		this.substitutionHeadNamespace = astSubstitutionHeadNamespace;
-		this.firePropertyChanged(SUBSTITUTION_HEAD_NAMESPACE_PROPERTY, old, astSubstitutionHeadNamespace);
+		firePropertyChanged(SUBSTITUTION_HEAD_NAMESPACE_PROPERTY, old, astSubstitutionHeadNamespace);
 	}
-
+	
 	private String buildSubstitutionHeadNamespace(CompilationUnit astRoot) {
 		return this.substitutionHeadNamespaceAdapter.getValue(astRoot);
 	}
-
+	
 	public TextRange getSubstitutionHeadNamespaceTextRange(CompilationUnit astRoot) {
-		return this.getElementTextRange(SUBSTITUTION_HEAD_NAMESPACE_ADAPTER, astRoot);
+		return getElementTextRange(this.substitutionHeadNamespaceDeclarationAdapter, astRoot);
 	}
-
-
-	// ********** static methods **********
-
-	private static DeclarationAnnotationElementAdapter<String> buildNameAdapter() {
-		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__NAME);
+	
+	public boolean substitutionHeadNamespaceTouches(int pos, CompilationUnit astRoot) {
+		return elementTouches(this.substitutionHeadNamespaceDeclarationAdapter, pos, astRoot);
 	}
-
-	private static DeclarationAnnotationElementAdapter<String> buildNamespaceAdapter() {
-		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__NAMESPACE);
+	
+	
+	// ***** substitutionHeadName *****
+	
+	public String getSubstitutionHeadName() {
+		return this.substitutionHeadName;
 	}
-
-	private static DeclarationAnnotationElementAdapter<String> buildDefaultValueAdapter() {
-		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__DEFAULT_VALUE);
+	
+	public void setSubstitutionHeadName(String substitutionHeadName) {
+		if (attributeValueHasChanged(this.substitutionHeadName, substitutionHeadName)) {
+			this.substitutionHeadName = substitutionHeadName;
+			this.substitutionHeadNameAdapter.setValue(substitutionHeadName);
+		}
 	}
-
-	private static DeclarationAnnotationElementAdapter<String> buildScopeAdapter() {
-		return buildAnnotationElementAdapter(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__SCOPE, SimpleTypeStringExpressionConverter.instance());
+	
+	private void syncSubstitutionHeadName(String astSubstitutionHeadName) {
+		String old = this.substitutionHeadName;
+		this.substitutionHeadName = astSubstitutionHeadName;
+		firePropertyChanged(SUBSTITUTION_HEAD_NAME_PROPERTY, old, astSubstitutionHeadName);
 	}
-
-	private static DeclarationAnnotationElementAdapter<String> buildSubstitutionHeadNameAdapter() {
-		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAME);
+	
+	private String buildSubstitutionHeadName(CompilationUnit astRoot) {
+		return this.substitutionHeadNameAdapter.getValue(astRoot);
 	}
-
-	private static DeclarationAnnotationElementAdapter<String> buildSubstitutionHeadNamespaceAdapter() {
-		return ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAMESPACE);
+	
+	public TextRange getSubstitutionHeadNameTextRange(CompilationUnit astRoot) {
+		return getElementTextRange(this.substitutionHeadNameDeclarationAdapter, astRoot);
 	}
-
-	private static DeclarationAnnotationElementAdapter<String> buildAnnotationElementAdapter(DeclarationAnnotationAdapter annotationAdapter, String elementName, ExpressionConverter<String> converter) {
-		return new ConversionDeclarationAnnotationElementAdapter<String>(annotationAdapter, elementName, converter);
+	
+	public boolean substitutionHeadNameTouches(int pos, CompilationUnit astRoot) {
+		return elementTouches(this.substitutionHeadNameDeclarationAdapter, pos, astRoot);
+	}
+	
+	
+	// ***** defaultValue *****
+	
+	public String getDefaultValue() {
+		return this.defaultValue;
+	}
+	
+	public void setDefaultValue(String defaultValue) {
+		if (attributeValueHasChanged(this.defaultValue, defaultValue)) {
+			this.defaultValue = defaultValue;
+			this.defaultValueAdapter.setValue(defaultValue);
+		}
+	}
+	
+	private void syncDefaultValue(String astDefaultValue) {
+		String old = this.defaultValue;
+		this.defaultValue = astDefaultValue;
+		firePropertyChanged(DEFAULT_VALUE_PROPERTY, old, astDefaultValue);
+	}
+	
+	private String buildDefaultValue(CompilationUnit astRoot) {
+		return this.defaultValueAdapter.getValue(astRoot);
+	}
+	
+	public TextRange getDefaultValueTextRange(CompilationUnit astRoot) {
+		return getElementTextRange(this.defaultValueDeclarationAdapter, astRoot);
 	}
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java
index b31f92f..41844b2 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/internal/validation/JaxbValidationMessages.java
@@ -47,11 +47,23 @@
 	String XML_ELEMENT__UNSPECIFIED_TYPE = "XML_ELEMENT__UNSPECIFIED_TYPE";
 	String XML_ELEMENT__ILLEGAL_TYPE = "XML_ELEMENT__ILLEGAL_TYPE";
 	
+	String XML_ELEMENT_DECL__SUBST_HEAD_NAME_EQUALS_NAME = "XML_ELEMENT_DECL__SUBST_HEAD_NAME_EQUALS_NAME";
+	String XML_ELEMENT_DECL__SUBST_HEAD_NO_MATCHING_ELEMENT_DECL = "XML_ELEMENT_DECL__SUBST_HEAD_NO_MATCHING_ELEMENT_DECL";
+	
+	String XML_ELEMENT_REF__UNSPECIFIED_TYPE = "XML_ELEMENT_REF__UNSPECIFIED_TYPE";
+	String XML_ELEMENT_REF__ILLEGAL_TYPE = "XML_ELEMENT_REF__ILLEGAL_TYPE";
+	String XML_ELEMENT_REF__NO_ROOT_ELEMENT = "XML_ELEMENT_REF__NO_ROOT_ELEMENT";
 	String XML_ELEMENT_REF__NO_REGISTRY = "XML_ELEMENT_REF__NO_REGISTRY";
 	String XML_ELEMENT_REF__NO_MATCHING_ELEMENT_DECL = "XML_ELEMENT_REF__NO_MATCHING_ELEMENT_DECL";
 	
+	String XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_TYPE = "XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_TYPE";
+	String XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_QNAME = "XML_ELEMENT_REFS__DUPLICATE_XML_ELEMENT_QNAME";
+	
 	String XML_ELEMENTS__DUPLICATE_XML_ELEMENT_TYPE = "XML_ELEMENTS__DUPLICATE_XML_ELEMENT_TYPE";
 	String XML_ELEMENTS__DUPLICATE_XML_ELEMENT_QNAME = "XML_ELEMENTS__DUPLICATE_XML_ELEMENT_QNAME";
+	
+	String XML_REGISTRY__DUPLICATE_XML_ELEMENT_QNAME = "XML_REGISTRY__DUPLICATE_XML_ELEMENT_QNAME";
+	
 	String XML_IDREF__TYPE_DOES_NOT_CONTAIN_XML_ID = "XML_IDREF__TYPE_DOES_NOT_CONTAIN_XML_ID";
 	String XML_LIST_DEFINED_ON_NON_ARRAY_NON_COLLECTION = "XML_LIST_DEFINED_ON_NON_ARRAY_NON_COLLECTION";
 	String MULTIPLE_XML_ANY_ATTRIBUTE_MAPPINGS_DEFINED = "MULTIPLE_XML_ANY_ATTRIBUTE_MAPPINGS_DEFINED";
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlElementDeclAnnotation.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlElementDeclAnnotation.java
index a9450c8..9b3a83e 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlElementDeclAnnotation.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/resource/java/XmlElementDeclAnnotation.java
@@ -10,7 +10,6 @@
 package org.eclipse.jpt.jaxb.core.resource.java;
 
 import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jpt.common.core.resource.java.Annotation;
 import org.eclipse.jpt.common.core.utility.TextRange;
 
 /**
@@ -27,65 +26,15 @@
  * @since 3.0
  */
 public interface XmlElementDeclAnnotation
-		extends Annotation {
+		extends QNameAnnotation {
+	
+	// ***** scope *****
 	
 	/**
-	 * Corresponds to the 'name' element of the XmlElementDecl annotation.
-	 * Return null if the element does not exist in Java.
+	 * String associated with "scope" property changes.
 	 */
-	String getName();
-		String NAME_PROPERTY = "name"; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the 'name' element of the XmlElementDecl annotation.
-	 * Set to null to remove the element.
-	 */
-	void setName(String name);
-
-	/**
-	 * Return the {@link TextRange} for the 'name' element. If the element 
-	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
-	 */
-	TextRange getNameTextRange(CompilationUnit astRoot);
-
-	/**
-	 * Corresponds to the 'namespace' element of the XmlElementDecl annotation.
-	 * Return null if the element does not exist in Java.
-	 */
-	String getNamespace();
-		String NAMESPACE_PROPERTY = "namespace"; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the 'namespace' element of the XmlElementDecl annotation.
-	 * Set to null to remove the element.
-	 */
-	void setNamespace(String namespace);
-
-	/**
-	 * Return the {@link TextRange} for the 'namespace' element. If the element 
-	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
-	 */
-	TextRange getNamespaceTextRange(CompilationUnit astRoot);
-
-	/**
-	 * Corresponds to the 'defaultValue' element of the XmlElementDecl annotation.
-	 * Return null if the element does not exist in Java.
-	 */
-	String getDefaultValue();
-		String DEFAULT_VALUE_PROPERTY = "defaultValue"; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the 'defaultValue' element of the XmlElementDecl annotation.
-	 * Set to null to remove the element.
-	 */
-	void setDefaultValue(String defaultValue);
-
-	/**
-	 * Return the {@link TextRange} for the 'defaultValue' element. If the element 
-	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
-	 */
-	TextRange getDefaultValueTextRange(CompilationUnit astRoot);
-
+	String SCOPE_PROPERTY = "scope"; //$NON-NLS-1$
+	
 	/**
 	 * Corresponds to the 'scope' element of the XmlElementDecl annotation.
 	 * Return null if the element does not exist in Java.
@@ -96,20 +45,24 @@
 	 * will return "XmlElementDecl.GLOBAL"
 	 */
 	String getScope();
-		String SCOPE_PROPERTY = "scope"; //$NON-NLS-1$
-
+	
 	/**
 	 * Corresponds to the 'scope' element of the XmlElementDecl annotation.
 	 * Set to null to remove the element.
 	 */
 	void setScope(String scope);
-
+	
 	/**
 	 * Return the {@link TextRange} for the 'scope' element. If the element 
 	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
 	 */
 	TextRange getScopeTextRange(CompilationUnit astRoot);
-
+	
+	/**
+	 * String associated with "fullyQualifiedScopeClassName" property changes.
+	 */
+	String FULLY_QUALIFIED_SCOPE_CLASS_NAME_PROPERTY = "fullyQualifiedScopeClassName"; //$NON-NLS-1$
+	
 	/**
 	 * Return the fully-qualified scope class name as resolved by the AST's bindings.
 	 * <pre>
@@ -118,44 +71,94 @@
 	 * will return "javax.xml.bind.annotation.XmlElementDecl.GLOBAL"
 	 */
 	String getFullyQualifiedScopeClassName();
-		String FULLY_QUALIFIED_SCOPE_CLASS_NAME_PROPERTY = "fullyQualifiedScopeClassName"; //$NON-NLS-1$
-
+	
+	
+	// ***** substitution head namespace *****
+	
 	/**
-	 * Corresponds to the 'substitutionHeadName' element of the XmlElementDecl annotation.
-	 * Return null if the element does not exist in Java.
+	 * String associated with "substitutionHeadNamespace" property changes.
 	 */
-	String getSubstitutionHeadName();
-		String SUBSTITUTION_HEAD_NAME_PROPERTY = "substitutionHeadName"; //$NON-NLS-1$
-
-	/**
-	 * Corresponds to the 'substitutionHeadName' element of the XmlElementDecl annotation.
-	 * Set to null to remove the element.
-	 */
-	void setSubstitutionHeadName(String substitutionHeadName);
-
-	/**
-	 * Return the {@link TextRange} for the 'substitutionHeadName' element. If the element 
-	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
-	 */
-	TextRange getSubstitutionHeadNameTextRange(CompilationUnit astRoot);
-
+	String SUBSTITUTION_HEAD_NAMESPACE_PROPERTY = "substitutionHeadNamespace"; //$NON-NLS-1$
+	
 	/**
 	 * Corresponds to the 'substitutionHeadNamespace' element of the XmlElementDecl annotation.
 	 * Return null if the element does not exist in Java.
 	 */
 	String getSubstitutionHeadNamespace();
-		String SUBSTITUTION_HEAD_NAMESPACE_PROPERTY = "substitutionHeadNamespace"; //$NON-NLS-1$
-
+	
 	/**
 	 * Corresponds to the 'substitutionHeadNamespace' element of the XmlElementDecl annotation.
 	 * Set to null to remove the element.
 	 */
 	void setSubstitutionHeadNamespace(String substitutionHeadNamespace);
-
+	
 	/**
 	 * Return the {@link TextRange} for the 'substitutionHeadNamespace' element. If the element 
 	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
 	 */
 	TextRange getSubstitutionHeadNamespaceTextRange(CompilationUnit astRoot);
-
+	
+	/**
+	 * Return whether the specified position touches the 'substitutionHeadNamespace' element.
+	 * Return false if the element does not exist.
+	 */
+	boolean substitutionHeadNamespaceTouches(int pos, CompilationUnit astRoot);
+	
+	
+	// ***** substitution head name *****
+	
+	/**
+	 * String associated with "substitutionHeadName" property changes.
+	 */
+	String SUBSTITUTION_HEAD_NAME_PROPERTY = "substitutionHeadName"; //$NON-NLS-1$
+	
+	/**
+	 * Corresponds to the 'substitutionHeadName' element of the XmlElementDecl annotation.
+	 * Return null if the element does not exist in Java.
+	 */
+	String getSubstitutionHeadName();
+	
+	/**
+	 * Corresponds to the 'substitutionHeadName' element of the XmlElementDecl annotation.
+	 * Set to null to remove the element.
+	 */
+	void setSubstitutionHeadName(String substitutionHeadName);
+	
+	/**
+	 * Return the {@link TextRange} for the 'substitutionHeadName' element. If the element 
+	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
+	 */
+	TextRange getSubstitutionHeadNameTextRange(CompilationUnit astRoot);
+	
+	/**
+	 * Return whether the specified position touches the 'substitutionHeadName' element.
+	 * Return false if the element does not exist.
+	 */
+	boolean substitutionHeadNameTouches(int pos, CompilationUnit astRoot);
+	
+	
+	// ***** default value *****
+	
+	/**
+	 * String associated with "defaultValue" property changes.
+	 */
+	String DEFAULT_VALUE_PROPERTY = "defaultValue"; //$NON-NLS-1$
+	
+	/**
+	 * Corresponds to the 'defaultValue' element of the XmlElementDecl annotation.
+	 * Return null if the element does not exist in Java.
+	 */
+	String getDefaultValue();
+	
+	/**
+	 * Corresponds to the 'defaultValue' element of the XmlElementDecl annotation.
+	 * Set to null to remove the element.
+	 */
+	void setDefaultValue(String defaultValue);
+	
+	/**
+	 * Return the {@link TextRange} for the 'defaultValue' element. If the element 
+	 * does not exist return the {@link TextRange} for the XmlElementDecl annotation.
+	 */
+	TextRange getDefaultValueTextRange(CompilationUnit astRoot);
 }
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XSDNodeVisitor.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XSDNodeVisitor.java
index 77cce31..81c7a42 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XSDNodeVisitor.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XSDNodeVisitor.java
@@ -29,6 +29,10 @@
 	
 	protected boolean visitChildren = true;
 	
+	protected boolean visitChildren() {
+		return this.visitChildren;
+	}
+	
 	public void visitNode(XSDComponent node) {
 		if (node != null && ! visitedNodeStack.contains(node)) {
 			visitedNodeStack.push(node);
@@ -95,7 +99,7 @@
 	public void visitXSDAttributeDeclaration(XSDAttributeDeclaration node) {}
 	
 	public void visitXSDAttributeGroupDefinition(XSDAttributeGroupDefinition node) {
-		if (visitChildren) {
+		if (visitChildren()) {
 			for (XSDAttributeUse attrUse : node.getAttributeUses()) {
 				visitNode(attrUse);
 			}
@@ -109,7 +113,7 @@
 			visitNode(node.getBaseType());
 		}
 		
-		if (visitChildren) {
+		if (visitChildren()) {
 			for (XSDAttributeUse attrUse : node.getAttributeUses()) {
 				visitNode(attrUse);
 			}
@@ -125,7 +129,7 @@
 			visitNode(element);
 		}
 		
-		if (visitChildren) {
+		if (visitChildren()) {
 			if (node.getTypeDefinition() != null) {
 				visitNode(node.getTypeDefinition());
 			}
@@ -133,7 +137,7 @@
 	}
 	
 	public void visitXSDModelGroup(XSDModelGroup node) {
-		if (visitChildren) {
+		if (visitChildren()) {
 			for (XSDParticle particle : node.getParticles()) {
 				visitNode(particle);
 			}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdComplexTypeDefinition.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdComplexTypeDefinition.java
index f7ee575..c7f0792 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdComplexTypeDefinition.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdComplexTypeDefinition.java
@@ -67,8 +67,8 @@
 	}
 	
 	@Override
-	public XsdElementDeclaration getElement(String namespace, String name) {
-		for (XsdElementDeclaration element : getElementDeclarations(namespace)) {
+	public XsdElementDeclaration getElement(String namespace, String name, boolean recurseChildren) {
+		for (XsdElementDeclaration element : getElementDeclarations(namespace, recurseChildren)) {
 			if (element.getXSDComponent().getName().equals(name)) {
 				return element;
 			}
@@ -77,10 +77,10 @@
 	}
 	
 	@Override
-	public Iterable<String> getElementNameProposals(String namespace, Filter<String> filter) {
+	public Iterable getElementNameProposals(String namespace, Filter<String> filter, boolean recurseChildren) {
 		return StringTools.convertToJavaStringLiterals(
 				new FilteringIterable<String>(
-					new TransformationIterable<XsdElementDeclaration, String>(getElementDeclarations(namespace)) {
+					new TransformationIterable<XsdElementDeclaration, String>(getElementDeclarations(namespace, recurseChildren)) {
 						@Override
 						protected String transform(XsdElementDeclaration element) {
 							return element.getXSDComponent().getName();
@@ -89,9 +89,9 @@
 					filter));
 	}
 	
-	protected Iterable<XsdElementDeclaration> getElementDeclarations(final String namespace) {
+	protected Iterable<XsdElementDeclaration> getElementDeclarations(final String namespace, boolean recurseChildren) {
 		return new TransformationIterable<XSDElementDeclaration, XsdElementDeclaration>(
-				new FilteringIterable<XSDElementDeclaration>(getXSDElementDeclarations()) {
+				new FilteringIterable<XSDElementDeclaration>(getXSDElementDeclarations(recurseChildren)) {
 					@Override
 					protected boolean accept(XSDElementDeclaration element) {
 						return XsdUtil.namespaceEquals(element, namespace);
@@ -104,8 +104,8 @@
 		};
 	}
 	
-	protected Iterable<XSDElementDeclaration> getXSDElementDeclarations() {
-		ElementFinder elementFinder = new ElementFinder();
+	protected Iterable<XSDElementDeclaration> getXSDElementDeclarations(boolean recurseChildren) {
+		ElementFinder elementFinder = new ElementFinder(recurseChildren);
 		elementFinder.visitNode(getXSDComponent());
 		return elementFinder.getElements();
 	}
@@ -114,9 +114,21 @@
 	private class ElementFinder
 			extends XSDNodeVisitor {
 		
+		private boolean recurseChildren;
+		
 		private List<XSDElementDeclaration> elements = new ArrayList<XSDElementDeclaration>();
 		
 		
+		private ElementFinder(boolean recurseChildren) {
+			this.recurseChildren = recurseChildren;
+		}
+		
+		
+		@Override
+		protected boolean visitChildren() {
+			return super.visitChildren() || this.recurseChildren;
+		}
+		
 		@Override
 		public void visitXSDElementDeclaration(XSDElementDeclaration node) {
 			boolean cachedVisitChildren = this.visitChildren;
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSchema.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSchema.java
index 267aaed..19296ae 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSchema.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSchema.java
@@ -34,7 +34,11 @@
 	}
 	
 	public Iterable<String> getNamespaces() {
-		return new SnapshotCloneIterable(getXSDSchema().getQNamePrefixToNamespaceMap().values());
+		Iterable<String> result = new SnapshotCloneIterable(getXSDSchema().getQNamePrefixToNamespaceMap().values());
+		if (StringTools.stringIsEmpty(getXSDSchema().getTargetNamespace())) {
+			result = new CompositeIterable<String>("", result);
+		}
+		return result;
 	}
 	
 	public Iterable<XsdTypeDefinition> getAllTypeDefinitions() {
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java
index 1706871..93aafa4 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdSimpleTypeDefinition.java
@@ -35,13 +35,13 @@
 	}
 	
 	@Override
-	public XsdElementDeclaration getElement(String namespace, String name) {
+	public XsdElementDeclaration getElement(String namespace, String name, boolean recurseChildren) {
 		// simple types have no elements
 		return null;
 	}
 	
 	@Override
-	public Iterable<String> getElementNameProposals(String namespace, Filter<String> filter) {
+	public Iterable<String> getElementNameProposals(String namespace, Filter<String> filter, boolean recurseChildren) {
 		// simple types have no elements
 		return EmptyIterable.instance();
 	}
diff --git a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdTypeDefinition.java b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdTypeDefinition.java
index cddb3c4..debb3c6 100644
--- a/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdTypeDefinition.java
+++ b/jaxb/plugins/org.eclipse.jpt.jaxb.core/src/org/eclipse/jpt/jaxb/core/xsd/XsdTypeDefinition.java
@@ -29,7 +29,15 @@
 	
 	public abstract Iterable<String> getAttributeNameProposals(String namespace, Filter<String> filter);
 	
-	public abstract XsdElementDeclaration getElement(String namespace, String name);
+	public XsdElementDeclaration getElement(String namespace, String name) {
+		return getElement(namespace, name, false);
+	}
 	
-	public abstract Iterable<String> getElementNameProposals(String namespace, Filter<String> filter);
+	public abstract XsdElementDeclaration getElement(String namespace, String name, boolean recurseChildren);
+	
+	public Iterable<String> getElementNameProposals(String namespace, Filter<String> filter) {
+		return getElementNameProposals(namespace, filter, false);
+	}
+	
+	public abstract Iterable getElementNameProposals(String namespace, Filter<String> filter, boolean recurseChildren);
 }
diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaElementFactoryMethodTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaElementFactoryMethodTests.java
index 7ebd9fa..e7a7d8d 100644
--- a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaElementFactoryMethodTests.java
+++ b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaElementFactoryMethodTests.java
@@ -79,18 +79,18 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getElementName());
+		assertNull(elementFactoryMethod.getQName().getName());
 
-		elementFactoryMethod.setElementName("bar");
+		elementFactoryMethod.getQName().setSpecifiedName("bar");
 		XmlElementDeclAnnotation elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertEquals("bar", elementDeclAnnotation.getName());
-		assertEquals("bar", elementFactoryMethod.getElementName());
+		assertEquals("bar", elementFactoryMethod.getQName().getName());
 
 		 //verify the xml element decl annotation is not removed when the element name is set to null
-		elementFactoryMethod.setElementName(null);
+		elementFactoryMethod.getQName().setSpecifiedName(null);
 		elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertNull(elementDeclAnnotation.getName());
-		assertNull(elementFactoryMethod.getElementName());
+		assertNull(elementFactoryMethod.getQName().getName());
 	}
 	
 	public void testUpdateElementName() throws Exception {
@@ -103,7 +103,7 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getElementName());
+		assertNull(elementFactoryMethod.getQName().getName());
 		
 		//add a name member value pair
 		AnnotatedElement annotatedElement = this.annotatedElement(resourceMethod);
@@ -112,7 +112,7 @@
 				GenericJavaElementFactoryMethodTests.this.addXmlElementDeclMemberValuePair(declaration, JAXB.XML_ELEMENT_DECL__NAME, "foo");
 			}
 		});
-		assertEquals("foo", elementFactoryMethod.getElementName());
+		assertEquals("foo", elementFactoryMethod.getQName().getName());
 
 		annotatedElement.edit(new Member.Editor() {
 			public void edit(ModifiedDeclaration declaration) {
@@ -184,12 +184,20 @@
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
 		assertNull(elementFactoryMethod.getScope());
-
+		assertTrue(elementFactoryMethod.isGlobalScope());
+		
 		elementFactoryMethod.setScope("Bar");
 		XmlElementDeclAnnotation elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertEquals("Bar", elementDeclAnnotation.getScope());
 		assertEquals("Bar", elementFactoryMethod.getScope());
-
+		assertFalse(elementFactoryMethod.isGlobalScope());
+		
+		elementFactoryMethod.setScope(JaxbElementFactoryMethod.DEFAULT_SCOPE_CLASS_NAME);
+		elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
+		assertEquals(JaxbElementFactoryMethod.DEFAULT_SCOPE_CLASS_NAME, elementDeclAnnotation.getScope());
+		assertEquals(JaxbElementFactoryMethod.DEFAULT_SCOPE_CLASS_NAME, elementFactoryMethod.getScope());
+		assertTrue(elementFactoryMethod.isGlobalScope());
+		
 		 //verify the xml element decl annotation is not removed when the element name is set to null
 		elementFactoryMethod.setScope(null);
 		elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
@@ -208,6 +216,7 @@
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
 		assertNull(elementFactoryMethod.getScope());
+		assertTrue(elementFactoryMethod.isGlobalScope());
 		
 		//add a name member value pair
 		AnnotatedElement annotatedElement = this.annotatedElement(resourceMethod);
@@ -217,6 +226,7 @@
 			}
 		});
 		assertEquals("Foo", elementFactoryMethod.getScope());
+		assertFalse(elementFactoryMethod.isGlobalScope());
 
 		annotatedElement.edit(new Member.Editor() {
 			public void edit(ModifiedDeclaration declaration) {
@@ -235,18 +245,18 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getSubstitutionHeadName());
+		assertNull(elementFactoryMethod.getSubstitutionHeadQName().getName());
 
-		elementFactoryMethod.setSubstitutionHeadName("bar");
+		elementFactoryMethod.getSubstitutionHeadQName().setSpecifiedName("bar");
 		XmlElementDeclAnnotation elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertEquals("bar", elementDeclAnnotation.getSubstitutionHeadName());
-		assertEquals("bar", elementFactoryMethod.getSubstitutionHeadName());
+		assertEquals("bar", elementFactoryMethod.getSubstitutionHeadQName().getName());
 
 		 //verify the xml element decl annotation is not removed when the element name is set to null
-		elementFactoryMethod.setSubstitutionHeadName(null);
+		elementFactoryMethod.getSubstitutionHeadQName().setSpecifiedName(null);
 		elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertNull(elementDeclAnnotation.getSubstitutionHeadName());
-		assertNull(elementFactoryMethod.getSubstitutionHeadName());
+		assertNull(elementFactoryMethod.getSubstitutionHeadQName().getName());
 	}
 	
 	public void testUpdateSubstitutionHeadName() throws Exception {
@@ -259,7 +269,7 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getSubstitutionHeadName());
+		assertNull(elementFactoryMethod.getSubstitutionHeadQName().getName());
 		
 		//add a name member value pair
 		AnnotatedElement annotatedElement = this.annotatedElement(resourceMethod);
@@ -268,7 +278,7 @@
 				GenericJavaElementFactoryMethodTests.this.addXmlElementDeclMemberValuePair(declaration, JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAME, "foo");
 			}
 		});
-		assertEquals("foo", elementFactoryMethod.getSubstitutionHeadName());
+		assertEquals("foo", elementFactoryMethod.getSubstitutionHeadQName().getName());
 
 		annotatedElement.edit(new Member.Editor() {
 			public void edit(ModifiedDeclaration declaration) {
@@ -287,18 +297,18 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getSubstitutionHeadNamespace());
+		assertEquals("", elementFactoryMethod.getSubstitutionHeadQName().getNamespace());
 
-		elementFactoryMethod.setSubstitutionHeadNamespace("bar");
+		elementFactoryMethod.getSubstitutionHeadQName().setSpecifiedNamespace("bar");
 		XmlElementDeclAnnotation elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertEquals("bar", elementDeclAnnotation.getSubstitutionHeadNamespace());
-		assertEquals("bar", elementFactoryMethod.getSubstitutionHeadNamespace());
+		assertEquals("bar", elementFactoryMethod.getSubstitutionHeadQName().getNamespace());
 
 		 //verify the xml element decl annotation is not removed when the element name is set to null
-		elementFactoryMethod.setSubstitutionHeadNamespace(null);
+		elementFactoryMethod.getSubstitutionHeadQName().setSpecifiedNamespace(null);
 		elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertNull(elementDeclAnnotation.getSubstitutionHeadNamespace());
-		assertNull(elementFactoryMethod.getSubstitutionHeadNamespace());
+		assertEquals("", elementFactoryMethod.getSubstitutionHeadQName().getNamespace());
 	}
 	
 	public void testUpdateSubstitutionHeadNamespace() throws Exception {
@@ -311,7 +321,7 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getSubstitutionHeadNamespace());
+		assertEquals("", elementFactoryMethod.getSubstitutionHeadQName().getNamespace());
 		
 		//add a name member value pair
 		AnnotatedElement annotatedElement = this.annotatedElement(resourceMethod);
@@ -320,7 +330,7 @@
 				GenericJavaElementFactoryMethodTests.this.addXmlElementDeclMemberValuePair(declaration, JAXB.XML_ELEMENT_DECL__SUBSTITUTION_HEAD_NAMESPACE, "foo");
 			}
 		});
-		assertEquals("foo", elementFactoryMethod.getSubstitutionHeadNamespace());
+		assertEquals("foo", elementFactoryMethod.getSubstitutionHeadQName().getNamespace());
 
 		annotatedElement.edit(new Member.Editor() {
 			public void edit(ModifiedDeclaration declaration) {
@@ -339,18 +349,18 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getNamespace());
+		assertEquals("", elementFactoryMethod.getQName().getNamespace());
 
-		elementFactoryMethod.setNamespace("bar");
+		elementFactoryMethod.getQName().setSpecifiedNamespace("bar");
 		XmlElementDeclAnnotation elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertEquals("bar", elementDeclAnnotation.getNamespace());
-		assertEquals("bar", elementFactoryMethod.getNamespace());
+		assertEquals("bar", elementFactoryMethod.getQName().getNamespace());
 
 		 //verify the xml element decl annotation is not removed when the element name is set to null
-		elementFactoryMethod.setNamespace(null);
+		elementFactoryMethod.getQName().setSpecifiedNamespace(null);
 		elementDeclAnnotation = (XmlElementDeclAnnotation) resourceMethod.getAnnotation(JAXB.XML_ELEMENT_DECL);
 		assertNull(elementDeclAnnotation.getNamespace());
-		assertNull(elementFactoryMethod.getNamespace());
+		assertEquals("", elementFactoryMethod.getQName().getNamespace());
 	}
 	
 	public void testUpdateNamespace() throws Exception {
@@ -363,7 +373,7 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		JavaResourceMethod resourceMethod = elementFactoryMethod.getResourceMethod();
-		assertNull(elementFactoryMethod.getNamespace());
+		assertEquals("", elementFactoryMethod.getQName().getNamespace());
 		
 		//add a name member value pair
 		AnnotatedElement annotatedElement = this.annotatedElement(resourceMethod);
@@ -372,7 +382,7 @@
 				GenericJavaElementFactoryMethodTests.this.addXmlElementDeclMemberValuePair(declaration, JAXB.XML_ELEMENT_DECL__NAMESPACE, "foo");
 			}
 		});
-		assertEquals("foo", elementFactoryMethod.getNamespace());
+		assertEquals("foo", elementFactoryMethod.getQName().getNamespace());
 
 		annotatedElement.edit(new Member.Editor() {
 			public void edit(ModifiedDeclaration declaration) {
diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaRegistryTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaRegistryTests.java
index 5ff255d..2271abc 100644
--- a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaRegistryTests.java
+++ b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaRegistryTests.java
@@ -136,10 +136,10 @@
 		Iterator<JaxbElementFactoryMethod> elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		JaxbElementFactoryMethod elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createFoo", elementFactoryMethod.getName());
-		assertEquals("foo", elementFactoryMethod.getElementName());
+		assertEquals("foo", elementFactoryMethod.getQName().getName());
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createBar", elementFactoryMethod.getName());
-		assertEquals("bar", elementFactoryMethod.getElementName());
+		assertEquals("bar", elementFactoryMethod.getQName().getName());
 		assertFalse(elementFactoryMethods.hasNext());
 
 		
@@ -154,16 +154,16 @@
 		elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createFoo", elementFactoryMethod.getName());
-		assertEquals("foo", elementFactoryMethod.getElementName());
+		assertEquals("foo", elementFactoryMethod.getQName().getName());
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createBar", elementFactoryMethod.getName());
-		assertEquals("bar", elementFactoryMethod.getElementName());
+		assertEquals("bar", elementFactoryMethod.getQName().getName());
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createFoo2", elementFactoryMethod.getName());
-		assertEquals(null, elementFactoryMethod.getElementName());
+		assertEquals(null, elementFactoryMethod.getQName().getName());
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createBar2", elementFactoryMethod.getName());
-		assertEquals(null, elementFactoryMethod.getElementName());
+		assertEquals(null, elementFactoryMethod.getQName().getName());
 		assertFalse(elementFactoryMethods.hasNext());
 
 
@@ -176,13 +176,13 @@
 		elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createBar", elementFactoryMethod.getName());
-		assertEquals("bar", elementFactoryMethod.getElementName());
+		assertEquals("bar", elementFactoryMethod.getQName().getName());
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createFoo2", elementFactoryMethod.getName());
-		assertEquals(null, elementFactoryMethod.getElementName());
+		assertEquals(null, elementFactoryMethod.getQName().getName());
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createBar2", elementFactoryMethod.getName());
-		assertEquals(null, elementFactoryMethod.getElementName());
+		assertEquals(null, elementFactoryMethod.getQName().getName());
 		assertFalse(elementFactoryMethods.hasNext());
 
 		annotatedElement.edit(new Member.Editor() {
@@ -195,7 +195,7 @@
 		elementFactoryMethods = contextRegistry.getElementFactoryMethods().iterator();
 		elementFactoryMethod = elementFactoryMethods.next();
 		assertEquals("createBar", elementFactoryMethod.getName());
-		assertEquals("bar", elementFactoryMethod.getElementName());
+		assertEquals("bar", elementFactoryMethod.getQName().getName());
 		assertFalse(elementFactoryMethods.hasNext());
 
 		annotatedElement.edit(new Member.Editor() {
diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlAnyElementMappingTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlAnyElementMappingTests.java
index cc6a42c..40e77a4 100644
--- a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlAnyElementMappingTests.java
+++ b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlAnyElementMappingTests.java
@@ -26,8 +26,11 @@
 import org.eclipse.jpt.jaxb.core.context.XmlAnyElementMapping;
 import org.eclipse.jpt.jaxb.core.context.XmlAttributeMapping;
 import org.eclipse.jpt.jaxb.core.context.XmlElementMapping;
+import org.eclipse.jpt.jaxb.core.context.XmlElementRef;
 import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlAnyElementAnnotation;
+import org.eclipse.jpt.jaxb.core.resource.java.XmlElementRefAnnotation;
+import org.eclipse.jpt.jaxb.core.resource.java.XmlElementRefsAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlJavaTypeAdapterAnnotation;
 import org.eclipse.jpt.jaxb.core.resource.java.XmlMixedAnnotation;
 import org.eclipse.jpt.jaxb.core.tests.internal.context.JaxbContextModelTestCase;
@@ -260,6 +263,10 @@
 		assertNull(xmlAnyElementMapping.getSpecifiedValue());
 	}
 
+	protected Annotation getXmlAnyElementAnnotation(ModifiedDeclaration declaration) {
+		return declaration.getAnnotationNamed(JAXB.XML_ANY_ELEMENT);
+	}
+	
 	protected void addXmlAnyElementMemberValuePair(ModifiedDeclaration declaration, String name, boolean value) {
 		this.addMemberValuePair((MarkerAnnotation) this.getXmlAnyElementAnnotation(declaration), name, value);
 	}
@@ -270,9 +277,181 @@
 			name, 
 			this.newTypeLiteral(declaration.getAst(), typeName));
 	}
+	
+	
+	// ***** XmlElementRefs *****
+	
+	public void testSyncXmlElementRefs() throws Exception {
+		createTypeWithXmlAnyElement();
+		JaxbPersistentClass persistentClass = CollectionTools.get(getContextRoot().getPersistentClasses(), 0);
+		XmlAnyElementMapping mapping = (XmlAnyElementMapping) CollectionTools.get(persistentClass.getAttributes(), 0).getMapping();
+		JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+		
+		Iterable<XmlElementRef> xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
+		assertTrue(CollectionTools.isEmpty(xmlElementRefs));
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		
+		//add XmlElementRef annotation
+		AnnotatedElement annotatedElement = annotatedElement(resourceAttribute);
+		annotatedElement.edit(
+				new Member.Editor() {
+					public void edit(ModifiedDeclaration declaration) {
+						GenericJavaXmlAnyElementMappingTests.this.addMemberValuePair(
+								GenericJavaXmlAnyElementMappingTests.this.addMarkerAnnotation(declaration.getDeclaration(), JAXB.XML_ELEMENT_REF),
+								JAXB.XML_ELEMENT_REF__NAME, "foo");
+					}
+				});
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
+		
+		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(1, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("foo", CollectionTools.get(xmlElementRefs, 0).getQName().getName());
+		
+		// add XmlElementRefs annotation with nested annotation
+		annotatedElement.edit(
+				new Member.Editor() {
+					public void edit(ModifiedDeclaration declaration) {
+						GenericJavaXmlAnyElementMappingTests.this.addMarkerAnnotation(
+								declaration.getDeclaration(), JAXB.XML_ELEMENT_REFS);
+						NormalAnnotation annotation = 
+								GenericJavaXmlAnyElementMappingTests.this.newNormalAnnotation(declaration.getAst(), JAXB.XML_ELEMENT_REF);
+						GenericJavaXmlAnyElementMappingTests.this.addMemberValuePair(
+								annotation, JAXB.XML_ELEMENT_REF__NAME, "bar");
+						GenericJavaXmlAnyElementMappingTests.this.addArrayElement(
+								declaration, JAXB.XML_ELEMENT_REFS, 0, JAXB.XML_ELEMENT_REFS__VALUE, annotation);		
+					}
+				});
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
+		
+		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(1, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("bar", CollectionTools.get(xmlElementRefs, 0).getQName().getName());
+				
+		// add second nested XmlElementRef annotation
+		annotatedElement.edit(
+				new Member.Editor() {
+					public void edit(ModifiedDeclaration declaration) {
+						NormalAnnotation annotation = 
+								GenericJavaXmlAnyElementMappingTests.this.newNormalAnnotation(declaration.getAst(), JAXB.XML_ELEMENT_REF);
+						GenericJavaXmlAnyElementMappingTests.this.addMemberValuePair(
+								annotation, JAXB.XML_ELEMENT_REF__NAME, "baz");
+						GenericJavaXmlAnyElementMappingTests.this.addArrayElement(
+								declaration, JAXB.XML_ELEMENT_REFS, 1, JAXB.XML_ELEMENT_REFS__VALUE, annotation);		
+					}
+				});
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
+		
+		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(2, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("bar", CollectionTools.get(xmlElementRefs, 0).getQName().getName());
+		assertEquals("baz", CollectionTools.get(xmlElementRefs, 1).getQName().getName());
+		
+		// switch nested XmlElementRef annotations
+		annotatedElement.edit(
+				new Member.Editor() {
+					public void edit(ModifiedDeclaration declaration) {
+						GenericJavaXmlAnyElementMappingTests.this.moveArrayElement(
+								(NormalAnnotation) declaration.getAnnotationNamed(JAXB.XML_ELEMENT_REFS), 
+								JAXB.XML_ELEMENT_REFS__VALUE, 0, 1);
+					}
+				});
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
+		
+		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(2, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("baz", CollectionTools.get(xmlElementRefs, 0).getQName().getName());
+		assertEquals("bar", CollectionTools.get(xmlElementRefs, 1).getQName().getName());
+		
+		// remove XmlElementRefs annotation
+		annotatedElement.edit(
+				new Member.Editor() {
+					public void edit(ModifiedDeclaration declaration) {
+						GenericJavaXmlAnyElementMappingTests.this.removeArrayElement(
+								(NormalAnnotation) declaration.getAnnotationNamed(JAXB.XML_ELEMENT_REFS), 
+								JAXB.XML_ELEMENT_REFS__VALUE, 1);
+						GenericJavaXmlAnyElementMappingTests.this.removeArrayElement(
+								(NormalAnnotation) declaration.getAnnotationNamed(JAXB.XML_ELEMENT_REFS), 
+								JAXB.XML_ELEMENT_REFS__VALUE, 0);
+						GenericJavaXmlAnyElementMappingTests.this.removeAnnotation(
+								declaration, JAXB.XML_ELEMENT_REFS);
+					}
+				});
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
+		
+		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(1, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("foo", CollectionTools.get(xmlElementRefs, 0).getQName().getName());
+		
+		// remove XmlElementRef annotation
+		annotatedElement.edit(
+				new Member.Editor() {
+					public void edit(ModifiedDeclaration declaration) {
+						GenericJavaXmlAnyElementMappingTests.this.removeAnnotation(
+								declaration, JAXB.XML_ELEMENT_REF);
+					}
+				});
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
+		
+		assertTrue(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
+	}
 
-	protected Annotation getXmlAnyElementAnnotation(ModifiedDeclaration declaration) {
-		return declaration.getAnnotationNamed(JAXB.XML_ANY_ELEMENT);
+	public void testModifyXmlElementRefs() throws Exception {
+		createTypeWithXmlAnyElement();
+		JaxbPersistentClass persistentClass = CollectionTools.get(getContextRoot().getPersistentClasses(), 0);
+		XmlAnyElementMapping mapping = (XmlAnyElementMapping) CollectionTools.get(persistentClass.getAttributes(), 0).getMapping();
+		JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
+		XmlElementRefsAnnotation xmlElementRefsAnnotation;
+		XmlElementRefAnnotation xmlElementRefAnnotation;
+		
+		assertNull(resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REFS));
+		assertNull(resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REF));
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		
+		mapping.getXmlElementRefs().addXmlElementRef(0).getQName().setSpecifiedName("foo");
+		xmlElementRefsAnnotation = (XmlElementRefsAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REFS);
+		xmlElementRefAnnotation = (XmlElementRefAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REF);
+		
+		assertNull(xmlElementRefsAnnotation);
+		assertNotNull(xmlElementRefAnnotation);
+		assertEquals("foo", xmlElementRefAnnotation.getName());
+		
+		mapping.getXmlElementRefs().addXmlElementRef(1).getQName().setSpecifiedName("bar");
+		xmlElementRefsAnnotation = (XmlElementRefsAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REFS);
+		xmlElementRefAnnotation = (XmlElementRefAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REF);
+		
+		assertNotNull(xmlElementRefsAnnotation);
+		assertNull(xmlElementRefAnnotation);
+		assertEquals(2, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("foo", CollectionTools.get(xmlElementRefsAnnotation.getXmlElementRefs(), 0).getName());
+		assertEquals("bar", CollectionTools.get(xmlElementRefsAnnotation.getXmlElementRefs(), 1).getName());
+		
+		mapping.getXmlElementRefs().moveXmlElementRef(0, 1);
+		xmlElementRefsAnnotation = (XmlElementRefsAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REFS);
+		xmlElementRefAnnotation = (XmlElementRefAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REF);
+		
+		assertNotNull(xmlElementRefsAnnotation);
+		assertNull(xmlElementRefAnnotation);
+		assertEquals(2, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("bar", CollectionTools.get(xmlElementRefsAnnotation.getXmlElementRefs(), 0).getName());
+		assertEquals("foo", CollectionTools.get(xmlElementRefsAnnotation.getXmlElementRefs(), 1).getName());
+		
+		mapping.getXmlElementRefs().removeXmlElementRef(0);
+		xmlElementRefsAnnotation = (XmlElementRefsAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REFS);
+		xmlElementRefAnnotation = (XmlElementRefAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REF);
+		
+		assertNull(xmlElementRefsAnnotation);
+		assertNotNull(xmlElementRefAnnotation);
+		assertEquals(1, mapping.getXmlElementRefs().getXmlElementRefsSize());
+		assertEquals("foo", xmlElementRefAnnotation.getName());
+		
+		mapping.getXmlElementRefs().removeXmlElementRef(0);
+		xmlElementRefsAnnotation = (XmlElementRefsAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REFS);
+		xmlElementRefAnnotation = (XmlElementRefAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REF);
+		
+		assertNull(resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REFS));
+		assertNull(resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_REF));
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
 	}
 
 	public void testModifyXmlMixed() throws Exception {
diff --git a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlElementRefsMappingTests.java b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlElementRefsMappingTests.java
index 0ef0b29..f1b12e6 100644
--- a/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlElementRefsMappingTests.java
+++ b/jaxb/tests/org.eclipse.jpt.jaxb.core.tests/src/org/eclipse/jpt/jaxb/core/tests/internal/context/java/GenericJavaXmlElementRefsMappingTests.java
@@ -84,7 +84,7 @@
 	}
 	
 	
-	// ***** XmlElements *****
+	// ***** XmlElementRefs *****
 	
 	protected NormalAnnotation newXmlElementRefAnnotation(AST ast, String name) {
 		NormalAnnotation annotation = newNormalAnnotation(ast, JAXB.XML_ELEMENT_REF);
@@ -111,9 +111,9 @@
 		XmlElementRefsMapping mapping = (XmlElementRefsMapping) CollectionTools.get(persistentClass.getAttributes(), 0).getMapping();
 		JavaResourceAttribute resourceAttribute = mapping.getPersistentAttribute().getJavaResourceAttribute();
 		
-		Iterable<XmlElementRef> xmlElementRefs = mapping.getXmlElementRefs();
+		Iterable<XmlElementRef> xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
 		assertTrue(CollectionTools.isEmpty(xmlElementRefs));
-		assertEquals(0, mapping.getXmlElementRefsSize());
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
 		
 		//add 2 XmlElementRef annotations
 		AnnotatedElement annotatedElement = annotatedElement(resourceAttribute);
@@ -126,10 +126,10 @@
 					}
 				});
 		
-		xmlElementRefs = mapping.getXmlElementRefs();
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
 		
-		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs()));
-		assertEquals(2, mapping.getXmlElementRefsSize());
+		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(2, mapping.getXmlElementRefs().getXmlElementRefsSize());
 		assertEquals("foo", CollectionTools.get(xmlElementRefs, 0).getQName().getName());
 		assertEquals("bar", CollectionTools.get(xmlElementRefs, 1).getQName().getName());
 		
@@ -142,10 +142,10 @@
 					}
 				});
 		
-		xmlElementRefs = mapping.getXmlElementRefs();
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
 		
-		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs()));
-		assertEquals(2, mapping.getXmlElementRefsSize());
+		assertFalse(CollectionTools.isEmpty(mapping.getXmlElementRefs().getXmlElementRefs()));
+		assertEquals(2, mapping.getXmlElementRefs().getXmlElementRefsSize());
 		assertEquals("bar", CollectionTools.get(xmlElementRefs, 0).getQName().getName());
 		assertEquals("foo", CollectionTools.get(xmlElementRefs, 1).getQName().getName());
 		
@@ -159,10 +159,10 @@
 					}
 				});
 		
-		xmlElementRefs = mapping.getXmlElementRefs();
+		xmlElementRefs = mapping.getXmlElementRefs().getXmlElementRefs();
 		
 		assertTrue(CollectionTools.isEmpty(xmlElementRefs));
-		assertEquals(0, mapping.getXmlElementRefsSize());
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
 	}
 
 	public void testModifyXmlElementRefs() throws Exception {
@@ -175,36 +175,36 @@
 		Iterable<XmlElementRefAnnotation> annotations = annotation.getXmlElementRefs();
 		
 		assertEquals(0, annotation.getXmlElementRefsSize());
-		assertEquals(0, mapping.getXmlElementRefsSize());
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
 		
-		mapping.addXmlElementRef(0).getQName().setSpecifiedName("foo");
-		mapping.addXmlElementRef(1).getQName().setSpecifiedName("baz");
-		mapping.addXmlElementRef(1).getQName().setSpecifiedName("bar");
+		mapping.getXmlElementRefs().addXmlElementRef(0).getQName().setSpecifiedName("foo");
+		mapping.getXmlElementRefs().addXmlElementRef(1).getQName().setSpecifiedName("baz");
+		mapping.getXmlElementRefs().addXmlElementRef(1).getQName().setSpecifiedName("bar");
 		
 		annotations = annotation.getXmlElementRefs();
 		
 		assertEquals(3, annotation.getXmlElementRefsSize());
-		assertEquals(3, mapping.getXmlElementRefsSize());
+		assertEquals(3, mapping.getXmlElementRefs().getXmlElementRefsSize());
 		assertEquals("foo", CollectionTools.get(annotations, 0).getName());
 		assertEquals("bar", CollectionTools.get(annotations, 1).getName());
 		assertEquals("baz", CollectionTools.get(annotations, 2).getName());
 		
-		mapping.moveXmlElementRef(1, 2);
+		mapping.getXmlElementRefs().moveXmlElementRef(1, 2);
 		
 		annotations = annotation.getXmlElementRefs();
 		
 		assertEquals(3, annotation.getXmlElementRefsSize());
-		assertEquals(3, mapping.getXmlElementRefsSize());
+		assertEquals(3, mapping.getXmlElementRefs().getXmlElementRefsSize());
 		assertEquals("foo", CollectionTools.get(annotations, 0).getName());
 		assertEquals("baz", CollectionTools.get(annotations, 1).getName());
 		assertEquals("bar", CollectionTools.get(annotations, 2).getName());
 		
-		mapping.removeXmlElementRef(2);
-		mapping.removeXmlElementRef(0);
-		mapping.removeXmlElementRef(0);
+		mapping.getXmlElementRefs().removeXmlElementRef(2);
+		mapping.getXmlElementRefs().removeXmlElementRef(0);
+		mapping.getXmlElementRefs().removeXmlElementRef(0);
 		
 		assertEquals(0, annotation.getXmlElementRefsSize());
-		assertEquals(0, mapping.getXmlElementRefsSize());
+		assertEquals(0, mapping.getXmlElementRefs().getXmlElementRefsSize());
 	}
 
 	public void testChangeMappingType() throws Exception {
@@ -310,7 +310,7 @@
 		xmlElementWrapperAnnotation = (XmlElementWrapperAnnotation) resourceAttribute.getAnnotation(JAXB.XML_ELEMENT_WRAPPER);
 	}
 	
-	public void testUpdateXmlElementRefWrapper() throws Exception {
+	public void testUpdateXmlElementWrapper() throws Exception {
 		createTypeWithXmlElementRefs();
 
 		JaxbPersistentClass persistentClass = CollectionTools.get(getContextRoot().getPersistentClasses(), 0);