/**
   * Return an error message describing the types and number of failures in the BatchWrite.
   *
   * @param failedRows the rows which failed, and their respective error messages
   * @return error message describing the failed rows
   */
  private String getFailedRowsMessage(IntObjectOpenHashMap<WriteResult> failedRows) {

    if (failedRows != null && failedRows.size() > 0) {

      // Aggregate the error counts by code.
      HashMap<Code, Integer> errorCodeToCountMap = new HashMap<>();
      for (IntObjectCursor<WriteResult> failedRowCursor : failedRows) {
        WriteResult wr = failedRowCursor.value;
        Code errorCode = (wr == null ? null : wr.getCode());
        Integer errorCount = errorCodeToCountMap.get(errorCode);
        errorCodeToCountMap.put(
            errorCode, (errorCode == null || errorCount == null ? 1 : errorCount + 1));
      }

      // Make a string out of the error map.
      StringBuilder buf = new StringBuilder();
      buf.append("{ ");
      boolean first = true;
      for (Map.Entry<Code, Integer> entry : errorCodeToCountMap.entrySet()) {
        if (!first) {
          buf.append(", ");
        } else {
          first = false;
        }
        buf.append(String.format("%s=%s", entry.getKey(), entry.getValue()));
      }
      buf.append(" }");
      return buf.toString();
    } else {
      return "NONE";
    }
  }