diff --git a/internal/pkg/application/igmpprofiles.go b/internal/pkg/application/igmpprofiles.go
index b855eb8..a1d999c 100644
--- a/internal/pkg/application/igmpprofiles.go
+++ b/internal/pkg/application/igmpprofiles.go
@@ -11,7 +11,7 @@
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-*/
+ */
 
 package application
 
@@ -24,10 +24,10 @@
 	"strings"
 	"sync"
 
-	cntlr "voltha-go-controller/internal/pkg/controller"
-	"voltha-go-controller/internal/pkg/types"
 	"voltha-go-controller/database"
+	cntlr "voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/internal/pkg/of"
+	common "voltha-go-controller/internal/pkg/types"
 	"voltha-go-controller/internal/pkg/util"
 	"voltha-go-controller/log"
 )
@@ -45,30 +45,30 @@
 
 // MCGroupProxy identifies source specific multicast(SSM) config.
 type MCGroupProxy struct {
-        // Mode represents source list include/exclude
-        Mode common.MulticastSrcListMode
-        // SourceList represents list of multicast server IP addresses.
-        SourceList []net.IP
+	// Mode represents source list include/exclude
+	Mode common.MulticastSrcListMode
+	// SourceList represents list of multicast server IP addresses.
+	SourceList []net.IP
 }
 
 // MvlanGroup identifies MC group info
 type MvlanGroup struct {
-        Name     string
-        Wildcard bool
-        McIPs    []string
-        IsStatic bool
+	Name     string
+	McIPs    []string
+	Wildcard bool
+	IsStatic bool
 }
 
 // OperInProgress type
 type OperInProgress uint8
 
 const (
-        // UpdateInProgress constant
-        UpdateInProgress OperInProgress = 2
-        // NoOp constant
-        NoOp OperInProgress = 1
-        // Nil constant
-        Nil OperInProgress = 0
+	// UpdateInProgress constant
+	UpdateInProgress OperInProgress = 2
+	// NoOp constant
+	NoOp OperInProgress = 1
+	// Nil constant
+	Nil OperInProgress = 0
 )
 
 // MvlanProfile : A set of groups of MC IPs for a MVLAN profile. It is assumed that
@@ -76,1155 +76,1134 @@
 // MVLAN profiles. The first match is used up on search to lcoate the
 // MVLAN profile for an MC IP
 type MvlanProfile struct {
-        Name                string
-        Mvlan               of.VlanType
-        PonVlan             of.VlanType
-        Groups              map[string]*MvlanGroup
-        Proxy               map[string]*MCGroupProxy
-        Version             string
-        IsPonVlanPresent    bool
-        IsChannelBasedGroup bool
-        DevicesList         map[string]OperInProgress //device serial number //here
-        oldGroups           map[string]*MvlanGroup
-        oldProxy            map[string]*MCGroupProxy
-        MaxActiveChannels   uint32
-        PendingDeleteFlow   map[string]map[string]bool
-        DeleteInProgress    bool
-        IgmpServVersion     map[string]*uint8
-        mvpLock             sync.RWMutex
-        mvpFlowLock         sync.RWMutex
+	Groups              map[string]*MvlanGroup
+	Proxy               map[string]*MCGroupProxy
+	oldGroups           map[string]*MvlanGroup
+	oldProxy            map[string]*MCGroupProxy
+	IgmpServVersion     map[string]*uint8
+	PendingDeleteFlow   map[string]map[string]bool
+	DevicesList         map[string]OperInProgress //device serial number //here
+	Version             string
+	Name                string
+	mvpLock             sync.RWMutex
+	mvpFlowLock         sync.RWMutex
+	MaxActiveChannels   uint32
+	Mvlan               of.VlanType
+	PonVlan             of.VlanType
+	IsPonVlanPresent    bool
+	IsChannelBasedGroup bool
+	DeleteInProgress    bool
 }
 
 // NewMvlanProfile is constructor for MVLAN profile.
 func NewMvlanProfile(name string, mvlan of.VlanType, ponVlan of.VlanType, isChannelBasedGroup bool, OLTSerialNums []string, actChannelPerPon uint32) *MvlanProfile {
-        var mvp MvlanProfile
-        mvp.Name = name
-        mvp.Mvlan = mvlan
-        mvp.PonVlan = ponVlan
-        mvp.mvpLock = sync.RWMutex{}
-        mvp.Groups = make(map[string]*MvlanGroup)
-        mvp.Proxy = make(map[string]*MCGroupProxy)
-        mvp.DevicesList = make(map[string]OperInProgress)
-        mvp.PendingDeleteFlow = make(map[string]map[string]bool)
-        mvp.IsChannelBasedGroup = isChannelBasedGroup
-        mvp.MaxActiveChannels = actChannelPerPon
-        mvp.DeleteInProgress = false
-        mvp.IgmpServVersion = make(map[string]*uint8)
+	var mvp MvlanProfile
+	mvp.Name = name
+	mvp.Mvlan = mvlan
+	mvp.PonVlan = ponVlan
+	mvp.mvpLock = sync.RWMutex{}
+	mvp.Groups = make(map[string]*MvlanGroup)
+	mvp.Proxy = make(map[string]*MCGroupProxy)
+	mvp.DevicesList = make(map[string]OperInProgress)
+	mvp.PendingDeleteFlow = make(map[string]map[string]bool)
+	mvp.IsChannelBasedGroup = isChannelBasedGroup
+	mvp.MaxActiveChannels = actChannelPerPon
+	mvp.DeleteInProgress = false
+	mvp.IgmpServVersion = make(map[string]*uint8)
 
-        if (ponVlan != of.VlanNone) && (ponVlan != 0) {
-                mvp.IsPonVlanPresent = true
-        }
-        return &mvp
+	if (ponVlan != of.VlanNone) && (ponVlan != 0) {
+		mvp.IsPonVlanPresent = true
+	}
+	return &mvp
 }
 
 // AddMvlanProxy for addition of groups to an MVLAN profile
 func (mvp *MvlanProfile) AddMvlanProxy(name string, proxyInfo common.MulticastGroupProxy) {
-        proxy := &MCGroupProxy{}
-        proxy.Mode = proxyInfo.Mode
-        proxy.SourceList = util.GetExpIPList(proxyInfo.SourceList)
+	proxy := &MCGroupProxy{}
+	proxy.Mode = proxyInfo.Mode
+	proxy.SourceList = util.GetExpIPList(proxyInfo.SourceList)
 
-        if _, ok := mvp.Proxy[name]; !ok {
-                logger.Debugw(ctx, "Added MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
-        } else {
-                logger.Debugw(ctx, "Updated MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
-        }
-        if proxyInfo.IsStatic == common.IsStaticYes {
-                mvp.Groups[name].IsStatic = true
-        }
-        mvp.Proxy[name] = proxy
+	if _, ok := mvp.Proxy[name]; !ok {
+		logger.Debugw(ctx, "Added MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
+	} else {
+		logger.Debugw(ctx, "Updated MVLAN Proxy", log.Fields{"Name": name, "Proxy": proxy})
+	}
+	if proxyInfo.IsStatic == common.IsStaticYes {
+		mvp.Groups[name].IsStatic = true
+	}
+	mvp.Proxy[name] = proxy
 }
 
 // AddMvlanGroup for addition of groups to an MVLAN profile
 func (mvp *MvlanProfile) AddMvlanGroup(name string, ips []string) {
-        mvg := &MvlanGroup{}
-        mvg.Name = name
-        mvg.Wildcard = len(ips) == 0
-        mvg.McIPs = ips
-        mvg.IsStatic = false
-        if _, ok := mvp.Groups[name]; !ok {
-                logger.Debugw(ctx, "Added MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name, "mvg": mvg, "IPs": mvg.McIPs})
-        } else {
-                logger.Debugw(ctx, "Updated MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name})
-        }
-        mvp.Groups[name] = mvg
+	mvg := &MvlanGroup{}
+	mvg.Name = name
+	mvg.Wildcard = len(ips) == 0
+	mvg.McIPs = ips
+	mvg.IsStatic = false
+	if _, ok := mvp.Groups[name]; !ok {
+		logger.Debugw(ctx, "Added MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name, "mvg": mvg, "IPs": mvg.McIPs})
+	} else {
+		logger.Debugw(ctx, "Updated MVLAN Group", log.Fields{"VLAN": mvp.Mvlan, "Name": name})
+	}
+	mvp.Groups[name] = mvg
 }
 
 // GetUsMatchVlan provides mvlan for US Match parameter
 func (mvp *MvlanProfile) GetUsMatchVlan() of.VlanType {
-        if mvp.IsPonVlanPresent {
-                return mvp.PonVlan
-        }
-        return mvp.Mvlan
+	if mvp.IsPonVlanPresent {
+		return mvp.PonVlan
+	}
+	return mvp.Mvlan
 }
 
 // WriteToDb is utility to write Mvlan Profile Info to database
 func (mvp *MvlanProfile) WriteToDb(cntx context.Context) error {
+	if mvp.DeleteInProgress {
+		logger.Warnw(ctx, "Skipping Redis Update for MvlanProfile, MvlanProfile delete in progress", log.Fields{"Mvlan": mvp.Mvlan})
+		return nil
+	}
 
-        if mvp.DeleteInProgress {
-                logger.Warnw(ctx, "Skipping Redis Update for MvlanProfile, MvlanProfile delete in progress", log.Fields{"Mvlan": mvp.Mvlan})
-                return nil
-        }
-
-        mvp.Version = database.PresentVersionMap[database.MvlanPath]
-        b, err := json.Marshal(mvp)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutMvlan(cntx, uint16(mvp.Mvlan), string(b)); err1 != nil {
-                return err1
-        }
-        return nil
+	mvp.Version = database.PresentVersionMap[database.MvlanPath]
+	b, err := json.Marshal(mvp)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutMvlan(cntx, uint16(mvp.Mvlan), string(b)); err1 != nil {
+		return err1
+	}
+	return nil
 }
 
-//isChannelStatic - Returns true if the given channel is part of static group in the Mvlan Profile
+// isChannelStatic - Returns true if the given channel is part of static group in the Mvlan Profile
 func (mvp *MvlanProfile) isChannelStatic(channel net.IP) bool {
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic {
-                        if isChannelStatic := doesIPMatch(channel, mvg.McIPs); isChannelStatic {
-                                return true
-                        }
-                }
-        }
-        return false
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic {
+			if isChannelStatic := doesIPMatch(channel, mvg.McIPs); isChannelStatic {
+				return true
+			}
+		}
+	}
+	return false
 }
 
-//containsStaticChannels - Returns if any static channels is part of the Mvlan Profile
+// containsStaticChannels - Returns if any static channels is part of the Mvlan Profile
 func (mvp *MvlanProfile) containsStaticChannels() bool {
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic && len(mvg.McIPs) != 0 {
-                        return true
-                }
-        }
-        return false
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic && len(mvg.McIPs) != 0 {
+			return true
+		}
+	}
+	return false
 }
 
-//getAllStaticChannels - Returns all static channels in the Mvlan Profile
+// getAllStaticChannels - Returns all static channels in the Mvlan Profile
 func (mvp *MvlanProfile) getAllStaticChannels() ([]net.IP, bool) {
-        channelList := []net.IP{}
-        containsStatic := false
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic {
-                        staticChannels, _ := mvg.getAllChannels()
-                        channelList = append(channelList, staticChannels...)
-                }
-        }
-        if len(channelList) > 0 {
-                containsStatic = true
-        }
-        return channelList, containsStatic
+	channelList := []net.IP{}
+	containsStatic := false
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic {
+			staticChannels, _ := mvg.getAllChannels()
+			channelList = append(channelList, staticChannels...)
+		}
+	}
+	if len(channelList) > 0 {
+		containsStatic = true
+	}
+	return channelList, containsStatic
 }
 
