From 20a705929c2acefb4c7a123735d4a5f0d342b196 Mon Sep 17 00:00:00 2001
From: jamesagnew <jamesagnew@gmail.com>
Date: Sat, 22 Feb 2014 15:33:02 -0500
Subject: [PATCH] Starting on extensions

---
 .../BaseRuntimeChildDatatypeDefinition.java   |   2 +-
 .../context/BaseRuntimeChildDefinition.java   | 186 +---------------
 .../context/BaseRuntimeElementDefinition.java |   2 +-
 .../BaseRuntimeUndeclaredChildDefinition.java | 186 ++++++++++++++++
 .../java/ca/uhn/fhir/context/FhirContext.java |   8 +-
 .../ca/uhn/fhir/context/ModelScanner.java     | 154 +++++++------
 .../context/RuntimeChildChoiceDefinition.java |   2 +-
 .../RuntimeChildResourceBlockDefinition.java  |   2 +-
 .../RuntimeChildResourceDefinition.java       |   4 +-
 ...imeChildUndeclaredExtensionDefinition.java |  98 +++++++++
 .../RuntimePrimitiveDatatypeDefinition.java   |   5 +-
 ...ePrimitiveDatatypeNarrativeDefinition.java |  14 +-
 .../RuntimeResourceReferenceDefinition.java   |   5 +-
 .../ca/uhn/fhir/model/api/BaseElement.java    |  17 +-
 .../ca/uhn/fhir/model/api/IExtension.java     |   5 +
 .../fhir/model/api/IPrimitiveDatatype.java    |   2 +-
 .../api/ISupportsUndeclaredExtensions.java    |  12 +
 .../fhir/model/api/UndeclaredExtension.java   |  24 ++
 .../fhir/model/api/annotation/Extension.java  |  22 ++
 .../model/api/annotation/ExtensionBlock.java  |   7 +
 .../ca/uhn/fhir/model/datatype/AddressDt.java |  11 +
 .../fhir/model/datatype/BaseDateTimeDt.java   |   4 +-
 .../ca/uhn/fhir/model/datatype/CodeDt.java    |   4 +-
 .../ca/uhn/fhir/model/datatype/ContactDt.java |  11 +
 .../uhn/fhir/model/datatype/HumanNameDt.java  |  11 +
 .../fhir/model/datatype/ICodedDatatype.java   |   2 +-
 .../uhn/fhir/model/datatype/NarrativeDt.java  |  11 +
 .../uhn/fhir/model/datatype/QuantityDt.java   |  11 +
 .../ca/uhn/fhir/model/datatype/XhtmlDt.java   |  76 ++++++-
 .../uhn/fhir/model/resource/Observation.java  |  11 +
 .../ca/uhn/fhir/model/resource/Patient.java   |  45 ++++
 .../java/ca/uhn/fhir/parser/ParserState.java  | 201 ++++++++++++++---
 .../java/ca/uhn/fhir/parser/XmlParser.java    | 206 +++++++++++++++---
 .../ca/uhn/fhir/parser/XmlParserTest.java     |   1 +
 .../resources/observation-example-eeg.xml     |  80 ++++---
 .../java/ca/uhn/fhir/starter/BaseParser.java  | 144 ++++++------
 .../ca/uhn/fhir/starter/ResourceParser.java   |  78 ++++---
 .../ca/uhn/fhir/starter/model/Extension.java  |  84 +++++++
 .../src/main/resources/dt_composite.vm        |   3 +
 .../src/main/resources/resource.vm            |   3 +
 .../src/main/resources/templates.vm           |  59 +++++
 41 files changed, 1333 insertions(+), 480 deletions(-)
 create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeUndeclaredChildDefinition.java
 create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildUndeclaredExtensionDefinition.java
 create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IExtension.java
 create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java
 create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/UndeclaredExtension.java
 create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/Extension.java
 create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/ExtensionBlock.java
 create mode 100644 hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/model/Extension.java

diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java
index 0ad65bf4253..c53389e6b1b 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDatatypeDefinition.java
@@ -9,7 +9,7 @@ import ca.uhn.fhir.model.api.ICodeEnum;
 import ca.uhn.fhir.model.api.IDatatype;
 import ca.uhn.fhir.model.api.IElement;
 
-public abstract class BaseRuntimeChildDatatypeDefinition extends BaseRuntimeChildDefinition {
+public abstract class BaseRuntimeChildDatatypeDefinition extends BaseRuntimeUndeclaredChildDefinition {
 
 	private Class<? extends ICodeEnum> myCodeType;
 	private Class<? extends IDatatype> myDatatype;
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDefinition.java
index 16cc8f29dd7..73b4afaaff9 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeChildDefinition.java
@@ -1,204 +1,32 @@
 package ca.uhn.fhir.context;
 
-import static org.apache.commons.lang3.StringUtils.isBlank;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import ca.uhn.fhir.model.api.IDatatype;
 import ca.uhn.fhir.model.api.IElement;
-import ca.uhn.fhir.util.BeanUtils;
 
 public abstract class BaseRuntimeChildDefinition {
 
-	private final IAccessor myAccessor;
-	private final String myElementName;
-	private final Field myField;
-	private final int myMax;
-	private final int myMin;
-	private final IMutator myMutator;
-
-	BaseRuntimeChildDefinition(Field theField, int theMin, int theMax, String theElementName) throws ConfigurationException {
-		super();
-		if (theField == null) {
-			throw new IllegalArgumentException("No field speficied");
-		}
-		if (theMin < 0) {
-			throw new ConfigurationException("Min must be >= 0");
-		}
-		if (theMax != -1 && theMax < theMin) {
-			throw new ConfigurationException("Max must be >= Min (unless it is -1 / unlimited)");
-		}
-		if (isBlank(theElementName)) {
-			throw new ConfigurationException("Element name must not be blank");
-		}
-
-		myField = theField;
-		myMin = theMin;
-		myMax = theMax;
-		myElementName = theElementName;
-
-		// TODO: handle lists (max>0), and maybe max=0?
-
-		Class<?> declaringClass = myField.getDeclaringClass();
-		final Class<?> targetReturnType = myField.getType();
-		try {
-			final Method accessor = BeanUtils.findAccessor(declaringClass, targetReturnType, myElementName);
-			final Method mutator = BeanUtils.findMutator(declaringClass, targetReturnType, myElementName);
-			
-			if (List.class.isAssignableFrom(targetReturnType)) {
-				myAccessor = new ListAccessor(accessor);
-				myMutator = new ListMutator(mutator);
-			}else {
-				myAccessor = new PlainAccessor(accessor);
-				myMutator = new PlainMutator(targetReturnType, mutator);
-			}
-		} catch (NoSuchFieldException e) {
-			throw new ConfigurationException(e);
-		}
-
-	}
-
-	public IAccessor getAccessor() {
-		return myAccessor;
-	}
+	public abstract IAccessor getAccessor();
 
 	public abstract BaseRuntimeElementDefinition<?> getChildByName(String theName);
 
-	public String getElementName() {
-		return myElementName;
-	}
-
-	public Field getField() {
-		return myField;
-	}
-
-	public int getMax() {
-		return myMax;
-	}
-
-	public int getMin() {
-		return myMin;
-	}
-
-	public IMutator getMutator() {
-		return myMutator;
-	}
-
-	public abstract Set<String> getValidChildNames();
+	public abstract BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IElement> theType);
 
 	public abstract String getChildNameByDatatype(Class<? extends IElement> theDatatype);
 
-	public abstract BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IElement> theType);
+	public abstract IMutator getMutator();
+
+	public abstract Set<String> getValidChildNames();
 
 	abstract void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions);
 
