VOL-1552 - inital stub
remove extra file

Change-Id: I9f5c93eefbde51c64a7c1b13244eca3a16de8a41
diff --git a/Gopkg.lock b/Gopkg.lock
index 42709c8..ddf7aad 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -27,6 +27,14 @@
 
 [[projects]]
   branch = "master"
+  digest = "1:c16f511247fb7dd5b3e8428bed24b9f74473f343b3fb7c14763b47f567feb8a5"
+  name = "github.com/bclicn/color"
+  packages = ["."]
+  pruneopts = "UT"
+  revision = "108f2023dc84f1f9e64f246fa3997993971b2706"
+
+[[projects]]
+  branch = "master"
   digest = "1:0b0303f763128c8e8092843b9d85fdf03bb5bfa4145f1ebe77c12e835a871dc2"
   name = "github.com/boljen/go-bitmap"
   packages = ["."]
@@ -745,6 +753,7 @@
   analyzer-name = "dep"
   analyzer-version = 1
   input-imports = [
+    "github.com/bclicn/color",
     "github.com/boljen/go-bitmap",
     "github.com/bsm/sarama-cluster",
     "github.com/cevaris/ordered_map",
diff --git a/cli/main.go b/cli/main.go
new file mode 100644
index 0000000..a20fbf4
--- /dev/null
+++ b/cli/main.go
@@ -0,0 +1,63 @@
+/*
+   * 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 main
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"os/exec"
+
+	"github.com/opencord/voltha-go/cli/menu/mainmenu"
+	"google.golang.org/grpc"
+)
+
+func main() {
+
+	// disable input buffering
+	exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
+	// do not display entered characters on the screen
+	exec.Command("stty", "-F", "/dev/tty", "-echo").Run()
+	printHeader()
+
+	volthaAddress := flag.String("voltha_address", "localhost:6161", "IP/Hostname:Port for Voltha Core")
+	h := flag.Bool("h", false, "Print help")
+	help := flag.Bool("help", false, "Print help")
+	flag.Parse()
+	if *h || *help {
+		fmt.Println("cli -h(elp) print this message")
+		fmt.Println("cli -voltha_address=$VOLTHA_ADDRESS:PORT default localhost:6161")
+		return
+	}
+	conn, err := grpc.Dial(*volthaAddress, grpc.WithInsecure())
+	if err != nil {
+		log.Fatalf("did not connect: %s", err)
+	}
+	defer conn.Close()
+	fmt.Println("Connecting to " + *volthaAddress)
+
+	mainmenu.MainLoop(conn)
+}
+func printHeader() {
+	header :=
+		`         _ _   _            ___ _    ___
+__ _____| | |_| |_  __ _   / __| |  |_ _|
+\ V / _ \ |  _| ' \/ _' | | (__| |__ | |
+ \_/\___/_|\__|_||_\__,_|  \___|____|___|
+`
+	fmt.Println(header)
+}
diff --git a/cli/menu/devicemenu/deviceMenu.go b/cli/menu/devicemenu/deviceMenu.go
new file mode 100644
index 0000000..a435f16
--- /dev/null
+++ b/cli/menu/devicemenu/deviceMenu.go
@@ -0,0 +1,84 @@
+/*
+   * 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 devicemenu
+
+import (
+	"fmt"
+
+	"github.com/bclicn/color"
+	"github.com/opencord/voltha-go/cli/util"
+	"google.golang.org/grpc"
+)
+
+/*
+Conn - the grpc connection to use for making calls to voltha core
+*/
+var (
+	Conn        *grpc.ClientConn
+	DeviceId    *string
+	InputPrompt *string
+	Commands    *[]string
+)
+
+/*
+MainLoop - the loop which processes commands at the main level
+*/
+func MainLoop(conn *grpc.ClientConn, deviceId string) {
+
+	DeviceId = &deviceId
+	inputPrompt := fmt.Sprint("(" + color.LightRed("device "+deviceId) + ") ")
+	InputPrompt = &inputPrompt
+	funcTable := make(map[string]func(bool))
+	//	inputPromptSize := len(inputPrompt)
+	Conn = conn
+	funcTable["quit"] = util.Exit
+	funcTable["exit"] = nil
+	funcTable["edit"] = doEdit
+	funcTable["history"] = doHistory
+	funcTable["img_dnld_request"] = doImgDnldRequest
+	funcTable["perf_config"] = doPerfConfig
+	funcTable["save"] = doSave
+	funcTable["eof"] = doEof
+	funcTable["images"] = doImages
+	funcTable["img_dnld_status"] = doImgDnldStatus
+	funcTable["ports"] = doPorts
+	funcTable["set"] = doSet
+	funcTable["img_activate"] = doImgActivate
+	funcTable["img_revert"] = doImgRevert
+	funcTable["py"] = doPy
+	funcTable["shell"] = doShell
+	funcTable["flows"] = doFlows
+	funcTable["img_dnld_canel"] = doImgDnldCancel
+	funcTable["list"] = doList
+	funcTable["shortcuts"] = doShortCuts
+	funcTable["help"] = doHelp
+	funcTable["img_dnld_list"] = doImgDnldList
+	funcTable["pause"] = doPause
+	funcTable["run"] = doRun
+	funcTable["show"] = doShow
+
+	commands := make([]string, len(funcTable))
+	i := 0
+	for key, _ := range funcTable {
+		commands[i] = key
+		i++
+	}
+	Commands = &commands
+
+	util.ProcessTable(funcTable, inputPrompt)
+
+}
diff --git a/cli/menu/devicemenu/edit.go b/cli/menu/devicemenu/edit.go
new file mode 100644
index 0000000..c5c1e8e
--- /dev/null
+++ b/cli/menu/devicemenu/edit.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doEdit(enterPressed bool) {
+	fmt.Println("doEdit")
+}
diff --git a/cli/menu/devicemenu/eof.go b/cli/menu/devicemenu/eof.go
new file mode 100644
index 0000000..4d752fb
--- /dev/null
+++ b/cli/menu/devicemenu/eof.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doEof(enterPressed bool) {
+	fmt.Println("doEof")
+}
diff --git a/cli/menu/devicemenu/flows.go b/cli/menu/devicemenu/flows.go
new file mode 100644
index 0000000..9a648b2
--- /dev/null
+++ b/cli/menu/devicemenu/flows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doFlows(enterPressed bool) {
+	fmt.Println("doFlows")
+}
diff --git a/cli/menu/devicemenu/help.go b/cli/menu/devicemenu/help.go
new file mode 100644
index 0000000..340817d
--- /dev/null
+++ b/cli/menu/devicemenu/help.go
@@ -0,0 +1,96 @@
+/*
+   * 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 devicemenu
+
+import (
+	"fmt"
+	"os"
+	"strings"
+
+	"github.com/opencord/voltha-go/cli/util"
+)
+
+func doHelp(enterPressed bool) {
+	input := ""
+	var b = make([]byte, 1)
+	inputPrompt := *InputPrompt + "help "
+	for {
+		os.Stdin.Read(b)
+		char := string(b)
+		if char == "\t" || char == "\n" || char == "?" {
+			if enterPressed {
+				baseHelp()
+				return
+			}
+
+			fmt.Println("")
+			ret, prompt := util.Test(input, *Commands)
+			if len(ret) == 1 {
+				input = ret[0]
+				if input == "quit" {
+					util.Exit(true)
+				} else if input == "exit" {
+					return
+				}
+
+				MainLoop(Conn, input)
+				return
+			} else if len(ret) == 0 {
+				input = ""
+				fmt.Print("Invalid Input \n" + inputPrompt)
+			} else {
+
+				fmt.Println(ret)
+				input = prompt
+				fmt.Print(prompt + inputPrompt)
+			}
+		} else if b[0] == 127 || char == "\b" {
+
+			sz := len(input)
+			if sz > 0 {
+				fmt.Print("\b \b")
+				input = input[:sz-1]
+			}
+			if !(strings.HasPrefix(input, "device")) {
+				return
+			}
+		} else {
+			fmt.Print(char)
+			input += char
+		}
+	}
+}
+func baseHelp() {
+	message := `
+Documented commands (type help <topic>):
+========================================
+edit   help          img_dnld_cancel   img_revert   ports  set
+eof    history       img_dnld_list     list         py     shell
+exit   images        img_dnld_request  pause        run    shortcuts
+flows  img_activate  img_dnld_status   perf_config  save   show
+
+Miscellaneous help topics:
+==========================
+load
+
+Undocumented commands:
+======================
+quit
+
+`
+	fmt.Println(message)
+}
diff --git a/cli/menu/devicemenu/history.go b/cli/menu/devicemenu/history.go
new file mode 100644
index 0000000..b4d2423
--- /dev/null
+++ b/cli/menu/devicemenu/history.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doHistory(enterPressed bool) {
+	fmt.Println("doHistory")
+}
diff --git a/cli/menu/devicemenu/images.go b/cli/menu/devicemenu/images.go
new file mode 100644
index 0000000..dc2105e
--- /dev/null
+++ b/cli/menu/devicemenu/images.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImages(enterPressed bool) {
+	fmt.Println("doImages")
+}
diff --git a/cli/menu/devicemenu/img_activate.go b/cli/menu/devicemenu/img_activate.go
new file mode 100644
index 0000000..b615c1b
--- /dev/null
+++ b/cli/menu/devicemenu/img_activate.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgActivate(enterPressed bool) {
+	fmt.Println("doImgActivate")
+}
diff --git a/cli/menu/devicemenu/img_dnld_cancel.go b/cli/menu/devicemenu/img_dnld_cancel.go
new file mode 100644
index 0000000..cc9881d
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_cancel.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldCancel(enterPressed bool) {
+	fmt.Println("doImgDnldCancel")
+}
diff --git a/cli/menu/devicemenu/img_dnld_list.go b/cli/menu/devicemenu/img_dnld_list.go
new file mode 100644
index 0000000..ea6d31f
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_list.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldList(enterPressed bool) {
+	fmt.Println("doImgDnldList")
+}
diff --git a/cli/menu/devicemenu/img_dnld_request.go b/cli/menu/devicemenu/img_dnld_request.go
new file mode 100644
index 0000000..1a0ee98
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_request.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldRequest(enterPressed bool) {
+	fmt.Println("doImgDnldRequest")
+}
diff --git a/cli/menu/devicemenu/img_dnld_status.go b/cli/menu/devicemenu/img_dnld_status.go
new file mode 100644
index 0000000..2177996
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_status.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldStatus(enterPressed bool) {
+	fmt.Println("doImgDnldStatus")
+}
diff --git a/cli/menu/devicemenu/img_revert.go b/cli/menu/devicemenu/img_revert.go
new file mode 100644
index 0000000..bac7b37
--- /dev/null
+++ b/cli/menu/devicemenu/img_revert.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgRevert(enterPressed bool) {
+	fmt.Println("doImgRevert")
+}
diff --git a/cli/menu/devicemenu/list.go b/cli/menu/devicemenu/list.go
new file mode 100644
index 0000000..053fec9
--- /dev/null
+++ b/cli/menu/devicemenu/list.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doList(enterPressed bool) {
+	fmt.Println("doList")
+}
diff --git a/cli/menu/devicemenu/pause.go b/cli/menu/devicemenu/pause.go
new file mode 100644
index 0000000..6fec137
--- /dev/null
+++ b/cli/menu/devicemenu/pause.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPause(enterPressed bool) {
+	fmt.Println("doPause")
+}
diff --git a/cli/menu/devicemenu/perf_config.go b/cli/menu/devicemenu/perf_config.go
new file mode 100644
index 0000000..bdc9ab4
--- /dev/null
+++ b/cli/menu/devicemenu/perf_config.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPerfConfig(enterPressed bool) {
+	fmt.Println("doPrefConfig")
+}
diff --git a/cli/menu/devicemenu/ports.go b/cli/menu/devicemenu/ports.go
new file mode 100644
index 0000000..4b1aefb
--- /dev/null
+++ b/cli/menu/devicemenu/ports.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPorts(enterPressed bool) {
+	fmt.Println("doPorts")
+}
diff --git a/cli/menu/devicemenu/py.go b/cli/menu/devicemenu/py.go
new file mode 100644
index 0000000..8a489fd
--- /dev/null
+++ b/cli/menu/devicemenu/py.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPy(enterPressed bool) {
+	fmt.Println("doPy")
+}
diff --git a/cli/menu/devicemenu/run.go b/cli/menu/devicemenu/run.go
new file mode 100644
index 0000000..081fddb
--- /dev/null
+++ b/cli/menu/devicemenu/run.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doRun(enterPressed bool) {
+	fmt.Println("doRun")
+}
diff --git a/cli/menu/devicemenu/save.go b/cli/menu/devicemenu/save.go
new file mode 100644
index 0000000..ba4ef89
--- /dev/null
+++ b/cli/menu/devicemenu/save.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doSave(enterPressed bool) {
+	fmt.Println("doSave")
+}
diff --git a/cli/menu/devicemenu/set.go b/cli/menu/devicemenu/set.go
new file mode 100644
index 0000000..c8d8a15
--- /dev/null
+++ b/cli/menu/devicemenu/set.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doSet(enterPressed bool) {
+	fmt.Println("doSet")
+}
diff --git a/cli/menu/devicemenu/shell.go b/cli/menu/devicemenu/shell.go
new file mode 100644
index 0000000..cffbcbd
--- /dev/null
+++ b/cli/menu/devicemenu/shell.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doShell(enterPressed bool) {
+	fmt.Println("doShell")
+}
diff --git a/cli/menu/devicemenu/shortcuts.go b/cli/menu/devicemenu/shortcuts.go
new file mode 100644
index 0000000..14596d0
--- /dev/null
+++ b/cli/menu/devicemenu/shortcuts.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doShortCuts(enterPressed bool) {
+	fmt.Println("doShortCuts")
+}
diff --git a/cli/menu/devicemenu/show.go b/cli/menu/devicemenu/show.go
new file mode 100644
index 0000000..b9e22bd
--- /dev/null
+++ b/cli/menu/devicemenu/show.go
@@ -0,0 +1,88 @@
+/*
+   * 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 devicemenu
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	"github.com/opencord/voltha-go/cli/util"
+	"github.com/opencord/voltha-protos/go/common"
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+func doShow(enterPressed bool) {
+	client := voltha.NewVolthaServiceClient(Conn)
+	fmt.Println(*DeviceId)
+	device, err := client.GetDevice(context.Background(), &common.ID{Id: *DeviceId})
+	if err != nil {
+		fmt.Println(err)
+	}
+	fields := []string{"field", "value"}
+	var rows []map[string]string
+
+	id := make(map[string]string)
+	id["field"] = "id"
+	id["value"] = device.Id
+	rows = append(rows, id)
+
+	Type := make(map[string]string)
+	Type["field"] = "type"
+	Type["value"] = device.Type
+	rows = append(rows, Type)
+
+	parentId := make(map[string]string)
+	parentId["field"] = "parent_id"
+	parentId["value"] = device.ParentId
+	rows = append(rows, parentId)
+
+	vlan := make(map[string]string)
+	vlan["field"] = "vlan"
+	vlan["value"] = strconv.FormatUint(uint64(device.Vlan), 10)
+	rows = append(rows, vlan)
+
+	adminState := make(map[string]string)
+	adminState["field"] = "admin_state"
+	adminState["value"] = strconv.FormatUint(uint64(device.AdminState), 10)
+	rows = append(rows, adminState)
+
+	proxyAddress := device.GetProxyAddress()
+	proxyDeviceId := make(map[string]string)
+	proxyDeviceId["field"] = "proxy_address.device_id"
+	proxyDeviceId["value"] = proxyAddress.DeviceId
+	rows = append(rows, proxyDeviceId)
+
+	proxyDeviceType := make(map[string]string)
+	proxyDeviceType["field"] = "proxy_address.device_type"
+	proxyDeviceType["value"] = proxyAddress.DeviceType
+	rows = append(rows, proxyDeviceType)
+
+	proxyChannelId := make(map[string]string)
+	proxyChannelId["field"] = "proxy_address.channel_id"
+	proxyChannelId["value"] = strconv.FormatUint(uint64(proxyAddress.ChannelId), 10)
+	rows = append(rows, proxyChannelId)
+
+	parentPortNumber := make(map[string]string)
+	parentPortNumber["field"] = "parent_port_no"
+	parentPortNumber["value"] = strconv.FormatUint(uint64(device.GetParentPortNo()), 10)
+	rows = append(rows, parentPortNumber)
+
+	output, _ := util.BuildTable(fields, rows)
+
+	fmt.Println(output)
+}
diff --git a/cli/menu/mainmenu/Makefile b/cli/menu/mainmenu/Makefile
new file mode 100644
index 0000000..fd522a5
--- /dev/null
+++ b/cli/menu/mainmenu/Makefile
@@ -0,0 +1,13 @@
+VOLTHA_PROTO_PATH := protos/voltha_protos
+VOLTHA_PROTO_FILES := $(wildcard protos/voltha_protos/*.proto)
+VOLTHA_PROTO_GO_FILES := $(foreach f,$(VOLTHA_PROTO_FILES),$(subst .proto,.pb.go,$(f)))
+VOLTHA_PROTO_DESC_FILES := $(foreach f,$(VOLTHA_PROTO_FILES),$(subst .proto,.desc,$(f)))
+
+voltha-api: $(VOLTHA_PROTO_GO_FILES)
+
+%.pb.go: %.proto
+	@protoc -I ${VOLTHA_PROTO_PATH} \
+                --go_out=plugins=grpc:${VOLTHA_PROTO_PATH} \
+                -I${GOPATH}/src \
+                -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
+                $<
diff --git a/cli/menu/mainmenu/alarmFilters.go b/cli/menu/mainmenu/alarmFilters.go
new file mode 100644
index 0000000..4a1b274
--- /dev/null
+++ b/cli/menu/mainmenu/alarmFilters.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doAlarmFilters(enterPressed bool) {
+	fmt.Print("input: alarm_filters>")
+}
diff --git a/cli/menu/mainmenu/arriveOnus.go b/cli/menu/mainmenu/arriveOnus.go
new file mode 100644
index 0000000..75e6263
--- /dev/null
+++ b/cli/menu/mainmenu/arriveOnus.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doArriveOnus(enterPressed bool) {
+	fmt.Print("input: arrive_onus>")
+}
diff --git a/cli/menu/mainmenu/cmdEnvironment.go b/cli/menu/mainmenu/cmdEnvironment.go
new file mode 100644
index 0000000..0342e87
--- /dev/null
+++ b/cli/menu/mainmenu/cmdEnvironment.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doCmdEnvironment(enterPressed bool) {
+	fmt.Println("input: doCmdEnvironment> ")
+}
diff --git a/cli/menu/mainmenu/delete.go b/cli/menu/mainmenu/delete.go
new file mode 100644
index 0000000..9b9f49b
--- /dev/null
+++ b/cli/menu/mainmenu/delete.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doDelete(enterPressed bool) {
+	fmt.Println("input: delete > ")
+}
diff --git a/cli/menu/mainmenu/deleteAllFlows.go b/cli/menu/mainmenu/deleteAllFlows.go
new file mode 100644
index 0000000..9888fa9
--- /dev/null
+++ b/cli/menu/mainmenu/deleteAllFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doDeleteAllFlows(enterPressed bool) {
+	fmt.Print("input: delete_all_flows>")
+}
diff --git a/cli/menu/mainmenu/device.go b/cli/menu/mainmenu/device.go
new file mode 100644
index 0000000..45b35a9
--- /dev/null
+++ b/cli/menu/mainmenu/device.go
@@ -0,0 +1,87 @@
+/*
+   * 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 mainmenu
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"strings"
+
+	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/opencord/voltha-go/cli/menu/devicemenu"
+	"github.com/opencord/voltha-go/cli/util"
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+func doDevice(enterPressed bool) {
+	fmt.Print(" ")
+	client := voltha.NewVolthaServiceClient(Conn)
+	devices, err := client.ListDevices(context.Background(), &empty.Empty{})
+	items := devices.GetItems()
+	if err != nil {
+		fmt.Println(err)
+	}
+	deviceIds := []string{"exit", "quit"}
+	for i := 0; i < len(items); i++ {
+		deviceIds = append(deviceIds, items[i].Id)
+	}
+	var b = make([]byte, 1)
+	input := ""
+
+	for {
+		os.Stdin.Read(b)
+		char := string(b)
+		if char == "\t" || char == "\n" || char == "?" {
+			fmt.Println("")
+			ret, prompt := util.Test(input, deviceIds)
+			if len(ret) == 1 {
+				input = ret[0]
+				if input == "quit" {
+					util.Exit(true)
+				} else if input == "exit" {
+					return
+				}
+
+				devicemenu.MainLoop(Conn, input)
+				return
+			} else if len(ret) == 0 {
+				input = ""
+				fmt.Print("Invalid Input \ninput:")
+			} else {
+
+				fmt.Println(ret)
+				input = prompt
+				fmt.Print("input: " + prompt)
+			}
+		} else if b[0] == 127 || char == "\b" {
+
+			sz := len(input)
+			if sz > 0 {
+				fmt.Print("\b \b")
+				input = input[:sz-1]
+			}
+			if !(strings.HasPrefix(input, "device")) {
+				return
+			}
+		} else {
+			fmt.Print(char)
+			input += char
+		}
+	}
+
+}
diff --git a/cli/menu/mainmenu/devices.go b/cli/menu/mainmenu/devices.go
new file mode 100644
index 0000000..f5ef716
--- /dev/null
+++ b/cli/menu/mainmenu/devices.go
@@ -0,0 +1,78 @@
+/*
+   * 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 mainmenu
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/opencord/voltha-go/cli/util"
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+/*
+ reason | proxy_address.device_id | proxy_address.onu_id | proxy_address.onu_session_id |
+*/
+func doDevices(enterPressed bool) {
+
+	client := voltha.NewVolthaServiceClient(Conn)
+	devices, err := client.ListDevices(context.Background(), &empty.Empty{})
+	if err != nil {
+		fmt.Println(err)
+	}
+	var rows []map[string]string
+	items := devices.GetItems()
+	var fields = []string{"id", "type", "root", "parent_id", "serial_number", "admin_state", "oper_status", "connect_status", "parent_port_no", "host_and_port", "reason",
+		"proxy_address.device_id", "proxy_address.onu_id", "proxy_address.onu_session_id"}
+
+	for i := 0; i < len(items); i++ {
+		//fmt.Println(items[i])
+		device := items[i]
+		row := make(map[string]string)
+		row["id"] = device.Id
+		row["type"] = device.Type
+		row["root"] = strconv.FormatBool(device.Root)
+		row["parent_id"] = device.ParentId
+		row["serial_number"] = device.SerialNumber
+		row["admin_state"] = device.AdminState.String()
+		row["oper_status"] = device.OperStatus.String()
+		row["connect_status"] = device.ConnectStatus.String()
+		row["parent_port_no"] = strconv.FormatUint(uint64(device.GetParentPortNo()), 10)
+		row["host_and_port"] = device.GetHostAndPort()
+		row["reason"] = device.Reason
+		proxyAddress := device.GetProxyAddress()
+		if proxyAddress != nil {
+			row["proxy_address.device_id"] = proxyAddress.DeviceId
+			row["proxy_address.onu_id"] = strconv.FormatUint(uint64(proxyAddress.OnuId), 10)
+			row["proxy_address.onu_session_id"] = strconv.FormatUint(uint64(proxyAddress.OnuSessionId), 10)
+		} else {
+			row["proxy_address.device_id"] = ""
+			row["proxy_address.onu_id"] = ""
+			row["proxy_address.onu_session_id"] = ""
+		}
+
+		rows = append(rows, row)
+	}
+	output, err := util.BuildTable(fields, rows)
+	if err != nil {
+		fmt.Println(err)
+	}
+	fmt.Print(output)
+
+}
diff --git a/cli/menu/mainmenu/disable.go b/cli/menu/mainmenu/disable.go
new file mode 100644
index 0000000..45d86af
--- /dev/null
+++ b/cli/menu/mainmenu/disable.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doDisable(enterPressed bool) {
+	fmt.Print("input: disable>")
+}
diff --git a/cli/menu/mainmenu/enable.go b/cli/menu/mainmenu/enable.go
new file mode 100644
index 0000000..3068c72
--- /dev/null
+++ b/cli/menu/mainmenu/enable.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doEnable(enterPressed bool) {
+	fmt.Print("input: enable>")
+}
diff --git a/cli/menu/mainmenu/health.go b/cli/menu/mainmenu/health.go
new file mode 100644
index 0000000..562ff9b
--- /dev/null
+++ b/cli/menu/mainmenu/health.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doHealth(enterPressed bool) {
+	fmt.Print("input: health>")
+}
diff --git a/cli/menu/mainmenu/injectEapolStart.go b/cli/menu/mainmenu/injectEapolStart.go
new file mode 100644
index 0000000..8015013
--- /dev/null
+++ b/cli/menu/mainmenu/injectEapolStart.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInjectEapolStart(enterPressed bool) {
+	fmt.Print("input: inject_eapol_start>")
+}
diff --git a/cli/menu/mainmenu/installAllControllerBoundFlows.go b/cli/menu/mainmenu/installAllControllerBoundFlows.go
new file mode 100644
index 0000000..c994831
--- /dev/null
+++ b/cli/menu/mainmenu/installAllControllerBoundFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallAllControllerBoundFlows(enterPressed bool) {
+	fmt.Print("input: install_all_controller_bound_flows>")
+}
diff --git a/cli/menu/mainmenu/installAllSampleFlows.go b/cli/menu/mainmenu/installAllSampleFlows.go
new file mode 100644
index 0000000..a9d08e4
--- /dev/null
+++ b/cli/menu/mainmenu/installAllSampleFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallAllSampleFlows(enterPressed bool) {
+	fmt.Print("input: install_all_sample_flows>")
+}
diff --git a/cli/menu/mainmenu/installDhcpFlows.go b/cli/menu/mainmenu/installDhcpFlows.go
new file mode 100644
index 0000000..799867d
--- /dev/null
+++ b/cli/menu/mainmenu/installDhcpFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallDhcpFlows(enterPressed bool) {
+	fmt.Print("input: install_dhcp_flows>")
+}
diff --git a/cli/menu/mainmenu/installEapolFlow.go b/cli/menu/mainmenu/installEapolFlow.go
new file mode 100644
index 0000000..2a76bae
--- /dev/null
+++ b/cli/menu/mainmenu/installEapolFlow.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallEapolFlow(enterPressed bool) {
+	fmt.Print("input: install_eapol_flow>")
+}
diff --git a/cli/menu/mainmenu/launch.go b/cli/menu/mainmenu/launch.go
new file mode 100644
index 0000000..818e5a4
--- /dev/null
+++ b/cli/menu/mainmenu/launch.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLaunch(enterPressed bool) {
+	fmt.Print("input: launch")
+}
diff --git a/cli/menu/mainmenu/load.go b/cli/menu/mainmenu/load.go
new file mode 100644
index 0000000..20fd7c7
--- /dev/null
+++ b/cli/menu/mainmenu/load.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLoad(enterPressed bool) {
+	fmt.Println("input: load>")
+}
diff --git a/cli/menu/mainmenu/log.go b/cli/menu/mainmenu/log.go
new file mode 100644
index 0000000..d94c4cf
--- /dev/null
+++ b/cli/menu/mainmenu/log.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLog(enterPressed bool) {
+	fmt.Print("input: log>")
+}
diff --git a/cli/menu/mainmenu/logicalDevice.go b/cli/menu/mainmenu/logicalDevice.go
new file mode 100644
index 0000000..9e306ec
--- /dev/null
+++ b/cli/menu/mainmenu/logicalDevice.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLogicalDevice(enterPressed bool) {
+	fmt.Print("input: logical_device>")
+}
diff --git a/cli/menu/mainmenu/logicalDevices.go b/cli/menu/mainmenu/logicalDevices.go
new file mode 100644
index 0000000..5d6f2fc
--- /dev/null
+++ b/cli/menu/mainmenu/logicalDevices.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLogicalDevices(enterPressed bool) {
+	fmt.Print("input: logical_devices>")
+}
diff --git a/cli/menu/mainmenu/mainMenu.go b/cli/menu/mainmenu/mainMenu.go
new file mode 100644
index 0000000..3d57892
--- /dev/null
+++ b/cli/menu/mainmenu/mainMenu.go
@@ -0,0 +1,75 @@
+/*
+   * 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 mainmenu
+
+import (
+	"fmt"
+
+	"github.com/bclicn/color"
+	"github.com/opencord/voltha-go/cli/util"
+	"google.golang.org/grpc"
+)
+
+/*
+Conn - the grpc connection to use for making calls to voltha core
+*/
+var Conn *grpc.ClientConn
+
+/*
+MainLoop - the loop which processes commands at the main level
+*/
+func MainLoop(conn *grpc.ClientConn) {
+
+	inputPrompt := fmt.Sprint("(" + color.LightBlue("voltha") + ") ")
+	//	inputPromptSize := len(inputPrompt)
+	Conn = conn
+	mainFuncTable := make(map[string]func(bool))
+	mainFuncTable["quit"] = util.Exit
+	mainFuncTable["exit"] = nil
+	mainFuncTable["cmdenvironment"] = doCmdEnvironment
+	mainFuncTable["load"] = doLoad
+	mainFuncTable["relative_load"] = doRelativeLoad
+	mainFuncTable["reset_history"] = doResetHistory
+	mainFuncTable["log"] = doLog
+	mainFuncTable["launch"] = doLaunch
+	mainFuncTable["restart"] = doRestart
+	mainFuncTable["devices"] = doDevices
+	mainFuncTable["device"] = doDevice
+	mainFuncTable["logical_devices"] = doLogicalDevices
+	mainFuncTable["logical_device"] = doLogicalDevice
+	mainFuncTable["omci"] = doOmci
+	mainFuncTable["pdb"] = doPdb
+	mainFuncTable["version"] = doVersion
+	mainFuncTable["health"] = doHealth
+	mainFuncTable["preprovison_olt"] = doPreprovisionOlt
+	mainFuncTable["enable"] = doEnable
+	mainFuncTable["reboot"] = doReboot
+	mainFuncTable["self_test"] = doSelfTest
+	mainFuncTable["delete"] = doDelete
+	mainFuncTable["disable"] = doDisable
+	mainFuncTable["test"] = doTest
+	mainFuncTable["alarm_filters"] = doAlarmFilters
+	mainFuncTable["arrive_onus"] = doArriveOnus
+	mainFuncTable["install_eapol_flow"] = doInstallEapolFlow
+	mainFuncTable["install_all_controller_bound_flows"] = doInstallAllControllerBoundFlows
+	mainFuncTable["install_all_sample_flows"] = doInstallAllSampleFlows
+	mainFuncTable["install_dhcp_flows"] = doInstallDhcpFlows
+	mainFuncTable["delete_all_flows"] = doDeleteAllFlows
+	mainFuncTable["send_simulated_upstream_eapol"] = doSendSimulatedUpstreamEapol
+	mainFuncTable["inject_eapol_start"] = doInjectEapolStart
+	util.ProcessTable(mainFuncTable, inputPrompt)
+}
diff --git a/cli/menu/mainmenu/omci.go b/cli/menu/mainmenu/omci.go
new file mode 100644
index 0000000..98d3328
--- /dev/null
+++ b/cli/menu/mainmenu/omci.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doOmci(enterPressed bool) {
+	fmt.Print("input: ocmi>")
+}
diff --git a/cli/menu/mainmenu/pdb.go b/cli/menu/mainmenu/pdb.go
new file mode 100644
index 0000000..32b9035
--- /dev/null
+++ b/cli/menu/mainmenu/pdb.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doPdb(enterPressed bool) {
+	fmt.Print("input: pdb>")
+}
diff --git a/cli/menu/mainmenu/preprovisionOlt.go b/cli/menu/mainmenu/preprovisionOlt.go
new file mode 100644
index 0000000..f185b14
--- /dev/null
+++ b/cli/menu/mainmenu/preprovisionOlt.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doPreprovisionOlt(enterPressed bool) {
+	fmt.Print("input preprovision_olt>")
+}
diff --git a/cli/menu/mainmenu/reboot.go b/cli/menu/mainmenu/reboot.go
new file mode 100644
index 0000000..a0a4b12
--- /dev/null
+++ b/cli/menu/mainmenu/reboot.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doReboot(enterPressed bool) {
+	fmt.Print("input: reboot>")
+}
diff --git a/cli/menu/mainmenu/relativeLoad.go b/cli/menu/mainmenu/relativeLoad.go
new file mode 100644
index 0000000..ab492b4
--- /dev/null
+++ b/cli/menu/mainmenu/relativeLoad.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doRelativeLoad(enterPressed bool) {
+	fmt.Print("input: relative_load>")
+}
diff --git a/cli/menu/mainmenu/resetHistory.go b/cli/menu/mainmenu/resetHistory.go
new file mode 100644
index 0000000..61187a5
--- /dev/null
+++ b/cli/menu/mainmenu/resetHistory.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doResetHistory(enterPressed bool) {
+	fmt.Print("input: reset_history>")
+}
diff --git a/cli/menu/mainmenu/restart.go b/cli/menu/mainmenu/restart.go
new file mode 100644
index 0000000..62ce7e1
--- /dev/null
+++ b/cli/menu/mainmenu/restart.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doRestart(enterPressed bool) {
+	fmt.Print("input: restart>")
+}
diff --git a/cli/menu/mainmenu/selfTest.go b/cli/menu/mainmenu/selfTest.go
new file mode 100644
index 0000000..f25e6fb
--- /dev/null
+++ b/cli/menu/mainmenu/selfTest.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doSelfTest(enterPressed bool) {
+	fmt.Print("input: self_test>")
+}
diff --git a/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go b/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go
new file mode 100644
index 0000000..c82b0df
--- /dev/null
+++ b/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doSendSimulatedUpstreamEapol(enterPressed bool) {
+	fmt.Print("input: send_simulated_upstream_eapol>")
+}
diff --git a/cli/menu/mainmenu/test.go b/cli/menu/mainmenu/test.go
new file mode 100644
index 0000000..96e3f0a
--- /dev/null
+++ b/cli/menu/mainmenu/test.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doTest(enterPressed bool) {
+	fmt.Print("input: test>")
+}
diff --git a/cli/menu/mainmenu/version.go b/cli/menu/mainmenu/version.go
new file mode 100644
index 0000000..7464c1b
--- /dev/null
+++ b/cli/menu/mainmenu/version.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doVersion(enterPressed bool) {
+	fmt.Print("input: version>")
+}
diff --git a/cli/util/menuProcessor.go b/cli/util/menuProcessor.go
new file mode 100644
index 0000000..c9ba837
--- /dev/null
+++ b/cli/util/menuProcessor.go
@@ -0,0 +1,102 @@
+/*
+   * 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 util
+
+import (
+	"fmt"
+	"os"
+)
+
+/*
+ProcessTable parses table structure and executes functions
+*/
+func ProcessTable(functionTable map[string]func(bool), inputPrompt string) {
+	keys := []string{}
+	for k := range functionTable {
+		keys = append(keys, k)
+	}
+	var b = make([]byte, 1)
+	input := ""
+	fmt.Print(inputPrompt)
+	for {
+		os.Stdin.Read(b)
+		char := string(b)
+		if char == "\t" || char == "\n" || char == "?" {
+			fmt.Println("")
+			ret, prompt := Test(input, keys)
+			if len(ret) == 1 {
+				input = ret[0]
+				if input == "exit" {
+					return
+				}
+				if char == "\n" {
+					Route(input, functionTable, true)
+				} else {
+					Route(input, functionTable, false)
+				}
+				input = ""
+				fmt.Print(inputPrompt)
+			} else if len(ret) == 0 {
+				input = ""
+				fmt.Println("\nInvalid Input ")
+				fmt.Print(inputPrompt)
+			} else if len(ret) == 0 {
+			} else {
+
+				fmt.Println(ret)
+				input = prompt
+				fmt.Print(inputPrompt)
+				fmt.Print(prompt)
+			}
+		} else if char == " " {
+			_, ok := functionTable[input]
+			if ok {
+				Route(input, functionTable, false)
+				fmt.Print(inputPrompt)
+				input = ""
+			} else {
+				ret, prompt := Test(input, keys)
+				if len(ret) == 1 {
+					input = ret[0]
+					Route(input, functionTable, false)
+					input = ""
+					fmt.Print(inputPrompt)
+				} else if len(ret) == 0 {
+					input = ""
+					fmt.Println("\nInvalid Input ")
+					fmt.Print(inputPrompt)
+				} else {
+
+					fmt.Println(ret)
+					input = prompt
+					fmt.Print(inputPrompt + input)
+				}
+			}
+
+		} else if b[0] == 127 || char == "\b" {
+			sz := len(input)
+
+			if sz > 0 {
+				fmt.Print("\b \b")
+				input = input[:sz-1]
+			}
+		} else {
+			fmt.Print(char)
+			input += char
+		}
+	}
+}
diff --git a/cli/util/parseCmd.go b/cli/util/parseCmd.go
new file mode 100644
index 0000000..06ad8b8
--- /dev/null
+++ b/cli/util/parseCmd.go
@@ -0,0 +1,67 @@
+/*
+   * 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 util
+
+import (
+	"os"
+	"strings"
+)
+
+func Test(chars string, values []string) ([]string, string) {
+
+	var ret []string
+	for i := 0; i < len(values); i++ {
+		if strings.HasPrefix(values[i], chars) {
+			ret = append(ret, values[i])
+		}
+	}
+	if len(ret) == 0 {
+		return ret, ""
+	}
+	shortIndex := 0
+	if len(ret) > 1 {
+		for i := 0; i < len(ret); i++ {
+			if len(ret[i]) < len(ret[shortIndex]) {
+				shortIndex = i
+			}
+		}
+	}
+	for i := len(chars); i < len(ret[shortIndex]); i++ {
+		inAllWords := true
+		for j := 0; j < len(ret); j++ {
+			inAllWords = inAllWords && ret[j][i] == ret[shortIndex][i]
+		}
+		if inAllWords {
+			chars += string(ret[shortIndex][i])
+		} else {
+			return ret, chars
+		}
+
+	}
+
+	return ret, chars
+}
+
+func Route(command string, table map[string]func(bool), enterPressed bool) {
+	cmd := table[command]
+	cmd(enterPressed)
+
+}
+
+func Exit(notUsed bool) {
+	os.Exit(0)
+}
diff --git a/cli/util/tableGen.go b/cli/util/tableGen.go
new file mode 100644
index 0000000..3b07ef0
--- /dev/null
+++ b/cli/util/tableGen.go
@@ -0,0 +1,73 @@
+/*
+   * 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 util
+
+import (
+	"fmt"
+	"strings"
+)
+
+func BuildTable(keys []string, rows []map[string]string) (string, error) {
+	var returnString string
+	fieldSizes := make(map[string]int)
+
+	for i := 0; i < len(rows); i++ {
+		for key, value := range rows[i] {
+			currentSize := len(value)
+			if currentSize > fieldSizes[key] {
+				fieldSizes[key] = currentSize
+			}
+
+		}
+	}
+	for i := 0; i < len(keys); i++ {
+		currentSize := len(keys[i])
+		if currentSize > fieldSizes[keys[i]] {
+			fieldSizes[keys[i]] = currentSize
+		}
+	}
+	bottom := "+"
+
+	for i := 0; i < len(rows); i++ {
+		header := "|"
+		line := "|"
+		for j := 0; j < len(keys); j++ {
+			key := keys[j]
+			value := rows[i][key]
+			if i == 0 {
+				pad := 2 + fieldSizes[key] - len(key)
+				field := fmt.Sprintf("%s%s|", strings.Repeat(" ", pad), key)
+				spacer := fmt.Sprintf("%s+", strings.Repeat("-", fieldSizes[key]+2))
+				header = header + field
+				bottom = bottom + spacer
+			}
+			pad := 2 + fieldSizes[key] - len(value)
+			field := fmt.Sprintf("%s%s|", strings.Repeat(" ", pad), value)
+			line = line + field
+
+		}
+		if i == 0 {
+			returnString = bottom + "\n" + header + "\n" + bottom + "\n"
+		}
+
+		returnString = returnString + line + "\n"
+	}
+	returnString = returnString + bottom + "\n"
+
+	return returnString, nil
+
+}
diff --git a/vendor/github.com/bclicn/color/LICENSE b/vendor/github.com/bclicn/color/LICENSE
new file mode 100644
index 0000000..c22bc5f
--- /dev/null
+++ b/vendor/github.com/bclicn/color/LICENSE
@@ -0,0 +1,23 @@
+
+The MIT License (MIT)
+
+Copyright (c) 2016-2018 bcli
+
+
+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/bclicn/color/README.md b/vendor/github.com/bclicn/color/README.md
new file mode 100644
index 0000000..1065950
--- /dev/null
+++ b/vendor/github.com/bclicn/color/README.md
@@ -0,0 +1,43 @@
+# GoLang Colorized Output
+
+GoLang colorized output library for Mac & Linux Shell, [中文版说明](README_CN.md)
+
+## Showcase
+![img](showcase.jpg)
+
+## Install
+
+1. __Make sure__ your've read [GoLang Official File Structure](https://golang.org/doc/code.html)
+2. Make sure you've set a correct GOPATH
+3. `$ go get github.com/bclicn/color`
+4. In your script, `import "github.com/bclicn/color"` then call `color.Test()`
+5. Use `fmt.Println("Hello" + color.Red("World"))` to assemble a colorized output
+6. API examples available in `color-test.go`
+
+## Quick (brainless) Usage
+
+1. Download `color.go`
+2. Modify its `package color` to `package main`
+3. Put your script under the same directory and write `fmt.Println(Red("I'm red !!!"))`
+4. Run `go run color.go yourScript.go`
+5. Or build by `go build color.go yourScript.go`
+
+## A simple test script
+
+    package main
+
+    import (
+	    "fmt"
+	    "github.com/bclicn/color"
+    )
+
+    func main(){
+	    fmt.Println(color.Red("Red output"))
+	    color.Test()
+    }
+
+## License
+
+[MIT](LICENSE)
+
+bcli, 2018-7-11
diff --git a/vendor/github.com/bclicn/color/README_CN.md b/vendor/github.com/bclicn/color/README_CN.md
new file mode 100644
index 0000000..25b447e
--- /dev/null
+++ b/vendor/github.com/bclicn/color/README_CN.md
@@ -0,0 +1,43 @@
+# GoLang 彩色输出
+
+用于Mac和Linux Shell的GoLang彩色文字输出, [English Version](README.md)
+
+## 效果展示
+![img](showcase.jpg)
+
+## 安装
+
+1. __确保__你已经读过  [GoLang官方文件结构](https://golang.org/doc/code.html)
+2. 确保你的GOPATH环境变量正确
+3. `go get github.com/bclicn/color`
+3. 在你的脚本中,`import "github.com/bclicn/color"` 然后调用 `color.Test()`查看全部效果
+5. 使用`fmt.Println("Hello" + color.Red("World"))`进行彩色输出
+4. API调用示例在`color-test.go`
+
+## 快速(无脑)使用
+
+1. 下载`color.go`
+2. 将其第一行的`package color`改为`package main`
+3. 把你的脚本放在同一个文件夹下,直接调用如`fmt.Println(Red("I'm red !!!"))`
+4. 运行`go run color.go yourScript.go`
+5. 你也可以直接`go build color.go yourScript.go`
+
+## 快速调用示例
+
+    package main
+
+    import (
+	    "fmt"
+	    "github.com/bclicn/color"
+    )
+
+    func main(){
+	    fmt.Println(color.Red("Red output"))
+	    color.Test()
+    }
+
+##  License
+
+[MIT](LICENSE)
+
+bcli, 2018-7-11
diff --git a/vendor/github.com/bclicn/color/color-test.go b/vendor/github.com/bclicn/color/color-test.go
new file mode 100644
index 0000000..59e9b5b
--- /dev/null
+++ b/vendor/github.com/bclicn/color/color-test.go
@@ -0,0 +1,87 @@
+package color
+
+import (
+	"fmt"
+)
+
+// github.com/bclicn/color
+// colorized output for Mac & Linux terminal
+// version: 1.0.0
+// author:  bcli, bclicn@gmail.com, 2016-11-4
+// see:     http://misc.flogisoft.com/bash/tip_colors_and_formatting
+// usage:
+// For official code layout
+// 	$ go get github.com/bclicn/color
+// 	# in your project
+// 	import "github.com/bclicn/color"
+// 	func main() {
+//		color.Test()
+//	}
+
+func ColorTest() {
+
+	const HEAD = " "
+	const TAIL = " "
+
+	// regular
+	fmt.Println(HEAD + Black("black") + TAIL)
+	fmt.Println(HEAD + Red("red") + TAIL)
+	fmt.Println(HEAD + Green("green") + TAIL)
+	fmt.Println(HEAD + Yellow("yellow") + TAIL)
+	fmt.Println(HEAD + Blue("blue") + TAIL)
+	fmt.Println(HEAD + Purple("purple") + TAIL)
+	fmt.Println(HEAD + Cyan("cyan") + TAIL)
+	fmt.Println(HEAD + LightGray("light gray") + TAIL)
+	fmt.Println(HEAD + DarkGray("dark gray") + TAIL)
+	fmt.Println(HEAD + LightRed("light red") + TAIL)
+	fmt.Println(HEAD + LightGreen("light green") + TAIL)
+	fmt.Println(HEAD + LightYellow("light yellow") + TAIL)
+	fmt.Println(HEAD + LightBlue("light blue") + TAIL)
+	fmt.Println(HEAD + LightPurple("light purple") + TAIL)
+	fmt.Println(HEAD + LightCyan("light cyan") + TAIL)
+	fmt.Println(HEAD + White("white") + TAIL)
+
+	// bold
+	fmt.Println(HEAD + BBlack("bold black") + TAIL)
+	fmt.Println(HEAD + BRed("bold red") + TAIL)
+	fmt.Println(HEAD + BGreen("bold green") + TAIL)
+	fmt.Println(HEAD + BYellow("bold yellow") + TAIL)
+	fmt.Println(HEAD + BBlue("bold blue") + TAIL)
+	fmt.Println(HEAD + BPurple("bold purple") + TAIL)
+	fmt.Println(HEAD + BCyan("bold cyan") + TAIL)
+	fmt.Println(HEAD + BLightGray("bold light gray") + TAIL)
+	fmt.Println(HEAD + BDarkGray("bold dark gray") + TAIL)
+	fmt.Println(HEAD + BLightRed("bold light red") + TAIL)
+	fmt.Println(HEAD + BLightGreen("bold light green") + TAIL)
+	fmt.Println(HEAD + BLightYellow("bold light yellow") + TAIL)
+	fmt.Println(HEAD + BLightBlue("bold light blue") + TAIL)
+	fmt.Println(HEAD + BLightPurple("bold light purple") + TAIL)
+	fmt.Println(HEAD + BLightCyan("bold light cyan") + TAIL)
+	fmt.Println(HEAD + BWhite("bold white") + TAIL)
+
+	// background
+	fmt.Println(HEAD + GBlack("background black") + TAIL)
+	fmt.Println(HEAD + GRed("background red") + TAIL)
+	fmt.Println(HEAD + GGreen("background green") + TAIL)
+	fmt.Println(HEAD + GYellow("background yellow") + TAIL)
+	fmt.Println(HEAD + GBlue("background blue") + TAIL)
+	fmt.Println(HEAD + GPurple("background purple") + TAIL)
+	fmt.Println(HEAD + GCyan("background cyan") + TAIL)
+	fmt.Println(HEAD + GLightGray("background light gray") + TAIL)
+	fmt.Println(HEAD + GDarkGray("background dark gray") + TAIL)
+	fmt.Println(HEAD + GLightRed("background light red") + TAIL)
+	fmt.Println(HEAD + GLightGreen("background light green") + TAIL)
+	fmt.Println(HEAD + GLightYellow("background light yellow") + TAIL)
+	fmt.Println(HEAD + GLightBlue("background light blue") + TAIL)
+	fmt.Println(HEAD + GLightPurple("background light purple") + TAIL)
+	fmt.Println(HEAD + GLightCyan("background light cyan") + TAIL)
+	fmt.Println(HEAD + GWhite("background white") + TAIL)
+
+	// special
+	fmt.Println("A " + Bold("bold") + " text")
+	fmt.Println("This is a " + Dim("dimmed") + " text")
+	fmt.Println("Add a " + Underline("underline"))
+	fmt.Println("Use " + Invert("invert") + " to highlight your text")
+	fmt.Println("Your password is:" + Hide("myPass"))
+	fmt.Println("OMG I'm " + Blink("blinking") + " !!!") // blinking works only on mac
+}
diff --git a/vendor/github.com/bclicn/color/color.go b/vendor/github.com/bclicn/color/color.go
new file mode 100644
index 0000000..ce7fc83
--- /dev/null
+++ b/vendor/github.com/bclicn/color/color.go
@@ -0,0 +1,330 @@
+// github.com/bclicn/color
+// colorized output for Mac & Linux terminal
+// version: 1.0.0
+// author:  bcli, bclicn@gmail.com, 2018-7-11
+// see:     http://misc.flogisoft.com/bash/tip_colors_and_formatting
+// usage:
+// Official layout
+// 	$ go get github.com/bclicn/color
+// 	# in your project
+// 	import "github.com/bclicn/color"
+// 	func main() {
+//		fmt.Println(color.Red("I'm red!"))
+//		color.Test()
+//	}
+
+package color
+
+import (
+	"strconv"
+)
+
+const (
+	// common
+	reset  = "\033[0m" // auto reset the rest of text to default color
+	normal = 0
+	bold   = 1 // increase this value if you want bolder text
+	// special
+	dim       = 2
+	underline = 4
+	blink     = 5
+	reverse   = 7
+	hidden    = 8
+	// color
+	black       = 30 // default = 39
+	red         = 31
+	green       = 32
+	yellow      = 33
+	blue        = 34
+	purple      = 35 // purple = magenta
+	cyan        = 36
+	lightGray   = 37
+	darkGray    = 90
+	lightRed    = 91
+	lightGreen  = 92
+	lightYellow = 93
+	lightBlue   = 94
+	lightPurple = 95
+	lightCyan   = 96
+	white       = 97
+)
+
+// you can use custom color code and font size by calling this function
+func Render(colorCode int, fontSize int, content string) string {
+	return "\033[" + strconv.Itoa(fontSize) + ";" + strconv.Itoa(colorCode) + "m" + content + reset
+}
+
+// black text (use this with caution since most geeks use dark console)
+func Black(txt string) string {
+	return Render(black, normal, txt)
+}
+
+// red text
+func Red(txt string) string {
+	return Render(red, normal, txt)
+}
+
+// green text
+func Green(txt string) string {
+	return Render(green, normal, txt)
+}
+
+// yellow text
+func Yellow(txt string) string {
+	return Render(yellow, normal, txt)
+}
+
+// blue text
+func Blue(txt string) string {
+	return Render(blue, normal, txt)
+}
+
+// purple text
+func Purple(txt string) string {
+	return Render(purple, normal, txt)
+}
+
+// cyan text
+func Cyan(txt string) string {
+	return Render(cyan, normal, txt)
+}
+
+// light gray text
+func LightGray(txt string) string {
+	return Render(lightGray, normal, txt)
+}
+
+// dark gray text
+func DarkGray(txt string) string {
+	return Render(darkGray, normal, txt)
+}
+
+// light red text
+func LightRed(txt string) string {
+	return Render(lightRed, normal, txt)
+}
+
+// light green text
+func LightGreen(txt string) string {
+	return Render(lightGreen, normal, txt)
+}
+
+// light yellow text
+func LightYellow(txt string) string {
+	return Render(lightYellow, normal, txt)
+}
+
+// light blue text
+func LightBlue(txt string) string {
+	return Render(lightBlue, normal, txt)
+}
+
+// light purple text
+func LightPurple(txt string) string {
+	return Render(lightPurple, normal, txt)
+}
+
+// light cyan text
+func LightCyan(txt string) string {
+	return Render(lightCyan, normal, txt)
+}
+
+// white text
+func White(txt string) string {
+	return Render(white, normal, txt)
+}
+
+// black text (use this with caution since most geeks use dark console)
+func BBlack(txt string) string {
+	return Render(black, bold, txt)
+}
+
+// bold red
+func BRed(txt string) string {
+	return Render(red, bold, txt)
+}
+
+// bold green
+func BGreen(txt string) string {
+	return Render(green, bold, txt)
+}
+
+// bold yellow
+func BYellow(txt string) string {
+	return Render(yellow, bold, txt)
+}
+
+// bold blue
+func BBlue(txt string) string {
+	return Render(blue, bold, txt)
+}
+
+// bold purple
+func BPurple(txt string) string {
+	return Render(purple, bold, txt)
+}
+
+// bold cyan
+func BCyan(txt string) string {
+	return Render(cyan, bold, txt)
+}
+
+// bold light gray
+func BLightGray(txt string) string {
+	return Render(lightGray, bold, txt)
+}
+
+// bold dark gray
+func BDarkGray(txt string) string {
+	return Render(darkGray, bold, txt)
+}
+
+// bold light red
+func BLightRed(txt string) string {
+	return Render(lightRed, bold, txt)
+}
+
+// bold light green
+func BLightGreen(txt string) string {
+	return Render(lightGreen, bold, txt)
+}
+
+// bold light yellow
+func BLightYellow(txt string) string {
+	return Render(lightYellow, bold, txt)
+}
+
+// bold light blue
+func BLightBlue(txt string) string {
+	return Render(lightBlue, bold, txt)
+}
+
+// bold light purple
+func BLightPurple(txt string) string {
+	return Render(lightPurple, bold, txt)
+}
+
+// bold light cyan
+func BLightCyan(txt string) string {
+	return Render(lightCyan, bold, txt)
+}
+
+// bold white
+func BWhite(txt string) string {
+	return Render(white, bold, txt)
+}
+
+// black background (use this with caution since most of geeks use dark console)
+func GBlack(txt string) string {
+	return Render(black+1, normal, txt)
+}
+
+// red background
+func GRed(txt string) string {
+	return Render(red+1, normal, txt)
+}
+
+// green background
+func GGreen(txt string) string {
+	return Render(green+1, normal, txt)
+}
+
+// yellow background
+func GYellow(txt string) string {
+	return Render(yellow+1, normal, txt)
+}
+
+// blue background
+func GBlue(txt string) string {
+	return Render(blue+1, normal, txt)
+}
+
+// purple background
+func GPurple(txt string) string {
+	return Render(purple+1, normal, txt)
+}
+
+// cyan background
+func GCyan(txt string) string {
+	return Render(cyan+1, normal, txt)
+}
+
+// light gray background
+func GLightGray(txt string) string {
+	return Render(lightGray+1, normal, txt)
+}
+
+// dark gray background
+func GDarkGray(txt string) string {
+	return Render(darkGray+1, normal, txt)
+}
+
+// light red background
+func GLightRed(txt string) string {
+	return Render(lightRed+1, normal, txt)
+}
+
+// light green background
+func GLightGreen(txt string) string {
+	return Render(lightGreen+1, normal, txt)
+}
+
+// light yellow background
+func GLightYellow(txt string) string {
+	return Render(lightYellow+1, normal, txt)
+}
+
+// blue background
+func GLightBlue(txt string) string {
+	return Render(lightBlue+1, normal, txt)
+}
+
+// light purple background
+func GLightPurple(txt string) string {
+	return Render(lightPurple+1, normal, txt)
+}
+
+// light cyan background
+func GLightCyan(txt string) string {
+	return Render(lightCyan+1, normal, txt)
+}
+
+// give text a white background
+func GWhite(txt string) string {
+	return Render(white+1, normal, txt)
+}
+
+// bold text
+func Bold(txt string) string {
+	return Render(bold, normal, txt)
+}
+
+// dimmed text
+func Dim(txt string) string {
+	return Render(dim, normal, txt)
+}
+
+// underlined text
+func Underline(txt string) string {
+	return Render(underline, 0, txt)
+}
+
+// make given text blink, not supported by all consoles
+func Blink(txt string) string {
+	return Render(blink, normal, txt)
+}
+
+// invert the color of text and its background
+func Invert(txt string) string {
+	return Render(reverse, normal, txt)
+}
+
+// hide given text, useful for password input
+func Hide(txt string) string {
+	return Render(hidden, normal, txt)
+}
+
+// test all functions
+func Test() {
+	ColorTest()
+}
diff --git a/vendor/github.com/bclicn/color/showcase.jpg b/vendor/github.com/bclicn/color/showcase.jpg
new file mode 100644
index 0000000..39f270c
--- /dev/null
+++ b/vendor/github.com/bclicn/color/showcase.jpg
Binary files differ