Added more unit-tests
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/AbstractExternalFormTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/AbstractExternalFormTests.java
index 3925704..383fefd 100644
--- a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/AbstractExternalFormTests.java
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/AbstractExternalFormTests.java
@@ -19,8 +19,11 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import org.eclipse.persistence.tools.mapping.ExternalForm;
 import org.eclipse.persistence.tools.utility.ClassTools;
+import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.junit.Test;
 import org.w3c.dom.Node;
 import static org.junit.Assert.*;
@@ -39,7 +42,7 @@
 	 * @param tester The {@link RootNodeTester} is used to adds the appropriate testers to test the
 	 * property of a node; i.e. its attributes and child nodes
 	 */
-	protected abstract void populate(RootNodeTester<FORM> tester);
+	protected abstract void populate(RootNodeTester tester);
 
 	/**
 	 * Performs the actual tests on the XML document for a particular node that is being manipulated
@@ -47,13 +50,69 @@
 	 */
 	@Test
 	public final void test() throws Exception {
-		DefaultRootNodeTester tester = new DefaultRootNodeTester();
+		RootNodeTester tester = new RootNodeTester();
 		populate(tester);
 		tester.test();
 	}
 
 	/**
-	 * This controller simply asks its runner to add the attribute node.
+	 * The runner manages testing a single child node.
+	 */
+	private abstract class AbstractChildNodeTesterRunner extends NodeTesterRunner {
+
+		/**
+		 * Indicates whether the child node being tested is present or not.
+		 */
+		boolean hasChild;
+
+		/**
+		 * Creates a new <code>AbstractChildNodeTesterRunner</code>.
+		 *
+		 * @param tester This object defines a single child node to test
+		 */
+		AbstractChildNodeTesterRunner(NodeTester<FORM, ?> tester) {
+			super(tester);
+		}
+
+		final String displayString() {
+			return "<" + getNodeName() + ">";
+		}
+
+		final Node getChildNode(Node node) {
+
+			node = node.getFirstChild();
+
+			while (node != null) {
+
+				if (getNodeName().equals(node.getNodeName())) {
+					return node;
+				}
+
+				node = node.getNextSibling();
+			}
+
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		boolean isMultipleSupported() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		boolean isNodeDeletedWithNullValue() {
+			return false;
+		}
+	}
+
+	/**
+	 * This controller simply asks its runner to test adding the attribute node.
 	 */
 	private class AttributeNodeRunnerAddingController extends Controller {
 
@@ -61,8 +120,10 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + " " + runner.tester.getNodeName() + "=\"\"> : addition");
+		@SuppressWarnings("unchecked")
+		void log(Logger logger) {
+			AttributeNodeTesterRunner runner = (AttributeNodeTesterRunner) this.runner;
+			logger.log(Level.FINE, "<" + runner.parentNodeName + " " + runner.getNodeName() + "=\"" + runner.propertyTester().getDefaultValue() + "\"> : adding");
 		}
 
 		/**
@@ -70,19 +131,19 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			AttributeNodeTesterRunner runner = (AttributeNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testAdding(form, node);
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
 	}
 
 	/**
-	 * This controller simply asks its runner to reading the attribute node.
+	 * This controller simply asks its runner to test reading the attribute node.
 	 */
 	private class AttributeNodeRunnerReadingController extends Controller {
 
@@ -90,8 +151,10 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + " " + runner.tester.getNodeName() + "=\"\"> : reading");
+		@SuppressWarnings("unchecked")
+		void log(Logger logger) {
+			AttributeNodeTesterRunner runner = (AttributeNodeTesterRunner) this.runner;
+			logger.log(Level.FINE, "<" + runner.parentNodeName + " " + runner.getNodeName() + "=\"" + runner.propertyTester().getDefaultValue() + "\"> : reading");
 		}
 
 		/**
@@ -99,19 +162,19 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			AttributeNodeTesterRunner runner = (AttributeNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testReading(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
 	}
 
 	/**
-	 * This controller simply asks its runner to removing the attribute node.
+	 * This controller simply asks its runner to test removing the attribute node.
 	 */
 	private class AttributeNodeRunnerRemovingController extends Controller {
 
@@ -119,8 +182,10 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + " " + runner.tester.getNodeName() + "=\"\"> : removing");
+		@SuppressWarnings("unchecked")
+		void log(Logger logger) {
+			AttributeNodeTesterRunner runner = (AttributeNodeTesterRunner) this.runner;
+			logger.log(Level.FINE, "<" + runner.parentNodeName + " " + runner.getNodeName() + "=\"" + runner.propertyTester().getDefaultValue() + "\"> : removing");
 		}
 
 		/**
@@ -128,12 +193,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			AttributeNodeTesterRunner runner = (AttributeNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testRemoving(form, node);
+			runner.testInitialState(holder);
+			runner.testRemoving(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -168,7 +233,7 @@
 		 */
 		@Override
 		String displayString() {
-			return "<" + parentNodeName + " " + getNodeName() + "=\"\">";
+			return "<" + parentNodeName + " " + getNodeName() + "=\"" + propertyTester().getDefaultValue() + "\">";
 		}
 
 		/**
@@ -197,7 +262,7 @@
 	}
 
 	/**
-	 * This controller simply asks its runner to add or remove a child node.
+	 * This controller simply asks its runner to test adding or removing a child node.
 	 */
 	private class BooleanChildNodeRunnerAddingController extends Controller {
 
@@ -205,8 +270,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + ">> : addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
 		}
 
 		/**
@@ -214,19 +279,19 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			BooleanChildNodeTesterRunner runner = (BooleanChildNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testAdding(form, node);
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
 	}
 
 	/**
-	 * This controller simply asks its runner to read if a child node is present or not.
+	 * This controller simply asks its runner to test reading if a child node is present or not.
 	 */
 	private class BooleanChildNodeRunnerReadingController extends Controller {
 
@@ -234,8 +299,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + ">> : reading");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : reading");
 		}
 
 		/**
@@ -243,19 +308,19 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			BooleanChildNodeTesterRunner runner = (BooleanChildNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testReading(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
 	}
 
 	/**
-	 * This controller simply asks its runner to removing the child node.
+	 * This controller simply asks its runner to test removing the child node.
 	 */
 	private class BooleanChildNodeRunnerRemovingController extends Controller {
 
@@ -263,8 +328,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + ">> : removing");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : removing");
 		}
 
 		/**
@@ -272,19 +337,20 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			BooleanChildNodeTesterRunner runner = (BooleanChildNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testRemoving(form, node);
+			runner.testInitialState(holder);
+			runner.testRemoving(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
 	}
 
 	/**
-	 * This <code>BooleanChildNodeTester</code> tests when a form add or remove a single child node.
+	 * This <code>BooleanChildNodeTester</code> tests when a form add or remove a single child node
+	 * that is represented by a boolean property in the {@link ExternalForm}.
 	 */
 	public interface BooleanChildNodeTester<FORM extends ExternalForm> extends NodeTester<FORM, Boolean> {
 
@@ -307,12 +373,7 @@
 	/**
 	 * The runner associated with {@link BooleanChildNodeTester}.
 	 */
-	private class BooleanChildNodeTesterRunner extends NodeTesterRunner {
-
-		/**
-		 *
-		 */
-		private boolean hasChild;
+	private class BooleanChildNodeTesterRunner extends AbstractChildNodeTesterRunner {
 
 		/**
 		 * Creates a new <code>BooleanChildNodeTesterRunner</code>.
@@ -323,76 +384,154 @@
 			super(tester);
 		}
 
-		private String displayString() {
-			return "<" + getNodeName() + ">";
-		}
-
-		private Node getChildNode(Node node) {
-
-			node = node.getFirstChild();
-
-			while (node != null) {
-
-				if (getNodeName().equals(node.getNodeName())) {
-					return node;
-				}
-
-				node = node.getNextSibling();
-			}
-
-			return null;
-		}
-
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		boolean isMultipleSupported() {
-			return false;
-		}
+		@SuppressWarnings("unchecked")
+		void testAdding(ExternalFormHolder holder) {
 
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testAdding(FORM form, Node node) {
-
-			// Don't add the child if it's not present
+			// Don't add the child if it's present
 			if (hasChild) {
 				return;
 			}
 
+			BooleanChildNodeTester<FORM> tester = (BooleanChildNodeTester<FORM>) ((NodeTester<FORM, ?>) this.tester);
+
+			// Add the child node
+			tester.setValue(holder.form, true);
+			hasChild = true;
+			currentChildrenCount++;
+
+			// Make sure the child node was indeed added
+			assertEquals(
+				displayString() + " : The number of children is inconsistent",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// Make sure the child node is correctly retrieved
+			assertTrue(
+				displayString() + " : The child node should have been found",
+				tester.getValue(holder.form)
+			);
+
+			// Make sure the right child node was added and is retrieved by the ExternalForm
+			assertNotNull(
+				displayString() + " : The child node should exist",
+				getChildNode(holder.node)
+			);
+
+			// Make sure nothing changed
+			assertEquals(
+				displayString() + " : The child node should exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		@SuppressWarnings({"rawtypes", "unchecked"})
-		void testInitialState(FORM form, Node node) {
+		@SuppressWarnings("unchecked")
+		void testInitialState(ExternalFormHolder holder) {
 
-			BooleanChildNodeTester<FORM> tester = (BooleanChildNodeTester) this.tester;
+			BooleanChildNodeTester<FORM> tester = (BooleanChildNodeTester<FORM>) ((NodeTester<FORM, ?>) this.tester);
 
+			// Make sure the child node does not exist
+			assertEquals(
+				displayString() + " : The child node should not exist",
+				hasChild,
+				tester.getValue(holder.form)
+			);
+
+			// Make sure nothing changed
+			assertEquals(
+				displayString() + " : The child node should not exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// The child node should not exist
+			if (hasChild) {
+				assertNotNull(
+					displayString() + " : The child node should exist",
+					getChildNode(holder.node)
+				);
+			}
+			else {
+				assertNull(
+					displayString() + " : The child node should not exist",
+					getChildNode(holder.node)
+				);
+			}
+
+			// Make sure nothing changed
+			assertEquals(
+				displayString() + " : The child node should not exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testReading(FORM form, Node node) {
+		void testReading(ExternalFormHolder holder) {
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testRemoving(FORM form, Node node) {
+		@SuppressWarnings("unchecked")
+		void testRemoving(ExternalFormHolder holder) {
 
 			// Nothing to remove
 			if (!hasChild) {
 				return;
 			}
 
+			BooleanChildNodeTester<FORM> tester = (BooleanChildNodeTester<FORM>) ((NodeTester<FORM, ?>) this.tester);
+
+			// Make sure the child node exists
+			assertTrue(
+				displayString() + " : The child node should exist",
+				tester.getValue(holder.form)
+			);
+
+			// Make sure nothing changed with the previous check
+			assertEquals(
+				displayString() + " : The child node should exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// Remove the child node
+			tester.setValue(holder.form, false);
+			currentChildrenCount--;
+			hasChild = false;
+
+			// Make sure the child node was indeed removed
+			assertEquals(
+				displayString() + " : The child node should have been removed",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// Make sure the right child node was removed
+			assertNull(
+				displayString() + " : The wrong child node was removed",
+				getChildNode(holder.node)
+			);
+
+			// Test to make sure the child node is not found
+			assertFalse(
+				displayString() + " : The child node should not exist",
+				tester.getValue(holder.form)
+			);
 		}
 	}
 
@@ -406,9 +545,9 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void log() {
+		void log(Logger logger) {
 			ChildAttributeTesterRunner runner = (ChildAttributeTesterRunner) this.runner;
-			System.out.println("<" + runner.parentNodeName + "><" + runner.getChildNodeName() + " " + runner.tester.getNodeName() + "=\"\">> : adding");
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getChildNodeName() + " " + runner.tester.getNodeName() + "=\"\">> : adding");
 		}
 
 		/**
@@ -416,12 +555,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildAttributeTesterRunner runner = (ChildAttributeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testAdding(form, node);
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -437,9 +576,9 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void log() {
+		void log(Logger logger) {
 			ChildAttributeTesterRunner runner = (ChildAttributeTesterRunner) this.runner;
-			System.out.println("<" + runner.parentNodeName + "><" + runner.getChildNodeName() + " " + runner.tester.getNodeName() + "=\"\">> : reading");
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getChildNodeName() + " " + runner.tester.getNodeName() + "=\"\">> : reading");
 		}
 
 		/**
@@ -447,12 +586,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildAttributeTesterRunner runner = (ChildAttributeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testReading(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -468,9 +607,9 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void log() {
+		void log(Logger logger) {
 			ChildAttributeTesterRunner runner = (ChildAttributeTesterRunner) this.runner;
-			System.out.println("<" + runner.parentNodeName + "><" + runner.getChildNodeName() + " " + runner.tester.getNodeName() + "=\"\">> : removing");
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getChildNodeName() + " " + runner.tester.getNodeName() + "=\"\">> : removing");
 		}
 
 		/**
@@ -478,12 +617,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildAttributeTesterRunner runner = (ChildAttributeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testRemoving(form, node);
+			runner.testInitialState(holder);
+			runner.testRemoving(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -562,7 +701,15 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testAdding(FORM form, Node parentNode) {
+		boolean isNodeDeletedWithNullValue() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testAdding(ExternalFormHolder holder) {
 
 			ChildAttributeTester<FORM, Object> tester = (ChildAttributeTester<FORM, Object>) this.tester;
 
@@ -570,7 +717,7 @@
 			// Test 1
 			//
 			// Change the node value to null
-			tester.setValue(form, null);
+			tester.setValue(holder.form, null);
 
 			if (nodeExists) {
 				currentChildrenCount--;
@@ -580,11 +727,11 @@
 			assertEquals(
 				displayString() + " : The element should not have any children",
 				currentChildrenCount,
-				parentNode.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 
 			// Make sure the value retrieved is null
-			Object result = tester.getValue(form);
+			Object result = tester.getValue(holder.form);
 
 			assertNull(
 				displayString() + " : The element's value should be null",
@@ -595,7 +742,7 @@
 			assertEquals(
 				displayString() + " : The element should not have any children",
 				currentChildrenCount,
-				parentNode.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 
 			//
@@ -609,7 +756,7 @@
 				expectedValue1
 			);
 
-			tester.setValue(form, expectedValue1);
+			tester.setValue(holder.form, expectedValue1);
 
 			if (!nodeExists) {
 				nodeExists = true;
@@ -620,10 +767,10 @@
 			assertEquals(
 				displayString() + " : The number of children is inconsistent",
 				currentChildrenCount,
-				parentNode.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 
-			Node childNode = getChildNode(parentNode);
+			Node childNode = getChildNode(holder.node);
 
 			assertNotNull(
 				displayString() + " : The child node was not added correctly",
@@ -653,7 +800,7 @@
 			);
 
 			// Get the value
-			result = tester.getValue(form);
+			result = tester.getValue(holder.form);
 
 			assertNotNull(
 				displayString() + " : The element's value was not set correctly",
@@ -686,16 +833,16 @@
 				expectedValue2
 			);
 
-			tester.setValue(form, expectedValue2);
+			tester.setValue(holder.form, expectedValue2);
 
 			// The number of children should not have changed
 			assertEquals(
 				displayString() + " : The number of children is inconsistent",
 				currentChildrenCount,
-				parentNode.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 
-			childNode = getChildNode(parentNode);
+			childNode = getChildNode(holder.node);
 
 			assertNotNull(
 				displayString() + " : The child node was not added correctly",
@@ -725,7 +872,7 @@
 			);
 
 			// Get the value
-			result = tester.getValue(form);
+			result = tester.getValue(holder.form);
 
 			assertNotNull(
 				displayString() + " : The element's value was not set correctly",
@@ -752,14 +899,14 @@
 				defaultValue
 			);
 
-			tester.setValue(form, defaultValue);
+			tester.setValue(holder.form, defaultValue);
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testInitialState(FORM form, Node parent) {
+		void testInitialState(ExternalFormHolder holder) {
 
 			ChildAttributeTester<FORM, Object> tester = (ChildAttributeTester<FORM, Object>) this.tester;
 			nodeExists |= tester.doesNodeAlreadyExist();
@@ -784,11 +931,11 @@
 			assertEquals(
 				displayString() + " : The number of children is incorrect",
 				currentChildrenCount,
-				parent.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 
 			// The child node should either not exist or already being present
-			Node childNode = getChildNode(parent);
+			Node childNode = getChildNode(holder.node);
 
 			if (!nodeExists) {
 				assertNull(
@@ -830,12 +977,12 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testReading(FORM form, Node node) {
+		void testReading(ExternalFormHolder holder) {
 
 			ChildAttributeTester<FORM, Object> tester = (ChildAttributeTester<FORM, Object>) this.tester;
 
 			// The node value should either be null or not null
-			Object result = tester.getValue(form);
+			Object result = tester.getValue(holder.form);
 
 			// Make sure the node's value is not null
 			if (nodeExists) {
@@ -863,11 +1010,11 @@
 			assertEquals(
 				displayString() + " : The element should not have any children",
 				currentChildrenCount,
-				node.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 
 			// Retrieve the actual node
-			Node childNode = getChildNode(node);
+			Node childNode = getChildNode(holder.node);
 
 			if (nodeExists) {
 
@@ -894,7 +1041,7 @@
 			assertEquals(
 				displayString() + " : The element should not have any children",
 				currentChildrenCount,
-				node.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 		}
 
@@ -902,12 +1049,12 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testRemoving(FORM form, Node parentNode) {
+		void testRemoving(ExternalFormHolder holder) {
 
 			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
 
 			// Change the node value to null, which will remove it from the parent node
-			tester.setValue(form, null);
+			tester.setValue(holder.form, null);
 
 			if (nodeExists) {
 				nodeExists = false;
@@ -917,7 +1064,7 @@
 			assertEquals(
 				displayString() + " : The number of children is inconsistent",
 				currentChildrenCount,
-				parentNode.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 		}
 	}
@@ -931,8 +1078,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "*> : addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "*> : addition");
 		}
 
 		/**
@@ -940,7 +1087,7 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildListNodeTesterRunner runner = (ChildListNodeTesterRunner) this.runner;
 
@@ -959,9 +1106,9 @@
 			runner.currentChildrenCount = currentChildrenCount;
 			runner.addRange(startIndex, endIndex);
 			runner.rangeIndex = runner.ranges.size() - 1;
-			runner.testInitialState(form, node);
-			runner.testAdding(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
+			runner.testReading(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -976,8 +1123,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "*> : reading");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "*> : reading");
 		}
 
 		/**
@@ -985,7 +1132,7 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildListNodeTesterRunner runner = (ChildListNodeTesterRunner) this.runner;
 			int rangesCount = runner.ranges.size();
@@ -1001,8 +1148,8 @@
 			runner.rangeIndex = rangeIndex;
 
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testReading(holder);
 		}
 	}
 
@@ -1015,8 +1162,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "*> : removal");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "*> : removal");
 		}
 
 		/**
@@ -1024,7 +1171,7 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildListNodeTesterRunner runner = (ChildListNodeTesterRunner) this.runner;
 			int rangesCount = runner.ranges.size();
@@ -1040,8 +1187,8 @@
 			runner.rangeIndex = rangeIndex;
 
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testRemoving(form, node);
+			runner.testInitialState(holder);
+			runner.testRemoving(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -1073,11 +1220,12 @@
 		CHILD_FORM getChild(FORM form, int index);
 
 		/**
-		 * Returns
+		 * Returns the child form at the given position.
 		 *
-		 * @param childForms
-		 * @param index
-		 * @return
+		 * @param childForms The list of child forms that was collected from the {@link ExternalForm}
+		 * being tested
+		 * @param index The position of the child form to retrieve
+		 * @return The child form at the given position
 		 */
 		CHILD_FORM getChildForm(List<CHILD_FORM> childForms, int index);
 
@@ -1109,7 +1257,10 @@
 		CHILD_VALUE getChildValue(CHILD_FORM childForm);
 
 		/**
+		 * Retrieves the value to be expected at the given position when inserted into the document.
 		 *
+		 * @param index The position of the value used to insert a child node
+		 * @return The value at the given position that is used to insert a child node
 		 */
 		CHILD_VALUE getExpectedChildValue(int index);
 
@@ -1122,9 +1273,9 @@
 		List<CHILD_VALUE> getExpectedChildValues();
 
 		/**
-		 * Returns
+		 * Returns the ordered list of names that composes the different children being tested.
 		 *
-		 * @return
+		 * @return A non-<code>null</code> list of at least one item or more
 		 */
 		List<String> getNodeNames();
 
@@ -1158,6 +1309,12 @@
 			initialize(tester);
 		}
 
+		/**
+		 * Adds the given range of
+		 *
+		 * @param startIndex The beginning position of the range, inclusive
+		 * @param endIndex The end position of the range, exclusive
+		 */
 		void addRange(int startIndex, int endIndex) {
 			ranges.add(new Integer[] { Math.min(startIndex, endIndex), Math.max(startIndex, endIndex) });
 		}
@@ -1246,6 +1403,18 @@
 			return true;
 		}
 
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		boolean isNodeDeletedWithNullValue() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
 		void setup() {
 			rangeIndex = ranges.size();
 			ranges.add(new Integer[] { 0, getDefaultChildrenCount() });
@@ -1255,17 +1424,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void test(FORM form, Node node) {
-			setup();
-			super.test(form, node);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
 		@SuppressWarnings("unchecked")
-		void testAdding(FORM form, Node parent) {
+		void testAdding(ExternalFormHolder holder) {
 
 			ChildListNodeTester<FORM, Object, Object> tester = (ChildListNodeTester<FORM, Object, Object>) this.tester;
 			List<String> nodeNames = tester.getNodeNames();
@@ -1287,7 +1447,7 @@
 				);
 
 				// Create the child node
-				Object childForm = tester.addChild(form, value);
+				Object childForm = tester.addChild(holder.form, value);
 				currentChildrenCount++;
 				currentChildListCount++;
 
@@ -1298,7 +1458,7 @@
 
 				// Retrieve the list of child nodes and make sure it matches
 				// the number of child nodes that have been created so far
-				Node containerNode = getContainerNode(parent);
+				Node containerNode = getContainerNode(holder.node);
 				List<Node> childrenNode = getChildrenNodes(containerNode);
 
 				assertEquals(
@@ -1326,25 +1486,25 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void testInitialState(FORM form, Node parent) {
+		void testInitialState(ExternalFormHolder holder) {
 
 			ChildListNodeTester<FORM, Object, Object> tester = (ChildListNodeTester<FORM, Object, Object>) this.tester;
 
 			assertEquals(
 				displayString() + " : Incorrect number of children was retrieved",
 				currentChildListCount,
-				tester.getChildren(form).size()
+				tester.getChildren(holder.form).size()
 			);
 
 			// Test to make sure the number of child nodes is correctly retrieved
 			assertEquals(
 				displayString() + " : The number of children is inconsistent",
 				currentChildListCount,
-				tester.getChildrenSize(form)
+				tester.getChildrenSize(holder.form)
 			);
 
 			// Make sure nothing changed
-			Node containerNode = getContainerNode(parent);
+			Node containerNode = getContainerNode(holder.node);
 
 			if (containerNode == null) {
 				assertEquals(
@@ -1396,10 +1556,10 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void testReading(FORM form, Node node) {
+		void testReading(ExternalFormHolder holder) {
 
 			ChildListNodeTester<FORM, Object, Object> tester = (ChildListNodeTester<FORM, Object, Object>) this.tester;
-			List<Object> childForms = tester.getChildren(form);
+			List<Object> childForms = tester.getChildren(holder.form);
 
 			assertEquals(
 				displayString() + " : The number of children is inconsistent",
@@ -1416,7 +1576,7 @@
 				int translatedPosition = translatePosition(rangeIndex, index);
 
 				// Retrieve the child form
-				Object childForm = tester.getChild(form, translatedPosition);
+				Object childForm = tester.getChild(holder.form, translatedPosition);
 
 				assertNotNull(
 					displayString() + " : The child form cannot be null",
@@ -1471,7 +1631,7 @@
 				int translatedPosition = translatePosition(rangeIndex, index);
 
 				// Retrieve the child form
-				Object childForm = tester.getChild(form, translatedPosition);
+				Object childForm = tester.getChild(holder.form, translatedPosition);
 
 				assertNotNull(
 					displayString() + " : The child form cannot be null",
@@ -1509,7 +1669,7 @@
 		}
 
 		private void testReadingAfterRemoval(ChildListNodeTester<FORM, Object, Object> tester,
-		                                     FORM form,
+		                                     ExternalFormHolder holder,
 		                                     List<Object> childForms,
 		                                     List<Object> values,
 		                                     int rangesIndexToSkip,
@@ -1540,7 +1700,7 @@
 					}
 
 					// Retrieve the child form
-					Object childForm = tester.getChild(form, translatedPosition);
+					Object childForm = tester.getChild(holder.form, translatedPosition);
 
 					assertNotNull(
 						displayString() + " : The child form cannot be null",
@@ -1578,7 +1738,7 @@
 		}
 
 		private void testReadingAfterRemoval(ChildListNodeTester<FORM, Object, Object> tester,
-		                                     FORM form,
+		                                     ExternalFormHolder holder,
 		                                     List<Object> childForms,
 		                                     List<Object> values,
 		                                     List<Integer> positions) {
@@ -1588,7 +1748,7 @@
 			for (int position : positions) {
 
 				// Retrieve the child form
-				Object childForm = tester.getChild(form, childIndex++);
+				Object childForm = tester.getChild(holder.form, childIndex++);
 
 				assertNotNull(
 					displayString() + " : The child form cannot be null",
@@ -1612,7 +1772,7 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void testRemoving(FORM form, Node node) {
+		void testRemoving(ExternalFormHolder holder) {
 
 			// Nothing to test
 			if (ranges.isEmpty()) {
@@ -1622,7 +1782,7 @@
 			ChildListNodeTester<FORM, Object, Object> tester = (ChildListNodeTester<FORM, Object, Object>) this.tester;
 			Random random = new Random();
 			List<Object> values = tester.getExpectedChildValues();
-			List<Object> readOnlyChildForms = tester.getChildren(form);
+			List<Object> readOnlyChildForms = tester.getChildren(holder.form);
 
 			// Now remove all the children at random position and
 			// test reading the remaining between each removal
@@ -1658,7 +1818,7 @@
 				}
 
 				// Retrieve the child form
-				tester.removeChild(form, translatedPosition);
+				tester.removeChild(holder.form, translatedPosition);
 				currentChildrenCount--;
 				currentChildListCount--;
 
@@ -1674,10 +1834,10 @@
 				assertEquals(
 					displayString() + " : The number of children is inconsistent",
 					currentChildListCount,
-					tester.getChildrenSize(form)
+					tester.getChildrenSize(holder.form)
 				);
 
-				Node containerNode = getContainerNode(node);
+				Node containerNode = getContainerNode(holder.node);
 
 				if (containerNode == null) {
 					assertEquals(
@@ -1695,7 +1855,7 @@
 				}
 
 				// Retrieve the values that will be used to create the child nodes
-				List<Object> childForms = tester.getChildren(form);
+				List<Object> childForms = tester.getChildren(holder.form);
 
 				assertEquals(
 					displayString() + " : The number of children is inconsistent",
@@ -1708,10 +1868,10 @@
 				//
 				// Retrieve the child
 				if (rangeCount == 1) {
-					testReadingAfterRemoval(tester, form, readOnlyChildForms, values, readOnlyPositions);
+					testReadingAfterRemoval(tester, holder, readOnlyChildForms, values, readOnlyPositions);
 				}
 				else {
-					testReadingAfterRemoval(tester, form, childForms, values, rangeIndex, positions.size());
+					testReadingAfterRemoval(tester, holder, childForms, values, rangeIndex, positions.size());
 				}
 			}
 
@@ -1761,8 +1921,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
 		}
 
 		/**
@@ -1770,12 +1930,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildNodeTesterRunner runner = (ChildNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testAdding(form, node);
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -1790,8 +1950,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
 		}
 
 		/**
@@ -1799,12 +1959,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildNodeTesterRunner runner = (ChildNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testReading(holder);
 		}
 	}
 
@@ -1817,8 +1977,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
 		}
 
 		/**
@@ -1826,12 +1986,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ChildNodeTesterRunner runner = (ChildNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testRemoving(form, node);
+			runner.testInitialState(holder);
+			runner.testRemoving(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -1878,12 +2038,7 @@
 	/**
 	 * The runner associated with {@link ChildNodeTester}.
 	 */
-	private class ChildNodeTesterRunner extends NodeTesterRunner {
-
-		/**
-		 *
-		 */
-		private boolean hasChild;
+	private class ChildNodeTesterRunner extends AbstractChildNodeTesterRunner {
 
 		/**
 		 * Creates a new <code>ChildNodeTesterRunner</code>.
@@ -1894,24 +2049,291 @@
 			super(tester);
 		}
 
-		private String displayString() {
-			return "<" + getNodeName() + ">";
-		}
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testAdding(ExternalFormHolder holder) {
 
-		private Node getChildNode(Node node) {
-
-			node = node.getFirstChild();
-
-			while (node != null) {
-
-				if (getNodeName().equals(node.getNodeName())) {
-					return node;
-				}
-
-				node = node.getNextSibling();
+			// Don't add the child if it's present
+			if (hasChild) {
+				return;
 			}
 
-			return null;
+			ChildNodeTester<FORM, ? extends ExternalForm> tester = (ChildNodeTester<FORM, ?>) this.tester;
+
+			// Add the child node
+			ExternalForm childForm = tester.addChild(holder.form);
+			hasChild = true;
+			currentChildrenCount++;
+
+			assertNotNull(
+				displayString() + " : The child form should exist",
+				childForm
+			);
+
+			// Make sure the child node was indeed added
+			assertEquals(
+				displayString() + " : The number of children is inconsistent",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// Make sure the child node is correctly retrieved
+			assertTrue(
+				displayString() + " : The child node should have been found",
+				tester.hasChild(holder.form)
+			);
+
+			// Make sure the right child node was added and is retrieved by the ExternalForm
+			assertNotNull(
+				displayString() + " : The child node should exist",
+				getChildNode(holder.node)
+			);
+
+			// Make sure nothing changed
+			assertEquals(
+				displayString() + " : The child node should exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testInitialState(ExternalFormHolder holder) {
+
+			ChildNodeTester<FORM, ?> tester = (ChildNodeTester<FORM, ?>) this.tester;
+
+			// Make sure the child node does not exist
+			assertEquals(
+				displayString() + " : The child node should not exist",
+				hasChild,
+				tester.hasChild(holder.form)
+			);
+
+			// Make sure nothing changed
+			assertEquals(
+				displayString() + " : The child node should not exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// The child node should not exist
+			if (hasChild) {
+				assertNotNull(
+					displayString() + " : The child node should exist",
+					getChildNode(holder.node)
+				);
+			}
+			else {
+				assertNull(
+					displayString() + " : The child node should not exist",
+					getChildNode(holder.node)
+				);
+			}
+
+			// Make sure nothing changed
+			assertEquals(
+				displayString() + " : The child node should not exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testReading(ExternalFormHolder holder) {
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testRemoving(ExternalFormHolder holder) {
+
+			// Nothing to remove
+			if (!hasChild) {
+				return;
+			}
+
+			ChildNodeTester<FORM, ?> tester = (ChildNodeTester<FORM, ?>) this.tester;
+
+			// Make sure the child node exists
+			assertTrue(
+				displayString() + " : The child node should exist",
+				tester.hasChild(holder.form)
+			);
+
+			// Make sure nothing changed with the previous check
+			assertEquals(
+				displayString() + " : The child node should exist",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// Remove the child node
+			tester.removeChild(holder.form);
+			currentChildrenCount--;
+			hasChild = false;
+
+			// Make sure the child node was indeed removed
+			assertEquals(
+				displayString() + " : The child node should have been removed",
+				currentChildrenCount,
+				holder.node.getChildNodes().getLength()
+			);
+
+			// Make sure the right child node was removed
+			assertNull(
+				displayString() + " : The wrong child node was removed",
+				getChildNode(holder.node)
+			);
+
+			// Test to make sure the child node is not found
+			assertFalse(
+				displayString() + " : The child node should not exist",
+				tester.hasChild(holder.form)
+			);
+		}
+	}
+
+	/**
+	 * This controller tests adding one of the possible child nodes.
+	 */
+	private class ChoiceChildNodeRunnerAddingController extends Controller {
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		void log(Logger logger) {
+			ChoiceChildNodeTesterRunner runner = (ChoiceChildNodeTesterRunner) this.runner;
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getNodeName() + "> : addition");
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		void test(ExternalFormHolder holder) {
+
+			ChoiceChildNodeTesterRunner runner = (ChoiceChildNodeTesterRunner) this.runner;
+
+			// Create a random range within the list of values used to create the child nodes
+			Random random = new Random();
+			int index = random.nextInt(runner.testers.length);
+
+			runner.currentChildrenCount = currentChildrenCount;
+			runner.index = index;
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
+			runner.testReading(holder);
+
+			currentChildrenCount = runner.currentChildrenCount;
+		}
+	}
+
+	/**
+	 * This controller tests reading the child node that was added.
+	 */
+	private class ChoiceChildNodeRunnerReadingController extends Controller {
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		void log(Logger logger) {
+			ChoiceChildNodeTesterRunner runner = (ChoiceChildNodeTesterRunner) this.runner;
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getNodeName() + "> : reading");
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		void test(ExternalFormHolder holder) {
+
+			ChoiceChildNodeTesterRunner runner = (ChoiceChildNodeTesterRunner) this.runner;
+
+			runner.currentChildrenCount = currentChildrenCount;
+			runner.testInitialState(holder);
+			runner.testReading(holder);
+
+			currentChildrenCount = runner.currentChildrenCount;
+		}
+	}
+
+	/**
+	 * This controller tests removing the child node that was added.
+	 */
+	private class ChoiceChildNodeRunnerRemovingController extends Controller {
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		void log(Logger logger) {
+			ChoiceChildNodeTesterRunner runner = (ChoiceChildNodeTesterRunner) this.runner;
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getNodeName() + "> : removing");
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		@SuppressWarnings("unchecked")
+		void test(ExternalFormHolder holder) {
+
+			ChoiceChildNodeTesterRunner runner = (ChoiceChildNodeTesterRunner) this.runner;
+
+			runner.currentChildrenCount = currentChildrenCount;
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
+			runner.testReading(holder);
+
+			currentChildrenCount = runner.currentChildrenCount;
+		}
+	}
+
+	private class ChoiceChildNodeTesterRunner extends NodeTesterRunner {
+
+		/**
+		 * Specifies which child to add or remove.
+		 */
+		public int index;
+
+		/**
+		 * The testers for each of the child nodes when only one can be added.
+		 */
+		private ChildNodeTester<?, ?>[] testers;
+
+		/**
+		 * Creates a new <code>ChoiceChildNodeTesterRunner</code>.
+		 *
+		 * @param testers The testers for each of the child nodes when only one can be added
+		 */
+		ChoiceChildNodeTesterRunner(ChildNodeTester<?, ?>[] testers) {
+			super(null);
+			this.index   = -1;
+			this.testers = testers;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		String getNodeName() {
+			return testers[index].getNodeName();
 		}
 
 		/**
@@ -1926,152 +2348,36 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testAdding(FORM form, Node node) {
-
-			// Don't add the child if it's not present
-			if (hasChild) {
-				return;
-			}
-
-			ChildNodeTester<FORM, ? extends ExternalForm> tester = (ChildNodeTester<FORM, ?>) this.tester;
-
-			// Add the child node
-			ExternalForm childForm = tester.addChild(form);
-			hasChild = true;
-			currentChildrenCount++;
-
-			assertNotNull(
-				displayString() + " : The child form should exist",
-				childForm
-			);
-
-			// Make sure the child node was indeed added
-			assertEquals(
-				displayString() + " : The number of children is inconsistent",
-				currentChildrenCount,
-				node.getChildNodes().getLength()
-			);
-
-			// Make sure the child node is correctly retrieved
-			assertTrue(
-				displayString() + " : The child node should have been found",
-				tester.hasChild(form)
-			);
-
-			// Make sure the right child node was added and is retrieved by the ExternalForm
-			assertNotNull(
-				displayString() + " : The child node should exist",
-				getChildNode(node)
-			);
-
-			// Make sure nothing changed
-			assertEquals(
-				displayString() + " : The child node should exist",
-				currentChildrenCount,
-				node.getChildNodes().getLength()
-			);
+		boolean isNodeDeletedWithNullValue() {
+			return false;
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testInitialState(FORM form, Node node) {
-
-			ChildNodeTester<FORM, ?> tester = (ChildNodeTester<FORM, ?>) this.tester;
-
-			// Make sure the child node does not exist
-			assertEquals(
-				displayString() + " : The child node should not exist",
-				hasChild,
-				tester.hasChild(form)
-			);
-
-			// Make sure nothing changed
-			assertEquals(
-				displayString() + " : The child node should not exist",
-				currentChildrenCount,
-				node.getChildNodes().getLength()
-			);
-
-			// The child node should not exist
-			if (hasChild) {
-				assertNotNull(
-					displayString() + " : The child node should exist",
-					getChildNode(node)
-				);
-			}
-			else {
-				assertNull(
-					displayString() + " : The child node should not exist",
-					getChildNode(node)
-				);
-			}
-
-			// Make sure nothing changed
-			assertEquals(
-				displayString() + " : The child node should not exist",
-				currentChildrenCount,
-				node.getChildNodes().getLength()
-			);
+		void testAdding(ExternalFormHolder holder) {
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testReading(FORM form, Node node) {
+		void testInitialState(ExternalFormHolder holder) {
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testRemoving(FORM form, Node node) {
+		void testReading(ExternalFormHolder holder) {
+		}
 
-			// Nothing to remove
-			if (!hasChild) {
-				return;
-			}
-
-			ChildNodeTester<FORM, ?> tester = (ChildNodeTester<FORM, ?>) this.tester;
-
-			// Make sure the child node exists
-			assertTrue(
-				displayString() + " : The child node should exist",
-				tester.hasChild(form)
-			);
-
-			// Make sure nothing changed with the previous check
-			assertEquals(
-				displayString() + " : The child node should exist",
-				currentChildrenCount,
-				node.getChildNodes().getLength()
-			);
-
-			// Remove the child node
-			tester.removeChild(form);
-			currentChildrenCount--;
-			hasChild = false;
-
-			// Make sure the child node was indeed removed
-			assertEquals(
-				displayString() + " : The child node should have been removed",
-				currentChildrenCount,
-				node.getChildNodes().getLength()
-			);
-
-			// Make sure the right child node was removed
-			assertNull(
-				displayString() + " : The wrong child node was removed",
-				getChildNode(node)
-			);
-
-			// Test to make sure the child node is not found
-			assertFalse(
-				displayString() + " : The child node should not exist",
-				tester.hasChild(form)
-			);
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testRemoving(ExternalFormHolder holder) {
 		}
 	}
 
@@ -2085,9 +2391,9 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void log() {
+		void log(Logger logger) {
 			ContainerChildListNodeTesterRunner runner = (ContainerChildListNodeTesterRunner) this.runner;
-			System.out.println("<" + runner.parentNodeName + "><" + runner.getContainerNodeName() + "> : addition");
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getContainerNodeName() + "> : adding");
 		}
 
 		/**
@@ -2095,7 +2401,7 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ContainerChildListNodeTesterRunner runner = (ContainerChildListNodeTesterRunner) this.runner;
 
@@ -2114,9 +2420,9 @@
 			runner.currentChildrenCount = currentChildrenCount;
 			runner.runner.addRange(startIndex, endIndex);
 			runner.runner.rangeIndex = runner.runner.ranges.size() - 1;
-			runner.testInitialState(form, node);
-			runner.testAdding(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
+			runner.testReading(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -2132,9 +2438,9 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void log() {
+		void log(Logger logger) {
 			ContainerChildListNodeTesterRunner runner = (ContainerChildListNodeTesterRunner) this.runner;
-			System.out.println("<" + runner.parentNodeName + "><" + runner.getContainerNodeName() + "> : reading");
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getContainerNodeName() + "> : reading");
 		}
 
 		/**
@@ -2142,7 +2448,7 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ContainerChildListNodeTesterRunner runner = (ContainerChildListNodeTesterRunner) this.runner;
 			int rangesCount = runner.runner.ranges.size();
@@ -2158,8 +2464,8 @@
 			runner.runner.rangeIndex = rangeIndex;
 
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testReading(holder);
 		}
 	}
 
@@ -2173,9 +2479,9 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void log() {
+		void log(Logger logger) {
 			ContainerChildListNodeTesterRunner runner = (ContainerChildListNodeTesterRunner) this.runner;
-			System.out.println("<" + runner.parentNodeName + "><" + runner.getContainerNodeName() + "> : removing");
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.getContainerNodeName() + "> : removing");
 		}
 
 		/**
@@ -2183,7 +2489,7 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			ContainerChildListNodeTesterRunner runner = (ContainerChildListNodeTesterRunner) this.runner;
 			int rangesCount = runner.runner.ranges.size();
@@ -2199,8 +2505,8 @@
 			runner.runner.rangeIndex = rangeIndex;
 
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testRemoving(form, node);
+			runner.testInitialState(holder);
+			runner.testRemoving(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -2304,32 +2610,40 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void test(FORM form, Node node) {
-			runner.setup();
-			super.test(form, node);
+		boolean isNodeDeletedWithNullValue() {
+			return false;
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testAdding(FORM form, Node parent) {
+		void test(ExternalFormHolder holder) {
+			runner.setup();
+			super.test(holder);
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testAdding(ExternalFormHolder holder) {
 
 			// Check to see if the container node will be added during addition
-			Node childNode = getNode(parent);
+			Node childNode = getNode(holder.node);
 
 			if (childNode == null) {
 				currentChildrenCount++;
 			}
 
 			// Delegate the call
-			runner.testAdding(form, parent);
+			runner.testAdding(holder);
 
 			// Test to make sure the children were added to the container node
 			assertEquals(
 				runner.displayString() + " : The child nodes were not created correctly",
 				currentChildrenCount,
-				parent.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 		}
 
@@ -2337,29 +2651,29 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testInitialState(FORM form, Node parent) {
-			runner.testInitialState(form, parent);
+		void testInitialState(ExternalFormHolder holder) {
+			runner.testInitialState(holder);
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testReading(FORM form, Node parent) {
-			runner.testReading(form, parent);
+		void testReading(ExternalFormHolder holder) {
+			runner.testReading(holder);
 		}
 
 		/**
 		 * {@inheritDoc}
 		 */
 		@Override
-		void testRemoving(FORM form, Node parent) {
+		void testRemoving(ExternalFormHolder holder) {
 
 			// Delegate the call
-			runner.testRemoving(form, parent);
+			runner.testRemoving(holder);
 
 			// Make sure the deletion happened correctly
-			Node childNode = getNode(parent);
+			Node childNode = getNode(holder.node);
 
 			if (runner.currentChildListCount == 0) {
 
@@ -2380,21 +2694,22 @@
 			assertEquals(
 				displayString() + " : The child nodes were not removed correctly",
 				currentChildrenCount,
-				parent.getChildNodes().getLength()
+				holder.node.getChildNodes().getLength()
 			);
 		}
 	}
 
 	/**
-	 *
+	 * This is used to retrieve the actual container of the node being tested.
 	 */
 	interface ContainerNodeRetriever {
 
 		/**
-		 * Retrieves
+		 * Retrieves the node that contains the child nodes, which may differ from the given node that
+		 * is been manipulated by its {@link ExternalForm}.
 		 *
-		 * @param parent
-		 * @return
+		 * @param parent The parent node manipulated by the {@link ExternalForm} being tested
+		 * @return Either the given node or a child node acting like a container
 		 */
 		Node getContainerNode(Node parent);
 	}
@@ -2419,16 +2734,17 @@
 
 		/**
 		 * Outputs what is being executed, used for debug purposes.
+		 *
+		 * @param logger Used to log messages during execution
 		 */
-		abstract void log();
+		abstract void log(Logger logger);
 
 		/**
 		 * Executes one of the operations that can be performed on an node.
 		 *
-		 * @param form The {@link ExternalForm} to test
-		 * @param node The node that is manipulated by the given {@link ExternalForm}
+		 * @param holder The holder of The {@link ExternalForm} to test and the node that is manipulated
 		 */
-		abstract void test(FORM form, Node node);
+		abstract void test(ExternalFormHolder holder);
 
 		/**
 		 * {@inheritDoc}
@@ -2439,7 +2755,879 @@
 		}
 	}
 
-	private class DefaultRootNodeTester implements RootNodeTester<FORM> {
+	/**
+	 * A <code>ExternalFormBuilder</code> is responsible to create the {@link ExternalForm} to be tested.
+	 */
+	public interface ExternalFormBuilder<FORM extends ExternalForm> {
+
+		/**
+		 * Creates the {@link ExternalForm} to test.
+		 *
+		 * @return The {@link ExternalForm} to test
+		 * @throws IOException If an error occurred during the creation process
+		 */
+		FORM buildExternalForm() throws IOException;
+
+		/**
+		 * Adds
+		 *
+		 * @param form
+		 * @return
+		 */
+		FORM buildExternalForm(ExternalForm parentForm);
+
+		/**
+		 * Returns the number of attributes the {@link Node} contains before any manipulation has been performed.
+		 *
+		 * @return The count of children before any testing has been done
+		 */
+		int getDefaultAttributeCount();
+
+		/**
+		 * Returns the node represented by the {@link ExternalForm}.
+		 *
+		 * @param form The {@link ExternalForm} for which to return its node
+		 * @return The node from the document that is been manipulated
+		 */
+		Node getNode(FORM form);
+
+		/**
+		 * Returns
+		 *
+		 * @return
+		 */
+		String getNodeName();
+
+		/**
+		 * Returns
+		 *
+		 * @return
+		 */
+		List<String> getTreeNodeNames();
+	}
+
+	private abstract class ExternalFormHolder {
+
+		/**
+		 *
+		 */
+		FORM form;
+
+		/**
+		 * @param form The {@link ExternalForm} to test
+		 * @param node The node that is manipulated by the given {@link ExternalForm}
+		 */
+		Node node;
+
+		/**
+		 *
+		 */
+		abstract void rebuild();
+	}
+
+	private interface NodeCountRetriever {
+		int getCount(Node parent);
+	}
+
+	/**
+	 * The root interface of the testers defined to test the manipulation of a node's property (either
+	 * an attribute, a single child node, a list of child nodes or a text node).
+	 */
+
+	private interface NodeTester<FORM extends ExternalForm, Value> {
+		/**
+		 * Retrieves the name of the node for which retrieving and setting its value is tested.
+		 *
+		 * @return The name of the node to test
+		 */
+		String getNodeName();
+	}
+
+	/**
+	 * This is the root of the runner class, which is associated with a {@link NodeTester}.
+	 */
+	private abstract class NodeTesterRunner {
+
+		/**
+		 * Keeps track of the current count of child nodes owned by the node being manipulated.
+		 */
+		int currentChildrenCount;
+
+		/**
+		 *
+		 */
+		@SuppressWarnings("unused")
+		ExternalFormHolder holder;
+
+		/**
+		 * For debug purposes, this is the name of the parent node.
+		 */
+		String parentNodeName;
+
+		/**
+		 * This object defines a single node to test (which is either a child element or an attribute).
+		 */
+		final NodeTester<FORM, Object> tester;
+
+		/**
+		 * Creates a new <code>AbstractNodeTester</code>.
+		 *
+		 * @param tester The bridge between this tester and the document's node being tested
+		 */
+		@SuppressWarnings("unchecked")
+		NodeTesterRunner(NodeTester<FORM, ?> tester) {
+			super();
+			this.tester = (NodeTester<FORM, Object>) tester;
+			assertNotNull("The tester cannot be null: "    + tester, tester);
+			assertNotNull("The node name cannot be null: " + tester, tester.getNodeName());
+		}
+
+		/**
+		 * Returns
+		 *
+		 * @return
+		 */
+		String getActualNodeName() {
+			return getNodeName();
+		}
+
+		/**
+		 * Returns the name of the node for which this runner tests.
+		 *
+		 * @return The node name
+		 */
+		String getNodeName() {
+			return tester.getNodeName();
+		}
+
+		/**
+		 * Determines whether
+		 *
+		 * @return
+		 */
+		abstract boolean isMultipleSupported();
+
+		/**
+		 * Determines whether the node being tested is removed from its parent element when the value
+		 * set is <code>null</code>.
+		 *
+		 * @return <code>true</code> if the node is removed from its parents after the property is
+		 * nullified; <code>false</code> if it is not removed
+		 */
+		abstract boolean isNodeDeletedWithNullValue();
+
+		/**
+		 * Notification before a test is performed.
+		 */
+		void setup() {
+		}
+
+		/**
+		 * Tests the given {@link ExternalForm} by manipulating the node for a single property.
+		 *
+		 * @param holder The holder of The {@link ExternalForm} to test and the node that is manipulated
+		 */
+		void test(ExternalFormHolder holder) {
+			setup();
+			testInitialState(holder);
+			testAdding(holder);
+			testReading(holder);
+			testRemoving(holder);
+		}
+
+		/**
+		 * Tests the given {@link ExternalForm} by adding the property to the node.
+		 *
+		 * @param holder The holder of The {@link ExternalForm} to test and the node that is manipulated
+		 */
+		abstract void testAdding(ExternalFormHolder holder);
+
+		/**
+		 * Tests the given {@link ExternalForm} by making sure the given node is in its original state.
+		 *
+		 * @param holder The holder of The {@link ExternalForm} to test and the node that is manipulated
+		 */
+		abstract void testInitialState(ExternalFormHolder holder);
+
+		/**
+		 * Tests the given {@link ExternalForm} by reading the property from the node.
+		 *
+		 * @param holder The holder of The {@link ExternalForm} to test and the node that is manipulated
+		 */
+		abstract void testReading(ExternalFormHolder holder);
+
+		/**
+		 * Tests the given {@link ExternalForm} by removing the property from the node.
+		 *
+		 * @param holder The holder of The {@link ExternalForm} to test and the node that is manipulated
+		 */
+		abstract void testRemoving(ExternalFormHolder holder);
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public String toString() {
+			return getClass().getSimpleName() + " : " + tester.getNodeName();
+		}
+	}
+
+	/**
+	 * This <code>AttributeNodeTester</code> does nothing, it is used when an attribute is not
+	 * currently by the {@link ExternalForm}.
+	 */
+	private class NotSupportedAttributeTester implements AttributeNodeTester<FORM, Object> {
+
+		/**
+		 * The name of the attribute that is not supported by the {@link ExternalForm}.
+		 */
+		private String attributeName;
+
+		/**
+		 * Creates a new <code>NotSupportedAttributeTester</code>.
+		 *
+		 * @param attributeName The name of the attribute that is not supported by the {@link ExternalForm}
+		 */
+		NotSupportedAttributeTester(String attributeName) {
+			super();
+			this.attributeName = attributeName;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public boolean doesNodeAlreadyExist() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public Object getDefaultValue() {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public String getNodeName() {
+			return attributeName;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public Object getValue(FORM form) {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public Object getValue1() {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public Object getValue2() {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public boolean isNodeDeletedWithNullValue() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public boolean isNullAllowed() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void setValue(FORM form, Object value) {
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public String toString(Object value) {
+			return null;
+		}
+	}
+
+	/**
+	 * This runner simply does nothing but adds support for adding an attribute name into the list of
+	 * attributes so that the ordering defined by the XML schema is properly tested.
+	 */
+	private class NotSupportedAttributeTesterRunner extends AttributeNodeTesterRunner {
+
+		/**
+		 * Creates a new <code>NotSupportedAttributeTesterRunner</code>.
+		 *
+		 * @param attributeName The name of the attribute that is currently not supported by the
+		 * {@link ExternalForm}
+		 */
+		NotSupportedAttributeTesterRunner(String attributeName) {
+			super(new NotSupportedAttributeTester(attributeName));
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testAdding(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testInitialState(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testReading(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testRemoving(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+	}
+
+	/**
+	 * This wraps a node name that is currently not supported by the Mapping SPI.
+	 */
+	private class NotSupportedNodeTester implements NodeTester<FORM, Object> {
+
+		/**
+		 * The name of the node that is currently not supported by the {@link ExternalForm}.
+		 */
+		private String nodeName;
+
+		/**
+		 * Creates a new <code>NotSupportedNodeTester</code>.
+		 *
+		 * @param nodeName The name of the node that is currently not supported by the {@link ExternalForm}
+		 */
+		NotSupportedNodeTester(String nodeName) {
+			super();
+			this.nodeName = nodeName;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public String getNodeName() {
+			return nodeName;
+		}
+	}
+
+	/**
+	 * This runner simply does nothing but adds support for adding a node name into the list of child
+	 * nodes so that the ordering defined by the XML schema is properly tested.
+	 */
+	private class NotSupportedNodeTesterRunner extends NodeTesterRunner {
+
+		/**
+		 * Creates a new <code>NotSupportedNodeTesterRunner</code>.
+		 *
+		 * @param nodeName The name of the node that is currently not supported by the {@link ExternalForm}
+		 */
+		NotSupportedNodeTesterRunner(String nodeName) {
+			super(new NotSupportedNodeTester(nodeName));
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		boolean isMultipleSupported() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		boolean isNodeDeletedWithNullValue() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testAdding(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testInitialState(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testReading(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testRemoving(ExternalFormHolder holder) {
+			// Nothing to do
+		}
+	}
+
+	private abstract class PropertyNodeTesterRunner extends NodeTesterRunner {
+
+		/**
+		 * Keeps track of the status of the node's existence.
+		 */
+		private boolean nodeExists;
+
+		/**
+		 * Creates a new <code>PropertyNodeTesterRunner</code>.
+		 *
+		 * @param tester This object defines a single node to test a child text node
+		 */
+		PropertyNodeTesterRunner(PropertyTester<FORM, ?> tester) {
+			super(tester);
+		}
+
+		/**
+		 * Returns the display string representing this runner.
+		 *
+		 * @return A description of the node being tested
+		 */
+		abstract String displayString();
+
+		/**
+		 * Returns the number of children owned by the given parent {@link Node}.
+		 *
+		 * @param parentNode The owner of the child node being tested
+		 * @return The count of children, which could be either attributes or child nodes
+		 */
+		abstract int getChildrenCount(Node parentNode);
+
+		/**
+		 * Returns the node being tested.
+		 *
+		 * @param parentNode The owner of the node being tested
+		 * @return The child node of the given node that is being tested
+		 */
+		abstract Node getNode(Node parentNode);
+
+		/**
+		 * Returns the value of the given node.
+		 *
+		 * @param node The node being tested
+		 * @return The value being tested
+		 */
+		abstract String getNodeValue(Node node);
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		final boolean isMultipleSupported() {
+			return false;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		boolean isNodeDeletedWithNullValue() {
+			return propertyTester().isNodeDeletedWithNullValue();
+		}
+
+		PropertyTester<FORM, Object> propertyTester() {
+			return (PropertyTester<FORM, Object>) tester;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testAdding(ExternalFormHolder holder) {
+
+			PropertyTester<FORM, Object> tester = propertyTester();
+
+			// Change the node value to null
+			if (tester.isNullAllowed()) {
+
+				tester.setValue(holder.form, null);
+
+				if (nodeExists) {
+					nodeExists = false;
+					currentChildrenCount--;
+				}
+
+				assertEquals(
+					displayString() + " : The element should not have any children",
+					currentChildrenCount,
+					getChildrenCount(holder.node)
+				);
+
+				// Make sure nothing changed
+				Object result = tester.getValue(holder.form);
+
+				assertNull(
+					displayString() + " : The element's value should be null",
+					result
+				);
+
+				// Make sure nothing changed
+				assertEquals(
+					displayString() + " : The element should not have any children",
+					currentChildrenCount,
+					getChildrenCount(holder.node)
+				);
+
+				if (tester.isNodeDeletedWithNullValue()) {
+					holder.rebuild();
+				}
+			}
+
+			// Change the value to something
+			Object expectedValue1 = tester.getValue1();
+
+			assertNotNull(
+				displayString() + " : Value 1 cannot be null",
+				expectedValue1
+			);
+
+			tester.setValue(holder.form, expectedValue1);
+
+			if (!nodeExists) {
+				nodeExists = true;
+				currentChildrenCount++;
+			}
+
+			// The child node should have been added
+			Node childNode = getNode(holder.node);
+
+			assertNotNull(
+				displayString() + " : The node cannot be null",
+				childNode
+			);
+
+			assertEquals(
+				displayString() + " : The element should have a " + currentChildrenCount + " children",
+				currentChildrenCount,
+				getChildrenCount(holder.node)
+			);
+
+			// Get the value
+			Object result = tester.getValue(holder.form);
+
+			assertEquals(
+				displayString() + " : The element's value was not set correctly",
+				expectedValue1,
+				result
+			);
+
+			// Get the value directly
+			String stringResult = getNodeValue(childNode);
+			String stringNodeValue = tester.toString(expectedValue1);
+
+			assertEquals(
+				displayString() + " : The value was not set correctly",
+				stringNodeValue,
+				stringResult
+			);
+
+			// Change the value to something else
+			Object expectedValue2 = tester.getValue2();
+			assertNotNull(displayString() + " : Value 2 cannot be null", expectedValue2);
+
+			assertNotSame(
+				displayString() + " : Value 1 and value 2 cannot be the same",
+				expectedValue1,
+				expectedValue2
+			);
+
+			tester.setValue(holder.form, expectedValue2);
+
+			// Get the value
+			result = tester.getValue(holder.form);
+
+			assertEquals(
+				displayString() + " The element's value was not set correctly",
+				expectedValue2,
+				result
+			);
+
+			// Get the value directly
+			stringResult = getNodeValue(childNode);
+			stringNodeValue = tester.toString(expectedValue2);
+
+			assertEquals(
+				displayString() + " : The element's value was not set correctly",
+				stringNodeValue,
+				stringResult
+			);
+
+			// Change the value back to its original value
+			Object defaultValue = tester.getDefaultValue();
+
+			assertNotNull(
+				displayString() + " : The default value cannot be null",
+				defaultValue
+			);
+
+			tester.setValue(holder.form, defaultValue);
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testInitialState(ExternalFormHolder holder) {
+
+			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
+			nodeExists |= tester.doesNodeAlreadyExist();
+
+			// Node name
+			String nodeName = getNodeName();
+			assertNotNull("The node name cannot be null", nodeName);
+
+			// Test the initial state of the parent node
+			assertEquals(
+				displayString() + " : The child count is incorrect",
+				currentChildrenCount,
+				getChildrenCount(holder.node)
+			);
+
+			// The child node should either not exist or already being present
+			Node childNode = getNode(holder.node);
+
+			if (nodeExists) {
+				assertNotNull(
+					displayString() + " : The node should not be null",
+					childNode
+				);
+			}
+			else {
+				assertNull(
+					displayString() + " : The node should be null",
+					childNode
+				);
+			}
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testReading(ExternalFormHolder holder) {
+
+			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
+
+			// The node value should either be null or not null
+			Object result = tester.getValue(holder.form);
+
+			// Make sure the node's value is not null
+			if (nodeExists) {
+				assertNotNull(
+					displayString() + " : The element's value should not be null",
+					result
+				);
+				assertSame(
+					displayString() + " : The element's value was not retrived correctly",
+					tester.getDefaultValue(),
+					result
+				);
+			}
+			// The node is not present, make sure reading its value returns null
+			else {
+				assertNull(
+					displayString() + " : The element's value should be null",
+					result
+				);
+			}
+
+			// Make sure nothing changed by reading the node's value
+			assertEquals(
+				displayString() + " : The element should not have any children",
+				currentChildrenCount,
+				getChildrenCount(holder.node)
+			);
+
+			// Retrieve the actual node
+			Node childNode = getNode(holder.node);
+
+			if (nodeExists) {
+				assertNotNull(
+					displayString() + " : The node should not be null",
+					childNode
+				);
+			}
+			else {
+				assertNull(
+					displayString() + " : The node should be null",
+					childNode
+				);
+			}
+
+			// Make sure nothing changed after retrieving the node
+			assertEquals(
+				displayString() + " : The element should not have any children",
+				currentChildrenCount,
+				getChildrenCount(holder.node)
+			);
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		void testRemoving(ExternalFormHolder holder) {
+
+			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
+
+			// Change the node value to null, which will remove it from the parent node
+			if (tester.isNullAllowed()) {
+
+				tester.setValue(holder.form, null);
+
+				if (nodeExists) {
+					nodeExists = false;
+					currentChildrenCount--;
+				}
+
+				assertEquals(
+					displayString() + " : The child count does not match the current state",
+					currentChildrenCount,
+					getChildrenCount(holder.node)
+				);
+			}
+		}
+	}
+
+	/**
+	 * A <code>PropertyTester</code> handles testing either an attribute or a single child node of
+	 * the node being tested.
+	 */
+	private interface PropertyTester<FORM extends ExternalForm, VALUE> extends NodeTester<FORM, VALUE> {
+
+		/**
+		 * Determines whether the property is by default present in the document.
+		 *
+		 * @return <code>true</code> if the property exists before any changes is done to the document;
+		 * <code>false</code> otherwise
+		 */
+		boolean doesNodeAlreadyExist();
+
+		/**
+		 * If {@link #doesNodeAlreadyExist()} returns <code>true</code>, then this should return the
+		 * node value that is already present in the document, which is done before the document is
+		 * being changed.
+		 *
+		 * @return Either a non-<code>null</code> value if the node is present in the document or
+		 * <code>null</code> if the node is not by default present in the document
+		 */
+		VALUE getDefaultValue();
+
+		/**
+		 * Retrieves the value of the node.
+		 *
+		 * @param form The external form that will retrieve the value
+		 * @return The value, which can be <code>null</code>
+		 */
+		VALUE getValue(FORM form);
+
+		/**
+		 * Retrieves a non-<code>null</code> value that will be used for testing that is different
+		 * than the one returned by {@link #getValue2()}.
+		 *
+		 * @return A non-<code>null</code> value used for testing
+		 */
+		VALUE getValue1();
+
+		/**
+		 * Retrieves a non-<code>null</code> value that will be used for testing that is different
+		 * than the one returned by {@link #getValue1()}.
+		 *
+		 * @return A non-<code>null</code> value used for testing
+		 */
+		VALUE getValue2();
+
+		/**
+		 * Determines whether the node being tested is removed from its parent element when the value
+		 * set is <code>null</code>.
+		 *
+		 * @return <code>true</code> if the node is removed from its parents after the property is
+		 * nullified; <code>false</code> if it is not removed
+		 */
+		boolean isNodeDeletedWithNullValue();
+
+		/**
+		 * Determines whether the node can receive a <code>null</code> value or not.
+		 *
+		 * @return <code>true</code> if <code>null</code> is a valid value; <code>false</code> otherwise
+		 */
+		boolean isNullAllowed();
+
+		/**
+		 * Sets the value of the node.
+		 *
+		 * @param form The external form that will set the value
+		 * @return The value, which can be <code>null</code>
+		 */
+		void setValue(FORM form, VALUE value);
+
+		/**
+		 * Converts the value to its string representation.
+		 *
+		 * @param value A non-<code>null</code> value to convert into a string
+		 * @return The given value represented as a string
+		 */
+		String toString(VALUE value);
+	}
+
+	/**
+	 * A <code>RootNodeTester</code> is the container of all the testers that will test every single
+	 * property of the node to test, i.e. its attributes and child nodes.
+	 */
+	public final class RootNodeTester {
 
 		/**
 		 * The list of testers that used to test every single attribute
@@ -2459,82 +3647,106 @@
 		private List<NodeTesterRunner> children;
 
 		/**
-		 * Creates a new <code>DefaultRootNodeTester</code>.
+		 * Creates a new <code>RootNodeTester</code>.
 		 */
-		private DefaultRootNodeTester() {
+		private RootNodeTester() {
 			super();
 			attributes = new ArrayList<AttributeNodeTesterRunner>();
 			children   = new ArrayList<NodeTesterRunner>();
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given tester when the form has an attribute.
+		 *
+		 * @param tester The tester for a single attribute
 		 */
-		@Override
 		public void addAttribute(AttributeNodeTester<FORM, ?> tester) {
 			attributes.add(new AttributeNodeTesterRunner(tester));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given tester when the form representing the node it represents can have one child
+		 * node of a certain type and its property is represented by a boolean value.
+		 *
+		 * @param tester The tester for a single child node
 		 */
-		@Override
 		public void addBooleanNode(BooleanChildNodeTester<FORM> tester) {
 			children.add(new BooleanChildNodeTesterRunner(tester));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given tester when the form has a child node with a single attribute.
+		 *
+		 * @param tester The tester for a single attribute owned by a single child node
 		 */
-		@Override
 		public void addChildAttribute(ChildAttributeTester<FORM,?> tester) {
 			children.add(new ChildAttributeTesterRunner(tester));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given list of testers when the form has a single child node from a list of choices.
+		 *
+		 * @param testers The testers for each of the child nodes when only one can be added
 		 */
-		@Override
+		public void addChoiceNodes(ChildNodeTester<?, ?>[] testers) {
+			children.add(new ChoiceChildNodeTesterRunner(testers));
+		}
+
+		/**
+		 * Adds the given tester when the form representing the node it represents can have zero or
+		 * many child nodes of the same type (i.e. with the same node name).
+		 *
+		 * @param tester The tester for a list of child nodes with the same type
+		 */
 		public void addContainerListNodes(ContainerChildListNodeTester<FORM, ?, ?> tester) {
 			children.add(new ContainerChildListNodeTesterRunner(tester));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given tester when the form representing the node it represents can have zero or
+		 * many child nodes of the same type (i.e. with the same node name).
+		 *
+		 * @param tester The tester for a list of child nodes with the same type
 		 */
-		@Override
 		public void addListNodes(ChildListNodeTester<FORM, ?, ?> tester) {
 			children.add(new ChildListNodeTesterRunner(tester));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given tester when the form representing the node it represents can have one child
+		 * node of a certain type.
+		 *
+		 * @param tester The tester for a single child node
 		 */
-		@Override
 		public void addNode(ChildNodeTester<FORM, ?> tester) {
 			children.add(new ChildNodeTesterRunner(tester));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given tester when the form has a single child node that is a text node.
+		 *
+		 * @param tester The tester for a single child text node
 		 */
-		@Override
 		public void addTextNode(TextNodeTester<FORM, ?> tester) {
 			children.add(new TextNodeTesterRunner(tester));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given attribute name to indicate it is part of the "root" node but it is not
+		 * supported by the {@link ExternalForm} yet.
+		 *
+		 * @param attributeName The name of the attribute not currently supported
 		 */
-		@Override
 		public void addUnsupportedAttribute(String attributeName) {
 			attributes.add(new NotSupportedAttributeTesterRunner(attributeName));
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Adds the given node name to indicate it is part of the "root" node but it is not supported
+		 * by the {@link ExternalForm} yet.
+		 *
+		 * @param nodeName The name of the node not currently supported
 		 */
-		@Override
 		public void addUnsupportedNode(String nodeName) {
 			children.add(new NotSupportedNodeTesterRunner(nodeName));
 		}
@@ -2624,6 +3836,15 @@
 				}
 			);
 
+			classes.put(
+				ChoiceChildNodeTesterRunner.class,
+				new Class<?>[] {
+					ChoiceChildNodeRunnerAddingController.class,
+					ChoiceChildNodeRunnerReadingController.class,
+					ChoiceChildNodeRunnerRemovingController.class
+				}
+			);
+
 			return classes;
 		}
 
@@ -2636,6 +3857,17 @@
 			};
 		}
 
+		private ExternalFormHolder buildExternalFormHolder() {
+			return new ExternalFormHolder() {
+				@Override
+				void rebuild() {
+					form = ObjectTools.execute(form, "getParent");
+					form = builder.buildExternalForm(form);
+					node = ObjectTools.execute(form, "getElement");
+				}
+			};
+		}
+
 		private String displayString() {
 			return "<" + builder.getNodeName() + ">";
 		}
@@ -2691,9 +3923,10 @@
 		}
 
 		/**
-		 * {@inheritDoc}
+		 * Sets the builder that will create the document and tree node representation down to node to test.
+		 *
+		 * @param builder The builder of the node to test
 		 */
-		@Override
 		@SuppressWarnings("unchecked")
 		public void setBuilder(ExternalFormBuilder<? extends FORM> builder) {
 			this.builder = (ExternalFormBuilder<FORM>) builder;
@@ -2729,20 +3962,24 @@
 				node
 			);
 
+			ExternalFormHolder holder = buildExternalFormHolder();
+			holder.form = form;
+			holder.node = node;
+
 			// Test each attribute
-			testAttributes(form, node);
+			testAttributes(holder);
 
 			// Test each child node
-			testChildren(form, node);
+			testChildren(holder);
 
 			// Now test manipulating the attributes in random order
-			testAttributesRandomly(form, node);
+			testAttributesRandomly(holder);
 
 			// Now test manipulating the child nodes in random order
-			testChildNodesRandomly(form, node);
+			testChildNodesRandomly(holder);
 		}
 
-		private void testAttributes(FORM form, Node node) {
+		private void testAttributes(ExternalFormHolder holder) {
 
 			int defaultAttributeCount = builder.getDefaultAttributeCount();
 
@@ -2750,53 +3987,68 @@
 
 				runner.currentChildrenCount = defaultAttributeCount;
 				runner.parentNodeName = builder.getNodeName();
-				runner.test(form, node);
+				runner.test(holder);
 
+				// The node was deleted when testing with a null value,
+				// make sure the node is rebuilt before runner the next tester
+				if (runner.isNodeDeletedWithNullValue()) {
+					holder.rebuild();
+				}
+
+				// Make sure the number of attributes didn't change after the test
 				assertEquals(
 					displayString() + " : The number of attributes is inconsistent",
 					defaultAttributeCount,
-					node.getAttributes().getLength()
+					holder.node.getAttributes().getLength()
+				);
+
+				// Make sure the number of children didn't change after the test
+				assertEquals(
+					displayString() + " : The number of children is inconsistent",
+					0,
+					holder.node.getChildNodes().getLength()
 				);
 			}
 		}
 
-		private void testAttributesRandomly(FORM form, Node parent) throws Exception {
+		private void testAttributesRandomly(ExternalFormHolder holder) throws Exception {
 			testNodesRandomly(
-				form,
-				parent,
+				holder,
 				attributes,
 				buildAttributeCountRetriever(),
 				buildAttributeControllerTypes()
 			);
 		}
 
-		private void testChildNodesRandomly(FORM form, Node parent) throws Exception {
+		private void testChildNodesRandomly(ExternalFormHolder holder) throws Exception {
 			testNodesRandomly(
-				form,
-				parent,
+				holder,
 				children,
 				buildChildrenCountRetriever(),
 				buildChildrenControllerTypes()
 			);
 		}
 
-		private void testChildren(FORM form, Node node) {
+		private void testChildren(ExternalFormHolder holder) {
 
 			for (NodeTesterRunner runner : children) {
 
 				runner.parentNodeName = builder.getNodeName();
-				runner.test(form, node);
+				runner.test(holder);
 
 				assertEquals(
 					displayString() + " : No child nodes should have been left after a test",
 					0,
-					node.getChildNodes().getLength()
+					holder.node.getChildNodes().getLength()
 				);
+
+				if (runner.isNodeDeletedWithNullValue()) {
+					holder.rebuild();
+				}
 			}
 		}
 
-		private void testNodesRandomly(FORM form,
-		                               Node parent,
+		private void testNodesRandomly(ExternalFormHolder holder,
 		                               List<? extends NodeTesterRunner> runners,
 		                               NodeCountRetriever countRetriever,
 		                               Map<Class<NodeTesterRunner>, Class<Controller>[]> controllerClasses) throws Exception {
@@ -2843,12 +4095,12 @@
 			// Run each controller and keep the child nodes count up to date
 			for (Controller controller : controllers) {
 
-				controller.currentChildrenCount = countRetriever.getCount(parent);
+				controller.currentChildrenCount = countRetriever.getCount(holder.node);
 				//controller.log();
-				controller.test(form, parent);
+				controller.test(holder);
 
 				// Test the ordinal of each child node
-				testOrdinalPosition(parent);
+				testOrdinalPosition(holder.node);
 			}
 
 			// Note: The runners don't need to be disposed since there are not used anymore
@@ -2885,857 +4137,6 @@
 	}
 
 	/**
-	 * A <code>ExternalFormBuilder</code> is responsible to create the {@link ExternalForm} to be tested.
-	 */
-	public interface ExternalFormBuilder<FORM extends ExternalForm> {
-
-		/**
-		 * Creates the {@link ExternalForm} to test.
-		 *
-		 * @return The {@link ExternalForm} to test
-		 * @throws IOException If an error occurred during the creation process
-		 */
-		FORM buildExternalForm() throws IOException;
-
-		/**
-		 * Returns the number of attributes the {@link Node} contains before any manipulation has been performed.
-		 *
-		 * @return The count of children before any testing has been done
-		 */
-		int getDefaultAttributeCount();
-
-		/**
-		 * Returns the node represented by the {@link ExternalForm}.
-		 *
-		 * @param form The {@link ExternalForm} for which to return its node
-		 * @return The node from the document that is been manipulated
-		 */
-		Node getNode(FORM form);
-
-		String getNodeName();
-
-		List<String> getTreeNodeNames();
-	}
-
-	private interface NodeCountRetriever {
-		int getCount(Node parent);
-	}
-
-	/**
-	 * The root interface of the testers defined to test the manipulation of a node's property (either
-	 * an attribute, a single child node, a list of child nodes or a text node).
-	 */
-	private interface NodeTester<FORM extends ExternalForm, Value> {
-
-		/**
-		 * Retrieves the name of the node for which retrieving and setting its value is tested.
-		 *
-		 * @return The name of the node to test
-		 */
-		String getNodeName();
-	}
-
-	/**
-	 * This is the root of the runner class, which is associated with a {@link NodeTester}.
-	 */
-	private abstract class NodeTesterRunner {
-
-		/**
-		 * Keeps track of the current count of child nodes owned by the node being manipulated.
-		 */
-		int currentChildrenCount;
-
-		/**
-		 * For debug purposes, this is the name of the parent node.
-		 */
-		String parentNodeName;
-
-		/**
-		 * This object defines a single node to test (which is either a child element or an attribute).
-		 */
-		final NodeTester<FORM, Object> tester;
-
-		/**
-		 * Creates a new <code>AbstractNodeTester</code>.
-		 *
-		 * @param tester The bridge between this tester and the document's node being tested
-		 */
-		@SuppressWarnings("unchecked")
-		NodeTesterRunner(NodeTester<FORM, ?> tester) {
-			super();
-			this.tester = (NodeTester<FORM, Object>) tester;
-			assertNotNull("The tester cannot be null",    tester);
-			assertNotNull("The node name cannot be null", tester.getNodeName());
-		}
-
-		String getActualNodeName() {
-			return tester.getNodeName();
-		}
-
-		/**
-		 * Returns the name of the node for which this runner tests.
-		 *
-		 * @return The node name
-		 */
-		final String getNodeName() {
-			return tester.getNodeName();
-		}
-
-		/**
-		 * Determines whether
-		 *
-		 * @return
-		 */
-		abstract boolean isMultipleSupported();
-
-		/**
-		 * Tests the given {@link ExternalForm} by manipulating the node for a single property.
-		 *
-		 * @param form The {@link ExternalForm} to test
-		 * @param node The node that is manipulated by the given {@link ExternalForm}
-		 */
-		void test(FORM form, Node node) {
-			testInitialState(form, node);
-			testAdding(form, node);
-			testReading(form, node);
-			testRemoving(form, node);
-		}
-
-		/**
-		 * Tests the given {@link ExternalForm} by adding the property to the node.
-		 *
-		 * @param form The {@link ExternalForm} to test
-		 * @param node The node that is manipulated by the given {@link ExternalForm}
-		 */
-		abstract void testAdding(FORM form, Node node);
-
-		/**
-		 * Tests the given {@link ExternalForm} by making sure the given node is in its original state.
-		 *
-		 * @param form The {@link ExternalForm} to test
-		 * @param node The node that is manipulated by the given {@link ExternalForm}
-		 */
-		abstract void testInitialState(FORM form, Node node);
-
-		/**
-		 * Tests the given {@link ExternalForm} by reading the property from the node.
-		 *
-		 * @param form The {@link ExternalForm} to test
-		 * @param node The node that is manipulated by the given {@link ExternalForm}
-		 */
-		abstract void testReading(FORM form, Node node);
-
-		/**
-		 * Tests the given {@link ExternalForm} by removing the property from the node.
-		 *
-		 * @param form The {@link ExternalForm} to test
-		 * @param node The node that is manipulated by the given {@link ExternalForm}
-		 */
-		abstract void testRemoving(FORM form, Node node);
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public String toString() {
-			return getClass().getSimpleName() + " : " + tester.getNodeName();
-		}
-	}
-
-	/**
-	 * This <code>AttributeNodeTester</code> does nothing, it is used when an attribute is not
-	 * currently by the {@link ExternalForm}.
-	 */
-	private class NotSupportedAttributeTester implements AttributeNodeTester<FORM, Object> {
-
-		/**
-		 * The name of the attribute that is not supported by the {@link ExternalForm}.
-		 */
-		private String attributeName;
-
-		/**
-		 * Creates a new <code>NotSupportedAttributeTester</code>.
-		 *
-		 * @param attributeName The name of the attribute that is not supported by the {@link ExternalForm}
-		 */
-		NotSupportedAttributeTester(String attributeName) {
-			super();
-			this.attributeName = attributeName;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean doesNodeAlreadyExist() {
-			return false;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object getDefaultValue() {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public String getNodeName() {
-			return attributeName;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object getValue(FORM form) {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object getValue1() {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public Object getValue2() {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public boolean isNullAllowed() {
-			return false;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void setValue(FORM form, Object value) {
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public String toString(Object value) {
-			return null;
-		}
-	}
-
-	/**
-	 * This runner simply does nothing but adds support for adding an attribute name into the list of
-	 * attributes so that the ordering defined by the XML schema is properly tested.
-	 */
-	private class NotSupportedAttributeTesterRunner extends AttributeNodeTesterRunner {
-
-		/**
-		 * Creates a new <code>NotSupportedAttributeTesterRunner</code>.
-		 *
-		 * @param attributeName The name of the attribute that is currently not supported by the
-		 * {@link ExternalForm}
-		 */
-		NotSupportedAttributeTesterRunner(String attributeName) {
-			super(new NotSupportedAttributeTester(attributeName));
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testAdding(FORM form, Node node) {
-			// Nothing to do
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testInitialState(FORM form, Node node) {
-			// Nothing to do
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testReading(FORM form, Node node) {
-			// Nothing to do
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testRemoving(FORM form, Node node) {
-			// Nothing to do
-		}
-	}
-
-	/**
-	 * This wraps a node name that is currently not supported by the Mapping SPI.
-	 */
-	private class NotSupportedNodeTester implements NodeTester<FORM, Object> {
-
-		/**
-		 * The name of the node that is currently not supported by the {@link ExternalForm}.
-		 */
-		private String nodeName;
-
-		/**
-		 * Creates a new <code>NotSupportedNodeTester</code>.
-		 *
-		 * @param nodeName The name of the node that is currently not supported by the {@link ExternalForm}
-		 */
-		NotSupportedNodeTester(String nodeName) {
-			super();
-			this.nodeName = nodeName;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public String getNodeName() {
-			return nodeName;
-		}
-	}
-
-	/**
-	 * This runner simply does nothing but adds support for adding a node name into the list of child
-	 * nodes so that the ordering defined by the XML schema is properly tested.
-	 */
-	private class NotSupportedNodeTesterRunner extends NodeTesterRunner {
-
-		/**
-		 * Creates a new <code>NotSupportedNodeTesterRunner</code>.
-		 *
-		 * @param nodeName The name of the node that is currently not supported by the {@link ExternalForm}
-		 */
-		NotSupportedNodeTesterRunner(String nodeName) {
-			super(new NotSupportedNodeTester(nodeName));
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		boolean isMultipleSupported() {
-			return false;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testAdding(FORM form, Node node) {
-			// Nothing to do
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testInitialState(FORM form, Node node) {
-			// Nothing to do
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testReading(FORM form, Node node) {
-			// Nothing to do
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testRemoving(FORM form, Node node) {
-			// Nothing to do
-		}
-	}
-
-	private abstract class PropertyNodeTesterRunner extends NodeTesterRunner {
-
-		/**
-		 * Keeps track of the status of the node's existence.
-		 */
-		private boolean nodeExists;
-
-		/**
-		 * Creates a new <code>PropertyNodeTesterRunner</code>.
-		 *
-		 * @param tester This object defines a single node to test a child text node
-		 */
-		PropertyNodeTesterRunner(PropertyTester<FORM, ?> tester) {
-			super(tester);
-		}
-
-		/**
-		 * Returns
-		 *
-		 * @return
-		 */
-		abstract String displayString();
-
-		/**
-		 * Returns the number of children owned by the given parent {@link Node}.
-		 *
-		 * @param parentNode The owner of the child node being tested
-		 * @return The count of children, which could be either attributes or child nodes
-		 */
-		abstract int getChildrenCount(Node parentNode);
-
-		/**
-		 * Returns
-		 *
-		 * @param parentNode
-		 * @return
-		 */
-		abstract Node getNode(Node parentNode);
-
-		/**
-		 * Returns
-		 *
-		 * @param node
-		 * @return
-		 */
-		abstract String getNodeValue(Node node);
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		final boolean isMultipleSupported() {
-			return false;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testAdding(FORM form, Node parentNode) {
-
-			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
-
-			// Change the node value to null
-			if (tester.isNullAllowed()) {
-
-				tester.setValue(form, null);
-
-				if (nodeExists) {
-					nodeExists = false;
-					currentChildrenCount--;
-				}
-
-				assertEquals(
-					displayString() + " : The element should not have any children",
-					currentChildrenCount,
-					getChildrenCount(parentNode)
-				);
-
-				// Make sure nothing changed
-				Object result = tester.getValue(form);
-
-				assertNull(
-					displayString() + " : The element's value should be null",
-					result
-				);
-
-				// Make sure nothing changed
-				assertEquals(
-					displayString() + " : The element should not have any children",
-					currentChildrenCount,
-					getChildrenCount(parentNode)
-				);
-			}
-
-			// Change the value to something
-			Object expectedValue1 = tester.getValue1();
-
-			assertNotNull(
-				displayString() + " : Value 1 cannot be null",
-				expectedValue1
-			);
-
-			tester.setValue(form, expectedValue1);
-
-			if (!nodeExists) {
-				nodeExists = true;
-				currentChildrenCount++;
-			}
-
-			// The child node should have been added
-			Node childNode = getNode(parentNode);
-
-			assertNotNull(
-				displayString() + " : The node cannot be null",
-				childNode
-			);
-
-			assertEquals(
-				displayString() + " : The element should have a " + currentChildrenCount + " children",
-				currentChildrenCount,
-				getChildrenCount(parentNode)
-			);
-
-			// Get the value
-			Object result = tester.getValue(form);
-
-			assertEquals(
-				displayString() + "The element's value was not set correctly",
-				expectedValue1,
-				result
-			);
-
-			// Get the value directly
-			String stringResult = getNodeValue(childNode);
-			String stringNodeValue = tester.toString(expectedValue1);
-
-			assertEquals(
-				displayString() + " : The value was not set correctly",
-				stringNodeValue,
-				stringResult
-			);
-
-			// Change the value to something else
-			Object expectedValue2 = tester.getValue2();
-			assertNotNull(displayString() + " : Value 2 cannot be null", expectedValue2);
-
-			assertNotSame(
-				displayString() + " : Value 1 and value 2 cannot be the same",
-				expectedValue1,
-				expectedValue2
-			);
-
-			tester.setValue(form, expectedValue2);
-
-			// Get the value
-			result = tester.getValue(form);
-
-			assertEquals(
-				displayString() + " The element's value was not set correctly",
-				expectedValue2,
-				result
-			);
-
-			// Get the value directly
-			stringResult = getNodeValue(childNode);
-			stringNodeValue = tester.toString(expectedValue2);
-
-			assertEquals(
-				displayString() + " : The element's value was not set correctly",
-				stringNodeValue,
-				stringResult
-			);
-
-			// Change the value back to its original value
-			Object defaultValue = tester.getDefaultValue();
-
-			assertNotNull(
-				displayString() + " : The default value cannot be null",
-				defaultValue
-			);
-
-			tester.setValue(form, defaultValue);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testInitialState(FORM form, Node parent) {
-
-			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
-			nodeExists |= tester.doesNodeAlreadyExist();
-
-			// Node name
-			String nodeName = getNodeName();
-			assertNotNull("The node name cannot be null", nodeName);
-
-			// Test the initial state of the parent node
-			assertEquals(
-				displayString() + " : The parent node child count is incorrect",
-				currentChildrenCount,
-				getChildrenCount(parent)
-			);
-
-			// The child node should either not exist or already being present
-			Node childNode = getNode(parent);
-
-			if (nodeExists) {
-				assertNotNull(
-					displayString() + " : The node should not be null",
-					childNode
-				);
-			}
-			else {
-				assertNull(
-					displayString() + " : The node should be null",
-					childNode
-				);
-			}
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testReading(FORM form, Node node) {
-
-			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
-
-			// The node value should either be null or not null
-			Object result = tester.getValue(form);
-
-			// Make sure the node's value is not null
-			if (nodeExists) {
-				assertNotNull(
-					displayString() + " : The element's value should not be null",
-					result
-				);
-				assertSame(
-					displayString() + " : The element's value was not retrived correctly",
-					tester.getDefaultValue(),
-					result
-				);
-			}
-			// The node is not present, make sure reading its value returns null
-			else {
-				assertNull(
-					displayString() + " : The element's value should be null",
-					result
-				);
-			}
-
-			// Make sure nothing changed by reading the node's value
-			assertEquals(
-				displayString() + " : The element should not have any children",
-				0,
-				getChildrenCount(node) - currentChildrenCount
-			);
-
-			// Retrieve the actual node
-			Node childNode = getNode(node);
-
-			if (nodeExists) {
-				assertNotNull(
-					displayString() + " : The node should not be null",
-					childNode
-				);
-			}
-			else {
-				assertNull(
-					displayString() + " : The node should be null",
-					childNode
-				);
-			}
-
-			// Make sure nothing changed after retrieving the node
-			assertEquals(
-				displayString() + " : The element should not have any children",
-				0,
-				getChildrenCount(node) - currentChildrenCount
-			);
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		void testRemoving(FORM form, Node parentNode) {
-
-			PropertyTester<FORM, Object> tester = (PropertyTester<FORM, Object>) this.tester;
-
-			// Change the node value to null, which will remove it from the parent node
-			if (tester.isNullAllowed()) {
-
-				tester.setValue(form, null);
-
-				if (nodeExists) {
-					nodeExists = false;
-					currentChildrenCount--;
-				}
-
-				assertEquals(
-					displayString() + " : The child count does not match the current state",
-					currentChildrenCount,
-					getChildrenCount(parentNode)
-				);
-			}
-		}
-	}
-
-	/**
-	 * A <code>PropertyTester</code> handles testing either an attribute or a single child node of
-	 * the node being tested.
-	 */
-	private interface PropertyTester<FORM extends ExternalForm, VALUE> extends NodeTester<FORM, VALUE> {
-
-		/**
-		 * Determines whether the property is by default present in the document.
-		 *
-		 * @return <code>true</code> if the property exists before any changes is done to the document;
-		 * <code>false</code> otherwise
-		 */
-		boolean doesNodeAlreadyExist();
-
-		/**
-		 * If {@link #doesNodeAlreadyExist()} returns <code>true</code>, then this should return the
-		 * node value that is already present in the document, which is done before the document is
-		 * being changed.
-		 *
-		 * @return Either a non-<code>null</code> value if the node is present in the document or
-		 * <code>null</code> if the node is not by default present in the document
-		 */
-		VALUE getDefaultValue();
-
-		/**
-		 * Retrieves the value of the node.
-		 *
-		 * @param form The external form that will retrieve the value
-		 * @return The value, which can be <code>null</code>
-		 */
-		VALUE getValue(FORM form);
-
-		/**
-		 * Retrieves a non-<code>null</code> value that will be used for testing that is different
-		 * than the one returned by {@link #getValue2()}.
-		 *
-		 * @return A non-<code>null</code> value used for testing
-		 */
-		VALUE getValue1();
-
-		/**
-		 * Retrieves a non-<code>null</code> value that will be used for testing that is different
-		 * than the one returned by {@link #getValue1()}.
-		 *
-		 * @return A non-<code>null</code> value used for testing
-		 */
-		VALUE getValue2();
-
-		/**
-		 * Determines whether the node can receive a <code>null</code> value or not.
-		 *
-		 * @return <code>true</code> if <code>null</code> is a valid value; <code>false</code> otherwise
-		 */
-		boolean isNullAllowed();
-
-		/**
-		 * Sets the value of the node.
-		 *
-		 * @param form The external form that will set the value
-		 * @return The value, which can be <code>null</code>
-		 */
-		void setValue(FORM form, VALUE value);
-
-		/**
-		 * Converts the value to its string representation.
-		 *
-		 * @param value A non-<code>null</code> value to convert into a string
-		 * @return The given value represented as a string
-		 */
-		String toString(VALUE value);
-	}
-
-	/**
-	 * A <code>RootNodeTester</code> is the container of all the testers that will test every single
-	 * property of the node to test, i.e. its attributes and child nodes.
-	 */
-	public interface RootNodeTester<FORM extends ExternalForm> {
-
-		/**
-		 * Adds the given tester when the form has an attribute.
-		 *
-		 * @param tester The tester for a single attribute
-		 */
-		void addAttribute(AttributeNodeTester<FORM, ?> tester);
-
-		/**
-		 * Adds the given tester when the form representing the node it represents can have one child
-		 * node of a certain type and its property is represented by a boolean value.
-		 *
-		 * @param tester The tester for a single child node
-		 */
-		void addBooleanNode(BooleanChildNodeTester<FORM> tester);
-
-		/**
-		 * Adds the given tester when the form has a child node with a single attribute.
-		 *
-		 * @param tester The tester for a single attribute owned by a single child node
-		 */
-		void addChildAttribute(ChildAttributeTester<FORM, ?> tester);
-
-		/**
-		 * Adds the given tester when the form representing the node it represents can have zero or
-		 * many child nodes of the same type (i.e. with the same node name).
-		 *
-		 * @param tester The tester for a list of child nodes with the same type
-		 */
-		void addContainerListNodes(ContainerChildListNodeTester<FORM, ?, ?> tester);
-
-		/**
-		 * Adds the given tester when the form representing the node it represents can have zero or
-		 * many child nodes of the same type (i.e. with the same node name).
-		 *
-		 * @param tester The tester for a list of child nodes with the same type
-		 */
-		void addListNodes(ChildListNodeTester<FORM, ?, ?> tester);
-
-		/**
-		 * Adds the given tester when the form representing the node it represents can have one child
-		 * node of a certain type.
-		 *
-		 * @param tester The tester for a single child node
-		 */
-		void addNode(ChildNodeTester<FORM, ?> tester);
-
-		/**
-		 * Adds the given tester when the form has a single child node that is a text node.
-		 *
-		 * @param tester The tester for a single child text node
-		 */
-		void addTextNode(TextNodeTester<FORM, ?> tester);
-
-		/**
-		 * Adds the given attribute name to indicate it is part of the "root" node but it is not
-		 * supported by the {@link ExternalForm} yet.
-		 *
-		 * @param attributeName The name of the attribute not currently supported
-		 */
-		void addUnsupportedAttribute(String attributeName);
-
-		/**
-		 * Adds the given node name to indicate it is part of the "root" node but it is not supported
-		 * by the {@link ExternalForm} yet.
-		 *
-		 * @param nodeName The name of the node not currently supported
-		 */
-		void addUnsupportedNode(String nodeName);
-
-		/**
-		 * Sets the builder that will create the document and tree node representation down to node to test.
-		 *
-		 * @param builder The builder of the node to test
-		 */
-		void setBuilder(ExternalFormBuilder<? extends FORM> builder);
-	}
-
-	/**
 	 * This controller simply asks its runner to add the child text node.
 	 */
 	private class TextNodeRunnerAddingController extends Controller {
@@ -3744,8 +4145,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
 		}
 
 		/**
@@ -3753,12 +4154,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			TextNodeTesterRunner runner = (TextNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testAdding(form, node);
+			runner.testInitialState(holder);
+			runner.testAdding(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -3773,8 +4174,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> addition");
 		}
 
 		/**
@@ -3782,12 +4183,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			TextNodeTesterRunner runner = (TextNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testReading(form, node);
+			runner.testInitialState(holder);
+			runner.testReading(holder);
 		}
 	}
 
@@ -3800,8 +4201,8 @@
 		 * {@inheritDoc}
 		 */
 		@Override
-		void log() {
-			System.out.println("<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
+		void log(Logger logger) {
+			logger.log(Level.FINE, "<" + runner.parentNodeName + "><" + runner.tester.getNodeName() + "> : addition");
 		}
 
 		/**
@@ -3809,12 +4210,12 @@
 		 */
 		@Override
 		@SuppressWarnings("unchecked")
-		void test(FORM form, Node node) {
+		void test(ExternalFormHolder holder) {
 
 			TextNodeTesterRunner runner = (TextNodeTesterRunner) this.runner;
 			runner.currentChildrenCount = currentChildrenCount;
-			runner.testInitialState(form, node);
-			runner.testRemoving(form, node);
+			runner.testInitialState(holder);
+			runner.testRemoving(holder);
 
 			currentChildrenCount = runner.currentChildrenCount;
 		}
@@ -3885,5 +4286,13 @@
 		String getNodeValue(Node node) {
 			return node.getTextContent();
 		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		boolean isNodeDeletedWithNullValue() {
+			return ((TextNodeTester<?, ?>) tester).isNodeDeletedWithNullValue();
+		}
 	}
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AccessMethodsTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AccessMethodsTests.java
new file mode 100644
index 0000000..aa75661
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AccessMethodsTests.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.persistence.tools.mapping.ExternalForm;
+import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddable;
+import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
+import org.eclipse.persistence.tools.mapping.tests.AbstractExternalFormTests;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.w3c.dom.Node;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalAccessMethods}.
+ *
+ * @version 2.6
+ */
+@SuppressWarnings("nls")
+public final class AccessMethodsTests extends AbstractExternalFormTests<ExternalAccessMethods> {
+
+	static <T extends ExternalEmbeddable> ChildNodeTester<T, ExternalAccessMethods> buildAccessMethodsTester() {
+		return new ChildNodeTester<T, ExternalAccessMethods>() {
+			@Override
+			public ExternalAccessMethods addChild(T form) {
+				return form.addAccessMethods(null, null);
+			}
+			@Override
+			public ExternalAccessMethods getChild(T form) {
+				return form.getAccessMethods();
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalAccessMethods.ACCESS_METHODS;
+			}
+			@Override
+			public boolean hasChild(T form) {
+				return form.hasAccessMethods();
+			}
+			@Override
+			public void removeChild(T form) {
+				form.removeAccessMethods();
+			}
+		};
+	}
+
+	private ExternalFormBuilder<ExternalAccessMethods> buildEmbeddableAccessMethodsBuilder() {
+		return new ExternalFormBuilder<ExternalAccessMethods>() {
+			@Override
+			public ExternalAccessMethods buildExternalForm() throws IOException {
+				ExternalORMConfiguration orm = ORMConfigurationTests.buildExternalForm();
+				ExternalEmbeddable embeddable = orm.addEmbeddable("org.test.MyEmbeddable");
+				return embeddable.addAccessMethods(null, null);
+			}
+			@Override
+			public ExternalAccessMethods buildExternalForm(ExternalForm parentForm) {
+				return ((ExternalEmbeddable) parentForm).addAccessMethods(null, null);
+			}
+			@Override
+			public int getDefaultAttributeCount() {
+				return 0;
+			}
+			@Override
+			public Node getNode(ExternalAccessMethods form) {
+				return ObjectTools.execute(form, "getElement");
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalAccessMethods.ACCESS_METHODS;
+			}
+			@Override
+			public List<String> getTreeNodeNames() {
+				return ListTools.list(
+					ExternalORMConfiguration.ENTITY_MAPPINGS,
+					ExternalEmbeddable.EMBEDDABLE,
+					ExternalAccessMethods.ACCESS_METHODS
+				);
+			}
+		};
+	}
+
+	private AttributeNodeTester<ExternalAccessMethods, String> buildGetMethodTester() {
+		return new AttributeNodeTester<ExternalAccessMethods, String>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public String getDefaultValue() {
+				return "GET_METHOD_0";
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalAccessMethods.GET_METHOD;
+			}
+			@Override
+			public String getValue(ExternalAccessMethods form) {
+				return form.getGetMethod();
+			}
+			@Override
+			public String getValue1() {
+				return "GET_METHOD_1";
+			}
+			@Override
+			public String getValue2() {
+				return "GET_METHOD_2";
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalAccessMethods form, String value) {
+				form.setGetMethod(value);
+			}
+			@Override
+			public String toString(String value) {
+				return value;
+			}
+		};
+	}
+
+	private AttributeNodeTester<ExternalAccessMethods, String> buildSetMethodTester() {
+		return new AttributeNodeTester<ExternalAccessMethods, String>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public String getDefaultValue() {
+				return "SET_METHOD_0";
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalAccessMethods.SET_METHOD;
+			}
+			@Override
+			public String getValue(ExternalAccessMethods form) {
+				return form.getSetMethod();
+			}
+			@Override
+			public String getValue1() {
+				return "SET_METHOD_1";
+			}
+			@Override
+			public String getValue2() {
+				return "SET_METHOD_2";
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalAccessMethods form, String value) {
+				form.setSetMethod(value);
+			}
+			@Override
+			public String toString(String value) {
+				return value;
+			}
+		};
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected void populate(RootNodeTester tester) {
+
+		tester.setBuilder(buildEmbeddableAccessMethodsBuilder());
+
+		tester.addAttribute(buildGetMethodTester());
+		tester.addAttribute(buildSetMethodTester());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AccessTypeTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AccessTypeTests.java
index 1863b08..62ab94b 100644
--- a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AccessTypeTests.java
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AccessTypeTests.java
@@ -61,6 +61,10 @@
 				return AccessType.VIRTUAL;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -102,6 +106,10 @@
 				return AccessType.VIRTUAL;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AllORMTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AllORMTests.java
index 8ffa922..f24240d 100644
--- a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AllORMTests.java
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/AllORMTests.java
@@ -18,7 +18,8 @@
 import org.junit.runners.Suite.SuiteClasses;
 
 /**
- * The test suite for the unit-tests defined in the same package.
+ * The test suite for the unit-tests defined in the same package, which contains the tests testing
+ * the ORM Configuration SPI.
  *
  * @version 2.6
  */
@@ -30,9 +31,141 @@
 	// Managed types
 	EmbeddableTests.class,
 	MappedSuperclassTests.class,
-	EntityTests.class
+	EntityTests.class,
 
 	// Mappings
+	BasicMappingTests.class,
+	BasicCollectionMappingTests.class,
+	BasicMapMappingTests.class,
+	ElementCollectionMappingTests.class,
+	EmbeddedMappingTests.class,
+	EmbeddedIdMappingTests.class,
+	IdMappingTests.class,
+	ManyToManyMappingTests.class,
+	ManyToOneMappingTests.class,
+	OneToManyMappingTests.class,
+	OneToOneMappingTests.class,
+	TransformationMappingTests.class,
+	TransientMappingTests.class,
+	VariableOneToOneMappingTests.class,
+	VersionMappingTests.class,
+	TransientMappingTests.class,
+
+	// Various properties
+	AccessMethodsTests.class,
+//	AdditionalCriteriaTests.class, // Not supported
+	CacheTests.class
+//	CacheInterceptorTests.class,
+//	ChangeTrackingTests.class,
+//	CustomizerTests.class,
+//	PersistenceUnitMetadataTests.class,
+//	PersistenceUnitDefaults.class,
+//	PartitioningGroupTests.class,
+//	AssociationOverrideTests.class,
+//	AttributeOverrideTests.class,
+//	AttributesTests.class,
+//	ClassExtractorTests.class,
+//	CloneCopyPolicyTests.class,
+//	ColumnTests.class,
+//	CollectionTableMappingTests.class,
+//	EclipseLinkCollectionTableMappingTests.class,
+//	ConversionValueTests.class,
+//	MixedConverterTests.class,
+//	ConverterTestsTests.class,
+////	PartitioningTests.class, // Not supported
+////	HashPartitioningTests.class, // Not supported
+////	RangePartitioningTests.class, // Not supported
+////	RangePartitionTests.class, // Not supported
+////	ValuePartitioningTests.class, // Not supported
+////	RoundRobinPartitioningTests.class, // Not supported
+////	ReplicationPartitioningTests.class, // Not supported
+////	UnionPartitioningTests.class, // Not supported
+////	PinnedPartitioningTests.class, // Not supported
+//	ColumnResultTests.class,
+//	ConstructorResult.class,
+//	ConvertTests.class,
+//	CopyPolicyTests.class,
+//	DiscriminatorColumnTests.class,
+//	DiscriminatorClassTests.class,
+//	ArrayTests.class,
+//	EntityListenerTests.class,
+//	EntityListenersTests.class,
+//	EntityResultTests.class,
+//	EnumeratedTests.class,
+//	FetchAttributeTests.class,
+//	FetchGroupTests.class,
+//	FetchResultTests.class,
+//	ForeignKeyTests.class,
+//	GeneratedValueTests.class,
+//	IdClassTests.class,
+//	InheritanceTests.class,
+//	InstantiationCopyPolicyTests.class,
+//	JoinColumnTests.class,
+//	JoinTableTests.class,
+//	LobTests.class,
+//	MapKeyTests.class,
+//	MapKeyClassTests.class,
+//	MapKeyColumnTests.class,
+//	MapKeyJoinColumnTests.class,
+//	MultitenantTests.class,
+//	NamedAttributeNodeTests.class,
+//	NamedEntityGraphTests.class,
+//	NamedNativeQueryTests.class,
+//	NamedQueryTests.class,
+//	NamedStoredProcedureQueryTests.class,
+//	NamedSubgraphTests.class,
+//	NamedStoredFunctionQueryTests.class,
+//	NamedPlsqlStoredFunctionQueryTests.class,
+//	NamedPlsqlStoredProcedureQueryTests.class,
+//	OracleObjectTests.class,
+//	OracleArrayTests.class,
+//	PlsqlRecordTests.class,
+//	PlsqlTableTests.class,
+//	ObjectTypeConverterTests.class,
+//	OptimisticLockingTests.class,
+//	OrderByTests.class,
+//	OrderColumnTests.class,
+//	PostLoadTests.class,
+//	PostPersistTests.class,
+//	PostRemoveTests.class,
+//	PostUpdateTests.class,
+//	PrePersistTests.class,
+//	PreRemoveTests.class,
+//	PreUpdateTests.class,
+//	PrimaryKeyTests.class,
+//	PrimaryKeyJoinColumnTests.class,
+//	PropertyTests.class,
+//	QueryHintTests.class,
+//	QueryRedirectorsTests.class,
+//	ReadTransformerTests.class,
+//	ReturnInsertTests.class,
+//	SecondaryTableTests.class,
+//	SequenceGeneratorTests.class,
+//	SerializedObjectTests.class,
+//	SqlResultSetMappingTests.class,
+//	StoredProcedureParameterTests.class,
+//	PlsqlParameterTests.class,
+//	StructConverterTests.class,
+//	StructTests.class,
+//	StructureTests.class,
+//	TableTests.class,
+//	IndexTests.class,
+//	EclipseLinkIndexTests.class,
+//	CacheIndexTests.class,
+//	TableGeneratorTests.class,
+//	UuidGeneratorTests.class,
+//	TemporalTests.class,
+//	TenantDiscriminatorColumnTests.class,
+//	TenantTableDiscriminatorTests.class,
+//	TimeOfDayTests.class,
+//	TypeConverterTests.class,
+//	SerializedConverterTests.class,
+//	UniqueConstraintTests.class,
+//	WriteTransformerTests.class,
+//	BatchFetchTests.class,
+//	NoSqlTests.class,
+//	FieldTests.class,
+//	JoinFieldTests.class,
 })
 @RunWith(Suite.class)
 public final class AllORMTests {
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicCollectionMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicCollectionMappingTests.java
new file mode 100644
index 0000000..7a4f4ef
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicCollectionMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalBasicCollectionMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalBasicCollectionMapping}.
+ *
+ * @version 2.6
+ */
+public final class BasicCollectionMappingTests extends ConvertibleMappingTests<ExternalBasicCollectionMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalBasicCollectionMapping addMapping(ExternalEntity entity) {
+		return entity.addBasicCollectionMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalBasicCollectionMapping.BASIC_COLLECTION;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicMapMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicMapMappingTests.java
new file mode 100644
index 0000000..26a4649
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicMapMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalBasicMapMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalBasicMapMapping}.
+ *
+ * @version 2.6
+ */
+public final class BasicMapMappingTests extends ConvertibleMappingTests<ExternalBasicMapMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalBasicMapMapping addMapping(ExternalEntity entity) {
+		return entity.addBasicMapMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalBasicMapMapping.BASIC_MAP;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicMappingTests.java
new file mode 100644
index 0000000..8c130d7
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/BasicMappingTests.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalBasicMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalBasicMapping}.
+ *
+ * @version 2.6
+ */
+public final class BasicMappingTests extends ConvertibleMappingTests<ExternalBasicMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+//		tester.addAttribute(buildNameTester());
+//		tester.addAttribute(buildFetchTester());
+//		tester.addAttribute(buildOptionalTester());
+//		tester.addAttribute(buildAccessTester());
+//		tester.addAttribute(buildMutableTester());       // EclipseLink
+//		tester.addAttribute(buildAttributeTypeTester()); // EclipseLink
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+		tester.addNode(buildColumnTester());
+//		tester.addNode(buildFieldTester());                  // EclipseLink
+//		tester.addNode(buildIndexTester());                  // EclipseLink
+//		tester.addNode(buildCacheIndexTester());             // EclipseLink
+//		tester.addNode(buildGeneratedValueTester());         // EclipseLink
+//		tester.addNode(buildLobTester());
+//		tester.addNode(buildTemporalTester());
+//		tester.addNode(buildEnumeratedTester());
+//		tester.addTextNode(buildConvertTester());
+//		tester.addChoiceNodes(buildConverterChoiceTester()); // EclipseLink
+//		tester.addNode(buildTableGeneratorTester());         // EclipseLink
+//		tester.addNode(buildSequenceGeneratorTester());      // EclipseLink
+//		tester.addNode(buildUuidGeneratorTester());          // EclipseLink
+//		tester.addListNodes(buildPropertyTester());          // EclipseLink
+//		tester.addNodes(buildAccessMethodsTester());         // EclipseLink
+//		tester.addNodes(buildReturnInsertTester());          // EclipseLink
+//		tester.addNodes(buildReturnUpdateTester());          // EclipseLink
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalBasicMapping addMapping(ExternalEntity entity) {
+		return entity.addBasicMapping(mappingName());
+	}
+
+	private ChildNodeTester<ExternalBasicMapping, ExternalEntityColumn> buildColumnTester() {
+		return new ChildNodeTester<ExternalBasicMapping, ExternalEntityColumn>() {
+			@Override
+			public ExternalEntityColumn addChild(ExternalBasicMapping form) {
+				return form.addColumn();
+			}
+			@Override
+			public ExternalEntityColumn getChild(ExternalBasicMapping form) {
+				return form.getColumn();
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalEntityColumn.COLUMN;
+			}
+			@Override
+			public boolean hasChild(ExternalBasicMapping form) {
+				return form.hasColumn();
+			}
+			@Override
+			public void removeChild(ExternalBasicMapping form) {
+				form.removeColumn();
+			}
+		};
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalBasicMapping.BASIC;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/CacheTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/CacheTests.java
new file mode 100644
index 0000000..bddc38d
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/CacheTests.java
@@ -0,0 +1,431 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.persistence.annotations.CacheType;
+import org.eclipse.persistence.config.CacheIsolationType;
+import org.eclipse.persistence.tools.mapping.ExternalForm;
+import org.eclipse.persistence.tools.mapping.orm.ExternalCache;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
+import org.eclipse.persistence.tools.mapping.orm.ExternalTimeOfDay;
+import org.eclipse.persistence.tools.mapping.tests.AbstractExternalFormTests;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.eclipse.persistence.tools.utility.collection.ListTools;
+import org.w3c.dom.Node;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalCache}.
+ *
+ * @version 2.6
+ */
+@SuppressWarnings("nls")
+public final class CacheTests extends AbstractExternalFormTests<ExternalCache> {
+
+	private AttributeNodeTester<ExternalCache, Boolean> buildAlwaysRefreshTester() {
+		return new AttributeNodeTester<ExternalCache, Boolean>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public Boolean getDefaultValue() {
+				return Boolean.TRUE;
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.ALWAYS_REFRESH;
+			}
+			@Override
+			public Boolean getValue(ExternalCache form) {
+				return form.isAlwaysRefresh();
+			}
+			@Override
+			public Boolean getValue1() {
+				return Boolean.TRUE;
+			}
+			@Override
+			public Boolean getValue2() {
+				return Boolean.FALSE;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalCache form, Boolean value) {
+				form.setAlwaysRefresh(value);
+			}
+			@Override
+			public String toString(Boolean value) {
+				return value.toString();
+			}
+		};
+	}
+
+	private ExternalFormBuilder<ExternalCache> buildCacheBuilder() {
+		return new ExternalFormBuilder<ExternalCache>() {
+			@Override
+			public ExternalCache buildExternalForm() throws IOException {
+				ExternalORMConfiguration orm = ORMConfigurationTests.buildExternalForm();
+				ExternalEntity entity = orm.addEntity("org.test.MyEntity");
+				return entity.addCache();
+			}
+			@Override
+			public ExternalCache buildExternalForm(ExternalForm parentForm) {
+				return ((ExternalEntity) parentForm).addCache();
+			}
+			@Override
+			public int getDefaultAttributeCount() {
+				return 0;
+			}
+			@Override
+			public Node getNode(ExternalCache form) {
+				return ObjectTools.execute(form, "getElement");
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.CACHE;
+			}
+			@Override
+			public List<String> getTreeNodeNames() {
+				return ListTools.list(
+					ExternalORMConfiguration.ENTITY_MAPPINGS,
+					ExternalEntity.ENTITY,
+					ExternalCache.CACHE
+				);
+			}
+		};
+	}
+
+	private TextNodeTester<ExternalCache, Integer> buildExpiryTester() {
+		return new TextNodeTester<ExternalCache, Integer>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public Integer getDefaultValue() {
+				return 123;
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.EXPIRY;
+			}
+			@Override
+			public Integer getValue(ExternalCache form) {
+				return form.getExpiryTimeToLive();
+			}
+			@Override
+			public Integer getValue1() {
+				return 1234;
+			}
+			@Override
+			public Integer getValue2() {
+				return 5678;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalCache form, Integer value) {
+				form.setExpiryTimeToLive(value);
+			}
+			@Override
+			public String toString(Integer value) {
+				return value.toString();
+			}
+		};
+	}
+
+	private ChildNodeTester<ExternalCache, ExternalTimeOfDay> buildExpiryTimeOfDayTester() {
+		return new ChildNodeTester<ExternalCache, ExternalTimeOfDay>() {
+			@Override
+			public ExternalTimeOfDay addChild(ExternalCache form) {
+				return form.addExpiryTimeOfDay();
+			}
+			@Override
+			public ExternalTimeOfDay getChild(ExternalCache form) {
+				return form.getExpiryTimeOfDay();
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalTimeOfDay.EXPIRY_TIME_OF_DAY;
+			}
+			@Override
+			public boolean hasChild(ExternalCache form) {
+				return form.hasExpiryTimeOfDay();
+			}
+			@Override
+			public void removeChild(ExternalCache form) {
+				form.removeExpiryTimeOfDay();
+			}
+		};
+	}
+
+	private AttributeNodeTester<ExternalCache, CacheIsolationType> buildIsolationTester() {
+		return new AttributeNodeTester<ExternalCache, CacheIsolationType>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public CacheIsolationType getDefaultValue() {
+				return CacheIsolationType.ISOLATED;
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.ISOLATION;
+			}
+			@Override
+			public CacheIsolationType getValue(ExternalCache form) {
+				return form.getIsolationType();
+			}
+			@Override
+			public CacheIsolationType getValue1() {
+				return CacheIsolationType.PROTECTED;
+			}
+			@Override
+			public CacheIsolationType getValue2() {
+				return CacheIsolationType.SHARED;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalCache form, CacheIsolationType value) {
+				form.setIsolationType(value);
+			}
+			@Override
+			public String toString(CacheIsolationType value) {
+				return value.toString();
+			}
+		};
+	}
+
+	private AttributeNodeTester<ExternalCache, Boolean> buildRefreshOnlyIfNewerTester() {
+		return new AttributeNodeTester<ExternalCache, Boolean>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public Boolean getDefaultValue() {
+				return Boolean.TRUE;
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.REFRESH_ONLY_IF_NEWER;
+			}
+			@Override
+			public Boolean getValue(ExternalCache form) {
+				return form.isRefreshOnlyIfNewer();
+			}
+			@Override
+			public Boolean getValue1() {
+				return Boolean.TRUE;
+			}
+			@Override
+			public Boolean getValue2() {
+				return Boolean.FALSE;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalCache form, Boolean value) {
+				form.setRefreshOnlyIfNewer(value);
+			}
+			@Override
+			public String toString(Boolean value) {
+				return value.toString();
+			}
+		};
+	}
+
+	private AttributeNodeTester<ExternalCache, Boolean> buildSharedTester() {
+		return new AttributeNodeTester<ExternalCache, Boolean>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public Boolean getDefaultValue() {
+				return Boolean.TRUE;
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.SHARED;
+			}
+			@Override
+			public Boolean getValue(ExternalCache form) {
+				return form.isShared();
+			}
+			@Override
+			public Boolean getValue1() {
+				return Boolean.TRUE;
+			}
+			@Override
+			public Boolean getValue2() {
+				return Boolean.FALSE;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalCache form, Boolean value) {
+				form.setShared(value);
+			}
+			@Override
+			public String toString(Boolean value) {
+				return value.toString();
+			}
+		};
+	}
+
+	private AttributeNodeTester<ExternalCache, Integer> buildSizeTester() {
+		return new AttributeNodeTester<ExternalCache, Integer>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public Integer getDefaultValue() {
+				return 123;
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.SIZE;
+			}
+			@Override
+			public Integer getValue(ExternalCache form) {
+				return form.getSize();
+			}
+			@Override
+			public Integer getValue1() {
+				return 12345;
+			}
+			@Override
+			public Integer getValue2() {
+				return 6789;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalCache form, Integer value) {
+				form.setSize(value);
+			}
+			@Override
+			public String toString(Integer value) {
+				return value.toString();
+			}
+		};
+	}
+
+	private AttributeNodeTester<ExternalCache, CacheType> buildTypeTester() {
+		return new AttributeNodeTester<ExternalCache, CacheType>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public CacheType getDefaultValue() {
+				return CacheType.CACHE;
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalCache.TYPE;
+			}
+			@Override
+			public CacheType getValue(ExternalCache form) {
+				return form.getType();
+			}
+			@Override
+			public CacheType getValue1() {
+				return CacheType.FULL;
+			}
+			@Override
+			public CacheType getValue2() {
+				return CacheType.HARD_WEAK;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(ExternalCache form, CacheType value) {
+				form.setType(value);
+			}
+			@Override
+			public String toString(CacheType value) {
+				return value.name();
+			}
+		};
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected void populate(RootNodeTester tester) {
+
+		tester.setBuilder(buildCacheBuilder());
+
+		tester.addAttribute(buildSizeTester());
+		tester.addAttribute(buildSharedTester());
+		tester.addAttribute(buildIsolationTester());
+		tester.addAttribute(buildTypeTester());
+		tester.addAttribute(buildAlwaysRefreshTester());
+		tester.addAttribute(buildRefreshOnlyIfNewerTester());
+
+		tester.addTextNode(buildExpiryTester());
+		tester.addNode(buildExpiryTimeOfDayTester());
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ConvertibleMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ConvertibleMappingTests.java
new file mode 100644
index 0000000..7269c5a
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ConvertibleMappingTests.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalConverter;
+import org.eclipse.persistence.tools.mapping.orm.ExternalConvertibleMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
+import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
+import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalConvertibleMappingg}.
+ *
+ * @version 2.6
+ */
+public abstract class ConvertibleMappingTests<T extends ExternalConvertibleMapping> extends NonTriensientMappingTests<T> {
+
+	final ChildNodeTester<?, ?>[] buildConverterChoiceTester() {
+		return new ChildNodeTester<?, ?>[] {
+			buildConverterTester(),
+			buildTypeConverterTester(),
+			buildObjectTypeConverterTester(),
+			buildSerializedConverterTester(),
+			buildStructConverterTester()
+		};
+	}
+
+	private ChildNodeTester<T, ExternalConverter> buildConverterTester() {
+		return null;
+	}
+
+	final TextNodeTester<T, String> buildConvertTester() {
+		return new TextNodeTester<T, String>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public String getDefaultValue() {
+				return null;
+			}
+			@Override
+			public String getNodeName() {
+				return null;
+			}
+			@Override
+			public String getValue(T form) {
+				return null;
+			}
+			@Override
+			public String getValue1() {
+				return null;
+			}
+			@Override
+			public String getValue2() {
+				return null;
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return false;
+			}
+			@Override
+			public void setValue(T form, String value) {
+			}
+			@Override
+			public String toString(String value) {
+				return null;
+			}
+		};
+	}
+
+	private ChildNodeTester<T, ExternalObjectTypeConverter> buildObjectTypeConverterTester() {
+		return null;
+	}
+
+	private ChildNodeTester<T, ?> buildSerializedConverterTester() {
+		return null;
+	}
+
+	private ChildNodeTester<T, ExternalStructConverter> buildStructConverterTester() {
+		return null;
+	}
+
+	private ChildNodeTester<T, ExternalTypeConverter> buildTypeConverterTester() {
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ElementCollectionMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ElementCollectionMappingTests.java
new file mode 100644
index 0000000..15ad0ab
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ElementCollectionMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalElementCollectionMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalElementCollectionMapping}.
+ *
+ * @version 2.6
+ */
+public final class ElementCollectionMappingTests extends ConvertibleMappingTests<ExternalElementCollectionMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalElementCollectionMapping addMapping(ExternalEntity entity) {
+		return entity.addElementCollectionMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalElementCollectionMapping.ELEMENT_COLLECTION;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddableTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddableTests.java
index 8e37e96..9a33a12 100644
--- a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddableTests.java
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddableTests.java
@@ -18,6 +18,7 @@
 import java.util.Collections;
 import java.util.List;
 import org.eclipse.persistence.annotations.ChangeTrackingType;
+import org.eclipse.persistence.tools.mapping.ExternalForm;
 import org.eclipse.persistence.tools.mapping.ExternalProperty;
 import org.eclipse.persistence.tools.mapping.orm.AccessType;
 import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
@@ -55,7 +56,7 @@
 import org.w3c.dom.Node;
 
 /**
- * This unit-tests tests the behavior of {@link T}.
+ * This unit-tests tests the behavior of {@link ExternalEmbeddable}.
  *
  * @version 2.6
  */
@@ -63,28 +64,7 @@
 public class EmbeddableTests<T extends ExternalEmbeddable> extends AbstractExternalFormTests<T> {
 
 	final ChildNodeTester<T, ExternalAccessMethods> buildAccessMethodsTester() {
-		return new ChildNodeTester<T, ExternalAccessMethods>() {
-			@Override
-			public ExternalAccessMethods addChild(T form) {
-				return form.addAccessMethods(null, null);
-			}
-			@Override
-			public ExternalAccessMethods getChild(T form) {
-				return form.getAccessMethods();
-			}
-			@Override
-			public String getNodeName() {
-				return ExternalAccessMethods.ACCESS_METHODS;
-			}
-			@Override
-			public boolean hasChild(T form) {
-				return form.hasAccessMethods();
-			}
-			@Override
-			public void removeChild(T form) {
-				form.removeAccessMethods();
-			}
-		};
+		return AccessMethodsTests.buildAccessMethodsTester();
 	}
 
 	final AttributeNodeTester<T, AccessType> buildAccessTester() {
@@ -214,11 +194,6 @@
 			}
 
 			@Override
-			public String getContainerNodeName() {
-				return ExternalMapping.ATTRIBUTES;
-			}
-
-			@Override
 			public ExternalMapping addChild(T form, String value) {
 
 				// Extract the mapping name
@@ -372,6 +347,11 @@
 			}
 
 			@Override
+			public String getContainerNodeName() {
+				return ExternalMapping.ATTRIBUTES;
+			}
+
+			@Override
 			public String getExpectedChildValue(int index) {
 				// Return the mapping name that is ordered based on the mapping type
 				return expectedValues.get(index);
@@ -480,6 +460,10 @@
 				return ChangeTrackingType.DEFERRED;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -521,6 +505,10 @@
 				return "org.test.Embeddable_2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return false;
 			}
@@ -620,6 +608,10 @@
 				return "org.test.Customizer2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -661,6 +653,10 @@
 				return "something else";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -684,6 +680,11 @@
 				return (T) orm.addEmbeddable(defaultClassName());
 			}
 			@Override
+			@SuppressWarnings("unchecked")
+			public T buildExternalForm(ExternalForm parentForm) {
+				return (T) ((ExternalORMConfiguration) parentForm).addEmbeddable(defaultClassName());
+			}
+			@Override
 			public int getDefaultAttributeCount() {
 				return 1;
 			}
@@ -757,6 +758,10 @@
 				return Boolean.FALSE;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -835,6 +840,10 @@
 				return "org.test.ParentClass2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -885,7 +894,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	protected void populate(RootNodeTester<T> tester) {
+	protected void populate(RootNodeTester tester) {
 
 		tester.setBuilder(buildEmbeddableBuilder());
 
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddedIdMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddedIdMappingTests.java
new file mode 100644
index 0000000..4093c02
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddedIdMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedIDMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalEmbeddedIDMapping}.
+ *
+ * @version 2.6
+ */
+public final class EmbeddedIdMappingTests extends NonTriensientMappingTests<ExternalEmbeddedIDMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalEmbeddedIDMapping addMapping(ExternalEntity entity) {
+		return entity.addEmbeddedIdMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalEmbeddedIDMapping.EMBEDDED_ID;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddedMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddedMappingTests.java
new file mode 100644
index 0000000..ec4ec04
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EmbeddedMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalEmbeddedMapping}.
+ *
+ * @version 2.6
+ */
+public final class EmbeddedMappingTests extends NonTriensientMappingTests<ExternalEmbeddedMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalEmbeddedMapping addMapping(ExternalEntity entity) {
+		return entity.addEmbeddedMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalEmbeddedMapping.EMBEDDED;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EntityTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EntityTests.java
index 3ff132e..265e68c 100644
--- a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EntityTests.java
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/EntityTests.java
@@ -18,6 +18,7 @@
 import java.util.Collections;
 import java.util.List;
 import javax.persistence.InheritanceType;
+import org.eclipse.persistence.tools.mapping.ExternalForm;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityTable;
 import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
@@ -47,6 +48,10 @@
 				return orm.addEntity(defaultClassName());
 			}
 			@Override
+			public ExternalEntity buildExternalForm(ExternalForm parentForm) {
+				return ((ExternalORMConfiguration) parentForm).addEntity(defaultClassName());
+			}
+			@Override
 			public int getDefaultAttributeCount() {
 				return 1;
 			}
@@ -103,6 +108,10 @@
 				return InheritanceType.TABLE_PER_CLASS;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -144,6 +153,10 @@
 				return "address";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -297,7 +310,15 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	protected void populate(RootNodeTester<ExternalEntity> tester) {
+	String defaultClassName() {
+		return "org.eclipse.persistence.tool.mappings.tests.Entity";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected void populate(RootNodeTester tester) {
 
 		tester.setBuilder(buildEntityBuilder());
 
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/IdMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/IdMappingTests.java
new file mode 100644
index 0000000..e73aaf6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/IdMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalIDMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalIDMapping}.
+ *
+ * @version 2.6
+ */
+public final class IdMappingTests extends ConvertibleMappingTests<ExternalIDMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalIDMapping addMapping(ExternalEntity entity) {
+		return entity.addIdMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalIDMapping.ID;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ManyToManyMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ManyToManyMappingTests.java
new file mode 100644
index 0000000..3d1d6f1
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ManyToManyMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalManyToManyMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalManyToManyMapping}.
+ *
+ * @version 2.6
+ */
+public final class ManyToManyMappingTests extends ObjectCollectionMappingTests<ExternalManyToManyMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalManyToManyMapping addMapping(ExternalEntity entity) {
+		return entity.addManyToManyMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalManyToManyMapping.MANY_TO_MANY;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ManyToOneMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ManyToOneMappingTests.java
new file mode 100644
index 0000000..b534087
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ManyToOneMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalManyToOneMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalManyToOneMapping}.
+ *
+ * @version 2.6
+ */
+public final class ManyToOneMappingTests extends RelationshipMappingTests<ExternalManyToOneMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalManyToOneMapping addMapping(ExternalEntity entity) {
+		return entity.addManyToOneMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalManyToOneMapping.MANY_TO_ONE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/MappedSuperclassTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/MappedSuperclassTests.java
index 6586336..1db1dd7 100644
--- a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/MappedSuperclassTests.java
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/MappedSuperclassTests.java
@@ -11,6 +11,7 @@
 import java.util.Collections;
 import java.util.List;
 import org.eclipse.persistence.annotations.ExistenceType;
+import org.eclipse.persistence.tools.mapping.ExternalForm;
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicNamedQuery;
 import org.eclipse.persistence.tools.mapping.orm.ExternalCache;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddable;
@@ -69,6 +70,10 @@
 				return Boolean.FALSE;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -118,6 +123,10 @@
 				return "org.test.AnotherCacheInterceptor";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -258,6 +267,10 @@
 				return Boolean.FALSE;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -316,6 +329,10 @@
 				return ExistenceType.CHECK_CACHE;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -418,6 +435,10 @@
 				return "org.test.IDClass_2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -441,6 +462,11 @@
 				return (T) orm.addMappedSuperClass(defaultClassName());
 			}
 			@Override
+			@SuppressWarnings("unchecked")
+			public T buildExternalForm(ExternalForm parentForm) {
+				return (T) ((ExternalORMConfiguration) parentForm).addMappedSuperClass(defaultClassName());
+			}
+			@Override
 			public int getDefaultAttributeCount() {
 				return 1;
 			}
@@ -726,6 +752,10 @@
 				return "postLoadMethod2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -771,6 +801,10 @@
 				return "postPersistMethod2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -816,6 +850,10 @@
 				return "postRemoveMethod2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -861,6 +899,10 @@
 				return "postRemoveMethod2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -906,6 +948,10 @@
 				return "prePersistMethod2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -951,6 +997,10 @@
 				return "preRemoveMethod2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -996,6 +1046,10 @@
 				return "preUpdateMethod2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -1070,6 +1124,10 @@
 				return Boolean.FALSE;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -1174,7 +1232,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	protected void populate(RootNodeTester<T> tester) {
+	protected void populate(RootNodeTester tester) {
 
 		tester.setBuilder(buildMappedSuperclassBuilder());
 
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/MappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/MappingTests.java
new file mode 100644
index 0000000..0f570c8
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/MappingTests.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import org.eclipse.persistence.tools.mapping.ExternalForm;
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
+import org.eclipse.persistence.tools.mapping.tests.AbstractExternalFormTests;
+import org.eclipse.persistence.tools.utility.ObjectTools;
+import org.junit.After;
+import org.w3c.dom.Node;
+
+/**
+ * This root hierarchy of the unit-test testing the behavior of {@link ExternalMapping}.
+ *
+ * @version 2.6
+ */
+@SuppressWarnings("nls")
+public abstract class MappingTests<T extends ExternalMapping> extends AbstractExternalFormTests<T> {
+
+	/**
+	 * The cached name used when creating or accessing the mapping from its parent entity.
+	 */
+	private String mappingName;
+
+	/**
+	 * Adds the {@link AttributeNodeTester} for each attribute composing the mapping.
+	 *
+	 * @param tester The {@link RootNodeTester} is used to adds the appropriate testers to test the
+	 * property of a node; i.e. its attributes and child nodes
+	 */
+	abstract void addAttributeTesters(RootNodeTester tester);
+
+	/**
+	 * Adds the {@link NodeTester} for each child elements composing the mapping.
+	 *
+	 * @param tester The {@link RootNodeTester} is used to adds the appropriate testers to test the
+	 * property of a node; i.e. its attributes and child nodes
+	 */
+	abstract void addChildTesters(RootNodeTester tester);
+
+	/**
+	 * Adds to the given {@link ExternalEntity} the mapping being tested.
+	 *
+	 * @param entity The {@link ExternalEntity} representing the managed type
+	 */
+	abstract T addMapping(ExternalEntity entity);
+
+	final AttributeNodeTester<T, String> buildAttributeTypeTester() {
+		return new AttributeNodeTester<T, String>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return false;
+			}
+			@Override
+			public String getDefaultValue() {
+				return mappingName() + "_type_default";
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalMapping.ATTRIBUTE_TYPE;
+			}
+			@Override
+			public String getValue(T form) {
+				return form.getAttributeType();
+			}
+			@Override
+			public String getValue1() {
+				return mappingName() + "_type_one";
+			}
+			@Override
+			public String getValue2() {
+				return mappingName() + "_type_two";
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return true;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return true;
+			}
+			@Override
+			public void setValue(T form, String value) {
+				form.setAttributeType(value);
+			}
+			@Override
+			public String toString(String value) {
+				return value;
+			}
+		};
+	}
+
+	private ExternalFormBuilder<T> buildMappingBuilder() {
+		return new ExternalFormBuilder<T>() {
+			@Override
+			public T buildExternalForm() throws IOException {
+				ExternalORMConfiguration orm = ORMConfigurationTests.buildExternalForm();
+				ExternalEntity entity = orm.addEntity(entityClassName());
+				return addMapping(entity);
+			}
+			@Override
+			public T buildExternalForm(ExternalForm parentForm) {
+				return addMapping((ExternalEntity) parentForm);
+			}
+			@Override
+			public int getDefaultAttributeCount() {
+				return 1;
+			}
+			@Override
+			public Node getNode(T form) {
+				return ObjectTools.execute(form, "getElement");
+			}
+			@Override
+			public String getNodeName() {
+				return elementName();
+			}
+			@Override
+			public List<String> getTreeNodeNames() {
+				List<String> names = new ArrayList<String>();
+				names.add(ExternalORMConfiguration.ENTITY_MAPPINGS);
+				names.add(ExternalEntity.ENTITY);
+				names.add(ExternalMapping.ATTRIBUTES);
+				names.add(elementName());
+				return names;
+			}
+		};
+	}
+
+	final AttributeNodeTester<T, String> buildNameTester() {
+		return new AttributeNodeTester<T, String>() {
+			@Override
+			public boolean doesNodeAlreadyExist() {
+				return true;
+			}
+			@Override
+			public String getDefaultValue() {
+				return mappingName();
+			}
+			@Override
+			public String getNodeName() {
+				return ExternalMapping.NAME;
+			}
+			@Override
+			public String getValue(T form) {
+				return form.getName();
+			}
+			@Override
+			public String getValue1() {
+				return mappingName() + "_one";
+			}
+			@Override
+			public String getValue2() {
+				return mappingName() + "_two";
+			}
+			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
+			public boolean isNullAllowed() {
+				return false;
+			}
+			@Override
+			public void setValue(T form, String value) {
+				form.setName(value);
+			}
+			@Override
+			public String toString(String value) {
+				return value;
+			}
+		};
+	}
+
+	/**
+	 * The name of the element representing the mapping being tested.
+	 *
+	 * @return The mapping name
+	 */
+	abstract String elementName();
+
+	private String entityClassName() {
+		return "org.eclipse.persistence.tool.mappings.tests.Entity";
+	}
+
+	/**
+	 * Returns a uniquely generated name to be used as the mapping name.
+	 *
+	 * @return A unique string that is the same throughout the execution of this unit-test
+	 */
+	final String mappingName() {
+		if (mappingName == null) {
+			return "mapping_name_" + new Random().nextInt();
+		}
+		return mappingName;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	protected final void populate(RootNodeTester tester) {
+
+		tester.setBuilder(buildMappingBuilder());
+
+		addAttributeTesters(tester);
+		addChildTesters(tester);
+	}
+
+	@After
+	public void tearDown() {
+		mappingName = null;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/NonTriensientMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/NonTriensientMappingTests.java
new file mode 100644
index 0000000..66866c5
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/NonTriensientMappingTests.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalNonTransientMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalNonTransientMapping}.
+ *
+ * @version 2.6
+ */
+public abstract class NonTriensientMappingTests<T extends ExternalNonTransientMapping> extends MappingTests<T> {
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ORMConfigurationTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ORMConfigurationTests.java
index 97a14a1..fc722d3 100644
--- a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ORMConfigurationTests.java
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ORMConfigurationTests.java
@@ -17,6 +17,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import org.eclipse.persistence.tools.mapping.ExternalForm;
 import org.eclipse.persistence.tools.mapping.orm.AccessType;
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicNamedQuery;
 import org.eclipse.persistence.tools.mapping.orm.ExternalClassConverter;
@@ -92,6 +93,10 @@
 				return "CATALOG_VALUE_2";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -137,6 +142,10 @@
 				return "something";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -504,6 +513,10 @@
 				return ORMConfigurationTests.buildExternalForm();
 			}
 			@Override
+			public ORMConfiguration buildExternalForm(ExternalForm parentForm) {
+				return null;
+			}
+			@Override
 			public int getDefaultAttributeCount() {
 				return 4;
 			}
@@ -549,6 +562,10 @@
 				return "java.io";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -643,6 +660,10 @@
 				return "eclipselink";
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return true;
 			}
@@ -922,6 +943,10 @@
 				return ORMDocumentType.JPA_1_0;
 			}
 			@Override
+			public boolean isNodeDeletedWithNullValue() {
+				return false;
+			}
+			@Override
 			public boolean isNullAllowed() {
 				return false;
 			}
@@ -940,7 +965,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	protected void populate(RootNodeTester<ExternalORMConfiguration> tester) {
+	protected void populate(RootNodeTester tester) {
 
 		tester.setBuilder(buildORMConfigurationBuilder());
 
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ObjectCollectionMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ObjectCollectionMappingTests.java
new file mode 100644
index 0000000..4e035b9
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/ObjectCollectionMappingTests.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalObjectCollectionMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalObjectCollectionMapping}.
+ *
+ * @version 2.6
+ */
+public abstract class ObjectCollectionMappingTests<T extends ExternalObjectCollectionMapping> extends RelationshipMappingTests<T> {
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/OneToManyMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/OneToManyMappingTests.java
new file mode 100644
index 0000000..f146b8f
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/OneToManyMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalOneToManyMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalOneToManyMapping}.
+ *
+ * @version 2.6
+ */
+public final class OneToManyMappingTests extends ObjectCollectionMappingTests<ExternalOneToManyMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalOneToManyMapping addMapping(ExternalEntity entity) {
+		return entity.addOneToManyMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalOneToManyMapping.ONE_TO_MANY;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/OneToOneMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/OneToOneMappingTests.java
new file mode 100644
index 0000000..c6309a6
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/OneToOneMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalOneToOneMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalOneToOneMapping}.
+ *
+ * @version 2.6
+ */
+public final class OneToOneMappingTests extends RelationshipMappingTests<ExternalOneToOneMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalOneToOneMapping addMapping(ExternalEntity entity) {
+		return entity.addOneToOneMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalOneToOneMapping.ONE_TO_ONE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/RelationshipMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/RelationshipMappingTests.java
new file mode 100644
index 0000000..81d0f3e
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/RelationshipMappingTests.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalNonTransientMapping;
+
+/**
+ * This unit-tests tests the behavior of a relationship mapping.
+ *
+ * @version 2.6
+ */
+public abstract class RelationshipMappingTests<T extends ExternalNonTransientMapping> extends NonTriensientMappingTests<T> {
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/TransformationMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/TransformationMappingTests.java
new file mode 100644
index 0000000..8e21e52
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/TransformationMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalTransformationMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalTransformationMapping}.
+ *
+ * @version 2.6
+ */
+public final class TransformationMappingTests extends NonTriensientMappingTests<ExternalTransformationMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalTransformationMapping addMapping(ExternalEntity entity) {
+		return entity.addTransformationMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalTransformationMapping.TRANSFORMATION;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/TransientMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/TransientMappingTests.java
new file mode 100644
index 0000000..85e9596
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/TransientMappingTests.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalTransientMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalTransientMapping}.
+ *
+ * @version 2.6
+ */
+public final class TransientMappingTests extends MappingTests<ExternalTransientMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+//		tester.addAttribute(buildNameTester());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+		// Transient mapping does not have any children
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalTransientMapping addMapping(ExternalEntity entity) {
+		return entity.addTransientMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalTransientMapping.TRANSIENT;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/VariableOneToOneMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/VariableOneToOneMappingTests.java
new file mode 100644
index 0000000..be24754
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/VariableOneToOneMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalVariableOneToOneMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalVariableOneToOneMapping}.
+ *
+ * @version 2.6
+ */
+public final class VariableOneToOneMappingTests extends NonTriensientMappingTests<ExternalVariableOneToOneMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalVariableOneToOneMapping addMapping(ExternalEntity entity) {
+		return entity.addVariableOneToOneMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalVariableOneToOneMapping.VARIABLE_ONE_TO_ONE;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/VersionMappingTests.java b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/VersionMappingTests.java
new file mode 100644
index 0000000..9f190b0
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping.tests/src/org/eclipse/persistence/tools/mapping/tests/dom/orm/VersionMappingTests.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.tests.dom.orm;
+
+import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
+import org.eclipse.persistence.tools.mapping.orm.ExternalVersionMapping;
+
+/**
+ * This unit-tests tests the behavior of {@link ExternalVersionMapping}.
+ *
+ * @version 2.6
+ */
+public final class VersionMappingTests extends ConvertibleMappingTests<ExternalVersionMapping> {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addAttributeTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	void addChildTesters(RootNodeTester tester) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	ExternalVersionMapping addMapping(ExternalEntity entity) {
+		return entity.addVersionMapping(mappingName());
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	String elementName() {
+		return ExternalVersionMapping.VERSION;
+	}
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicCollectionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicCollectionMapping.java
index bc25643..d832737 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicCollectionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicCollectionMapping.java
@@ -52,6 +52,13 @@
 	String VALUE_COLUMN = "value-column";
 
 	/**
+	 * Visits this {@link ExternalBasicCollectionMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds a batch fetch to use.
 	 */
 	ExternalBatchFetch addBatchFetch();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicMapMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicMapMapping.java
index 96d0e10..46fc39d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicMapMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalBasicMapMapping.java
@@ -65,6 +65,13 @@
 	String VALUE_CONVERTER = "value-converter";
 
 	/**
+	 * Visits this {@link ExternalBasicMapMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds the key column for this mapping.
 	 */
 	ExternalEntityColumn addKeyColumn(String columnName);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalCache.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalCache.java
index b004fdc..a1b7f6c 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalCache.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalCache.java
@@ -145,7 +145,7 @@
 	 * Returns the {@link TextRange} for the cache's time to live before expiration.
 	 */
 	TextRange getExpiryTimeToLiveTextRange();
-	
+
 	/**
 	 * Returns the isolation type for this cache
 	 */
@@ -187,6 +187,11 @@
 	TextRange getTypeTextRange();
 
 	/**
+	 * Determines whether this cache's time of day for expiration is defined or not.
+	 */
+	boolean hasExpiryTimeOfDay();
+
+	/**
 	 * Returns whether this cache is always refreshed.
 	 */
 	Boolean isAlwaysRefresh();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalColumnMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalColumnMapping.java
index 7a07339..0e94015 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalColumnMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalColumnMapping.java
@@ -60,6 +60,16 @@
 	TextRange getTemporalTypeTextRange();
 
 	/**
+	 * Determines whether the column definition that represents the column is present or not.
+	 */
+	boolean hasColumn();
+
+	/**
+	 * Removes the column definition that represents the column from this mapping.
+	 */
+	void removeColumn();
+
+	/**
 	 * Creates new column definition to be used as the version column replacing the old one.
 	 */
 	void setColumn(String columnName);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalElementCollectionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalElementCollectionMapping.java
index 8abd93f..1052dd0 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalElementCollectionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalElementCollectionMapping.java
@@ -99,6 +99,13 @@
 	String TEMPORAL = "temporal";
 
 	/**
+	 * Visits this {@link ExternalElementCollectionMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds a override with the given name.
 	 */
 	ExternalAssociationOverride addAssociationOverride(String name);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java
index e0fabd6..fd35d4e 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedIDMapping.java
@@ -39,6 +39,13 @@
 	String EMBEDDED_ID = "embedded-id";
 
 	/**
+	 * Visits this {@link ExternalEmbeddedIDMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds a override with the given name.
 	 */
 	ExternalAttributeOverride addAttributeOverride(String name);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java
index 62c8e80..fba6f2d 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalEmbeddedMapping.java
@@ -37,6 +37,13 @@
 	String EMBEDDED = "embedded";
 
 	/**
+	 * Visits this {@link ExternalEmbeddedMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds a override with the given name
 	 */
 	ExternalAssociationOverride addAssociationOverride();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToManyMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToManyMapping.java
index 0b28c8e..4804e7b 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToManyMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToManyMapping.java
@@ -36,4 +36,11 @@
 	 * The node name used to store and retrieve the element encapsulated by this external form.
 	 */
 	String MANY_TO_MANY = "many-to-many";
+
+	/**
+	 * Visits this {@link ExternalManyToManyMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java
index a7b0b02..3e3916a 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalManyToOneMapping.java
@@ -50,6 +50,13 @@
 	String MAPS_ID = "maps-id";
 
 	/**
+	 * Visits this {@link ExternalManyToOneMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds a join column with the given name
 	 */
 	ExternalJoinColumn addJoinColumn(String name);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java
index 1d7fff5..7d65d1b 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMapping.java
@@ -83,26 +83,6 @@
 	String getSetMethodName();
 
 	/**
-	 * Indicates whether this mapping is of type {@link Basic}.
-	 */
-	boolean isBasicMapping();
-
-	/**
-	 * Indicates whether this mapping is of type {@link ElementCollection}.
-	 */
-	boolean isElementCollectionMapping();
-
-	/**
-	 * Indicates whether this mapping is of type {@link Embedded}.
-	 */
-	boolean isEmbeddedMapping();
-
-	/**
-	 * Indicates whether this mapping is of type {@link Id}.
-	 */
-	boolean isIdMapping();
-
-	/**
 	 * Sets the attribute type of this mapping.
 	 */
 	void setAttributeType(String attributeType);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappingVisitor.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappingVisitor.java
new file mode 100644
index 0000000..e1be1eb
--- /dev/null
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalMappingVisitor.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *     Oracle - initial API and implementation
+ *
+ ******************************************************************************/
+package org.eclipse.persistence.tools.mapping.orm;
+
+/**
+ * The interface is used to traverse the mapping SPI. It follows the Visitor pattern. It visits
+ * the leaf interfaces of {@link ExternalMapping}.
+ * <p>
+ * Provisional API: This interface is part of an interim API that is still under development and
+ * expected to change significantly before reaching stability. It is available at this early stage
+ * to solicit feedback from pioneering adopters on the understanding that any code that uses this
+ * API will almost certainly be broken (repeatedly) as the API evolves.
+ *
+ * @version 2.6
+ */
+public interface ExternalMappingVisitor {
+
+	/**
+	 * Visits the {@link ExternalBasicCollectionMapping} expression.
+	 *
+	 * @param expression The {@link ExternalBasicCollectionMapping} to visit
+	 */
+	void visit(ExternalBasicCollectionMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalBasicMapMapping} expression.
+	 *
+	 * @param expression The {@link ExternalBasicMapMapping} to visit
+	 */
+	void visit(ExternalBasicMapMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalBasicMapping} expression.
+	 *
+	 * @param expression The {@link ExternalBasicMapping} to visit
+	 */
+	void visit(ExternalBasicMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalElementCollectionMapping} expression.
+	 *
+	 * @param expression The {@link ExternalElementCollectionMapping} to visit
+	 */
+	void visit(ExternalElementCollectionMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalEmbeddedIDMapping} expression.
+	 *
+	 * @param expression The {@link ExternalEmbeddedIDMapping} to visit
+	 */
+	void visit(ExternalEmbeddedIDMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalEmbeddedMapping} expression.
+	 *
+	 * @param expression The {@link ExternalEmbeddedMapping} to visit
+	 */
+	void visit(ExternalEmbeddedMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalIDMapping} expression.
+	 *
+	 * @param expression The {@link ExternalIDMapping} to visit
+	 */
+	void visit(ExternalIDMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalManyToManyMapping} expression.
+	 *
+	 * @param expression The {@link ExternalManyToManyMapping} to visit
+	 */
+	void visit(ExternalManyToManyMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalManyToOneMapping} expression.
+	 *
+	 * @param expression The {@link ExternalManyToOneMapping} to visit
+	 */
+	void visit(ExternalManyToOneMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalOneToManyMapping} expression.
+	 *
+	 * @param expression The {@link ExternalOneToManyMapping} to visit
+	 */
+	void visit(ExternalOneToManyMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalOneToOneMapping} expression.
+	 *
+	 * @param expression The {@link ExternalOneToOneMapping} to visit
+	 */
+	void visit(ExternalOneToOneMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalTransformationMapping} expression.
+	 *
+	 * @param expression The {@link ExternalTransformationMapping} to visit
+	 */
+	void visit(ExternalTransformationMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalTransientMapping} expression.
+	 *
+	 * @param expression The {@link ExternalTransientMapping} to visit
+	 */
+	void visit(ExternalTransientMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalVariableOneToOneMapping} expression.
+	 *
+	 * @param expression The {@link ExternalVariableOneToOneMapping} to visit
+	 */
+	void visit(ExternalVariableOneToOneMapping mapping);
+
+	/**
+	 * Visits the {@link ExternalVersionMapping} expression.
+	 *
+	 * @param expression The {@link ExternalVersionMapping} to visit
+	 */
+	void visit(ExternalVersionMapping mapping);
+}
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java
index ce7d390..bba2e27 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransformationMapping.java
@@ -51,6 +51,13 @@
 	String TRANSFORMATION = "transformation";
 
 	/**
+	 * Visits this {@link ExternalTransformationMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds the read transformer.
 	 */
 	ExternalTransformer addReadTransformer();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransientMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransientMapping.java
index 01579f6..25ef7de 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransientMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalTransientMapping.java
@@ -33,4 +33,11 @@
 	 * The node name used to store and retrieve the element encapsulated by this external form.
 	 */
 	String TRANSIENT = "transient";
+
+	/**
+	 * Visits this {@link ExternalTransientMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
 }
\ No newline at end of file
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java
index 9849fd5..06db967 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVariableOneToOneMapping.java
@@ -94,6 +94,13 @@
 	String VARIABLE_ONE_TO_ONE = "variable-one-to-one";
 
 	/**
+	 * Visits this {@link ExternalVariableOneToOneMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Adds a cascaded type to use.
 	 */
 	void addCascadeType(CascadeType type);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVersionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVersionMapping.java
index cf5248f..99c4c05 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVersionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/ExternalVersionMapping.java
@@ -42,6 +42,13 @@
 	String VERSION = "version";
 
 	/**
+	 * Visits this {@link ExternalVersionMapping} by the given {@link ExternalMappingVisitor visitor}.
+	 *
+	 * @param visitor The {@link ExternalMappingVisitor} to visit this object
+	 */
+	void accept(ExternalMappingVisitor visitor);
+
+	/**
 	 * Returns the {@link TextRange} for the mutable value.
 	 */
 	TextRange getMutableTextRange();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java
index 4b6c9fe..a7dfb45 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/AccessMethods.java
@@ -69,7 +69,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final TextRange getGetMethodTextRange() {
+	public TextRange getGetMethodTextRange() {
 		return getAttributeTextRange(GET_METHOD);
 	}
 
@@ -85,7 +85,7 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final TextRange getSetMethodTextRange() {
+	public TextRange getSetMethodTextRange() {
 		return getAttributeTextRange(SET_METHOD);
 	}
 
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicCollectionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicCollectionMapping.java
index dbf3e81..d452603 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicCollectionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicCollectionMapping.java
@@ -21,6 +21,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalBatchFetch;
 import org.eclipse.persistence.tools.mapping.orm.ExternalCollectionTable;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.utility.TextRange;
 
 /**
@@ -46,6 +47,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalBatchFetch addBatchFetch() {
 		BatchFetch batchFetch = buildBatchFetch();
 		batchFetch.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapMapping.java
index 72b8889..f22bd75 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapMapping.java
@@ -22,6 +22,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalClassConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalCollectionTable;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
@@ -50,6 +51,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalBatchFetch addBatchFetch() {
 		BatchFetch batchFetch = buildBatchFetch();
 		batchFetch.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapping.java
index 3a9909c..c44b327 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/BasicMapping.java
@@ -21,6 +21,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalBasicMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityIDGeneratedValue;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlField;
 import org.eclipse.persistence.tools.mapping.orm.ExternalSequenceGenerator;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTableGenerator;
@@ -50,6 +51,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalEntityColumn addColumn() {
 		EntityColumn column = buildColumn();
 		column.addSelf();
@@ -311,8 +320,8 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public boolean isBasicMapping() {
-		return true;
+	public boolean hasColumn() {
+		return hasChild(EntityColumn.COLUMN);
 	}
 
 	/**
@@ -343,6 +352,15 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void removeColumn() {
+		EntityColumn column = buildColumn();
+		column.removeSelf();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public void removeGeneratedValue() {
 		EntityIDGeneratedValue generatedValue = buildGeneratedValue();
 		generatedValue.removeSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Cache.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Cache.java
index 7777b29..ea0dad2 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Cache.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Cache.java
@@ -146,7 +146,7 @@
 	@Override
 	public ExternalTimeOfDay getExpiryTimeOfDay() {
 
-		if (hasChild(TimeOfDay.EXPIRY_TIME_OF_DAY)) {
+		if (hasExpiryTimeOfDay()) {
 			return buildTimeOfDay();
 		}
 
@@ -245,6 +245,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public boolean hasExpiryTimeOfDay() {
+		return hasChild(TimeOfDay.EXPIRY_TIME_OF_DAY);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public Boolean isAlwaysRefresh() {
 		return getBooleanAttribute(ALWAYS_REFRESH);
 	}
@@ -295,7 +303,7 @@
 
 		setAttribute(ALWAYS_REFRESH, alwaysRefresh);
 
-		if (!hasAnything()) {
+		if ((alwaysRefresh == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -308,7 +316,7 @@
 
 		setAttribute(COORDINATION_TYPE, type);
 
-		if (!hasAnything()) {
+		if ((type == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -321,7 +329,7 @@
 
 		setAttribute(DATABASE_CHANGE_NOTIFICATION_TYPE, type);
 
-		if (!hasAnything()) {
+		if ((type == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -334,7 +342,7 @@
 
 		setAttribute(DISABLE_HITS, disableHits);
 
-		if (!hasAnything()) {
+		if ((disableHits == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -347,7 +355,7 @@
 
 		updateChildTextNode(EXPIRY, timeToLive);
 
-		if (!hasAnything()) {
+		if ((timeToLive == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -360,7 +368,7 @@
 
 		setAttribute(ISOLATION, isolationType);
 
-		if (!hasAnything()) {
+		if ((isolationType == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -373,7 +381,7 @@
 
 		setAttribute(REFRESH_ONLY_IF_NEWER, refreshOnlyIfNewer);
 
-		if (!hasAnything()) {
+		if ((refreshOnlyIfNewer == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -386,7 +394,7 @@
 
 		setAttribute(SHARED, shared);
 
-		if (!hasAnything()) {
+		if ((shared == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -399,7 +407,7 @@
 
 		setAttribute(SIZE, size);
 
-		if (!hasAnything()) {
+		if ((size == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
@@ -412,7 +420,7 @@
 
 		setAttribute(TYPE, type);
 
-		if (!hasAnything()) {
+		if ((type == null) && !hasAnything()) {
 			removeSelf();
 		}
 	}
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java
index efad47f..31abe83 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ElementCollectionMapping.java
@@ -27,6 +27,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalElementCollectionMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlField;
 import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
 import org.eclipse.persistence.tools.mapping.orm.ExternalOrderColumn;
@@ -58,6 +59,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalAssociationOverride addAssociationOverride(String name) {
 		AssociationOverride associationOverride = buildAssociationOverride(-1);
 		associationOverride.addSelf();
@@ -653,16 +662,16 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public boolean hasOrderByClause() {
-		return hasChild(ORDER_BY);
+	public boolean hasColumn() {
+		return hasChild(EntityColumn.COLUMN);
 	}
 
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	public boolean isElementCollectionMapping() {
-		return true;
+	public boolean hasOrderByClause() {
+		return hasChild(ORDER_BY);
 	}
 
 	/**
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java
index 150ad88..d2eb868 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedIDMapping.java
@@ -17,6 +17,7 @@
 import java.util.List;
 import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedIDMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 
 /**
  * The external form for a embedded ID mapping, which is a child of an entity.
@@ -41,6 +42,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalAttributeOverride addAttributeOverride(String name) {
 		AttributeOverride attributeOverride = buildAttributeOverride(-1);
 		attributeOverride.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java
index 147a79c..31cf0f9 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/EmbeddedMapping.java
@@ -18,6 +18,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalAssociationOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalAttributeOverride;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlField;
 
 /**
@@ -43,6 +44,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalAssociationOverride addAssociationOverride() {
 		AssociationOverride associationOverride = buildAssociationOverride(-1);
 		associationOverride.addSelf();
@@ -191,14 +200,6 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final boolean isEmbeddedMapping() {
-		return true;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
 	public void removeAssociationOverride(int index) {
 		AssociationOverride associationOverride = buildAssociationOverride(index);
 		associationOverride.removeSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
index bedd496..da174fc 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/IdMapping.java
@@ -19,6 +19,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityIDGeneratedValue;
 import org.eclipse.persistence.tools.mapping.orm.ExternalIDMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlField;
 import org.eclipse.persistence.tools.mapping.orm.ExternalSequenceGenerator;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTableGenerator;
@@ -47,6 +48,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalEntityColumn addColumn() {
 		EntityColumn column = buildColumn();
 		column.addSelf();
@@ -237,8 +246,8 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public final boolean isIdMapping() {
-		return true;
+	public boolean hasColumn() {
+		return hasChild(EntityColumn.COLUMN);
 	}
 
 	/**
@@ -253,6 +262,15 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void removeColumn() {
+		EntityColumn column = buildColumn();
+		column.removeSelf();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public void removeGeneratedValue() {
 		EntityIDGeneratedValue generatedValue = buildGeneratedValue();
 		generatedValue.removeSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java
index 48f9d76..7c3d113 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToManyMapping.java
@@ -16,6 +16,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import org.eclipse.persistence.tools.mapping.orm.ExternalManyToManyMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
 import org.eclipse.persistence.tools.utility.TextRange;
 
@@ -42,6 +43,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalNoSqlJoinField addJoinField(String name) {
 		NoSqlJoinField joinField = buildJoinField(-1);
 		joinField.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java
index d07762b..82eb850 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/ManyToOneMapping.java
@@ -17,6 +17,7 @@
 import java.util.List;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalManyToOneMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
 import org.eclipse.persistence.tools.utility.TextRange;
 
@@ -43,6 +44,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalJoinColumn addJoinColumn(String name) {
 		JoinColumn joinColumn = buildJoinColumn(-1);
 		joinColumn.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java
index 5069b94..909fefb 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/Mapping.java
@@ -159,38 +159,6 @@
 	}
 
 	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isBasicMapping() {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isElementCollectionMapping() {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isEmbeddedMapping() {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean isIdMapping() {
-		return false;
-	}
-
-	/**
 	 * Generates a JavaBean compliant method name based on the provided property name. Does not alter
 	 * the case of the property name if the second character is capitalized, e.g.:
 	 * <ul>
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java
index 77b544e..c688e03 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToManyMapping.java
@@ -17,6 +17,7 @@
 import java.util.List;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalManyToOneMapping;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
 import org.eclipse.persistence.tools.mapping.orm.ExternalOneToManyMapping;
 import org.eclipse.persistence.tools.utility.TextRange;
@@ -44,6 +45,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalJoinColumn addJoinColumn(String name) {
 		JoinColumn joinColumn = buildJoinColumn(JoinColumn.JOIN_COLUMN, -1);
 		joinColumn.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java
index dcf9a7e..8a5c9c6 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/OneToOneMapping.java
@@ -16,6 +16,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalNoSqlJoinField;
 import org.eclipse.persistence.tools.mapping.orm.ExternalOneToOneMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalPrimaryKeyJoinColumn;
@@ -44,6 +45,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalJoinColumn addJoinColumn(String name) {
 		JoinColumn joinColumn = buildJoinColumn(-1);
 		joinColumn.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java
index 50a533e..6f72113 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransformationMapping.java
@@ -16,6 +16,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.FetchType;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalReadTransformer;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransformationMapping;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransformer;
@@ -45,6 +46,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalTransformer addReadTransformer() {
 		ReadTransformer transformer = buildReadTransformer();
 		transformer.addSelf();
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransientMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransientMapping.java
index bda39ad..3d358da 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransientMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/TransientMapping.java
@@ -13,6 +13,7 @@
  ******************************************************************************/
 package org.eclipse.persistence.tools.mapping.orm.dom;
 
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalTransientMapping;
 
 /**
@@ -38,6 +39,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	protected String getElementName() {
 		return TRANSIENT;
 	}
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java
index 39b7bba..b07d2d2 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VariableOneToOneMapping.java
@@ -21,6 +21,7 @@
 import org.eclipse.persistence.tools.mapping.orm.ExternalDiscriminatorClass;
 import org.eclipse.persistence.tools.mapping.orm.ExternalDiscriminatorColumn;
 import org.eclipse.persistence.tools.mapping.orm.ExternalJoinColumn;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalVariableOneToOneMapping;
 import org.eclipse.persistence.tools.utility.ObjectTools;
 import org.eclipse.persistence.tools.utility.TextRange;
@@ -54,6 +55,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public void addCascadeType(CascadeType type) {
 
 		Element element = getChild(CASCADE);
diff --git a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VersionMapping.java b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VersionMapping.java
index 249ee55..51fdbfe 100644
--- a/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VersionMapping.java
+++ b/tools/org.eclipse.persistence.tools.mapping/src/org/eclipse/persistence/tools/mapping/orm/dom/VersionMapping.java
@@ -17,6 +17,7 @@
 import java.util.List;
 import javax.persistence.TemporalType;
 import org.eclipse.persistence.tools.mapping.orm.ExternalEntityColumn;
+import org.eclipse.persistence.tools.mapping.orm.ExternalMappingVisitor;
 import org.eclipse.persistence.tools.mapping.orm.ExternalVersionMapping;
 import org.eclipse.persistence.tools.utility.TextRange;
 
@@ -43,6 +44,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void accept(ExternalMappingVisitor visitor) {
+		visitor.visit(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public ExternalEntityColumn addColumn() {
 		EntityColumn column = buildColumn();
 		column.addSelf();
@@ -150,6 +159,14 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public boolean hasColumn() {
+		return hasChild(EntityColumn.COLUMN);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	public Boolean isMutable() {
 		return getBooleanAttribute(MUTABLE);
 	}
@@ -158,6 +175,15 @@
 	 * {@inheritDoc}
 	 */
 	@Override
+	public void removeColumn() {
+		EntityColumn column = buildColumn();
+		column.removeSelf();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
 	@SuppressWarnings("null")
 	public void setColumn(String columnName) {