diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
index 1f8a96f..fc7e265 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/FpcManager.java
@@ -16,9 +16,6 @@
 
 package org.onosproject.fpcagent;
 
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Maps;
-import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.felix.scr.annotations.*;
 import org.onosproject.config.DynamicConfigService;
 import org.onosproject.core.ApplicationId;
@@ -28,45 +25,21 @@
 import org.onosproject.fpcagent.workers.ZMQSBSubscriberManager;
 import org.onosproject.net.config.*;
 import org.onosproject.net.config.basics.SubjectFactories;
-import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.connectioninfo.DefaultConnections;
-import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.deregisterclient.DefaultDeregisterClientOutput;
-import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.registerclient.DefaultRegisterClientInput;
-import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.registerclient.DefaultRegisterClientOutput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.IetfDmmFpcagentService;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ClientIdentifier;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.ErrorTypeId;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.Result;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureInput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureOutput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.DefaultConfigureBundlesInput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.DefaultConfigureBundlesOutput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.configurebundlesoutput.Bundles;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.configurebundlesoutput.DefaultBundles;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configuredpn.DefaultConfigureDpnInput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configuredpn.DefaultConfigureDpnOutput;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.CreateOrUpdate;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.opinput.opbody.DeleteOrQuery;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.result.ResultEnum;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultErr;
-import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultEmptyCase;
-import org.onosproject.yang.model.*;
+import org.onosproject.yang.model.ModelConverter;
+import org.onosproject.yang.model.RpcRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Optional;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
 
-import static org.onosproject.fpcagent.util.FpcUtil.*;
+import static org.onosproject.fpcagent.util.FpcUtil.FPC_APP_ID;
 
 /**
  * Fpc Manager.
  */
 @Component(immediate = true)
 @Service
-public class FpcManager implements IetfDmmFpcagentService,
-        FpcService,
-        org.onosproject.yang.gen.v1.fpc.rev20150105.FpcService {
+public class FpcManager implements FpcService {
     private static final Logger log = LoggerFactory.getLogger(FpcManager.class);
 
     private static final Class<FpcConfig> CONFIG_CLASS = FpcConfig.class;
@@ -97,7 +70,6 @@
 
     /* Variables */
     private FpcConfig fpcConfig;
-    private ConcurrentMap<ClientIdentifier, DefaultRegisterClientInput> clientInfo = Maps.newConcurrentMap();
     private boolean started = false;
 
     /* Config */
@@ -116,7 +88,6 @@
         configService.addListener(configListener);
         registry.registerConfigFactory(fpcConfigConfigFactory);
 
-        rpcRegistry.registerRpcService(this);
 
         log.info("FPC Agent Started");
     }
@@ -131,10 +102,6 @@
             ZMQSBPublisherManager.getInstance().close();
         }
 
-        rpcRegistry.unregisterRpcService(this);
-
-        clientInfo.clear();
-
         log.info("FPC Agent Stopped");
     }
 
@@ -170,250 +137,6 @@
         return fpcConfig != null ? fpcConfig.getConfig() : Optional.empty();
     }
 
