/** Sets a property. */
  public void setProperty(String propertyId, Object value) throws XMLConfigurationException {
    super.setProperty(propertyId, value);

    if (propertyId.equals(FILTERS)) {
      XMLDocumentFilter[] filters = (XMLDocumentFilter[]) getProperty(FILTERS);
      if (filters != null) {
        for (int i = 0; i < filters.length; i++) {
          XMLDocumentFilter filter = filters[i];
          if (filter instanceof HTMLComponent) {
            addComponent((HTMLComponent) filter);
          }
        }
      }
    }

    int size = fHTMLComponents.size();
    for (int i = 0; i < size; i++) {
      HTMLComponent component = (HTMLComponent) fHTMLComponents.elementAt(i);
      component.setProperty(propertyId, value);
    }
  } // setProperty(String,Object)
  /** Default constructor. */
  public HTMLConfiguration() {

    // add components
    addComponent(fDocumentScanner);
    addComponent(fTagBalancer);
    addComponent(fNamespaceBinder);

    //
    // features
    //

    // recognized features
    String VALIDATION = "http://xml.org/sax/features/validation";
    String[] recognizedFeatures = {
      AUGMENTATIONS, NAMESPACES, VALIDATION, REPORT_ERRORS, SIMPLE_ERROR_FORMAT, BALANCE_TAGS,
    };
    addRecognizedFeatures(recognizedFeatures);
    setFeature(AUGMENTATIONS, false);
    setFeature(NAMESPACES, true);
    setFeature(VALIDATION, false);
    setFeature(REPORT_ERRORS, false);
    setFeature(SIMPLE_ERROR_FORMAT, false);
    setFeature(BALANCE_TAGS, true);

    // HACK: Xerces 2.0.0
    if (XERCES_2_0_0) {
      // NOTE: These features should not be required but it causes a
      //       problem if they're not there. This will be fixed in
      //       subsequent releases of Xerces.
      recognizedFeatures =
          new String[] {
            "http://apache.org/xml/features/scanner/notify-builtin-refs",
          };
      addRecognizedFeatures(recognizedFeatures);
    }

    // HACK: Xerces 2.0.1
    if (XERCES_2_0_0 || XERCES_2_0_1 || XML4J_4_0_x) {
      // NOTE: These features should not be required but it causes a
      //       problem if they're not there. This should be fixed in
      //       subsequent releases of Xerces.
      recognizedFeatures =
          new String[] {
            "http://apache.org/xml/features/validation/schema/normalized-value",
            "http://apache.org/xml/features/scanner/notify-char-refs",
          };
      addRecognizedFeatures(recognizedFeatures);
    }

    //
    // properties
    //

    // recognized properties
    String[] recognizedProperties = {
      NAMES_ELEMS, NAMES_ATTRS, FILTERS, ERROR_REPORTER,
    };
    addRecognizedProperties(recognizedProperties);
    setProperty(NAMES_ELEMS, "upper");
    setProperty(NAMES_ATTRS, "lower");
    setProperty(ERROR_REPORTER, fErrorReporter);

    // HACK: Xerces 2.0.0
    if (XERCES_2_0_0) {
      // NOTE: This is a hack to get around a problem in the Xerces 2.0.0
      //       AbstractSAXParser. If it uses a parser configuration that
      //       does not have a SymbolTable, then it will remove *all*
      //       attributes. This will be fixed in subsequent releases of
      //       Xerces.
      String SYMBOL_TABLE = "http://apache.org/xml/properties/internal/symbol-table";
      recognizedProperties =
          new String[] {
            SYMBOL_TABLE,
          };
      addRecognizedProperties(recognizedProperties);
      Object symbolTable =
          ObjectFactory.createObject(
              "org.apache.xerces.util.SymbolTable", "org.apache.xerces.util.SymbolTable");
      setProperty(SYMBOL_TABLE, symbolTable);
    }
  } // <init>()