/// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group that contains the keyword.
    /// </param>
    /// <param name="keywordId">Id of the keyword to be updated.</param>
    public void Run(AdWordsUser user, long adGroupId, long keywordId) {
      // Get the AdGroupCriterionService.
      AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(AdWordsService.v201409.AdGroupCriterionService);

      // Since we are not updating any keyword-specific fields, it is enough to
      // create a criterion object.
      Criterion criterion = new Criterion();
      criterion.id = keywordId;

      // Create ad group criterion.
      BiddableAdGroupCriterion biddableAdGroupCriterion = new BiddableAdGroupCriterion();
      biddableAdGroupCriterion.adGroupId = adGroupId;
      biddableAdGroupCriterion.criterion = criterion;

      // Create the bids.
      BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
      CpcBid cpcBid = new CpcBid();
      cpcBid.bid = new Money();
      cpcBid.bid.microAmount = 1000000;
      biddingConfig.bids = new Bids[] {cpcBid};

      biddableAdGroupCriterion.biddingStrategyConfiguration = biddingConfig;

      // Create the operation.
      AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
      operation.@operator = Operator.SET;
      operation.operand = biddableAdGroupCriterion;

      try {
        // Update the keyword.
        AdGroupCriterionReturnValue retVal =
            adGroupCriterionService.mutate(new AdGroupCriterionOperation[] {operation});

        // Display the results.
        if (retVal != null && retVal.value != null && retVal.value.Length > 0) {
          AdGroupCriterion adGroupCriterion = retVal.value[0];
          long bidAmount = 0;
          foreach (Bids bids in (adGroupCriterion as BiddableAdGroupCriterion).
              biddingStrategyConfiguration.bids) {
            if (bids is CpcBid) {
              bidAmount = (bids as CpcBid).bid.microAmount;
              break;
            }
          }

          Console.WriteLine("Keyword with ad group id = '{0}', id = '{1}' was updated with " +
              "bid amount = '{2}' micros.", adGroupCriterion.adGroupId,
              adGroupCriterion.criterion.id, bidAmount);
        } else {
          Console.WriteLine("No keyword was updated.");
        }
      } catch (Exception ex) {
        throw new System.ApplicationException("Failed to update keyword.", ex);
      }
    }
    /// <summary>
    /// Creates a test adgroup for running further tests.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">The campaign id for which the adgroup is created.</param>
    /// <param name="isCpmBid">True, if a ManualCPM bid is to be used.</param>
    /// <returns>The adgroup id.</returns>
    public long CreateAdGroup(AdWordsUser user, long campaignId, bool isCpmBid) {
      AdGroupService adGroupService =
          (AdGroupService) user.GetService(AdWordsService.v201409.AdGroupService);

      AdGroupOperation adGroupOperation = new AdGroupOperation();
      adGroupOperation.@operator = Operator.ADD;
      adGroupOperation.operand = new AdGroup();
      adGroupOperation.operand.campaignId = campaignId;
      adGroupOperation.operand.name =
          string.Format("AdGroup {0}", DateTime.Now.ToString("yyyy-M-d H:m:s.ffffff"));
      adGroupOperation.operand.status = AdGroupStatus.ENABLED;

      if (isCpmBid) {
        BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
        CpmBid cpmBid = new CpmBid();
        cpmBid.bid = new Money();
        cpmBid.bid.microAmount = 10000000;
        biddingConfig.bids = new Bids[] {cpmBid};
        adGroupOperation.operand.biddingStrategyConfiguration = biddingConfig;
      } else {
        BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();
        CpcBid cpcBid = new CpcBid();
        cpcBid.bid = new Money();
        cpcBid.bid.microAmount = 10000000;
        biddingConfig.bids = new Bids[] {cpcBid};
        adGroupOperation.operand.biddingStrategyConfiguration = biddingConfig;
      }
      AdGroupReturnValue retVal = adGroupService.mutate(new AdGroupOperation[] {adGroupOperation});
      return retVal.value[0].id;
    }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign to which ad groups are
    /// added.</param>
    public void Run(AdWordsUser user, long campaignId) {
      // Get the AdGroupService.
      AdGroupService adGroupService =
          (AdGroupService) user.GetService(AdWordsService.v201409.AdGroupService);

      List<AdGroupOperation> operations = new List<AdGroupOperation>();

      for (int i = 0; i < NUM_ITEMS; i++) {
        // Create the ad group.
        AdGroup adGroup = new AdGroup();
        adGroup.name = string.Format("Earth to Mars Cruises #{0}",
            ExampleUtilities.GetRandomString());
        adGroup.status = AdGroupStatus.ENABLED;
        adGroup.campaignId = campaignId;

        // Set the ad group bids.
        BiddingStrategyConfiguration biddingConfig = new BiddingStrategyConfiguration();

        CpcBid cpcBid = new CpcBid();
        cpcBid.bid = new Money();
        cpcBid.bid.microAmount = 10000000;

        biddingConfig.bids = new Bids[] {cpcBid};

        adGroup.biddingStrategyConfiguration = biddingConfig;

        // Optional: Set targeting restrictions.
        // These settings only affect serving for the Display Network.
        TargetingSetting targetingSetting = new TargetingSetting();

        // Restricting to serve ads that match your ad group placements.
        // This is equivalent to choosing "Target and bid" in the UI.
        TargetingSettingDetail placementDetail = new TargetingSettingDetail();
        placementDetail.criterionTypeGroup = CriterionTypeGroup.PLACEMENT;
        placementDetail.targetAll = false;

        // Using your ad group verticals only for bidding. This is equivalent
        // to choosing "Bid only" in the UI.
        TargetingSettingDetail verticalDetail = new TargetingSettingDetail();
        verticalDetail.criterionTypeGroup = CriterionTypeGroup.VERTICAL;
        verticalDetail.targetAll = true;

        targetingSetting.details = new TargetingSettingDetail[] {placementDetail, verticalDetail};

        adGroup.settings = new Setting[] {targetingSetting};

        // Create the operation.
        AdGroupOperation operation = new AdGroupOperation();
        operation.@operator = Operator.ADD;
        operation.operand = adGroup;

        operations.Add(operation);
      }

      try {
        // Create the ad group.
        AdGroupReturnValue retVal = adGroupService.mutate(operations.ToArray());

        // Display the results.
        if (retVal != null && retVal.value != null && retVal.value.Length > 0) {
          foreach (AdGroup newAdGroup in retVal.value) {
            Console.WriteLine("Ad group with id = '{0}' and name = '{1}' was created.",
                newAdGroup.id, newAdGroup.name);
          }
        } else {
          Console.WriteLine("No ad groups were created.");
        }
      } catch (Exception ex) {
        throw new System.ApplicationException("Failed to create ad groups.", ex);
      }
    }
      /// <summary>
      /// Creates the unit.
      /// </summary>
      /// <param name="parent">The node that should be this node's parent.
      /// </param>
      /// <param name="value">The value being paritioned on.</param>
      /// <param name="bidAmount">The amount to bid for matching products,
      /// in micros.</param>
      /// <param name="isNegative">True, if this is negative criterion, false
      /// otherwise.</param>
      /// <returns>A new unit node.</returns>
      public ProductPartition CreateUnit(ProductPartition parent, ProductDimension value,
          long bidAmount, bool isNegative) {
        ProductPartition unit = new ProductPartition();
        unit.partitionType = ProductPartitionType.UNIT;

        // The root node has neither a parent nor a value.
        if (parent != null) {
          unit.parentCriterionId = parent.id;
          unit.caseValue = value;
        }

        AdGroupCriterion criterion;

        if (isNegative) {
          criterion = new NegativeAdGroupCriterion();
        } else {
          BiddingStrategyConfiguration biddingStrategyConfiguration =
              new BiddingStrategyConfiguration();

          CpcBid cpcBid = new CpcBid();
          cpcBid.bid = new Money();
          cpcBid.bid.microAmount = bidAmount;
          biddingStrategyConfiguration.bids = new Bids[] { cpcBid };

          criterion = new BiddableAdGroupCriterion();
          (criterion as BiddableAdGroupCriterion).biddingStrategyConfiguration =
              biddingStrategyConfiguration;
        }

        criterion.adGroupId = this.adGroupId;
        criterion.criterion = unit;

        this.CreateAddOperation(criterion);

        return unit;
      }