-    @Override
-    public RpcOutput configureDpn(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        DefaultConfigureDpnOutput configureDpnOutput = new DefaultConfigureDpnOutput();
-        configureDpnOutput.result(Result.of(ResultEnum.OK));
-        configureDpnOutput.resultType(new DefaultEmptyCase());
-        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
-        try {
-            for (ModelObject modelObject : tenantService.getModelObjects(rpcInput.data(), configureDpn)) {
-                DefaultConfigureDpnInput input = (DefaultConfigureDpnInput) modelObject;
-                switch (input.operation().enumeration()) {
-                    case ADD:
-                        configureDpnOutput = tenantService.configureDpnAdd(input);
-                        break;
-                    case REMOVE:
-                        configureDpnOutput = tenantService.configureDpnRemove(input);
-                        break;
-                }
-            }
-        } catch (Exception e) {
-            status = RpcOutput.Status.RPC_FAILURE;
-            org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultErr defaultErr = new org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultErr();
-            defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
-            defaultErr.errorTypeId(ErrorTypeId.of(0));
-            configureDpnOutput.resultType(defaultErr);
-            configureDpnOutput.result(Result.of(ResultEnum.ERR));
-            log.error(ExceptionUtils.getFullStackTrace(e));
-        }
-        ResourceData dataNode = modelConverter.createDataNode(
-                DefaultModelObjectData.builder()
-                        .addModelObject(configureDpnOutput)
-                        .build()
-        );
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return new RpcOutput(status, dataNode.dataNodes().get(0));
-    }
-
-    @Override
-    public RpcOutput configure(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
-        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
-        try {
-            for (ModelObject modelObject : tenantService.getModelObjects(rpcInput.data(), configure)) {
-                DefaultConfigureInput input = (DefaultConfigureInput) modelObject;
-                switch (input.opType()) {
-                    case CREATE:
-                        configureOutput = tenantService.configureCreate(
-                                (CreateOrUpdate) input.opBody(),
-                                clientInfo.get(input.clientId()),
-                                input.opId()
-                        );
-                        break;
-                    case UPDATE:
-                        configureOutput = tenantService.configureUpdate(
-                                (CreateOrUpdate) input.opBody(),
-                                clientInfo.get(input.clientId()),
-                                input.opId()
-                        );
-                        break;
-                    case QUERY:
-                        break;
-                    case DELETE:
-                        configureOutput = tenantService.configureDelete(
-                                (DeleteOrQuery) input.opBody(),
-                                clientInfo.get(input.clientId()),
-                                input.opId()
-                        );
-                        break;
-                }
-                configureOutput.opId(input.opId());
-            }
-        } catch (Exception e) {
-            // if there is an exception respond with an error.
-            status = RpcOutput.Status.RPC_FAILURE;
-            DefaultErr defaultErr = new DefaultErr();
-            defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
-            defaultErr.errorTypeId(ErrorTypeId.of(0));
-            configureOutput.resultType(defaultErr);
-            configureOutput.result(Result.of(ResultEnum.ERR));
-            log.error(ExceptionUtils.getFullStackTrace(e));
-        }
-        ResourceData dataNode = modelConverter.createDataNode(
-                DefaultModelObjectData.builder()
-                        .addModelObject(configureOutput)
-                        .build()
-        );
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return new RpcOutput(status, dataNode.dataNodes().get(0));
-    }
-
-    @Override
-    public RpcOutput configureBundles(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        DefaultConfigureBundlesOutput configureBundlesOutput = new DefaultConfigureBundlesOutput();
-        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
-        try {
-            for (ModelObject modelObject : tenantService.getModelObjects(rpcInput.data(), configureBundles)) {
-                DefaultConfigureBundlesInput input = (DefaultConfigureBundlesInput) modelObject;
-                for (org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.configurebundlesinput.Bundles bundle : input.bundles()) {
-                    DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
-                    switch (bundle.opType()) {
-                        case CREATE:
-                            configureOutput = tenantService.configureCreate(
-                                    (CreateOrUpdate) bundle.opBody(),
-                                    clientInfo.get(input.clientId()),
-                                    bundle.opId()
-                            );
-                            break;
-                        case UPDATE:
-                            configureOutput = tenantService.configureUpdate(
-                                    (CreateOrUpdate) bundle.opBody(),
-                                    clientInfo.get(input.clientId()),
-                                    bundle.opId()
-                            );
-                            break;
-                        case QUERY:
-                            break;
-                        case DELETE:
-                            configureOutput = tenantService.configureDelete(
-                                    (DeleteOrQuery) bundle.opBody(),
-                                    clientInfo.get(input.clientId()),
-                                    bundle.opId()
-                            );
-                            break;
-                    }
-                    Bundles result = new DefaultBundles();
-                    result.opId(bundle.opId());
-                    result.result(configureOutput.result());
-                    result.resultType(configureOutput.resultType());
-                    configureBundlesOutput.addToBundles(result);
-                }
-            }
-        } catch (Exception e) {
-            // if there is an exception respond with an error.
-            status = RpcOutput.Status.RPC_FAILURE;
-            log.error(ExceptionUtils.getFullStackTrace(e));
-        }
-        ResourceData dataNode = modelConverter.createDataNode(
-                DefaultModelObjectData.builder()
-                        .addModelObject(configureBundlesOutput)
-                        .build()
-        );
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return new RpcOutput(status, dataNode.dataNodes().get(0));
-    }
-
-    @Override
-    public RpcOutput eventRegister(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        // TODO implement
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return null;
-    }
-
-    @Override
-    public RpcOutput eventDeregister(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        // TODO implement
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return null;
-    }
-
-    @Override
-    public RpcOutput probe(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        // TODO implement
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return null;
-    }
-
-    @Override
-    public RpcOutput registerClient(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        DefaultRegisterClientOutput registerClientOutput = new DefaultRegisterClientOutput();
-        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
-
-        try {
-            for (ModelObject modelObject : tenantService.getModelObjects(rpcInput.data(), registerClient)) {
-                DefaultRegisterClientInput input = (DefaultRegisterClientInput) modelObject;
-                if (clientInfo.containsKey(input.clientId())) {
-                    throw new RuntimeException("Client already registered.");
-                }
-                clientInfo.put(input.clientId(), input);
-                registerClientOutput.clientId(input.clientId());
-                registerClientOutput.supportedFeatures(input.supportedFeatures());
-                registerClientOutput.endpointUri(input.endpointUri());
-                registerClientOutput.supportsAckModel(input.supportsAckModel());
-                registerClientOutput.tenantId(input.tenantId());
-
-                // TODO create node to DCS
-            }
-        } catch (Exception e) {
-            // if there is an exception respond with an error.
-            status = RpcOutput.Status.RPC_FAILURE;
-            log.error(ExceptionUtils.getFullStackTrace(e));
-        }
-
-        ResourceData dataNode = modelConverter.createDataNode(
-                DefaultModelObjectData.builder()
-                        .addModelObject(registerClientOutput)
-                        .build()
-        );
-
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return new RpcOutput(status, dataNode.dataNodes().get(0));
-    }
-
-    @Override
-    public RpcOutput deregisterClient(RpcInput rpcInput) {
-        Stopwatch timer = Stopwatch.createStarted();
-        DefaultDeregisterClientOutput deregisterClientOutput = new DefaultDeregisterClientOutput();
-        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
-
-        try {
-            for (ModelObject modelObject : tenantService.getModelObjects(rpcInput.data(), registerClient)) {
-                DefaultRegisterClientInput input = (DefaultRegisterClientInput) modelObject;
-                if (!clientInfo.containsKey(input.clientId())) {
-                    throw new RuntimeException("Client does not exist.");
-                }
-                clientInfo.remove(input.clientId());
-                deregisterClientOutput.clientId(input.clientId());
-
-                DefaultConnections defaultConnections = new DefaultConnections();
-                defaultConnections.clientId(input.clientId().toString());
-
-                // TODO delete node from DCS
-            }
-        } catch (Exception e) {
-            // if there is an exception respond with an error.
-            status = RpcOutput.Status.RPC_FAILURE;
-            log.error(ExceptionUtils.getFullStackTrace(e));
-        }
-
-        ResourceData dataNode = modelConverter.createDataNode(
-                DefaultModelObjectData.builder()
-                        .addModelObject(deregisterClientOutput)
-                        .build()
-        );
-
-        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
-        return new RpcOutput(status, dataNode.dataNodes().get(0));
-    }
-
     private class InternalNetworkConfigListener implements NetworkConfigListener {
 
         @Override
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
index 77bfc4a..d84b35f 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantManager.java
@@ -16,22 +16,33 @@
 
 package org.onosproject.fpcagent;
 
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Maps;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.felix.scr.annotations.*;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
-import org.onlab.util.AbstractAccumulator;
-import org.onlab.util.Accumulator;
-import org.onosproject.config.*;
+import org.onosproject.config.DynamicConfigService;
+import org.onosproject.config.DynamicConfigStore;
+import org.onosproject.config.Filter;
 import org.onosproject.fpcagent.util.CacheManager;
 import org.onosproject.fpcagent.util.DpnCommunicationService;
 import org.onosproject.fpcagent.util.DpnNgicCommunicator;
 import org.onosproject.fpcagent.util.FpcUtil;
 import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.DefaultConnectionInfo;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.connectioninfo.DefaultConnections;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.deregisterclient.DefaultDeregisterClientOutput;
 import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.registerclient.DefaultRegisterClientInput;
+import org.onosproject.yang.gen.v1.fpc.rev20150105.fpc.registerclient.DefaultRegisterClientOutput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.IetfDmmFpcagentService;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.*;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureInput;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configure.DefaultConfigureOutput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.DefaultConfigureBundlesInput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.DefaultConfigureBundlesOutput;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.configurebundlesoutput.Bundles;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.configurebundlesoutput.DefaultBundles;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configuredpn.DefaultConfigureDpnInput;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configuredpn.DefaultConfigureDpnOutput;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.instructions.instructions.instrtype.Instr3GppMob;
@@ -41,6 +52,7 @@
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.result.ResultEnum;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultCommonSuccess;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultDeleteSuccess;
+import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbody.resulttype.DefaultErr;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultCommonDeleteSuccess;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultEmptyCase;
 import org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.tenants.DefaultTenant;
@@ -62,25 +74,21 @@
 import org.slf4j.LoggerFactory;
 
 import java.math.BigInteger;
-import java.util.*;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.*;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.fpcagent.util.Converter.convertContext;
 import static org.onosproject.fpcagent.util.FpcUtil.*;
 
 @Component(immediate = true)
 @Service
-public class TenantManager implements TenantService {
+public class TenantManager implements TenantService, IetfDmmFpcagentService, org.onosproject.yang.gen.v1.fpc.rev20150105.FpcService {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
-    private final InternalConfigListener listener = new InternalConfigListener();
-
-    private final Accumulator<DynamicConfigEvent> accumulator = new InternalEventAccumulator();
-
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     private ModelConverter modelConverter;
 
@@ -90,8 +98,13 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     private DynamicConfigStore dynamicConfigStore;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private RpcRegistry registry;
+
     private DpnCommunicationService dpnCommunicationService;
 
+    private ConcurrentMap<ClientIdentifier, DefaultRegisterClientInput> clientInfo = Maps.newConcurrentMap();
+
     @Activate
     protected void activate() {
         CacheManager.addManager(this);
@@ -100,8 +113,6 @@
 
         dpnCommunicationService = new DpnNgicCommunicator();
 
-        dynamicConfigService.addListener(listener);
-
         // Create the Default Tenant and added to the Tenants structure.
         final DefaultTenants tenants = new DefaultTenants();
         final DefaultTenant tenant = new DefaultTenant();
@@ -123,12 +134,15 @@
         createNode(fpcAgentInfo, root);
         createNode(defaultConnectionInfo, root);
 
+        registry.registerRpcService(this);
+
         log.info("Tenant Service Started");
     }
 
     @Deactivate
     protected void deactivate() {
-        dynamicConfigService.removeListener(listener);
+        registry.unregisterRpcService(this);
+
         log.info("Tenant Service Stopped");
     }
 
@@ -192,116 +206,6 @@
         );
     }
 
-    private Collection<Callable<Object>> create(
-            Dpns dpn,
-            Contexts context,
-            DefaultRegisterClientInput clientId,
-            OpIdentifier operationId
-    ) throws Exception {
-        Collection<Callable<Object>> tasks = new ArrayList<>();
-        CacheManager cacheManager = CacheManager.getInstance(clientId.tenantId());
-        // check if dpns exists and if there is a DPN registered for the wanted identifier.
-        if (!cacheManager.dpnsCache.get(dpn.dpnId()).isPresent()) {
-            // throw exception if DPN ID is not registered.
-            throw new RuntimeException("DPN ID is not registered to the topology.");
-        }
-
-        // handle only 3GPP instructions.
-        if (!(context.instructions().instrType() instanceof Instr3GppMob)) {
-            throw new RuntimeException("No 3GPP instructions where given.");
-        }
-
-        // from DPN ID find the Network and Node Identifiers
-        Optional<String> key = cacheManager.dpnsCache.get(dpn.dpnId())
-                .map(node -> node.nodeId() + "/" + node.networkId());
-        if (!key.isPresent()) {
-            throw new RuntimeException("DPN does not have node and network ID defined.");
-        }
-
-        // get DPN Topic from Node/Network pair
-        Short topic_id = getTopicFromNode(key.get());
-        if (topic_id == null) {
-            throw new RuntimeException("Could not find Topic ID");
-        }
-
-        // parse tunnel identifiers. throw exception if mobility profile parameters are missing.
-        if (!(context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
-            throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
-
-        }
-        if (!(context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
-            throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
-        }
-
-        // Extract variables
-        Instr3GppMob instr3GppMob = (Instr3GppMob) context.instructions().instrType();
-        String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
-
-        Ip4Address s1u_enodeb_ipv4 = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
-                s1u_sgw_ipv4 = Ip4Address.valueOf(context.ul().tunnelRemoteAddress().toString());
-
-        long client_id = clientId.clientId().fpcIdentity().union().int64(),
-                session_id = context.contextId().fpcIdentity().union().int64(),
-                s1u_sgw_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
-                        .mobprofileParameters()).tunnelIdentifier(),
-                s1u_enb_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
-                        .mobprofileParameters()).tunnelIdentifier();
-
-        BigInteger op_id = operationId.uint64(),
-                imsi = context.imsi().uint64();
-
-        short default_ebi = context.ebi().uint8();
-
-        // TODO try to make sense out of this...
-        if (commands.contains("session")) {
-            DefaultContexts convertContext = convertContext(context);
-            tasks.add(Executors.callable(() -> {
-                dpnCommunicationService.create_session(
-                        topic_id,
-                        imsi,
-                        default_ebi,
-                        Ip4Prefix.valueOf(context.delegatingIpPrefixes().get(0).toString()).address(),
-                        s1u_sgw_gtpu_teid,
-                        s1u_sgw_ipv4,
-                        session_id,
-                        client_id,
-                        op_id
-                );
-
-                ModelObjectId modelObjectId = defaultTenantBuilder()
-                        .addChild(DefaultFpcMobility.class)
-                        .build();
-                createNode(convertContext, modelObjectId);
-                cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
-            }));
-
-            if (commands.contains("downlink")) {
-                tasks.add(Executors.callable(() -> {
-                    dpnCommunicationService.modify_bearer(
-                            topic_id,
-                            s1u_sgw_ipv4,
-                            s1u_enb_gtpu_teid,
-                            s1u_enodeb_ipv4,
-                            session_id,
-                            client_id,
-                            op_id
-                    );
-
-                    ModelObjectId modelObjectId = defaultTenantBuilder()
-                            .addChild(DefaultFpcMobility.class)
-                            .build();
-                    createNode(convertContext, modelObjectId);
-                    cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
-                }));
-            }
-        } else if (commands.contains("indirect-forward")) {
-            // TODO - Modify API for Indirect Forwarding to/from another SGW
-        } else if (commands.contains("uplink")) {
-            // TODO create bearer ul
-        }
-        return tasks;
-    }
-
     @Override
     public DefaultConfigureOutput configureCreate(
             CreateOrUpdate create,
@@ -323,7 +227,106 @@
             }
 
             for (Dpns dpn : context.dpns()) {
-                tasks = create(dpn, context, clientInfo, operationId);
+                CacheManager cacheManager = CacheManager.getInstance(clientInfo.tenantId());
+                // check if dpns exists and if there is a DPN registered for the wanted identifier.
+                if (!cacheManager.dpnsCache.get(dpn.dpnId()).isPresent()) {
+                    // throw exception if DPN ID is not registered.
+                    throw new RuntimeException("DPN ID is not registered to the topology.");
+                }
+
+                // handle only 3GPP instructions.
+                if (!(context.instructions().instrType() instanceof Instr3GppMob)) {
+                    throw new RuntimeException("No 3GPP instructions where given.");
+                }
+
+                // from DPN ID find the Network and Node Identifiers
+                Optional<String> key = cacheManager.dpnsCache.get(dpn.dpnId())
+                        .map(node -> node.nodeId() + "/" + node.networkId());
+                if (!key.isPresent()) {
+                    throw new RuntimeException("DPN does not have node and network ID defined.");
+                }
+
+                // get DPN Topic from Node/Network pair
+                Short topic_id = getTopicFromNode(key.get());
+                if (topic_id == null) {
+                    throw new RuntimeException("Could not find Topic ID");
+                }
+
+                // parse tunnel identifiers. throw exception if mobility profile parameters are missing.
+                if (!(context.ul().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
+                    throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
+
+                }
+                if (!(context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
+                    throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
+                }
+
+                // Extract variables
+                Instr3GppMob instr3GppMob = (Instr3GppMob) context.instructions().instrType();
+                String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
+
+                Ip4Address s1u_enodeb_ipv4 = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
+                        s1u_sgw_ipv4 = Ip4Address.valueOf(context.ul().tunnelRemoteAddress().toString());
+
+                long client_id = clientInfo.clientId().fpcIdentity().union().int64(),
+                        session_id = context.contextId().fpcIdentity().union().int64(),
+                        s1u_sgw_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
+                                .mobprofileParameters()).tunnelIdentifier(),
+                        s1u_enb_gtpu_teid = ((ThreegppTunnel) context.ul().mobilityTunnelParameters()
+                                .mobprofileParameters()).tunnelIdentifier();
+
+                BigInteger op_id = operationId.uint64(),
+                        imsi = context.imsi().uint64();
+
+                short default_ebi = context.ebi().uint8();
+
+                // TODO try to make sense out of this...
+                if (commands.contains("session")) {
+                    DefaultContexts convertContext = convertContext(context);
+                    tasks.add(Executors.callable(() -> {
+                        dpnCommunicationService.create_session(
+                                topic_id,
+                                imsi,
+                                default_ebi,
+                                Ip4Prefix.valueOf(context.delegatingIpPrefixes().get(0).toString()).address(),
+                                s1u_sgw_gtpu_teid,
+                                s1u_sgw_ipv4,
+                                session_id,
+                                client_id,
+                                op_id
+                        );
+
+                        ModelObjectId modelObjectId = defaultTenantBuilder()
+                                .addChild(DefaultFpcMobility.class)
+                                .build();
+                        createNode(convertContext, modelObjectId);
+                        cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
+                    }));
+
+                    if (commands.contains("downlink")) {
+                        tasks.add(Executors.callable(() -> {
+                            dpnCommunicationService.modify_bearer(
+                                    topic_id,
+                                    s1u_sgw_ipv4,
+                                    s1u_enb_gtpu_teid,
+                                    s1u_enodeb_ipv4,
+                                    session_id,
+                                    client_id,
+                                    op_id
+                            );
+
+                            ModelObjectId modelObjectId = defaultTenantBuilder()
+                                    .addChild(DefaultFpcMobility.class)
+                                    .build();
+                            createNode(convertContext, modelObjectId);
+                            cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
+                        }));
+                    }
+                } else if (commands.contains("indirect-forward")) {
+                    // TODO - Modify API for Indirect Forwarding to/from another SGW
+                } else if (commands.contains("uplink")) {
+                    // TODO create bearer ul
+                }
             }
         }
 
@@ -346,104 +349,6 @@
         return configureOutput;
     }
 
