Imports System.Data.Common
Imports Microsoft.Practices.EnterpriseLibrary.Data
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Collections.Generic
Imports System.Xml
Imports System.Configuration
Imports System.Web
Imports CharterDotCom.CommonEntities.Library
Imports CharterDotCom.CommonEntities.Library.Enumerations
Imports CharterDotCom.CommonEntities.Library.EntityMemberServices
Imports CharterDotCom.CommonEntities.Library.EntityEBSServices
Imports CharterDotCom.CommonEntities.Library.EntitySupport
Imports CharterDotCom.CommonEntities.Library.EntitySearch
Imports CharterDotCom.CommonEntities.Library.EntityWebConfig
Imports CharterDotCom.CommonEntities.Library.EntityG2BServices
Imports CharterDotCom.WebSite.Library.BLCommon

Imports System.Xml.Serialization

Public Class BLAffliateCatalogManager
    Inherits AffliateCatalogClient
    ' class level declarations / variables

    Private _FTAID As String
    Private catalog As BLProductCatalog
    Private featureList As Dictionary(Of String, ISubCartItem)
    Private UndoStack As Stack(Of Items)
    Private promoCode As Dictionary(Of String, String)      '9/2007 jbm added for 4.1
    Private _message As Notification
    Private _undoremove As Boolean = False
    Private receivers As Dictionary(Of String, Receivers)
    Private configdata_content As XmlNode
    Private configdata_ebs As XmlNode
    Private configdata_member As XmlNode
    Private configdata_g2b As XmlNode
    Friend CookieID As String

    Public Sub New()

    End Sub

    Public Sub New(ByVal DictionaryOfVariables As Dictionary(Of String, Object))
        If DictionaryOfVariables.ContainsKey("catalog") Then
            If Not (DictionaryOfVariables("catalog") Is Nothing) Then
                Me.catalog = CType(DictionaryOfVariables("catalog"), BLProductCatalog)
            End If
        End If
        If DictionaryOfVariables.ContainsKey("featureList") Then
            If Not (DictionaryOfVariables("featureList") Is Nothing) Then
                Me.featureList = CType(DictionaryOfVariables("featureList"), Dictionary(Of String, ISubCartItem))
            End If
        End If
        If DictionaryOfVariables.ContainsKey("UndoStack") Then
            If Not (DictionaryOfVariables("UndoStack") Is Nothing) Then
                Me.UndoStack = CType(DictionaryOfVariables("UndoStack"), Stack(Of Items))
            End If
        End If
        If DictionaryOfVariables.ContainsKey("CookieID") Then
            If Not (DictionaryOfVariables("CookieID") Is Nothing) Then
                Me.CookieID = CType(DictionaryOfVariables("CookieID"), String)
            End If
        End If
        If DictionaryOfVariables.ContainsKey("promoCode") Then
            If Not (DictionaryOfVariables("promoCode") Is Nothing) Then
                Me.promoCode = CType(DictionaryOfVariables("promoCode"), Dictionary(Of String, String))
            End If
        End If

    End Sub

    Public ReadOnly Property ValuesForSetSession() As Dictionary(Of String, Object)
        Get
            Dim VarList As New Dictionary(Of String, Object)
            VarList.Add("catalog", Me.catalog)
            VarList.Add("featureList", Me.featureList)
            VarList.Add("UndoStack", Me.UndoStack)
            VarList.Add("CookieID", Me.CookieID)
            VarList.Add("promoCode", Me.promoCode)
            Return VarList
        End Get
    End Property

    Friend Property ProductCatalog() As BLProductCatalog
        Get
            Return catalog
        End Get
        Set(ByVal value As BLProductCatalog)
            catalog = value
        End Set
    End Property

    Private ReadOnly Property sCart() As BLShoppingCart
        Get
            Return CType(catalog.Cart, BLShoppingCart)
        End Get
    End Property

    Protected Overrides Sub PopulateLocalVariables(ByVal trackingID As String)
        Try
            If Not (trackingID Is Nothing) Then
                MyBase.TrackingID = trackingID
                Dim sessionEntry As Object = Session(BLCommon.AffiliateCatalogManagerKey)
                If Not sessionEntry Is Nothing Then
                    Dim lmanager As New BLAffliateCatalogManager(CType(sessionEntry, Dictionary(Of String, Object)))

                    Me.catalog = lmanager.catalog
                    Me.featureList = lmanager.featureList
                    Me.UndoStack = lmanager.UndoStack
                    Me.CookieID = lmanager.CookieID
                    Me.promoCode = lmanager.promoCode
                End If
                'Dim lProviderSection As ProviderSectionHandler = CType(System.Web.HttpContext.Current.Application("ProviderSection"), ProviderSectionHandler)
                'configdata_content = lProviderSection.ProviderData("ContentProvider")
                'configdata_ebs = lProviderSection.ProviderData("EBSServicesProvider")
                'configdata_member = lProviderSection.ProviderData("MemberServicesProvider")
                'configdata_g2b = lProviderSection.ProviderData("G2BServicesProvider")
            End If
        Catch ex As Exception
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        End Try
    End Sub

