diff --git a/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/yab/MockYmsManager.java b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/yab/MockYmsManager.java
new file mode 100644
index 0000000..7645a32
--- /dev/null
+++ b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/yab/MockYmsManager.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.yab;
+
+import static java.lang.String.valueOf;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.drivers.netconf.MockCoreService;
+import org.onosproject.yms.app.ych.DefaultYangCodecHandler;
+import org.onosproject.yms.app.ych.defaultcodecs.YangCodecRegistry;
+import org.onosproject.yms.app.ydt.YangRequestWorkBench;
+import org.onosproject.yms.app.ysr.DefaultYangModuleLibrary;
+import org.onosproject.yms.app.ysr.MockYangSchemaRegistry;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ych.YangCodecHandler;
+import org.onosproject.yms.ych.YangDataTreeCodec;
+import org.onosproject.yms.ych.YangProtocolEncodingFormat;
+import org.onosproject.yms.ydt.YdtBuilder;
+import org.onosproject.yms.ydt.YdtResponse;
+import org.onosproject.yms.ydt.YdtWalker;
+import org.onosproject.yms.ydt.YmsOperationType;
+import org.onosproject.yms.ymsm.YmsService;
+import org.onosproject.yms.ynh.YangNotificationService;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+
+/**
+ * Represents implementation of YANG application management system manager.
+ */
+public class MockYmsManager
+        implements YmsService {
+    private static final String MODULE_ID = "module-id";
+
+    YangSchemaRegistry schemaRegistry;
+    private YangModuleLibrary library;
+    private IdGenerator moduleIdGenerator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    public MockYmsManager()
+            throws InstantiationException, IllegalAccessException, IOException {
+        coreService = new MockCoreService();
+        moduleIdGenerator = coreService.getIdGenerator(MODULE_ID);
+        library = new DefaultYangModuleLibrary(getNewModuleId());
+        YangCodecRegistry.initializeDefaultCodec();
+    }
+
+    @Override
+    public YdtBuilder getYdtBuilder(String logicalRootName,
+                                    String rootNamespace,
+                                    YmsOperationType operationType) {
+        return new YangRequestWorkBench(logicalRootName, rootNamespace,
+                                        operationType, schemaRegistry, false);
+    }
+
+    @Override
+    public YdtBuilder getYdtBuilder(String logicalRootName,
+                                    String rootNamespace,
+                                    YmsOperationType operationType,
+                                    Object schemaRegistryForYdt) {
+        return null;
+    }
+
+    @Override
+    public YdtWalker getYdtWalker() {
+        return null;
+    }
+
+    @Override
+    public YdtResponse executeOperation(YdtBuilder operationRequest) {
+        YangApplicationBroker requestBroker =
+                new YangApplicationBroker(schemaRegistry);
+        switch (operationRequest.getYmsOperationType()) {
+            case EDIT_CONFIG_REQUEST:
+                try {
+                    return requestBroker.processEdit(operationRequest);
+                } catch (CloneNotSupportedException e) {
+                }
+                break;
+            case QUERY_CONFIG_REQUEST:
+            case QUERY_REQUEST:
+                return requestBroker.processQuery(operationRequest);
+            case RPC_REQUEST:
+                return requestBroker.processOperation(operationRequest);
+            default:
+        }
+        return null;
+    }
+
+    @Override
+    public YangNotificationService getYangNotificationService() {
+        return null;
+    }
+
+    @Override
+    public void registerService(Object appManager, Class<?> yangService,
+                                List<String> supportedFeatureList) {
+    }
+
+    @Override
+    public void unRegisterService(Object appManager, Class<?> yangService) {
+
+    }
+
+    @Override
+    public YangModuleLibrary getYangModuleLibrary() {
+        return library;
+    }
+
+    @Override
+    public String getYangFile(YangModuleIdentifier moduleIdentifier) {
+        return null;
+    }
+
+    @Override
+    public void registerDefaultCodec(YangDataTreeCodec defaultCodec,
+                                     YangProtocolEncodingFormat dataFormat) {
+    }
+
+    @Override
+    public YangCodecHandler getYangCodecHandler() {
+        YangSchemaRegistry registry = new MockYangSchemaRegistry();
+        DefaultYangCodecHandler handler = new DefaultYangCodecHandler(registry);
+        handler.setLibrary(new DefaultYangModuleLibrary(getNewModuleId()));
+        return handler;
+    }
+
+    private String getNewModuleId() {
+        return valueOf(moduleIdGenerator.getNewId());
+    }
+}
diff --git a/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/yab/package-info.java b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/yab/package-info.java
new file mode 100644
index 0000000..a8a971c
--- /dev/null
+++ b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/yab/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for Microsemi device drivers support for NETCONF for EA1000.
+ */
+package org.onosproject.yms.app.yab;
\ No newline at end of file
diff --git a/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/ysr/MockYangSchemaRegistry.java b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/ysr/MockYangSchemaRegistry.java
new file mode 100644
index 0000000..5de56fd
--- /dev/null
+++ b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/ysr/MockYangSchemaRegistry.java
@@ -0,0 +1,767 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yms.app.ysr;
+
+import org.onosproject.yangutils.datamodel.YangInclude;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleInformation;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+import org.slf4j.Logger;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Pattern;
+
+import static java.util.Collections.sort;
+import static org.apache.commons.io.FileUtils.deleteDirectory;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.deSerializeDataModel;
+import static org.onosproject.yangutils.utils.UtilConstants.EVENT_STRING;
+import static org.onosproject.yangutils.utils.UtilConstants.HYPHEN;
+import static org.onosproject.yangutils.utils.UtilConstants.OP_PARAM;
+import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
+import static org.onosproject.yangutils.utils.UtilConstants.SERVICE;
+import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
+import static org.slf4j.LoggerFactory.getLogger;
+
+
+/**
+ * Representation of default YANG schema registry. Yang schema registry
+ * provides interface to an application to register its YANG schema
+ * with YMS. It provides YANG schema nodes to YDT, YNB and YSB.
+ */
+public class MockYangSchemaRegistry implements YangSchemaRegistry {
+
+    private static final String SYSTEM = SLASH + "system" + SLASH;
+    private static final String MAVEN = "mvn:";
+    private static final String JAR = ".jar";
+    private static final String USER_DIRECTORY = "user.dir";
+    private static final String AT = "@";
+    private static final String DATE_FORMAT = "yyyy-mm-dd";
+    private static final String ONOS = "org.onosproject";
+    private static final Logger log = getLogger(MockYangSchemaRegistry.class);
+
+    private static final String FS = File.separator;
+    private static final String USER_DIR = System.getProperty("user.dir").replaceAll("ea1000driver", "ea1000yang");
+//    private static final String BUCK_OUT_DIR = "/buck-out/gen/drivers/microsemi/ea1000yang/";
+    private static final String BUCK_OUT_BIN_LOC =
+            "/buck-out/bin/drivers/microsemi/ea1000yang/"
+            + "lib__onos-drivers-microsemi-ea1000yang__classes/YangMetaData.ser";
+    private static final String PATH = FS + "target" + FS + "classes" + FS;
+    private static final String SER_FILE_PATH = "yang" + FS + "resources" +
+            FS + "YangMetaData.ser";
+    private static final String RESOURCE = "src/test/resources";
+
+
+    /*
+     * Map for storing app objects.
+     */
+    private final ConcurrentMap<String, Object> appObjectStore;
+
+    /*
+     * Map for storing YANG schema nodes.
+     */
+    private final ConcurrentMap<String, ConcurrentMap<String, YangSchemaNode>>
+            yangSchemaStore;
+
+    /*
+     * Map for storing YANG schema nodes with respect to root's generated
+     * interface file name.
+     */
+    private final ConcurrentMap<String, YangSchemaNode> interfaceNameKeyStore;
+
+    /*
+     * Map for storing YANG schema nodes root's generated op param file name.
+     */
+    private final ConcurrentMap<String, YangSchemaNode> opParamNameKeyStore;
+
+    /*
+     * Map for storing YANG schema nodes with respect to notifications.
+     */
+    private final ConcurrentMap<String, YangSchemaNode> eventNameKeyStore;
+
+    /*
+     * Map for storing YANG schema nodes with respect to app name.
+     */
+    private final ConcurrentMap<String, YangSchemaNode> appNameKeyStore;
+
+    /*
+     * Map for storing registered classes.
+     */
+    private final ConcurrentMap<String, Class<?>> registerClassStore;
+
+    /*
+     * Map for storing YANG file details.
+     */
+    private final ConcurrentMap<YangModuleIdentifier, String> yangFileStore;
+
+    /**
+     * Map for storing schema nodes with respect to namespace.
+     */
+    private final ConcurrentMap<String, YangSchemaNode> nameSpaceSchemaStore;
+
+    private final ConcurrentMap<Object, Boolean> ynhRegistrationStore;
+    private final ConcurrentMap<String, String> jarPathStore;
+
+    /**
+     * Creates an instance of default YANG schema registry.
+     */
+    public MockYangSchemaRegistry() {
+        appObjectStore = new ConcurrentHashMap<>();
+        yangSchemaStore = new ConcurrentHashMap<>();
+        interfaceNameKeyStore = new ConcurrentHashMap<>();
+        opParamNameKeyStore = new ConcurrentHashMap<>();
+        eventNameKeyStore = new ConcurrentHashMap<>();
+        registerClassStore = new ConcurrentHashMap<>();
+        yangFileStore = new ConcurrentHashMap<>();
+        appNameKeyStore = new ConcurrentHashMap<>();
+        ynhRegistrationStore = new ConcurrentHashMap<>();
+        jarPathStore = new ConcurrentHashMap<>();
+        nameSpaceSchemaStore = new ConcurrentHashMap<>();
+    }
+
+
+    /**
+     * This is overridden for Maven and Buck.
+     *
+     * Because they don't have a Bundle Context, and the JAR file doesn't exist
+     * when this is called, we have to work with the .ser file
+     */
+    @Override
+    public void registerApplication(Object appObject, Class<?> serviceClass) {
+        synchronized (MockYangSchemaRegistry.class) {
+            doPreProcessing(serviceClass, appObject);
+            if (!verifyIfApplicationAlreadyRegistered(serviceClass)) {
+
+                List<YangNode> curNodes = new ArrayList<>();
+                Path serFile = Paths.get(USER_DIR, PATH, SER_FILE_PATH);
+                if (USER_DIR.contains("ea1000yang")) {
+                    serFile = Paths.get(USER_DIR, PATH, SER_FILE_PATH);
+                } else {
+                    serFile = Paths.get(USER_DIR, BUCK_OUT_BIN_LOC);
+                }
+
+                if (Files.notExists(serFile)) {
+                    throw new UncheckedIOException(
+                            new IOException("File " + serFile.toString() + " does not exist!"));
+                }
+
+                try {
+                    curNodes.addAll(deSerializeDataModel(serFile.toString()));
+                } catch (IOException e) {
+                    throw new UncheckedIOException(e);
+                }
+
+                // process application registration.
+                if (curNodes != null && !curNodes.isEmpty()) {
+                    jarPathStore.put(serviceClass.getName(), serFile.toString());
+                    processRegistration(serviceClass, serFile.toString(),
+                                        curNodes, appObject, false);
+                } else {
+                    throw new UncheckedIOException(
+                            new IOException("Unable to find Yang Nodes in serFile: " + serFile.toString()));
+                }
+            }
+        }
+    }
+
+    @Override
+    public void unRegisterApplication(Object managerObject,
+                                      Class<?> serviceClass) {
+        synchronized (MockYangSchemaRegistry.class) {
+            YangSchemaNode curNode;
+            String serviceName = serviceClass.getName();
+
+            //Check if service should be unregistered?
+            if (managerObject != null) {
+                verifyApplicationRegistration(managerObject, serviceClass);
+            }
+            //Remove registered class from store.
+            registerClassStore.remove(serviceName);
+            //check if service is in app store.
+            curNode = appNameKeyStore.get(serviceName);
+            if (curNode == null) {
+                curNode = interfaceNameKeyStore.get(serviceName);
+            }
+
+            if (curNode != null) {
+                removeSchemaNode(curNode);
+                eventNameKeyStore.remove(getEventClassName(curNode));
+                appObjectStore.remove(serviceName);
+                interfaceNameKeyStore.remove(getInterfaceClassName(curNode));
+                opParamNameKeyStore.remove(getOpParamClassName(curNode));
+                yangFileStore.remove(getModuleIdentifier(curNode));
+                appNameKeyStore.remove(serviceName);
+                nameSpaceSchemaStore.remove(curNode.getNameSpace()
+                                                    .getModuleNamespace());
+                removeYsrGeneratedTemporaryResources(jarPathStore.get(serviceName),
+                                                     serviceName);
+                log.info(" service {} is unregistered.",
+                         serviceClass.getSimpleName());
+            } else {
+                throw new RuntimeException(serviceClass.getSimpleName() +
+                                                   " service was not registered.");
+            }
+        }
+    }
+
+    @Override
+    public Object getRegisteredApplication(YangSchemaNode schemaNode) {
+        Object obj = null;
+        if (schemaNode != null) {
+            String name = getServiceName(schemaNode);
+            obj = appObjectStore.get(name);
+            if (obj == null) {
+                log.error("{} not found.", name);
+            }
+        }
+        return obj;
+    }
+
+    @Override
+    public YangSchemaNode getYangSchemaNodeUsingSchemaName(String schemaName) {
+        return getSchemaNodeUsingSchemaNameWithRev(schemaName);
+    }
+
+    @Override
+    public YangSchemaNode getYangSchemaNodeUsingAppName(String appName) {
+        YangSchemaNode node = appNameKeyStore.get(appName);
+        if (node == null) {
+            log.error("{} not found.", appName);
+        }
+        return node;
+    }
+
+    @Override
+    public YangSchemaNode
+    getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(String name) {
+        YangSchemaNode node = interfaceNameKeyStore.get(name);
+        if (node == null) {
+            log.error("{} not found.", name);
+        }
+        return node;
+    }
+
+    @Override
+    public YangSchemaNode getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+            String name) {
+        YangSchemaNode node = opParamNameKeyStore.get(name);
+        if (node == null) {
+            log.error("{} not found.", name);
+        }
+        return node;
+    }
+
+    @Override
+    public YangSchemaNode getRootYangSchemaNodeForNotification(String name) {
+        YangSchemaNode node = eventNameKeyStore.get(name);
+        if (node == null) {
+            log.error("{} not found.", name);
+        }
+        return node;
+    }
+
+    @Override
+    public Class<?> getRegisteredClass(YangSchemaNode schemaNode) {
+        String interfaceName = getInterfaceClassName(schemaNode);
+        String serviceName = getServiceName(schemaNode);
+        Class<?> regClass = registerClassStore.get(serviceName);
+        if (regClass == null) {
+            regClass = registerClassStore.get(interfaceName);
+        }
+        return regClass;
+    }
+
+    @Override
+    public YangSchemaNode getSchemaWrtNameSpace(String nameSpace) {
+
+        YangSchemaNode node = nameSpaceSchemaStore.get(nameSpace);
+        if (node == null) {
+            log.error("node with {} namespace not found.", nameSpace);
+        }
+        return node;
+    }
+
+    @Override
+    public String getYangFile(YangModuleIdentifier moduleIdentifier) {
+        String file = yangFileStore.get(moduleIdentifier);
+        if (file == null) {
+            log.error("YANG files for corresponding module identifier {} not " +
+                              "found", moduleIdentifier);
+        }
+        return file;
+    }
+
+    @Override
+    public boolean verifyNotificationObject(Object appObj, Class<?> service) {
+        synchronized (MockYangSchemaRegistry.class) {
+            YangSchemaNode node = appNameKeyStore.get(service.getName());
+            if (node == null) {
+                log.error("application is not registered with YMS {}",
+                          service.getName());
+                return false;
+            }
+            try {
+                if (node.isNotificationPresent()) {
+                    if (appObj != null) {
+                        Boolean ifPresent = ynhRegistrationStore.get(appObj);
+                        if (ifPresent == null) {
+                            ynhRegistrationStore.put(appObj, true);
+                            return true;
+                        }
+                    }
+                }
+            } catch (DataModelException e) {
+                log.error("notification registration error: {} {}", e
+                        .getLocalizedMessage(), e);
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public void flushYsrData() {
+        appObjectStore.clear();
+        yangSchemaStore.clear();
+        eventNameKeyStore.clear();
+        opParamNameKeyStore.clear();
+        interfaceNameKeyStore.clear();
+        registerClassStore.clear();
+        yangFileStore.clear();
+        nameSpaceSchemaStore.clear();
+    }
+
+    @Override
+    public void processModuleLibrary(String serviceName,
+                                     YangModuleLibrary library) {
+        synchronized (MockYangSchemaRegistry.class) {
+            YangSchemaNode node = appNameKeyStore.get(serviceName);
+            if (node != null) {
+                YangModuleInformation moduleInformation =
+                        new DefaultYangModuleInformation(getModuleIdentifier(node),
+                                                         node.getNameSpace());
+                addSubModuleIdentifier(node, (
+                        DefaultYangModuleInformation) moduleInformation);
+                //TODO: add feature list to module information.
+                ((DefaultYangModuleLibrary) library)
+                        .addModuleInformation(moduleInformation);
+            }
+        }
+    }
+
+    /**
+     * Process service class.
+     *
+     * @param serviceClass service class
+     * @param appObject    application object
+     */
+
+    void doPreProcessing(Class<?> serviceClass, Object appObject) {
+
+        //Check if service should be registered?
+        if (appObject != null) {
+            verifyApplicationRegistration(appObject, serviceClass);
+        }
+        String name = serviceClass.getName();
+        //Add app class to registered service store.
+        if (!registerClassStore.containsKey(name)) {
+            registerClassStore.put(name, serviceClass);
+        }
+    }
+
+    void updateServiceClass(Class<?> service) {
+        registerClassStore.put(service.getName(), service);
+    }
+
+    /**
+     * Process application registration.
+     *
+     * @param service  service class
+     * @param jarPath  jar path
+     * @param nodes    YANG nodes
+     * @param appObj   application object
+     * @param isFromUt if registration is being called form unit test
+     */
+    void processRegistration(Class<?> service, String jarPath,
+                             List<YangNode> nodes,
+                             Object appObj, boolean isFromUt) {
+
+        // process storing operations.
+        YangNode schemaNode = findNodeWhichShouldBeReg(service.getName(), nodes);
+        if (schemaNode != null) {
+            if (appObj != null) {
+                appObjectStore.put(service.getName(), appObj);
+            }
+            //Process application context for registrations.
+            processApplicationContext(schemaNode, service.getName(), isFromUt);
+            //Update YANG file store.
+            updateYangFileStore(schemaNode, jarPath);
+        }
+    }
+
+    /**
+     * Returns the node for which corresponding class is generated.
+     *
+     * @param name  generated class name
+     * @param nodes list of yang nodes
+     * @return node for which corresponding class is generated
+     */
+    private YangNode findNodeWhichShouldBeReg(String name, List<YangNode> nodes) {
+        for (YangNode node : nodes) {
+            if (name.equals(getServiceName(node)) ||
+                    name.equals(getInterfaceClassName(node))) {
+                return node;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Verifies if service class should be registered or not.
+     *
+     * @param appObject application object
+     * @param appClass  application class
+     */
+    private void verifyApplicationRegistration(Object appObject,
+                                               Class<?> appClass) {
+        Class<?> managerClass = appObject.getClass();
+        Class<?>[] services = managerClass.getInterfaces();
+        List<Class<?>> classes = new ArrayList<>();
+        Collections.addAll(classes, services);
+        if (!classes.contains(appClass)) {
+            throw new RuntimeException("service class " + appClass.getName() +
+                                               "is not being implemented by " +
+                                               managerClass.getName());
+        }
+    }
+
+    /**
+     * Verifies if application is already registered with YMS.
+     *
+     * @param appClass application class
+     * @return true if application already registered
+     */
+    private boolean verifyIfApplicationAlreadyRegistered(Class<?> appClass) {
+        String appName = appClass.getName();
+        return appObjectStore.containsKey(appName) ||
+                interfaceNameKeyStore.containsKey(appName);
+    }
+
+    /**
+     * Updates yang file store for YANG node.
+     *
+     * @param node    YANG node
+     * @param jarPath jar file path
+     */
+    private void updateYangFileStore(YangNode node, String jarPath) {
+        yangFileStore.put(getModuleIdentifier(node),
+                          getYangFilePath(jarPath, node.getFileName()));
+    }
+
+    /**
+     * Returns yang file path.
+     *
+     * @param jarPath          jar path
+     * @param metaDataFileName name of yang file from metadata
+     * @return yang file path
+     */
+    private String getYangFilePath(String jarPath, String metaDataFileName) {
+        String[] metaData = metaDataFileName.split(SLASH);
+        return jarPath + SLASH + metaData[metaData.length - 1];
+    }
+
+
+    /**
+     * Process an application an updates the maps for YANG schema registry.
+     *
+     * @param appNode  application YANG schema nodes
+     * @param name     class name
+     * @param isFormUt if method is being called from unit tests
+     */
+    private void processApplicationContext(YangSchemaNode appNode, String name,
+                                           boolean isFormUt) {
+
+        //Update map for which registrations is being called.
+        appNameKeyStore.put(name, appNode);
+
+        // Updates schema store.
+        addToSchemaStore(appNode);
+        // update interface store.
+        interfaceNameKeyStore.put(getInterfaceClassName(appNode), appNode);
+
+        //update op param store.
+        opParamNameKeyStore.put(getOpParamClassName(appNode), appNode);
+
+        //update namespaceSchema store.
+        nameSpaceSchemaStore.put(appNode.getNameSpace().getModuleNamespace(), appNode);
+
+        //Checks if notification is present then update notification store map.
+        String eventSubject = null;
+        try {
+            if (appNode.isNotificationPresent()) {
+                eventSubject = getEventClassName(appNode);
+            }
+        } catch (DataModelException e) {
+            log.error("failed to search notification from schema map : {}",
+                      e.getLocalizedMessage());
+        }
+        if (eventSubject != null) {
+            eventNameKeyStore.put(eventSubject, appNode);
+        }
+        if (!isFormUt) {
+            log.info("successfully registered this application {}", name);
+        }
+    }
+
+    /**
+     * Returns jar path from bundle mvnLocationPath.
+     *
+     * @param mvnLocationPath mvnLocationPath of bundle
+     * @return path of jar
+     */
+    private String getJarPathFromBundleLocation(String mvnLocationPath,
+                                                String currentDirectory) {
+        String path = currentDirectory + SYSTEM;
+        if (mvnLocationPath.contains(MAVEN)) {
+            String[] strArray = mvnLocationPath.split(MAVEN);
+            if (strArray[1].contains(File.separator)) {
+                String[] split = strArray[1].split(File.separator);
+                if (split[0].contains(PERIOD)) {
+                    String[] groupId = split[0].split(Pattern.quote(PERIOD));
+                    return path + groupId[0] + SLASH + groupId[1] + SLASH + split[1] +
+                            SLASH + split[2] + SLASH + split[1] + HYPHEN + split[2];
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns schema node based on the revision.
+     *
+     * @param name name of the schema node
+     * @return schema node based on the revision
+     */
+    private YangSchemaNode getSchemaNodeUsingSchemaNameWithRev(String name) {
+        ConcurrentMap<String, YangSchemaNode> revMap;
+        YangSchemaNode schemaNode;
+        if (name.contains(AT)) {
+            String[] revArray = name.split(AT);
+            revMap = yangSchemaStore.get(revArray[0]);
+            schemaNode = revMap.get(name);
+            if (schemaNode == null) {
+                log.error("{} not found.", name);
+            }
+            return schemaNode;
+        }
+        if (yangSchemaStore.containsKey(name)) {
+            revMap = yangSchemaStore.get(name);
+            if (revMap != null && !revMap.isEmpty()) {
+                YangSchemaNode node = revMap.get(name);
+                if (node != null) {
+                    return node;
+                }
+                String revName = getLatestVersion(revMap);
+                return revMap.get(revName);
+            }
+        }
+        log.error("{} not found.", name);
+        return null;
+    }
+
+    private String getLatestVersion(ConcurrentMap<String, YangSchemaNode> revMap) {
+        List<String> keys = new ArrayList<>();
+        for (Map.Entry<String, YangSchemaNode> entry : revMap.entrySet()) {
+            keys.add(entry.getKey());
+        }
+        sort(keys);
+        return keys.get(keys.size() - 1);
+    }
+
+    /**
+     * Adds schema node when different revision of node has received.
+     *
+     * @param schemaNode schema node
+     */
+    private void addToSchemaStore(YangSchemaNode schemaNode) {
+
+        String date = getDateInStringFormat(schemaNode);
+        String name = schemaNode.getName();
+        String revName = name;
+        if (date != null) {
+            revName = name + AT + date;
+        }
+        //check if already present.
+        if (!yangSchemaStore.containsKey(name)) {
+            ConcurrentMap<String, YangSchemaNode> revStore =
+                    new ConcurrentHashMap<>();
+            revStore.put(revName, schemaNode);
+            yangSchemaStore.put(name, revStore);
+        } else {
+            yangSchemaStore.get(name).put(revName, schemaNode);
+        }
+    }
+
+    /**
+     * Returns date in string format.
+     *
+     * @param schemaNode schema node
+     * @return date in string format
+     */
+    String getDateInStringFormat(YangSchemaNode schemaNode) {
+        if (schemaNode != null) {
+            if (((YangNode) schemaNode).getRevision() != null) {
+                return new SimpleDateFormat(DATE_FORMAT)
+                        .format(((YangNode) schemaNode).getRevision()
+                                        .getRevDate());
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes schema node from schema map.
+     *
+     * @param removableNode schema node which needs to be removed
+     */
+    private void removeSchemaNode(YangSchemaNode removableNode) {
+        String name = removableNode.getName();
+        String revName = name;
+        String date = getDateInStringFormat(removableNode);
+        if (date != null) {
+            revName = name + AT + date;
+        }
+        ConcurrentMap<String, YangSchemaNode> revMap = yangSchemaStore.get(name);
+        if (revMap != null && !revMap.isEmpty() && revMap.size() != 1) {
+            revMap.remove(revName);
+        } else {
+            yangSchemaStore.remove(removableNode.getName());
+        }
+    }
+
+    /**
+     * Adds sub module identifier.
+     *
+     * @param node        schema node
+     * @param information module information
+     */
+    private void addSubModuleIdentifier(
+            YangSchemaNode node, DefaultYangModuleInformation information) {
+        List<YangInclude> includeList = new ArrayList<>();
+        if (node instanceof YangModule) {
+            includeList = ((YangModule) node).getIncludeList();
+        } else if (node instanceof YangSubModule) {
+            includeList = ((YangSubModule) node).getIncludeList();
+        }
+        for (YangInclude include : includeList) {
+            information.addSubModuleIdentifiers(getModuleIdentifier(
+                    include.getIncludedNode()));
+        }
+    }
+
+    /**
+     * Returns module identifier for schema node.
+     *
+     * @param schemaNode schema node
+     * @return module identifier for schema node
+     */
+    private YangModuleIdentifier getModuleIdentifier(
+            YangSchemaNode schemaNode) {
+        return new DefaultYangModuleIdentifier(
+                schemaNode.getName(), getDateInStringFormat(schemaNode));
+    }
+
+    /**
+     * Returns schema node's generated interface class name.
+     *
+     * @param schemaNode schema node
+     * @return schema node's generated interface class name
+     */
+    String getInterfaceClassName(YangSchemaNode schemaNode) {
+        return schemaNode.getJavaPackage() + PERIOD +
+                getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType());
+    }
+
+    /**
+     * Returns schema node's generated op param class name.
+     *
+     * @param schemaNode schema node
+     * @return schema node's generated op param class name
+     */
+    private String getOpParamClassName(YangSchemaNode schemaNode) {
+        return getInterfaceClassName(schemaNode) + OP_PARAM;
+    }
+
+    /**
+     * Returns schema node's generated event class name.
+     *
+     * @param schemaNode schema node
+     * @return schema node's generated event class name
+     */
+    private String getEventClassName(YangSchemaNode schemaNode) {
+        return getInterfaceClassName(schemaNode).toLowerCase() + PERIOD +
+                getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType()) +
+                EVENT_STRING;
+    }
+
+    /**
+     * Returns schema node's generated service class name.
+     *
+     * @param schemaNode schema node
+     * @return schema node's generated service class name
+     */
+    String getServiceName(YangSchemaNode schemaNode) {
+        return getInterfaceClassName(schemaNode) + SERVICE;
+    }
+
+    /**
+     * Removes YSR generated temporary resources.
+     *
+     * @param rscPath resource path
+     * @param appName application name
+     */
+    private void removeYsrGeneratedTemporaryResources(String rscPath,
+                                                      String appName) {
+        if (rscPath != null) {
+            File jarPath = new File(rscPath);
+            if (jarPath.exists()) {
+                try {
+                    deleteDirectory(jarPath);
+                } catch (IOException e) {
+                    log.error("failed to delete ysr resources for {} : {}",
+                              appName, e.getLocalizedMessage());
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/ysr/package-info.java b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/ysr/package-info.java
new file mode 100644
index 0000000..6e7ab5c
--- /dev/null
+++ b/drivers/microsemi/ea1000yang/src/test/java/org/onosproject/yms/app/ysr/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Package for Microsemi device drivers support for NETCONF for EA1000.
+ */
+package org.onosproject.yms.app.ysr;
\ No newline at end of file
