You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by mb...@apache.org on 2017/11/17 16:12:11 UTC

[2/6] incubator-daffodil git commit: Property Resolution - part of fixing schema compilation

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-japi/src/test/java/edu/illinois/ncsa/daffodil/example/TestJavaAPI.java
----------------------------------------------------------------------
diff --git a/daffodil-japi/src/test/java/edu/illinois/ncsa/daffodil/example/TestJavaAPI.java b/daffodil-japi/src/test/java/edu/illinois/ncsa/daffodil/example/TestJavaAPI.java
index 69d452f..63fb7d7 100644
--- a/daffodil-japi/src/test/java/edu/illinois/ncsa/daffodil/example/TestJavaAPI.java
+++ b/daffodil-japi/src/test/java/edu/illinois/ncsa/daffodil/example/TestJavaAPI.java
@@ -58,803 +58,806 @@ import edu.illinois.ncsa.daffodil.japi.ParseResult;
 import edu.illinois.ncsa.daffodil.japi.ProcessorFactory;
 import edu.illinois.ncsa.daffodil.japi.UnparseResult;
 import edu.illinois.ncsa.daffodil.japi.ValidationMode;
+import edu.illinois.ncsa.daffodil.japi.infoset.JDOMInfosetInputter;
+import edu.illinois.ncsa.daffodil.japi.infoset.JDOMInfosetOutputter;
 import edu.illinois.ncsa.daffodil.japi.logger.ConsoleLogWriter;
 import edu.illinois.ncsa.daffodil.japi.logger.LogLevel;