-    private Collection<Callable<Object>> update(
-            Dpns dpn,
-            Contexts context,
-            DefaultRegisterClientInput clientId,
-            OpIdentifier operationId
-    ) throws Exception {
-        Collection<Callable<Object>> tasks = new ArrayList<>();
-        CacheManager cacheManager = CacheManager.getInstance(clientId.tenantId());
-        // check if dpns exists and if there is a DPN registered for the wanted identifier.
-        if (!cacheManager.dpnsCache.get(dpn.dpnId()).isPresent()) {
-            // throw exception if DPN ID is not registered.
-            throw new RuntimeException("DPN ID is not registered to the topology.");
-        }
-
-        // handle only 3GPP instructions.
-        if (!(context.instructions().instrType() instanceof Instr3GppMob)) {
-            throw new RuntimeException("No 3GPP instructions where given.");
-        }
-
-        // from DPN ID find the Network and Node Identifiers
-        Optional<String> key = cacheManager.dpnsCache.get(dpn.dpnId())
-                .map(node -> node.nodeId() + "/" + node.networkId());
-        if (!key.isPresent()) {
-            throw new RuntimeException("DPN does not have node and network ID defined.");
-        }
-
-        // get DPN Topic from Node/Network pair
-        Short topic_id = getTopicFromNode(key.get());
-        if (topic_id == null) {
-            throw new RuntimeException("Could not find Topic ID");
-        }
-
-        if (!(context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
-            throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
-        }
-
-        Instr3GppMob instr3GppMob = (Instr3GppMob) context.instructions().instrType();
-        String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
-
-        Ip4Address s1u_enodeb_ipv4 = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
-                s1u_sgw_ipv4 = Ip4Address.valueOf(context.ul().tunnelRemoteAddress().toString());
-
-        long s1u_enb_gtpu_teid = ((ThreegppTunnel) context.dl().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier(),
-                cId = clientId.clientId().fpcIdentity().union().int64(),
-                contextId = context.contextId().fpcIdentity().union().int64();
-
-        BigInteger opId = operationId.uint64();
-
-        DefaultContexts convertContext = convertContext(context);
-        if (commands.contains("downlink")) {
-            if (context.dl().lifetime() >= 0L) {
-                tasks.add(Executors.callable(() -> {
-                    dpnCommunicationService.modify_bearer(
-                            topic_id,
-                            s1u_sgw_ipv4,
-                            s1u_enb_gtpu_teid,
-                            s1u_enodeb_ipv4,
-                            contextId,
-                            cId,
-                            opId
-                    );
-
-                    ModelObjectId modelObjectId = defaultTenantBuilder()
-                            .addChild(DefaultFpcMobility.class)
-                            .build();
-                    updateNode(convertContext, modelObjectId);
-                    cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
-                }));
-            } else {
-                // TODO delete bearer
-            }
-        }
-        if (commands.contains("uplink")) {
-            if (context.ul().lifetime() >= 0L) {
-                tasks.add(Executors.callable(() -> {
-                    dpnCommunicationService.modify_bearer(
-                            topic_id,
-                            s1u_sgw_ipv4,
-                            s1u_enb_gtpu_teid,
-                            s1u_enodeb_ipv4,
-                            contextId,
-                            cId,
-                            opId
-                    );
-
-                    ModelObjectId modelObjectId = defaultTenantBuilder()
-                            .addChild(DefaultFpcMobility.class)
-                            .build();
-                    updateNode(convertContext, modelObjectId);
-                    cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
-                }));
-            } else {
-                // TODO delete bearer
-            }
-        }
-        return tasks;
-    }
-
     @Override
     public DefaultConfigureOutput configureUpdate(
             CreateOrUpdate update,
@@ -465,7 +370,94 @@
             }
 
             for (Dpns dpn : context.dpns()) {
-                update(dpn, context, clientInfo, operationId);
+                CacheManager cacheManager = CacheManager.getInstance(clientInfo.tenantId());
+                // check if dpns exists and if there is a DPN registered for the wanted identifier.
+                if (!cacheManager.dpnsCache.get(dpn.dpnId()).isPresent()) {
+                    // throw exception if DPN ID is not registered.
+                    throw new RuntimeException("DPN ID is not registered to the topology.");
+                }
+
+                // handle only 3GPP instructions.
+                if (!(context.instructions().instrType() instanceof Instr3GppMob)) {
+                    throw new RuntimeException("No 3GPP instructions where given.");
+                }
+
+                // from DPN ID find the Network and Node Identifiers
+                Optional<String> key = cacheManager.dpnsCache.get(dpn.dpnId())
+                        .map(node -> node.nodeId() + "/" + node.networkId());
+                if (!key.isPresent()) {
+                    throw new RuntimeException("DPN does not have node and network ID defined.");
+                }
+
+                // get DPN Topic from Node/Network pair
+                Short topic_id = getTopicFromNode(key.get());
+                if (topic_id == null) {
+                    throw new RuntimeException("Could not find Topic ID");
+                }
+
+                if (!(context.dl().mobilityTunnelParameters().mobprofileParameters() instanceof ThreegppTunnel)) {
+                    throw new RuntimeException("mobprofileParameters are not instance of ThreegppTunnel");
+                }
+
+                Instr3GppMob instr3GppMob = (Instr3GppMob) context.instructions().instrType();
+                String commands = Bits.toString(instr3GppMob.instr3GppMob().bits());
+
+                Ip4Address s1u_enodeb_ipv4 = Ip4Address.valueOf(context.ul().tunnelLocalAddress().toString()),
+                        s1u_sgw_ipv4 = Ip4Address.valueOf(context.ul().tunnelRemoteAddress().toString());
+
+                long s1u_enb_gtpu_teid = ((ThreegppTunnel) context.dl().mobilityTunnelParameters().mobprofileParameters()).tunnelIdentifier(),
+                        cId = clientInfo.clientId().fpcIdentity().union().int64(),
+                        contextId = context.contextId().fpcIdentity().union().int64();
+
+                BigInteger opId = operationId.uint64();
+
+                DefaultContexts convertContext = convertContext(context);
+                if (commands.contains("downlink")) {
+                    if (context.dl().lifetime() >= 0L) {
+                        tasks.add(Executors.callable(() -> {
+                            dpnCommunicationService.modify_bearer(
+                                    topic_id,
+                                    s1u_sgw_ipv4,
+                                    s1u_enb_gtpu_teid,
+                                    s1u_enodeb_ipv4,
+                                    contextId,
+                                    cId,
+                                    opId
+                            );
+
+                            ModelObjectId modelObjectId = defaultTenantBuilder()
+                                    .addChild(DefaultFpcMobility.class)
+                                    .build();
+                            updateNode(convertContext, modelObjectId);
+                            cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
+                        }));
+                    } else {
+                        // TODO delete bearer
+                    }
+                }
+                if (commands.contains("uplink")) {
+                    if (context.ul().lifetime() >= 0L) {
+                        tasks.add(Executors.callable(() -> {
+                            dpnCommunicationService.modify_bearer(
+                                    topic_id,
+                                    s1u_sgw_ipv4,
+                                    s1u_enb_gtpu_teid,
+                                    s1u_enodeb_ipv4,
+                                    contextId,
+                                    cId,
+                                    opId
+                            );
+
+                            ModelObjectId modelObjectId = defaultTenantBuilder()
+                                    .addChild(DefaultFpcMobility.class)
+                                    .build();
+                            updateNode(convertContext, modelObjectId);
+                            cacheManager.contextsCache.put(convertContext.contextId(), Optional.of(convertContext));
+                        }));
+                    } else {
+                        // TODO delete bearer
+                    }
+                }
             }
         }
 
@@ -487,69 +479,6 @@
         return configureOutput;
     }
 
