diff --git a/pkg/mocks/grpc/mock_adapter_services.go b/pkg/mocks/grpc/mock_adapter_services.go
deleted file mode 100644
index cbab060..0000000
--- a/pkg/mocks/grpc/mock_adapter_services.go
+++ /dev/null
@@ -1,1710 +0,0 @@
-/*
- * Copyright 2021-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.
- */
-// Code generated by MockGen. DO NOT EDIT.
-// Source: ./adapter_services.pb.go
-
-package grpc
-
-import (
-	context "context"
-	reflect "reflect"
-
-	gomock "github.com/golang/mock/gomock"
-	empty "github.com/golang/protobuf/ptypes/empty"
-	common "github.com/opencord/voltha-protos/v5/go/common"
-	extension "github.com/opencord/voltha-protos/v5/go/extension"
-	inter_container "github.com/opencord/voltha-protos/v5/go/inter_container"
-	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
-	grpc "google.golang.org/grpc"
-)
-
-// MockAdapterServiceClient is a mock of AdapterServiceClient interface.
-type MockAdapterServiceClient struct {
-	ctrl     *gomock.Controller
-	recorder *MockAdapterServiceClientMockRecorder
-}
-
-// MockAdapterServiceClientMockRecorder is the mock recorder for MockAdapterServiceClient.
-type MockAdapterServiceClientMockRecorder struct {
-	mock *MockAdapterServiceClient
-}
-
-// NewMockAdapterServiceClient creates a new mock instance.
-func NewMockAdapterServiceClient(ctrl *gomock.Controller) *MockAdapterServiceClient {
-	mock := &MockAdapterServiceClient{ctrl: ctrl}
-	mock.recorder = &MockAdapterServiceClientMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockAdapterServiceClient) EXPECT() *MockAdapterServiceClientMockRecorder {
-	return m.recorder
-}
-
-// AbortOnuImageUpgrade mocks base method.
-func (m *MockAdapterServiceClient) AbortOnuImageUpgrade(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "AbortOnuImageUpgrade", varargs...)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// AbortOnuImageUpgrade indicates an expected call of AbortOnuImageUpgrade.
-func (mr *MockAdapterServiceClientMockRecorder) AbortOnuImageUpgrade(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortOnuImageUpgrade", reflect.TypeOf((*MockAdapterServiceClient)(nil).AbortOnuImageUpgrade), varargs...)
-}
-
-// ActivateImageUpdate mocks base method.
-func (m *MockAdapterServiceClient) ActivateImageUpdate(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ActivateImageUpdate", varargs...)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
-func (mr *MockAdapterServiceClientMockRecorder) ActivateImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockAdapterServiceClient)(nil).ActivateImageUpdate), varargs...)
-}
-
-// ActivateOnuImage mocks base method.
-func (m *MockAdapterServiceClient) ActivateOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ActivateOnuImage", varargs...)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ActivateOnuImage indicates an expected call of ActivateOnuImage.
-func (mr *MockAdapterServiceClientMockRecorder) ActivateOnuImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateOnuImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).ActivateOnuImage), varargs...)
-}
-
-// AdoptDevice mocks base method.
-func (m *MockAdapterServiceClient) AdoptDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "AdoptDevice", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// AdoptDevice indicates an expected call of AdoptDevice.
-func (mr *MockAdapterServiceClientMockRecorder) AdoptDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdoptDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).AdoptDevice), varargs...)
-}
-
-// CancelImageDownload mocks base method.
-func (m *MockAdapterServiceClient) CancelImageDownload(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "CancelImageDownload", varargs...)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// CancelImageDownload indicates an expected call of CancelImageDownload.
-func (mr *MockAdapterServiceClientMockRecorder) CancelImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockAdapterServiceClient)(nil).CancelImageDownload), varargs...)
-}
-
-// ChildDeviceLost mocks base method.
-func (m *MockAdapterServiceClient) ChildDeviceLost(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ChildDeviceLost", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDeviceLost indicates an expected call of ChildDeviceLost.
-func (mr *MockAdapterServiceClientMockRecorder) ChildDeviceLost(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceLost", reflect.TypeOf((*MockAdapterServiceClient)(nil).ChildDeviceLost), varargs...)
-}
-
-// CommitOnuImage mocks base method.
-func (m *MockAdapterServiceClient) CommitOnuImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "CommitOnuImage", varargs...)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// CommitOnuImage indicates an expected call of CommitOnuImage.
-func (mr *MockAdapterServiceClientMockRecorder) CommitOnuImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitOnuImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).CommitOnuImage), varargs...)
-}
-
-// DeleteDevice mocks base method.
-func (m *MockAdapterServiceClient) DeleteDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DeleteDevice", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteDevice indicates an expected call of DeleteDevice.
-func (mr *MockAdapterServiceClientMockRecorder) DeleteDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).DeleteDevice), varargs...)
-}
-
-// DisableDevice mocks base method.
-func (m *MockAdapterServiceClient) DisableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DisableDevice", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DisableDevice indicates an expected call of DisableDevice.
-func (mr *MockAdapterServiceClientMockRecorder) DisableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).DisableDevice), varargs...)
-}
-
-// DisablePort mocks base method.
-func (m *MockAdapterServiceClient) DisablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DisablePort", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DisablePort indicates an expected call of DisablePort.
-func (mr *MockAdapterServiceClientMockRecorder) DisablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockAdapterServiceClient)(nil).DisablePort), varargs...)
-}
-
-// DownloadImage mocks base method.
-func (m *MockAdapterServiceClient) DownloadImage(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DownloadImage", varargs...)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DownloadImage indicates an expected call of DownloadImage.
-func (mr *MockAdapterServiceClientMockRecorder) DownloadImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).DownloadImage), varargs...)
-}
-
-// DownloadOnuImage mocks base method.
-func (m *MockAdapterServiceClient) DownloadOnuImage(ctx context.Context, in *voltha.DeviceImageDownloadRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DownloadOnuImage", varargs...)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DownloadOnuImage indicates an expected call of DownloadOnuImage.
-func (mr *MockAdapterServiceClientMockRecorder) DownloadOnuImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadOnuImage", reflect.TypeOf((*MockAdapterServiceClient)(nil).DownloadOnuImage), varargs...)
-}
-
-// EnablePort mocks base method.
-func (m *MockAdapterServiceClient) EnablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "EnablePort", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// EnablePort indicates an expected call of EnablePort.
-func (mr *MockAdapterServiceClientMockRecorder) EnablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockAdapterServiceClient)(nil).EnablePort), varargs...)
-}
-
-// GetExtValue mocks base method.
-func (m *MockAdapterServiceClient) GetExtValue(ctx context.Context, in *inter_container.GetExtValueMessage, opts ...grpc.CallOption) (*common.ReturnValues, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetExtValue", varargs...)
-	ret0, _ := ret[0].(*common.ReturnValues)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetExtValue indicates an expected call of GetExtValue.
-func (mr *MockAdapterServiceClientMockRecorder) GetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetExtValue), varargs...)
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockAdapterServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockAdapterServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetHealthStatus), varargs...)
-}
-
-// GetImageDownloadStatus mocks base method.
-func (m *MockAdapterServiceClient) GetImageDownloadStatus(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetImageDownloadStatus", varargs...)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
-func (mr *MockAdapterServiceClientMockRecorder) GetImageDownloadStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetImageDownloadStatus), varargs...)
-}
-
-// GetOfpDeviceInfo mocks base method.
-func (m *MockAdapterServiceClient) GetOfpDeviceInfo(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*inter_container.SwitchCapability, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetOfpDeviceInfo", varargs...)
-	ret0, _ := ret[0].(*inter_container.SwitchCapability)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetOfpDeviceInfo indicates an expected call of GetOfpDeviceInfo.
-func (mr *MockAdapterServiceClientMockRecorder) GetOfpDeviceInfo(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOfpDeviceInfo", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetOfpDeviceInfo), varargs...)
-}
-
-// GetOnuImageStatus mocks base method.
-func (m *MockAdapterServiceClient) GetOnuImageStatus(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetOnuImageStatus", varargs...)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetOnuImageStatus indicates an expected call of GetOnuImageStatus.
-func (mr *MockAdapterServiceClientMockRecorder) GetOnuImageStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImageStatus", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetOnuImageStatus), varargs...)
-}
-
-// GetOnuImages mocks base method.
-func (m *MockAdapterServiceClient) GetOnuImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.OnuImages, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetOnuImages", varargs...)
-	ret0, _ := ret[0].(*voltha.OnuImages)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetOnuImages indicates an expected call of GetOnuImages.
-func (mr *MockAdapterServiceClientMockRecorder) GetOnuImages(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetOnuImages), varargs...)
-}
-
-// GetSingleValue mocks base method.
-func (m *MockAdapterServiceClient) GetSingleValue(ctx context.Context, in *extension.SingleGetValueRequest, opts ...grpc.CallOption) (*extension.SingleGetValueResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetSingleValue", varargs...)
-	ret0, _ := ret[0].(*extension.SingleGetValueResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetSingleValue indicates an expected call of GetSingleValue.
-func (mr *MockAdapterServiceClientMockRecorder) GetSingleValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSingleValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).GetSingleValue), varargs...)
-}
-
-// ReEnableDevice mocks base method.
-func (m *MockAdapterServiceClient) ReEnableDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ReEnableDevice", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ReEnableDevice indicates an expected call of ReEnableDevice.
-func (mr *MockAdapterServiceClientMockRecorder) ReEnableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReEnableDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).ReEnableDevice), varargs...)
-}
-
-// RebootDevice mocks base method.
-func (m *MockAdapterServiceClient) RebootDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "RebootDevice", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// RebootDevice indicates an expected call of RebootDevice.
-func (mr *MockAdapterServiceClientMockRecorder) RebootDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).RebootDevice), varargs...)
-}
-
-// ReconcileDevice mocks base method.
-func (m *MockAdapterServiceClient) ReconcileDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ReconcileDevice", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ReconcileDevice indicates an expected call of ReconcileDevice.
-func (mr *MockAdapterServiceClientMockRecorder) ReconcileDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).ReconcileDevice), varargs...)
-}
-
-// RevertImageUpdate mocks base method.
-func (m *MockAdapterServiceClient) RevertImageUpdate(ctx context.Context, in *inter_container.ImageDownloadMessage, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "RevertImageUpdate", varargs...)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// RevertImageUpdate indicates an expected call of RevertImageUpdate.
-func (mr *MockAdapterServiceClientMockRecorder) RevertImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockAdapterServiceClient)(nil).RevertImageUpdate), varargs...)
-}
-
-// SelfTestDevice mocks base method.
-func (m *MockAdapterServiceClient) SelfTestDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "SelfTestDevice", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SelfTestDevice indicates an expected call of SelfTestDevice.
-func (mr *MockAdapterServiceClientMockRecorder) SelfTestDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTestDevice", reflect.TypeOf((*MockAdapterServiceClient)(nil).SelfTestDevice), varargs...)
-}
-
-// SendPacketOut mocks base method.
-func (m *MockAdapterServiceClient) SendPacketOut(ctx context.Context, in *inter_container.PacketOut, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "SendPacketOut", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SendPacketOut indicates an expected call of SendPacketOut.
-func (mr *MockAdapterServiceClientMockRecorder) SendPacketOut(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketOut", reflect.TypeOf((*MockAdapterServiceClient)(nil).SendPacketOut), varargs...)
-}
-
-// SetExtValue mocks base method.
-func (m *MockAdapterServiceClient) SetExtValue(ctx context.Context, in *inter_container.SetExtValueMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "SetExtValue", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SetExtValue indicates an expected call of SetExtValue.
-func (mr *MockAdapterServiceClientMockRecorder) SetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).SetExtValue), varargs...)
-}
-
-// SetSingleValue mocks base method.
-func (m *MockAdapterServiceClient) SetSingleValue(ctx context.Context, in *extension.SingleSetValueRequest, opts ...grpc.CallOption) (*extension.SingleSetValueResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "SetSingleValue", varargs...)
-	ret0, _ := ret[0].(*extension.SingleSetValueResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SetSingleValue indicates an expected call of SetSingleValue.
-func (mr *MockAdapterServiceClientMockRecorder) SetSingleValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSingleValue", reflect.TypeOf((*MockAdapterServiceClient)(nil).SetSingleValue), varargs...)
-}
-
-// SimulateAlarm mocks base method.
-func (m *MockAdapterServiceClient) SimulateAlarm(ctx context.Context, in *inter_container.SimulateAlarmMessage, opts ...grpc.CallOption) (*common.OperationResp, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "SimulateAlarm", varargs...)
-	ret0, _ := ret[0].(*common.OperationResp)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SimulateAlarm indicates an expected call of SimulateAlarm.
-func (mr *MockAdapterServiceClientMockRecorder) SimulateAlarm(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockAdapterServiceClient)(nil).SimulateAlarm), varargs...)
-}
-
-// StartOmciTest mocks base method.
-func (m *MockAdapterServiceClient) StartOmciTest(ctx context.Context, in *inter_container.OMCITest, opts ...grpc.CallOption) (*voltha.TestResponse, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "StartOmciTest", varargs...)
-	ret0, _ := ret[0].(*voltha.TestResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// StartOmciTest indicates an expected call of StartOmciTest.
-func (mr *MockAdapterServiceClientMockRecorder) StartOmciTest(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTest", reflect.TypeOf((*MockAdapterServiceClient)(nil).StartOmciTest), varargs...)
-}
-
-// SuppressEvent mocks base method.
-func (m *MockAdapterServiceClient) SuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "SuppressEvent", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SuppressEvent indicates an expected call of SuppressEvent.
-func (mr *MockAdapterServiceClientMockRecorder) SuppressEvent(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SuppressEvent", reflect.TypeOf((*MockAdapterServiceClient)(nil).SuppressEvent), varargs...)
-}
-
-// UnSuppressEvent mocks base method.
-func (m *MockAdapterServiceClient) UnSuppressEvent(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "UnSuppressEvent", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UnSuppressEvent indicates an expected call of UnSuppressEvent.
-func (mr *MockAdapterServiceClientMockRecorder) UnSuppressEvent(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnSuppressEvent", reflect.TypeOf((*MockAdapterServiceClient)(nil).UnSuppressEvent), varargs...)
-}
-
-// UpdateFlowsBulk mocks base method.
-func (m *MockAdapterServiceClient) UpdateFlowsBulk(ctx context.Context, in *inter_container.BulkFlows, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "UpdateFlowsBulk", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdateFlowsBulk indicates an expected call of UpdateFlowsBulk.
-func (mr *MockAdapterServiceClientMockRecorder) UpdateFlowsBulk(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsBulk", reflect.TypeOf((*MockAdapterServiceClient)(nil).UpdateFlowsBulk), varargs...)
-}
-
-// UpdateFlowsIncrementally mocks base method.
-func (m *MockAdapterServiceClient) UpdateFlowsIncrementally(ctx context.Context, in *inter_container.IncrementalFlows, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "UpdateFlowsIncrementally", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdateFlowsIncrementally indicates an expected call of UpdateFlowsIncrementally.
-func (mr *MockAdapterServiceClientMockRecorder) UpdateFlowsIncrementally(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsIncrementally", reflect.TypeOf((*MockAdapterServiceClient)(nil).UpdateFlowsIncrementally), varargs...)
-}
-
-// UpdatePmConfig mocks base method.
-func (m *MockAdapterServiceClient) UpdatePmConfig(ctx context.Context, in *inter_container.PmConfigsInfo, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "UpdatePmConfig", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdatePmConfig indicates an expected call of UpdatePmConfig.
-func (mr *MockAdapterServiceClientMockRecorder) UpdatePmConfig(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePmConfig", reflect.TypeOf((*MockAdapterServiceClient)(nil).UpdatePmConfig), varargs...)
-}
-
-// MockAdapterServiceServer is a mock of AdapterServiceServer interface.
-type MockAdapterServiceServer struct {
-	ctrl     *gomock.Controller
-	recorder *MockAdapterServiceServerMockRecorder
-}
-
-// MockAdapterServiceServerMockRecorder is the mock recorder for MockAdapterServiceServer.
-type MockAdapterServiceServerMockRecorder struct {
-	mock *MockAdapterServiceServer
-}
-
-// NewMockAdapterServiceServer creates a new mock instance.
-func NewMockAdapterServiceServer(ctrl *gomock.Controller) *MockAdapterServiceServer {
-	mock := &MockAdapterServiceServer{ctrl: ctrl}
-	mock.recorder = &MockAdapterServiceServerMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockAdapterServiceServer) EXPECT() *MockAdapterServiceServerMockRecorder {
-	return m.recorder
-}
-
-// AbortOnuImageUpgrade mocks base method.
-func (m *MockAdapterServiceServer) AbortOnuImageUpgrade(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "AbortOnuImageUpgrade", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// AbortOnuImageUpgrade indicates an expected call of AbortOnuImageUpgrade.
-func (mr *MockAdapterServiceServerMockRecorder) AbortOnuImageUpgrade(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortOnuImageUpgrade", reflect.TypeOf((*MockAdapterServiceServer)(nil).AbortOnuImageUpgrade), arg0, arg1)
-}
-
-// ActivateImageUpdate mocks base method.
-func (m *MockAdapterServiceServer) ActivateImageUpdate(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ActivateImageUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
-func (mr *MockAdapterServiceServerMockRecorder) ActivateImageUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockAdapterServiceServer)(nil).ActivateImageUpdate), arg0, arg1)
-}
-
-// ActivateOnuImage mocks base method.
-func (m *MockAdapterServiceServer) ActivateOnuImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ActivateOnuImage", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ActivateOnuImage indicates an expected call of ActivateOnuImage.
-func (mr *MockAdapterServiceServerMockRecorder) ActivateOnuImage(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateOnuImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).ActivateOnuImage), arg0, arg1)
-}
-
-// AdoptDevice mocks base method.
-func (m *MockAdapterServiceServer) AdoptDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "AdoptDevice", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// AdoptDevice indicates an expected call of AdoptDevice.
-func (mr *MockAdapterServiceServerMockRecorder) AdoptDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdoptDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).AdoptDevice), arg0, arg1)
-}
-
-// CancelImageDownload mocks base method.
-func (m *MockAdapterServiceServer) CancelImageDownload(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "CancelImageDownload", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// CancelImageDownload indicates an expected call of CancelImageDownload.
-func (mr *MockAdapterServiceServerMockRecorder) CancelImageDownload(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockAdapterServiceServer)(nil).CancelImageDownload), arg0, arg1)
-}
-
-// ChildDeviceLost mocks base method.
-func (m *MockAdapterServiceServer) ChildDeviceLost(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ChildDeviceLost", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDeviceLost indicates an expected call of ChildDeviceLost.
-func (mr *MockAdapterServiceServerMockRecorder) ChildDeviceLost(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceLost", reflect.TypeOf((*MockAdapterServiceServer)(nil).ChildDeviceLost), arg0, arg1)
-}
-
-// CommitOnuImage mocks base method.
-func (m *MockAdapterServiceServer) CommitOnuImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "CommitOnuImage", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// CommitOnuImage indicates an expected call of CommitOnuImage.
-func (mr *MockAdapterServiceServerMockRecorder) CommitOnuImage(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitOnuImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).CommitOnuImage), arg0, arg1)
-}
-
-// DeleteDevice mocks base method.
-func (m *MockAdapterServiceServer) DeleteDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteDevice", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteDevice indicates an expected call of DeleteDevice.
-func (mr *MockAdapterServiceServerMockRecorder) DeleteDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).DeleteDevice), arg0, arg1)
-}
-
-// DisableDevice mocks base method.
-func (m *MockAdapterServiceServer) DisableDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DisableDevice", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DisableDevice indicates an expected call of DisableDevice.
-func (mr *MockAdapterServiceServerMockRecorder) DisableDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).DisableDevice), arg0, arg1)
-}
-
-// DisablePort mocks base method.
-func (m *MockAdapterServiceServer) DisablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DisablePort", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DisablePort indicates an expected call of DisablePort.
-func (mr *MockAdapterServiceServerMockRecorder) DisablePort(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockAdapterServiceServer)(nil).DisablePort), arg0, arg1)
-}
-
-// DownloadImage mocks base method.
-func (m *MockAdapterServiceServer) DownloadImage(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DownloadImage", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DownloadImage indicates an expected call of DownloadImage.
-func (mr *MockAdapterServiceServerMockRecorder) DownloadImage(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).DownloadImage), arg0, arg1)
-}
-
-// DownloadOnuImage mocks base method.
-func (m *MockAdapterServiceServer) DownloadOnuImage(arg0 context.Context, arg1 *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DownloadOnuImage", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DownloadOnuImage indicates an expected call of DownloadOnuImage.
-func (mr *MockAdapterServiceServerMockRecorder) DownloadOnuImage(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadOnuImage", reflect.TypeOf((*MockAdapterServiceServer)(nil).DownloadOnuImage), arg0, arg1)
-}
-
-// EnablePort mocks base method.
-func (m *MockAdapterServiceServer) EnablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "EnablePort", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// EnablePort indicates an expected call of EnablePort.
-func (mr *MockAdapterServiceServerMockRecorder) EnablePort(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockAdapterServiceServer)(nil).EnablePort), arg0, arg1)
-}
-
-// GetExtValue mocks base method.
-func (m *MockAdapterServiceServer) GetExtValue(arg0 context.Context, arg1 *inter_container.GetExtValueMessage) (*common.ReturnValues, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetExtValue", arg0, arg1)
-	ret0, _ := ret[0].(*common.ReturnValues)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetExtValue indicates an expected call of GetExtValue.
-func (mr *MockAdapterServiceServerMockRecorder) GetExtValue(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetExtValue), arg0, arg1)
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockAdapterServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockAdapterServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetHealthStatus), arg0, arg1)
-}
-
-// GetImageDownloadStatus mocks base method.
-func (m *MockAdapterServiceServer) GetImageDownloadStatus(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetImageDownloadStatus", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
-func (mr *MockAdapterServiceServerMockRecorder) GetImageDownloadStatus(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetImageDownloadStatus), arg0, arg1)
-}
-
-// GetOfpDeviceInfo mocks base method.
-func (m *MockAdapterServiceServer) GetOfpDeviceInfo(arg0 context.Context, arg1 *voltha.Device) (*inter_container.SwitchCapability, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetOfpDeviceInfo", arg0, arg1)
-	ret0, _ := ret[0].(*inter_container.SwitchCapability)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetOfpDeviceInfo indicates an expected call of GetOfpDeviceInfo.
-func (mr *MockAdapterServiceServerMockRecorder) GetOfpDeviceInfo(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOfpDeviceInfo", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetOfpDeviceInfo), arg0, arg1)
-}
-
-// GetOnuImageStatus mocks base method.
-func (m *MockAdapterServiceServer) GetOnuImageStatus(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetOnuImageStatus", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetOnuImageStatus indicates an expected call of GetOnuImageStatus.
-func (mr *MockAdapterServiceServerMockRecorder) GetOnuImageStatus(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImageStatus", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetOnuImageStatus), arg0, arg1)
-}
-
-// GetOnuImages mocks base method.
-func (m *MockAdapterServiceServer) GetOnuImages(arg0 context.Context, arg1 *common.ID) (*voltha.OnuImages, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetOnuImages", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.OnuImages)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetOnuImages indicates an expected call of GetOnuImages.
-func (mr *MockAdapterServiceServerMockRecorder) GetOnuImages(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetOnuImages), arg0, arg1)
-}
-
-// GetSingleValue mocks base method.
-func (m *MockAdapterServiceServer) GetSingleValue(arg0 context.Context, arg1 *extension.SingleGetValueRequest) (*extension.SingleGetValueResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetSingleValue", arg0, arg1)
-	ret0, _ := ret[0].(*extension.SingleGetValueResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetSingleValue indicates an expected call of GetSingleValue.
-func (mr *MockAdapterServiceServerMockRecorder) GetSingleValue(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSingleValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).GetSingleValue), arg0, arg1)
-}
-
-// ReEnableDevice mocks base method.
-func (m *MockAdapterServiceServer) ReEnableDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ReEnableDevice", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ReEnableDevice indicates an expected call of ReEnableDevice.
-func (mr *MockAdapterServiceServerMockRecorder) ReEnableDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReEnableDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).ReEnableDevice), arg0, arg1)
-}
-
-// RebootDevice mocks base method.
-func (m *MockAdapterServiceServer) RebootDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "RebootDevice", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// RebootDevice indicates an expected call of RebootDevice.
-func (mr *MockAdapterServiceServerMockRecorder) RebootDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).RebootDevice), arg0, arg1)
-}
-
-// ReconcileDevice mocks base method.
-func (m *MockAdapterServiceServer) ReconcileDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ReconcileDevice", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ReconcileDevice indicates an expected call of ReconcileDevice.
-func (mr *MockAdapterServiceServerMockRecorder) ReconcileDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).ReconcileDevice), arg0, arg1)
-}
-
-// RevertImageUpdate mocks base method.
-func (m *MockAdapterServiceServer) RevertImageUpdate(arg0 context.Context, arg1 *inter_container.ImageDownloadMessage) (*voltha.ImageDownload, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "RevertImageUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.ImageDownload)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// RevertImageUpdate indicates an expected call of RevertImageUpdate.
-func (mr *MockAdapterServiceServerMockRecorder) RevertImageUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockAdapterServiceServer)(nil).RevertImageUpdate), arg0, arg1)
-}
-
-// SelfTestDevice mocks base method.
-func (m *MockAdapterServiceServer) SelfTestDevice(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SelfTestDevice", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SelfTestDevice indicates an expected call of SelfTestDevice.
-func (mr *MockAdapterServiceServerMockRecorder) SelfTestDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTestDevice", reflect.TypeOf((*MockAdapterServiceServer)(nil).SelfTestDevice), arg0, arg1)
-}
-
-// SendPacketOut mocks base method.
-func (m *MockAdapterServiceServer) SendPacketOut(arg0 context.Context, arg1 *inter_container.PacketOut) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SendPacketOut", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SendPacketOut indicates an expected call of SendPacketOut.
-func (mr *MockAdapterServiceServerMockRecorder) SendPacketOut(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketOut", reflect.TypeOf((*MockAdapterServiceServer)(nil).SendPacketOut), arg0, arg1)
-}
-
-// SetExtValue mocks base method.
-func (m *MockAdapterServiceServer) SetExtValue(arg0 context.Context, arg1 *inter_container.SetExtValueMessage) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetExtValue", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SetExtValue indicates an expected call of SetExtValue.
-func (mr *MockAdapterServiceServerMockRecorder) SetExtValue(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).SetExtValue), arg0, arg1)
-}
-
-// SetSingleValue mocks base method.
-func (m *MockAdapterServiceServer) SetSingleValue(arg0 context.Context, arg1 *extension.SingleSetValueRequest) (*extension.SingleSetValueResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SetSingleValue", arg0, arg1)
-	ret0, _ := ret[0].(*extension.SingleSetValueResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SetSingleValue indicates an expected call of SetSingleValue.
-func (mr *MockAdapterServiceServerMockRecorder) SetSingleValue(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSingleValue", reflect.TypeOf((*MockAdapterServiceServer)(nil).SetSingleValue), arg0, arg1)
-}
-
-// SimulateAlarm mocks base method.
-func (m *MockAdapterServiceServer) SimulateAlarm(arg0 context.Context, arg1 *inter_container.SimulateAlarmMessage) (*common.OperationResp, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SimulateAlarm", arg0, arg1)
-	ret0, _ := ret[0].(*common.OperationResp)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SimulateAlarm indicates an expected call of SimulateAlarm.
-func (mr *MockAdapterServiceServerMockRecorder) SimulateAlarm(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockAdapterServiceServer)(nil).SimulateAlarm), arg0, arg1)
-}
-
-// StartOmciTest mocks base method.
-func (m *MockAdapterServiceServer) StartOmciTest(arg0 context.Context, arg1 *inter_container.OMCITest) (*voltha.TestResponse, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "StartOmciTest", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.TestResponse)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// StartOmciTest indicates an expected call of StartOmciTest.
-func (mr *MockAdapterServiceServerMockRecorder) StartOmciTest(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTest", reflect.TypeOf((*MockAdapterServiceServer)(nil).StartOmciTest), arg0, arg1)
-}
-
-// SuppressEvent mocks base method.
-func (m *MockAdapterServiceServer) SuppressEvent(arg0 context.Context, arg1 *voltha.EventFilter) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SuppressEvent", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SuppressEvent indicates an expected call of SuppressEvent.
-func (mr *MockAdapterServiceServerMockRecorder) SuppressEvent(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SuppressEvent", reflect.TypeOf((*MockAdapterServiceServer)(nil).SuppressEvent), arg0, arg1)
-}
-
-// UnSuppressEvent mocks base method.
-func (m *MockAdapterServiceServer) UnSuppressEvent(arg0 context.Context, arg1 *voltha.EventFilter) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UnSuppressEvent", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UnSuppressEvent indicates an expected call of UnSuppressEvent.
-func (mr *MockAdapterServiceServerMockRecorder) UnSuppressEvent(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UnSuppressEvent", reflect.TypeOf((*MockAdapterServiceServer)(nil).UnSuppressEvent), arg0, arg1)
-}
-
-// UpdateFlowsBulk mocks base method.
-func (m *MockAdapterServiceServer) UpdateFlowsBulk(arg0 context.Context, arg1 *inter_container.BulkFlows) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UpdateFlowsBulk", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdateFlowsBulk indicates an expected call of UpdateFlowsBulk.
-func (mr *MockAdapterServiceServerMockRecorder) UpdateFlowsBulk(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsBulk", reflect.TypeOf((*MockAdapterServiceServer)(nil).UpdateFlowsBulk), arg0, arg1)
-}
-
-// UpdateFlowsIncrementally mocks base method.
-func (m *MockAdapterServiceServer) UpdateFlowsIncrementally(arg0 context.Context, arg1 *inter_container.IncrementalFlows) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UpdateFlowsIncrementally", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdateFlowsIncrementally indicates an expected call of UpdateFlowsIncrementally.
-func (mr *MockAdapterServiceServerMockRecorder) UpdateFlowsIncrementally(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateFlowsIncrementally", reflect.TypeOf((*MockAdapterServiceServer)(nil).UpdateFlowsIncrementally), arg0, arg1)
-}
-
-// UpdatePmConfig mocks base method.
-func (m *MockAdapterServiceServer) UpdatePmConfig(arg0 context.Context, arg1 *inter_container.PmConfigsInfo) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UpdatePmConfig", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdatePmConfig indicates an expected call of UpdatePmConfig.
-func (mr *MockAdapterServiceServerMockRecorder) UpdatePmConfig(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePmConfig", reflect.TypeOf((*MockAdapterServiceServer)(nil).UpdatePmConfig), arg0, arg1)
-}
-
-// MockOnuInterAdapterServiceClient is a mock of OnuInterAdapterServiceClient interface.
-type MockOnuInterAdapterServiceClient struct {
-	ctrl     *gomock.Controller
-	recorder *MockOnuInterAdapterServiceClientMockRecorder
-}
-
-// MockOnuInterAdapterServiceClientMockRecorder is the mock recorder for MockOnuInterAdapterServiceClient.
-type MockOnuInterAdapterServiceClientMockRecorder struct {
-	mock *MockOnuInterAdapterServiceClient
-}
-
-// NewMockOnuInterAdapterServiceClient creates a new mock instance.
-func NewMockOnuInterAdapterServiceClient(ctrl *gomock.Controller) *MockOnuInterAdapterServiceClient {
-	mock := &MockOnuInterAdapterServiceClient{ctrl: ctrl}
-	mock.recorder = &MockOnuInterAdapterServiceClientMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockOnuInterAdapterServiceClient) EXPECT() *MockOnuInterAdapterServiceClientMockRecorder {
-	return m.recorder
-}
-
-// DeleteGemPort mocks base method.
-func (m *MockOnuInterAdapterServiceClient) DeleteGemPort(ctx context.Context, in *inter_container.DeleteGemPortMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DeleteGemPort", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteGemPort indicates an expected call of DeleteGemPort.
-func (mr *MockOnuInterAdapterServiceClientMockRecorder) DeleteGemPort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteGemPort", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).DeleteGemPort), varargs...)
-}
-
-// DeleteTCont mocks base method.
-func (m *MockOnuInterAdapterServiceClient) DeleteTCont(ctx context.Context, in *inter_container.DeleteTcontMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DeleteTCont", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteTCont indicates an expected call of DeleteTCont.
-func (mr *MockOnuInterAdapterServiceClientMockRecorder) DeleteTCont(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTCont", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).DeleteTCont), varargs...)
-}
-
-// DownloadTechProfile mocks base method.
-func (m *MockOnuInterAdapterServiceClient) DownloadTechProfile(ctx context.Context, in *inter_container.TechProfileDownloadMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DownloadTechProfile", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DownloadTechProfile indicates an expected call of DownloadTechProfile.
-func (mr *MockOnuInterAdapterServiceClientMockRecorder) DownloadTechProfile(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadTechProfile", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).DownloadTechProfile), varargs...)
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockOnuInterAdapterServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockOnuInterAdapterServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).GetHealthStatus), varargs...)
-}
-
-// OmciResponse mocks base method.
-func (m *MockOnuInterAdapterServiceClient) OmciResponse(ctx context.Context, in *inter_container.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "OmciResponse", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// OmciResponse indicates an expected call of OmciResponse.
-func (mr *MockOnuInterAdapterServiceClientMockRecorder) OmciResponse(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OmciResponse", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).OmciResponse), varargs...)
-}
-
-// OnuIndication mocks base method.
-func (m *MockOnuInterAdapterServiceClient) OnuIndication(ctx context.Context, in *inter_container.OnuIndicationMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "OnuIndication", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// OnuIndication indicates an expected call of OnuIndication.
-func (mr *MockOnuInterAdapterServiceClientMockRecorder) OnuIndication(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnuIndication", reflect.TypeOf((*MockOnuInterAdapterServiceClient)(nil).OnuIndication), varargs...)
-}
-
-// MockOnuInterAdapterServiceServer is a mock of OnuInterAdapterServiceServer interface.
-type MockOnuInterAdapterServiceServer struct {
-	ctrl     *gomock.Controller
-	recorder *MockOnuInterAdapterServiceServerMockRecorder
-}
-
-// MockOnuInterAdapterServiceServerMockRecorder is the mock recorder for MockOnuInterAdapterServiceServer.
-type MockOnuInterAdapterServiceServerMockRecorder struct {
-	mock *MockOnuInterAdapterServiceServer
-}
-
-// NewMockOnuInterAdapterServiceServer creates a new mock instance.
-func NewMockOnuInterAdapterServiceServer(ctrl *gomock.Controller) *MockOnuInterAdapterServiceServer {
-	mock := &MockOnuInterAdapterServiceServer{ctrl: ctrl}
-	mock.recorder = &MockOnuInterAdapterServiceServerMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockOnuInterAdapterServiceServer) EXPECT() *MockOnuInterAdapterServiceServerMockRecorder {
-	return m.recorder
-}
-
-// DeleteGemPort mocks base method.
-func (m *MockOnuInterAdapterServiceServer) DeleteGemPort(arg0 context.Context, arg1 *inter_container.DeleteGemPortMessage) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteGemPort", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteGemPort indicates an expected call of DeleteGemPort.
-func (mr *MockOnuInterAdapterServiceServerMockRecorder) DeleteGemPort(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteGemPort", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).DeleteGemPort), arg0, arg1)
-}
-
-// DeleteTCont mocks base method.
-func (m *MockOnuInterAdapterServiceServer) DeleteTCont(arg0 context.Context, arg1 *inter_container.DeleteTcontMessage) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteTCont", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteTCont indicates an expected call of DeleteTCont.
-func (mr *MockOnuInterAdapterServiceServerMockRecorder) DeleteTCont(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTCont", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).DeleteTCont), arg0, arg1)
-}
-
-// DownloadTechProfile mocks base method.
-func (m *MockOnuInterAdapterServiceServer) DownloadTechProfile(arg0 context.Context, arg1 *inter_container.TechProfileDownloadMessage) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DownloadTechProfile", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DownloadTechProfile indicates an expected call of DownloadTechProfile.
-func (mr *MockOnuInterAdapterServiceServerMockRecorder) DownloadTechProfile(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadTechProfile", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).DownloadTechProfile), arg0, arg1)
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockOnuInterAdapterServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockOnuInterAdapterServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).GetHealthStatus), arg0, arg1)
-}
-
-// OmciResponse mocks base method.
-func (m *MockOnuInterAdapterServiceServer) OmciResponse(arg0 context.Context, arg1 *inter_container.OmciMessage) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OmciResponse", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// OmciResponse indicates an expected call of OmciResponse.
-func (mr *MockOnuInterAdapterServiceServerMockRecorder) OmciResponse(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OmciResponse", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).OmciResponse), arg0, arg1)
-}
-
-// OnuIndication mocks base method.
-func (m *MockOnuInterAdapterServiceServer) OnuIndication(arg0 context.Context, arg1 *inter_container.OnuIndicationMessage) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "OnuIndication", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// OnuIndication indicates an expected call of OnuIndication.
-func (mr *MockOnuInterAdapterServiceServerMockRecorder) OnuIndication(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnuIndication", reflect.TypeOf((*MockOnuInterAdapterServiceServer)(nil).OnuIndication), arg0, arg1)
-}
-
-// MockOltInterAdapterServiceClient is a mock of OltInterAdapterServiceClient interface.
-type MockOltInterAdapterServiceClient struct {
-	ctrl     *gomock.Controller
-	recorder *MockOltInterAdapterServiceClientMockRecorder
-}
-
-// MockOltInterAdapterServiceClientMockRecorder is the mock recorder for MockOltInterAdapterServiceClient.
-type MockOltInterAdapterServiceClientMockRecorder struct {
-	mock *MockOltInterAdapterServiceClient
-}
-
-// NewMockOltInterAdapterServiceClient creates a new mock instance.
-func NewMockOltInterAdapterServiceClient(ctrl *gomock.Controller) *MockOltInterAdapterServiceClient {
-	mock := &MockOltInterAdapterServiceClient{ctrl: ctrl}
-	mock.recorder = &MockOltInterAdapterServiceClientMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockOltInterAdapterServiceClient) EXPECT() *MockOltInterAdapterServiceClientMockRecorder {
-	return m.recorder
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockOltInterAdapterServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockOltInterAdapterServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOltInterAdapterServiceClient)(nil).GetHealthStatus), varargs...)
-}
-
-// GetTechProfileInstance mocks base method.
-func (m *MockOltInterAdapterServiceClient) GetTechProfileInstance(ctx context.Context, in *inter_container.TechProfileInstanceRequestMessage, opts ...grpc.CallOption) (*inter_container.TechProfileDownloadMessage, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetTechProfileInstance", varargs...)
-	ret0, _ := ret[0].(*inter_container.TechProfileDownloadMessage)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetTechProfileInstance indicates an expected call of GetTechProfileInstance.
-func (mr *MockOltInterAdapterServiceClientMockRecorder) GetTechProfileInstance(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTechProfileInstance", reflect.TypeOf((*MockOltInterAdapterServiceClient)(nil).GetTechProfileInstance), varargs...)
-}
-
-// ProxyOmciRequest mocks base method.
-func (m *MockOltInterAdapterServiceClient) ProxyOmciRequest(ctx context.Context, in *inter_container.OmciMessage, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ProxyOmciRequest", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ProxyOmciRequest indicates an expected call of ProxyOmciRequest.
-func (mr *MockOltInterAdapterServiceClientMockRecorder) ProxyOmciRequest(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProxyOmciRequest", reflect.TypeOf((*MockOltInterAdapterServiceClient)(nil).ProxyOmciRequest), varargs...)
-}
-
-// MockOltInterAdapterServiceServer is a mock of OltInterAdapterServiceServer interface.
-type MockOltInterAdapterServiceServer struct {
-	ctrl     *gomock.Controller
-	recorder *MockOltInterAdapterServiceServerMockRecorder
-}
-
-// MockOltInterAdapterServiceServerMockRecorder is the mock recorder for MockOltInterAdapterServiceServer.
-type MockOltInterAdapterServiceServerMockRecorder struct {
-	mock *MockOltInterAdapterServiceServer
-}
-
-// NewMockOltInterAdapterServiceServer creates a new mock instance.
-func NewMockOltInterAdapterServiceServer(ctrl *gomock.Controller) *MockOltInterAdapterServiceServer {
-	mock := &MockOltInterAdapterServiceServer{ctrl: ctrl}
-	mock.recorder = &MockOltInterAdapterServiceServerMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockOltInterAdapterServiceServer) EXPECT() *MockOltInterAdapterServiceServerMockRecorder {
-	return m.recorder
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockOltInterAdapterServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockOltInterAdapterServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockOltInterAdapterServiceServer)(nil).GetHealthStatus), arg0, arg1)
-}
-
-// GetTechProfileInstance mocks base method.
-func (m *MockOltInterAdapterServiceServer) GetTechProfileInstance(arg0 context.Context, arg1 *inter_container.TechProfileInstanceRequestMessage) (*inter_container.TechProfileDownloadMessage, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetTechProfileInstance", arg0, arg1)
-	ret0, _ := ret[0].(*inter_container.TechProfileDownloadMessage)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetTechProfileInstance indicates an expected call of GetTechProfileInstance.
-func (mr *MockOltInterAdapterServiceServerMockRecorder) GetTechProfileInstance(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTechProfileInstance", reflect.TypeOf((*MockOltInterAdapterServiceServer)(nil).GetTechProfileInstance), arg0, arg1)
-}
-
-// ProxyOmciRequest mocks base method.
-func (m *MockOltInterAdapterServiceServer) ProxyOmciRequest(arg0 context.Context, arg1 *inter_container.OmciMessage) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ProxyOmciRequest", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ProxyOmciRequest indicates an expected call of ProxyOmciRequest.
-func (mr *MockOltInterAdapterServiceServerMockRecorder) ProxyOmciRequest(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProxyOmciRequest", reflect.TypeOf((*MockOltInterAdapterServiceServer)(nil).ProxyOmciRequest), arg0, arg1)
-}
diff --git a/pkg/mocks/grpc/mock_core_services.go b/pkg/mocks/grpc/mock_core_services.go
deleted file mode 100644
index 49abae7..0000000
--- a/pkg/mocks/grpc/mock_core_services.go
+++ /dev/null
@@ -1,917 +0,0 @@
-/*
- * Copyright 2021-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.
- */
-// Code generated by MockGen. DO NOT EDIT.
-// Source: core.pb.go
-
-package grpc
-
-import (
-	context "context"
-	reflect "reflect"
-
-	gomock "github.com/golang/mock/gomock"
-	empty "github.com/golang/protobuf/ptypes/empty"
-	common "github.com/opencord/voltha-protos/v5/go/common"
-	inter_container "github.com/opencord/voltha-protos/v5/go/inter_container"
-	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
-	grpc "google.golang.org/grpc"
-)
-
-// MockCoreServiceClient is a mock of CoreServiceClient interface.
-type MockCoreServiceClient struct {
-	ctrl     *gomock.Controller
-	recorder *MockCoreServiceClientMockRecorder
-}
-
-// MockCoreServiceClientMockRecorder is the mock recorder for MockCoreServiceClient.
-type MockCoreServiceClientMockRecorder struct {
-	mock *MockCoreServiceClient
-}
-
-// NewMockCoreServiceClient creates a new mock instance.
-func NewMockCoreServiceClient(ctrl *gomock.Controller) *MockCoreServiceClient {
-	mock := &MockCoreServiceClient{ctrl: ctrl}
-	mock.recorder = &MockCoreServiceClientMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockCoreServiceClient) EXPECT() *MockCoreServiceClientMockRecorder {
-	return m.recorder
-}
-
-// ChildDeviceDetected mocks base method.
-func (m *MockCoreServiceClient) ChildDeviceDetected(ctx context.Context, in *inter_container.DeviceDiscovery, opts ...grpc.CallOption) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ChildDeviceDetected", varargs...)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDeviceDetected indicates an expected call of ChildDeviceDetected.
-func (mr *MockCoreServiceClientMockRecorder) ChildDeviceDetected(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceDetected", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDeviceDetected), varargs...)
-}
-
-// ChildDevicesDetected mocks base method.
-func (m *MockCoreServiceClient) ChildDevicesDetected(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ChildDevicesDetected", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDevicesDetected indicates an expected call of ChildDevicesDetected.
-func (mr *MockCoreServiceClientMockRecorder) ChildDevicesDetected(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesDetected", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDevicesDetected), varargs...)
-}
-
-// ChildDevicesLost mocks base method.
-func (m *MockCoreServiceClient) ChildDevicesLost(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ChildDevicesLost", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDevicesLost indicates an expected call of ChildDevicesLost.
-func (mr *MockCoreServiceClientMockRecorder) ChildDevicesLost(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesLost", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDevicesLost), varargs...)
-}
-
-// ChildrenStateUpdate mocks base method.
-func (m *MockCoreServiceClient) ChildrenStateUpdate(ctx context.Context, in *inter_container.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ChildrenStateUpdate", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildrenStateUpdate indicates an expected call of ChildrenStateUpdate.
-func (mr *MockCoreServiceClientMockRecorder) ChildrenStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildrenStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildrenStateUpdate), varargs...)
-}
-
-// DeleteAllPorts mocks base method.
-func (m *MockCoreServiceClient) DeleteAllPorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DeleteAllPorts", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteAllPorts indicates an expected call of DeleteAllPorts.
-func (mr *MockCoreServiceClientMockRecorder) DeleteAllPorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllPorts", reflect.TypeOf((*MockCoreServiceClient)(nil).DeleteAllPorts), varargs...)
-}
-
-// DevicePMConfigUpdate mocks base method.
-func (m *MockCoreServiceClient) DevicePMConfigUpdate(ctx context.Context, in *voltha.PmConfigs, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DevicePMConfigUpdate", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DevicePMConfigUpdate indicates an expected call of DevicePMConfigUpdate.
-func (mr *MockCoreServiceClientMockRecorder) DevicePMConfigUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DevicePMConfigUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DevicePMConfigUpdate), varargs...)
-}
-
-// DeviceReasonUpdate mocks base method.
-func (m *MockCoreServiceClient) DeviceReasonUpdate(ctx context.Context, in *inter_container.DeviceReason, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DeviceReasonUpdate", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeviceReasonUpdate indicates an expected call of DeviceReasonUpdate.
-func (mr *MockCoreServiceClientMockRecorder) DeviceReasonUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceReasonUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceReasonUpdate), varargs...)
-}
-
-// DeviceStateUpdate mocks base method.
-func (m *MockCoreServiceClient) DeviceStateUpdate(ctx context.Context, in *inter_container.DeviceStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DeviceStateUpdate", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeviceStateUpdate indicates an expected call of DeviceStateUpdate.
-func (mr *MockCoreServiceClientMockRecorder) DeviceStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceStateUpdate), varargs...)
-}
-
-// DeviceUpdate mocks base method.
-func (m *MockCoreServiceClient) DeviceUpdate(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "DeviceUpdate", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeviceUpdate indicates an expected call of DeviceUpdate.
-func (mr *MockCoreServiceClientMockRecorder) DeviceUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceUpdate), varargs...)
-}
-
-// GetChildDevice mocks base method.
-func (m *MockCoreServiceClient) GetChildDevice(ctx context.Context, in *inter_container.ChildDeviceFilter, opts ...grpc.CallOption) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetChildDevice", varargs...)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetChildDevice indicates an expected call of GetChildDevice.
-func (mr *MockCoreServiceClientMockRecorder) GetChildDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevice", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDevice), varargs...)
-}
-
-// GetChildDeviceWithProxyAddress mocks base method.
-func (m *MockCoreServiceClient) GetChildDeviceWithProxyAddress(ctx context.Context, in *voltha.Device_ProxyAddress, opts ...grpc.CallOption) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetChildDeviceWithProxyAddress", varargs...)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetChildDeviceWithProxyAddress indicates an expected call of GetChildDeviceWithProxyAddress.
-func (mr *MockCoreServiceClientMockRecorder) GetChildDeviceWithProxyAddress(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDeviceWithProxyAddress", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDeviceWithProxyAddress), varargs...)
-}
-
-// GetChildDevices mocks base method.
-func (m *MockCoreServiceClient) GetChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Devices, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetChildDevices", varargs...)
-	ret0, _ := ret[0].(*voltha.Devices)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetChildDevices indicates an expected call of GetChildDevices.
-func (mr *MockCoreServiceClientMockRecorder) GetChildDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevices", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDevices), varargs...)
-}
-
-// GetDevice mocks base method.
-func (m *MockCoreServiceClient) GetDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetDevice", varargs...)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetDevice indicates an expected call of GetDevice.
-func (mr *MockCoreServiceClientMockRecorder) GetDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockCoreServiceClient)(nil).GetDevice), varargs...)
-}
-
-// GetDevicePort mocks base method.
-func (m *MockCoreServiceClient) GetDevicePort(ctx context.Context, in *inter_container.PortFilter, opts ...grpc.CallOption) (*voltha.Port, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetDevicePort", varargs...)
-	ret0, _ := ret[0].(*voltha.Port)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetDevicePort indicates an expected call of GetDevicePort.
-func (mr *MockCoreServiceClientMockRecorder) GetDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevicePort", reflect.TypeOf((*MockCoreServiceClient)(nil).GetDevicePort), varargs...)
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockCoreServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockCoreServiceClientMockRecorder) GetHealthStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockCoreServiceClient)(nil).GetHealthStatus), varargs...)
-}
-
-// GetPorts mocks base method.
-func (m *MockCoreServiceClient) GetPorts(ctx context.Context, in *inter_container.PortFilter, opts ...grpc.CallOption) (*voltha.Ports, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "GetPorts", varargs...)
-	ret0, _ := ret[0].(*voltha.Ports)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetPorts indicates an expected call of GetPorts.
-func (mr *MockCoreServiceClientMockRecorder) GetPorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPorts", reflect.TypeOf((*MockCoreServiceClient)(nil).GetPorts), varargs...)
-}
-
-// ListDevicePorts mocks base method.
-func (m *MockCoreServiceClient) ListDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Ports, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ListDevicePorts", varargs...)
-	ret0, _ := ret[0].(*voltha.Ports)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ListDevicePorts indicates an expected call of ListDevicePorts.
-func (mr *MockCoreServiceClientMockRecorder) ListDevicePorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockCoreServiceClient)(nil).ListDevicePorts), varargs...)
-}
-
-// PortCreated mocks base method.
-func (m *MockCoreServiceClient) PortCreated(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "PortCreated", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// PortCreated indicates an expected call of PortCreated.
-func (mr *MockCoreServiceClientMockRecorder) PortCreated(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortCreated", reflect.TypeOf((*MockCoreServiceClient)(nil).PortCreated), varargs...)
-}
-
-// PortStateUpdate mocks base method.
-func (m *MockCoreServiceClient) PortStateUpdate(ctx context.Context, in *inter_container.PortState, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "PortStateUpdate", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// PortStateUpdate indicates an expected call of PortStateUpdate.
-func (mr *MockCoreServiceClientMockRecorder) PortStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).PortStateUpdate), varargs...)
-}
-
-// PortsStateUpdate mocks base method.
-func (m *MockCoreServiceClient) PortsStateUpdate(ctx context.Context, in *inter_container.PortStateFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "PortsStateUpdate", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// PortsStateUpdate indicates an expected call of PortsStateUpdate.
-func (mr *MockCoreServiceClientMockRecorder) PortsStateUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortsStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).PortsStateUpdate), varargs...)
-}
-
-// ReconcileChildDevices mocks base method.
-func (m *MockCoreServiceClient) ReconcileChildDevices(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "ReconcileChildDevices", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ReconcileChildDevices indicates an expected call of ReconcileChildDevices.
-func (mr *MockCoreServiceClientMockRecorder) ReconcileChildDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileChildDevices", reflect.TypeOf((*MockCoreServiceClient)(nil).ReconcileChildDevices), varargs...)
-}
-
-// RegisterAdapter mocks base method.
-func (m *MockCoreServiceClient) RegisterAdapter(ctx context.Context, in *inter_container.AdapterRegistration, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "RegisterAdapter", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// RegisterAdapter indicates an expected call of RegisterAdapter.
-func (mr *MockCoreServiceClientMockRecorder) RegisterAdapter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterAdapter", reflect.TypeOf((*MockCoreServiceClient)(nil).RegisterAdapter), varargs...)
-}
-
-// SendPacketIn mocks base method.
-func (m *MockCoreServiceClient) SendPacketIn(ctx context.Context, in *inter_container.PacketIn, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "SendPacketIn", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SendPacketIn indicates an expected call of SendPacketIn.
-func (mr *MockCoreServiceClientMockRecorder) SendPacketIn(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketIn", reflect.TypeOf((*MockCoreServiceClient)(nil).SendPacketIn), varargs...)
-}
-
-// UpdateImageDownload mocks base method.
-func (m *MockCoreServiceClient) UpdateImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	varargs := []interface{}{ctx, in}
-	for _, a := range opts {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "UpdateImageDownload", varargs...)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdateImageDownload indicates an expected call of UpdateImageDownload.
-func (mr *MockCoreServiceClientMockRecorder) UpdateImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	varargs := append([]interface{}{ctx, in}, opts...)
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateImageDownload", reflect.TypeOf((*MockCoreServiceClient)(nil).UpdateImageDownload), varargs...)
-}
-
-// MockCoreServiceServer is a mock of CoreServiceServer interface.
-type MockCoreServiceServer struct {
-	ctrl     *gomock.Controller
-	recorder *MockCoreServiceServerMockRecorder
-}
-
-// MockCoreServiceServerMockRecorder is the mock recorder for MockCoreServiceServer.
-type MockCoreServiceServerMockRecorder struct {
-	mock *MockCoreServiceServer
-}
-
-// NewMockCoreServiceServer creates a new mock instance.
-func NewMockCoreServiceServer(ctrl *gomock.Controller) *MockCoreServiceServer {
-	mock := &MockCoreServiceServer{ctrl: ctrl}
-	mock.recorder = &MockCoreServiceServerMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockCoreServiceServer) EXPECT() *MockCoreServiceServerMockRecorder {
-	return m.recorder
-}
-
-// ChildDeviceDetected mocks base method.
-func (m *MockCoreServiceServer) ChildDeviceDetected(arg0 context.Context, arg1 *inter_container.DeviceDiscovery) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ChildDeviceDetected", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDeviceDetected indicates an expected call of ChildDeviceDetected.
-func (mr *MockCoreServiceServerMockRecorder) ChildDeviceDetected(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceDetected", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDeviceDetected), arg0, arg1)
-}
-
-// ChildDevicesDetected mocks base method.
-func (m *MockCoreServiceServer) ChildDevicesDetected(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ChildDevicesDetected", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDevicesDetected indicates an expected call of ChildDevicesDetected.
-func (mr *MockCoreServiceServerMockRecorder) ChildDevicesDetected(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesDetected", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDevicesDetected), arg0, arg1)
-}
-
-// ChildDevicesLost mocks base method.
-func (m *MockCoreServiceServer) ChildDevicesLost(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ChildDevicesLost", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildDevicesLost indicates an expected call of ChildDevicesLost.
-func (mr *MockCoreServiceServerMockRecorder) ChildDevicesLost(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesLost", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDevicesLost), arg0, arg1)
-}
-
-// ChildrenStateUpdate mocks base method.
-func (m *MockCoreServiceServer) ChildrenStateUpdate(arg0 context.Context, arg1 *inter_container.DeviceStateFilter) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ChildrenStateUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ChildrenStateUpdate indicates an expected call of ChildrenStateUpdate.
-func (mr *MockCoreServiceServerMockRecorder) ChildrenStateUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildrenStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildrenStateUpdate), arg0, arg1)
-}
-
-// DeleteAllPorts mocks base method.
-func (m *MockCoreServiceServer) DeleteAllPorts(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteAllPorts", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeleteAllPorts indicates an expected call of DeleteAllPorts.
-func (mr *MockCoreServiceServerMockRecorder) DeleteAllPorts(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllPorts", reflect.TypeOf((*MockCoreServiceServer)(nil).DeleteAllPorts), arg0, arg1)
-}
-
-// DevicePMConfigUpdate mocks base method.
-func (m *MockCoreServiceServer) DevicePMConfigUpdate(arg0 context.Context, arg1 *voltha.PmConfigs) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DevicePMConfigUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DevicePMConfigUpdate indicates an expected call of DevicePMConfigUpdate.
-func (mr *MockCoreServiceServerMockRecorder) DevicePMConfigUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DevicePMConfigUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DevicePMConfigUpdate), arg0, arg1)
-}
-
-// DeviceReasonUpdate mocks base method.
-func (m *MockCoreServiceServer) DeviceReasonUpdate(arg0 context.Context, arg1 *inter_container.DeviceReason) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeviceReasonUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeviceReasonUpdate indicates an expected call of DeviceReasonUpdate.
-func (mr *MockCoreServiceServerMockRecorder) DeviceReasonUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceReasonUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceReasonUpdate), arg0, arg1)
-}
-
-// DeviceStateUpdate mocks base method.
-func (m *MockCoreServiceServer) DeviceStateUpdate(arg0 context.Context, arg1 *inter_container.DeviceStateFilter) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeviceStateUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeviceStateUpdate indicates an expected call of DeviceStateUpdate.
-func (mr *MockCoreServiceServerMockRecorder) DeviceStateUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceStateUpdate), arg0, arg1)
-}
-
-// DeviceUpdate mocks base method.
-func (m *MockCoreServiceServer) DeviceUpdate(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeviceUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// DeviceUpdate indicates an expected call of DeviceUpdate.
-func (mr *MockCoreServiceServerMockRecorder) DeviceUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceUpdate), arg0, arg1)
-}
-
-// GetChildDevice mocks base method.
-func (m *MockCoreServiceServer) GetChildDevice(arg0 context.Context, arg1 *inter_container.ChildDeviceFilter) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetChildDevice", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetChildDevice indicates an expected call of GetChildDevice.
-func (mr *MockCoreServiceServerMockRecorder) GetChildDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevice", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDevice), arg0, arg1)
-}
-
-// GetChildDeviceWithProxyAddress mocks base method.
-func (m *MockCoreServiceServer) GetChildDeviceWithProxyAddress(arg0 context.Context, arg1 *voltha.Device_ProxyAddress) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetChildDeviceWithProxyAddress", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetChildDeviceWithProxyAddress indicates an expected call of GetChildDeviceWithProxyAddress.
-func (mr *MockCoreServiceServerMockRecorder) GetChildDeviceWithProxyAddress(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDeviceWithProxyAddress", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDeviceWithProxyAddress), arg0, arg1)
-}
-
-// GetChildDevices mocks base method.
-func (m *MockCoreServiceServer) GetChildDevices(arg0 context.Context, arg1 *common.ID) (*voltha.Devices, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetChildDevices", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Devices)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetChildDevices indicates an expected call of GetChildDevices.
-func (mr *MockCoreServiceServerMockRecorder) GetChildDevices(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevices", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDevices), arg0, arg1)
-}
-
-// GetDevice mocks base method.
-func (m *MockCoreServiceServer) GetDevice(arg0 context.Context, arg1 *common.ID) (*voltha.Device, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetDevice", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Device)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetDevice indicates an expected call of GetDevice.
-func (mr *MockCoreServiceServerMockRecorder) GetDevice(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockCoreServiceServer)(nil).GetDevice), arg0, arg1)
-}
-
-// GetDevicePort mocks base method.
-func (m *MockCoreServiceServer) GetDevicePort(arg0 context.Context, arg1 *inter_container.PortFilter) (*voltha.Port, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetDevicePort", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Port)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetDevicePort indicates an expected call of GetDevicePort.
-func (mr *MockCoreServiceServerMockRecorder) GetDevicePort(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevicePort", reflect.TypeOf((*MockCoreServiceServer)(nil).GetDevicePort), arg0, arg1)
-}
-
-// GetHealthStatus mocks base method.
-func (m *MockCoreServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.HealthStatus)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetHealthStatus indicates an expected call of GetHealthStatus.
-func (mr *MockCoreServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockCoreServiceServer)(nil).GetHealthStatus), arg0, arg1)
-}
-
-// GetPorts mocks base method.
-func (m *MockCoreServiceServer) GetPorts(arg0 context.Context, arg1 *inter_container.PortFilter) (*voltha.Ports, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetPorts", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Ports)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetPorts indicates an expected call of GetPorts.
-func (mr *MockCoreServiceServerMockRecorder) GetPorts(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPorts", reflect.TypeOf((*MockCoreServiceServer)(nil).GetPorts), arg0, arg1)
-}
-
-// ListDevicePorts mocks base method.
-func (m *MockCoreServiceServer) ListDevicePorts(arg0 context.Context, arg1 *common.ID) (*voltha.Ports, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ListDevicePorts", arg0, arg1)
-	ret0, _ := ret[0].(*voltha.Ports)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ListDevicePorts indicates an expected call of ListDevicePorts.
-func (mr *MockCoreServiceServerMockRecorder) ListDevicePorts(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockCoreServiceServer)(nil).ListDevicePorts), arg0, arg1)
-}
-
-// PortCreated mocks base method.
-func (m *MockCoreServiceServer) PortCreated(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "PortCreated", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// PortCreated indicates an expected call of PortCreated.
-func (mr *MockCoreServiceServerMockRecorder) PortCreated(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortCreated", reflect.TypeOf((*MockCoreServiceServer)(nil).PortCreated), arg0, arg1)
-}
-
-// PortStateUpdate mocks base method.
-func (m *MockCoreServiceServer) PortStateUpdate(arg0 context.Context, arg1 *inter_container.PortState) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "PortStateUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// PortStateUpdate indicates an expected call of PortStateUpdate.
-func (mr *MockCoreServiceServerMockRecorder) PortStateUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).PortStateUpdate), arg0, arg1)
-}
-
-// PortsStateUpdate mocks base method.
-func (m *MockCoreServiceServer) PortsStateUpdate(arg0 context.Context, arg1 *inter_container.PortStateFilter) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "PortsStateUpdate", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// PortsStateUpdate indicates an expected call of PortsStateUpdate.
-func (mr *MockCoreServiceServerMockRecorder) PortsStateUpdate(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortsStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).PortsStateUpdate), arg0, arg1)
-}
-
-// ReconcileChildDevices mocks base method.
-func (m *MockCoreServiceServer) ReconcileChildDevices(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "ReconcileChildDevices", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// ReconcileChildDevices indicates an expected call of ReconcileChildDevices.
-func (mr *MockCoreServiceServerMockRecorder) ReconcileChildDevices(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileChildDevices", reflect.TypeOf((*MockCoreServiceServer)(nil).ReconcileChildDevices), arg0, arg1)
-}
-
-// RegisterAdapter mocks base method.
-func (m *MockCoreServiceServer) RegisterAdapter(arg0 context.Context, arg1 *inter_container.AdapterRegistration) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "RegisterAdapter", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// RegisterAdapter indicates an expected call of RegisterAdapter.
-func (mr *MockCoreServiceServerMockRecorder) RegisterAdapter(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterAdapter", reflect.TypeOf((*MockCoreServiceServer)(nil).RegisterAdapter), arg0, arg1)
-}
-
-// SendPacketIn mocks base method.
-func (m *MockCoreServiceServer) SendPacketIn(arg0 context.Context, arg1 *inter_container.PacketIn) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "SendPacketIn", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// SendPacketIn indicates an expected call of SendPacketIn.
-func (mr *MockCoreServiceServerMockRecorder) SendPacketIn(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketIn", reflect.TypeOf((*MockCoreServiceServer)(nil).SendPacketIn), arg0, arg1)
-}
-
-// UpdateImageDownload mocks base method.
-func (m *MockCoreServiceServer) UpdateImageDownload(arg0 context.Context, arg1 *voltha.ImageDownload) (*empty.Empty, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "UpdateImageDownload", arg0, arg1)
-	ret0, _ := ret[0].(*empty.Empty)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// UpdateImageDownload indicates an expected call of UpdateImageDownload.
-func (mr *MockCoreServiceServerMockRecorder) UpdateImageDownload(arg0, arg1 interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateImageDownload", reflect.TypeOf((*MockCoreServiceServer)(nil).UpdateImageDownload), arg0, arg1)
-}
diff --git a/pkg/mocks/grpc/mock_grpc_server.go b/pkg/mocks/grpc/mock_grpc_server.go
index 789fc8b..63c7f95 100644
--- a/pkg/mocks/grpc/mock_grpc_server.go
+++ b/pkg/mocks/grpc/mock_grpc_server.go
@@ -22,8 +22,8 @@
 	vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
 	"github.com/opencord/voltha-lib-go/v7/pkg/log"
 	"github.com/opencord/voltha-lib-go/v7/pkg/probe"
-	"github.com/opencord/voltha-protos/v5/go/adapter_services"
-	"github.com/opencord/voltha-protos/v5/go/core"
+	"github.com/opencord/voltha-protos/v5/go/adapter_service"
+	"github.com/opencord/voltha-protos/v5/go/core_service"
 	"github.com/phayes/freeport"
 	"google.golang.org/grpc"
 )
