/// <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.v201506.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 e) {
        throw new System.ApplicationException("Failed to set Campaign criteria.", e);
      }
    }
 /// <summary>
 /// Gets a string representation for a location.
 /// </summary>
 /// <param name="location">The location</param>
 /// <returns>The string representation</returns>
 public string GetLocationString(Location location) {
   return string.Format("{0} ({1})", location.locationName, location.displayType);
 }
    /// <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>
    /// <param name="feedId">ID of a feed that has been configured for location
    /// targeting, meaning it has an ENABLED FeedMapping with criterionType of
    /// 77. Feeds linked to a GMB account automatically have this FeedMapping.
    /// If you don't have such a feed, set this value to null.</param>
    public void Run(AdWordsUser user, long campaignId, long? feedId) {
      // Get the CampaignCriterionService.
      CampaignCriterionService campaignCriterionService =
          (CampaignCriterionService) user.GetService(
              AdWordsService.v201506.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;

      // Target Tier 3 income group near Miami, Florida.
      LocationGroups incomeLocationGroups = new LocationGroups();

      IncomeOperand incomeOperand = new IncomeOperand();
      // Tiers are numbered 1-10, and represent 10% segments of earners.
      // For example, TIER_1 is the top 10%, TIER_2 is the 80-90%, etc.
      // Tiers 6 through 10 are grouped into TIER_6_TO_10.
      incomeOperand.tier = IncomeTier.TIER_3;

      GeoTargetOperand geoTargetOperand1 = new GeoTargetOperand();
      geoTargetOperand1.locations = new long[] { 1015116 }; // Miami, FL.

      incomeLocationGroups.matchingFunction = new Function();
      incomeLocationGroups.matchingFunction.lhsOperand =
          new FunctionArgumentOperand[] { incomeOperand };
      incomeLocationGroups.matchingFunction.@operator = FunctionOperator.AND;
      incomeLocationGroups.matchingFunction.rhsOperand =
          new FunctionArgumentOperand[] { geoTargetOperand1 };

      CampaignCriterion locationGroupCriterion1 = new CampaignCriterion();
      locationGroupCriterion1.campaignId = campaignId;
      locationGroupCriterion1.criterion = incomeLocationGroups;

      // Target places of interest near Downtown Miami, Florida.
      LocationGroups interestLocationGroups = new LocationGroups();

      PlacesOfInterestOperand placesOfInterestOperand = new PlacesOfInterestOperand();
      placesOfInterestOperand.category = PlacesOfInterestOperandCategory.DOWNTOWN;

      GeoTargetOperand geoTargetOperand2 = new GeoTargetOperand();
      geoTargetOperand2.locations = new long[] { 1015116 }; // Miami, FL.

      interestLocationGroups.matchingFunction = new Function();
      interestLocationGroups.matchingFunction.lhsOperand =
          new FunctionArgumentOperand[] { placesOfInterestOperand };
      interestLocationGroups.matchingFunction.@operator = FunctionOperator.AND;
      interestLocationGroups.matchingFunction.rhsOperand =
          new FunctionArgumentOperand[] { geoTargetOperand2 };

      CampaignCriterion locationGroupCriterion2 = new CampaignCriterion();
      locationGroupCriterion2.campaignId = campaignId;
      locationGroupCriterion2.criterion = interestLocationGroups;

      CampaignCriterion locationGroupCriterion3 = new CampaignCriterion();

      if (feedId.HasValue) {
        // Distance targeting. Area of 10 miles around targets above.
        ConstantOperand radius = new ConstantOperand();
        radius.type = ConstantOperandConstantType.DOUBLE;
        radius.unit = ConstantOperandUnit.MILES;
        radius.doubleValue = 10.0;
        LocationExtensionOperand distance = new LocationExtensionOperand();
        distance.radius = radius;

        LocationGroups radiusLocationGroups = new LocationGroups();
        radiusLocationGroups.matchingFunction = new Function();
        radiusLocationGroups.matchingFunction.@operator = FunctionOperator.IDENTITY;
        radiusLocationGroups.matchingFunction.lhsOperand =
            new FunctionArgumentOperand[] { distance };

        // FeedID should be the ID of a feed that has been configured for location
        // targeting, meaning it has an ENABLED FeedMapping with criterionType of
        // 77. Feeds linked to a GMB account automatically have this FeedMapping.
        radiusLocationGroups.feedId = feedId.Value;

        locationGroupCriterion3.campaignId = campaignId;
        locationGroupCriterion3.criterion = radiusLocationGroups;
      }

      // 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 keyword.
      NegativeCampaignCriterion negativeCriterion = new NegativeCampaignCriterion();
      negativeCriterion.campaignId = campaignId;

      Keyword keyword = new Keyword();
      keyword.matchType = KeywordMatchType.BROAD;
      keyword.text = "jupiter cruise";

      negativeCriterion.criterion = keyword;

      List<CampaignCriterion> criteria = new List<CampaignCriterion>(
          new CampaignCriterion[] {languageCriterion1,
          languageCriterion2, locationCriterion1, locationCriterion2, negativeCriterion,
          locationGroupCriterion1, locationGroupCriterion2});

      if (feedId.HasValue) {
        criteria.Add(locationGroupCriterion3);
      }

      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>
    public void Run(AdWordsUser user) {
      // Get the BudgetSuggestionService.
      BudgetSuggestionService budgetSuggestionService = (BudgetSuggestionService)
          user.GetService(AdWordsService.v201506.BudgetSuggestionService);

      BudgetSuggestionSelector selector = new BudgetSuggestionSelector();

      List<Criterion> criteria = new List<Criterion>();

      // Criterion - Travel Agency product/service. See GetProductServices.cs for an example
      // of how to get valid product/service settings.
      ProductService productService = new ProductService();
      productService.text = "Travel Agency";
      productService.locale = "en_US";
      criteria.Add(productService);

      // Criterion - English language.
      // The ID can be found in the documentation:
      // https://developers.google.com/adwords/api/docs/appendix/languagecodes
      Language language = new Language();
      language.id = 1000L;
      criteria.Add(language);

      // Criterion - Mountain View, California location.
      // The ID can be found in the documentation:
      // https://developers.google.com/adwords/api/docs/appendix/geotargeting
      // https://developers.google.com/adwords/api/docs/appendix/cities-DMAregions
      Location location = new Location();
      location.id = 1014044L;
      criteria.Add(location);

      selector.criteria = criteria.ToArray();

      try {
        BudgetSuggestion budgetSuggestion = budgetSuggestionService.get(selector);

        Console.WriteLine("Budget suggestion for criteria is:\n" +
            "  SuggestedBudget={0}\n" +
            "  Min/MaxBudget={1}/{2}\n" +
            "  Min/MaxCpc={3}/{4}\n" +
            "  CPM={5}\n" +
            "  CPC={6}\n" +
            "  Impressions={7}\n",
            budgetSuggestion.suggestedBudget.microAmount,
            budgetSuggestion.minBudget.microAmount, budgetSuggestion.maxBudget.microAmount,
            budgetSuggestion.minCpc.microAmount, budgetSuggestion.maxCpc.microAmount,
            budgetSuggestion.cpm.microAmount,
            budgetSuggestion.cpc.microAmount,
            budgetSuggestion.impressions);

        if (budgetSuggestion.budgetQuantiles != null
            && budgetSuggestion.budgetQuantiles.Length > 0) {
          int quantileCount = 0;
          Console.WriteLine("  Budget quantiles:");
          foreach (Money budgetQuantile in budgetSuggestion.budgetQuantiles) {
            Console.WriteLine("    {0}) {1}", ++quantileCount, budgetQuantile.microAmount);
          }
        } else {
          Console.WriteLine("  No budget quantiles found on budget suggestion");
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to get budget suggestion.", e);
      }
    }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    public void Run(AdWordsUser user) {
      // Get the TrafficEstimatorService.
      TrafficEstimatorService trafficEstimatorService = (TrafficEstimatorService) user.GetService(
          AdWordsService.v201506.TrafficEstimatorService);

      // Create keywords. Up to 2000 keywords can be passed in a single request.
      Keyword keyword1 = new Keyword();
      keyword1.text = "mars cruise";
      keyword1.matchType = KeywordMatchType.BROAD;

      Keyword keyword2 = new Keyword();
      keyword2.text = "cheap cruise";
      keyword2.matchType = KeywordMatchType.PHRASE;

      Keyword keyword3 = new Keyword();
      keyword3.text = "cruise";
      keyword3.matchType = KeywordMatchType.EXACT;

      Keyword[] keywords = new Keyword[] { keyword1, keyword2, keyword3 };

      // Create a keyword estimate request for each keyword.
      List<KeywordEstimateRequest> keywordEstimateRequests = new List<KeywordEstimateRequest>();

      foreach (Keyword keyword in keywords) {
        KeywordEstimateRequest keywordEstimateRequest = new KeywordEstimateRequest();
        keywordEstimateRequest.keyword = keyword;
        keywordEstimateRequests.Add(keywordEstimateRequest);
      }

      // Create negative keywords.
      Keyword negativeKeyword1 = new Keyword();
      negativeKeyword1.text = "moon walk";
      negativeKeyword1.matchType = KeywordMatchType.BROAD;

      KeywordEstimateRequest negativeKeywordEstimateRequest = new KeywordEstimateRequest();
      negativeKeywordEstimateRequest.keyword = negativeKeyword1;
      negativeKeywordEstimateRequest.isNegative = true;
      keywordEstimateRequests.Add(negativeKeywordEstimateRequest);

      // Create ad group estimate requests.
      AdGroupEstimateRequest adGroupEstimateRequest = new AdGroupEstimateRequest();
      adGroupEstimateRequest.keywordEstimateRequests = keywordEstimateRequests.ToArray();
      adGroupEstimateRequest.maxCpc = new Money();
      adGroupEstimateRequest.maxCpc.microAmount = 1000000;

      // Create campaign estimate requests.
      CampaignEstimateRequest campaignEstimateRequest = new CampaignEstimateRequest();
      campaignEstimateRequest.adGroupEstimateRequests = new AdGroupEstimateRequest[] {
          adGroupEstimateRequest};

      // See http://code.google.com/apis/adwords/docs/appendix/countrycodes.html
      // for a detailed list of country codes.
      Location countryCriterion = new Location();
      countryCriterion.id = 2840; //US

      // See http://code.google.com/apis/adwords/docs/appendix/languagecodes.html
      // for a detailed list of language codes.
      Language languageCriterion = new Language();
      languageCriterion.id = 1000; //en

      campaignEstimateRequest.criteria = new Criterion[] { countryCriterion, languageCriterion };

      // Create the selector.
      TrafficEstimatorSelector selector = new TrafficEstimatorSelector();
      selector.campaignEstimateRequests = new CampaignEstimateRequest[] { campaignEstimateRequest };

      try {
        // Get traffic estimates.
        TrafficEstimatorResult result = trafficEstimatorService.get(selector);

        // Display traffic estimates.
        if (result != null && result.campaignEstimates != null &&
            result.campaignEstimates.Length > 0) {
          CampaignEstimate campaignEstimate = result.campaignEstimates[0];
          if (campaignEstimate.adGroupEstimates != null &&
              campaignEstimate.adGroupEstimates.Length > 0) {
            AdGroupEstimate adGroupEstimate = campaignEstimate.adGroupEstimates[0];

            if (adGroupEstimate.keywordEstimates != null) {
              for (int i = 0; i < adGroupEstimate.keywordEstimates.Length; i++) {
                Keyword keyword = keywordEstimateRequests[i].keyword;
                KeywordEstimate keywordEstimate = adGroupEstimate.keywordEstimates[i];

                if (keywordEstimateRequests[i].isNegative) {
                  continue;
                }

                // Find the mean of the min and max values.
                long meanAverageCpc = 0;
                double meanAveragePosition = 0;
                float meanClicks = 0;
                long meanTotalCost = 0;

                if (keywordEstimate.min != null && keywordEstimate.max != null) {
                  if (keywordEstimate.min.averageCpc != null &&
                      keywordEstimate.max.averageCpc != null) {
                    meanAverageCpc = (keywordEstimate.min.averageCpc.microAmount +
                        keywordEstimate.max.averageCpc.microAmount) / 2;
                  }

                  meanAveragePosition = (keywordEstimate.min.averagePosition +
                      keywordEstimate.max.averagePosition) / 2;
                  meanClicks = (keywordEstimate.min.clicksPerDay +
                      keywordEstimate.max.clicksPerDay) / 2;
                  if (keywordEstimate.min.totalCost != null &&
                      keywordEstimate.max.totalCost != null) {
                    meanTotalCost = (keywordEstimate.min.totalCost.microAmount +
                        keywordEstimate.max.totalCost.microAmount) / 2;
                  }
                }

                Console.WriteLine("Results for the keyword with text = '{0}' and match type = " +
                     "'{1}':", keyword.text, keyword.matchType);
                Console.WriteLine("  Estimated average CPC: {0}", meanAverageCpc);
                Console.WriteLine("  Estimated ad position: {0:0.00}", meanAveragePosition);
                Console.WriteLine("  Estimated daily clicks: {0}", meanClicks);
                Console.WriteLine("  Estimated daily cost: {0}", meanTotalCost);
              }
            }
          }
        } else {
          Console.WriteLine("No traffic estimates were returned.\n");
        }
      } catch (Exception e) {
        throw new System.ApplicationException("Failed to retrieve traffic estimates.", e);
      }
    }