/**
   * Build a Map between VO name and a collection of reservation summary information. This
   * collection of reservation summary information is itself a Map between the reservation
   * description and a summary of all reservations with that same description. Those reservations
   * without a description are ignored.
   *
   * @param reservations a Map between reservation ID and a corresponding ReservationInfo object
   *     describing that reservation.
   * @return a Map of VO to reservation-description summaries.
   */
  private Map<String, Map<String, ReservationSummaryInfo>> buildSummaryInfo(
      Map<String, ReservationInfo> reservations) {
    Map<String, Map<String, ReservationSummaryInfo>> summary = new HashMap<>();

    for (Map.Entry<String, ReservationInfo> entry : reservations.entrySet()) {
      String reservationId = entry.getKey();
      ReservationInfo info = entry.getValue();

      /*
       * Ignore those reservations that don't have a state or that
       * state is a final one
       */
      if (!info.hasState() || info.getState().isFinalState()) {
        _log.debug("ignoring reservation " + reservationId + " as state is undefined or final");
        continue;
      }

      /* Skip those reservations that don't have a description */
      if (!info.hasDescription() || info.getDescription().isEmpty()) {
        _log.debug(
            "ignoring reservation " + reservationId + " as description is undefined or empty");
        continue;
      }

      /* Skip all those reservations that don't have a well-defined VO */
      if (!info.hasVo() || info.getVo().isEmpty()) {
        _log.debug("ignoring reservation " + reservationId + " as VO is undefined or empty");
        continue;
      }

      String voName = info.getVo();

      ReservationSummaryInfo thisSummary;

      Map<String, ReservationSummaryInfo> thisVoSummary;

      thisVoSummary = summary.get(voName);

      if (thisVoSummary == null) {
        thisVoSummary = new HashMap<>();
        summary.put(voName, thisVoSummary);
      }

      thisSummary = thisVoSummary.get(info.getDescription());

      if (thisSummary == null) {
        thisSummary = new ReservationSummaryInfo();
        thisVoSummary.put(info.getDescription(), thisSummary);
      }

      // update summary with this reservation.
      thisSummary.addReservationInfo(reservationId, info);
    }

    return summary;
  }
 /**
  * Add a SRM reservation to this Reservation summary.
  *
  * @param reservationId the ID of this reservation.
  * @param info the information about this reservation.
  */
 public void addReservationInfo(String reservationId, ReservationInfo info) {
   if (info.hasTotal()) {
     _total += info.getTotal();
   }
   if (info.hasUsed()) {
     _used += info.getUsed();
   }
   if (info.hasFree()) {
     _free += info.getFree();
   }
   if (info.hasAllocated()) {
     _allocated += info.getAllocated();
   }
   _ids.add(reservationId);
 }