VOL-3504 Code changes to support force delete

Change-Id: I041ab2101a607b99e0372e432819a3f10f3a774c
diff --git a/VERSION b/VERSION
index 745ec0d..21f3dae 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.6.2-dev
+2.6.3-dev
diff --git a/go.mod b/go.mod
index 0401589..b84d647 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@
 	github.com/golang/protobuf v1.3.2
 	github.com/google/uuid v1.1.1
 	github.com/opencord/voltha-lib-go/v4 v4.0.2
-	github.com/opencord/voltha-protos/v4 v4.0.2
+	github.com/opencord/voltha-protos/v4 v4.0.5
 	github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
 	github.com/stretchr/testify v1.4.0
 	google.golang.org/grpc v1.24.0
diff --git a/go.sum b/go.sum
index 628d20e..df7b62a 100644
--- a/go.sum
+++ b/go.sum
@@ -202,6 +202,8 @@
 github.com/opencord/voltha-lib-go/v4 v4.0.2/go.mod h1:QgdIa7PlU0jhZT3qCPtcVt8/CpingKm4dUEROBrUBZg=
 github.com/opencord/voltha-protos/v4 v4.0.2 h1:SI25ljqftc8Tc28CgfqSE4IGCLJ5MgCmBQlE96hl9X8=
 github.com/opencord/voltha-protos/v4 v4.0.2/go.mod h1:W/OIFIyvFh/C0vchRUuarIsMylEhzCRM9pNxLvkPtKc=
+github.com/opencord/voltha-protos/v4 v4.0.5 h1:aOCk7SbIZhM8uHtsqAEADvO3l0xQgDPytoKZKb5Y4Zg=
+github.com/opencord/voltha-protos/v4 v4.0.5/go.mod h1:W/OIFIyvFh/C0vchRUuarIsMylEhzCRM9pNxLvkPtKc=
 github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/rw_core/core/api/grpc_nbi_handler.go b/rw_core/core/api/grpc_nbi_handler.go
index e0933c3..ea4c757 100755
--- a/rw_core/core/api/grpc_nbi_handler.go
+++ b/rw_core/core/api/grpc_nbi_handler.go
@@ -112,6 +112,3 @@
 func (handler *NBIHandler) UpdateMembership(context.Context, *voltha.Membership) (*empty.Empty, error) {
 	return nil, errUnimplemented
 }
-func (handler *NBIHandler) ForceDeleteDevice(ctx context.Context, id *common.ID) (*empty.Empty, error) {
-	return nil, errUnimplemented
-}
diff --git a/rw_core/core/api/grpc_nbi_handler_test.go b/rw_core/core/api/grpc_nbi_handler_test.go
index d6491c8..2891c36 100755
--- a/rw_core/core/api/grpc_nbi_handler_test.go
+++ b/rw_core/core/api/grpc_nbi_handler_test.go
@@ -353,6 +353,206 @@
 	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
 	assert.Nil(t, err)
 }
+func (nb *NBTest) enableDevice(t *testing.T, nbi *NBIHandler, oltDevice *voltha.Device) {
+	// Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go nb.monitorLogicalDevice(t, nbi, 1, nb.numONUPerOLT, &wg, false, false)
+
+	// Enable the oltDevice
+	_, err := nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	// Wait for the logical device to be in the ready state
+	var vldFunction = func(ports []*voltha.LogicalPort) bool {
+		return len(ports) == nb.numONUPerOLT+1
+	}
+	err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
+	assert.Nil(t, err)
+
+	// Verify that the devices have been setup correctly
+	nb.verifyDevices(t, nbi)
+
+	// Get latest oltDevice data
+	oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	// Verify that the logical device has been setup correctly
+	nb.verifyLogicalDevices(t, oltDevice, nbi)
+
+	// Wait until all flows has been sent to the devices successfully
+	wg.Wait()
+
+}
+func (nb *NBTest) testForceDeletePreProvDevice(t *testing.T, nbi *NBIHandler) {
+	//	Create a valid device
+	oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+	assert.Nil(t, err)
+	assert.NotNil(t, oltDevice)
+	device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+	assert.NotNil(t, device)
+	assert.Equal(t, oltDevice.String(), device.String())
+
+	// Ensure we only have 1 device in the Core
+	devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
+	assert.Nil(t, err)
+	assert.NotNil(t, devices)
+	assert.Equal(t, 1, len(devices.Items))
+	assert.Equal(t, oltDevice.String(), devices.Items[0].String())
+
+	//Remove the device forcefully
+	_, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+	var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == 0
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+	assert.Nil(t, err)
+}
+
+func (nb *NBTest) testForceDeleteEnabledDevice(t *testing.T, nbi *NBIHandler) {
+	//	Create a valid device
+	oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+	assert.Nil(t, err)
+	assert.NotNil(t, oltDevice)
+	device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+	assert.NotNil(t, device)
+	assert.Equal(t, oltDevice.String(), device.String())
+
+	nb.enableDevice(t, nbi, oltDevice)
+
+	//Remove the device forcefully
+	_, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+	var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == 0
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+	assert.Nil(t, err)
+}
+
+func (nb *NBTest) testDeletePreProvDevice(t *testing.T, nbi *NBIHandler) {
+	//	Create a valid device
+	oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+	assert.Nil(t, err)
+	assert.NotNil(t, oltDevice)
+	device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+	assert.NotNil(t, device)
+	assert.Equal(t, oltDevice.String(), device.String())
+
+	// Ensure we only have 1 device in the Core
+	devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
+	assert.Nil(t, err)
+	assert.NotNil(t, devices)
+	assert.Equal(t, 1, len(devices.Items))
+	assert.Equal(t, oltDevice.String(), devices.Items[0].String())
+
+	//Remove the device forcefully
+	_, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+	var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == 0
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+	assert.Nil(t, err)
+}
+
+func (nb *NBTest) testDeleteEnabledDevice(t *testing.T, nbi *NBIHandler) {
+	//	Create a valid device
+	oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+	assert.Nil(t, err)
+	assert.NotNil(t, oltDevice)
+	device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+	assert.NotNil(t, device)
+	assert.Equal(t, oltDevice.String(), device.String())
+
+	nb.enableDevice(t, nbi, oltDevice)
+
+	//Remove the device
+	_, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+	var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == 0
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+	assert.Nil(t, err)
+}
+
+func (nb *NBTest) testForceDeleteDeviceFailure(t *testing.T, nbi *NBIHandler) {
+	//	Create a valid device
+	oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+	assert.Nil(t, err)
+	assert.NotNil(t, oltDevice)
+	device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+	assert.NotNil(t, device)
+	assert.Equal(t, oltDevice.String(), device.String())
+
+	nb.enableDevice(t, nbi, oltDevice)
+	nb.oltAdapter.SetDeleteAction(true)
+	//Remove the device
+	_, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are no devices in the Core although delete was failed - wait until condition satisfied or timeout
+	var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == 0
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+	assert.Nil(t, err)
+
+}
+
+func (nb *NBTest) testDeleteDeviceFailure(t *testing.T, nbi *NBIHandler) {
+	//	Create a valid device
+	oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+	assert.Nil(t, err)
+	assert.NotNil(t, oltDevice)
+	device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+	assert.NotNil(t, device)
+	assert.Equal(t, oltDevice.String(), device.String())
+
+	nb.enableDevice(t, nbi, oltDevice)
+
+	nb.oltAdapter.SetDeleteAction(true)
+	//Remove the device
+	_, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are devices in the Core as delete was failed - wait until condition satisfied or timeout
+	var vFunction1 isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == (nb.numONUPerOLT+1)
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction1)
+	assert.Nil(t, err)
+
+	nb.oltAdapter.SetDeleteAction(false)
+
+	// Now Force Delete this device
+	_, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are devices in the Core as delete was failed - wait until condition satisfied or timeout
+	var vFunction2 isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == 0
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction2)
+	assert.Nil(t, err)
+
+}
 
 func (nb *NBTest) testEnableDevice(t *testing.T, nbi *NBIHandler) {
 	// Create a device that has no adapter registered
@@ -1235,37 +1435,46 @@
 
 	numberOfTestRuns := 2
 	for i := 1; i <= numberOfTestRuns; i++ {
-		//3. Test create device
+
+		// 3. Test create device
 		nb.testCreateDevice(t, nbi)
 
-		// 4. Test Enable a device
+		// 4. Test Delete Device Scenarios
+		nb.testForceDeletePreProvDevice(t, nbi)
+		nb.testDeletePreProvDevice(t, nbi)
+		nb.testForceDeleteEnabledDevice(t, nbi)
+		nb.testDeleteEnabledDevice(t, nbi)
+		nb.testForceDeleteDeviceFailure(t, nbi)
+		nb.testDeleteDeviceFailure(t, nbi)
+
+		// 5. Test Enable a device
 		nb.testEnableDevice(t, nbi)
 
-		//// 5. Test disable and ReEnable a root device
+		// 6. Test disable and ReEnable a root device
 		nb.testDisableAndReEnableRootDevice(t, nbi)
 
-		// 6. Test disable and Enable pon port of OLT device
+		// 7. Test disable and Enable pon port of OLT device
 		nb.testDisableAndEnablePort(t, nbi)
 
-		// 7.Test Device unreachable when OLT is enabled
+		// 8.Test Device unreachable when OLT is enabled
 		nb.testDeviceRebootWhenOltIsEnabled(t, nbi)
 
-		// 8. Test disable and delete all devices
+		// 9. Test disable and delete all devices
 		nb.testDisableAndDeleteAllDevice(t, nbi)
 
-		// 9. Test enable and delete all devices
+		// 10. Test enable and delete all devices
 		nb.testEnableAndDeleteAllDevice(t, nbi)
 
-		// 10. Test omci test
+		// 11. Test omci test
 		nb.testStartOmciTestAction(t, nbi)
 
-		// 11. Remove all devices from tests above
+		// 12. Remove all devices from tests above
 		nb.deleteAllDevices(t, nbi)
 
-		// 11. Test flow add failure
+		// 13. Test flow add failure
 		nb.testFlowAddFailure(t, nbi)
 
-		// 12.  Clean up
+		// 14.  Clean up
 		nb.deleteAllDevices(t, nbi)
 	}
 }
diff --git a/rw_core/core/device/agent.go b/rw_core/core/device/agent.go
index 4fc5197..a9767d4 100755
--- a/rw_core/core/device/agent.go
+++ b/rw_core/core/device/agent.go
@@ -25,18 +25,18 @@
 	"sync"
 	"time"
 