@@ -60,15 +60,15 @@
 	return s, nil
 }
 
-func (s *MockGRPCServer) AddCoreService(ctx context.Context, srv core.CoreServiceServer) {
+func (s *MockGRPCServer) AddCoreService(ctx context.Context, srv core_service.CoreServiceServer) {
 	s.server.AddService(func(server *grpc.Server) {
-		core.RegisterCoreServiceServer(server, srv)
+		core_service.RegisterCoreServiceServer(server, srv)
 	})
 }
 
-func (s *MockGRPCServer) AddAdapterService(ctx context.Context, srv adapter_services.AdapterServiceServer) {
+func (s *MockGRPCServer) AddAdapterService(ctx context.Context, srv adapter_service.AdapterServiceServer) {
 	s.server.AddService(func(server *grpc.Server) {
-		adapter_services.RegisterAdapterServiceServer(server, srv)
+		adapter_service.RegisterAdapterServiceServer(server, srv)
 	})
 }
 
diff --git a/pkg/mocks/kafka/kafka_client_test.go b/pkg/mocks/kafka/kafka_client_test.go
index cc3a779..ad849c2 100644
--- a/pkg/mocks/kafka/kafka_client_test.go
+++ b/pkg/mocks/kafka/kafka_client_test.go
@@ -22,7 +22,7 @@
 	"time"
 
 	"github.com/opencord/voltha-lib-go/v7/pkg/kafka"
-	ic "github.com/opencord/voltha-protos/v5/go/inter_container"
+	"github.com/opencord/voltha-protos/v5/go/core_adapter"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -51,7 +51,7 @@
 	assert.NotNil(t, ch)
 	testCh := make(chan bool)
 	maxWait := 5 * time.Millisecond
-	msg := &ic.DeviceReason{
+	msg := &core_adapter.DeviceReason{
 		DeviceId: "1234",
 		Reason:   "mock",
 	}
