/// <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.v201409.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);
      }
    }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="campaignId">Id of the campaign to which targeting criteria
    /// are added.</param>
    public void Run(AdWordsUser user, long campaignId) {
      // Get the CampaignCriterionService.
      CampaignCriterionService campaignCriterionService =
          (CampaignCriterionService) user.GetService(
              AdWordsService.v201409.CampaignCriterionService);

      // Create language criteria.
      // See http://code.google.com/apis/adwords/docs/appendix/languagecodes.html
      // for a detailed list of language codes.
      Language language1 = new Language();
      language1.id = 1002; // French
      CampaignCriterion languageCriterion1 = new CampaignCriterion();
      languageCriterion1.campaignId = campaignId;
      languageCriterion1.criterion = language1;

      Language language2 = new Language();
      language2.id = 1005; // Japanese
      CampaignCriterion languageCriterion2 = new CampaignCriterion();
      languageCriterion2.campaignId = campaignId;
      languageCriterion2.criterion = language2;

      // Create location criteria.
      // See http://code.google.com/apis/adwords/docs/appendix/countrycodes.html
      // for a detailed list of country codes.
      Location location1 = new Location();
      location1.id = 2840; // USA
      CampaignCriterion locationCriterion1 = new CampaignCriterion();
      locationCriterion1.campaignId = campaignId;
      locationCriterion1.criterion = location1;

      Location location2 = new Location();
      location2.id = 2392; // Japan
      CampaignCriterion locationCriterion2 = new CampaignCriterion();
      locationCriterion2.campaignId = campaignId;
      locationCriterion2.criterion = location2;

      // Add a negative campaign placement.
      NegativeCampaignCriterion negativeCriterion = new NegativeCampaignCriterion();
      negativeCriterion.campaignId = campaignId;

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

      negativeCriterion.criterion = placement;

      CampaignCriterion[] criteria = new CampaignCriterion[] {languageCriterion1,
          languageCriterion2, locationCriterion1, locationCriterion2, negativeCriterion};

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

      foreach (CampaignCriterion criterion in criteria) {
        CampaignCriterionOperation operation = new CampaignCriterionOperation();
        operation.@operator = Operator.ADD;
        operation.operand = criterion;
        operations.Add(operation);
      }

      try {
        // Set the campaign targets.
        CampaignCriterionReturnValue retVal = campaignCriterionService.mutate(operations.ToArray());

        if (retVal != null && retVal.value != null) {
          // Display campaign targets.
          foreach (CampaignCriterion criterion in retVal.value) {
            Console.WriteLine("Campaign criteria of type '{0}' was set to campaign with" +
                " id = '{1}'.", criterion.criterion.CriterionType, criterion.campaignId);
          }
        }
      } catch (Exception ex) {
        throw new System.ApplicationException("Failed to set Campaign criteria.", ex);
      }
    }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="adGroupId">Id of the ad groups to which placements are
    /// added.</param>
    public void Run(AdWordsUser user, long adGroupId) {
      // Get the MutateJobService.
      MutateJobService mutateJobService = (MutateJobService) user.GetService(
          AdWordsService.v201409.MutateJobService);

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

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

      // Create AdGroupCriterionOperation to add placements.
      for (int i = 0; i < PLACEMENT_NUMBER; i++) {
        Placement placement = new Placement();
        placement.url = "http://mars.google.com/" + i.ToString();

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

        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(string.Format("Failed to fetch simple mutate " +
              "job with id = {0}.", job.id), 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>
    /// 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.v201409.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;
    }