diff --git a/core/mediator.go b/core/mediator.go
new file mode 100644
index 0000000..496621a
--- /dev/null
+++ b/core/mediator.go
@@ -0,0 +1,180 @@
+/*
+ * 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 core
+
+import (
+	"sync"
+	"gerrit.opencord.org/voltha-bbsim/common"
+	"os"
+	"os/signal"
+	"fmt"
+	"flag"
+	"strings"
+	"strconv"
+)
+
+type option struct{
+	address string
+	port uint32
+	oltid uint32
+	npon uint32
+	nonus uint32
+	aaawait int
+	dhcpwait int
+	dhcpservip string
+	intvl int
+	intvl_test int
+	Mode Mode
+}
+
+func GetOptions() *option {
+	o := new(option)
+	addressport := flag.String("H", ":50060", "IP address:port")
+	oltid :=flag.Int("id", 0, "OLT-ID")
+	npon := flag.Int("i", 1, "Number of PON-IF ports")
+	nonus := flag.Int("n", 1, "Number of ONUs per PON-IF port")
+	modeopt := flag.String("m", "default", "Emulation mode (default, aaa, both (aaa & dhcp))")
+	aaawait := flag.Int("aw", 30, "Wait time (sec) for activation WPA supplicants")
+	dhcpwait := flag.Int("dw", 50, "Wait time (sec) for activation DHCP clients")
+	dhcpservip := flag.String("s", "182.21.0.1", "DHCP Server IP Address")
+	intvl := flag.Int("v", 1, "Interval each Indication")
+	intvl_test := flag.Int("V", 1, "Interval each Indication")
+	o.Mode = DEFAULT
+	flag.Parse()
+	if *modeopt == "aaa" {
+		o.Mode = AAA
+	} else if *modeopt == "both" {
+		o.Mode = BOTH
+	}
+	o.oltid = uint32(*oltid)
+	o.npon = uint32(*npon)
+	o.nonus = uint32(*nonus)
+	o.aaawait = *aaawait
+	o.dhcpwait = *dhcpwait
+	o.dhcpservip = *dhcpservip
+	o.intvl = *intvl
+	o.intvl_test = *intvl_test
+	o.address = (strings.Split(*addressport, ":")[0])
+	tmp, _ := strconv.Atoi(strings.Split(*addressport, ":")[1])
+	o.port = uint32(tmp)
+	return o
+}
+
+type stateMachine struct{
+	handlers []*handler
+	state coreState
+}
+
+type handler struct{
+	dst coreState
+	src coreState
+	method func(s *Server) error
+}
+
+func (sm *stateMachine) transit(next coreState) func(s *Server) error {
+	for _, handler := range sm.handlers{
+		if handler.src == sm.state && handler.dst == next {
+			logger.Debug("Hit (src:%d, dst:%d)",handler.src, handler.dst)
+			sm.state = next
+			return handler.method
+		}
+	}
+	sm.state = next
+	return nil
+}
+
+type mediator struct {
+	opt *option
+	sm *stateMachine
+	server *Server
+	tester *Tester
+}
+
+func NewMediator(o *option) *mediator{
+	m := new(mediator)
+	m.opt = o
+	logger.Debug("ip:%s, baseport:%d, npon:%d, nonus:%d, mode:%d\n", o.address, o.port, o.npon, o.nonus, o.Mode)
+	return m
+}
+
+func (m *mediator) Start(){
+	var wg sync.WaitGroup
+	opt := m.opt
+	server := NewCore(opt)
+	wg.Add(1)
+	go func(){
+		if err:= server.Start(); err != nil {	//Blocking
+			logger.Error("%s", err)
+		}
+		wg.Done()
+		return
+	}()
+
+	tester := NewTester(opt)
+	m.server = server
+	m.tester = tester
+	m.sm = &stateMachine{
+		state: INACTIVE,
+		handlers: []*handler{
+			&handler{src: PRE_ACTIVE,dst: ACTIVE, method: m.tester.Start},
+			&handler{src: ACTIVE,dst: PRE_ACTIVE, method: m.tester.Stop},
+		},
+	}
+	go func(){
+		m.Mediate()
+	}()
+
+	c := make(chan os.Signal, 1)
+	signal.Notify(c, os.Interrupt)
+	go func() {
+		defer func(){
+			logger.Debug("SIGINT catcher Done")
+			wg.Done()
+		}()
+		for sig := range c {
+			wg.Add(1)
+			fmt.Println("SIGINT", sig)
+			close(c)
+			server.Stop()	//Non-blocking
+			tester.Stop(server)   //Non-blocking
+			return
+		}
+	}()
+	wg.Wait()
+	logger.Debug("Reach to the end line")
+}
+
+func (m *mediator) Mediate(){
+	wg := sync.WaitGroup{}
+	defer logger.Debug("Mediate Done")
+	for  corestat := range m.server.stateChan {
+		logger.Debug("Mediator receives state %d of server", corestat)
+		method := m.sm.transit(corestat)
+		if method != nil {
+			wg.Add(1)
+			defer wg.Done()
+			go func() error {
+				if err := method(m.server); err != nil{ //blocking
+					m.server.Stop()
+					return err
+				}
+				return nil
+			}()
+		}
+	}
+	wg.Wait()
+}
\ No newline at end of file
