/// <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.v201601.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 e) {
                    throw new System.ApplicationException("Failed to fetch simple mutate job with " +
                                                          "id = {0}.", e);
                }
            }

            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="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.v201509.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 e) {
          throw new System.ApplicationException("Failed to fetch simple mutate job with " +
              "id = {0}.", e);
        }
      }

      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);
      }
    }