protected EndpointDescriptor resolveClaimsEndpoint(CredentialClaimsRequest requestCredential)
      throws IdentityMediationException {

    for (IdentityMediationEndpoint endpoint : requestCredential.getClaimsChannel().getEndpoints()) {
      // Look for PWD endpoint using Artifacct binding
      if (AuthnCtxClass.PASSWORD_AUTHN_CTX.getValue().equals(endpoint.getType())
          && SSOBinding.SSO_ARTIFACT.getValue().equals(endpoint.getBinding())) {

        if (logger.isDebugEnabled()) logger.debug("Resolved claims endpoint " + endpoint);

        return new EndpointDescriptorImpl(
            endpoint.getName(),
            endpoint.getType(),
            endpoint.getBinding(),
            requestCredential.getClaimsChannel().getLocation() + endpoint.getLocation(),
            endpoint.getResponseLocation() != null
                ? requestCredential.getClaimsChannel().getLocation()
                    + endpoint.getResponseLocation()
                : null);
      }
    }

    return null;
  }
  @Override
  protected ModelAndView onSubmit(
      HttpServletRequest hreq, HttpServletResponse hres, Object o, BindException error)
      throws Exception {

    CollectUsernamePasswordClaims cmd = (CollectUsernamePasswordClaims) o;

    if (logger.isDebugEnabled()) logger.debug("Received CMD" + cmd);

    CredentialClaimsRequest cRequestCredential = cmd.getCredentialClaimsRequest();
    if (logger.isDebugEnabled())
      logger.debug(
          "Collecting usenrame/password claims for request "
              + (cRequestCredential != null ? cRequestCredential.getId() : "NULL"));

    ClaimSet claims = new ClaimSetImpl();
    claims.addClaim(new CredentialClaimImpl("username", cmd.getUsername()));
    claims.addClaim(new CredentialClaimImpl("password", cmd.getPassword()));
    claims.addClaim(new CredentialClaimImpl("rememberMe", cmd.isRememberMe()));

    CredentialClaimsResponse responseCredential =
        new CredentialClaimsResponseImpl(
            idGenerator.generateId(),
            null,
            cRequestCredential.getId(),
            claims,
            cRequestCredential.getRelayState());

    EndpointDescriptor claimsEndpoint = resolveClaimsEndpoint(cRequestCredential);
    if (claimsEndpoint == null) {
      logger.error("No claims endpoint found!");
      // TODO : Create error and redirect to error view using 'IDBusErrArt'
    }

    // We want the binding factory to use a binding component to build this URL, if possible
    Channel claimsChannel = cRequestCredential.getClaimsChannel();
    claimsChannel = getNonSerializedChannel(claimsChannel);

    String claimsEndpointUrl = null;
    if (claimsChannel != null) {

      MediationBindingFactory f = claimsChannel.getIdentityMediator().getBindingFactory();
      MediationBinding b =
          f.createBinding(
              SSOBinding.SSO_ARTIFACT.getValue(), cRequestCredential.getClaimsChannel());

      claimsEndpointUrl = claimsEndpoint.getResponseLocation();
      if (claimsEndpointUrl == null) claimsEndpointUrl = claimsEndpoint.getLocation();

      if (b instanceof AbstractMediationHttpBinding) {
        AbstractMediationHttpBinding httpBinding = (AbstractMediationHttpBinding) b;
        claimsEndpointUrl =
            ((AbstractMediationHttpBinding) b).buildHttpTargetLocation(hreq, claimsEndpoint, true);

      } else {
        logger.warn("Cannot delegate URL construction to binding, non-http binding found " + b);
        claimsEndpointUrl =
            claimsEndpoint.getResponseLocation() != null
                ? claimsEndpoint.getResponseLocation()
                : claimsEndpoint.getLocation();
      }
    } else {

      logger.warn(
          "Cannot delegate URL construction to binding, valid definition of channel "
              + cRequestCredential.getClaimsChannel().getName()
              + " not foud ...");
      claimsEndpointUrl =
          claimsEndpoint.getResponseLocation() != null
              ? claimsEndpoint.getResponseLocation()
              : claimsEndpoint.getLocation();
    }

    if (logger.isDebugEnabled())
      logger.debug("Using claims endpoint URL [" + claimsEndpointUrl + "]");

    Artifact a = getArtifactQueueManager().pushMessage(responseCredential);
    claimsEndpointUrl += "?SSOArt=" + a.getContent();

    if (logger.isDebugEnabled()) logger.debug("Returing claims to " + claimsEndpointUrl);

    hreq.getSession().removeAttribute("CollectUsernamePasswordClaims");

    return new ModelAndView(new RedirectView(claimsEndpointUrl));
  }
  @Override
  protected Object formBackingObject(HttpServletRequest hreq) throws Exception {

    String artifactId = hreq.getParameter(SsoHttpArtifactBinding.SSO_ARTIFACT_ID);
    CollectUsernamePasswordClaims collectClaims;

    // No request parameter , try to get the form from the session
    if (artifactId == null) {

      collectClaims =
          (CollectUsernamePasswordClaims)
              hreq.getSession().getAttribute("CollectUsernamePasswordClaims");
      // No collect claims in session, build an empty value and return.
      if (collectClaims == null) collectClaims = new CollectUsernamePasswordClaims();

      return collectClaims;
    }

    collectClaims = new CollectUsernamePasswordClaims();

    if (logger.isDebugEnabled())
      logger.debug("Creating form backing object for artifact " + artifactId);

    // Lookup for ClaimsRequest!
    CredentialClaimsRequest credentialClaimsRequest =
        (CredentialClaimsRequest) artifactQueueManager.pullMessage(new ArtifactImpl(artifactId));

    if (credentialClaimsRequest != null) {

      if (logger.isDebugEnabled())
        logger.debug(
            "Received claims request "
                + credentialClaimsRequest.getId()
                + " from "
                + credentialClaimsRequest.getIssuerChannel()
                + " at "
                + credentialClaimsRequest.getIssuerEndpoint());

      if (credentialClaimsRequest.getLastErrorId() != null) {
        if (logger.isDebugEnabled())
          logger.debug(
              "Received last error ID : "
                  + credentialClaimsRequest.getLastErrorId()
                  + " ("
                  + credentialClaimsRequest.getLastErrorMsg()
                  + ")");

        hreq.setAttribute("statusMessageKey", "claims.text.invalidCredentials");
      }

      List<DashboardMessage> ssoPolicyMsgs = new ArrayList<DashboardMessage>();

      // Publish SSO Policies information to be displayed ...
      for (SSOPolicyEnforcementStatement ssoPolicyEnforcement :
          credentialClaimsRequest.getSsoPolicyEnforcements()) {
        List<Object> values = null;
        if (ssoPolicyEnforcement.getValues().size() > 0) {
          values = new ArrayList<Object>();
          values.addAll(ssoPolicyEnforcement.getValues());
        }
        ssoPolicyMsgs.add(
            new DashboardMessage("claims.text." + ssoPolicyEnforcement.getName(), values));
      }

      if (ssoPolicyMsgs.size() > 0) hreq.setAttribute("ssoPolicyMessages", ssoPolicyMsgs);

      collectClaims.setCredentialClaimsRequest(credentialClaimsRequest);

    } else {
      // TODO : redirect User to configured fallback URL
      if (logger.isDebugEnabled())
        logger.debug("No claims request received, use the one stored in session, if any!");
      CollectUsernamePasswordClaims oldClaims =
          (CollectUsernamePasswordClaims)
              hreq.getSession().getAttribute("CollectUsernamePasswordClaims");
      if (oldClaims != null) {
        if (logger.isDebugEnabled())
          logger.debug(
              "No claims request received, using old claims request : "
                  + oldClaims.getCredentialClaimsRequest());

        collectClaims.setCredentialClaimsRequest(oldClaims.getCredentialClaimsRequest());
      }
    }

    hreq.getSession().setAttribute("CollectUsernamePasswordClaims", collectClaims);

    return collectClaims;
  }