+	"github.com/gogo/protobuf/proto"
 	"github.com/golang/protobuf/ptypes"
 	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/opencord/voltha-go/db/model"
 	"github.com/opencord/voltha-go/rw_core/core/adapter"
 	"github.com/opencord/voltha-go/rw_core/core/device/flow"
 	"github.com/opencord/voltha-go/rw_core/core/device/group"
 	"github.com/opencord/voltha-go/rw_core/core/device/port"
 	"github.com/opencord/voltha-go/rw_core/core/device/remote"
-	"github.com/opencord/voltha-lib-go/v4/pkg/kafka"
-
-	"github.com/gogo/protobuf/proto"
-	"github.com/opencord/voltha-go/db/model"
+	"github.com/opencord/voltha-go/rw_core/core/device/transientstate"
 	coreutils "github.com/opencord/voltha-go/rw_core/utils"
+	"github.com/opencord/voltha-lib-go/v4/pkg/kafka"
 	"github.com/opencord/voltha-lib-go/v4/pkg/log"
 	ic "github.com/opencord/voltha-protos/v4/go/inter_container"
 	ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
@@ -63,9 +63,10 @@
 	stopOnce       sync.Once
 	stopped        bool
 
-	flowLoader  *flow.Loader
-	groupLoader *group.Loader
-	portLoader  *port.Loader
+	flowLoader           *flow.Loader
+	groupLoader          *group.Loader
+	portLoader           *port.Loader
+	transientStateLoader *transientstate.Loader
 }
 
 //newAgent creates a new device agent. The device will be initialized when start() is called.
@@ -76,21 +77,22 @@
 	}
 
 	return &Agent{
-		deviceID:       deviceID,
-		adapterProxy:   ap,
-		isRootDevice:   device.Root,
-		parentID:       device.ParentId,
-		deviceType:     device.Type,
-		deviceMgr:      deviceMgr,
-		adapterMgr:     deviceMgr.adapterMgr,
-		exitChannel:    make(chan int, 1),
-		dbProxy:        deviceProxy,
-		defaultTimeout: timeout,
-		device:         proto.Clone(device).(*voltha.Device),
-		requestQueue:   coreutils.NewRequestQueue(),
-		flowLoader:     flow.NewLoader(dbPath.SubPath("flows").Proxy(deviceID)),
-		groupLoader:    group.NewLoader(dbPath.SubPath("groups").Proxy(deviceID)),
-		portLoader:     port.NewLoader(dbPath.SubPath("ports").Proxy(deviceID)),
+		deviceID:             deviceID,
+		adapterProxy:         ap,
+		isRootDevice:         device.Root,
+		parentID:             device.ParentId,
+		deviceType:           device.Type,
+		deviceMgr:            deviceMgr,
+		adapterMgr:           deviceMgr.adapterMgr,
+		exitChannel:          make(chan int, 1),
+		dbProxy:              deviceProxy,
+		defaultTimeout:       timeout,
+		device:               proto.Clone(device).(*voltha.Device),
+		requestQueue:         coreutils.NewRequestQueue(),
+		flowLoader:           flow.NewLoader(dbPath.SubPath("flows").Proxy(deviceID)),
+		groupLoader:          group.NewLoader(dbPath.SubPath("groups").Proxy(deviceID)),
+		portLoader:           port.NewLoader(dbPath.SubPath("ports").Proxy(deviceID)),
+		transientStateLoader: transientstate.NewLoader(dbPath.SubPath("core").Proxy("transientstate"), deviceID),
 	}
 }
 
@@ -128,6 +130,7 @@
 		agent.flowLoader.Load(ctx)
 		agent.groupLoader.Load(ctx)
 		agent.portLoader.Load(ctx)
+		agent.transientStateLoader.Load(ctx)
 
 		logger.Infow(ctx, "device-loaded-from-dB", log.Fields{"device-id": agent.deviceID})
 	} else {
@@ -169,7 +172,10 @@
 	defer agent.requestQueue.RequestComplete()
 
 	logger.Infow(ctx, "stopping-device-agent", log.Fields{"device-id": agent.deviceID, "parentId": agent.parentID})
-
+	// Remove the device transient loader
+	if err := agent.deleteTransientState(ctx); err != nil {
+		return err
+	}
 	//	Remove the device from the KV store
 	if err := agent.dbProxy.Remove(ctx, agent.deviceID); err != nil {
 		return err
@@ -206,13 +212,15 @@
 	agent.flowLoader.Load(ctx)
 	agent.groupLoader.Load(ctx)
 	agent.portLoader.Load(ctx)
+	agent.transientStateLoader.Load(ctx)
+
 	logger.Debugw(ctx, "reconciled-device-agent-devicetype", log.Fields{"device-id": agent.deviceID, "type": agent.deviceType})
 }
 
 // onSuccess is a common callback for scenarios where we receive a nil response following a request to an adapter
 // and the only action required is to publish a successful result on kafka
 func (agent *Agent) onSuccess(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
-	logger.Debugw(ctx, "response successful", log.Fields{"rpc": rpc, "device-id": agent.deviceID})
+	logger.Debugw(ctx, "response-successful", log.Fields{"rpc": rpc, "device-id": agent.deviceID})
 	// TODO: Post success message onto kafka
 }
 
@@ -244,6 +252,53 @@
 	}
 }
 
+// onDeleteSuccess is a common callback for scenarios where we receive a nil response following a delete request
+// to an adapter.
+func (agent *Agent) onDeleteSuccess(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
+	logger.Debugw(ctx, "response-successful", log.Fields{"rpc": rpc, "device-id": agent.deviceID})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		logger.Errorw(ctx, "delete-device-failure", log.Fields{"device-id": agent.deviceID, "error": err, "args": reqArgs})
+	}
+	previousDeviceTransientState := agent.getTransientState()
+	newDevice := agent.cloneDeviceWithoutLock()
+	if err := agent.updateDeviceWithTransientStateAndReleaseLock(ctx, newDevice,
+		voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE, previousDeviceTransientState); err != nil {
+		logger.Errorw(ctx, "delete-device-failure", log.Fields{"device-id": agent.deviceID, "error": err, "args": reqArgs})
+	}
+}
+
+// onDeleteFailure is a common callback for scenarios where we receive an error response following a delete request
+//  to an adapter and the only action required is to return the error response.
+func (agent *Agent) onDeleteFailure(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
+	if res, ok := response.(error); ok {
+		logger.Errorw(ctx, "rpc-failed", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "error": res, "args": reqArgs})
+	} else {
+		logger.Errorw(ctx, "rpc-failed-invalid-error", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "args": reqArgs})
+	}
+	//Only updating of transient state is required, no transition.
+	if err := agent.updateTransientState(ctx, voltha.DeviceTransientState_DELETE_FAILED); err != nil {
+		logger.Errorw(ctx, "failed-to-update-transient-state-as-delete-failed", log.Fields{"device-id": agent.deviceID})
+	}
+
+}
+
+func (agent *Agent) waitForAdapterDeleteResponse(ctx context.Context, cancel context.CancelFunc, rpc string, ch chan *kafka.RpcResponse,
+	onSuccess coreutils.ResponseCallback, onFailure coreutils.ResponseCallback, reqArgs ...interface{}) {
+	defer cancel()
+	select {
+	case rpcResponse, ok := <-ch:
+		if !ok {
+			onFailure(ctx, rpc, status.Errorf(codes.Aborted, "channel-closed"), reqArgs)
+		} else if rpcResponse.Err != nil {
+			onFailure(ctx, rpc, rpcResponse.Err, reqArgs)
+		} else {
+			onSuccess(ctx, rpc, rpcResponse.Reply, reqArgs)
+		}
+	case <-ctx.Done():
+		onFailure(ctx, rpc, ctx.Err(), reqArgs)
+	}
+}
+
 // getDeviceReadOnly returns a device which MUST NOT be modified, but is safe to keep forever.
 func (agent *Agent) getDeviceReadOnly(ctx context.Context) (*voltha.Device, error) {
 	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
@@ -278,12 +333,10 @@
 		agent.requestQueue.RequestComplete()
 		return status.Error(codes.FailedPrecondition, fmt.Sprintf("cannot-enable-an-already-enabled-device: %s", oldDevice.Id))
 	}
-	if oldDevice.AdminState == voltha.AdminState_DELETED {
-		// This is a temporary state when a device is deleted before it gets removed from the model.
+	if agent.isDeletionInProgress() {
 		agent.requestQueue.RequestComplete()
-		return status.Error(codes.FailedPrecondition, fmt.Sprintf("cannot-enable-a-deleted-device: %s", oldDevice.Id))
+		return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device deletion is in progress.", agent.deviceID)
 	}
-
 	// First figure out which adapter will handle this device type.  We do it at this stage as allow devices to be
 	// pre-provisioned with the required adapter not registered.   At this stage, since we need to communicate
 	// with the adapter then we need to know the adapter that will handle this request
@@ -406,11 +459,14 @@
 		agent.requestQueue.RequestComplete()
 		return nil
 	}
-	if cloned.AdminState == voltha.AdminState_PREPROVISIONED || cloned.AdminState == voltha.AdminState_DELETED {
+	if cloned.AdminState == voltha.AdminState_PREPROVISIONED {
 		agent.requestQueue.RequestComplete()
 		return status.Errorf(codes.FailedPrecondition, "deviceId:%s, invalid-admin-state:%s", agent.deviceID, cloned.AdminState)
 	}
-
+	if agent.isDeletionInProgress() {
+		agent.requestQueue.RequestComplete()
+		return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device deletion is in progress.", agent.deviceID)
+	}
 	// Update the Admin State and operational state before sending the request out
 	cloned.AdminState = voltha.AdminState_DISABLED
 	cloned.OperStatus = voltha.OperStatus_UNKNOWN
@@ -437,6 +493,9 @@
 	logger.Debugw(ctx, "rebootDevice", log.Fields{"device-id": agent.deviceID})
 
 	device := agent.getDeviceReadOnlyWithoutLock()
+	if agent.isDeletionInProgress() {
+		return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device deletion is in progress.", agent.deviceID)
+	}
 	subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
 	ch, err := agent.adapterProxy.RebootDevice(subCtx, device)
 	if err != nil {
@@ -447,32 +506,79 @@
 	return nil
 }
 
+func (agent *Agent) deleteDeviceForce(ctx context.Context) error {
+	logger.Debugw(ctx, "deleteDeviceForce", log.Fields{"device-id": agent.deviceID})
+	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+		return err
+	}
+	// Get the device Transient state, return err if it is DELETING
+	previousDeviceTransientState := agent.getTransientState()
+
+	if agent.isStateDeleting(previousDeviceTransientState) {
+		agent.requestQueue.RequestComplete()
+		return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device Deletion is in progress",
+			agent.deviceID)
+	}
+	device := agent.cloneDeviceWithoutLock()
+	if err := agent.updateDeviceWithTransientStateAndReleaseLock(ctx, device, voltha.DeviceTransientState_FORCE_DELETING,
+		previousDeviceTransientState); err != nil {
+		return err
+	}
+	previousAdminState := device.AdminState
+	if previousAdminState != ic.AdminState_PREPROVISIONED {
+		subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
+		ch, err := agent.adapterProxy.DeleteDevice(subCtx, device)
+		if err != nil {
+			cancel()
+			return err
+		}
+		// Since it is a case of force delete, nothing needs to be done on adapter responses.
+		go agent.waitForAdapterResponse(subCtx, cancel, "deleteDeviceForce", ch, agent.onSuccess,
+			agent.onFailure)
+	}
+	return nil
+}
+
 func (agent *Agent) deleteDevice(ctx context.Context) error {
 	logger.Debugw(ctx, "deleteDevice", log.Fields{"device-id": agent.deviceID})
 	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
 		return err
 	}
