/**
   * Returns a new AdGroupCriterion configured for a SET operation that will set the criterion's
   * bid.
   *
   * @param node the node whose criterion should be updated
   * @param adGroupId the ad group ID of the criterion
   * @param biddingConfig the bidding strategy configuration of the criterion
   */
  static AdGroupCriterion createCriterionForSetBid(
      ProductPartitionNode node, long adGroupId, BiddingStrategyConfiguration biddingConfig) {
    Preconditions.checkNotNull(node, "Null node");
    Preconditions.checkNotNull(biddingConfig, "Null bidding configuration");
    Preconditions.checkArgument(node.isBiddableUnit(), "Node is not a biddable unit");

    BiddableAdGroupCriterion biddableCriterion = new BiddableAdGroupCriterion();
    biddableCriterion.setAdGroupId(adGroupId);

    ProductPartition partition = new ProductPartition();
    partition.setId(node.getProductPartitionId());
    if (node.getParent() != null) {
      partition.setParentCriterionId(node.getParent().getProductPartitionId());
    }
    partition.setCaseValue(node.getDimension());
    partition.setPartitionType(ProductPartitionType.UNIT);

    biddableCriterion.setCriterion(partition);

    if (node.getBid() != null) {
      Money bidMoney = new Money();
      bidMoney.setMicroAmount(node.getBid());
      CpcBid cpcBid = new CpcBid();
      cpcBid.setBid(bidMoney);
      biddingConfig.setBids(new Bids[] {cpcBid});
    } else {
      biddingConfig.setBids(new Bids[0]);
    }
    biddableCriterion.setBiddingStrategyConfiguration(biddingConfig);
    return biddableCriterion;
  }
  /**
   * Returns a new AdGroupCriterion configured for an ADD operation.
   *
   * @param node the node whose criterion should be added
   * @param adGroupId the ad group ID of the criterion
   * @param biddingConfig the bidding strategy configuration of the criterion
   */
  static AdGroupCriterion createCriterionForAdd(
      ProductPartitionNode node, long adGroupId, BiddingStrategyConfiguration biddingConfig) {
    Preconditions.checkNotNull(node, "Null node");
    Preconditions.checkNotNull(biddingConfig, "Null bidding configuration");

    AdGroupCriterion adGroupCriterion;
    if (node.isExcludedUnit()) {
      adGroupCriterion = new NegativeAdGroupCriterion();
    } else {
      adGroupCriterion = new BiddableAdGroupCriterion();
      if (node.isUnit() && node.getBid() != null) {
        Money bidMoney = new Money();
        bidMoney.setMicroAmount(node.getBid());
        CpcBid cpcBid = new CpcBid();
        cpcBid.setBid(bidMoney);
        cpcBid.setCpcBidSource(BidSource.CRITERION);
        biddingConfig.setBids(new Bids[] {cpcBid});
        ((BiddableAdGroupCriterion) adGroupCriterion)
            .setBiddingStrategyConfiguration(biddingConfig);
      }
    }
    adGroupCriterion.setAdGroupId(adGroupId);

    ProductPartition partition = new ProductPartition();
    partition.setId(node.getProductPartitionId());
    if (node.getParent() != null) {
      partition.setParentCriterionId(node.getParent().getProductPartitionId());
    }
    partition.setCaseValue(node.getDimension());
    partition.setPartitionType(
        node.isUnit() ? ProductPartitionType.UNIT : ProductPartitionType.SUBDIVISION);
    adGroupCriterion.setCriterion(partition);
    return adGroupCriterion;
  }
  private static List<AdGroupOperation> buildAdGroupOperations(
      Iterator<Long> tempIdGenerator,
      String namePrefix,
      Iterable<CampaignOperation> campaignOperations) {
    List<AdGroupOperation> operations = Lists.newArrayList();
    for (CampaignOperation campaignOperation : campaignOperations) {
      for (int i = 0; i < NUMBER_OF_ADGROUPS_TO_ADD; i++) {
        AdGroup adGroup = new AdGroup();
        adGroup.setCampaignId(campaignOperation.getOperand().getId());
        adGroup.setId(tempIdGenerator.next());
        adGroup.setName(String.format("Batch Ad Group %s.%s", namePrefix, i));

        BiddingStrategyConfiguration biddingStrategyConfiguration =
            new BiddingStrategyConfiguration();
        CpcBid bid = new CpcBid();
        bid.setBid(new Money(null, 10000000L));
        biddingStrategyConfiguration.setBids(new Bids[] {bid});

        adGroup.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

        AdGroupOperation operation = new AdGroupOperation();
        operation.setOperand(adGroup);
        operation.setOperator(Operator.ADD);

        operations.add(operation);
      }
    }
    return operations;
  }