diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcRpcManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcRpcManager.java
index 3a8c2f9..f29b1a2 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcRpcManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcRpcManager.java
@@ -175,8 +175,16 @@
     protected void deactivate() {
         deviceService.removeListener(listener);
         rpcRegistry.unregisterRpcService(this);
+
+        CLIENT_INFO.keySet().forEach(this::deleteSessions);
         CLIENT_INFO.clear();
+        CLIENT_CONTEXTS_INFO.clear();
         TENANT_INFO.clear();
+
+        deleteNode(connections);
+        deleteNode(fpcAgents);
+        deleteNode(tenants);
+
         log.info("FPC RPC Service Stopped");
     }
 
@@ -299,7 +307,7 @@
 
                 Ip4Address s1USgwIpv4Dl = Ip4Address.valueOf(context.dl().tunnelLocalAddress().toString()),
                         s1UEnodebIpv4Dl = Ip4Address.valueOf(context.dl().tunnelRemoteAddress().toString()),
-			s1UEnodebIpv4Ul = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
+                        s1UEnodebIpv4Ul = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
                         s1USgwIpv4Ul = Ip4Address.valueOf(context.ul().tunnelRemoteAddress().toString());
 
                 long clientId = clientInfo.clientId().fpcIdentity().union().int64(),
@@ -339,6 +347,11 @@
                                 .build();
                         createNode(convertContext, modelObjectId);
                         cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
+                        HashSet<FpcContextId> contexts = CLIENT_CONTEXTS_INFO.getOrDefault(
+                                clientInfo.clientId(),
+                                Sets.newHashSet()
+                        );
+                        contexts.add(context.contextId());
                     }));
 
                     // FIXME why downlink is in session while uplink is not?
@@ -359,6 +372,11 @@
                                     .build();
                             createNode(convertContext, modelObjectId);
                             cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
+                            HashSet<FpcContextId> contexts = CLIENT_CONTEXTS_INFO.getOrDefault(
+                                    clientInfo.clientId(),
+                                    Sets.newHashSet()
+                            );
+                            contexts.add(context.contextId());
                         }));
                     }
                 } else if (commands.contains("indirect-forward")) {
@@ -468,13 +486,13 @@
 
                 Ip4Address s1USgwIpv4Dl = Ip4Address.valueOf(context.dl().tunnelLocalAddress().toString()),
                         s1UEnodebIpv4Dl = Ip4Address.valueOf(context.dl().tunnelRemoteAddress().toString()),
-			s1UEnodebIpv4Ul = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
+                        s1UEnodebIpv4Ul = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
                         s1USgwIpv4Ul = Ip4Address.valueOf(context.ul().tunnelRemoteAddress().toString());
 
                 long s1UEnbGtpuTeidDl = ((ThreegppTunnel) context.dl().mobilityTunnelParameters()
                         .mobprofileParameters()).tunnelIdentifier(),
-			s1UEnbGtpuTeidUl = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
-                        .mobprofileParameters()).tunnelIdentifier(),
+                        s1UEnbGtpuTeidUl = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
+                                .mobprofileParameters()).tunnelIdentifier(),
                         cId = clientInfo.clientId().fpcIdentity().union().int64(),
                         contextId = context.contextId().fpcIdentity().union().int64();
 
@@ -549,86 +567,67 @@
         return configureOutput;
     }
 
