YAB and YOB defect fix

Change-Id: Ifed54236cfa83b4754383467818581bec59191d9
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/YangApplicationBroker.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/YangApplicationBroker.java
index cb6f7d7..aa76750 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/YangApplicationBroker.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yab/YangApplicationBroker.java
@@ -44,6 +44,7 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.yms.app.utils.TraversalType.CHILD;
@@ -67,6 +68,7 @@
     private static final String AUGMENTED = "Augmented";
     private static final String VOID = "void";
     private final YangSchemaRegistry schemaRegistry;
+    private Set<String> augGenMethodSet;
 
     /**
      * Creates a new YANG application broker.
@@ -88,11 +90,14 @@
             throws YabException {
         List<Object> responseObjects = new LinkedList<>();
         YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
+        augGenMethodSet = ((YangRequestWorkBench) ydtWorkBench).getAugGenMethodSet();
 
         for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
              appContext != null; appContext = appContext.getNextSibling()) {
             Object responseObject = processQueryOfApplication(appContext);
-            responseObjects.add(responseObject);
+            if (responseObject != null) {
+                responseObjects.add(responseObject);
+            }
         }
 
         YdtContext rootYdtContext = workBench.getRootNode();
@@ -116,7 +121,7 @@
     public YdtResponse processEdit(YdtBuilder ydtWorkBench)
             throws CloneNotSupportedException, YabException {
         YangRequestWorkBench workBench = (YangRequestWorkBench) ydtWorkBench;
-
+        augGenMethodSet = ((YangRequestWorkBench) ydtWorkBench).getAugGenMethodSet();
         for (YdtAppContext appContext = workBench.getAppRootNode().getFirstChild();
              appContext != null; appContext = appContext.getNextSibling()) {
             processEditOfApplication(appContext);
@@ -229,10 +234,13 @@
                 String methodName = getApplicationMethodName(appContext,
                                                              appName, GET);
 
+                String moduleName = appContext.getAppData()
+                        .getRootSchemaNode().getName();
+
                 // invoke application's getter method
                 outputObject = invokeApplicationsMethod(appManagerObject,
                                                         outputObject,
-                                                        methodName);
+                                                        methodName, moduleName);
             }
 
             /*
@@ -293,9 +301,12 @@
                     String methodName = getApplicationMethodName(appContext,
                                                                  appName, SET);
 
+                    String moduleName = appContext.getAppData()
+                            .getRootSchemaNode().getName();
+
                     // invoke application's setter method
                     invokeApplicationsMethod(appManagerObject, outputObject,
-                                             methodName);
+                                             methodName, moduleName);
                 }
 
                 /*
@@ -366,8 +377,12 @@
                 String methodName = getApplicationMethodName(appContext,
                                                              appName, SET);
 
+                String moduleName = appContext.getAppData().getRootSchemaNode()
+                        .getName();
+
                 // invoke application's setter method
-                invokeApplicationsMethod(appManagerObject, inputObject, methodName);
+                invokeApplicationsMethod(appManagerObject, inputObject,
+                                         methodName, moduleName);
 
                 if (appContext.getPreviousSibling() != null) {
                     curTraversal = SIBLING;
@@ -614,7 +629,8 @@
                 .getAugmentedInfoList()) {
             Object appManagerObject = schemaRegistry
                     .getRegisteredApplication(yangAugment.getParent());
-            if (appManagerObject != null) {
+            if (appManagerObject != null
+                    && augGenMethodSet.add(yangAugment.getSetterMethodName())) {
                 childAppContext = addChildToYdtAppTree(curAppContext,
                                                        yangAugment);
                 processAugmentForChildNode(childAppContext, yangAugment);
@@ -788,7 +804,8 @@
      */
     private Object invokeApplicationsMethod(Object appManagerObject,
                                             Object inputObject,
-                                            String methodName) throws YabException {
+                                            String methodName, String appName)
+            throws YabException {
         checkNotNull(appManagerObject);
         Class<?> appClass = appManagerObject.getClass();
         try {
@@ -798,9 +815,11 @@
                 return methodObject.invoke(appManagerObject, inputObject);
             }
             throw new YabException("No such method in application");
-        } catch (IllegalAccessException | NoSuchMethodException |
-                InvocationTargetException e) {
+        } catch (IllegalAccessException | NoSuchMethodException e) {
             throw new YabException(e);
+        } catch (InvocationTargetException e) {
+            throw new YabException("Invocation exception in service " + appName,
+                                   e.getCause());
         }
     }
 
@@ -869,4 +888,13 @@
             throw new YabException(e);
         }
     }
+
+    /**
+     * Sets the augment setter method name.
+     *
+     * @param augGenMethodSet augment setter method name
+     */
+    public void setAugGenMethodSet(Set<String> augGenMethodSet) {
+        this.augGenMethodSet = augGenMethodSet;
+    }
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java
index 6df0724..03af131 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobBuilderOrBuiltObject.java
@@ -20,6 +20,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.onosproject.yms.app.yob.YobConstants.E_BUILDER_IS_NOT_ALREADY_SET;
 import static org.onosproject.yms.app.yob.YobConstants.E_BUILDER_IS_NOT_SET;
 import static org.onosproject.yms.app.yob.YobConstants.E_BUILT_OBJ_IS_NOT_SET;
 import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_CREATE_OBJ;
@@ -27,6 +28,7 @@
 import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_BUILDING_WITHOUT_BUILDER;
 import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_IS_ALREADY_BUILT_NOT_BUILD;
 import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_IS_ALREADY_BUILT_NOT_FETCH;
+import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_IS_ALREADY_BUILT_NOT_SET;
 import static org.onosproject.yms.app.yob.YobConstants.E_OBJ_IS_NOT_SET_NOT_FETCH;
 import static org.onosproject.yms.app.yob.YobConstants.E_REFLECTION_FAIL_TO_CREATE_OBJ;
 import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_CREATE_OBJ;
@@ -73,7 +75,7 @@
             yangDefaultClass =
                     registeredAppClassLoader.loadClass(qualifiedClassName);
             yangBuilderClass = yangDefaultClass.getDeclaredClasses()[0];
