/// <summary>
        /// Gets the site links from a feed.
        /// </summary>
        /// <param name="user">The user that owns the feed.</param>
        /// <param name="feedId">The feed ID.</param>
        /// <returns>A dictionary of sitelinks from the feed, with key as the feed
        /// item ID, and value as the sitelink.</returns>
        private Dictionary <long, SiteLinkFromFeed> GetSiteLinksFromFeed(AdWordsUser user,
                                                                         long feedId)
        {
            Dictionary <long, SiteLinkFromFeed> siteLinks = new Dictionary <long, SiteLinkFromFeed>();

            // Retrieve all the feed items from the feed.
            FeedItem[] feedItems = GetFeedItems(user, feedId);

            // Retrieve the feed's attribute mapping.
            Dictionary <long, HashSet <long> > feedMappings = GetFeedMapping(user, feedId,
                                                                             PLACEHOLDER_TYPE_SITELINKS);

            if (feedItems != null)
            {
                foreach (FeedItem feedItem in feedItems)
                {
                    SiteLinkFromFeed sitelinkFromFeed = new SiteLinkFromFeed()
                    {
                        FeedId     = feedItem.feedId,
                        FeedItemId = feedItem.feedItemId
                    };

                    foreach (FeedItemAttributeValue attributeValue in feedItem.attributeValues)
                    {
                        // This attribute hasn't been mapped to a field.
                        if (!feedMappings.ContainsKey(attributeValue.feedAttributeId))
                        {
                            continue;
                        }
                        // Get the list of all the fields to which this attribute has been mapped.
                        foreach (long fieldId in feedMappings[attributeValue.feedAttributeId])
                        {
                            // Read the appropriate value depending on the ID of the mapped
                            // field.
                            switch (fieldId)
                            {
                            case SiteLinkFields.TEXT:
                                sitelinkFromFeed.Text = attributeValue.stringValue;
                                break;

                            case SiteLinkFields.URL:
                                sitelinkFromFeed.Url = attributeValue.stringValue;
                                break;

                            case SiteLinkFields.FINAL_URLS:
                                sitelinkFromFeed.FinalUrls = attributeValue.stringValues;
                                break;

                            case SiteLinkFields.FINAL_MOBILE_URLS:
                                sitelinkFromFeed.FinalMobileUrls = attributeValue.stringValues;
                                break;

                            case SiteLinkFields.TRACKING_URL_TEMPLATE:
                                sitelinkFromFeed.TrackingUrlTemplate = attributeValue.stringValue;
                                break;

                            case SiteLinkFields.LINE2:
                                sitelinkFromFeed.Line2 = attributeValue.stringValue;
                                break;

                            case SiteLinkFields.LINE3:
                                sitelinkFromFeed.Line3 = attributeValue.stringValue;
                                break;
                            }
                        }
                    }

                    sitelinkFromFeed.Scheduling = feedItem.scheduling;

                    siteLinks.Add(feedItem.feedItemId, sitelinkFromFeed);
                }
            }
            return(siteLinks);
        }
    /// <summary>
    /// Gets the site links from a feed.
    /// </summary>
    /// <param name="user">The user that owns the feed.</param>
    /// <param name="feedId">The feed ID.</param>
    /// <returns>A dictionary of sitelinks from the feed, with key as the feed
    /// item ID, and value as the sitelink.</returns>
    private Dictionary<long, SiteLinkFromFeed> GetSiteLinksFromFeed(AdWordsUser user,
        long feedId) {
      Dictionary<long, SiteLinkFromFeed> siteLinks = new Dictionary<long, SiteLinkFromFeed>();

      // Retrieve all the feed items from the feed.
      FeedItem[] feedItems = GetFeedItems(user, feedId);

      // Retrieve the feed's attribute mapping.
      Dictionary<long, HashSet<long>> feedMappings = GetFeedMapping(user, feedId,
          PLACEHOLDER_TYPE_SITELINKS);

      if (feedItems != null) {
        foreach (FeedItem feedItem in feedItems) {
          SiteLinkFromFeed sitelinkFromFeed = new SiteLinkFromFeed() {
            FeedId = feedItem.feedId,
            FeedItemId = feedItem.feedItemId
          };

          foreach (FeedItemAttributeValue attributeValue in feedItem.attributeValues) {
            // This attribute hasn't been mapped to a field.
            if (!feedMappings.ContainsKey(attributeValue.feedAttributeId)) {
              continue;
            }
            // Get the list of all the fields to which this attribute has been mapped.
            foreach (long fieldId in feedMappings[attributeValue.feedAttributeId]) {
              // Read the appropriate value depending on the ID of the mapped
              // field.
              switch (fieldId) {
                case SiteLinkFields.TEXT:
                  sitelinkFromFeed.Text = attributeValue.stringValue;
                  break;

                case SiteLinkFields.URL:
                  sitelinkFromFeed.Url = attributeValue.stringValue;
                  break;

                case SiteLinkFields.FINAL_URLS:
                  sitelinkFromFeed.FinalUrls = attributeValue.stringValues;
                  break;

                case SiteLinkFields.FINAL_MOBILE_URLS:
                  sitelinkFromFeed.FinalMobileUrls = attributeValue.stringValues;
                  break;

                case SiteLinkFields.TRACKING_URL_TEMPLATE:
                  sitelinkFromFeed.TrackingUrlTemplate = attributeValue.stringValue;
                  break;

                case SiteLinkFields.LINE2:
                  sitelinkFromFeed.Line2 = attributeValue.stringValue;
                  break;

                case SiteLinkFields.LINE3:
                  sitelinkFromFeed.Line3 = attributeValue.stringValue;
                  break;
              }
            }
          }

          sitelinkFromFeed.Scheduling = feedItem.scheduling;

          siteLinks.Add(feedItem.feedItemId, sitelinkFromFeed);
        }
      }
      return siteLinks;
    }
        /// <summary>
        /// Creates the extension setting fo a list of feed items.
        /// </summary>
        /// <param name="user">The user for which extension settings are created.
        /// </param>
        /// <param name="feedItems">The list of all feed items.</param>
        /// <param name="campaignId">ID of the campaign to which extension settings
        /// are added.</param>
        /// <param name="feedItemIds">IDs of the feed items for which extension
        /// settings should be created.</param>
        /// <param name="platformRestrictions">The platform restrictions for the
        /// extension setting.</param>
        private static void CreateExtensionSetting(AdWordsUser user,
                                                   Dictionary <long, SiteLinkFromFeed> feedItems, long campaignId, List <long> feedItemIds,
                                                   ExtensionSettingPlatform platformRestrictions)
        {
            CampaignExtensionSetting extensionSetting = new CampaignExtensionSetting()
            {
                campaignId       = campaignId,
                extensionType    = FeedType.SITELINK,
                extensionSetting = new ExtensionSetting()
                {
                }
            };

            List <ExtensionFeedItem> extensionFeedItems = new List <ExtensionFeedItem>();

            foreach (long feedItemId in feedItemIds)
            {
                SiteLinkFromFeed feedItem    = feedItems[feedItemId];
                SitelinkFeedItem newFeedItem = new SitelinkFeedItem()
                {
                    sitelinkText      = feedItem.Text,
                    sitelinkUrl       = feedItem.Url,
                    sitelinkFinalUrls = new UrlList()
                    {
                        urls = feedItem.FinalUrls
                    },
                    sitelinkFinalMobileUrls = new UrlList()
                    {
                        urls = feedItem.FinalMobileUrls
                    },
                    sitelinkTrackingUrlTemplate = feedItem.TrackingUrlTemplate,
                    sitelinkLine2 = feedItem.Line2,
                    sitelinkLine3 = feedItem.Line3
                };

                extensionFeedItems.Add(newFeedItem);
            }

            extensionSetting.extensionSetting.extensions           = extensionFeedItems.ToArray();
            extensionSetting.extensionSetting.platformRestrictions = platformRestrictions;
            extensionSetting.extensionType = FeedType.SITELINK;

            using (CampaignExtensionSettingService campaignExtensionSettingService =
                       (CampaignExtensionSettingService)user.GetService(AdWordsService.v201809
                                                                        .CampaignExtensionSettingService))
            {
                CampaignExtensionSettingOperation operation =
                    new CampaignExtensionSettingOperation()
                {
                    operand   = extensionSetting,
                    @operator = Operator.ADD
                };

                campaignExtensionSettingService.mutate(new CampaignExtensionSettingOperation[]
                {
                    operation
                });
            }

            return;
        }