-	private final class ListMutator implements IMutator {
-		private final Method myMutator;
-
-		private ListMutator(Method theMutator) {
-			myMutator = theMutator;
-		}
-
-		@Override
-		public void addValue(Object theTarget, IElement theValue) {
-			List<IElement> existingList = myAccessor.getValues(theTarget);
-			if (existingList == null) {
-				existingList = new ArrayList<IElement>();
-				try {
-					myMutator.invoke(theTarget, existingList);
-				} catch (IllegalAccessException e) {
-					throw new ConfigurationException("Failed to get value", e);
-				} catch (IllegalArgumentException e) {
-					throw new ConfigurationException("Failed to get value", e);
-				} catch (InvocationTargetException e) {
-					throw new ConfigurationException("Failed to get value", e);
-				}
-			}
-			existingList.add(theValue);
-		}
-	}
-
-	private final class ListAccessor implements IAccessor {
-		private final Method myAccessor;
-
-		private ListAccessor(Method theAccessor) {
-			myAccessor = theAccessor;
-		}
-
-		@SuppressWarnings("unchecked")
-		@Override
-		public List<IElement> getValues(Object theTarget) {
-			try {
-				return (List<IElement>) myAccessor.invoke(theTarget);
-			} catch (IllegalAccessException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			} catch (IllegalArgumentException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			} catch (InvocationTargetException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			}
-		}
-	}
-
-	private final class PlainMutator implements IMutator {
-		private final Class<?> myTargetReturnType;
-		private final Method myMutator;
-
-		private PlainMutator(Class<?> theTargetReturnType, Method theMutator) {
-			myTargetReturnType = theTargetReturnType;
-			myMutator = theMutator;
-		}
-
-		@Override
-		public void addValue(Object theTarget, IElement theValue) {
-			try {
-				if (theValue != null && !myTargetReturnType.isAssignableFrom(theValue.getClass())) {
-					throw new ConfigurationException("Value for field " + myElementName + " expects type " + myTargetReturnType + " but got " + theValue.getClass());
-				}
-				myMutator.invoke(theTarget, theValue);
-			} catch (IllegalAccessException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			} catch (IllegalArgumentException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			} catch (InvocationTargetException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			}
-		}
-	}
-
-	private final class PlainAccessor implements IAccessor {
-		private final Method myAccessor;
-
-		private PlainAccessor(Method theAccessor) {
-			myAccessor = theAccessor;
-		}
-
-		@Override
-		public List<IElement> getValues(Object theTarget) {
-			try {
-				return Collections.singletonList((IElement)myAccessor.invoke(theTarget));
-			} catch (IllegalAccessException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			} catch (IllegalArgumentException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			} catch (InvocationTargetException e) {
-				throw new ConfigurationException("Failed to get value", e);
-			}
-		}
+	public interface IAccessor {
+		List<? extends IElement> getValues(Object theTarget);
 	}
 
 	public interface IMutator {
 		void addValue(Object theTarget, IElement theValue);
 	}
-
-	public interface IAccessor {
-		List<IElement> getValues(Object theTarget);
-	}
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java
index dc023002635..8a69c6ced86 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeElementDefinition.java
@@ -49,7 +49,7 @@ public abstract class BaseRuntimeElementDefinition<T extends IElement> {
 	public abstract ChildTypeEnum getChildType();
 	
 	public enum ChildTypeEnum {
-		COMPOSITE_DATATYPE, PRIMITIVE_DATATYPE, RESOURCE, RESOURCE_REF, RESOURCE_BLOCK, PRIMITIVE_XHTML
+		COMPOSITE_DATATYPE, PRIMITIVE_DATATYPE, RESOURCE, RESOURCE_REF, RESOURCE_BLOCK, PRIMITIVE_XHTML, UNDECL_EXT
 		
 	}
 	
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeUndeclaredChildDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeUndeclaredChildDefinition.java
new file mode 100644
index 00000000000..e01d237b52d
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/BaseRuntimeUndeclaredChildDefinition.java
@@ -0,0 +1,186 @@
+package ca.uhn.fhir.context;
+
+import static org.apache.commons.lang3.StringUtils.*;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import ca.uhn.fhir.model.api.IElement;
+import ca.uhn.fhir.util.BeanUtils;
+
+public abstract class BaseRuntimeUndeclaredChildDefinition extends BaseRuntimeChildDefinition {
+
+	private final IAccessor myAccessor;
+	private final String myElementName;
+	private final Field myField;
+	private final int myMax;
+	private final int myMin;
+	private final IMutator myMutator;
+
+	BaseRuntimeUndeclaredChildDefinition(Field theField, int theMin, int theMax, String theElementName) throws ConfigurationException {
+		super();
+		if (theField == null) {
+			throw new IllegalArgumentException("No field speficied");
+		}
+		if (theMin < 0) {
+			throw new ConfigurationException("Min must be >= 0");
+		}
+		if (theMax != -1 && theMax < theMin) {
+			throw new ConfigurationException("Max must be >= Min (unless it is -1 / unlimited)");
+		}
+		if (isBlank(theElementName)) {
+			throw new ConfigurationException("Element name must not be blank");
+		}
+
+		myField = theField;
+		myMin = theMin;
+		myMax = theMax;
+		myElementName = theElementName;
+
+		// TODO: handle lists (max>0), and maybe max=0?
+
+		Class<?> declaringClass = myField.getDeclaringClass();
+		final Class<?> targetReturnType = myField.getType();
+		try {
+			final Method accessor = BeanUtils.findAccessor(declaringClass, targetReturnType, myElementName);
+			final Method mutator = BeanUtils.findMutator(declaringClass, targetReturnType, myElementName);
+			
+			if (List.class.isAssignableFrom(targetReturnType)) {
+				myAccessor = new ListAccessor(accessor);
+				myMutator = new ListMutator(mutator);
+			}else {
+				myAccessor = new PlainAccessor(accessor);
+				myMutator = new PlainMutator(targetReturnType, mutator);
+			}
+		} catch (NoSuchFieldException e) {
+			throw new ConfigurationException(e);
+		}
+
+	}
+
+	public IAccessor getAccessor() {
+		return myAccessor;
+	}
+
+	public String getElementName() {
+		return myElementName;
+	}
+
+	public Field getField() {
+		return myField;
+	}
+
+	public int getMax() {
+		return myMax;
+	}
+
+	public int getMin() {
+		return myMin;
+	}
+
+	public IMutator getMutator() {
+		return myMutator;
+	}
+
+	private final class ListMutator implements IMutator {
+		private final Method myMutator;
+
+		private ListMutator(Method theMutator) {
+			myMutator = theMutator;
+		}
+
+		@Override
+		public void  addValue(Object theTarget, IElement theValue) {
+			@SuppressWarnings("unchecked")
+			List<IElement> existingList = (List<IElement>) myAccessor.getValues(theTarget);
+			if (existingList == null) {
+				existingList = new ArrayList<IElement>();
+				try {
+					myMutator.invoke(theTarget, existingList);
+				} catch (IllegalAccessException e) {
+					throw new ConfigurationException("Failed to get value", e);
+				} catch (IllegalArgumentException e) {
+					throw new ConfigurationException("Failed to get value", e);
+				} catch (InvocationTargetException e) {
+					throw new ConfigurationException("Failed to get value", e);
+				}
+			}
+			existingList.add(theValue);
+		}
+	}
+
+	private final class ListAccessor implements IAccessor {
+		private final Method myAccessor;
+
+		private ListAccessor(Method theAccessor) {
+			myAccessor = theAccessor;
+		}
+
+		@SuppressWarnings("unchecked")
+		@Override
+		public List<IElement> getValues(Object theTarget) {
+			try {
+				return (List<IElement>) myAccessor.invoke(theTarget);
+			} catch (IllegalAccessException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			} catch (IllegalArgumentException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			} catch (InvocationTargetException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			}
+		}
+	}
+
+	private final class PlainMutator implements IMutator {
+		private final Class<?> myTargetReturnType;
+		private final Method myMutator;
+
+		private PlainMutator(Class<?> theTargetReturnType, Method theMutator) {
+			myTargetReturnType = theTargetReturnType;
+			myMutator = theMutator;
+		}
+
+		@Override
+		public void addValue(Object theTarget, IElement theValue) {
+			try {
+				if (theValue != null && !myTargetReturnType.isAssignableFrom(theValue.getClass())) {
+					throw new ConfigurationException("Value for field " + myElementName + " expects type " + myTargetReturnType + " but got " + theValue.getClass());
+				}
+				myMutator.invoke(theTarget, theValue);
+			} catch (IllegalAccessException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			} catch (IllegalArgumentException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			} catch (InvocationTargetException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			}
+		}
+	}
+
+	private final class PlainAccessor implements IAccessor {
+		private final Method myAccessor;
+
+		private PlainAccessor(Method theAccessor) {
+			myAccessor = theAccessor;
+		}
+
+		@Override
+		public List<IElement> getValues(Object theTarget) {
+			try {
+				return Collections.singletonList((IElement)myAccessor.invoke(theTarget));
+			} catch (IllegalAccessException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			} catch (IllegalArgumentException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			} catch (InvocationTargetException e) {
+				throw new ConfigurationException("Failed to get value", e);
+			}
+		}
+	}
+
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java
index f9e71c0e084..d3ca31e6328 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java
@@ -10,11 +10,17 @@ public class FhirContext {
 
 	private final Map<String, RuntimeResourceDefinition> myNameToElementDefinition;
 	private Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> myClassToElementDefinition;
+	private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
 
 	public FhirContext(Class<? extends IResource>... theResourceTypes) {
 		ModelScanner scanner = new ModelScanner(theResourceTypes);
 		myNameToElementDefinition = Collections.unmodifiableMap(scanner.getNameToResourceDefinitions());
-		myClassToElementDefinition = scanner.getClassToElementDefinitions();
+		myClassToElementDefinition = Collections.unmodifiableMap(scanner.getClassToElementDefinitions());
+		myRuntimeChildUndeclaredExtensionDefinition = scanner.getRuntimeChildUndeclaredExtensionDefinition();
+	}
+
+	public RuntimeChildUndeclaredExtensionDefinition getRuntimeChildUndeclaredExtensionDefinition() {
+		return myRuntimeChildUndeclaredExtensionDefinition;
 	}
 
 	public Map<String, RuntimeResourceDefinition> getNameToResourceDefinition() {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java
index b7972a334b1..7829a3a0233 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java
@@ -1,6 +1,6 @@
 package ca.uhn.fhir.context;
 
-import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.apache.commons.lang3.StringUtils.*;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.ParameterizedType;
@@ -34,6 +34,8 @@ import ca.uhn.fhir.model.api.annotation.CodeTableDef;
 import ca.uhn.fhir.model.api.annotation.DatatypeDef;
 import ca.uhn.fhir.model.api.annotation.Narrative;
 import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.model.datatype.CodeDt;
+import ca.uhn.fhir.model.datatype.DateDt;
 import ca.uhn.fhir.model.datatype.ICodedDatatype;
 import ca.uhn.fhir.model.datatype.NarrativeDt;
 import ca.uhn.fhir.model.datatype.XhtmlDt;
@@ -42,22 +44,24 @@ class ModelScanner {
 	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
 
 	private Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>();
+	private Map<String, BaseRuntimeElementDefinition<?>> myDatatypeAttributeNameToDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
 	private Map<String, RuntimeResourceDefinition> myNameToResourceDefinitions = new HashMap<String, RuntimeResourceDefinition>();
 	private Set<Class<? extends IElement>> myScanAlso = new HashSet<Class<? extends IElement>>();
-	private Set<Class<? extends ICodeEnum>> myScanAlsoCodeTable = new HashSet<Class<? extends ICodeEnum>>();
 
 	// private Map<String, RuntimeResourceDefinition>
 	// myNameToDatatypeDefinitions = new HashMap<String,
 	// RuntimeDatatypeDefinition>();
 
-	public Map<String, RuntimeResourceDefinition> getNameToResourceDefinitions() {
-		return (myNameToResourceDefinitions);
-	}
+	private Set<Class<? extends ICodeEnum>> myScanAlsoCodeTable = new HashSet<Class<? extends ICodeEnum>>();
+
+	private RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
 
 	ModelScanner(Class<? extends IResource>... theResourceTypes) throws ConfigurationException {
 
 		Set<Class<? extends IElement>> toScan = new HashSet<Class<? extends IElement>>(Arrays.asList(theResourceTypes));
 		toScan.add(NarrativeDt.class);
+		toScan.add(DateDt.class);
+		toScan.add(CodeDt.class);
 
 		do {
 			for (Class<? extends IElement> nextClass : toScan) {
@@ -77,10 +81,41 @@ class ModelScanner {
 			next.sealAndInitialize(myClassToElementDefinitions);
 		}
 
+		myRuntimeChildUndeclaredExtensionDefinition = new RuntimeChildUndeclaredExtensionDefinition(myDatatypeAttributeNameToDefinition);
+		
 		ourLog.info("Done scanning FHIR library, found {} model entries", myClassToElementDefinitions.size());
 
 	}
 
+	public RuntimeChildUndeclaredExtensionDefinition getRuntimeChildUndeclaredExtensionDefinition() {
+		return myRuntimeChildUndeclaredExtensionDefinition;
+	}
+
+	public Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> getClassToElementDefinitions() {
+		return myClassToElementDefinitions;
+	}
+
+	public Map<String, RuntimeResourceDefinition> getNameToResourceDefinitions() {
+		return (myNameToResourceDefinitions);
+	}
+
+	private void addDatatype(BaseRuntimeElementDefinition<?> theResourceDef) {
+		String attrName = theResourceDef.getName();
+		attrName = "value" + attrName.substring(0, 1).toUpperCase() + attrName.substring(1);
+		myDatatypeAttributeNameToDefinition.put(attrName, theResourceDef);
+	}
+
+	private void addScanAlso(Class<? extends IElement> theType) {
+		if (theType.isInterface()) {
+			return;
+		}
+		myScanAlso.add(theType);
+	}
+
+	public Map<String, BaseRuntimeElementDefinition<?>> getDatatypeAttributeNameToDefinition() {
+		return myDatatypeAttributeNameToDefinition;
+	}
+
 	private void scan(Class<? extends IElement> theClass) throws ConfigurationException {
 		BaseRuntimeElementDefinition<?> existingDef = myClassToElementDefinitions.get(theClass);
 		if (existingDef != null) {
@@ -153,6 +188,10 @@ class ModelScanner {
 		scanCompositeElementForChildren(theClass, resourceDef, null);
 	}
 
+	private String scanCodeTable(Class<? extends ICodeEnum> theCodeType, CodeTableDef theCodeTableDefinition) {
+		return null; // TODO: implement
+	}
+
 	private void scanCompositeDatatype(Class<? extends ICompositeDatatype> theClass, DatatypeDef theDatatypeDefinition) {
 		ourLog.debug("Scanning resource class: {}", theClass.getName());
 
@@ -163,57 +202,15 @@ class ModelScanner {
 
 		RuntimeCompositeDatatypeDefinition resourceDef = new RuntimeCompositeDatatypeDefinition(resourceName, theClass);
 		myClassToElementDefinitions.put(theClass, resourceDef);
+		addDatatype(resourceDef);
 
 		scanCompositeElementForChildren(theClass, resourceDef, null);
 	}
 
-	private String scanPrimitiveDatatype(Class<? extends IPrimitiveDatatype<?>> theClass, DatatypeDef theDatatypeDefinition) {
-		ourLog.debug("Scanning resource class: {}", theClass.getName());
-
-		String resourceName = theDatatypeDefinition.name();
-		if (isBlank(resourceName)) {
-			throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name: " + theClass.getCanonicalName());
-		}
-
-		RuntimePrimitiveDatatypeDefinition resourceDef;
-		if (theClass.equals(XhtmlDt.class)) {
-			resourceDef = new RuntimePrimitiveDatatypeNarrativeDefinition(resourceName, theClass);
-		} else {
-			resourceDef = new RuntimePrimitiveDatatypeDefinition(resourceName, theClass);
-		}
-		myClassToElementDefinitions.put(theClass, resourceDef);
-
-		return resourceName;
-	}
-
-	private String scanResource(Class<? extends IResource> theClass, ResourceDef resourceDefinition) {
-		ourLog.debug("Scanning resource class: {}", theClass.getName());
-
-		String resourceName = resourceDefinition.name();
-		if (isBlank(resourceName)) {
-			throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name: " + theClass.getCanonicalName());
-		}
-
-		if (myNameToResourceDefinitions.containsKey(resourceName)) {
-			if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
-				throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '" + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
-			}
-			return resourceName;
-		}
-
-		RuntimeResourceDefinition resourceDef = new RuntimeResourceDefinition(theClass, resourceName);
-		myClassToElementDefinitions.put(theClass, resourceDef);
-		myNameToResourceDefinitions.put(resourceName, resourceDef);
-
-		scanCompositeElementForChildren(theClass, resourceDef, resourceDefinition.identifierOrder());
-
-		return resourceName;
-	}
-
 	@SuppressWarnings("unchecked")
 	private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Integer theIdentifierOrder) {
 		Set<String> elementNames = new HashSet<String>();
-		TreeMap<Integer, BaseRuntimeChildDefinition> orderToElementDef = new TreeMap<Integer, BaseRuntimeChildDefinition>();
+		TreeMap<Integer, BaseRuntimeUndeclaredChildDefinition> orderToElementDef = new TreeMap<Integer, BaseRuntimeUndeclaredChildDefinition>();
 
 		LinkedList<Class<? extends ICompositeElement>> classes = new LinkedList<Class<? extends ICompositeElement>>();
 		Class<? extends ICompositeElement> current = theClass;
@@ -231,7 +228,7 @@ class ModelScanner {
 		}
 
 		while (orderToElementDef.size() > 0 && orderToElementDef.firstKey() < 0) {
-			BaseRuntimeChildDefinition elementDef = orderToElementDef.remove(orderToElementDef.firstKey());
+			BaseRuntimeUndeclaredChildDefinition elementDef = orderToElementDef.remove(orderToElementDef.firstKey());
 			if (elementDef.getElementName().equals("identifier")) {
 				orderToElementDef.put(theIdentifierOrder, elementDef);
 			} else {
@@ -250,7 +247,7 @@ class ModelScanner {
 	}
 
 	@SuppressWarnings("unchecked")
-	private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Set<String> elementNames, TreeMap<Integer, BaseRuntimeChildDefinition> orderToElementDef) {
+	private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Set<String> elementNames, TreeMap<Integer, BaseRuntimeUndeclaredChildDefinition> orderToElementDef) {
 		for (Field next : theClass.getDeclaredFields()) {
 
 			Narrative hasNarrative = next.getAnnotation(Narrative.class);
@@ -377,11 +374,50 @@ class ModelScanner {
 		}
 	}
 
-	private void addScanAlso(Class<? extends IElement> theType) {
-		if (theType.isInterface()) {
-			return;
+	private String scanPrimitiveDatatype(Class<? extends IPrimitiveDatatype<?>> theClass, DatatypeDef theDatatypeDefinition) {
+		ourLog.debug("Scanning resource class: {}", theClass.getName());
+
+		String resourceName = theDatatypeDefinition.name();
+		if (isBlank(resourceName)) {
+			throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name: " + theClass.getCanonicalName());
 		}
-		myScanAlso.add(theType);
+
+		BaseRuntimeElementDefinition<?> resourceDef;
+		if (theClass.equals(XhtmlDt.class)) {
+			@SuppressWarnings("unchecked")
+			Class<XhtmlDt> clazz = (Class<XhtmlDt>) theClass;
+			resourceDef = new RuntimePrimitiveDatatypeNarrativeDefinition(resourceName, clazz);
+		} else {
+			resourceDef = new RuntimePrimitiveDatatypeDefinition(resourceName, theClass);
+		}
+		myClassToElementDefinitions.put(theClass, resourceDef);
+		addDatatype(resourceDef);
+
+		return resourceName;
+	}
+
+	private String scanResource(Class<? extends IResource> theClass, ResourceDef resourceDefinition) {
+		ourLog.debug("Scanning resource class: {}", theClass.getName());
+
+		String resourceName = resourceDefinition.name();
+		if (isBlank(resourceName)) {
+			throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource name: " + theClass.getCanonicalName());
+		}
+
+		if (myNameToResourceDefinitions.containsKey(resourceName)) {
+			if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
+				throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '" + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
+			}
+			return resourceName;
+		}
+
+		RuntimeResourceDefinition resourceDef = new RuntimeResourceDefinition(theClass, resourceName);
+		myClassToElementDefinitions.put(theClass, resourceDef);
+		myNameToResourceDefinitions.put(resourceName, resourceDef);
+
+		scanCompositeElementForChildren(theClass, resourceDef, resourceDefinition.identifierOrder());
+
+		return resourceName;
 	}
 
 	private static Class<?> getGenericCollectionTypeOfField(Field next) {
@@ -398,12 +434,4 @@ class ModelScanner {
 		return type;
 	}
 
-	private String scanCodeTable(Class<? extends ICodeEnum> theCodeType, CodeTableDef theCodeTableDefinition) {
-		return null; // TODO: implement
-	}
-
-	public Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> getClassToElementDefinitions() {
-		return myClassToElementDefinitions;
-	}
-
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java
index 45e4ae77c0d..61a4212ef92 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java
@@ -10,7 +10,7 @@ import java.util.Set;
 import ca.uhn.fhir.model.api.IDatatype;
 import ca.uhn.fhir.model.api.IElement;
 
-public class RuntimeChildChoiceDefinition extends BaseRuntimeChildDefinition {
+public class RuntimeChildChoiceDefinition extends BaseRuntimeUndeclaredChildDefinition {
 
 	private List<Class<? extends IElement>> myChoiceTypes;
 	private Map<String, BaseRuntimeElementDefinition<?>> myNameToChildDefinition;
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceBlockDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceBlockDefinition.java
index a492f62296a..45895587413 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceBlockDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceBlockDefinition.java
@@ -9,7 +9,7 @@ import ca.uhn.fhir.model.api.IDatatype;
 import ca.uhn.fhir.model.api.IElement;
 import ca.uhn.fhir.model.api.IResourceBlock;
 
-public class RuntimeChildResourceBlockDefinition extends BaseRuntimeChildDefinition {
+public class RuntimeChildResourceBlockDefinition extends BaseRuntimeUndeclaredChildDefinition {
 
 	private RuntimeResourceBlockDefinition myElementDef;
 	private Class<? extends IResourceBlock> myResourceBlockType;
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceDefinition.java
index ce0a37930ec..aa7dec17dce 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildResourceDefinition.java
@@ -11,7 +11,7 @@ import ca.uhn.fhir.model.api.IElement;
 import ca.uhn.fhir.model.api.IResource;
 import ca.uhn.fhir.model.api.ResourceReference;
 
-public class RuntimeChildResourceDefinition extends BaseRuntimeChildDefinition {
+public class RuntimeChildResourceDefinition extends BaseRuntimeUndeclaredChildDefinition {
 
 	private BaseRuntimeElementDefinition<?> myRuntimeDef;
 	private List<Class<? extends IResource>> myResourceTypes;
@@ -49,6 +49,6 @@ public class RuntimeChildResourceDefinition extends BaseRuntimeChildDefinition {
 
 	@Override
 	void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
-		myRuntimeDef = new RuntimeResourceReferenceDefinition(getElementName(), myResourceTypes);
+		myRuntimeDef = new RuntimeResourceReferenceDefinition(getElementName());
 	}
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildUndeclaredExtensionDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildUndeclaredExtensionDefinition.java
new file mode 100644
index 00000000000..a615148aaa5
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildUndeclaredExtensionDefinition.java
@@ -0,0 +1,98 @@
+package ca.uhn.fhir.context;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import ca.uhn.fhir.model.api.IDatatype;
+import ca.uhn.fhir.model.api.IElement;
+import ca.uhn.fhir.model.api.ResourceReference;
+import ca.uhn.fhir.model.api.UndeclaredExtension;
+
+public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildDefinition {
+
+	
+	private Map<String, BaseRuntimeElementDefinition<?>> myAttributeNameToDefinition;
+	private Map<Class<? extends IElement>,String> myDatatypeToAttributeName;
+	private Map<Class<? extends IElement>,BaseRuntimeElementDefinition<?>> myDatatypeToDefinition;
+
+	public RuntimeChildUndeclaredExtensionDefinition(Map<String, BaseRuntimeElementDefinition<?>> theDatatypeAttributeNameToDefinition) {
+		myAttributeNameToDefinition=theDatatypeAttributeNameToDefinition;
+		
+		myDatatypeToAttributeName = new HashMap<Class<? extends IElement>, String>();
+		myDatatypeToDefinition = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>();
+
+		for (Entry<String, BaseRuntimeElementDefinition<?>> next : myAttributeNameToDefinition.entrySet()) {
+			@SuppressWarnings("unchecked")
+			Class<? extends IDatatype> type = (Class<? extends IDatatype>) next.getValue().getImplementingClass();
+			myDatatypeToAttributeName.put(type, next.getKey());
+			myDatatypeToDefinition.put(type, next.getValue());
+		}
+		
+		// Resource Reference
+		myDatatypeToAttributeName.put(ResourceReference.class, "valueReference");
+		RuntimeResourceReferenceDefinition def = new RuntimeResourceReferenceDefinition("valueResource");
+		myAttributeNameToDefinition.put("valueResource", def);
+		myDatatypeToDefinition.put(ResourceReference.class, def);
+		
+	}
+
+	
+	@Override
+	public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
+		return myAttributeNameToDefinition.get(theName);
+	}
+
+	@Override
+	public Set<String> getValidChildNames() {
+		return myAttributeNameToDefinition.keySet();
+	}
+
+	@Override
+	public String getChildNameByDatatype(Class<? extends IElement> theDatatype) {
+		return myDatatypeToAttributeName.get(theDatatype);
+	}
+
+	@Override
+	public BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IElement> theType) {
+		return myDatatypeToDefinition.get(theType);
+	}
+
+	@Override
+	void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
+		// nothing
+	}
+
+
+	@Override
+	public IAccessor getAccessor() {
+		return new IAccessor() {
+			@Override
+			public List<? extends IElement> getValues(Object theTarget) {
+				UndeclaredExtension target = (UndeclaredExtension)theTarget;
+				if (target.getValue() != null) {
+					return Collections.singletonList(target.getValue());
+				}
+				return target.getUndeclaredExtensions();
+			}};
+	}
+
+
+	@Override
+	public IMutator getMutator() {
+		return new IMutator() {
+			@Override
+			public void addValue(Object theTarget, IElement theValue) {
+				UndeclaredExtension target = (UndeclaredExtension)theTarget;
+				if (theValue instanceof IDatatype) {
+					target.setValue((IDatatype) theTarget);
+				}else {
+					target.getUndeclaredExtensions().add((UndeclaredExtension) theValue);
+				}
+			}};
+	}
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java
index 0e67400bfce..3801aeb525b 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java
@@ -2,13 +2,12 @@ package ca.uhn.fhir.context;
 
 import java.util.Map;
 
-import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
 import ca.uhn.fhir.model.api.IElement;
 import ca.uhn.fhir.model.api.IPrimitiveDatatype;
 
-public class RuntimePrimitiveDatatypeDefinition extends BaseRuntimeElementDefinition<IPrimitiveDatatype>{
+public class RuntimePrimitiveDatatypeDefinition extends BaseRuntimeElementDefinition<IPrimitiveDatatype<?>>{
 
-	public RuntimePrimitiveDatatypeDefinition(String theName, Class<? extends IPrimitiveDatatype> theImplementingClass) {
+	public RuntimePrimitiveDatatypeDefinition(String theName, Class<? extends IPrimitiveDatatype<?>> theImplementingClass) {
 		super(theName, theImplementingClass);
 	}
 
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeNarrativeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeNarrativeDefinition.java
index e6bbd7ffb6e..39e34fdbb20 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeNarrativeDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeNarrativeDefinition.java
@@ -1,10 +1,13 @@
 package ca.uhn.fhir.context;
 
-import ca.uhn.fhir.model.api.IPrimitiveDatatype;
+import java.util.Map;
 
-public class RuntimePrimitiveDatatypeNarrativeDefinition extends RuntimePrimitiveDatatypeDefinition {
+import ca.uhn.fhir.model.api.IElement;
+import ca.uhn.fhir.model.datatype.XhtmlDt;
 
-	public RuntimePrimitiveDatatypeNarrativeDefinition(String theName, Class<? extends IPrimitiveDatatype<?>> theImplementingClass) {
+public class RuntimePrimitiveDatatypeNarrativeDefinition  extends BaseRuntimeElementDefinition<XhtmlDt> {
+
+	public RuntimePrimitiveDatatypeNarrativeDefinition(String theName, Class<XhtmlDt> theImplementingClass) {
 		super(theName, theImplementingClass);
 	}
 
@@ -13,4 +16,9 @@ public class RuntimePrimitiveDatatypeNarrativeDefinition extends RuntimePrimitiv
 		return ChildTypeEnum.PRIMITIVE_XHTML;
 	}
 
+	@Override
+	void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
+		// nothing
+	}
+
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceReferenceDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceReferenceDefinition.java
index 081547ca214..208689e05c3 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceReferenceDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeResourceReferenceDefinition.java
@@ -1,16 +1,13 @@
 package ca.uhn.fhir.context;
 
-import java.util.List;
 import java.util.Map;
 
-import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
 import ca.uhn.fhir.model.api.IElement;
-import ca.uhn.fhir.model.api.IResource;
 import ca.uhn.fhir.model.api.ResourceReference;
 
 public class RuntimeResourceReferenceDefinition extends BaseRuntimeElementDefinition<ResourceReference> {
 
-	public RuntimeResourceReferenceDefinition(String theName, List<Class<? extends IResource>> theResourceTypes) {
+	public RuntimeResourceReferenceDefinition(String theName) {
 		super(theName, ResourceReference.class);
 	}
 
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BaseElement.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BaseElement.java
index c3a67104a00..3623be9cba3 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BaseElement.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BaseElement.java
@@ -1,5 +1,20 @@
 package ca.uhn.fhir.model.api;
 
-public abstract class BaseElement implements IElement {
+import java.util.ArrayList;
+import java.util.List;
 
+public abstract class BaseElement implements IElement, ISupportsUndeclaredExtensions {
+
+	private List<UndeclaredExtension> myUndeclaredExtensions;
+
+	@Override
+	public List<UndeclaredExtension> getUndeclaredExtensions() {
+		if (myUndeclaredExtensions==null) {
+			myUndeclaredExtensions=new ArrayList<UndeclaredExtension>();
+		}
+		return myUndeclaredExtensions;
+	}
+
+	
+	
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IExtension.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IExtension.java
new file mode 100644
index 00000000000..2573fcdcbdb
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IExtension.java
@@ -0,0 +1,5 @@
+package ca.uhn.fhir.model.api;
+
+public interface IExtension extends IElement {
+	// nothing
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IPrimitiveDatatype.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IPrimitiveDatatype.java
index a2a4dc8db4c..da040174bce 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IPrimitiveDatatype.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IPrimitiveDatatype.java
@@ -6,7 +6,7 @@ public interface IPrimitiveDatatype<T> extends IDatatype {
 
 	void setValueAsString(String theValue) throws DataFormatException;
 
-	String getValueAsString();
+	String getValueAsString() throws DataFormatException;
 
 	T getValue();
 	
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java
new file mode 100644
index 00000000000..65183d43475
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ISupportsUndeclaredExtensions.java
@@ -0,0 +1,12 @@
+package ca.uhn.fhir.model.api;
+
+import java.util.List;
+
+public interface ISupportsUndeclaredExtensions {
+	
+	/**
+	 * Returns a list containing all undeclared extensions
+	 */
+	List<UndeclaredExtension> getUndeclaredExtensions();
+	
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/UndeclaredExtension.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/UndeclaredExtension.java
new file mode 100644
index 00000000000..315c1c721bb
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/UndeclaredExtension.java
@@ -0,0 +1,24 @@
+package ca.uhn.fhir.model.api;
+
+public class UndeclaredExtension extends BaseElement {
+
+	private String myUrl;
+	private IElement myValue;
+
+	public String getUrl() {
+		return myUrl;
+	}
+
+	public IElement getValue() {
+		return myValue;
+	}
+
+	public void setUrl(String theUrl) {
+		myUrl = theUrl;
+	}
+
+	public void setValue(IElement theValue) {
+		myValue = theValue;
+	}
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/Extension.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/Extension.java
new file mode 100644
index 00000000000..bb31dd848d5
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/Extension.java
@@ -0,0 +1,22 @@
+package ca.uhn.fhir.model.api.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+import ca.uhn.fhir.model.api.IDatatype;
+
+@Target(value= {ElementType.FIELD})
+public @interface Extension {
+
+	String url();
+	
+	Class<? extends IDatatype> datatype() default NoDatatype.class;
+	
+	public static class NoDatatype implements IDatatype
+	{
+		private NoDatatype() {
+			// non-instantiable
+		}
+	}
+	
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/ExtensionBlock.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/ExtensionBlock.java
new file mode 100644
index 00000000000..1dda0872e94
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/ExtensionBlock.java
@@ -0,0 +1,7 @@
+package ca.uhn.fhir.model.api.annotation;
+
+public @interface ExtensionBlock {
+	
+	String url();
+	
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/AddressDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/AddressDt.java
index 7fcb76823e5..aa0b10d5957 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/AddressDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/AddressDt.java
@@ -1,5 +1,15 @@
 
 
+
+
+
+
+
+
+
+
+
+
 package ca.uhn.fhir.model.datatype;
 
 import java.util.*;
@@ -243,4 +253,5 @@ P.O. Box number, delivery hints, and similar address information
 	}
 	
 
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/BaseDateTimeDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/BaseDateTimeDt.java
index 05b8a37e974..58a1db13a4b 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/BaseDateTimeDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/BaseDateTimeDt.java
@@ -17,7 +17,7 @@ public abstract class BaseDateTimeDt extends BasePrimitiveDatatype<Date> {
 	private static final FastDateFormat ourYearMonthDayFormat = FastDateFormat.getInstance("yyyy-MM-dd");
 	private static final FastDateFormat ourYearMonthFormat = FastDateFormat.getInstance("yyyy-MM");
 	private static final FastDateFormat ourYearMonthDayTimeFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss");
-	private static final FastDateFormat ourYearMonthDayTimeZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssX");
+	private static final FastDateFormat ourYearMonthDayTimeZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ");
 
 	private int myPrecision = Calendar.SECOND;
 	private Date myValue;
@@ -114,7 +114,7 @@ public abstract class BaseDateTimeDt extends BasePrimitiveDatatype<Date> {
 				setValue(ourYearMonthFormat.parse(theValue));
 				setPrecision(Calendar.MONTH);
 				clearTimeZone();
-			} else if (theValue.length() == 9 && isPrecisionAllowed(Calendar.DAY_OF_MONTH)) {
+			} else if (theValue.length() == 10 && isPrecisionAllowed(Calendar.DAY_OF_MONTH)) {
 				setValue(ourYearMonthDayFormat.parse(theValue));
 				setPrecision(Calendar.DAY_OF_MONTH);
 				clearTimeZone();
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/CodeDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/CodeDt.java
index c205ba46a65..52792d6615c 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/CodeDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/CodeDt.java
@@ -1,12 +1,12 @@
 package ca.uhn.fhir.model.datatype;
 
 import ca.uhn.fhir.model.api.BasePrimitiveDatatype;
-import ca.uhn.fhir.model.api.ICodeEnum;
+import ca.uhn.fhir.model.api.IPrimitiveDatatype;
 import ca.uhn.fhir.model.api.annotation.DatatypeDef;
 import ca.uhn.fhir.parser.DataFormatException;
 
 @DatatypeDef(name = "code")
-public class CodeDt extends BasePrimitiveDatatype<String> implements ICodedDatatype {
+public class CodeDt extends BasePrimitiveDatatype<String> implements ICodedDatatype, IPrimitiveDatatype<String> {
 
 	private String myValue;
 
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ContactDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ContactDt.java
index 118a05406aa..5f3bb1981e2 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ContactDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ContactDt.java
@@ -1,5 +1,15 @@
 
 
+
+
+
+
+
+
+
+
+
+
 package ca.uhn.fhir.model.datatype;
 
 import java.util.*;
@@ -133,4 +143,5 @@ public class ContactDt extends BaseCompositeDatatype {
 	}
 	
 
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/HumanNameDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/HumanNameDt.java
index e72f24412b7..c2b2234f71e 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/HumanNameDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/HumanNameDt.java
@@ -1,5 +1,15 @@
 
 
+
+
+
+
+
+
+
+
+
+
 package ca.uhn.fhir.model.datatype;
 
 import java.util.*;
@@ -214,4 +224,5 @@ public class HumanNameDt extends BaseCompositeDatatype {
 	}
 	
 
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ICodedDatatype.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ICodedDatatype.java
index 5bedb943da3..d36a61d13de 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ICodedDatatype.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/ICodedDatatype.java
@@ -3,5 +3,5 @@ package ca.uhn.fhir.model.datatype;
 import ca.uhn.fhir.model.api.IDatatype;
 
 public interface ICodedDatatype extends IDatatype {
-
+	// nothing
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/NarrativeDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/NarrativeDt.java
index 92dbcde4388..41d53722318 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/NarrativeDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/NarrativeDt.java
@@ -1,5 +1,15 @@
 
 
+
+
+
+
+
+
+
+
+
+
 package ca.uhn.fhir.model.datatype;
 
 import java.util.*;
@@ -79,4 +89,5 @@ public class NarrativeDt extends BaseCompositeDatatype {
 	}
 	
 
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/QuantityDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/QuantityDt.java
index ac520f1d69d..f620dea1ecf 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/QuantityDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/QuantityDt.java
@@ -1,5 +1,15 @@
 
 
+
+
+
+
+
+
+
+
+
+
 package ca.uhn.fhir.model.datatype;
 
 import java.util.*;
@@ -160,4 +170,5 @@ public class QuantityDt extends BaseCompositeDatatype {
 	}
 	
 
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/XhtmlDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/XhtmlDt.java
index 9ed8d622553..6212e2ed0ce 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/XhtmlDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/datatype/XhtmlDt.java
@@ -1,32 +1,86 @@
 package ca.uhn.fhir.model.datatype;
 
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+
+import ca.uhn.fhir.context.ConfigurationException;
 import ca.uhn.fhir.model.api.IPrimitiveDatatype;
 import ca.uhn.fhir.model.api.annotation.DatatypeDef;
 import ca.uhn.fhir.parser.DataFormatException;
 
 @DatatypeDef(name = "xhtml")
-public class XhtmlDt implements IPrimitiveDatatype<String> {
+public class XhtmlDt implements IPrimitiveDatatype<List<XMLEvent>> {
 
-	private String myValue;
+	private List<XMLEvent> myValue;
 
 	@Override
 	public void setValueAsString(String theValue) throws DataFormatException {
-		myValue=theValue;
+		if (theValue == null) {
+			myValue = null;
+			return;
+		}
+		String val = "<a>" + theValue + "</a>";
+		try {
+			ArrayList<XMLEvent> value = new ArrayList<XMLEvent>();
+			XMLEventReader er = XMLInputFactory.newInstance().createXMLEventReader(new StringReader(val));
+			boolean first = true;
+			while (er.hasNext()) {
+				if (first) {
+					first = false;
+					continue;
+				}
+				XMLEvent next = er.nextEvent();
+				if (er.hasNext()) {
+					// don't add the last event
+					value.add(next);
+				}
+			}
+
+		} catch (XMLStreamException e) {
+			throw new DataFormatException("String does not appear to be valid XML/XHTML", e);
+		} catch (FactoryConfigurationError e) {
+			throw new ConfigurationException(e);
+		}
 	}
 
 	@Override
-	public String getValueAsString() {
+	public String getValueAsString() throws DataFormatException {
+		if (myValue == null) {
+			return null;
+		}
+		try {
+			StringWriter w = new StringWriter();
+			XMLEventWriter ew = XMLOutputFactory.newInstance().createXMLEventWriter(w);
+			for (XMLEvent next : myValue) {
+				ew.add(next);
+			}
+			ew.close();
+			return w.toString();
+		} catch (XMLStreamException e) {
+			throw new DataFormatException("Problem with the contained XML events", e);
+		} catch (FactoryConfigurationError e) {
+			throw new ConfigurationException(e);
+		}
+	}
+
+	@Override
+	public List<XMLEvent> getValue() {
 		return myValue;
 	}
 
 	@Override
-	public String getValue() {
-		return myValue;
-	}
-
-	@Override
-	public void setValue(String theValue) throws DataFormatException {
-		myValue=theValue;
+	public void setValue(List<XMLEvent> theValue) throws DataFormatException {
+		myValue = theValue;
 	}
 
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Observation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Observation.java
index 5a95e4b1858..3b2adb6e4d0 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Observation.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Observation.java
@@ -1,5 +1,15 @@
 
 
+
+
+
+
+
+
+
+
+
+
 package ca.uhn.fhir.model.resource;
 
 import java.util.*;
@@ -1421,4 +1431,5 @@ public class Observation extends BaseResource {
 	}
 
 
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Patient.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Patient.java
index 0868e07c52e..53c52b432c3 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Patient.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Patient.java
@@ -1,5 +1,15 @@
 
 
+
+
+
+
+
+
+
+
+
+
 package ca.uhn.fhir.model.resource;
 
 import java.util.*;
@@ -24,6 +34,10 @@ import ca.uhn.fhir.model.datatype.*;
 @ResourceDef(name="Patient")
 public class Patient extends BaseResource {
 
+	@Child()
+	private Foo1 myFoo1;
+	@Child()
+	private Bar1 myBar1;
 	@Child(name="identifier", order=0, min=0, max=Child.MAX_UNLIMITED)	
 	private List<IdentifierDt> myIdentifier;
 	
@@ -1950,4 +1964,35 @@ public class Patient extends BaseResource {
 	}
 
 
+	@ExtensionBlock(url="http://foo/1")
+	public class Foo1 implements IExtension {
+		
+		@Child(name="value", order=0)
+		private StringDt myValue;
+
+		/**
+		 * Gets the value 
+		 */
+		public StringDt getValue() {
+			return myValue;
+		}
+	
+		/**
+		 * Sets the value
+		 */
+		public void setValue(StringDt theValue) {
+			myValue = theValue;
+		}
+
+
+	}
+	
+	@ExtensionBlock(url="http://bar/1")
+	public class Bar1 implements IExtension {
+		
+
+
+	}
+	
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java
index c596ca7be66..3eac0df19c3 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java
@@ -1,11 +1,8 @@
 package ca.uhn.fhir.parser;
 
-import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
 
-import javax.xml.stream.XMLEventFactory;
-import javax.xml.stream.XMLEventWriter;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.events.Attribute;
 import javax.xml.stream.events.EndElement;
 import javax.xml.stream.events.StartElement;
@@ -16,15 +13,20 @@ import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
 import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
 import ca.uhn.fhir.context.FhirContext;
 import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
+import ca.uhn.fhir.context.RuntimePrimitiveDatatypeNarrativeDefinition;
 import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
 import ca.uhn.fhir.context.RuntimeResourceDefinition;
 import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
+import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
 import ca.uhn.fhir.model.api.ICompositeDatatype;
 import ca.uhn.fhir.model.api.ICompositeElement;
+import ca.uhn.fhir.model.api.IElement;
 import ca.uhn.fhir.model.api.IPrimitiveDatatype;
 import ca.uhn.fhir.model.api.IResource;
 import ca.uhn.fhir.model.api.IResourceBlock;
 import ca.uhn.fhir.model.api.ResourceReference;
+import ca.uhn.fhir.model.api.UndeclaredExtension;
+import ca.uhn.fhir.model.datatype.XhtmlDt;
 
 class ParserState {
 
@@ -51,6 +53,10 @@ class ParserState {
 		myState.enteringNewElement(theElement, theName);
 	}
 
+	public void enteringNewElementExtension(StartElement theElem, String theUrlAttr) {
+		myState.enteringNewElementExtension(theElem, theUrlAttr);
+	}
+
 	public Object getObject() {
 		return myObject;
 	}
@@ -59,6 +65,10 @@ class ParserState {
 		return myObject != null;
 	}
 
+	public void otherEvent(XMLEvent theEvent) throws DataFormatException {
+		myState.otherEvent(theEvent);
+	}
+
 	private void pop() {
 		myState = myState.myStack;
 	}
@@ -96,11 +106,25 @@ class ParserState {
 
 		public abstract void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException;
 
+		public void enteringNewElementExtension(@SuppressWarnings("unused") StartElement theElement, String theUrlAttr) {
+			// TODO: handle predefined extensions
+
+			if (getCurrentElement() instanceof ISupportsUndeclaredExtensions) {
+				UndeclaredExtension newExtension = new UndeclaredExtension();
+				newExtension.setUrl(theUrlAttr);
+				((ISupportsUndeclaredExtensions) getCurrentElement()).getUndeclaredExtensions().add(newExtension);
+				ExtensionState newState = new ExtensionState(newExtension);
+				push(newState);
+			}
+		}
+
+		public abstract void otherEvent(XMLEvent theEvent) throws DataFormatException;
+
 		public void setStack(BaseState theState) {
 			myStack = theState;
 		}
 
-		public abstract void otherEvent(XMLEvent theEvent);
+		protected abstract IElement getCurrentElement();
 
 	}
 
@@ -165,18 +189,107 @@ class ParserState {
 				push(newState);
 				return;
 			}
+			case PRIMITIVE_XHTML: {
+				RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
+				XhtmlDt newDt = xhtmlTarget.newInstance();
+				child.getMutator().addValue(myInstance, newDt);
+				XhtmlState state = new XhtmlState(newDt, theElement);
+				push(state);
+				return;
+			}
+			case UNDECL_EXT:
 			case RESOURCE: {
 				// Throw an exception because this shouldn't happen here
 				break;
-			}
-			case PRIMITIVE_XHTML: {
-
 			}
 			}
 
 			throw new DataFormatException("Illegal resource position: " + target.getChildType());
 		}
 
+		@Override
+		public void otherEvent(XMLEvent theEvent) {
+			// ignore
+		}
+
+		@Override
+		protected IElement getCurrentElement() {
+			return myInstance;
+		}
+
+	}
+
+	private class ExtensionState extends BaseState {
+
+		private UndeclaredExtension myExtension;
+
+		public ExtensionState(UndeclaredExtension theExtension) {
+			myExtension = theExtension;
+		}
+
+		@Override
+		public void attributeValue(Attribute theAttribute, String theValue) throws DataFormatException {
+			throw new DataFormatException("'value' attribute is invalid in 'extension' element");
+		}
+
+		@Override
+		public void endingElement(EndElement theElem) throws DataFormatException {
+			if (myExtension.getValue() != null && myExtension.getUndeclaredExtensions().size() > 0) {
+				throw new DataFormatException("Extension must not have both a value and other contained extensions");
+			}
+			pop();
+		}
+
+		@Override
+		public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException {
+			BaseRuntimeElementDefinition<?> target = myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(theLocalPart);
+			if (target == null) {
+				throw new DataFormatException("Unknown extension element name: " + theLocalPart);
+			}
+
+			switch (target.getChildType()) {
+			case COMPOSITE_DATATYPE: {
+				BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
+				ICompositeDatatype newChildInstance = (ICompositeDatatype) compositeTarget.newInstance();
+				myExtension.setValue(newChildInstance);
+				ContainerState newState = new ContainerState(compositeTarget, newChildInstance);
+				push(newState);
+				return;
+			}
+			case PRIMITIVE_DATATYPE: {
+				RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
+				IPrimitiveDatatype<?> newChildInstance = primitiveTarget.newInstance();
+				myExtension.setValue(newChildInstance);
+				PrimitiveState newState = new PrimitiveState(newChildInstance);
+				push(newState);
+				return;
+			}
+			case RESOURCE_REF: {
+				RuntimeResourceReferenceDefinition resourceRefTarget = (RuntimeResourceReferenceDefinition) target;
+				ResourceReference newChildInstance = new ResourceReference();
+				myExtension.setValue(newChildInstance);
+				ResourceReferenceState newState = new ResourceReferenceState(resourceRefTarget, newChildInstance);
+				push(newState);
+				return;
+			}
+			case PRIMITIVE_XHTML:
+			case RESOURCE:
+			case RESOURCE_BLOCK:
+			case UNDECL_EXT:
+				break;
+			}
+		}
+
+		@Override
+		public void otherEvent(XMLEvent theEvent) throws DataFormatException {
+			// ignore
+		}
+
+		@Override
+		protected IElement getCurrentElement() {
+			return myExtension;
+		}
+
 	}
 
 	private class PrimitiveState extends BaseState {
@@ -202,6 +315,16 @@ class ParserState {
 			throw new Error("?? can this happen?"); // TODO: can this happen?
 		}
 
+		@Override
+		public void otherEvent(XMLEvent theEvent) {
+			// ignore
+		}
+
+		@Override
+		protected IElement getCurrentElement() {
+			return myInstance;
+		}
+
 	}
 
 	private class ResourceReferenceState extends BaseState {
@@ -260,6 +383,16 @@ class ParserState {
 			}
 		}
 
+		@Override
+		public void otherEvent(XMLEvent theEvent) {
+			// ignore
+		}
+
+		@Override
+		protected IElement getCurrentElement() {
+			return myInstance;
+		}
+
 	}
 
 	private enum ResourceReferenceSubState {
@@ -267,47 +400,47 @@ class ParserState {
 	}
 
 	private class XhtmlState extends BaseState {
-		private StringWriter myStringWriter;
-		private XMLEventWriter myEventWriter;
-		private XMLEventFactory myEventFactory;
+		private int myDepth;
+		private XhtmlDt myDt;
+		private List<XMLEvent> myEvents = new ArrayList<XMLEvent>();
 
-		private XhtmlState() throws DataFormatException {
-			try {
-				XMLOutputFactory xmlFactory = XMLOutputFactory.newInstance();
-				myStringWriter = new StringWriter();
-				myEventWriter = xmlFactory.createXMLEventWriter(myStringWriter);
-			} catch (XMLStreamException e) {
-				throw new DataFormatException(e);
-			}
+		private XhtmlState(XhtmlDt theXhtmlDt, StartElement theXhtmlStartElement) throws DataFormatException {
+			myDepth = 1;
+			myDt = theXhtmlDt;
+			myEvents.add(theXhtmlStartElement);
 		}
 
 		@Override
 		public void attributeValue(Attribute theAttr, String theValue) throws DataFormatException {
-			try {
-				myEventWriter.add(theAttr);
-			} catch (XMLStreamException e) {
-				throw new DataFormatException(e);
-			}
+			myEvents.add(theAttr);
 		}
 
 		@Override
 		public void endingElement(EndElement theElement) throws DataFormatException {
-			try {
-				myEventWriter.add(theElement);
-			} catch (XMLStreamException e) {
-				throw new DataFormatException(e);
+			myEvents.add(theElement);
+
+			myDepth--;
+			if (myDepth == 0) {
+				myDt.setValue(myEvents);
+				pop();
 			}
 		}
 
 		@Override
 		public void enteringNewElement(StartElement theElem, String theLocalPart) throws DataFormatException {
-			// TODO Auto-generated method stub
+			myDepth++;
+			myEvents.add(theElem);
+		}
 
+		@Override
+		public void otherEvent(XMLEvent theEvent) throws DataFormatException {
+			myEvents.add(theEvent);
+		}
+
+		@Override
+		protected IElement getCurrentElement() {
+			return myDt;
 		}
 	}
 
-	public void otherEvent(XMLEvent theEvent) {
-		myState.otherEvent(theEvent);
-	}
-
 }
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
index 2a4b71636f7..907f6c16195 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
@@ -1,21 +1,28 @@
 package ca.uhn.fhir.parser;
 
+import static org.apache.commons.lang3.StringUtils.*;
+
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.Iterator;
 import java.util.List;
 
+import javax.xml.namespace.QName;
 import javax.xml.stream.FactoryConfigurationError;
 import javax.xml.stream.XMLEventReader;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.Comment;
 import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.EntityReference;
+import javax.xml.stream.events.Namespace;
 import javax.xml.stream.events.StartElement;
 import javax.xml.stream.events.XMLEvent;
-import javax.xml.transform.OutputKeys;
 
 import org.apache.commons.lang3.StringUtils;
 
@@ -24,14 +31,20 @@ import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
 import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
 import ca.uhn.fhir.context.ConfigurationException;
 import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.context.RuntimeChildUndeclaredExtensionDefinition;
 import ca.uhn.fhir.context.RuntimeResourceDefinition;
+import ca.uhn.fhir.model.api.IExtension;
+import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
 import ca.uhn.fhir.model.api.IElement;
 import ca.uhn.fhir.model.api.IPrimitiveDatatype;
 import ca.uhn.fhir.model.api.IResource;
 import ca.uhn.fhir.model.api.ResourceReference;
+import ca.uhn.fhir.model.api.UndeclaredExtension;
+import ca.uhn.fhir.model.datatype.XhtmlDt;
 import ca.uhn.fhir.util.PrettyPrintWriterWrapper;
 
 public class XmlParser {
+	private static final String XHTML_NS = "http://www.w3.org/1999/xhtml";
 	private static final String FHIR_NS = "http://hl7.org/fhir";
 	@SuppressWarnings("unused")
 	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParser.class);
@@ -45,13 +58,13 @@ public class XmlParser {
 		myXmlOutputFactory = XMLOutputFactory.newInstance();
 	}
 
-	public String encodeResourceToString(IResource theResource) {
+	public String encodeResourceToString(IResource theResource) throws DataFormatException {
 		XMLStreamWriter eventWriter;
 		StringWriter stringWriter = new StringWriter();
 		try {
 			eventWriter = myXmlOutputFactory.createXMLStreamWriter(stringWriter);
 			eventWriter = new PrettyPrintWriterWrapper(eventWriter);
-			
+
 			RuntimeResourceDefinition resDef = (RuntimeResourceDefinition) myContext.getClassToElementDefinition().get(theResource.getClass());
 			eventWriter.writeStartElement(resDef.getName());
 			eventWriter.writeDefaultNamespace(FHIR_NS);
@@ -67,9 +80,10 @@ public class XmlParser {
 		return stringWriter.toString();
 	}
 
-	private void encodeCompositeElementToStreamWriter(IElement theResource, XMLStreamWriter theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef) throws XMLStreamException {
+	private void encodeCompositeElementToStreamWriter(IElement theElement, XMLStreamWriter theEventWriter,BaseRuntimeElementCompositeDefinition<?> resDef) throws XMLStreamException, DataFormatException {
+		encodeExtensionsIfPresent(theEventWriter, theElement);
 		for (BaseRuntimeChildDefinition nextChild : resDef.getChildren()) {
-			List<IElement> values = nextChild.getAccessor().getValues(theResource);
+			List<? extends IElement> values = nextChild.getAccessor().getValues(theElement);
 			if (values == null || values.isEmpty()) {
 				continue;
 			}
@@ -81,34 +95,146 @@ public class XmlParser {
 				Class<? extends IElement> type = nextValue.getClass();
 				String childName = nextChild.getChildNameByDatatype(type);
 				BaseRuntimeElementDefinition<?> childDef = nextChild.getChildElementDefinitionByDatatype(type);
-				theEventWriter.writeStartElement(childName);
 
-				switch (childDef.getChildType()) {
-				case PRIMITIVE_DATATYPE: {
-					IPrimitiveDatatype<?> pd = (IPrimitiveDatatype<?>) nextValue;
-					theEventWriter.writeAttribute("value", pd.getValueAsString());
-					break;
-				}
-				case RESOURCE_BLOCK:
-				case COMPOSITE_DATATYPE: {
-					BaseRuntimeElementCompositeDefinition<?> childCompositeDef = (BaseRuntimeElementCompositeDefinition<?>) childDef;
-					encodeCompositeElementToStreamWriter(nextValue, theEventWriter, childCompositeDef);
-					break;
-				}
-				case RESOURCE_REF: {
-					ResourceReference ref = (ResourceReference) nextValue;
-					encodeResourceReferenceToStreamWriter(theEventWriter, ref);
-					break;
-				}
-				case RESOURCE:
-					throw new IllegalStateException(); // should not happen
-				}
-
-				theEventWriter.writeEndElement();
+				encodeChildElementToStreamWriter(theEventWriter, nextValue, childName, childDef);
 			}
 		}
 	}
 
+	private void encodeChildElementToStreamWriter(XMLStreamWriter theEventWriter, IElement nextValue, String childName, BaseRuntimeElementDefinition<?> childDef) throws XMLStreamException, DataFormatException {
+		switch (childDef.getChildType()) {
+		case PRIMITIVE_DATATYPE: {
+			theEventWriter.writeStartElement(childName);
+			IPrimitiveDatatype<?> pd = (IPrimitiveDatatype<?>) nextValue;
+			theEventWriter.writeAttribute("value", pd.getValueAsString());
+			encodeExtensionsIfPresent(theEventWriter, nextValue);
+			theEventWriter.writeEndElement();
+			break;
+		}
+		case RESOURCE_BLOCK:
+		case COMPOSITE_DATATYPE: {
+			theEventWriter.writeStartElement(childName);
+			BaseRuntimeElementCompositeDefinition<?> childCompositeDef = (BaseRuntimeElementCompositeDefinition<?>) childDef;
+			encodeCompositeElementToStreamWriter(nextValue, theEventWriter,  childCompositeDef);
+			encodeExtensionsIfPresent(theEventWriter, nextValue);
+			theEventWriter.writeEndElement();
+			break;
+		}
+		case RESOURCE_REF: {
+			theEventWriter.writeStartElement(childName);
+			ResourceReference ref = (ResourceReference) nextValue;
+			encodeResourceReferenceToStreamWriter(theEventWriter, ref);
+			theEventWriter.writeEndElement();
+			break;
+		}
+		case RESOURCE: {
+			throw new IllegalStateException(); // should not happen
+		}
+		case PRIMITIVE_XHTML: {
+			XhtmlDt dt = (XhtmlDt) nextValue;
+			encodeXhtml(dt, theEventWriter);
+			break;
+		}
+		case UNDECL_EXT: {
+			throw new IllegalStateException("should not happen");
+		}
+		}
+	}
+
+	private void encodeExtensionsIfPresent(XMLStreamWriter theWriter, IElement theResource) throws XMLStreamException, DataFormatException {
+		if (theResource instanceof ISupportsUndeclaredExtensions) {
+			for (UndeclaredExtension next : ((ISupportsUndeclaredExtensions) theResource).getUndeclaredExtensions()) {
+				theWriter.writeStartElement("extension");
+				theWriter.writeAttribute("url", next.getUrl());
+				
+				if (next.getValue() != null) {
+					IElement nextValue = next.getValue();
+					RuntimeChildUndeclaredExtensionDefinition extDef = myContext.getRuntimeChildUndeclaredExtensionDefinition();
+					String childName = extDef.getChildNameByDatatype(nextValue.getClass());
+					BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(nextValue.getClass());
+					encodeChildElementToStreamWriter(theWriter, nextValue, childName, childDef);
+				}
+				
+				// child extensions
+				encodeExtensionsIfPresent(theWriter, next);
+				
+				theWriter.writeEndElement();
+			}
+		}
+	}
+
+	private void encodeXhtml(XhtmlDt theDt, XMLStreamWriter theEventWriter) throws XMLStreamException {
+		if (theDt == null || theDt.getValue() == null) {
+			return;
+		}
+
+		boolean firstEvent = true;
+		for (XMLEvent event : theDt.getValue()) {
+			switch (event.getEventType()) {
+			case XMLStreamConstants.ATTRIBUTE:
+				Attribute attr = (Attribute) event;
+				if (isBlank(attr.getName().getPrefix())) {
+					if (isBlank(attr.getName().getNamespaceURI())) {
+						theEventWriter.writeAttribute(attr.getName().getLocalPart(), attr.getValue());
+					} else {
+						theEventWriter.writeAttribute(attr.getName().getNamespaceURI(), attr.getName().getLocalPart(), attr.getValue());
+					}
+				} else {
+					theEventWriter.writeAttribute(attr.getName().getPrefix(), attr.getName().getNamespaceURI(), attr.getName().getLocalPart(), attr.getValue());
+				}
+
+				break;
+			case XMLStreamConstants.CDATA:
+				theEventWriter.writeCData(((Characters) event).getData());
+				break;
+			case XMLStreamConstants.CHARACTERS:
+			case XMLStreamConstants.SPACE:
+				theEventWriter.writeCharacters(((Characters) event).getData());
+				break;
+			case XMLStreamConstants.COMMENT:
+				theEventWriter.writeComment(((Comment) event).getText());
+				break;
+			case XMLStreamConstants.END_ELEMENT:
+				theEventWriter.writeEndElement();
+				break;
+			case XMLStreamConstants.ENTITY_REFERENCE:
+				EntityReference er = (EntityReference) event;
+				theEventWriter.writeEntityRef(er.getName());
+				break;
+			case XMLStreamConstants.NAMESPACE:
+				Namespace ns = (Namespace) event;
+				theEventWriter.writeNamespace(ns.getPrefix(), ns.getNamespaceURI());
+				break;
+			case XMLStreamConstants.START_ELEMENT:
+				StartElement se = event.asStartElement();
+				if (firstEvent) {
+					theEventWriter.writeStartElement(se.getName().getLocalPart());
+					theEventWriter.writeNamespace(se.getName().getPrefix(), se.getName().getNamespaceURI());
+				} else {
+					if (isBlank(se.getName().getPrefix())) {
+						if (isBlank(se.getName().getNamespaceURI())) {
+							theEventWriter.writeStartElement(se.getName().getLocalPart());
+						} else {
+							theEventWriter.writeStartElement(se.getName().getNamespaceURI(), se.getName().getLocalPart());
+						}
+					} else {
+						theEventWriter.writeStartElement(se.getName().getPrefix(), se.getName().getLocalPart(), se.getName().getNamespaceURI());
+					}
+				}
+				break;
+			case XMLStreamConstants.DTD:
+			case XMLStreamConstants.END_DOCUMENT:
+			case XMLStreamConstants.ENTITY_DECLARATION:
+			case XMLStreamConstants.NOTATION_DECLARATION:
+			case XMLStreamConstants.PROCESSING_INSTRUCTION:
+			case XMLStreamConstants.START_DOCUMENT:
+				break;
+			}
+
+			firstEvent = false;
+		}
+	}
+
 	private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, ResourceReference theRef) throws XMLStreamException {
 		if (StringUtils.isNotBlank(theRef.getDisplay())) {
 			theEventWriter.writeStartElement("display");
@@ -138,21 +264,29 @@ public class XmlParser {
 				XMLEvent nextEvent = streamReader.nextEvent();
 				if (nextEvent.isStartElement()) {
 					StartElement elem = nextEvent.asStartElement();
-					if (!FHIR_NS.equals(elem.getName().getNamespaceURI())) {
+
+					String namespaceURI = elem.getName().getNamespaceURI();
+					if (!FHIR_NS.equals(namespaceURI) && !XHTML_NS.equals(namespaceURI)) {
 						continue;
 					}
 
 					if (parserState == null) {
 						parserState = ParserState.getResourceInstance(myContext, elem.getName().getLocalPart());
+					} else if ("extension".equals(elem.getName().getLocalPart())) {
+						Attribute urlAttr = elem.getAttributeByName(new QName("url"));
+						if (urlAttr==null||isBlank(urlAttr.getValue())) {
+							throw new DataFormatException("Extension element has no 'url' attribute");
+						}
+						parserState.enteringNewElementExtension(elem, urlAttr.getValue());
 					} else {
-						parserState.enteringNewElement(elem.getName().getLocalPart());
+						parserState.enteringNewElement(elem, elem.getName().getLocalPart());
 					}
 
 					for (@SuppressWarnings("unchecked")
 					Iterator<Attribute> iter = elem.getAttributes(); iter.hasNext();) {
 						Attribute next = iter.next();
 						if (next.getName().getLocalPart().equals("value")) {
-							parserState.attributeValue(next.getValue());
+							parserState.attributeValue(next, next.getValue());
 						}
 					}
 
@@ -167,12 +301,14 @@ public class XmlParser {
 					if (parserState == null) {
 						throw new DataFormatException("Detected attribute before element");
 					}
-					parserState.attributeValue(elem.getValue());
+					parserState.attributeValue(elem, elem.getValue());
 				} else if (nextEvent.isEndElement()) {
 					EndElement elem = nextEvent.asEndElement();
-					if (!FHIR_NS.equals(elem.getName().getNamespaceURI())) {
+					String namespaceURI = elem.getName().getNamespaceURI();
+					if (!FHIR_NS.equals(namespaceURI) && !XHTML_NS.equals(namespaceURI)) {
 						continue;
 					}
+
 					if (parserState == null) {
 						throw new DataFormatException("Detected unexpected end-element");
 					}
@@ -181,7 +317,9 @@ public class XmlParser {
 						return (IResource) parserState.getObject();
 					}
 				} else {
-					parserState.otherEvent(nextEvent);
+					if (parserState != null) {
+						parserState.otherEvent(nextEvent);
+					}
 				}
 
 			}
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java
index 549060c0a7c..5ee550fb4dc 100644
--- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java
@@ -8,6 +8,7 @@ import org.junit.Test;
 import ca.uhn.fhir.context.ConfigurationException;
 import ca.uhn.fhir.context.FhirContext;
 import ca.uhn.fhir.model.api.IResource;
+import ca.uhn.fhir.model.datatype.DateDt;
 import ca.uhn.fhir.model.resource.Observation;
 
 public class XmlParserTest {
diff --git a/hapi-fhir-base/src/test/resources/observation-example-eeg.xml b/hapi-fhir-base/src/test/resources/observation-example-eeg.xml
index 32bb3f283cc..00f09b24d3f 100644
--- a/hapi-fhir-base/src/test/resources/observation-example-eeg.xml
+++ b/hapi-fhir-base/src/test/resources/observation-example-eeg.xml
@@ -1,39 +1,51 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
- This example is taken from the v3 data types (SLIST)
--->
- 
+<!-- This example is taken from the v3 data types (SLIST) -->
+
 <Observation xmlns="http://hl7.org/fhir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hl7.org/fhir ..\..\schema\observation.xsd">
-  <text>
-    <status value="generated"/>
-    <div xmlns="http://www.w3.org/1999/xhtml">Sept 17, 2012: Systolic Blood pressure 107 mmHg (normal)</div>
-  </text>
-  <name>
-    <!-- Actually, this is not a vull EEG. A todo is to turn it into one -->
-    <coding>
-      <system value="http://loinc.org"/>
-      <code value="11523-8"/>
-      <display value="EEG study"/>
-    </coding>
-  </name>
-  <valueSampledData>
-    <origin>
-      <value value="0"/>
-      <units value="μV"/>
-      <system value="http://unitsofmeasure.org"/>
-      <code value="uV"/>
-    </origin> 
-    <period value="100"/>
-    <factor value="2.5"/>
-    <dimensions value="1"/>
-    <data value="-4 -13 -18 -18 -18 -17 -16 -16 -16 -16 -16 -17 -18 -18 -1 -17 -16 -16 -16 -15 -13 -11 -10 -10 -9 -6 -4 -5 -5 -3 -2 -2 -1 1 2 7 8 9 10 11 12 13 15 17 19 21 23 25 27 29 30 30 31 34 37 40 43 45 4 46 46 46 46 47 49 51 53 55 57 59 60 59 58 58 58 57 56 56 56 57 57 5 53 50 47 45 74 51 38 33 31 2 25 21 16 14 15 13 9 7 4 1 -1 -3 -4 -6 -10 -12 -13 -12 -12 -17 -18 -18 -18 -19 -20 -21 -20 -20 -20 -20 -2 2 1 0 0 0 1 2 2 1 1 1 0 -1 0 1 1 1 1 2 E"/> 
-  </valueSampledData>
-  
-  <status value="final"/>
-  <reliability value="ok"/>
+	<extension url="http://acme.org/fhir/Profile/main#trial-status">
+		<extension url="http://acme.org/fhir/Profile/main#trial-status-code">
+			<valueCode value="unsure" />
+		</extension>
+		<extension url="http://acme.org/fhir/Profile/main#trial-status-date">
+			<valueDate value="2009-03-14" />
+		</extension>
+		<extension url="http://acme.org/fhir/Profile/main#trial-status-who">
+			<valueResource>
+				<reference value="Practitioner/example" />
+			</valueResource>
+		</extension>
+	</extension>
+	<text>
+		<status value="generated" />
+		<div xmlns="http://www.w3.org/1999/xhtml">Sept 17, 2012: Systolic Blood pressure 107 mmHg (normal)</div>
+	</text>
+	<name>
+		<!-- Actually, this is not a vull EEG. A todo is to turn it into one -->
+		<coding>
+			<system value="http://loinc.org" />
+			<code value="11523-8" />
+			<display value="EEG study" />
+		</coding>
+	</name>
+	<valueSampledData>
+		<origin>
+			<value value="0" />
+			<units value="μV" />
+			<system value="http://unitsofmeasure.org" />
+			<code value="uV" />
+		</origin>
+		<period value="100" />
+		<factor value="2.5" />
+		<dimensions value="1" />
+		<data
+			value="-4 -13 -18 -18 -18 -17 -16 -16 -16 -16 -16 -17 -18 -18 -1 -17 -16 -16 -16 -15 -13 -11 -10 -10 -9 -6 -4 -5 -5 -3 -2 -2 -1 1 2 7 8 9 10 11 12 13 15 17 19 21 23 25 27 29 30 30 31 34 37 40 43 45 4 46 46 46 46 47 49 51 53 55 57 59 60 59 58 58 58 57 56 56 56 57 57 5 53 50 47 45 74 51 38 33 31 2 25 21 16 14 15 13 9 7 4 1 -1 -3 -4 -6 -10 -12 -13 -12 -12 -17 -18 -18 -18 -19 -20 -21 -20 -20 -20 -20 -2 2 1 0 0 0 1 2 2 1 1 1 0 -1 0 1 1 1 1 2 E" />
+	</valueSampledData>
+
+	<status value="final" />
+	<reliability value="ok" />
 
 
-  <subject>
-    <reference value="Patient/example"/>
-  </subject>
+	<subject>
+		<reference value="Patient/example" />
+	</subject>
 </Observation>
\ No newline at end of file
diff --git a/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/BaseParser.java b/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/BaseParser.java
index 4191f893913..bfbfdfe9368 100644
--- a/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/BaseParser.java
+++ b/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/BaseParser.java
@@ -8,9 +8,11 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
@@ -19,30 +21,29 @@ import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-import ch.qos.logback.core.db.dialect.MySQLDialect;
 import ca.uhn.fhir.model.api.IDatatype;
 import ca.uhn.fhir.model.api.ResourceReference;
-import ca.uhn.fhir.model.datatype.CodeDt;
-import ca.uhn.fhir.model.datatype.CodeableConceptDt;
 import ca.uhn.fhir.starter.model.BaseElement;
 import ca.uhn.fhir.starter.model.Child;
+import ca.uhn.fhir.starter.model.Extension;
 import ca.uhn.fhir.starter.model.Resource;
 import ca.uhn.fhir.starter.model.ResourceBlock;
 import ca.uhn.fhir.starter.util.XMLUtils;
 
 public abstract class BaseParser {
 
-	private String myDirectory;
-	private String myOutputFile;
-	private int myColName;
-	private int myColCard;
-	private int myColType;
-	private int myColBinding;
-	private int myColShortName;
-	private int myColDefinition;
-	private int myColV2Mapping;
-	private int myColRequirements;
 	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseParser.class);
+	private int myColBinding;
+	private int myColCard;
+	private int myColDefinition;
+	private int myColName;
+	private int myColRequirements;
+	private int myColShortName;
+	private int myColType;
+	private int myColV2Mapping;
+	private String myDirectory;
+	private ArrayList<Extension> myExtensions;
+	private String myOutputFile;
 
 	public void parse() throws Exception {
 		File baseDir = new File(myDirectory);
@@ -145,66 +146,14 @@ public abstract class BaseParser {
 		myDirectory = theDirectory;
 	}
 
+	public void setExtensions(ArrayList<Extension> theExts) {
+		myExtensions = theExts;
+	}
+
 	public void setOutputFile(String theOutputFile) {
 		myOutputFile = theOutputFile;
 	}
 
-	static String cellValue(Node theRowXml, int theCellIndex) {
-		NodeList cells = ((Element) theRowXml).getElementsByTagName("Cell");
-
-		for (int i = 0, currentCell = 0; i < cells.getLength(); i++) {
-			Element nextCell = (Element) cells.item(i);
-			String indexVal = nextCell.getAttributeNS("urn:schemas-microsoft-com:office:spreadsheet", "Index");
-			if (StringUtils.isNotBlank(indexVal)) {
-				// 1-indexed for some reason...
-				currentCell = Integer.parseInt(indexVal) - 1;
-			}
-
-			if (currentCell == theCellIndex) {
-				NodeList dataElems = nextCell.getElementsByTagName("Data");
-				Element dataElem = (Element) dataElems.item(0);
-				if (dataElem == null) {
-					return null;
-				}
-				String retVal = dataElem.getTextContent();
-				return retVal;
-			}
-
-			currentCell++;
-		}
-
-		return null;
-	}
-
-	private void write(Resource theResource) throws IOException {
-		File f = new File(myOutputFile);
-		FileWriter w = new FileWriter(f, false);
-
-		ourLog.info("Writing file: {}", f.getAbsolutePath());
-
-		VelocityContext ctx = new VelocityContext();
-		ctx.put("className", theResource.getName());
-		ctx.put("shortName", defaultString(theResource.getShortName()));
-		ctx.put("definition", defaultString(theResource.getDefinition()));
-		ctx.put("requirements", defaultString(theResource.getRequirement()));
-		ctx.put("children", theResource.getChildren());
-		ctx.put("resourceBlockChildren", theResource.getResourceBlockChildren());
-
-		VelocityEngine v = new VelocityEngine();
-		v.setProperty("resource.loader", "cp");
-		v.setProperty("cp.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
-
-		InputStream templateIs = ResourceParser.class.getResourceAsStream(getTemplate());
-		InputStreamReader templateReader = new InputStreamReader(templateIs);
-		v.evaluate(ctx, w, "", templateReader);
-
-		w.close();
-	}
-
-	protected abstract String getFilename();
-
-	protected abstract String getTemplate();
-
 	private void parseFirstRow(Element theDefRow) {
 		for (int i = 0; i < 20; i++) {
 			String nextName = cellValue(theDefRow, i);
@@ -232,6 +181,36 @@ public abstract class BaseParser {
 		}
 	}
 
+	private void write(Resource theResource) throws IOException {
+		File f = new File(myOutputFile);
+		FileWriter w = new FileWriter(f, false);
+
+		ourLog.info("Writing file: {}", f.getAbsolutePath());
+
+		VelocityContext ctx = new VelocityContext();
+		ctx.put("className", theResource.getName());
+		ctx.put("shortName", defaultString(theResource.getShortName()));
+		ctx.put("definition", defaultString(theResource.getDefinition()));
+		ctx.put("requirements", defaultString(theResource.getRequirement()));
+		ctx.put("children", theResource.getChildren());
+		ctx.put("resourceBlockChildren", theResource.getResourceBlockChildren());
+		ctx.put("childExtensionTypes", ObjectUtils.defaultIfNull(myExtensions, new ArrayList<Extension>()));
+
+		VelocityEngine v = new VelocityEngine();
+		v.setProperty("resource.loader", "cp");
+		v.setProperty("cp.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+
+		InputStream templateIs = ResourceParser.class.getResourceAsStream(getTemplate());
+		InputStreamReader templateReader = new InputStreamReader(templateIs);
+		v.evaluate(ctx, w, "", templateReader);
+
+		w.close();
+	}
+
+	protected abstract String getFilename();
+
+	protected abstract String getTemplate();
+
 	protected void parseBasicElements(Element theRowXml, BaseElement theTarget) {
 		String name = cellValue(theRowXml, myColName);
 		theTarget.setName(name);
@@ -263,4 +242,31 @@ public abstract class BaseParser {
 		theTarget.setV2Mapping(cellValue(theRowXml, myColV2Mapping));
 	}
 
+	static String cellValue(Node theRowXml, int theCellIndex) {
+		NodeList cells = ((Element) theRowXml).getElementsByTagName("Cell");
+
+		for (int i = 0, currentCell = 0; i < cells.getLength(); i++) {
+			Element nextCell = (Element) cells.item(i);
+			String indexVal = nextCell.getAttributeNS("urn:schemas-microsoft-com:office:spreadsheet", "Index");
+			if (StringUtils.isNotBlank(indexVal)) {
+				// 1-indexed for some reason...
+				currentCell = Integer.parseInt(indexVal) - 1;
+			}
+
+			if (currentCell == theCellIndex) {
+				NodeList dataElems = nextCell.getElementsByTagName("Data");
+				Element dataElem = (Element) dataElems.item(0);
+				if (dataElem == null) {
+					return null;
+				}
+				String retVal = dataElem.getTextContent();
+				return retVal;
+			}
+
+			currentCell++;
+		}
+
+		return null;
+	}
+
 }
diff --git a/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/ResourceParser.java b/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/ResourceParser.java
index 93f82ff8468..d519d2a4d87 100644
--- a/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/ResourceParser.java
+++ b/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/ResourceParser.java
@@ -1,5 +1,10 @@
 package ca.uhn.fhir.starter;
 
+import java.util.ArrayList;
+
+import ca.uhn.fhir.model.datatype.DateDt;
+import ca.uhn.fhir.model.datatype.StringDt;
+import ca.uhn.fhir.starter.model.Extension;
 
 public class ResourceParser extends BaseParser {
 	private String myResourceName;
@@ -13,50 +18,59 @@ public class ResourceParser extends BaseParser {
 		return myResourceName + "-spreadsheet.xml";
 	}
 
+	// @Override
+	// protected void parseBasicElements(Element theRowXml, BaseElement
+	// theTarget) {
+	// String name = cellValue(theRowXml, 0);
+	// theTarget.setName(name);
+	//
+	// int lastDot = name.lastIndexOf('.');
+	// if (lastDot == -1) {
+	// theTarget.setElementName(name);
+	// } else {
+	// String elementName = name.substring(lastDot + 1);
+	// String elementParentName = name.substring(0, lastDot);
+	// theTarget.setElementName(elementName);
+	// theTarget.setElementParentName(elementParentName);
+	// }
+	//
+	// String cardValue = cellValue(theRowXml, 1);
+	// if (cardValue != null && cardValue.contains("..")) {
+	// String[] split = cardValue.split("\\.\\.");
+	// theTarget.setCardMin(split[0]);
+	// theTarget.setCardMax(split[1]);
+	// }
+	//
+	// String type = cellValue(theRowXml, 5);
+	// theTarget.setTypeFromString(type);
+	//
+	// theTarget.setBinding(cellValue(theRowXml, 6));
+	// theTarget.setShortName(cellValue(theRowXml, 7));
+	// theTarget.setDefinition(cellValue(theRowXml, 8));
+	// theTarget.setRequirement(cellValue(theRowXml, 9));
+	// theTarget.setV2Mapping(cellValue(theRowXml, 14));
+	// }
+
 	@Override
 	protected String getTemplate() {
 		return "/resource.vm";
 	}
 
-//	@Override
-//	protected void parseBasicElements(Element theRowXml, BaseElement theTarget) {
-//		String name = cellValue(theRowXml, 0);
-//		theTarget.setName(name);
-//
-//		int lastDot = name.lastIndexOf('.');
-//		if (lastDot == -1) {
-//			theTarget.setElementName(name);
-//		} else {
-//			String elementName = name.substring(lastDot + 1);
-//			String elementParentName = name.substring(0, lastDot);
-//			theTarget.setElementName(elementName);
-//			theTarget.setElementParentName(elementParentName);
-//		}
-//
-//		String cardValue = cellValue(theRowXml, 1);
-//		if (cardValue != null && cardValue.contains("..")) {
-//			String[] split = cardValue.split("\\.\\.");
-//			theTarget.setCardMin(split[0]);
-//			theTarget.setCardMax(split[1]);
-//		}
-//
-//		String type = cellValue(theRowXml, 5);
-//		theTarget.setTypeFromString(type);
-//
-//		theTarget.setBinding(cellValue(theRowXml, 6));
-//		theTarget.setShortName(cellValue(theRowXml, 7));
-//		theTarget.setDefinition(cellValue(theRowXml, 8));
-//		theTarget.setRequirement(cellValue(theRowXml, 9));
-//		theTarget.setV2Mapping(cellValue(theRowXml, 14));
-//	}
-
 	public static void main(String[] args) throws Exception {
 		ResourceParser p = new ResourceParser();
 		p.setDirectory("src/test/resources/res");
 		p.setResourceName("patient");
 		p.setOutputFile("../hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Patient.java");
+		ArrayList<Extension> exts = new ArrayList<Extension>();
+		Extension ext1 = new Extension("foo1", "http://foo/1", StringDt.class);
+		exts.add(ext1);
+		Extension ext2 = new Extension("bar1", "http://bar/1", new Extension("bar11", "http://bar/1/1", DateDt.class), new Extension("bar12", "http://bar/1/2", DateDt.class));
+		exts.add(ext2);
+		p.setExtensions(exts);
 		p.parse();
 
+		p = new ResourceParser();
+		p.setDirectory("src/test/resources/res");
 		p.setResourceName("observation");
 		p.setOutputFile("../hapi-fhir-base/src/main/java/ca/uhn/fhir/model/resource/Observation.java");
 		p.parse();
diff --git a/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/model/Extension.java b/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/model/Extension.java
new file mode 100644
index 00000000000..8cdc6e3e534
--- /dev/null
+++ b/hapi-fhir-starter/src/main/java/ca/uhn/fhir/starter/model/Extension.java
@@ -0,0 +1,84 @@
+package ca.uhn.fhir.starter.model;
+
+import java.util.Arrays;
+import java.util.List;
+
+import ca.uhn.fhir.model.api.IDatatype;
+
+public class Extension {
+
+	private List<Extension> myChildExtensions;
+	private Class<? extends IDatatype> myDatatype;
+	private String myName;
+	private String myUrl;
+
+	public Extension() {
+		super();
+	}
+
+	public boolean isHasDatatype() {
+		return myDatatype != null;
+	}
+	
+	public String getDatatypeSimpleName() {
+		return myDatatype.getSimpleName();
+	}
+	
+	public String getNameType() {
+		return getName().substring(0, 1).toUpperCase()+getName().substring(1);
+	}
+	
+	public Extension(String theName, String theUrl, Class<? extends IDatatype> theDatatype) {
+		setName(theName);
+		setUrl(theUrl);
+		setDatatype(theDatatype);
+	}
+
+	public Extension(String theName, String theUrl, Extension... theChildExtensions) {
+		setName(theName);
+		setUrl(theUrl);
+		if (theChildExtensions != null) {
+			setChildExtensions(Arrays.asList(theChildExtensions));
+		}
+	}
+
+	public List<Extension> getChildExtensions() {
+		return myChildExtensions;
+	}
+
+	public Class<? extends IDatatype> getDatatype() {
+		return myDatatype;
+	}
+
+	public String getName() {
+		return myName;
+	}
+
+	public String getUrl() {
+		return myUrl;
+	}
+
+	public void setChildExtensions(List<Extension> theChildExtensions) {
+		if (theChildExtensions != null && theChildExtensions.size() > 0 && myDatatype != null) {
+			throw new IllegalArgumentException("Extension may not have a datatype AND child extensions");
+		}
+		myChildExtensions = theChildExtensions;
+	}
+
+	public void setDatatype(Class<? extends IDatatype> theDatatype) {
+		if (myChildExtensions != null && myChildExtensions.size() > 0 && theDatatype != null) {
+			throw new IllegalArgumentException("Extension may not have a datatype AND child extensions");
+		}
+		myDatatype = theDatatype;
+	}
+
+	public void setName(String theName) {
+		// TODO: validate that this is a valid name (no punctuation, spaces,
+		// etc.)
+		myName = theName;
+	}
+
+	public void setUrl(String theUrl) {
+		myUrl = theUrl;
+	}
+}
diff --git a/hapi-fhir-starter/src/main/resources/dt_composite.vm b/hapi-fhir-starter/src/main/resources/dt_composite.vm
index bd8933336d5..c1c61829a05 100644
--- a/hapi-fhir-starter/src/main/resources/dt_composite.vm
+++ b/hapi-fhir-starter/src/main/resources/dt_composite.vm
@@ -24,7 +24,10 @@ import ca.uhn.fhir.model.datatype.*;
 @DatatypeDef(name="${className}") 
 public class ${className}Dt extends BaseCompositeDatatype {
 
+#childExtensionFields( $childExtensionTypes )
 #childVars( $children )
 #childAccessors( $children )
 
+#childExtensionTypes( $childExtensionTypes )
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-starter/src/main/resources/resource.vm b/hapi-fhir-starter/src/main/resources/resource.vm
index c467642f44a..c5e1b86280b 100644
--- a/hapi-fhir-starter/src/main/resources/resource.vm
+++ b/hapi-fhir-starter/src/main/resources/resource.vm
@@ -24,6 +24,7 @@ import ca.uhn.fhir.model.datatype.*;
 @ResourceDef(name="${className}")
 public class ${className} extends BaseResource {
 
+#childExtensionFields( $childExtensionTypes )
 #childVars( $children )
 #childAccessors( $children )
 
@@ -44,4 +45,6 @@ public class ${className} extends BaseResource {
 
 #end
 
+#childExtensionTypes( $childExtensionTypes )
+
 }
\ No newline at end of file
diff --git a/hapi-fhir-starter/src/main/resources/templates.vm b/hapi-fhir-starter/src/main/resources/templates.vm
index c625d7b2f7a..ebe309b024a 100644
--- a/hapi-fhir-starter/src/main/resources/templates.vm
+++ b/hapi-fhir-starter/src/main/resources/templates.vm
@@ -1,3 +1,7 @@
+##################################################################
+## childVars
+##################################################################
+
 #macro ( childVars $childElements )
 #foreach ( $child in $children )
 #if ($child.resourceRef) 
@@ -21,6 +25,11 @@
 #end
 #end
 
+
+##################################################################
+## childAccessors
+##################################################################
+
 #macro ( childAccessors $childElements )
 #foreach ( $child in $children )
 	/**
@@ -49,3 +58,53 @@
 	
 #end
 #end
+
+##################################################################
+## childExtensionFields
+##################################################################
+
+#macro ( childExtensionFields $childExtensionTypes )
+#foreach ( $extensionType in $childExtensionTypes )
+	@Child()
+	private ${extensionType.nameType} my${extensionType.nameType};
+
+#end
+#end
+
+
+##################################################################
+## childExtensionTypes
+##################################################################
+
+#macro ( childExtensionTypes $childExtensionTypes )
+#foreach ( $extensionType in $childExtensionTypes )
+	@ExtensionBlock(url="${extensionType.url}")
+	public class ${extensionType.nameType} implements IExtension {
+		
+#if(${extensionType.hasDatatype})
+		@Child(name="value", order=0)
+		private ${extensionType.datatypeSimpleName} myValue;
+
+		/**
+		 * Gets the value 
+		 */
+		public ${extensionType.datatypeSimpleName} getValue() {
+			return myValue;
+		}
+	
+		/**
+		 * Sets the value
+		 */
+		public void setValue(${extensionType.datatypeSimpleName} theValue) {
+			myValue = theValue;
+		}
+#else
+#end
+
+
+	}
+	
+#end
+#end
+
+