-    @Override
-    public DefaultConfigureOutput configureDelete(
-            DeleteOrQuery delete,
-            DefaultRegisterClientInput clientInfo,
-            OpIdentifier operationId
-    ) throws Exception {
-        DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
+    public Collection<Callable<Object>> deleteSessions(ClientIdentifier clientIdentifier) {
         Collection<Callable<Object>> tasks = new ArrayList<>();
-        // get client's tenant.
-        FpcIdentity tenantId = clientInfo.tenantId();
-        // get cache for specific tenant.
-        CacheManager cacheManager = CacheManager.getInstance(tenantId);
-        DefaultDeleteSuccess defaultDeleteSuccess = new DefaultDeleteSuccess();
-        for (Targets target : delete.targets()) {
-            defaultDeleteSuccess.addToTargets(target);
-            // parse context id.
-            String targetStr = target.target().toString(),
-                    s = StringUtils.substringBetween(targetStr, "contexts=", "/"),
-                    trgt = s != null ? s : StringUtils.substringAfter(targetStr, "contexts=");
+        try {
+            FpcIdentity tenantId = CLIENT_INFO.get(clientIdentifier).tenantId();
+            CacheManager cacheManager = CacheManager.getInstance(tenantId);
 
-            // find context that this target is about.
-            FpcContextId fpcContextId = FpcContextId.of(FpcIdentity.fromString(trgt));
-            Optional<DefaultContexts> defaultContexts = CacheManager.getInstance(tenantId)
-                    .contextsCache.get(fpcContextId);
-            if (!defaultContexts.isPresent()) {
-                throw new RuntimeException("Context doesn't exist. Please issue create operation..");
-            }
+            for (FpcContextId fpcContextId : CLIENT_CONTEXTS_INFO.get(clientIdentifier)) {
+                Optional<DefaultContexts> defaultContexts = null;
 
-            log.debug("handling configure-delete {}", targetStr);
+                defaultContexts = CacheManager.getInstance(tenantId).contextsCache.get(fpcContextId);
 
-            DefaultContexts context = defaultContexts.get();
-            for (Dpns dpn : context.dpns()) {
-                Optional<DefaultDpns> optionalDpn = cacheManager.dpnsCache.get(dpn.dpnId());
-                // check if dpns exists and if there is a DPN registered for the wanted identifier.
-                if (!optionalDpn.isPresent()) {
-                    // throw exception if DPN ID is not registered.
-                    throw new RuntimeException("DPN ID is not registered to the topology.");
+                if (!defaultContexts.isPresent()) {
+                    throw new RuntimeException("Context doesn't exist. Please issue create operation..");
                 }
 
-                final DpnCommunicationService dpnCommunicationService;
-                Class<? extends FpcDpnControlProtocol> controlProtocol = optionalDpn.get().controlProtocol();
-                if (controlProtocol.isAssignableFrom(ZmqDpnControlProtocol.class)) {
-                    dpnCommunicationService = DpnNgicCommunicator.getInstance();
-                } else if (controlProtocol.isAssignableFrom(P4DpnControlProtocol.class)) {
-                    DpnP4Communicator instance = DpnP4Communicator.getInstance();
-                    dpnCommunicationService = instance;
-                    instance.setDeviceId(
-                            DeviceId.deviceId(optionalDpn.get().dpnId().toString())
-                    );
-                    instance.setClientId(clientInfo.clientId());
-                } else {
-                    throw new RuntimeException("Control Protocol is not supported.");
-                }
+                DefaultContexts context = defaultContexts.get();
+                for (Dpns dpn : context.dpns()) {
+                    Optional<DefaultDpns> optionalDpn = cacheManager.dpnsCache.get(dpn.dpnId());
+                    // check if dpns exists and if there is a DPN registered for the wanted identifier.
+                    if (!optionalDpn.isPresent()) {
+                        // throw exception if DPN ID is not registered.
+                        throw new RuntimeException("DPN ID is not registered to the topology.");
+                    }
 
-                // from DPN ID find the Network and Node Identifiers
-                Optional<String> key = optionalDpn
-                        .map(node -> node.nodeId() + "/" + node.networkId());
-                if (!key.isPresent()) {
-                    throw new RuntimeException("DPN does not have node and network ID defined.");
-                }
+                    final DpnCommunicationService dpnCommunicationService;
+                    Class<? extends FpcDpnControlProtocol> controlProtocol = optionalDpn.get().controlProtocol();
+                    if (controlProtocol.isAssignableFrom(ZmqDpnControlProtocol.class)) {
+                        dpnCommunicationService = DpnNgicCommunicator.getInstance();
+                    } else if (controlProtocol.isAssignableFrom(P4DpnControlProtocol.class)) {
+                        DpnP4Communicator instance = DpnP4Communicator.getInstance();
+                        dpnCommunicationService = instance;
+                        instance.setDeviceId(
+                                DeviceId.deviceId(optionalDpn.get().dpnId().toString())
+                        );
+                        instance.setClientId(clientIdentifier);
+                    } else {
+                        throw new RuntimeException("Control Protocol is not supported.");
+                    }
 
-                // find DPN Topic from Node/Network ID pair.
-                byte topicId = getTopicFromNode(key.get());
-                if (topicId == -1 && dpnCommunicationService instanceof ZmqDpnControlProtocol) {
-                    throw new RuntimeException("Could not find Topic ID");
-                }
+                    // from DPN ID find the Network and Node Identifiers
+                    Optional<String> key = optionalDpn
+                            .map(node -> node.nodeId() + "/" + node.networkId());
+                    if (!key.isPresent()) {
+                        throw new RuntimeException("DPN does not have node and network ID defined.");
+                    }
 
-                if (!(context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
-                    throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
-                }
+                    // find DPN Topic from Node/Network ID pair.
+                    byte topicId = getTopicFromNode(key.get());
+                    if (topicId == -1 && dpnCommunicationService instanceof ZmqDpnControlProtocol) {
+                        throw new RuntimeException("Could not find Topic ID");
+                    }
 
-                Long teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
-                        .mobprofileParameters()).tunnelIdentifier();
-                long clientId = clientInfo.clientId().fpcIdentity().union().int64();
-                BigInteger opId = operationId.uint64();
+                    if (!(context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
+                        throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
+                    }
 
-                // TODO figure out what is going on.
-                if (targetStr.endsWith("ul") || targetStr.endsWith("dl")) {
-                    // TODO delete bearer
-                } else {
+                    Long teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
+                            .mobprofileParameters()).tunnelIdentifier();
+                    long clientId = clientIdentifier.fpcIdentity().union().int64();
+                    BigInteger opId = BigInteger.valueOf(-1);
+
                     tasks.add(Executors.callable(() -> {
                         dpnCommunicationService.deleteSession(
                                 topicId,
@@ -647,9 +646,132 @@
 
                         dynamicConfigService.deleteNode(resourceVal);
                         cacheManager.contextsCache.put(context.contextId(), Optional.empty());
+                        CLIENT_CONTEXTS_INFO.get(clientIdentifier).remove(fpcContextId);
                     }));
                 }
             }
+        } catch (Exception e) {
+            log.error(ExceptionUtils.getFullStackTrace(e));
+        }
+        return tasks;
+    }
+
+    public Collection<Callable<Object>> deleteSession(
+            ClientIdentifier clientIdentifier,
+            FpcContextId fpcContextId,
+            OpIdentifier operationId
+    ) throws ExecutionException {
+        Collection<Callable<Object>> tasks = new ArrayList<>();
+
+        FpcIdentity tenantId = CLIENT_INFO.get(clientIdentifier).tenantId();
+        CacheManager cacheManager = CacheManager.getInstance(tenantId);
+
+        Optional<DefaultContexts> defaultContexts = null;
+
+        defaultContexts = CacheManager.getInstance(tenantId)
+                .contextsCache.get(fpcContextId);
+
+        if (!defaultContexts.isPresent()) {
+            throw new RuntimeException("Context doesn't exist. Please issue create operation..");
+        }
+
+        DefaultContexts context = defaultContexts.get();
+        for (Dpns dpn : context.dpns()) {
+            Optional<DefaultDpns> optionalDpn = cacheManager.dpnsCache.get(dpn.dpnId());
+            // check if dpns exists and if there is a DPN registered for the wanted identifier.
+            if (!optionalDpn.isPresent()) {
+                // throw exception if DPN ID is not registered.
+                throw new RuntimeException("DPN ID is not registered to the topology.");
+            }
+
+            final DpnCommunicationService dpnCommunicationService;
+            Class<? extends FpcDpnControlProtocol> controlProtocol = optionalDpn.get().controlProtocol();
+            if (controlProtocol.isAssignableFrom(ZmqDpnControlProtocol.class)) {
+                dpnCommunicationService = DpnNgicCommunicator.getInstance();
+            } else if (controlProtocol.isAssignableFrom(P4DpnControlProtocol.class)) {
+                DpnP4Communicator instance = DpnP4Communicator.getInstance();
+                dpnCommunicationService = instance;
+                instance.setDeviceId(
+                        DeviceId.deviceId(optionalDpn.get().dpnId().toString())
+                );
+                instance.setClientId(clientIdentifier);
+            } else {
+                throw new RuntimeException("Control Protocol is not supported.");
+            }
+
+            // from DPN ID find the Network and Node Identifiers
+            Optional<String> key = optionalDpn
+                    .map(node -> node.nodeId() + "/" + node.networkId());
+            if (!key.isPresent()) {
+                throw new RuntimeException("DPN does not have node and network ID defined.");
+            }
+
+            // find DPN Topic from Node/Network ID pair.
+            byte topicId = getTopicFromNode(key.get());
+            if (topicId == -1 && dpnCommunicationService instanceof ZmqDpnControlProtocol) {
+                throw new RuntimeException("Could not find Topic ID");
+            }
+
+            if (!(context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
+                throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
+            }
+
+            Long teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
+                    .mobprofileParameters()).tunnelIdentifier();
+            long clientId = clientIdentifier.fpcIdentity().union().int64();
+            BigInteger opId = operationId.uint64();
+
+            tasks.add(Executors.callable(() -> {
+                dpnCommunicationService.deleteSession(
+                        topicId,
+                        context.contextId().fpcIdentity().union().int64(),
+                        clientId,
+                        opId
+                );
+
+                ContextsKeys contextsKeys = new ContextsKeys();
+                contextsKeys.contextId(context.contextId());
+
+                ResourceId resourceVal = getResourceVal(tenantBuilder(tenantId)
+                        .addChild(DefaultFpcMobility.class)
+                        .addChild(DefaultContexts.class, contextsKeys)
+                        .build());
+
+                dynamicConfigService.deleteNode(resourceVal);
+                cacheManager.contextsCache.put(context.contextId(), Optional.empty());
+                CLIENT_CONTEXTS_INFO.get(clientIdentifier).remove(fpcContextId);
+            }));
+        }
+
+        return tasks;
+    }
+
+    @Override
+    public DefaultConfigureOutput configureDelete(
+            DeleteOrQuery delete,
+            DefaultRegisterClientInput clientInfo,
+            OpIdentifier operationId
+    ) throws Exception {
+        Collection<Callable<Object>> tasks = new ArrayList<>();
+        DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
+        // get cache for specific tenant.
+        DefaultDeleteSuccess defaultDeleteSuccess = new DefaultDeleteSuccess();
+        for (Targets target : delete.targets()) {
+            defaultDeleteSuccess.addToTargets(target);
+            // parse context id.
+            String targetStr = target.target().toString(),
+                    s = StringUtils.substringBetween(targetStr, "contexts=", "/"),
+                    trgt = s != null ? s : StringUtils.substringAfter(targetStr, "contexts=");
+
+            log.debug("handling configure-delete {}", targetStr);
+
+            // TODO figure out what is going on.
+            if (targetStr.endsWith("ul") || targetStr.endsWith("dl")) {
+                // TODO delete bearer
+            } else {
+                FpcContextId fpcContextId = FpcContextId.of(FpcIdentity.fromString(trgt));
+                tasks = deleteSession(clientInfo.clientId(), fpcContextId, operationId);
+            }
         }
 
         // execute all tasks
@@ -984,7 +1106,11 @@
                 for (ModelObject modelObject : getModelObjects(rpcInput.data(), registerClient)) {
                     DefaultRegisterClientInput input = (DefaultRegisterClientInput) modelObject;
                     if (CLIENT_INFO.containsKey(input.clientId())) {
-                        throw new RuntimeException("Client already registered.");
+//                        throw new RuntimeException("Client already registered.");
+                        log.error("Client already registered. Deleting previous contexts...");
+                        deleteSessions(input.clientId());
+                        CLIENT_INFO.remove(input.clientId());
+                        CLIENT_CONTEXTS_INFO.remove(input.clientId());
                     }
                     // keep information for each client. this can be moved to the DC Store and use Cache.
                     CLIENT_INFO.put(input.clientId(), input);
@@ -1041,6 +1167,13 @@
                     if (!CLIENT_INFO.containsKey(input.clientId())) {
                         throw new RuntimeException("Client does not exist.");
                     }
+
+                    for (HashSet<ClientIdentifier> clientIdentifiers : TENANT_INFO.values()) {
+                       if (clientIdentifiers.remove(input.clientId())) {
+                           break;
+                       }
+                    }
+
                     CLIENT_INFO.remove(input.clientId());
                     deregisterClientOutput.clientId(input.clientId());
 
@@ -1052,6 +1185,9 @@
                     ConnectionsKeys connectionsKeys = new ConnectionsKeys();
                     connectionsKeys.clientId(input.clientId().toString());
 
+                    // delete all sessions associated with this client.
+                    deleteSessions(input.clientId());
+
                     ResourceId resourceVal = getResourceVal(ModelObjectId.builder()
                             .addChild(DefaultConnectionInfo.class)
                             .addChild(DefaultConnections.class, connectionsKeys)
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/FpcUtil.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/FpcUtil.java
index bccc8e8..23934b7 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/FpcUtil.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/util/FpcUtil.java
@@ -28,9 +28,11 @@
 import org.onosproject.net.device.DeviceStore;
 import org.onosproject.restconf.api.RestconfService;
 import org.onosproject.restconf.utils.RestconfUtils;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.DefaultConnectionInfo;
 import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.registerclient.DefaultRegisterClientInput;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.DefaultConfigResultNotification;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.DefaultFpcAgentInfo;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.DefaultTenants;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.NotificationId;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.OpIdentifier;
@@ -42,6 +44,7 @@
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultEmptyCase;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.DefaultTenant;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.TenantKeys;
+import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcContextId;
 import org.onosproject.yang.gen.v1.ietfdmmfpcbase.rev20160803.ietfdmmfpcbase.FpcIdentity;
 import org.onosproject.yang.model.DataNode;
 import org.onosproject.yang.model.DefaultModelObjectData;
@@ -74,6 +77,7 @@
     public static final FpcIdentity DEFAULT_IDENTITY;
     public static final ConcurrentMap<ClientIdentifier, DefaultRegisterClientInput> CLIENT_INFO;
     public static final ConcurrentMap<FpcIdentity, HashSet<ClientIdentifier>> TENANT_INFO;
+    public static final ConcurrentMap<ClientIdentifier, HashSet<FpcContextId>> CLIENT_CONTEXTS_INFO;
     private static final Logger log = LoggerFactory.getLogger(FpcUtil.class);
     // Services
     public static DynamicConfigService dynamicConfigService;
@@ -84,6 +88,8 @@
     public static ResourceId configureDpn;
     public static ResourceId configure;
     public static ResourceId tenants;
+    public static ResourceId fpcAgents;
+    public static ResourceId connections;
     public static ResourceId configureBundles;
     public static ResourceId registerClient;
     public static ResourceId deregisterClient;
@@ -96,6 +102,7 @@
         DEFAULT_IDENTITY = FpcIdentity.fromString("default");
         CLIENT_INFO = Maps.newConcurrentMap();
         TENANT_INFO = Maps.newConcurrentMap();
+        CLIENT_CONTEXTS_INFO = Maps.newConcurrentMap();
     }
 
     private FpcUtil() {
@@ -127,6 +134,18 @@
 
         tenants = getResourceVal(tenantsId);
 
+        ModelObjectId fpcAgentInfo = ModelObjectId.builder()
+                .addChild(DefaultFpcAgentInfo.class)
+                .build();
+
+        fpcAgents = getResourceVal(fpcAgentInfo);
+
+        ModelObjectId connectionInfo = ModelObjectId.builder()
+                .addChild(DefaultConnectionInfo.class)
+                .build();
+
+        connections = getResourceVal(connectionInfo);
+
         configure = ResourceId.builder()
                 .addBranchPointSchema("/", null)
                 .addBranchPointSchema("configure", "urn:ietf:params:xml:ns:yang:fpcagent")
@@ -305,7 +324,11 @@
                         .build()
         );
         dataNode.dataNodes().forEach(
-                node -> dynamicConfigService.createNode(dataNode.resourceId(), node)
+                node -> {
+                    if (!dynamicConfigService.nodeExist(dataNode.resourceId())) {
+                        dynamicConfigService.createNode(dataNode.resourceId(), node);
+                    }
+                }
         );
     }
 
@@ -323,14 +346,29 @@
                         .build()
         );
         dataNode.dataNodes().forEach(
-                node -> dynamicConfigService.updateNode(dataNode.resourceId(), node)
+                node -> {
+                    if (!dynamicConfigService.nodeExist(dataNode.resourceId())) {
+                        dynamicConfigService.updateNode(dataNode.resourceId(), node);
+                    }
+                }
         );
     }
 
     /**
+     * Deletes a Node based on provided resource Id.
+     *
+     * @param resourceId Resource Id
+     */
+    public static void deleteNode(ResourceId resourceId) {
+        if (dynamicConfigService.nodeExist(resourceId)) {
+            dynamicConfigService.deleteNode(resourceId);
+        }
+    }
+
+    /**
      * Creates a Config Result Notification for SPGW-C.
      *
-     * @param opId operation identifier
+     * @param opId  operation identifier
      * @param cause cause id
      * @return config result notification model
      */
@@ -354,7 +392,7 @@
      * Sends to specified CP the notification object.
      *
      * @param clientId client identifier (CP)
-     * @param notify notification object
+     * @param notify   notification object
      */
     public static void sendNotification(String clientId, ModelObject notify) {
         try {
