/** Returns a REMOVE operation for the specified node. */
  private OperationPair createRemoveOperation(ProductPartitionNode node) {
    Preconditions.checkNotNull(
        node.getProductPartitionId(), "Node for REMOVE operation has no partition ID: %s", node);
    Preconditions.checkArgument(
        node.getProductPartitionId().longValue() >= 0L,
        "Node for REMOVE operation has a negative partition ID: %s",
        node);

    AdGroupCriterionOperation removeOp = new AdGroupCriterionOperation();
    removeOp.setOperator(Operator.REMOVE);
    removeOp.setOperand(ProductPartitionNodeAdapter.createCriterionForRemove(node, adGroupId));

    return new OperationPair(node, removeOp);
  }
  /** Returns a SET operation for the specified node. */
  private OperationPair createSetBidOperation(ProductPartitionNode node) {
    Preconditions.checkNotNull(
        node.getProductPartitionId(), "Node for SET operation has no partition ID: %s", node);
    Preconditions.checkArgument(
        node.getProductPartitionId().longValue() >= 0L,
        "Node for SET operation has a negative partition ID: %s",
        node);
    AdGroupCriterionOperation setOp = new AdGroupCriterionOperation();
    setOp.setOperator(Operator.SET);
    setOp.setOperand(
        ProductPartitionNodeAdapter.createCriterionForSetBid(
            node, adGroupId, getBiddingStrategyConfiguration()));

    return new OperationPair(node, setOp);
  }
  /**
   * Creates ADD operations for the node and ALL of its children and adds them to the provided
   * operations list.
   */
  private List<OperationPair> createAddOperations(ProductPartitionNode node) {
    AdGroupCriterionOperation addOp = new AdGroupCriterionOperation();
    addOp.setOperator(Operator.ADD);

    // Set the node's ID to a new temporary ID.
    node.setProductPartitionId(idGenerator.next());

    addOp.setOperand(
        ProductPartitionNodeAdapter.createCriterionForAdd(
            node, adGroupId, getBiddingStrategyConfiguration()));

    List<OperationPair> operationsList = Lists.newArrayList();
    operationsList.add(new OperationPair(node, addOp));

    // Recursively add all of this node's children to the operations list.
    for (ProductPartitionNode child : node.getChildren()) {
      operationsList.addAll(createAddOperations(child));
    }
    return operationsList;
  }