/// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="user">The AdWords user.</param>
        /// <param name="campaignId">The campaign id to add product scope.</param>
        public void Run(AdWordsUser user, long campaignId)
        {
            // Get the CampaignCriterionService.
              CampaignCriterionService campaignCriterionService =
              (CampaignCriterionService) user.GetService(
              AdWordsService.v201601.CampaignCriterionService);

              ProductScope productScope = new ProductScope();
              // This set of dimensions is for demonstration purposes only. It would be
              // extremely unlikely that you want to include so many dimensions in your
              // product scope.
              ProductBrand nexusBrand = new ProductBrand();
              nexusBrand.value = "Nexus";

              ProductCanonicalCondition newProducts = new ProductCanonicalCondition();
              newProducts.condition = ProductCanonicalConditionCondition.NEW;

              ProductCustomAttribute customAttribute = new ProductCustomAttribute();
              customAttribute.type = ProductDimensionType.CUSTOM_ATTRIBUTE_0;
              customAttribute.value = "my attribute value";

              ProductOfferId bookOffer = new ProductOfferId();
              bookOffer.value = "book1";

              ProductType mediaProducts = new ProductType();
              mediaProducts.type = ProductDimensionType.PRODUCT_TYPE_L1;
              mediaProducts.value = "Media";

              ProductType bookProducts = new ProductType();
              bookProducts.type = ProductDimensionType.PRODUCT_TYPE_L2;
              bookProducts.value = "Books";

              // The value for the bidding category is a fixed ID for the
              // 'Luggage & Bags' category. You can retrieve IDs for categories from
              // the ConstantDataService. See the 'GetProductCategoryTaxonomy' example
              // for more details.
              ProductBiddingCategory luggageBiddingCategory = new ProductBiddingCategory();
              luggageBiddingCategory.type = ProductDimensionType.BIDDING_CATEGORY_L1;
              luggageBiddingCategory.value = -5914235892932915235;

              productScope.dimensions = new ProductDimension[] {nexusBrand, newProducts, bookOffer,
              mediaProducts, luggageBiddingCategory};

              CampaignCriterion campaignCriterion = new CampaignCriterion();
              campaignCriterion.campaignId = campaignId;
              campaignCriterion.criterion = productScope;

              // Create operation.
              CampaignCriterionOperation operation = new CampaignCriterionOperation();
              operation.operand = campaignCriterion;
              operation.@operator = Operator.ADD;

              try {
            // Make the mutate request.
            CampaignCriterionReturnValue result = campaignCriterionService.mutate(
            new CampaignCriterionOperation[] { operation });

            Console.WriteLine("Created a ProductScope criterion with ID '{0}'",
              result.value[0].criterion.id);
              } catch (Exception e) {
            throw new System.ApplicationException("Failed to set shopping product scope.", e);
              }
        }
        public void TestProductCustomAttributeEquals()
        {
            ProductCustomAttribute customAttributeA = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "google"
              };

              ProductCustomAttribute customAttributeATitleCase = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "Google"
              };

              ProductCustomAttribute customAttributeB = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "google"
              };

              ProductCustomAttribute customAttributeC = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "motorola"
              };

              ProductCustomAttribute customAttributeD = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L2,
            value = "google"
              };

              ProductCustomAttribute customAttributeE = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
              };

              ProductCustomAttribute customAttributeF = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
              };

              ProductCustomAttribute customAttributeG = new ProductCustomAttribute();
              ProductCustomAttribute customAttributeH = new ProductCustomAttribute();

              Assert.True(comparer.Equals(customAttributeA, customAttributeB));
              Assert.False(comparer.Equals(customAttributeA, customAttributeC));
              Assert.False(comparer.Equals(customAttributeA, customAttributeD));
              Assert.False(comparer.Equals(customAttributeA, customAttributeE));

              // Case of value is ignored.
              Assert.True(comparer.Equals(customAttributeA, customAttributeATitleCase));

              //Null value is handled gracefully.
              Assert.False(comparer.Equals(customAttributeA, customAttributeE));
              Assert.True(comparer.Equals(customAttributeE, customAttributeF));
              Assert.True(comparer.Equals(customAttributeG, customAttributeH));
        }
        public void TestProductCustomAttributeGetHashcode()
        {
            ProductCustomAttribute customAttributeA = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "google"
              };

              ProductCustomAttribute customAttributeATitleCase = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "Google"
              };

              ProductCustomAttribute customAttributeB = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "google"
              };

              ProductCustomAttribute customAttributeC = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "motorola"
              };

              ProductCustomAttribute customAttributeD = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L2,
            value = "google"
              };

              Assert.AreEqual(comparer.GetHashCode(customAttributeA),
              comparer.GetHashCode(customAttributeB));
              Assert.AreNotEqual(comparer.GetHashCode(customAttributeA),
              comparer.GetHashCode(customAttributeC));
              Assert.AreNotEqual(comparer.GetHashCode(customAttributeA),
              comparer.GetHashCode(customAttributeD));

              // Case of value is ignored.
              Assert.AreEqual(comparer.GetHashCode(customAttributeA),
              comparer.GetHashCode(customAttributeATitleCase));
        }
        public void TestCreateCustomAttribute()
        {
            ProductCustomAttribute customAttributeA = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
            value = "google"
              };

              ProductCustomAttribute customAttributeB = ProductDimensions.CreateCustomAttribute(
              ProductDimensionType.BIDDING_CATEGORY_L1, "google");

              Assert.True(comparer.Equals(customAttributeA, customAttributeB));

              ProductCustomAttribute customAttributeC = new ProductCustomAttribute() {
            type = ProductDimensionType.BIDDING_CATEGORY_L1,
              };

              ProductCustomAttribute customAttributeD = ProductDimensions.CreateCustomAttribute(
              ProductDimensionType.BIDDING_CATEGORY_L1);

              Assert.True(comparer.Equals(customAttributeC, customAttributeD));
        }