-            builderOrBuiltObject = yangBuilderClass.newInstance();
+            setBuilderObject(yangBuilderClass.newInstance());
         } catch (ClassNotFoundException e) {
             log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
             throw new YobException(E_FAIL_TO_LOAD_CLASS + qualifiedClassName);
@@ -91,8 +93,7 @@
      * Returns the builder object if it is set.
      *
      * @return builder object
-     * @throws YobException if builder object is not available or if it is
-     *                      already built
+     * @throws YobException if builder is not available
      */
     Object getBuilderObject() {
         if (isBuilt) {
@@ -107,6 +108,25 @@
     }
 
     /**
+     * Check if the builder object is being initialized for the first time and
+     * set it.
+     *
+     * @param builderObject new builder object
+     * @throws YobException if built object is not available
+     */
+    private void setBuilderObject(Object builderObject) {
+        if (isBuilt) {
+            throw new YobException(E_OBJ_IS_ALREADY_BUILT_NOT_SET);
+        }
+
+        if (builderOrBuiltObject != null) {
+            throw new YobException(E_BUILDER_IS_NOT_ALREADY_SET);
+        }
+
+        builderOrBuiltObject = builderObject;
+    }
+
+    /**
      * Returns the built object.
      *
      * @return built object
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java
index 6ed14267..cf2638e 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobConstants.java
@@ -30,12 +30,16 @@
     static final String DEFAULT = "Default";
     static final String ADD_TO = "addTo";
     static final String VALUE_OF = "valueOf";
-    static final String OPERATION_TYPE = "onosYangNodeOperationType";
-    static final String OP_TYPE = "OnosYangNodeOperationType";
+    static final String OP_TYPE = "OpType";
+    static final String ONOS_YANG_OP_TYPE = "OnosYangOpType";
     static final String OF = "of";
     static final String PERIOD = ".";
     static final String SPACE = " ";
     static final String ADD_AUGMENT_METHOD = "addYangAugmentedInfo";
+    static final String YANG = "yang";
+    static final String JAVA_LANG = "java.lang";
+    static final String LEAF_IDENTIFIER = "LeafIdentifier";
+    static final String SELECT_LEAF = "selectLeaf";
 
     //Error strings
     static final String E_NO_HANDLE_FOR_YDT = "No handler for YDT node";
@@ -78,6 +82,10 @@
             "Builder is not yet set, cannot fetch it";
     static final String E_BUILT_OBJ_IS_NOT_SET =
             "Built object is not set";
+    static final String E_OBJ_IS_ALREADY_BUILT_NOT_SET =
+            "Object is already built, cannot set builder";
+    static final String E_BUILDER_IS_NOT_ALREADY_SET =
+            "Builder is not already set";
     static final String E_OBJ_IS_NOT_SET_NOT_FETCH =
             "Builder is not yet set, cannot fetch it";
     static final String E_OBJ_IS_ALREADY_BUILT_NOT_BUILD =
@@ -88,4 +96,6 @@
             "YANG data tree is missing the data required for YOB";
     static final String E_INVALID_DATA_TREE =
             "YANG tree does not have a application root";
+    static final String E_INVALID_EMPTY_DATA =
+            "Value for empty data type is invalid";
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
index abb6248..28527ea 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandler.java
@@ -47,6 +47,9 @@
                               YangSchemaRegistry registry) {
         String setterName = null;
         YangSchemaNode node = curNode.getYangSchemaNode();
+        while (node.getReferredSchema() != null) {
+            node = node.getReferredSchema();
+        }
 
         String qualName = getQualifiedDefaultClass(node);
         ClassLoader classLoader = YobUtils.getClassLoader(registry, qualName,
@@ -56,7 +59,7 @@
             setterName = node.getJavaAttributeName();
         }
 
-        Object workBench = new YobWorkBench(node, classLoader, qualName,
+        Object workBench = new YobWorkBench(curNode.getYangSchemaNode(), classLoader, qualName,
                                             setterName);
 
         curNode.addAppInfo(YOB, workBench);
@@ -71,8 +74,9 @@
      */
     public void setInParent(YdtExtendedContext ydtNode,
                             YangSchemaRegistry schemaRegistry) {
-        YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
-        yobWorkBench.setObjectInParent(ydtNode);
+        YdtExtendedContext parentNode = (YdtExtendedContext) ydtNode.getParent();
+        YobWorkBench parentWorkbench = (YobWorkBench) parentNode.getAppInfo(YOB);
+        parentWorkbench.setObject(ydtNode, schemaRegistry);
     }
 
     /**
@@ -88,6 +92,6 @@
                             YdtExtendedContext ydtRootNode,
                             YangSchemaRegistry schemaRegistry) {
         YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
-        yobWorkBench.buildObject(ydtNode);
+        yobWorkBench.buildObject(ydtNode.getYdtContextOperationType(), schemaRegistry);
     }
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java
index c59725a..6d97841 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobMultiInstanceLeafHandler.java
@@ -33,6 +33,7 @@
 import java.lang.reflect.ParameterizedType;
 import java.util.Set;
 
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.IDENTITYREF;
 import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
 import static org.onosproject.yms.app.ydt.AppType.YOB;
 import static org.onosproject.yms.app.yob.YobConstants.ADD_TO;
@@ -74,6 +75,10 @@
                             YangSchemaRegistry schemaRegistry) {
         Class<?> parentBuilderClass = null;
         YangSchemaNode yangSchemaNode = leafListNode.getYangSchemaNode();
+        while (yangSchemaNode.getReferredSchema() != null) {
+            yangSchemaNode = yangSchemaNode.getReferredSchema();
+        }
+
         YdtExtendedContext parentYdtNode =
                 (YdtExtendedContext) leafListNode.getParent();
         YobWorkBench parentYobWorkBench =
@@ -90,17 +95,25 @@
                         .getDeclaredField(setterInParent);
                 ParameterizedType genericListType =
                         (ParameterizedType) leafName.getGenericType();
-                Class<?> genericListClass =
-                        (Class<?>) genericListType.getActualTypeArguments()[0];
-                Method setterMethod =
-                        parentBuilderClass.getDeclaredMethod(
-                                ADD_TO + getCapitalCase(setterInParent),
-                                genericListClass);
+                Class<?> genericListClass;
+                if (((YangLeafList) leafListNode.getYangSchemaNode())
+                        .getDataType().getDataType() == IDENTITYREF) {
+                    ParameterizedType type = (ParameterizedType)
+                            genericListType.getActualTypeArguments()[0];
+                    genericListClass = type.getClass().getClass();
+                } else {
+                    genericListClass = (Class<?>) genericListType.getActualTypeArguments()[0];
+                }
+
+                Method setterMethod = parentBuilderClass.getDeclaredMethod(
+                        ADD_TO + getCapitalCase(setterInParent), genericListClass);
+
                 JavaQualifiedTypeInfoContainer javaQualifiedType =
                         (JavaQualifiedTypeInfoContainer) yangSchemaNode;
                 YangType<?> yangType =
                         ((YangLeafList) javaQualifiedType).getDataType();
-                YobUtils.setDataFromStringValue(yangType, value, setterMethod,
+                YobUtils.setDataFromStringValue(yangType.getDataType(), value,
+                                                setterMethod,
                                                 builderObject, leafListNode);
             } catch (NoSuchMethodException | InvocationTargetException
                     | IllegalAccessException | NoSuchFieldException e) {
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java
index 6840684..4d8736b 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobSingleInstanceLeafHandler.java
@@ -19,6 +19,7 @@
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
 import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
@@ -69,6 +70,10 @@
 
         try {
             YangSchemaNode schemaNode = leafNode.getYangSchemaNode();
+            while (schemaNode.getReferredSchema() != null) {
+                schemaNode = schemaNode.getReferredSchema();
+            }
+
             String setterInParent = schemaNode.getJavaAttributeName();
             YdtExtendedContext parentNode =
                     (YdtExtendedContext) leafNode.getParent();
@@ -76,13 +81,20 @@
             Object builderObject = workBench
                     .getParentBuilder(leafNode, schemaRegistry);
             builderClass = builderObject.getClass();
-            Field leafName = builderClass.getDeclaredField(setterInParent);
-            Method setterMethod = builderClass
-                    .getDeclaredMethod(setterInParent, leafName.getType());
-            YangType<?> yangType = ((YangLeaf) schemaNode).getDataType();
-            YobUtils.setDataFromStringValue(yangType, leafNode.getValue(),
-                                            setterMethod, builderObject,
-                                            leafNode);
+            if (leafNode.getValue() != null || ((YangLeaf) schemaNode)
+                    .getDataType().getDataType() == YangDataTypes.EMPTY) {
+                Field leafName = builderClass.getDeclaredField(setterInParent);
+                Method setterMethod = builderClass
+                        .getDeclaredMethod(setterInParent, leafName.getType());
+                YangType<?> yangType = ((YangLeaf) schemaNode).getDataType();
+                YobUtils.setDataFromStringValue(yangType.getDataType(), leafNode
+                                                        .getValue(),
+                                                setterMethod, builderObject,
+                                                leafNode);
+            } else {
+                YobUtils.setSelectLeaf(builderClass, leafNode,
+                                       schemaRegistry, builderObject);
+            }
         } catch (NoSuchMethodException | InvocationTargetException |
                 IllegalAccessException | NoSuchFieldException e) {
             log.error(L_FAIL_TO_INVOKE_METHOD, builderClass.getName());
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java
index c8256c9..c4cbfc5 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java
@@ -17,14 +17,17 @@
 package org.onosproject.yms.app.yob;
 
 import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
-import org.onosproject.yangutils.datamodel.YangBit;
-import org.onosproject.yangutils.datamodel.YangBits;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
+import org.onosproject.yangutils.datamodel.YangIdentity;
+import org.onosproject.yangutils.datamodel.YangIdentityRef;
 import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafList;
 import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
 import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
 import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
@@ -37,22 +40,23 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Base64;
-import java.util.BitSet;
-import java.util.Map;
 
 import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
-import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
 import static org.onosproject.yms.app.ydt.AppType.YOB;
 import static org.onosproject.yms.app.yob.YobConstants.DEFAULT;
 import static org.onosproject.yms.app.yob.YobConstants.E_DATA_TYPE_NOT_SUPPORT;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_LOAD_CLASS;
 import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_LOAD_CONSTRUCTOR;
 import static org.onosproject.yms.app.yob.YobConstants.E_INVALID_DATA_TREE;
+import static org.onosproject.yms.app.yob.YobConstants.E_INVALID_EMPTY_DATA;
 import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
+import static org.onosproject.yms.app.yob.YobConstants.LEAF_IDENTIFIER;
 import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_LOAD_CLASS;
 import static org.onosproject.yms.app.yob.YobConstants.OF;
 import static org.onosproject.yms.app.yob.YobConstants.OP_PARAM;
 import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
-import static org.onosproject.yms.app.yob.YobConstants.SPACE;
+import static org.onosproject.yms.app.yob.YobConstants.SELECT_LEAF;
+import static org.onosproject.yms.app.yob.YobConstants.VALUE_OF;
 
 /**
  * Utils to support object creation.
@@ -82,13 +86,13 @@
      * @throws IllegalAccessException    if member cannot be accessed
      * @throws NoSuchMethodException     if method is not found
      */
-    static void setDataFromStringValue(YangType<?> type, String leafValue,
+    static void setDataFromStringValue(YangDataTypes type, String leafValue,
                                        Method parentSetterMethod,
                                        Object parentBuilderObject,
                                        YdtExtendedContext ydtExtendedContext)
             throws InvocationTargetException, IllegalAccessException,
             NoSuchMethodException {
-        switch (type.getDataType()) {
+        switch (type) {
             case INT8:
                 parentSetterMethod.invoke(parentBuilderObject,
                                           Byte.parseByte(leafValue));
@@ -118,6 +122,13 @@
                 break;
 
             case EMPTY:
+                if (leafValue == null || leafValue.equals("")) {
+                    parentSetterMethod.invoke(parentBuilderObject, true);
+                } else {
+                    log.info(E_INVALID_EMPTY_DATA);
+                }
+                break;
+
             case BOOLEAN:
                 parentSetterMethod.invoke(parentBuilderObject,
                                           Boolean.parseBoolean(leafValue));
@@ -133,10 +144,8 @@
                 break;
 
             case BITS:
-                YangBits yangBits = (YangBits) type.getDataTypeExtendedInfo();
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          getBitSetValueFromString(yangBits,
-                                                                   leafValue));
+                parseBitSetTypeInfo(ydtExtendedContext, parentSetterMethod,
+                                    parentBuilderObject, leafValue);
                 break;
 
             case DECIMAL64:
@@ -149,6 +158,11 @@
                                      parentBuilderObject, leafValue, false);
                 break;
 
+            case IDENTITYREF:
+                parseIdentityRefInfo(ydtExtendedContext, parentSetterMethod,
+                                     parentBuilderObject, leafValue);
+                break;
+
             case UNION:
                 parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
                                      parentBuilderObject, leafValue, false);
@@ -170,20 +184,72 @@
     }
 
     /**
+     * Sets the select leaf flag for leaf.
+     *
+     * @param builderClass   builder in which the select leaf flag needs to be
+     *                       set
+     * @param leafNode       YANG data tree leaf node
+     * @param schemaRegistry YANG schema registry
+     * @param builderObject  the parent build object on which to invoke
+     *                       the method
+     * @throws InvocationTargetException if method could not be invoked
+     * @throws IllegalAccessException    if method could not be accessed
+     * @throws NoSuchMethodException     if method does not exist
+     */
+    static void setSelectLeaf(Class builderClass,
+                              YdtExtendedContext leafNode,
+                              YangSchemaRegistry schemaRegistry,
+                              Object builderObject) throws NoSuchMethodException,
+            InvocationTargetException, IllegalAccessException {
+
+        YangSchemaNode parentSchema = ((YdtExtendedContext) leafNode
+                .getParent()).getYangSchemaNode();
+        while (parentSchema.getReferredSchema() != null) {
+            parentSchema = parentSchema.getReferredSchema();
+        }
+
+        while (((YangNode) parentSchema).getParent() != null) {
+            parentSchema = ((YangNode) parentSchema).getParent();
+        }
+
+        String qualName = getQualifiedinterface(parentSchema);
+        Class<?> regClass = schemaRegistry.getRegisteredClass(parentSchema);
+        if (regClass == null) {
+            throw new YobException(E_FAIL_TO_LOAD_CLASS + qualName);
+        }
+
+        Class<?> interfaceClass = null;
+        try {
+            interfaceClass = regClass.getClassLoader().loadClass(qualName);
+        } catch (ClassNotFoundException e) {
+            log.info(E_FAIL_TO_LOAD_CLASS, qualName);
+        }
+
+        Class<?>[] innerClasses = interfaceClass.getClasses();
+        for (Class<?> innerEnumClass : innerClasses) {
+            if (innerEnumClass.getSimpleName().equals(LEAF_IDENTIFIER)) {
+                Method valueOfMethod = innerEnumClass
+                        .getDeclaredMethod(VALUE_OF, String.class);
+                String leafName = leafNode.getYangSchemaNode()
+                        .getJavaAttributeName().toUpperCase();
+                Object obj = valueOfMethod.invoke(null, leafName);
+                Method selectLeafMethod = builderClass
+                        .getDeclaredMethod(SELECT_LEAF, innerEnumClass);
+                selectLeafMethod.invoke(builderObject, obj);
+                break;
+            }
+        }
+    }
+
+    /**
      * To set data into parent setter method from string value for derived type.
      *
-     * @param leafValue           leafValue argument is used to set the value
-     *                            in method
-     * @param parentSetterMethod  Invokes the underlying method represented
-     *                            by this parentSetterMethod
-     * @param parentBuilderObject the parentBuilderObject is to invoke the
-     *                            underlying method
-     * @param ydtExtendedContext  ydtExtendedContext is used to get
-     *                            application related
-     *                            information maintained in YDT
-     * @param isEnum              isEnum parameter is used to check whether
-     *                            type is enum or derived
-     *                            information maintained in YDT
+     * @param leafValue           value to be set in method
+     * @param parentSetterMethod  the parent setter method to be invoked
+     * @param parentBuilderObject the parent build object on which to invoke the
+     *                            method
+     * @param ydtExtendedContext  application context
+     * @param isEnum              flag to check whether type is enum or derived
      * @throws InvocationTargetException if failed to invoke method
      * @throws IllegalAccessException    if member cannot be accessed
      * @throws NoSuchMethodException     if the required method is not found
@@ -201,6 +267,10 @@
         Method childMethod = null;
 
         YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
+        while (yangJavaModule.getReferredSchema() != null) {
+            yangJavaModule = yangJavaModule.getReferredSchema();
+        }
+
         String qualifiedClassName = yangJavaModule.getJavaPackage() + PERIOD +
                 getCapitalCase(yangJavaModule.getJavaClassNameOrBuiltInType());
         ClassLoader classLoader = getClassLoader(null, qualifiedClassName,
@@ -210,8 +280,8 @@
         } catch (ClassNotFoundException e) {
             log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
         }
-        if (!isEnum) {
 
+        if (!isEnum) {
             if (childSetClass != null) {
                 childConstructor = childSetClass.getDeclaredConstructor();
             }
@@ -219,6 +289,7 @@
             if (childConstructor != null) {
                 childConstructor.setAccessible(true);
             }
+
             try {
                 if (childConstructor != null) {
                     childObject = childConstructor.newInstance();
@@ -234,8 +305,59 @@
             if (childSetClass != null) {
                 childMethod = childSetClass.getDeclaredMethod(OF, String.class);
             }
-            //leafValue = JavaIdentifierSyntax.getEnumJavaAttribute(leafValue);
-            //leafValue = leafValue.toUpperCase();
+        }
+        if (childMethod != null) {
+            childValue = childMethod.invoke(childObject, leafValue);
+        }
+
+        parentSetterMethod.invoke(parentBuilderObject, childValue);
+    }
+
+    /**
+     * To set data into parent setter method from string value for bits type.
+     *
+     * @param leafValue           value to be set in method
+     * @param parentSetterMethod  the parent setter method to be invoked
+     * @param parentBuilderObject the parent build object on which to invoke the
+     *                            method
+     * @param ydtExtendedContext  application context
+     * @throws InvocationTargetException if failed to invoke method
+     * @throws IllegalAccessException    if member cannot be accessed
+     * @throws NoSuchMethodException     if the required method is not found
+     */
+    private static void parseBitSetTypeInfo(YdtExtendedContext ydtExtendedContext,
+                                            Method parentSetterMethod,
+                                            Object parentBuilderObject,
+                                            String leafValue)
+            throws InvocationTargetException, IllegalAccessException,
+            NoSuchMethodException {
+        Class<?> childSetClass = null;
+        Object childValue = null;
+        Object childObject = null;
+        Method childMethod = null;
+
+        YangSchemaNode schemaNode = ydtExtendedContext.getYangSchemaNode();
+        while (schemaNode.getReferredSchema() != null) {
+            schemaNode = schemaNode.getReferredSchema();
+        }
+
+        YangSchemaNode parentSchema = ((YdtExtendedContext) ydtExtendedContext
+                .getParent()).getYangSchemaNode();
+        String qualifiedClassName = parentSchema.getJavaPackage() + PERIOD +
+                parentSchema.getJavaAttributeName().toLowerCase() +
+                PERIOD + getCapitalCase(schemaNode.getJavaAttributeName());
+
+        ClassLoader classLoader = getClassLoader(null, qualifiedClassName,
+                                                 ydtExtendedContext, null);
+
+        try {
+            childSetClass = classLoader.loadClass(qualifiedClassName);
+        } catch (ClassNotFoundException e) {
+            log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
+        }
+
+        if (childSetClass != null) {
+            childMethod = childSetClass.getDeclaredMethod(FROM_STRING, String.class);
         }
         if (childMethod != null) {
             childValue = childMethod.invoke(childObject, leafValue);
@@ -262,12 +384,42 @@
                                              String leafValue)
             throws InvocationTargetException, IllegalAccessException,
             NoSuchMethodException {
+
         YangSchemaNode schemaNode = ydtExtendedContext.getYangSchemaNode();
-        YangLeafRef leafRef = (YangLeafRef) ((YangLeaf) schemaNode)
-                .getDataType().getDataTypeExtendedInfo();
-        YobUtils.setDataFromStringValue(leafRef.getEffectiveDataType(),
-                                        leafValue, parentSetterMethod,
-                                        parentBuilderObject, ydtExtendedContext);
+        while (schemaNode.getReferredSchema() != null) {
+            schemaNode = schemaNode.getReferredSchema();
+        }
+
+        YangLeafRef leafRef;
+        if (schemaNode instanceof YangLeaf) {
+            leafRef = (YangLeafRef) ((YangLeaf) schemaNode)
+                    .getDataType().getDataTypeExtendedInfo();
+        } else {
+            leafRef = (YangLeafRef) ((YangLeafList) schemaNode)
+                    .getDataType().getDataTypeExtendedInfo();
+        }
+
+        YangType type = leafRef.getEffectiveDataType();
+        if (type.getDataType() == YangDataTypes.DERIVED &&
+                schemaNode.getJavaPackage().equals(YobConstants.JAVA_LANG)) {
+            /*
+             * If leaf is inside grouping, then its return type will be of type
+             * Object and if its actual type is derived type then get the
+             * effective built-in type and set the value.
+             */
+            YangDerivedInfo derivedInfo = (YangDerivedInfo) leafRef
+                    .getEffectiveDataType()
+                    .getDataTypeExtendedInfo();
+            YobUtils.setDataFromStringValue(derivedInfo.getEffectiveBuiltInType(),
+                                            leafValue, parentSetterMethod,
+                                            parentBuilderObject,
+                                            ydtExtendedContext);
+        } else {
+            YobUtils.setDataFromStringValue(type.getDataType(),
+                                            leafValue, parentSetterMethod,
+                                            parentBuilderObject,
+                                            ydtExtendedContext);
+        }
     }
 
     /**
@@ -278,12 +430,12 @@
      * @param curNode            YDT context
      * @param rootNode           application root node
      * @return current class loader
-     * @throws YobException if the YDT is an invalid tree
      */
     static ClassLoader getClassLoader(YangSchemaRegistry registry,
                                       String qualifiedClassName,
                                       YdtExtendedContext curNode,
                                       YdtExtendedContext rootNode) {
+
         if (rootNode != null && curNode == rootNode) {
             YangSchemaNode curSchemaNode = curNode.getYangSchemaNode();
             while (!(curSchemaNode instanceof RpcNotificationContainer)) {
@@ -292,21 +444,16 @@
                     throw new YobException(E_INVALID_DATA_TREE);
                 }
                 curSchemaNode = curNode.getYangSchemaNode();
-
             }
 
-            Class<?> regClass = registry.getRegisteredClass(curSchemaNode
-            );
+            Class<?> regClass = registry.getRegisteredClass(curSchemaNode);
             return regClass.getClassLoader();
-
         }
 
-        YdtExtendedContext parent =
-                (YdtExtendedContext) curNode.getParent();
-        YobWorkBench parentBuilderContainer =
-                (YobWorkBench) parent.getAppInfo(YOB);
-        Object parentObj =
-                parentBuilderContainer.getParentBuilder(curNode, registry);
+        YdtExtendedContext parent = (YdtExtendedContext) curNode.getParent();
+        YobWorkBench parentBuilderContainer = (YobWorkBench) parent.getAppInfo(YOB);
+        Object parentObj = parentBuilderContainer.getParentBuilder(curNode,
+                                                                   registry);
         return parentObj.getClass().getClassLoader();
     }
 
@@ -318,24 +465,58 @@
      * @param registry  schema registry
      * @return class loader to be used for the switched context schema node
      */
-    static ClassLoader getTargetClassLoader(
-            ClassLoader curLoader,
-            YangSchemaNodeContextInfo context,
-            YangSchemaRegistry registry) {
+    static ClassLoader getTargetClassLoader(ClassLoader curLoader,
+                                            YangSchemaNodeContextInfo context,
+                                            YangSchemaRegistry registry) {
         YangSchemaNode augmentSchemaNode = context.getContextSwitchedNode();
         if (augmentSchemaNode.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
-            YangSchemaNode moduleNode =
-                    ((YangNode) augmentSchemaNode).getParent();
+            YangSchemaNode moduleNode = ((YangNode) augmentSchemaNode).getParent();
 
-            Class<?> moduleClass = registry.getRegisteredClass(
-                    moduleNode);
+            Class<?> moduleClass = registry.getRegisteredClass(moduleNode);
+            if (moduleClass == null) {
+                throw new YobException(E_FAIL_TO_LOAD_CLASS + moduleNode
+                        .getJavaClassNameOrBuiltInType());
+            }
             return moduleClass.getClassLoader();
         }
-
         return curLoader;
     }
 
     /**
+     * Returns the schema node's module interface.
+     *
+     * @param schemaNode     YANG schema node
+     * @param schemaRegistry YANG schema registry
+     * @return schema node's module interface
+     */
+    public static Class<?> getModuleInterface(YangSchemaNode schemaNode,
+                                              YangSchemaRegistry schemaRegistry) {
+
+        YangNode yangNode = (YangNode) schemaNode;
+        while (yangNode.getReferredSchema() != null) {
+            yangNode = (YangNode) yangNode.getReferredSchema();
+        }
+
+        while (yangNode.getParent() != null) {
+            yangNode = yangNode.getParent();
+        }
+
+        String qualName = getQualifiedinterface(yangNode);
+        Class<?> regClass = schemaRegistry.getRegisteredClass(yangNode);
+        if (regClass == null) {
+            throw new YobException(E_FAIL_TO_LOAD_CLASS + qualName);
+        }
+
+        try {
+            return regClass.getClassLoader().loadClass(qualName);
+        } catch (ClassNotFoundException e) {
+            log.error(L_FAIL_TO_LOAD_CLASS, qualName);
+        }
+
+        return null;
+    }
+
+    /**
      * Returns the qualified default / op param class.
      *
      * @param schemaNode schema node of the required class
@@ -368,26 +549,86 @@
     }
 
     /**
-     * Returns BitSet value from string.
+     * Returns the capital cased first letter of the given string.
      *
-     * @param yangBits  schema node of the YANG bits
-     * @param leafValue leaf value from RESTCONF
-     * @return BitSet value
+     * @param name string to be capital cased
+     * @return capital cased string
      */
-    private static BitSet getBitSetValueFromString(YangBits yangBits,
-                                                   String leafValue) {
-        String[] bitNames = leafValue.trim().split(SPACE);
-        Map<String, YangBit> bitNameMap = yangBits.getBitNameMap();
-        BitSet bitDataSet = new BitSet();
-        YangBit bit;
-        for (String bitName : bitNames) {
-            bit = bitNameMap.get(bitName);
-            if (bit == null) {
-                throw new YobException("Unable to find corresponding bit" +
-                                               " position for bit : " + bitName);
-            }
-            bitDataSet.set(bit.getPosition());
+    public static String getCapitalCase(String name) {
+        // TODO: It will be removed if common util is committed.
+        return name.substring(0, 1).toUpperCase() +
+                name.substring(1);
+    }
+
+    /**
+     * To set data into parent setter method from string value for identity ref.
+     *
+     * @param leafValue           leaf value to be set
+     * @param parentSetterMethod  the parent setter method to be invoked
+     * @param parentBuilderObject the parent build object on which to invoke
+     *                            the method
+     * @param ydtExtendedContext  application context
+     * @throws InvocationTargetException if method could not be invoked
+     * @throws IllegalAccessException    if method could not be accessed
+     * @throws NoSuchMethodException     if method does not exist
+     */
+    private static void parseIdentityRefInfo(YdtExtendedContext
+                                                     ydtExtendedContext,
+                                             Method parentSetterMethod,
+                                             Object parentBuilderObject,
+                                             String leafValue)
+            throws InvocationTargetException, IllegalAccessException,
+            NoSuchMethodException {
+        Class<?> childSetClass = null;
+        Object childValue = null;
+        Method childMethod = null;
+
+        YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
+        while (yangJavaModule.getReferredSchema() != null) {
+            yangJavaModule = yangJavaModule.getReferredSchema();
         }
-        return bitDataSet;
+
+        String qualifiedClassName = null;
+        YangType type;
+        if (yangJavaModule instanceof YangLeaf) {
+            type = ((YangLeaf) yangJavaModule).getDataType();
+        } else {
+            type = ((YangLeafList) yangJavaModule).getDataType();
+        }
+
+        if (type.getDataType() == YangDataTypes.LEAFREF && yangJavaModule
+                .getJavaPackage().equals(YobConstants.JAVA_LANG)) {
+            YangLeafRef leafref = ((YangLeafRef) type.getDataTypeExtendedInfo());
+            YangType effectiveType = leafref.getEffectiveDataType();
+            if (effectiveType.getDataType() == YangDataTypes.IDENTITYREF) {
+                YangIdentityRef identityref = ((YangIdentityRef) effectiveType
+                        .getDataTypeExtendedInfo());
+                YangIdentity identity = identityref.getReferredIdentity();
+                qualifiedClassName = identity.getJavaPackage() + PERIOD +
+                        getCapitalCase(identity.getJavaClassNameOrBuiltInType());
+            }
+        } else {
+            qualifiedClassName = yangJavaModule.getJavaPackage() + PERIOD +
+                    getCapitalCase(yangJavaModule.getJavaClassNameOrBuiltInType());
+        }
+
+        ClassLoader classLoader = getClassLoader(null, qualifiedClassName,
+                                                 ydtExtendedContext, null);
+        try {
+            childSetClass = classLoader.loadClass(qualifiedClassName);
+        } catch (ClassNotFoundException e) {
+            log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
+        }
+
+        if (childSetClass != null) {
+            childMethod = childSetClass
+                    .getDeclaredMethod(FROM_STRING, String.class);
+        }
+
+        if (childMethod != null) {
+            childValue = childMethod.invoke(null, leafValue);
+        }
+
+        parentSetterMethod.invoke(parentBuilderObject, childValue);
     }
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java
index 29031ff..37d22ad 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobWorkBench.java
@@ -23,6 +23,7 @@
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
 import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtContextOperationType;
 import org.onosproject.yms.ydt.YdtType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,7 +37,6 @@
 
 import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
 import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_CHOICE_NODE;
-import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
 import static org.onosproject.yms.app.ydt.AppType.YOB;
 import static org.onosproject.yms.app.yob.YobConstants.ADD_AUGMENT_METHOD;
 import static org.onosproject.yms.app.yob.YobConstants.ADD_TO;
@@ -47,15 +47,18 @@
 import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_INVOKE_METHOD;
 import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_LOAD_CLASS;
 import static org.onosproject.yms.app.yob.YobConstants.E_HAS_NO_CHILD;
-import static org.onosproject.yms.app.yob.YobConstants.E_NO_HANDLE_FOR_YDT;
 import static org.onosproject.yms.app.yob.YobConstants.E_SET_OP_TYPE_FAIL;
 import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_BUILD;
 import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_GET_FIELD;
 import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_GET_METHOD;
 import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_INVOKE_METHOD;
-import static org.onosproject.yms.app.yob.YobConstants.OPERATION_TYPE;
+import static org.onosproject.yms.app.yob.YobConstants.ONOS_YANG_OP_TYPE;
 import static org.onosproject.yms.app.yob.YobConstants.OP_TYPE;
 import static org.onosproject.yms.app.yob.YobConstants.VALUE_OF;
+import static org.onosproject.yms.app.yob.YobConstants.YANG;
+import static org.onosproject.yms.app.yob.YobUtils.getCapitalCase;
+import static org.onosproject.yms.app.yob.YobUtils.getModuleInterface;
+import static org.onosproject.yms.app.yob.YobUtils.getQualifiedDefaultClass;
 import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
 import static org.onosproject.yms.ydt.YdtType.SINGLE_INSTANCE_NODE;
 
@@ -113,228 +116,12 @@
     }
 
     /**
-     * Returns the builder object or the built object corresponding to the
-     * current schema node.
-     *
-     * @return builder or built object
-     */
-    YobBuilderOrBuiltObject getBuilderOrBuiltObject() {
-        return builderOrBuiltObject;
-    }
-
-    /**
-     * Returns the parent builder object in which the child object can be set.
-     *
-     * @param node     child YDT node
-     * @param registry schema registry
-     * @return parent builder object
-     * @throws YobException if schema node does not have child
-     */
-    Object getParentBuilder(YdtExtendedContext node,
-                            YangSchemaRegistry registry) {
-
-        // Descendant schema node for whom the builder is required.
-        YangSchemaNodeIdentifier targetNode =
-                node.getYangSchemaNode().getYangSchemaNodeIdentifier();
-
-        //Current builder container
-        YobWorkBench curWorkBench = this;
-
-        YangSchemaNode nonSchemaHolder;
-        do {
-
-            //Current Schema node context
-            YangSchemaNodeContextInfo schemaContext;
-            try {
-                //Find the new schema context node.
-                schemaContext = curWorkBench.yangSchemaNode.getChildSchema(
-                        targetNode);
-
-            } catch (DataModelException e) {
-                throw new YobException(yangSchemaNode.getName() +
-                                               E_HAS_NO_CHILD +
-                                               targetNode.getName());
-            }
-
-            nonSchemaHolder = schemaContext.getContextSwitchedNode();
-
-            //If the descendant schema node is in switched context
-            if (nonSchemaHolder != null) {
-
-                YangSchemaNodeIdentifier nonSchemaIdentifier =
-                        nonSchemaHolder.getYangSchemaNodeIdentifier();
-
-                //check if the descendant builder container is already available
-                YobWorkBench childWorkBench =
-                        curWorkBench.attributeMap.get(nonSchemaIdentifier);
-
-                if (childWorkBench == null) {
-                    YobWorkBench newWorkBench = getNewChildWorkBench(
-                            schemaContext, targetNode, curWorkBench, registry);
-
-                    curWorkBench.attributeMap.put(nonSchemaIdentifier,
-                                                  newWorkBench);
-                    curWorkBench = newWorkBench;
-                } else {
-                    curWorkBench = childWorkBench;
-                }
-            }
-
-        } while (nonSchemaHolder != null);
-
-        return curWorkBench.builderOrBuiltObject.getBuilderObject();
-    }
-
-    /**
-     * Set the operation type attribute and build the object from the builder
-     * object, by invoking the build method.
-     *
-     * @param ydtNode data tree node
-     * @throws YobException if member method is not found or failed to build
-     */
-    void buildObject(YdtExtendedContext ydtNode) {
-
-        buildNonSchemaAttributes(ydtNode);
-
-        Object builderObject = builderOrBuiltObject.getBuilderObject();
-        Class<?> defaultBuilderClass = builderOrBuiltObject.yangBuilderClass;
-
-        //set the operation type
-        setOperationType(ydtNode);
-
-        // Invoking the build method to get built object from build method.
-        try {
-            Method method = defaultBuilderClass.getDeclaredMethod(BUILD);
-            if (method == null) {
-                log.error(L_FAIL_TO_GET_METHOD, defaultBuilderClass.getName());
-                throw new YobException(E_FAIL_TO_GET_METHOD +
-                                               defaultBuilderClass.getName());
-            }
-            Object builtObject = method.invoke(builderObject);
-            // The built object will be maintained in ydt context and same will
-            // be used while setting into parent method.
-            builderOrBuiltObject.setBuiltObject(builtObject);
-
-        } catch (NoSuchMethodException | InvocationTargetException |
-                IllegalAccessException e) {
-            log.error(L_FAIL_TO_BUILD, defaultBuilderClass.getName());
-            throw new YobException(E_FAIL_TO_BUILD +
-                                           defaultBuilderClass.getName());
-        }
-    }
-
-    /**
-     * Set the operation type in the built object from the YDT node.
-     * <p>
-     * It needs to be invoked only for the workbench corresponding to the
-     * schema YDT nodes, non schema node without the YDT node should not
-     * invoke this, as it is not applicable to it.
-     *
-     * @param ydtNode schema data tree node
-     * @throws YobException if fail to set the operation type
-     */
-    private void setOperationType(YdtExtendedContext ydtNode) {
-
-        Object builderObject = builderOrBuiltObject.getBuilderObject();
-        Class<?> defaultBuilderClass = builderOrBuiltObject.yangBuilderClass;
-
-        // Setting the value into YANG node operation type from ydtContext
-        // operation type.
-        try {
-            Class<?> interfaceClass = builderOrBuiltObject.yangDefaultClass;
-            Object operationType;
-            Class<?>[] innerClasses = interfaceClass.getClasses();
-            for (Class<?> innerEnumClass : innerClasses) {
-                if (innerEnumClass.getSimpleName().equals(OP_TYPE)) {
-                    Method valueOfMethod = innerEnumClass
-                            .getDeclaredMethod(VALUE_OF, String.class);
-                    if (ydtNode.getYdtContextOperationType() != null) {
-                        operationType = valueOfMethod.invoke(null, ydtNode
-                                .getYdtContextOperationType().toString());
-                        Field operationTypeField = defaultBuilderClass
-                                .getDeclaredField(OPERATION_TYPE);
-                        operationTypeField.setAccessible(true);
-                        operationTypeField.set(builderObject, operationType);
-                        break;
-                    }
-                }
-            }
-        } catch (NoSuchFieldException | NoSuchMethodException |
-                InvocationTargetException | IllegalAccessException e) {
-            log.error(E_SET_OP_TYPE_FAIL);
-            throw new YobException(E_SET_OP_TYPE_FAIL);
-        }
-    }
-
-    /**
-     * build the non schema objects and maintain it in the contained schema
-     * node.
-     *
-     * @param ydtNode contained schema node
-     */
-    private void buildNonSchemaAttributes(YdtExtendedContext ydtNode) {
-        for (Map.Entry<YangSchemaNodeIdentifier, YobWorkBench> entry :
-                attributeMap.entrySet()) {
-            YobWorkBench childWorkBench = entry.getValue();
-            childWorkBench.buildObject(ydtNode);
-
-            if (childWorkBench.yangSchemaNode.getYangSchemaNodeType() ==
-                    YANG_AUGMENT_NODE) {
-                addInAugmentation(builderOrBuiltObject.getBuilderObject(),
-                                  childWorkBench.setterInParent,
-                                  childWorkBench.getBuilderOrBuiltObject()
-                                          .getBuiltObject());
-                return;
-            }
-
-            setObjectInBuilder(
-                    builderOrBuiltObject.getBuilderObject(),
-                    childWorkBench.setterInParent,
-                    SINGLE_INSTANCE_NODE,
-                    childWorkBench.getBuilderOrBuiltObject().getBuiltObject());
-        }
-    }
-
-
-    //TODO add objectIn Augmentation
-
-    /**
-     * Sets the YANG built object in corresponding parent class method.
-     *
-     * @param ydtNode ydtExtendedContext is used to get application
-     *                related information maintained in YDT
-     * @throws YobException if there is no parent's YOB handler
-     */
-    void setObjectInParent(YdtExtendedContext ydtNode) {
-        YdtExtendedContext parentNode =
-                (YdtExtendedContext) ydtNode.getParent();
-        if (parentNode == null || parentNode.getAppInfo(YOB) == null) {
-            throw new YobException(E_NO_HANDLE_FOR_YDT);
-        }
-        YobWorkBench parentWorkBench =
-                (YobWorkBench) parentNode.getAppInfo(YOB);
-        Object parentBuilderObject =
-                parentWorkBench.builderOrBuiltObject.getBuilderObject();
-        YdtType nodeType = ydtNode.getYdtType();
-        Object objectToSetInParent = builderOrBuiltObject.getBuiltObject();
-
-        // set the object in the parent builder
-        setObjectInBuilder(parentBuilderObject, setterInParent, nodeType,
-                           objectToSetInParent);
-
-        ydtNode.addAppInfo(YOB, this);
-    }
-
-    /**
      * Set the attribute in a builder object.
      *
-     * @param builder   builder object in which the attribute needs to be
-     *                  set
+     * @param builder   builder object in which the attribute needs to be set
      * @param setter    setter method in parent
      * @param nodeType  type of node to set
      * @param attribute attribute to set in the builder
-     * @throws YobException if member is not found or failed to invoke the
-     *                      method
      */
     private static void setObjectInBuilder(Object builder, String setter,
                                            YdtType nodeType, Object attribute) {
@@ -408,7 +195,6 @@
 
     }
 
-
     /**
      * Creates a new builder container object corresponding to a context
      * switch schema node.
@@ -420,7 +206,6 @@
      * @param registry     schema registry
      * @return new builder container object corresponding to a context
      * switch schema node
-     * @throws YobException if expected child is not found in schema
      */
     private static YobWorkBench getNewChildWorkBench(
             YangSchemaNodeContextInfo childContext,
@@ -430,7 +215,7 @@
         YangSchemaNode ctxSwitchedNode = childContext.getContextSwitchedNode();
         String name;
 
-         /*This is the first child trying to set its object in the
+         /* This is the first child trying to set its object in the
          current context. */
         String setterInParent = ctxSwitchedNode.getJavaAttributeName();
 
@@ -440,7 +225,7 @@
             try {
                 childContext = ctxSwitchedNode.getChildSchema(targetNode);
                 ctxSwitchedNode = childContext.getContextSwitchedNode();
-                name = YobUtils.getQualifiedDefaultClass(
+                name = getQualifiedDefaultClass(
                         childContext.getContextSwitchedNode());
 
             } catch (DataModelException e) {
@@ -450,10 +235,10 @@
             }
         } else if (ctxSwitchedNode.getYangSchemaNodeType() ==
                 YANG_AUGMENT_NODE) {
-            name = YobUtils.getQualifiedDefaultClass(ctxSwitchedNode);
+            name = getQualifiedDefaultClass(ctxSwitchedNode);
             setterInParent = YobUtils.getQualifiedinterface(ctxSwitchedNode);
         } else {
-            name = YobUtils.getQualifiedDefaultClass(childContext.getSchemaNode());
+            name = getQualifiedDefaultClass(childContext.getSchemaNode());
         }
 
         ClassLoader newClassesLoader = YobUtils.getTargetClassLoader(
@@ -463,4 +248,216 @@
                                 setterInParent);
     }
 
+    /**
+     * Returns the builder object or the built object corresponding to the
+     * current schema node.
+     *
+     * @return builder or built object
+     */
+    YobBuilderOrBuiltObject getBuilderOrBuiltObject() {
+        return builderOrBuiltObject;
+    }
+
+    /**
+     * Returns the parent builder object in which the child object can be set.
+     *
+     * @param node     child YDT node
+     * @param registry schema registry
+     * @return parent builder object
+     */
+    Object getParentBuilder(YdtExtendedContext node,
+                            YangSchemaRegistry registry) {
+
+        // Descendant schema node for whom the builder is required.
+        YangSchemaNodeIdentifier targetNode =
+                node.getYangSchemaNode().getYangSchemaNodeIdentifier();
+
+        //Current builder container
+        YobWorkBench curWorkBench = this;
+
+        YangSchemaNode nonSchemaHolder;
+        do {
+
+            //Current Schema node context
+            YangSchemaNodeContextInfo schemaContext;
+            try {
+                //Find the new schema context node.
+                schemaContext = curWorkBench.yangSchemaNode
+                        .getChildSchema(targetNode);
+
+            } catch (DataModelException e) {
+                throw new YobException(yangSchemaNode.getName() +
+                                               E_HAS_NO_CHILD +
+                                               targetNode.getName());
+            }
+
+            nonSchemaHolder = schemaContext.getContextSwitchedNode();
+
+            //If the descendant schema node is in switched context
+            if (nonSchemaHolder != null) {
+
+                YangSchemaNodeIdentifier nonSchemaIdentifier =
+                        nonSchemaHolder.getYangSchemaNodeIdentifier();
+
+                //check if the descendant builder container is already available
+                YobWorkBench childWorkBench =
+                        curWorkBench.attributeMap.get(nonSchemaIdentifier);
+
+                if (childWorkBench == null) {
+                    YobWorkBench newWorkBench = getNewChildWorkBench(
+                            schemaContext, targetNode, curWorkBench, registry);
+
+                    curWorkBench.attributeMap.put(nonSchemaIdentifier,
+                                                  newWorkBench);
+                    curWorkBench = newWorkBench;
+                } else {
+                    curWorkBench = childWorkBench;
+                }
+            }
+
+        } while (nonSchemaHolder != null);
+
+        return curWorkBench.builderOrBuiltObject.getBuilderObject();
+    }
+
+    /**
+     * Set the operation type attribute and build the object from the builder
+     * object, by invoking the build method.
+     *
+     * @param operationType  data tree node
+     * @param schemaRegistry YANG schema registry
+     */
+    void buildObject(YdtContextOperationType operationType,
+                     YangSchemaRegistry schemaRegistry) {
+
+        buildNonSchemaAttributes(operationType, schemaRegistry);
+
+        Object builderObject = builderOrBuiltObject.getBuilderObject();
+        Class<?> defaultBuilderClass = builderOrBuiltObject.yangBuilderClass;
+
+        //set the operation type
+        setOperationType(operationType, schemaRegistry);
+
+        // Invoking the build method to get built object from build method.
+        try {
+            Method method = defaultBuilderClass.getDeclaredMethod(BUILD);
+            if (method == null) {
+                log.error(L_FAIL_TO_GET_METHOD, defaultBuilderClass.getName());
+                throw new YobException(E_FAIL_TO_GET_METHOD +
+                                               defaultBuilderClass.getName());
+            }
+            Object builtObject = method.invoke(builderObject);
+            // The built object will be maintained in ydt context and same will
+            // be used while setting into parent method.
+            builderOrBuiltObject.setBuiltObject(builtObject);
+
+        } catch (NoSuchMethodException | InvocationTargetException |
+                IllegalAccessException e) {
+            log.error(L_FAIL_TO_BUILD, defaultBuilderClass.getName());
+            throw new YobException(E_FAIL_TO_BUILD +
+                                           defaultBuilderClass.getName());
+        }
+    }
+
+    /**
+     * Set the operation type in the built object from the YDT node.
+     * <p>
+     * It needs to be invoked only for the workbench corresponding to the
+     * schema YDT nodes, non schema node without the YDT node should not
+     * invoke this, as it is not applicable to it.
+     *
+     * @param ydtoperation   schema data tree node
+     * @param schemaRegistry YANG schema registry
+     */
+    private void setOperationType(YdtContextOperationType ydtoperation,
+                                  YangSchemaRegistry schemaRegistry) {
+
+        if (ydtoperation == null) {
+            return;
+        }
+
+        Object builderObject = builderOrBuiltObject.getBuilderObject();
+        Class<?> defaultBuilderClass = builderOrBuiltObject.yangBuilderClass;
+        Class<?>[] intfClass = builderOrBuiltObject.yangDefaultClass
+                .getInterfaces();
+        String setterName = YANG + intfClass[0].getSimpleName() + OP_TYPE;
+
+        // Setting the value into YANG node operation type from ydtContext
+        // operation type.
+        try {
+            Class<?> interfaceClass;
+            interfaceClass = getModuleInterface(yangSchemaNode,
+                                                schemaRegistry);
+            Object operationType;
+            Class<?>[] innerClasses = interfaceClass.getClasses();
+            for (Class<?> innerEnumClass : innerClasses) {
+                if (innerEnumClass.getSimpleName().equals(ONOS_YANG_OP_TYPE)) {
+                    Method valueOfMethod = innerEnumClass
+                            .getDeclaredMethod(VALUE_OF, String.class);
+                    operationType = valueOfMethod.invoke(null, ydtoperation.
+                            toString());
+                    Field operationTypeField = defaultBuilderClass
+                            .getDeclaredField(setterName);
+                    operationTypeField.setAccessible(true);
+                    operationTypeField.set(builderObject, operationType);
+                    break;
+                }
+            }
+        } catch (NoSuchMethodException |
+                InvocationTargetException | IllegalAccessException |
+                IllegalArgumentException e) {
+            log.error(E_SET_OP_TYPE_FAIL);
+            throw new YobException(E_SET_OP_TYPE_FAIL);
+        } catch (NoSuchFieldException e) {
+            log.error(E_SET_OP_TYPE_FAIL);
+        }
+    }
+
+    /**
+     * build the non schema objects and maintain it in the contained schema
+     * node.
+     *
+     * @param operationType  contained schema node
+     * @param schemaRegistry YANG schema registry
+     */
+    private void buildNonSchemaAttributes(YdtContextOperationType operationType,
+                                          YangSchemaRegistry schemaRegistry) {
+        for (Map.Entry<YangSchemaNodeIdentifier, YobWorkBench> entry :
+                attributeMap.entrySet()) {
+            YobWorkBench childWorkBench = entry.getValue();
+            childWorkBench.buildObject(operationType, schemaRegistry);
+
+            if (childWorkBench.yangSchemaNode.getYangSchemaNodeType() ==
+                    YANG_AUGMENT_NODE) {
+                addInAugmentation(builderOrBuiltObject.getBuilderObject(),
+                                  childWorkBench.setterInParent,
+                                  childWorkBench.getBuilderOrBuiltObject()
+                                          .getBuiltObject());
+                continue;
+            }
+
+            setObjectInBuilder(
+                    builderOrBuiltObject.getBuilderObject(),
+                    childWorkBench.setterInParent,
+                    SINGLE_INSTANCE_NODE,
+                    childWorkBench.getBuilderOrBuiltObject().getBuiltObject());
+        }
+    }
+
+    /**
+     * Sets the YANG built object in corresponding parent class method.
+     *
+     * @param childnode      ydtExtendedContext is used to get application
+     *                       related information maintained in YDT
+     * @param schemaRegistry YANG schema registry
+     */
+    public void setObject(YdtExtendedContext childnode,
+                          YangSchemaRegistry schemaRegistry) {
+        Object builder = getParentBuilder(childnode, schemaRegistry);
+        YobWorkBench childWorkBench = (YobWorkBench) childnode.getAppInfo(YOB);
+
+        setObjectInBuilder(builder, childWorkBench.setterInParent,
+                           childnode.getYdtType(), childWorkBench
+                                   .builderOrBuiltObject.getBuiltObject());
+    }
 }