-//getAllOldGroupStaticChannels - Returns all static channels in the Mvlan Profile
+// getAllOldGroupStaticChannels - Returns all static channels in the Mvlan Profile
 func (mvp *MvlanProfile) getAllOldGroupStaticChannels() ([]net.IP, bool) {
-        channelList := []net.IP{}
-        containsStatic := false
-        for _, mvg := range mvp.oldGroups {
-                if mvg.IsStatic {
-                        staticChannels, _ := mvg.getAllChannels()
-                        channelList = append(channelList, staticChannels...)
-                }
-        }
-        if len(channelList) > 0 {
-                containsStatic = true
-        }
-        return channelList, containsStatic
+	channelList := []net.IP{}
+	containsStatic := false
+	for _, mvg := range mvp.oldGroups {
+		if mvg.IsStatic {
+			staticChannels, _ := mvg.getAllChannels()
+			channelList = append(channelList, staticChannels...)
+		}
+	}
+	if len(channelList) > 0 {
+		containsStatic = true
+	}
+	return channelList, containsStatic
 }
 
-//getAllChannels - Returns all channels in the Mvlan Profile
+// getAllChannels - Returns all channels in the Mvlan Profile
 func (mvg *MvlanGroup) getAllChannels() ([]net.IP, bool) {
-        channelList := []net.IP{}
+	channelList := []net.IP{}
 
-        if mvg == nil || len(mvg.McIPs) == 0 {
-                return []net.IP{}, false
-        }
+	if mvg == nil || len(mvg.McIPs) == 0 {
+		return []net.IP{}, false
+	}
 
-        grpChannelOrRange := mvg.McIPs
-        for _, channelOrRange := range grpChannelOrRange {
-                if strings.Contains(channelOrRange, "-") {
-                        var splits = strings.Split(channelOrRange, "-")
-                        ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
-                        ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
+	grpChannelOrRange := mvg.McIPs
+	for _, channelOrRange := range grpChannelOrRange {
+		if strings.Contains(channelOrRange, "-") {
+			var splits = strings.Split(channelOrRange, "-")
+			ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
+			ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
 
-                        for i := ipStart; i <= ipEnd; i++ {
-                                channelList = append(channelList, util.Long2ipConv(i))
-                        }
-                } else {
-                        channelList = append(channelList, net.ParseIP(channelOrRange))
-                }
-        }
-        return channelList, true
+			for i := ipStart; i <= ipEnd; i++ {
+				channelList = append(channelList, util.Long2ipConv(i))
+			}
+		} else {
+			channelList = append(channelList, net.ParseIP(channelOrRange))
+		}
+	}
+	return channelList, true
 }
 
-//SetUpdateStatus - Sets profile update status for devices
+// SetUpdateStatus - Sets profile update status for devices
 func (mvp *MvlanProfile) SetUpdateStatus(serialNum string, status OperInProgress) {
-        if serialNum != "" {
-                mvp.DevicesList[serialNum] = status
-                return
-        }
+	if serialNum != "" {
+		mvp.DevicesList[serialNum] = status
+		return
+	}
 
-        for srNo := range mvp.DevicesList {
-                mvp.DevicesList[srNo] = status
-        }
+	for srNo := range mvp.DevicesList {
+		mvp.DevicesList[srNo] = status
+	}
 }
 
-//isUpdateInProgress - checking is update is in progress for the mvlan profile
+// isUpdateInProgress - checking is update is in progress for the mvlan profile
 func (mvp *MvlanProfile) isUpdateInProgress() bool {
-
-        for srNo := range mvp.DevicesList {
-                if mvp.DevicesList[srNo] == UpdateInProgress {
-                        return true
-                }
-        }
-        return false
+	for srNo := range mvp.DevicesList {
+		if mvp.DevicesList[srNo] == UpdateInProgress {
+			return true
+		}
+	}
+	return false
 }
 
-//IsUpdateInProgressForDevice - Checks is Mvlan Profile update is is progress for the given device
+// IsUpdateInProgressForDevice - Checks is Mvlan Profile update is is progress for the given device
 func (mvp *MvlanProfile) IsUpdateInProgressForDevice(device string) bool {
-        if vd := GetApplication().GetDevice(device); vd != nil {
-                if mvp.DevicesList[vd.SerialNum] == UpdateInProgress {
-                        return true
-                }
-        }
-        return false
+	if vd := GetApplication().GetDevice(device); vd != nil {
+		if mvp.DevicesList[vd.SerialNum] == UpdateInProgress {
+			return true
+		}
+	}
+	return false
 }
 
 // DelFromDb to delere mvlan from database
 func (mvp *MvlanProfile) DelFromDb(cntx context.Context) {
-        _ = db.DelMvlan(cntx, uint16(mvp.Mvlan))
+	_ = db.DelMvlan(cntx, uint16(mvp.Mvlan))
 }
 
-//DelFlows - Triggers flow deletion after registering for flow indication event
+// DelFlows - Triggers flow deletion after registering for flow indication event
 func (mvp *MvlanProfile) DelFlows(cntx context.Context, device *VoltDevice, flow *of.VoltFlow) error {
-        mvp.mvpFlowLock.Lock()
-        defer mvp.mvpFlowLock.Unlock()
+	mvp.mvpFlowLock.Lock()
+	defer mvp.mvpFlowLock.Unlock()
 
-        var flowMap map[string]bool
-        var ok bool
+	var flowMap map[string]bool
+	var ok bool
 
-        for cookie := range flow.SubFlows {
-                cookie := strconv.FormatUint(cookie, 10)
-                fe := &FlowEvent{
-                        eType:     EventTypeMcastFlowRemoved,
-                        device:    device.Name,
-                        cookie:    cookie,
-                        eventData: mvp,
-                }
-                device.RegisterFlowDelEvent(cookie, fe)
+	for cookie := range flow.SubFlows {
+		cookie := strconv.FormatUint(cookie, 10)
+		fe := &FlowEvent{
+			eType:     EventTypeMcastFlowRemoved,
+			device:    device.Name,
+			cookie:    cookie,
+			eventData: mvp,
+		}
+		device.RegisterFlowDelEvent(cookie, fe)
 
-                if flowMap, ok = mvp.PendingDeleteFlow[device.Name]; !ok {
-                        flowMap = make(map[string]bool)
-                }
-                flowMap[cookie] = true
-                mvp.PendingDeleteFlow[device.Name] = flowMap
-        }
-        if err := mvp.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
-        }
-        return cntlr.GetController().DelFlows(cntx, device.NniPort, device.Name, flow)
+		if flowMap, ok = mvp.PendingDeleteFlow[device.Name]; !ok {
+			flowMap = make(map[string]bool)
+		}
+		flowMap[cookie] = true
+		mvp.PendingDeleteFlow[device.Name] = flowMap
+	}
+	if err := mvp.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+	}
+	return cntlr.GetController().DelFlows(cntx, device.NniPort, device.Name, flow)
 }
 
-//FlowRemoveSuccess - Process flow success indication
+// FlowRemoveSuccess - Process flow success indication
 func (mvp *MvlanProfile) FlowRemoveSuccess(cntx context.Context, cookie string, device string) {
-        mvp.mvpFlowLock.Lock()
-        defer mvp.mvpFlowLock.Unlock()
+	mvp.mvpFlowLock.Lock()
+	defer mvp.mvpFlowLock.Unlock()
 
-        logger.Infow(ctx, "Mvlan Flow Remove Success Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "Device": device})
+	logger.Infow(ctx, "Mvlan Flow Remove Success Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "Device": device})
 
-        if _, ok := mvp.PendingDeleteFlow[device]; ok {
-                delete(mvp.PendingDeleteFlow[device], cookie)
-        }
+	if _, ok := mvp.PendingDeleteFlow[device]; ok {
+		delete(mvp.PendingDeleteFlow[device], cookie)
+	}
 
-        if err := mvp.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
-        }
+	if err := mvp.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+	}
 }
 
-//FlowRemoveFailure - Process flow failure indication
+// FlowRemoveFailure - Process flow failure indication
 func (mvp *MvlanProfile) FlowRemoveFailure(cookie string, device string, errorCode uint32, errReason string) {
+	mvp.mvpFlowLock.Lock()
+	defer mvp.mvpFlowLock.Unlock()
 
-        mvp.mvpFlowLock.Lock()
-        defer mvp.mvpFlowLock.Unlock()
-
-        if flowMap, ok := mvp.PendingDeleteFlow[device]; ok {
-                if _, ok := flowMap[cookie]; ok {
-                        logger.Errorw(ctx, "Mvlan Flow Remove Failure Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason, "Device": device})
-                        return
-                }
-        }
-        logger.Errorw(ctx, "Mvlan Flow Del Failure Notification for Unknown cookie", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason})
-
+	if flowMap, ok := mvp.PendingDeleteFlow[device]; ok {
+		if _, ok := flowMap[cookie]; ok {
+			logger.Errorw(ctx, "Mvlan Flow Remove Failure Notification", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason, "Device": device})
+			return
+		}
+	}
+	logger.Errorw(ctx, "Mvlan Flow Del Failure Notification for Unknown cookie", log.Fields{"MvlanProfile": mvp.Name, "Cookie": cookie, "ErrorCode": errorCode, "ErrorReason": errReason})
 }
 
 // IsStaticGroup to check if group is static
 func (mvp *MvlanProfile) IsStaticGroup(groupName string) bool {
-        return mvp.Groups[groupName].IsStatic
+	return mvp.Groups[groupName].IsStatic
 }
 
 // generateGroupKey to generate group key
 func (mvp *MvlanProfile) generateGroupKey(name string, ipAddr string) string {
-        if mvp.IsChannelBasedGroup {
-                return mvp.Mvlan.String() + "_" + ipAddr
-        }
-        return mvp.Mvlan.String() + "_" + name
+	if mvp.IsChannelBasedGroup {
+		return mvp.Mvlan.String() + "_" + ipAddr
+	}
+	return mvp.Mvlan.String() + "_" + name
 }
 
 // GetStaticGroupName to get static igmp group
 func (mvp *MvlanProfile) GetStaticGroupName(gip net.IP) string {
-        for _, mvg := range mvp.Groups {
-                if mvg.IsStatic {
-                        if doesIPMatch(gip, mvg.McIPs) {
-                                return mvg.Name
-                        }
-                }
-        }
-        return ""
+	for _, mvg := range mvp.Groups {
+		if mvg.IsStatic {
+			if doesIPMatch(gip, mvg.McIPs) {
+				return mvg.Name
+			}
+		}
+	}
+	return ""
 }
 
 // GetStaticIgmpGroup to get static igmp group
 func (mvp *MvlanProfile) GetStaticIgmpGroup(gip net.IP) *IgmpGroup {
-
-        staticGroupName := mvp.GetStaticGroupName(gip)
-        grpKey := mvp.generateGroupKey(staticGroupName, gip.String())
-        logger.Debugw(ctx, "Get Static IGMP Group", log.Fields{"Group": grpKey})
-        ig, ok := GetApplication().IgmpGroups.Load(grpKey)
-        if ok {
-                logger.Debugw(ctx, "Get Static IGMP Group Success", log.Fields{"Group": grpKey})
-                return ig.(*IgmpGroup)
-        }
-        return nil
+	staticGroupName := mvp.GetStaticGroupName(gip)
+	grpKey := mvp.generateGroupKey(staticGroupName, gip.String())
+	logger.Debugw(ctx, "Get Static IGMP Group", log.Fields{"Group": grpKey})
+	ig, ok := GetApplication().IgmpGroups.Load(grpKey)
+	if ok {
+		logger.Debugw(ctx, "Get Static IGMP Group Success", log.Fields{"Group": grpKey})
+		return ig.(*IgmpGroup)
+	}
+	return nil
 }
 
