docs: @Nonnull
    public static DigestAuthClientCredentials createDigestAuthClientCredentials (@Nonnull final EHttpMethod eMethod,
                                                                                 @Nonnull @Nonempty final String sDigestURI,
                                                                                 @Nonnull @Nonempty final String sUserName,
                                                                                 @Nonnull final String sPassword,
                                                                                 @Nonnull @Nonempty final String sRealm,
                                                                                 @Nonnull @Nonempty final String sServerNonce,
                                                                                 @Nullable final String sAlgorithm,
                                                                                 @Nullable final String sClientNonce,
                                                                                 @Nullable final String sOpaque,
                                                                                 @Nullable final String sMessageQOP,
                                                                                 @CheckForSigned final int nNonceCount)
    {
      ValueEnforcer.notNull (eMethod, "Method");
      ValueEnforcer.notEmpty (sDigestURI, "DigestURI");
      ValueEnforcer.notEmpty (sUserName, "UserName");
      ValueEnforcer.notNull (sPassword, "Password");
      ValueEnforcer.notEmpty (sRealm, "Realm");
      ValueEnforcer.notEmpty (sServerNonce, "ServerNonce");
      if (sMessageQOP != null && StringHelper.hasNoText (sClientNonce))
        throw new IllegalArgumentException ("If a QOP is defined, client nonce must be set!");
      if (sMessageQOP != null && nNonceCount <= 0)
        throw new IllegalArgumentException ("If a QOP is defined, nonce count must be positive!");
  
      final String sRealAlgorithm = sAlgorithm == null ? DEFAULT_ALGORITHM : sAlgorithm;
      if (!sRealAlgorithm.equals (ALGORITHM_MD5) && !sRealAlgorithm.equals (ALGORITHM_MD5_SESS))
        throw new IllegalArgumentException ("Currently only '" +
                                            ALGORITHM_MD5 +
                                            "' and '" +
                                            ALGORITHM_MD5_SESS +
                                            "' algorithms are supported!");
  
      if (sMessageQOP != null && !sMessageQOP.equals (QOP_AUTH))
        throw new IllegalArgumentException ("Currently only '" + QOP_AUTH + "' QOP is supported!");
  
      // Nonce must always by 8 chars long
      final String sNonceCount = getNonceCountString (nNonceCount);
  
      // Create HA1
      String sHA1 = _md5 (sUserName + SEPARATOR + sRealm + SEPARATOR + sPassword);
      if (sRealAlgorithm.equals (ALGORITHM_MD5_SESS))
      {
        if (StringHelper.hasNoText (sClientNonce))
          throw new IllegalArgumentException ("Algorithm requires client nonce!");
        sHA1 = _md5 (sHA1 + SEPARATOR + sServerNonce + SEPARATOR + sClientNonce);
      }
  
      // Create HA2
      // Method name must be upper-case!
      final String sHA2 = _md5 (eMethod.getName () + SEPARATOR + sDigestURI);
  
      // Create the request digest - result must be all lowercase hex chars!
      String sRequestDigest;
      if (sMessageQOP == null)
      {
        // RFC 2069 backwards compatibility
        sRequestDigest = _md5 (sHA1 + SEPARATOR + sServerNonce + SEPARATOR + sHA2);
      }
      else
      {
        sRequestDigest = _md5 (sHA1 +
                               SEPARATOR +
                               sServerNonce +
                               SEPARATOR +
                               sNonceCount +
                               SEPARATOR +
                               sClientNonce +
                               SEPARATOR +
                               sMessageQOP +
                               SEPARATOR +
                               sHA2);
      }
  
      return new DigestAuthClientCredentials (sUserName,
                                              sRealm,
                                              sServerNonce,
                                              sDigestURI,
                                              sRequestDigest,
                                              sAlgorithm,
                                              sClientNonce,
                                              sOpaque,
                                              sMessageQOP,
                                              sNonceCount);
    }