diff --git a/api/handler.go b/api/handler.go
index 593afed..ee70d74 100644
--- a/api/handler.go
+++ b/api/handler.go
@@ -19,21 +19,10 @@
 import (
 	"errors"
 	"fmt"
-	"io/ioutil"
-	"log"
 	"net"
-	"net/http"
-	"os"
-	"strings"
 	"sync"
 
-	"gerrit.opencord.org/abstract-olt/internal/pkg/settings"
-	"gerrit.opencord.org/abstract-olt/models"
-	"gerrit.opencord.org/abstract-olt/models/abstract"
-	"gerrit.opencord.org/abstract-olt/models/physical"
-	"github.com/mongodb/mongo-go-driver/bson"
-	"github.com/mongodb/mongo-go-driver/mongo"
-	"github.com/mongodb/mongo-go-driver/mongo/updateopt"
+	"gerrit.opencord.org/abstract-olt/internal/pkg/impl"
 	context "golang.org/x/net/context"
 )
 
@@ -77,11 +66,6 @@
 CreateChassis - allocates a new Chassis struct and stores it in chassisMap
 */
 func (s *Server) CreateChassis(ctx context.Context, in *AddChassisMessage) (*AddChassisReturn, error) {
-	myChan := getSyncChannel()
-	fmt.Println("after getSyncChannel")
-	<-myChan
-	defer done(myChan, true)
-	chassisMap := models.GetChassisMap()
 	clli := in.GetCLLI()
 
 	xosIP := net.ParseIP(in.GetXOSIP())
@@ -90,70 +74,33 @@
 		errStr := fmt.Sprintf("Invalid IP %s supplied for XOSIP", in.GetXOSIP())
 		return nil, errors.New(errStr)
 	}
-
 	xosAddress := net.TCPAddr{IP: xosIP, Port: xosPort}
-
 	xosUser := in.GetXOSUser()
 	xosPassword := in.GetXOSPassword()
 	if xosUser == "" || xosPassword == "" {
 		return nil, errors.New("Either XOSUser or XOSPassword supplied were empty")
 	}
-	loginWorked := testLogin(xosUser, xosPassword, xosIP, xosPort)
-	if !loginWorked {
-		return nil, errors.New("Unable to validate login not creating Abstract Chassis")
-	}
 	shelf := int(in.GetShelf())
 	rack := int(in.GetRack())
-
-	chassisHolder := (*chassisMap)[clli]
-	if chassisHolder != nil {
-		return &AddChassisReturn{DeviceID: chassisHolder.AbstractChassis.CLLI}, nil
+	deviceID, err := impl.CreateChassis(clli, xosAddress, xosUser, xosPassword, shelf, rack)
+	if err != nil {
+		return nil, err
 	}
-
-	abstractChassis := abstract.GenerateChassis(clli, int(in.GetRack()), int(in.GetShelf()))
-	phyChassis := physical.Chassis{CLLI: clli, XOSUser: xosUser, XOSPassword: xosPassword, XOSAddress: xosAddress, Rack: rack, Shelf: shelf}
-
-	chassisHolder = &models.ChassisHolder{AbstractChassis: abstractChassis, PhysicalChassis: phyChassis}
-	if settings.GetDebug() {
-		output := fmt.Sprintf("%v", abstractChassis)
-		formatted := strings.Replace(output, "{", "\n{", -1)
-		log.Printf("new chassis %s\n", formatted)
-	}
-	(*chassisMap)[clli] = chassisHolder
-	isDirty = true
-	return &AddChassisReturn{DeviceID: clli}, nil
+	return &AddChassisReturn{DeviceID: deviceID}, nil
 }
 
 /*
 ChangeXOSUserPassword - allows update of xos credentials
 */
 func (s *Server) ChangeXOSUserPassword(ctx context.Context, in *ChangeXOSUserPasswordMessage) (*ChangeXOSUserPasswordReturn, error) {
-	myChan := getSyncChannel()
-	<-myChan
-	defer done(myChan, true)
 	clli := in.GetCLLI()
 	xosUser := in.GetXOSUser()
 	xosPassword := in.GetXOSPassword()
 	if xosUser == "" || xosPassword == "" {
 		return nil, errors.New("Either XOSUser or XOSPassword supplied were empty")
 	}
-	chassisMap := models.GetChassisMap()
-	chassisHolder := (*chassisMap)[clli]
-	if chassisHolder == nil {
-		errString := fmt.Sprintf("There is no chassis with CLLI of %s", clli)
-		return nil, errors.New(errString)
-	}
-	xosIP := chassisHolder.PhysicalChassis.XOSAddress.IP
-	xosPort := chassisHolder.PhysicalChassis.XOSAddress.Port
-	loginWorked := testLogin(xosUser, xosPassword, xosIP, xosPort)
-	if !loginWorked {
-		return nil, errors.New("Unable to validate login when changing password")
-	}
-
-	chassisHolder.PhysicalChassis.XOSUser = xosUser
-	chassisHolder.PhysicalChassis.XOSPassword = xosPassword
-	isDirty = true
-	return &ChangeXOSUserPasswordReturn{Success: true}, nil
+	success, err := impl.ChangeXOSUserPassword(clli, xosUser, xosPassword)
+	return &ChangeXOSUserPasswordReturn{Success: success}, err
 
 }
 
