@Test
	public void testDisposeInAnotherThread() throws Exception {
		final ThreadedXmlPullParserImpl parser =
			new ThreadedXmlPullParserImpl(new ByteArrayInputStream(GOOD_XML.getBytes()),
				testName.getMethodName(), new TestErrorHandler(), false, 3);

		parser.start("doc");
		XmlElement projectXml = parser.start("project");
		assertNotNull(projectXml);
		assertEquals("foo", projectXml.getAttribute("name"));
		parser.end(projectXml);
		assertTrue("parser should be running", parser.isParsing());
		SwingUtilities.invokeAndWait(() -> parser.dispose());

		int count = 0;
		while (parser.isParsing()) {
			if (count++ > 10) {
				Assert.fail("parser should have shutdown");
			}
			Thread.sleep(1);
		}
		try {
			parser.hasNext();
			Assert.fail("Expected exception");
		}
		catch (Exception e) {
			// expected
		}

	}
<p>
XML External Entities attacks benefit from an XML feature to build documents dynamically at 
the time of processing.  An XML entity allows inclusion of data dynamically from a given 
resource.  External entities allow an XML document to include data from an external URI. 
Unless configured to do otherwise, external entities force the XML parser to access the 
resource specified by the URI, e.g., a file on the local machine or remote system. 
This behavior exposes the application to XML External Entity (XXE) attacks.
<p>
Normally, a custom Entity Resolver implementing org.xml.sax.EntityResolver should not return null 
as it will then default to the SAX Entity Resolver that allows and resolves external 
entities. 
<p>
This test ensures external entities are ignored whether or not a default SAX Entity Resolver 
is used. Using the ThreadedXmlPullParserImpl constructor which takes an InputStream (rather 
than ResourceFile) will use a default Entity Resolver. The XmlUtilities.createSecureSAXParserFactory 
factory configurations will disable external entities regardless of which Entity Resolver is used.

@throws Exception
Ghidra/Framework/Generic/src/test/java/ghidra/xml/ThreadedXmlParserTest.java