/**
   * Fill in the filter context data.
   *
   * @param profileRequestContext current profile request context
   * @param filterContext context to populate
   */
  private void populateFilterContext(
      @Nonnull final ProfileRequestContext profileRequestContext,
      @Nonnull final AttributeFilterContext filterContext) {

    filterContext.setPrincipal(principalNameLookupStrategy.apply(profileRequestContext));

    filterContext.setPrincipalAuthenticationMethod(null);
    if (null != authenticationContext) {
      final AuthenticationResult result = authenticationContext.getAuthenticationResult();
      if (null != result) {
        filterContext.setPrincipalAuthenticationMethod(result.getAuthenticationFlowId());
      }
    }

    if (recipientLookupStrategy != null) {
      filterContext.setAttributeRecipientID(recipientLookupStrategy.apply(profileRequestContext));
    } else {
      filterContext.setAttributeRecipientID(null);
    }

    if (issuerLookupStrategy != null) {
      filterContext.setAttributeIssuerID(issuerLookupStrategy.apply(profileRequestContext));
    } else {
      filterContext.setAttributeIssuerID(null);
    }

    filterContext.setRequesterMetadataContextLookupStrategy(metadataFromFilterLookupStrategy);

    // If the filter context doesn't have a set of attributes to filter already
    // then look for them in the AttributeContext.
    if (filterContext.getPrefilteredIdPAttributes().isEmpty()) {
      filterContext.setPrefilteredIdPAttributes(attributeContext.getIdPAttributes().values());
    }
  }
  /** {@inheritDoc} */
  @Override
  protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {

    // Get the filter context from the profile request
    // this may already exist but if not, auto-create it.
    final AttributeFilterContext filterContext =
        filterContextCreationStrategy.apply(profileRequestContext);
    if (filterContext == null) {
      log.error("{} Unable to locate or create AttributeFilterContext", getLogPrefix());
      if (maskFailures) {
        log.warn("Filter error masked, clearing resolved attributes");
        attributeContext.setIdPAttributes(null);
      } else {
        ActionSupport.buildEvent(profileRequestContext, IdPEventIds.UNABLE_FILTER_ATTRIBS);
      }
      return;
    }

    populateFilterContext(profileRequestContext, filterContext);

    ServiceableComponent<AttributeFilter> component = null;

    try {
      component = attributeFilterService.getServiceableComponent();
      if (null == component) {
        log.error(
            "{} Error encountered while filtering attributes : Invalid Attribute Filter configuration",
            getLogPrefix());
        if (maskFailures) {
          log.warn("Filter error masked, clearing resolved attributes");
          attributeContext.setIdPAttributes(null);
        } else {
          ActionSupport.buildEvent(profileRequestContext, IdPEventIds.UNABLE_FILTER_ATTRIBS);
        }
      } else {
        final AttributeFilter filter = component.getComponent();
        filter.filterAttributes(filterContext);
        filterContext.getParent().removeSubcontext(filterContext);
        attributeContext.setIdPAttributes(filterContext.getFilteredIdPAttributes().values());
      }
    } catch (final AttributeFilterException e) {
      log.error("{} Error encountered while filtering attributes", getLogPrefix(), e);
      if (maskFailures) {
        log.warn("Filter error masked, clearing resolved attributes");
        attributeContext.setIdPAttributes(null);
      } else {
        ActionSupport.buildEvent(profileRequestContext, IdPEventIds.UNABLE_FILTER_ATTRIBS);
      }
    } finally {
      if (null != component) {
        component.unpinComponent();
      }
    }
  }
  /**
   * Compare the issuer from the context with the provided regexp.
   *
   * @param filterContext the context
   * @return whether it matches
   *     <p>{@inheritDoc}
   */
  @Override
  public Tristate matches(@Nonnull AttributeFilterContext filterContext) {

    ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);

    final String issuer = filterContext.getAttributeIssuerID();
    if (null == issuer) {
      log.warn("{} No attribute issuer found for comparison", getLogPrefix());
      return Tristate.FAIL;
    }
    log.debug("{} Found attribute issuer: {}", getLogPrefix(), issuer);

    return regexpCompare(issuer);
  }