+	// Get the device Transient state, return err if it is DELETING
+	previousDeviceTransientState := agent.getTransientState()
 
-	cloned := agent.cloneDeviceWithoutLock()
-	previousState := cloned.AdminState
+	if agent.isStateDeleting(previousDeviceTransientState) {
+		agent.requestQueue.RequestComplete()
+		return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device Deletion is in progress", agent.deviceID)
+	}
+	device := agent.cloneDeviceWithoutLock()
+	previousAdminState := device.AdminState
+	// Change the device transient state to DELETING_FROM_ADAPTER  state till the device is removed from adapters.
+	currentDeviceTransientState := voltha.DeviceTransientState_DELETING_FROM_ADAPTER
 
-	// No check is required when deleting a device.  Changing the state to DELETE will trigger the removal of this
-	// device by the state machine
-	cloned.AdminState = voltha.AdminState_DELETED
-	if err := agent.updateDeviceAndReleaseLock(ctx, cloned); err != nil {
+	if previousAdminState == ic.AdminState_PREPROVISIONED {
+		// Change the state to DELETING POST ADAPTER RESPONSE directly as adapters have no info of the device.
+		currentDeviceTransientState = voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE
+	}
+	if err := agent.updateDeviceWithTransientStateAndReleaseLock(ctx, device, currentDeviceTransientState,
+		previousDeviceTransientState); err != nil {
 		return err
 	}
-
 	// If the device was in pre-prov state (only parent device are in that state) then do not send the request to the
 	// adapter
-	if previousState != ic.AdminState_PREPROVISIONED {
+	if previousAdminState != ic.AdminState_PREPROVISIONED {
 		subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
-		ch, err := agent.adapterProxy.DeleteDevice(subCtx, cloned)
+		ch, err := agent.adapterProxy.DeleteDevice(subCtx, device)
 		if err != nil {
 			cancel()
+			//updating of transient state is required in error
+			if err := agent.updateTransientState(ctx, voltha.DeviceTransientState_DELETE_FAILED); err != nil {
+				logger.Errorw(ctx, "failed-to-update-transient-state-as-delete-failed", log.Fields{"device-id": agent.deviceID})
+			}
 			return err
 		}
-		go agent.waitForAdapterResponse(subCtx, cancel, "deleteDevice", ch, agent.onSuccess, agent.onFailure)
+		go agent.waitForAdapterDeleteResponse(subCtx, cancel, "deleteDevice", ch, agent.onDeleteSuccess,
+			agent.onDeleteFailure)
 	}
 	return nil
 }
@@ -654,7 +760,7 @@
 	// fail early if this agent is no longer valid
 	if agent.stopped {
 		agent.requestQueue.RequestComplete()
-		return errors.New("device agent stopped")
+		return errors.New("device-agent-stopped")
 	}
 
 	// update in db
@@ -671,12 +777,52 @@
 	// release lock before processing transition
 	agent.requestQueue.RequestComplete()
 
-	if err := agent.deviceMgr.stateTransitions.ProcessTransition(log.WithSpanFromContext(context.Background(), ctx), device, prevDevice); err != nil {
+	if err := agent.deviceMgr.stateTransitions.ProcessTransition(log.WithSpanFromContext(context.Background(), ctx),
+		device, prevDevice, voltha.DeviceTransientState_NONE, voltha.DeviceTransientState_NONE); err != nil {
 		logger.Errorw(ctx, "failed-process-transition", log.Fields{"device-id": device.Id, "previousAdminState": prevDevice.AdminState, "currentAdminState": device.AdminState})
 	}
 	return nil
 }
 
+// This function updates the device transient in the DB through loader, releases the device lock, and runs any state transitions.
+// The calling function MUST hold the device lock.  The caller MUST NOT modify the device after this is called.
+func (agent *Agent) updateDeviceWithTransientStateAndReleaseLock(ctx context.Context, device *voltha.Device,
+	transientState, prevTransientState voltha.DeviceTransientState_Types) error {
+	// fail early if this agent is no longer valid
+	if agent.stopped {
+		agent.requestQueue.RequestComplete()
+		return errors.New("device-agent-stopped")
+	}
+	//update device TransientState
+	if err := agent.updateTransientState(ctx, transientState); err != nil {
+		agent.requestQueue.RequestComplete()
+		return err
+	}
+	// update in db
+	if err := agent.dbProxy.Set(ctx, agent.deviceID, device); err != nil {
+		//Reverting TransientState update
+		err := agent.updateTransientState(ctx, prevTransientState)
+		logger.Errorw(ctx, "failed-to-revert-transient-state-update-on-error", log.Fields{"device-id": device.Id,
+			"previousTransientState": prevTransientState, "currentTransientState": transientState})
+		agent.requestQueue.RequestComplete()
+		return status.Errorf(codes.Internal, "failed-update-device:%s: %s", agent.deviceID, err)
+	}
+
+	logger.Debugw(ctx, "updated-device-in-store", log.Fields{"device-id: ": agent.deviceID})
+
+	prevDevice := agent.device
+	// update the device
+	agent.device = device
+
+	// release lock before processing transition
+	agent.requestQueue.RequestComplete()
+
+	if err := agent.deviceMgr.stateTransitions.ProcessTransition(log.WithSpanFromContext(context.Background(), ctx),
+		device, prevDevice, transientState, prevTransientState); err != nil {
+		logger.Errorw(ctx, "failed-process-transition", log.Fields{"device-id": device.Id, "previousAdminState": prevDevice.AdminState, "currentAdminState": device.AdminState})
+	}
+	return nil
+}
 func (agent *Agent) updateDeviceReason(ctx context.Context, reason string) error {
 	if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
 		return err
diff --git a/rw_core/core/device/agent_port.go b/rw_core/core/device/agent_port.go
index e90a0a4..a3489fc 100644
--- a/rw_core/core/device/agent_port.go
+++ b/rw_core/core/device/agent_port.go
@@ -123,8 +123,9 @@
 		return err
 	}
 
-	if device.AdminState != voltha.AdminState_DISABLED && device.AdminState != voltha.AdminState_DELETED {
-		err := status.Error(codes.FailedPrecondition, fmt.Sprintf("invalid-state-%v", device.AdminState))
+	if device.AdminState != voltha.AdminState_DISABLED && !agent.isDeletionInProgress() {
+		err := status.Error(codes.FailedPrecondition, fmt.Sprintf("invalid-admin-state-%v",
+			device.AdminState))
 		logger.Warnw(ctx, "invalid-state-removing-ports", log.Fields{"state": device.AdminState, "error": err})
 		return err
 	}
diff --git a/rw_core/core/device/agent_transient_state.go b/rw_core/core/device/agent_transient_state.go
new file mode 100644
index 0000000..776d60d
--- /dev/null
+++ b/rw_core/core/device/agent_transient_state.go
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+	"context"
+	"github.com/opencord/voltha-protos/v4/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+func (agent *Agent) getTransientState() voltha.DeviceTransientState_Types {
+	transientStateHandle := agent.transientStateLoader.Lock()
+	deviceTransientState := transientStateHandle.GetReadOnly()
+	transientStateHandle.UnLock()
+	return deviceTransientState
+}
+
+func (agent *Agent) updateTransientState(ctx context.Context, transientState voltha.DeviceTransientState_Types) error {
+	// Update device transient state
+	transientStateHandle := agent.transientStateLoader.Lock()
+	if err := transientStateHandle.Update(ctx, transientState); err != nil {
+		transientStateHandle.UnLock()
+		return status.Errorf(codes.Internal, "failed-update-device-transient-state:%s: %s", agent.deviceID, err)
+	}
+	transientStateHandle.UnLock()
+	return nil
+}
+
+func (agent *Agent) isDeletionInProgress() bool {
+	deviceTransientState := agent.getTransientState()
+	return deviceTransientState == voltha.DeviceTransientState_FORCE_DELETING ||
+		deviceTransientState == voltha.DeviceTransientState_DELETING_FROM_ADAPTER ||
+		deviceTransientState == voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE
+}
+
+func (agent *Agent) isStateDeleting(deviceTransientState voltha.DeviceTransientState_Types) bool {
+	return deviceTransientState == voltha.DeviceTransientState_FORCE_DELETING ||
+		deviceTransientState == voltha.DeviceTransientState_DELETING_FROM_ADAPTER ||
+		deviceTransientState == voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE
+}
+func (agent *Agent) deleteTransientState(ctx context.Context) error {
+	transientStateHandle := agent.transientStateLoader.Lock()
+	if err := transientStateHandle.Delete(ctx); err != nil {
+		transientStateHandle.UnLock()
+		return status.Errorf(codes.Internal, "failed-delete-device-transient-state:%s: %s", agent.deviceID, err)
+	}
+	transientStateHandle.UnLock()
+	return nil
+}
diff --git a/rw_core/core/device/manager.go b/rw_core/core/device/manager.go
index 3899623..9220fe5 100755
--- a/rw_core/core/device/manager.go
+++ b/rw_core/core/device/manager.go
@@ -209,7 +209,6 @@
 // DeleteDevice removes a device from the data model
 func (dMgr *Manager) DeleteDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
 	log.EnrichSpan(ctx, log.Fields{"device-id": id.Id})
-
 	logger.Debugw(ctx, "DeleteDevice", log.Fields{"device-id": id.Id})
 	agent := dMgr.getDeviceAgent(ctx, id.Id)
 	if agent == nil {
@@ -218,6 +217,17 @@
 	return &empty.Empty{}, agent.deleteDevice(ctx)
 }
 
+// ForceDeleteDevice removes a device from the data model forcefully without successfully waiting for the adapters.
+func (dMgr *Manager) ForceDeleteDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
+	log.EnrichSpan(ctx, log.Fields{"device-id": id.Id})
+	logger.Debugw(ctx, "ForceDeleteDevice", log.Fields{"device-id": id.Id})
+	agent := dMgr.getDeviceAgent(ctx, id.Id)
+	if agent == nil {
+		return nil, status.Errorf(codes.NotFound, "%s", id.Id)
+	}
+	return &empty.Empty{}, agent.deleteDeviceForce(ctx)
+}
+
 // GetDevicePort returns the port details for a specific device port entry
 func (dMgr *Manager) GetDevicePort(ctx context.Context, deviceID string, portID uint32) (*voltha.Port, error) {
 	logger.Debugw(ctx, "ListDevicePorts", log.Fields{"device-id": deviceID})
@@ -473,10 +483,11 @@
 		if !device.Root {
 			continue
 		}
-		if hostPort != "" && hostPort == device.GetHostAndPort() && device.AdminState != voltha.AdminState_DELETED {
+
+		if hostPort != "" && hostPort == device.GetHostAndPort() {
 			return true, nil
 		}
-		if newDevice.MacAddress != "" && newDevice.MacAddress == device.MacAddress && device.AdminState != voltha.AdminState_DELETED {
+		if newDevice.MacAddress != "" && newDevice.MacAddress == device.MacAddress {
 			return true, nil
 		}
 	}
@@ -589,8 +600,8 @@
 		return err
 	}
 
-	// If the device is in Pre-provisioning or deleted state stop here
-	if device.AdminState == voltha.AdminState_PREPROVISIONED || device.AdminState == voltha.AdminState_DELETED {
+	// If the device is in Pre-provisioning or getting deleted state stop here
+	if device.AdminState == voltha.AdminState_PREPROVISIONED || dAgent.isDeletionInProgress() {
 		return nil
 	}
 
@@ -645,11 +656,14 @@
 }
 
 // isOkToReconcile validates whether a device is in the correct status to be reconciled
-func isOkToReconcile(device *voltha.Device) bool {
+func (dMgr *Manager) isOkToReconcile(ctx context.Context, device *voltha.Device) bool {
 	if device == nil {
 		return false
 	}
-	return device.AdminState != voltha.AdminState_PREPROVISIONED && device.AdminState != voltha.AdminState_DELETED
+	if agent := dMgr.getDeviceAgent(ctx, device.Id); agent != nil {
+		return device.AdminState != voltha.AdminState_PREPROVISIONED && (!agent.isDeletionInProgress())
+	}
+	return false
 }
 
 // adapterRestarted is invoked whenever an adapter is restarted
@@ -672,7 +686,7 @@
 				continue
 			}
 			if isDeviceOwnedByService {
-				if isOkToReconcile(rootDevice) {
+				if dMgr.isOkToReconcile(ctx, rootDevice) {
 					logger.Debugw(ctx, "reconciling-root-device", log.Fields{"rootId": rootDevice.Id})
 					responses = append(responses, dMgr.sendReconcileDeviceRequest(ctx, rootDevice))
 				} else {
@@ -689,7 +703,7 @@
 								logger.Warnw(ctx, "is-device-owned-by-service", log.Fields{"error": err, "child-device-id": childDevice.Id, "adapterType": adapter.Type, "replica-number": adapter.CurrentReplica})
 							}
 							if isDeviceOwnedByService {
-								if isOkToReconcile(childDevice) {
+								if dMgr.isOkToReconcile(ctx, childDevice) {
 									logger.Debugw(ctx, "reconciling-child-device", log.Fields{"child-device-id": childDevice.Id})
 									responses = append(responses, dMgr.sendReconcileDeviceRequest(ctx, childDevice))
 								} else {
@@ -1222,11 +1236,29 @@
 //DeleteAllChildDevices is invoked as a callback when the parent device is deleted
 func (dMgr *Manager) DeleteAllChildDevices(ctx context.Context, parentCurrDevice *voltha.Device) error {
 	logger.Debug(ctx, "DeleteAllChildDevices")
+	force := false
+	// Get the parent device Transient state, if its FORCE_DELETED(go for force delete for child devices)
+	// So in cases when this handler is getting called other than DELETE operation, no force option would be used.
+	agent := dMgr.getDeviceAgent(ctx, parentCurrDevice.Id)
+	if agent == nil {
+		return status.Errorf(codes.NotFound, "%s", parentCurrDevice.Id)
+	}
+
+	force = agent.getTransientState() == voltha.DeviceTransientState_FORCE_DELETING
+
 	ports, _ := dMgr.listDevicePorts(ctx, parentCurrDevice.Id)
 	for childDeviceID := range dMgr.getAllChildDeviceIds(ctx, ports) {
 		if agent := dMgr.getDeviceAgent(ctx, childDeviceID); agent != nil {
-			if err := agent.deleteDevice(ctx); err != nil {
-				logger.Warnw(ctx, "failure-delete-device", log.Fields{"device-id": childDeviceID, "error": err.Error()})
+			if force {
+				if err := agent.deleteDeviceForce(ctx); err != nil {
+					logger.Warnw(ctx, "failure-delete-device-force", log.Fields{"device-id": childDeviceID,
+						"error": err.Error()})
+				}
+			} else {
+				if err := agent.deleteDevice(ctx); err != nil {
+					logger.Warnw(ctx, "failure-delete-device", log.Fields{"device-id": childDeviceID,
+						"error": err.Error()})
+				}
 			}
 			// No further action is required here.  The deleteDevice will change the device state where the resulting
 			// callback will take care of cleaning the child device agent.
diff --git a/rw_core/core/device/state/transitions.go b/rw_core/core/device/state/transitions.go
index 81ac69d..e65c396 100644
--- a/rw_core/core/device/state/transitions.go
+++ b/rw_core/core/device/state/transitions.go
@@ -18,11 +18,10 @@
 
 import (
 	"context"
-	"reflect"
-	"runtime"
-
 	"github.com/opencord/voltha-lib-go/v4/pkg/log"
 	"github.com/opencord/voltha-protos/v4/go/voltha"
+	"reflect"
+	"runtime"
 )
 
 // deviceType mentions type of device like parent, child
@@ -34,7 +33,7 @@
 	any    deviceType = 2
 )
 
-type matchResult uint8
+type matchResult uint16
 
 const (
 	noMatch            matchResult = iota // current state has not match in the transition table
@@ -45,17 +44,18 @@
 
 // match is used to keep the current match states
 type match struct {
-	admin, oper, conn matchResult
+	admin, oper, conn, transient matchResult
 }
 
 // toInt returns an integer representing the matching level of the match (the larger the number the better)
 func (m *match) toInt() int {
-	return int(m.admin<<4 | m.oper<<2 | m.conn)
+	return int(m.transient<<8 | m.admin<<4 | m.oper<<2 | m.conn)
 }
 
 // isExactMatch returns true if match is an exact match
 func (m *match) isExactMatch() bool {
-	return m.admin == currPrevStateMatch && m.oper == currPrevStateMatch && m.conn == currPrevStateMatch
+	return m.admin == currPrevStateMatch && m.oper == currPrevStateMatch && m.conn == currPrevStateMatch &&
+		m.transient == currPrevStateMatch
 }
 
 // isBetterMatch returns true if newMatch is a worse match
@@ -68,6 +68,7 @@
 	Admin       voltha.AdminState_Types
 	Connection  voltha.ConnectStatus_Types
 	Operational voltha.OperStatus_Types
+	Transient   voltha.DeviceTransientState_Types
 }
 
 // transitionHandler function type which takes the current and previous device info as input parameter
@@ -110,161 +111,203 @@
 		transitionMap.transitions,
 		transition{
 			deviceType:    parent,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.CreateLogicalDevice}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    child,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    child,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.SetupUNILogicalPorts}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    child,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    child,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.SetupUNILogicalPorts}})
 	transitionMap.transitions = append(transitionMap.transitions,
-		transition{
+		transition{ //DELETE PRE PROVISIONED State device forcefully
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_FORCE_DELETING},
 			handlers:      []transitionHandler{dMgr.RunPostDeviceDelete}})
 	transitionMap.transitions = append(transitionMap.transitions,
-		transition{
+		transition{ // DELETE PRE PROVISIONED State device no force option set
+			deviceType:    any,
+			previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE},
+			handlers:      []transitionHandler{dMgr.RunPostDeviceDelete}})
+	transitionMap.transitions = append(transitionMap.transitions,
+		transition{ //DELETE device forcefully
 			deviceType:    parent,
-			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_FORCE_DELETING},
 			handlers:      []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.RunPostDeviceDelete}})
 	transitionMap.transitions = append(transitionMap.transitions,
+		transition{ //DELETE device after adapter response
+			deviceType:    parent,
+			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE},
+			handlers:      []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.RunPostDeviceDelete}})
+	transitionMap.transitions = append(transitionMap.transitions,
+		transition{ //DELETE no operation transition
+			deviceType:    parent,
+			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_FROM_ADAPTER},
+			handlers:      []transitionHandler{}})
+	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    parent,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.DeleteAllDeviceFlows}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    parent,
-			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.DeleteAllDeviceFlows}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    parent,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.CreateLogicalDevice}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    parent,
-			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.CreateLogicalDevice}})
 	transitionMap.transitions = append(transitionMap.transitions,
-		transition{
+		transition{ //DELETE force case
 			deviceType:    child,
-			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_FORCE_DELETING},
 			handlers:      []transitionHandler{dMgr.ChildDeviceLost, dMgr.DeleteLogicalPorts, dMgr.RunPostDeviceDelete}})
 	transitionMap.transitions = append(transitionMap.transitions,
-		transition{
+		transition{ //DELETE after adapter response case
 			deviceType:    child,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE},
 			handlers:      []transitionHandler{dMgr.ChildDeviceLost, dMgr.DeleteLogicalPorts, dMgr.RunPostDeviceDelete}})
 	transitionMap.transitions = append(transitionMap.transitions,
+		transition{ //DELETE wait for adapter response(no operation)
+			deviceType:    child,
+			previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_FROM_ADAPTER},
+			handlers:      []transitionHandler{}})
+	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    parent,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
-			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    child,
-			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 	transitionMap.transitions = append(transitionMap.transitions,
 		transition{
 			deviceType:    any,
-			previousState: deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
-			currentState:  deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+			previousState: deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+			currentState:  deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
 			handlers:      []transitionHandler{dMgr.NotifyInvalidTransition}})
 
 	return &transitionMap
 }
 
