/// <summary>
    /// Creates a new Feed for ad customizers.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="feedName">Name of the feed to be created.</param>
    /// <returns>A new CustomizersDataHolder, populated with the feed ID and
    /// attribute IDs of the new Feed.</returns>
    private static CustomizersDataHolder CreateCustomizerFeed(AdWordsUser user, string feedName) {
      // Get the FeedService.
      FeedService feedService = (FeedService) user.GetService(AdWordsService.v201409.FeedService);

      Feed customizerFeed = new Feed();
      customizerFeed.name = feedName;

      FeedAttribute nameAttribute = new FeedAttribute();
      nameAttribute.name = "Name";
      nameAttribute.type = FeedAttributeType.STRING;

      FeedAttribute priceAttribute = new FeedAttribute();
      priceAttribute.name = "Price";
      priceAttribute.type = FeedAttributeType.STRING;

      FeedAttribute dateAttribute = new FeedAttribute();
      dateAttribute.name = "Date";
      dateAttribute.type = FeedAttributeType.DATE_TIME;

      customizerFeed.attributes = new FeedAttribute[] {
          nameAttribute, priceAttribute, dateAttribute
      };

      FeedOperation feedOperation = new FeedOperation();
      feedOperation.operand = customizerFeed;
      feedOperation.@operator = (Operator.ADD);

      Feed addedFeed = feedService.mutate(new FeedOperation[] { feedOperation }).value[0];

      CustomizersDataHolder dataHolder = new CustomizersDataHolder();
      dataHolder.FeedId = addedFeed.id;
      dataHolder.NameFeedAttributeId = addedFeed.attributes[0].id;
      dataHolder.PriceFeedAttributeId = addedFeed.attributes[1].id;
      dataHolder.DateFeedAttributeId = addedFeed.attributes[2].id;

      Console.WriteLine("Feed with name '{0}' and ID {1} was added with:\n", addedFeed.name,
          dataHolder.FeedId);
      Console.WriteLine("  Name attribute ID {0}\n", dataHolder.NameFeedAttributeId);
      Console.WriteLine("  Price attribute ID {0}\n", dataHolder.PriceFeedAttributeId);
      Console.WriteLine("  Date attribute ID {0}\n", dataHolder.DateFeedAttributeId);

      return dataHolder;
    }
    /// <summary>
    /// Runs the code example.
    /// </summary>
    /// <param name="user">The AdWords user.</param>
    /// <param name="gmbEmailAddress">The email address for Google My Business
    /// account.</param>
    /// <param name="gmbAccessToken">The OAuth2 access token for Google
    /// My Business account.</param>
    /// <param name="businessAccountIdentifier">The account identifier for
    /// Google My Business account.</param>
    public void Run(AdWordsUser user, string gmbEmailAddress, string gmbAccessToken,
        string businessAccountIdentifier) {
      FeedService feedService = (FeedService) user.GetService(AdWordsService.v201409.FeedService);

      CustomerFeedService customerFeedService = (CustomerFeedService) user.GetService(
          AdWordsService.v201409.CustomerFeedService);

      // Create a feed that will sync to the Google My Business account
      // specified by gmbEmailAddress. Do not add FeedAttributes to this object,
      // as AdWords will add them automatically because this will be a
      // system generated feed.
      Feed gmbFeed = new Feed();
      gmbFeed.name = String.Format("Google My Business feed #{0}",
          ExampleUtilities.GetRandomString());

      PlacesLocationFeedData feedData = new PlacesLocationFeedData();
      feedData.emailAddress = gmbEmailAddress;
      feedData.businessAccountIdentifier = businessAccountIdentifier;

      OAuthInfo oAuthInfo = new OAuthInfo();
      oAuthInfo.httpMethod = "GET";

      // Permissions for the AdWords API scope will also cover GMB.
      oAuthInfo.httpRequestUrl = user.Config.GetDefaultOAuth2Scope();
      oAuthInfo.httpAuthorizationHeader = string.Format("Bearer {0}", gmbAccessToken);
      feedData.oAuthInfo = oAuthInfo;

      gmbFeed.systemFeedGenerationData = feedData;

      // Since this feed's feed items will be managed by AdWords,
      // you must set its origin to ADWORDS.
      gmbFeed.origin = FeedOrigin.ADWORDS;

      // Create an operation to add the feed.
      FeedOperation feedOperation = new FeedOperation();
      feedOperation.operand = gmbFeed;
      feedOperation.@operator = Operator.ADD;

      try {
        // Add the feed. Since it is a system generated feed, AdWords will
        // automatically:
        // 1. Set up the FeedAttributes on the feed.
        // 2. Set up a FeedMapping that associates the FeedAttributes of the
        //    feed with the placeholder fields of the LOCATION placeholder
        //    type.
        FeedReturnValue addFeedResult = feedService.mutate(new FeedOperation[] { feedOperation });
        Feed addedFeed = addFeedResult.value[0];
        Console.WriteLine("Added GMB feed with ID {0}", addedFeed.id);

        // Add a CustomerFeed that associates the feed with this customer for
        // the LOCATION placeholder type.
        CustomerFeed customerFeed = new CustomerFeed();
        customerFeed.feedId = addedFeed.id;
        customerFeed.placeholderTypes = new int[] { PLACEHOLDER_LOCATION };

        // Create a matching function that will always evaluate to true.
        Function customerMatchingFunction = new Function();
        ConstantOperand constOperand = new ConstantOperand();
        constOperand.type = ConstantOperandConstantType.BOOLEAN;
        constOperand.booleanValue = true;
        customerMatchingFunction.lhsOperand = new FunctionArgumentOperand[] { constOperand };
        customerMatchingFunction.@operator = FunctionOperator.IDENTITY;
        customerFeed.matchingFunction = customerMatchingFunction;

        // Create an operation to add the customer feed.
        CustomerFeedOperation customerFeedOperation = new CustomerFeedOperation();
        customerFeedOperation.operand = customerFeed;
        customerFeedOperation.@operator = Operator.ADD;

        // After the completion of the Feed ADD operation above the added feed
        // will not be available for usage in a CustomerFeed until the sync
        // between the AdWords and GMB accounts completes.  The loop below
        // will retry adding the CustomerFeed up to ten times with an
        // exponential back-off policy.
        CustomerFeed addedCustomerFeed = null;

        AdWordsAppConfig config = new AdWordsAppConfig();
        config.RetryCount = 10;

        ErrorHandler errorHandler = new ErrorHandler(config);
        do {
          try {
            CustomerFeedReturnValue customerFeedResult =
                customerFeedService.mutate(new CustomerFeedOperation[] { customerFeedOperation });
            addedCustomerFeed = customerFeedResult.value[0];

            Console.WriteLine("Added CustomerFeed for feed ID {0} and placeholder type {1}",
                addedCustomerFeed.feedId, addedCustomerFeed.placeholderTypes[0]);
            break;
          } catch (AdWordsApiException e) {
            ApiException apiException = (ApiException) e.ApiException;
            foreach (ApiError error in apiException.errors) {
              if (error is CustomerFeedError) {
                if ((error as CustomerFeedError).reason ==
                    CustomerFeedErrorReason.MISSING_FEEDMAPPING_FOR_PLACEHOLDER_TYPE) {
                  errorHandler.DoExponentialBackoff();
                  errorHandler.IncrementRetriedAttempts();
                } else {
                  throw;
                }
              }
            }
          }
        } while (errorHandler.HaveMoreRetryAttemptsLeft());

        // OPTIONAL: Create a CampaignFeed to specify which FeedItems to use at
        // the Campaign level.  This will be similar to the CampaignFeed in the
        // AddSiteLinks example, except you can also filter based on the
        // business name and category of each FeedItem by using a
        // FeedAttributeOperand in your matching function.

        // OPTIONAL: Create an AdGroupFeed for even more fine grained control
        // over which feed items are used at the AdGroup level.
      } catch (Exception ex) {
        throw new System.ApplicationException("Failed to create customer feed.", ex);
      }
    }
    /// <summary>
    /// Gets the campaignfeeds that use a particular feed.
    /// </summary>
    /// <param name="user">The user that owns the feed.</param>
    /// <param name="feed">The feed for which campaign feeds should be
    /// retrieved.</param>
    /// <param name="placeholderType">The type of placeholder to restrict
    /// search.</param>
    /// <returns>The list of campaignfeeds.</returns>
    private CampaignFeed[] GetCampaignFeeds(AdWordsUser user, Feed feed, int placeholderType) {
      CampaignFeedService campaignFeedService = (CampaignFeedService) user.GetService(
          AdWordsService.v201409.CampaignFeedService);

      CampaignFeedPage page = campaignFeedService.query(string.Format(
          "SELECT CampaignId, MatchingFunction, PlaceholderTypes where Status='ENABLED' " +
          "and FeedId = '{0}' and PlaceholderTypes CONTAINS_ANY[{1}]", feed.id, placeholderType));
      return page.entries;
    }