#Region "Populate catalog functions"

    ''' <summary>
    ''' Returns an Object of type ICatalog which has Bundles and ServivcePlans.
    ''' If a user is Returning User(cookie information is in Database) populates Cart also.
    ''' </summary>
    ''' <returns>An object of type Icatalog which has Bundles and Service plans</returns>
    ''' <remarks>
    '''  Calls QueryOffersProvider's QueryOffers method, which populates catalog object.
    ''' set's Removable Property to all the features in Serviceplans.
    ''' Feature List is created to use in Grid mode.
    ''' If user is Returning user( already visited site) cart is retrived from Database if persisted.
    ''' Rules will be also populated in provider.
    ''' Before calling this method Account Mangager's Localization or SinIn should be called.
    ''' </remarks>
    Public Overrides Function GetCatalog(ByVal trackID As String) As ICatalog
        Try
            PopulateLocalVariables(trackID)
            If catalog Is Nothing Then
                Dim am As New BLAccountManager(CType(Session(AccountManagerKey), Dictionary(Of String, Object)))

                Dim iProvider As IG2BServicesProvider = CType(Activator.GetObject(GetType(IG2BServicesProvider), CStr(HttpContext.Current.Application("RemoteURL_G2BServicesProvider"))), IG2BServicesProvider)

                Dim address As Address = ConvertBLAddressToGwyAddress(CType(am.account.Address, BLAddress))
                Dim account As BLAccount = am.account
                If account.UserStatus = UserStatus.Localized OrElse account.UserStatus = UserStatus.Authenticated OrElse account.UserStatus = UserStatus.Identified Then
                    If account.AddressID Is Nothing OrElse account.AddressID = String.Empty Then
                        ' first time request

                        Dim providerRequest As EntityG2BServices.G2BQueryOffersRequest
                        providerRequest = New EntityG2BServices.G2BQueryOffersRequest(address, Nothing, account.AffliateID) ' ConverToGWYLOB(am.account.AvailableLOB))

                        If Not Me.promoCode Is Nothing Then
                            '9/18/2007 Brad Miller - Add population of promoCode for G2B 4.1
                            providerRequest.PromotionCode = Me.promoCode
                        End If

                        Dim providerResponse As EntityG2BServices.G2BQueryOffersResponse
                        providerResponse = CType(iProvider.QueryOffers(providerRequest), EntityG2BServices.G2BQueryOffersResponse)

                        If Not providerResponse Is Nothing Then
                            If providerResponse.Exception Then
                                BLCommon.LogException(New ApplicationException("Catalog Manager: Cannot retrive Catalog for Address : " + account.Address.Street1 + "," + account.Address.Street2 + "," + account.Address.Zip), ExceptionSeverity.Catastrophic)
                                Return Nothing
                            End If

                            account.TrackingID = providerResponse.TrackingID
                            account.MSOID = providerResponse.MSOID

                            If providerResponse.ProductCatalog Is Nothing Then
                                Return Nothing
                            End If

                            catalog = New BLProductCatalog(providerResponse.ProductCatalog)

                            Call BuildGeneralQuestionList(providerResponse, account)

                        Else
                            BLCommon.LogException(New ApplicationException("Cannot retrive Catalog for Address : " + account.Address.Street1 + "," + account.Address.Street2 + "," + account.Address.Zip), ExceptionSeverity.Catastrophic)
                            Return Nothing
                        End If

                    Else
                        ' this is a resubmit

                        Dim providerRequest As EntityG2BServices.G2BQueryOffersResubmitRequest
                        providerRequest = New EntityG2BServices.G2BQueryOffersResubmitRequest(account.TrackingID, account.MSOID, account.AddressID, account.AffliateID)

                        Dim providerResponse As EntityG2BServices.G2BQueryOffersResubmitResponse
                        providerResponse = CType(iProvider.QueryOffersResubmit(providerRequest), EntityG2BServices.G2BQueryOffersResubmitResponse)

                        If Not providerResponse Is Nothing Then
                            If providerResponse.Exception Then
                                BLCommon.LogException(New ApplicationException("Cannot retrive Catalog for Address : " + account.Address.Street1 + "," + account.Address.Street2 + "," + account.Address.Zip), ExceptionSeverity.Catastrophic)
                                Return Nothing
                            Else
                                If Not providerResponse.ProductCatalog Is Nothing Then
                                    catalog = New BLProductCatalog(providerResponse.ProductCatalog)
                                Else
                                    Return Nothing
                                End If
                            End If

                        Else
                            BLCommon.LogException(New ApplicationException("Cannot retrive Catalog for Address : " + account.Address.Street1 + "," + account.Address.Street2 + "," + account.Address.Zip), ExceptionSeverity.Catastrophic)
                            Return Nothing
                        End If

                    End If

                    PopulateFeatureList()

                    Me.CookieID = am.CookieID
                End If
                SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
                SetSession(AccountManagerKey, am.ValuesForSetSession)
            End If

            Return catalog

        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot get Product Catalog", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try

    End Function

    Private Sub BuildGeneralQuestionList(ByVal providerResponse As EntityG2BServices.G2BQueryOffersResponse, ByVal account As BLAccount)

        '#############################################################################
        '10/24/2007 Brad Miller
        'BUILD A LIST OF NEW AND EXISTING CUSTOMERS IN THE SAME COLLECTION WITH A 
        'DISTINCTION OF THE CUSTOMERTYPE TO SHOW DIFF BETWEEN THE QUESTIONS TO ASK 
        'EACH CUSTOMER
        '#############################################################################


        '##############################################################################
        'BUILD THE LIST FOR THE NEW CUSTOMERS 
        '##############################################################################
        If providerResponse.CustomerAuthFieldDefinition.NewCustomer IsNot Nothing Then
            account.G2B_AuthQuestion = New Dictionary(Of String, IAccount.IAuthQuestion)
            For iItem As Integer = 0 To providerResponse.CustomerAuthFieldDefinition.NewCustomer.Count - 1
                If providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth IsNot Nothing Then
                    For iCustAuth As Integer = 0 To providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth.Count - 1

                        Dim objAuthQuestion As New BLG2BAuthQuestion
                        objAuthQuestion.CustomerType = CustomerType.NewCustomer
                        objAuthQuestion.QuestionID = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth(iCustAuth).authFieldID
                        objAuthQuestion.IsBoolean = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth(iCustAuth).booleanField
                        objAuthQuestion.QuestionDescription = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth(iCustAuth).description
                        objAuthQuestion.MaxLen = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth(iCustAuth).maxLen
                        If Not (providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth(iCustAuth).name Is Nothing) Then
                            objAuthQuestion.QuestionName = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth(iCustAuth).name().Trim().ToUpper()
                        End If
                        objAuthQuestion.AuthQuestionType = eAuthQuestionType.Custom
                        objAuthQuestion.IsMasked = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).CustomAuth(iCustAuth).privateField

                        '##############################################################################
                        'THIS QUESTION CHECK IS FOR DETERMINING IF THE USER SUCESSFULLY AUTHENTICATED 
                        'VIA THE MEMBER SERVICE WEB SERVICE VIA THE MS PROVIDER
                        '##############################################################################
                        If Not (objAuthQuestion.QuestionID Is Nothing) Then
                            If objAuthQuestion.QuestionID.Trim() = "300" Then
                                If account.UserStatus = UserStatus.Authenticated Then
                                    objAuthQuestion.UserResponded = True
                                    objAuthQuestion.AnswerFromUser = "true"
                                End If
                            End If
                        End If

                        If Not account.G2B_AuthQuestion.ContainsKey(objAuthQuestion.QuestionID) Then
                            account.G2B_AuthQuestion.Add(objAuthQuestion.QuestionID, objAuthQuestion)
                        End If

                    Next
                End If

                If providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).StandardAuth IsNot Nothing Then
                    For iStdAuth As Integer = 0 To providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).StandardAuth.Count - 1
                        Dim objAuthQuestion As New BLG2BAuthQuestion

                        objAuthQuestion.QuestionID = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).StandardAuth(iStdAuth).ToString()

                        objAuthQuestion.QuestionName = providerResponse.CustomerAuthFieldDefinition.NewCustomer(iItem).StandardAuth(iStdAuth).ToString().Trim().ToUpper()

                        objAuthQuestion.AuthQuestionType = eAuthQuestionType.Standard

                        If Not account.G2B_AuthQuestion.ContainsKey(objAuthQuestion.QuestionID) Then
                            account.G2B_AuthQuestion.Add(objAuthQuestion.QuestionID, objAuthQuestion)
                        End If
                    Next
                End If
            Next
        End If





        '##############################################################################
        'BUILD THE LIST FOR THE EXISTING CUSTOMERS
        '##############################################################################
        If providerResponse.CustomerAuthFieldDefinition.ExistingCustomer IsNot Nothing Then
            If (account.G2B_AuthQuestion Is Nothing) Then
                account.G2B_AuthQuestion = New Dictionary(Of String, IAccount.IAuthQuestion)
            End If

            For iItem As Integer = 0 To providerResponse.CustomerAuthFieldDefinition.ExistingCustomer.Count - 1
                If providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth IsNot Nothing Then
                    For iCustAuth As Integer = 0 To providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth.Count - 1

                        Dim objAuthQuestion As New BLG2BAuthQuestion
                        objAuthQuestion.CustomerType = CustomerType.ExistingCustomer
                        objAuthQuestion.QuestionID = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).authFieldID
                        objAuthQuestion.IsBoolean = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).booleanField
                        objAuthQuestion.QuestionDescription = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).description
                        objAuthQuestion.MaxLen = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).maxLen
                        If Not (providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).name Is Nothing) Then
                            If Not (providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).name() Is Nothing) Then
                                objAuthQuestion.QuestionName = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).name().Trim().ToUpper()
                            End If
                        End If
                        objAuthQuestion.AuthQuestionType = eAuthQuestionType.Custom
                        objAuthQuestion.IsMasked = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).CustomAuth(iCustAuth).privateField

                        '##############################################################################
                        'THIS QUESTION CHECK IS FOR DETERMINING IF THE USER SUCESSFULLY AUTHENTICATED 
                        'VIA THE MEMBER SERVICE WEB SERVICE VIA THE MS PROVIDER
                        '##############################################################################
                        If Not (objAuthQuestion.QuestionID Is Nothing) Then
                            If objAuthQuestion.QuestionID.Trim() = "300" Then
                                If account.UserStatus = UserStatus.Authenticated Then
                                    objAuthQuestion.UserResponded = True
                                    objAuthQuestion.AnswerFromUser = "true"
                                End If
                            End If
                        End If

                        If Not account.G2B_AuthQuestion.ContainsKey(objAuthQuestion.QuestionID) Then
                            account.G2B_AuthQuestion.Add(objAuthQuestion.QuestionID, objAuthQuestion)
                        End If
                    Next
                End If

                If providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).StandardAuth IsNot Nothing Then
                    For iStdAuth As Integer = 0 To providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).StandardAuth.Count - 1
                        Dim objAuthQuestion As New BLG2BAuthQuestion

                        objAuthQuestion.QuestionID = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).StandardAuth(iStdAuth).ToString()

                        objAuthQuestion.QuestionName = providerResponse.CustomerAuthFieldDefinition.ExistingCustomer(iItem).StandardAuth(iStdAuth).ToString().Trim().ToUpper()


                        objAuthQuestion.AuthQuestionType = eAuthQuestionType.Standard

                        If Not account.G2B_AuthQuestion.ContainsKey(objAuthQuestion.QuestionID) Then
                            account.G2B_AuthQuestion.Add(objAuthQuestion.QuestionID, objAuthQuestion)
                        End If
                    Next
                End If
            Next
        End If



    End Sub


    Private Sub PopulateFeatureList(Optional ByVal providerFactory As String = Nothing)
        Try

            If featureList Is Nothing Then

                featureList = New Dictionary(Of String, ISubCartItem)

                For Each sp As BLServicePlan In catalog.ServicePlans.Values
                    ' sp = CType(item, ServicePlan)
                    For Each f As ISubCartItem In sp.Features.Values
                        AddToFeatureList(f)
                        For Each ch As ISubCartItem In f.Children.Values
                            AddToFeatureList(ch)
                        Next
                    Next
                Next

                SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
            End If

        Catch ex As Exception
            Throw
        End Try

    End Sub

    Private Function GetFeatureCategory(ByVal c As GWYCategory) As FeatureCategory
        Select Case c
            Case GWYCategory.Cable
                Return FeatureCategory.VideoFeature
            Case GWYCategory.HSD
                Return FeatureCategory.DataFeature
            Case GWYCategory.Telephoney
                Return FeatureCategory.VoiceFeature
            Case Else
                Return FeatureCategory.Other
        End Select
    End Function

#End Region

#Region "Cart related functions"

    Friend Sub ClearShoppingCart(ByVal trackingID As String)
        Try
            catalog.ClearCart()
            RefreshFeatureList()
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot Clear cart", ex)
            BLCommon.LogException(aex, ExceptionSeverity.High)
            Throw aex
        End Try
    End Sub

    ''' <summary>
    '''  Adds Bundles and Service Plans to the shopping cart.
    ''' </summary>
    ''' <param name="itemID"> ID of BUndle/ Service Plan that should be added to cart</param>
    ''' <param name="trackID">TrackingID of he request</param>
    ''' <remarks> 
    ''' From given ItemID checks to see if it a bundle or service plan, and calls AddItemToCart with appropriate item.
    ''' Dynamic Bundling will be done.
    ''' UndoStack will be cleared.
    ''' Refreshes FeatureList.
    ''' Invokes Notify delegate about any unexpected changes to ShoppingCart.
    ''' Updates Shopping cart price.
    ''' After all the Chages are done adds CatalogManager to session.
    ''' </remarks>

    Public Overrides Function AddCartItem(ByVal trackID As String, ByVal itemID As String) As INotification
        Dim item As ICartItem
        Try
            PopulateLocalVariables(trackID)
            If catalog.Cart.Submitted Then
                ClearShoppingCart(trackID)
                CType(catalog.Cart, BLShoppingCart).OrderSubmitted = False
            End If
            'if item type is bundle then, add all the children(service plans) to cart insted of bundle itself
            If catalog.Bundles.ContainsKey(itemID) Then
                item = catalog.Bundles(itemID)

                ' set cart notification message
                _message = New Notification(NotificationAction.Add, item.Name, NotificationCode.Success)

                AddItemToCart(item)

            Else
                If catalog.ServicePlans.ContainsKey(itemID) Then
                    item = catalog.ServicePlans(itemID)

                    ' set cart notification message
                    _message = New Notification(NotificationAction.Add, item.Name, NotificationCode.Success)

                    AddItemToCart(item)

                End If
            End If

            ' When an item is added clear un do stack
            ClearUnDoStack()

            RefreshFeatureList()
            'To update prices
            sCart.UpdateCartItemsPrice()

            SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)

            Return _message

        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot add item to cart", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try

        Return Nothing
    End Function

    Private Sub AddItemToCart(ByVal item As ICartItem, Optional ByVal userSelectionList As Dictionary(Of String, CartSelections) = Nothing, Optional ByVal doDynamicBundle As Boolean = True)
        Dim cartItemsWithcategory As Dictionary(Of String, CartSelections)
        'Commented user selection logic as every cart item is user selected    
        Dim objCartSelection As CartSelections
        Dim objServicePlan As BLServicePlan

        If userSelectionList Is Nothing Then
            cartItemsWithcategory = GetCartItemsWithcategory()
        Else
            cartItemsWithcategory = userSelectionList
        End If

        If Not cartItemsWithcategory.ContainsKey(item.ID) Then

            objCartSelection.Category = item.Category
            objCartSelection.FeatureType = FeatureType.NotSpecified

            cartItemsWithcategory.Add(item.ID, objCartSelection)
        End If

        sCart.AddCartItem(item)
        catalog.Refresh(item, False, True, cartItemsWithcategory)


    End Sub

    ''' <summary>
    ''' Adds a Feature to Shopping Cart.
    ''' </summary>
    ''' <param name="itemID">ID of feature that should be added to cart.</param>
    ''' <param name="trackID">TrackingID of he request</param>
    ''' <remarks>
    ''' Finds appropriate service plan based on the current selection and the existing items in the cart by calling FindServicePlan method.
    ''' Adds the ServicePlan found in above method to cart. 
    ''' selected item will be added as sub item to the service plan.
    ''' If there is a change in Service plan with current selections Carries any customization selections to new ServicePlan.
    ''' Applies Dynamic Bundling.
    ''' UndoStack will be cleared.
    ''' Refreshes FeatureList.
    ''' Invokes Notify delegate about any unexpected changes to ShoppingCart.
    ''' Updates Shopping cart price.
    ''' After all the Chages are done adds CatalogManager to session.
    ''' </remarks>
    Public Overrides Function AddSubCartItemWithParent(ByVal trackID As String, ByVal itemID As String, ByVal ParentID As String) As INotification
        Dim receiverLogic As Boolean = False
        Dim item As ISubCartItem
        If receivers Is Nothing Then receivers = GenerateReceivers()
        Try
            If (ParentID Is Nothing) Then
                receiverLogic = False
            Else
                If Not receivers.ContainsKey(ParentID) Then
                    receiverLogic = False
                Else
                    Select Case receivers(ParentID)
                        Case BLCommon.Receivers.HDTV_OR_DVR_SERVICE, BLCommon.Receivers.HDTV_TIER
                            receiverLogic = False
                        Case Else
                            Select Case receivers(itemID)
                                Case BLCommon.Receivers.DVR_MULTI, BLCommon.Receivers.HD_MULTI, BLCommon.Receivers.HD_EQUIP_2, BLCommon.Receivers.EQUIP_2
                                    receiverLogic = False
                                Case Else
                                    receiverLogic = True
                            End Select
                    End Select
                End If

            End If

            If Not receiverLogic Then
                PopulateLocalVariables(trackID)
                ' returning after submitting order
                If catalog.Cart.Submitted Then
                    ClearShoppingCart(trackID)
                    CType(catalog.Cart, BLShoppingCart).OrderSubmitted = False
                End If

                If featureList.TryGetValue(itemID, item) Then

                    ' set cart notification message
                    _message = New Notification(NotificationAction.Add, item.Name, NotificationCode.Success)
                    If Not ParentID Is Nothing Then
                        AddSubItemToCart_Checkout(item)
                    End If

                    Return _message

                End If
            Else
                PopulateLocalVariables(trackID)
                If featureList.TryGetValue(itemID, item) Then

                    ' set cart notification message
                    _message = New Notification(NotificationAction.Add, item.Name, NotificationCode.Success)
                    AddSubItemToCart(item, ParentID)

                    Return _message

                End If
            End If
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot add feature to Cart")
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try

        Return Nothing
    End Function

    Private Sub AddSubItemToCart_Checkout(ByVal item As ISubCartItem)
        If Not item Is Nothing Then
            Dim objCartSelection As CartSelections
            Dim sp As BLServicePlan
            Dim cartItemsWithCategory As Dictionary(Of String, CartSelections)
            cartItemsWithCategory = GetCartItemsWithcategory()
            If cartItemsWithCategory Is Nothing Then
                cartItemsWithCategory = New Dictionary(Of String, CartSelections)
            End If

            objCartSelection.Category = item.Category
            objCartSelection.FeatureType = item.FeatureType

            If Not cartItemsWithCategory.ContainsKey(item.ID) Then cartItemsWithCategory.Add(item.ID, objCartSelection)

            For Each objitem As ICartItem In catalog.Cart.CartItems.Values
                If objitem.Type = ItemType.Bundle Then
                    For Each objsubitem As ISubCartItem In objitem.Children.Values
                        If objsubitem.Category = item.Category Then
                            sp = CType(objsubitem, BLServicePlan)
                            Exit For
                        End If
                    Next
                Else
                    If objitem.Category = item.Category Then
                        sp = CType(objitem, BLServicePlan)
                        Exit For
                    End If
                End If
            Next


            Dim objFeature As BLFeature = FindOption(sp.ID, item.ID)
            If Not objFeature Is Nothing Then
                Dim strTemp As String = UpdateSelectedChoices(objFeature, item.ID, True, cartItemsWithCategory, sp)
                objCartSelection = cartItemsWithCategory(item.ID)
                objCartSelection.FeatureType = FeatureType.IsOptional
                cartItemsWithCategory(item.ID) = objCartSelection
                If Not strTemp Is Nothing Then
                    cartItemsWithCategory.Add(strTemp, objCartSelection)
                End If
            End If
            catalog.Refresh(sp, False, True, cartItemsWithCategory)

            RefreshFeatureList()
            'To update prices
            sCart.UpdateCartItemsPrice()

            ' when an item is added uoDo remove should be set to false and lcear stack
            ClearUnDoStack()

            SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
        End If

    End Sub

    Private Sub AddSubItemToCart(ByVal item As ISubCartItem, ByVal parentID As String)
        If Not item Is Nothing Then
            Dim objCartSelection As CartSelections
            Dim sp As BLServicePlan
            Dim cartItemsWithCategory As Dictionary(Of String, CartSelections)
            cartItemsWithCategory = GetCartItemsWithcategory()
            If cartItemsWithCategory Is Nothing Then
                cartItemsWithCategory = New Dictionary(Of String, CartSelections)
            End If

            objCartSelection.Category = item.Category
            objCartSelection.FeatureType = item.FeatureType

            If Not cartItemsWithCategory.ContainsKey(item.ID) Then cartItemsWithCategory.Add(item.ID, objCartSelection)


            For Each objitem As ICartItem In catalog.Cart.CartItems.Values
                If objitem.Type = ItemType.Bundle Then
                    For Each objsubitem As ISubCartItem In objitem.Children.Values
                        If objsubitem.Category = item.Category Then
                            sp = CType(objsubitem, BLServicePlan)
                            Exit For
                        End If
                    Next
                Else
                    If objitem.Category = item.Category Then
                        sp = CType(objitem, BLServicePlan)
                        Exit For
                    End If
                End If
            Next

            Dim subitem As ISubCartItem
            Dim f As BLFeature

            If sp.Features.TryGetValue(BLCommon.GetKey(BLCommon.Receivers.TV_NUMBERS, receivers), subitem) Then
                f = DirectCast(subitem, BLFeature)
                Dim strTemp As String = UpdateTVOptions(sp, receivers, f.SelectedChoices, parentID, item.ID)
                objCartSelection = cartItemsWithCategory(item.ID)
                objCartSelection.FeatureType = FeatureType.IsOptional
                cartItemsWithCategory(item.ID) = objCartSelection
                If Not strTemp Is Nothing Then
                    cartItemsWithCategory.Add(strTemp, objCartSelection)
                End If
                If f.SelectedChoices.Count > 0 Then
                    Dim cartsel As CartSelections
                    cartsel.Category = f.Category
                    cartsel.FeatureType = f.FeatureType
                    If Not cartItemsWithCategory.ContainsKey(f.ID) Then cartItemsWithCategory.Add(f.ID, cartsel)
                End If
                catalog.Refresh(sp, False, True, cartItemsWithCategory)
                RefreshFeatureList()
                'To update prices
                sCart.UpdateCartItemsPrice()

                ' when an item is added uoDo remove should be set to false and lcear stack
                ClearUnDoStack()

                SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
            Else
                Exit Sub
            End If


        End If
    End Sub

    '9/18/2007 Brad Miller - Added for G2B 4.1
    Public Sub PopulatePromoCodes(ByVal pc As String)
        If promoCode Is Nothing Then
            promoCode = New Dictionary(Of String, String)
        End If
        If Not promoCode.ContainsKey(pc) Then
            promoCode.Add(pc, pc)
        End If
    End Sub

    Private Function UpdateHDTV_DVR_Service(ByRef sp As BLServicePlan) As Boolean
        Try
            'TO DO: CHange this from hard-coded to drive from Affiliate receivers
            Dim strTempKey_HDTVDVR As String = "410007" 'Common.GetKey(Common.Receivers.HDTV_OR_DVR_SERVICE, receivers)
            Dim strTempKey_TVNUM As String = BLCommon.GetKey(BLCommon.Receivers.TV_NUMBERS, receivers)
            Dim strTempKey_HDTVTIER As String = BLCommon.GetKey(BLCommon.Receivers.HDTV_TIER, receivers)

            Dim subItem_HDTVDVR As ISubCartItem
            Dim subitem_TVNUM As ISubCartItem
            Dim subitem_HDTVTIER As ISubCartItem

            If sp.Features.TryGetValue(strTempKey_HDTVDVR, subItem_HDTVDVR) Then
                Dim f_HDTVDVR As BLFeature = CType(subItem_HDTVDVR, BLFeature)
                'f_HDTVDVR.SelectedChoices.Clear()

                If sp.Features.TryGetValue(strTempKey_HDTVTIER, subitem_HDTVTIER) Then
                    Dim f_HDTVTier As BLFeature = CType(subitem_HDTVTIER, BLFeature)
                    If f_HDTVTier.SelectedChoices.Count > 0 Then
                        If Not f_HDTVDVR.SelectedChoices.Contains(BLCommon.GetKey(BLCommon.Receivers.HDTV_SERVICE, receivers)) Then f_HDTVDVR.SelectedChoices.Add(BLCommon.GetKey(BLCommon.Receivers.HDTV_SERVICE, receivers))
                    End If
                End If

                If sp.Features.TryGetValue(strTempKey_TVNUM, subitem_TVNUM) Then
                    Dim f_TVNUM As BLFeature = CType(subitem_TVNUM, BLFeature)
                    If f_TVNUM.SelectedChoices.Count > 0 Then

                        If f_TVNUM.SelectedChoices.Exists(AddressOf IsHDTV) Then
                            If Not f_HDTVDVR.SelectedChoices.Contains(BLCommon.GetKey(BLCommon.Receivers.HDTV_SERVICE, receivers)) Then f_HDTVDVR.SelectedChoices.Add(BLCommon.GetKey(BLCommon.Receivers.HDTV_SERVICE, receivers))
                        End If

                        If f_TVNUM.SelectedChoices.Exists(AddressOf IsDVR) Then
                            If Not f_HDTVDVR.SelectedChoices.Contains(BLCommon.GetKey(BLCommon.Receivers.DVR_SERVICE, receivers)) Then f_HDTVDVR.SelectedChoices.Add(BLCommon.GetKey(BLCommon.Receivers.DVR_SERVICE, receivers))
                        End If
                    End If
                End If

            End If

        Catch ex As Exception
            Throw ex
        End Try

    End Function

    Private Function IsHDTV(ByVal s As String) As Boolean
        Try
            If InStr(s, BLCommon.GetKey(BLCommon.Receivers.HD, receivers)) > 0 Or InStr(s, BLCommon.GetKey(BLCommon.Receivers.HD_MULTI, receivers)) > 0 Then
                Return True
            Else
                Return False
            End If

        Catch ex As Exception
            Return False
        End Try
    End Function

    Private Function IsDVR(ByVal s As String) As Boolean
        Try
            If InStr(s, BLCommon.GetKey(BLCommon.Receivers.DVR_1, receivers)) > 0 Or InStr(s, BLCommon.GetKey(BLCommon.Receivers.DVR_MULTI, receivers)) > 0 Or InStr(s, BLCommon.GetKey(BLCommon.Receivers.HD_1, receivers)) > 0 Then
                Return True
            Else
                Return False
            End If

        Catch ex As Exception
            Return False
        End Try
    End Function

    Private Function GenerateReceivers() As Dictionary(Of String, Receivers)
        Try
            If Not HttpContext.Current.Application("Receivers") Is Nothing Then
                Return CType(HttpContext.Current.Application("Receivers"), Dictionary(Of String, Receivers))
            Else
                Return Nothing
            End If
        Catch ex As Exception
            Throw ex
        End Try
    End Function

    Private Function UpdateTVOptions(ByRef sp As BLServicePlan, ByVal dict As Dictionary(Of String, Receivers), ByRef selections As List(Of String), Optional ByVal ParentID As String = Nothing, Optional ByVal choiceID As String = Nothing) As String
        Try
            Dim subitem As ISubCartItem
            Dim f As BLFeature

            Dim objList As New List(Of String)

            If Not ParentID Is Nothing Then
                Select Case dict(ParentID)
                    Case BLCommon.Receivers.TV_1
                        If selections.Count = 0 Then
                            selections.Add("1" & choiceID)
                        Else
                            If selections.Count > 1 AndAlso (selections(0) = "1" & BLCommon.GetKey(BLCommon.Receivers.DVR_MULTI, dict) Or selections(0) = "1" & BLCommon.GetKey(BLCommon.Receivers.HD_MULTI, dict)) Then
                                selections(0) = "1" & choiceID
                                selections.RemoveAt(1)
                            Else
                                selections(0) = "1" & choiceID
                            End If
                        End If
                    Case BLCommon.Receivers.TV_2
                        If selections.Count > 1 AndAlso (selections(0) = "1" & BLCommon.GetKey(BLCommon.Receivers.DVR_MULTI, dict) Or selections(0) = "1" & BLCommon.GetKey(BLCommon.Receivers.HD_MULTI, dict)) Then
                            _message.SetMessageResult(String.Empty, String.Empty, NotificationCode.CannotAddCustomization, NotificationSeverity.IsError)
                            Return Nothing
                        End If
                        If selections.Count = 1 Then
                            selections.Add("2" & choiceID)
                        Else
                            selections(1) = "2" & choiceID
                        End If
                    Case BLCommon.Receivers.TV_3
                        If selections.Count = 2 Then
                            selections.Add("3" & choiceID)
                        Else
                            selections(2) = "3" & choiceID
                        End If
                    Case BLCommon.Receivers.TV_4
                        If selections.Count = 3 Then
                            selections.Add("4" & choiceID)
                        Else
                            selections(3) = "4" & choiceID
                        End If
                End Select
            End If
            'UPDATE TV 1 Option
            If sp.Features.TryGetValue(BLCommon.GetKey(BLCommon.Receivers.TV_1, dict), subitem) Then
                f = DirectCast(subitem, BLFeature)
                f.SelectedChoices.Clear()
                If selections.Count > 0 Then
                    Dim strTemp As String = Right(selections(0), selections(0).Length - 1)
                    If strTemp = BLCommon.GetKey(BLCommon.Receivers.RECEIVER, dict) Then
                        Dim strTemp1 As String = BLCommon.GetKey(BLCommon.Receivers.INCLUDED, dict)
                        f.SelectedChoices.Add(strTemp1)
                        objList.Add("1" & strTemp1)
                        UpdateTVOptions = strTemp1
                    Else
                        f.SelectedChoices.Add(Right(selections(0), selections(0).Length - 1))
                        objList.Add("1" & Right(selections(0), selections(0).Length - 1))
                    End If
                End If
            End If

            'UPDATE TV 2 Option
            If sp.Features.TryGetValue(BLCommon.GetKey(BLCommon.Receivers.TV_2, dict), subitem) Then
                f = DirectCast(subitem, BLFeature)
                f.SelectedChoices.Clear()
                If selections.Count > 1 Then
                    Dim strTemp As String = Right(selections(1), selections(1).Length - 1)
                    If strTemp = BLCommon.GetKey(BLCommon.Receivers.HD_EQUIP_2, dict) Or strTemp = BLCommon.GetKey(BLCommon.Receivers.EQUIP_2, dict) Then
                        Dim subItem1 As ISubCartItem
                        If f.Choices.TryGetValue(strTemp, subItem1) Then
                            Dim f1 As BLFeature = DirectCast(subItem1, BLFeature)
                            f1.ISRemovable = False
                        End If
                    End If
                    If strTemp = BLCommon.GetKey(BLCommon.Receivers.INCLUDED, dict) Then
                        Dim strTemp1 As String = BLCommon.GetKey(BLCommon.Receivers.RECEIVER, dict)
                        f.SelectedChoices.Add(strTemp1)
                        objList.Add("2" & strTemp1)
                        UpdateTVOptions = strTemp1
                    Else
                        f.SelectedChoices.Add(strTemp)
                        objList.Add("2" & strTemp)
                    End If

                End If
            End If

            'UPDATE TV 3 Option
            If sp.Features.TryGetValue(BLCommon.GetKey(BLCommon.Receivers.TV_3, dict), subitem) Then
                f = DirectCast(subitem, BLFeature)
                f.SelectedChoices.Clear()
                If selections.Count > 2 Then
                    f.SelectedChoices.Add(Right(selections(2), selections(2).Length - 1))
                    'selections.Add("3" & Right(selections(2), selections(2).Length - 1))
                    'selections.RemoveAt(0)
                    objList.Add("3" & Right(selections(2), selections(2).Length - 1))
                End If
            End If

            'UPDATE TV 4 Option
            If sp.Features.TryGetValue(BLCommon.GetKey(BLCommon.Receivers.TV_4, dict), subitem) Then
                f = DirectCast(subitem, BLFeature)
                f.SelectedChoices.Clear()
                If selections.Count > 3 Then
                    f.SelectedChoices.Add(Right(selections(3), selections(3).Length - 1))
                    'selections.Add("4" & Right(selections(3), selections(3).Length - 1))
                    'selections.RemoveAt(0)
                    objList.Add("4" & Right(selections(3), selections(3).Length - 1))
                End If
            End If

            If sp.Features.TryGetValue(BLCommon.GetKey(BLCommon.Receivers.TV_NUMBERS, dict), subitem) Then
                f = DirectCast(subitem, BLFeature)
                f.SelectedChoices.Clear()
                f.SelectedChoices.AddRange(objList)
                f.QuantitySelected = objList.Count
                If objList.Count > 0 Then
                    f.ISSelected = True
                End If
            End If

        Catch ex As Exception
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        End Try
    End Function

    Private Function FindOption(ByVal spID As String, ByVal itemID As String) As BLFeature

        Dim sp As BLServicePlan

        If catalog.Cart Is Nothing Then
            Return Nothing
        End If

        If catalog.Cart.CartItems.ContainsKey(spID) Then
            sp = CType(catalog.Cart.CartItems(spID), BLServicePlan)
        Else
            For Each objCartItem As ICartItem In catalog.Cart.CartItems.Values
                If objCartItem.Type = ItemType.Bundle AndAlso objCartItem.Children.ContainsKey(spID) Then
                    sp = CType(objCartItem.Children(spID), BLServicePlan)
                End If
            Next
        End If

        If sp Is Nothing Then
            sp = CType(catalog.ServicePlans(spID), BLServicePlan)
        End If

        For Each f As BLFeature In sp.Features.Values
            If f.ID = itemID Then
                Return Nothing
            Else
                If Not f.Choices Is Nothing AndAlso f.Choices.Count > 0 Then
                    Dim objChoice As ISubCartItem
                    If f.Choices.TryGetValue(itemID, objChoice) Then
                        Return f
                    End If
                End If
            End If
        Next
        Return Nothing
    End Function

    ''' <summary>
    ''' this method provides functionality to remove Bundle / Service Plan / Promotion from the shopping cart.
    ''' </summary>
    ''' <param name="itemID">ID of BUndle/ Service Plan that should be removed from cart</param>
    ''' <remarks>
    ''' From given ItemID finds the item, and calls RemoveItemFromCart.
    ''' Dynamic Bundling will be done.
    ''' Updates UndoStack with the new item.
    ''' Refreshes FeatureList.
    ''' Invokes Notify delegate about any unexpected changes to ShoppingCart.
    ''' Updates Shopping cart price.
    ''' After all the Chages are done adds CatalogManager to session.
    ''' </remarks>
    Public Overrides Function RemoveCartItem(ByVal trackID As String, ByVal itemID As String) As INotification
        Try
            PopulateLocalVariables(trackID)
            Dim strName As String
            ' set cart notification message
            If catalog.Cart.CartItems.ContainsKey(itemID) Then
                strName = catalog.Cart.CartItems(itemID).Name
                ' when an item is removed push it to undo remove stack
                PushToUnDoStack(CreateUnDoStackItem(catalog.Cart.CartItems(itemID)))
            Else
                For Each i As ICartItem In catalog.Cart.CartItems.Values
                    If i.Type = ItemType.Bundle Then
                        For Each si As BLServicePlan In i.Children.Values
                            If si.ID = itemID Then
                                strName = si.Name
                                ' when an item is removed puch it to undo remove stack
                                PushToUnDoStack(CreateUnDoStackItem(si))
                                Exit For
                            End If
                        Next
                    End If
                Next
            End If

            _message = New Notification(NotificationAction.Remove, strName, NotificationCode.Success)

            RemoveItemFromCart(itemID, Nothing)

            RefreshFeatureList()
            'To update prices
            sCart.UpdateCartItemsPrice()

            SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
            Return _message
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot remove from cart", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try

        Return Nothing
    End Function

    Private Sub RemoveItemFromCart(ByVal itemID As String, ByVal userSelections As Dictionary(Of String, CartSelections))
        Dim item As ICartItem
        Dim subItem As ISubCartItem
        If catalog.Cart.CartItems.ContainsKey(itemID) Then
            item = catalog.Cart.CartItems(itemID)
        Else
            For Each i As ICartItem In catalog.Cart.CartItems.Values
                If i.Type = ItemType.Bundle Then
                    If i.Children.ContainsKey(itemID) Then
                        subItem = i.Children(itemID)
                    End If
                End If
            Next
        End If

        If userSelections Is Nothing Then
            userSelections = GetCartItemsWithcategory()
            UpdateSelectedChoices(itemID)
        End If

        userSelections.Remove(itemID)
        If Not item Is Nothing Then
            sCart.RemoveCartItem(item.ID)
            catalog.Refresh(item, True, False, userSelections)
        End If

    End Sub

    ' clears all selected choices in a bundle \Service plan
    Private Sub UpdateSelectedChoices(ByVal itemID As String)
        Dim item As ICartItem

        For Each i As ICartItem In catalog.Cart.CartItems.Values
            If i.ID = itemID Then
                item = i
                Exit For
            Else
                If i.Children.ContainsKey(itemID) Then
                    item = DirectCast(i.Children(itemID), BLServicePlan)
                End If
            End If
        Next
        'DirectCast(catalog.Cart, ShoppingCart).ClearMessage()
        '' set cart notification message
        'DirectCast(catalog.Cart, ShoppingCart).SetMessageInput("Remove", item.Description)

        If item.Type = ItemType.Bundle Then
            For Each sp As BLServicePlan In item.Children.Values
                For Each f As BLFeature In sp.Features.Values
                    If f.FeatureType = FeatureType.IsOptional AndAlso Not f.ChoicesSelection Is Nothing Then
                        f.SelectedChoices.Clear()
                    End If
                Next
            Next
        Else
            For Each f As BLFeature In item.Children.Values
                If f.FeatureType = FeatureType.IsOptional AndAlso Not f.ChoicesSelection Is Nothing Then
                    f.SelectedChoices.Clear()
                End If
            Next
        End If

    End Sub

    Private Function UpdateSelectedChoices(ByVal objFeature As BLFeature, ByVal choiceID As String, ByVal Add As Boolean, ByRef cartitems As Dictionary(Of String, CartSelections), Optional ByVal sp As BLServicePlan = Nothing) As String
        Try
            If Add Then

                receivers = GenerateReceivers()

                'If (Not receivers.ContainsKey(choiceID)) Then

                If objFeature.ChoicesSelection.Count < objFeature.MaxChoiceSelection Then
                    objFeature.SelectedChoices.Add(choiceID)
                Else
                    If objFeature.MaxChoiceSelection = 1 Then
                        objFeature.SelectedChoices.RemoveAt(0)
                        objFeature.SelectedChoices.Add(choiceID)
                    Else
                        _message.SetMessageResult(String.Empty, String.Empty, NotificationCode.CannotAddCustomization, NotificationSeverity.IsError)
                    End If
                End If

                If objFeature.ID = BLCommon.GetKey(BLCommon.Receivers.HDTV_TIER, receivers) Then
                    UpdateHDTV_DVR_Service(sp)
                End If

                'Else
                '  Dim strTemp As String = Common.GetKey(Common.Receivers.TV_NUMBERS, receivers)
                '  Dim subitem As ISubCartItem
                '  If sp.Features.TryGetValue(strTemp, subitem) Then
                '    Dim f As BLFeature = DirectCast(subitem, BLFeature)
                '    Dim intCount As Integer = f.SelectedChoices.Count

                '    Select Case receivers(choiceID)

                '      Case Common.Receivers.RECEIVER
                '        Select Case intCount
                '          Case 0
                '            f.SelectedChoices.Add("1" & Common.GetKey(Common.Receivers.INCLUDED, receivers))
                '            UpdateSelectedChoices = Common.GetKey(Common.Receivers.INCLUDED, receivers)
                '          Case 4
                '            _message.SetMessageResult(String.Empty, String.Empty, NotificationCode.CannotAddCustomization, NotificationSeverity.IsError)
                '          Case Else
                '            f.SelectedChoices.Add(intCount + 1 & Common.GetKey(Common.Receivers.RECEIVER, receivers))
                '        End Select
                '        UpdateTVOptions(sp, receivers, f.SelectedChoices)

                '      Case Common.Receivers.HD

                '        If f.SelectedChoices.Contains("1" & Common.GetKey(Common.Receivers.HD, receivers)) Or f.SelectedChoices.Contains("2" & Common.GetKey(Common.Receivers.HD, receivers)) Or f.SelectedChoices.Contains("3" & Common.GetKey(Common.Receivers.HD, receivers)) Then
                '          _message.SetMessageResult(String.Empty, String.Empty, NotificationCode.CannotAddCustomization, NotificationSeverity.IsError)
                '          Exit Function
                '        End If

                '        Select Case intCount
                '          Case 0, 1, 2
                '            f.SelectedChoices.Add(intCount + 1 & Common.GetKey(Common.Receivers.HD, receivers))
                '          Case 4
                '            _message.SetMessageResult(String.Empty, String.Empty, NotificationCode.CannotAddCustomization, NotificationSeverity.IsError)
                '          Case Else
                '            f.SelectedChoices.Insert(2, "3" & Common.GetKey(Common.Receivers.HD, receivers))
                '        End Select
                '        UpdateTVOptions(sp, receivers, f.SelectedChoices)


                '      Case Common.Receivers.DVR_1, Common.Receivers.HD_1

                '        If intCount > 0 Then
                '          If f.SelectedChoices(0) = "1" & Common.GetKey(Common.Receivers.DVR_MULTI, receivers) Or f.SelectedChoices(0) = "1" & Common.GetKey(Common.Receivers.HD_MULTI, receivers) Then
                '            f.SelectedChoices.RemoveAt(0)
                '            f.SelectedChoices.RemoveAt(0)
                '          Else
                '            If f.SelectedChoices(0) = "1" & Common.GetKey(Common.Receivers.HD_1, receivers) Or f.SelectedChoices(0) = "1" & Common.GetKey(Common.Receivers.DVR_1, receivers) Then
                '              f.SelectedChoices.RemoveAt(0)
                '            End If
                '          End If
                '        End If
                '        intCount = f.SelectedChoices.Count
                '        Select Case intCount
                '          Case 0
                '            f.SelectedChoices.Add("1" & Common.GetKey(receivers(choiceID), receivers))
                '          Case Else
                '            f.SelectedChoices.Insert(0, "1" & Common.GetKey(receivers(choiceID), receivers))
                '        End Select
                '        UpdateTVOptions(sp, receivers, f.SelectedChoices)

                '      Case Common.Receivers.DVR_MULTI

                '        If intCount > 0 Then
                '          If f.SelectedChoices.Contains("1" & Common.GetKey(Common.Receivers.HD_MULTI, receivers)) Then
                '            f.SelectedChoices.RemoveAt(0)
                '            f.SelectedChoices.RemoveAt(0)
                '          Else
                '            f.SelectedChoices.RemoveAt(0)
                '          End If
                '        End If
                '        intCount = f.SelectedChoices.Count

                '        If f.SelectedChoices.Contains("3" & Common.GetKey(Common.Receivers.HD, receivers)) Then
                '          f.SelectedChoices.RemoveAt(1)
                '          f.SelectedChoices.Insert(0, 1 & Common.GetKey(Common.Receivers.DVR_MULTI, receivers))
                '          f.SelectedChoices.Insert(1, 2 & Common.GetKey(Common.Receivers.EQUIP_2, receivers))
                '          f.SelectedChoices.Insert(2, 3 & Common.GetKey(Common.Receivers.HD, receivers))
                '        Else
                '          f.SelectedChoices.Insert(0, 1 & Common.GetKey(Common.Receivers.DVR_MULTI, receivers))
                '          f.SelectedChoices.Insert(1, 2 & Common.GetKey(Common.Receivers.EQUIP_2, receivers))
                '        End If
                '        UpdateSelectedChoices = Common.GetKey(Common.Receivers.EQUIP_2, receivers)
                '        UpdateTVOptions(sp, receivers, f.SelectedChoices)

                '      Case Common.Receivers.HD_MULTI

                '        If intCount > 0 Then
                '          If f.SelectedChoices(0) = "1" & Common.GetKey(Common.Receivers.DVR_MULTI, receivers) Then
                '            f.SelectedChoices.RemoveAt(0)
                '            f.SelectedChoices.RemoveAt(0)
                '          Else
                '            f.SelectedChoices.RemoveAt(0)
                '          End If
                '        End If

                '        intCount = f.SelectedChoices.Count
                '        Select Case intCount
                '          Case 0, 1, 2
                '            f.SelectedChoices.Insert(0, 1 & Common.GetKey(Common.Receivers.HD_MULTI, receivers))
                '            f.SelectedChoices.Insert(1, 2 & Common.GetKey(Common.Receivers.HD_EQUIP_2, receivers))
                '          Case Else
                '            If f.SelectedChoices.Contains("3" & Common.GetKey(Common.Receivers.HD_1, receivers)) Then
                '              f.SelectedChoices.RemoveAt(1)
                '              f.SelectedChoices.Insert(0, 1 & Common.GetKey(Common.Receivers.HD_MULTI, receivers))
                '              f.SelectedChoices.Insert(1, 2 & Common.GetKey(Common.Receivers.HD_EQUIP_2, receivers))
                '              f.SelectedChoices.Insert(2, 3 & Common.GetKey(Common.Receivers.HD_1, receivers))
                '            Else
                '              f.SelectedChoices.Insert(0, 1 & Common.GetKey(Common.Receivers.HD_MULTI, receivers))
                '              f.SelectedChoices.Insert(1, 2 & Common.GetKey(Common.Receivers.HD_EQUIP_2, receivers))
                '            End If
                '        End Select
                '        UpdateSelectedChoices = Common.GetKey(Common.Receivers.HD_EQUIP_2, receivers)
                '        UpdateTVOptions(sp, receivers, f.SelectedChoices)

                '      Case Common.Receivers.EQUIP_2, Common.Receivers.HD_EQUIP_2
                '      Case Common.Receivers.INCLUDED
                '        Select Case intCount
                '          Case 0
                '            f.SelectedChoices.Add("1" & Common.GetKey(Common.Receivers.INCLUDED, receivers))
                '            UpdateSelectedChoices = Common.GetKey(Common.Receivers.INCLUDED, receivers)
                '          Case 4
                '            _message.SetMessageResult(String.Empty, String.Empty, NotificationCode.CannotAddCustomization, NotificationSeverity.IsError)
                '          Case Else
                '            f.SelectedChoices.Add(intCount + 1 & Common.GetKey(Common.Receivers.RECEIVER, receivers))
                '        End Select
                '        UpdateTVOptions(sp, receivers, f.SelectedChoices)
                '      Case Else
                '        If objFeature.ChoicesSelection.Count < objFeature.MaxChoiceSelection Then
                '          objFeature.SelectedChoices.Add(choiceID)
                '        Else
                '          If objFeature.MaxChoiceSelection = 1 Then
                '            objFeature.SelectedChoices.RemoveAt(0)
                '            objFeature.SelectedChoices.Add(choiceID)
                '          Else
                '            _message.SetMessageResult(String.Empty, String.Empty, NotificationCode.CannotAddCustomization, NotificationSeverity.IsError)
                '          End If
                '        End If
                '    End Select
                '    If f.SelectedChoices.Count > 0 Then
                '      Dim cartsel As CartSelections
                '      cartsel.Category = f.Category
                '      cartsel.FeatureType = f.FeatureType
                '      If Not cartitems.ContainsKey(f.ID) Then cartitems.Add(f.ID, cartsel)
                '    End If
                '  End If
                '  UpdateHDTV_DVR_Service(sp)
                'End If

            Else

                receivers = GenerateReceivers()
                'If receivers.ContainsKey(choiceID) Then

                '  If receivers(choiceID) = Common.Receivers.HDTV_SERVICE Or receivers(choiceID) = Common.Receivers.DVR_SERVICE Then
                '    If objFeature.ChoicesSelection.Contains(choiceID) Then objFeature.SelectedChoices.Remove(choiceID)
                '    UpdateHDTV_DVR_Service(sp)
                '    Exit Try
                '  End If

                '  Dim subitem As ISubCartItem
                '  Dim f As BLFeature

                '  If sp.Features.TryGetValue(Common.GetKey(Common.Receivers.TV_NUMBERS, receivers), subitem) Then
                '    f = DirectCast(subitem, BLFeature)
                '  Else
                '    Exit Try
                '  End If
                '  'UPDATE TV NUMBER Option1

                '  If f.SelectedChoices.Contains("1" & choiceID) Then
                '    If choiceID = Common.GetKey(Common.Receivers.DVR_MULTI, receivers) Or choiceID = Common.GetKey(Common.Receivers.HD_MULTI, receivers) Then
                '      f.SelectedChoices.RemoveAt(0)
                '      f.SelectedChoices.RemoveAt(0)
                '      UpdateSelectedChoices = UpdateTVOptions(sp, receivers, f.SelectedChoices)
                '      UpdateHDTV_DVR_Service(sp)
                '      If f.SelectedChoices.Count > 0 Then
                '        Dim cartsel As CartSelections
                '        cartsel.Category = f.Category
                '        cartsel.FeatureType = f.FeatureType
                '        If Not cartitems.ContainsKey(f.ID) Then cartitems.Add(f.ID, cartsel)
                '      End If
                '      Exit Try
                '    Else
                '      f.SelectedChoices.RemoveAt(0)
                '      UpdateSelectedChoices = UpdateTVOptions(sp, receivers, f.SelectedChoices)
                '      UpdateHDTV_DVR_Service(sp)
                '      If f.SelectedChoices.Count > 0 Then
                '        Dim cartsel As CartSelections
                '        cartsel.Category = f.Category
                '        cartsel.FeatureType = f.FeatureType
                '        If Not cartitems.ContainsKey(f.ID) Then cartitems.Add(f.ID, cartsel)
                '      End If
                '      Exit Try
                '    End If
                '  End If

                '  'UPDATE TV NUMBER Option2
                '  If f.SelectedChoices.Contains("2" & choiceID) Then
                '    f.SelectedChoices.RemoveAt(1)
                '    UpdateTVOptions(sp, receivers, f.SelectedChoices)
                '    UpdateHDTV_DVR_Service(sp)
                '    If f.SelectedChoices.Count > 0 Then
                '      Dim cartsel As CartSelections
                '      cartsel.Category = f.Category
                '      cartsel.FeatureType = f.FeatureType
                '      If Not cartitems.ContainsKey(f.ID) Then cartitems.Add(f.ID, cartsel)
                '    End If
                '    Exit Try
                '  End If


                '  'UPDATE TV NUMBER Option3
                '  If f.SelectedChoices.Contains("3" & choiceID) Then
                '    f.SelectedChoices.RemoveAt(2)
                '    UpdateTVOptions(sp, receivers, f.SelectedChoices)
                '    UpdateHDTV_DVR_Service(sp)
                '    If f.SelectedChoices.Count > 0 Then
                '      Dim cartsel As CartSelections
                '      cartsel.Category = f.Category
                '      cartsel.FeatureType = f.FeatureType
                '      If Not cartitems.ContainsKey(f.ID) Then cartitems.Add(f.ID, cartsel)
                '    End If
                '    Exit Try
                '  End If

                '  'UPDATE TV NUMBER Option4
                '  If f.SelectedChoices.Contains("4" & choiceID) Then
                '    f.SelectedChoices.RemoveAt(3)
                '    UpdateTVOptions(sp, receivers, f.SelectedChoices)
                '    UpdateHDTV_DVR_Service(sp)
                '    If f.SelectedChoices.Count > 0 Then
                '      Dim cartsel As CartSelections
                '      cartsel.Category = f.Category
                '      cartsel.FeatureType = f.FeatureType
                '      If Not cartitems.ContainsKey(f.ID) Then cartitems.Add(f.ID, cartsel)
                '    End If
                '    Exit Try
                '  End If
                'Else
                If objFeature.ChoicesSelection.Contains(choiceID) Then objFeature.SelectedChoices.Remove(choiceID)
                If objFeature.ID = BLCommon.GetKey(BLCommon.Receivers.HDTV_TIER, receivers) Then
                    UpdateHDTV_DVR_Service(sp)
                End If
                'End If

            End If
        Catch ex As Exception
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        End Try
    End Function

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="itemID">ID of feature that should be removed from cart</param>
    ''' <remarks>
    ''' From given ItemID finds the feature.
    ''' Dynamic Bundling will be done.
    ''' Updates UndoStack with the new item, and removes that feature from UserSelectedList.
    ''' Finds service plan with the new UserSelectionList, by calling FindServiceplan.
    ''' Adds the ServicePlan found in above method to cart. 
    ''' If there is a change in Service plan with current selections Carries any customization selections to new ServicePlan.
    ''' Refreshes Catalog,FeatureList.
    ''' Invokes Notify delegate about any unexpected changes to ShoppingCart.
    ''' Updates Shopping cart price.
    ''' After all the Chages are done adds CatalogManager to session.
    ''' </remarks>
    Public Overrides Function RemoveSubCartItem(ByVal trackID As String, ByVal itemID As String, ByVal parentid As String) As INotification
        Try
            PopulateLocalVariables(trackID)
            If featureList.ContainsKey(itemID) Then
                Dim f As BLFeature = DirectCast(featureList(itemID), BLFeature)
                Dim objCartSelection As CartSelections
                Dim cartItemsWithCategory As Dictionary(Of String, CartSelections) = GetCartItemsWithcategory()
                If cartItemsWithCategory.ContainsKey(itemID) Then
                    objCartSelection = cartItemsWithCategory(itemID)
                    cartItemsWithCategory.Remove(itemID)
                End If

                ' set cart notification message
                _message = New Notification(NotificationAction.Remove, f.Name, NotificationCode.Success)

                ' this remove is from select options page, don't need to do bundling
                Dim parent As ISubCartItem = CType(catalog.Cart, BLShoppingCart).GetParentFeature(itemID, parentid)

                If Not parent Is Nothing Then
                    Dim parentFeature As BLFeature = CType(parent, BLFeature)
                    If parentFeature.ChoicesSelection.Contains(itemID) Then parentFeature.SelectedChoices.Remove(itemID)
                    receivers = GenerateReceivers()
                    If receivers IsNot Nothing AndAlso receivers.ContainsKey(parentFeature.ID) Then

                        Dim sp As BLServicePlan
                        Dim subitem As ISubCartItem
                        For Each objitem As ICartItem In catalog.Cart.CartItems.Values
                            If objitem.Type = ItemType.Bundle Then
                                For Each objsubitem As ISubCartItem In objitem.Children.Values
                                    If objsubitem.Category = parentFeature.Category Then
                                        sp = CType(objsubitem, BLServicePlan)
                                        Exit For
                                    End If
                                Next
                            Else
                                If objitem.Category = parentFeature.Category Then
                                    sp = CType(objitem, BLServicePlan)
                                    Exit For
                                End If
                            End If
                        Next

                        If sp.Features.TryGetValue(BLCommon.GetKey(BLCommon.Receivers.TV_NUMBERS, receivers), subitem) Then
                            f = DirectCast(subitem, BLFeature)
                            Select Case receivers(parentFeature.ID)
                                Case BLCommon.Receivers.TV_1
                                    If f.SelectedChoices.Count > 0 Then
                                        f.SelectedChoices.RemoveAt(0)
                                        f.QuantitySelected = f.QuantitySelected - 1
                                    End If
                                Case BLCommon.Receivers.TV_2
                                    If f.SelectedChoices.Count > 1 Then
                                        f.SelectedChoices.RemoveAt(1)
                                        f.QuantitySelected = f.QuantitySelected - 1
                                    End If
                                Case BLCommon.Receivers.TV_3
                                    If f.SelectedChoices.Count > 2 Then
                                        f.SelectedChoices.RemoveAt(2)
                                        f.QuantitySelected = f.QuantitySelected - 1
                                    End If
                                Case BLCommon.Receivers.TV_4
                                    If f.SelectedChoices.Count > 3 Then
                                        f.SelectedChoices.RemoveAt(3)
                                        f.QuantitySelected = f.QuantitySelected - 1
                                    End If
                            End Select
                        End If

                    End If
                    catalog.RefreshFeature(parentFeature, False, True, cartItemsWithCategory)
                End If


                RefreshFeatureList()
                ' when an itemis removed add it to unDoRemoveStack
                PushToUnDoStack(CreateUnDoStackItem(DirectCast(featureList(itemID), BLFeature)))

                SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)

                Return _message
            End If
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot remove feature from cart", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try

        Return Nothing

    End Function


    ''' <summary>
    ''' Undo a Previous Remove.
    ''' </summary>
    ''' <remarks>
    ''' Adds the last added item from stack to Shopping Cart by using AddCartItem.
    ''' Updates UnDoRemove Flag based on Stack count.
    ''' </remarks>
    ''' 
    Public Overrides Function UndoRemove(ByVal trackID As String) As INotification
        Try
            PopulateLocalVariables(trackID)
            If Not UndoStack Is Nothing Then
                If UndoStack.Count > 0 Then

                    Dim item As Items = UndoStack.Pop()

                    _undoremove = True

                    If UndoStack.Count > 0 Then
                        sCart.m_undo = True
                    Else
                        sCart.m_undo = False
                    End If

                    Dim userSelections As Dictionary(Of String, CartSelections)
                    Dim selection As CartSelections
                    _message = New Notification(NotificationAction.Add, item.Description, NotificationCode.Success)

                    Select Case item.Type
                        Case GwyItemType.Bundle
                            If catalog.Bundles.ContainsKey(item.ID) Then
                                AddItemToCart(catalog.Bundles(item.ID))
                                userSelections = GetCartItemsWithcategory()
                                Dim cz As BLFeature
                                ' For Each subItem As Items In item.SubItems.Values
                                For Each choice As Items In item.SubItems.Values
                                    selection.Category = featureList(choice.ID).Category
                                    selection.FeatureType = FeatureType.IsPlaceholder
                                    userSelections.Add(choice.ID, selection)
                                    cz = DirectCast(catalog.Cart, BLShoppingCart).FindPlaceholder(choice.ID)
                                    cz.ChoicesSelection.Add(choice.ID)
                                    catalog.RefreshFeature(cz, False, True, userSelections)
                                Next
                                'Next
                            End If
                        Case GwyItemType.ServicePlan
                            If catalog.ServicePlans.ContainsKey(item.ID) Then
                                AddItemToCart(catalog.ServicePlans(item.ID))
                                Dim cz As BLFeature
                                userSelections = GetCartItemsWithcategory()
                                For Each choice As Items In item.SubItems.Values
                                    selection.Category = featureList(choice.ID).Category
                                    selection.FeatureType = FeatureType.IsPlaceholder
                                    userSelections.Add(choice.ID, selection)
                                    cz = DirectCast(catalog.Cart, BLShoppingCart).FindPlaceholder(choice.ID)
                                    cz.ChoicesSelection.Add(choice.ID)
                                    catalog.RefreshFeature(cz, False, True, userSelections)
                                Next
                            End If
                        Case GwyItemType.Choice
                            'selection.Category = featureList(item.ID).Category
                            'selection.FeatureType = FeatureType.IsPlaceholder
                            'userSelections.Add(item.ID, selection)
                            'AddSubItemToCart(featureList(item.ID))
                        Case Else
                            Throw New ApplicationException("This type is not Acceptable")
                    End Select

                    _undoremove = False
                    SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
                End If
            End If

            Return _message
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot un-do previous removal", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try
        Return Nothing
    End Function

    Private Sub AddToFeatureList(ByVal item As ISubCartItem)
        Dim category As FeatureCategory = DirectCast(item, BLFeature).FeatureCategory
        If item.Children Is Nothing OrElse item.Children.Count = 0 Then
            If Not featureList.ContainsKey(item.ID) Then
                ' If Not (category = FeatureCategory.Installation OrElse category = FeatureCategory.DataEquipment OrElse category = FeatureCategory.VideoEquipment OrElse category = FeatureCategory.VideoEquipment) Then
                featureList.Add(item.ID, item)
                'End If
            End If
        End If
    End Sub

    ' gets the user selected cart items as a list
    Private Function GetCartItemsWithcategory() As Dictionary(Of String, CartSelections)
        Dim list As New Dictionary(Of String, CartSelections)
        Dim objCartSelection As CartSelections
        For Each item As ICartItem In catalog.Cart.CartItems.Values
            If item.Type = ItemType.Bundle Then
                objCartSelection.Category = item.Category
                objCartSelection.FeatureType = FeatureType.NotSpecified
                list.Add(item.ID, objCartSelection)
                For Each sp As BLServicePlan In item.Children.Values
                    AddSelectedServicePlan(sp, list)
                Next
            ElseIf item.Type = ItemType.ServicePlan Then
                Dim sp As BLServicePlan = DirectCast(item, BLServicePlan)
                AddSelectedServicePlan(sp, list)
            End If
        Next
        Return list
    End Function

    ' adds user selected service plan and its children to the list
    Private Sub AddSelectedServicePlan(ByVal sp As BLServicePlan, ByVal list As Dictionary(Of String, CartSelections))

        Dim objCartSelection As CartSelections

        If sp.IsSelected Then
            objCartSelection.Category = sp.Category
            objCartSelection.FeatureType = FeatureType.NotSpecified
            If Not list.ContainsKey(sp.ID) Then list.Add(sp.ID, objCartSelection)
        End If

        For Each feature As ISubCartItem In sp.Features.Values
            objCartSelection.Category = feature.Category
            objCartSelection.FeatureType = feature.FeatureType
            If feature.Children Is Nothing OrElse feature.Children.Count = 0 Then
                If feature.IsSelected Then
                    If Not list.ContainsKey(feature.ID) Then list.Add(feature.ID, objCartSelection)
                End If
            End If
            For Each choice As ISubCartItem In feature.Children.Values
                If choice.IsSelected Then
                    objCartSelection.Category = feature.Category
                    objCartSelection.FeatureType = feature.FeatureType
                    If Not list.ContainsKey(choice.ID) Then list.Add(choice.ID, objCartSelection)
                End If
            Next
        Next

    End Sub

    Private Sub RefreshFeatureList()
        Try
            If featureList Is Nothing Then Exit Sub
            For Each f As BLFeature In featureList.Values
                Dim objfeature As ISubCartItem = CType(catalog.Cart, BLShoppingCart).ContainsThisFeature(f.ID)
                If Not objfeature Is Nothing Then
                    If Not receivers Is Nothing Then
                        If objfeature.ID = BLCommon.GetKey(BLCommon.Receivers.RECEIVER, receivers) Or objfeature.ID = BLCommon.GetKey(BLCommon.Receivers.HD, receivers) Then
                            f.IsAvailable = True
                        Else
                            f.IsAvailable = objfeature.IsAvailable
                        End If
                    Else
                        f.IsAvailable = objfeature.IsAvailable
                    End If

                Else
                    f.IsAvailable = True
                End If
            Next
        Catch ex As Exception
            Throw New ApplicationException("cannot refresh feature list", ex)
        End Try
    End Sub

    Public Overrides Function AddSubCartItem(ByVal trackingid As String, ByVal itemID As String, ByVal Quantity As Integer) As INotification
        Try
            If trackingid IsNot Nothing Then
                PopulateLocalVariables(trackingid)
            End If
            ' returning after order is submitted
            If catalog.Cart.Submitted Then
                ClearShoppingCart(trackingid)
                CType(catalog.Cart, BLShoppingCart).OrderSubmitted = False
            End If

            Dim item As ISubCartItem
            Dim objCartSelection As CartSelections
            Dim cartItemsWithCategory As Dictionary(Of String, CartSelections)

            cartItemsWithCategory = GetCartItemsWithcategory()

            If cartItemsWithCategory Is Nothing Then
                cartItemsWithCategory = New Dictionary(Of String, CartSelections)
            End If

            Dim sp As BLServicePlan
            featureList.TryGetValue(itemID, item)
            For Each objitem As ICartItem In catalog.Cart.CartItems.Values
                If objitem.Type = ItemType.Bundle Then
                    For Each objsubitem As ISubCartItem In objitem.Children.Values
                        If objsubitem.Category = item.Category Then
                            sp = CType(objsubitem, BLServicePlan)
                            Exit For
                        End If
                    Next
                Else
                    If objitem.Category = item.Category Then
                        sp = CType(objitem, BLServicePlan)
                        Exit For
                    End If
                End If
            Next

            If Not sp Is Nothing AndAlso sp.Features.ContainsKey(itemID) Then
                Dim f As BLFeature = DirectCast(sp.Features(itemID), BLFeature)
                If f Is Nothing Then Return New Notification(NotificationAction.Add, "Item Not Found", NotificationCode.CannotAddCustomization)
                objCartSelection.Category = f.Category
                objCartSelection.FeatureType = f.FeatureType
                _message = New Notification(NotificationAction.Add, f.Name, NotificationCode.Success)


                CType(f, BLFeature).QuantitySelected = Quantity
                If Quantity = 0 Then
                    cartItemsWithCategory.Remove(itemID)
                    catalog.RefreshFeature(CType(f, BLFeature), True, False, cartItemsWithCategory)
                Else
                    If Not cartItemsWithCategory.ContainsKey(itemID) Then cartItemsWithCategory.Add(itemID, objCartSelection)
                    catalog.RefreshFeature(CType(f, BLFeature), False, True, cartItemsWithCategory)
                End If

                RefreshFeatureList()
                'To update prices
                sCart.UpdateCartItemsPrice()
            Else
                Return New Notification(NotificationAction.Add, "Item Not Found", NotificationCode.CannotAddCustomization)
            End If
            SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
            Return _message
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot add feature with quantity to cart", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try
    End Function

    Public Overrides Function AddSubcartItem(ByVal trackingid As String, ByVal itemID As String, ByVal TextEntry As String) As INotification
        Try
            If trackingid IsNot Nothing Then
                PopulateLocalVariables(trackingid)
            End If
            ' returning after order is submitted
            If catalog.Cart.Submitted Then
                ClearShoppingCart(trackingid)
                CType(catalog.Cart, BLShoppingCart).OrderSubmitted = False
            End If

            Dim item As ISubCartItem
            Dim objCartSelection As CartSelections
            Dim cartItemsWithCategory As Dictionary(Of String, CartSelections)

            cartItemsWithCategory = GetCartItemsWithcategory()

            If cartItemsWithCategory Is Nothing Then
                cartItemsWithCategory = New Dictionary(Of String, CartSelections)
            End If

            featureList.TryGetValue(itemID, item)

            Dim sp As BLServicePlan
            featureList.TryGetValue(itemID, item)
            For Each objitem As ICartItem In catalog.Cart.CartItems.Values
                If objitem.Type = ItemType.Bundle Then
                    For Each objsubitem As ISubCartItem In objitem.Children.Values
                        If objsubitem.Category = item.Category Then
                            sp = CType(objsubitem, BLServicePlan)
                            Exit For
                        End If
                    Next
                Else
                    If objitem.Category = item.Category Then
                        sp = CType(objitem, BLServicePlan)
                        Exit For
                    End If
                End If
            Next

            If Not sp Is Nothing AndAlso sp.Features.ContainsKey(itemID) Then
                Dim f As BLFeature = DirectCast(sp.Features(itemID), BLFeature)
                If f Is Nothing Then Return New Notification(NotificationAction.Add, "Item Not Found", NotificationCode.CannotAddCustomization)
                objCartSelection.Category = f.Category
                objCartSelection.FeatureType = f.FeatureType
                _message = New Notification(NotificationAction.Add, f.Name, NotificationCode.Success)


                If f Is Nothing Then Return New Notification(NotificationAction.Add, "Item Not Found", NotificationCode.CannotAddCustomization)
                objCartSelection.Category = item.Category
                objCartSelection.FeatureType = item.FeatureType
                _message = New Notification(NotificationAction.Add, item.Name, NotificationCode.Success)


                CType(f, BLFeature).Text = TextEntry
                If TextEntry.Equals(String.Empty) Then
                    If cartItemsWithCategory.ContainsKey(itemID) Then cartItemsWithCategory.Remove(itemID)
                    catalog.RefreshFeature(CType(f, BLFeature), True, False, cartItemsWithCategory)
                Else
                    If Not cartItemsWithCategory.ContainsKey(itemID) Then cartItemsWithCategory.Add(itemID, objCartSelection)
                    catalog.RefreshFeature(CType(f, BLFeature), False, True, cartItemsWithCategory)
                End If

                RefreshFeatureList()
                'To update prices
                sCart.UpdateCartItemsPrice()
            Else
                Return New Notification(NotificationAction.Add, "Item Not Found", NotificationCode.CannotAddCustomization)
            End If
            SetSession(AffiliateCatalogManagerKey, Me.ValuesForSetSession)
            Return _message
        Catch ex As ApplicationException
            BLCommon.LogException(ex, ExceptionSeverity.Catastrophic)
            Throw ex
        Catch ex As Exception
            Dim aex As New ApplicationException("Cannot add feature with text entry to cart", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Catastrophic)
            Throw aex
        End Try
    End Function

    Private Sub ClearUnDoStack()
        If Not _undoremove Then
            'Set Undo /Remove to False as user just added items to cart as this functionality is available only when the last action is an "Add Cart"
            sCart.m_undo = False

            'If not initialized, then instantiate it
            If UndoStack Is Nothing Then
                UndoStack = New Stack(Of Items)
            End If
            'Adding an item to cart should reset the stack.
            UndoStack.Clear()
        End If
    End Sub

    Private Function CreateUnDoStackItem(ByVal cartItem As ICartItem) As Items
        Dim item As Items
        Dim subItem As Items
        'Dim endItem As Items
        ' Dim endItems As Dictionary(Of String, Items)
        Dim subItems As New Dictionary(Of String, Items)
        Try
            If cartItem.Type = ItemType.Bundle Then
                For Each subCartItem As BLServicePlan In cartItem.Children.Values
                    For Each feature As BLFeature In subCartItem.Features.Values
                        For Each choice As BLFeature In feature.Choices.Values
                            If choice.ISSelected Then
                                subItem = New Items(choice.ID, choice.Description, GwyItemType.Choice)
                                subItems.Add(subItem.ID, subItem)
                            End If
                        Next
                    Next
                Next
            Else
                For Each subCartItem As BLFeature In cartItem.Children.Values
                    For Each choice As BLFeature In subCartItem.Choices.Values
                        If choice.ISSelected Then
                            subItem = New Items(choice.ID, choice.Description, GwyItemType.Choice)
                            subItems.Add(subItem.ID, subItem)
                        End If
                    Next
                Next
            End If

            Dim type As GwyItemType
            If cartItem.Type = ItemType.Bundle Then
                type = GwyItemType.Bundle
            Else
                type = GwyItemType.ServicePlan
            End If
            item = New Items(cartItem.ID, cartItem.Description, type, Nothing, Nothing, subItems)
            Return item
        Catch ex As Exception
            Throw New ApplicationException("Error creating undo stack", ex)
        End Try
    End Function

    Private Function CreateUnDoStackItem(ByVal f As BLFeature) As Items
        Return New Items(f.ID, f.Description, GwyItemType.Choice)
    End Function

    Private Sub PushToUnDoStack(ByVal item As Items)
        'Set Undo /Remove to true as user just removed from cart
        sCart.m_undo = True

        'If not initialized, then instantiate it
        If UndoStack Is Nothing Then
            UndoStack = New Stack(Of Items)
        End If


        'Add the last removed item to stack.
        UndoStack.Push(item)
    End Sub

#End Region

#Region "Rules"

    Public Overrides Function GetChooseOptionsXml(ByVal trackingid As String) As String
        PopulateLocalVariables(trackingid)
        Dim iProvider As IG2BServicesProvider = CType(Activator.GetObject(GetType(IG2BServicesProvider), CStr(HttpContext.Current.Application("RemoteURL_G2BServicesProvider"))), IG2BServicesProvider)
        Try
            Dim objresult As EntityG2BServices.EntityUIRules = CType(iProvider.GetChooseOptionsXml(), EntityG2BServices.EntityUIRules)
            If Not objresult.Exception Then
                Return objresult.Data
            Else
                BLCommon.LogException(New Exception("catalog Manager - Get Choose options xml failed as:" & objresult.ExceptionMessage & " - " & objresult.ExceptionStackTrace), ExceptionSeverity.Fatal)
                Return Nothing
            End If
        Catch ex As Exception
            Dim aex As New ApplicationException("catalog Manager - Get Choose options xml failed", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Fatal)
            Throw aex
        Finally
            iProvider = Nothing
        End Try
    End Function

    Public Overrides Function GetShowPriceList(ByVal trackingid As String) As List(Of String)
        PopulateLocalVariables(trackingid)
        Dim iProvider As IG2BServicesProvider = CType(Activator.GetObject(GetType(IG2BServicesProvider), CStr(HttpContext.Current.Application("RemoteURL_G2BServicesProvider"))), IG2BServicesProvider)
        Try
            Dim objresult As EntityG2BServices.EntityUIRules = CType(iProvider.GetShowPriceList(), EntityG2BServices.EntityUIRules)
            If Not objresult.Exception Then
                Dim doc As New XmlDocument
                doc.LoadXml(objresult.Data.ToString)
                Dim idlist As New List(Of String)
                For Each pageNode As XmlNode In doc.ChildNodes
                    For Each node As XmlNode In pageNode.ChildNodes
                        If node.Attributes("id") IsNot Nothing Then
                            idlist.Add(node.Attributes("id").Value)
                        End If
                    Next
                Next
                Return idlist
            Else
                BLCommon.LogException(New Exception("catalog Manager - GetShowPriceList xml failed as:" & objresult.ExceptionMessage & " - " & objresult.ExceptionStackTrace), ExceptionSeverity.Fatal)
                Return Nothing
            End If
        Catch ex As Exception
            Dim aex As New ApplicationException("catalog Manager - GetShowPriceList failed", ex)
            BLCommon.LogException(aex, ExceptionSeverity.Fatal)
            Throw aex
        Finally
            iProvider = Nothing
        End Try
    End Function

#End Region

End Class
