diff --git a/vendor/github.com/gyuho/goraph/.travis.yml b/vendor/github.com/gyuho/goraph/.travis.yml
deleted file mode 100644
index 4228e24..0000000
--- a/vendor/github.com/gyuho/goraph/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: go
-
-sudo: false
-
-go:
-- 1.6
-- tip
-
-script:
-- ./test
-
diff --git a/vendor/github.com/gyuho/goraph/LICENSE b/vendor/github.com/gyuho/goraph/LICENSE
deleted file mode 100644
index f7303ba..0000000
--- a/vendor/github.com/gyuho/goraph/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Gyu-Ho Lee
-Copyright (c) 2016 Google Inc
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/github.com/gyuho/goraph/README.md b/vendor/github.com/gyuho/goraph/README.md
deleted file mode 100644
index 0b5b590..0000000
--- a/vendor/github.com/gyuho/goraph/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-## goraph [![Build Status](https://img.shields.io/travis/gyuho/goraph.svg?style=flat-square)](https://travis-ci.org/gyuho/goraph) [![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/gyuho/goraph)
-
-Package goraph implements graph data structure and algorithms.
-
-```
-go get -v gopkg.in/gyuho/goraph.v2;
-```
-
-<br>
-I have tutorials and visualizations of graph, tree algorithms:
-
-- [**_Binary search tree_**](https://github.com/gyuho/learn/tree/master/doc/binary_search_tree)
-- [**_Go: heap, priority queue_**](https://github.com/gyuho/learn/tree/master/doc/go_heap_priority_queue)
-- [**_Go: red black tree_**](https://github.com/gyuho/learn/tree/master/doc/go_red_black_tree)
-- [**_Go: b-tree_**](https://github.com/gyuho/learn/tree/master/doc/go_b_tree)
-- [**_Go: graph, interface_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_interface)
-- [**_Go: graph, traversal_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_traversal)
-- [**_Go: graph, shortest path_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_shortest_path)
-- [**_Go: graph, topological sort_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_topological_sort)
-- [**_Go: graph, minimum spanning tree_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_minimum_spanning_tree)
-- [**_Go: graph, strongly connected components_**](https://github.com/gyuho/learn/tree/master/doc/go_graph_strongly_connected_components)
-
-<br>
-For fast query and retrieval, please check out  <a href="http://google-opensource.blogspot.co.uk/2014/06/cayley-graphs-in-go.html" target="_blank">Cayley</a>.
-
-
-<br>
-<a href="http://www.youtube.com/watch?v=ImMnYq2zP4Y" target="_blank"><img src="http://img.youtube.com/vi/ImMnYq2zP4Y/0.jpg"></a>
-
-- <a href="https://www.youtube.com/channel/UCWzSgIp_DYRQnEsJuH32Fww" target="_blank">Please visit my YouTube Channel</a>
-- <a href="https://www.youtube.com/watch?v=NdfIfxTsVDo&list=PLT6aABhFfinvsSn1H195JLuHaXNS6UVhf" target="_blank">`Tree`, `Graph` Theory Algorithms (Playlist)</a>
-- <a href="https://www.youtube.com/watch?v=ImMnYq2zP4Y&list=PLT6aABhFfinvsSn1H195JLuHaXNS6UVhf&index=4" target="_blank">`Graph` : BFS, DFS</a>
diff --git a/vendor/github.com/gyuho/goraph/disjoint_set.go b/vendor/github.com/gyuho/goraph/disjoint_set.go
deleted file mode 100644
index 3a8085f..0000000
--- a/vendor/github.com/gyuho/goraph/disjoint_set.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package goraph
-
-import "sync"
-
-// DisjointSet implements disjoint set.
-// (https://en.wikipedia.org/wiki/Disjoint-set_data_structure)
-type DisjointSet struct {
-	represent string
-	members   map[string]struct{}
-}
-
-// Forests is a set of DisjointSet.
-type Forests struct {
-	mu   sync.Mutex // guards the following
-	data map[*DisjointSet]struct{}
-}
-
-// NewForests creates a new Forests.
-func NewForests() *Forests {
-	set := &Forests{}
-	set.data = make(map[*DisjointSet]struct{})
-	return set
-}
-
-// MakeDisjointSet creates a DisjointSet.
-func MakeDisjointSet(forests *Forests, name string) {
-	newDS := &DisjointSet{}
-	newDS.represent = name
-	members := make(map[string]struct{})
-	members[name] = struct{}{}
-	newDS.members = members
-	forests.mu.Lock()
-	defer forests.mu.Unlock()
-	forests.data[newDS] = struct{}{}
-}
-
-// FindSet returns the DisjointSet with the represent name.
-func FindSet(forests *Forests, name string) *DisjointSet {
-	forests.mu.Lock()
-	defer forests.mu.Unlock()
-	for data := range forests.data {
-		if data.represent == name {
-			return data
-		}
-		for k := range data.members {
-			if k == name {
-				return data
-			}
-		}
-	}
-	return nil
-}
-
-// Union unions two DisjointSet, with ds1's represent.
-func Union(forests *Forests, ds1, ds2 *DisjointSet) {
-	newDS := &DisjointSet{}
-	newDS.represent = ds1.represent
-	newDS.members = ds1.members
-	for k := range ds2.members {
-		newDS.members[k] = struct{}{}
-	}
-	forests.mu.Lock()
-	defer forests.mu.Unlock()
-	forests.data[newDS] = struct{}{}
-	delete(forests.data, ds1)
-	delete(forests.data, ds2)
-}
diff --git a/vendor/github.com/gyuho/goraph/doc.go b/vendor/github.com/gyuho/goraph/doc.go
deleted file mode 100644
index 191d299..0000000
--- a/vendor/github.com/gyuho/goraph/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package goraph implements graph data structure and algorithms.
-package goraph // import "github.com/gyuho/goraph"
diff --git a/vendor/github.com/gyuho/goraph/graph.go b/vendor/github.com/gyuho/goraph/graph.go
deleted file mode 100644
index 87f87c5..0000000
--- a/vendor/github.com/gyuho/goraph/graph.go
+++ /dev/null
@@ -1,503 +0,0 @@
-package goraph
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io"
-	"sync"
-)
-
-// ID is unique identifier.
-type ID interface {
-	// String returns the string ID.
-	String() string
-}
-
-type StringID string
-
-func (s StringID) String() string {
-	return string(s)
-}
-
-// Node is vertex. The ID must be unique within the graph.
-type Node interface {
-	// ID returns the ID.
-	ID() ID
-	String() string
-}
-
-type node struct {
-	id string
-}
-
-var nodeCnt uint64
-
-func NewNode(id string) Node {
-	return &node{
-		id: id,
-	}
-}
-
-func (n *node) ID() ID {
-	return StringID(n.id)
-}
-
-func (n *node) String() string {
-	return n.id
-}
-
-// Edge connects between two Nodes.
-type Edge interface {
-	Source() Node
-	Target() Node
-	Weight() float64
-	String() string
-}
-
-// edge is an Edge from Source to Target.
-type edge struct {
-	src Node
-	tgt Node
-	wgt float64
-}
-
-func NewEdge(src, tgt Node, wgt float64) Edge {
-	return &edge{
-		src: src,
-		tgt: tgt,
-		wgt: wgt,
-	}
-}
-
-func (e *edge) Source() Node {
-	return e.src
-}
-
-func (e *edge) Target() Node {
-	return e.tgt
-}
-
-func (e *edge) Weight() float64 {
-	return e.wgt
-}
-
-func (e *edge) String() string {
-	return fmt.Sprintf("%s -- %.3f -→ %s\n", e.src, e.wgt, e.tgt)
-}
-
-type EdgeSlice []Edge
-
-func (e EdgeSlice) Len() int           { return len(e) }
-func (e EdgeSlice) Less(i, j int) bool { return e[i].Weight() < e[j].Weight() }
-func (e EdgeSlice) Swap(i, j int)      { e[i], e[j] = e[j], e[i] }
-
-// Graph describes the methods of graph operations.
-// It assumes that the identifier of a Node is unique.
-// And weight values is float64.
-type Graph interface {
-	// Init initializes a Graph.
-	Init()
-
-	// GetNodeCount returns the total number of nodes.
-	GetNodeCount() int
-
-	// GetNode finds the Node. It returns nil if the Node
-	// does not exist in the graph.
-	GetNode(id ID) Node
-
-	// GetNodes returns a map from node ID to
-	// empty struct value. Graph does not allow duplicate
-	// node ID or name.
-	GetNodes() map[ID]Node
-
-	// AddNode adds a node to a graph, and returns false
-	// if the node already existed in the graph.
-	AddNode(nd Node) bool
-
-	// DeleteNode deletes a node from a graph.
-	// It returns true if it got deleted.
-	// And false if it didn't get deleted.
-	DeleteNode(id ID) bool
-
-	// AddEdge adds an edge from nd1 to nd2 with the weight.
-	// It returns error if a node does not exist.
-	AddEdge(id1, id2 ID, weight float64) error
-
-	// ReplaceEdge replaces an edge from id1 to id2 with the weight.
-	ReplaceEdge(id1, id2 ID, weight float64) error
-
-	// DeleteEdge deletes an edge from id1 to id2.
-	DeleteEdge(id1, id2 ID) error
-
-	// GetWeight returns the weight from id1 to id2.
-	GetWeight(id1, id2 ID) (float64, error)
-
-	// GetSources returns the map of parent Nodes.
-	// (Nodes that come towards the argument vertex.)
-	GetSources(id ID) (map[ID]Node, error)
-
-	// GetTargets returns the map of child Nodes.
-	// (Nodes that go out of the argument vertex.)
-	GetTargets(id ID) (map[ID]Node, error)
-
-	// String describes the Graph.
-	String() string
-}
-
-// graph is an internal default graph type that
-// implements all methods in Graph interface.
-type graph struct {
-	mu sync.RWMutex // guards the following
-
-	// idToNodes stores all nodes.
-	idToNodes map[ID]Node
-
-	// nodeToSources maps a Node identifer to sources(parents) with edge weights.
-	nodeToSources map[ID]map[ID]float64
-
-	// nodeToTargets maps a Node identifer to targets(children) with edge weights.
-	nodeToTargets map[ID]map[ID]float64
-}
-
-// newGraph returns a new graph.
-func newGraph() *graph {
-	return &graph{
-		idToNodes:     make(map[ID]Node),
-		nodeToSources: make(map[ID]map[ID]float64),
-		nodeToTargets: make(map[ID]map[ID]float64),
-		//
-		// without this
-		// panic: assignment to entry in nil map
-	}
-}
-
-// NewGraph returns a new graph.
-func NewGraph() Graph {
-	return newGraph()
-}
-
-func (g *graph) Init() {
-	// (X) g = newGraph()
-	// this only updates the pointer
-	//
-	//
-	// (X) *g = *newGraph()
-	// assignment copies lock value
-
-	g.idToNodes = make(map[ID]Node)
-	g.nodeToSources = make(map[ID]map[ID]float64)
-	g.nodeToTargets = make(map[ID]map[ID]float64)
-}
-
-func (g *graph) GetNodeCount() int {
-	g.mu.RLock()
-	defer g.mu.RUnlock()
-
-	return len(g.idToNodes)
-}
-
-func (g *graph) GetNode(id ID) Node {
-	g.mu.RLock()
-	defer g.mu.RUnlock()
-
-	return g.idToNodes[id]
-}
-
-func (g *graph) GetNodes() map[ID]Node {
-	g.mu.RLock()
-	defer g.mu.RUnlock()
-
-	return g.idToNodes
-}
-
-func (g *graph) unsafeExistID(id ID) bool {
-	_, ok := g.idToNodes[id]
-	return ok
-}
-
-func (g *graph) AddNode(nd Node) bool {
-	g.mu.Lock()
-	defer g.mu.Unlock()
-
-	if g.unsafeExistID(nd.ID()) {
-		return false
-	}
-
-	id := nd.ID()
-	g.idToNodes[id] = nd
-	return true
-}
-
-func (g *graph) DeleteNode(id ID) bool {
-	g.mu.Lock()
-	defer g.mu.Unlock()
-
-	if !g.unsafeExistID(id) {
-		return false
-	}
-
-	delete(g.idToNodes, id)
-
-	delete(g.nodeToTargets, id)
-	for _, smap := range g.nodeToTargets {
-		delete(smap, id)
-	}
-
-	delete(g.nodeToSources, id)
-	for _, smap := range g.nodeToSources {
-		delete(smap, id)
-	}
-
-	return true
-}
-
-func (g *graph) AddEdge(id1, id2 ID, weight float64) error {
-	g.mu.Lock()
-	defer g.mu.Unlock()
-
-	if !g.unsafeExistID(id1) {
-		return fmt.Errorf("%s does not exist in the graph.", id1)
-	}
-	if !g.unsafeExistID(id2) {
-		return fmt.Errorf("%s does not exist in the graph.", id2)
-	}
-
-	if _, ok := g.nodeToTargets[id1]; ok {
-		if v, ok2 := g.nodeToTargets[id1][id2]; ok2 {
-			g.nodeToTargets[id1][id2] = v + weight
-		} else {
-			g.nodeToTargets[id1][id2] = weight
-		}
-	} else {
-		tmap := make(map[ID]float64)
-		tmap[id2] = weight
-		g.nodeToTargets[id1] = tmap
-	}
-	if _, ok := g.nodeToSources[id2]; ok {
-		if v, ok2 := g.nodeToSources[id2][id1]; ok2 {
-			g.nodeToSources[id2][id1] = v + weight
-		} else {
-			g.nodeToSources[id2][id1] = weight
-		}
-	} else {
-		tmap := make(map[ID]float64)
-		tmap[id1] = weight
-		g.nodeToSources[id2] = tmap
-	}
-
-	return nil
-}
-
-func (g *graph) ReplaceEdge(id1, id2 ID, weight float64) error {
-	g.mu.Lock()
-	defer g.mu.Unlock()
-
-	if !g.unsafeExistID(id1) {
-		return fmt.Errorf("%s does not exist in the graph.", id1)
-	}
-	if !g.unsafeExistID(id2) {
-		return fmt.Errorf("%s does not exist in the graph.", id2)
-	}
-
-	if _, ok := g.nodeToTargets[id1]; ok {
-		g.nodeToTargets[id1][id2] = weight
-	} else {
-		tmap := make(map[ID]float64)
-		tmap[id2] = weight
-		g.nodeToTargets[id1] = tmap
-	}
-	if _, ok := g.nodeToSources[id2]; ok {
-		g.nodeToSources[id2][id1] = weight
-	} else {
-		tmap := make(map[ID]float64)
-		tmap[id1] = weight
-		g.nodeToSources[id2] = tmap
-	}
-	return nil
-}
-
-func (g *graph) DeleteEdge(id1, id2 ID) error {
-	g.mu.Lock()
-	defer g.mu.Unlock()
-
-	if !g.unsafeExistID(id1) {
-		return fmt.Errorf("%s does not exist in the graph.", id1)
-	}
-	if !g.unsafeExistID(id2) {
-		return fmt.Errorf("%s does not exist in the graph.", id2)
-	}
-
-	if _, ok := g.nodeToTargets[id1]; ok {
-		if _, ok := g.nodeToTargets[id1][id2]; ok {
-			delete(g.nodeToTargets[id1], id2)
-		}
-	}
-	if _, ok := g.nodeToSources[id2]; ok {
-		if _, ok := g.nodeToSources[id2][id1]; ok {
-			delete(g.nodeToSources[id2], id1)
-		}
-	}
-	return nil
-}
-
-func (g *graph) GetWeight(id1, id2 ID) (float64, error) {
-	g.mu.RLock()
-	defer g.mu.RUnlock()
-
-	if !g.unsafeExistID(id1) {
-		return 0, fmt.Errorf("%s does not exist in the graph.", id1)
-	}
-	if !g.unsafeExistID(id2) {
-		return 0, fmt.Errorf("%s does not exist in the graph.", id2)
-	}
-
-	if _, ok := g.nodeToTargets[id1]; ok {
-		if v, ok := g.nodeToTargets[id1][id2]; ok {
-			return v, nil
-		}
-	}
-	return 0.0, fmt.Errorf("there is no edge from %s to %s", id1, id2)
-}
-
-func (g *graph) GetSources(id ID) (map[ID]Node, error) {
-	g.mu.RLock()
-	defer g.mu.RUnlock()
-
-	if !g.unsafeExistID(id) {
-		return nil, fmt.Errorf("%s does not exist in the graph.", id)
-	}
-
-	rs := make(map[ID]Node)
-	if _, ok := g.nodeToSources[id]; ok {
-		for n := range g.nodeToSources[id] {
-			rs[n] = g.idToNodes[n]
-		}
-	}
-	return rs, nil
-}
-
-func (g *graph) GetTargets(id ID) (map[ID]Node, error) {
-	g.mu.RLock()
-	defer g.mu.RUnlock()
-
-	if !g.unsafeExistID(id) {
-		return nil, fmt.Errorf("%s does not exist in the graph.", id)
-	}
-
-	rs := make(map[ID]Node)
-	if _, ok := g.nodeToTargets[id]; ok {
-		for n := range g.nodeToTargets[id] {
-			rs[n] = g.idToNodes[n]
-		}
-	}
-	return rs, nil
-}
-
-func (g *graph) String() string {
-	g.mu.RLock()
-	defer g.mu.RUnlock()
-
-	buf := new(bytes.Buffer)
-	for id1, nd1 := range g.idToNodes {
-		nmap, _ := g.GetTargets(id1)
-		for id2, nd2 := range nmap {
-			weight, _ := g.GetWeight(id1, id2)
-			fmt.Fprintf(buf, "%s -- %.3f -→ %s\n", nd1, weight, nd2)
-		}
-	}
-	return buf.String()
-}
-
-// NewGraphFromJSON returns a new Graph from a JSON file.
-// Here's the sample JSON data:
-//
-//	{
-//	    "graph_00": {
-//	        "S": {
-//	            "A": 100,
-//	            "B": 14,
-//	            "C": 200
-//	        },
-//	        "A": {
-//	            "S": 15,
-//	            "B": 5,
-//	            "D": 20,
-//	            "T": 44
-//	        },
-//	        "B": {
-//	            "S": 14,
-//	            "A": 5,
-//	            "D": 30,
-//	            "E": 18
-//	        },
-//	        "C": {
-//	            "S": 9,
-//	            "E": 24
-//	        },
-//	        "D": {
-//	            "A": 20,
-//	            "B": 30,
-//	            "E": 2,
-//	            "F": 11,
-//	            "T": 16
-//	        },
-//	        "E": {
-//	            "B": 18,
-//	            "C": 24,
-//	            "D": 2,
-//	            "F": 6,
-//	            "T": 19
-//	        },
-//	        "F": {
-//	            "D": 11,
-//	            "E": 6,
-//	            "T": 6
-//	        },
-//	        "T": {
-//	            "A": 44,
-//	            "D": 16,
-//	            "F": 6,
-//	            "E": 19
-//	        }
-//	    },
-//	}
-//
-func NewGraphFromJSON(rd io.Reader, graphID string) (Graph, error) {
-	js := make(map[string]map[string]map[string]float64)
-	dec := json.NewDecoder(rd)
-	for {
-		if err := dec.Decode(&js); err == io.EOF {
-			break
-		} else if err != nil {
-			return nil, err
-		}
-	}
-	if _, ok := js[graphID]; !ok {
-		return nil, fmt.Errorf("%s does not exist", graphID)
-	}
-	gmap := js[graphID]
-
-	g := newGraph()
-	for id1, mm := range gmap {
-		nd1 := g.GetNode(StringID(id1))
-		if nd1 == nil {
-			nd1 = NewNode(id1)
-			if ok := g.AddNode(nd1); !ok {
-				return nil, fmt.Errorf("%s already exists", nd1)
-			}
-		}
-		for id2, weight := range mm {
-			nd2 := g.GetNode(StringID(id2))
-			if nd2 == nil {
-				nd2 = NewNode(id2)
-				if ok := g.AddNode(nd2); !ok {
-					return nil, fmt.Errorf("%s already exists", nd2)
-				}
-			}
-			g.ReplaceEdge(nd1.ID(), nd2.ID(), weight)
-		}
-	}
-
-	return g, nil
-}
diff --git a/vendor/github.com/gyuho/goraph/minimum_spanning_tree.go b/vendor/github.com/gyuho/goraph/minimum_spanning_tree.go
deleted file mode 100644
index a86e279..0000000
--- a/vendor/github.com/gyuho/goraph/minimum_spanning_tree.go
+++ /dev/null
@@ -1,287 +0,0 @@
-package goraph
-
-import (
-	"container/heap"
-	"math"
-	"sort"
-)
-
-// Kruskal finds the minimum spanning tree with disjoint-set data structure.
-// (http://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
-//
-//	 0. Kruskal(G)
-//	 1.
-//	 2. 	A = ∅
-//	 3.
-//	 4. 	for each vertex v in G:
-//	 5. 		MakeDisjointSet(v)
-//	 6.
-//	 7. 	edges = get all edges
-//	 8. 	sort edges in ascending order of weight
-//	 9.
-//	10. 	for each edge (u, v) in edges:
-//	11. 		if FindSet(u) ≠ FindSet(v):
-//	12. 			A = A ∪ {(u, v)}
-//	13. 			Union(u, v)
-//	14.
-//	15. 	return A
-//
-func Kruskal(g Graph) (map[Edge]struct{}, error) {
-
-	// A = ∅
-	A := make(map[Edge]struct{})
-
-	// disjointSet maps a member Node to a represent.
-	// (https://en.wikipedia.org/wiki/Disjoint-set_data_structure)
-	forests := NewForests()
-
-	// for each vertex v in G:
-	for _, nd := range g.GetNodes() {
-		// MakeDisjointSet(v)
-		MakeDisjointSet(forests, nd.String())
-	}
-
-	// edges = get all edges
-	edges := []Edge{}
-	foundEdge := make(map[string]struct{})
-	for id1, nd1 := range g.GetNodes() {
-		tm, err := g.GetTargets(id1)
-		if err != nil {
-			return nil, err
-		}
-		for id2, nd2 := range tm {
-			weight, err := g.GetWeight(id1, id2)
-			if err != nil {
-				return nil, err
-			}
-			edge := NewEdge(nd1, nd2, weight)
-			if _, ok := foundEdge[edge.String()]; !ok {
-				edges = append(edges, edge)
-				foundEdge[edge.String()] = struct{}{}
-			}
-		}
-
-		sm, err := g.GetSources(id1)
-		if err != nil {
-			return nil, err
-		}
-		for id3, nd3 := range sm {
-			weight, err := g.GetWeight(id3, id1)
-			if err != nil {
-				return nil, err
-			}
-			edge := NewEdge(nd3, nd1, weight)
-			if _, ok := foundEdge[edge.String()]; !ok {
-				edges = append(edges, edge)
-				foundEdge[edge.String()] = struct{}{}
-			}
-		}
-	}
-
-	// sort edges in ascending order of weight
-	sort.Sort(EdgeSlice(edges))
-
-	// for each edge (u, v) in edges:
-	for _, edge := range edges {
-		// if FindSet(u) ≠ FindSet(v):
-		if FindSet(forests, edge.Source().String()).represent != FindSet(forests, edge.Target().String()).represent {
-
-			// A = A ∪ {(u, v)}
-			A[edge] = struct{}{}
-
-			// Union(u, v)
-			// overwrite v's represent with u's represent
-			Union(forests, FindSet(forests, edge.Source().String()), FindSet(forests, edge.Target().String()))
-		}
-	}
-
-	return A, nil
-}
-
-// Prim finds the minimum spanning tree with min-heap (priority queue).
-// (http://en.wikipedia.org/wiki/Prim%27s_algorithm)
-//
-//	 0. Prim(G, source)
-//	 1.
-//	 2. 	let Q be a priority queue
-//	 3. 	distance[source] = 0
-//	 4.
-//	 5. 	for each vertex v in G:
-//	 6.
-//	 7. 		if v ≠ source:
-//	 8. 			distance[v] = ∞
-//	 9. 			prev[v] = undefined
-//	10.
-//	11. 		Q.add_with_priority(v, distance[v])
-//	12.
-//	13.
-//	14. 	while Q is not empty:
-//	15.
-//	16. 		u = Q.extract_min()
-//	17.
-//	18. 		for each adjacent vertex v of u:
-//	19.
-//	21. 			if v ∈ Q and distance[v] > weight(u, v):
-//	22. 				distance[v] = weight(u, v)
-//	23. 				prev[v] = u
-//	24. 				Q.decrease_priority(v, weight(u, v))
-//	25.
-//	26.
-//	27. 	return tree from prev
-//
-func Prim(g Graph, src ID) (map[Edge]struct{}, error) {
-
-	// let Q be a priority queue
-	minHeap := &nodeDistanceHeap{}
-
-	// distance[source] = 0
-	distance := make(map[ID]float64)
-	distance[src] = 0.0
-
-	// for each vertex v in G:
-	for id := range g.GetNodes() {
-
-		// if v ≠ src:
-		if id != src {
-			// distance[v] = ∞
-			distance[id] = math.MaxFloat64
-
-			// prev[v] = undefined
-			// prev[v] = ""
-		}
-
-		// Q.add_with_priority(v, distance[v])
-		nds := nodeDistance{}
-		nds.id = id
-		nds.distance = distance[id]
-
-		heap.Push(minHeap, nds)
-	}
-
-	heap.Init(minHeap)
-	prev := make(map[ID]ID)
-
-	// while Q is not empty:
-	for minHeap.Len() != 0 {
-
-		// u = Q.extract_min()
-		u := heap.Pop(minHeap).(nodeDistance)
-		uID := u.id
-
-		// for each adjacent vertex v of u:
-		tm, err := g.GetTargets(uID)
-		if err != nil {
-			return nil, err
-		}
-		for vID := range tm {
-
-			isExist := false
-			for _, one := range *minHeap {
-				if vID == one.id {
-					isExist = true
-					break
-				}
-			}
-
-			// weight(u, v)
-			weight, err := g.GetWeight(uID, vID)
-			if err != nil {
-				return nil, err
-			}
-
-			// if v ∈ Q and distance[v] > weight(u, v):
-			if isExist && distance[vID] > weight {
-
-				// distance[v] = weight(u, v)
-				distance[vID] = weight
-
-				// prev[v] = u
-				prev[vID] = uID
-
-				// Q.decrease_priority(v, weight(u, v))
-				minHeap.updateDistance(vID, weight)
-				heap.Init(minHeap)
-			}
-		}
-
-		sm, err := g.GetSources(uID)
-		if err != nil {
-			return nil, err
-		}
-		vID := uID
-		for uID := range sm {
-
-			isExist := false
-			for _, one := range *minHeap {
-				if vID == one.id {
-					isExist = true
-					break
-				}
-			}
-
-			// weight(u, v)
-			weight, err := g.GetWeight(uID, vID)
-			if err != nil {
-				return nil, err
-			}
-
-			// if v ∈ Q and distance[v] > weight(u, v):
-			if isExist && distance[vID] > weight {
-
-				// distance[v] = weight(u, v)
-				distance[vID] = weight
-
-				// prev[v] = u
-				prev[vID] = uID
-
-				// Q.decrease_priority(v, weight(u, v))
-				minHeap.updateDistance(vID, weight)
-				heap.Init(minHeap)
-			}
-		}
-	}
-
-	tree := make(map[Edge]struct{})
-	for k, v := range prev {
-		weight, err := g.GetWeight(v, k)
-		if err != nil {
-			return nil, err
-		}
-		tree[NewEdge(g.GetNode(v), g.GetNode(k), weight)] = struct{}{}
-	}
-	return tree, nil
-}
-
-type nodeDistance struct {
-	id       ID
-	distance float64
-}
-
-// container.Heap's Interface needs sort.Interface, Push, Pop to be implemented
-
-// nodeDistanceHeap is a min-heap of nodeDistances.
-type nodeDistanceHeap []nodeDistance
-
-func (h nodeDistanceHeap) Len() int           { return len(h) }
-func (h nodeDistanceHeap) Less(i, j int) bool { return h[i].distance < h[j].distance } // Min-Heap
-func (h nodeDistanceHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
-
-func (h *nodeDistanceHeap) Push(x interface{}) {
-	*h = append(*h, x.(nodeDistance))
-}
-
-func (h *nodeDistanceHeap) Pop() interface{} {
-	heapSize := len(*h)
-	lastNode := (*h)[heapSize-1]
-	*h = (*h)[0 : heapSize-1]
-	return lastNode
-}
-
-func (h *nodeDistanceHeap) updateDistance(id ID, val float64) {
-	for i := 0; i < len(*h); i++ {
-		if (*h)[i].id == id {
-			(*h)[i].distance = val
-			break
-		}
-	}
-}
diff --git a/vendor/github.com/gyuho/goraph/shortest_path.go b/vendor/github.com/gyuho/goraph/shortest_path.go
deleted file mode 100644
index e6f405c..0000000
--- a/vendor/github.com/gyuho/goraph/shortest_path.go
+++ /dev/null
@@ -1,348 +0,0 @@
-package goraph
-
-import (
-	"container/heap"
-	"fmt"
-	"math"
-)
-
-// Dijkstra returns the shortest path using Dijkstra
-// algorithm with a min-priority queue. This algorithm
-// does not work with negative weight edges.
-// (https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)
-//
-//	 0. Dijkstra(G, source, target)
-//	 1.
-//	 2. 	let Q be a priority queue
-//	 3. 	distance[source] = 0
-//	 4.
-//	 5. 	for each vertex v in G:
-//	 6.
-//	 7. 		if v ≠ source:
-//	 8. 			distance[v] = ∞
-//	 9. 			prev[v] = undefined
-//	10.
-//	11. 		Q.add_with_priority(v, distance[v])
-//	12.
-//	13. 	while Q is not empty:
-//	14.
-//	15. 		u = Q.extract_min()
-//	16. 		if u == target:
-//	17. 			break
-//	18.
-//	19. 		for each child vertex v of u:
-//	20.
-//	21. 			alt = distance[u] + weight(u, v)
-//	22. 			if distance[v] > alt:
-//	23. 				distance[v] = alt
-//	24. 				prev[v] = u
-//	25. 				Q.decrease_priority(v, alt)
-//	26.
-//	27. 		reheapify(Q)
-//	28.
-//	29.
-//	30. 	path = []
-//	31. 	u = target
-//	32. 	while prev[u] is defined:
-//	33. 		path.push_front(u)
-//	34. 		u = prev[u]
-//	35.
-//	36. 	return path, prev
-//
-func Dijkstra(g Graph, source, target ID) ([]ID, map[ID]float64, error) {
-	// let Q be a priority queue
-	minHeap := &nodeDistanceHeap{}
-
-	// distance[source] = 0
-	distance := make(map[ID]float64)
-	distance[source] = 0.0
-
-	// for each vertex v in G:
-	for id := range g.GetNodes() {
-		// if v ≠ source:
-		if id != source {
-			// distance[v] = ∞
-			distance[id] = math.MaxFloat64
-
-			// prev[v] = undefined
-			// prev[v] = ""
-		}
-
-		// Q.add_with_priority(v, distance[v])
-		nds := nodeDistance{}
-		nds.id = id
-		nds.distance = distance[id]
-
-		heap.Push(minHeap, nds)
-	}
-
-	heap.Init(minHeap)
-	prev := make(map[ID]ID)
-
-	// while Q is not empty:
-	for minHeap.Len() != 0 {
-
-		// u = Q.extract_min()
-		u := heap.Pop(minHeap).(nodeDistance)
-
-		// if u == target:
-		if u.id == target {
-			break
-		}
-
-		// for each child vertex v of u:
-		cmap, err := g.GetTargets(u.id)
-		if err != nil {
-			return nil, nil, err
-		}
-		for v := range cmap {
-
-			// alt = distance[u] + weight(u, v)
-			weight, err := g.GetWeight(u.id, v)
-			if err != nil {
-				return nil, nil, err
-			}
-			alt := distance[u.id] + weight
-
-			// if distance[v] > alt:
-			if distance[v] > alt {
-
-				// distance[v] = alt
-				distance[v] = alt
-
-				// prev[v] = u
-				prev[v] = u.id
-
-				// Q.decrease_priority(v, alt)
-				minHeap.updateDistance(v, alt)
-			}
-		}
-		heap.Init(minHeap)
-	}
-
-	// path = []
-	path := []ID{}
-
-	// u = target
-	u := target
-
-	// while prev[u] is defined:
-	for {
-		if _, ok := prev[u]; !ok {
-			break
-		}
-		// path.push_front(u)
-		temp := make([]ID, len(path)+1)
-		temp[0] = u
-		copy(temp[1:], path)
-		path = temp
-
-		// u = prev[u]
-		u = prev[u]
-	}
-
-	// add the source
-	temp := make([]ID, len(path)+1)
-	temp[0] = source
-	copy(temp[1:], path)
-	path = temp
-
-	return path, distance, nil
-}
-
-// BellmanFord returns the shortest path using Bellman-Ford algorithm
-// This algorithm works with negative weight edges.
-// Time complexity is O(|V||E|).
-// (http://courses.csail.mit.edu/6.006/spring11/lectures/lec15.pdf)
-// It returns error when there is a negative-weight cycle.
-// A negatively-weighted cycle adds up to infinite negative-weight.
-//
-//	 0. BellmanFord(G, source, target)
-//	 1.
-//	 2. 	distance[source] = 0
-//	 3.
-//	 4. 	for each vertex v in G:
-//	 5.
-//	 6. 		if v ≠ source:
-//	 7. 			distance[v] = ∞
-//	 8. 			prev[v] = undefined
-//	 9.
-//	10.
-//	11. 	for 1 to |V|-1:
-//	12.
-//	13. 		for every edge (u, v):
-//	14.
-//	15. 			alt = distance[u] + weight(u, v)
-//	16. 			if distance[v] > alt:
-//	17. 				distance[v] = alt
-//	18. 				prev[v] = u
-//	19.
-//	20.
-//	21. 	for every edge (u, v):
-//	22.
-//	23. 		alt = distance[u] + weight(u, v)
-//	24. 		if distance[v] > alt:
-//	25. 			there is a negative-weight cycle
-//	26.
-//	27.
-//	28. 	path = []
-//	29. 	u = target
-//	30. 	while prev[u] is defined:
-//	31. 		path.push_front(u)
-//	32. 		u = prev[u]
-//	33.
-//	34. 	return path, prev
-//
-func BellmanFord(g Graph, source, target ID) ([]ID, map[ID]float64, error) {
-	// distance[source] = 0
-	distance := make(map[ID]float64)
-	distance[source] = 0.0
-
-	// for each vertex v in G:
-	for id := range g.GetNodes() {
-
-		// if v ≠ source:
-		if id != source {
-			// distance[v] = ∞
-			distance[id] = math.MaxFloat64
-
-			// prev[v] = undefined
-			// prev[v] = ""
-		}
-	}
-
-	prev := make(map[ID]ID)
-
-	// for 1 to |V|-1:
-	for i := 1; i <= g.GetNodeCount()-1; i++ {
-
-		// for every edge (u, v):
-		for id := range g.GetNodes() {
-
-			cmap, err := g.GetTargets(id)
-			if err != nil {
-				return nil, nil, err
-			}
-			u := id
-			for v := range cmap {
-				// edge (u, v)
-				weight, err := g.GetWeight(u, v)
-				if err != nil {
-					return nil, nil, err
-				}
-
-				// alt = distance[u] + weight(u, v)
-				alt := distance[u] + weight
-
-				// if distance[v] > alt:
-				if distance[v] > alt {
-					// distance[v] = alt
-					distance[v] = alt
-
-					// prev[v] = u
-					prev[v] = u
-				}
-			}
-
-			pmap, err := g.GetSources(id)
-			if err != nil {
-				return nil, nil, err
-			}
-			v := id
-			for u := range pmap {
-				// edge (u, v)
-				weight, err := g.GetWeight(u, v)
-				if err != nil {
-					return nil, nil, err
-				}
-
-				// alt = distance[u] + weight(u, v)
-				alt := distance[u] + weight
-
-				// if distance[v] > alt:
-				if distance[v] > alt {
-					// distance[v] = alt
-					distance[v] = alt
-
-					// prev[v] = u
-					prev[v] = u
-				}
-			}
-		}
-	}
-
-	// for every edge (u, v):
-	for id := range g.GetNodes() {
-
-		cmap, err := g.GetTargets(id)
-		if err != nil {
-			return nil, nil, err
-		}
-		u := id
-		for v := range cmap {
-			// edge (u, v)
-			weight, err := g.GetWeight(u, v)
-			if err != nil {
-				return nil, nil, err
-			}
-
-			// alt = distance[u] + weight(u, v)
-			alt := distance[u] + weight
-
-			// if distance[v] > alt:
-			if distance[v] > alt {
-				return nil, nil, fmt.Errorf("there is a negative-weight cycle: %v", g)
-			}
-		}
-
-		pmap, err := g.GetSources(id)
-		if err != nil {
-			return nil, nil, err
-		}
-		v := id
-		for u := range pmap {
-			// edge (u, v)
-			weight, err := g.GetWeight(u, v)
-			if err != nil {
-				return nil, nil, err
-			}
-
-			// alt = distance[u] + weight(u, v)
-			alt := distance[u] + weight
-
-			// if distance[v] > alt:
-			if distance[v] > alt {
-				return nil, nil, fmt.Errorf("there is a negative-weight cycle: %v", g)
-			}
-		}
-	}
-
-	// path = []
-	path := []ID{}
-
-	// u = target
-	u := target
-
-	// while prev[u] is defined:
-	for {
-		if _, ok := prev[u]; !ok {
-			break
-		}
-		// path.push_front(u)
-		temp := make([]ID, len(path)+1)
-		temp[0] = u
-		copy(temp[1:], path)
-		path = temp
-
-		// u = prev[u]
-		u = prev[u]
-	}
-
-	// add the source
-	temp := make([]ID, len(path)+1)
-	temp[0] = source
-	copy(temp[1:], path)
-	path = temp
-
-	return path, distance, nil
-}
diff --git a/vendor/github.com/gyuho/goraph/strongly_connected_components.go b/vendor/github.com/gyuho/goraph/strongly_connected_components.go
deleted file mode 100644
index b0a11a5..0000000
--- a/vendor/github.com/gyuho/goraph/strongly_connected_components.go
+++ /dev/null
@@ -1,195 +0,0 @@
-package goraph
-
-import "sync"
-
-// Tarjan finds the strongly connected components.
-// In the mathematics, a directed graph is "strongly connected"
-// if every vertex is reachable from every other node.
-// Therefore, a graph is strongly connected if there is a path
-// in each direction between each pair of node of a graph.
-// Then a pair of vertices u and v is strongly connected to each other
-// because there is a path in each direction.
-// "Strongly connected components" of an arbitrary graph
-// partition into sub-graphs that are themselves strongly connected.
-// That is, "strongly connected component" of a directed graph
-// is a sub-graph that is strongly connected.
-// Formally, "Strongly connected components" of a graph is a maximal
-// set of vertices C in G.V such that for all u, v ∈ C, there is a path
-// both from u to v, and from v to u.
-// (https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm)
-//
-//	 0. Tarjan(G):
-//	 1.
-//	 2. 	globalIndex = 0 // smallest unused index
-//	 3. 	let S be a stack
-//	 4. 	result = [][]
-//	 5.
-//	 6. 	for each vertex v in G:
-//	 7. 		if v.index is undefined:
-//	 8. 			tarjan(G, v, globalIndex, S, result)
-//	 9.
-//	10. 	return result
-//	11.
-//	12.
-//	13. tarjan(G, v, globalIndex, S, result):
-//	14.
-//	15. 	v.index = globalIndex
-//	16. 	v.lowLink = globalIndex
-//	17. 	globalIndex++
-//	18. 	S.push(v)
-//	19.
-//	20. 	for each child vertex w of v:
-//	21.
-//	22. 		if w.index is undefined:
-//	23. 			recursively tarjan(G, w, globalIndex, S, result)
-//	24. 			v.lowLink = min(v.lowLink, w.lowLink)
-//	25.
-//	26. 		else if w is in S:
-//	27. 			v.lowLink = min(v.lowLink, w.index)
-//	28.
-//	29. 	// if v is the root
-//	30. 	if v.lowLink == v.index:
-//	31.
-//	32. 		// start a new strongly connected component
-//	33. 		component = []
-//	34.
-//	35. 		while True:
-//	36.
-//	37. 			u = S.pop()
-//	38. 			component.push(u)
-//	39.
-//	40. 			if u == v:
-//	41. 				result.push(component)
-//	42. 				break
-//
-func Tarjan(g Graph) [][]ID {
-	d := newTarjanData()
-
-	// for each vertex v in G:
-	for v := range g.GetNodes() {
-		// if v.index is undefined:
-		if _, ok := d.index[v]; !ok {
-			// tarjan(G, v, globalIndex, S, result)
-			tarjan(g, v, d)
-		}
-	}
-	return d.result
-}
-
-type tarjanData struct {
-	mu sync.Mutex // guards the following
-
-	// globalIndex is the smallest unused index
-	globalIndex int
-
-	// index is an index of a node to record
-	// the order of being discovered.
-	index map[ID]int
-
-	// lowLink is the smallest index of any index
-	// reachable from v, including v itself.
-	lowLink map[ID]int
-
-	// S is the stack.
-	S []ID
-
-	// extra map to check if a vertex is in S.
-	smap map[ID]struct{}
-
-	result [][]ID
-}
-
-func newTarjanData() *tarjanData {
-	return &tarjanData{
-		globalIndex: 0,
-		index:       make(map[ID]int),
-		lowLink:     make(map[ID]int),
-		S:           []ID{},
-		smap:        make(map[ID]struct{}),
-		result:      [][]ID{},
-	}
-}
-
-func tarjan(
-	g Graph,
-	id ID,
-	data *tarjanData,
-) {
-	// This is not inherently parallelizable problem,
-	// but just to make sure.
-	data.mu.Lock()
-
-	// v.index = globalIndex
-	data.index[id] = data.globalIndex
-
-	// v.lowLink = globalIndex
-	data.lowLink[id] = data.globalIndex
-
-	// globalIndex++
-	data.globalIndex++
-
-	// S.push(v)
-	data.S = append(data.S, id)
-	data.smap[id] = struct{}{}
-
-	data.mu.Unlock()
-
-	// for each child vertex w of v:
-	cmap, err := g.GetTargets(id)
-	if err != nil {
-		panic(err)
-	}
-	for w := range cmap {
-
-		// if w.index is undefined:
-		if _, ok := data.index[w]; !ok {
-
-			// recursively tarjan(G, w, globalIndex, S, result)
-			tarjan(g, w, data)
-
-			// v.lowLink = min(v.lowLink, w.lowLink)
-			data.lowLink[id] = min(data.lowLink[id], data.lowLink[w])
-
-		} else if _, ok := data.smap[w]; ok {
-			// else if w is in S:
-
-			// v.lowLink = min(v.lowLink, w.index)
-			data.lowLink[id] = min(data.lowLink[id], data.index[w])
-		}
-	}
-
-	data.mu.Lock()
-	defer data.mu.Unlock()
-
-	// if v is the root
-	// if v.lowLink == v.index:
-	if data.lowLink[id] == data.index[id] {
-		// start a new strongly connected component
-		component := []ID{}
-
-		// while True:
-		for {
-
-			// u = S.pop()
-			u := data.S[len(data.S)-1]
-			data.S = data.S[:len(data.S)-1 : len(data.S)-1]
-			delete(data.smap, u)
-
-			// component.push(u)
-			component = append(component, u)
-
-			// if u == v:
-			if u == id {
-				data.result = append(data.result, component)
-				break
-			}
-		}
-	}
-}
-
-func min(a, b int) int {
-	if a < b {
-		return a
-	}
-	return b
-}
diff --git a/vendor/github.com/gyuho/goraph/test b/vendor/github.com/gyuho/goraph/test
deleted file mode 100755
index a7d8a6d..0000000
--- a/vendor/github.com/gyuho/goraph/test
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-
-TEST=./...;
-FMT="*.go"
-
-echo "Running tests...";
-go test -v -cover -cpu 1,2,4 $TEST;
-go test -v -cover -cpu 1,2,4 -race $TEST;
-
-echo "Checking gofmt..."
-fmtRes=$(gofmt -l -s $FMT)
-if [ -n "${fmtRes}" ]; then
-	echo -e "gofmt checking failed:\n${fmtRes}"
-	exit 255
-fi
-
-echo "Checking govet..."
-vetRes=$(go vet $TEST)
-if [ -n "${vetRes}" ]; then
-	echo -e "govet checking failed:\n${vetRes}"
-	exit 255
-fi
-
-echo "Success";
diff --git a/vendor/github.com/gyuho/goraph/topological_sort.go b/vendor/github.com/gyuho/goraph/topological_sort.go
deleted file mode 100644
index b63675a..0000000
--- a/vendor/github.com/gyuho/goraph/topological_sort.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package goraph
-
-// TopologicalSort does topological sort(ordering) with DFS.
-// It returns true if the graph is a DAG (no cycle, with a topological sort).
-// False if the graph is not a DAG (cycle, with no topological sort).
-//
-//	 0. TopologicalSort(G)
-//	 1.
-//	 2. 	L = Empty list that will contain the sorted nodes
-//	 3. 	isDAG = true
-//	 4.
-//	 5. 	for each vertex v in G:
-//	 6.
-//	 7. 		if v.color == "white":
-//	 8.
-//	 9. 			topologicalSortVisit(v, L, isDAG)
-//	10.
-//	11.
-//	12.
-//	13.
-//	14. topologicalSortVisit(v, L, isDAG)
-//	15.
-//	16. 	if v.color == "gray":
-//	17. 		isDAG = false
-//	18. 		return
-//	19.
-//	20. 	if v.color == "white":
-//	21.
-//	22. 		v.color = "gray":
-//	23.
-//	24.			for each child vertex w of v:
-//	25. 			topologicalSortVisit(w, L, isDAG)
-//	26.
-//	27. 		v.color = "black"
-//	28.			L.push_front(v)
-//
-func TopologicalSort(g Graph) ([]ID, bool) {
-
-	// L = Empty list that will contain the sorted nodes
-	L := []ID{}
-	isDAG := true
-	color := make(map[ID]string)
-	for v := range g.GetNodes() {
-		color[v] = "white"
-	}
-
-	// for each vertex v in G:
-	for v := range g.GetNodes() {
-		// if v.color == "white":
-		if color[v] == "white" {
-			// topologicalSortVisit(v, L, isDAG)
-			topologicalSortVisit(g, v, &L, &isDAG, &color)
-		}
-	}
-
-	return L, isDAG
-}
-
-func topologicalSortVisit(
-	g Graph,
-	id ID,
-	L *[]ID,
-	isDAG *bool,
-	color *map[ID]string,
-) {
-
-	// if v.color == "gray":
-	if (*color)[id] == "gray" {
-		// isDAG = false
-		*isDAG = false
-		return
-	}
-
-	// if v.color == "white":
-	if (*color)[id] == "white" {
-		// v.color = "gray":
-		(*color)[id] = "gray"
-
-		// for each child vertex w of v:
-		cmap, err := g.GetTargets(id)
-		if err != nil {
-			panic(err)
-		}
-		for w := range cmap {
-			// topologicalSortVisit(w, L, isDAG)
-			topologicalSortVisit(g, w, L, isDAG, color)
-		}
-
-		// v.color = "black"
-		(*color)[id] = "black"
-
-		// L.push_front(v)
-		temp := make([]ID, len(*L)+1)
-		temp[0] = id
-		copy(temp[1:], *L)
-		*L = temp
-	}
-}
diff --git a/vendor/github.com/gyuho/goraph/traversal.go b/vendor/github.com/gyuho/goraph/traversal.go
deleted file mode 100644
index fa45c29..0000000
--- a/vendor/github.com/gyuho/goraph/traversal.go
+++ /dev/null
@@ -1,184 +0,0 @@
-package goraph
-
-// BFS does breadth-first search, and returns the list of vertices.
-// (https://en.wikipedia.org/wiki/Breadth-first_search)
-//
-//	 0. BFS(G, v):
-//	 1.
-//	 2. 	let Q be a queue
-//	 3. 	Q.push(v)
-//	 4. 	label v as visited
-//	 5.
-//	 6. 	while Q is not empty:
-//	 7.
-//	 8. 		u = Q.dequeue()
-//	 9.
-//	10. 		for each vertex w adjacent to u:
-//	11.
-//	12. 			if w is not visited yet:
-//	13. 				Q.push(w)
-//	14. 				label w as visited
-//
-func BFS(g Graph, id ID) []ID {
-	if g.GetNode(id) == nil {
-		return nil
-	}
-
-	q := []ID{id}
-	visited := make(map[ID]bool)
-	visited[id] = true
-	rs := []ID{id}
-
-	// while Q is not empty:
-	for len(q) != 0 {
-
-		u := q[0]
-		q = q[1:len(q):len(q)]
-
-		// for each vertex w adjacent to u:
-		cmap, _ := g.GetTargets(u)
-		for _, w := range cmap {
-			// if w is not visited yet:
-			if _, ok := visited[w.ID()]; !ok {
-				q = append(q, w.ID())  // Q.push(w)
-				visited[w.ID()] = true // label w as visited
-
-				rs = append(rs, w)
-			}
-		}
-		pmap, _ := g.GetSources(u)
-		for _, w := range pmap {
-			// if w is not visited yet:
-			if _, ok := visited[w.ID()]; !ok {
-				q = append(q, w.ID())  // Q.push(w)
-				visited[w.ID()] = true // label w as visited
-
-				rs = append(rs, w.ID())
-			}
-		}
-	}
-
-	return rs
-}
-
-// DFS does depth-first search, and returns the list of vertices.
-// (https://en.wikipedia.org/wiki/Depth-first_search)
-//
-//	 0. DFS(G, v):
-//	 1.
-//	 2. 	let S be a stack
-//	 3. 	S.push(v)
-//	 4.
-//	 5. 	while S is not empty:
-//	 6.
-//	 7. 		u = S.pop()
-//	 8.
-//	 9. 		if u is not visited yet:
-//	10.
-//	11. 			label u as visited
-//	12.
-//	13. 			for each vertex w adjacent to u:
-//	14.
-//	15. 				if w is not visited yet:
-//	16. 					S.push(w)
-//
-func DFS(g Graph, id ID) []ID {
-	if g.GetNode(id) == nil {
-		return nil
-	}
-
-	s := []ID{id}
-	visited := make(map[ID]bool)
-	rs := []ID{}
-
-	// while S is not empty:
-	for len(s) != 0 {
-
-		u := s[len(s)-1]
-		s = s[:len(s)-1 : len(s)-1]
-
-		// if u is not visited yet:
-		if _, ok := visited[u]; !ok {
-			// label u as visited
-			visited[u] = true
-
-			rs = append(rs, u)
-
-			// for each vertex w adjacent to u:
-			cmap, _ := g.GetTargets(u)
-			for _, w := range cmap {
-				// if w is not visited yet:
-				if _, ok := visited[w.ID()]; !ok {
-					s = append(s, w.ID()) // S.push(w)
-				}
-			}
-			pmap, _ := g.GetSources(u)
-			for _, w := range pmap {
-				// if w is not visited yet:
-				if _, ok := visited[w.ID()]; !ok {
-					s = append(s, w.ID()) // S.push(w)
-				}
-			}
-		}
-	}
-
-	return rs
-}
-
-// DFSRecursion does depth-first search recursively.
-//
-//	 0. DFS(G, v):
-//	 1.
-//	 2. 	if v is visited:
-//	 3. 		return
-//	 4.
-//	 5. 	label v as visited
-//	 6.
-//	 7. 	for each vertex u adjacent to v:
-//	 8.
-//	 9. 		if u is not visited yet:
-//	10. 			recursive DFS(G, u)
-//
-func DFSRecursion(g Graph, id ID) []ID {
-	if g.GetNode(id) == nil {
-		return nil
-	}
-
-	visited := make(map[ID]bool)
-	rs := []ID{}
-
-	dfsRecursion(g, id, visited, &rs)
-
-	return rs
-}
-
-func dfsRecursion(g Graph, id ID, visited map[ID]bool, rs *[]ID) {
-	// base case of recursion
-	//
-	// if v is visited:
-	if _, ok := visited[id]; ok {
-		return
-	}
-
-	// label v as visited
-	visited[id] = true
-	*rs = append(*rs, id)
-
-	// for each vertex u adjacent to v:
-	cmap, _ := g.GetTargets(id)
-	for _, u := range cmap {
-		// if u is not visited yet:
-		if _, ok := visited[u.ID()]; !ok {
-			// recursive DFS(G, u)
-			dfsRecursion(g, u.ID(), visited, rs)
-		}
-	}
-	pmap, _ := g.GetSources(id)
-	for _, u := range pmap {
-		// if u is not visited yet:
-		if _, ok := visited[u.ID()]; !ok {
-			// recursive DFS(G, u)
-			dfsRecursion(g, u.ID(), visited, rs)
-		}
-	}
-}
diff --git a/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go b/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
index 2873dbc..b4f9130 100755
--- a/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
+++ b/vendor/github.com/opencord/voltha-go/common/ponresourcemanager/ponresourcemanager.go
@@ -182,7 +182,7 @@
 		return nil, errors.New("Failed to init KV client")
 	}
 	// Initialize techprofile for this technology
-	if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(&PONMgr); PONMgr.TechProfileMgr == nil {
+	if PONMgr.TechProfileMgr, _ = tp.NewTechProfile(&PONMgr, Backend, Host, Port); PONMgr.TechProfileMgr == nil {
 		log.Error("Techprofile initialization failed")
 		return nil, errors.New("Failed to init tech profile")
 	}
diff --git a/vendor/github.com/opencord/voltha-go/common/techprofile/config.go b/vendor/github.com/opencord/voltha-go/common/techprofile/config.go
index 5312dc0..9d521ed 100644
--- a/vendor/github.com/opencord/voltha-go/common/techprofile/config.go
+++ b/vendor/github.com/opencord/voltha-go/common/techprofile/config.go
@@ -30,9 +30,9 @@
 	defaultPbits                  = "0b11111111"
 
 	defaultKVStoreType    = "etcd"
-	defaultKVStoreTimeout = 5            //in seconds
-	defaultKVStoreHost    = "172.21.0.8" // TODO: Need to get IP from adapter
-	defaultKVStorePort    = 2379         // Consul = 8500; Etcd = 2379
+	defaultKVStoreTimeout = 5 //in seconds
+	defaultKVStoreHost    = "127.0.0.1"
+	defaultKVStorePort    = 2379 // Consul = 8500; Etcd = 2379
 
 	// Tech profile path prefix in kv store
 	defaultKVPathPrefix = "service/voltha/technology_profiles"
@@ -98,13 +98,13 @@
 	DefaultNumTconts     uint32
 }
 
-func NewTechProfileFlags() *TechProfileFlags {
+func NewTechProfileFlags(KVStoreType string, KVStoreHost string, KVStorePort int) *TechProfileFlags {
 	// initialize with default values
 	var techProfileFlags = TechProfileFlags{
 		KVBackend:            nil,
-		KVStoreHost:          defaultKVStoreHost,
-		KVStorePort:          defaultKVStorePort,
-		KVStoreType:          defaultKVStoreType,
+		KVStoreHost:          KVStoreHost,
+		KVStorePort:          KVStorePort,
+		KVStoreType:          KVStoreType,
 		KVStoreTimeout:       defaultKVStoreTimeout,
 		DefaultTPName:        defaultTechProfileName,
 		TPKVPathPrefix:       defaultKVPathPrefix,
diff --git a/vendor/github.com/opencord/voltha-go/common/techprofile/tech_profile.go b/vendor/github.com/opencord/voltha-go/common/techprofile/tech_profile.go
index 2879e99..e41e064 100644
--- a/vendor/github.com/opencord/voltha-go/common/techprofile/tech_profile.go
+++ b/vendor/github.com/opencord/voltha-go/common/techprofile/tech_profile.go
@@ -255,7 +255,7 @@
 
 func newKVClient(storeType string, address string, timeout int) (kvstore.Client, error) {
 
-	log.Infow("kv-store-type", log.Fields{"store": storeType})
+	log.Infow("kv-store", log.Fields{"storeType": storeType, "address": address})
 	switch storeType {
 	case "consul":
 		return kvstore.NewConsulClient(address, timeout)
@@ -265,10 +265,10 @@
 	return nil, errors.New("unsupported-kv-store")
 }
 
-func NewTechProfile(resourceMgr iPonResourceMgr) (*TechProfileMgr, error) {
+func NewTechProfile(resourceMgr iPonResourceMgr, KVStoreType string, KVStoreHost string, KVStorePort int) (*TechProfileMgr, error) {
 	var techprofileObj TechProfileMgr
 	log.Debug("Initializing techprofile Manager")
-	techprofileObj.config = NewTechProfileFlags()
+	techprofileObj.config = NewTechProfileFlags(KVStoreType, KVStoreHost, KVStorePort)
 	techprofileObj.config.KVBackend = techprofileObj.SetKVClient()
 	if techprofileObj.config.KVBackend == nil {
 		log.Error("Failed to initialize KV backend\n")
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/coreIf/device_manager_if.go b/vendor/github.com/opencord/voltha-go/rw_core/coreIf/device_manager_if.go
deleted file mode 100644
index 367f442..0000000
--- a/vendor/github.com/opencord/voltha-go/rw_core/coreIf/device_manager_if.go
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.
- */
-/*
-Defines a DeviceManager Interface - Used for unit testing of the flow decomposer only at this
-time.
-*/
-package coreIf
-
-import "github.com/opencord/voltha-protos/go/voltha"
-
-// DeviceManager represents a generic device manager
-type DeviceManager interface {
-	GetDevice(string) (*voltha.Device, error)
-	IsRootDevice(string) (bool, error)
-	NotifyInvalidTransition(*voltha.Device) error
-	SetAdminStateToEnable(*voltha.Device) error
-	CreateLogicalDevice(*voltha.Device) error
-	SetupUNILogicalPorts(*voltha.Device) error
-	DisableAllChildDevices(cDevice *voltha.Device) error
-	DeleteLogicalDevice(cDevice *voltha.Device) error
-	DeleteLogicalPorts(cDevice *voltha.Device) error
-	DeleteAllChildDevices(cDevice *voltha.Device) error
-	RunPostDeviceDelete(cDevice *voltha.Device) error
-}
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/coreIf/logical_device_agent_if.go b/vendor/github.com/opencord/voltha-go/rw_core/coreIf/logical_device_agent_if.go
deleted file mode 100644
index c2614b2..0000000
--- a/vendor/github.com/opencord/voltha-go/rw_core/coreIf/logical_device_agent_if.go
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.
- */
-/*
-  Defines a logicalDeviceAgent Interface - Used for unit testing of the flow decomposer only at this
- time.
-*/
-package coreIf
-
-import (
-	"github.com/opencord/voltha-go/rw_core/graph"
-	"github.com/opencord/voltha-go/rw_core/utils"
-	"github.com/opencord/voltha-protos/go/voltha"
-)
-
-// LogicalAgent represents a generic agent
-type LogicalDeviceAgent interface {
-	GetLogicalDevice() (*voltha.LogicalDevice, error)
-	GetDeviceGraph() *graph.DeviceGraph
-	GetAllDefaultRules() *utils.DeviceRules
-	GetWildcardInputPorts(excludePort ...uint32) []uint32
-	GetRoute(ingressPortNo uint32, egressPortNo uint32) []graph.RouteHop
-}
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/flow_decomposition/flow_decomposer.go b/vendor/github.com/opencord/voltha-go/rw_core/flow_decomposition/flow_decomposer.go
deleted file mode 100644
index 41fdc4a..0000000
--- a/vendor/github.com/opencord/voltha-go/rw_core/flow_decomposition/flow_decomposer.go
+++ /dev/null
@@ -1,1314 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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 flow_decomposition
-
-import (
-	"bytes"
-	"crypto/md5"
-	"fmt"
-	"github.com/gogo/protobuf/proto"
-	"github.com/opencord/voltha-go/common/log"
-	"github.com/opencord/voltha-go/rw_core/coreIf"
-	"github.com/opencord/voltha-go/rw_core/graph"
-	fu "github.com/opencord/voltha-go/rw_core/utils"
-	ofp "github.com/opencord/voltha-protos/go/openflow_13"
-	"github.com/opencord/voltha-protos/go/voltha"
-	"math/big"
-)
-
-func init() {
-	log.AddPackage(log.JSON, log.DebugLevel, nil)
-}
-
-var (
-	// Instructions shortcut
-	APPLY_ACTIONS = ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS
-
-	//OFPAT_* shortcuts
-	OUTPUT       = ofp.OfpActionType_OFPAT_OUTPUT
-	COPY_TTL_OUT = ofp.OfpActionType_OFPAT_COPY_TTL_OUT
-	COPY_TTL_IN  = ofp.OfpActionType_OFPAT_COPY_TTL_IN
-	SET_MPLS_TTL = ofp.OfpActionType_OFPAT_SET_MPLS_TTL
-	DEC_MPLS_TTL = ofp.OfpActionType_OFPAT_DEC_MPLS_TTL
-	PUSH_VLAN    = ofp.OfpActionType_OFPAT_PUSH_VLAN
-	POP_VLAN     = ofp.OfpActionType_OFPAT_POP_VLAN
-	PUSH_MPLS    = ofp.OfpActionType_OFPAT_PUSH_MPLS
-	POP_MPLS     = ofp.OfpActionType_OFPAT_POP_MPLS
-	SET_QUEUE    = ofp.OfpActionType_OFPAT_SET_QUEUE
-	GROUP        = ofp.OfpActionType_OFPAT_GROUP
-	SET_NW_TTL   = ofp.OfpActionType_OFPAT_SET_NW_TTL
-	NW_TTL       = ofp.OfpActionType_OFPAT_DEC_NW_TTL
-	SET_FIELD    = ofp.OfpActionType_OFPAT_SET_FIELD
-	PUSH_PBB     = ofp.OfpActionType_OFPAT_PUSH_PBB
-	POP_PBB      = ofp.OfpActionType_OFPAT_POP_PBB
-	EXPERIMENTER = ofp.OfpActionType_OFPAT_EXPERIMENTER
-
-	//OFPXMT_OFB_* shortcuts (incomplete)
-	IN_PORT         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT
-	IN_PHY_PORT     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT
-	METADATA        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_METADATA
-	ETH_DST         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST
-	ETH_SRC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_SRC
-	ETH_TYPE        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE
-	VLAN_VID        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID
-	VLAN_PCP        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP
-	IP_DSCP         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_DSCP
-	IP_ECN          = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_ECN
-	IP_PROTO        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO
-	IPV4_SRC        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC
-	IPV4_DST        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST
-	TCP_SRC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TCP_SRC
-	TCP_DST         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TCP_DST
-	UDP_SRC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC
-	UDP_DST         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST
-	SCTP_SRC        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_SCTP_SRC
-	SCTP_DST        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_SCTP_DST
-	ICMPV4_TYPE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV4_TYPE
-	ICMPV4_CODE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV4_CODE
-	ARP_OP          = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_OP
-	ARP_SPA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_SPA
-	ARP_TPA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_TPA
-	ARP_SHA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_SHA
-	ARP_THA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_THA
-	IPV6_SRC        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_SRC
-	IPV6_DST        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_DST
-	IPV6_FLABEL     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_FLABEL
-	ICMPV6_TYPE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV6_TYPE
-	ICMPV6_CODE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV6_CODE
-	IPV6_ND_TARGET  = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_TARGET
-	OFB_IPV6_ND_SLL = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_SLL
-	IPV6_ND_TLL     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_TLL
-	MPLS_LABEL      = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_LABEL
-	MPLS_TC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_TC
-	MPLS_BOS        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_BOS
-	PBB_ISID        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_PBB_ISID
-	TUNNEL_ID       = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TUNNEL_ID
-	IPV6_EXTHDR     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_EXTHDR
-)
-
-//ofp_action_* shortcuts
-
-func Output(port uint32, maxLen ...ofp.OfpControllerMaxLen) *ofp.OfpAction {
-	maxLength := ofp.OfpControllerMaxLen_OFPCML_MAX
-	if len(maxLen) > 0 {
-		maxLength = maxLen[0]
-	}
-	return &ofp.OfpAction{Type: OUTPUT, Action: &ofp.OfpAction_Output{Output: &ofp.OfpActionOutput{Port: port, MaxLen: uint32(maxLength)}}}
-}
-
-func MplsTtl(ttl uint32) *ofp.OfpAction {
-	return &ofp.OfpAction{Type: SET_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: ttl}}}
-}
-
-func PushVlan(ethType uint32) *ofp.OfpAction {
-	return &ofp.OfpAction{Type: PUSH_VLAN, Action: &ofp.OfpAction_Push{Push: &ofp.OfpActionPush{Ethertype: ethType}}}
-}
-
-func PopVlan() *ofp.OfpAction {
-	return &ofp.OfpAction{Type: POP_VLAN}
-}
-
-func PopMpls(ethType uint32) *ofp.OfpAction {
-	return &ofp.OfpAction{Type: POP_MPLS, Action: &ofp.OfpAction_PopMpls{PopMpls: &ofp.OfpActionPopMpls{Ethertype: ethType}}}
-}
-
-func Group(groupId uint32) *ofp.OfpAction {
-	return &ofp.OfpAction{Type: GROUP, Action: &ofp.OfpAction_Group{Group: &ofp.OfpActionGroup{GroupId: groupId}}}
-}
-
-func NwTtl(nwTtl uint32) *ofp.OfpAction {
-	return &ofp.OfpAction{Type: NW_TTL, Action: &ofp.OfpAction_NwTtl{NwTtl: &ofp.OfpActionNwTtl{NwTtl: nwTtl}}}
-}
-
-func SetField(field *ofp.OfpOxmOfbField) *ofp.OfpAction {
-	actionSetField := &ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: &ofp.OfpOxmField_OfbField{OfbField: field}}
-	return &ofp.OfpAction{Type: SET_FIELD, Action: &ofp.OfpAction_SetField{SetField: &ofp.OfpActionSetField{Field: actionSetField}}}
-}
-
-func Experimenter(experimenter uint32, data []byte) *ofp.OfpAction {
-	return &ofp.OfpAction{Type: EXPERIMENTER, Action: &ofp.OfpAction_Experimenter{Experimenter: &ofp.OfpActionExperimenter{Experimenter: experimenter, Data: data}}}
-}
-
-//ofb_field generators (incomplete set)
-
-func InPort(inPort uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IN_PORT, Value: &ofp.OfpOxmOfbField_Port{Port: inPort}}
-}
-
-func InPhyPort(inPhyPort uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IN_PHY_PORT, Value: &ofp.OfpOxmOfbField_Port{Port: inPhyPort}}
-}
-
-func Metadata_ofp(tableMetadata uint64) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: METADATA, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: tableMetadata}}
-}
-
-// should Metadata_ofp used here ?????
-func EthDst(ethDst uint64) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ETH_DST, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: ethDst}}
-}
-
-// should Metadata_ofp used here ?????
-func EthSrc(ethSrc uint64) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ETH_SRC, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: ethSrc}}
-}
-
-func EthType(ethType uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ETH_TYPE, Value: &ofp.OfpOxmOfbField_EthType{EthType: ethType}}
-}
-
-func VlanVid(vlanVid uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: VLAN_VID, Value: &ofp.OfpOxmOfbField_VlanVid{VlanVid: vlanVid}}
-}
-
-func VlanPcp(vlanPcp uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: VLAN_PCP, Value: &ofp.OfpOxmOfbField_VlanPcp{VlanPcp: vlanPcp}}
-}
-
-func IpDscp(ipDscp uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IP_DSCP, Value: &ofp.OfpOxmOfbField_IpDscp{IpDscp: ipDscp}}
-}
-
-func IpEcn(ipEcn uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IP_ECN, Value: &ofp.OfpOxmOfbField_IpEcn{IpEcn: ipEcn}}
-}
-
-func IpProto(ipProto uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IP_PROTO, Value: &ofp.OfpOxmOfbField_IpProto{IpProto: ipProto}}
-}
-
-func Ipv4Src(ipv4Src uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV4_SRC, Value: &ofp.OfpOxmOfbField_Ipv4Src{Ipv4Src: ipv4Src}}
-}
-
-func Ipv4Dst(ipv4Dst uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV4_DST, Value: &ofp.OfpOxmOfbField_Ipv4Dst{Ipv4Dst: ipv4Dst}}
-}
-
-func TcpSrc(tcpSrc uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: TCP_SRC, Value: &ofp.OfpOxmOfbField_TcpSrc{TcpSrc: tcpSrc}}
-}
-
-func TcpDst(tcpDst uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: TCP_DST, Value: &ofp.OfpOxmOfbField_TcpDst{TcpDst: tcpDst}}
-}
-
-func UdpSrc(udpSrc uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: UDP_SRC, Value: &ofp.OfpOxmOfbField_UdpSrc{UdpSrc: udpSrc}}
-}
-
-func UdpDst(udpDst uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: UDP_DST, Value: &ofp.OfpOxmOfbField_UdpDst{UdpDst: udpDst}}
-}
-
-func SctpSrc(sctpSrc uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: SCTP_SRC, Value: &ofp.OfpOxmOfbField_SctpSrc{SctpSrc: sctpSrc}}
-}
-
-func SctpDst(sctpDst uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: SCTP_DST, Value: &ofp.OfpOxmOfbField_SctpDst{SctpDst: sctpDst}}
-}
-
-func Icmpv4Type(icmpv4Type uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ICMPV4_TYPE, Value: &ofp.OfpOxmOfbField_Icmpv4Type{Icmpv4Type: icmpv4Type}}
-}
-
-func Icmpv4Code(icmpv4Code uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ICMPV4_CODE, Value: &ofp.OfpOxmOfbField_Icmpv4Code{Icmpv4Code: icmpv4Code}}
-}
-
-func ArpOp(arpOp uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ARP_OP, Value: &ofp.OfpOxmOfbField_ArpOp{ArpOp: arpOp}}
-}
-
-func ArpSpa(arpSpa uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ARP_SPA, Value: &ofp.OfpOxmOfbField_ArpSpa{ArpSpa: arpSpa}}
-}
-
-func ArpTpa(arpTpa uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ARP_TPA, Value: &ofp.OfpOxmOfbField_ArpTpa{ArpTpa: arpTpa}}
-}
-
-func ArpSha(arpSha []byte) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ARP_SHA, Value: &ofp.OfpOxmOfbField_ArpSha{ArpSha: arpSha}}
-}
-
-func ArpTha(arpTha []byte) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ARP_THA, Value: &ofp.OfpOxmOfbField_ArpTha{ArpTha: arpTha}}
-}
-
-func Ipv6Src(ipv6Src []byte) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV6_SRC, Value: &ofp.OfpOxmOfbField_Ipv6Src{Ipv6Src: ipv6Src}}
-}
-
-func Ipv6Dst(ipv6Dst []byte) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV6_DST, Value: &ofp.OfpOxmOfbField_Ipv6Dst{Ipv6Dst: ipv6Dst}}
-}
-
-func Ipv6Flabel(ipv6Flabel uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV6_FLABEL, Value: &ofp.OfpOxmOfbField_Ipv6Flabel{Ipv6Flabel: ipv6Flabel}}
-}
-
-func Icmpv6Type(icmpv6Type uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ICMPV6_TYPE, Value: &ofp.OfpOxmOfbField_Icmpv6Type{Icmpv6Type: icmpv6Type}}
-}
-
-func Icmpv6Code(icmpv6Code uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: ICMPV6_CODE, Value: &ofp.OfpOxmOfbField_Icmpv6Code{Icmpv6Code: icmpv6Code}}
-}
-
-func Ipv6NdTarget(ipv6NdTarget []byte) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV6_ND_TARGET, Value: &ofp.OfpOxmOfbField_Ipv6NdTarget{Ipv6NdTarget: ipv6NdTarget}}
-}
-
-func OfbIpv6NdSll(ofbIpv6NdSll []byte) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: OFB_IPV6_ND_SLL, Value: &ofp.OfpOxmOfbField_Ipv6NdSsl{Ipv6NdSsl: ofbIpv6NdSll}}
-}
-
-func Ipv6NdTll(ipv6NdTll []byte) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV6_ND_TLL, Value: &ofp.OfpOxmOfbField_Ipv6NdTll{Ipv6NdTll: ipv6NdTll}}
-}
-
-func MplsLabel(mplsLabel uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: MPLS_LABEL, Value: &ofp.OfpOxmOfbField_MplsLabel{MplsLabel: mplsLabel}}
-}
-
-func MplsTc(mplsTc uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: MPLS_TC, Value: &ofp.OfpOxmOfbField_MplsTc{MplsTc: mplsTc}}
-}
-
-func MplsBos(mplsBos uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: MPLS_BOS, Value: &ofp.OfpOxmOfbField_MplsBos{MplsBos: mplsBos}}
-}
-
-func PbbIsid(pbbIsid uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: PBB_ISID, Value: &ofp.OfpOxmOfbField_PbbIsid{PbbIsid: pbbIsid}}
-}
-
-func TunnelId(tunnelId uint64) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: TUNNEL_ID, Value: &ofp.OfpOxmOfbField_TunnelId{TunnelId: tunnelId}}
-}
-
-func Ipv6Exthdr(ipv6Exthdr uint32) *ofp.OfpOxmOfbField {
-	return &ofp.OfpOxmOfbField{Type: IPV6_EXTHDR, Value: &ofp.OfpOxmOfbField_Ipv6Exthdr{Ipv6Exthdr: ipv6Exthdr}}
-}
-
-//frequently used extractors
-
-func excludeAction(action *ofp.OfpAction, exclude ...ofp.OfpActionType) bool {
-	for _, actionToExclude := range exclude {
-		if action.Type == actionToExclude {
-			return true
-		}
-	}
-	return false
-}
-
-func GetActions(flow *ofp.OfpFlowStats, exclude ...ofp.OfpActionType) []*ofp.OfpAction {
-	if flow == nil {
-		return nil
-	}
-	for _, instruction := range flow.Instructions {
-		if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
-			instActions := instruction.GetActions()
-			if instActions == nil {
-				return nil
-			}
-			if len(exclude) == 0 {
-				return instActions.Actions
-			} else {
-				filteredAction := make([]*ofp.OfpAction, 0)
-				for _, action := range instActions.Actions {
-					if !excludeAction(action, exclude...) {
-						filteredAction = append(filteredAction, action)
-					}
-				}
-				return filteredAction
-			}
-		}
-	}
-	return nil
-}
-
-func UpdateOutputPortByActionType(flow *ofp.OfpFlowStats, actionType uint32, toPort uint32) *ofp.OfpFlowStats {
-	if flow == nil {
-		return nil
-	}
-	nFlow := (proto.Clone(flow)).(*ofp.OfpFlowStats)
-	nFlow.Instructions = nil
-	nInsts := make([]*ofp.OfpInstruction, 0)
-	for _, instruction := range flow.Instructions {
-		if instruction.Type == actionType {
-			instActions := instruction.GetActions()
-			if instActions == nil {
-				return nil
-			}
-			nActions := make([]*ofp.OfpAction, 0)
-			for _, action := range instActions.Actions {
-				if action.GetOutput() != nil {
-					nActions = append(nActions, Output(toPort))
-				} else {
-					nActions = append(nActions, action)
-				}
-			}
-			instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: nActions}}
-			nInsts = append(nInsts, &ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction})
-		} else {
-			nInsts = append(nInsts, instruction)
-		}
-	}
-	nFlow.Instructions = nInsts
-	return nFlow
-}
-
-func excludeOxmOfbField(field *ofp.OfpOxmOfbField, exclude ...ofp.OxmOfbFieldTypes) bool {
-	for _, fieldToExclude := range exclude {
-		if field.Type == fieldToExclude {
-			return true
-		}
-	}
-	return false
-}
-
-func GetOfbFields(flow *ofp.OfpFlowStats, exclude ...ofp.OxmOfbFieldTypes) []*ofp.OfpOxmOfbField {
-	if flow == nil || flow.Match == nil || flow.Match.Type != ofp.OfpMatchType_OFPMT_OXM {
-		return nil
-	}
-	ofbFields := make([]*ofp.OfpOxmOfbField, 0)
-	for _, field := range flow.Match.OxmFields {
-		if field.OxmClass == ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
-			ofbFields = append(ofbFields, field.GetOfbField())
-		}
-	}
-	if len(exclude) == 0 {
-		return ofbFields
-	} else {
-		filteredFields := make([]*ofp.OfpOxmOfbField, 0)
-		for _, ofbField := range ofbFields {
-			if !excludeOxmOfbField(ofbField, exclude...) {
-				filteredFields = append(filteredFields, ofbField)
-			}
-		}
-		return filteredFields
-	}
-}
-
-func GetPacketOutPort(packet *ofp.OfpPacketOut) uint32 {
-	if packet == nil {
-		return 0
-	}
-	for _, action := range packet.GetActions() {
-		if action.Type == OUTPUT {
-			return action.GetOutput().Port
-		}
-	}
-	return 0
-}
-
-func GetOutPort(flow *ofp.OfpFlowStats) uint32 {
-	if flow == nil {
-		return 0
-	}
-	for _, action := range GetActions(flow) {
-		if action.Type == OUTPUT {
-			out := action.GetOutput()
-			if out == nil {
-				return 0
-			}
-			return out.GetPort()
-		}
-	}
-	return 0
-}
-
-func GetInPort(flow *ofp.OfpFlowStats) uint32 {
-	if flow == nil {
-		return 0
-	}
-	for _, field := range GetOfbFields(flow) {
-		if field.Type == IN_PORT {
-			return field.GetPort()
-		}
-	}
-	return 0
-}
-
-func GetGotoTableId(flow *ofp.OfpFlowStats) uint32 {
-	if flow == nil {
-		return 0
-	}
-	for _, instruction := range flow.Instructions {
-		if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE) {
-			gotoTable := instruction.GetGotoTable()
-			if gotoTable == nil {
-				return 0
-			}
-			return gotoTable.GetTableId()
-		}
-	}
-	return 0
-}
-
-func GetTunnelId(flow *ofp.OfpFlowStats) uint64 {
-	if flow == nil {
-		return 0
-	}
-	for _, field := range GetOfbFields(flow) {
-		if field.Type == TUNNEL_ID {
-			return field.GetTunnelId()
-		}
-	}
-	return 0
-}
-
-//GetMetaData - legacy get method (only want lower 32 bits)
-func GetMetaData(flow *ofp.OfpFlowStats) uint32 {
-	if flow == nil {
-		return 0
-	}
-	for _, field := range GetOfbFields(flow) {
-		if field.Type == METADATA {
-			return uint32(field.GetTableMetadata() & 0xffffffff)
-		}
-	}
-	return 0
-}
-
-func GetMetaData64Bit(flow *ofp.OfpFlowStats) uint64 {
-	if flow == nil {
-		return 0
-	}
-	for _, field := range GetOfbFields(flow) {
-		if field.Type == METADATA {
-			return field.GetTableMetadata()
-		}
-	}
-	return 0
-}
-
-// GetPortNumberFromMetadata retrieves the port number from the Metadata_ofp. The port number (UNI on ONU) is in the
-// lower 32-bits of Metadata_ofp and the inner_tag is in the upper 32-bits. This is set in the ONOS OltPipeline as
-// a Metadata_ofp field
-func GetPortNumberFromMetadata(flow *ofp.OfpFlowStats) uint64 {
-	md := GetMetaData64Bit(flow)
-	if md == 0 {
-		return 0
-	}
-	if md <= 0xffffffff {
-		log.Debugw("onos-upgrade-suggested", log.Fields{"Metadata_ofp": md, "message": "Legacy MetaData detected form OltPipeline"})
-		return md
-	}
-	return md & 0xffffffff
-}
-
-//GetInnerTagFromMetaData retrieves the inner tag from the Metadata_ofp. The port number (UNI on ONU) is in the
-// lower 32-bits of Metadata_ofp and the inner_tag is in the upper 32-bits. This is set in the ONOS OltPipeline as
-//// a Metadata_ofp field
-func GetInnerTagFromMetaData(flow *ofp.OfpFlowStats) uint64 {
-	md := GetMetaData64Bit(flow)
-	if md == 0 {
-		return 0
-	}
-	if md <= 0xffffffff {
-		log.Debugw("onos-upgrade-suggested", log.Fields{"Metadata_ofp": md, "message": "Legacy MetaData detected form OltPipeline"})
-		return md
-	}
-	return (md >> 32) & 0xffffffff
-}
-
-// Extract the child device port from a flow that contains the parent device peer port.  Typically the UNI port of an
-// ONU child device.  Per TST agreement this will be the lower 32 bits of tunnel id reserving upper 32 bits for later
-// use
-func GetChildPortFromTunnelId(flow *ofp.OfpFlowStats) uint32 {
-	tid := GetTunnelId(flow)
-	if tid == 0 {
-		return 0
-	}
-	// Per TST agreement we are keeping any child port id (uni port id) in the lower 32 bits
-	return uint32(tid & 0xffffffff)
-}
-
-func HasNextTable(flow *ofp.OfpFlowStats) bool {
-	if flow == nil {
-		return false
-	}
-	return GetGotoTableId(flow) != 0
-}
-
-func GetGroup(flow *ofp.OfpFlowStats) uint32 {
-	if flow == nil {
-		return 0
-	}
-	for _, action := range GetActions(flow) {
-		if action.Type == GROUP {
-			grp := action.GetGroup()
-			if grp == nil {
-				return 0
-			}
-			return grp.GetGroupId()
-		}
-	}
-	return 0
-}
-
-func HasGroup(flow *ofp.OfpFlowStats) bool {
-	return GetGroup(flow) != 0
-}
-
-// GetNextTableId returns the next table ID if the "table_id" is present in the map, otherwise return nil
-func GetNextTableId(kw fu.OfpFlowModArgs) *uint32 {
-	if val, exist := kw["table_id"]; exist {
-		ret := uint32(val)
-		return &ret
-	}
-	return nil
-}
-
-// Return unique 64-bit integer hash for flow covering the following attributes:
-// 'table_id', 'priority', 'flags', 'cookie', 'match', '_instruction_string'
-func hashFlowStats(flow *ofp.OfpFlowStats) uint64 {
-	if flow == nil { // Should never happen
-		return 0
-	}
-	// Create string with the instructions field first
-	var instructionString bytes.Buffer
-	for _, instruction := range flow.Instructions {
-		instructionString.WriteString(instruction.String())
-	}
-	var flowString = fmt.Sprintf("%d%d%d%d%s%s", flow.TableId, flow.Priority, flow.Flags, flow.Cookie, flow.Match.String(), instructionString.String())
-	h := md5.New()
-	h.Write([]byte(flowString))
-	hash := big.NewInt(0)
-	hash.SetBytes(h.Sum(nil))
-	return hash.Uint64()
-}
-
-// flowStatsEntryFromFlowModMessage maps an ofp_flow_mod message to an ofp_flow_stats message
-func FlowStatsEntryFromFlowModMessage(mod *ofp.OfpFlowMod) *ofp.OfpFlowStats {
-	flow := &ofp.OfpFlowStats{}
-	if mod == nil {
-		return flow
-	}
-	flow.TableId = mod.TableId
-	flow.Priority = mod.Priority
-	flow.IdleTimeout = mod.IdleTimeout
-	flow.HardTimeout = mod.HardTimeout
-	flow.Flags = mod.Flags
-	flow.Cookie = mod.Cookie
-	flow.Match = mod.Match
-	flow.Instructions = mod.Instructions
-	flow.Id = hashFlowStats(flow)
-	return flow
-}
-
-func GroupEntryFromGroupMod(mod *ofp.OfpGroupMod) *ofp.OfpGroupEntry {
-	group := &ofp.OfpGroupEntry{}
-	if mod == nil {
-		return group
-	}
-	group.Desc = &ofp.OfpGroupDesc{Type: mod.Type, GroupId: mod.GroupId, Buckets: mod.Buckets}
-	group.Stats = &ofp.OfpGroupStats{GroupId: mod.GroupId}
-	//TODO do we need to instantiate bucket bins?
-	return group
-}
-
-func MkOxmFields(matchFields []ofp.OfpOxmField) []*ofp.OfpOxmField {
-	oxmFields := make([]*ofp.OfpOxmField, 0)
-	for _, matchField := range matchFields {
-		oxmField := ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: matchField.Field}
-		oxmFields = append(oxmFields, &oxmField)
-	}
-	return oxmFields
-}
-
-func MkInstructionsFromActions(actions []*ofp.OfpAction) []*ofp.OfpInstruction {
-	instructions := make([]*ofp.OfpInstruction, 0)
-	instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: actions}}
-	instruction := ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction}
-	instructions = append(instructions, &instruction)
-	return instructions
-}
-
-// Convenience function to generare ofp_flow_mod message with OXM BASIC match composed from the match_fields, and
-// single APPLY_ACTIONS instruction with a list if ofp_action objects.
-func MkSimpleFlowMod(matchFields []*ofp.OfpOxmField, actions []*ofp.OfpAction, command *ofp.OfpFlowModCommand, kw fu.OfpFlowModArgs) *ofp.OfpFlowMod {
-
-	// Process actions instructions
-	instructions := make([]*ofp.OfpInstruction, 0)
-	instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: actions}}
-	instruction := ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction}
-	instructions = append(instructions, &instruction)
-
-	// Process next table
-	if tableId := GetNextTableId(kw); tableId != nil {
-		var instGotoTable ofp.OfpInstruction_GotoTable
-		instGotoTable.GotoTable = &ofp.OfpInstructionGotoTable{TableId: *tableId}
-		inst := ofp.OfpInstruction{Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE), Data: &instGotoTable}
-		instructions = append(instructions, &inst)
-	}
-
-	// Process match fields
-	oxmFields := make([]*ofp.OfpOxmField, 0)
-	for _, matchField := range matchFields {
-		oxmField := ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: matchField.Field}
-		oxmFields = append(oxmFields, &oxmField)
-	}
-	var match ofp.OfpMatch
-	match.Type = ofp.OfpMatchType_OFPMT_OXM
-	match.OxmFields = oxmFields
-
-	// Create ofp_flow_message
-	msg := &ofp.OfpFlowMod{}
-	if command == nil {
-		msg.Command = ofp.OfpFlowModCommand_OFPFC_ADD
-	} else {
-		msg.Command = *command
-	}
-	msg.Instructions = instructions
-	msg.Match = &match
-
-	// Set the variadic argument values
-	msg = setVariadicModAttributes(msg, kw)
-
-	return msg
-}
-
-func MkMulticastGroupMod(groupId uint32, buckets []*ofp.OfpBucket, command *ofp.OfpGroupModCommand) *ofp.OfpGroupMod {
-	group := &ofp.OfpGroupMod{}
-	if command == nil {
-		group.Command = ofp.OfpGroupModCommand_OFPGC_ADD
-	} else {
-		group.Command = *command
-	}
-	group.Type = ofp.OfpGroupType_OFPGT_ALL
-	group.GroupId = groupId
-	group.Buckets = buckets
-	return group
-}
-
-//SetVariadicModAttributes sets only uint64 or uint32 fields of the ofp_flow_mod message
-func setVariadicModAttributes(mod *ofp.OfpFlowMod, args fu.OfpFlowModArgs) *ofp.OfpFlowMod {
-	if args == nil {
-		return mod
-	}
-	for key, val := range args {
-		switch key {
-		case "cookie":
-			mod.Cookie = val
-		case "cookie_mask":
-			mod.CookieMask = val
-		case "table_id":
-			mod.TableId = uint32(val)
-		case "idle_timeout":
-			mod.IdleTimeout = uint32(val)
-		case "hard_timeout":
-			mod.HardTimeout = uint32(val)
-		case "priority":
-			mod.Priority = uint32(val)
-		case "buffer_id":
-			mod.BufferId = uint32(val)
-		case "out_port":
-			mod.OutPort = uint32(val)
-		case "out_group":
-			mod.OutGroup = uint32(val)
-		case "flags":
-			mod.Flags = uint32(val)
-		}
-	}
-	return mod
-}
-
-func MkPacketIn(port uint32, packet []byte) *ofp.OfpPacketIn {
-	packetIn := &ofp.OfpPacketIn{
-		Reason: ofp.OfpPacketInReason_OFPR_ACTION,
-		Match: &ofp.OfpMatch{
-			Type: ofp.OfpMatchType_OFPMT_OXM,
-			OxmFields: []*ofp.OfpOxmField{
-				{
-					OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC,
-					Field: &ofp.OfpOxmField_OfbField{
-						OfbField: InPort(port)},
-				},
-			},
-		},
-		Data: packet,
-	}
-	return packetIn
-}
-
-// MkFlowStat is a helper method to build flows
-func MkFlowStat(fa *fu.FlowArgs) *ofp.OfpFlowStats {
-	//Build the matchfields
-	matchFields := make([]*ofp.OfpOxmField, 0)
-	for _, val := range fa.MatchFields {
-		matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
-	}
-	return FlowStatsEntryFromFlowModMessage(MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV))
-}
-
-func MkGroupStat(ga *fu.GroupArgs) *ofp.OfpGroupEntry {
-	return GroupEntryFromGroupMod(MkMulticastGroupMod(ga.GroupId, ga.Buckets, ga.Command))
-}
-
-type FlowDecomposer struct {
-	deviceMgr coreIf.DeviceManager
-}
-
-func NewFlowDecomposer(deviceMgr coreIf.DeviceManager) *FlowDecomposer {
-	var decomposer FlowDecomposer
-	decomposer.deviceMgr = deviceMgr
-	return &decomposer
-}
-
-//DecomposeRules decomposes per-device flows and flow-groups from the flows and groups defined on a logical device
-func (fd *FlowDecomposer) DecomposeRules(agent coreIf.LogicalDeviceAgent, flows ofp.Flows, groups ofp.FlowGroups, includeDefaultFlows bool) *fu.DeviceRules {
-	rules := agent.GetAllDefaultRules()
-	deviceRules := rules.Copy()
-	devicesToUpdate := make(map[string]string)
-
-	groupMap := make(map[uint32]*ofp.OfpGroupEntry)
-	for _, groupEntry := range groups.Items {
-		groupMap[groupEntry.Desc.GroupId] = groupEntry
-	}
-
-	var decomposedRules *fu.DeviceRules
-	for _, flow := range flows.Items {
-		decomposedRules = fd.decomposeFlow(agent, flow, groupMap)
-		for deviceId, flowAndGroups := range decomposedRules.Rules {
-			deviceRules.CreateEntryIfNotExist(deviceId)
-			deviceRules.Rules[deviceId].AddFrom(flowAndGroups)
-			devicesToUpdate[deviceId] = deviceId
-		}
-	}
-	if includeDefaultFlows {
-		return deviceRules
-	}
-	updatedDeviceRules := deviceRules.FilterRules(devicesToUpdate)
-
-	return updatedDeviceRules
-}
-
-// Handles special case of any controller-bound flow for a parent device
-func (fd *FlowDecomposer) updateOutputPortForControllerBoundFlowForParentDevide(flow *ofp.OfpFlowStats,
-	dr *fu.DeviceRules) *fu.DeviceRules {
-	EAPOL := EthType(0x888e)
-	IGMP := IpProto(2)
-	UDP := IpProto(17)
-
-	newDeviceRules := dr.Copy()
-	//	Check whether we are dealing with a parent device
-	for deviceId, fg := range dr.GetRules() {
-		if root, _ := fd.deviceMgr.IsRootDevice(deviceId); root {
-			newDeviceRules.ClearFlows(deviceId)
-			for i := 0; i < fg.Flows.Len(); i++ {
-				f := fg.GetFlow(i)
-				UpdateOutPortNo := false
-				for _, field := range GetOfbFields(f) {
-					UpdateOutPortNo = (field.String() == EAPOL.String())
-					UpdateOutPortNo = UpdateOutPortNo || (field.String() == IGMP.String())
-					UpdateOutPortNo = UpdateOutPortNo || (field.String() == UDP.String())
-					if UpdateOutPortNo {
-						break
-					}
-				}
-				if UpdateOutPortNo {
-					f = UpdateOutputPortByActionType(f, uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
-						uint32(ofp.OfpPortNo_OFPP_CONTROLLER))
-				}
-				// Update flow Id as a change in the instruction field will result in a new flow ID
-				f.Id = hashFlowStats(f)
-				newDeviceRules.AddFlow(deviceId, (proto.Clone(f)).(*ofp.OfpFlowStats))
-			}
-		}
-	}
-
-	return newDeviceRules
-}
-
-//processControllerBoundFlow decomposes trap flows
-func (fd *FlowDecomposer) processControllerBoundFlow(agent coreIf.LogicalDeviceAgent, route []graph.RouteHop,
-	inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
-
-	log.Debugw("trap-flow", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo, "flow": flow})
-	deviceRules := fu.NewDeviceRules()
-
-	egressHop := route[1]
-
-	fg := fu.NewFlowsAndGroups()
-	if agent.GetDeviceGraph().IsRootPort(inPortNo) {
-		log.Debug("trap-nni")
-		// no decomposition required - it is already an OLT flow from NNI
-		fg.AddFlow(flow)
-	} else {
-		// Trap flow for UNI port
-		log.Debug("trap-uni")
-
-		//inPortNo is 0 for wildcard input case, do not include upstream port for 4000 flow in input
-		var inPorts []uint32
-		if inPortNo == 0 {
-			inPorts = agent.GetWildcardInputPorts(egressHop.Egress) // exclude egress_hop.egress_port.port_no
-		} else {
-			inPorts = []uint32{inPortNo}
-		}
-		for _, inputPort := range inPorts {
-			var fa *fu.FlowArgs
-			// Upstream flow
-			fa = &fu.FlowArgs{
-				KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-				MatchFields: []*ofp.OfpOxmOfbField{
-					InPort(egressHop.Ingress),
-					VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | inputPort),
-					TunnelId(uint64(inputPort)),
-				},
-				Actions: []*ofp.OfpAction{
-					PushVlan(0x8100),
-					SetField(VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
-					Output(egressHop.Egress),
-				},
-			}
-			// Augment the matchfields with the ofpfields from the flow
-			fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT, VLAN_VID)...)
-			fg.AddFlow(MkFlowStat(fa))
-
-			// Downstream flow
-			fa = &fu.FlowArgs{
-				KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority)},
-				MatchFields: []*ofp.OfpOxmOfbField{
-					InPort(egressHop.Egress),
-					VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000),
-					VlanPcp(0),
-					Metadata_ofp(uint64(inputPort)),
-					TunnelId(uint64(inputPort)),
-				},
-				Actions: []*ofp.OfpAction{
-					PopVlan(),
-					Output(egressHop.Ingress),
-				},
-			}
-			fg.AddFlow(MkFlowStat(fa))
-		}
-	}
-	deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
-
-	return deviceRules
-}
-
-// processUpstreamNonControllerBoundFlow processes non-controller bound flow. We assume that anything that is
-// upstream needs to get Q-in-Q treatment and that this is expressed via two flow rules, the first using the
-// goto-statement. We also assume that the inner tag is applied at the ONU, while the outer tag is
-// applied at the OLT
-func (fd *FlowDecomposer) processUpstreamNonControllerBoundFlow(agent coreIf.LogicalDeviceAgent,
-	route []graph.RouteHop, inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
-
-	log.Debugw("upstream-non-controller-bound-flow", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo})
-	deviceRules := fu.NewDeviceRules()
-
-	ingressHop := route[0]
-	egressHop := route[1]
-
-	if HasNextTable(flow) {
-		log.Debugw("has-next-table", log.Fields{"table_id": flow.TableId})
-		if outPortNo != 0 {
-			log.Warnw("outPort-should-not-be-specified", log.Fields{"outPortNo": outPortNo})
-		}
-		var fa *fu.FlowArgs
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(ingressHop.Ingress),
-				TunnelId(uint64(inPortNo)),
-			},
-			Actions: GetActions(flow),
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-
-		// Augment the Actions
-		fa.Actions = append(fa.Actions, Output(ingressHop.Egress))
-
-		fg := fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
-	} else {
-		var actions []ofp.OfpActionType
-		var isOutputTypeInActions bool
-		for _, action := range GetActions(flow) {
-			actions = append(actions, action.Type)
-			if !isOutputTypeInActions && action.Type == OUTPUT {
-				isOutputTypeInActions = true
-			}
-		}
-		if len(actions) == 1 && isOutputTypeInActions {
-			var fa *fu.FlowArgs
-			// child device flow
-			fa = &fu.FlowArgs{
-				KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-				MatchFields: []*ofp.OfpOxmOfbField{
-					InPort(ingressHop.Ingress),
-				},
-				Actions: []*ofp.OfpAction{
-					Output(ingressHop.Egress),
-				},
-			}
-			// Augment the matchfields with the ofpfields from the flow
-			fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-			fg := fu.NewFlowsAndGroups()
-			fg.AddFlow(MkFlowStat(fa))
-			deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
-
-			// parent device flow
-			fa = &fu.FlowArgs{
-				KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-				MatchFields: []*ofp.OfpOxmOfbField{
-					InPort(egressHop.Ingress), //egress_hop.ingress_port.port_no
-					TunnelId(uint64(inPortNo)),
-				},
-				Actions: []*ofp.OfpAction{
-					Output(egressHop.Egress),
-				},
-			}
-			// Augment the matchfields with the ofpfields from the flow
-			fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-			fg = fu.NewFlowsAndGroups()
-			fg.AddFlow(MkFlowStat(fa))
-			deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
-		} else {
-			if outPortNo == 0 {
-				log.Warnw("outPort-should-be-specified", log.Fields{"outPortNo": outPortNo})
-			}
-			var fa *fu.FlowArgs
-			fa = &fu.FlowArgs{
-				KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-				MatchFields: []*ofp.OfpOxmOfbField{
-					InPort(egressHop.Ingress),
-					TunnelId(uint64(inPortNo)),
-				},
-			}
-			// Augment the matchfields with the ofpfields from the flow
-			fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-
-			//Augment the actions
-			filteredAction := GetActions(flow, OUTPUT)
-			filteredAction = append(filteredAction, Output(egressHop.Egress))
-			fa.Actions = filteredAction
-
-			fg := fu.NewFlowsAndGroups()
-			fg.AddFlow(MkFlowStat(fa))
-			deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
-		}
-	}
-	return deviceRules
-}
-
-// processDownstreamFlowWithNextTable decomposes downstream flows containing next table ID instructions
-func (fd *FlowDecomposer) processDownstreamFlowWithNextTable(agent coreIf.LogicalDeviceAgent, route []graph.RouteHop,
-	inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
-
-	log.Debugw("downstream-flow-with-next-table", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo})
-	deviceRules := fu.NewDeviceRules()
-
-	if outPortNo != 0 {
-		log.Warnw("outPort-should-not-be-specified", log.Fields{"outPortNo": outPortNo})
-	}
-	ingressHop := route[0]
-	egressHop := route[1]
-
-	if GetMetaData(flow) != 0 {
-		log.Debugw("creating-metadata-flow", log.Fields{"flow": flow})
-		portNumber := uint32(GetPortNumberFromMetadata(flow))
-		if portNumber != 0 {
-			recalculatedRoute := agent.GetRoute(inPortNo, portNumber)
-			switch len(recalculatedRoute) {
-			case 0:
-				log.Errorw("no-route-double-tag", log.Fields{"inPortNo": inPortNo, "outPortNo": portNumber, "comment": "deleting-flow", "metadata": GetMetaData64Bit(flow)})
-				//	TODO: Delete flow
-				return deviceRules
-			case 2:
-				log.Debugw("route-found", log.Fields{"ingressHop": ingressHop, "egressHop": egressHop})
-				break
-			default:
-				log.Errorw("invalid-route-length", log.Fields{"routeLen": len(route)})
-				return deviceRules
-			}
-			ingressHop = recalculatedRoute[0]
-		}
-		innerTag := GetInnerTagFromMetaData(flow)
-		if innerTag == 0 {
-			log.Errorw("no-inner-route-double-tag", log.Fields{"inPortNo": inPortNo, "outPortNo": portNumber, "comment": "deleting-flow", "metadata": GetMetaData64Bit(flow)})
-			//	TODO: Delete flow
-			return deviceRules
-		}
-		var fa *fu.FlowArgs
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(ingressHop.Ingress),
-				Metadata_ofp(innerTag),
-				TunnelId(uint64(portNumber)),
-			},
-			Actions: GetActions(flow),
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT, METADATA)...)
-
-		// Augment the Actions
-		fa.Actions = append(fa.Actions, Output(ingressHop.Egress))
-
-		fg := fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
-	} else { // Create standard flow
-		log.Debugw("creating-standard-flow", log.Fields{"flow": flow})
-		var fa *fu.FlowArgs
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(ingressHop.Ingress),
-				TunnelId(uint64(inPortNo)),
-			},
-			Actions: GetActions(flow),
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-
-		// Augment the Actions
-		fa.Actions = append(fa.Actions, Output(ingressHop.Egress))
-
-		fg := fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
-	}
-
-	return deviceRules
-}
-
-// processUnicastFlow decomposes unicast flows
-func (fd *FlowDecomposer) processUnicastFlow(agent coreIf.LogicalDeviceAgent, route []graph.RouteHop,
-	inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats) *fu.DeviceRules {
-
-	log.Debugw("unicast-flow", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo})
-	deviceRules := fu.NewDeviceRules()
-
-	ingressHop := route[0]
-	egressHop := route[1]
-
-	var actions []ofp.OfpActionType
-	var isOutputTypeInActions bool
-	for _, action := range GetActions(flow) {
-		actions = append(actions, action.Type)
-		if !isOutputTypeInActions && action.Type == OUTPUT {
-			isOutputTypeInActions = true
-		}
-	}
-	if len(actions) == 1 && isOutputTypeInActions {
-		var fa *fu.FlowArgs
-		// Parent device flow
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(ingressHop.Ingress),
-				TunnelId(uint64(inPortNo)),
-			},
-			Actions: []*ofp.OfpAction{
-				Output(ingressHop.Egress),
-			},
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-
-		fg := fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
-
-		// Child device flow
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(egressHop.Ingress),
-			},
-			Actions: []*ofp.OfpAction{
-				Output(egressHop.Egress),
-			},
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-
-		fg = fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
-	} else {
-		var fa *fu.FlowArgs
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(egressHop.Ingress),
-			},
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-
-		// Augment the Actions
-		filteredAction := GetActions(flow, OUTPUT)
-		filteredAction = append(filteredAction, Output(egressHop.Egress))
-		fa.Actions = filteredAction
-
-		fg := fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
-	}
-	return deviceRules
-}
-
-// processMulticastFlow decompose multicast flows
-func (fd *FlowDecomposer) processMulticastFlow(agent coreIf.LogicalDeviceAgent, route []graph.RouteHop,
-	inPortNo uint32, outPortNo uint32, flow *ofp.OfpFlowStats, grpId uint32,
-	groupMap map[uint32]*ofp.OfpGroupEntry) *fu.DeviceRules {
-
-	log.Debugw("multicast-flow", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo})
-	deviceRules := fu.NewDeviceRules()
-
-	//having no Group yet is the same as having a Group with no buckets
-	var grp *ofp.OfpGroupEntry
-	var ok bool
-	if grp, ok = groupMap[grpId]; !ok {
-		log.Warnw("Group-id-not-present-in-map", log.Fields{"grpId": grpId, "groupMap": groupMap})
-		return deviceRules
-	}
-	if grp == nil || grp.Desc == nil {
-		log.Warnw("Group-or-desc-nil", log.Fields{"grpId": grpId, "grp": grp})
-		return deviceRules
-	}
-	for _, bucket := range grp.Desc.Buckets {
-		otherActions := make([]*ofp.OfpAction, 0)
-		for _, action := range bucket.Actions {
-			if action.Type == OUTPUT {
-				outPortNo = action.GetOutput().Port
-			} else if action.Type != POP_VLAN {
-				otherActions = append(otherActions, action)
-			}
-		}
-
-		route2 := agent.GetRoute(inPortNo, outPortNo)
-		switch len(route2) {
-		case 0:
-			log.Errorw("mc-no-route", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo, "comment": "deleting flow"})
-			//	TODO: Delete flow
-			return deviceRules
-		case 2:
-			log.Debugw("route-found", log.Fields{"ingressHop": route2[0], "egressHop": route2[1]})
-			break
-		default:
-			log.Errorw("invalid-route-length", log.Fields{"routeLen": len(route)})
-			return deviceRules
-		}
-
-		ingressHop := route[0]
-		ingressHop2 := route2[0]
-		egressHop := route2[1]
-
-		if ingressHop.Ingress != ingressHop2.Ingress {
-			log.Errorw("mc-ingress-hop-hop2-mismatch", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo, "comment": "ignoring flow"})
-			return deviceRules
-		}
-		// Set the parent device flow
-		var fa *fu.FlowArgs
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(ingressHop.Ingress),
-			},
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT)...)
-
-		// Augment the Actions
-		filteredAction := GetActions(flow, GROUP)
-		filteredAction = append(filteredAction, PopVlan())
-		filteredAction = append(filteredAction, Output(route2[1].Ingress))
-		fa.Actions = filteredAction
-
-		fg := fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
-
-		// Set the child device flow
-		fa = &fu.FlowArgs{
-			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
-			MatchFields: []*ofp.OfpOxmOfbField{
-				InPort(egressHop.Ingress),
-			},
-		}
-		// Augment the matchfields with the ofpfields from the flow
-		fa.MatchFields = append(fa.MatchFields, GetOfbFields(flow, IN_PORT, VLAN_VID, VLAN_PCP)...)
-
-		// Augment the Actions
-		otherActions = append(otherActions, Output(egressHop.Egress))
-		fa.Actions = otherActions
-
-		fg = fu.NewFlowsAndGroups()
-		fg.AddFlow(MkFlowStat(fa))
-		deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
-	}
-	return deviceRules
-}
-
-// decomposeFlow decomposes a flow for a logical device into flows for each physical device
-func (fd *FlowDecomposer) decomposeFlow(agent coreIf.LogicalDeviceAgent, flow *ofp.OfpFlowStats,
-	groupMap map[uint32]*ofp.OfpGroupEntry) *fu.DeviceRules {
-
-	inPortNo := GetInPort(flow)
-	outPortNo := GetOutPort(flow)
-	deviceRules := fu.NewDeviceRules()
-	route := agent.GetRoute(inPortNo, outPortNo)
-
-	switch len(route) {
-	case 0:
-		log.Errorw("no-route", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo, "comment": "deleting-flow"})
-		//	TODO: Delete flow
-		return deviceRules
-	case 2:
-		log.Debugw("route-found", log.Fields{"ingressHop": route[0], "egressHop": route[1]})
-		break
-	default:
-		log.Errorw("invalid-route-length", log.Fields{"routeLen": len(route)})
-		return deviceRules
-	}
-
-	// Process controller bound flow
-	if outPortNo != 0 && (outPortNo&0x7fffffff) == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
-		deviceRules = fd.processControllerBoundFlow(agent, route, inPortNo, outPortNo, flow)
-	} else {
-		var ingressDevice *voltha.Device
-		var err error
-		if ingressDevice, err = fd.deviceMgr.GetDevice(route[0].DeviceID); err != nil {
-			log.Errorw("ingress-device-not-found", log.Fields{"deviceId": route[0].DeviceID, "flow": flow})
-			return deviceRules
-		}
-		isUpstream := !ingressDevice.Root
-		if isUpstream {
-			deviceRules = fd.processUpstreamNonControllerBoundFlow(agent, route, inPortNo, outPortNo, flow)
-		} else if HasNextTable(flow) {
-			deviceRules = fd.processDownstreamFlowWithNextTable(agent, route, inPortNo, outPortNo, flow)
-		} else if outPortNo != 0 { // Unicast
-			deviceRules = fd.processUnicastFlow(agent, route, inPortNo, outPortNo, flow)
-		} else if grpId := GetGroup(flow); grpId != 0 { //Multicast
-			deviceRules = fd.processMulticastFlow(agent, route, inPortNo, outPortNo, flow, grpId, groupMap)
-		}
-	}
-	deviceRules = fd.updateOutputPortForControllerBoundFlowForParentDevide(flow, deviceRules)
-	return deviceRules
-}
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/graph/device_graph.go b/vendor/github.com/opencord/voltha-go/rw_core/graph/device_graph.go
deleted file mode 100644
index 5583023..0000000
--- a/vendor/github.com/opencord/voltha-go/rw_core/graph/device_graph.go
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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 graph
-
-import (
-	"errors"
-	"fmt"
-	"github.com/gyuho/goraph"
-	"github.com/opencord/voltha-go/common/log"
-	"github.com/opencord/voltha-protos/go/voltha"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-func init() {
-	log.AddPackage(log.JSON, log.WarnLevel, nil)
-}
-
-type RouteHop struct {
-	DeviceID string
-	Ingress  uint32
-	Egress   uint32
-}
-
-type OFPortLink struct {
-	Ingress uint32
-	Egress  uint32
-}
-
-type ofPortLinkToPath struct {
-	link OFPortLink
-	path []RouteHop
-}
-
-type GetDeviceFunc func(id string) (*voltha.Device, error)
-
-type DeviceGraph struct {
-	logicalDeviceId    string
-	GGraph             goraph.Graph
-	getDeviceFromModel GetDeviceFunc
-	logicalPorts       []*voltha.LogicalPort
-	rootPortsString    map[string]uint32
-	nonRootPortsString map[string]uint32
-	RootPorts          map[uint32]uint32
-	rootPortsLock      sync.RWMutex
-	Routes             map[OFPortLink][]RouteHop
-	graphBuildLock     sync.RWMutex
-	boundaryPorts      map[string]uint32
-	boundaryPortsLock  sync.RWMutex
-	cachedDevices      map[string]*voltha.Device
-	cachedDevicesLock  sync.RWMutex
-	devicesAdded       map[string]string
-	portsAdded         map[string]string
-}
-
-func NewDeviceGraph(logicalDeviceId string, getDevice GetDeviceFunc) *DeviceGraph {
-	var dg DeviceGraph
-	dg.logicalDeviceId = logicalDeviceId
-	dg.GGraph = goraph.NewGraph()
-	dg.getDeviceFromModel = getDevice
-	dg.graphBuildLock = sync.RWMutex{}
-	dg.cachedDevicesLock = sync.RWMutex{}
-	dg.rootPortsLock = sync.RWMutex{}
-	dg.devicesAdded = make(map[string]string)
-	dg.portsAdded = make(map[string]string)
-	dg.rootPortsString = make(map[string]uint32)
-	dg.nonRootPortsString = make(map[string]uint32)
-	dg.RootPorts = make(map[uint32]uint32)
-	dg.boundaryPorts = make(map[string]uint32)
-	dg.Routes = make(map[OFPortLink][]RouteHop)
-	dg.cachedDevices = make(map[string]*voltha.Device)
-	log.Debug("new device graph created ...")
-	return &dg
-}
-
-//IsRootPort returns true if the port is a root port on a logical device
-func (dg *DeviceGraph) IsRootPort(port uint32) bool {
-	dg.rootPortsLock.RLock()
-	defer dg.rootPortsLock.RUnlock()
-	_, exist := dg.RootPorts[port]
-	return exist
-}
-
-//GetDeviceNodeIds retrieves all the nodes in the device graph
-func (dg *DeviceGraph) GetDeviceNodeIds() map[string]string {
-	dg.graphBuildLock.RLock()
-	defer dg.graphBuildLock.RUnlock()
-	nodeIds := make(map[string]string)
-	nodesMap := dg.GGraph.GetNodes()
-	for id, node := range nodesMap {
-		if len(strings.Split(node.String(), ":")) != 2 { // not port node
-			nodeIds[id.String()] = id.String()
-		}
-	}
-	return nodeIds
-}
-
-//ComputeRoutes creates a device graph from the logical ports and then calculates all the routes
-//between the logical ports.  This will clear up the graph and routes if there were any.
-func (dg *DeviceGraph) ComputeRoutes(lps []*voltha.LogicalPort) {
-	if dg == nil {
-		return
-	}
-	dg.graphBuildLock.Lock()
-	defer dg.graphBuildLock.Unlock()
-
-	// Clear the graph
-	dg.reset()
-
-	dg.logicalPorts = lps
-
-	// Set the root, non-root ports and boundary ports
-	for _, lp := range lps {
-		portId := concatDeviceIdPortId(lp.DeviceId, lp.DevicePortNo)
-		if lp.RootPort {
-			dg.rootPortsString[portId] = lp.OfpPort.PortNo
-			dg.RootPorts[lp.OfpPort.PortNo] = lp.OfpPort.PortNo
-		} else {
-			dg.nonRootPortsString[portId] = lp.OfpPort.PortNo
-		}
-		dg.boundaryPorts[portId] = lp.OfpPort.PortNo
-	}
-
-	// Build the graph
-	var device *voltha.Device
-	for _, logicalPort := range dg.logicalPorts {
-		device, _ = dg.getDevice(logicalPort.DeviceId, false)
-		dg.GGraph = dg.addDevice(device, dg.GGraph, &dg.devicesAdded, &dg.portsAdded, dg.boundaryPorts)
-	}
-
-	dg.Routes = dg.buildRoutes()
-}
-
-// AddPort adds a port to the graph.  If the graph is empty it will just invoke ComputeRoutes function
-func (dg *DeviceGraph) AddPort(lp *voltha.LogicalPort) {
-	log.Debugw("Addport", log.Fields{"logicalPort": lp})
-	//  If the graph does not exist invoke ComputeRoutes.
-	if len(dg.boundaryPorts) == 0 {
-		dg.ComputeRoutes([]*voltha.LogicalPort{lp})
-		return
-	}
-
-	dg.graphBuildLock.Lock()
-	defer dg.graphBuildLock.Unlock()
-
-	portId := concatDeviceIdPortId(lp.DeviceId, lp.DevicePortNo)
-
-	//	If the port is already part of the boundary ports, do nothing
-	if dg.portExist(portId) {
-		return
-	}
-	// Add the port to the set of boundary ports
-	dg.boundaryPorts[portId] = lp.OfpPort.PortNo
-
-	// Add the device where this port is located to the device graph. If the device is already added then
-	// only the missing port will be added
-	device, _ := dg.getDevice(lp.DeviceId, false)
-	dg.GGraph = dg.addDevice(device, dg.GGraph, &dg.devicesAdded, &dg.portsAdded, dg.boundaryPorts)
-
-	if lp.RootPort {
-		// Compute the route from this root port to all non-root ports
-		dg.rootPortsString[portId] = lp.OfpPort.PortNo
-		dg.RootPorts[lp.OfpPort.PortNo] = lp.OfpPort.PortNo
-		dg.Routes = dg.buildPathsToAllNonRootPorts(lp)
-	} else {
-		// Compute the route from this port to all root ports
-		dg.nonRootPortsString[portId] = lp.OfpPort.PortNo
-		dg.Routes = dg.buildPathsToAllRootPorts(lp)
-	}
-
-	dg.Print()
-}
-
-func (dg *DeviceGraph) Print() error {
-	log.Debugw("Print", log.Fields{"graph": dg.logicalDeviceId, "boundaryPorts": dg.boundaryPorts})
-	if level, err := log.GetPackageLogLevel(); err == nil && level == log.DebugLevel {
-		output := ""
-		routeNumber := 1
-		for k, v := range dg.Routes {
-			key := fmt.Sprintf("LP:%d->LP:%d", k.Ingress, k.Egress)
-			val := ""
-			for _, i := range v {
-				val += fmt.Sprintf("{%d->%s->%d},", i.Ingress, i.DeviceID, i.Egress)
-			}
-			val = val[:len(val)-1]
-			output += fmt.Sprintf("%d:{%s=>%s}   ", routeNumber, key, fmt.Sprintf("[%s]", val))
-			routeNumber += 1
-		}
-		if len(dg.Routes) == 0 {
-			log.Debugw("no-routes-found", log.Fields{"lDeviceId": dg.logicalDeviceId, "Graph": dg.GGraph.String()})
-		} else {
-			log.Debugw("graph_routes", log.Fields{"lDeviceId": dg.logicalDeviceId, "Routes": output})
-		}
-	}
-	return nil
-}
-
-//getDevice returns the device either from the local cache (default) or from the model.
-//TODO: Set a cache timeout such that we do not use invalid data.  The full device lifecycle should also
-//be taken in consideration
-func (dg *DeviceGraph) getDevice(id string, useCache bool) (*voltha.Device, error) {
-	if useCache {
-		dg.cachedDevicesLock.RLock()
-		if d, exist := dg.cachedDevices[id]; exist {
-			dg.cachedDevicesLock.RUnlock()
-			//log.Debugw("getDevice - returned from cache", log.Fields{"deviceId": id})
-			return d, nil
-		}
-		dg.cachedDevicesLock.RUnlock()
-	}
-	//	Not cached
-	if d, err := dg.getDeviceFromModel(id); err != nil {
-		log.Errorw("device-not-found", log.Fields{"deviceId": id, "error": err})
-		return nil, err
-	} else { // cache it
-		dg.cachedDevicesLock.Lock()
-		dg.cachedDevices[id] = d
-		dg.cachedDevicesLock.Unlock()
-		//log.Debugw("getDevice - returned from model", log.Fields{"deviceId": id})
-		return d, nil
-	}
-}
-
-// addDevice adds a device to a device graph and setup edges that represent the device connections to its peers
-func (dg *DeviceGraph) addDevice(device *voltha.Device, g goraph.Graph, devicesAdded *map[string]string, portsAdded *map[string]string,
-	boundaryPorts map[string]uint32) goraph.Graph {
-
-	if device == nil {
-		return g
-	}
-
-	if _, exist := (*devicesAdded)[device.Id]; !exist {
-		g.AddNode(goraph.NewNode(device.Id))
-		(*devicesAdded)[device.Id] = device.Id
-	}
-
-	var portId string
-	var peerPortId string
-	for _, port := range device.Ports {
-		portId = concatDeviceIdPortId(device.Id, port.PortNo)
-		if _, exist := (*portsAdded)[portId]; !exist {
-			(*portsAdded)[portId] = portId
-			g.AddNode(goraph.NewNode(portId))
-			g.AddEdge(goraph.StringID(device.Id), goraph.StringID(portId), 1)
-			g.AddEdge(goraph.StringID(portId), goraph.StringID(device.Id), 1)
-		}
-		for _, peer := range port.Peers {
-			if _, exist := (*devicesAdded)[peer.DeviceId]; !exist {
-				d, _ := dg.getDevice(peer.DeviceId, true)
-				g = dg.addDevice(d, g, devicesAdded, portsAdded, boundaryPorts)
-			}
-			peerPortId = concatDeviceIdPortId(peer.DeviceId, peer.PortNo)
-			g.AddEdge(goraph.StringID(portId), goraph.StringID(peerPortId), 1)
-			g.AddEdge(goraph.StringID(peerPortId), goraph.StringID(portId), 1)
-
-		}
-	}
-	return g
-}
-
-//portExist returns true if the port ID is already part of the boundary ports map.
-func (dg *DeviceGraph) portExist(id string) bool {
-	dg.boundaryPortsLock.RLock()
-	defer dg.boundaryPortsLock.RUnlock()
-	_, exist := dg.boundaryPorts[id]
-	return exist
-}
-
-// buildPathsToAllRootPorts builds all the paths from the non-root logical port to all root ports
-// on the logical device
-func (dg *DeviceGraph) buildPathsToAllRootPorts(lp *voltha.LogicalPort) map[OFPortLink][]RouteHop {
-	paths := dg.Routes
-	source := concatDeviceIdPortId(lp.DeviceId, lp.DevicePortNo)
-	sourcePort := lp.OfpPort.PortNo
-	ch := make(chan *ofPortLinkToPath)
-	numBuildRequest := 0
-	for target, targetPort := range dg.rootPortsString {
-		go dg.buildRoute(source, target, sourcePort, targetPort, ch)
-		numBuildRequest += 1
-	}
-	responseReceived := 0
-forloop:
-	for {
-		if responseReceived == numBuildRequest {
-			break
-		}
-		select {
-		case res, ok := <-ch:
-			if !ok {
-				log.Debug("channel closed")
-				break forloop
-			}
-			if res != nil && len(res.path) > 0 {
-				paths[res.link] = res.path
-				paths[OFPortLink{Ingress: res.link.Egress, Egress: res.link.Ingress}] = getReverseRoute(res.path)
-			}
-		}
-		responseReceived += 1
-	}
-	return paths
-}
-
-// buildPathsToAllNonRootPorts builds all the paths from the root logical port to all non-root ports
-// on the logical device
-func (dg *DeviceGraph) buildPathsToAllNonRootPorts(lp *voltha.LogicalPort) map[OFPortLink][]RouteHop {
-	paths := dg.Routes
-	source := concatDeviceIdPortId(lp.DeviceId, lp.DevicePortNo)
-	sourcePort := lp.OfpPort.PortNo
-	ch := make(chan *ofPortLinkToPath)
-	numBuildRequest := 0
-	for target, targetPort := range dg.nonRootPortsString {
-		go dg.buildRoute(source, target, sourcePort, targetPort, ch)
-		numBuildRequest += 1
-	}
-	responseReceived := 0
-forloop:
-	for {
-		if responseReceived == numBuildRequest {
-			break
-		}
-		select {
-		case res, ok := <-ch:
-			if !ok {
-				log.Debug("channel closed")
-				break forloop
-			}
-			if res != nil && len(res.path) > 0 {
-				paths[res.link] = res.path
-				paths[OFPortLink{Ingress: res.link.Egress, Egress: res.link.Ingress}] = getReverseRoute(res.path)
-			}
-		}
-		responseReceived += 1
-	}
-	return paths
-}
-
-//buildRoute builds a route between a source and a target logical port
-func (dg *DeviceGraph) buildRoute(sourceId, targetId string, sourcePort, targetPort uint32, ch chan *ofPortLinkToPath) {
-	var pathIds []goraph.ID
-	path := make([]RouteHop, 0)
-	var err error
-	var hop RouteHop
-	var result *ofPortLinkToPath
-
-	if sourceId == targetId {
-		ch <- result
-		return
-	}
-	//Ignore Root - Root Routes
-	if dg.IsRootPort(sourcePort) && dg.IsRootPort(targetPort) {
-		ch <- result
-		return
-	}
-
-	//Ignore non-Root - non-Root Routes
-	if !dg.IsRootPort(sourcePort) && !dg.IsRootPort(targetPort) {
-		ch <- result
-		return
-	}
-
-	if pathIds, _, err = goraph.Dijkstra(dg.GGraph, goraph.StringID(sourceId), goraph.StringID(targetId)); err != nil {
-		log.Errorw("no-path", log.Fields{"sourceId": sourceId, "targetId": targetId, "error": err})
-		ch <- result
-		return
-	}
-	if len(pathIds)%3 != 0 {
-		ch <- result
-		return
-	}
-	var deviceId string
-	var ingressPort uint32
-	var egressPort uint32
-	for i := 0; i < len(pathIds); i = i + 3 {
-		if deviceId, ingressPort, err = splitIntoDeviceIdPortId(pathIds[i].String()); err != nil {
-			log.Errorw("id-error", log.Fields{"sourceId": sourceId, "targetId": targetId, "error": err})
-			break
-		}
-		if _, egressPort, err = splitIntoDeviceIdPortId(pathIds[i+2].String()); err != nil {
-			log.Errorw("id-error", log.Fields{"sourceId": sourceId, "targetId": targetId, "error": err})
-			break
-		}
-		hop = RouteHop{Ingress: ingressPort, DeviceID: deviceId, Egress: egressPort}
-		path = append(path, hop)
-	}
-	result = &ofPortLinkToPath{link: OFPortLink{Ingress: sourcePort, Egress: targetPort}, path: path}
-	ch <- result
-}
-
-//buildRoutes build all routes between all the ports on the logical device
-func (dg *DeviceGraph) buildRoutes() map[OFPortLink][]RouteHop {
-	paths := make(map[OFPortLink][]RouteHop)
-	ch := make(chan *ofPortLinkToPath)
-	numBuildRequest := 0
-	for source, sourcePort := range dg.boundaryPorts {
-		for target, targetPort := range dg.boundaryPorts {
-			go dg.buildRoute(source, target, sourcePort, targetPort, ch)
-			numBuildRequest += 1
-		}
-	}
-	responseReceived := 0
-forloop:
-	for {
-		if responseReceived == numBuildRequest {
-			break
-		}
-		select {
-		case res, ok := <-ch:
-			if !ok {
-				log.Debug("channel closed")
-				break forloop
-			}
-			if res != nil && len(res.path) > 0 {
-				paths[res.link] = res.path
-			}
-		}
-		responseReceived += 1
-	}
-	return paths
-}
-
-// reset cleans up the device graph
-func (dg *DeviceGraph) reset() {
-	dg.devicesAdded = make(map[string]string)
-	dg.portsAdded = make(map[string]string)
-	dg.rootPortsString = make(map[string]uint32)
-	dg.nonRootPortsString = make(map[string]uint32)
-	dg.RootPorts = make(map[uint32]uint32)
-	dg.boundaryPorts = make(map[string]uint32)
-	dg.Routes = make(map[OFPortLink][]RouteHop)
-	dg.cachedDevices = make(map[string]*voltha.Device)
-}
-
-//concatDeviceIdPortId formats a portid using the device id and the port number
-func concatDeviceIdPortId(deviceId string, portNo uint32) string {
-	return fmt.Sprintf("%s:%d", deviceId, portNo)
-}
-
-// splitIntoDeviceIdPortId extracts the device id and port number from the portId
-func splitIntoDeviceIdPortId(id string) (string, uint32, error) {
-	result := strings.Split(id, ":")
-	if len(result) != 2 {
-		return "", 0, errors.New(fmt.Sprintf("invalid-id-%s", id))
-	}
-	if temp, err := strconv.ParseInt(result[1], 10, 32); err != nil {
-		return "", 0, errors.New(fmt.Sprintf("invalid-id-%s-%s", id, err.Error()))
-	} else {
-		return result[0], uint32(temp), nil
-	}
-}
-
-//getReverseRoute returns the reverse of the route in param
-func getReverseRoute(route []RouteHop) []RouteHop {
-	reverse := make([]RouteHop, len(route))
-	for i, j := 0, len(route)-1; i < j; i, j = i+1, j-1 {
-		reverse[i], reverse[j] = route[j], route[i]
-	}
-	return reverse
-}
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go b/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go
index cf77d59..813c978 100644
--- a/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go
+++ b/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go
@@ -59,12 +59,12 @@
 		if !ok { // closed channel
 			//Set the channel at that index to nil to disable this case, hence preventing it from interfering with other cases.
 			cases[index].Chan = reflect.ValueOf(nil)
-			errors[index] = status.Errorf(codes.Internal, "channel closed")
+			errors[index] = status.Error(codes.Internal, "channel closed")
 			errorsReceived = true
 		} else if index == len(chnls) { // Timeout has occurred
 			for k := range errors {
 				if !resultsReceived[k] {
-					errors[k] = status.Errorf(codes.Aborted, "timeout")
+					errors[k] = status.Error(codes.Aborted, "timeout")
 				}
 			}
 			errorsReceived = true
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go b/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go
index c2c9287..c1ca18d 100644
--- a/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go
+++ b/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go
@@ -17,12 +17,746 @@
 
 import (
 	"bytes"
+	"crypto/md5"
+	"fmt"
 	"github.com/cevaris/ordered_map"
 	"github.com/gogo/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
 	ofp "github.com/opencord/voltha-protos/go/openflow_13"
+	"math/big"
 	"strings"
 )
 
+var (
+	// Instructions shortcut
+	APPLY_ACTIONS = ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS
+
+	//OFPAT_* shortcuts
+	OUTPUT       = ofp.OfpActionType_OFPAT_OUTPUT
+	COPY_TTL_OUT = ofp.OfpActionType_OFPAT_COPY_TTL_OUT
+	COPY_TTL_IN  = ofp.OfpActionType_OFPAT_COPY_TTL_IN
+	SET_MPLS_TTL = ofp.OfpActionType_OFPAT_SET_MPLS_TTL
+	DEC_MPLS_TTL = ofp.OfpActionType_OFPAT_DEC_MPLS_TTL
+	PUSH_VLAN    = ofp.OfpActionType_OFPAT_PUSH_VLAN
+	POP_VLAN     = ofp.OfpActionType_OFPAT_POP_VLAN
+	PUSH_MPLS    = ofp.OfpActionType_OFPAT_PUSH_MPLS
+	POP_MPLS     = ofp.OfpActionType_OFPAT_POP_MPLS
+	SET_QUEUE    = ofp.OfpActionType_OFPAT_SET_QUEUE
+	GROUP        = ofp.OfpActionType_OFPAT_GROUP
+	SET_NW_TTL   = ofp.OfpActionType_OFPAT_SET_NW_TTL
+	NW_TTL       = ofp.OfpActionType_OFPAT_DEC_NW_TTL
+	SET_FIELD    = ofp.OfpActionType_OFPAT_SET_FIELD
+	PUSH_PBB     = ofp.OfpActionType_OFPAT_PUSH_PBB
+	POP_PBB      = ofp.OfpActionType_OFPAT_POP_PBB
+	EXPERIMENTER = ofp.OfpActionType_OFPAT_EXPERIMENTER
+
+	//OFPXMT_OFB_* shortcuts (incomplete)
+	IN_PORT         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT
+	IN_PHY_PORT     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT
+	METADATA        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_METADATA
+	ETH_DST         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST
+	ETH_SRC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_SRC
+	ETH_TYPE        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE
+	VLAN_VID        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID
+	VLAN_PCP        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP
+	IP_DSCP         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_DSCP
+	IP_ECN          = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_ECN
+	IP_PROTO        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO
+	IPV4_SRC        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC
+	IPV4_DST        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST
+	TCP_SRC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TCP_SRC
+	TCP_DST         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TCP_DST
+	UDP_SRC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC
+	UDP_DST         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST
+	SCTP_SRC        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_SCTP_SRC
+	SCTP_DST        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_SCTP_DST
+	ICMPV4_TYPE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV4_TYPE
+	ICMPV4_CODE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV4_CODE
+	ARP_OP          = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_OP
+	ARP_SPA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_SPA
+	ARP_TPA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_TPA
+	ARP_SHA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_SHA
+	ARP_THA         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ARP_THA
+	IPV6_SRC        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_SRC
+	IPV6_DST        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_DST
+	IPV6_FLABEL     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_FLABEL
+	ICMPV6_TYPE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV6_TYPE
+	ICMPV6_CODE     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ICMPV6_CODE
+	IPV6_ND_TARGET  = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_TARGET
+	OFB_IPV6_ND_SLL = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_SLL
+	IPV6_ND_TLL     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_ND_TLL
+	MPLS_LABEL      = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_LABEL
+	MPLS_TC         = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_TC
+	MPLS_BOS        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_MPLS_BOS
+	PBB_ISID        = ofp.OxmOfbFieldTypes_OFPXMT_OFB_PBB_ISID
+	TUNNEL_ID       = ofp.OxmOfbFieldTypes_OFPXMT_OFB_TUNNEL_ID
+	IPV6_EXTHDR     = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV6_EXTHDR
+)
+
+//ofp_action_* shortcuts
+
+func Output(port uint32, maxLen ...ofp.OfpControllerMaxLen) *ofp.OfpAction {
+	maxLength := ofp.OfpControllerMaxLen_OFPCML_MAX
+	if len(maxLen) > 0 {
+		maxLength = maxLen[0]
+	}
+	return &ofp.OfpAction{Type: OUTPUT, Action: &ofp.OfpAction_Output{Output: &ofp.OfpActionOutput{Port: port, MaxLen: uint32(maxLength)}}}
+}
+
+func MplsTtl(ttl uint32) *ofp.OfpAction {
+	return &ofp.OfpAction{Type: SET_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: ttl}}}
+}
+
+func PushVlan(ethType uint32) *ofp.OfpAction {
+	return &ofp.OfpAction{Type: PUSH_VLAN, Action: &ofp.OfpAction_Push{Push: &ofp.OfpActionPush{Ethertype: ethType}}}
+}
+
+func PopVlan() *ofp.OfpAction {
+	return &ofp.OfpAction{Type: POP_VLAN}
+}
+
+func PopMpls(ethType uint32) *ofp.OfpAction {
+	return &ofp.OfpAction{Type: POP_MPLS, Action: &ofp.OfpAction_PopMpls{PopMpls: &ofp.OfpActionPopMpls{Ethertype: ethType}}}
+}
+
+func Group(groupId uint32) *ofp.OfpAction {
+	return &ofp.OfpAction{Type: GROUP, Action: &ofp.OfpAction_Group{Group: &ofp.OfpActionGroup{GroupId: groupId}}}
+}
+
+func NwTtl(nwTtl uint32) *ofp.OfpAction {
+	return &ofp.OfpAction{Type: NW_TTL, Action: &ofp.OfpAction_NwTtl{NwTtl: &ofp.OfpActionNwTtl{NwTtl: nwTtl}}}
+}
+
+func SetField(field *ofp.OfpOxmOfbField) *ofp.OfpAction {
+	actionSetField := &ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: &ofp.OfpOxmField_OfbField{OfbField: field}}
+	return &ofp.OfpAction{Type: SET_FIELD, Action: &ofp.OfpAction_SetField{SetField: &ofp.OfpActionSetField{Field: actionSetField}}}
+}
+
+func Experimenter(experimenter uint32, data []byte) *ofp.OfpAction {
+	return &ofp.OfpAction{Type: EXPERIMENTER, Action: &ofp.OfpAction_Experimenter{Experimenter: &ofp.OfpActionExperimenter{Experimenter: experimenter, Data: data}}}
+}
+
+//ofb_field generators (incomplete set)
+
+func InPort(inPort uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IN_PORT, Value: &ofp.OfpOxmOfbField_Port{Port: inPort}}
+}
+
+func InPhyPort(inPhyPort uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IN_PHY_PORT, Value: &ofp.OfpOxmOfbField_Port{Port: inPhyPort}}
+}
+
+func Metadata_ofp(tableMetadata uint64) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: METADATA, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: tableMetadata}}
+}
+
+// should Metadata_ofp used here ?????
+func EthDst(ethDst uint64) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ETH_DST, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: ethDst}}
+}
+
+// should Metadata_ofp used here ?????
+func EthSrc(ethSrc uint64) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ETH_SRC, Value: &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: ethSrc}}
+}
+
+func EthType(ethType uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ETH_TYPE, Value: &ofp.OfpOxmOfbField_EthType{EthType: ethType}}
+}
+
+func VlanVid(vlanVid uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: VLAN_VID, Value: &ofp.OfpOxmOfbField_VlanVid{VlanVid: vlanVid}}
+}
+
+func VlanPcp(vlanPcp uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: VLAN_PCP, Value: &ofp.OfpOxmOfbField_VlanPcp{VlanPcp: vlanPcp}}
+}
+
+func IpDscp(ipDscp uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IP_DSCP, Value: &ofp.OfpOxmOfbField_IpDscp{IpDscp: ipDscp}}
+}
+
+func IpEcn(ipEcn uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IP_ECN, Value: &ofp.OfpOxmOfbField_IpEcn{IpEcn: ipEcn}}
+}
+
+func IpProto(ipProto uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IP_PROTO, Value: &ofp.OfpOxmOfbField_IpProto{IpProto: ipProto}}
+}
+
+func Ipv4Src(ipv4Src uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV4_SRC, Value: &ofp.OfpOxmOfbField_Ipv4Src{Ipv4Src: ipv4Src}}
+}
+
+func Ipv4Dst(ipv4Dst uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV4_DST, Value: &ofp.OfpOxmOfbField_Ipv4Dst{Ipv4Dst: ipv4Dst}}
+}
+
+func TcpSrc(tcpSrc uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: TCP_SRC, Value: &ofp.OfpOxmOfbField_TcpSrc{TcpSrc: tcpSrc}}
+}
+
+func TcpDst(tcpDst uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: TCP_DST, Value: &ofp.OfpOxmOfbField_TcpDst{TcpDst: tcpDst}}
+}
+
+func UdpSrc(udpSrc uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: UDP_SRC, Value: &ofp.OfpOxmOfbField_UdpSrc{UdpSrc: udpSrc}}
+}
+
+func UdpDst(udpDst uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: UDP_DST, Value: &ofp.OfpOxmOfbField_UdpDst{UdpDst: udpDst}}
+}
+
+func SctpSrc(sctpSrc uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: SCTP_SRC, Value: &ofp.OfpOxmOfbField_SctpSrc{SctpSrc: sctpSrc}}
+}
+
+func SctpDst(sctpDst uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: SCTP_DST, Value: &ofp.OfpOxmOfbField_SctpDst{SctpDst: sctpDst}}
+}
+
+func Icmpv4Type(icmpv4Type uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ICMPV4_TYPE, Value: &ofp.OfpOxmOfbField_Icmpv4Type{Icmpv4Type: icmpv4Type}}
+}
+
+func Icmpv4Code(icmpv4Code uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ICMPV4_CODE, Value: &ofp.OfpOxmOfbField_Icmpv4Code{Icmpv4Code: icmpv4Code}}
+}
+
+func ArpOp(arpOp uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ARP_OP, Value: &ofp.OfpOxmOfbField_ArpOp{ArpOp: arpOp}}
+}
+
+func ArpSpa(arpSpa uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ARP_SPA, Value: &ofp.OfpOxmOfbField_ArpSpa{ArpSpa: arpSpa}}
+}
+
+func ArpTpa(arpTpa uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ARP_TPA, Value: &ofp.OfpOxmOfbField_ArpTpa{ArpTpa: arpTpa}}
+}
+
+func ArpSha(arpSha []byte) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ARP_SHA, Value: &ofp.OfpOxmOfbField_ArpSha{ArpSha: arpSha}}
+}
+
+func ArpTha(arpTha []byte) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ARP_THA, Value: &ofp.OfpOxmOfbField_ArpTha{ArpTha: arpTha}}
+}
+
+func Ipv6Src(ipv6Src []byte) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV6_SRC, Value: &ofp.OfpOxmOfbField_Ipv6Src{Ipv6Src: ipv6Src}}
+}
+
+func Ipv6Dst(ipv6Dst []byte) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV6_DST, Value: &ofp.OfpOxmOfbField_Ipv6Dst{Ipv6Dst: ipv6Dst}}
+}
+
+func Ipv6Flabel(ipv6Flabel uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV6_FLABEL, Value: &ofp.OfpOxmOfbField_Ipv6Flabel{Ipv6Flabel: ipv6Flabel}}
+}
+
+func Icmpv6Type(icmpv6Type uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ICMPV6_TYPE, Value: &ofp.OfpOxmOfbField_Icmpv6Type{Icmpv6Type: icmpv6Type}}
+}
+
+func Icmpv6Code(icmpv6Code uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: ICMPV6_CODE, Value: &ofp.OfpOxmOfbField_Icmpv6Code{Icmpv6Code: icmpv6Code}}
+}
+
+func Ipv6NdTarget(ipv6NdTarget []byte) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV6_ND_TARGET, Value: &ofp.OfpOxmOfbField_Ipv6NdTarget{Ipv6NdTarget: ipv6NdTarget}}
+}
+
+func OfbIpv6NdSll(ofbIpv6NdSll []byte) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: OFB_IPV6_ND_SLL, Value: &ofp.OfpOxmOfbField_Ipv6NdSsl{Ipv6NdSsl: ofbIpv6NdSll}}
+}
+
+func Ipv6NdTll(ipv6NdTll []byte) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV6_ND_TLL, Value: &ofp.OfpOxmOfbField_Ipv6NdTll{Ipv6NdTll: ipv6NdTll}}
+}
+
+func MplsLabel(mplsLabel uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: MPLS_LABEL, Value: &ofp.OfpOxmOfbField_MplsLabel{MplsLabel: mplsLabel}}
+}
+
+func MplsTc(mplsTc uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: MPLS_TC, Value: &ofp.OfpOxmOfbField_MplsTc{MplsTc: mplsTc}}
+}
+
+func MplsBos(mplsBos uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: MPLS_BOS, Value: &ofp.OfpOxmOfbField_MplsBos{MplsBos: mplsBos}}
+}
+
+func PbbIsid(pbbIsid uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: PBB_ISID, Value: &ofp.OfpOxmOfbField_PbbIsid{PbbIsid: pbbIsid}}
+}
+
+func TunnelId(tunnelId uint64) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: TUNNEL_ID, Value: &ofp.OfpOxmOfbField_TunnelId{TunnelId: tunnelId}}
+}
+
+func Ipv6Exthdr(ipv6Exthdr uint32) *ofp.OfpOxmOfbField {
+	return &ofp.OfpOxmOfbField{Type: IPV6_EXTHDR, Value: &ofp.OfpOxmOfbField_Ipv6Exthdr{Ipv6Exthdr: ipv6Exthdr}}
+}
+
+//frequently used extractors
+
+func excludeAction(action *ofp.OfpAction, exclude ...ofp.OfpActionType) bool {
+	for _, actionToExclude := range exclude {
+		if action.Type == actionToExclude {
+			return true
+		}
+	}
+	return false
+}
+
+func GetActions(flow *ofp.OfpFlowStats, exclude ...ofp.OfpActionType) []*ofp.OfpAction {
+	if flow == nil {
+		return nil
+	}
+	for _, instruction := range flow.Instructions {
+		if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
+			instActions := instruction.GetActions()
+			if instActions == nil {
+				return nil
+			}
+			if len(exclude) == 0 {
+				return instActions.Actions
+			} else {
+				filteredAction := make([]*ofp.OfpAction, 0)
+				for _, action := range instActions.Actions {
+					if !excludeAction(action, exclude...) {
+						filteredAction = append(filteredAction, action)
+					}
+				}
+				return filteredAction
+			}
+		}
+	}
+	return nil
+}
+
+func UpdateOutputPortByActionType(flow *ofp.OfpFlowStats, actionType uint32, toPort uint32) *ofp.OfpFlowStats {
+	if flow == nil {
+		return nil
+	}
+	nFlow := (proto.Clone(flow)).(*ofp.OfpFlowStats)
+	nFlow.Instructions = nil
+	nInsts := make([]*ofp.OfpInstruction, 0)
+	for _, instruction := range flow.Instructions {
+		if instruction.Type == actionType {
+			instActions := instruction.GetActions()
+			if instActions == nil {
+				return nil
+			}
+			nActions := make([]*ofp.OfpAction, 0)
+			for _, action := range instActions.Actions {
+				if action.GetOutput() != nil {
+					nActions = append(nActions, Output(toPort))
+				} else {
+					nActions = append(nActions, action)
+				}
+			}
+			instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: nActions}}
+			nInsts = append(nInsts, &ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction})
+		} else {
+			nInsts = append(nInsts, instruction)
+		}
+	}
+	nFlow.Instructions = nInsts
+	return nFlow
+}
+
+func excludeOxmOfbField(field *ofp.OfpOxmOfbField, exclude ...ofp.OxmOfbFieldTypes) bool {
+	for _, fieldToExclude := range exclude {
+		if field.Type == fieldToExclude {
+			return true
+		}
+	}
+	return false
+}
+
+func GetOfbFields(flow *ofp.OfpFlowStats, exclude ...ofp.OxmOfbFieldTypes) []*ofp.OfpOxmOfbField {
+	if flow == nil || flow.Match == nil || flow.Match.Type != ofp.OfpMatchType_OFPMT_OXM {
+		return nil
+	}
+	ofbFields := make([]*ofp.OfpOxmOfbField, 0)
+	for _, field := range flow.Match.OxmFields {
+		if field.OxmClass == ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
+			ofbFields = append(ofbFields, field.GetOfbField())
+		}
+	}
+	if len(exclude) == 0 {
+		return ofbFields
+	} else {
+		filteredFields := make([]*ofp.OfpOxmOfbField, 0)
+		for _, ofbField := range ofbFields {
+			if !excludeOxmOfbField(ofbField, exclude...) {
+				filteredFields = append(filteredFields, ofbField)
+			}
+		}
+		return filteredFields
+	}
+}
+
+func GetPacketOutPort(packet *ofp.OfpPacketOut) uint32 {
+	if packet == nil {
+		return 0
+	}
+	for _, action := range packet.GetActions() {
+		if action.Type == OUTPUT {
+			return action.GetOutput().Port
+		}
+	}
+	return 0
+}
+
+func GetOutPort(flow *ofp.OfpFlowStats) uint32 {
+	if flow == nil {
+		return 0
+	}
+	for _, action := range GetActions(flow) {
+		if action.Type == OUTPUT {
+			out := action.GetOutput()
+			if out == nil {
+				return 0
+			}
+			return out.GetPort()
+		}
+	}
+	return 0
+}
+
+func GetInPort(flow *ofp.OfpFlowStats) uint32 {
+	if flow == nil {
+		return 0
+	}
+	for _, field := range GetOfbFields(flow) {
+		if field.Type == IN_PORT {
+			return field.GetPort()
+		}
+	}
+	return 0
+}
+
+func GetGotoTableId(flow *ofp.OfpFlowStats) uint32 {
+	if flow == nil {
+		return 0
+	}
+	for _, instruction := range flow.Instructions {
+		if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE) {
+			gotoTable := instruction.GetGotoTable()
+			if gotoTable == nil {
+				return 0
+			}
+			return gotoTable.GetTableId()
+		}
+	}
+	return 0
+}
+
+func GetTunnelId(flow *ofp.OfpFlowStats) uint64 {
+	if flow == nil {
+		return 0
+	}
+	for _, field := range GetOfbFields(flow) {
+		if field.Type == TUNNEL_ID {
+			return field.GetTunnelId()
+		}
+	}
+	return 0
+}
+
+//GetMetaData - legacy get method (only want lower 32 bits)
+func GetMetaData(flow *ofp.OfpFlowStats) uint32 {
+	if flow == nil {
+		return 0
+	}
+	for _, field := range GetOfbFields(flow) {
+		if field.Type == METADATA {
+			return uint32(field.GetTableMetadata() & 0xffffffff)
+		}
+	}
+	return 0
+}
+
+func GetMetaData64Bit(flow *ofp.OfpFlowStats) uint64 {
+	if flow == nil {
+		return 0
+	}
+	for _, field := range GetOfbFields(flow) {
+		if field.Type == METADATA {
+			return field.GetTableMetadata()
+		}
+	}
+	return 0
+}
+
+// GetPortNumberFromMetadata retrieves the port number from the Metadata_ofp. The port number (UNI on ONU) is in the
+// lower 32-bits of Metadata_ofp and the inner_tag is in the upper 32-bits. This is set in the ONOS OltPipeline as
+// a Metadata_ofp field
+func GetPortNumberFromMetadata(flow *ofp.OfpFlowStats) uint64 {
+	md := GetMetaData64Bit(flow)
+	if md == 0 {
+		return 0
+	}
+	if md <= 0xffffffff {
+		log.Debugw("onos-upgrade-suggested", log.Fields{"Metadata_ofp": md, "message": "Legacy MetaData detected form OltPipeline"})
+		return md
+	}
+	return md & 0xffffffff
+}
+
+//GetInnerTagFromMetaData retrieves the inner tag from the Metadata_ofp. The port number (UNI on ONU) is in the
+// lower 32-bits of Metadata_ofp and the inner_tag is in the upper 32-bits. This is set in the ONOS OltPipeline as
+//// a Metadata_ofp field
+func GetInnerTagFromMetaData(flow *ofp.OfpFlowStats) uint64 {
+	md := GetMetaData64Bit(flow)
+	if md == 0 {
+		return 0
+	}
+	if md <= 0xffffffff {
+		log.Debugw("onos-upgrade-suggested", log.Fields{"Metadata_ofp": md, "message": "Legacy MetaData detected form OltPipeline"})
+		return md
+	}
+	return (md >> 32) & 0xffffffff
+}
+
+// Extract the child device port from a flow that contains the parent device peer port.  Typically the UNI port of an
+// ONU child device.  Per TST agreement this will be the lower 32 bits of tunnel id reserving upper 32 bits for later
+// use
+func GetChildPortFromTunnelId(flow *ofp.OfpFlowStats) uint32 {
+	tid := GetTunnelId(flow)
+	if tid == 0 {
+		return 0
+	}
+	// Per TST agreement we are keeping any child port id (uni port id) in the lower 32 bits
+	return uint32(tid & 0xffffffff)
+}
+
+func HasNextTable(flow *ofp.OfpFlowStats) bool {
+	if flow == nil {
+		return false
+	}
+	return GetGotoTableId(flow) != 0
+}
+
+func GetGroup(flow *ofp.OfpFlowStats) uint32 {
+	if flow == nil {
+		return 0
+	}
+	for _, action := range GetActions(flow) {
+		if action.Type == GROUP {
+			grp := action.GetGroup()
+			if grp == nil {
+				return 0
+			}
+			return grp.GetGroupId()
+		}
+	}
+	return 0
+}
+
+func HasGroup(flow *ofp.OfpFlowStats) bool {
+	return GetGroup(flow) != 0
+}
+
+// GetNextTableId returns the next table ID if the "table_id" is present in the map, otherwise return nil
+func GetNextTableId(kw OfpFlowModArgs) *uint32 {
+	if val, exist := kw["table_id"]; exist {
+		ret := uint32(val)
+		return &ret
+	}
+	return nil
+}
+
+// Return unique 64-bit integer hash for flow covering the following attributes:
+// 'table_id', 'priority', 'flags', 'cookie', 'match', '_instruction_string'
+func HashFlowStats(flow *ofp.OfpFlowStats) uint64 {
+	if flow == nil { // Should never happen
+		return 0
+	}
+	// Create string with the instructions field first
+	var instructionString bytes.Buffer
+	for _, instruction := range flow.Instructions {
+		instructionString.WriteString(instruction.String())
+	}
+	var flowString = fmt.Sprintf("%d%d%d%d%s%s", flow.TableId, flow.Priority, flow.Flags, flow.Cookie, flow.Match.String(), instructionString.String())
+	h := md5.New()
+	h.Write([]byte(flowString))
+	hash := big.NewInt(0)
+	hash.SetBytes(h.Sum(nil))
+	return hash.Uint64()
+}
+
+// flowStatsEntryFromFlowModMessage maps an ofp_flow_mod message to an ofp_flow_stats message
+func FlowStatsEntryFromFlowModMessage(mod *ofp.OfpFlowMod) *ofp.OfpFlowStats {
+	flow := &ofp.OfpFlowStats{}
+	if mod == nil {
+		return flow
+	}
+	flow.TableId = mod.TableId
+	flow.Priority = mod.Priority
+	flow.IdleTimeout = mod.IdleTimeout
+	flow.HardTimeout = mod.HardTimeout
+	flow.Flags = mod.Flags
+	flow.Cookie = mod.Cookie
+	flow.Match = mod.Match
+	flow.Instructions = mod.Instructions
+	flow.Id = HashFlowStats(flow)
+	return flow
+}
+
+func GroupEntryFromGroupMod(mod *ofp.OfpGroupMod) *ofp.OfpGroupEntry {
+	group := &ofp.OfpGroupEntry{}
+	if mod == nil {
+		return group
+	}
+	group.Desc = &ofp.OfpGroupDesc{Type: mod.Type, GroupId: mod.GroupId, Buckets: mod.Buckets}
+	group.Stats = &ofp.OfpGroupStats{GroupId: mod.GroupId}
+	//TODO do we need to instantiate bucket bins?
+	return group
+}
+
+func MkOxmFields(matchFields []ofp.OfpOxmField) []*ofp.OfpOxmField {
+	oxmFields := make([]*ofp.OfpOxmField, 0)
+	for _, matchField := range matchFields {
+		oxmField := ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: matchField.Field}
+		oxmFields = append(oxmFields, &oxmField)
+	}
+	return oxmFields
+}
+
+func MkInstructionsFromActions(actions []*ofp.OfpAction) []*ofp.OfpInstruction {
+	instructions := make([]*ofp.OfpInstruction, 0)
+	instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: actions}}
+	instruction := ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction}
+	instructions = append(instructions, &instruction)
+	return instructions
+}
+
+// Convenience function to generare ofp_flow_mod message with OXM BASIC match composed from the match_fields, and
+// single APPLY_ACTIONS instruction with a list if ofp_action objects.
+func MkSimpleFlowMod(matchFields []*ofp.OfpOxmField, actions []*ofp.OfpAction, command *ofp.OfpFlowModCommand, kw OfpFlowModArgs) *ofp.OfpFlowMod {
+
+	// Process actions instructions
+	instructions := make([]*ofp.OfpInstruction, 0)
+	instructionAction := ofp.OfpInstruction_Actions{Actions: &ofp.OfpInstructionActions{Actions: actions}}
+	instruction := ofp.OfpInstruction{Type: uint32(APPLY_ACTIONS), Data: &instructionAction}
+	instructions = append(instructions, &instruction)
+
+	// Process next table
+	if tableId := GetNextTableId(kw); tableId != nil {
+		var instGotoTable ofp.OfpInstruction_GotoTable
+		instGotoTable.GotoTable = &ofp.OfpInstructionGotoTable{TableId: *tableId}
+		inst := ofp.OfpInstruction{Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE), Data: &instGotoTable}
+		instructions = append(instructions, &inst)
+	}
+
+	// Process match fields
+	oxmFields := make([]*ofp.OfpOxmField, 0)
+	for _, matchField := range matchFields {
+		oxmField := ofp.OfpOxmField{OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC, Field: matchField.Field}
+		oxmFields = append(oxmFields, &oxmField)
+	}
+	var match ofp.OfpMatch
+	match.Type = ofp.OfpMatchType_OFPMT_OXM
+	match.OxmFields = oxmFields
+
+	// Create ofp_flow_message
+	msg := &ofp.OfpFlowMod{}
+	if command == nil {
+		msg.Command = ofp.OfpFlowModCommand_OFPFC_ADD
+	} else {
+		msg.Command = *command
+	}
+	msg.Instructions = instructions
+	msg.Match = &match
+
+	// Set the variadic argument values
+	msg = setVariadicModAttributes(msg, kw)
+
+	return msg
+}
+
+func MkMulticastGroupMod(groupId uint32, buckets []*ofp.OfpBucket, command *ofp.OfpGroupModCommand) *ofp.OfpGroupMod {
+	group := &ofp.OfpGroupMod{}
+	if command == nil {
+		group.Command = ofp.OfpGroupModCommand_OFPGC_ADD
+	} else {
+		group.Command = *command
+	}
+	group.Type = ofp.OfpGroupType_OFPGT_ALL
+	group.GroupId = groupId
+	group.Buckets = buckets
+	return group
+}
+
+//SetVariadicModAttributes sets only uint64 or uint32 fields of the ofp_flow_mod message
+func setVariadicModAttributes(mod *ofp.OfpFlowMod, args OfpFlowModArgs) *ofp.OfpFlowMod {
+	if args == nil {
+		return mod
+	}
+	for key, val := range args {
+		switch key {
+		case "cookie":
+			mod.Cookie = val
+		case "cookie_mask":
+			mod.CookieMask = val
+		case "table_id":
+			mod.TableId = uint32(val)
+		case "idle_timeout":
+			mod.IdleTimeout = uint32(val)
+		case "hard_timeout":
+			mod.HardTimeout = uint32(val)
+		case "priority":
+			mod.Priority = uint32(val)
+		case "buffer_id":
+			mod.BufferId = uint32(val)
+		case "out_port":
+			mod.OutPort = uint32(val)
+		case "out_group":
+			mod.OutGroup = uint32(val)
+		case "flags":
+			mod.Flags = uint32(val)
+		}
+	}
+	return mod
+}
+
+func MkPacketIn(port uint32, packet []byte) *ofp.OfpPacketIn {
+	packetIn := &ofp.OfpPacketIn{
+		Reason: ofp.OfpPacketInReason_OFPR_ACTION,
+		Match: &ofp.OfpMatch{
+			Type: ofp.OfpMatchType_OFPMT_OXM,
+			OxmFields: []*ofp.OfpOxmField{
+				{
+					OxmClass: ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC,
+					Field: &ofp.OfpOxmField_OfbField{
+						OfbField: InPort(port)},
+				},
+			},
+		},
+		Data: packet,
+	}
+	return packetIn
+}
+
+// MkFlowStat is a helper method to build flows
+func MkFlowStat(fa *FlowArgs) *ofp.OfpFlowStats {
+	//Build the matchfields
+	matchFields := make([]*ofp.OfpOxmField, 0)
+	for _, val := range fa.MatchFields {
+		matchFields = append(matchFields, &ofp.OfpOxmField{Field: &ofp.OfpOxmField_OfbField{OfbField: val}})
+	}
+	return FlowStatsEntryFromFlowModMessage(MkSimpleFlowMod(matchFields, fa.Actions, fa.Command, fa.KV))
+}
+
+func MkGroupStat(ga *GroupArgs) *ofp.OfpGroupEntry {
+	return GroupEntryFromGroupMod(MkMulticastGroupMod(ga.GroupId, ga.Buckets, ga.Command))
+}
+
 type OfpFlowModArgs map[string]uint64
 
 type FlowArgs struct {
@@ -127,6 +861,10 @@
 }
 
 func (fg *FlowsAndGroups) AddFlow(flow *ofp.OfpFlowStats) {
+	if flow == nil {
+		return
+	}
+
 	if fg.Flows == nil {
 		fg.Flows = ordered_map.NewOrderedMap()
 	}
@@ -139,6 +877,23 @@
 	}
 }
 