-//pushIgmpMcastFlows - Adds all IGMP related flows (generic DS flow & static group flows)
+// pushIgmpMcastFlows - Adds all IGMP related flows (generic DS flow & static group flows)
 func (mvp *MvlanProfile) pushIgmpMcastFlows(cntx context.Context, OLTSerialNum string) {
+	mvp.mvpLock.RLock()
+	defer mvp.mvpLock.RUnlock()
 
-        mvp.mvpLock.RLock()
-        defer mvp.mvpLock.RUnlock()
+	if mvp.DevicesList[OLTSerialNum] == Nil {
+		logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": OLTSerialNum, "Mvlan": mvp.Mvlan})
+		return
+	}
 
-        if mvp.DevicesList[OLTSerialNum] == Nil {
-                logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": OLTSerialNum, "Mvlan": mvp.Mvlan})
-                return
-        }
+	d, _ := GetApplication().GetDeviceBySerialNo(OLTSerialNum)
+	if d == nil {
+		logger.Warnw(ctx, "Skipping Igmp & Mcast Flow processing: Device Not Found", log.Fields{"Device_SrNo": OLTSerialNum, "Mvlan": mvp.Mvlan})
+		return
+	}
 
-        d, _ := GetApplication().GetDeviceBySerialNo(OLTSerialNum)
-        if d == nil {
-                logger.Warnw(ctx, "Skipping Igmp & Mcast Flow processing: Device Not Found", log.Fields{"Device_SrNo": OLTSerialNum, "Mvlan": mvp.Mvlan})
-                return
-        }
+	p := d.GetPort(d.NniPort)
 
-        p := d.GetPort(d.NniPort)
+	if p != nil && p.State == PortStateUp {
+		logger.Infow(ctx, "NNI Port Status is: UP & Vlan Enabled", log.Fields{"Device": d, "port": p})
 
-        if p != nil && p.State == PortStateUp {
-                logger.Infow(ctx, "NNI Port Status is: UP & Vlan Enabled", log.Fields{"Device": d, "port": p})
+		//Push Igmp DS Control Flows
+		err := mvp.ApplyIgmpDSFlowForMvp(cntx, d.Name)
+		if err != nil {
+			logger.Errorw(ctx, "DS IGMP Flow Add Failed for device",
+				log.Fields{"Reason": err.Error(), "device": d.Name})
+		}
 
-                //Push Igmp DS Control Flows
-                err := mvp.ApplyIgmpDSFlowForMvp(cntx, d.Name)
-                if err != nil {
-                        logger.Errorw(ctx, "DS IGMP Flow Add Failed for device",
-                                log.Fields{"Reason": err.Error(), "device": d.Name})
-                }
-
-                //Trigger Join for static channels
-                if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
-                        mvp.ProcessStaticGroup(cntx, d.Name, channelList, true)
-                } else {
-                        logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
-                }
-        }
+		//Trigger Join for static channels
+		if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
+			mvp.ProcessStaticGroup(cntx, d.Name, channelList, true)
+		} else {
+			logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
+		}
+	}
 }
-//removeIgmpMcastFlows - Removes all IGMP related flows (generic DS flow & static group flows)
+
+// removeIgmpMcastFlows - Removes all IGMP related flows (generic DS flow & static group flows)
 func (mvp *MvlanProfile) removeIgmpMcastFlows(cntx context.Context, oltSerialNum string) {
+	mvp.mvpLock.RLock()
+	defer mvp.mvpLock.RUnlock()
 
-        mvp.mvpLock.RLock()
-        defer mvp.mvpLock.RUnlock()
+	if d, _ := GetApplication().GetDeviceBySerialNo(oltSerialNum); d != nil {
+		p := d.GetPort(d.NniPort)
+		if p != nil {
+			logger.Infow(ctx, "NNI Port Status is: UP", log.Fields{"Device": d, "port": p})
 
-        if d, _ := GetApplication().GetDeviceBySerialNo(oltSerialNum); d != nil {
-                p := d.GetPort(d.NniPort)
-                if p != nil {
-                        logger.Infow(ctx, "NNI Port Status is: UP", log.Fields{"Device": d, "port": p})
+			// ***Do not change the order***
+			// When Vlan is disabled, the process end is determined by the DS Igmp flag in device
 
-                        // ***Do not change the order***
-                        // When Vlan is disabled, the process end is determined by the DS Igmp flag in device
+			//Trigger Leave for static channels
+			if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
+				mvp.ProcessStaticGroup(cntx, d.Name, channelList, false)
+			} else {
+				logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
+			}
 
-                        //Trigger Leave for static channels
-                        if channelList, containsStatic := mvp.getAllStaticChannels(); containsStatic {
-                                mvp.ProcessStaticGroup(cntx, d.Name, channelList, false)
-                        } else {
-                                logger.Infow(ctx, "No Static Channels Present", log.Fields{"mvp": mvp.Name, "Mvlan": mvp.Mvlan})
-                        }
+			//Remove all dynamic members for the Mvlan Profile
+			GetApplication().IgmpGroups.Range(func(key, value interface{}) bool {
+				ig := value.(*IgmpGroup)
+				if ig.Mvlan == mvp.Mvlan {
+					igd := ig.Devices[d.Name]
+					ig.DelIgmpGroupDevice(cntx, igd)
+					if ig.NumDevicesActive() == 0 {
+						GetApplication().DelIgmpGroup(cntx, ig)
+					}
+				}
+				return true
+			})
 
-                        //Remove all dynamic members for the Mvlan Profile
-                        GetApplication().IgmpGroups.Range(func(key, value interface{}) bool {
-                                ig := value.(*IgmpGroup)
-                                if ig.Mvlan == mvp.Mvlan {
-                                        igd := ig.Devices[d.Name]
-                                        ig.DelIgmpGroupDevice(cntx, igd)
-                                        if ig.NumDevicesActive() == 0 {
-                                                GetApplication().DelIgmpGroup(cntx, ig)
-                                        }
-                                }
-                                return true
-                        })
-
-                        //Remove DS Igmp trap flow
-                        err := mvp.RemoveIgmpDSFlowForMvp(cntx, d.Name)
-                        if err != nil {
-                                logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error(), "device": d.Name})
-                        }
-                }
-        }
+			//Remove DS Igmp trap flow
+			err := mvp.RemoveIgmpDSFlowForMvp(cntx, d.Name)
+			if err != nil {
+				logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error(), "device": d.Name})
+			}
+		}
+	}
 }
 
 // ApplyIgmpDSFlowForMvp to apply Igmp DS flow for mvlan.
 func (mvp *MvlanProfile) ApplyIgmpDSFlowForMvp(cntx context.Context, device string) error {
-        va := GetApplication()
-        dIntf, ok := va.DevicesDisc.Load(device)
-        if !ok {
-                return errors.New("Device Doesn't Exist")
-        }
-        d := dIntf.(*VoltDevice)
-        mvlan := mvp.Mvlan
+	va := GetApplication()
+	dIntf, ok := va.DevicesDisc.Load(device)
+	if !ok {
+		return errors.New("Device Doesn't Exist")
+	}
+	d := dIntf.(*VoltDevice)
+	mvlan := mvp.Mvlan
 
-        flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
-        if !ok || !flowAlreadyApplied {
-                flows, err := mvp.BuildIgmpDSFlows(device)
-                if err == nil {
-                        err = cntlr.GetController().AddFlows(cntx, d.NniPort, device, flows)
-                        if err != nil {
-                                logger.Warnw(ctx, "Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
-                                return err
-                        }
-                        d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = true
-                        logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"added\" for ",
-                                log.Fields{"device": d.SerialNum, "mvlan": mvlan})
-                } else {
-                        logger.Errorw(ctx, "DS IGMP Flow Add Failed", log.Fields{"Reason": err.Error(), "Mvlan": mvlan})
-                }
-        }
+	flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
+	if !ok || !flowAlreadyApplied {
+		flows, err := mvp.BuildIgmpDSFlows(device)
+		if err == nil {
+			err = cntlr.GetController().AddFlows(cntx, d.NniPort, device, flows)
+			if err != nil {
+				logger.Warnw(ctx, "Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
+				return err
+			}
+			d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = true
+			logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"added\" for ",
+				log.Fields{"device": d.SerialNum, "mvlan": mvlan})
+		} else {
+			logger.Errorw(ctx, "DS IGMP Flow Add Failed", log.Fields{"Reason": err.Error(), "Mvlan": mvlan})
+		}
+	}
 
-        return nil
+	return nil
 }
 
 // RemoveIgmpDSFlowForMvp to remove Igmp DS flow for mvlan.
 func (mvp *MvlanProfile) RemoveIgmpDSFlowForMvp(cntx context.Context, device string) error {
+	va := GetApplication()
+	mvlan := mvp.Mvlan
 
-        va := GetApplication()
-        mvlan := mvp.Mvlan
+	dIntf, ok := va.DevicesDisc.Load(device)
+	if !ok {
+		return errors.New("Device Doesn't Exist")
+	}
+	d := dIntf.(*VoltDevice)
+	/* No need of strict check during DS IGMP deletion
+	   flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
+	   if ok && flowAlreadyApplied
+	*/
+	flows, err := mvp.BuildIgmpDSFlows(device)
+	if err == nil {
+		flows.ForceAction = true
 
-        dIntf, ok := va.DevicesDisc.Load(device)
-        if !ok {
-                return errors.New("Device Doesn't Exist")
-        }
-        d := dIntf.(*VoltDevice)
-        /* No need of strict check during DS IGMP deletion
-        flowAlreadyApplied, ok := d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)]
-        if ok && flowAlreadyApplied
-        */
-        flows, err := mvp.BuildIgmpDSFlows(device)
-        if err == nil {
-                flows.ForceAction = true
+		err = mvp.DelFlows(cntx, d, flows)
+		if err != nil {
+			logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
+			return err
+		}
+		d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = false
+		logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"removed\" for ",
+			log.Fields{"device": d.SerialNum, "mvlan": mvlan})
+	} else {
+		logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error()})
+	}
 