-import edu.illinois.ncsa.daffodil.japi.infoset.JDOMInfosetOutputter;
-import edu.illinois.ncsa.daffodil.japi.infoset.JDOMInfosetInputter;
 
 public class TestJavaAPI {
 
-	public java.io.File getResource(String resPath) {
-		try {
-			return new java.io.File(this.getClass().getResource(resPath).toURI());
-		} catch (Exception e) {
-			return null;
-		}
-	}
-
-	@Test
-	public void testJavaAPI1() throws IOException {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-		DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		dp.setDebugger(debugger);
-		dp.setDebugging(true);
-		java.io.File file = getResource("/test/japi/myData.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 2 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertTrue(res.location().isAtEnd());
-		assertEquals(0, lw.errors.size());
-		assertEquals(0, lw.warnings.size());
-		assertTrue(lw.others.size() > 0);
-		assertTrue(debugger.lines.size() > 0);
-		assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
-		assertTrue(debugger.getCommand().equals("trace"));
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertEquals("42", bos.toString());
-
-		// reset the global logging and debugger state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	// This is a duplicate of test testJavaAPI1 that serializes the parser
-	// before executing the test.
-	@Test
-	public void testJavaAPI1_A() throws Exception {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-		DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-
-		// Serialize the parser to memory, then deserialize for parsing.
-		ByteArrayOutputStream os = new ByteArrayOutputStream();
-		WritableByteChannel output = Channels.newChannel(os);
-		dp.save(output);
-
-		ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
-		ReadableByteChannel input = Channels.newChannel(is);
-		edu.illinois.ncsa.daffodil.japi.Compiler compiler = Daffodil.compiler();
-		DataProcessor parser = compiler.reload(input);
-		parser.setDebugger(debugger);
-		parser.setDebugging(true);
-
-		java.io.File file = getResource("/test/japi/myData.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = parser.parse(rbc, outputter, 2 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertTrue(res.location().isAtEnd());
-		assertEquals(0, lw.errors.size());
-		assertEquals(0, lw.warnings.size());
-		assertTrue(lw.others.size() > 0);
-		assertTrue(debugger.lines.size() > 0);
-		assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
-		assertTrue(debugger.getCommand().equals("trace"));
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertEquals("42", bos.toString());
-
-		// reset the global logging and debugger state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	// This is a duplicate of test testJavaAPI1 that serializes the parser
-	// before executing the test.
-	@Test
-	public void testJavaAPI1_A_FullFails() throws Exception {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-		DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		dp.setDebugger(debugger);
-		dp.setDebugging(true);
-
-		// Serialize the parser to memory, then deserialize for parsing.
-		ByteArrayOutputStream os = new ByteArrayOutputStream();
-		WritableByteChannel output = Channels.newChannel(os);
-		dp.save(output);
-
-		ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
-		ReadableByteChannel input = Channels.newChannel(is);
-		edu.illinois.ncsa.daffodil.japi.Compiler compiler = Daffodil.compiler();
-		DataProcessor parser = compiler.reload(input);
-
-		try {
-			parser.setValidationMode(ValidationMode.Full);
-			fail();
-		} catch (InvalidUsageException e) {
-			assertEquals("'Full' validation not allowed when using a restored parser.", e.getMessage());
-		}
-
-		// reset the global logging and debugger state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	@Test
-	public void testJavaAPI2() throws IOException {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Info);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/myDataBroken.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter);
-
-		// TODO: NEED a java friendly way to get the status of the outputter. Scala enums don't work well
-		//assertTrue(outputter.getStatus() != Status.DONE); // This is a hack so that Java doesn't have to know about Nope/Maybe, need to figure out better api that is Java compatible
-		assertTrue(res.isError());
-		java.util.List<Diagnostic> diags = res.getDiagnostics();
-		assertEquals(1, diags.size());
-		Diagnostic d = diags.get(0);
-		// System.err.println(d.getMessage());
-		assertTrue(d.getMessage().contains("int"));
-		assertTrue(d.getMessage().contains("Not an int"));
-		assertTrue(d.getDataLocations().toString().contains("10"));
-		java.util.List<LocationInSchemaFile> locs = d.getLocationsInSchemaFiles();
-		assertEquals(1, locs.size());
-		LocationInSchemaFile loc = locs.get(0);
-		assertTrue(loc.toString().contains("mySchema2.dfdl.xsd"));
-
-		assertEquals(0, lw.errors.size());
-		assertEquals(0, lw.warnings.size());
-		// assertTrue(lw.infos.size() > 0);
-		assertEquals(0, lw.others.size());
-
-		// reset the global logging state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	/**
-	 * Verify that we can detect when the parse did not consume all the data.
-	 * 
-	 * @throws IOException
-	 */
-	@Test
-	public void testJavaAPI3() throws IOException {
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema3.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		pf.setDistinguishedRootNode("e3", null);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/myData16.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 16 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertFalse(res.location().isAtEnd());
-		assertEquals(2, res.location().bytePos1b());
-		assertEquals(9, res.location().bitPos1b());
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertEquals("9", bos.toString());
-	}
-
-	// This is a duplicate of test testJavaAPI3 that serializes the parser
-	// before executing the test.
-	@Test
-	public void testJavaAPI3_A() throws Exception {
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema3.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		pf.setDistinguishedRootNode("e3", null);
-		DataProcessor dp = pf.onPath("/");
-
-		// Serialize the parser to memory, then deserialize for parsing.
-		ByteArrayOutputStream os = new ByteArrayOutputStream();
-		WritableByteChannel output = Channels.newChannel(os);
-		dp.save(output);
-
-		ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
-		ReadableByteChannel input = Channels.newChannel(is);
-		edu.illinois.ncsa.daffodil.japi.Compiler compiler = Daffodil.compiler();
-		DataProcessor parser = compiler.reload(input);
-
-		java.io.File file = getResource("/test/japi/myData16.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = parser.parse(rbc, outputter, 16 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertFalse(res.location().isAtEnd());
-		assertEquals(2, res.location().bytePos1b());
-		assertEquals(9, res.location().bitPos1b());
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertEquals("9", bos.toString());
-	}
-
-	@Test
-	public void testJavaAPI4b() throws IOException {
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		File schemaFileName = getResource("/test/japi/mySchema3.dfdl.xsd");
-		c.setDistinguishedRootNode("e4", null);
-		ProcessorFactory pf = c.compileFile(schemaFileName);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/myData2.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 64 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertFalse(res.location().isAtEnd());
-		assertEquals(5, res.location().bytePos1b());
-		assertEquals(33, res.location().bitPos1b());
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertEquals("data", bos.toString());
-	}
-
-	@Test
-	public void testJavaAPI5() throws IOException {
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		File schemaFileName = getResource("/test/japi/mySchema3.dfdl.xsd");
-		c.setDistinguishedRootNode("e4", null); // e4 is a 4-byte long string
-												// element
-		ProcessorFactory pf = c.compileFile(schemaFileName);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/myData3.dat"); // contains 5
-																	// bytes
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 4 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertTrue("Assertion failed: End of data not reached.", res.location().isAtEnd());
-		assertEquals(5, res.location().bytePos1b());
-		assertEquals(33, res.location().bitPos1b());
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertEquals("data", bos.toString());
-	}
-
-	/***
-	 * Verify that the compiler throws a FileNotFound exception when fed a list
-	 * of schema files that do not exist.
-	 * 
-	 * @throws IOException
-	 */
-	@Test
-	public void testJavaAPI6() throws IOException {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = new java.io.File("/test/japi/notHere1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		assertTrue(pf.isError());
-		List<Diagnostic> diags = pf.getDiagnostics();
-		boolean found1 = false;
-		for (Diagnostic d : diags) {
-			if (d.getMessage().contains("notHere1")) {
-				found1 = true;
-			}
-		}
-		assertTrue(found1);
-
-		// reset the global logging state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	/**
-	 * Tests a user submitted case where the XML appears to be serializing odd
-	 * xml entities into the output.
-	 * 
-	 * @throws IOException
-	 */
-	@Test
-	public void testJavaAPI7() throws IOException {
-		// TODO: This is due to the fact that we are doing several conversions
-		// back and forth between Scala.xml.Node and JDOM. And the conversions
-		// both use XMLOutputter to format the result (which escapes the
-		// entities).
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/TopLevel.xsd");
-		c.setDistinguishedRootNode("TopLevel", null);
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/01very_simple.txt");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertTrue(res.location().isAtEnd());
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertTrue(bos.toString().contains("Return-Path: <bo...@smith.com>"));
-
-		// reset the global logging state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	/**
-	 * This test is nearly identical to testJavaAPI7. The only difference is
-	 * that this test uses double newline as a terminator for the first element
-	 * in the sequence rather than double newline as a separator for the
-	 * sequence
-	 * 
-	 * @throws IOException
-	 */
-	@Test
-	public void testJavaAPI8() throws IOException {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/TopLevel.xsd");
-		c.setDistinguishedRootNode("TopLevel2", null);
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/01very_simple.txt");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertTrue(res.location().isAtEnd());
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
-		UnparseResult res2 = dp.unparse(inputter, wbc);
-		err = res2.isError();
-		assertFalse(err);
-		assertTrue(bos.toString().contains("Return-Path: <bo...@smith.com>"));
-
-
-		// reset the global logging state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	/**
-	 * Verify that calling result() on the ParseResult multiple times does not
-	 * error.
-	 */
-	@Test
-	public void testJavaAPI9() throws IOException {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/TopLevel.xsd");
-		c.setDistinguishedRootNode("TopLevel2", null);
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/01very_simple.txt");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertTrue(res.location().isAtEnd());
-
-		org.jdom2.Document doc1 = outputter.getResult();
-
-		java.io.ByteArrayOutputStream bos1 = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc1 = java.nio.channels.Channels.newChannel(bos1);
-		JDOMInfosetInputter inputter1 = new JDOMInfosetInputter(doc1);
-		UnparseResult res2 = dp.unparse(inputter1, wbc1);
-		err = res2.isError();
-		assertFalse(err);
-		assertTrue(bos1.toString().contains("Return-Path: <bo...@smith.com>"));
-
-		org.jdom2.Document doc2 = outputter.getResult();
-
-		java.io.ByteArrayOutputStream bos2 = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc2 = java.nio.channels.Channels.newChannel(bos2);
-		JDOMInfosetInputter inputter2 = new JDOMInfosetInputter(doc2);
-		UnparseResult res3 = dp.unparse(inputter2, wbc2);
-		err = res3.isError();
-		assertFalse(err);
-		assertTrue(bos2.toString().contains("Return-Path: <bo...@smith.com>"));
-
-		// reset the global logging state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	/**
-	 * Verify that hidden elements do not appear in the resulting infoset
-	 */
-	@Test
-	public void testJavaAPI10() throws IOException {
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema4.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/myData4.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter);
-		boolean err = res.isError();
-		assertFalse(err);
-		org.jdom2.Document doc = outputter.getResult();
-		org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
-		xo.setFormat(Format.getPrettyFormat());
-		org.jdom2.Element rootNode = doc.getRootElement();
-		org.jdom2.Element hidden = rootNode.getChild("hiddenElement", rootNode.getNamespace());
-		assertTrue(null == hidden);
-		assertTrue(res.location().isAtEnd());
-	}
-
-	/**
-	 * Verify that nested elements do not appear as duplicates
-	 */
-	@Test
-	public void testJavaAPI11() throws IOException {
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema5.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/myData5.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter);
-		boolean err = res.isError();
-		assertFalse(err);
-		org.jdom2.Document doc = outputter.getResult();
-		org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
-		xo.setFormat(Format.getPrettyFormat());
-		// xo.output(doc, System.out);
-		org.jdom2.Element rootNode = doc.getRootElement();
-		org.jdom2.Element elementGroup = rootNode.getChild("elementGroup", null); // local
-																					// element
-																					// names
-																					// are
-																					// unqualified
-		assertTrue(null != elementGroup);
-		org.jdom2.Element groupE2 = elementGroup.getChild("e2", null);
-		assertTrue(null != groupE2);
-		org.jdom2.Element groupE3 = elementGroup.getChild("e3", null);
-		assertTrue(null != groupE3);
-		org.jdom2.Element rootE2 = rootNode.getChild("e2", null);
-		assertTrue(null == rootE2);
-		org.jdom2.Element rootE3 = rootNode.getChild("e3", null);
-		assertTrue(null == rootE3);
-		assertTrue(res.location().isAtEnd());
-	}
-
-	@Test
-	public void testJavaAPI12() throws IOException {
-		LogWriterForJAPITest2 lw2 = new LogWriterForJAPITest2();
-		DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
-
-		Daffodil.setLogWriter(lw2);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		dp.setDebugger(debugger);
-		dp.setDebugging(true);
-
-		java.io.File file = getResource("/test/japi/myData.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 2 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		assertTrue(res.location().isAtEnd());
-
-		assertEquals(0, lw2.errors.size());
-		assertEquals(0, lw2.warnings.size());
-		assertTrue(lw2.others.size() > 0);
-		assertTrue(debugger.lines.size() > 0);
-		assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
-
-		// reset the global logging and debugger state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	@Test
-	public void testJavaAPI13() throws IOException {
-		// Demonstrates here that we can set external variables
-		// after compilation but before parsing via Compiler.
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-		DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File extVarsFile = getResource("/test/japi/external_vars_1.xml");
-		java.io.File schemaFile = getResource("/test/japi/mySchemaWithVars.dfdl.xsd");
-		c.setExternalDFDLVariables(extVarsFile);
-		ProcessorFactory pf = c.compileFile(schemaFile);
-
-		DataProcessor dp = pf.onPath("/");
-		dp.setDebugger(debugger);
-		dp.setDebugging(true);
-
-		java.io.File file = getResource("/test/japi/myData.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 2 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		org.jdom2.Document doc = outputter.getResult();
-		org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
-		xo.setFormat(Format.getPrettyFormat());
-		String docString = xo.outputString(doc);
-		boolean containsVar1 = docString.contains("var1Value");
-		boolean containsVar1Value = docString.contains("externallySet");
-		assertTrue(containsVar1);
-		assertTrue(containsVar1Value);
-
-		// reset the global logging and debugger state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-	@Test
-	public void testJavaAPI14() throws IOException {
-		// Demonstrates here that we can set external variables
-		// after compilation but before parsing via DataProcessor.
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-		DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Debug);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File extVarFile = getResource("/test/japi/external_vars_1.xml");
-		java.io.File schemaFile = getResource("/test/japi/mySchemaWithVars.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		dp.setDebugger(debugger);
-		dp.setDebugging(true);
-		dp.setExternalVariables(extVarFile);
-
-		java.io.File file = getResource("/test/japi/myData.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 2 << 3);
-		boolean err = res.isError();
-		assertFalse(err);
-		org.jdom2.Document doc = outputter.getResult();
-		org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
-		xo.setFormat(Format.getPrettyFormat());
-		String docString = xo.outputString(doc);
-		boolean containsVar1 = docString.contains("var1Value");
-		boolean containsVar1Value = docString.contains("externallySet");
-		assertTrue(containsVar1);
-		assertTrue(containsVar1Value);
-		assertTrue(res.location().isAtEnd());
-
-		assertEquals(0, lw.errors.size());
-		assertEquals(0, lw.warnings.size());
-		assertTrue(lw.others.size() > 0);
-		assertTrue(debugger.lines.size() > 0);
-		assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
-
-		// reset the global logging and debugger state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-	
-	@Test
-	public void testJavaAPI15() throws IOException {
-		LogWriterForJAPITest lw = new LogWriterForJAPITest();
-
-		Daffodil.setLogWriter(lw);
-		Daffodil.setLoggingLevel(LogLevel.Info);
-
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		java.io.File file = getResource("/test/japi/myInfosetBroken.xml");
-		org.jdom2.input.SAXBuilder builder = new org.jdom2.input.SAXBuilder();
-
-		org.jdom2.Document doc = null;
-		try {
-			doc = builder.build(file);
-		} catch (Exception e) {
-			fail();
-		}
-
-		java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
-		java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
-		JDOMInfosetInputter inputter = new JDOMInfosetInputter(doc);
-		UnparseResult res = dp.unparse(inputter, wbc);
-		boolean err = res.isError();
-		assertTrue(err);
-
-		java.util.List<Diagnostic> diags = res.getDiagnostics();
-		assertEquals(1, diags.size());
-		Diagnostic d = diags.get(0);
-		assertTrue(d.getMessage().contains("wrong"));
-		assertTrue(d.getMessage().contains("e1"));
-
-		// reset the global logging state
-		Daffodil.setLogWriter(new ConsoleLogWriter());
-		Daffodil.setLoggingLevel(LogLevel.Info);
-	}
-
-
-	@Test
-	public void testJavaAPI16() throws IOException, InvalidUsageException {
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		dp.setValidationMode(ValidationMode.Limited);
-		java.io.File file = getResource("/test/japi/myData.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 2 << 3);
-		assertTrue(res.isError());
-		assertFalse(res.isProcessingError());
-		assertTrue(res.isValidationError());
-		assertTrue(res.location().isAtEnd());
-
-		java.util.List<Diagnostic> diags = res.getDiagnostics();
-		assertEquals(1, diags.size());
-		Diagnostic d = diags.get(0);
-		assertTrue(d.getMessage().contains("maxInclusive"));
-		assertTrue(d.getMessage().contains("e2"));
-		assertTrue(d.getMessage().contains("20"));
-	}
-
-	@Test
-	public void testJavaAPI17() throws IOException, InvalidUsageException {
-		edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
-		c.setValidateDFDLSchemas(false);
-		java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
-		ProcessorFactory pf = c.compileFile(schemaFile);
-		DataProcessor dp = pf.onPath("/");
-		dp.setValidationMode(ValidationMode.Full);
-		java.io.File file = getResource("/test/japi/myData.dat");
-		java.io.FileInputStream fis = new java.io.FileInputStream(file);
-		java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
-		JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
-		ParseResult res = dp.parse(rbc, outputter, 2 << 3);
-		assertTrue(res.isError());
-		assertFalse(res.isProcessingError());
-		assertTrue(res.isValidationError());
-		assertTrue(res.location().isAtEnd());
-
-		java.util.List<Diagnostic> diags = res.getDiagnostics();
-		assertEquals(3, diags.size());
-		Diagnostic d0 = diags.get(0);
-		Diagnostic d1 = diags.get(1);
-		Diagnostic d2 = diags.get(2);
-
-		assertTrue(d0.getMessage().contains("42"));
-		assertTrue(d0.getMessage().contains("e2"));
-		assertTrue(d0.getMessage().contains("not valid"));
-
-		assertTrue(d1.getMessage().contains("42"));
-		assertTrue(d1.getMessage().contains("maxInclusive"));
-		assertTrue(d1.getMessage().contains("20"));
-
-		assertTrue(d2.getMessage().contains("maxInclusive"));
-		assertTrue(d2.getMessage().contains("e2"));
-		assertTrue(d2.getMessage().contains("20"));
-	}
+    public java.io.File getResource(String resPath) {
+        try {
+            return new java.io.File(this.getClass().getResource(resPath).toURI());
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    @Test
+    public void testJavaAPI1() throws IOException {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+        DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        dp.setDebugger(debugger);
+        dp.setDebugging(true);
+        java.io.File file = getResource("/test/japi/myData.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 2 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertTrue(res.location().isAtEnd());
+        assertEquals(0, lw.errors.size());
+        assertEquals(0, lw.warnings.size());
+        assertTrue(lw.others.size() > 0);
+        assertTrue(debugger.lines.size() > 0);
+        assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
+        assertTrue(debugger.getCommand().equals("trace"));
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertEquals("42", bos.toString());
+
+        // reset the global logging and debugger state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    // This is a duplicate of test testJavaAPI1 that serializes the parser
+    // before executing the test.
+    @Test
+    public void testJavaAPI1_A() throws Exception {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+        DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+
+        // Serialize the parser to memory, then deserialize for parsing.
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        WritableByteChannel output = Channels.newChannel(os);
+        dp.save(output);
+
+        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+        ReadableByteChannel input = Channels.newChannel(is);
+        edu.illinois.ncsa.daffodil.japi.Compiler compiler = Daffodil.compiler();
+        DataProcessor parser = compiler.reload(input);
+        parser.setDebugger(debugger);
+        parser.setDebugging(true);
+
+        java.io.File file = getResource("/test/japi/myData.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = parser.parse(rbc, outputter, 2 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertTrue(res.location().isAtEnd());
+        assertEquals(0, lw.errors.size());
+        assertEquals(0, lw.warnings.size());
+        assertTrue(lw.others.size() > 0);
+        assertTrue(debugger.lines.size() > 0);
+        assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
+        assertTrue(debugger.getCommand().equals("trace"));
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertEquals("42", bos.toString());
+
+        // reset the global logging and debugger state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    // This is a duplicate of test testJavaAPI1 that serializes the parser
+    // before executing the test.
+    @Test
+    public void testJavaAPI1_A_FullFails() throws Exception {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+        DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        dp.setDebugger(debugger);
+        dp.setDebugging(true);
+
+        // Serialize the parser to memory, then deserialize for parsing.
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        WritableByteChannel output = Channels.newChannel(os);
+        dp.save(output);
+
+        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+        ReadableByteChannel input = Channels.newChannel(is);
+        edu.illinois.ncsa.daffodil.japi.Compiler compiler = Daffodil.compiler();
+        DataProcessor parser = compiler.reload(input);
+
+        try {
+            parser.setValidationMode(ValidationMode.Full);
+            fail();
+        } catch (InvalidUsageException e) {
+            assertEquals("'Full' validation not allowed when using a restored parser.", e.getMessage());
+        }
+
+        // reset the global logging and debugger state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    @Test
+    public void testJavaAPI2() throws IOException {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Info);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/myDataBroken.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter);
+
+        // TODO: NEED a java friendly way to get the status of the outputter.
+        // Scala enums don't work well
+        // assertTrue(outputter.getStatus() != Status.DONE); // This is a hack
+        // so that Java doesn't have to know about Nope/Maybe, need to figure
+        // out better api that is Java compatible
+        assertTrue(res.isError());
+        java.util.List<Diagnostic> diags = res.getDiagnostics();
+        assertEquals(1, diags.size());
+        Diagnostic d = diags.get(0);
+        // System.err.println(d.getMessage());
+        assertTrue(d.getMessage().contains("int"));
+        assertTrue(d.getMessage().contains("Not an int"));
+        assertTrue(d.getDataLocations().toString().contains("10"));
+        java.util.List<LocationInSchemaFile> locs = d.getLocationsInSchemaFiles();
+        assertEquals(1, locs.size());
+        LocationInSchemaFile loc = locs.get(0);
+        assertTrue(loc.toString().contains("mySchema1.dfdl.xsd"));
+        // above is mySchema1 as it reports the element ref location,
+        // not element decl.
+
+        assertEquals(0, lw.errors.size());
+        assertEquals(0, lw.warnings.size());
+        // assertTrue(lw.infos.size() > 0);
+        assertEquals(0, lw.others.size());
+
+        // reset the global logging state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    /**
+     * Verify that we can detect when the parse did not consume all the data.
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testJavaAPI3() throws IOException {
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema3.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        pf.setDistinguishedRootNode("e3", null);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/myData16.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 16 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertFalse(res.location().isAtEnd());
+        assertEquals(2, res.location().bytePos1b());
+        assertEquals(9, res.location().bitPos1b());
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertEquals("9", bos.toString());
+    }
+
+    // This is a duplicate of test testJavaAPI3 that serializes the parser
+    // before executing the test.
+    @Test
+    public void testJavaAPI3_A() throws Exception {
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema3.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        pf.setDistinguishedRootNode("e3", null);
+        DataProcessor dp = pf.onPath("/");
+
+        // Serialize the parser to memory, then deserialize for parsing.
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        WritableByteChannel output = Channels.newChannel(os);
+        dp.save(output);
+
+        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+        ReadableByteChannel input = Channels.newChannel(is);
+        edu.illinois.ncsa.daffodil.japi.Compiler compiler = Daffodil.compiler();
+        DataProcessor parser = compiler.reload(input);
+
+        java.io.File file = getResource("/test/japi/myData16.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = parser.parse(rbc, outputter, 16 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertFalse(res.location().isAtEnd());
+        assertEquals(2, res.location().bytePos1b());
+        assertEquals(9, res.location().bitPos1b());
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertEquals("9", bos.toString());
+    }
+
+    @Test
+    public void testJavaAPI4b() throws IOException {
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        File schemaFileName = getResource("/test/japi/mySchema3.dfdl.xsd");
+        c.setDistinguishedRootNode("e4", null);
+        ProcessorFactory pf = c.compileFile(schemaFileName);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/myData2.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 64 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertFalse(res.location().isAtEnd());
+        assertEquals(5, res.location().bytePos1b());
+        assertEquals(33, res.location().bitPos1b());
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertEquals("data", bos.toString());
+    }
+
+    @Test
+    public void testJavaAPI5() throws IOException {
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        File schemaFileName = getResource("/test/japi/mySchema3.dfdl.xsd");
+        c.setDistinguishedRootNode("e4", null); // e4 is a 4-byte long string
+                                                // element
+        ProcessorFactory pf = c.compileFile(schemaFileName);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/myData3.dat"); // contains 5
+                                                                   // bytes
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 4 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertTrue("Assertion failed: End of data not reached.", res.location().isAtEnd());
+        assertEquals(5, res.location().bytePos1b());
+        assertEquals(33, res.location().bitPos1b());
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertEquals("data", bos.toString());
+    }
+
+    /***
+     * Verify that the compiler throws a FileNotFound exception when fed a list
+     * of schema files that do not exist.
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testJavaAPI6() throws IOException {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = new java.io.File("/test/japi/notHere1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        assertTrue(pf.isError());
+        List<Diagnostic> diags = pf.getDiagnostics();
+        boolean found1 = false;
+        for (Diagnostic d : diags) {
+            if (d.getMessage().contains("notHere1")) {
+                found1 = true;
+            }
+        }
+        assertTrue(found1);
+
+        // reset the global logging state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    /**
+     * Tests a user submitted case where the XML appears to be serializing odd
+     * xml entities into the output.
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testJavaAPI7() throws IOException {
+        // TODO: This is due to the fact that we are doing several conversions
+        // back and forth between Scala.xml.Node and JDOM. And the conversions
+        // both use XMLOutputter to format the result (which escapes the
+        // entities).
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/TopLevel.xsd");
+        c.setDistinguishedRootNode("TopLevel", null);
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/01very_simple.txt");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertTrue(res.location().isAtEnd());
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertTrue(bos.toString().contains("Return-Path: <bo...@smith.com>"));
+
+        // reset the global logging state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    /**
+     * This test is nearly identical to testJavaAPI7. The only difference is
+     * that this test uses double newline as a terminator for the first element
+     * in the sequence rather than double newline as a separator for the
+     * sequence
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testJavaAPI8() throws IOException {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/TopLevel.xsd");
+        c.setDistinguishedRootNode("TopLevel2", null);
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/01very_simple.txt");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertTrue(res.location().isAtEnd());
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(outputter.getResult());
+        UnparseResult res2 = dp.unparse(inputter, wbc);
+        err = res2.isError();
+        assertFalse(err);
+        assertTrue(bos.toString().contains("Return-Path: <bo...@smith.com>"));
+
+        // reset the global logging state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    /**
+     * Verify that calling result() on the ParseResult multiple times does not
+     * error.
+     */
+    @Test
+    public void testJavaAPI9() throws IOException {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/TopLevel.xsd");
+        c.setDistinguishedRootNode("TopLevel2", null);
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/01very_simple.txt");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertTrue(res.location().isAtEnd());
+
+        org.jdom2.Document doc1 = outputter.getResult();
+
+        java.io.ByteArrayOutputStream bos1 = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc1 = java.nio.channels.Channels.newChannel(bos1);
+        JDOMInfosetInputter inputter1 = new JDOMInfosetInputter(doc1);
+        UnparseResult res2 = dp.unparse(inputter1, wbc1);
+        err = res2.isError();
+        assertFalse(err);
+        assertTrue(bos1.toString().contains("Return-Path: <bo...@smith.com>"));
+
+        org.jdom2.Document doc2 = outputter.getResult();
+
+        java.io.ByteArrayOutputStream bos2 = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc2 = java.nio.channels.Channels.newChannel(bos2);
+        JDOMInfosetInputter inputter2 = new JDOMInfosetInputter(doc2);
+        UnparseResult res3 = dp.unparse(inputter2, wbc2);
+        err = res3.isError();
+        assertFalse(err);
+        assertTrue(bos2.toString().contains("Return-Path: <bo...@smith.com>"));
+
+        // reset the global logging state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    /**
+     * Verify that hidden elements do not appear in the resulting infoset
+     */
+    @Test
+    public void testJavaAPI10() throws IOException {
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema4.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/myData4.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter);
+        boolean err = res.isError();
+        assertFalse(err);
+        org.jdom2.Document doc = outputter.getResult();
+        org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
+        xo.setFormat(Format.getPrettyFormat());
+        org.jdom2.Element rootNode = doc.getRootElement();
+        org.jdom2.Element hidden = rootNode.getChild("hiddenElement", rootNode.getNamespace());
+        assertTrue(null == hidden);
+        assertTrue(res.location().isAtEnd());
+    }
+
+    /**
+     * Verify that nested elements do not appear as duplicates
+     */
+    @Test
+    public void testJavaAPI11() throws IOException {
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema5.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/myData5.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter);
+        boolean err = res.isError();
+        assertFalse(err);
+        org.jdom2.Document doc = outputter.getResult();
+        org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
+        xo.setFormat(Format.getPrettyFormat());
+        // xo.output(doc, System.out);
+        org.jdom2.Element rootNode = doc.getRootElement();
+        org.jdom2.Element elementGroup = rootNode.getChild("elementGroup", null); // local
+                                                                                  // element
+                                                                                  // names
+                                                                                  // are
+                                                                                  // unqualified
+        assertTrue(null != elementGroup);
+        org.jdom2.Element groupE2 = elementGroup.getChild("e2", null);
+        assertTrue(null != groupE2);
+        org.jdom2.Element groupE3 = elementGroup.getChild("e3", null);
+        assertTrue(null != groupE3);
+        org.jdom2.Element rootE2 = rootNode.getChild("e2", null);
+        assertTrue(null == rootE2);
+        org.jdom2.Element rootE3 = rootNode.getChild("e3", null);
+        assertTrue(null == rootE3);
+        assertTrue(res.location().isAtEnd());
+    }
+
+    @Test
+    public void testJavaAPI12() throws IOException {
+        LogWriterForJAPITest2 lw2 = new LogWriterForJAPITest2();
+        DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
+
+        Daffodil.setLogWriter(lw2);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        dp.setDebugger(debugger);
+        dp.setDebugging(true);
+
+        java.io.File file = getResource("/test/japi/myData.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 2 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        assertTrue(res.location().isAtEnd());
+
+        assertEquals(0, lw2.errors.size());
+        assertEquals(0, lw2.warnings.size());
+        assertTrue(lw2.others.size() > 0);
+        assertTrue(debugger.lines.size() > 0);
+        assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
+
+        // reset the global logging and debugger state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    @Test
+    public void testJavaAPI13() throws IOException {
+        // Demonstrates here that we can set external variables
+        // after compilation but before parsing via Compiler.
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+        DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File extVarsFile = getResource("/test/japi/external_vars_1.xml");
+        java.io.File schemaFile = getResource("/test/japi/mySchemaWithVars.dfdl.xsd");
+        c.setExternalDFDLVariables(extVarsFile);
+        ProcessorFactory pf = c.compileFile(schemaFile);
+
+        DataProcessor dp = pf.onPath("/");
+        dp.setDebugger(debugger);
+        dp.setDebugging(true);
+
+        java.io.File file = getResource("/test/japi/myData.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 2 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        org.jdom2.Document doc = outputter.getResult();
+        org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
+        xo.setFormat(Format.getPrettyFormat());
+        String docString = xo.outputString(doc);
+        boolean containsVar1 = docString.contains("var1Value");
+        boolean containsVar1Value = docString.contains("externallySet");
+        assertTrue(containsVar1);
+        assertTrue(containsVar1Value);
+
+        // reset the global logging and debugger state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    @Test
+    public void testJavaAPI14() throws IOException {
+        // Demonstrates here that we can set external variables
+        // after compilation but before parsing via DataProcessor.
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+        DebuggerRunnerForJAPITest debugger = new DebuggerRunnerForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Debug);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File extVarFile = getResource("/test/japi/external_vars_1.xml");
+        java.io.File schemaFile = getResource("/test/japi/mySchemaWithVars.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        dp.setDebugger(debugger);
+        dp.setDebugging(true);
+        dp.setExternalVariables(extVarFile);
+
+        java.io.File file = getResource("/test/japi/myData.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 2 << 3);
+        boolean err = res.isError();
+        assertFalse(err);
+        org.jdom2.Document doc = outputter.getResult();
+        org.jdom2.output.XMLOutputter xo = new org.jdom2.output.XMLOutputter();
+        xo.setFormat(Format.getPrettyFormat());
+        String docString = xo.outputString(doc);
+        boolean containsVar1 = docString.contains("var1Value");
+        boolean containsVar1Value = docString.contains("externallySet");
+        assertTrue(containsVar1);
+        assertTrue(containsVar1Value);
+        assertTrue(res.location().isAtEnd());
+
+        assertEquals(0, lw.errors.size());
+        assertEquals(0, lw.warnings.size());
+        assertTrue(lw.others.size() > 0);
+        assertTrue(debugger.lines.size() > 0);
+        assertTrue(debugger.lines.contains("----------------------------------------------------------------- 1\n"));
+
+        // reset the global logging and debugger state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    @Test
+    public void testJavaAPI15() throws IOException {
+        LogWriterForJAPITest lw = new LogWriterForJAPITest();
+
+        Daffodil.setLogWriter(lw);
+        Daffodil.setLoggingLevel(LogLevel.Info);
+
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        java.io.File file = getResource("/test/japi/myInfosetBroken.xml");
+        org.jdom2.input.SAXBuilder builder = new org.jdom2.input.SAXBuilder();
+
+        org.jdom2.Document doc = null;
+        try {
+            doc = builder.build(file);
+        } catch (Exception e) {
+            fail();
+        }
+
+        java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
+        java.nio.channels.WritableByteChannel wbc = java.nio.channels.Channels.newChannel(bos);
+        JDOMInfosetInputter inputter = new JDOMInfosetInputter(doc);
+        UnparseResult res = dp.unparse(inputter, wbc);
+        boolean err = res.isError();
+        assertTrue(err);
+
+        java.util.List<Diagnostic> diags = res.getDiagnostics();
+        assertEquals(1, diags.size());
+        Diagnostic d = diags.get(0);
+        assertTrue(d.getMessage().contains("wrong"));
+        assertTrue(d.getMessage().contains("e1"));
+
+        // reset the global logging state
+        Daffodil.setLogWriter(new ConsoleLogWriter());
+        Daffodil.setLoggingLevel(LogLevel.Info);
+    }
+
+    @Test
+    public void testJavaAPI16() throws IOException, InvalidUsageException {
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        dp.setValidationMode(ValidationMode.Limited);
+        java.io.File file = getResource("/test/japi/myData.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 2 << 3);
+        assertTrue(res.isError());
+        assertFalse(res.isProcessingError());
+        assertTrue(res.isValidationError());
+        assertTrue(res.location().isAtEnd());
+
+        java.util.List<Diagnostic> diags = res.getDiagnostics();
+        assertEquals(1, diags.size());
+        Diagnostic d = diags.get(0);
+        assertTrue(d.getMessage().contains("maxInclusive"));
+        assertTrue(d.getMessage().contains("e2"));
+        assertTrue(d.getMessage().contains("20"));
+    }
+
+    @Test
+    public void testJavaAPI17() throws IOException, InvalidUsageException {
+        edu.illinois.ncsa.daffodil.japi.Compiler c = Daffodil.compiler();
+        c.setValidateDFDLSchemas(false);
+        java.io.File schemaFile = getResource("/test/japi/mySchema1.dfdl.xsd");
+        ProcessorFactory pf = c.compileFile(schemaFile);
+        DataProcessor dp = pf.onPath("/");
+        dp.setValidationMode(ValidationMode.Full);
+        java.io.File file = getResource("/test/japi/myData.dat");
+        java.io.FileInputStream fis = new java.io.FileInputStream(file);
+        java.nio.channels.ReadableByteChannel rbc = java.nio.channels.Channels.newChannel(fis);
+        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
+        ParseResult res = dp.parse(rbc, outputter, 2 << 3);
+        assertTrue(res.isError());
+        assertFalse(res.isProcessingError());
+        assertTrue(res.isValidationError());
+        assertTrue(res.location().isAtEnd());
+
+        java.util.List<Diagnostic> diags = res.getDiagnostics();
+        assertEquals(3, diags.size());
+        Diagnostic d0 = diags.get(0);
+        Diagnostic d1 = diags.get(1);
+        Diagnostic d2 = diags.get(2);
+
+        assertTrue(d0.getMessage().contains("42"));
+        assertTrue(d0.getMessage().contains("e2"));
+        assertTrue(d0.getMessage().contains("not valid"));
+
+        assertTrue(d1.getMessage().contains("42"));
+        assertTrue(d1.getMessage().contains("maxInclusive"));
+        assertTrue(d1.getMessage().contains("20"));
+
+        assertTrue(d2.getMessage().contains("maxInclusive"));
+        assertTrue(d2.getMessage().contains("e2"));
+        assertTrue(d2.getMessage().contains("20"));
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/oolag/OOLAG.scala
----------------------------------------------------------------------
diff --git a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/oolag/OOLAG.scala b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/oolag/OOLAG.scala
index 2a81b31..3eab287 100644
--- a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/oolag/OOLAG.scala
+++ b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/oolag/OOLAG.scala
@@ -46,7 +46,8 @@ import edu.illinois.ncsa.daffodil.util.Maybe._
  * OOLAG = Object-oriented Lazy Attribute Grammars
  *
  * It's a collection of techniques for compilation/transformation
- * in a functional programming style
+ * in a functional programming style. You can find an article about
+ * Attribute Grammars on Wikipedia.
  */
 
 object OOLAG extends Logging {
@@ -89,28 +90,48 @@ object OOLAG extends Logging {
    */
   private val OOLAGRoot: OOLAGHost = null
 
-  private sealed abstract class Args
-  private case object OneArg extends Args
-  private case object ZeroArgs extends Args
+  sealed abstract class Args
+  case object OneArg extends Args
+  case object ZeroArgs extends Args
+
+  /**
+   * Convenience class for implementing OOLAGHost trait.
+   *
+   *  Insures context is set by way of construction. Use the trait and
+   *  implement the context yourself if you want to make use of setting the
+   *  context after the objects are constructed.
+   */
+  abstract class OOLAGHostImpl private (
+    oolagContextArg: OOLAGHost,
+    final override val nArgs: Args)
+    extends OOLAGHost {
+
+    def this(oolagContext: OOLAGHost) = this(oolagContext, OneArg)
+    def this() = this(null, ZeroArgs)
+
+    final protected override def oolagContextViaArgs = {
+      Some(oolagContextArg)
+    }
+  }
 
   /**
    * An OOLAGHost, or OOLAG for short, is a collection of OOLAGValues
    * or LVs for short.
    *
    * The way these are generally used now is like this
-   *
+   * {{{
    *  def foo = LV('foo) {...calculation...}.value
-   *
+   * }}}
    * or, if you would like a slot to show up in the debugger so you
    * can more easily see the value of the LV then you can
-   *
+   * {{{
    * lazy val foo = LV('foo){...calculation...}.value
-   *
+   * }}}
    * Why scala needs 'real' Lisp-style macros: Well wouldn't it be
    * nicer if I could write:
-   *
+   * {{{
    *    defAttribute foo {... calculation ...}
-   *
+   * }}}
    * and have that be equivalent the more verbose stuff above it?
    * But I digress...
    *
@@ -123,18 +144,21 @@ object OOLAG extends Logging {
    * we want to say that our particular OOLAGHost-derived class must
    * evaluate the 'foo' LV otherwise we don't know if it has errors or not,
    * then we write:
-   *
+   * {{{
    *     requiredEvaluations(foo)
-   *
+   * }}}
    * This goes at the top of the class definition. When isError is invoked
    * the value of 'foo' will be computed if it has not been attempted
    * already. This insures that the value exists for 'foo', or any errors/warnings
    * to be determined by its calculation have been recorded.
    */
-  abstract class OOLAGHost private (oolagContextArg: OOLAGHost, nArgs: Args)
+  trait OOLAGHost
     extends Logging with WithDiagnostics
     with NamedMixinBase {
 
+    protected def oolagContextViaArgs: Option[OOLAGHost] = None
+    protected def nArgs: Args = OneArg
+
     private var oolagContextViaSet: Option[OOLAGHost] = None
 
     final def setOOLAGContext(oolagContextArg: OOLAGHost) {
@@ -142,7 +166,7 @@ object OOLAG extends Logging {
       if (oolagContextViaSet != None)
         Assert.usageError("Cannot set oolag context more than once.")
       oolagContextViaSet = Some(oolagContextArg)
-      if (oolagContextArg != OOLAGRoot) {
+      if (oolagContext != OOLAGRoot) {
         oolagRoot.requiredEvalFunctions ++= this.requiredEvalFunctions
         this.requiredEvalFunctions = Nil
       }
@@ -155,9 +179,6 @@ object OOLAG extends Logging {
         false
     }
 
-    def this(oolagContextArg: OOLAGHost) = this(oolagContextArg, OneArg)
-    def this() = this(null, ZeroArgs)
-
     /**
      * Used to check things that OOLAG doesn't protect against such as
      * index out of bounds.
@@ -193,7 +214,7 @@ object OOLAG extends Logging {
         Assert.usage(oolagContextViaSet != None, "Must call setOOLAGContext before accessing when OOLAGHost is constructed with no args.")
         oolagContextViaSet.get
       }
-      case OneArg => oolagContextArg
+      case OneArg => oolagContextViaArgs.get
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/PropertyScoping.scala
----------------------------------------------------------------------
diff --git a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/PropertyScoping.scala b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/PropertyScoping.scala
index 4a88770..61bdc41 100644
--- a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/PropertyScoping.scala
+++ b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/PropertyScoping.scala
@@ -206,11 +206,12 @@ trait FindPropertyMixin extends PropTypes {
   }
 
   /**
-   * For unit testing convenience
+   * For unit testing convenience, or for use when debugging.
    */
   final def verifyPropValue(key: String, value: String): Boolean = {
-    findPropertyOption(key) match {
-      case Found(`value`, _, _, _) => true
+    val prop = findPropertyOption(key)
+    prop match {
+      case Found(v, _, _, _) if (v == value) => true
       case _: Found => false
       case _: NotFound => false
     }

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/QNameBase.scala
----------------------------------------------------------------------
diff --git a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/QNameBase.scala b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/QNameBase.scala
index c661fbe..d60fc77 100644
--- a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/QNameBase.scala
+++ b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/QNameBase.scala
@@ -357,6 +357,8 @@ sealed trait NamedQName
     Assert.usage(!namespace.isNoNamespace)
     Assert.usage(!namespace.isUnspecified)
   }
+
+  def toRefQName = RefQName(prefix, local, namespace)
 }
 
 /**
@@ -516,7 +518,7 @@ object StepQNameFactory extends RefQNameFactoryBase[StepQName] {
   override def constructor(prefix: Option[String], local: String, namespace: NS) =
     StepQName(prefix, local, namespace)
 
-    /* This is what needs Tunables and propagates into Expression */
+  /* This is what needs Tunables and propagates into Expression */
   override def resolveDefaultNamespace(scope: scala.xml.NamespaceBinding, tunable: DaffodilTunables) = {
     tunable.unqualifiedPathStepPolicy match {
       case UnqualifiedPathStepPolicy.NoNamespace => None // don't consider default namespace

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/XMLUtils.scala
----------------------------------------------------------------------
diff --git a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/XMLUtils.scala b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/XMLUtils.scala
index d2738c4..c86f959 100644
--- a/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/XMLUtils.scala
+++ b/daffodil-lib/src/main/scala/edu/illinois/ncsa/daffodil/xml/XMLUtils.scala
@@ -330,6 +330,27 @@ object XMLUtils {
   val XHTML_NAMESPACE = NS("http://www.w3.org/1999/xhtml")
 
   /**
+   * Returns an Elem with local name "element", and the scope provided
+   * with the prefix of the Elem setup to match the scope's binding
+   * for the XSD_NAMESPACE.
+   *
+   * If the XSD_NAMESPACE is the default namespace, then the prefix will
+   * be null. If the XSD_NAMESPACE is bound to a prefix, the first such
+   * prefix will be used for the returned Elem.
+   */
+  def getXSDElement(scope: NamespaceBinding): Elem = {
+    val xsdPre = scope.getPrefix(XSD_NAMESPACE.toString)
+    val isXSDTheDefaultNS = XSD_NAMESPACE.toString() == scope.getURI(null)
+    val xsdPrefix =
+      if (xsdPre ne null) xsdPre
+      else if (isXSDTheDefaultNS) null
+      else Assert.usageError("Scope argument must have a binding for the XSD namespace.")
+    val res =
+      Elem(xsdPrefix, "element", Null, scope, true)
+    res
+  }
+
+  /**
    * Added to support extensions and proposed future features as part of daffodil.
    *
    * The DFDL standard requires us to keep these out of the primary DFDL namespace, and

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/oolag/TestOOLAG.scala
----------------------------------------------------------------------
diff --git a/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/oolag/TestOOLAG.scala b/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/oolag/TestOOLAG.scala
index a06bb8e..7332563 100644
--- a/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/oolag/TestOOLAG.scala
+++ b/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/oolag/TestOOLAG.scala
@@ -49,7 +49,7 @@ class MyException(msg: String)
 }
 
 abstract class MyBase(parentArg: MyBase)
-  extends OOLAGHost(parentArg) {
+  extends OOLAGHostImpl(parentArg) {
 
   def a1 = a1_.value
   def a1_ = LV('a1) {

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/TestGeneratedProperties.scala
----------------------------------------------------------------------
diff --git a/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/TestGeneratedProperties.scala b/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/TestGeneratedProperties.scala
index a4a63b8..5e281e8 100644
--- a/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/TestGeneratedProperties.scala
+++ b/daffodil-lib/src/test/scala/edu/illinois/ncsa/daffodil/schema/annotation/props/TestGeneratedProperties.scala
@@ -35,7 +35,7 @@ package edu.illinois.ncsa.daffodil.schema.annotation.props
 import edu.illinois.ncsa.daffodil.schema.annotation.props.gen._
 import junit.framework.Assert._
 import org.junit.Test
-import edu.illinois.ncsa.daffodil.oolag.OOLAG.OOLAGHost
+import edu.illinois.ncsa.daffodil.oolag.OOLAG.OOLAGHostImpl
 import edu.illinois.ncsa.daffodil.exceptions.SchemaFileLocation
 import edu.illinois.ncsa.daffodil.api.WarnID
 import edu.illinois.ncsa.daffodil.api.DaffodilTunables
@@ -54,7 +54,7 @@ class TestGeneratedProperties {
    * retrieves the property if it is present.
    */
   class HasLotsOfProperties
-    extends OOLAGHost(null)
+    extends OOLAGHostImpl(null)
     with LookupLocation
     with Format_AnnotationMixin
     with SeparatorSuppressionPolicyMixin {

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dsom/CompiledExpression1.scala
----------------------------------------------------------------------
diff --git a/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dsom/CompiledExpression1.scala b/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dsom/CompiledExpression1.scala
index 9b48188..cd24bcf 100644
--- a/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dsom/CompiledExpression1.scala
+++ b/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dsom/CompiledExpression1.scala
@@ -221,7 +221,7 @@ class DPathCompileInfo(
   lazy val variableMap =
     variableMapArg
 
-  override def preSerialization = {
+  override def preSerialization: Any = {
     parent
     variableMap
   }
@@ -314,6 +314,7 @@ class DPathCompileInfo(
 class DPathElementCompileInfo(
   @TransientParam parentArg: => Option[DPathCompileInfo],
   @TransientParam variableMap: => VariableMap,
+  @TransientParam elementChildrenCompileInfoArg: => Seq[DPathElementCompileInfo],
   namespaces: scala.xml.NamespaceBinding,
   path: String,
   val name: String,
@@ -321,11 +322,17 @@ class DPathElementCompileInfo(
   val namedQName: NamedQName,
   val optPrimType: Option[PrimType],
   sfl: SchemaFileLocation,
-  val elementChildrenCompileInfo: Seq[DPathElementCompileInfo],
   override val tunable: DaffodilTunables)
   extends DPathCompileInfo(parentArg, variableMap, namespaces, path, sfl, tunable)
   with HasSchemaFileLocation {
 
+  lazy val elementChildrenCompileInfo = elementChildrenCompileInfoArg
+
+  override def preSerialization: Any = {
+    super.preSerialization
+    elementChildrenCompileInfo
+  }
+
   override def toString = "DPathElementCompileInfo(%s)".format(name)
 
   @throws(classOf[java.io.IOException])

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-sapi/src/test/scala/edu/illinois/ncsa/daffodil/example/TestScalaAPI.scala
----------------------------------------------------------------------
diff --git a/daffodil-sapi/src/test/scala/edu/illinois/ncsa/daffodil/example/TestScalaAPI.scala b/daffodil-sapi/src/test/scala/edu/illinois/ncsa/daffodil/example/TestScalaAPI.scala
index 9a05ff9..a16e479 100644
--- a/daffodil-sapi/src/test/scala/edu/illinois/ncsa/daffodil/example/TestScalaAPI.scala
+++ b/daffodil-sapi/src/test/scala/edu/illinois/ncsa/daffodil/example/TestScalaAPI.scala
@@ -196,7 +196,7 @@ class TestScalaAPI {
     val locs = d.getLocationsInSchemaFiles
     assertEquals(1, locs.size)
     val loc = locs(0)
-    assertTrue(loc.toString().contains("mySchema2.dfdl.xsd"))
+    assertTrue(loc.toString().contains("mySchema1.dfdl.xsd")) // reports the element ref, not element decl.
 
     assertEquals(0, lw.errors.size)
     assertEquals(0, lw.warnings.size)
@@ -786,7 +786,7 @@ class TestScalaAPI {
     val res = dp.parse(rbc, outputter, 2 << 3)
     assertTrue(res.isError())
     assertFalse(res.isProcessingError())
-    assertTrue(res.isValidationError() )
+    assertTrue(res.isValidationError())
     assertTrue(res.location().isAtEnd())
 
     val diags = res.getDiagnostics
@@ -812,7 +812,7 @@ class TestScalaAPI {
     val res = dp.parse(rbc, outputter, 2 << 3)
     assertTrue(res.isError())
     assertFalse(res.isProcessingError())
-    assertTrue(res.isValidationError() )
+    assertTrue(res.isValidationError())
     assertTrue(res.location().isAtEnd())
 
     val diags = res.getDiagnostics
@@ -833,5 +833,4 @@ class TestScalaAPI {
     assertTrue(d2.getMessage().contains("20"))
   }
 
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-tdml/src/main/scala/edu/illinois/ncsa/daffodil/tdml/TDMLRunner.scala
----------------------------------------------------------------------
diff --git a/daffodil-tdml/src/main/scala/edu/illinois/ncsa/daffodil/tdml/TDMLRunner.scala b/daffodil-tdml/src/main/scala/edu/illinois/ncsa/daffodil/tdml/TDMLRunner.scala
index d8aec66..47e3c11 100644
--- a/daffodil-tdml/src/main/scala/edu/illinois/ncsa/daffodil/tdml/TDMLRunner.scala
+++ b/daffodil-tdml/src/main/scala/edu/illinois/ncsa/daffodil/tdml/TDMLRunner.scala
@@ -1108,7 +1108,12 @@ object VerifyTestCase {
 
     if (expectedDiags.isDefined && actualDiags.length == 0) {
       throw new TDMLException(""""Diagnostic message(s) were expected but not found."""" +
-        "\n" + """Expected: """ + expectedDiagMsgs.mkString("\n"))
+        "\n" + """Expected: """ + expectedDiagMsgs.mkString("\n") +
+        ( if (actualDiagMsgs.length == 0)
+          "\n No diagnostic messages were issued."
+        else
+          "\n The actual diagnostics messages were: " + actualDiagMsgs.mkString("\n")
+        ))
     }
 
     // must find each expected warning message within some actual warning message.

http://git-wip-us.apache.org/repos/asf/incubator-daffodil/blob/89517717/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section06/entities/Entities.tdml
----------------------------------------------------------------------
diff --git a/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section06/entities/Entities.tdml b/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section06/entities/Entities.tdml
index 4bff868..b8afcaf 100644
--- a/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section06/entities/Entities.tdml
+++ b/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section06/entities/Entities.tdml
@@ -1141,7 +1141,7 @@ is multiple bytes in UTF-8 encoding that is used"
           dfdl:lengthPattern="[^END]{0,49}(?=END)|.{50}" dfdl:representation="text" />
           <xs:sequence
           dfdl:terminator="{if (fn:string-length(./ex:value) eq 50) then '%ES; %DEL;' else 'END'}" />
-          <!-- can replace %ES with WSP* if ES doesn't work, %ES cannot be alone in list. -->
+          <!-- %DEL is there because %ES cannot be alone in list. -->
       </xs:sequence>
     </xs:group>