-func getDeviceStates(device *voltha.Device) deviceState {
-	return deviceState{Admin: device.AdminState, Connection: device.ConnectStatus, Operational: device.OperStatus}
+func getDeviceStates(device *voltha.Device, transientState voltha.DeviceTransientState_Types) deviceState {
+	return deviceState{Admin: device.AdminState, Connection: device.ConnectStatus, Operational: device.OperStatus,
+		Transient: transientState}
 }
 
 // isMatched matches a state transition.  It returns whether there is a match and if there is whether it is an exact match
 func getHandler(previous deviceState, current deviceState, transition *transition) ([]transitionHandler, *match) {
 	m := &match{}
+	var waitForOtherStatesMatch bool
 	// Do we have an exact match?
 	if previous == transition.previousState && current == transition.currentState {
-		return transition.handlers, &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch}
+		return transition.handlers, &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch,
+			transient: currPrevStateMatch}
+	}
+	// Do we have transient state match?
+	if current.Transient == transition.currentState.Transient && transition.currentState.Transient != voltha.DeviceTransientState_ANY {
+		if previous.Transient == transition.previousState.Transient || transition.previousState.Transient == voltha.DeviceTransientState_ANY {
+			m.transient = currPrevStateMatch
+		} else {
+			m.transient = currStateOnlyMatch
+		}
+	} else if current.Transient == transition.currentState.Transient && transition.currentState.Transient == voltha.DeviceTransientState_ANY {
+		if previous.Transient == transition.previousState.Transient || transition.previousState.Transient == voltha.DeviceTransientState_ANY {
+			m.transient = currWildcardMatch
+		}
+	}
+	if m.transient == noMatch {
+		return nil, m
 	}
 
 	// Do we have Admin state match?
