docs: public AccountEventsStreams buildForAccount(final Map<UUID, List<SubscriptionBase>> subscriptions, final Catalog catalog, final InternalTenantContext internalTenantContext) throws EntitlementApiException {
          // Retrieve the account
          final ImmutableAccountData account;
          final int accountBCD;
          try {
              account = accountInternalApi.getImmutableAccountDataByRecordId(internalTenantContext.getAccountRecordId(), internalTenantContext);
              accountBCD = accountInternalApi.getBCD(internalTenantContext);
          } catch (final AccountApiException e) {
              throw new EntitlementApiException(e);
          }
  
          if (subscriptions.isEmpty()) {
              // Bail early
              return new DefaultAccountEventsStreams(account);
          }
  
          // Retrieve the bundles
          final List<SubscriptionBaseBundle> bundles = subscriptionInternalApi.getBundlesForAccount(account.getId(), internalTenantContext);
          // Map bundle id -> bundles
          final Map<UUID, SubscriptionBaseBundle> bundlesPerId = new HashMap<UUID, SubscriptionBaseBundle>();
          for (final SubscriptionBaseBundle bundle : bundles) {
              bundlesPerId.put(bundle.getId(), bundle);
          }
  
          // Retrieve the blocking states
          final List<BlockingState> blockingStatesForAccount = defaultBlockingStateDao.getBlockingAllForAccountRecordId(catalog, internalTenantContext);
  
          // Optimization: build lookup tables for blocking states states
          final Collection<BlockingState> accountBlockingStates = new LinkedList<BlockingState>();
          final Map<UUID, List<BlockingState>> blockingStatesPerSubscription = new HashMap<UUID, List<BlockingState>>();
          final Map<UUID, List<BlockingState>> blockingStatesPerBundle = new HashMap<UUID, List<BlockingState>>();
          for (final BlockingState blockingState : blockingStatesForAccount) {
              if (BlockingStateType.SUBSCRIPTION.equals(blockingState.getType())) {
                  if (blockingStatesPerSubscription.get(blockingState.getBlockedId()) == null) {
                      blockingStatesPerSubscription.put(blockingState.getBlockedId(), new LinkedList<BlockingState>());
                  }
                  blockingStatesPerSubscription.get(blockingState.getBlockedId()).add(blockingState);
              } else if (BlockingStateType.SUBSCRIPTION_BUNDLE.equals(blockingState.getType())) {
                  if (blockingStatesPerBundle.get(blockingState.getBlockedId()) == null) {
                      blockingStatesPerBundle.put(blockingState.getBlockedId(), new LinkedList<BlockingState>());
                  }
                  blockingStatesPerBundle.get(blockingState.getBlockedId()).add(blockingState);
              } else if (BlockingStateType.ACCOUNT.equals(blockingState.getType()) &&
                         account.getId().equals(blockingState.getBlockedId())) {
                  accountBlockingStates.add(blockingState);
              }
          }
  
          // Build the EventsStream objects
          final Map<UUID, Integer> bcdCache = new HashMap<UUID, Integer>();
          final Map<UUID, Collection<EventsStream>> eventsStreamPerBundle = new HashMap<UUID, Collection<EventsStream>>();
          final Map<UUID, Collection<SubscriptionBase>> subscriptionsPerBundle = new HashMap<UUID, Collection<SubscriptionBase>>();
          for (final UUID bundleId : subscriptions.keySet()) {
              final SubscriptionBaseBundle bundle = bundlesPerId.get(bundleId);
              final List<SubscriptionBase> allSubscriptionsForBundle = subscriptions.get(bundleId);
              final SubscriptionBase baseSubscription = findBaseSubscription(allSubscriptionsForBundle);
              final List<BlockingState> bundleBlockingStates = MoreObjects.firstNonNull(blockingStatesPerBundle.get(bundleId), ImmutableList.<BlockingState>of());
  
              if (eventsStreamPerBundle.get(bundleId) == null) {
                  eventsStreamPerBundle.put(bundleId, new LinkedList<EventsStream>());
              }
              if (subscriptionsPerBundle.get(bundleId) == null) {
                  subscriptionsPerBundle.put(bundleId, allSubscriptionsForBundle);
              }
  
              for (final SubscriptionBase subscription : allSubscriptionsForBundle) {
                  final List<BlockingState> subscriptionBlockingStatesOnDisk = MoreObjects.firstNonNull(blockingStatesPerSubscription.get(subscription.getId()), ImmutableList.<BlockingState>of());
  
                  // We cannot always use blockingStatesForAccount here: we need subscriptionBlockingStates to contain the events not on disk when building an EventsStream
                  // for an add-on - which means going through the magic of ProxyBlockingStateDao, which will recursively
                  // create EventsStream objects. To avoid an infinite recursion, bypass ProxyBlockingStateDao when it's not
                  // needed, i.e. if this EventStream is for a standalone or a base subscription
                  final Collection<BlockingState> subscriptionBlockingStates;
                  if (baseSubscription == null || subscription.getId().equals(baseSubscription.getId())) {
                      subscriptionBlockingStates = subscriptionBlockingStatesOnDisk;
                  } else {
                      subscriptionBlockingStates = blockingStateDao.getBlockingHistory(subscriptionBlockingStatesOnDisk,
                                                                                       blockingStatesForAccount,
                                                                                       account,
                                                                                       bundle,
                                                                                       baseSubscription,
                                                                                       subscription,
                                                                                       allSubscriptionsForBundle,
                                                                                       accountBCD,
                                                                                       catalog,
                                                                                       internalTenantContext);
  
                  }
  
                  // Merge the BlockingStates
                  final Collection<BlockingState> blockingStateSet = new LinkedHashSet<BlockingState>(accountBlockingStates);
                  blockingStateSet.addAll(bundleBlockingStates);
                  blockingStateSet.addAll(subscriptionBlockingStates);
                  final List<BlockingState> blockingStates = ProxyBlockingStateDao.sortedCopy(blockingStateSet);
  
                  final EventsStream eventStream = buildForEntitlement(account,
                                                                       bundle,
                                                                       baseSubscription,
                                                                       subscription,
                                                                       allSubscriptionsForBundle,
                                                                       blockingStates,
                                                                       accountBCD,
                                                                       bcdCache,
                                                                       catalog,
                                                                       internalTenantContext);
                  eventsStreamPerBundle.get(bundleId).add(eventStream);
              }
          }
  
          return new DefaultAccountEventsStreams(account, bundles, subscriptionsPerBundle, eventsStreamPerBundle);
      }