-                err = mvp.DelFlows(cntx, d, flows)
-                if err != nil {
-                        logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
-                        return err
-                }
-                d.IgmpDsFlowAppliedForMvlan[uint16(mvlan)] = false
-                logger.Infow(ctx, "Updating voltDevice that IGMP DS flow as \"removed\" for ",
-                        log.Fields{"device": d.SerialNum, "mvlan": mvlan})
-        } else {
-                logger.Errorw(ctx, "DS IGMP Flow Del Failed", log.Fields{"Reason": err.Error()})
-        }
-
-        return nil
+	return nil
 }
 
 // BuildIgmpDSFlows to build Igmp DS flows for NNI port
 func (mvp *MvlanProfile) BuildIgmpDSFlows(device string) (*of.VoltFlow, error) {
-        dIntf, ok := GetApplication().DevicesDisc.Load(device)
-        if !ok {
-                return nil, errors.New("Device Doesn't Exist")
-        }
-        d := dIntf.(*VoltDevice)
+	dIntf, ok := GetApplication().DevicesDisc.Load(device)
+	if !ok {
+		return nil, errors.New("Device Doesn't Exist")
+	}
+	d := dIntf.(*VoltDevice)
 
-        logger.Infow(ctx, "Building DS IGMP Flow for NNI port", log.Fields{"vs": d.NniPort, "Mvlan": mvp.Mvlan})
-        flow := &of.VoltFlow{}
-        flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
-        subFlow := of.NewVoltSubFlow()
-        subFlow.SetTableID(0)
-        subFlow.SetMatchVlan(mvp.Mvlan)
+	logger.Infow(ctx, "Building DS IGMP Flow for NNI port", log.Fields{"vs": d.NniPort, "Mvlan": mvp.Mvlan})
+	flow := &of.VoltFlow{}
+	flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
+	subFlow := of.NewVoltSubFlow()
+	subFlow.SetTableID(0)
+	subFlow.SetMatchVlan(mvp.Mvlan)
 
-        nniPort, err := GetApplication().GetNniPort(device)
-        if err != nil {
-                return nil, err
-        }
-        nniPortID, err1 := GetApplication().GetPortID(nniPort)
-        if err1 != nil {
-                return nil, errors.New("Unknown NNI outport")
-        }
-        subFlow.SetInPort(nniPortID)
-        subFlow.SetIgmpMatch()
-        subFlow.SetReportToController()
-        subFlow.Cookie = uint64(nniPortID)<<32 | uint64(mvp.Mvlan)
-        subFlow.Priority = of.IgmpFlowPriority
+	nniPort, err := GetApplication().GetNniPort(device)
+	if err != nil {
+		return nil, err
+	}
+	nniPortID, err1 := GetApplication().GetPortID(nniPort)
+	if err1 != nil {
+		return nil, errors.New("Unknown NNI outport")
+	}
+	subFlow.SetInPort(nniPortID)
+	subFlow.SetIgmpMatch()
+	subFlow.SetReportToController()
+	subFlow.Cookie = uint64(nniPortID)<<32 | uint64(mvp.Mvlan)
+	subFlow.Priority = of.IgmpFlowPriority
 
-        flow.SubFlows[subFlow.Cookie] = subFlow
-        logger.Infow(ctx, "Built DS IGMP flow", log.Fields{"cookie": subFlow.Cookie, "subflow": subFlow})
-        return flow, nil
+	flow.SubFlows[subFlow.Cookie] = subFlow
+	logger.Infow(ctx, "Built DS IGMP flow", log.Fields{"cookie": subFlow.Cookie, "subflow": subFlow})
+	return flow, nil
 }
 
-//updateStaticGroups - Generates static joins & leaves for newly added and removed static channels respectively
+// updateStaticGroups - Generates static joins & leaves for newly added and removed static channels respectively
 func (mvp *MvlanProfile) updateStaticGroups(cntx context.Context, deviceID string, added []net.IP, removed []net.IP) {
+	// Update static group configs for all associated devices
+	updateGroups := func(key interface{}, value interface{}) bool {
+		d := value.(*VoltDevice)
 
-        //Update static group configs for all associated devices
-        updateGroups := func(key interface{}, value interface{}) bool {
-                d := value.(*VoltDevice)
+		if mvp.DevicesList[d.SerialNum] == Nil {
+			logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
+			return true
+		}
+		// TODO if mvp.IsChannelBasedGroup {
+		mvp.ProcessStaticGroup(cntx, d.Name, added, true)
+		mvp.ProcessStaticGroup(cntx, d.Name, removed, false)
+		//}
+		return true
+	}
 
-                if mvp.DevicesList[d.SerialNum] == Nil {
-                        logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
-                        return true
-                }
-                //TODO if mvp.IsChannelBasedGroup {
-                mvp.ProcessStaticGroup(cntx, d.Name, added, true)
-                mvp.ProcessStaticGroup(cntx, d.Name, removed, false)
-                //}
-                return true
-        }
-
-        if deviceID != "" {
-                vd := GetApplication().GetDevice(deviceID)
-                updateGroups(deviceID, vd)
-        } else {
-                GetApplication().DevicesDisc.Range(updateGroups)
-        }
+	if deviceID != "" {
+		vd := GetApplication().GetDevice(deviceID)
+		updateGroups(deviceID, vd)
+	} else {
+		GetApplication().DevicesDisc.Range(updateGroups)
+	}
 }
 
