// find eligible local IDPs for the tenant
  private List<String> getEligibleLocalIdpList(AuthnRequestState t) {
    Validate.notNull(t);
    IdmAccessor accessor = t.getIdmAccessor();

    List<String> localIDPs =
        new ArrayList<String>(
            Arrays.asList(accessor.getIdpEntityId(), accessor.getDefaultIdpEntityId()));
    List<String> eligibleLocalIDPs = new ArrayList<>();

    IDPList idpList =
        t.getAuthnRequest().getScoping() == null
            ? null
            : t.getAuthnRequest().getScoping().getIDPList();

    if (idpList != null && idpList.getIDPEntrys() != null) {
      for (IDPEntry entry : idpList.getIDPEntrys()) {
        if (entry != null && localIDPs.contains(entry.getProviderID())) {
          eligibleLocalIDPs.add(entry.getProviderID());
        }
      }
      if (eligibleLocalIDPs.isEmpty()) {
        log.debug("samlp:Scoping:IDPList does not contain VMWare local Identity Store.");
      }
    } else {
      eligibleLocalIDPs = localIDPs;
    }

    return eligibleLocalIDPs;
  }
  /**
   * Read the list of supported IDPs that the SP sent and determine if the chosen IdP is supported.
   * Request = opensaml ECP request header.
   *
   * @param header
   * @return
   */
  public URL determineIdP(Header header, IDPEntry idpEntry) {

    IDPList idpList = null;
    List<XMLObject> list = header.getUnknownXMLObjects();

    for (XMLObject xmlObject : list) {
      if (xmlObject.getElementQName().equals(Request.DEFAULT_ELEMENT_NAME)) {
        idpList = ((Request) xmlObject).getIDPList();
      }
    }

    // If the list from the SP contains the same entry that
    // was chosen by the client...
    if (idpList != null) {
      for (IDPEntry spIdpEntry : idpList.getIDPEntrys()) {
        if (spIdpEntry.getName() != null
            && spIdpEntry.getLoc() != null
            && idpEntry.getProviderID() != null)
          if (spIdpEntry.getName().equals(idpEntry.getName()))
            if (spIdpEntry.getLoc().equals(idpEntry.getLoc()))
              if (spIdpEntry.getProviderID().equals(idpEntry.getProviderID()))
                return getURL(spIdpEntry.getLoc());
      }
    }
    return null;
  }
  // check if the provided IDPList contains a trusted external IDP
  // return the list of valid ones
  private List<String> findValidExternalIdpListWithinScoping(
      List<IDPEntry> requestIdpList, IdmAccessor accessor) {
    Validate.notNull(requestIdpList);
    Validate.notNull(accessor);
    List<String> retVal = new ArrayList<>();
    Collection<IDPConfig> extIdps = accessor.getExternalIdps();

    if (extIdps == null || extIdps.isEmpty()) {
      log.debug("No external IDP registered! ");
    } else {
      for (IDPEntry entry : requestIdpList) {
        if (entry != null) {
          IDPConfig foundConfig =
              accessor.getExternalIdpConfigForTenant(accessor.getTenant(), entry.getProviderID());
          if (foundConfig != null) {
            retVal.add(entry.getProviderID());
          }
        }
      }
    }
    log.debug("check if IDPList contain a trusted external IDP, result: {}", !retVal.isEmpty());

    return retVal;
  }
  /**
   * Extracts the forced IDP list from the session.
   *
   * @param session The authentication session.
   * @return The forced IDPs.
   * @throws OAException If organization storage exist check can't be performed.
   */
  @SuppressWarnings("unchecked")
  private List<String> getForcedIDPs(ISession session) throws OAException {
    List<String> retval = new Vector<String>();

    IUser oUser = session.getUser();
    if (oUser instanceof SAMLRemoteUser) {
      SAMLRemoteUser remoteUser = (SAMLRemoteUser) oUser;
      String sRemoteIdP = remoteUser.getOrganization();
      if (sRemoteIdP != null && _organizationStorage.exists(sRemoteIdP)) {
        StringBuffer sbDebug = new StringBuffer();
        sbDebug.append("There is a Remote SAML User available in session with ID '");
        sbDebug.append(session.getId());
        sbDebug.append("' that is known at remote IdP '");
        sbDebug.append(sRemoteIdP);
        sbDebug.append("' so this IdP will be forced");
        _logger.debug(sbDebug.toString());
        retval.add(sRemoteIdP);
        return retval;
      }
    }

    ISessionAttributes atts = session.getAttributes();
    String sGetComplete =
        (String) atts.get(ProxyAttributes.class, ProxyAttributes.IDPLIST_GETCOMPLETE);

    if (sGetComplete != null) {
      _logger.debug(
          "Using proxy attribute: " + ProxyAttributes.IDPLIST_GETCOMPLETE + ": " + sGetComplete);
      // getcomplete
      IDPList idpList = null;
      try {
        if (_mRemoteIDPLists.containsKey(sGetComplete)) {
          idpList = _mRemoteIDPLists.get(sGetComplete).getList();
        } else {
          RemoteIDPListEntry entry = new RemoteIDPListEntry(sGetComplete, 1000);
          idpList = entry.getList();

          // DD Add the RemoteIDPListEntry to a map for caching purposes; The getEntry() retrieves
          // the list from the url.
          _mRemoteIDPLists.put(sGetComplete, entry);
        }

        if (idpList != null) {
          for (IDPEntry entry : idpList.getIDPEntrys()) {
            retval.add(entry.getProviderID());
          }
        }
      } catch (ResourceException e) {
        _logger.warn("Failed retrieval of IDPList from GetComplete URL: " + sGetComplete, e);
      }
    }

    List<SAML2IDPEntry> idpList =
        (List<SAML2IDPEntry>) atts.get(ProxyAttributes.class, ProxyAttributes.IDPLIST);
    if (idpList != null) {
      if (_logger.isDebugEnabled()) {
        StringBuffer sbMessage = new StringBuffer("Using proxy attribute ");
        sbMessage.append(ProxyAttributes.IDPLIST);
        sbMessage.append(": ").append(idpList);
        _logger.debug(sbMessage);
      }

      for (SAML2IDPEntry entry : idpList) {
        // DD We currently ignore the proxied SAML2IDPEntry.getName() (friendlyname) and
        // SAML2IDPEntry.getLoc()
        String sID = entry.getProviderID();
        if (sID != null) {
          if (!retval.contains(sID)) retval.add(sID);
        }
      }
    }

    Collection cForcedOrganizations =
        (Collection)
            atts.get(
                com.alfaariss.oa.util.session.ProxyAttributes.class,
                com.alfaariss.oa.util.session.ProxyAttributes.FORCED_ORGANIZATIONS);
    if (cForcedOrganizations != null) {
      if (_logger.isDebugEnabled()) {
        StringBuffer sbMessage = new StringBuffer("Using proxy attribute ");
        sbMessage.append(com.alfaariss.oa.util.session.ProxyAttributes.FORCED_ORGANIZATIONS);
        sbMessage.append(": ").append(cForcedOrganizations);
        _logger.debug(sbMessage);
      }
      for (Object oForceOrganization : cForcedOrganizations) {
        String sForceOrganization = (String) oForceOrganization;
        if (!retval.contains(sForceOrganization)) retval.add(sForceOrganization);
      }
    }

    return retval;
  }