/// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group to which keywords are added.
    /// </param>
    public void Run(AdWordsUser user, long adGroupId) {
      // Get the AdGroupCriterionService.
      AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(
              AdWordsService.v201502.AdGroupCriterionService);

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

      foreach (string keywordText in KEYWORDS) {
        // Create the keyword.
        Keyword keyword = new Keyword();
        keyword.text = keywordText;
        keyword.matchType = KeywordMatchType.BROAD;

        // Create the biddable ad group criterion.
        BiddableAdGroupCriterion keywordCriterion = new BiddableAdGroupCriterion();
        keywordCriterion.adGroupId = adGroupId;
        keywordCriterion.criterion = keyword;

        // Optional: Set the user status.
        keywordCriterion.userStatus = UserStatus.PAUSED;

        // Optional: Set the keyword destination url.
        keywordCriterion.finalUrls = new UrlList() {
          urls = new string[] { "http://example.com/mars/cruise/?kw=" +
              HttpUtility.UrlEncode(keywordText) }
        };

        // Create the operations.
        AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
        operation.@operator = Operator.ADD;
        operation.operand = keywordCriterion;

        operations.Add(operation);
      }
      try {
        // Create the keywords.
        AdGroupCriterionReturnValue retVal = adGroupCriterionService.mutate(operations.ToArray());

        // Display the results.
        if (retVal != null && retVal.value != null) {
          foreach (AdGroupCriterion adGroupCriterion in retVal.value) {
            // If you are adding multiple type of criteria, then you may need to
            // check for
            //
            // if (adGroupCriterion is Keyword) { ... }
            //
            // to identify the criterion type.
            Console.WriteLine("Keyword with ad group id = '{0}', keyword id = '{1}', text = " +
                "'{2}' and match type = '{3}' was created.", adGroupCriterion.adGroupId,
                adGroupCriterion.criterion.id, (adGroupCriterion.criterion as Keyword).text,
                (adGroupCriterion.criterion as Keyword).matchType);
          }
        } else {
          Console.WriteLine("No keywords were added.");
        }
      } catch (Exception ex) {
        throw new System.ApplicationException("Failed to create keywords.", ex);
      }
    }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">Id of the ad group to which criteria are
        /// added.</param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            // Get the AdGroupCriterionService.
              AdGroupCriterionService adGroupCriterionService =
              (AdGroupCriterionService) user.GetService(AdWordsService.v201502.AdGroupCriterionService);

              // Create biddable ad group criterion for gender
              Gender genderTarget = new Gender();
              // Criterion Id for male. The IDs can be found here
              // https://developers.google.com/adwords/api/docs/appendix/genders
              genderTarget.id = 10;

              BiddableAdGroupCriterion genderBiddableAdGroupCriterion = new BiddableAdGroupCriterion();
              genderBiddableAdGroupCriterion.adGroupId = adGroupId;
              genderBiddableAdGroupCriterion.criterion = genderTarget;

              // Create negative ad group criterion for age range
              AgeRange ageRangeNegative = new AgeRange();
              // Criterion Id for age 18 to 24. The IDs can be found here
              // https://developers.google.com/adwords/api/docs/appendix/ages

              ageRangeNegative.id = 503001;
              NegativeAdGroupCriterion ageRangeNegativeAdGroupCriterion = new NegativeAdGroupCriterion();
              ageRangeNegativeAdGroupCriterion.adGroupId = adGroupId;
              ageRangeNegativeAdGroupCriterion.criterion = ageRangeNegative;

              // Create operations.
              AdGroupCriterionOperation genderBiddableAdGroupCriterionOperation =
              new AdGroupCriterionOperation();
              genderBiddableAdGroupCriterionOperation.operand = genderBiddableAdGroupCriterion;
              genderBiddableAdGroupCriterionOperation.@operator = Operator.ADD;

              AdGroupCriterionOperation ageRangeNegativeAdGroupCriterionOperation =
              new AdGroupCriterionOperation();
              ageRangeNegativeAdGroupCriterionOperation.operand = ageRangeNegativeAdGroupCriterion;
              ageRangeNegativeAdGroupCriterionOperation.@operator = Operator.ADD;

              AdGroupCriterionOperation[] operations = new AdGroupCriterionOperation[] {
              genderBiddableAdGroupCriterionOperation, ageRangeNegativeAdGroupCriterionOperation};

              try {
            // Add ad group criteria.
            AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(operations);

            // Display ad group criteria.
            if (result != null && result.value != null) {
              foreach (AdGroupCriterion adGroupCriterionResult in result.value) {
            Console.WriteLine("Ad group criterion with ad group id \"{0}\", criterion id " +
                "\"{1}\", and type \"{2}\" was added.", adGroupCriterionResult.adGroupId,
                adGroupCriterionResult.criterion.id,
                adGroupCriterionResult.criterion.CriterionType);
              }
            } else {
              Console.WriteLine("No ad group criteria were added.");
            }
              } catch (Exception e) {
            throw new System.ApplicationException("Failed to create ad group criteria.", e);
              }
        }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="adGroupId">Id of the ad group to which placements are added.
        /// </param>
        public void Run(AdWordsUser user, long adGroupId)
        {
            // Get the AdGroupCriterionService.
              AdGroupCriterionService adGroupCriterionService =
              (AdGroupCriterionService) user.GetService(AdWordsService.v201502.AdGroupCriterionService);

              // Create the placement.
              Placement placement1 = new Placement();
              placement1.url = "http://mars.google.com";

              // Create biddable ad group criterion.
              AdGroupCriterion placementCriterion1 = new BiddableAdGroupCriterion();
              placementCriterion1.adGroupId = adGroupId;
              placementCriterion1.criterion = placement1;

              // Create the placement.
              Placement placement2 = new Placement();
              placement2.url = "http://venus.google.com";

              // Create biddable ad group criterion.
              AdGroupCriterion placementCriterion2 = new BiddableAdGroupCriterion();
              placementCriterion2.adGroupId = adGroupId;
              placementCriterion2.criterion = placement2;

              // Create the operations.
              AdGroupCriterionOperation placementOperation1 = new AdGroupCriterionOperation();
              placementOperation1.@operator = Operator.ADD;
              placementOperation1.operand = placementCriterion1;

              AdGroupCriterionOperation placementOperation2 = new AdGroupCriterionOperation();
              placementOperation2.@operator = Operator.ADD;
              placementOperation2.operand = placementCriterion2;

              try {
            // Create the placements.
            AdGroupCriterionReturnValue retVal = adGroupCriterionService.mutate(
            new AdGroupCriterionOperation[] {placementOperation1, placementOperation2});

            // Display the results.
            if (retVal != null && retVal.value != null) {
              foreach (AdGroupCriterion adGroupCriterion in retVal.value) {
            // If you are adding multiple type of criteria, then you may need to
            // check for
            //
            // if (adGroupCriterion is Placement) { ... }
            //
            // to identify the criterion type.
            Console.WriteLine("Placement with ad group id = '{0}, placement id = '{1}, url = " +
                "'{2}' was created.", adGroupCriterion.adGroupId,
                adGroupCriterion.criterion.id, (adGroupCriterion.criterion as Placement).url);
              }
            } else {
              Console.WriteLine("No placements were added.");
            }
              } catch (Exception e) {
            throw new System.ApplicationException("Failed to create placements.", e);
              }
        }
    /// <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.v201502.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>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group that contains the placement.
    /// </param>
    /// <param name="placementId">Id of the placement to be removed.</param>
    public void Run(AdWordsUser user, long adGroupId, long placementId) {
      // Get the AdGroupCriterionService.
      AdGroupCriterionService adGroupCriterionService = (AdGroupCriterionService)user.GetService(
          AdWordsService.v201502.AdGroupCriterionService);

      // Create base class criterion to avoid setting placement-specific fields.
      Criterion criterion = new Criterion();
      criterion.id = placementId;

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

      // Create the operation.
      AdGroupCriterionOperation operation = new AdGroupCriterionOperation();
      operation.operand = adGroupCriterion;
      operation.@operator = Operator.REMOVE;

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

        // Display the results.
        if (retVal != null && retVal.value != null && retVal.value.Length > 0) {
          AdGroupCriterion removedPlacement = retVal.value[0];
          Console.WriteLine("Placement with ad group id = \"{0}\" and id = \"{1}\" was removed.",
              removedPlacement.adGroupId, removedPlacement.criterion.id);
        } else {
          Console.WriteLine("No placement was removed.");
        }
      } catch (Exception ex) {
        throw new System.ApplicationException("Failed to remove placement.", ex);
      }
    }
            /// <summary>
            /// Main method for the thread.
            /// </summary>
            /// <param name="obj">The thread parameter.</param>
            public void Run(Object obj)
            {
                // Create the operations.
                List<AdGroupCriterionOperation> operations = new List<AdGroupCriterionOperation>();

                for (int j = 0; j < NUM_KEYWORDS; j++) {
                  // Create the keyword.
                  Keyword keyword = new Keyword();
                  keyword.text = "mars cruise thread " + threadIndex.ToString() + " seed " + j.ToString();
                  keyword.matchType = KeywordMatchType.BROAD;

                  // Create the biddable ad group criterion.
                  AdGroupCriterion keywordCriterion = new BiddableAdGroupCriterion();
                  keywordCriterion.adGroupId = adGroupId;
                  keywordCriterion.criterion = keyword;

                  // Create the operations.
                  AdGroupCriterionOperation keywordOperation = new AdGroupCriterionOperation();
                  keywordOperation.@operator = Operator.ADD;
                  keywordOperation.operand = keywordCriterion;

                  operations.Add(keywordOperation);
                }

                // Get the AdGroupCriterionService. This should be done within the
                // thread, since a service can only handle one outgoing HTTP request
                // at a time.
                AdGroupCriterionService service = (AdGroupCriterionService) user.GetService(
                AdWordsService.v201502.AdGroupCriterionService);
                service.RequestHeader.validateOnly = true;
                int retryCount = 0;
                const int NUM_RETRIES = 3;
                try {
                  while (retryCount < NUM_RETRIES) {
                try {
                  // Validate the keywords.
                  AdGroupCriterionReturnValue retval = service.mutate(operations.ToArray());
                  break;
                } catch (AdWordsApiException e) {
                  // Handle API errors.
                  ApiException innerException = e.ApiException as ApiException;
                  if (innerException == null) {
                throw new Exception("Failed to retrieve ApiError. See inner exception for more " +
                    "details.", e);
                  }
                  foreach (ApiError apiError in innerException.errors) {
                if (!(apiError is RateExceededError)) {
                  // Rethrow any errors other than RateExceededError.
                  throw;
                }
                // Handle rate exceeded errors.
                RateExceededError rateExceededError = (RateExceededError) apiError;
                Console.WriteLine("Got Rate exceeded error - rate name = '{0}', scope = '{1}', " +
                    "retry After {2} seconds.", rateExceededError.rateScope,
                    rateExceededError.rateName, rateExceededError.retryAfterSeconds);
                Thread.Sleep(rateExceededError.retryAfterSeconds * 1000);
                retryCount = retryCount + 1;
                  }
                } finally {
                  if (retryCount == NUM_RETRIES) {
                throw new Exception(String.Format("Could not recover after making {0} attempts.",
                    retryCount));
                  }
                }
                  }
                } catch (Exception e) {
                  throw new System.ApplicationException("Failed to validate keywords.", e);
                }
            }
    /// <summary>
    /// Creates the placement.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">The adgroup id for which the placement is
    /// created.</param>
    /// <returns>The placement id.</returns>
    public long CreatePlacement(AdWordsUser user, long adGroupId) {
      AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(AdWordsService.v201502.AdGroupCriterionService);

      Placement placement = new Placement();
      placement.url = "http://mars.google.com";

      AdGroupCriterion placementCriterion = new BiddableAdGroupCriterion();
      placementCriterion.adGroupId = adGroupId;
      placementCriterion.criterion = placement;

      AdGroupCriterionOperation placementOperation = new AdGroupCriterionOperation();
      placementOperation.@operator = Operator.ADD;
      placementOperation.operand = placementCriterion;

      AdGroupCriterionReturnValue retVal = adGroupCriterionService.mutate(
          new AdGroupCriterionOperation[] {placementOperation});

      return retVal.value[0].criterion.id;
    }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad groups to which keywords are
    /// added.</param>
    public void Run(AdWordsUser user, long adGroupId) {
      // Get the MutateJobService.
      MutateJobService mutateJobService = (MutateJobService) user.GetService(
          AdWordsService.v201502.MutateJobService);

      const int RETRY_INTERVAL = 30;
      const int RETRIES_COUNT = 30;
      const int KEYWORD_NUMBER = 100;
      const string INDEX_REGEX = "operations\\[(\\d+)\\].operand";

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

      // Create AdGroupCriterionOperation to add keywords.
      for (int i = 0; i < KEYWORD_NUMBER; i++) {
        Keyword keyword = new Keyword();
        keyword.text = string.Format("mars cruise {0}", i);
        keyword.matchType = KeywordMatchType.BROAD;

        BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
        criterion.adGroupId = adGroupId;
        criterion.criterion = keyword;

        AdGroupCriterionOperation adGroupCriterionOperation = new AdGroupCriterionOperation();
        adGroupCriterionOperation.@operator = Operator.ADD;
        adGroupCriterionOperation.operand = criterion;

        operations.Add(adGroupCriterionOperation);
      }

      BulkMutateJobPolicy policy = new BulkMutateJobPolicy();
      // You can specify up to 3 job IDs that must successfully complete before
      // this job can be processed.
      policy.prerequisiteJobIds = new long[] {};

      SimpleMutateJob job = mutateJobService.mutate(operations.ToArray(), policy);

      // Wait for the job to complete.
      bool completed = false;
      int retryCount = 0;
      Console.WriteLine("Retrieving job status...");

      while (completed == false && retryCount < RETRIES_COUNT) {
        BulkMutateJobSelector selector = new BulkMutateJobSelector();
        selector.jobIds = new long[] {job.id};

        try {
          Job[] allJobs = mutateJobService.get(selector);
          if (allJobs != null && allJobs.Length > 0) {
            job = (SimpleMutateJob) allJobs[0];
            if (job.status == BasicJobStatus.COMPLETED || job.status == BasicJobStatus.FAILED) {
              completed = true;
              break;
            } else {
              Console.WriteLine("{0}: Current status is {1}, waiting {2} seconds to retry...",
                  retryCount, job.status, RETRY_INTERVAL);
              Thread.Sleep(RETRY_INTERVAL * 1000);
              retryCount++;
            }
          }
        } catch (Exception ex) {
          throw new System.ApplicationException("Failed to fetch simple mutate job with " +
              "id = {0}.", ex);
        }
      }

      if (job.status == BasicJobStatus.COMPLETED) {
        // Handle cases where the job completed.

        // Create the job selector.
        BulkMutateJobSelector selector = new BulkMutateJobSelector();
        selector.jobIds = new long[] {job.id};

        // Get the job results.
        JobResult jobResult = mutateJobService.getResult(selector);
        if (jobResult != null) {
          SimpleMutateResult results = (SimpleMutateResult) jobResult.Item;
          if (results != null) {
            // Display the results.
            if (results.results != null) {
              for (int i = 0; i < results.results.Length; i++) {
                Operand operand = results.results[i];
                Console.WriteLine("Operation {0} - {1}", i, (operand.Item is PlaceHolder) ?
                    "FAILED" : "SUCCEEDED");
              }
            }

            // Display the errors.
            if (results.errors != null) {
              foreach (ApiError apiError in results.errors) {
                Match match = Regex.Match(apiError.fieldPath, INDEX_REGEX, RegexOptions.IgnoreCase);
                string index = (match.Success)? match.Groups[1].Value : "???";
                Console.WriteLine("Operation index {0} failed due to reason: '{1}', " +
                    "trigger: '{2}'", index, apiError.errorString, apiError.trigger);
              }
            }
          }
        }
        Console.WriteLine("Job completed successfully!");
      } else if (job.status == BasicJobStatus.FAILED) {
        // Handle the cases where job failed.
        Console.WriteLine("Job failed with reason: " + job.failureReason);
      } else if (job.status == BasicJobStatus.PROCESSING || job.status == BasicJobStatus.PENDING) {
        // Handle the cases where job didn't complete after wait period.
        Console.WriteLine("Job did not complete in {0} secconds.", RETRY_INTERVAL * RETRIES_COUNT);
      }
    }
        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="campaignId">Id of the campaign to which experiments are
        /// added.</param>
        /// <param name="adGroupId">Id of the ad group to which experiments are
        /// added.</param>
        /// <param name="criterionId">Id of the criterion for which experiments
        /// are added.</param>
        public void Run(AdWordsUser user, long campaignId, long adGroupId, long criterionId)
        {
            // Get the ExperimentService.
              ExperimentService experimentService =
              (ExperimentService) user.GetService(AdWordsService.v201502.ExperimentService);

              // Get the AdGroupService.
              AdGroupService adGroupService =
              (AdGroupService) user.GetService(AdWordsService.v201502.AdGroupService);

              // Get the AdGroupCriterionService.
              AdGroupCriterionService adGroupCriterionService =
              (AdGroupCriterionService) user.GetService(AdWordsService.v201502.AdGroupCriterionService);

              // Create the experiment.
              Experiment experiment = new Experiment();
              experiment.campaignId = campaignId;
              experiment.name = "Interplanetary Cruise #" + ExampleUtilities.GetRandomString();
              experiment.queryPercentage = 10;
              experiment.startDateTime = DateTime.Now.AddDays(1).ToString("yyyyMMdd HHmmss");

              // Optional: Set the end date.
              experiment.endDateTime = DateTime.Now.AddDays(30).ToString("yyyyMMdd HHmmss");

              // Optional: Set the status.
              experiment.status = ExperimentStatus.ENABLED;

              // Create the operation.
              ExperimentOperation experimentOperation = new ExperimentOperation();
              experimentOperation.@operator = Operator.ADD;
              experimentOperation.operand = experiment;

              try {
            // Add the experiment.
            ExperimentReturnValue experimentRetVal = experimentService.mutate(
            new ExperimentOperation[] {experimentOperation});

            // Display the results.
            if (experimentRetVal != null && experimentRetVal.value != null && experimentRetVal.value.
            Length > 0) {
              long experimentId = 0;

              Experiment newExperiment = experimentRetVal.value[0];

              Console.WriteLine("Experiment with name = \"{0}\" and id = \"{1}\" was added.\n",
              newExperiment.name, newExperiment.id);
              experimentId = newExperiment.id;

              // Set ad group for the experiment.
              AdGroup adGroup = new AdGroup();
              adGroup.id = adGroupId;

              // Create experiment bid multiplier rule that will modify ad group bid
              // for the experiment.
              ManualCPCAdGroupExperimentBidMultipliers adGroupBidMultiplier =
              new ManualCPCAdGroupExperimentBidMultipliers();
              adGroupBidMultiplier.maxCpcMultiplier = new BidMultiplier();
              adGroupBidMultiplier.maxCpcMultiplier.multiplier = 1.5;

              // Set experiment data to the ad group.
              AdGroupExperimentData adGroupExperimentData = new AdGroupExperimentData();
              adGroupExperimentData.experimentId = experimentId;
              adGroupExperimentData.experimentDeltaStatus = ExperimentDeltaStatus.MODIFIED;
              adGroupExperimentData.experimentBidMultipliers = adGroupBidMultiplier;

              adGroup.experimentData = adGroupExperimentData;

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

              // Update the ad group.
              AdGroupReturnValue adGroupRetVal = adGroupService.mutate(new AdGroupOperation[] {
              adGroupOperation});

              // Display the results.
              if (adGroupRetVal != null && adGroupRetVal.value != null &&
              adGroupRetVal.value.Length > 0) {
            AdGroup updatedAdGroup = adGroupRetVal.value[0];
            Console.WriteLine("Ad group with name = \"{0}\", id = \"{1}\" and status = \"{2}\" " +
                "was updated for the experiment.\n", updatedAdGroup.name, updatedAdGroup.id,
                updatedAdGroup.status);
              } else {
            Console.WriteLine("No ad groups were updated.");
              }

              // Set ad group criteria for the experiment.
              Criterion criterion = new Criterion();
              criterion.id = criterionId;

              BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion();
              adGroupCriterion.adGroupId = adGroupId;
              adGroupCriterion.criterion = criterion;

              // Create experiment bid multiplier rule that will modify criterion bid
              // for the experiment.
              ManualCPCAdGroupCriterionExperimentBidMultiplier bidMultiplier =
              new ManualCPCAdGroupCriterionExperimentBidMultiplier();
              bidMultiplier.maxCpcMultiplier = new BidMultiplier();
              bidMultiplier.maxCpcMultiplier.multiplier = 1.5;

              // Set experiment data to the criterion.
              BiddableAdGroupCriterionExperimentData adGroupCriterionExperimentData =
              new BiddableAdGroupCriterionExperimentData();
              adGroupCriterionExperimentData.experimentId = experimentId;
              adGroupCriterionExperimentData.experimentDeltaStatus = ExperimentDeltaStatus.MODIFIED;
              adGroupCriterionExperimentData.experimentBidMultiplier = bidMultiplier;

              adGroupCriterion.experimentData = adGroupCriterionExperimentData;

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

              // Update the ad group criteria.
              AdGroupCriterionReturnValue adGroupCriterionRetVal = adGroupCriterionService.mutate(
              new AdGroupCriterionOperation[] {adGroupCriterionOperation});

              // Display the results.
              if (adGroupCriterionRetVal != null && adGroupCriterionRetVal.value != null &&
              adGroupCriterionRetVal.value.Length > 0) {
            AdGroupCriterion updatedAdGroupCriterion = adGroupCriterionRetVal.value[0];
            Console.WriteLine("Ad group criterion with ad group id = \"{0}\", criterion id = "
                + "\"{1}\" and type = \"{2}\" was updated for the experiment.\n",
                updatedAdGroupCriterion.adGroupId, updatedAdGroupCriterion.criterion.id,
                updatedAdGroupCriterion.criterion.CriterionType);
              } else {
            Console.WriteLine("No ad group criteria were updated.");
              }
            } else {
              Console.WriteLine("No experiments were added.");
            }
              } catch (Exception e) {
            throw new System.ApplicationException("Failed to add experiment.", e);
              }
        }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group to which keywords are added.
    /// </param>
    public void Run(AdWordsUser user, long adGroupId) {
      // Get the AdGroupCriterionService.
      AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(AdWordsService.v201502.AdGroupCriterionService);

      // Set partial failure mode for the service.
      adGroupCriterionService.RequestHeader.partialFailure = true;

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

      // Create the keywords.
      string[] keywords = new String[] {"mars cruise", "inv@lid cruise", "venus cruise",
          "b(a)d keyword cruise"};

      foreach (String keywordText in keywords) {
        Keyword keyword = new Keyword();
        keyword.text = keywordText;
        keyword.matchType = KeywordMatchType.BROAD;

        // Create biddable ad group criterion.
        BiddableAdGroupCriterion keywordBiddableAdGroupCriterion = new BiddableAdGroupCriterion();
        keywordBiddableAdGroupCriterion.adGroupId = adGroupId;
        keywordBiddableAdGroupCriterion.criterion = keyword;

        // Create the operation.
        AdGroupCriterionOperation keywordAdGroupCriterionOperation =
            new AdGroupCriterionOperation();
        keywordAdGroupCriterionOperation.operand = keywordBiddableAdGroupCriterion;
        keywordAdGroupCriterionOperation.@operator = Operator.ADD;
        operations.Add(keywordAdGroupCriterionOperation);
      }

      try {
        // Create the keywords.
        AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(operations.ToArray());

        // Display the results.
        if (result != null && result.value != null) {
          foreach (AdGroupCriterion adGroupCriterionResult in result.value) {
            if (adGroupCriterionResult.criterion != null) {
              Console.WriteLine("Keyword with ad group id '{0}', criterion id '{1}', and " +
                  "text '{2}' was added.\n", adGroupCriterionResult.adGroupId,
                  adGroupCriterionResult.criterion.id,
                  ((Keyword) adGroupCriterionResult.criterion).text);
            }
          }
        } else {
          Console.WriteLine("No keywords were added.");
        }

        // Display the partial failure errors.
        if (result != null && result.partialFailureErrors != null) {
          foreach (ApiError apiError in result.partialFailureErrors) {
            int operationIndex = ErrorUtilities.GetOperationIndex(apiError.fieldPath);
            if (operationIndex != -1) {
              AdGroupCriterion adGroupCriterion = operations[operationIndex].operand;
              Console.WriteLine("Keyword with ad group id '{0}' and text '{1}' "
                  + "triggered a failure for the following reason: '{2}'.\n",
                  adGroupCriterion.adGroupId, ((Keyword) adGroupCriterion.criterion).text,
                  apiError.errorString);
            } else {
              Console.WriteLine("A failure for the following reason: '{0}' has occurred.\n",
                  apiError.errorString);
            }
          }
        }
      } catch (Exception ex) {
        throw new System.ApplicationException("Failed to add keywords in partial failure mode.",
            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;
            }
            /// <summary>
            /// Creates a subdivision node.
            /// </summary>
            /// <param name="parent">The node that should be this node's parent.
            /// </param>
            /// <param name="value">The value being paritioned on.</param>
            /// <returns>A new subdivision node.</returns>
            public ProductPartition CreateSubdivision(ProductPartition parent, ProductDimension value)
            {
                ProductPartition division = new ProductPartition();
                division.partitionType = ProductPartitionType.SUBDIVISION;
                division.id = this.nextId--;

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

                BiddableAdGroupCriterion criterion = new BiddableAdGroupCriterion();
                criterion.adGroupId = this.adGroupId;
                criterion.criterion = division;

                this.CreateAddOperation(criterion);
                return division;
            }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad group to which keywords are added.
    /// </param>
    public void Run(AdWordsUser user, long adGroupId) {
      // Get the AdGroupCriterionService.
      AdGroupCriterionService adGroupCriterionService =
          (AdGroupCriterionService) user.GetService(AdWordsService.v201502.AdGroupCriterionService);

      // Set partial failure mode for the service.
      adGroupCriterionService.RequestHeader.partialFailure = true;

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

      // Create the placements.
      string[] urls = new String[] {"http://mars.google.com", "http:/mars.google.com",
          "mars.google.com"};

      foreach (String url in urls) {
        Placement placement = new Placement();
        placement.url = url;

        // Create biddable ad group criterion.
        BiddableAdGroupCriterion placementBiddableAdGroupCriterion = new BiddableAdGroupCriterion();
        placementBiddableAdGroupCriterion.adGroupId = adGroupId;
        placementBiddableAdGroupCriterion.criterion = placement;

        // Create the operation.
        AdGroupCriterionOperation placementAdGroupCriterionOperation =
            new AdGroupCriterionOperation();
        placementAdGroupCriterionOperation.operand = placementBiddableAdGroupCriterion;
        placementAdGroupCriterionOperation.@operator = Operator.ADD;
        operations.Add(placementAdGroupCriterionOperation);
      }

      try {
        // Create the placements.
        AdGroupCriterionReturnValue result = adGroupCriterionService.mutate(operations.ToArray());

        // Display the results.
        if (result != null && result.value != null) {
          foreach (AdGroupCriterion adGroupCriterionResult in result.value) {
            if (adGroupCriterionResult.criterion != null) {
              Console.WriteLine("Placement with ad group id '{0}', and criterion " +
                  "id '{1}', and url '{2}' was added.\n", adGroupCriterionResult.adGroupId,
                  adGroupCriterionResult.criterion.id,
                  ((Placement) adGroupCriterionResult.criterion).url);
            }
          }
        } else {
          Console.WriteLine("No placements were added.");
        }

        // Display the partial failure errors.
        if (result != null && result.partialFailureErrors != null) {
          foreach (ApiError apiError in result.partialFailureErrors) {
            int operationIndex = ErrorUtilities.GetOperationIndex(apiError.fieldPath);
            if (operationIndex != -1) {
              AdGroupCriterion adGroupCriterion = operations[operationIndex].operand;
              Console.WriteLine("Placement with ad group id '{0}' and url '{1}' "
                  + "triggered a failure for the following reason: '{2}'.\n",
                  adGroupCriterion.adGroupId, ((Placement) adGroupCriterion.criterion).url,
                  apiError.errorString);
            } else {
              Console.WriteLine("A failure for the following reason: '{0}' has occurred.\n",
                  apiError.errorString);
            }
          }
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to add placements in partial failure mode.",
            e);
      }
    }