@@ -278,12 +321,14 @@
 		if previous.Admin == transition.previousState.Admin || transition.previousState.Admin == voltha.AdminState_UNKNOWN {
 			m.admin = currWildcardMatch
 		}
+	} else if transition.previousState.Admin == voltha.AdminState_UNKNOWN && transition.currentState.Admin == voltha.AdminState_UNKNOWN {
+		// Will only be the case of DELETION currently.(to allow only transient match, we can avoid this check if
+		// we can allow wild card in admin state)
+		waitForOtherStatesMatch = true
 	}
-	if m.admin == noMatch {
-		// invalid transition - need to match on current admin state
+	if !waitForOtherStatesMatch && m.admin == noMatch {
 		return nil, m
 	}
-
 	// Do we have an operational state match?
 	if current.Operational == transition.currentState.Operational && transition.previousState.Operational != voltha.OperStatus_UNKNOWN {
 		if previous.Operational == transition.previousState.Operational || transition.previousState.Operational == voltha.OperStatus_UNKNOWN {
@@ -309,15 +354,15 @@
 			m.conn = currWildcardMatch
 		}
 	}
-
 	return transition.handlers, m
 }
 
 // getTransitionHandler returns transition handler & a flag that's set if the transition is invalid
-func (tMap *TransitionMap) getTransitionHandler(ctx context.Context, cDevice, pDevice *voltha.Device) []transitionHandler {
+func (tMap *TransitionMap) getTransitionHandler(ctx context.Context, cDevice, pDevice *voltha.Device,
+	cTransientState, pTransientState voltha.DeviceTransientState_Types) []transitionHandler {
 	//1. Get the previous and current set of states
-	cState := getDeviceStates(cDevice)
-	pState := getDeviceStates(pDevice)
+	cState := getDeviceStates(cDevice, cTransientState)
+	pState := getDeviceStates(pDevice, pTransientState)
 
 	// Do nothing is there are no states change
 	if pState == cState {
@@ -355,23 +400,27 @@
 	return currentMatch
 }
 
-func (tMap *TransitionMap) ProcessTransition(ctx context.Context, device, prevDevice *voltha.Device) error {
+func (tMap *TransitionMap) ProcessTransition(ctx context.Context, device, prevDevice *voltha.Device,
+	deviceTransientState, prevDeviceTransientState voltha.DeviceTransientState_Types) error {
 	// This will be triggered on every state update
 	logger.Debugw(ctx, "state-transition", log.Fields{
-		"device":           device.Id,
-		"prev-admin-state": prevDevice.AdminState,
-		"prev-oper-state":  prevDevice.OperStatus,
-		"prev-conn-state":  prevDevice.ConnectStatus,
-		"curr-admin-state": device.AdminState,
-		"curr-oper-state":  device.OperStatus,
-		"curr-conn-state":  device.ConnectStatus,
+		"device":               device.Id,
+		"prev-admin-state":     prevDevice.AdminState,
+		"prev-oper-state":      prevDevice.OperStatus,
+		"prev-conn-state":      prevDevice.ConnectStatus,
+		"curr-admin-state":     device.AdminState,
+		"curr-oper-state":      device.OperStatus,
+		"curr-conn-state":      device.ConnectStatus,
+		"curr-transient-state": deviceTransientState,
+		"prev-transient-state": prevDeviceTransientState,
 	})
-	handlers := tMap.getTransitionHandler(ctx, device, prevDevice)
+	handlers := tMap.getTransitionHandler(ctx, device, prevDevice, deviceTransientState, prevDeviceTransientState)
 	if handlers == nil {
 		logger.Debugw(ctx, "no-op-transition", log.Fields{"deviceId": device.Id})
 		return nil
 	}
-	logger.Debugw(ctx, "handler-found", log.Fields{"num-expectedHandlers": len(handlers), "isParent": device.Root, "current-data": device, "previous-data": prevDevice})
+	logger.Debugw(ctx, "handler-found", log.Fields{"num-expectedHandlers": len(handlers), "isParent": device.Root,
+		"current-data": device, "previous-data": prevDevice})
 	for _, handler := range handlers {
 		logger.Debugw(ctx, "running-handler", log.Fields{"handler": funcName(handler)})
 		if err := handler(ctx, device); err != nil {
diff --git a/rw_core/core/device/state/transitions_test.go b/rw_core/core/device/state/transitions_test.go
index a8f96ad..a085f97 100644
--- a/rw_core/core/device/state/transitions_test.go
+++ b/rw_core/core/device/state/transitions_test.go
@@ -52,123 +52,151 @@
 }
 
 func assertInvalidTransition(t *testing.T, device, prevDevice *voltha.Device) {
-	handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice)
+	handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.NotifyInvalidTransition).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 }
 
 func assertNoOpTransition(t *testing.T, device, prevDevice *voltha.Device) {
-	handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice)
+	handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 0, len(handlers))
 }
 
 func TestValidTransitions(t *testing.T) {
 	ctx := context.Background()
+
 	previousDevice := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
 	device := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers := transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers := transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
 	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
 	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
 	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
 	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
 	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	device = getDevice(true, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	device = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+		voltha.DeviceTransientState_ANY)
+	assert.Equal(t, 1, len(handlers))
+	assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
+
+	previousDevice = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE,
+		voltha.DeviceTransientState_ANY)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	device = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	device = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+		voltha.DeviceTransientState_ANY)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	device = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+		voltha.DeviceTransientState_ANY)
 	assert.Equal(t, 3, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.ChildDeviceLost).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.DeleteLogicalPorts).Pointer() == reflect.ValueOf(handlers[1]).Pointer())
@@ -176,7 +204,8 @@
 
 	previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
 	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 4, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.DeleteAllLogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.DeleteAllChildDevices).Pointer() == reflect.ValueOf(handlers[1]).Pointer())
@@ -185,13 +214,15 @@
 
 	previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
 	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	previousDevice = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN)
 	device = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 4, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.DeleteAllLogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.DeleteAllChildDevices).Pointer() == reflect.ValueOf(handlers[1]).Pointer())
@@ -200,7 +231,8 @@
 
 	previousDevice = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
 	device = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+	handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+		voltha.DeviceTransientState_NONE)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
@@ -220,9 +252,9 @@
 			getDevice(false, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
 		},
 		devices: []*voltha.Device{
-			getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
-			getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
-			getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_FAILED),
+			getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
+			getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
+			getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_FAILED),
 		},
 		expectedParentHandlers: []transitionHandler{
 			tdm.DeleteAllLogicalPorts,
@@ -242,7 +274,8 @@
 		for _, device := range deleteDeviceTest.devices {
 			device.Root = true
 			t.Run(testName, func(t *testing.T) {
-				handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+				handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+					voltha.DeviceTransientState_ANY)
 				assert.Equal(t, 4, len(handlers))
 				for idx, expHandler := range deleteDeviceTest.expectedParentHandlers {
 					assert.True(t, reflect.ValueOf(expHandler).Pointer() == reflect.ValueOf(handlers[idx]).Pointer())
@@ -256,7 +289,8 @@
 		for _, device := range deleteDeviceTest.devices {
 			device.Root = false
 			t.Run(testName, func(t *testing.T) {
-				handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+				handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+					voltha.DeviceTransientState_ANY)
 				assert.Equal(t, 3, len(handlers))
 				for idx, expHandler := range deleteDeviceTest.expectedChildHandlers {
 					assert.True(t, reflect.ValueOf(expHandler).Pointer() == reflect.ValueOf(handlers[idx]).Pointer())
@@ -264,6 +298,7 @@
 			})
 		}
 	}
+
 }
 
 func TestInvalidTransitions(t *testing.T) {
@@ -297,6 +332,7 @@
 }
 
 func TestNoOpTransitions(t *testing.T) {
+
 	previousDevice := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
 	device := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
 	assertNoOpTransition(t, device, previousDevice)
@@ -323,7 +359,7 @@
 }
 
 func TestMatch(t *testing.T) {
-	best := &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch}
-	m := &match{admin: currStateOnlyMatch, oper: currWildcardMatch, conn: currWildcardMatch}
+	best := &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch, transient: currWildcardMatch}
+	m := &match{admin: currStateOnlyMatch, oper: currWildcardMatch, conn: currWildcardMatch, transient: currWildcardMatch}
 	fmt.Println(m.isBetterMatch(best), m.toInt(), best.toInt())
 }
