/// <summary>
        /// Converts the node to string expression.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <returns></returns>
        protected override string ConvertNodeToStringExpression(FilterExpressionNode node)
        {
            string retVal = string.Empty;

            if (node.NodeType == FilterExpressionNodeType.OrBlock)
            {
                return(ConvertNodesToStringExpression(node.ChildNodes, "||"));
            }
            if (node.NodeType == FilterExpressionNodeType.AndBlock)
            {
                return(ConvertNodesToStringExpression(node.ChildNodes, "&&"));
            }
            if (node != null && node.Key == FilterExpressionItem.chooseBlock)
            {
                return(retVal);
            }

            ElementDefs elementDef = FindElementDef(node.Key);

            if (elementDef == null)
            {
                throw new ArgumentException("element  " + node.Key + " not registered");
            }

            //is Method Block
            if (elementDef.Methods != null)
            {
                //Get selected methods
                ElementDefs methodDef = elementDef.GetMethodDef(node.Method.Key);
                if (methodDef == null)
                {
                    throw new ArgumentException("method " + node.Method.Key + " not registered");
                }
                //Get methods conditions
                ElementDefs conditionDef = methodDef.GetConditionDefByName(node.Condition.Key);
                if (conditionDef == null)
                {
                    throw new ArgumentException("condition  " + node.Condition.Key + " not registered");
                }
                string collectionName            = elementDef.Name;
                string conditionOp               = conditionDef.Name;
                MethodElementParams methodParams = node.Method.Params;

                string rightStatement = GetEscapedAndCleanedExpressionNodeRightValue(node);

                string predicateExpression = "1 == 1";
                string leftStatement       = null;

                if (node.ChildNodes != null && node.ChildNodes.Count != 0)
                {
                    predicateExpression = ConvertNodesToStringExpression(node.ChildNodes);
                    //Parser bug. Nested double quotes
                    predicateExpression = predicateExpression.Replace('\"', '\'');
                }

                if (methodDef == MethodSumDef)
                {
                    FilterExpressionNode filterNode       = methodParams[0] as FilterExpressionNode;
                    ElementDefs          methodElementDef = FindElementDef(filterNode.Key);
                    if (methodElementDef == null)
                    {
                        throw new ArgumentException("element method" + filterNode.Key + " not registered");
                    }
                    leftStatement = methodElementDef.Name.Replace("this", string.Empty).Trim(new char[] { '[', ']', '\'', '.' });
                    retVal        = String.Format(@"({0}.{1}({2},""{3}"",""{4}"")) {5} {6}", ContextClass, methodDef.Name,
                                                  collectionName, leftStatement, predicateExpression, conditionOp, rightStatement);
                }
                else if (methodDef == MethodCountDef)
                {
                    retVal = String.Format(@"{0}.{1}({2},""{3}"")  {4} {5}", ContextClass, methodDef.Name,
                                           collectionName, predicateExpression, conditionOp, rightStatement);
                }
                else
                {
                    retVal = String.Format(@"{0}.{1}({2},""{3}"")", ContextClass, methodDef.Name,
                                           collectionName, predicateExpression);
                }
            }
            else
            {
                //call base impl
                retVal = base.ConvertNodeToStringExpression(node);
            }

            return(retVal);
        }
        /// <summary>
        /// Converts the node to string expression.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <returns></returns>
        protected override string ConvertNodeToStringExpression(FilterExpressionNode node)
        {
            string expression = String.Empty;

            decimal             quantity     = 0;
            decimal             rewardAmount = 0;
            var                 skuList      = new string[] { };
            MethodElementParams methodParams = null;
            //Find registered element definition by key
            ElementDefs elementDef = FindElementDef(node.Key);

            if (elementDef == null)
            {
                throw new ArgumentException("element " + node.Key + " not registered");
            }
            if (elementDef.Methods != null)
            {
                skuList      = node.Value != null ? ((Dictionary <string, string>)node.Value).Keys.ToArray() : skuList;
                skuList      = EntryId2LineItemCode(skuList).ToArray();
                methodParams = node.Method.Params;
            }
            else
            {
                rewardAmount = Convert.ToDecimal(node.Value);
            }
            //Find registered method definition by key
            ElementDefs methodDef = null;

            if (elementDef.Methods != null)
            {
                methodDef = elementDef.GetMethodDef(node.Method.Key);
            }

            string[] namePart = elementDef.Name.Split(':');

            string rewardAmountType = PromotionRewardAmountType.Value;
            string rewardType       = PromotionRewardType.WholeOrder;

            if (namePart.Count() == 2)
            {
                rewardAmountType = namePart[0];
                rewardType       = namePart[1];
            }

            //gift
            if (methodDef == MethodGiftDefs)
            {
                if (skuList.Count() != 0)
                {
                    quantity = Convert.ToDecimal(methodParams[0]);
                    var skuPattern = skuList.Select(x => String.Format("\"{0}\"", x));
                    expression = String.Format("this.AddFreeGiftToCart(\"{0}\", {1})",
                                               quantity.ToString(CultureInfo.InvariantCulture),
                                               String.Join(",", skuPattern.ToArray()));
                }
            }             //with quantity, amount, sku list
            else if (methodDef == MethodEachEntryDefs)
            {
                quantity     = Convert.ToDecimal(methodParams[1]);
                rewardAmount = Convert.ToDecimal(methodParams[0]);
                if (skuList.Count() != 0)
                {
                    var entryPattern = "this.CreatePromotionEntriesSetFromTarget(\"{0}\", {1})";
                    expression = String.Format("AddPromotionItemRecord(this.CreatePromotionReward(\"{0}\", \"{1}\", \"{2}\"), {3})",
                                               rewardType, rewardAmount.ToString(CultureInfo.InvariantCulture), rewardAmountType,
                                               String.Join(",", skuList.Select(x => String.Format(entryPattern, x, quantity)).ToArray()));
                }
            }             //with amount, sku list
            else if (methodDef == MethodAllEntryDefs || methodDef == MethodAllEntryPercentDefs)
            {
                rewardAmount = Convert.ToDecimal(methodParams[0]);
                if (skuList.Count() != 0)
                {
                    var entryPattern = "this.CreatePromotionEntriesSetFromTarget(\"{0}\")";
                    expression = String.Format("AddPromotionItemRecord(this.CreatePromotionReward(\"{0}\", \"{1}\", \"{2}\"), {3})",
                                               rewardType, rewardAmount.ToString(CultureInfo.InvariantCulture), rewardAmountType,
                                               String.Join(",", skuList.Select(x => String.Format(entryPattern, x)).ToArray()));
                }
            }             // only amount
            else
            {
                var pattern = "this.AddPromotionItemRecord(this.CreatePromotionReward(\"{0}\", \"{1}\", \"{2}\")," +
                              "this.PromotionContext.TargetEntriesSet)";
                expression = String.Format(pattern, rewardType, rewardAmount.ToString(CultureInfo.InvariantCulture), rewardAmountType);
            }

            return(expression);
        }