/// <summary>
    /// Generates variants into DataSet and DataTable.
    /// </summary>
    /// <returns>DataSet of generated variants</returns>
    private DataSet GenerateVariants()
    {
        List <ProductVariant> productVariantList;

        // Creating new variants and some has been already generated
        if ((NewCategories.Count > 0) && (ExistingCategories.Count > 0))
        {
            ProductAttributeSet   productAttributeSet = new ProductAttributeSet(CategorySelector.SelectedCategories.Values.Where(x => x > VariantOptionInfo.NewOption));
            List <ProductVariant> oldVariants         = VariantHelper.AddNewCategoriesToVariantsOfProduct(ProductID, productAttributeSet);
            productVariantList = VariantHelper.GetAllPossibleVariants(oldVariants);
        }
        else
        {
            productVariantList = VariantHelper.GetAllPossibleVariants(ProductID, NewCategories.Concat(ExistingCategories));
        }

        DataSet   ds = new DataSet("VariantsDS");
        DataTable dt = new DataTable("VariantsDT");

        // Combine new and existing categories in right order
        var combinedCategories = ExistingCategories.Union(NewCategories).OrderBy(cID => mAllCategoriesOptions.FindIndex(ca => ca.Item1.CategoryID == cID));

        // Build DataTable and UniGrid structure
        foreach (int categoryId in combinedCategories)
        {
            var optionCategory = mAllCategoriesOptions.FirstOrDefault(k => k.Item1.CategoryID == categoryId);

            // Add columns to DataTable
            dt.Columns.Add(new DataColumn(categoryId.ToString(), typeof(String)));

            // Add column with option category live site display name to the grid with variant preview. In case live site display name is not available option category display name is used
            if (optionCategory != null)
            {
                AddGridColumn(ResHelper.LocalizeString(optionCategory.Item1.CategoryTitle), categoryId.ToString(), "#transform: ecommerce.skuoption.SKUName");
            }
        }

        // Add RowNumber column to DataTable
        dt.Columns.Add(new DataColumn("RowNumber", typeof(int)));
        AddGridColumn("RowNumber", "RowNumber", string.Empty, true);

        // Add Exist column to DataTable
        dt.Columns.Add(new DataColumn("Exist", typeof(bool)));

        // Add Variant number column to DataTable and UniGrid
        dt.Columns.Add(new DataColumn("VariantNumber", typeof(string)));
        AddGridColumn(GetString("com.sku.skunumber"), "VariantNumber");

        // Fill DataTable
        int index = 0;

        foreach (ProductVariant productVariant in productVariantList)
        {
            DataRow dr = dt.NewRow();

            int i = 0;
            foreach (int categoryId in productVariant.ProductAttributes.CategoryIDs)
            {
                // Fill values to dynamically added column
                var optionCategory = mAllCategoriesOptions.FirstOrDefault(k => k.Item1.CategoryID == categoryId);

                if (optionCategory != null)
                {
                    dr[optionCategory.Item1.CategoryID.ToString()] = productVariant.ProductAttributes[i].SKUID;
                    i++;
                }
            }

            dr["RowNumber"]     = index;
            dr["Exist"]         = productVariant.Existing;
            dr["VariantNumber"] = productVariant.Variant.SKUNumber;

            dt.Rows.Add(dr);
            index++;
        }

        ds.Tables.Add(dt);
        return(ds);
    }