+func (fg *FlowsAndGroups) AddGroup(group *ofp.OfpGroupEntry) {
+	if group == nil {
+		return
+	}
+
+	if fg.Flows == nil {
+		fg.Flows = ordered_map.NewOrderedMap()
+	}
+	if fg.Groups == nil {
+		fg.Groups = ordered_map.NewOrderedMap()
+	}
+	//Add group only if absent
+	if _, exist := fg.Groups.Get(group.Desc.GroupId); !exist {
+		fg.Groups.Set(group.Desc.GroupId, group)
+	}
+}
+
 //AddFrom add flows and groups from the argument into this structure only if they do not already exist
 func (fg *FlowsAndGroups) AddFrom(from *FlowsAndGroups) {
 	iter := from.Flows.IterFunc()
@@ -266,6 +1021,9 @@
 //FlowMatch returns true if two flows matches on the following flow attributes:
 //TableId, Priority, Flags, Cookie, Match
 func FlowMatch(f1 *ofp.OfpFlowStats, f2 *ofp.OfpFlowStats) bool {
+	if f1 == nil || f2 == nil {
+		return false
+	}
 	keysMatter := []string{"TableId", "Priority", "Flags", "Cookie", "Match"}
 	for _, key := range keysMatter {
 		switch key {
@@ -297,6 +1055,9 @@
 //FlowMatchesMod returns True if given flow is "covered" by the wildcard flow_mod, taking into consideration of
 //both exact matches as well as masks-based match fields if any. Otherwise return False
 func FlowMatchesMod(flow *ofp.OfpFlowStats, mod *ofp.OfpFlowMod) bool {
+	if flow == nil || mod == nil {
+		return false
+	}
 	//Check if flow.cookie is covered by mod.cookie and mod.cookie_mask
 	if (flow.Cookie & mod.CookieMask) != (mod.Cookie & mod.CookieMask) {
 		return false
@@ -331,6 +1092,9 @@
 
 //FlowHasOutPort returns True if flow has a output command with the given out_port
 func FlowHasOutPort(flow *ofp.OfpFlowStats, outPort uint32) bool {
+	if flow == nil {
+		return false
+	}
 	for _, instruction := range flow.Instructions {
 		if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
 			if instruction.GetActions() == nil {
@@ -351,6 +1115,9 @@
 
 //FlowHasOutGroup return True if flow has a output command with the given out_group
 func FlowHasOutGroup(flow *ofp.OfpFlowStats, groupID uint32) bool {
+	if flow == nil {
+		return false
+	}
 	for _, instruction := range flow.Instructions {
 		if instruction.Type == uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
 			if instruction.GetActions() == nil {
