/// <summary>
        /// Creates a new operation for adding a feed item.
        /// </summary>
        /// <param name="siteLinksFeed">The site links feed.</param>
        /// <param name="text">The sitelinks text.</param>
        /// <param name="url">The sitelinks URL.</param>
        /// <returns>A FeedItemOperation for adding the feed item.</returns>
        private static FeedItemOperation newSiteLinkFeedItemAddOperation(
        SiteLinksFeed siteLinksFeed, string text, string url)
        {
            // Create the FeedItemAttributeValues for our text values.
              FeedItemAttributeValue linkTextAttributeValue = new FeedItemAttributeValue();
              linkTextAttributeValue.feedAttributeId = siteLinksFeed.LinkTextFeedAttributeId;
              linkTextAttributeValue.stringValue = text;
              FeedItemAttributeValue linkUrlAttributeValue = new FeedItemAttributeValue();
              linkUrlAttributeValue.feedAttributeId = siteLinksFeed.LinkUrlFeedAttributeId;
              linkUrlAttributeValue.stringValue = url;

              // Create the feed item and operation.
              FeedItem item = new FeedItem();
              item.feedId = siteLinksFeed.SiteLinksFeedId;
              item.attributeValues =
              new FeedItemAttributeValue[] {linkTextAttributeValue, linkUrlAttributeValue};
              FeedItemOperation operation = new FeedItemOperation();
              operation.operand = item;
              operation.@operator = Operator.ADD;
              return operation;
        }
        /// <summary>
        /// Retrieve an existing feed that is mapped to hold sitelinks. The first
        /// active sitelinks feed is retrieved by this method.
        /// </summary>
        /// <param name="feedMappingService">The feed mapping service.</param>
        /// <returns>A SiteLinksFeed if a feed is found, or null otherwise.</returns>
        private static SiteLinksFeed getExistingFeed(FeedMappingService feedMappingService)
        {
            Selector selector = new Selector();
              selector.fields = new string[] {"FeedId", "FeedMappingId", "PlaceholderType", "Status",
            "AttributeFieldMappings"};

              Predicate placeHolderPredicate = new Predicate();
              placeHolderPredicate.field = "PlaceholderType";
              placeHolderPredicate.@operator = PredicateOperator.EQUALS;
              placeHolderPredicate.values = new string[] {PLACEHOLDER_SITELINKS.ToString()};

              Predicate statusPredicate = new Predicate();
              statusPredicate.field = "Status";
              statusPredicate.@operator = PredicateOperator.EQUALS;
              statusPredicate.values = new string[] {"ACTIVE"};

              selector.predicates = new Predicate[] {placeHolderPredicate, statusPredicate};

              FeedMappingPage page = feedMappingService.get(selector);

              if (page != null && page.entries != null && page.entries.Length > 0) {
            foreach (FeedMapping feedMapping in page.entries) {
              long? feedId = feedMapping.feedId;
              long? textAttributeId = null;
              long? urlAttributeId = null;
              foreach (AttributeFieldMapping attributeMapping in feedMapping.attributeFieldMappings) {
            if (attributeMapping.fieldId == PLACEHOLDER_FIELD_SITELINK_LINK_TEXT) {
              textAttributeId = attributeMapping.feedAttributeId;
            } else if (attributeMapping.fieldId == PLACEHOLDER_FIELD_SITELINK_URL) {
              urlAttributeId = attributeMapping.feedAttributeId;
            }
              }

              if (feedId != null && textAttributeId != null && urlAttributeId != null) {
            SiteLinksFeed siteLinksFeed = new SiteLinksFeed();
            siteLinksFeed.SiteLinksFeedId = feedId.Value;
            siteLinksFeed.LinkTextFeedAttributeId = textAttributeId.Value;
            siteLinksFeed.LinkUrlFeedAttributeId = urlAttributeId.Value;
            return siteLinksFeed;
              }
            }
              }
              return null;
        }
        /// <summary>
        /// Map the feed for use with Sitelinks.
        /// </summary>
        /// <param name="feedMappingService">The feed mapping service.</param>
        /// <param name="siteLinksFeed">The feed for holding sitelinks.</param>
        private static void createSiteLinksFeedMapping(FeedMappingService feedMappingService,
        SiteLinksFeed siteLinksFeed)
        {
            // Map the FeedAttributeIds to the fieldId constants.
              AttributeFieldMapping linkTextFieldMapping = new AttributeFieldMapping();
              linkTextFieldMapping.feedAttributeId = siteLinksFeed.LinkTextFeedAttributeId;
              linkTextFieldMapping.fieldId = PLACEHOLDER_FIELD_SITELINK_LINK_TEXT;
              AttributeFieldMapping linkUrlFieldMapping = new AttributeFieldMapping();
              linkUrlFieldMapping.feedAttributeId = siteLinksFeed.LinkUrlFeedAttributeId;
              linkUrlFieldMapping.fieldId = PLACEHOLDER_FIELD_SITELINK_URL;

              // Create the FieldMapping and operation.
              FeedMapping feedMapping = new FeedMapping();
              feedMapping.placeholderType = PLACEHOLDER_SITELINKS;
              feedMapping.feedId = siteLinksFeed.SiteLinksFeedId;
              feedMapping.attributeFieldMappings =
              new AttributeFieldMapping[] {linkTextFieldMapping, linkUrlFieldMapping};
              FeedMappingOperation operation = new FeedMappingOperation();
              operation.operand = feedMapping;
              operation.@operator = Operator.ADD;

              // Save the field mapping.
              feedMappingService.mutate(new FeedMappingOperation[] {operation});
        }
        /// <summary>
        /// Create a feed for holding upgraded sitelinks.
        /// </summary>
        /// <param name="feedService">The feed service.</param>
        /// <returns>A SiteLinksFeed for holding the sitelinks.</returns>
        private static SiteLinksFeed createSiteLinksFeed(FeedService feedService)
        {
            SiteLinksFeed siteLinksData = new SiteLinksFeed();

              // Create attributes.
              FeedAttribute textAttribute = new FeedAttribute();
              textAttribute.type = FeedAttributeType.STRING;
              textAttribute.name = "Link Text";
              FeedAttribute urlAttribute = new FeedAttribute();
              urlAttribute.type = FeedAttributeType.URL;
              urlAttribute.name = "Link URL";

              // Create the feed.
              Feed siteLinksFeed = new Feed();
              siteLinksFeed.name = "Feed For Sitelinks";
              siteLinksFeed.attributes = new FeedAttribute[] {textAttribute, urlAttribute};
              siteLinksFeed.origin = FeedOrigin.USER;

              // Create operation.
              FeedOperation operation = new FeedOperation();
              operation.operand = siteLinksFeed;
              operation.@operator = Operator.ADD;

              // Add the feed.
              FeedReturnValue result = feedService.mutate(new FeedOperation[] {operation});

              Feed savedFeed = result.value[0];
              siteLinksData.SiteLinksFeedId = savedFeed.id;
              FeedAttribute[] savedAttributes = savedFeed.attributes;
              siteLinksData.LinkTextFeedAttributeId = savedAttributes[0].id;
              siteLinksData.LinkUrlFeedAttributeId = savedAttributes[1].id;
              return siteLinksData;
        }
        /// <summary>
        /// Add legacy sitelinks to the sitelinks feed.
        /// </summary>
        /// <param name="feedItemService">The feed item service.</param>
        /// <param name="siteLinksFeed">The feed for adding sitelinks.</param>
        /// <param name="sitelinks">The list of legacy sitelinks to be added to the
        /// feed.</param>
        /// <returns>The list of feeditems that were added to the feed.</returns>
        private static List<long> createSiteLinkFeedItems(FeedItemService feedItemService,
        SiteLinksFeed siteLinksFeed, Sitelink[] sitelinks)
        {
            List<long> siteLinkFeedItemIds = new List<long>();

              // Create operation for adding each legacy sitelink to the sitelinks feed.
              List<FeedItemOperation> feedItemOperations = new List<FeedItemOperation>();

              foreach (Sitelink sitelink in sitelinks) {
            FeedItemOperation operation = newSiteLinkFeedItemAddOperation(
            siteLinksFeed, sitelink.displayText, sitelink.destinationUrl);
            feedItemOperations.Add(operation);
              }

              FeedItemReturnValue result = feedItemService.mutate(feedItemOperations.ToArray());

              // Retrieve the feed item ids.
              foreach (FeedItem item in result.value) {
            siteLinkFeedItemIds.Add(item.feedItemId);
              }
              return siteLinkFeedItemIds;
        }
        /// <summary>
        /// Associates the sitelink feed items with a campaign.
        /// </summary>
        /// <param name="campaignFeedService">The campaign feed service.</param>
        /// <param name="siteLinksFeed">The feed for holding the sitelinks.</param>
        /// <param name="siteLinkFeedItemIds">The list of feed item ids to be
        /// associated with a campaign as sitelinks.</param>
        /// <param name="campaignId">The campaign id to which upgraded sitelinks are
        /// added.</param>
        private static void associateSitelinkFeedItemsWithCampaign(
        CampaignFeedService campaignFeedService, SiteLinksFeed siteLinksFeed,
        List<long> siteLinkFeedItemIds, long campaignId)
        {
            // Create a custom matching function that matches the given feed items to
              // the campaign.
              RequestContextOperand requestContextOperand = new RequestContextOperand();
              requestContextOperand.contextType = RequestContextOperandContextType.FEED_ITEM_ID;

              Function function = new Function();
              function.lhsOperand = new FunctionArgumentOperand[] {requestContextOperand};
              function.@operator = FunctionOperator.IN;

              List<FunctionArgumentOperand> operands = new List<FunctionArgumentOperand>();
              foreach (long feedItemId in siteLinkFeedItemIds) {
            ConstantOperand constantOperand = new ConstantOperand();
            constantOperand.longValue = feedItemId;
            constantOperand.type = ConstantOperandConstantType.LONG;
            operands.Add(constantOperand);
              }
              function.rhsOperand = operands.ToArray();

              // Create upgraded sitelinks for the campaign. Use the sitelinks feed we
              // created, and restrict feed items by matching function.
              CampaignFeed campaignFeed = new CampaignFeed();
              campaignFeed.feedId = siteLinksFeed.SiteLinksFeedId;
              campaignFeed.campaignId = campaignId;
              campaignFeed.matchingFunction = function;
              campaignFeed.placeholderTypes = new int[] {PLACEHOLDER_SITELINKS};

              CampaignFeedOperation operation = new CampaignFeedOperation();
              operation.operand = campaignFeed;
              operation.@operator = Operator.ADD;
              campaignFeedService.mutate(new CampaignFeedOperation[] {operation});
        }