/**
   * Method engineResolvePublicKey
   *
   * @param element
   * @param BaseURI
   * @param storage
   * @return null if no {@link PublicKey} could be obtained
   * @throws KeyResolverException
   */
  public PublicKey engineResolvePublicKey(Element element, String BaseURI, StorageResolver storage)
      throws KeyResolverException {

    if (this._rsaKeyElement == null) {
      boolean weCanResolve = this.engineCanResolve(element, BaseURI, storage);

      if (!weCanResolve || (this._rsaKeyElement == null)) {
        return null;
      }
    }

    try {
      RSAKeyValue rsaKeyValue = new RSAKeyValue(this._rsaKeyElement, BaseURI);

      return rsaKeyValue.getPublicKey();
    } catch (XMLSecurityException ex) {
      cat.debug("XMLSecurityException", ex);
    }

    return null;
  }
  /**
   * Method engineCanResolve
   *
   * @param element
   * @param BaseURI
   * @param storage
   * @return
   */
  public boolean engineCanResolve(Element element, String BaseURI, StorageResolver storage) {

    cat.debug("Can I resolve " + element.getTagName());

    if (element == null) {
      return false;
    }

    boolean isKeyValue = XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYVALUE);
    boolean isRSAKeyValue = XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_RSAKEYVALUE);

    if (isKeyValue) {
      try {
        Element nscontext =
            XMLUtils.createDSctx(element.getOwnerDocument(), "ds", Constants.SignatureSpecNS);

        this._rsaKeyElement =
            (Element)
                XPathAPI.selectSingleNode(element, "./ds:" + Constants._TAG_RSAKEYVALUE, nscontext);

        if (this._rsaKeyElement != null) {
          return true;
        }
      } catch (TransformerException ex) {
      }
    } else if (isRSAKeyValue) {

      // this trick is needed to allow the RetrievalMethodResolver to eat a
      // ds:RSAKeyValue directly (without KeyValue)
      this._rsaKeyElement = element;

      return true;
    }

    return false;
  }