[ONOS-5084],[ONOS-5083] YANG schema registry for YMS

Change-Id: I88394307cb9be30237be0bb17e013d7af88a607c
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java
new file mode 100644
index 0000000..f4030ce
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/YmsManager.java
@@ -0,0 +1,181 @@
+/*
+ * 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.ymsm;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.yms.app.ynh.YangNotificationExtendedService;
+import org.onosproject.yms.app.ysr.DefaultYangSchemaRegistry;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Represents implementation of YANG management system manager.
+ */
+@Service
+@Component(immediate = true)
+public class YmsManager
+        implements YmsService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final String APP_ID = "org.onosproject.app.yms";
+    private static final String MODULE_ID = "module-id";
+    private ApplicationId appId;
+    private YangSchemaRegistry schemaRegistry;
+    //module id generator should be used to generate a new module id for
+    //each YSR instance. So YCH also should generate it.
+    private IdGenerator moduleIdGenerator;
+    private ExecutorService schemaRegistryExecutor;
+    private YangNotificationExtendedService ynhExtendedService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID);
+        moduleIdGenerator = coreService.getIdGenerator(MODULE_ID);
+        schemaRegistry = new DefaultYangSchemaRegistry(String.valueOf(
+                moduleIdGenerator.getNewId()));
+        schemaRegistryExecutor =
+                Executors.newSingleThreadExecutor(groupedThreads(
+                        "onos/apps/yang-management-system/schema-registry",
+                        "schema-registry-handler", log));
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        ((DefaultYangSchemaRegistry) schemaRegistry).flushYsrData();
+        schemaRegistryExecutor.shutdown();
+
+        // TODO implementation for other components.
+        log.info("Stopped");
+    }
+
+    @Override
+    public YdtBuilder getYdtBuilder(String logicalRootName,
+                                    String rootNamespace,
+                                    YmsOperationType operationType) {
+        return null;
+    }
+
+    @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) {
+        return null;
+    }
+
+    @Override
+    public YangNotificationService getYangNotificationService() {
+        return ynhExtendedService;
+    }
+
+    /**
+     * Returns YANG notification extended service.
+     *
+     * @return YANG notification extended service
+     */
+    private YangNotificationExtendedService getYnhExtendedService() {
+        return ynhExtendedService;
+    }
+
+    @Override
+    public YangModuleLibrary getYangModuleLibrary() {
+        return ((DefaultYangSchemaRegistry) schemaRegistry).getLibrary();
+    }
+
+    @Override
+    public String getYangFile(YangModuleIdentifier moduleIdentifier) {
+        return ((DefaultYangSchemaRegistry) schemaRegistry)
+                .getYangFile(moduleIdentifier);
+    }
+
+    @Override
+    public void registerDefaultCodec(YangDataTreeCodec defaultCodec,
+                                     YangProtocolEncodingFormat dataFormat) {
+
+    }
+
+    @Override
+    public void registerService(Object yangManager, Class<?> yangService,
+                                List<String> supportedFeatureList) {
+
+        //perform registration of service
+        schemaRegistryExecutor.execute(() -> schemaRegistry
+                .registerApplication(yangManager, yangService,
+                                     getYnhExtendedService()));
+    }
+
+    @Override
+    public void unRegisterService(Object appManager, Class<?> yangService) {
+        schemaRegistry.unRegisterApplication(appManager, yangService);
+    }
+
+    @Override
+    public YangCodecHandler getYangCodecHandler() {
+        return null;
+    }
+
+    /**
+     * Returns schema registry.
+     *
+     * @return schema registry
+     */
+    public YangSchemaRegistry getSchemaRegistry() {
+        return schemaRegistry;
+    }
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/package-info.java
new file mode 100644
index 0000000..2d29667
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ymsm/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides implementation of YANG application management system manager. YMSM is manager
+ * of the YANG Core, it manages interaction between application and protocols.
+ */
+package org.onosproject.yms.app.ymsm;
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/YangNotificationExtendedService.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/YangNotificationExtendedService.java
new file mode 100644
index 0000000..690eae4
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/YangNotificationExtendedService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015-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.ynh;
+
+import org.onosproject.event.ListenerService;
+import org.onosproject.yms.ynh.YangNotificationService;
+
+/**
+ * Abstraction of an entity which provides interfaces to YANG extended notification
+ * service. It provides extended interfaces required by YMS internal modules.
+ * Application registers their schema with YMSM, YMSM delegates the registration
+ * request to YSR. YSR then looks for the presence of notification in application
+ * schema, presence of notification will trigger YSR to ask YANG extended notification
+ * service to register it as a listener to that application events.
+ */
+public interface YangNotificationExtendedService extends YangNotificationService {
+
+    /**
+     * Registers as listener with application. This is called by YSR when it
+     * detects notification presence in application YANG file at the time when
+     * application registers it's schema with YMS.
+     *
+     * @param appObject application object
+     */
+    void registerAsListener(ListenerService appObject);
+
+    // TODO handle scenario when multiple services are implemented by single manager.
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/package-info.java
new file mode 100644
index 0000000..1815ef7
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ynh/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides implementation of YANG notification handler. YNH handles notification
+ * from the application and provide it to the protocols.
+ */
+package org.onosproject.yms.app.ynh;
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleIdentifier.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleIdentifier.java
new file mode 100644
index 0000000..e98e982
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleIdentifier.java
@@ -0,0 +1,90 @@
+/*
+ * 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.yms.ysr.YangModuleIdentifier;
+
+import java.util.Comparator;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of default YANG module identifier.
+ */
+class DefaultYangModuleIdentifier implements YangModuleIdentifier,
+        Comparator<YangModuleIdentifier> {
+
+    private final String moduleName;
+    private final String revision;
+
+    /**
+     * Creates an instance of YANG module identifier.
+     *
+     * @param moduleName module's name
+     * @param revision   module's revision
+     */
+    DefaultYangModuleIdentifier(String moduleName, String revision) {
+        this.moduleName = moduleName;
+        this.revision = revision;
+    }
+
+    @Override
+    public String moduleName() {
+        return moduleName;
+    }
+
+    @Override
+    public String revision() {
+        return revision;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(moduleName, revision);
+    }
+
+    @Override
+    public int compare(YangModuleIdentifier id1, YangModuleIdentifier id2) {
+        int compare = id1.moduleName().compareTo(id2.moduleName());
+        if (compare != 0) {
+            return compare;
+        }
+        return id1.revision().compareTo(id2.revision());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultYangModuleIdentifier) {
+            DefaultYangModuleIdentifier that = (DefaultYangModuleIdentifier) obj;
+            return Objects.equals(moduleName, that.moduleName) &&
+                    Objects.equals(revision, that.revision);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("moduleName", moduleName)
+                .add("revision", revision)
+                .toString();
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleInformation.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleInformation.java
new file mode 100644
index 0000000..79778f7
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleInformation.java
@@ -0,0 +1,111 @@
+/*
+ * 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 com.google.common.collect.ImmutableList;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleInformation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of default YANG module information.
+ */
+class DefaultYangModuleInformation implements YangModuleInformation {
+
+    private final YangModuleIdentifier moduleIdentifier;
+    private final String nameSpace;
+    private final List<String> features;
+    private final List<YangModuleIdentifier> subModuleIdentifiers;
+
+    /**
+     * Creates an instance of YANG module information.
+     *
+     * @param moduleIdentifier module identifier
+     * @param nameSpace        name space of module
+     */
+    DefaultYangModuleInformation(YangModuleIdentifier moduleIdentifier,
+                                 String nameSpace) {
+        this.moduleIdentifier = moduleIdentifier;
+        this.nameSpace = nameSpace;
+        subModuleIdentifiers = new ArrayList<>();
+        features = new ArrayList<>();
+    }
+
+    @Override
+    public YangModuleIdentifier moduleIdentifier() {
+        return moduleIdentifier;
+    }
+
+    @Override
+    public String namespace() {
+        return nameSpace;
+    }
+
+    @Override
+    public List<String> featureList() {
+        return ImmutableList.copyOf(features);
+    }
+
+    @Override
+    public List<YangModuleIdentifier> subModuleIdentifiers() {
+        return ImmutableList.copyOf(subModuleIdentifiers);
+    }
+
+    /**
+     * Adds to YANG sub module identifier list.
+     *
+     * @param subModuleIdentifier YANG sub module identifier
+     */
+    void addSubModuleIdentifiers(YangModuleIdentifier subModuleIdentifier) {
+        subModuleIdentifiers.add(subModuleIdentifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(moduleIdentifier, subModuleIdentifiers, nameSpace, features);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultYangModuleInformation) {
+            DefaultYangModuleInformation that = (DefaultYangModuleInformation) obj;
+            return Objects.equals(moduleIdentifier, that.moduleIdentifier) &&
+                    Objects.equals(nameSpace, that.nameSpace) &&
+                    Objects.equals(features, that.features) &&
+                    Objects.equals(subModuleIdentifiers, that.subModuleIdentifiers);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("yangModuleIdentifier", moduleIdentifier)
+                .add("nameSpace", nameSpace)
+                .add("features", features)
+                .add("yangModuleIdentifiers", subModuleIdentifiers)
+                .toString();
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleLibrary.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleLibrary.java
new file mode 100644
index 0000000..4187746
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangModuleLibrary.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.google.common.collect.ImmutableList;
+import org.onosproject.yms.ysr.YangModuleInformation;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Representation of default YANG module library.
+ */
+class DefaultYangModuleLibrary implements YangModuleLibrary {
+
+    private final String moduleSetId;
+    private final List<YangModuleInformation> moduleInformation;
+
+    /**
+     * Creates an instance of YANG module library.
+     *
+     * @param moduleSetId module id
+     */
+    DefaultYangModuleLibrary(String moduleSetId) {
+        this.moduleSetId = moduleSetId;
+        moduleInformation = new ArrayList<>();
+    }
+
+    @Override
+    public String moduleSetId() {
+        return moduleSetId;
+    }
+
+    @Override
+    public List<YangModuleInformation> yangModuleList() {
+        return ImmutableList.copyOf(moduleInformation);
+    }
+
+    /**
+     * Adds module information.
+     *
+     * @param information module information
+     */
+    void addModuleInformation(YangModuleInformation information) {
+        moduleInformation.add(information);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(moduleInformation, moduleSetId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultYangModuleLibrary) {
+            DefaultYangModuleLibrary that = (DefaultYangModuleLibrary) obj;
+            return Objects.equals(moduleInformation, that.moduleInformation) &&
+                    Objects.equals(moduleSetId, that.moduleSetId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("moduleInformation", moduleInformation)
+                .add("moduleId", moduleSetId)
+                .toString();
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java
new file mode 100644
index 0000000..370e9cc
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java
@@ -0,0 +1,1116 @@
+/*
+ * 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.event.ListenerService;
+import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
+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.app.ynh.YangNotificationExtendedService;
+import org.onosproject.yms.ysr.YangModuleIdentifier;
+import org.onosproject.yms.ysr.YangModuleInformation;
+import org.onosproject.yms.ysr.YangModuleLibrary;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Pattern;
+
+import static org.apache.commons.io.FileUtils.deleteDirectory;
+import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.parseJarFile;
+import static org.onosproject.yangutils.utils.UtilConstants.DEFAULT;
+import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
+import static org.onosproject.yangutils.utils.UtilConstants.EVENT_STRING;
+import static org.onosproject.yangutils.utils.UtilConstants.OP_PARAM;
+import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+
+
+/**
+ * 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 DefaultYangSchemaRegistry
+        implements YangSchemaRegistry {
+
+    private static final String SYSTEM = File.separator + "system" +
+            File.separator;
+    private static final String MAVEN = "mvn:";
+    private static final String HYPHEN = "-";
+    private static final String DELIMITER = ".";
+    private static final String SERVICE = "Service";
+    private static final String JAR = ".jar";
+    private static final String USER_DIRECTORY = "user.dir";
+    private static final String SLASH = File.separator;
+    private static final String AT = "@";
+    private static final String DATE_FORMAT = "yyyy-mm-dd";
+    private static final Logger log =
+            LoggerFactory.getLogger(DefaultYangSchemaRegistry.class);
+
+    /*
+     * Map for storing app objects.
+     */
+    private final ConcurrentMap<String, YsrAppContext> appObjectStore;
+
+    /*
+     * Map for storing YANG schema nodes.
+     */
+    private final ConcurrentMap<String, YsrAppContext> yangSchemaStore;
+
+    /*
+     * Map for storing YANG schema nodes with respect to root's generated
+     * interface file name.
+     */
+    private final ConcurrentMap<String, YsrAppContext>
+            yangSchemaStoreForRootInterface;
+
+    /*
+     * Map for storing YANG schema nodes root's generated op param file name.
+     */
+    private final ConcurrentMap<String, YsrAppContext>
+            yangSchemaStoreForRootOpParam;
+
+    /*
+     * Map for storing YANG schema nodes with respect to notifications.
+     */
+    private final ConcurrentMap<String, YsrAppContext>
+            yangRootSchemaStoreForNotification;
+
+    /*
+     * Map for storing registered classes.
+     */
+    private final ConcurrentMap<String, Class<?>> registerClassStore;
+
+    /*
+     * Map for storing YANG file details.
+     */
+    private final ConcurrentMap<YangModuleIdentifier, String> yangFileStore;
+
+    /*
+     * Context of application which is registering with YMS.
+     */
+    private YsrAppContext ysrAppContext;
+
+    /*
+     * Context of application which is registering with YMS with multiple
+     * revision.
+     */
+    private YsrAppContext ysrContextForSchemaStore;
+
+    /*
+     * Context of application which is registering with YMS with multiple
+     * manager object.
+     */
+    private YsrAppContext ysrContextForAppStore;
+
+    /*
+     * Class loader of service application.
+     */
+    private ClassLoader classLoader;
+
+    /**
+     * YANG module library.
+     */
+    private final YangModuleLibrary library;
+
+    /**
+     * Creates an instance of default YANG schema registry.
+     *
+     * @param moduleId module set id of YSR module library
+     */
+    public DefaultYangSchemaRegistry(String moduleId) {
+        appObjectStore = new ConcurrentHashMap<>();
+        yangSchemaStore = new ConcurrentHashMap<>();
+        yangSchemaStoreForRootInterface = new ConcurrentHashMap<>();
+        yangSchemaStoreForRootOpParam = new ConcurrentHashMap<>();
+        yangRootSchemaStoreForNotification = new ConcurrentHashMap<>();
+        registerClassStore = new ConcurrentHashMap<>();
+        yangFileStore = new ConcurrentHashMap<>();
+        library = new DefaultYangModuleLibrary(moduleId);
+    }
+
+
+    @Override
+    public void registerApplication(Object appObject, Class<?> serviceClass,
+                                    YangNotificationExtendedService
+                                            notificationExtendedService) {
+
+        BundleContext bundleContext = getBundle(serviceClass)
+                .getBundleContext();
+        String jarPath = getJarPathFromBundleLocation(
+                bundleContext.getBundle().getLocation(),
+                bundleContext.getProperty(USER_DIRECTORY));
+        // process application registration.
+        processRegistration(serviceClass, appObject, jarPath);
+        //process notification registration.
+        processNotificationRegistration(serviceClass, appObject,
+                                        notificationExtendedService);
+    }
+
+    /**
+     * Process application registration.
+     *
+     * @param serviceClass service class
+     * @param appObject    application object
+     * @param jarPath      jar path
+     */
+    void processRegistration(Class<?> serviceClass, Object appObject,
+                             String jarPath) {
+
+        // set class loader for service class.
+        setClassLoader(serviceClass.getClassLoader());
+
+        //Check if service should be registered?
+        if (appObject != null) {
+            verifyApplicationRegistration(appObject, serviceClass);
+        }
+        //Add app class to registered service store.
+        if (!registerClassStore.containsKey(serviceClass.getName())) {
+            updateServiceClass(serviceClass);
+        }
+
+        // process storing operations.
+        if (!verifyIfApplicationAlreadyRegistered(serviceClass)) {
+            List<YangNode> curNodes =
+                    processJarParsingOperations(jarPath);
+
+            if (curNodes != null) {
+                for (YangNode schemaNode : curNodes) {
+                    //Process application context for registrations.
+                    processApplicationContext(schemaNode);
+                    //Update YANG file store.
+                    updateYangFileStore(schemaNode, jarPath);
+                    //Process module library operation for current node list.
+                    processModuleLibrary(schemaNode);
+                }
+                //Set jar path for app context.
+                ysrAppContext.jarPath(jarPath);
+                ysrContextForSchemaStore.jarPath(jarPath);
+                ysrContextForAppStore.jarPath(jarPath);
+            }
+        }
+
+        //Verifies if object is updated for app store.
+        updateApplicationObject(appObject, serviceClass);
+    }
+
+    /**
+     * 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 simpleName = appClass.getSimpleName();
+        String appName = appClass.getName();
+        if (!appObjectStore.containsKey(appName)) {
+            if (simpleName.contains(OP_PARAM)) {
+                return yangSchemaStoreForRootOpParam
+                        .containsKey(appName);
+            } else {
+                return yangSchemaStoreForRootInterface
+                        .containsKey(appName);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Verifies if service is being implemented by some new object.
+     *
+     * @param appObject application's object
+     * @param appClass  application's class
+     */
+    private void updateApplicationObject(Object appObject, Class<?> appClass) {
+        YsrAppContext appContext =
+                appObjectStore.get(appClass.getName());
+        if (appContext != null) {
+            YangSchemaNode schemaNode = appContext.curNode();
+            String name = getInterfaceClassName(schemaNode);
+            if (appContext.appObject() == null) {
+                //update in application store.
+                appContext.appObject(appObject);
+                //Update app object for schema store for root interface.
+                appContext = yangSchemaStoreForRootInterface.get(name);
+                if (appContext != null) {
+                    appContext.appObject(appObject);
+                }
+                // Update app object for schema store for root op param
+                appContext = yangSchemaStoreForRootOpParam.get(name + OP_PARAM);
+                if (appContext != null) {
+                    appContext.appObject(appObject);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void unRegisterApplication(Object managerObject,
+                                      Class<?> serviceClass) {
+        YangSchemaNode curNode = null;
+        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.
+        if (appObjectStore.containsKey(serviceName)) {
+            curNode = retrieveNodeForUnregister(serviceName, appObjectStore,
+                                                managerObject);
+        } else if (yangSchemaStoreForRootInterface.containsKey(serviceName)) {
+            //check if service is in interface store.
+            curNode = retrieveNodeForUnregister(serviceName,
+                                                yangSchemaStoreForRootInterface,
+                                                managerObject);
+        } else if (yangSchemaStoreForRootOpParam.containsKey(serviceName)) {
+            //check if service is in op param store.
+            curNode = retrieveNodeForUnregister(serviceName,
+                                                yangSchemaStoreForRootOpParam,
+                                                managerObject);
+        }
+        if (curNode != null) {
+            String javaName = getInterfaceClassName(curNode);
+            removeFromYangSchemaStore(curNode);
+            removeFromYangNotificationStore(curNode);
+            removeFromAppSchemaStore(serviceName);
+            removeFromYangSchemaNodeForRootInterface(javaName);
+            removeFromYangSchemaNodeForRootOpParam(javaName);
+            removeYangFileInfoFromStore(curNode);
+            log.info(" service {} is unregistered.",
+                     serviceClass.getSimpleName());
+        } else {
+            throw new RuntimeException(serviceClass.getSimpleName() +
+                                               " service was not registered.");
+        }
+    }
+
+    @Override
+    public Object getRegisteredApplication(YangSchemaNode schemaNode) {
+        if (schemaNode != null) {
+            String name = getInterfaceClassName(schemaNode);
+            if (yangSchemaStoreForRootInterface.containsKey(name)) {
+                return yangSchemaStoreForRootInterface.get(name)
+                        .appObject();
+            }
+            log.error("{} not found.", name);
+        }
+        return null;
+    }
+
+    @Override
+    public YangSchemaNode getYangSchemaNodeUsingSchemaName(String schemaName) {
+        return getSchemaNodeUsingSchemaNameWithRev(schemaName);
+    }
+
+    @Override
+    public YangSchemaNode getYangSchemaNodeUsingAppName(String appName) {
+        YsrAppContext appContext = appObjectStore.get(appName);
+        if (appContext != null) {
+            return appContext.curNode();
+        }
+        log.error("{} not found.", appName);
+        return null;
+    }
+
+    @Override
+    public YangSchemaNode
+    getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(String name) {
+        YsrAppContext appContext = yangSchemaStoreForRootInterface.get(name);
+        if (appContext != null) {
+            return appContext.curNode();
+        }
+        log.error("{} not found.", name);
+        return null;
+    }
+
+    @Override
+    public YangSchemaNode getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+            String name) {
+        YsrAppContext appContext = yangSchemaStoreForRootOpParam.get(name);
+        if (appContext != null) {
+            return appContext.curNode();
+        }
+        log.error("{} not found.", name);
+        return null;
+    }
+
+    @Override
+    public YangSchemaNode getRootYangSchemaNodeForNotification(String name) {
+        YsrAppContext appContext = yangRootSchemaStoreForNotification.get(name);
+        if (appContext != null) {
+            return appContext.curNode();
+        }
+        log.error("{} not found.", name);
+        return null;
+    }
+
+    @Override
+    public Class<?> getRegisteredClass(YangSchemaNode schemaNode,
+                                       String appName) {
+        String interfaceName = getInterfaceClassName(schemaNode);
+        String serviceName = getServiceName(schemaNode);
+        String defaultClass;
+        if (schemaNode instanceof RpcNotificationContainer) {
+            defaultClass = getOpParamClassName(schemaNode);
+        } else {
+            defaultClass = getDefaultClassName(schemaNode);
+        }
+        //If application class is registered.
+        if (registerClassStore.containsKey(appName)) {
+            return registerClassStore.get(appName);
+        } else if (registerClassStore.containsKey(interfaceName)) {
+            //If interface class is registered.
+            return registerClassStore.get(interfaceName);
+        } else if (registerClassStore.containsKey(serviceName)) {
+            //If service class is registered.
+            return registerClassStore.get(serviceName);
+        } else if (registerClassStore.containsKey(defaultClass)) {
+            //If default class is registered.
+            return registerClassStore.get(defaultClass);
+        }
+        return null;
+    }
+
+    /**
+     * Returns YANG file path for module identifier.
+     *
+     * @param moduleIdentifier module identifier
+     * @return YANG file path for module identifier
+     */
+    public String getYangFile(YangModuleIdentifier moduleIdentifier) {
+        if (yangFileStore.containsKey(moduleIdentifier)) {
+            return yangFileStore.get(moduleIdentifier);
+        }
+        log.error("YANG files for corresponding module identifier {} not " +
+                          "found", moduleIdentifier);
+        return null;
+    }
+
+    /**
+     * Updates service class store.
+     *
+     * @param serviceClass service class
+     */
+    void updateServiceClass(Class<?> serviceClass) {
+        registerClassStore.put(serviceClass.getName(), serviceClass);
+    }
+
+    /**
+     * Updates application object store.
+     *
+     * @param appName application name
+     */
+    private void updateAppObjectStore(String appName) {
+        if (verifyClassExistence(appName)) {
+            appObjectStore.put(appName, ysrContextForAppStore);
+        }
+    }
+
+    /**
+     * Updates YANG schema object store.
+     *
+     * @param schemaNode application's schema node
+     */
+    private void updateYangSchemaStore(YangSchemaNode schemaNode) {
+        addSchemaNodeUsingSchemaNameWithRev(schemaNode);
+    }
+
+    /**
+     * Updates YANG schema notification object store.
+     *
+     * @param name application's notification name
+     */
+    private void updateYangNotificationStore(String name) {
+        if (verifyClassExistence(name)) {
+            yangRootSchemaStoreForNotification.put(name, ysrAppContext);
+        }
+    }
+
+    /**
+     * Updates YANG schema object store for root interface file name.
+     *
+     * @param name name of generated interface file for root
+     *             node
+     */
+    private void updateYangSchemaForRootInterfaceFileNameStore(String name) {
+        if (verifyClassExistence(name)) {
+            yangSchemaStoreForRootInterface.put(name, ysrAppContext);
+        }
+    }
+
+    /**
+     * Updates YANG schema object store  for root op param file name.
+     *
+     * @param name name of generated op param file for root node
+     */
+    private void updateYangSchemaForRootOpParamFileNameStore(String name) {
+        if (verifyClassExistence(name)) {
+            yangSchemaStoreForRootOpParam.put(name, ysrAppContext);
+        }
+    }
+
+    /**
+     * Updates yang file store for YANG node.
+     *
+     * @param node    YANG node
+     * @param jarPath jar file path
+     */
+    private void updateYangFileStore(YangNode node, String jarPath) {
+       //FIXME: fix when yang tools support for file name.
+       //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 jar file for fetching YANG nodes.
+     *
+     * @param path jar file path
+     * @return YANG schema nodes
+     */
+    private List<YangNode> processJarParsingOperations(String path) {
+        //Deserialize data model and get the YANG node set.
+        try {
+            return parseJarFile(path + JAR, path);
+        } catch (IOException e) {
+            log.error(" failed to parse the jar file in path {} : {} ", path,
+                      e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * Process an application an updates the maps for YANG schema registry.
+     *
+     * @param appNode application YANG schema nodes
+     */
+    void processApplicationContext(YangSchemaNode appNode) {
+
+        String appName = getInterfaceClassName(appNode);
+
+        //Create a new instance of ysr app context for each node.
+        ysrAppContext = new YsrAppContext();
+        ysrContextForSchemaStore = new YsrAppContext();
+        ysrContextForAppStore = new YsrAppContext();
+
+        //add cur node to app context.
+        ysrAppContext.curNode(appNode);
+        ysrContextForAppStore.curNode(appNode);
+
+        //Updates maps wih schema nodes.
+        updateAppObjectStore(getServiceName(appNode));
+
+        // Updates schema store.
+        updateYangSchemaStore(appNode);
+        // update interface store.
+        updateYangSchemaForRootInterfaceFileNameStore(appName);
+        //update op param store.
+        updateYangSchemaForRootOpParamFileNameStore(getOpParamClassName(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) {
+            updateYangNotificationStore(eventSubject);
+        }
+        log.info("successfully registered this application {}{}", appName,
+                 SERVICE);
+
+    }
+
+    /**
+     * 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;
+        String[] strArray = mvnLocationPath.split(MAVEN);
+        String[] split = strArray[1].split(File.separator);
+        String[] groupId = split[0].split(Pattern.quote(DELIMITER));
+
+        return path + groupId[0] + SLASH + groupId[1] + SLASH + split[1] +
+                SLASH + split[2] + SLASH + split[1] + HYPHEN + split[2];
+    }
+
+    /**
+     * Returns de-serializes YANG data-model nodes.
+     *
+     * @param serializedFileInfo serialized File Info
+     * @return de-serializes YANG data-model nodes
+     */
+    Set<YangSchemaNode> deSerializeDataModel(String serializedFileInfo) {
+
+        Set<YangSchemaNode> nodes = new HashSet<>();
+        Object readValue;
+        try {
+            FileInputStream fileInputStream =
+                    new FileInputStream(serializedFileInfo);
+            ObjectInputStream objectInputStream =
+                    new ObjectInputStream(fileInputStream);
+            readValue = objectInputStream.readObject();
+            if (readValue instanceof Set<?>) {
+                for (Object obj : (Set<?>) readValue) {
+                    if (obj instanceof YangSchemaNode) {
+                        nodes.add((YangSchemaNode) obj);
+                    } else {
+                        throw new RuntimeException(
+                                "deserialize object is not an instance of " +
+                                        "YANG schema node" + obj);
+                    }
+                }
+            } else {
+                throw new RuntimeException(
+                        "deserialize object is not an instance of set of" +
+                                "YANG schema node" + readValue);
+            }
+            objectInputStream.close();
+            fileInputStream.close();
+        } catch (IOException | ClassNotFoundException e) {
+            log.error(" {} not found.: {}", serializedFileInfo,
+                      e.getLocalizedMessage());
+        }
+
+        return nodes;
+    }
+
+    /**
+     * Returns ysr app context.
+     *
+     * @return ysr app context
+     */
+    YsrAppContext ysrAppContext() {
+        return ysrAppContext;
+    }
+
+    /**
+     * 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) {
+        YsrAppContext appContext;
+        YangSchemaNode schemaNode;
+        if (name.contains(AT)) {
+            String[] revArray = name.split(AT);
+            appContext = yangSchemaStore.get(revArray[0]);
+            schemaNode = appContext.getSchemaNodeForRevisionStore(name);
+            if (schemaNode != null) {
+                return schemaNode;
+            }
+            return appContext.curNode();
+        }
+        if (yangSchemaStore.containsKey(name)) {
+            appContext = yangSchemaStore.get(name);
+            if (appContext != null) {
+                Iterator<YangSchemaNode> iterator = appContext
+                        .getYangSchemaNodeForRevisionStore().values()
+                        .iterator();
+                if (iterator.hasNext()) {
+                    return appContext.getYangSchemaNodeForRevisionStore()
+                            .values().iterator().next();
+                } else {
+                    return null;
+                }
+            }
+        }
+        log.error("{} not found.", name);
+        return null;
+    }
+
+    /**
+     * Adds schema node when different revision of node has received.
+     *
+     * @param schemaNode schema node
+     */
+    private void addSchemaNodeUsingSchemaNameWithRev(
+            YangSchemaNode schemaNode) {
+
+        String date = getDateInStringFormat(schemaNode);
+        String name = schemaNode.getName();
+        if (!date.equals(EMPTY_STRING)) {
+            name = name + AT + date;
+        }
+        //check if already present.
+        if (!yangSchemaStore.containsKey(schemaNode.getName())) {
+            ysrContextForSchemaStore.curNode(schemaNode);
+            //if revision is not present no need to add in revision store.
+            ysrContextForSchemaStore
+                    .addSchemaNodeWithRevisionStore(name, schemaNode);
+            yangSchemaStore.put(schemaNode.getName(),
+                                ysrContextForSchemaStore);
+        } else {
+            YsrAppContext appContext =
+                    yangSchemaStore.get(schemaNode.getName());
+            appContext.addSchemaNodeWithRevisionStore(name, schemaNode);
+            appContext.curNode(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 EMPTY_STRING;
+    }
+
+    /**
+     * 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 date = getDateInStringFormat(removableNode);
+
+        if (!date.isEmpty()) {
+            name = removableNode.getName() + AT +
+                    getDateInStringFormat(removableNode);
+        }
+        YsrAppContext appContext = yangSchemaStore
+                .get(removableNode.getName());
+        if (appContext != null &&
+                !appContext.getYangSchemaNodeForRevisionStore().isEmpty() &&
+                appContext.getYangSchemaNodeForRevisionStore().size() != 1) {
+            appContext.removeSchemaNodeForRevisionStore(name);
+        } else {
+            yangSchemaStore.remove(removableNode.getName());
+        }
+    }
+
+    /**
+     * Verifies if the manager object is already registered with notification
+     * handler.
+     *
+     * @param serviceClass service class
+     * @return true if the manager object is already registered with
+     * notification handler
+     */
+    boolean verifyNotificationObject(Class<?> serviceClass) {
+        YangSchemaNode schemaNode = null;
+        String serviceName = serviceClass.getName();
+        if (appObjectStore.containsKey(serviceName)) {
+            schemaNode = getYangSchemaNodeUsingAppName(serviceName);
+        } else if (yangSchemaStoreForRootInterface.containsKey(serviceName)) {
+            schemaNode =
+                    getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+                            serviceName);
+        } else if (yangSchemaStoreForRootOpParam.containsKey(serviceName)) {
+            schemaNode = getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+                    serviceName);
+        }
+
+        if (schemaNode != null) {
+            String name = getEventClassName(schemaNode);
+
+            YsrAppContext appContext =
+                    yangRootSchemaStoreForNotification.get(name);
+            if (appContext != null && !appContext.isNotificationRegistered()) {
+                appContext.setNotificationRegistered(true);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns schema node's generated interface class name.
+     *
+     * @param schemaNode schema node
+     * @return schema node's generated interface class name
+     */
+    private 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 op param class name.
+     *
+     * @param schemaNode schema node
+     * @return schema node's generated op param class name
+     */
+    private String getDefaultClassName(YangSchemaNode schemaNode) {
+        return schemaNode.getJavaPackage() + PERIOD + getCapitalCase(DEFAULT) +
+                getCapitalCase(schemaNode.getJavaClassNameOrBuiltInType());
+    }
+
+    /**
+     * 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
+     */
+    private String getServiceName(YangSchemaNode schemaNode) {
+        return getInterfaceClassName(schemaNode) + SERVICE;
+    }
+
+    /**
+     * Returns YSR application context for schema map.
+     *
+     * @return YSR application context for schema map
+     */
+    YsrAppContext ysrContextForSchemaStore() {
+        return ysrContextForSchemaStore;
+    }
+
+    /**
+     * Sets YSR application context for schema map.
+     *
+     * @param context YSR application context for
+     *                schema map
+     */
+    void ysrContextForSchemaStore(YsrAppContext context) {
+        ysrContextForSchemaStore = context;
+    }
+
+    /**
+     * Returns YSR app context for application store.
+     *
+     * @return YSR app context for application store
+     */
+    YsrAppContext ysrContextForAppStore() {
+        return ysrContextForAppStore;
+    }
+
+    /**
+     * Retrieves schema node from the store and deletes jar file path.
+     *
+     * @param appName   application name
+     * @param store     YSR stores
+     * @param appObject applications object
+     * @return schema node from the store
+     */
+    private YangSchemaNode retrieveNodeForUnregister(
+            String appName,
+            ConcurrentMap<String, YsrAppContext> store, Object appObject) {
+
+        YsrAppContext curContext = store.get(appName);
+        boolean isValidObject;
+        if (curContext != null) {
+            isValidObject = verifyAppObject(appObject, curContext.appObject());
+            if (isValidObject) {
+                YangSchemaNode curNode = curContext.curNode();
+                //Delete all the generated ysr information in application's
+                // package.
+                removeYsrGeneratedTemporaryResources(curContext.jarPath(),
+                                                     appName);
+                return curNode;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Verifies the application object which needs to be unregistered.
+     *
+     * @param appObject current received application object
+     * @param context   stored application object
+     * @return true if objects are equal
+     */
+    private boolean verifyAppObject(Object appObject, Object context) {
+        if (appObject != null && context != null) {
+            return appObject.equals(context);
+        }
+        return appObject == null && context == null;
+    }
+
+    /**
+     * 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());
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes from YANG schema store.
+     *
+     * @param curNode schema node
+     */
+    private void removeFromYangSchemaStore(YangSchemaNode curNode) {
+        removeSchemaNode(curNode);
+    }
+
+    /**
+     * Removes from YANG schema  notification store.
+     *
+     * @param curNode schema node
+     */
+    private void removeFromYangNotificationStore(YangSchemaNode curNode) {
+        yangRootSchemaStoreForNotification
+                .remove(getEventClassName(curNode));
+    }
+
+    /**
+     * Removes from app store.
+     *
+     * @param appName application name
+     */
+    private void removeFromAppSchemaStore(String appName) {
+        appObjectStore.remove(appName);
+    }
+
+    /**
+     * Removes from interface store.
+     *
+     * @param appName application name
+     */
+    private void removeFromYangSchemaNodeForRootInterface(String appName) {
+        yangSchemaStoreForRootInterface.remove(appName);
+    }
+
+    /**
+     * Removes from op param store.
+     *
+     * @param appName application name
+     */
+    private void removeFromYangSchemaNodeForRootOpParam(String appName) {
+        yangSchemaStoreForRootOpParam.remove(appName + OP_PARAM);
+    }
+
+    /**
+     * Removes YANG file information from file store.
+     *
+     * @param schemaNode schema node
+     */
+    private void removeYangFileInfoFromStore(YangSchemaNode schemaNode) {
+        yangFileStore.remove(getModuleIdentifier(schemaNode));
+    }
+
+    /**
+     * Verifies if class with given name exists.
+     *
+     * @param appName application name
+     * @return true if class exists
+     */
+    boolean verifyClassExistence(String appName) {
+        try {
+            classLoader.loadClass(appName);
+            return true;
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Process notification registration for manager class object.
+     *
+     * @param yangService yang service
+     * @param yangManager yang manager
+     * @param ynhService  notification extended service
+     */
+    private void processNotificationRegistration(
+            Class<?> yangService, Object yangManager,
+            YangNotificationExtendedService ynhService) {
+
+        if (yangManager != null && yangManager instanceof ListenerService) {
+            if (verifyNotificationObject(yangService)) {
+                ynhService.registerAsListener(
+                        (ListenerService) yangManager);
+            }
+        }
+    }
+
+    /**
+     * Clears database for YSR.
+     */
+    public void flushYsrData() {
+        appObjectStore.clear();
+        yangSchemaStore.clear();
+        yangRootSchemaStoreForNotification.clear();
+        yangSchemaStoreForRootOpParam.clear();
+        yangSchemaStoreForRootInterface.clear();
+        registerClassStore.clear();
+        yangFileStore.clear();
+    }
+
+    /**
+     * Sets class loader of registered class.
+     *
+     * @param classLoader class loader of registered class
+     */
+    void setClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    /**
+     * Process module library for a registered service.
+     *
+     * @param node YANG schema nodes
+     */
+    private void processModuleLibrary(YangNode node) {
+        YangModuleInformation moduleInformation =
+                new DefaultYangModuleInformation(getModuleIdentifier(node),
+                                                 node.getNameSpace());
+        addSubModuleIdentifier(node, (
+                DefaultYangModuleInformation) moduleInformation);
+        //TODO: add feature list to module information.
+        ((DefaultYangModuleLibrary) library)
+                .addModuleInformation(moduleInformation);
+    }
+
+    /**
+     * 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 module library.
+     *
+     * @return module library
+     */
+    public YangModuleLibrary getLibrary() {
+        return library;
+    }
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YangSchemaRegistry.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YangSchemaRegistry.java
new file mode 100644
index 0000000..1812f04
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YangSchemaRegistry.java
@@ -0,0 +1,110 @@
+/*
+ * 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.YangSchemaNode;
+import org.onosproject.yms.app.ynh.YangNotificationExtendedService;
+
+/**
+ * Abstraction of entity which provides interfaces to YANG schema registry.
+ */
+public interface YangSchemaRegistry {
+
+    /**
+     * Registers applications to YMS.
+     *
+     * @param managerObject               application's object
+     * @param serviceClass                service class which needs to be
+     *                                    registered
+     * @param notificationExtendedService notification extended service to
+     *                                    register application object with YNH
+     */
+    void registerApplication(Object managerObject, Class<?> serviceClass,
+                             YangNotificationExtendedService
+                                     notificationExtendedService);
+
+    /**
+     * Unregisters applications to YMS.
+     *
+     * @param managerObject application's object
+     * @param serviceClass  service class which needs to be unregistered
+     */
+    void unRegisterApplication(Object managerObject, Class<?> serviceClass);
+
+    /**
+     * Returns application's implementation's class object.
+     *
+     * @param yangSchemaNode application's schema node
+     * @return application's implementation's class object
+     */
+    Object getRegisteredApplication(YangSchemaNode yangSchemaNode);
+
+    /**
+     * Returns YANG schema node using schema name.
+     *
+     * @param schemaName module name.
+     * @return YANG schema node using schema name
+     */
+    YangSchemaNode getYangSchemaNodeUsingSchemaName(String schemaName);
+
+    /**
+     * Returns YANG schema nodes using application name.
+     *
+     * @param appName application's service name
+     * @return YANG schema nodes using application name
+     */
+    YangSchemaNode getYangSchemaNodeUsingAppName(String appName);
+
+    /**
+     * Returns YANG schema nodes using root interface file name.
+     *
+     * @param rootInterfaceFileName name of generated interface file
+     *                              for root node
+     * @return YANG schema nodes using root interface file name
+     */
+    YangSchemaNode
+    getYangSchemaNodeUsingGeneratedRootNodeInterfaceFileName(
+            String rootInterfaceFileName);
+
+    /**
+     * Returns YANG schema nodes using root op param file name.
+     *
+     * @param rootOpParamFileName name of generated op param file for root node
+     * @return YANG schema nodes using root op param file name
+     */
+    YangSchemaNode
+    getYangSchemaNodeUsingGeneratedRootNodeOpPramFileName(
+            String rootOpParamFileName);
+
+    /**
+     * Returns YANG schema node of root for notifications.
+     *
+     * @param eventSubject event subject
+     * @return YANG schema node of root for notifications
+     */
+    YangSchemaNode getRootYangSchemaNodeForNotification(String eventSubject);
+
+    /**
+     * Returns registered service class.
+     *
+     * @param schemaNode YANG schema node
+     * @param appName    application's name
+     * @return registered service class
+     */
+    Class<?> getRegisteredClass(YangSchemaNode schemaNode, String appName);
+
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YsrAppContext.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YsrAppContext.java
new file mode 100644
index 0000000..4f076ab
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/YsrAppContext.java
@@ -0,0 +1,192 @@
+/*
+ * 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 com.google.common.collect.ImmutableMap;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * Represents registered application's context for YANG schema registry.
+ */
+public class YsrAppContext {
+
+    /**
+     * Current application's YANG schema node.
+     */
+    private YangSchemaNode curNode;
+
+    /**
+     * Current application's YANG schema node with different revision store.
+     */
+    private final ConcurrentMap<String, YangSchemaNode>
+            multiRevisionSchemaNodeStore;
+
+    /**
+     * Current application's object.
+     */
+    private Object appObject;
+
+    /**
+     * Jar file path.
+     */
+    private String jarPath;
+
+    /**
+     * If for current object notification is registered.
+     */
+    private boolean isNotificationRegistered;
+
+    /**
+     * Creates an instance of YANG schema registry application context.
+     */
+    YsrAppContext() {
+        multiRevisionSchemaNodeStore = new ConcurrentHashMap<>();
+    }
+
+    /**
+     * Returns current application's object.
+     *
+     * @return current application's object
+     */
+    Object appObject() {
+        return appObject;
+    }
+
+    /**
+     * Sets current application's object.
+     *
+     * @param appObject current application's object
+     */
+    void appObject(Object appObject) {
+        this.appObject = appObject;
+    }
+
+    /**
+     * Returns current application's YANG schema node.
+     *
+     * @return current application's YANG schema node
+     */
+    YangSchemaNode curNode() {
+        return curNode;
+    }
+
+    /**
+     * Sets current application's schema node.
+     *
+     * @param node current schema's node
+     */
+    void curNode(YangSchemaNode node) {
+        curNode = node;
+    }
+
+    /**
+     * Returns jar file path.
+     *
+     * @return jar file path
+     */
+    String jarPath() {
+        return jarPath;
+    }
+
+    /**
+     * Sets jar file path.
+     *
+     * @param jarPath jar file path
+     */
+    void jarPath(String jarPath) {
+        this.jarPath = jarPath;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(curNode, appObject);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof YsrAppContext) {
+            YsrAppContext that = (YsrAppContext) obj;
+            return Objects.equals(curNode, that.curNode) &&
+                    Objects.equals(appObject, that.appObject);
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if for application object notification is registered.
+     *
+     * @return true if for application object notification is registered
+     */
+    boolean isNotificationRegistered() {
+        return isNotificationRegistered;
+    }
+
+    /**
+     * Sets true if for application object notification is registered.
+     *
+     * @param notificationRegistered true if for application object notification is registered
+     */
+    void setNotificationRegistered(boolean notificationRegistered) {
+        isNotificationRegistered = notificationRegistered;
+    }
+
+    /**
+     * Returns YANG schema node store for specific revision.
+     *
+     * @return YANG schema node store for specific revision
+     */
+    Map<String, YangSchemaNode> getYangSchemaNodeForRevisionStore() {
+        return ImmutableMap.copyOf(multiRevisionSchemaNodeStore);
+    }
+
+    /**
+     * Returns a schema node for specific revision from store.
+     *
+     * @param nodeNameWithRevision schema node name for specific revision
+     * @return schema node for specific revision.
+     */
+    YangSchemaNode getSchemaNodeForRevisionStore(String nodeNameWithRevision) {
+        return multiRevisionSchemaNodeStore.get(nodeNameWithRevision);
+    }
+
+    /**
+     * Removes a schema node of specific revision from store.
+     *
+     * @param nodeNameWithRevision schema node name for specific revision
+     */
+    void removeSchemaNodeForRevisionStore(String nodeNameWithRevision) {
+        multiRevisionSchemaNodeStore.remove(nodeNameWithRevision);
+    }
+
+    /**
+     * Adds schema node with revision from store.
+     *
+     * @param nodeNameWithRevision schema node name for specific revision
+     * @param schemaNode           schema node for specific revision
+     */
+    void addSchemaNodeWithRevisionStore(String nodeNameWithRevision, YangSchemaNode schemaNode) {
+        multiRevisionSchemaNodeStore.put(nodeNameWithRevision, schemaNode);
+    }
+}
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/package-info.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/package-info.java
new file mode 100644
index 0000000..2b86091
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides implementation of YANG Schema Registry. YSR maintains the schema
+ * information registry corresponding to registered app.
+ */
+package org.onosproject.yms.app.ysr;