-    private Collection<Callable<Object>> delete(
-            Dpns dpn,
-            DefaultContexts context,
-            DefaultRegisterClientInput clientId,
-            OpIdentifier operationId,
-            String target
-    ) throws Exception {
-        Collection<Callable<Object>> tasks = new ArrayList<>();
-        CacheManager cacheManager = CacheManager.getInstance(clientId.tenantId());
-        // check if dpns exists and if there is a DPN registered for the wanted identifier.
-        if (!cacheManager.dpnsCache.get(dpn.dpnId()).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 = cacheManager.dpnsCache.get(dpn.dpnId())
-                .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.
-        Short topic_id = getTopicFromNode(key.get());
-        if (topic_id == null) {
-            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 client_id = clientId.clientId().fpcIdentity().union().int64();
-        BigInteger op_id = operationId.uint64();
-
-        // TODO figure out what is going on.
-        if (target.endsWith("ul") || target.endsWith("dl")) {
-            // TODO delete bearer
-        } else {
-            tasks.add(Executors.callable(() -> {
-                dpnCommunicationService.delete_session(
-                        topic_id,
-                        context.contextId().fpcIdentity().union().int64(),
-                        client_id,
-                        op_id
-                );
-
-                ContextsKeys contextsKeys = new ContextsKeys();
-                contextsKeys.contextId(context.contextId());
-
-                ResourceId resourceVal = getResourceVal(defaultTenantBuilder()
-                        .addChild(DefaultFpcMobility.class)
-                        .addChild(DefaultContexts.class, contextsKeys)
-                        .build());
-
-                dynamicConfigService.deleteNode(resourceVal);
-                cacheManager.contextsCache.put(context.contextId(), Optional.empty());
-            }));
-        }
-        return tasks;
-    }
-
     @Override
     public DefaultConfigureOutput configureDelete(
             DeleteOrQuery delete,
@@ -576,7 +505,58 @@
 
             DefaultContexts context = defaultContexts.get();
             for (Dpns dpn : context.dpns()) {
-                tasks = delete(dpn, context, clientInfo, operationId, targetStr);
+                CacheManager cacheManager = CacheManager.getInstance(clientInfo.tenantId());
+                // check if dpns exists and if there is a DPN registered for the wanted identifier.
+                if (!cacheManager.dpnsCache.get(dpn.dpnId()).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 = cacheManager.dpnsCache.get(dpn.dpnId())
+                        .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.
+                Short topic_id = getTopicFromNode(key.get());
+                if (topic_id == null) {
+                    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 client_id = clientInfo.clientId().fpcIdentity().union().int64();
+                BigInteger op_id = operationId.uint64();
+
+                // TODO figure out what is going on.
+                if (targetStr.endsWith("ul") || targetStr.endsWith("dl")) {
+                    // TODO delete bearer
+                } else {
+                    tasks.add(Executors.callable(() -> {
+                        dpnCommunicationService.delete_session(
+                                topic_id,
+                                context.contextId().fpcIdentity().union().int64(),
+                                client_id,
+                                op_id
+                        );
+
+                        ContextsKeys contextsKeys = new ContextsKeys();
+                        contextsKeys.contextId(context.contextId());
+
+                        ResourceId resourceVal = getResourceVal(defaultTenantBuilder()
+                                .addChild(DefaultFpcMobility.class)
+                                .addChild(DefaultContexts.class, contextsKeys)
+                                .build());
+
+                        dynamicConfigService.deleteNode(resourceVal);
+                        cacheManager.contextsCache.put(context.contextId(), Optional.empty());
+                    }));
+                }
             }
         }
 
@@ -693,84 +673,248 @@
         return defaultConfigureDpnOutput;
     }
 
-    /**
-     * Accumulates events to allow processing after a desired number of
-     * events were accumulated.
-     */
-    private class InternalEventAccumulator extends AbstractAccumulator<DynamicConfigEvent> {
-
-        /**
-         * Constructs the event accumulator with timer and event limit.
-         */
-        private InternalEventAccumulator() {
-            super(new Timer(TIMER), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
-        }
-
-        @Override
-        public void processItems(List<DynamicConfigEvent> events) {
-            events.forEach(
-                    event -> {
-                        checkNotNull(event, EVENT_NULL);
-                        switch (event.type()) {
-                            case NODE_ADDED:
-                            case NODE_DELETED:
-                            case NODE_UPDATED:
-                            case NODE_REPLACED:
-//                                List<NodeKey> nodeKeys = event.subject().nodeKeys();
-//                                if (nodeKeys.size() >= 4) {
-//                                    NodeKey nodeKey = nodeKeys.get(3);
-//                                    if (nodeKey.schemaId().name().equals("dpns") && nodeKey instanceof ListKey) {
-//                                        Object dpnId = ((ListKey) nodeKey).keyLeafs().get(0).leafValue();
-//                                        cacheManager.dpnsCache.invalidate(FpcDpnId.fromString(dpnId.toString()));
-//                                    } else if (nodeKey.schemaId().name().equals("contexts") && nodeKey instanceof ListKey) {
-//                                        Object contextId = ((ListKey) nodeKey).keyLeafs().get(0).leafValue();
-//                                        cacheManager.contextsCache.invalidate(FpcContextId.fromString(contextId.toString()));
-//                                    }
-//                                }
-                                break;
-                            default:
-                                log.warn(UNKNOWN_EVENT, event.type());
-                                break;
-                        }
-                    }
-            );
-        }
-
-    }
-
-    /**
-     * Representation of internal listener, listening for dynamic config event.
-     */
-    private class InternalConfigListener implements DynamicConfigListener {
-        /**
-         * Returns true if the event resource id points to the root level node
-         * only and event is for addition and deletion; false otherwise.
-         *
-         * @param event config event
-         * @return true if event is supported; false otherwise
-         */
-        private boolean isSupported(DynamicConfigEvent event) {
-            ResourceId rsId = event.subject();
-            List<NodeKey> storeKeys = rsId.nodeKeys();
-            List<NodeKey> regKeys = tenants.nodeKeys();
-            // store[0] = tenants, reg[0] = /
-            if (storeKeys != null) {
-                int storeSize = storeKeys.size();
-                if (storeSize >= 4) {
-                    return storeKeys.get(0).equals(regKeys.get(1));
+    @Override
+    public RpcOutput configureDpn(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        DefaultConfigureDpnOutput configureDpnOutput = new DefaultConfigureDpnOutput();
+        configureDpnOutput.result(Result.of(ResultEnum.OK));
+        configureDpnOutput.resultType(new DefaultEmptyCase());
+        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
+        try {
+            for (ModelObject modelObject : getModelObjects(rpcInput.data(), configureDpn)) {
+                DefaultConfigureDpnInput input = (DefaultConfigureDpnInput) modelObject;
+                switch (input.operation().enumeration()) {
+                    case ADD:
+                        configureDpnOutput = configureDpnAdd(input);
+                        break;
+                    case REMOVE:
+                        configureDpnOutput = configureDpnRemove(input);
+                        break;
                 }
             }
-            return false;
+        } catch (Exception e) {
+            status = RpcOutput.Status.RPC_FAILURE;
+            org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultErr defaultErr = new org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.resultbodydpn.resulttype.DefaultErr();
+            defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
+            defaultErr.errorTypeId(ErrorTypeId.of(0));
+            configureDpnOutput.resultType(defaultErr);
+            configureDpnOutput.result(Result.of(ResultEnum.ERR));
+            log.error(ExceptionUtils.getFullStackTrace(e));
         }
-
-        @Override
-        public boolean isRelevant(DynamicConfigEvent event) {
-            return isSupported(event);
-        }
-
-        @Override
-        public void event(DynamicConfigEvent event) {
-            accumulator.add(event);
-        }
+        ResourceData dataNode = modelConverter.createDataNode(
+                DefaultModelObjectData.builder()
+                        .addModelObject(configureDpnOutput)
+                        .build()
+        );
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return new RpcOutput(status, dataNode.dataNodes().get(0));
     }
+
+    @Override
+    public RpcOutput configure(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
+        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
+        try {
+            for (ModelObject modelObject : getModelObjects(rpcInput.data(), configure)) {
+                DefaultConfigureInput input = (DefaultConfigureInput) modelObject;
+                switch (input.opType()) {
+                    case CREATE:
+                        configureOutput = configureCreate(
+                                (CreateOrUpdate) input.opBody(),
+                                clientInfo.get(input.clientId()),
+                                input.opId()
+                        );
+                        break;
+                    case UPDATE:
+                        configureOutput = configureUpdate(
+                                (CreateOrUpdate) input.opBody(),
+                                clientInfo.get(input.clientId()),
+                                input.opId()
+                        );
+                        break;
+                    case QUERY:
+                        break;
+                    case DELETE:
+                        configureOutput = configureDelete(
+                                (DeleteOrQuery) input.opBody(),
+                                clientInfo.get(input.clientId()),
+                                input.opId()
+                        );
+                        break;
+                }
+                configureOutput.opId(input.opId());
+            }
+        } catch (Exception e) {
+            // if there is an exception respond with an error.
+            status = RpcOutput.Status.RPC_FAILURE;
+            DefaultErr defaultErr = new DefaultErr();
+            defaultErr.errorInfo(ExceptionUtils.getFullStackTrace(e));
+            defaultErr.errorTypeId(ErrorTypeId.of(0));
+            configureOutput.resultType(defaultErr);
+            configureOutput.result(Result.of(ResultEnum.ERR));
+            log.error(ExceptionUtils.getFullStackTrace(e));
+        }
+        ResourceData dataNode = modelConverter.createDataNode(
+                DefaultModelObjectData.builder()
+                        .addModelObject(configureOutput)
+                        .build()
+        );
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return new RpcOutput(status, dataNode.dataNodes().get(0));
+    }
+
+    @Override
+    public RpcOutput configureBundles(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        DefaultConfigureBundlesOutput configureBundlesOutput = new DefaultConfigureBundlesOutput();
+        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
+        try {
+            for (ModelObject modelObject : getModelObjects(rpcInput.data(), configureBundles)) {
+                DefaultConfigureBundlesInput input = (DefaultConfigureBundlesInput) modelObject;
+                for (org.onosproject.yang.gen.v1.ietfdmmfpcagent.rev20160803.ietfdmmfpcagent.configurebundles.configurebundlesinput.Bundles bundle : input.bundles()) {
+                    DefaultConfigureOutput configureOutput = new DefaultConfigureOutput();
+                    switch (bundle.opType()) {
+                        case CREATE:
+                            configureOutput = configureCreate(
+                                    (CreateOrUpdate) bundle.opBody(),
+                                    clientInfo.get(input.clientId()),
+                                    bundle.opId()
+                            );
+                            break;
+                        case UPDATE:
+                            configureOutput = configureUpdate(
+                                    (CreateOrUpdate) bundle.opBody(),
+                                    clientInfo.get(input.clientId()),
+                                    bundle.opId()
+                            );
+                            break;
+                        case QUERY:
+                            break;
+                        case DELETE:
+                            configureOutput = configureDelete(
+                                    (DeleteOrQuery) bundle.opBody(),
+                                    clientInfo.get(input.clientId()),
+                                    bundle.opId()
+                            );
+                            break;
+                    }
+                    Bundles result = new DefaultBundles();
+                    result.opId(bundle.opId());
+                    result.result(configureOutput.result());
+                    result.resultType(configureOutput.resultType());
+                    configureBundlesOutput.addToBundles(result);
+                }
+            }
+        } catch (Exception e) {
+            // if there is an exception respond with an error.
+            status = RpcOutput.Status.RPC_FAILURE;
+            log.error(ExceptionUtils.getFullStackTrace(e));
+        }
+        ResourceData dataNode = modelConverter.createDataNode(
+                DefaultModelObjectData.builder()
+                        .addModelObject(configureBundlesOutput)
+                        .build()
+        );
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return new RpcOutput(status, dataNode.dataNodes().get(0));
+    }
+
+    @Override
+    public RpcOutput eventRegister(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        // TODO implement
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return null;
+    }
+
+    @Override
+    public RpcOutput eventDeregister(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        // TODO implement
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return null;
+    }
+
+    @Override
+    public RpcOutput probe(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        // TODO implement
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return null;
+    }
+
+    @Override
+    public RpcOutput registerClient(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        DefaultRegisterClientOutput registerClientOutput = new DefaultRegisterClientOutput();
+        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
+
+        try {
+            for (ModelObject modelObject : getModelObjects(rpcInput.data(), registerClient)) {
+                DefaultRegisterClientInput input = (DefaultRegisterClientInput) modelObject;
+                if (clientInfo.containsKey(input.clientId())) {
+                    throw new RuntimeException("Client already registered.");
+                }
+                clientInfo.put(input.clientId(), input);
+                registerClientOutput.clientId(input.clientId());
+                registerClientOutput.supportedFeatures(input.supportedFeatures());
+                registerClientOutput.endpointUri(input.endpointUri());
+                registerClientOutput.supportsAckModel(input.supportsAckModel());
+                registerClientOutput.tenantId(input.tenantId());
+
+                // TODO create node to DCS
+            }
+        } catch (Exception e) {
+            // if there is an exception respond with an error.
+            status = RpcOutput.Status.RPC_FAILURE;
+            log.error(ExceptionUtils.getFullStackTrace(e));
+        }
+
+        ResourceData dataNode = modelConverter.createDataNode(
+                DefaultModelObjectData.builder()
+                        .addModelObject(registerClientOutput)
+                        .build()
+        );
+
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return new RpcOutput(status, dataNode.dataNodes().get(0));
+    }
+
+    @Override
+    public RpcOutput deregisterClient(RpcInput rpcInput) {
+        Stopwatch timer = Stopwatch.createStarted();
+        DefaultDeregisterClientOutput deregisterClientOutput = new DefaultDeregisterClientOutput();
+        RpcOutput.Status status = RpcOutput.Status.RPC_SUCCESS;
+
+        try {
+            for (ModelObject modelObject : getModelObjects(rpcInput.data(), registerClient)) {
+                DefaultRegisterClientInput input = (DefaultRegisterClientInput) modelObject;
+                if (!clientInfo.containsKey(input.clientId())) {
+                    throw new RuntimeException("Client does not exist.");
+                }
+                clientInfo.remove(input.clientId());
+                deregisterClientOutput.clientId(input.clientId());
+
+                DefaultConnections defaultConnections = new DefaultConnections();
+                defaultConnections.clientId(input.clientId().toString());
+
+                // TODO delete node from DCS
+            }
+        } catch (Exception e) {
+            // if there is an exception respond with an error.
+            status = RpcOutput.Status.RPC_FAILURE;
+            log.error(ExceptionUtils.getFullStackTrace(e));
+        }
+
+        ResourceData dataNode = modelConverter.createDataNode(
+                DefaultModelObjectData.builder()
+                        .addModelObject(deregisterClientOutput)
+                        .build()
+        );
+
+        log.debug("Time Elapsed {} ms", timer.stop().elapsed(TimeUnit.MILLISECONDS));
+        return new RpcOutput(status, dataNode.dataNodes().get(0));
+    }
+
 }
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
index af62447..f412c5f 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/TenantService.java
@@ -63,7 +63,7 @@
     Optional<DefaultTenant> getTenant(ClientIdentifier clientId);
 
     /**
-     * Handles create configure operations that are invoked through RPC.
+     * Handles create Configure operations that are invoked through RPC.
      *
      * @param create      RPC Input converted
      * @param clientInfo    Client Identifier
@@ -77,7 +77,7 @@
     ) throws Exception;
 
     /**
-     * Handles update configure operations that are invoked through RPC.
+     * Handles update Configure operations that are invoked through RPC.
      *
      * @param update      RPC Input converted
      * @param clientInfo    Client Identifier
@@ -91,7 +91,7 @@
     ) throws Exception;
 
     /**
-     * Handles delete configure operations that are invoked through RPC.
+     * Handles delete Configure operations that are invoked through RPC.
      *
      * @param delete      RPC Input converted
      * @param clientInfo    Client Identifier
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 94552ff..f528442 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
@@ -116,12 +116,12 @@
 
         configureDpn = ResourceId.builder()
                 .addBranchPointSchema("/", null)
-                .addBranchPointSchema("configure-dpn", "urn:ietf:params:xml:ns:yang:fpcagent")
+                .addBranchPointSchema("Configure-dpn", "urn:ietf:params:xml:ns:yang:fpcagent")
                 .build();
 
         configureBundles = ResourceId.builder()
                 .addBranchPointSchema("/", null)
-                .addBranchPointSchema("configure-bundles", "urn:ietf:params:xml:ns:yang:fpcagent")
+                .addBranchPointSchema("Configure-bundles", "urn:ietf:params:xml:ns:yang:fpcagent")
                 .build();
 
         registerClient = ResourceId.builder()
