YANG object builder support for choice, case and augment

Change-Id: I1750062be4443f1fe03a4d405164dbceec6be631
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 4caa212..6df0724 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
@@ -16,25 +16,29 @@
 
 package org.onosproject.yms.app.yob;
 
-import org.onosproject.yms.app.yob.exception.YobExceptions;
+import org.onosproject.yms.app.yob.exception.YobException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.onosproject.yms.app.yob.YobConstants.BUILDER_IS_NOT_SET;
-import static org.onosproject.yms.app.yob.YobConstants.BUILT_OBJ_IS_NOT_SET;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_CREATE_OBJ;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CLASS;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_BUILDING_WITHOUT_BUILDER;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_IS_ALREADY_BUILT_NOT_BUILD;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_IS_ALREADY_BUILT_NOT_FETCH;
-import static org.onosproject.yms.app.yob.YobConstants.OBJ_IS_NOT_SET_NOT_FETCH;
-import static org.onosproject.yms.app.yob.YobConstants.REFLECTION_FAIL_TO_CREATE_OBJ;
+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;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_LOAD_CLASS;
+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_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;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_LOAD_CLASS;
+import static org.onosproject.yms.app.yob.YobConstants.L_REFLECTION_FAIL_TO_CREATE_OBJ;
 
 /**
  * Represents the container of YANG object being built or the builder.
  */
 class YobBuilderOrBuiltObject {
-    private static final Logger log = LoggerFactory.getLogger(YobWorkBench.class);
+    private static final Logger log =
+            LoggerFactory.getLogger(YobWorkBench.class);
 
     /**
      * Is the contained object a built object.
@@ -56,6 +60,13 @@
      */
     Class<?> yangDefaultClass;
 
+    /**
+     * Create Node Object holder.
+     *
+     * @param qualifiedClassName       name of the class
+     * @param registeredAppClassLoader class loader to be used
+     * @throws YobException if failed to create the node object
+     */
     YobBuilderOrBuiltObject(String qualifiedClassName,
                             ClassLoader registeredAppClassLoader) {
         try {
@@ -64,11 +75,15 @@
             yangBuilderClass = yangDefaultClass.getDeclaredClasses()[0];
             builderOrBuiltObject = yangBuilderClass.newInstance();
         } catch (ClassNotFoundException e) {
-            log.error(FAIL_TO_LOAD_CLASS + qualifiedClassName);
+            log.error(L_FAIL_TO_LOAD_CLASS, qualifiedClassName);
+            throw new YobException(E_FAIL_TO_LOAD_CLASS + qualifiedClassName);
         } catch (InstantiationException | IllegalAccessException e) {
-            log.error(FAIL_TO_CREATE_OBJ + qualifiedClassName);
+            log.error(L_FAIL_TO_CREATE_OBJ, qualifiedClassName);
+            throw new YobException(E_FAIL_TO_CREATE_OBJ + qualifiedClassName);
         } catch (NullPointerException e) {
-            log.error(REFLECTION_FAIL_TO_CREATE_OBJ + qualifiedClassName);
+            log.error(L_REFLECTION_FAIL_TO_CREATE_OBJ, qualifiedClassName);
+            throw new YobException(E_REFLECTION_FAIL_TO_CREATE_OBJ +
+                                           qualifiedClassName);
         }
     }
 
@@ -76,15 +91,16 @@
      * Returns the builder object if it is set.
      *
      * @return builder object
-     * @throws YobExceptions if builder object is not available
+     * @throws YobException if builder object is not available or if it is
+     *                      already built
      */
     Object getBuilderObject() {
         if (isBuilt) {
-            throw new YobExceptions(OBJ_IS_ALREADY_BUILT_NOT_FETCH);
+            throw new YobException(E_OBJ_IS_ALREADY_BUILT_NOT_FETCH);
         }
 
         if (builderOrBuiltObject == null) {
-            throw new YobExceptions(BUILDER_IS_NOT_SET);
+            throw new YobException(E_BUILDER_IS_NOT_SET);
         }
 
         return builderOrBuiltObject;
@@ -94,15 +110,16 @@
      * Returns the built object.
      *
      * @return built object
-     * @throws YobExceptions if built object is not available
+     * @throws YobException if built object is not available or if it is not
+     *                      built
      */
     Object getBuiltObject() {
         if (!isBuilt) {
-            throw new YobExceptions(OBJ_IS_NOT_SET_NOT_FETCH);
+            throw new YobException(E_OBJ_IS_NOT_SET_NOT_FETCH);
         }
 
         if (builderOrBuiltObject == null) {
-            throw new YobExceptions(BUILT_OBJ_IS_NOT_SET);
+            throw new YobException(E_BUILT_OBJ_IS_NOT_SET);
         }
 
         return builderOrBuiltObject;
@@ -113,15 +130,16 @@
      * set it.
      *
      * @param builtObject new built object
-     * @throws YobExceptions if builder or built object is not available
+     * @throws YobException if builder object is not available or if it is
+     *                      already built
      */
     void setBuiltObject(Object builtObject) {
         if (isBuilt) {
-            throw new YobExceptions(OBJ_IS_ALREADY_BUILT_NOT_BUILD);
+            throw new YobException(E_OBJ_IS_ALREADY_BUILT_NOT_BUILD);
         }
 
         if (builderOrBuiltObject == null) {
-            throw new YobExceptions(OBJ_BUILDING_WITHOUT_BUILDER);
+            throw new YobException(E_OBJ_BUILDING_WITHOUT_BUILDER);
         }
 
         isBuilt = true;
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 2fc1343..3b8d728 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
@@ -20,6 +20,7 @@
  * Represents common constant utility for YANG object builder.
  */
 final class YobConstants {
+
     private YobConstants() {
     }
 
@@ -33,35 +34,57 @@
     static final String OP_TYPE = "OnosYangNodeOperationType";
     static final String OF = "of";
     static final String PERIOD = ".";
-    static final String NO_HANDLE_FOR_YDT = "No handler for YDT node";
-    static final String HAS_NO_CHILD = " does not have child ";
-    static final String SET_OP_TYPE_FAIL = "Failed to set Operation Type";
-    static final String FAIL_TO_BUILD = "Failed to build the object ";
-    static final String FAIL_TO_GET_FIELD = "Failed to get field for class ";
-    static final String FAIL_TO_GET_METHOD = "Failed to get method for class ";
-    static final String FAIL_TO_LOAD_CLASS = "Failed to load class for class ";
-    static final String YDT_TYPE_IS_NOT_SUPPORT =
+    static final String ADD_AUGMENT_METHOD = "addYangAugmentedInfo";
+
+    //Error strings
+    static final String E_NO_HANDLE_FOR_YDT = "No handler for YDT node";
+    static final String E_HAS_NO_CHILD = " does not have child ";
+    static final String E_SET_OP_TYPE_FAIL = "Failed to set Operation Type";
+    static final String E_FAIL_TO_BUILD = "Failed to build the object: ";
+    static final String L_FAIL_TO_BUILD = "Failed to build the object: {}";
+    static final String E_FAIL_TO_GET_FIELD = "Failed to get field for class: ";
+    static final String L_FAIL_TO_GET_FIELD =
+            "Failed to get field for class: {}";
+    static final String E_FAIL_TO_GET_METHOD =
+            "Failed to get method for class: ";
+    static final String L_FAIL_TO_GET_METHOD =
+            "Failed to get method for class: {}";
+    static final String E_FAIL_TO_LOAD_CLASS =
+            "Failed to load class for class: ";
+    static final String L_FAIL_TO_LOAD_CLASS =
+            "Failed to load class for class: {}";
+    static final String E_YDT_TYPE_IS_NOT_SUPPORT =
             "Given YDT type is not supported.";
-    static final String FAIL_TO_CREATE_OBJ =
-            "Failed to create an object for class ";
-    static final String REFLECTION_FAIL_TO_CREATE_OBJ =
-            "Reflection failed to create an object for class ";
-    static final String FAIL_TO_LOAD_CONSTRUCTOR =
-            "Failed to load constructor for class ";
-    static final String FAIL_TO_INVOKE_METHOD =
-            "Failed to invoke method for class ";
-    static final String DATA_TYPE_NOT_SUPPORT =
+    static final String E_FAIL_TO_CREATE_OBJ =
+            "Failed to create an object for class: ";
+    static final String L_FAIL_TO_CREATE_OBJ =
+            "Failed to create an object for class: {}";
+    static final String E_REFLECTION_FAIL_TO_CREATE_OBJ =
+            "Reflection failed to create an object for class: ";
+    static final String L_REFLECTION_FAIL_TO_CREATE_OBJ =
+            "Reflection failed to create an object for class: {}";
+    static final String E_FAIL_TO_LOAD_CONSTRUCTOR =
+            "Failed to load constructor for class: {}";
+    static final String E_FAIL_TO_INVOKE_METHOD =
+            "Failed to invoke method for class: ";
+    static final String L_FAIL_TO_INVOKE_METHOD =
+            "Failed to invoke method for class: {}";
+    static final String E_DATA_TYPE_NOT_SUPPORT =
             "Given data type is not supported.";
-    static final String OBJ_IS_ALREADY_BUILT_NOT_FETCH =
+    static final String E_OBJ_IS_ALREADY_BUILT_NOT_FETCH =
             "Object is already built, cannot fetch builder";
-    static final String BUILDER_IS_NOT_SET =
+    static final String E_BUILDER_IS_NOT_SET =
             "Builder is not yet set, cannot fetch it";
-    static final String BUILT_OBJ_IS_NOT_SET =
+    static final String E_BUILT_OBJ_IS_NOT_SET =
             "Built object is not set";
-    static final String OBJ_IS_NOT_SET_NOT_FETCH =
+    static final String E_OBJ_IS_NOT_SET_NOT_FETCH =
             "Builder is not yet set, cannot fetch it";
-    static final String OBJ_IS_ALREADY_BUILT_NOT_BUILD =
+    static final String E_OBJ_IS_ALREADY_BUILT_NOT_BUILD =
             "Object is already built, cannot build again";
-    static final String OBJ_BUILDING_WITHOUT_BUILDER =
+    static final String E_OBJ_BUILDING_WITHOUT_BUILDER =
             "Object building without builder";
+    static final String E_MISSING_DATA_IN_NODE =
+            "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";
 }
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 e2190f0..abb6248 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
@@ -16,31 +16,14 @@
 
 package org.onosproject.yms.app.yob;
 
-import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
-import org.onosproject.yangutils.datamodel.YangBinary;
 import org.onosproject.yangutils.datamodel.YangSchemaNode;
-import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
-import org.onosproject.yms.app.yob.exception.YobExceptions;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-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.DATA_TYPE_NOT_SUPPORT;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CLASS;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_LOAD_CONSTRUCTOR;
-import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
-import static org.onosproject.yms.app.yob.YobConstants.OF;
-import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
-import static org.onosproject.yms.app.yob.YobWorkBench.getQualifiedDefaultClassName;
+import static org.onosproject.yms.app.yob.YobUtils.getQualifiedDefaultClass;
 
 /**
  * Represents a YANG object builder handler to process the ydt content and
@@ -51,38 +34,32 @@
     private static final Logger log = LoggerFactory.getLogger(YobHandler.class);
 
     /**
-     * reference to YANG schema registry.
-     */
-    private YangSchemaRegistry registry;
-
-    /**
      * Creates a YANG builder object.
      *
-     * @param curYdtNode  ydtExtendedContext is used to get
-     *                    application related information maintained
-     *                    in YDT
-     * @param rootYdtNode ydtRootNode is refers to module node
-     * @param registry    registry
+     * @param curNode  ydtExtendedContext is used to get
+     *                 application related information maintained
+     *                 in YDT
+     * @param rootNode ydtRootNode is refers to module node
+     * @param registry registry
      */
-    public void createYangBuilderObject(YdtExtendedContext curYdtNode,
-                                        YdtExtendedContext rootYdtNode,
-                                        YangSchemaRegistry registry) {
+    public void createBuilder(YdtExtendedContext curNode,
+                              YdtExtendedContext rootNode,
+                              YangSchemaRegistry registry) {
         String setterName = null;
-        YangSchemaNode node = curYdtNode.getYangSchemaNode();
+        YangSchemaNode node = curNode.getYangSchemaNode();
 
-        String qualName = getQualifiedDefaultClassName(node);
-        ClassLoader classLoader = getClassLoader(registry,
-                                                 qualName,
-                                                 curYdtNode, rootYdtNode);
+        String qualName = getQualifiedDefaultClass(node);
+        ClassLoader classLoader = YobUtils.getClassLoader(registry, qualName,
+                                                          curNode, rootNode);
 
-        if (curYdtNode != rootYdtNode) {
+        if (curNode != rootNode) {
             setterName = node.getJavaAttributeName();
         }
 
-        Object builderObject = new YobWorkBench(node, classLoader,
-                                                qualName, setterName);
+        Object workBench = new YobWorkBench(node, classLoader, qualName,
+                                            setterName);
 
-        curYdtNode.addAppInfo(YOB, builderObject);
+        curNode.addAppInfo(YOB, workBench);
     }
 
     /**
@@ -92,8 +69,10 @@
      *                       related information maintained in YDT
      * @param schemaRegistry YANG schema registry
      */
-    public void setObjectInParent(YdtExtendedContext ydtNode,
-                                  YangSchemaRegistry schemaRegistry) {
+    public void setInParent(YdtExtendedContext ydtNode,
+                            YangSchemaRegistry schemaRegistry) {
+        YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
+        yobWorkBench.setObjectInParent(ydtNode);
     }
 
     /**
@@ -105,243 +84,10 @@
      * @param ydtRootNode    ydtRootNode
      * @param schemaRegistry YANG schema registry
      */
-    public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
-                                       YdtExtendedContext ydtRootNode,
-                                       YangSchemaRegistry schemaRegistry) {
+    public void buildObject(YdtExtendedContext ydtNode,
+                            YdtExtendedContext ydtRootNode,
+                            YangSchemaRegistry schemaRegistry) {
         YobWorkBench yobWorkBench = (YobWorkBench) ydtNode.getAppInfo(YOB);
-        yobWorkBench.buildObject(ydtNode, ydtRootNode);
-    }
-
-    /**
-     * This method is used to set data from string value in parent method.
-     *
-     * @param type                refers to YANG 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
-     * @throws InvocationTargetException throws InvocationTargetException
-     * @throws IllegalAccessException    throws IllegalAccessException
-     * @throws NoSuchMethodException     throws NoSuchMethodException
-     */
-    void setDataFromStringValue(YangType<?> type, String leafValue,
-                                Method parentSetterMethod,
-                                Object parentBuilderObject,
-                                YdtExtendedContext ydtExtendedContext)
-            throws InvocationTargetException, IllegalAccessException,
-            NoSuchMethodException {
-        switch (type.getDataType()) {
-            case INT8: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          Byte.parseByte(leafValue));
-                break;
-            }
-            case UINT8:
-            case INT16: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          Short.parseShort(leafValue));
-                break;
-            }
-            case UINT16:
-            case INT32: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          Integer.parseInt(leafValue));
-                break;
-            }
-            case UINT32:
-            case INT64: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          Long.parseLong(leafValue));
-                break;
-            }
-            case UINT64: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          new BigInteger(leafValue));
-                break;
-            }
-            case EMPTY:
-            case BOOLEAN: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          Boolean.parseBoolean(leafValue));
-                break;
-            }
-            case STRING: {
-                parentSetterMethod.invoke(parentBuilderObject, leafValue);
-                break;
-            }
-            case BINARY: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          new YangBinary(leafValue));
-                break;
-            }
-            case BITS: {
-                //TODO
-                break;
-            }
-            case DECIMAL64: {
-                parentSetterMethod.invoke(parentBuilderObject,
-                                          new BigDecimal(leafValue));
-                break;
-            }
-            case DERIVED: {
-                parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
-                                     parentBuilderObject, leafValue, false);
-                break;
-            }
-            case UNION: {
-                // TODO
-                break;
-            }
-            case LEAFREF: {
-                // TODO
-                break;
-            }
-            case ENUMERATION: {
-                parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
-                                     parentBuilderObject, leafValue, true);
-                break;
-            }
-            default: {
-                log.error(DATA_TYPE_NOT_SUPPORT);
-            }
-        }
-    }
-
-    /**
-     * 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
-     * @throws InvocationTargetException throws InvocationTargetException
-     * @throws IllegalAccessException    throws IllegalAccessException
-     * @throws NoSuchMethodException     throws NoSuchMethodException
-     */
-    private void parseDerivedTypeInfo(YdtExtendedContext ydtExtendedContext,
-                                      Method parentSetterMethod,
-                                      Object parentBuilderObject,
-                                      String leafValue, boolean isEnum)
-            throws InvocationTargetException, IllegalAccessException,
-            NoSuchMethodException {
-        Class<?> childSetClass = null;
-        Constructor<?> childConstructor = null;
-        Object childValue = null;
-        Object childObject = null;
-        Method childMethod = null;
-
-        YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
-        String packageName = yangJavaModule.getJavaPackage();
-        String className = getCapitalCase(
-                yangJavaModule.getJavaClassNameOrBuiltInType());
-        String qualifiedClassName = packageName + PERIOD + className;
-        ClassLoader classLoader = getClassLoader(registry,
-                                                 qualifiedClassName,
-                                                 ydtExtendedContext, null);
-        try {
-            childSetClass = classLoader.loadClass(qualifiedClassName);
-        } catch (ClassNotFoundException e) {
-            log.error(FAIL_TO_LOAD_CLASS + packageName + PERIOD + className);
-        }
-        if (!isEnum) {
-
-            if (childSetClass != null) {
-                childConstructor = childSetClass.getDeclaredConstructor();
-            }
-
-            if (childConstructor != null) {
-                childConstructor.setAccessible(true);
-            }
-            try {
-                if (childConstructor != null) {
-                    childObject = childConstructor.newInstance();
-                }
-            } catch (InstantiationException e) {
-                log.error(FAIL_TO_LOAD_CONSTRUCTOR + className);
-            }
-            if (childSetClass != null) {
-                childMethod = childSetClass
-                        .getDeclaredMethod(FROM_STRING, String.class);
-            }
-        } else {
-            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);
-    }
-
-    /**
-     * Updates class loader for all the classes.
-     *
-     * @param registry           YANG schema registry
-     * @param curNode            YDT context
-     * @param qualifiedClassName qualified class name
-     * @return current class loader
-     */
-    private ClassLoader getClassLoader(YangSchemaRegistry registry,
-                                       String qualifiedClassName,
-                                       YdtExtendedContext curNode,
-                                       YdtExtendedContext context) {
-
-        if (context != null && curNode == context) {
-            YangSchemaNode yangSchemaNode = curNode.getYangSchemaNode();
-            while (!(yangSchemaNode instanceof RpcNotificationContainer)) {
-                curNode = (YdtExtendedContext) curNode.getParent();
-                if (curNode == null) {
-                    throw new YobExceptions("Invalid YANG data tree");
-                }
-                yangSchemaNode = curNode.getYangSchemaNode();
-            }
-
-            Class<?> regClass = registry.getRegisteredClass(yangSchemaNode,
-                                                            qualifiedClassName);
-            return regClass.getClassLoader();
-        } else {
-            YdtExtendedContext parent =
-                    (YdtExtendedContext) curNode.getParent();
-            YobWorkBench parentBuilderContainer =
-                    (YobWorkBench) parent.getAppInfo(YOB);
-            Object parentObj =
-                    parentBuilderContainer.getParentBuilder(curNode, registry);
-            return parentObj.getClass().getClassLoader();
-        }
-    }
-
-    /**
-     * Returns the YANG schema registry.
-     *
-     * @return registry YANG schema registry
-     */
-    public YangSchemaRegistry getRegistry() {
-        return registry;
-    }
-
-    /**
-     * Sets the YANG schema registry.
-     *
-     * @param registry YANG schema registry
-     */
-    public void setRegistry(YangSchemaRegistry registry) {
-        this.registry = registry;
+        yobWorkBench.buildObject(ydtNode);
     }
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java
index 254edd9..5a8a8ef 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobHandlerFactory.java
@@ -17,6 +17,7 @@
 package org.onosproject.yms.app.yob;
 
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.ydt.YdtType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -24,7 +25,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import static org.onosproject.yms.app.yob.YobConstants.YDT_TYPE_IS_NOT_SUPPORT;
+import static org.onosproject.yms.app.yob.YobConstants.E_YDT_TYPE_IS_NOT_SUPPORT;
 import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_LEAF_VALUE_NODE;
 import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
 import static org.onosproject.yms.ydt.YdtType.SINGLE_INSTANCE_LEAF_VALUE_NODE;
