docs: @Nullable
    public static ICommonsOrderedMap <String, String> getDigestAuthParams (@Nullable final String sAuthHeader)
    {
      final String sRealHeader = StringHelper.trim (sAuthHeader);
      if (StringHelper.hasNoText (sRealHeader))
        return null;
  
      if (!sRealHeader.startsWith (HEADER_VALUE_PREFIX_DIGEST))
      {
        if (LOGGER.isErrorEnabled ())
          LOGGER.error ("String does not start with '" + HEADER_VALUE_PREFIX_DIGEST + "'");
        return null;
      }
  
      final char [] aChars = sRealHeader.toCharArray ();
      int nIndex = HEADER_VALUE_PREFIX_DIGEST.length ();
  
      if (nIndex >= aChars.length || !HttpStringHelper.isLinearWhitespaceChar (aChars[nIndex]))
      {
        if (LOGGER.isErrorEnabled ())
          LOGGER.error ("No whitespace after '" + HEADER_VALUE_PREFIX_DIGEST + "'");
        return null;
      }
      nIndex++;
  
      final ICommonsOrderedMap <String, String> aParams = new CommonsLinkedHashMap <> ();
      while (true)
      {
        // Skip all spaces
        while (nIndex < aChars.length && HttpStringHelper.isLinearWhitespaceChar (aChars[nIndex]))
          nIndex++;
  
        // Find token name
        int nStartIndex = nIndex;
        while (nIndex < aChars.length && HttpStringHelper.isTokenChar (aChars[nIndex]))
          nIndex++;
        if (nStartIndex == nIndex)
        {
          if (LOGGER.isErrorEnabled ())
            LOGGER.error ("No token and no whitespace found for auth-param name: '" + aChars[nIndex] + "'");
          return null;
        }
        final String sToken = sRealHeader.substring (nStartIndex, nIndex);
  
        // Skip all spaces
        while (nIndex < aChars.length && HttpStringHelper.isLinearWhitespaceChar (aChars[nIndex]))
          nIndex++;
  
        if (nIndex >= aChars.length || aChars[nIndex] != '=')
        {
          if (LOGGER.isErrorEnabled ())
            LOGGER.error ("No separator char '=' found after '" + sToken + "'");
          return null;
        }
        nIndex++;
  
        // Skip all spaces
        while (nIndex < aChars.length && HttpStringHelper.isLinearWhitespaceChar (aChars[nIndex]))
          nIndex++;
  
        if (nIndex >= aChars.length)
        {
          if (LOGGER.isErrorEnabled ())
            LOGGER.error ("Found nothing after '=' of '" + sToken + "'");
          return null;
        }
  
        String sValue;
        if (aChars[nIndex] == HttpStringHelper.QUOTEDTEXT_BEGIN)
        {
          // Quoted string
          ++nIndex;
          nStartIndex = nIndex;
          while (nIndex < aChars.length && HttpStringHelper.isQuotedTextChar (aChars[nIndex]))
            nIndex++;
          if (nIndex >= aChars.length)
          {
            if (LOGGER.isErrorEnabled ())
              LOGGER.error ("Unexpected EOF in quoted text for '" + sToken + "'");
            return null;
          }
          if (aChars[nIndex] != HttpStringHelper.QUOTEDTEXT_END)
          {
            if (LOGGER.isErrorEnabled ())
              LOGGER.error ("Quoted string of token '" +
                               sToken +
                               "' is not terminated correctly: '" +
                               aChars[nIndex] +
                               "'");
            return null;
          }
          sValue = sRealHeader.substring (nStartIndex, nIndex);
  
          // Skip termination char
          nIndex++;
        }
        else
        {
          // Token
          nStartIndex = nIndex;
          while (nIndex < aChars.length && HttpStringHelper.isTokenChar (aChars[nIndex]))
            nIndex++;
          if (nStartIndex == nIndex)
          {
            if (LOGGER.isErrorEnabled ())
              LOGGER.error ("No token and no whitespace found for auth-param value of '" +
                               sToken +
                               "': '" +
                               aChars[nIndex] +
                               "'");
            return null;
          }
          sValue = sRealHeader.substring (nStartIndex, nIndex);
        }
  
        // Remember key/value pair
        aParams.put (sToken, sValue);
  
        // Skip all spaces
        while (nIndex < aChars.length && HttpStringHelper.isLinearWhitespaceChar (aChars[nIndex]))
          nIndex++;
  
        // Check if there are any additional parameters
        if (nIndex >= aChars.length)
        {
          // No more tokens - we're done
          break;
        }
  
        // If there is a comma, another parameter is expected
        if (aChars[nIndex] != ',')
        {
          if (LOGGER.isErrorEnabled ())
            LOGGER.error ("Illegal character after auth-param '" + sToken + "': '" + aChars[nIndex] + "'");
          return null;
        }
        ++nIndex;
  
        if (nIndex >= aChars.length)
        {
          if (LOGGER.isErrorEnabled ())
            LOGGER.error ("Found nothing after continuation of auth-param '" + sToken + "'");
          return null;
        }
      }
  
      return aParams;
    }