@Override
  public void formatRequest(
      ChallengeWriter cw, ChallengeRequest challenge, Response response, Series<Header> httpHeaders)
      throws IOException {
    // Format the parameters WWW-Authenticate: OAuth realm='Example
    // Service', error='expired-token'
    cw.append("realm='");
    cw.append(challenge.getRealm());
    cw.append("'");

    for (Parameter p : challenge.getParameters()) {
      cw.append(", ");
      cw.append(p.getName());
      cw.append("='");
      cw.append(p.getValue());
      cw.append("'");
    }
  }
 @Override
 public void formatResponse(
     ChallengeWriter cw,
     ChallengeResponse challenge,
     Request request,
     Series<Header> httpHeaders) {
   try {
     final CharArrayWriter credentials = new CharArrayWriter();
     credentials.write("^@");
     credentials.write(challenge.getIdentifier());
     credentials.write("^@");
     credentials.write(challenge.getSecret());
     cw.append(Base64.encode(credentials.toCharArray(), "US-ASCII", false));
   } catch (UnsupportedEncodingException e) {
     throw new RuntimeException("Unsupported encoding, unable to encode credentials");
   } catch (IOException e) {
     throw new RuntimeException("Unexpected exception, unable to encode credentials", e);
   }
 }
  @Override
  public void formatResponse(
      ChallengeWriter cw,
      ChallengeResponse challenge,
      Request request,
      Series<Header> httpHeaders) {

    // Setup the Date header
    String date = "";

    if (httpHeaders.getFirstValue("x-ms-date", true) == null) {
      // X-ms-Date header didn't override the standard Date header
      date = httpHeaders.getFirstValue(HeaderConstants.HEADER_DATE, true);

      if (date == null) {
        // Add a fresh Date header
        date = DateUtils.format(new Date(), DateUtils.FORMAT_RFC_1123.get(0));
        httpHeaders.add(HeaderConstants.HEADER_DATE, date);
      }
    } else {
      date = httpHeaders.getFirstValue("x-ms-date", true);
    }

    // Setup the canonicalized path
    String canonicalizedResource = getCanonicalizedResourceName(request.getResourceRef());

    // Setup the message part
    StringBuilder rest = new StringBuilder();
    rest.append(date)
        .append('\n')
        .append('/')
        .append(challenge.getIdentifier())
        .append(canonicalizedResource);

    // Append the SharedKey credentials
    cw.append(challenge.getIdentifier())
        .append(':')
        .append(
            Base64.encode(
                DigestUtils.toHMacSha256(rest.toString(), Base64.decode(challenge.getSecret())),
                true));
  }
  @Override
  public void formatRequest(
      ChallengeWriter cw, ChallengeRequest challenge, Response response, Series<Header> httpHeaders)
      throws IOException {

    if (challenge.getRealm() != null) {
      cw.appendQuotedChallengeParameter("realm", challenge.getRealm());
    }

    if (!challenge.getDomainRefs().isEmpty()) {
      cw.append(", domain=\"");

      for (int i = 0; i < challenge.getDomainRefs().size(); i++) {
        if (i > 0) {
          cw.append(' ');
        }

        cw.append(challenge.getDomainRefs().get(i).toString());
      }

      cw.append('"');
    }

    if (challenge.getServerNonce() != null) {
      cw.appendQuotedChallengeParameter("nonce", challenge.getServerNonce());
    }

    if (challenge.getOpaque() != null) {
      cw.appendQuotedChallengeParameter("opaque", challenge.getOpaque());
    }

    if (challenge.isStale()) {
      cw.appendChallengeParameter("stale", "true");
    }

    if (challenge.getDigestAlgorithm() != null) {
      cw.appendChallengeParameter("algorithm", challenge.getDigestAlgorithm());
    }

    if (!challenge.getQualityOptions().isEmpty()) {
      cw.append(", qop=\"");

      for (int i = 0; i < challenge.getQualityOptions().size(); i++) {
        if (i > 0) {
          cw.append(',');
        }

        cw.appendToken(challenge.getQualityOptions().get(i).toString());
      }

      cw.append('"');
    }

    for (Parameter param : challenge.getParameters()) {
      if (HeaderUtils.isToken(param.getValue())) {
        cw.appendChallengeParameter(param);
      } else {
        cw.appendQuotedChallengeParameter(param);
      }
    }
  }
  @Override
  public void formatResponse(
      ChallengeWriter cw,
      ChallengeResponse challenge,
      Request request,
      Series<Header> httpHeaders) {

    if (challenge.getIdentifier() != null) {
      cw.appendQuotedChallengeParameter("username", challenge.getIdentifier());
    }

    if (challenge.getRealm() != null) {
      cw.appendQuotedChallengeParameter("realm", challenge.getRealm());
    }

    if (challenge.getServerNonce() != null) {
      cw.appendQuotedChallengeParameter("nonce", challenge.getServerNonce());
    }

    if (challenge.getDigestRef() != null) {
      challenge.setDigestRef(new Reference(request.getResourceRef().getPath()));
      cw.appendQuotedChallengeParameter("uri", challenge.getDigestRef().toString());
    }

    char[] responseDigest = formatResponseDigest(challenge, request);

    if (responseDigest != null) {
      cw.appendQuotedChallengeParameter("response", new String(responseDigest));
    }

    if ((challenge.getDigestAlgorithm() != null)
        && !Digest.ALGORITHM_MD5.equals(challenge.getDigestAlgorithm())) {
      cw.appendChallengeParameter("algorithm", challenge.getDigestAlgorithm());
    }

    if (challenge.getClientNonce() != null) {
      cw.appendQuotedChallengeParameter("cnonce", challenge.getClientNonce());
    }

    if (challenge.getOpaque() != null) {
      cw.appendQuotedChallengeParameter("opaque", challenge.getOpaque());
    }

    if (challenge.getQuality() != null) {
      cw.appendChallengeParameter("qop", challenge.getQuality());
    }

    if ((challenge.getQuality() != null) && (challenge.getServerNounceCount() > 0)) {
      cw.appendChallengeParameter("nc", challenge.getServerNounceCountAsHex());
    }

    for (Parameter param : challenge.getParameters()) {
      if (HeaderUtils.isToken(param.getValue())) {
        cw.appendChallengeParameter(param);
      } else {
        cw.appendQuotedChallengeParameter(param);
      }
    }
  }