/**
  * Returns the state of a feature.
  *
  * @param featureId The feature identifier.
  * @return true if the feature is supported
  * @throws XMLConfigurationException Thrown for configuration error. In general, components should
  *     only throw this exception if it is <strong>really</strong> a critical error.
  */
 public FeatureState getFeatureState(String featureId) throws XMLConfigurationException {
   if (PARSER_SETTINGS.equals(featureId)) {
     return FeatureState.is(fConfigUpdated);
   } else if (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId)) {
     return FeatureState.is(true);
   } else if (USE_GRAMMAR_POOL_ONLY.equals(featureId)) {
     return FeatureState.is(fUseGrammarPoolOnly);
   } else if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) {
     return FeatureState.is(fInitSecurityManager.isSecureProcessing());
   } else if (SCHEMA_ELEMENT_DEFAULT.equals(featureId)) {
     return FeatureState.is(
         true); // pre-condition: VALIDATION and SCHEMA_VALIDATION are always true
   }
   return super.getFeatureState(featureId);
 }
  /**
   * Set the state of a feature.
   *
   * @param featureId The unique identifier (URI) of the feature.
   * @param state The requested state of the feature (true or false).
   * @exception XMLConfigurationException If the requested feature is not known.
   */
  public void setFeature(String featureId, boolean value) throws XMLConfigurationException {
    if (PARSER_SETTINGS.equals(featureId)) {
      throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId);
    } else if (value == false
        && (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId))) {
      throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId);
    } else if (USE_GRAMMAR_POOL_ONLY.equals(featureId) && value != fUseGrammarPoolOnly) {
      throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId);
    }
    if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) {
      if (_isSecureMode && !value) {
        throw new XMLConfigurationException(
            Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING);
      }
      fInitSecurityManager.setSecureProcessing(value);
      setProperty(SECURITY_MANAGER, fInitSecurityManager);

      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);
        setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
      }

      return;
    }
    fConfigUpdated = true;
    fEntityManager.setFeature(featureId, value);
    fErrorReporter.setFeature(featureId, value);
    fSchemaValidator.setFeature(featureId, value);
    if (!fInitFeatures.containsKey(featureId)) {
      boolean current = super.getFeature(featureId);
      fInitFeatures.put(featureId, current ? Boolean.TRUE : Boolean.FALSE);
    }
    super.setFeature(featureId, value);
  }