docs: private static String calculateMessageAttributesMd5(final Map<String, MessageAttributeValue> messageAttributes) {
          if (log.isDebugEnabled()) {
              log.debug("Message attribtues: " + messageAttributes);
          }
          List<String> sortedAttributeNames = new ArrayList<String>(messageAttributes.keySet());
          Collections.sort(sortedAttributeNames);
  
          MessageDigest md5Digest = null;
          try {
              md5Digest = MessageDigest.getInstance("MD5");
  
              for (String attrName : sortedAttributeNames) {
                  MessageAttributeValue attrValue = messageAttributes.get(attrName);
  
                  // Encoded Name
                  updateLengthAndBytes(md5Digest, attrName);
                  // Encoded Type
                  updateLengthAndBytes(md5Digest, attrValue.getDataType());
  
                  // Encoded Value
                  if (attrValue.getStringValue() != null) {
                      md5Digest.update(STRING_TYPE_FIELD_INDEX);
                      updateLengthAndBytes(md5Digest, attrValue.getStringValue());
                  } else if (attrValue.getBinaryValue() != null) {
                      md5Digest.update(BINARY_TYPE_FIELD_INDEX);
                      updateLengthAndBytes(md5Digest, attrValue.getBinaryValue());
                  } else if (attrValue.getStringListValues().size() > 0) {
                      md5Digest.update(STRING_LIST_TYPE_FIELD_INDEX);
                      for (String strListMember : attrValue.getStringListValues()) {
                          updateLengthAndBytes(md5Digest, strListMember);
                      }
                  } else if (attrValue.getBinaryListValues().size() > 0) {
                      md5Digest.update(BINARY_LIST_TYPE_FIELD_INDEX);
                      for (ByteBuffer byteListMember : attrValue.getBinaryListValues()) {
                          updateLengthAndBytes(md5Digest, byteListMember);
                      }
                  }
              }
          } catch (Exception e) {
              throw new AmazonClientException("Unable to calculate the MD5 hash of the message attributes. "
                      + e.getMessage(), e);
          }
  
          String expectedMd5Hex = BinaryUtils.toHex(md5Digest.digest());
          if (log.isDebugEnabled()) {
              log.debug("Expected  MD5 of message attributes: " + expectedMd5Hex);
          }
          return expectedMd5Hex;
      }