/**
   * Load the profile information stored in the database
   *
   * @param
   */
  protected void loadProfile(AuctionMarkWorker worker) throws SQLException {
    synchronized (AuctionMarkProfile.class) {
      // Check whether we have a cached Profile we can copy from
      if (cachedProfile == null) {

        // Store everything in the cached profile.
        // We can then copy from that and extract out only the records
        // that we need for each AuctionMarkWorker
        cachedProfile = new AuctionMarkProfile(this.benchmark, this.rng);

        // Otherwise we have to go fetch everything again
        // So first we want to reset the database
        Connection conn = worker.getConnection();
        if (AuctionMarkConstants.RESET_DATABASE_ENABLE) {
          if (LOG.isDebugEnabled()) LOG.debug("Reseting database from last execution run");
          worker.getProcedure(ResetDatabase.class).run(conn);
        }

        // Then invoke LoadConfig to pull down the profile information we need
        if (LOG.isDebugEnabled()) LOG.debug("Loading AuctionMarkProfile for the first time");
        ResultSet results[] = worker.getProcedure(LoadConfig.class).run(conn);
        conn.commit();
        int result_idx = 0;

        // CONFIG_PROFILE
        loadConfigProfile(cachedProfile, results[result_idx++]);

        // IMPORTANT: We need to set these timestamps here. It must be done
        // after we have loaded benchmarkStartTime
        cachedProfile.setAndGetClientStartTime();
        cachedProfile.updateAndGetCurrentTime();

        // ITEM CATEGORY COUNTS
        loadItemCategoryCounts(cachedProfile, results[result_idx++]);

        // GLOBAL_ATTRIBUTE_GROUPS
        loadGlobalAttributeGroups(cachedProfile, results[result_idx++]);

        // PENDING COMMENTS
        loadPendingItemComments(cachedProfile, results[result_idx++]);

        // ITEMS
        while (result_idx < results.length) {
          //                assert(results[result_idx].isClosed() == false) :
          //                    "Unexpected closed ITEM ResultSet [idx=" + result_idx + "]";
          loadItems(cachedProfile, results[result_idx]);
          result_idx++;
        } // FOR

        for (ResultSet r : results) r.close();

        if (LOG.isDebugEnabled()) LOG.debug("Loaded profile:\n" + cachedProfile.toString());
      }
    } // SYNCH

    if (LOG.isTraceEnabled()) LOG.trace("Using cached SEATSProfile");
    this.copyProfile(worker, cachedProfile);
  }
  private AuctionMarkProfile copyProfile(AuctionMarkWorker worker, AuctionMarkProfile other) {
    this.client_id = worker.getId();
    this.scale_factor = other.scale_factor;
    this.loaderStartTime = other.loaderStartTime;
    this.loaderStopTime = other.loaderStopTime;
    this.users_per_itemCount = other.users_per_itemCount;
    this.items_per_category = other.items_per_category;
    this.gag_ids = other.gag_ids;

    // Initialize the UserIdGenerator so we can figure out whether our
    // client should even have these ids
    this.initializeUserIdGenerator(this.client_id);
    assert (this.userIdGenerator != null);

    for (int i = 0; i < this.allItemSets.length; i++) {
      LinkedList<ItemInfo> list = this.allItemSets[i];
      assert (list != null);
      LinkedList<ItemInfo> origList = other.allItemSets[i];
      assert (origList != null);

      for (ItemInfo itemInfo : origList) {
        UserId sellerId = itemInfo.getSellerId();
        if (this.userIdGenerator.checkClient(sellerId)) {
          this.seller_item_cnt.set(sellerId, sellerId.getItemCount());
          list.add(itemInfo);
        }
      } // FOR
      Collections.shuffle(list);
    } // FOR

    for (ItemCommentResponse cr : other.pending_commentResponses) {
      UserId sellerId = new UserId(cr.sellerId);
      if (this.userIdGenerator.checkClient(sellerId)) {
        this.pending_commentResponses.add(cr);
      }
    } // FOR

    if (LOG.isTraceEnabled()) LOG.trace("SellerItemCounts:\n" + this.seller_item_cnt);

    return (this);
  }