@@ -37,65 +38,56 @@
 final class YobHandlerFactory {
 
     private static final Logger log =
-            LoggerFactory.getLogger(YobSingleInstanceLeafHandler.class);
-
-    /**
-     * Creates single instance node handler.
-     */
-    private static YobSingleInstanceHandler singleInstanceNode =
-            new YobSingleInstanceHandler();
-
-    /**
-     * Creates multi instance node handler.
-     */
-    private static YobMultiInstanceHandler multiInstanceNode =
-            new YobMultiInstanceHandler();
-
-    /**
-     * Creates single instance leaf node handler.
-     */
-    private static YobSingleInstanceLeafHandler singleInstanceLeaf =
-            new YobSingleInstanceLeafHandler();
-
-    /**
-     * Creates multi instance leaf node handler.
-     */
-    private static YobMultiInstanceLeafHandler multiInstanceLeaf =
-            new YobMultiInstanceLeafHandler();
+            LoggerFactory.getLogger(YobHandlerFactory.class);
 
     /**
      * Map of YANG object builder handler.
      */
-    private static Map<YdtType, YobHandler> yobHandlerHashMap =
-            new HashMap<>();
+    private static final Map<YdtType, YobHandler> HANDLER_MAP = new HashMap<>();
 
     /**
      * Create instance of YobHandlerFactory.
      */
-    YobHandlerFactory() {
-        yobHandlerHashMap.put(SINGLE_INSTANCE_NODE, singleInstanceNode);
-        yobHandlerHashMap.put(MULTI_INSTANCE_NODE, multiInstanceNode);
-        yobHandlerHashMap.put(SINGLE_INSTANCE_LEAF_VALUE_NODE,
-                              singleInstanceLeaf);
-        yobHandlerHashMap.put(MULTI_INSTANCE_LEAF_VALUE_NODE,
-                              multiInstanceLeaf);
+    private YobHandlerFactory() {
+        HANDLER_MAP.put(SINGLE_INSTANCE_NODE, new YobSingleInstanceHandler());
+        HANDLER_MAP.put(MULTI_INSTANCE_NODE, new YobMultiInstanceHandler());
+        HANDLER_MAP.put(SINGLE_INSTANCE_LEAF_VALUE_NODE,
+                        new YobSingleInstanceLeafHandler());
+        HANDLER_MAP.put(MULTI_INSTANCE_LEAF_VALUE_NODE,
+                        new YobMultiInstanceLeafHandler());
     }
 
     /**
      * Returns the corresponding YOB handler for current context.
      *
-     * @param ydtExtendedContext ydtExtendedContext is used to get application
-     *                           related information maintained in YDT
-     * @return YANG object builder node
+     * @param currentNode current YDT node for which object needs to be created
+     * @return handler to create the object
+     * @throws YobException if the YDT node type is not supported in YOB
      */
-    YobHandler getYobHandlerForContext(
-            YdtExtendedContext ydtExtendedContext) {
-        YobHandler yobHandler =
-                yobHandlerHashMap.get(ydtExtendedContext.getYdtType());
+    YobHandler getYobHandlerForContext(YdtExtendedContext currentNode) {
+        YobHandler yobHandler = HANDLER_MAP.get(currentNode.getYdtType());
         if (yobHandler == null) {
-            log.error(YDT_TYPE_IS_NOT_SUPPORT);
-            return null;
+            log.error(E_YDT_TYPE_IS_NOT_SUPPORT);
+            throw new YobException(E_YDT_TYPE_IS_NOT_SUPPORT);
         }
         return yobHandler;
     }
+
+    /**
+     * Returns the YANG object builder factory instance.
+     *
+     * @return YANG object builder factory instance
+     */
+    public static YobHandlerFactory instance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    /*
+     * Bill Pugh Singleton pattern. INSTANCE won't be instantiated until the
+     * LazyHolder class is loaded via a call to the instance() method below.
+     */
+    private static class LazyHolder {
+        private static final YobHandlerFactory INSTANCE =
+                new YobHandlerFactory();
+    }
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java
index be52325..153f10f 100755
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobListener.java
@@ -18,11 +18,12 @@
 
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
 import org.onosproject.yms.app.ydt.YdtExtendedListener;
-import org.onosproject.yms.app.yob.exception.YobExceptions;
+import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
 import org.onosproject.yms.ydt.YdtContext;
 
-import static org.onosproject.yms.app.yob.YobConstants.NO_HANDLE_FOR_YDT;
+import static org.onosproject.yms.app.yob.YobConstants.E_MISSING_DATA_IN_NODE;
+import static org.onosproject.yms.app.yob.YobHandlerFactory.instance;
 
 /**
  * Represents implementation of YANG object builder listener.
@@ -32,7 +33,7 @@
     /**
      * Reference to the ydt root node.
      */
-    private YdtExtendedContext ydtRootNode;
+    private YdtExtendedContext rootNode;
 
     /**
      * Reference to YANG schema registry.
@@ -42,55 +43,65 @@
     /**
      * Reference to YOB handler.
      */
-    private YobHandlerFactory yobHandlerFactory;
+    private YobHandlerFactory handlerFactory;
 
     /**
      * Creates an instance of YANG object builder listener.
      *
-     * @param ydtRootExtendedContext refers to YDT context
-     * @param schemaRegistry         refers to YANG schema registry
+     * @param rootNode       refers to YDT context
+     * @param schemaRegistry refers to YANG schema registry
      */
-    YobListener(YdtExtendedContext ydtRootExtendedContext,
+    YobListener(YdtExtendedContext rootNode,
                 YangSchemaRegistry schemaRegistry) {
-        this.ydtRootNode = ydtRootExtendedContext;
+        this.rootNode = rootNode;
         this.schemaRegistry = schemaRegistry;
-        this.yobHandlerFactory = new YobHandlerFactory();
+        this.handlerFactory = instance();
     }
 
     @Override
-    public void enterYdtNode(YdtExtendedContext ydtExtendedContext) {
+    public void enterYdtNode(YdtExtendedContext node) {
 
         YobHandler nodeHandler =
-                yobHandlerFactory.getYobHandlerForContext(ydtExtendedContext);
+                handlerFactory.getYobHandlerForContext(node);
 
-        if (nodeHandler == null) {
-            throw new YobExceptions(NO_HANDLE_FOR_YDT);
-        }
-        nodeHandler.createYangBuilderObject(ydtExtendedContext,
-                                            ydtRootNode, schemaRegistry);
+        nodeHandler.createBuilder(node, rootNode, schemaRegistry);
 
     }
 
     @Override
-    public void exitYdtNode(YdtExtendedContext ydtExtendedContext) {
+    public void exitYdtNode(YdtExtendedContext node) {
         YobHandler nodeHandler =
-                yobHandlerFactory.getYobHandlerForContext(ydtExtendedContext);
-        if (nodeHandler != null) {
-            nodeHandler.buildObjectFromBuilder(ydtExtendedContext,
-                                               ydtRootNode, schemaRegistry);
-            // The current ydt context node and root node are same then return.
-            if (!ydtExtendedContext.equals(ydtRootNode)) {
-                nodeHandler.setObjectInParent(ydtExtendedContext,
-                                              schemaRegistry);
-            }
+                handlerFactory.getYobHandlerForContext(node);
+
+        nodeHandler.buildObject(node, rootNode, schemaRegistry);
+
+        // The current ydt context node and root node are same then built
+        // object needs to be returned.
+        if (!node.equals(rootNode)) {
+            nodeHandler.setInParent(node, schemaRegistry);
         }
+
     }
 
+    /**
+     * Does not support walking of non extended context YDT.
+     *
+     * @param ydtContext YANG data tree context
+     * @throws YobException if YDT walker is not using extended context walker
+     */
     @Override
     public void enterYdtNode(YdtContext ydtContext) {
+        throw new YobException(E_MISSING_DATA_IN_NODE);
     }
 
+    /**
+     * Does not support walking of non extended context YDT.
+     *
+     * @param ydtContext YANG data tree context
+     * @throws YobException if YDT walker is not using extended context walker
+     */
     @Override
     public void exitYdtNode(YdtContext ydtContext) {
+        throw new YobException(E_MISSING_DATA_IN_NODE);
     }
 }
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 9ad458b..c59725a 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
@@ -22,6 +22,7 @@
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.javadatamodel.JavaQualifiedTypeInfoContainer;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,7 +36,8 @@
 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;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_INVOKE_METHOD;
 
 /**
  * Represents a multi instance leaf node handler in YANG object builder.
@@ -47,43 +49,50 @@
             LoggerFactory.getLogger(YobMultiInstanceLeafHandler.class);
 
     @Override
-    public void createYangBuilderObject(YdtExtendedContext curYdtNode,
-                                        YdtExtendedContext rootYdtNode,
-                                        YangSchemaRegistry registry) {
+    public void createBuilder(YdtExtendedContext curNode,
+                              YdtExtendedContext rootNode,
+                              YangSchemaRegistry registry) {
         // For multi instance leaf no need to create an object.
     }
 
     @Override
-    public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
-                                       YdtExtendedContext ydtRootNode,
-                                       YangSchemaRegistry schemaRegistry) {
+    public void buildObject(YdtExtendedContext ydtNode,
+                            YdtExtendedContext ydtRootNode,
+                            YangSchemaRegistry schemaRegistry) {
         // For multi instance leaf no need to build object.
     }
 
+    /**
+     * Set the leaf list values in the YANG object.
+     *
+     * @param leafListNode   leaf list YDT node
+     * @param schemaRegistry YANG schema registry
+     * @throws YobException if failed to invoke the leaf list's setter
+     */
     @Override
-    public void setObjectInParent(YdtExtendedContext leafListYdtNode,
-                                  YangSchemaRegistry schemaRegistry) {
+    public void setInParent(YdtExtendedContext leafListNode,
+                            YangSchemaRegistry schemaRegistry) {
         Class<?> parentBuilderClass = null;
-        YangSchemaNode yangSchemaNode = leafListYdtNode.getYangSchemaNode();
+        YangSchemaNode yangSchemaNode = leafListNode.getYangSchemaNode();
         YdtExtendedContext parentYdtNode =
-                (YdtExtendedContext) leafListYdtNode.getParent();
+                (YdtExtendedContext) leafListNode.getParent();
         YobWorkBench parentYobWorkBench =
                 (YobWorkBench) parentYdtNode.getAppInfo(YOB);
-        Set<String> valueSet = leafListYdtNode.getValueSet();
+        Set<String> valueSet = leafListNode.getValueSet();
 
         for (String value : valueSet) {
             try {
                 String setterInParent = yangSchemaNode.getJavaAttributeName();
-                Object parentBuilderObject = parentYobWorkBench
-                        .getParentBuilder(leafListYdtNode, schemaRegistry);
-                parentBuilderClass = parentBuilderObject.getClass();
+                Object builderObject = parentYobWorkBench
+                        .getParentBuilder(leafListNode, schemaRegistry);
+                parentBuilderClass = builderObject.getClass();
                 Field leafName = parentBuilderClass
                         .getDeclaredField(setterInParent);
                 ParameterizedType genericListType =
                         (ParameterizedType) leafName.getGenericType();
                 Class<?> genericListClass =
                         (Class<?>) genericListType.getActualTypeArguments()[0];
-                Method parentSetterMethod =
+                Method setterMethod =
                         parentBuilderClass.getDeclaredMethod(
                                 ADD_TO + getCapitalCase(setterInParent),
                                 genericListClass);
@@ -91,11 +100,14 @@
                         (JavaQualifiedTypeInfoContainer) yangSchemaNode;
                 YangType<?> yangType =
                         ((YangLeafList) javaQualifiedType).getDataType();
-                setDataFromStringValue(yangType, value, parentSetterMethod,
-                                       parentBuilderObject, leafListYdtNode);
+                YobUtils.setDataFromStringValue(yangType, value, setterMethod,
+                                                builderObject, leafListNode);
             } catch (NoSuchMethodException | InvocationTargetException
                     | IllegalAccessException | NoSuchFieldException e) {
-                log.error(FAIL_TO_INVOKE_METHOD + parentBuilderClass.getName());
+                log.error(L_FAIL_TO_INVOKE_METHOD,
+                          parentBuilderClass.getName());
+                throw new YobException(E_FAIL_TO_INVOKE_METHOD +
+                                               parentBuilderClass.getName());
             }
         }
     }
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 f6d8642..6840684 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,9 +19,8 @@
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangType;
-import org.onosproject.yangutils.datamodel.javadatamodel
-        .JavaQualifiedTypeInfoContainer;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,7 +30,8 @@
 import java.lang.reflect.Method;
 
 import static org.onosproject.yms.app.ydt.AppType.YOB;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_INVOKE_METHOD;
+import static org.onosproject.yms.app.yob.YobConstants.L_FAIL_TO_INVOKE_METHOD;
 
 /**
  * Represents a single instance leaf node handler in YANG object builder.
@@ -42,46 +42,52 @@
             LoggerFactory.getLogger(YobSingleInstanceLeafHandler.class);
 
     @Override
-    public void createYangBuilderObject(YdtExtendedContext curYdtNode,
-                                        YdtExtendedContext rootYdtNode,
-                                        YangSchemaRegistry registry) {
+    public void createBuilder(YdtExtendedContext curNode,
+                              YdtExtendedContext rootNode,
+                              YangSchemaRegistry registry) {
         // For single instance leaf no need to create an object.
     }
 
     @Override
-    public void buildObjectFromBuilder(YdtExtendedContext ydtNode,
-                                       YdtExtendedContext ydtRootNode,
-                                       YangSchemaRegistry schemaRegistry) {
+    public void buildObject(YdtExtendedContext ydtNode,
+                            YdtExtendedContext ydtRootNode,
+                            YangSchemaRegistry schemaRegistry) {
         // For single instance leaf no need to build an object.
     }
 
+    /**
+     * Set the leaf's value in the YANG object.
+     *
+     * @param leafNode       leaf YDT node
+     * @param schemaRegistry YANG schema registry
+     * @throws YobException if failed to invoke the leaf's setter
+     */
     @Override
-    public void setObjectInParent(YdtExtendedContext leafNode,
-                                  YangSchemaRegistry schemaRegistry) {
-        Class<?> parentBldrClass = null;
-        YangSchemaNode yangSchemaNode = leafNode.getYangSchemaNode();
-        YdtExtendedContext parentYdtNode =
-                (YdtExtendedContext) leafNode.getParent();
-        YobWorkBench parentYobWorkBench =
-                (YobWorkBench) parentYdtNode.getAppInfo(YOB);
-        String value = leafNode.getValue();
+    public void setInParent(YdtExtendedContext leafNode,
+                            YangSchemaRegistry schemaRegistry) {
+        Class<?> builderClass = null;
 
         try {
-            String setterInParent = yangSchemaNode.getJavaAttributeName();
-            Object parentBuilderObject = parentYobWorkBench
+            YangSchemaNode schemaNode = leafNode.getYangSchemaNode();
+            String setterInParent = schemaNode.getJavaAttributeName();
+            YdtExtendedContext parentNode =
+                    (YdtExtendedContext) leafNode.getParent();
+            YobWorkBench workBench = (YobWorkBench) parentNode.getAppInfo(YOB);
+            Object builderObject = workBench
                     .getParentBuilder(leafNode, schemaRegistry);
-            parentBldrClass = parentBuilderObject.getClass();
-            Field leafName = parentBldrClass.getDeclaredField(setterInParent);
-            Method parentSetterMethod = parentBldrClass
+            builderClass = builderObject.getClass();
+            Field leafName = builderClass.getDeclaredField(setterInParent);
+            Method setterMethod = builderClass
                     .getDeclaredMethod(setterInParent, leafName.getType());
-            JavaQualifiedTypeInfoContainer javaQualifiedType =
-                    (JavaQualifiedTypeInfoContainer) yangSchemaNode;
-            YangType<?> yangType = ((YangLeaf) javaQualifiedType).getDataType();
-            setDataFromStringValue(yangType, value, parentSetterMethod,
-                                   parentBuilderObject, leafNode);
+            YangType<?> yangType = ((YangLeaf) schemaNode).getDataType();
+            YobUtils.setDataFromStringValue(yangType, leafNode.getValue(),
+                                            setterMethod, builderObject,
+                                            leafNode);
         } catch (NoSuchMethodException | InvocationTargetException |
                 IllegalAccessException | NoSuchFieldException e) {
-            log.error(FAIL_TO_INVOKE_METHOD + parentBldrClass.getName());
+            log.error(L_FAIL_TO_INVOKE_METHOD, builderClass.getName());
+            throw new YobException(E_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
new file mode 100644
index 0000000..e8d226f
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/YobUtils.java
@@ -0,0 +1,334 @@
+/*
+ * 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.yob;
+
+import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
+import org.onosproject.yangutils.datamodel.YangBinary;
+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.yms.app.ydt.YdtExtendedContext;
+import org.onosproject.yms.app.yob.exception.YobException;
+import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+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_CONSTRUCTOR;
+import static org.onosproject.yms.app.yob.YobConstants.E_INVALID_DATA_TREE;
+import static org.onosproject.yms.app.yob.YobConstants.FROM_STRING;
+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;
+
+/**
+ * Utils to support object creation.
+ */
+final class YobUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(YobUtils.class);
+
+    // no instantiation
+    private YobUtils() {
+    }
+
+    /**
+     * Sets data from string value in parent method.
+     *
+     * @param type                refers to YANG 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
+     * @throws InvocationTargetException if failed to invoke method
+     * @throws IllegalAccessException    if member cannot be accessed
+     * @throws NoSuchMethodException     if method is not found
+     */
+    static void setDataFromStringValue(YangType<?> type, String leafValue,
+                                       Method parentSetterMethod,
+                                       Object parentBuilderObject,
+                                       YdtExtendedContext ydtExtendedContext)
+            throws InvocationTargetException, IllegalAccessException,
+            NoSuchMethodException {
+        switch (type.getDataType()) {
+            case INT8:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          Byte.parseByte(leafValue));
+                break;
+
+            case UINT8:
+            case INT16:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          Short.parseShort(leafValue));
+                break;
+
+            case UINT16:
+            case INT32:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          Integer.parseInt(leafValue));
+                break;
+
+            case UINT32:
+            case INT64:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          Long.parseLong(leafValue));
+                break;
+
+            case UINT64:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          new BigInteger(leafValue));
+                break;
+
+            case EMPTY:
+            case BOOLEAN:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          Boolean.parseBoolean(leafValue));
+                break;
+
+            case STRING:
+                parentSetterMethod.invoke(parentBuilderObject, leafValue);
+                break;
+
+            case BINARY:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          new YangBinary(leafValue));
+                break;
+
+            case BITS:
+                //TODO
+                break;
+
+            case DECIMAL64:
+                parentSetterMethod.invoke(parentBuilderObject,
+                                          new BigDecimal(leafValue));
+                break;
+
+            case DERIVED:
+                parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
+                                     parentBuilderObject, leafValue, false);
+                break;
+
+            case UNION:
+                // TODO
+                break;
+
+            case LEAFREF:
+                // TODO
+                break;
+
+            case ENUMERATION:
+                parseDerivedTypeInfo(ydtExtendedContext, parentSetterMethod,
+                                     parentBuilderObject, leafValue, true);
+                break;
+
+            default:
+                log.error(E_DATA_TYPE_NOT_SUPPORT);
+        }
+    }
+
+    /**
+     * 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
+     * @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 parseDerivedTypeInfo(YdtExtendedContext ydtExtendedContext,
+                                             Method parentSetterMethod,
+                                             Object parentBuilderObject,
+                                             String leafValue, boolean isEnum)
+            throws InvocationTargetException, IllegalAccessException,
+            NoSuchMethodException {
+        Class<?> childSetClass = null;
+        Constructor<?> childConstructor = null;
+        Object childValue = null;
+        Object childObject = null;
+        Method childMethod = null;
+
+        YangSchemaNode yangJavaModule = ydtExtendedContext.getYangSchemaNode();
+        String 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 (!isEnum) {
+
+            if (childSetClass != null) {
+                childConstructor = childSetClass.getDeclaredConstructor();
+            }
+
+            if (childConstructor != null) {
+                childConstructor.setAccessible(true);
+            }
+            try {
+                if (childConstructor != null) {
+                    childObject = childConstructor.newInstance();
+                }
+            } catch (InstantiationException e) {
+                log.error(E_FAIL_TO_LOAD_CONSTRUCTOR, qualifiedClassName);
+            }
+            if (childSetClass != null) {
+                childMethod = childSetClass
+                        .getDeclaredMethod(FROM_STRING, String.class);
+            }
+        } else {
+            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);
+    }
+
+    /**
+     * Updates class loader for all the classes.
+     *
+     * @param registry           YANG schema registry
+     * @param qualifiedClassName qualified class name
+     * @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)) {
+                curNode = (YdtExtendedContext) curNode.getParent();
+                if (curNode == null) {
+                    throw new YobException(E_INVALID_DATA_TREE);
+                }
+                curSchemaNode = curNode.getYangSchemaNode();
+
+            }
+
+            Class<?> regClass = registry.getRegisteredClass(curSchemaNode,
+                                                            qualifiedClassName);
+            return regClass.getClassLoader();
+
+        }
+
+        YdtExtendedContext parent =
+                (YdtExtendedContext) curNode.getParent();
+        YobWorkBench parentBuilderContainer =
+                (YobWorkBench) parent.getAppInfo(YOB);
+        Object parentObj =
+                parentBuilderContainer.getParentBuilder(curNode, registry);
+        return parentObj.getClass().getClassLoader();
+    }
+
+    /**
+     * Returns the class loader to be used for the switched context schema node.
+     *
+     * @param curLoader current context class loader
+     * @param context   switched context
+     * @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) {
+        YangSchemaNode augmentSchemaNode = context.getContextSwitchedNode();
+        if (augmentSchemaNode.getYangSchemaNodeType() == YANG_AUGMENT_NODE) {
+            YangSchemaNode moduleNode =
+                    ((YangNode) augmentSchemaNode).getParent();
+
+            Class<?> moduleClass = registry.getRegisteredClass(
+                    moduleNode, getCapitalCase(
+                            moduleNode.getJavaClassNameOrBuiltInType()));
+            return moduleClass.getClassLoader();
+        }
+
+        return curLoader;
+    }
+
+    /**
+     * Returns the qualified default / op param class.
+     *
+     * @param schemaNode schema node of the required class
+     * @return qualified default / op param class name
+     */
+    static String getQualifiedDefaultClass(YangSchemaNode schemaNode) {
+        String packageName = schemaNode.getJavaPackage();
+        String className = getCapitalCase(
+                schemaNode.getJavaClassNameOrBuiltInType());
+
+        if (schemaNode instanceof RpcNotificationContainer) {
+            return packageName + PERIOD + className + OP_PARAM;
+        }
+
+        return packageName + PERIOD + DEFAULT + className;
+    }
+
+    /**
+     * Returns the qualified interface name.
+     *
+     * @param schemaNode schema node of the required class
+     * @return qualified interface name
+     */
+    static String getQualifiedinterface(YangSchemaNode schemaNode) {
+        String packageName = schemaNode.getJavaPackage();
+        String className = getCapitalCase(
+                schemaNode.getJavaClassNameOrBuiltInType());
+
+        return packageName + PERIOD + className;
+    }
+}
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 89720f4..29031ff 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
@@ -16,15 +16,14 @@
 
 package org.onosproject.yms.app.yob;
 
-import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
-import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
 import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
-import org.onosproject.yms.app.yob.exception.YobExceptions;
+import org.onosproject.yms.app.yob.exception.YobException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
+import org.onosproject.yms.ydt.YdtType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,21 +38,26 @@
 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;
 import static org.onosproject.yms.app.yob.YobConstants.BUILD;
-import static org.onosproject.yms.app.yob.YobConstants.DEFAULT;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_BUILD;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_GET_FIELD;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_GET_METHOD;
-import static org.onosproject.yms.app.yob.YobConstants.FAIL_TO_INVOKE_METHOD;
-import static org.onosproject.yms.app.yob.YobConstants.HAS_NO_CHILD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_BUILD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_GET_FIELD;
+import static org.onosproject.yms.app.yob.YobConstants.E_FAIL_TO_GET_METHOD;
+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.OP_PARAM;
 import static org.onosproject.yms.app.yob.YobConstants.OP_TYPE;
-import static org.onosproject.yms.app.yob.YobConstants.PERIOD;
-import static org.onosproject.yms.app.yob.YobConstants.SET_OP_TYPE_FAIL;
 import static org.onosproject.yms.app.yob.YobConstants.VALUE_OF;
 import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
+import static org.onosproject.yms.ydt.YdtType.SINGLE_INSTANCE_NODE;
 
 /**
  * Represents the YANG object builder's work bench corresponding to a YANG data
@@ -61,8 +65,8 @@
  */
 class YobWorkBench {
 
-    private static final Logger log
-            = LoggerFactory.getLogger(YobWorkBench.class);
+    private static final Logger log =
+            LoggerFactory.getLogger(YobWorkBench.class);
 
     /**
      * Class loader to be used to load the class.
@@ -72,8 +76,8 @@
     /**
      * Map of the non schema descendant objects.
      */
-    private Map<YangSchemaNodeIdentifier, YobWorkBench> attributeMap
-            = new HashMap<>();
+    private Map<YangSchemaNodeIdentifier, YobWorkBench> attributeMap =
+            new HashMap<>();
 
     /**
      * Reference for data-model schema node.
@@ -104,8 +108,8 @@
         this.yangSchemaNode = yangSchemaNode;
         this.classLoader = classLoader;
         this.setterInParent = setterInParent;
-        this.builderOrBuiltObject
-                = new YobBuilderOrBuiltObject(qualifiedClassName, classLoader);
+        this.builderOrBuiltObject =
+                new YobBuilderOrBuiltObject(qualifiedClassName, classLoader);
     }
 
     /**
@@ -121,168 +125,124 @@
     /**
      * Returns the parent builder object in which the child object can be set.
      *
-     * @param childNode child YDT node
-     * @param registry  schema registry
+     * @param node     child YDT node
+     * @param registry schema registry
      * @return parent builder object
-     * @throws YobExceptions schema node does not have child
+     * @throws YobException if schema node does not have child
      */
-    Object getParentBuilder(YdtExtendedContext childNode,
+    Object getParentBuilder(YdtExtendedContext node,
                             YangSchemaRegistry registry) {
 
         // Descendant schema node for whom the builder is required.
-        YangSchemaNodeIdentifier targetNode = childNode
-                .getYangSchemaNode().getYangSchemaNodeIdentifier();
+        YangSchemaNodeIdentifier targetNode =
+                node.getYangSchemaNode().getYangSchemaNodeIdentifier();
 
         //Current builder container
         YobWorkBench curWorkBench = this;
 
-        //Current Schema node context
-        YangSchemaNodeContextInfo schemaContext;
+        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 YobExceptions(yangSchemaNode.getName() +
-                                                HAS_NO_CHILD +
-                                                targetNode.getName());
+                throw new YobException(yangSchemaNode.getName() +
+                                               E_HAS_NO_CHILD +
+                                               targetNode.getName());
             }
 
+            nonSchemaHolder = schemaContext.getContextSwitchedNode();
+
             //If the descendant schema node is in switched context
-            if (schemaContext.getContextSwitchedNode() != null) {
+            if (nonSchemaHolder != null) {
+
+                YangSchemaNodeIdentifier nonSchemaIdentifier =
+                        nonSchemaHolder.getYangSchemaNodeIdentifier();
 
                 //check if the descendant builder container is already available
-                YobWorkBench childWorkBench
-                        = curWorkBench.attributeMap.get(targetNode);
+                YobWorkBench childWorkBench =
+                        curWorkBench.attributeMap.get(nonSchemaIdentifier);
 
                 if (childWorkBench == null) {
                     YobWorkBench newWorkBench = getNewChildWorkBench(
                             schemaContext, targetNode, curWorkBench, registry);
 
-                    //TODO: When choice and case support is added, confirm with
-                    // UT, the workbench is for case and not for choice
-
-                    curWorkBench.attributeMap.put(targetNode, newWorkBench);
+                    curWorkBench.attributeMap.put(nonSchemaIdentifier,
+                                                  newWorkBench);
                     curWorkBench = newWorkBench;
                 } else {
                     curWorkBench = childWorkBench;
                 }
             }
 
-        } while (schemaContext.getContextSwitchedNode() != null);
+        } while (nonSchemaHolder != null);
 
         return curWorkBench.builderOrBuiltObject.getBuilderObject();
     }
 
     /**
-     * Creates a new builder container object corresponding to a context
-     * switch schema node.
-     *
-     * @param childContext schema context of immediate child
-     * @param targetNode   final node whose parent builder is
-     *                     required
-     * @param curWorkBench current context builder container
-     * @param registry     schema registry
-     * @return new builder container object corresponding to a context
-     * switch schema node
-     */
-    private YobWorkBench getNewChildWorkBench(
-            YangSchemaNodeContextInfo childContext,
-            YangSchemaNodeIdentifier targetNode, YobWorkBench curWorkBench,
-            YangSchemaRegistry registry) {
-
-        YangSchemaNode ctxSwitchedNode = childContext.getContextSwitchedNode();
-
-         /*This is the first child trying to set its object in the
-         current context. */
-        String setterInParent = ctxSwitchedNode.getJavaAttributeName();
-
-        /* If current switched context is choice, then case class needs to be
-         used. */
-        if (ctxSwitchedNode.getYangSchemaNodeType() == YANG_CHOICE_NODE) {
-            try {
-                childContext = ctxSwitchedNode.getChildSchema(targetNode);
-            } catch (DataModelException e) {
-                throw new YobExceptions(yangSchemaNode.getName() +
-                                                HAS_NO_CHILD +
-                                                targetNode.getName());
-            }
-        }
-
-        ClassLoader newClassesLoader = getTargetClassLoader(
-                curWorkBench.classLoader, childContext, registry);
-
-        return new YobWorkBench(ctxSwitchedNode, newClassesLoader,
-                                getQualifiedDefaultClassName(
-                                        childContext.getSchemaNode()),
-                                setterInParent);
-    }
-
-    /**
-     * Returns the qualified default / op param class.
-     *
-     * @param schemaNode schema node of the required class
-     * @return qualified default / op param class name
-     */
-    static String getQualifiedDefaultClassName(YangSchemaNode schemaNode) {
-        String packageName = schemaNode.getJavaPackage();
-        String className = getCapitalCase(
-                schemaNode.getJavaClassNameOrBuiltInType());
-
-        if (schemaNode instanceof RpcNotificationContainer) {
-            return packageName + PERIOD + className + OP_PARAM;
-        }
-
-        return packageName + PERIOD + DEFAULT + className;
-    }
-
-    /**
-     * Returns the class loader to be used for the switched context schema node.
-     *
-     * @param currentClassLoader current context class loader
-     * @param switchedContext    switched context
-     * @param registry           schema registry
-     * @return class loader to be used for the switched context schema node
-     */
-    private ClassLoader getTargetClassLoader(
-            ClassLoader currentClassLoader,
-            YangSchemaNodeContextInfo switchedContext,
-            YangSchemaRegistry registry) {
-        YangSchemaNode augmentSchemaNode = switchedContext.getSchemaNode();
-        if (augmentSchemaNode.getYangSchemaNodeType() ==
-                YANG_AUGMENT_NODE) {
-            YangSchemaNode parentSchemaNode =
-                    ((YangNode) augmentSchemaNode).getParent();
-
-            Class<?> regClass = registry.getRegisteredClass(
-                    parentSchemaNode, getCapitalCase(
-                            parentSchemaNode.getJavaClassNameOrBuiltInType()));
-            return regClass.getClassLoader();
-        }
-
-        return currentClassLoader;
-    }
-
-    /**
      * Set the operation type attribute and build the object from the builder
      * object, by invoking the build method.
      *
-     * @param ydtNode     data tree node
-     * @param ydtRootNode root node
+     * @param ydtNode data tree node
+     * @throws YobException if member method is not found or failed to build
      */
-    void buildObject(YdtExtendedContext ydtNode,
-                     YdtExtendedContext ydtRootNode) {
+    void buildObject(YdtExtendedContext ydtNode) {
+
+        buildNonSchemaAttributes(ydtNode);
+
         Object builderObject = builderOrBuiltObject.getBuilderObject();
         Class<?> defaultBuilderClass = builderOrBuiltObject.yangBuilderClass;
-        Class<?> interfaceClass = builderOrBuiltObject.yangDefaultClass;
-        Object operationType;
+
+        //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)) {
@@ -301,92 +261,206 @@
             }
         } catch (NoSuchFieldException | NoSuchMethodException |
                 InvocationTargetException | IllegalAccessException e) {
-            log.error(SET_OP_TYPE_FAIL);
-            throw new YobExceptions(SET_OP_TYPE_FAIL);
-        }
-
-
-        // Invoking the build method to get built object from build method.
-        try {
-            Method method = defaultBuilderClass.getDeclaredMethod(BUILD);
-            if (method == null) {
-                log.error(FAIL_TO_GET_METHOD + defaultBuilderClass.getName());
-                throw new YobExceptions(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(FAIL_TO_BUILD + defaultBuilderClass.getName());
-            throw new YobExceptions(FAIL_TO_BUILD +
-                                            defaultBuilderClass.getName());
-        }
-
-        // The current ydt context node and root node are same then return.
-        if (!ydtNode.equals(ydtRootNode)) {
-            invokeSetObjectInParent(ydtNode);
+            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
      */
-    private void invokeSetObjectInParent(YdtExtendedContext ydtNode) {
-        Class<?> classType = null;
-        Method method;
-
+    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();
 
-        YdtExtendedContext parentNode = (YdtExtendedContext) ydtNode
-                .getParent();
-        if (parentNode != null) {
-            YobWorkBench parentYobWorkBench = (YobWorkBench)
-                    parentNode.getAppInfo(YOB);
-            Object parentBuilderObject = parentYobWorkBench
-                    .builderOrBuiltObject.getBuilderObject();
+        // set the object in the parent builder
+        setObjectInBuilder(parentBuilderObject, setterInParent, nodeType,
+                           objectToSetInParent);
 
-            Class<?> parentBuilderClass = parentBuilderObject.getClass();
-            String parentBuilderClassName = parentBuilderClass.getName();
-
-            try {
-                Field fieldName = parentBuilderClass
-                        .getDeclaredField(setterInParent);
-                if (fieldName != null) {
-                    classType = fieldName.getType();
-                }
-
-                if (ydtNode.getYdtType() == MULTI_INSTANCE_NODE) {
-                    if (fieldName != null) {
-                        ParameterizedType genericListType =
-                                (ParameterizedType) fieldName.getGenericType();
-                        classType = (Class<?>) genericListType
-                                .getActualTypeArguments()[0];
-                    }
-                    method = parentBuilderClass.getDeclaredMethod(
-                            ADD_TO + getCapitalCase(setterInParent), classType);
-                } else {
-                    method = parentBuilderClass.getDeclaredMethod(
-                            setterInParent, classType);
-                }
-
-                if (method != null) {
-                    method.invoke(parentBuilderObject, objectToSetInParent);
-                }
-            } catch (NoSuchFieldException e) {
-                log.error(FAIL_TO_GET_FIELD + parentBuilderClassName);
-            } catch (NoSuchMethodException e) {
-                log.error(FAIL_TO_GET_METHOD + parentBuilderClassName);
-            } catch (InvocationTargetException | IllegalAccessException e) {
-                log.error(FAIL_TO_INVOKE_METHOD + parentBuilderClassName);
-            }
-        }
         ydtNode.addAppInfo(YOB, this);
     }
+
+    /**
+     * Set the attribute in a builder object.
+     *
+     * @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) {
+        Class<?> builderClass = builder.getClass();
+        String builderClassName = builderClass.getName();
+        try {
+            Class<?> type = null;
+            Field fieldName = builderClass.getDeclaredField(setter);
+            if (fieldName != null) {
+                type = fieldName.getType();
+            }
+
+            Method method;
+            if (nodeType == MULTI_INSTANCE_NODE) {
+                if (fieldName != null) {
+                    ParameterizedType genericTypes =
+                            (ParameterizedType) fieldName.getGenericType();
+                    type = (Class<?>) genericTypes.getActualTypeArguments()[0];
+                }
+                method = builderClass.getDeclaredMethod(
+                        ADD_TO + getCapitalCase(setter), type);
+            } else {
+                method = builderClass.getDeclaredMethod(setter, type);
+            }
+
+            method.invoke(builder, attribute);
+        } catch (NoSuchFieldException e) {
+            log.error(L_FAIL_TO_GET_FIELD, builderClassName);
+            throw new YobException(E_FAIL_TO_GET_FIELD + builderClassName);
+        } catch (NoSuchMethodException e) {
+            log.error(L_FAIL_TO_GET_METHOD, builderClassName);
+            throw new YobException(E_FAIL_TO_GET_METHOD + builderClassName);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            log.error(L_FAIL_TO_INVOKE_METHOD, builderClassName);
+            throw new YobException(E_FAIL_TO_INVOKE_METHOD + builderClassName);
+        }
+    }
+
+    private static void addInAugmentation(Object builder, String className,
+                                          Object instance) {
+        Class<?>[] interfaces = instance.getClass().getInterfaces();
+        if (interfaces == null) {
+            throw new YobException(E_FAIL_TO_LOAD_CLASS + className);
+        }
+
+        int i;
+        for (i = 0; i < interfaces.length; i++) {
+            if (interfaces[i].getName().equals(className)) {
+                break;
+            }
+        }
+        if (i == interfaces.length) {
+            throw new YobException(E_FAIL_TO_LOAD_CLASS + className);
+        }
+
+        Class<?> builderClass = builder.getClass();
+        String builderClassName = builderClass.getName();
+        try {
+
+            Method method = builderClass.getDeclaredMethod(ADD_AUGMENT_METHOD,
+                                                           Object.class,
+                                                           Class.class);
+            method.invoke(builder, instance, interfaces[i]);
+        } catch (NoSuchMethodException e) {
+            log.error(L_FAIL_TO_GET_METHOD, builderClassName);
+            throw new YobException(E_FAIL_TO_GET_METHOD + builderClassName);
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            log.error(L_FAIL_TO_INVOKE_METHOD, builderClassName);
+            throw new YobException(E_FAIL_TO_INVOKE_METHOD + builderClassName);
+        }
+
+    }
+
+
+    /**
+     * Creates a new builder container object corresponding to a context
+     * switch schema node.
+     *
+     * @param childContext schema context of immediate child
+     * @param targetNode   final node whose parent builder is
+     *                     required
+     * @param curWorkBench current context builder container
+     * @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,
+            YangSchemaNodeIdentifier targetNode, YobWorkBench curWorkBench,
+            YangSchemaRegistry registry) {
+
+        YangSchemaNode ctxSwitchedNode = childContext.getContextSwitchedNode();
+        String name;
+
+         /*This is the first child trying to set its object in the
+         current context. */
+        String setterInParent = ctxSwitchedNode.getJavaAttributeName();
+
+        /* If current switched context is choice, then case class needs to be
+         used. */
+        if (ctxSwitchedNode.getYangSchemaNodeType() == YANG_CHOICE_NODE) {
+            try {
+                childContext = ctxSwitchedNode.getChildSchema(targetNode);
+                ctxSwitchedNode = childContext.getContextSwitchedNode();
+                name = YobUtils.getQualifiedDefaultClass(
+                        childContext.getContextSwitchedNode());
+
+            } catch (DataModelException e) {
+                throw new YobException(ctxSwitchedNode.getName() +
+                                               E_HAS_NO_CHILD +
+                                               targetNode.getName());
+            }
+        } else if (ctxSwitchedNode.getYangSchemaNodeType() ==
+                YANG_AUGMENT_NODE) {
+            name = YobUtils.getQualifiedDefaultClass(ctxSwitchedNode);
+            setterInParent = YobUtils.getQualifiedinterface(ctxSwitchedNode);
+        } else {
+            name = YobUtils.getQualifiedDefaultClass(childContext.getSchemaNode());
+        }
+
+        ClassLoader newClassesLoader = YobUtils.getTargetClassLoader(
+                curWorkBench.classLoader, childContext, registry);
+
+        return new YobWorkBench(ctxSwitchedNode, newClassesLoader, name,
+                                setterInParent);
+    }
+
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobExceptions.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobException.java
similarity index 93%
rename from apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobExceptions.java
rename to apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobException.java
index b7e5bb5..e8ce1a0 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobExceptions.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/yob/exception/YobException.java
@@ -19,7 +19,7 @@
 /**
  * Represents base class for exceptions in YOB operations.
  */
-public class YobExceptions
+public class YobException
         extends RuntimeException {
 
     private static final long serialVersionUID = 20160211L;
@@ -29,7 +29,7 @@
      *
      * @param message the detail of exception in string
      */
-    public YobExceptions(String message) {
+    public YobException(String message) {
         super(message);
     }
 }