@@ -161,201 +108,64 @@
 CreateOLTChassis adds an OLT chassis/line card to the Physical chassis
 */
 func (s *Server) CreateOLTChassis(ctx context.Context, in *AddOLTChassisMessage) (*AddOLTChassisReturn, error) {
-	myChan := getSyncChannel()
-	<-myChan
-	defer done(myChan, true)
-	fmt.Printf(" CreateOLTChassis %v \n", *in)
-	chassisMap := models.GetChassisMap()
 	clli := in.GetCLLI()
-	chassisHolder := (*chassisMap)[clli]
-	if chassisHolder == nil {
-		errString := fmt.Sprintf("There is no chassis with CLLI of %s", clli)
-		return &AddOLTChassisReturn{DeviceID: "", ChassisDeviceID: ""}, errors.New(errString)
-	}
-	oltType := in.GetType()
+	oltType := in.GetType().String()
 	address := net.TCPAddr{IP: net.ParseIP(in.GetSlotIP()), Port: int(in.GetSlotPort())}
-	physicalChassis := &chassisHolder.PhysicalChassis
-	sOlt := physical.SimpleOLT{CLLI: clli, Hostname: in.GetHostname(), Address: address, Parent: physicalChassis}
-	switch oltType {
-	case AddOLTChassisMessage_edgecore:
-		sOlt.CreateEdgecore()
-	case AddOLTChassisMessage_adtran:
-	case AddOLTChassisMessage_tibit:
-	}
-	physicalChassis.AddOLTChassis(sOlt)
-	ports := sOlt.GetPorts()
-	for i := 0; i < len(ports); i++ {
-		absPort, _ := chassisHolder.AbstractChassis.NextPort()
-
-		absPort.PhysPort = &ports[i]
-		//AssignTraits(&ports[i], absPort)
-	}
-	isDirty = true
-	return &AddOLTChassisReturn{DeviceID: in.GetHostname(), ChassisDeviceID: clli}, nil
-
+	hostname := in.GetHostname()
+	clli, err := impl.CreateOLTChassis(clli, oltType, address, hostname)
+	return &AddOLTChassisReturn{DeviceID: hostname, ChassisDeviceID: clli}, err
 }
 
 /*
 ProvisionOnt provisions an ONT on a specific Chassis/LineCard/Port
 */
 func (s *Server) ProvisionOnt(ctx context.Context, in *AddOntMessage) (*AddOntReturn, error) {
-	myChan := getSyncChannel()
-	<-myChan
-	defer done(myChan, true)
-	chassisMap := models.GetChassisMap()
 	clli := in.GetCLLI()
-	chassisHolder := (*chassisMap)[clli]
-	if chassisHolder == nil {
-		errString := fmt.Sprintf("There is no chassis with CLLI of %s", clli)
-		return &AddOntReturn{Success: false}, errors.New(errString)
-	}
-	err := chassisHolder.AbstractChassis.ActivateONT(int(in.GetSlotNumber()), int(in.GetPortNumber()), int(in.GetOntNumber()), in.GetSerialNumber())
-
-	if err != nil {
-		return nil, err
-	}
-	isDirty = true
-	return &AddOntReturn{Success: true}, nil
+	slotNumber := int(in.GetSlotNumber())
+	portNumber := int(in.GetPortNumber())
+	ontNumber := int(in.GetOntNumber())
+	serialNumber := in.GetSerialNumber()
+	success, err := impl.ProvisionOnt(clli, slotNumber, portNumber, ontNumber, serialNumber)
+	return &AddOntReturn{Success: success}, err
 }