-//updateDynamicGroups - Generates joins with updated sources for existing channels
+// updateDynamicGroups - Generates joins with updated sources for existing channels
 func (mvp *MvlanProfile) updateDynamicGroups(cntx context.Context, deviceID string, added []net.IP, removed []net.IP) {
+	//mvlan := mvp.Mvlan
+	va := GetApplication()
 
-        //mvlan := mvp.Mvlan
-        va := GetApplication()
+	updateGroups := func(key interface{}, value interface{}) bool {
+		d := value.(*VoltDevice)
 
-        updateGroups := func(key interface{}, value interface{}) bool {
-                d := value.(*VoltDevice)
+		if mvp.DevicesList[d.SerialNum] == Nil {
+			logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
+			return true
+		}
+		for _, groupAddr := range added {
+			_, gName := va.GetMvlanProfileForMcIP(mvp.Name, groupAddr)
+			grpKey := mvp.generateGroupKey(gName, groupAddr.String())
+			logger.Debugw(ctx, "IGMP Group", log.Fields{"Group": grpKey, "groupAddr": groupAddr})
+			if igIntf, ok := va.IgmpGroups.Load(grpKey); ok {
+				ig := igIntf.(*IgmpGroup)
+				if igd, ok := ig.getIgmpGroupDevice(cntx, d.Name); ok {
+					if igcIntf, ok := igd.GroupChannels.Load(groupAddr.String()); ok {
+						igc := igcIntf.(*IgmpGroupChannel)
+						incl := false
+						var ip []net.IP
+						var groupModified = false
+						if _, ok := mvp.Proxy[igc.GroupName]; ok {
+							if mvp.Proxy[igc.GroupName].Mode == common.Include {
+								incl = true
+							}
+							ip = mvp.Proxy[igc.GroupName].SourceList
+						}
+						for port, igp := range igc.NewReceivers {
+							// Process the include/exclude list which may end up modifying the group
+							if change, _ := igc.ProcessSources(cntx, port, ip, incl); change {
+								groupModified = true
+							}
+							igc.ProcessMode(port, incl)
 
-                if mvp.DevicesList[d.SerialNum] == Nil {
-                        logger.Infow(ctx, "Mvlan Profile not configure for device", log.Fields{"Device": d, "Profile Device List": mvp.DevicesList})
-                        return true
-                }
-                for _, groupAddr := range added {
+							if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
+								logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+							}
+						}
+						// If the group is modified as this is the first receiver or due to include/exclude list modification
+						// send a report to the upstream multicast servers
+						if groupModified {
+							logger.Debug(ctx, "Group Modified and IGMP report sent to the upstream server")
+							igc.SendReport(false)
+						}
+						if err := igc.WriteToDb(cntx); err != nil {
+							logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
+						}
+					}
+				}
+			}
+		}
 
-                        _, gName := va.GetMvlanProfileForMcIP(mvp.Name, groupAddr)
-                        grpKey := mvp.generateGroupKey(gName, groupAddr.String())
-                        logger.Debugw(ctx, "IGMP Group", log.Fields{"Group": grpKey, "groupAddr": groupAddr})
-                        if igIntf, ok := va.IgmpGroups.Load(grpKey); ok {
-                                ig := igIntf.(*IgmpGroup)
-                                if igd, ok := ig.getIgmpGroupDevice(cntx, d.Name); ok {
-                                        if igcIntf, ok := igd.GroupChannels.Load(groupAddr.String()); ok {
-                                                igc := igcIntf.(*IgmpGroupChannel)
-                                                incl := false
-                                                var ip []net.IP
-                                                var groupModified = false
-                                                if _, ok := mvp.Proxy[igc.GroupName]; ok {
-                                                        if mvp.Proxy[igc.GroupName].Mode == common.Include {
-                                                                incl = true
-                                                        }
-                                                        ip = mvp.Proxy[igc.GroupName].SourceList
-                                                }
-                                                for port, igp := range igc.NewReceivers {
-                                                        // Process the include/exclude list which may end up modifying the group
-                                                        if change, _ := igc.ProcessSources(cntx, port, ip, incl); change {
-                                                                groupModified = true
-                                                        }
-                                                        igc.ProcessMode(port, incl)
+		return true
+	}
 
-                                                        if err := igp.WriteToDb(cntx, igc.Mvlan, igc.GroupAddr, igc.Device); err != nil {
-                                                                logger.Errorw(ctx, "Igmp group port Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-                                                        }
-                                                }
-                                                // If the group is modified as this is the first receiver or due to include/exclude list modification
-                                                // send a report to the upstream multicast servers
-                                                if groupModified {
-                                                        logger.Debug(ctx, "Group Modified and IGMP report sent to the upstream server")
-                                                        igc.SendReport(false)
-                                                }
-                                                if err := igc.WriteToDb(cntx); err != nil {
-                                                        logger.Errorw(ctx, "Igmp group channel Write to DB failed", log.Fields{"mvlan": igc.Mvlan, "GroupAddr": igc.GroupAddr})
-                                                }
-                                        }
-                                }
-                        }
-                }
-
-                return true
-        }
-
-        if deviceID != "" {
-                vd := GetApplication().GetDevice(deviceID)
-                updateGroups(deviceID, vd)
-        } else {
-                GetApplication().DevicesDisc.Range(updateGroups)
-        }
+	if deviceID != "" {
+		vd := GetApplication().GetDevice(deviceID)
+		updateGroups(deviceID, vd)
+	} else {
+		GetApplication().DevicesDisc.Range(updateGroups)
+	}
 }
 
-//GroupsUpdated - Handles removing of Igmp Groups, flows & group table entries for
-//channels removed as part of update
+// GroupsUpdated - Handles removing of Igmp Groups, flows & group table entries for
+// channels removed as part of update
 func (mvp *MvlanProfile) GroupsUpdated(cntx context.Context, deviceID string) {
+	deleteChannelIfRemoved := func(key interface{}, value interface{}) bool {
+		ig := value.(*IgmpGroup)
 
-        deleteChannelIfRemoved := func(key interface{}, value interface{}) bool {
-                ig := value.(*IgmpGroup)
+		if ig.Mvlan != mvp.Mvlan {
+			return true
+		}
+		grpName := ig.GroupName
+		logger.Infow(ctx, "###Update Cycle", log.Fields{"IG": ig.GroupName, "Addr": ig.GroupAddr})
+		// Check if group exists and remove the entire group object otherwise
+		if currentChannels := mvp.Groups[grpName]; currentChannels != nil {
+			if mvp.IsChannelBasedGroup {
+				channelPresent := doesIPMatch(ig.GroupAddr, currentChannels.McIPs)
+				if channelPresent || mvp.isChannelStatic(ig.GroupAddr) {
+					return true
+				}
+			} else {
+				allExistingChannels := ig.GetAllIgmpChannelForDevice(deviceID)
+				for channel := range allExistingChannels {
+					channelIP := net.ParseIP(channel)
+					channelPresent := mvp.IsChannelPresent(channelIP, currentChannels.McIPs, mvp.IsStaticGroup(ig.GroupName))
+					if channelPresent {
+						staticChannel := mvp.isChannelStatic(channelIP)
+						logger.Infow(ctx, "###Channel Comparison", log.Fields{"staticChannel": staticChannel, "Group": mvp.IsStaticGroup(ig.GroupName), "Channel": channel})
+						// Logic:
+						// If channel is Static & existing Group is also static - No migration required
+						// If channel is not Static & existing Group is also not static - No migration required
 
-                if ig.Mvlan != mvp.Mvlan {
-                        return true
-                }
-                grpName := ig.GroupName
-                logger.Infow(ctx, "###Update Cycle", log.Fields{"IG": ig.GroupName, "Addr": ig.GroupAddr})
-                //Check if group exists and remove the entire group object otherwise
-                if currentChannels := mvp.Groups[grpName]; currentChannels != nil {
+						// If channel is Static and existing Group is not static - Migrate (from dynamic to static)
+						// (Channel already part of dynamic, added to static)
 
-                        if mvp.IsChannelBasedGroup {
-                                channelPresent := doesIPMatch(ig.GroupAddr, currentChannels.McIPs)
-                                if channelPresent || mvp.isChannelStatic(ig.GroupAddr) {
-                                        return true
-                                }
-                        } else {
-                                allExistingChannels := ig.GetAllIgmpChannelForDevice(deviceID)
-                                for channel := range allExistingChannels {
-                                        channelIP := net.ParseIP(channel)
-                                        channelPresent := mvp.IsChannelPresent(channelIP, currentChannels.McIPs, mvp.IsStaticGroup(ig.GroupName))
-                                        if channelPresent {
-                                                staticChannel := mvp.isChannelStatic(channelIP)
-                                                logger.Infow(ctx, "###Channel Comparision", log.Fields{"staticChannel": staticChannel, "Group": mvp.IsStaticGroup(ig.GroupName), "Channel": channel})
-                                                // Logic:
-                                                // If channel is Static & existing Group is also static - No migration required
-                                                // If channel is not Static & existing Group is also not static - No migration required
-
-                                                // If channel is Static and existing Group is not static - Migrate (from dynamic to static)
-                                                //    (Channel already part of dynamic, added to static)
-
-                                                // If channel is not Static but existing Group is static - Migrate (from static to dynamic)
-                                                //    (Channel removed from satic but part of dynamic)
-                                                if (staticChannel != mvp.IsStaticGroup(ig.GroupName)) || (ig.IsGroupStatic != mvp.IsStaticGroup(ig.GroupName)) { // Equivalent of XOR
-                                                        ig.HandleGroupMigration(cntx, deviceID, channelIP)
-                                                } else {
-                                                        if (ig.IsGroupStatic) && mvp.IsStaticGroup(ig.GroupName) {
-                                                                if ig.GroupName != mvp.GetStaticGroupName(channelIP) {
-                                                                        ig.HandleGroupMigration(cntx, deviceID, channelIP)
-                                                                }
-                                                        }
-                                                        continue
-                                                }
-                                        } else {
-                                                logger.Debugw(ctx, "Channel Removed", log.Fields{"Channel": channel, "Group": grpName})
-                                                ig.DelIgmpChannel(cntx, deviceID, net.ParseIP(channel))
-                                                if ig.NumDevicesActive() == 0 {
-                                                        GetApplication().DelIgmpGroup(cntx, ig)
-                                                }
-                                        }
-                                }
-                                ig.IsGroupStatic = mvp.IsStaticGroup(ig.GroupName)
-                                if err := ig.WriteToDb(cntx); err != nil {
-                                        logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
-                                }
-                                return true
-                        }
-                }
-                logger.Debugw(ctx, "Group Removed", log.Fields{"Channel": ig.GroupAddr, "Group": grpName, "ChannelBasedGroup": ig.IsChannelBasedGroup})
-                ig.DelIgmpGroup(cntx)
-                logger.Debugw(ctx, "Removed Igmp Group", log.Fields{"Channel": ig.GroupAddr, "Group": grpName})
-                return true
-        }
-        GetApplication().IgmpGroups.Range(deleteChannelIfRemoved)
+						// If channel is not Static but existing Group is static - Migrate (from static to dynamic)
+						// (Channel removed from satic but part of dynamic)
+						if (staticChannel != mvp.IsStaticGroup(ig.GroupName)) || (ig.IsGroupStatic != mvp.IsStaticGroup(ig.GroupName)) { // Equivalent of XOR
+							ig.HandleGroupMigration(cntx, deviceID, channelIP)
+						} else {
+							if (ig.IsGroupStatic) && mvp.IsStaticGroup(ig.GroupName) {
+								if ig.GroupName != mvp.GetStaticGroupName(channelIP) {
+									ig.HandleGroupMigration(cntx, deviceID, channelIP)
+								}
+							}
+							continue
+						}
+					} else {
+						logger.Debugw(ctx, "Channel Removed", log.Fields{"Channel": channel, "Group": grpName})
+						ig.DelIgmpChannel(cntx, deviceID, net.ParseIP(channel))
+						if ig.NumDevicesActive() == 0 {
+							GetApplication().DelIgmpGroup(cntx, ig)
+						}
+					}
+				}
+				ig.IsGroupStatic = mvp.IsStaticGroup(ig.GroupName)
+				if err := ig.WriteToDb(cntx); err != nil {
+					logger.Errorw(ctx, "Igmp group Write to DB failed", log.Fields{"groupName": ig.GroupName})
+				}
+				return true
+			}
+		}
+		logger.Debugw(ctx, "Group Removed", log.Fields{"Channel": ig.GroupAddr, "Group": grpName, "ChannelBasedGroup": ig.IsChannelBasedGroup})
+		ig.DelIgmpGroup(cntx)
+		logger.Debugw(ctx, "Removed Igmp Group", log.Fields{"Channel": ig.GroupAddr, "Group": grpName})
+		return true
+	}
+	GetApplication().IgmpGroups.Range(deleteChannelIfRemoved)
 }
 
 // IsChannelPresent to check if channel is present
 func (mvp *MvlanProfile) IsChannelPresent(channelIP net.IP, groupChannelList []string, IsStaticGroup bool) bool {
-        // Only in case of static group, migration need to be supported.
-        // Dynamic to dynamic group migration not supported currently
-        if doesIPMatch(channelIP, groupChannelList) || mvp.isChannelStatic(channelIP) {
-                return true
-        } else if IsStaticGroup {
-                return (mvp.GetMvlanGroup(channelIP) != "")
-        }
+	// Only in case of static group, migration need to be supported.
+	// Dynamic to dynamic group migration not supported currently
+	if doesIPMatch(channelIP, groupChannelList) || mvp.isChannelStatic(channelIP) {
+		return true
+	} else if IsStaticGroup {
+		return (mvp.GetMvlanGroup(channelIP) != "")
+	}
 
-        return false
+	return false
 }
 
-
 // GetMvlanGroup to get mvlan group
 func (mvp *MvlanProfile) GetMvlanGroup(ip net.IP) string {
-        //Check for Static Group First
-        if mvp.containsStaticChannels() {
-                grpName := mvp.GetStaticGroupName(ip)
-                if grpName != "" {
-                        return grpName
-                }
-        }
+	// Check for Static Group First
+	if mvp.containsStaticChannels() {
+		grpName := mvp.GetStaticGroupName(ip)
+		if grpName != "" {
+			return grpName
+		}
+	}
 
-        for _, mvg := range mvp.Groups {
-                if mvg.Wildcard {
-                        return mvg.Name
-                }
-                if doesIPMatch(ip, mvg.McIPs) {
-                        return mvg.Name
-                }
-        }
-        return ""
+	for _, mvg := range mvp.Groups {
+		if mvg.Wildcard {
+			return mvg.Name
+		}
+		if doesIPMatch(ip, mvg.McIPs) {
+			return mvg.Name
+		}
+	}
+	return ""
 }
 
 // ProcessStaticGroup - Process Static Join/Leave Req for static channels
 func (mvp *MvlanProfile) ProcessStaticGroup(cntx context.Context, device string, groupAddresses []net.IP, isJoin bool) {
+	logger.Debugw(ctx, "Received Static Group Request", log.Fields{"Device": device, "Join": isJoin, "Group Address List": groupAddresses})
 
-        logger.Debugw(ctx, "Received Static Group Request", log.Fields{"Device": device, "Join": isJoin, "Group Address List": groupAddresses})
+	mvlan := mvp.Mvlan
+	va := GetApplication()
 
-        mvlan := mvp.Mvlan
-        va := GetApplication()
+	// TODO - Handle bulk add of groupAddr
+	for _, groupAddr := range groupAddresses {
+		ig := mvp.GetStaticIgmpGroup(groupAddr)
+		if isJoin {
+			vd := va.GetDevice(device)
+			igmpProf, _, _ := getIgmpProxyCfgAndIP(mvlan, vd.SerialNum)
+			ver := igmpProf.IgmpVerToServer
 
-        //TODO - Handle bulk add of groupAddr
-        for _, groupAddr := range groupAddresses {
+			if ig == nil {
+				// First time group Creation: Create the IGMP group and then add the receiver to the group
+				logger.Infow(ctx, "Static IGMP Add received for new group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
+				if ig = GetApplication().AddIgmpGroup(cntx, mvp.Name, groupAddr, device); ig != nil {
+					ig.IgmpGroupLock.Lock()
+					ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
+						0, 0, 0xFF)
+					ig.IgmpGroupLock.Unlock()
+				} else {
+					logger.Warnw(ctx, "Static IGMP Group Creation Failed", log.Fields{"Addr": groupAddr})
+				}
+			} else {
+				// Converting existing dynamic group to static group
+				if !mvp.IsStaticGroup(ig.GroupName) {
+					ig.updateGroupName(cntx, ig.GroupName)
+				}
+				// Update case: If the IGMP group is already created. just add the receiver
+				logger.Infow(ctx, "Static IGMP Add received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
+				ig.IgmpGroupLock.Lock()
+				ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
+					0, 0, 0xFF)
+				ig.IgmpGroupLock.Unlock()
+			}
+		} else if ig != nil {
+			logger.Infow(ctx, "Static IGMP Del received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
 
-                ig := mvp.GetStaticIgmpGroup(groupAddr)
-                if isJoin {
-                        vd := va.GetDevice(device)
-                        igmpProf, _, _ := getIgmpProxyCfgAndIP(mvlan, vd.SerialNum)
-                        ver := igmpProf.IgmpVerToServer
-
-                        if ig == nil {
-                                // First time group Creation: Create the IGMP group and then add the receiver to the group
-                                logger.Infow(ctx, "Static IGMP Add received for new group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
-                                if ig := GetApplication().AddIgmpGroup(cntx, mvp.Name, groupAddr, device); ig != nil {
-                                        ig.IgmpGroupLock.Lock()
-                                        ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
-                                                0, 0, 0xFF)
-                                        ig.IgmpGroupLock.Unlock()
-                                } else {
-                                        logger.Warnw(ctx, "Static IGMP Group Creation Failed", log.Fields{"Addr": groupAddr})
-                                }
-                        } else {
-                                //Converting existing dynamic group to static group
-                                if !mvp.IsStaticGroup(ig.GroupName) {
-                                        ig.updateGroupName(cntx, ig.GroupName)
-                                }
-                                // Update case: If the IGMP group is already created. just add the receiver
-                                logger.Infow(ctx, "Static IGMP Add received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
-                                ig.IgmpGroupLock.Lock()
-                                ig.AddReceiver(cntx, device, StaticPort, groupAddr, nil, getVersion(ver),
-                                        0, 0, 0xFF)
-                                ig.IgmpGroupLock.Unlock()
-                        }
-                } else if ig != nil {
-                        logger.Infow(ctx, "Static IGMP Del received for existing group", log.Fields{"Addr": groupAddr, "Port": StaticPort})
-
-                        if ig.IsChannelBasedGroup {
-                                grpName := mvp.GetMvlanGroup(ig.GroupAddr)
-                                if grpName != "" {
-                                        ig.IgmpGroupLock.Lock()
-                                        ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
-                                        ig.IgmpGroupLock.Unlock()
-                                        ig.updateGroupName(cntx, grpName)
-                                } else {
-                                        ig.DelIgmpGroup(cntx)
-                                }
-                        } else {
-                                ig.IgmpGroupLock.Lock()
-                                ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
-                                ig.IgmpGroupLock.Unlock()
-                        }
-                        if ig.NumDevicesActive() == 0 {
-                                GetApplication().DelIgmpGroup(cntx, ig)
-                        }
-                } else {
-                        logger.Warnw(ctx, "Static IGMP Del received for unknown group", log.Fields{"Addr": groupAddr})
-                }
-        }
+			if ig.IsChannelBasedGroup {
+				grpName := mvp.GetMvlanGroup(ig.GroupAddr)
+				if grpName != "" {
+					ig.IgmpGroupLock.Lock()
+					ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
+					ig.IgmpGroupLock.Unlock()
+					ig.updateGroupName(cntx, grpName)
+				} else {
+					ig.DelIgmpGroup(cntx)
+				}
+			} else {
+				ig.IgmpGroupLock.Lock()
+				ig.DelReceiver(cntx, device, StaticPort, groupAddr, nil, 0xFF)
+				ig.IgmpGroupLock.Unlock()
+			}
+			if ig.NumDevicesActive() == 0 {
+				GetApplication().DelIgmpGroup(cntx, ig)
+			}
+		} else {
+			logger.Warnw(ctx, "Static IGMP Del received for unknown group", log.Fields{"Addr": groupAddr})
+		}
+	}
 }
 
-//getStaticChannelDiff - return the static channel newly added and removed from existing static group
+// getStaticChannelDiff - return the static channel newly added and removed from existing static group
 func (mvp *MvlanProfile) getStaticChannelDiff() (newlyAdded []net.IP, removed []net.IP, common []net.IP) {
-
-        var commonChannels []net.IP
-        newChannelList, _ := mvp.getAllStaticChannels()
-        existingChannelList, _ := mvp.getAllOldGroupStaticChannels()
-        if len(existingChannelList) == 0 {
-                return newChannelList, []net.IP{}, []net.IP{}
-        }
-        for _, newChannel := range append([]net.IP{}, newChannelList...) {
-                for _, existChannel := range append([]net.IP{}, existingChannelList...) {
-
-                        //Remove common channels between existing and new list
-                        // The remaining in the below slices give the results
-                        // Remaining in newChannelList: Newly added
-                        // Remaining in existingChannelList: Removed channels
-                        if existChannel.Equal(newChannel) {
-                                existingChannelList = removeIPFromList(existingChannelList, existChannel)
-                                newChannelList = removeIPFromList(newChannelList, newChannel)
-                                commonChannels = append(commonChannels, newChannel)
-                                logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
-                                break
-                        }
-                }
-        }
-        return newChannelList, existingChannelList, commonChannels
+	var commonChannels []net.IP
+	newChannelList, _ := mvp.getAllStaticChannels()
+	existingChannelList, _ := mvp.getAllOldGroupStaticChannels()
+	if len(existingChannelList) == 0 {
+		return newChannelList, []net.IP{}, []net.IP{}
+	}
+	for _, newChannel := range append([]net.IP{}, newChannelList...) {
+		for _, existChannel := range append([]net.IP{}, existingChannelList...) {
+			// Remove common channels between existing and new list
+			// The remaining in the below slices give the results
+			// Remaining in newChannelList: Newly added
+			// Remaining in existingChannelList: Removed channels
+			if existChannel.Equal(newChannel) {
+				existingChannelList = removeIPFromList(existingChannelList, existChannel)
+				newChannelList = removeIPFromList(newChannelList, newChannel)
+				commonChannels = append(commonChannels, newChannel)
+				logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
+				break
+			}
+		}
+	}
+	return newChannelList, existingChannelList, commonChannels
 }
 
-//getGroupChannelDiff - return the channel newly added and removed from existing group
+// getGroupChannelDiff - return the channel newly added and removed from existing group
 func (mvp *MvlanProfile) getGroupChannelDiff(newGroup *MvlanGroup, oldGroup *MvlanGroup) (newlyAdded []net.IP, removed []net.IP, common []net.IP) {
-
-        var commonChannels []net.IP
-        newChannelList, _ := newGroup.getAllChannels()
-        existingChannelList, _ := oldGroup.getAllChannels()
-        if len(existingChannelList) == 0 {
-                return newChannelList, []net.IP{}, []net.IP{}
-        }
-        for _, newChannel := range append([]net.IP{}, newChannelList...) {
-                for _, existChannel := range append([]net.IP{}, existingChannelList...) {
-
-                        //Remove common channels between existing and new list
-                        // The remaining in the below slices give the results
-                        // Remaining in newChannelList: Newly added
-                        // Remaining in existingChannelList: Removed channels
-                        if existChannel.Equal(newChannel) {
-                                existingChannelList = removeIPFromList(existingChannelList, existChannel)
-                                newChannelList = removeIPFromList(newChannelList, newChannel)
-                                commonChannels = append(commonChannels, newChannel)
-                                logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
-                                break
-                        }
-                }
-        }
-        return newChannelList, existingChannelList, commonChannels
+	var commonChannels []net.IP
+	newChannelList, _ := newGroup.getAllChannels()
+	existingChannelList, _ := oldGroup.getAllChannels()
+	if len(existingChannelList) == 0 {
+		return newChannelList, []net.IP{}, []net.IP{}
+	}
+	for _, newChannel := range append([]net.IP{}, newChannelList...) {
+		for _, existChannel := range append([]net.IP{}, existingChannelList...) {
+			// Remove common channels between existing and new list
+			// The remaining in the below slices give the results
+			// Remaining in newChannelList: Newly added
+			// Remaining in existingChannelList: Removed channels
+			if existChannel.Equal(newChannel) {
+				existingChannelList = removeIPFromList(existingChannelList, existChannel)
+				newChannelList = removeIPFromList(newChannelList, newChannel)
+				commonChannels = append(commonChannels, newChannel)
+				logger.Infow(ctx, "#############Channel: "+existChannel.String()+" New: "+newChannel.String(), log.Fields{"Added": newChannelList, "Removed": existingChannelList})
+				break
+			}
+		}
+	}
+	return newChannelList, existingChannelList, commonChannels
 }
 
 // UpdateProfile - Updates the group & member info w.r.t the mvlan profile for the given device
 func (mvp *MvlanProfile) UpdateProfile(cntx context.Context, deviceID string) {
-        logger.Infow(ctx, "Update Mvlan Profile task triggered", log.Fields{"Mvlan": mvp.Mvlan})
-        var removedStaticChannels []net.IP
-        addedStaticChannels := []net.IP{}
-        /* Taking mvpLock to protect the mvp groups and proxy */
-        mvp.mvpLock.RLock()
-        defer mvp.mvpLock.RUnlock()
+	logger.Infow(ctx, "Update Mvlan Profile task triggered", log.Fields{"Mvlan": mvp.Mvlan})
+	var removedStaticChannels []net.IP
+	addedStaticChannels := []net.IP{}
+	/* Taking mvpLock to protect the mvp groups and proxy */
+	mvp.mvpLock.RLock()
+	defer mvp.mvpLock.RUnlock()
 
-        serialNo := ""
-        if deviceID != "" {
-                if vd := GetApplication().GetDevice(deviceID); vd != nil {
-                        serialNo = vd.SerialNum
-                        if mvp.DevicesList[serialNo] != UpdateInProgress {
-                                logger.Warnw(ctx, "Exiting Update Task since device not present in MvlanProfile", log.Fields{"Device": deviceID, "SerialNum": vd.SerialNum, "MvlanProfile": mvp})
-                                return
-                        }
-                } else {
-                        logger.Errorw(ctx, "Volt Device not found. Stopping Update Mvlan Profile processing for device", log.Fields{"SerialNo": deviceID, "MvlanProfile": mvp})
-                        return
-                }
-        }
+	serialNo := ""
+	if deviceID != "" {
+		if vd := GetApplication().GetDevice(deviceID); vd != nil {
+			serialNo = vd.SerialNum
+			if mvp.DevicesList[serialNo] != UpdateInProgress {
+				logger.Warnw(ctx, "Exiting Update Task since device not present in MvlanProfile", log.Fields{"Device": deviceID, "SerialNum": vd.SerialNum, "MvlanProfile": mvp})
+				return
+			}
+		} else {
+			logger.Errorw(ctx, "Volt Device not found. Stopping Update Mvlan Profile processing for device", log.Fields{"SerialNo": deviceID, "MvlanProfile": mvp})
+			return
+		}
+	}
 
-        //Update the groups based on static channels added & removed
-        if mvp.containsStaticChannels() {
-                addedStaticChannels, removedStaticChannels, _ = mvp.getStaticChannelDiff()
-                logger.Debugw(ctx, "Update Task - Static Group Changes", log.Fields{"Added": addedStaticChannels, "Removed": removedStaticChannels})
+	// Update the groups based on static channels added & removed
+	if mvp.containsStaticChannels() {
+		addedStaticChannels, removedStaticChannels, _ = mvp.getStaticChannelDiff()
+		logger.Debugw(ctx, "Update Task - Static Group Changes", log.Fields{"Added": addedStaticChannels, "Removed": removedStaticChannels})
 
-                if len(addedStaticChannels) > 0 || len(removedStaticChannels) > 0 {
-                        mvp.updateStaticGroups(cntx, deviceID, []net.IP{}, removedStaticChannels)
-                }
-        }
-        mvp.GroupsUpdated(cntx, deviceID)
-        if len(addedStaticChannels) > 0 {
-                mvp.updateStaticGroups(cntx, deviceID, addedStaticChannels, []net.IP{})
-        }
+		if len(addedStaticChannels) > 0 || len(removedStaticChannels) > 0 {
+			mvp.updateStaticGroups(cntx, deviceID, []net.IP{}, removedStaticChannels)
+		}
+	}
+	mvp.GroupsUpdated(cntx, deviceID)
+	if len(addedStaticChannels) > 0 {
+		mvp.updateStaticGroups(cntx, deviceID, addedStaticChannels, []net.IP{})
+	}
 
-        /* Need to handle if SSM params are modified for groups */
-        for key := range mvp.Groups {
-                _, _, commonChannels := mvp.getGroupChannelDiff(mvp.Groups[key], mvp.oldGroups[key])
-                if mvp.checkStaticGrpSSMProxyDiff(mvp.oldProxy[key], mvp.Proxy[key]) {
-                        if mvp.Groups[key].IsStatic {
-                                /* Static group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
-                                mvp.updateStaticGroups(cntx, deviceID, commonChannels, []net.IP{})
-                        } else {
-                                /* Dynamic group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
-                                mvp.updateDynamicGroups(cntx, deviceID, commonChannels, []net.IP{})
-                        }
-                }
-        }
+	/* Need to handle if SSM params are modified for groups */
+	for key := range mvp.Groups {
+		_, _, commonChannels := mvp.getGroupChannelDiff(mvp.Groups[key], mvp.oldGroups[key])
+		if mvp.checkStaticGrpSSMProxyDiff(mvp.oldProxy[key], mvp.Proxy[key]) {
+			if mvp.Groups[key].IsStatic {
+				/* Static group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
+				mvp.updateStaticGroups(cntx, deviceID, commonChannels, []net.IP{})
+			} else {
+				/* Dynamic group proxy modified, need to trigger membership report with new mode/src-list for existing channels */
+				mvp.updateDynamicGroups(cntx, deviceID, commonChannels, []net.IP{})
+			}
+		}
+	}
 
-        mvp.SetUpdateStatus(serialNo, NoOp)
+	mvp.SetUpdateStatus(serialNo, NoOp)
 
-        if deviceID == "" || !mvp.isUpdateInProgress() {
-                mvp.oldGroups = nil
-        }
-        if err := mvp.WriteToDb(cntx); err != nil {
-                logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
-        }
-        logger.Debugw(ctx, "Updated MVLAN Profile", log.Fields{"VLAN": mvp.Mvlan, "Name": mvp.Name, "Grp IPs": mvp.Groups})
+	if deviceID == "" || !mvp.isUpdateInProgress() {
+		mvp.oldGroups = nil
+	}
+	if err := mvp.WriteToDb(cntx); err != nil {
+		logger.Errorw(ctx, "Mvlan profile write to DB failed", log.Fields{"ProfileName": mvp.Name})
+	}
+	logger.Debugw(ctx, "Updated MVLAN Profile", log.Fields{"VLAN": mvp.Mvlan, "Name": mvp.Name, "Grp IPs": mvp.Groups})
 }
 
-//checkStaticGrpSSMProxyDiff- return true if the proxy of oldGroup is modified in newGroup
+// checkStaticGrpSSMProxyDiff- return true if the proxy of oldGroup is modified in newGroup
 func (mvp *MvlanProfile) checkStaticGrpSSMProxyDiff(oldProxy *MCGroupProxy, newProxy *MCGroupProxy) bool {
+	if oldProxy == nil && newProxy == nil {
+		return false
+	}
+	if (oldProxy == nil && newProxy != nil) ||
+		(oldProxy != nil && newProxy == nil) {
+		return true
+	}
 
-        if oldProxy == nil && newProxy == nil {
-                return false
-        }
-        if (oldProxy == nil && newProxy != nil) ||
-                (oldProxy != nil && newProxy == nil) {
-                return true
-        }
+	if oldProxy.Mode != newProxy.Mode {
+		return true
+	}
 
-        if oldProxy.Mode != newProxy.Mode {
-                return true
-        }
+	oldSrcLst := oldProxy.SourceList
+	newSrcLst := newProxy.SourceList
+	oLen := len(oldSrcLst)
+	nLen := len(newSrcLst)
+	if oLen != nLen {
+		return true
+	}
 
-        oldSrcLst := oldProxy.SourceList
-        newSrcLst := newProxy.SourceList
-        oLen := len(oldSrcLst)
-        nLen := len(newSrcLst)
-        if oLen != nLen {
-                return true
-        }
+	visited := make([]bool, nLen)
 
-        visited := make([]bool, nLen)
+	/* check if any new IPs added in the src list, return true if present */
+	for i := 0; i < nLen; i++ {
+		found := false
+		element := newSrcLst[i]
+		for j := 0; j < oLen; j++ {
+			if visited[j] {
+				continue
+			}
+			if element.Equal(oldSrcLst[j]) {
+				visited[j] = true
+				found = true
+				break
+			}
+		}
+		if !found {
+			return true
+		}
+	}
 
-        /* check if any new IPs added in the src list, return true if present */
-        for i := 0; i < nLen; i++ {
-                found := false
-                element := newSrcLst[i]
-                for j := 0; j < oLen; j++ {
-                        if visited[j] {
-                                continue
-                        }
-                        if element.Equal(oldSrcLst[j]) {
-                                visited[j] = true
-                                found = true
-                                break
-                        }
-                }
-                if !found {
-                        return true
-                }
-        }
-
-        visited = make([]bool, nLen)
-        /* check if any IPs removed from existing  src list, return true if removed */
-        for i := 0; i < oLen; i++ {
-                found := false
-                element := oldSrcLst[i]
-                for j := 0; j < nLen; j++ {
-                        if visited[j] {
-                                continue
-                        }
-                        if element.Equal(newSrcLst[j]) {
-                                visited[j] = true
-                                found = true
-                                break
-                        }
-                }
-                if !found {
-                        return true
-                }
-        }
-        return false
+	visited = make([]bool, nLen)
+	/* check if any IPs removed from existing  src list, return true if removed */
+	for i := 0; i < oLen; i++ {
+		found := false
+		element := oldSrcLst[i]
+		for j := 0; j < nLen; j++ {
+			if visited[j] {
+				continue
+			}
+			if element.Equal(newSrcLst[j]) {
+				visited[j] = true
+				found = true
+				break
+			}
+		}
+		if !found {
+			return true
+		}
+	}
+	return false
 }
 
-
-//UpdateActiveChannelSubscriberAlarm - Updates the Active Channel Subscriber Alarm
+// UpdateActiveChannelSubscriberAlarm - Updates the Active Channel Subscriber Alarm
 func (mvp *MvlanProfile) UpdateActiveChannelSubscriberAlarm() {
-        va := GetApplication()
-        logger.Debugw(ctx, "Update of Active Channel Subscriber Alarm", log.Fields{"Mvlan": mvp.Mvlan})
-        for srNo := range mvp.DevicesList {
-                d, _ := va.GetDeviceBySerialNo(srNo)
-                if d == nil {
-                        logger.Warnw(ctx, "Device info not found", log.Fields{"Device_SrNo": srNo, "Mvlan": mvp.Mvlan})
-                        return
-                }
-                d.Ports.Range(func(key, value interface{}) bool {
-                        //port := key.(string)
-                        vp := value.(*VoltPort)
-                        if vp.Type != VoltPortTypeAccess {
-                                return true
-                        }
-                        if mvp.MaxActiveChannels > vp.ActiveChannels && vp.ChannelPerSubAlarmRaised {
-                                serviceName := GetMcastServiceForSubAlarm(vp, mvp)
-                                logger.Debugw(ctx, "Clearing-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
-                                vp.ChannelPerSubAlarmRaised = false
-                        } else if mvp.MaxActiveChannels < vp.ActiveChannels && !vp.ChannelPerSubAlarmRaised {
-                                /* When the max active channel count is reduced via update, we raise an alarm.
-                                   But the previous excess channels still exist until a leave or expiry */
-                                serviceName := GetMcastServiceForSubAlarm(vp, mvp)
-                                logger.Debugw(ctx, "Raising-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
-                                vp.ChannelPerSubAlarmRaised = true
-                        }
-                        return true
-                })
-        }
+	va := GetApplication()
+	logger.Debugw(ctx, "Update of Active Channel Subscriber Alarm", log.Fields{"Mvlan": mvp.Mvlan})
+	for srNo := range mvp.DevicesList {
+		d, _ := va.GetDeviceBySerialNo(srNo)
+		if d == nil {
+			logger.Warnw(ctx, "Device info not found", log.Fields{"Device_SrNo": srNo, "Mvlan": mvp.Mvlan})
+			return
+		}
+		d.Ports.Range(func(key, value interface{}) bool {
+			//port := key.(string)
+			vp := value.(*VoltPort)
+			if vp.Type != VoltPortTypeAccess {
+				return true
+			}
+			if mvp.MaxActiveChannels > vp.ActiveChannels && vp.ChannelPerSubAlarmRaised {
+				serviceName := GetMcastServiceForSubAlarm(vp, mvp)
+				logger.Debugw(ctx, "Clearing-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
+				vp.ChannelPerSubAlarmRaised = false
+			} else if mvp.MaxActiveChannels < vp.ActiveChannels && !vp.ChannelPerSubAlarmRaised {
+				/* When the max active channel count is reduced via update, we raise an alarm.
+				   But the previous excess channels still exist until a leave or expiry */
+				serviceName := GetMcastServiceForSubAlarm(vp, mvp)
+				logger.Debugw(ctx, "Raising-SendActiveChannelPerSubscriberAlarm-due-to-update", log.Fields{"ActiveChannels": vp.ActiveChannels, "ServiceName": serviceName})
+				vp.ChannelPerSubAlarmRaised = true
+			}
+			return true
+		})
+	}
 }
 
-//TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
+// TriggerAssociatedFlowDelete - Re-trigger delete for pending delete flows
 func (mvp *MvlanProfile) TriggerAssociatedFlowDelete(cntx context.Context, device string) bool {
-        mvp.mvpFlowLock.Lock()
+	mvp.mvpFlowLock.Lock()
 
-        cookieList := []uint64{}
-        flowMap := mvp.PendingDeleteFlow[device]
+	cookieList := []uint64{}
+	flowMap := mvp.PendingDeleteFlow[device]
 
-        for cookie := range flowMap {
-                cookieList = append(cookieList, convertToUInt64(cookie))
-        }
-        mvp.mvpFlowLock.Unlock()
+	for cookie := range flowMap {
+		cookieList = append(cookieList, convertToUInt64(cookie))
+	}
+	mvp.mvpFlowLock.Unlock()
 
-        if len(cookieList) == 0 {
-                return false
-        }
+	if len(cookieList) == 0 {
+		return false
+	}
 
-        for _, cookie := range cookieList {
-                if vd := GetApplication().GetDevice(device); vd != nil {
-                        flow := &of.VoltFlow{}
-                        flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
-                        subFlow := of.NewVoltSubFlow()
-                        subFlow.Cookie = cookie
-                        flow.SubFlows[cookie] = subFlow
-                        logger.Infow(ctx, "Retriggering Vnet Delete Flow", log.Fields{"Device": device, "Mvlan": mvp.Mvlan.String(), "Cookie": cookie})
-                        err := mvp.DelFlows(cntx, vd, flow)
-                        if err != nil {
-                                logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
-                        }
-                }
-        }
-        return true
+	for _, cookie := range cookieList {
+		if vd := GetApplication().GetDevice(device); vd != nil {
+			flow := &of.VoltFlow{}
+			flow.SubFlows = make(map[uint64]*of.VoltSubFlow)
+			subFlow := of.NewVoltSubFlow()
+			subFlow.Cookie = cookie
+			flow.SubFlows[cookie] = subFlow
+			logger.Infow(ctx, "Retriggering Vnet Delete Flow", log.Fields{"Device": device, "Mvlan": mvp.Mvlan.String(), "Cookie": cookie})
+			err := mvp.DelFlows(cntx, vd, flow)
+			if err != nil {
+				logger.Warnw(ctx, "De-Configuring IGMP Flow for device failed ", log.Fields{"Device": device, "err": err})
+			}
+		}
+	}
+	return true
 }
 
-// JsonMarshal wrapper function for json Marshal MvlanProfile
-func (mvp *MvlanProfile) JsonMarshal() ([]byte, error) {
-        return json.Marshal(MvlanProfile{
-                Name:                mvp.Name,
-                Mvlan:               mvp.Mvlan,
-                PonVlan:             mvp.PonVlan,
-                Groups:              mvp.Groups,
-                Proxy:               mvp.Proxy,
-                Version:             mvp.Version,
-                IsPonVlanPresent:    mvp.IsPonVlanPresent,
-                IsChannelBasedGroup: mvp.IsChannelBasedGroup,
-                DevicesList:         mvp.DevicesList,
-                MaxActiveChannels:   mvp.MaxActiveChannels,
-                PendingDeleteFlow:   mvp.PendingDeleteFlow,
-                DeleteInProgress:    mvp.DeleteInProgress,
-                IgmpServVersion:     mvp.IgmpServVersion,
-        })
+// JSONMarshal wrapper function for json Marshal MvlanProfile
+func (mvp *MvlanProfile) JSONMarshal() ([]byte, error) {
+	return json.Marshal(MvlanProfile{
+		Name:                mvp.Name,
+		Mvlan:               mvp.Mvlan,
+		PonVlan:             mvp.PonVlan,
+		Groups:              mvp.Groups,
+		Proxy:               mvp.Proxy,
+		Version:             mvp.Version,
+		IsPonVlanPresent:    mvp.IsPonVlanPresent,
+		IsChannelBasedGroup: mvp.IsChannelBasedGroup,
+		DevicesList:         mvp.DevicesList,
+		MaxActiveChannels:   mvp.MaxActiveChannels,
+		PendingDeleteFlow:   mvp.PendingDeleteFlow,
+		DeleteInProgress:    mvp.DeleteInProgress,
+		IgmpServVersion:     mvp.IgmpServVersion,
+	})
 }
 
 // removeIPFromList to remove ip from the list
 func removeIPFromList(s []net.IP, value net.IP) []net.IP {
-        i := 0
-        for i = 0; i < len(s); i++ {
-                if s[i].Equal(value) {
-                        break
-                }
-        }
-        if i != len(s) {
-                //It means value is found in the slice
-                return append(s[0:i], s[i+1:]...)
-        }
-        return s
+	i := 0
+	for i = 0; i < len(s); i++ {
+		if s[i].Equal(value) {
+			break
+		}
+	}
+	if i != len(s) {
+		//It means value is found in the slice
+		return append(s[0:i], s[i+1:]...)
+	}
+	return s
 }
 
 // doesIPMatch to check if ip match with any ip from the list
 func doesIPMatch(ip net.IP, ipsOrRange []string) bool {
-        for _, ipOrRange := range ipsOrRange {
-                if strings.Contains(ipOrRange, "-") {
-                        var splits = strings.Split(ipOrRange, "-")
-                        ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
-                        ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
-                        if ipEnd < ipStart {
-                                return false
-                        }
-                        ipInt := util.IP2LongConv(ip)
-                        if ipInt >= ipStart && ipInt <= ipEnd {
-                                return true
-                        }
-                } else if ip.Equal(net.ParseIP(ipOrRange)) {
-                        return true
-                }
-        }
-        return false
+	for _, ipOrRange := range ipsOrRange {
+		if strings.Contains(ipOrRange, "-") {
+			var splits = strings.Split(ipOrRange, "-")
+			ipStart := util.IP2LongConv(net.ParseIP(splits[0]))
+			ipEnd := util.IP2LongConv(net.ParseIP(splits[1]))
+			if ipEnd < ipStart {
+				return false
+			}
+			ipInt := util.IP2LongConv(ip)
+			if ipInt >= ipStart && ipInt <= ipEnd {
+				return true
+			}
+		} else if ip.Equal(net.ParseIP(ipOrRange)) {
+			return true
+		}
+	}
+	return false
 }
 
 // IgmpProfile structure
 type IgmpProfile struct {
-        ProfileID          string
-        UnsolicitedTimeOut uint32 //In seconds
-        MaxResp            uint32
-        KeepAliveInterval  uint32
-        KeepAliveCount     uint32
-        LastQueryInterval  uint32
-        LastQueryCount     uint32
-        FastLeave          bool
-        PeriodicQuery      bool
-        IgmpCos            uint8
-        WithRAUpLink       bool
-        WithRADownLink     bool
-        IgmpVerToServer    string
-        IgmpSourceIP       net.IP
-        Version            string
+	ProfileID          string
+	IgmpVerToServer    string
+	Version            string
+	IgmpSourceIP       net.IP
+	UnsolicitedTimeOut uint32 //In seconds
+	MaxResp            uint32
+	KeepAliveInterval  uint32
+	KeepAliveCount     uint32
+	LastQueryInterval  uint32
+	LastQueryCount     uint32
+	IgmpCos            uint8
+	FastLeave          bool
+	PeriodicQuery      bool
+	WithRAUpLink       bool
+	WithRADownLink     bool
 }
 
 func newIgmpProfile(igmpProfileConfig *common.IGMPConfig) *IgmpProfile {
-        var igmpProfile IgmpProfile
-        igmpProfile.ProfileID = igmpProfileConfig.ProfileID
-        igmpProfile.UnsolicitedTimeOut = uint32(igmpProfileConfig.UnsolicitedTimeOut)
-        igmpProfile.MaxResp = uint32(igmpProfileConfig.MaxResp)
+	var igmpProfile IgmpProfile
+	igmpProfile.ProfileID = igmpProfileConfig.ProfileID
+	igmpProfile.UnsolicitedTimeOut = uint32(igmpProfileConfig.UnsolicitedTimeOut)
+	igmpProfile.MaxResp = uint32(igmpProfileConfig.MaxResp)
 
-        keepAliveInterval := uint32(igmpProfileConfig.KeepAliveInterval)
+	keepAliveInterval := uint32(igmpProfileConfig.KeepAliveInterval)
 
-        //KeepAliveInterval should have a min of 10 seconds
-        if keepAliveInterval < MinKeepAliveInterval {
-                keepAliveInterval = MinKeepAliveInterval
-                logger.Infow(ctx, "Auto adjust keepAliveInterval - Value < 10", log.Fields{"Received": igmpProfileConfig.KeepAliveInterval, "Configured": keepAliveInterval})
-        }
-        igmpProfile.KeepAliveInterval = keepAliveInterval
+	//KeepAliveInterval should have a min of 10 seconds
+	if keepAliveInterval < MinKeepAliveInterval {
+		keepAliveInterval = MinKeepAliveInterval
+		logger.Infow(ctx, "Auto adjust keepAliveInterval - Value < 10", log.Fields{"Received": igmpProfileConfig.KeepAliveInterval, "Configured": keepAliveInterval})
+	}
+	igmpProfile.KeepAliveInterval = keepAliveInterval
 
-        igmpProfile.KeepAliveCount = uint32(igmpProfileConfig.KeepAliveCount)
-        igmpProfile.LastQueryInterval = uint32(igmpProfileConfig.LastQueryInterval)
-        igmpProfile.LastQueryCount = uint32(igmpProfileConfig.LastQueryCount)
-        igmpProfile.FastLeave = *igmpProfileConfig.FastLeave
-        igmpProfile.PeriodicQuery = *igmpProfileConfig.PeriodicQuery
-        igmpProfile.IgmpCos = uint8(igmpProfileConfig.IgmpCos)
-        igmpProfile.WithRAUpLink = *igmpProfileConfig.WithRAUpLink
-        igmpProfile.WithRADownLink = *igmpProfileConfig.WithRADownLink
+	igmpProfile.KeepAliveCount = uint32(igmpProfileConfig.KeepAliveCount)
+	igmpProfile.LastQueryInterval = uint32(igmpProfileConfig.LastQueryInterval)
+	igmpProfile.LastQueryCount = uint32(igmpProfileConfig.LastQueryCount)
+	igmpProfile.FastLeave = *igmpProfileConfig.FastLeave
+	igmpProfile.PeriodicQuery = *igmpProfileConfig.PeriodicQuery
+	igmpProfile.IgmpCos = uint8(igmpProfileConfig.IgmpCos)
+	igmpProfile.WithRAUpLink = *igmpProfileConfig.WithRAUpLink
+	igmpProfile.WithRADownLink = *igmpProfileConfig.WithRADownLink
 
-        if igmpProfileConfig.IgmpVerToServer == "2" || igmpProfileConfig.IgmpVerToServer == "v2" {
-                igmpProfile.IgmpVerToServer = "2"
-        } else {
-                igmpProfile.IgmpVerToServer = "3"
-        }
-        igmpProfile.IgmpSourceIP = net.ParseIP(igmpProfileConfig.IgmpSourceIP)
+	if igmpProfileConfig.IgmpVerToServer == "2" || igmpProfileConfig.IgmpVerToServer == "v2" {
+		igmpProfile.IgmpVerToServer = "2"
+	} else {
+		igmpProfile.IgmpVerToServer = "3"
+	}
+	igmpProfile.IgmpSourceIP = net.ParseIP(igmpProfileConfig.IgmpSourceIP)
 
-        return &igmpProfile
+	return &igmpProfile
 }
 
 // newDefaultIgmpProfile Igmp profiles with default values
 func newDefaultIgmpProfile() *IgmpProfile {
-        return &IgmpProfile{
-                ProfileID:          DefaultIgmpProfID,
-                UnsolicitedTimeOut: 60,
-                MaxResp:            10, // seconds
-                KeepAliveInterval:  60, // seconds
-                KeepAliveCount:     3,  // TODO - May not be needed
-                LastQueryInterval:  0,  // TODO - May not be needed
-                LastQueryCount:     0,  // TODO - May not be needed
-                FastLeave:          true,
-                PeriodicQuery:      false, // TODO - May not be needed
-                IgmpCos:            7,     //p-bit value included in the IGMP packet
-                WithRAUpLink:       false, // TODO - May not be needed
-                WithRADownLink:     false, // TODO - May not be needed
-                IgmpVerToServer:    "3",
-                IgmpSourceIP:       net.ParseIP("172.27.0.1"), // This will be replaced by configuration
-        }
+	return &IgmpProfile{
+		ProfileID:          DefaultIgmpProfID,
+		UnsolicitedTimeOut: 60,
+		MaxResp:            10, // seconds
+		KeepAliveInterval:  60, // seconds
+		KeepAliveCount:     3,  // TODO - May not be needed
+		LastQueryInterval:  0,  // TODO - May not be needed
+		LastQueryCount:     0,  // TODO - May not be needed
+		FastLeave:          true,
+		PeriodicQuery:      false, // TODO - May not be needed
+		IgmpCos:            7,     //p-bit value included in the IGMP packet
+		WithRAUpLink:       false, // TODO - May not be needed
+		WithRADownLink:     false, // TODO - May not be needed
+		IgmpVerToServer:    "3",
+		IgmpSourceIP:       net.ParseIP("172.27.0.1"), // This will be replaced by configuration
+	}
 }
 
 // WriteToDb is utility to write Igmp Config Info to database
 func (igmpProfile *IgmpProfile) WriteToDb(cntx context.Context) error {
-        igmpProfile.Version = database.PresentVersionMap[database.IgmpProfPath]
-        b, err := json.Marshal(igmpProfile)
-        if err != nil {
-                return err
-        }
-        if err1 := db.PutIgmpProfile(cntx, igmpProfile.ProfileID, string(b)); err1 != nil {
-                return err1
-        }
-        return nil
+	igmpProfile.Version = database.PresentVersionMap[database.IgmpProfPath]
+	b, err := json.Marshal(igmpProfile)
+	if err != nil {
+		return err
+	}
+	if err1 := db.PutIgmpProfile(cntx, igmpProfile.ProfileID, string(b)); err1 != nil {
+		return err1
+	}
+	return nil
 }
