/**
   * Set the value of any property in a SAX2 parser. The parser might not recognize the property,
   * and if it does recognize it, it might not support the requested value.
   *
   * @param propertyId The unique identifier (URI) of the property being set.
   * @param value The value to which the property is being set.
   * @exception SAXNotRecognizedException If the requested property is not known.
   * @exception SAXNotSupportedException If the requested property is known, but the requested value
   *     is not supported.
   */
  public void setProperty(String propertyId, Object value)
      throws SAXNotRecognizedException, SAXNotSupportedException {
    /**
     * It's possible for users to set a security manager through the interface. If it's the old
     * SecurityManager, convert it to the new XMLSecurityManager
     */
    if (propertyId.equals(Constants.SECURITY_MANAGER)) {
      securityManager = XMLSecurityManager.convert(value, securityManager);
      setProperty0(Constants.SECURITY_MANAGER, securityManager);
      return;
    }
    if (propertyId.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) {
      if (value == null) {
        securityPropertyManager = new XMLSecurityPropertyManager();
      } else {
        securityPropertyManager = (XMLSecurityPropertyManager) value;
      }
      setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
      return;
    }

    if (securityManager == null) {
      securityManager = new XMLSecurityManager(true);
      setProperty0(Constants.SECURITY_MANAGER, securityManager);
    }

    if (securityPropertyManager == null) {
      securityPropertyManager = new XMLSecurityPropertyManager();
      setProperty0(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager);
    }
    int index = securityPropertyManager.getIndex(propertyId);

    if (index > -1) {
      /**
       * this is a direct call to this parser, not a subclass since internally the support of this
       * property is done through XMLSecurityPropertyManager
       */
      securityPropertyManager.setValue(
          index, XMLSecurityPropertyManager.State.APIPROPERTY, (String) value);
    } else {
      // check if the property is managed by security manager
      if (!securityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) {
        // fall back to the default configuration to handle the property
        setProperty0(propertyId, value);
      }
    }
  }