docs: public UsageInArrearItemsAndNextNotificationDate computeMissingItemsAndNextNotificationDate(final List<InvoiceItem> existingUsage) throws CatalogApiException, InvoiceApiException {
  
          Preconditions.checkState(isBuilt.get());
  
          if (transitionTimes.size() < 2) {
              return new UsageInArrearItemsAndNextNotificationDate(ImmutableList.<InvoiceItem>of(), ImmutableSet.of(), computeNextNotificationDate());
          }
  
          final List<InvoiceItem> result = Lists.newLinkedList();
  
          final RolledUpUnitsWithTracking allUsageWithTracking = getRolledUpUsage();
          final List<RolledUpUsage> allUsage = allUsageWithTracking.getUsage();
  
          final Set<TrackingRecordId> allTrackingIds = allUsageWithTracking.getTrackingIds();
  
          final Set<TrackingRecordId> existingTrackingIds = extractTrackingIds(allExistingTrackingIds);
  
  
          final Set<TrackingRecordId> newTrackingIds = Sets.filter(allTrackingIds, new Predicate<TrackingRecordId>() {
              @Override
              public boolean apply(final TrackingRecordId allRecord) {
  
                  return ! Iterables.any(existingTrackingIds, new Predicate<TrackingRecordId>() {
                      @Override
                      public boolean apply(final TrackingRecordId existingRecord) {
                          return existingRecord.isSimilarRecord(allRecord);
                      }
                  });
              }
          });
  
  
          // Each RolledUpUsage 'ru' is for a specific time period and across all units
          for (final RolledUpUsage ru : allUsage) {
  
              //
              // Previously billed items:
              //
              // 1. Retrieves current price amount billed for that period of time (and usage section)
              final Iterable<InvoiceItem> billedItems = getBilledItems(ru.getStart(), ru.getEnd(), existingUsage);
              // 2. Verify whether previously built items have the item_details section
              final boolean areAllBilledItemsWithDetails = areAllBilledItemsWithDetails(billedItems);
              // 3. verify if we already billed that period - use to decide whether we should include $0 items when there is nothing to bill for.
              final boolean isPeriodPreviouslyBilled = !Iterables.isEmpty(billedItems);
              // 4. Computes total billed usage amount
              final BigDecimal billedUsage = computeBilledUsage(billedItems);
  
              final List<RolledUpUnit> rolledUpUnits = ru.getRolledUpUnits();
  
              final UsageInArrearAggregate toBeBilledUsageDetails = getToBeBilledUsageDetails(rolledUpUnits, billedItems, areAllBilledItemsWithDetails);
              final BigDecimal toBeBilledUsageUnrounded = toBeBilledUsageDetails.getAmount();
              // See https://github.com/killbill/killbill/issues/1124
              final BigDecimal toBeBilledUsage = KillBillMoney.of(toBeBilledUsageUnrounded, getCurrency());
              populateResults(ru.getStart(), ru.getEnd(), billedUsage, toBeBilledUsage, toBeBilledUsageDetails, areAllBilledItemsWithDetails, isPeriodPreviouslyBilled, result);
  
          }
          final LocalDate nextNotificationDate = computeNextNotificationDate();
          return new UsageInArrearItemsAndNextNotificationDate(result, newTrackingIds, nextNotificationDate);
      }