private void fillNests(JwSet<Integer> nestIds) {
    enterMonitor("AcActionSnapshotLoader.fillNest");
    try {
      if (nestIds.isEmpty()) return;

      // we need to continue loading nests until all parent and
      // top nests have been loaded into the snapshot.
      // also load all any aliases for nests newly loaded nests.
      JwSet<Integer> aliasIds = new JwSet<Integer>();
      while (nestIds.isNotEmpty()) {
        fillDatabaseNests(nestIds);
        fillMissingNests(nestIds);

        // determine missing nest ids
        JwSet<Integer> allNestIds = AcBatchNest.collectNestIds(_nests.values());
        JwSet<Integer> loadedNestIds = AcBatchNest.collectIds(_nests.values());
        nestIds = allNestIds;
        nestIds.removeAll(loadedNestIds);

        // determine missing alias ids
        JwSet<Integer> allAliasIds = AcBatchNest.collectAliasIds(_nests.values());
        JwSet<Integer> loadedAliasIds = AcBatchAlias.collectIds(_aliases.values());
        aliasIds = allAliasIds;
        aliasIds.removeAll(loadedAliasIds);
        fillAliases(aliasIds);
      }
    } finally {
      exitMonitor();
    }
  }
  private void fillMissingNests(JwSet<Integer> nestIds) {
    for (Integer id : nestIds) {
      if (isNestLoaded(id)) continue;

      AcBatchNest e = new AcBatchNest(getAccountCode());
      e.setNestId(id);
      _nests.put(id, e);
    }
  }
  private void loadLatestModelsRelatedToGroups(
      JwMap<Integer, JwSet<Integer>> m, Integer bId, JwSet<Integer> groups) {
    enterMonitor("AcActionSnapshotLoader.loadGroups");
    try {
      JwList<AcBatchItem> is;
      JwList<AcBatchNest> ns;
      JwList<AcBatchAlias> as;
      JwList<AcBatchFlight> fs;

      JwTimestamp utcTs = _batch.getStartUtcTs();
      is = _access.getBatchItemDb().getLatestViewBeforeByBatchGroups(bId, groups, utcTs);
      ns = _access.getBatchNestDb().getLatestViewBeforeByBatchGroups(bId, groups, utcTs);
      as = _access.getBatchAliasDb().getLatestViewBeforeByBatchGroups(bId, groups, utcTs);
      fs = _access.getBatchFlightDb().getLatestViewBeforeByBatchGroups(bId, groups, utcTs);

      for (AcBatchItem e : is) {
        //                if ( e.hasItemId(DEBUG_ITEM_ID) )
        //                {
        //                    debug("x","Item "+ e.getItemId()+ " batch "+ e.getBatchId()+ " group
        // "+ e.getGroupCode());
        //                    Thread.dumpStack();
        //                }
        _items.putIfMissing(e.getItemId(), e);
        addBatchGroup(m, e.getBatchId(), e.getGroupCode());
      }
      for (AcBatchNest e : ns) {
        _nests.putIfMissing(e.getNestId(), e);
        addBatchGroup(m, e.getBatchId(), e.getGroupCode());
      }
      for (AcBatchAlias e : as) {
        _aliases.putIfMissing(e.getAliasId(), e);
        //                if ( _aliases.putIfMissing(e.getAliasId(), e) )
        //                {
        //                    if ( e.hasAliasId(DEBUG_ALIAS_ID) )
        //                    {
        //                        debug("x", "Alias "
        //                            + e.getAliasId()
        //                            + " batch "
        //                            + e.getBatchId()
        //                            + " group "
        //                            + e.getGroupCode());
        //                        Thread.dumpStack();
        //                    }
        //                }
        addBatchGroup(m, e.getBatchId(), e.getGroupCode());
      }
      for (AcBatchFlight e : fs) {
        _flights.putIfMissing(e.getFlightId(), e);
        addBatchGroup(m, e.getBatchId(), e.getGroupCode());
      }
    } finally {
      exitMonitor();
    }
  }
  private void fillDatabaseNests(JwSet<Integer> nestIds) {
    JwList<AcBatchNest> v =
        _access.getBatchNestDb().getBatchNestsBefore(_batch.getStartUtcTs(), nestIds);
    for (AcBatchNest e : v) {
      Integer id = e.getNestId();
      if (isNestLoaded(id)) continue;

      _nests.put(id, e);
      if (e.hasGroupCode()) {
        // debug("1", "Nest "+ e.getNestId()+ " batch "+ e.getBatchId()+ " group "+
        // e.getGroupCode());
        addBatchGroup(_batchGroups, e.getBatchId(), e.getGroupCode());
      }
    }
  }
  private void loadMissing(boolean logMissing) {
    JwSet<Integer> nestIds = new JwSet<Integer>();
    AcBatchItem.collectNestIdsOn(_items.values(), nestIds);
    removeLoadedIds(nestIds, _nests.keySet());
    if (logMissing && nestIds.isNotEmpty()) logMissing("nests", nestIds);
    fillNests(nestIds);

    JwSet<Integer> aliasIds = new JwSet<Integer>();
    AcBatchNest.collectAliasIdsOn(_nests.values(), aliasIds);
    removeLoadedIds(aliasIds, _aliases.keySet());
    if (logMissing && aliasIds.isNotEmpty()) logMissing("aliases", aliasIds);
    fillAliases(aliasIds);

    JwSet<Integer> flightIds = new JwSet<Integer>();
    AcBatchItem.collectFlightIdsOn(_items.values(), flightIds);
    AcBatchNest.collectFlightIdsOn(_nests.values(), flightIds);
    removeLoadedIds(flightIds, _flights.keySet());
    if (logMissing && flightIds.isNotEmpty()) logMissing("flights", flightIds);
    fillFlights(flightIds);
  }
  /**
   * Load the batch nest associated with the specified nest. This is used when processing alias
   * actions where the alias has not yet been mapped to a nest. The nest being passed in could be
   * new or it could be an existing nest. Either way we need to load or create the associated batch
   * nest.
   */
  public AcActionSnapshot loadNest(AcBatch batch, AcNest nest) {
    _batch = batch;

    _items = new JwMap<Integer, AcBatchItem>();
    _nests = new JwMap<Integer, AcBatchNest>();
    _aliases = new JwMap<Integer, AcBatchAlias>();
    _flights = new JwMap<Integer, AcBatchFlight>();

    JwSet<Integer> flightIds = new JwSet<Integer>();
    JwSet<Integer> nestIds = new JwSet<Integer>();
    nestIds.add(nest.getId());

    fillNests(nestIds);
    AcBatchNest.collectFlightIdsOn(_nests.values(), flightIds);

    fillFlights(flightIds);
    return getSnapshot(true);
  }
  private void fillActions(JwList<AcAction> actions, boolean skipRevokedActions) {
    enterMonitor("AcActionSnapshotLoader.fillActions");
    try {
      // debug("B", "fillNonRevokedActions");
      JwSet<Integer> itemIds = new JwSet<Integer>();
      JwSet<Integer> nestIds = new JwSet<Integer>();
      JwSet<Integer> aliasIds = new JwSet<Integer>();
      JwSet<Integer> flightIds = new JwSet<Integer>();
      if (hasEntanglement()) {
        itemIds.addAll(_entanglement.getItemIds());
        nestIds.addAll(_entanglement.getNestIds());
        aliasIds.addAll(_entanglement.getAliasIds());
        flightIds.addAll(_entanglement.getFlightIds());
      }

      for (AcAction a : actions) {
        if (skipRevokedActions && a.hasStatusRevoked() && a.hasPendingChangeNone()) continue;
        a.collectItemIdsOn(itemIds);
        a.collectNestIdsOn(nestIds);
        a.collectAliasIdsOn(aliasIds);
        a.collectFlightIdsOn(flightIds);
      }

      fillItems(itemIds);
      AcBatchItem.collectNestIdsOn(_items.values(), nestIds);
      AcBatchItem.collectFlightIdsOn(_items.values(), flightIds);

      // load aliases before nests
      fillAliases(aliasIds);
      AcBatchAlias.collectNestIdsOn(_aliases.values(), nestIds);

      fillNests(nestIds);
      AcBatchNest.collectFlightIdsOn(_nests.values(), flightIds);

      fillFlights(flightIds);
      fillGroups();

      testAllItemsAndNestsLoaded();
    } finally {
      exitMonitor();
    }
  }
  public void loadBatch(AcBatch b) {
    enterMonitor("AcActionSnapshotLoader.loadBatch");
    try {
      _batch = b;
      Integer batchId = b.getId();

      JwList<AcBatchItem> items = _access.getBatchItemDb().getAllByBatchId(batchId);
      JwList<AcBatchNest> nests = _access.getBatchNestDb().getAllByBatchId(batchId);
      JwList<AcBatchAlias> aliases = _access.getBatchAliasDb().getAllByBatchId(batchId);
      JwList<AcBatchFlight> flights = _access.getBatchFlightDb().getAllByBatchId(batchId);

      _items = AcBatchItem.toItemIdMap(items);
      //            AcBatchItem e = _items.get(DEBUG_ITEM_ID);
      //            if ( e != null )
      //            {
      //                debug("x","Item "+ e.getItemId()+ " batch "+ e.getBatchId()+ " group "+
      // e.getGroupCode());
      //                Thread.dumpStack();
      //            }

      _nests = AcBatchNest.toNestIdMap(nests);
      _aliases = AcBatchAlias.toAliasIdMap(aliases);
      //            AcBatchAlias e = _aliases.get(DEBUG_ALIAS_ID);
      //            if ( e != null )
      //            {
      //                debug(
      //                    "x",
      //                    "Alias "
      //                        + e.getAliasId()
      //                        + " batch "
      //                        + e.getBatchId()
      //                        + " group "
      //                        + e.getGroupCode());
      //                Thread.dumpStack();
      //            }
      _flights = AcBatchFlight.toFlightIdMap(flights);
    } finally {
      exitMonitor();
    }
  }