public void testWithDummyExtSubset() throws Exception {
    final String XML =
        "<!DOCTYPE root PUBLIC '//some//public//id' 'no-such-thing.dtd'>\n" + "<root />";

    SAXParserFactoryImpl spf = new SAXParserFactoryImpl();
    spf.setNamespaceAware(true);
    SAXParser sp = spf.newSAXParser();
    DefaultHandler h = new DefaultHandler();

    /* First: let's verify that we get an exception for
     * unresolved reference...
     */
    try {
      sp.parse(new InputSource(new StringReader(XML)), h);
    } catch (SAXException e) {
      verifyException(e, "No such file or directory");
    }

    // And then with dummy resolver; should work ok now
    sp = spf.newSAXParser();
    sp.getXMLReader().setEntityResolver(new MyResolver("   "));
    h = new DefaultHandler();
    try {
      sp.parse(new InputSource(new StringReader(XML)), h);
    } catch (SAXException e) {
      fail(
          "Should not have failed with entity resolver, got ("
              + e.getClass()
              + "): "
              + e.getMessage());
    }
  }
  /**
   * Create a SAX parser with the associated features
   *
   * @param features Hashtable of SAX features, may be null
   */
  SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing)
      throws SAXException {
    fSecurityManager = new XMLSecurityManager(secureProcessing);
    fSecurityPropertyMgr = new XMLSecurityPropertyManager();
    // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader
    xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr, fSecurityManager);

    // JAXP "namespaceAware" == SAX Namespaces feature
    // Note: there is a compatibility problem here with default values:
    // JAXP default is false while SAX 2 default is true!
    xmlReader.setFeature0(NAMESPACES_FEATURE, spf.isNamespaceAware());

    // SAX "namespaces" and "namespace-prefixes" features should not
    // both be false.  We make them opposite for backward compatibility
    // since JAXP 1.0 apps may want to receive xmlns* attributes.
    xmlReader.setFeature0(NAMESPACE_PREFIXES_FEATURE, !spf.isNamespaceAware());

    // Avoid setting the XInclude processing feature if the value is false.
    // This will keep the configuration from throwing an exception if it
    // does not support XInclude.
    if (spf.isXIncludeAware()) {
      xmlReader.setFeature0(XINCLUDE_FEATURE, true);
    }

    xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);

    xmlReader.setProperty0(SECURITY_MANAGER, fSecurityManager);

    if (secureProcessing) {
      /**
       * By default, secure processing is set, no external access is allowed. However, we need to
       * check if it is actively set on the factory since we allow the use of the System Property or
       * jaxp.properties to override the default value
       */
      if (features != null) {

        Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
        if (temp != null) {
          boolean value = ((Boolean) temp).booleanValue();
          if (value && Constants.IS_JDK8_OR_ABOVE) {
            fSecurityPropertyMgr.setValue(
                XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
                XMLSecurityPropertyManager.State.FSP,
                Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
            fSecurityPropertyMgr.setValue(
                XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
                XMLSecurityPropertyManager.State.FSP,
                Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
          }
        }
      }
    }

    // Set application's features, followed by validation features.
    setFeatures(features);

    // If validating, provide a default ErrorHandler that prints
    // validation errors with a warning telling the user to set an
    // ErrorHandler.
    if (spf.isValidating()) {
      fInitErrorHandler = new DefaultValidationErrorHandler(xmlReader.getLocale());
      xmlReader.setErrorHandler(fInitErrorHandler);
    } else {
      fInitErrorHandler = xmlReader.getErrorHandler();
    }
    xmlReader.setFeature0(VALIDATION_FEATURE, spf.isValidating());

    // Get the Schema object from the factory
    this.grammar = spf.getSchema();
    if (grammar != null) {
      XMLParserConfiguration config = xmlReader.getXMLParserConfiguration();
      XMLComponent validatorComponent = null;
      /** For Xerces grammars, use built-in schema validator. * */
      if (grammar instanceof XSGrammarPoolContainer) {
        validatorComponent = new XMLSchemaValidator();
        fSchemaValidationManager = new ValidationManager();
        fUnparsedEntityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
        config.setDTDHandler(fUnparsedEntityHandler);
        fUnparsedEntityHandler.setDTDHandler(xmlReader);
        xmlReader.setDTDSource(fUnparsedEntityHandler);
        fSchemaValidatorComponentManager =
            new SchemaValidatorConfiguration(
                config, (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
      }
      /** For third party grammars, use the JAXP validator component. * */
      else {
        validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
        fSchemaValidationManager = null;
        fUnparsedEntityHandler = null;
        fSchemaValidatorComponentManager = config;
      }
      config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
      config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
      config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
      ((XMLDocumentSource) validatorComponent).setDocumentHandler(xmlReader);
      xmlReader.setDocumentSource((XMLDocumentSource) validatorComponent);
      fSchemaValidator = validatorComponent;
    } else {
      fSchemaValidationManager = null;
      fUnparsedEntityHandler = null;
      fSchemaValidatorComponentManager = null;
      fSchemaValidator = null;
    }

    // Initial EntityResolver
    fInitEntityResolver = xmlReader.getEntityResolver();
  }