diff --git a/rw_core/core/device/transientstate/common.go b/rw_core/core/device/transientstate/common.go
new file mode 100644
index 0000000..b22c789
--- /dev/null
+++ b/rw_core/core/device/transientstate/common.go
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package core Common Logger initialization
+package transientstate
+
+import (
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+var logger log.CLogger
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/rw_core/core/device/transientstate/loader.go b/rw_core/core/device/transientstate/loader.go
new file mode 100644
index 0000000..f8710cc
--- /dev/null
+++ b/rw_core/core/device/transientstate/loader.go
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package transientstate
+
+import (
+	"context"
+	"fmt"
+	"sync"
+
+	"github.com/opencord/voltha-go/db/model"
+	"github.com/opencord/voltha-lib-go/v4/pkg/log"
+	"github.com/opencord/voltha-protos/v4/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+// Loader hides all low-level locking & synchronization related to device transient state updates
+type Loader struct {
+	dbProxy *model.Proxy
+	// this lock protects the device transient state
+	lock                 sync.RWMutex
+	deviceTransientState *data
+}
+
+type data struct {
+	transientState voltha.DeviceTransientState_Types
+	deviceID       string
+}
+
+func NewLoader(dbProxy *model.Proxy, deviceID string) *Loader {
+	return &Loader{
+		dbProxy: dbProxy,
+		deviceTransientState: &data{
+			transientState: voltha.DeviceTransientState_NONE,
+			deviceID:       deviceID,
+		},
+	}
+}
+
+// Load queries existing transient state from the kv,
+// and should only be called once when first created.
+func (loader *Loader) Load(ctx context.Context) {
+	loader.lock.Lock()
+	defer loader.lock.Unlock()
+
+	var deviceTransientState voltha.DeviceTransientState
+	if have, err := loader.dbProxy.Get(ctx, loader.deviceTransientState.deviceID, &deviceTransientState); err != nil || !have {
+		logger.Errorw(ctx, "failed-to-get-device-transient-state-from-cluster-data-proxy", log.Fields{"error": err})
+		return
+	}
+	loader.deviceTransientState.transientState = deviceTransientState.TransientState
+}
+
+// Lock acquires the lock for deviceTransientStateLoader, and returns a handle
+// which can be used to access it until it's unlocked.
+// This handle ensures that the deviceTransientState cannot be accessed if the lock is not held.
+// TODO: consider accepting a ctx and aborting the lock attempt on cancellation
+func (loader *Loader) Lock() *Handle {
+	loader.lock.Lock()
+	dataTransientState := loader.deviceTransientState
+	return &Handle{loader: loader, data: dataTransientState}
+}
+
+// Handle is allocated for each Lock() call, all modifications are made using it, and it is invalidated by Unlock()
+// This enforces correct Lock()-Usage()-Unlock() ordering.
+type Handle struct {
+	loader *Loader
+	data   *data
+}
+
+// GetReadOnly returns device transient which MUST NOT be modified externally, but which is safe to keep indefinitely
+func (h *Handle) GetReadOnly() voltha.DeviceTransientState_Types {
+	return h.data.transientState
+}
+
+// Update updates device transient state in KV store
+// The provided device transient state must not be modified afterwards.
+func (h *Handle) Update(ctx context.Context, state voltha.DeviceTransientState_Types) error {
+	var tState voltha.DeviceTransientState
+	tState.TransientState = state
+	if err := h.loader.dbProxy.Set(ctx, fmt.Sprint(h.data.deviceID), &tState); err != nil {
+		return status.Errorf(codes.Internal, "failed-to-update-device-%v-transient-state: %s", h.data.deviceID, err)
+	}
+	h.data.transientState = state
+	return nil
+}
+
+// Delete deletes device transient state from KV store
+func (h *Handle) Delete(ctx context.Context) error {
+	if err := h.loader.dbProxy.Remove(ctx, fmt.Sprint(h.data.deviceID)); err != nil {
+		return status.Errorf(codes.Internal, "failed-to-delete-device-%v-transient-state: %s", h.data.deviceID, err)
+	}
+	return nil
+}
+
+// UnLock releases the lock on the device transient state.
+func (h *Handle) UnLock() {
+	defer h.loader.lock.Unlock()
+	h.data = nil
+}
diff --git a/rw_core/mocks/adapter.go b/rw_core/mocks/adapter.go
index 26f796fa4..c01fc70 100644
--- a/rw_core/mocks/adapter.go
+++ b/rw_core/mocks/adapter.go
@@ -45,13 +45,14 @@
 
 // Adapter represents adapter attributes
 type Adapter struct {
-	coreProxy      adapterif.CoreProxy
-	flows          map[uint64]*voltha.OfpFlowStats
-	flowLock       sync.RWMutex
-	devices        map[string]*voltha.Device
-	deviceLock     sync.RWMutex
-	failFlowAdd    bool
-	failFlowDelete bool
+	coreProxy        adapterif.CoreProxy
+	flows            map[uint64]*voltha.OfpFlowStats
+	flowLock         sync.RWMutex
+	devices          map[string]*voltha.Device
+	deviceLock       sync.RWMutex
+	failFlowAdd      bool
+	failFlowDelete   bool
+	failDeleteDevice bool
 }
 
 // NewAdapter creates adapter instance
@@ -133,6 +134,9 @@
 
 // Delete_device -
 func (ta *Adapter) Delete_device(ctx context.Context, device *voltha.Device) error { // nolint
+	if ta.failDeleteDevice {
+		return fmt.Errorf("delete-device-failure")
+	}
 	return nil
 }
 
@@ -284,3 +288,8 @@
 	ta.failFlowAdd = failFlowAdd
 	ta.failFlowDelete = failFlowDelete
 }
+
+// SetDeleteAction sets the adapter action on delete device
+func (ta *Adapter) SetDeleteAction(failDeleteDevice bool) {
+	ta.failDeleteDevice = failDeleteDevice
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go
index c476a08..0956330 100644
--- a/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go
@@ -57,10 +57,6 @@
 	AdminState_DISABLED AdminState_Types = 3
 	// The device is in the state of image download
 	AdminState_DOWNLOADING_IMAGE AdminState_Types = 4
-	// The device is marked to be deleted
-	AdminState_DELETED AdminState_Types = 5
-	// The device is marked to be in deleting state
-	AdminState_DELETING AdminState_Types = 6
 )
 
 var AdminState_Types_name = map[int32]string{
@@ -69,8 +65,6 @@
 	2: "ENABLED",
 	3: "DISABLED",
 	4: "DOWNLOADING_IMAGE",
-	5: "DELETED",
-	6: "DELETING",
 }
 
 var AdminState_Types_value = map[string]int32{
@@ -79,8 +73,6 @@
 	"ENABLED":           2,
 	"DISABLED":          3,
 	"DOWNLOADING_IMAGE": 4,
-	"DELETED":           5,
-	"DELETING":          6,
 }
 
 func (x AdminState_Types) String() string {
@@ -604,44 +596,43 @@
 func init() { proto.RegisterFile("voltha_protos/common.proto", fileDescriptor_c2e3fd231961e826) }
 
 var fileDescriptor_c2e3fd231961e826 = []byte{
-	// 614 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x4f, 0x4f, 0xdb, 0x4e,
-	0x10, 0x8d, 0x9d, 0x3f, 0x3f, 0x32, 0x21, 0xc6, 0xbf, 0x05, 0xaa, 0x14, 0x55, 0x6a, 0xe4, 0x0b,
-	0xb4, 0xa2, 0x89, 0x44, 0xb9, 0xf6, 0x60, 0xec, 0x2d, 0x5d, 0x01, 0xeb, 0x68, 0x6d, 0x07, 0xd1,
-	0x43, 0x23, 0x13, 0x2f, 0xc1, 0x12, 0xf1, 0x5a, 0xf6, 0x06, 0x89, 0x73, 0x3f, 0x64, 0xbf, 0x4e,
-	0xb5, 0xeb, 0xf0, 0xaf, 0xe2, 0x62, 0xfb, 0xcd, 0x7b, 0x3b, 0x33, 0x6f, 0xc6, 0x0b, 0x7b, 0xf7,
-	0xe2, 0x4e, 0xde, 0x26, 0xb3, 0xa2, 0x14, 0x52, 0x54, 0xe3, 0xb9, 0x58, 0x2e, 0x45, 0x3e, 0xd2,
-	0x08, 0x75, 0x6a, 0xe4, 0xec, 0x80, 0x49, 0x7c, 0x64, 0x81, 0x99, 0xa5, 0x03, 0x63, 0x68, 0x1c,
-	0x74, 0x99, 0x99, 0xa5, 0xce, 0x3e, 0x34, 0x89, 0x5f, 0xa1, 0x21, 0xb4, 0x33, 0xc9, 0x97, 0xd5,
-	0xc0, 0x18, 0x36, 0x0f, 0x7a, 0x47, 0x30, 0x5a, 0xa7, 0x20, 0x3e, 0xab, 0x09, 0xe7, 0xb7, 0x01,
-	0xe0, 0xa6, 0xcb, 0x2c, 0x0f, 0x65, 0x22, 0xb9, 0xb3, 0x82, 0x76, 0xf4, 0x50, 0xf0, 0x0a, 0xf5,
-	0xe0, 0xbf, 0x98, 0x9e, 0xd1, 0xe0, 0x92, 0xda, 0x0d, 0x84, 0xc0, 0x9a, 0x30, 0x3c, 0x61, 0xc1,
-	0x94, 0x84, 0x24, 0xa0, 0xd8, 0xb7, 0x0d, 0x25, 0xc0, 0xd4, 0x3d, 0x39, 0xc7, 0xbe, 0x6d, 0xa2,
-	0x4d, 0xd8, 0xf0, 0x49, 0x58, 0xa3, 0x26, 0xda, 0x85, 0xff, 0xfd, 0xe0, 0x92, 0x9e, 0x07, 0xae,
-	0x4f, 0xe8, 0xe9, 0x8c, 0x5c, 0xb8, 0xa7, 0xd8, 0x6e, 0xa9, 0x13, 0x3e, 0x3e, 0xc7, 0x11, 0xf6,
-	0xed, 0xb6, 0x3e, 0xa1, 0x00, 0xa1, 0xa7, 0x76, 0xc7, 0x59, 0x00, 0x04, 0x05, 0x2f, 0x55, 0x0f,
-	0xab, 0xca, 0xb9, 0x7a, 0xb3, 0x09, 0x0b, 0xc0, 0x27, 0xa1, 0x17, 0x4c, 0x31, 0xd3, 0x0d, 0x58,
-	0x00, 0xae, 0x17, 0x91, 0xa9, 0xab, 0x73, 0x98, 0x4a, 0x1c, 0xe1, 0x50, 0x83, 0x26, 0x02, 0xe8,
-	0x68, 0x52, 0xd5, 0x05, 0xe8, 0x7c, 0x77, 0x89, 0x6a, 0xad, 0xed, 0x60, 0xe8, 0x7b, 0x22, 0xcf,
-	0xf9, 0x5c, 0xae, 0x6b, 0x1d, 0xbf, 0x59, 0x6b, 0x0b, 0x7a, 0x31, 0x65, 0xd8, 0xf5, 0x7e, 0x28,
-	0x4f, 0xb6, 0x81, 0xfa, 0xd0, 0x7d, 0x86, 0xa6, 0xf3, 0xc7, 0x80, 0xbe, 0x6a, 0x38, 0x91, 0x99,
-	0xc8, 0x19, 0xaf, 0x0a, 0xf4, 0x0d, 0x5a, 0x73, 0x91, 0x72, 0xbd, 0x02, 0xeb, 0xe8, 0xd3, 0xe3,
-	0xa0, 0x5f, 0x89, 0x5e, 0x22, 0xb9, 0x2a, 0x73, 0x4f, 0xa4, 0x9c, 0xe9, 0x63, 0x68, 0x1f, 0xb6,
-	0x92, 0x34, 0xcd, 0x14, 0x97, 0xdc, 0xcd, 0xb2, 0xfc, 0x46, 0x0c, 0x4c, 0xbd, 0x4c, 0xeb, 0x39,
-	0x4c, 0xf2, 0x1b, 0xe1, 0xfc, 0x82, 0xed, 0x37, 0xb2, 0xa8, 0x91, 0x07, 0x13, 0xcc, 0xdc, 0x88,
-	0x04, 0x74, 0x16, 0xc6, 0x9e, 0x87, 0xc3, 0xd0, 0x6e, 0xbc, 0x0e, 0xab, 0x21, 0xc4, 0x4c, 0xb9,
-	0x79, 0x0f, 0xbb, 0xcf, 0xe1, 0x98, 0x86, 0xf1, 0x64, 0x12, 0x30, 0xb5, 0x17, 0xd3, 0x39, 0x84,
-	0xee, 0x34, 0xb9, 0x5b, 0x71, 0x35, 0x14, 0xe7, 0x23, 0xb4, 0xd4, 0x1b, 0x75, 0xa1, 0x8d, 0x2f,
-	0x26, 0xd1, 0x95, 0xdd, 0x58, 0x6f, 0x3a, 0x72, 0xa9, 0x87, 0x6d, 0xc3, 0xa1, 0x60, 0x69, 0x75,
-	0x58, 0xf0, 0x79, 0x76, 0x93, 0xf1, 0xf2, 0xdf, 0x1f, 0x11, 0x1d, 0x42, 0xfb, 0x5e, 0x29, 0xb4,
-	0x1d, 0xeb, 0xe8, 0xdd, 0xe3, 0x60, 0x9e, 0x8a, 0x8c, 0xd4, 0x83, 0xd5, 0x22, 0x47, 0xc2, 0x66,
-	0x6d, 0x4a, 0xd3, 0x15, 0xb2, 0xa1, 0x19, 0x72, 0xa9, 0xd3, 0xf5, 0x99, 0xfa, 0x44, 0x43, 0xe8,
-	0xc5, 0x79, 0xb5, 0x2a, 0x0a, 0x51, 0x4a, 0x9e, 0xea, 0xac, 0x7d, 0xf6, 0x32, 0x84, 0x76, 0xa0,
-	0x8d, 0xcb, 0x52, 0x94, 0x83, 0xa6, 0xe6, 0x6a, 0x80, 0xf6, 0x60, 0xc3, 0xcf, 0x2a, 0x99, 0xe4,
-	0x73, 0x3e, 0x68, 0x69, 0xe2, 0x09, 0x7f, 0xfe, 0x00, 0x9b, 0x11, 0xaf, 0xe4, 0x85, 0x48, 0xf9,
-	0x19, 0x7f, 0xa8, 0x94, 0xc7, 0xa4, 0xc8, 0x66, 0x92, 0x57, 0xd2, 0x6e, 0x9c, 0x60, 0xd8, 0x16,
-	0xe5, 0x62, 0x24, 0x0a, 0x9e, 0xcf, 0x45, 0x99, 0x8e, 0xea, 0x3b, 0xf9, 0x73, 0xb4, 0xc8, 0xe4,
-	0xed, 0xea, 0x5a, 0xf9, 0x19, 0x3f, 0x72, 0xe3, 0x9a, 0xfb, 0xb2, 0xbe, 0xaf, 0xf7, 0xc7, 0xe3,
-	0x85, 0x58, 0xdf, 0xda, 0xeb, 0x8e, 0x0e, 0x7e, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x36, 0xc3,
-	0x8c, 0xb0, 0xd4, 0x03, 0x00, 0x00,
+	// 598 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x5f, 0x4f, 0xdb, 0x3e,
+	0x14, 0x6d, 0xd2, 0x96, 0x1f, 0xbd, 0xa5, 0x21, 0x3f, 0x03, 0x53, 0x87, 0x26, 0xad, 0xca, 0x0b,
+	0x6c, 0x62, 0xad, 0xc4, 0x78, 0xdd, 0x43, 0x48, 0x3c, 0x66, 0x01, 0x4e, 0xe5, 0x24, 0x45, 0xf0,
+	0xb0, 0x2a, 0x34, 0xa6, 0x44, 0xa2, 0x71, 0x94, 0xb8, 0x48, 0x7c, 0xd2, 0x7d, 0x9d, 0xc9, 0x4e,
+	0xf9, 0x37, 0xf5, 0x25, 0xf1, 0xb9, 0xe7, 0xe4, 0x1e, 0xdf, 0xe3, 0x18, 0xf6, 0x1f, 0xc5, 0x83,
+	0xbc, 0x4f, 0xa6, 0x45, 0x29, 0xa4, 0xa8, 0x46, 0x33, 0xb1, 0x58, 0x88, 0x7c, 0xa8, 0x11, 0xda,
+	0xa8, 0x91, 0xb3, 0x0b, 0x26, 0xf1, 0x91, 0x05, 0x66, 0x96, 0xf6, 0x8d, 0x81, 0x71, 0xd8, 0x61,
+	0x66, 0x96, 0x3a, 0x07, 0xd0, 0x24, 0x7e, 0x85, 0x06, 0xd0, 0xce, 0x24, 0x5f, 0x54, 0x7d, 0x63,
+	0xd0, 0x3c, 0xec, 0x1e, 0xc3, 0x70, 0xd5, 0x82, 0xf8, 0xac, 0x26, 0x9c, 0x7b, 0x00, 0x37, 0x5d,
+	0x64, 0x79, 0x28, 0x13, 0xc9, 0x9d, 0x1b, 0x68, 0x47, 0x4f, 0x05, 0xaf, 0x50, 0x17, 0xfe, 0x8b,
+	0xe9, 0x39, 0x0d, 0xae, 0xa8, 0xdd, 0x40, 0x08, 0xac, 0x31, 0xc3, 0x63, 0x16, 0x4c, 0x48, 0x48,
+	0x02, 0x8a, 0x7d, 0xdb, 0x50, 0x02, 0x4c, 0xdd, 0xd3, 0x0b, 0xec, 0xdb, 0x26, 0xda, 0x82, 0x4d,
+	0x9f, 0x84, 0x35, 0x6a, 0xa2, 0x3d, 0xf8, 0xdf, 0x0f, 0xae, 0xe8, 0x45, 0xe0, 0xfa, 0x84, 0x9e,
+	0x4d, 0xc9, 0xa5, 0x7b, 0x86, 0xed, 0x96, 0x33, 0x07, 0x08, 0x0a, 0x5e, 0x2a, 0xa3, 0x65, 0xe5,
+	0x5c, 0xaf, 0x75, 0xb2, 0x00, 0x7c, 0x12, 0x7a, 0xc1, 0x04, 0x33, 0xed, 0x62, 0x01, 0xb8, 0x5e,
+	0x44, 0x26, 0x6e, 0x44, 0xe8, 0x99, 0x6d, 0x2a, 0x71, 0x84, 0x43, 0x0d, 0x9a, 0x08, 0x60, 0x43,
+	0x93, 0xd8, 0x6e, 0xa9, 0xf5, 0x4f, 0x97, 0x28, 0xff, 0xb6, 0x83, 0xa1, 0xe7, 0x89, 0x3c, 0xe7,
+	0x33, 0xb9, 0xf2, 0x3a, 0x59, 0xeb, 0xb5, 0x0d, 0xdd, 0x98, 0x32, 0xec, 0x7a, 0xbf, 0xd4, 0xc6,
+	0x6d, 0x03, 0xf5, 0xa0, 0xf3, 0x0a, 0x4d, 0xe7, 0x8f, 0x01, 0x3d, 0xb5, 0xe1, 0x44, 0x66, 0x22,
+	0x67, 0xbc, 0x2a, 0xd0, 0x0f, 0x68, 0xcd, 0x44, 0xca, 0x75, 0xcc, 0xd6, 0xf1, 0x97, 0xe7, 0x30,
+	0xdf, 0x89, 0xde, 0x22, 0xb9, 0x2c, 0x73, 0x4f, 0xa4, 0x9c, 0xe9, 0xcf, 0xd0, 0x01, 0x6c, 0x27,
+	0x69, 0x9a, 0x29, 0x2e, 0x79, 0x98, 0x66, 0xf9, 0x9d, 0xe8, 0x9b, 0xfa, 0xc0, 0xac, 0xd7, 0x32,
+	0xc9, 0xef, 0x84, 0xf3, 0x1b, 0x76, 0xd6, 0x74, 0x51, 0xb9, 0x06, 0x63, 0xcc, 0xdc, 0x88, 0x04,
+	0x74, 0x1a, 0xc6, 0x9e, 0x87, 0xc3, 0xd0, 0x6e, 0xbc, 0x2f, 0xab, 0x10, 0x62, 0xa6, 0xa6, 0xf9,
+	0x08, 0x7b, 0xaf, 0xe5, 0x98, 0x86, 0xf1, 0x78, 0x1c, 0xb0, 0x48, 0x1d, 0x97, 0x73, 0x04, 0x9d,
+	0x49, 0xf2, 0xb0, 0xe4, 0x2a, 0x14, 0xe7, 0x33, 0xb4, 0xd4, 0x1b, 0x75, 0xa0, 0x8d, 0x2f, 0xc7,
+	0xd1, 0xb5, 0xdd, 0x58, 0x1d, 0x67, 0xe4, 0x52, 0x0f, 0xdb, 0x86, 0x43, 0xc1, 0xd2, 0xea, 0xb0,
+	0xe0, 0xb3, 0xec, 0x2e, 0xe3, 0xe5, 0xbf, 0x3f, 0x1b, 0x3a, 0x82, 0xf6, 0xa3, 0x52, 0xe8, 0x71,
+	0xac, 0xe3, 0x0f, 0xcf, 0xc1, 0xbc, 0x98, 0x0c, 0xd5, 0x83, 0xd5, 0x22, 0x47, 0xc2, 0x56, 0x3d,
+	0x94, 0xa6, 0x2b, 0x64, 0x43, 0x33, 0xe4, 0x52, 0xb7, 0xeb, 0x31, 0xb5, 0x44, 0x03, 0xe8, 0xc6,
+	0x79, 0xb5, 0x2c, 0x0a, 0x51, 0x4a, 0x9e, 0xea, 0xae, 0x3d, 0xf6, 0xb6, 0x84, 0x76, 0xa1, 0x8d,
+	0xcb, 0x52, 0x94, 0xfd, 0xa6, 0xe6, 0x6a, 0x80, 0xf6, 0x61, 0xd3, 0xcf, 0x2a, 0x99, 0xe4, 0x33,
+	0xde, 0x6f, 0x69, 0xe2, 0x05, 0x7f, 0xfd, 0x04, 0x5b, 0x11, 0xaf, 0xe4, 0xa5, 0x48, 0xf9, 0x39,
+	0x7f, 0xaa, 0xd4, 0x8c, 0x49, 0x91, 0x4d, 0x25, 0xaf, 0xa4, 0xdd, 0x38, 0xc5, 0xb0, 0x23, 0xca,
+	0xf9, 0x50, 0x14, 0x3c, 0x9f, 0x89, 0x32, 0x1d, 0xd6, 0xf7, 0xee, 0x66, 0x38, 0xcf, 0xe4, 0xfd,
+	0xf2, 0x56, 0xcd, 0x33, 0x7a, 0xe6, 0x46, 0x35, 0xf7, 0x6d, 0x75, 0x27, 0x1f, 0x4f, 0x46, 0x73,
+	0xb1, 0xba, 0x99, 0xb7, 0x1b, 0xba, 0xf8, 0xfd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7d, 0x32,
+	0x70, 0x38, 0xb8, 0x03, 0x00, 0x00,
 }
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go
index 16c4520..752eecb 100644
--- a/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go
@@ -71,8 +71,6 @@
 const AdminState_ENABLED = AdminState_Types(common.AdminState_ENABLED)
 const AdminState_DISABLED = AdminState_Types(common.AdminState_DISABLED)
 const AdminState_DOWNLOADING_IMAGE = AdminState_Types(common.AdminState_DOWNLOADING_IMAGE)
-const AdminState_DELETED = AdminState_Types(common.AdminState_DELETED)
-const AdminState_DELETING = AdminState_Types(common.AdminState_DELETING)
 
 // OperStatus_Types from public import voltha_protos/common.proto
 type OperStatus_Types = common.OperStatus_Types
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/voltha/core.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/core.pb.go
new file mode 100644
index 0000000..4c92095
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/core.pb.go
@@ -0,0 +1,133 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/core.proto
+
+package voltha
+
+import (
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+// Transient State for devices
+type DeviceTransientState_Types int32
+
+const (
+	// The transient state of the device is not set
+	DeviceTransientState_NONE DeviceTransientState_Types = 0
+	// The state of the device in core is any state, i.e DELETING, DELETED, DELETE_FAILED, NONE.
+	// This state is only used for transitions.
+	DeviceTransientState_ANY DeviceTransientState_Types = 1
+	// The device is in FORCE_DELETING state
+	DeviceTransientState_FORCE_DELETING DeviceTransientState_Types = 2
+	// The device is getting deleted from adapter state
+	DeviceTransientState_DELETING_FROM_ADAPTER DeviceTransientState_Types = 3
+	// The device is deleted from adapter and is getting deleted in core.
+	DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE DeviceTransientState_Types = 4
+	// State to represent that the device deletion is failed
+	DeviceTransientState_DELETE_FAILED DeviceTransientState_Types = 5
+)
+
+var DeviceTransientState_Types_name = map[int32]string{
+	0: "NONE",
+	1: "ANY",
+	2: "FORCE_DELETING",
+	3: "DELETING_FROM_ADAPTER",
+	4: "DELETING_POST_ADAPTER_RESPONSE",
+	5: "DELETE_FAILED",
+}
+
+var DeviceTransientState_Types_value = map[string]int32{
+	"NONE":                           0,
+	"ANY":                            1,
+	"FORCE_DELETING":                 2,
+	"DELETING_FROM_ADAPTER":          3,
+	"DELETING_POST_ADAPTER_RESPONSE": 4,
+	"DELETE_FAILED":                  5,
+}
+
+func (x DeviceTransientState_Types) String() string {
+	return proto.EnumName(DeviceTransientState_Types_name, int32(x))
+}
+
+func (DeviceTransientState_Types) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_39634f15fb8a505e, []int{0, 0}
+}
+
+type DeviceTransientState struct {
+	TransientState       DeviceTransientState_Types `protobuf:"varint,1,opt,name=transient_state,json=transientState,proto3,enum=voltha.DeviceTransientState_Types" json:"transient_state,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                   `json:"-"`
+	XXX_unrecognized     []byte                     `json:"-"`
+	XXX_sizecache        int32                      `json:"-"`
+}
+
+func (m *DeviceTransientState) Reset()         { *m = DeviceTransientState{} }
+func (m *DeviceTransientState) String() string { return proto.CompactTextString(m) }
+func (*DeviceTransientState) ProtoMessage()    {}
+func (*DeviceTransientState) Descriptor() ([]byte, []int) {
+	return fileDescriptor_39634f15fb8a505e, []int{0}
+}
+
+func (m *DeviceTransientState) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_DeviceTransientState.Unmarshal(m, b)
+}
+func (m *DeviceTransientState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_DeviceTransientState.Marshal(b, m, deterministic)
+}
+func (m *DeviceTransientState) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_DeviceTransientState.Merge(m, src)
+}
+func (m *DeviceTransientState) XXX_Size() int {
+	return xxx_messageInfo_DeviceTransientState.Size(m)
+}
+func (m *DeviceTransientState) XXX_DiscardUnknown() {
+	xxx_messageInfo_DeviceTransientState.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceTransientState proto.InternalMessageInfo
+
+func (m *DeviceTransientState) GetTransientState() DeviceTransientState_Types {
+	if m != nil {
+		return m.TransientState
+	}
+	return DeviceTransientState_NONE
+}
+
+func init() {
+	proto.RegisterEnum("voltha.DeviceTransientState_Types", DeviceTransientState_Types_name, DeviceTransientState_Types_value)
+	proto.RegisterType((*DeviceTransientState)(nil), "voltha.DeviceTransientState")
+}
+
+func init() { proto.RegisterFile("voltha_protos/core.proto", fileDescriptor_39634f15fb8a505e) }
+
+var fileDescriptor_39634f15fb8a505e = []byte{
+	// 264 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc4, 0x30,
+	0x10, 0x86, 0xad, 0xfb, 0xa1, 0x0c, 0x58, 0x63, 0x54, 0x58, 0x2f, 0x22, 0x3d, 0x79, 0x31, 0x05,
+	0xf5, 0x0f, 0x54, 0x3b, 0x95, 0xc5, 0xb5, 0x2d, 0x6d, 0x2e, 0x7a, 0x09, 0xdd, 0x1a, 0xba, 0x05,
+	0x6d, 0x4a, 0x1a, 0x0b, 0xde, 0xfc, 0xb5, 0xfe, 0x0e, 0xb1, 0x1f, 0x82, 0xb0, 0xb7, 0x99, 0xe7,
+	0x99, 0xf7, 0x30, 0x2f, 0x2c, 0x5a, 0xf5, 0x66, 0x36, 0x99, 0xa8, 0xb5, 0x32, 0xaa, 0x71, 0x73,
+	0xa5, 0x25, 0xeb, 0x66, 0x3a, 0xef, 0x8d, 0xf3, 0x6d, 0xc1, 0x89, 0x2f, 0xdb, 0x32, 0x97, 0x5c,
+	0x67, 0x55, 0x53, 0xca, 0xca, 0xa4, 0x26, 0x33, 0x92, 0x3e, 0xc2, 0xa1, 0x19, 0x89, 0x68, 0x7e,
+	0xd1, 0xc2, 0xba, 0xb0, 0x2e, 0xed, 0x6b, 0x87, 0xf5, 0x51, 0xb6, 0x2d, 0xc6, 0xf8, 0x67, 0x2d,
+	0x9b, 0xc4, 0x36, 0xff, 0xa8, 0xf3, 0x65, 0xc1, 0xac, 0x33, 0x74, 0x1f, 0xa6, 0x61, 0x14, 0x22,
+	0xd9, 0xa1, 0x7b, 0x30, 0xf1, 0xc2, 0x67, 0x62, 0x51, 0x0a, 0x76, 0x10, 0x25, 0xf7, 0x28, 0x7c,
+	0x5c, 0x21, 0x5f, 0x86, 0x0f, 0x64, 0x97, 0x9e, 0xc1, 0xe9, 0xb8, 0x89, 0x20, 0x89, 0x9e, 0x84,
+	0xe7, 0x7b, 0x31, 0xc7, 0x84, 0x4c, 0xa8, 0x03, 0xe7, 0x7f, 0x2a, 0x8e, 0x52, 0x3e, 0x2a, 0x91,
+	0x60, 0x1a, 0x47, 0x61, 0x8a, 0x64, 0x4a, 0x8f, 0xe0, 0xa0, 0xbb, 0x41, 0x11, 0x78, 0xcb, 0x15,
+	0xfa, 0x64, 0x76, 0x87, 0x70, 0xac, 0x74, 0xc1, 0x54, 0x2d, 0xab, 0x5c, 0xe9, 0xd7, 0xe1, 0x89,
+	0x17, 0x56, 0x94, 0x66, 0xf3, 0xb1, 0x66, 0xb9, 0x7a, 0x77, 0x47, 0xe7, 0xf6, 0xee, 0x6a, 0x68,
+	0xad, 0xbd, 0x75, 0x0b, 0x35, 0xb0, 0xf5, 0xbc, 0x83, 0x37, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff,
+	0xe3, 0x06, 0xbc, 0xa1, 0x5a, 0x01, 0x00, 0x00,
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go
index 4db124f..217adcf 100644
--- a/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go
@@ -91,8 +91,6 @@
 const AdminState_ENABLED = AdminState_Types(common.AdminState_ENABLED)
 const AdminState_DISABLED = AdminState_Types(common.AdminState_DISABLED)
 const AdminState_DOWNLOADING_IMAGE = AdminState_Types(common.AdminState_DOWNLOADING_IMAGE)
-const AdminState_DELETED = AdminState_Types(common.AdminState_DELETED)
-const AdminState_DELETING = AdminState_Types(common.AdminState_DELETING)
 
 // OperStatus_Types from public import voltha_protos/common.proto
 type OperStatus_Types = common.OperStatus_Types
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c8b6a04..b190e83 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -117,7 +117,7 @@
 github.com/opencord/voltha-lib-go/v4/pkg/mocks/kafka
 github.com/opencord/voltha-lib-go/v4/pkg/probe
 github.com/opencord/voltha-lib-go/v4/pkg/version
-# github.com/opencord/voltha-protos/v4 v4.0.2
+# github.com/opencord/voltha-protos/v4 v4.0.5
 github.com/opencord/voltha-protos/v4/go/common
 github.com/opencord/voltha-protos/v4/go/ext/config
 github.com/opencord/voltha-protos/v4/go/inter_container