/**
   * Generates an authorisation header in response to wwwAuthHeader.
   *
   * @param method method of the request being authenticated
   * @param uri digest-uri
   * @param requestBody the body of the request.
   * @param authHeader the challenge that we should respond to
   * @param username
   * @param password
   * @return an authorisation header in response to authHeader.
   * @throws OperationFailedException if auth header was malformated.
   */
  public static AuthorizationHeader getAuthorizationHeader(
      String method,
      String uri,
      String requestBody,
      WWWAuthenticateHeader authHeader,
      String username,
      String password) {
    String response = null;
    HeaderFactory headerFactory = SipFactories.headerFactory;

    // JvB: authHeader.getQop() is a quoted _list_ of qop values
    // (e.g. "auth,auth-int") Client is supposed to pick one
    String qopList = authHeader.getQop();
    String qop = (qopList != null) ? "auth" : null;
    String nc_value = "00000001";
    String cnonce = "xyz";

    try {
      response =
          MessageDigestResponseAlgorithm.calculateResponse(
              authHeader.getAlgorithm(),
              username,
              authHeader.getRealm(),
              password,
              authHeader.getNonce(),
              nc_value, // JvB added
              cnonce, // JvB added
              method,
              uri,
              requestBody,
              qop); // jvb changed
    } catch (NullPointerException exc) {
      throw new IllegalStateException("The authenticate header was malformatted", exc);
    }

    AuthorizationHeader authorization = null;
    try {
      if (authHeader instanceof ProxyAuthenticateHeader) {
        authorization = headerFactory.createProxyAuthorizationHeader(authHeader.getScheme());
      } else {
        authorization = headerFactory.createAuthorizationHeader(authHeader.getScheme());
      }

      authorization.setUsername(username);
      authorization.setRealm(authHeader.getRealm());
      authorization.setNonce(authHeader.getNonce());
      authorization.setParameter("uri", uri);
      authorization.setResponse(response);
      if (authHeader.getAlgorithm() != null) {
        authorization.setAlgorithm(authHeader.getAlgorithm());
      }

      if (authHeader.getOpaque() != null && authHeader.getOpaque().length() > 0) {
        authorization.setOpaque(authHeader.getOpaque());
      }

      // jvb added
      if (qop != null) {
        authorization.setQop(qop);
        authorization.setCNonce(cnonce);
        authorization.setNonceCount(Integer.parseInt(nc_value));
      }

      authorization.setResponse(response);

    } catch (ParseException ex) {
      throw new SecurityException("Failed to create an authorization header!");
    }

    return authorization;
  }
  /**
   * Generates an authorisation header in response to wwwAuthHeader.
   *
   * @param method method of the request being authenticated
   * @param uri digest-uri
   * @param requestBody the body of the request.
   * @param authHeader the challenge that we should respond to
   * @param userCredentials username and pass
   * @return an authorisation header in response to authHeader.
   * @throws OperationFailedException if auth header was malformated.
   */
  private AuthorizationHeader getAuthorization(
      String method,
      String uri,
      String requestBody,
      WWWAuthenticateHeader authHeader,
      UserCredentialHash userCredentials) {
    String response = null;

    // JvB: authHeader.getQop() is a quoted _list_ of qop values
    // (e.g. "auth,auth-int") Client is supposed to pick one
    String qopList = authHeader.getQop();
    String qop = (qopList != null) ? "auth" : null;
    String nc_value = "00000001";
    String cnonce = "xyz";

    response =
        MessageDigestAlgorithm.calculateResponse(
            authHeader.getAlgorithm(),
            userCredentials.getHashUserDomainPassword(),
            authHeader.getNonce(),
            nc_value, // JvB added
            cnonce, // JvB added
            method,
            uri,
            requestBody,
            qop,
            sipStack.getStackLogger()); // jvb changed

    AuthorizationHeader authorization = null;
    try {
      if (authHeader instanceof ProxyAuthenticateHeader) {
        authorization = headerFactory.createProxyAuthorizationHeader(authHeader.getScheme());
      } else {
        authorization = headerFactory.createAuthorizationHeader(authHeader.getScheme());
      }

      authorization.setUsername(userCredentials.getUserName());
      authorization.setRealm(authHeader.getRealm());
      authorization.setNonce(authHeader.getNonce());
      authorization.setParameter("uri", uri);
      authorization.setResponse(response);
      if (authHeader.getAlgorithm() != null) {
        authorization.setAlgorithm(authHeader.getAlgorithm());
      }

      if (authHeader.getOpaque() != null) {
        authorization.setOpaque(authHeader.getOpaque());
      }

      // jvb added
      if (qop != null) {
        authorization.setQop(qop);
        authorization.setCNonce(cnonce);
        authorization.setNonceCount(Integer.parseInt(nc_value));
      }

      authorization.setResponse(response);

    } catch (ParseException ex) {
      throw new RuntimeException("Failed to create an authorization header!");
    }

    return authorization;
  }