public static List<Promotion> runExample(
      AdWordsServices adWordsServices, AdWordsSession session, Long businessId) throws Exception {

    session.setExpressBusinessId(businessId);

    // Get the PromotionService
    PromotionServiceInterface promotionService =
        adWordsServices.get(session, PromotionServiceInterface.class);

    int offset = 0;

    Selector selector =
        new SelectorBuilder()
            .fields(
                "PromotionId",
                "Name",
                "Status",
                "DestinationUrl",
                "CallTrackingEnabled",
                "Budget",
                "PromotionCriteria",
                "RemainingBudget",
                "Creatives",
                "CampaignIds")
            .offset(offset)
            .limit(PAGE_SIZE)
            .build();

    List<Promotion> promotions = Lists.newArrayList();
    PromotionPage page;
    do {
      // Get all promotions for the business
      page = promotionService.get(selector);

      // Display promotions
      if (page.getTotalNumEntries() > 0) {
        for (Promotion promotion : page.getEntries()) {
          System.out.printf(
              "Express promotion found with ID %d and name '%s'%n",
              promotion.getId(), promotion.getName());
          promotions.add(promotion);
        }
      } else {
        System.out.println("No promotions were found.");
      }

      offset += PAGE_SIZE;
      selector.getPaging().setStartIndex(offset);
    } while (offset < page.getTotalNumEntries());

    return promotions;
  }
  public static void runExample(
      AdWordsServices adWordsServices, AdWordsSession session, Long adGroupId) throws Exception {
    // Enable validation.
    session.setValidateOnly(true);

    // Get the validation AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdValidationService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    // Create text ad.
    TextAd textAd1 = new TextAd();
    textAd1.setHeadline("Luxury Cruise to Mars");
    textAd1.setDescription1("Visit the Red Planet in style.");
    textAd1.setDescription2("Low-gravity fun for everyone!");
    textAd1.setDisplayUrl("www.example.com");
    textAd1.setFinalUrls(new String[] {"http://www.example.com"});

    // Create ad group ad.
    AdGroupAd textAdGroupAd1 = new AdGroupAd();
    textAdGroupAd1.setAdGroupId(adGroupId);
    textAdGroupAd1.setAd(textAd1);

    // Create operations.
    AdGroupAdOperation textAdGroupAdOperation1 = new AdGroupAdOperation();
    textAdGroupAdOperation1.setOperand(textAdGroupAd1);
    textAdGroupAdOperation1.setOperator(Operator.ADD);

    AdGroupAdOperation[] operations = new AdGroupAdOperation[] {textAdGroupAdOperation1};

    // Add ads.
    adGroupAdValidationService.mutate(operations);

    // No error means the request is valid.

    // Now let's check an invalid ad using a very long line to trigger an error.
    textAd1.setDescription2("Low-gravity fun for all astronauts in orbit.");

    try {
      adGroupAdValidationService.mutate(operations);
    } catch (ApiException e) {
      System.err.println("Validation failed for reason \"" + e.getMessage1() + "\".");
    }
  }
  public static void runExample(
      AdWordsServices adWordsServices, AdWordsSession session, Long adGroupId) throws Exception {
    // Enable validateOnly mode.
    session.setValidateOnly(true);

    // Get the AdGroupAdService.
    AdGroupAdServiceInterface adGroupAdService =
        adWordsServices.get(session, AdGroupAdServiceInterface.class);

    // Create text ad that violates an exemptable policy. This ad will only
    // trigger an error in the production environment.
    TextAd exemptableTextAd = new TextAd();
    exemptableTextAd.setHeadline("Mars " + System.currentTimeMillis() + "!!!");
    exemptableTextAd.setDescription1("Visit the Red Planet in style.");
    exemptableTextAd.setDescription2("Low-gravity fun for everyone!");
    exemptableTextAd.setDisplayUrl("www.example.com");
    exemptableTextAd.setFinalUrls(new String[] {"http://www.example.com/"});

    // Create ad group ad.
    AdGroupAd exemptableAdGroupAd = new AdGroupAd();
    exemptableAdGroupAd.setAdGroupId(adGroupId);
    exemptableAdGroupAd.setAd(exemptableTextAd);

    // Create operations.
    AdGroupAdOperation exemptableOperation = new AdGroupAdOperation();
    exemptableOperation.setOperand(exemptableAdGroupAd);
    exemptableOperation.setOperator(Operator.ADD);

    // Create text ad that violates a non-exemptable policy.
    TextAd nonExemptableTextAd = new TextAd();
    nonExemptableTextAd.setHeadline("Mars Cruise with too long of a headline.");
    nonExemptableTextAd.setDescription1("Visit the Red Planet in style.");
    nonExemptableTextAd.setDescription2("Low-gravity fun for everyone.");
    nonExemptableTextAd.setDisplayUrl("www.example.com");
    nonExemptableTextAd.setFinalUrls(new String[] {"http://www.example.com/"});

    // Create ad group ad.
    AdGroupAd nonExemptableAdGroupAd = new AdGroupAd();
    nonExemptableAdGroupAd.setAdGroupId(adGroupId);
    nonExemptableAdGroupAd.setAd(nonExemptableTextAd);

    // Create operations.
    AdGroupAdOperation nonExemptableOperation = new AdGroupAdOperation();
    nonExemptableOperation.setOperand(nonExemptableAdGroupAd);
    nonExemptableOperation.setOperator(Operator.ADD);

    AdGroupAdOperation[] operations =
        new AdGroupAdOperation[] {exemptableOperation, nonExemptableOperation};

    boolean foundNonExemptableErrors;

    // Repeat the loop below with validateOnly = true until either no errors are found
    // or the only errors found have isExemptable == true.
    do {
      foundNonExemptableErrors = false;

      try {
        // Validate the ads.
        adGroupAdService.mutate(operations);
      } catch (ApiException e) {
        Set<Integer> indicesToRemove = new HashSet<Integer>();
        for (ApiError error : e.getErrors()) {
          if (error instanceof PolicyViolationError) {
            PolicyViolationError policyViolationError = (PolicyViolationError) error;
            Matcher matcher = operationIndexPattern.matcher(error.getFieldPath());
            if (matcher.matches()) {
              int operationIndex = Integer.parseInt(matcher.group(1));
              AdGroupAdOperation operation = operations[operationIndex];
              System.out.printf(
                  "Ad with headline '%s' violated %s policy '%s'.%n",
                  ((TextAd) operation.getOperand().getAd()).getHeadline(),
                  policyViolationError.getIsExemptable() ? "exemptable" : "non-exemptable",
                  policyViolationError.getExternalPolicyName());
              if (policyViolationError.getIsExemptable()) {
                // Add exemption request to the operation.
                System.out.printf(
                    "Adding exemption request for policy name '%s' on text '%s'.%n",
                    policyViolationError.getKey().getPolicyName(),
                    policyViolationError.getKey().getViolatingText());
                List<ExemptionRequest> exemptionRequests =
                    new ArrayList<ExemptionRequest>(
                        Arrays.asList(
                            operation.getExemptionRequests() == null
                                ? new ExemptionRequest[] {}
                                : operation.getExemptionRequests()));
                exemptionRequests.add(new ExemptionRequest(policyViolationError.getKey()));
                operation.setExemptionRequests(
                    exemptionRequests.toArray(new ExemptionRequest[] {}));
              } else {
                // Remove non-exemptable operation.
                System.out.printf(
                    "Removing non-exemptable operation at index %d.%n", operationIndex);
                indicesToRemove.add(operationIndex);
              }
            }
          } else {
            // Non-policy error returned.
            Matcher matcher = operationIndexPattern.matcher(error.getFieldPath());
            if (matcher.matches()) {
              int operationIndex = Integer.parseInt(matcher.group(1));
              AdGroupAdOperation operation = operations[operationIndex];
              System.out.printf(
                  "Ad with headline '%s' created non-policy error '%s'.%n",
                  ((TextAd) operation.getOperand().getAd()).getHeadline(), error.getErrorString());
              System.out.printf("Removing non-exemptable operation at index %d.%n", operationIndex);
              indicesToRemove.add(operationIndex);
            }
          }
        }

        // Remove operations that cannot be exempted.
        List<AdGroupAdOperation> remainingOperations = new ArrayList<AdGroupAdOperation>();
        for (int i = 0; i < operations.length; i++) {
          if (!indicesToRemove.contains(i)) {
            foundNonExemptableErrors = true;
            remainingOperations.add(operations[i]);
          }
        }
        operations = remainingOperations.toArray(new AdGroupAdOperation[] {});
      }
    } while (foundNonExemptableErrors && operations.length > 0);

    if (operations.length > 0) {
      // Disable validateOnly so we can submit the AdGroupAds with exemptions.
      session.setValidateOnly(false);

      // Add ads with exemptions.
      AdGroupAdReturnValue result = adGroupAdService.mutate(operations);

      // Display ads.
      if (result != null && result.getValue() != null) {
        for (AdGroupAd adGroupAdResult : result.getValue()) {
          System.out.printf(
              "Ad with ID %d and headline '%s' was added.%n",
              adGroupAdResult.getAd().getId(), ((TextAd) adGroupAdResult.getAd()).getHeadline());
        }
      }
    } else {
      System.out.println("No ads were added.");
    }
  }
  public static List<Promotion> runExample(
      AdWordsServices adWordsServices, AdWordsSession session, Long businessId) throws Exception {
    ExpressBusinessServiceInterface businessService =
        adWordsServices.get(session, ExpressBusinessServiceInterface.class);

    // Get the business for the businessId. We will need its geo point to create
    // a Proximity criterion for the new Promotion.
    Selector businessSelector =
        new SelectorBuilder()
            .fields(ExpressBusinessField.Id, ExpressBusinessField.GeoPoint)
            .equals(ExpressBusinessField.Id, String.valueOf(businessId))
            .build();

    ExpressBusiness business = businessService.get(businessSelector).getEntries(0);

    // Get the PromotionService
    PromotionServiceInterface promotionService =
        adWordsServices.get(session, PromotionServiceInterface.class);

    // PromotionService requires the businessId on the session
    session.setExpressBusinessId(businessId);

    // Set up the new Promotion
    Promotion marsTourPromotion = new Promotion();
    Money budget = new Money();
    budget.setMicroAmount(1000000L);
    marsTourPromotion.setName("Mars Tour Promotion " + System.currentTimeMillis());
    marsTourPromotion.setStatus(PromotionStatus.PAUSED);
    marsTourPromotion.setDestinationUrl("http://www.example.com");
    marsTourPromotion.setBudget(budget);
    marsTourPromotion.setCallTrackingEnabled(true);

    // Criteria
    List<Criterion> criteria = Lists.newArrayList();

    // Criterion - Travel Agency product/service.  See GetProductServices.java for an example
    // of how to get valid product/service settings.
    ProductService productService = new ProductService();
    productService.setText("Travel Agency");
    productService.setLocale("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.setId(1000L);
    criteria.add(language);

    // Criterion - Within 15 miles
    Proximity proximity = new Proximity();
    proximity.setGeoPoint(business.getGeoPoint());
    proximity.setRadiusDistanceUnits(ProximityDistanceUnits.MILES);
    proximity.setRadiusInUnits(15d);
    criteria.add(proximity);

    marsTourPromotion.setCriteria(criteria.toArray(new Criterion[criteria.size()]));

    // Creative
    Creative creative =
        new Creative("Standard Mars Trip", "Fly coach to Mars", "Free in-flight pretzels");

    marsTourPromotion.setCreatives(new Creative[] {creative});

    Promotion[] addedPromotions =
        promotionService.mutate(
            new PromotionOperation[] {
              new PromotionOperation(Operator.ADD, null, marsTourPromotion)
            });

    System.out.printf(
        "Added promotion ID %d with name '%s' to business ID %d%n",
        addedPromotions[0].getId(), addedPromotions[0].getName(), businessId);

    return Arrays.asList(addedPromotions);
  }
  public static void runExample(
      AdWordsServices adWordsServices, AdWordsSession session, Long adGroupId) throws Exception {
    // Enable partial failure.
    session.setPartialFailure(true);

    // Get the AdGroupCriterionService.
    AdGroupCriterionServiceInterface adGroupCriterionService =
        adWordsServices.get(session, AdGroupCriterionServiceInterface.class);

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

    // Create keywords.
    String[] keywords =
        new String[] {"mars cruise", "inv@lid cruise", "venus cruise", "b(a)d keyword cruise"};
    for (String keywordText : keywords) {
      // Create keyword
      Keyword keyword = new Keyword();
      keyword.setText(keywordText);
      keyword.setMatchType(KeywordMatchType.BROAD);

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

      // Create operation.
      AdGroupCriterionOperation keywordAdGroupCriterionOperation = new AdGroupCriterionOperation();
      keywordAdGroupCriterionOperation.setOperand(keywordBiddableAdGroupCriterion);
      keywordAdGroupCriterionOperation.setOperator(Operator.ADD);
      operations.add(keywordAdGroupCriterionOperation);
    }

    // Add ad group criteria.
    AdGroupCriterionReturnValue result =
        adGroupCriterionService.mutate(operations.toArray(new AdGroupCriterionOperation[] {}));

    // Display results.
    for (AdGroupCriterion adGroupCriterionResult : result.getValue()) {
      if (adGroupCriterionResult.getCriterion() != null) {
        System.out.printf(
            "Ad group criterion with ad group id '%d', and criterion id '%d', "
                + "and keyword '%s' was added.\n",
            adGroupCriterionResult.getAdGroupId(),
            adGroupCriterionResult.getCriterion().getId(),
            ((Keyword) adGroupCriterionResult.getCriterion()).getText());
      }
    }

    for (ApiError apiError : result.getPartialFailureErrors()) {
      Matcher matcher = operationIndexPattern.matcher(apiError.getFieldPath());
      if (matcher.matches()) {
        int operationIndex = Integer.parseInt(matcher.group(1));
        AdGroupCriterion adGroupCriterion = operations.get(operationIndex).getOperand();
        System.out.printf(
            "Ad group criterion with ad group id '%d' and keyword '%s' "
                + "triggered a failure for the following reason: '%s'.\n",
            adGroupCriterion.getAdGroupId(),
            ((Keyword) adGroupCriterion.getCriterion()).getText(),
            apiError.getErrorString());
      } else {
        System.out.printf(
            "A failure for the following reason: '%s' has occurred.\n", apiError.getErrorString());
      }
    }
  }