-func (s *Server) ProvisionOntFull(ctx context.Context, in *AddOntFullMessage) (*AddOntReturn, error) {
-	myChan := getSyncChannel()
-	<-myChan
-	defer done(myChan, true)
-	chassisMap := models.GetChassisMap()
-	clli := in.GetCLLI()
-	chassisHolder := (*chassisMap)[clli]
-	if chassisHolder == nil {
-		errString := fmt.Sprintf("There is no chassis with CLLI of %s", clli)
-		return &AddOntReturn{Success: false}, errors.New(errString)
-	}
-	err := chassisHolder.AbstractChassis.ActivateONTFull(int(in.GetSlotNumber()), int(in.GetPortNumber()), int(in.GetOntNumber()), in.GetSerialNumber(),
-		in.GetCTag(), in.GetSTag(), in.GetNasPortID(), in.GetCircuitID())
 
-	if err != nil {
-		return nil, err
-	}
-	isDirty = true
-	return &AddOntReturn{Success: true}, nil
+/*
+ProvsionOntFull - provisions ont using sTag,cTag,NasPortID, and CircuitID passed in
+*/
+func (s *Server) ProvisionOntFull(ctx context.Context, in *AddOntFullMessage) (*AddOntReturn, error) {
+	clli := in.GetCLLI()
+	slotNumber := int(in.GetSlotNumber())
+	portNumber := int(in.GetPortNumber())
+	ontNumber := int(in.GetOntNumber())
+	serialNumber := in.GetSerialNumber()
+	cTag := in.GetCTag()
+	sTag := in.GetSTag()
+	nasPortID := in.GetNasPortID()
+	circuitID := in.GetCircuitID()
+	success, err := impl.ProvisionOntFull(clli, slotNumber, portNumber, ontNumber, serialNumber, cTag, sTag, nasPortID, circuitID)
+	return &AddOntReturn{Success: success}, err
 }
 
 /*
 DeleteOnt - deletes a previously provision ont
 */
 func (s *Server) DeleteOnt(ctx context.Context, in *DeleteOntMessage) (*DeleteOntReturn, error) {
-	myChan := getSyncChannel()
-	<-myChan
-	defer done(myChan, true)
-	chassisMap := models.GetChassisMap()
 	clli := in.GetCLLI()
-	chassisHolder := (*chassisMap)[clli]
-	err := chassisHolder.AbstractChassis.DeleteONT(int(in.GetSlotNumber()), int(in.GetPortNumber()), int(in.GetOntNumber()), in.GetSerialNumber())
-	if err != nil {
-		return nil, err
-	}
-	isDirty = true
-	return &DeleteOntReturn{Success: true}, nil
+	slotNumber := int(in.GetSlotNumber())
+	portNumber := int(in.GetPortNumber())
+	ontNumber := int(in.GetOntNumber())
+	serialNumber := in.GetSerialNumber()
+	success, err := impl.DeleteOnt(clli, slotNumber, portNumber, ontNumber, serialNumber)
+	return &DeleteOntReturn{Success: success}, err
 }
 
+func (s *Server) Reflow(ctx context.Context, in *ReflowMessage) (*ReflowReturn, error) {
+	success, err := impl.Reflow()
+	return &ReflowReturn{Success: success}, err
+
+}
 func (s *Server) Output(ctx context.Context, in *OutputMessage) (*OutputReturn, error) {
-	return DoOutput()
-
-}
-func DoOutput() (*OutputReturn, error) {
-	if isDirty {
-		myChan := getSyncChannel()
-		<-myChan
-		defer done(myChan, true)
-		chassisMap := models.GetChassisMap()
-		if settings.GetMongo() {
-			client, err := mongo.NewClient(settings.GetMongodb())
-			client.Connect(context.Background())
-			if err != nil {
-				log.Printf("client connect to mongo db @%s failed with %v\n", settings.GetMongodb(), err)
-			}
-			defer client.Disconnect(context.Background())
-			for clli, chassisHolder := range *chassisMap {
-				json, _ := (chassisHolder).Serialize()
-				collection := client.Database("AbstractOLT").Collection("backup")
-				doc := bson.NewDocument(bson.EC.String("_id", clli))
-				filter := bson.NewDocument(bson.EC.String("_id", clli))
-				doc.Append(bson.EC.Binary("body", json))
-
-				updateDoc := bson.NewDocument(bson.EC.SubDocument("$set", doc))
-				//update or insert if not existent
-				res, err := collection.UpdateOne(context.Background(), filter, updateDoc, updateopt.Upsert(true))
-				if err != nil {
-					log.Printf("collection.UpdateOne failed with %v\n", err)
-				} else {
-					id := res.UpsertedID
-					if settings.GetDebug() {
-						log.Printf("Update Succeeded with id %v\n", id)
-					}
-				}
-			}
-		} else {
-			for clli, chassisHolder := range *chassisMap {
-
-				json, _ := (chassisHolder).Serialize()
-				if settings.GetMongo() {
-
-				} else {
-					//TODO parameterize dump location
-					backupFile := fmt.Sprintf("backup/%s", clli)
-					f, _ := os.Create(backupFile)
-
-					defer f.Close()
-
-					_, _ = f.WriteString(string(json))
-					f.Sync()
-				}
-			}
-		}
-		isDirty = false
-	} else {
-		if settings.GetDebug() {
-			log.Print("Not dirty not dumping config")
-		}
-
-	}
-	return &OutputReturn{Success: true}, nil
-
-}
-func testLogin(xosUser string, xosPassword string, xosIP net.IP, xosPort int) bool {
-	if settings.GetDummy() {
-		return true
-	}
-	var dummyYaml = `
-tosca_definitions_version: tosca_simple_yaml_1_0
-imports:
-  - custom_types/site.yaml
-description: anything
-topology_template:
-  node_templates:
-    mysite:
-      type: tosca.nodes.Site
-      properties:
-        must-exist: true
-        name: mysite
-`
-	client := &http.Client{}
-	requestList := fmt.Sprintf("http://%s:%d/run", xosIP, xosPort)
-	req, err := http.NewRequest("POST", requestList, strings.NewReader(dummyYaml))
-	req.Header.Add("xos-username", xosUser)
-	req.Header.Add("xos-password", xosPassword)
-	resp, err := client.Do(req)
-	log.Printf("testLogin resp:%v", resp)
-	if err != nil {
-		log.Printf("Unable to validate XOS Login Information %v", err)
-		return false
-	}
-	defer resp.Body.Close()
-
-	if resp.StatusCode == http.StatusOK {
-		bodyBytes, _ := ioutil.ReadAll(resp.Body)
-		bodyString := string(bodyBytes)
-		fmt.Println(bodyString)
-		return true
-	}
-	return false
+	success, err := impl.DoOutput()
+	return &OutputReturn{Success: success}, err
 
 }
