[ONOS-5693] YTB upgrade and defect fixes

Change-Id: I10d690bfd6e135a048c24946bfdd3839a0dae579
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YangRequestWorkBench.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YangRequestWorkBench.java
index dc36028..75e00f2 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YangRequestWorkBench.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YangRequestWorkBench.java
@@ -25,7 +25,6 @@
 import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
 import org.onosproject.yms.app.ydt.exceptions.YdtException;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
-import org.onosproject.yms.ydt.YdtContext;
 import org.onosproject.yms.ydt.YdtContextOperationType;
 import org.onosproject.yms.ydt.YdtType;
 import org.onosproject.yms.ydt.YmsOperationType;
@@ -593,7 +592,7 @@
     }
 
     @Override
-    public YdtContext getCurNode() {
+    public YdtExtendedContext getCurNode() {
         return curNode;
     }
 
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtExtendedBuilder.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtExtendedBuilder.java
index 19aacb5..d7904ee 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtExtendedBuilder.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtExtendedBuilder.java
@@ -72,4 +72,7 @@
 
     @Override
     YdtExtendedContext getRootNode();
+
+    @Override
+    YdtExtendedContext getCurNode();
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilder.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilder.java
index 6f8df8e..0e2a3ce 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilder.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/DefaultYangTreeBuilder.java
@@ -20,7 +20,6 @@
 import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
-import org.onosproject.yms.ydt.YdtContext;
 import org.onosproject.yms.ydt.YmsOperationType;
 
 import java.util.List;
@@ -47,12 +46,11 @@
     }
 
     @Override
-    public YdtExtendedBuilder getYdtBuilderForYo(
-            List<Object> moduleObj, String rootName,
-            String rootNameSpace, YmsOperationType opType,
-            YangSchemaRegistry registry) {
+    public YdtExtendedBuilder getYdtBuilderForYo(List<Object> moduleObj, String rootName,
+                                                 String rootNameSpace, YmsOperationType opType,
+                                                 YangSchemaRegistry registry) {
 
-        if (moduleObj == null || moduleObj.isEmpty()) {
+        if (moduleObj == null) {
             throw new YtbException(emptyObjErrMsg(OBJ_LIST));
         }
 
@@ -70,8 +68,8 @@
     }
 
     @Override
-    public YdtContext getYdtForNotification(Object object, String rootName,
-                                            YangSchemaRegistry registry) {
+    public YdtExtendedContext getYdtForNotification(Object object, String rootName,
+                                                    YangSchemaRegistry registry) {
 
         if (object == null) {
             throw new YtbException(emptyObjErrMsg(EVENT_OBJ));
@@ -93,13 +91,15 @@
     }
 
     @Override
-    public YdtExtendedBuilder getYdtForRpcResponse(
-            Object outputObj, YangRequestWorkBench workBench) {
+    public YdtExtendedBuilder getYdtForRpcResponse(Object outputObj,
+                                                   YdtExtendedBuilder reqBuilder) {
 
         if (outputObj == null) {
             throw new YtbException(emptyObjErrMsg(OUTPUT_OBJ));
         }
 
+        YangRequestWorkBench workBench = (YangRequestWorkBench) reqBuilder;
+
         // Gets the logical root node from RPC request work bench.
         YdtExtendedContext rootNode = workBench.getRootNode();
 
@@ -107,12 +107,13 @@
          * Creates a new work bench for RPC reply from the contents of the
          * request work bench
          */
-        YdtExtendedBuilder ydtBuilder = new YangRequestWorkBench(
-                rootNode.getName(), rootNode.getNamespace(),
-                RPC_REPLY, workBench.getYangSchemaRegistry(), false);
-        YdtBuilderFromYo moduleBuilder = new YdtBuilderFromYo(
-                ydtBuilder, outputObj,
-                workBench.getYangSchemaRegistry());
+        YdtExtendedBuilder ydtBuilder =
+                new YangRequestWorkBench(null, null, RPC_REPLY,
+                                         workBench.getYangSchemaRegistry(),
+                                         false);
+        YdtBuilderFromYo moduleBuilder =
+                new YdtBuilderFromYo(ydtBuilder, outputObj,
+                                     workBench.getYangSchemaRegistry());
 
         // Forms YDT till RPC, so that output can further enhance the tree.
         moduleBuilder.createModuleAndRpcInYdt(rootNode);
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YangTreeBuilder.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YangTreeBuilder.java
index 2c1df67..3f4fc0c 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YangTreeBuilder.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YangTreeBuilder.java
@@ -16,10 +16,9 @@
 
 package org.onosproject.yms.app.ytb;
 
-import org.onosproject.yms.app.ydt.YangRequestWorkBench;
 import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
+import org.onosproject.yms.app.ydt.YdtExtendedContext;
 import org.onosproject.yms.app.ysr.YangSchemaRegistry;
-import org.onosproject.yms.ydt.YdtContext;
 import org.onosproject.yms.ydt.YmsOperationType;
 
 import java.util.List;
@@ -36,8 +35,8 @@
      * YCH.
      *
      * @param moduleObj     application module object
-     * @param rootName      root node name
-     * @param rootNameSpace root node namespace
+     * @param rootName      logical root node name
+     * @param rootNameSpace logical root node namespace
      * @param opType        root node operation type
      * @param registry      application schema registry
      * @return YDT builder from the tree
@@ -53,22 +52,22 @@
      * protocol YNH.
      *
      * @param object   application notification object
-     * @param rootName root node name
+     * @param rootName logical root node name
      * @param registry application schema registry
      * @return YDT context from the tree
      */
-    YdtContext getYdtForNotification(Object object, String rootName,
-                                     YangSchemaRegistry registry);
+    YdtExtendedContext getYdtForNotification(Object object, String rootName,
+                                             YangSchemaRegistry registry);
 
     /**
      * Returns the YDT context after building the RPC response tree. The input
-     * for building the tree is RPC request workbench, RPC output java object.
+     * for building the tree is RPC request builder, RPC output java object.
      * These are received from the YSB protocol.
      *
-     * @param outputObj application output object
-     * @param workBench RPC request workbench from YDT
+     * @param outputObj  application output object
+     * @param reqBuilder RPC request builder from YDT
      * @return YDT builder where RPC response tree is created
      */
     YdtExtendedBuilder getYdtForRpcResponse(Object outputObj,
-                                            YangRequestWorkBench workBench);
+                                            YdtExtendedBuilder reqBuilder);
 }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YdtBuilderFromYo.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YdtBuilderFromYo.java
index a82eea2..10874f0 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YdtBuilderFromYo.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YdtBuilderFromYo.java
@@ -20,13 +20,17 @@
 import org.onosproject.yangutils.datamodel.YangAugmentableNode;
 import org.onosproject.yangutils.datamodel.YangCase;
 import org.onosproject.yangutils.datamodel.YangChoice;
+import org.onosproject.yangutils.datamodel.YangDerivedInfo;
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 import org.onosproject.yms.app.utils.TraversalType;
 import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
 import org.onosproject.yms.app.ydt.YdtExtendedContext;
@@ -34,12 +38,14 @@
 import org.onosproject.yms.ydt.YdtContextOperationType;
 
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
 import static org.onosproject.yms.app.utils.TraversalType.CHILD;
 import static org.onosproject.yms.app.utils.TraversalType.PARENT;
 import static org.onosproject.yms.app.utils.TraversalType.ROOT;
@@ -49,20 +55,20 @@
 import static org.onosproject.yms.app.ytb.YtbUtil.STR_NULL;
 import static org.onosproject.yms.app.ytb.YtbUtil.getAttributeFromInheritance;
 import static org.onosproject.yms.app.ytb.YtbUtil.getAttributeOfObject;
-import static org.onosproject.yms.app.ytb.YtbUtil.getCapitalCase;
 import static org.onosproject.yms.app.ytb.YtbUtil.getClassLoaderForAugment;
 import static org.onosproject.yms.app.ytb.YtbUtil.getInterfaceClassFromImplClass;
 import static org.onosproject.yms.app.ytb.YtbUtil.getJavaName;
-import static org.onosproject.yms.app.ytb.YtbUtil.getOperationTypeOfTheNode;
+import static org.onosproject.yms.app.ytb.YtbUtil.getNodeOpType;
+import static org.onosproject.yms.app.ytb.YtbUtil.getOpTypeName;
 import static org.onosproject.yms.app.ytb.YtbUtil.getParentObjectOfNode;
-import static org.onosproject.yms.app.ytb.YtbUtil.getStringFromDataType;
+import static org.onosproject.yms.app.ytb.YtbUtil.getStringFromType;
 import static org.onosproject.yms.app.ytb.YtbUtil.isAugmentNode;
 import static org.onosproject.yms.app.ytb.YtbUtil.isMultiInstanceNode;
 import static org.onosproject.yms.app.ytb.YtbUtil.isNodeProcessCompleted;
-import static org.onosproject.yms.app.ytb.YtbUtil.isNonEmpty;
 import static org.onosproject.yms.app.ytb.YtbUtil.isNonProcessableNode;
 import static org.onosproject.yms.app.ytb.YtbUtil.isTypePrimitive;
 import static org.onosproject.yms.app.ytb.YtbUtil.isValueOrSelectLeafSet;
+import static org.onosproject.yms.app.ytb.YtbUtil.nonEmpty;
 import static org.onosproject.yms.ydt.YdtContextOperationType.NONE;
 
 /**
@@ -79,6 +85,7 @@
     private static final String OUTPUT = "output";
     private static final String YANG_AUGMENTED_INFO_MAP =
             "yangAugmentedInfoMap";
+    private static final String FALSE = "false";
 
     /**
      * Application YANG schema registry.
@@ -319,6 +326,7 @@
                     continue;
                 }
                 curTraversal = SIBLING;
+                augmentNodeInfo = null;
                 traverseToParent(curNode);
                 curNode = curNode.getNextSibling();
                 if (isNonProcessableNode(curNode)) {
@@ -398,7 +406,7 @@
         if (augmentNodeInfo == null) {
             List<YangAugment> augmentList = ((YangAugmentableNode) curNode)
                     .getAugmentedInfoList();
-            if (isNonEmpty(augmentList)) {
+            if (nonEmpty(augmentList)) {
                 YtbNodeInfo parentNodeInfo = getParentYtbInfo();
                 Iterator<YangAugment> augmentItr = augmentList.listIterator();
                 parentNodeInfo.setAugmentIterator(augmentItr);
@@ -504,7 +512,7 @@
         if (listNodeInfo == null) {
             List<Object> childObjList = (List<Object>) getChildObject(
                     curNode, parentNodeInfo);
-            if (isNonEmpty(childObjList)) {
+            if (nonEmpty(childObjList)) {
                 Iterator<Object> listItr = childObjList.iterator();
                 if (!listItr.hasNext()) {
                     return null;
@@ -635,8 +643,7 @@
      * @return parent node YTB node info
      */
     private YtbNodeInfo getParentYtbInfo() {
-        YdtExtendedContext parentExtContext =
-                (YdtExtendedContext) extBuilder.getCurNode();
+        YdtExtendedContext parentExtContext = extBuilder.getCurNode();
         return (YtbNodeInfo) parentExtContext.getAppInfo(YTB);
     }
 
@@ -670,10 +677,10 @@
      */
     private void addChildNodeInYdt(Object childObj, YangNode curNode,
                                    YtbNodeInfo curNodeInfo) {
-        YdtContextOperationType opType = getOperationTypeOfTheNode(childObj);
+        YdtContextOperationType opType =
+                getNodeOpType(childObj, getOpTypeName(curNode));
         extBuilder.addChild(opType, curNode);
-        YdtExtendedContext curExtContext = (YdtExtendedContext) extBuilder
-                .getCurNode();
+        YdtExtendedContext curExtContext = extBuilder.getCurNode();
         curNodeInfo.setYangObject(childObj);
         curExtContext.addAppInfo(YTB, curNodeInfo);
     }
@@ -702,17 +709,15 @@
                         throw new YtbException(e);
                     }
 
-                    addLeafWithValue(yangLeaf, parentObj, leafType);
-                    addLeafWithoutValue(yangLeaf, parentObj);
+                    addLeafWithValue(yangNode, yangLeaf, parentObj, leafType);
+                    addLeafWithoutValue(yangNode, yangLeaf, parentObj);
                 }
             }
         }
     }
 
     /**
-     * Processes every leaf-list in a YANG node. For each leaf-list, the list of
-     * objects are iterated, value from each object is put in a set of string,
-     * and is added to the YDT.
+     * Processes every leaf-list in a YANG node for adding the value in YDT.
      *
      * @param yangNode list of leaf-list holder node
      */
@@ -723,39 +728,81 @@
 
             if (listOfLeafList != null) {
                 for (YangLeafList yangLeafList : listOfLeafList) {
-
-                    YtbNodeInfo ytbNodeInfo = getParentYtbInfo();
-                    Object parentObj = getParentObjectOfNode(ytbNodeInfo,
-                                                             yangNode);
-
-                    //TODO: Let the received object list be generic collection.
-                    List<Object> leafListObj;
-                    try {
-                        leafListObj = (List<Object>) getAttributeOfObject(
-                                parentObj, getJavaName(yangLeafList));
-                    } catch (NoSuchMethodException e) {
-                        throw new YtbException(e);
-                    }
-                    Set<String> leafListValue = new HashSet<>();
-                    /*
-                     * If list is present, then adds each object value in set.
-                     * Adds this set to the YDT, and traverse to parent.
-                     */
-                    if (leafListObj != null) {
-                        for (Object object : leafListObj) {
-                            String objValue = getStringFromDataType(
-                                    object, yangLeafList.getDataType());
-                            leafListValue.add(objValue);
-                        }
-                        extBuilder.addLeafList(leafListValue, yangLeafList);
-                        extBuilder.traverseToParentWithoutValidation();
-                    }
+                    addToBuilder(yangNode, yangLeafList);
                 }
             }
         }
     }
 
     /**
+     * Processes the list of objects of the leaf list and adds the leaf list
+     * value to the builder.
+     *
+     * @param yangNode YANG node
+     * @param leafList YANG leaf list
+     */
+    private void addToBuilder(YangNode yangNode, YangLeafList leafList) {
+        YtbNodeInfo ytbNodeInfo = getParentYtbInfo();
+        Object parentObj = getParentObjectOfNode(ytbNodeInfo, yangNode);
+        List<Object> obj;
+        try {
+            obj = (List<Object>) getAttributeOfObject(parentObj,
+                                                      getJavaName(leafList));
+        } catch (NoSuchMethodException e) {
+            throw new YtbException(e);
+        }
+        if (obj != null) {
+            addLeafListValue(yangNode, parentObj, leafList, obj);
+        }
+    }
+
+    /**
+     * Adds the leaf list value to the YDT builder by taking the string value
+     * from the data type.
+     *
+     * @param yangNode  YANG node
+     * @param parentObj parent object
+     * @param leafList  YANG leaf list
+     * @param obj       list of objects
+     */
+    private void addLeafListValue(YangNode yangNode, Object parentObj,
+                                  YangLeafList leafList, List<Object> obj) {
+
+        Set<String> leafListVal = new LinkedHashSet<>();
+        boolean isEmpty = false;
+        for (Object object : obj) {
+            String val = getStringFromType(yangNode, parentObj,
+                                           getJavaName(leafList), object,
+                                           leafList.getDataType());
+            isEmpty = isTypeEmpty(val, leafList.getDataType());
+            if (isEmpty) {
+                if (val.equals(TRUE)) {
+                    addLeafList(leafListVal, leafList);
+                }
+                break;
+            }
+            if (!val.equals("")) {
+                leafListVal.add(val);
+            }
+        }
+        if (!isEmpty && !leafListVal.isEmpty()) {
+            addLeafList(leafListVal, leafList);
+        }
+    }
+
+    /**
+     * Adds set of leaf list values in the builder and traverses back to the
+     * holder.
+     *
+     * @param leafListVal set of values
+     * @param leafList    YANG leaf list
+     */
+    private void addLeafList(Set<String> leafListVal, YangLeafList leafList) {
+        extBuilder.addLeafList(leafListVal, leafList);
+        extBuilder.traverseToParentWithoutValidation();
+    }
+
+    /**
      * Returns the schema node of notification from the root node. Gets the
      * enum value from event object and gives it to the root schema node for
      * getting back the notification schema node.
@@ -763,9 +810,8 @@
      * @return YANG schema node of notification
      */
     private YangSchemaNode getSchemaNodeOfNotification() {
-        Class parentClass = rootObj.getClass().getSuperclass();
-        Object eventObjType = getAttributeFromInheritance(
-                parentClass, rootObj, STR_TYPE);
+
+        Object eventObjType = getAttributeFromInheritance(rootObj, STR_TYPE);
         String opTypeValue = String.valueOf(eventObjType);
 
         if (opTypeValue.equals(STR_NULL) || opTypeValue.isEmpty()) {
@@ -787,9 +833,9 @@
      * @return notification YANG object
      */
     private Object getObjOfNotification() {
-        Class parentClass = rootObj.getClass().getSuperclass();
-        Object eventSubjectObj = getAttributeFromInheritance(
-                parentClass, rootObj, STR_SUBJECT);
+
+        Object eventSubjectObj =
+                getAttributeFromInheritance(rootObj, STR_SUBJECT);
         String notificationName = rootSchema.getJavaAttributeName();
         try {
             return getAttributeOfObject(eventSubjectObj, notificationName);
@@ -824,39 +870,92 @@
      * to avoid default values, the value select is set or not is checked and
      * then added.
      *
+     * @param holder    leaf holder
      * @param yangLeaf  YANG leaf node
      * @param parentObj leaf holder object
      * @param leafType  object of leaf type
      */
-    private void addLeafWithValue(YangLeaf yangLeaf, Object parentObj,
-                                  Object leafType) {
+    private void addLeafWithValue(YangSchemaNode holder, YangLeaf yangLeaf,
+                                  Object parentObj, Object leafType) {
         String fieldValue = null;
         if (isTypePrimitive(yangLeaf.getDataType())) {
-            fieldValue = getLeafValueFromValueSetFlag(parentObj, yangLeaf,
-                                                      leafType);
+            fieldValue = getLeafValueFromValueSetFlag(holder, parentObj,
+                                                      yangLeaf, leafType);
             /*
              * Checks the object is present or not, when type is
              * non-primitive. And adds the value from the respective data type.
              */
         } else if (leafType != null) {
-            fieldValue = getStringFromDataType(leafType,
-                                               yangLeaf.getDataType());
+            fieldValue = getStringFromType(holder, parentObj,
+                                           getJavaName(yangLeaf), leafType,
+                                           yangLeaf.getDataType());
         }
-        if (isNonEmpty(fieldValue)) {
+
+        if (nonEmpty(fieldValue)) {
+            boolean isEmpty = isTypeEmpty(fieldValue,
+                                          yangLeaf.getDataType());
+            if (isEmpty) {
+                if (!fieldValue.equals(TRUE)) {
+                    return;
+                }
+                fieldValue = null;
+            }
             extBuilder.addLeaf(fieldValue, yangLeaf);
             extBuilder.traverseToParentWithoutValidation();
         }
     }
 
     /**
+     * Returns the value as true if direct or referred type from leafref or
+     * derived points to empty data type; false otherwise.
+     *
+     * @param fieldValue value of the leaf
+     * @param dataType   type of the leaf
+     * @return true if type is empty; false otherwise.
+     */
+    private boolean isTypeEmpty(String fieldValue, YangType<?> dataType) {
+        if (fieldValue.equals(TRUE) || fieldValue.equals(FALSE)) {
+            switch (dataType.getDataType()) {
+                case EMPTY:
+                    return true;
+
+                case LEAFREF:
+                    YangLeafRef leafRef =
+                            (YangLeafRef) dataType.getDataTypeExtendedInfo();
+                    return isTypeEmpty(fieldValue,
+                                       leafRef.getEffectiveDataType());
+                case DERIVED:
+                    YangDerivedInfo info =
+                            (YangDerivedInfo) dataType
+                                    .getDataTypeExtendedInfo();
+                    YangDataTypes type = info.getEffectiveBuiltInType();
+                    return type == EMPTY;
+
+                default:
+                    return false;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Adds leaf without value, when the select leaf bit is set.
      *
+     * @param holder    leaf holder
      * @param yangLeaf  YANG leaf node
      * @param parentObj leaf holder object
      */
-    private void addLeafWithoutValue(YangLeaf yangLeaf, Object parentObj) {
-        String selectLeaf = isValueOrSelectLeafSet(
-                parentObj, getJavaName(yangLeaf), IS_SELECT_LEAF_SET_METHOD);
+    private void addLeafWithoutValue(YangSchemaNode holder, YangLeaf yangLeaf,
+                                     Object parentObj) {
+
+        String selectLeaf;
+        try {
+            selectLeaf = isValueOrSelectLeafSet(holder, parentObj,
+                                                getJavaName(yangLeaf),
+                                                IS_SELECT_LEAF_SET_METHOD);
+        } catch (NoSuchMethodException e) {
+            selectLeaf = FALSE;
+        }
         if (selectLeaf.equals(TRUE)) {
             extBuilder.addLeaf(null, yangLeaf);
             extBuilder.traverseToParentWithoutValidation();
@@ -864,20 +963,30 @@
     }
 
     /**
-     * Returns the value of type, after checking, the value leaf flag. If the
-     * flag is set, then it takes the value or returns null.
+     * Returns the value of type, after checking the value leaf flag. If the
+     * flag is set, then it takes the value else returns null.
      *
+     * @param holder    leaf holder
      * @param parentObj parent object
      * @param yangLeaf  YANG leaf node
      * @param leafType  object of leaf type
      * @return value of type
      */
-    private String getLeafValueFromValueSetFlag(
-            Object parentObj, YangLeaf yangLeaf, Object leafType) {
-        String valueOfLeaf = isValueOrSelectLeafSet(
-                parentObj, getJavaName(yangLeaf), IS_LEAF_VALUE_SET_METHOD);
+    private String getLeafValueFromValueSetFlag(YangSchemaNode holder, Object parentObj,
+                                                YangLeaf yangLeaf, Object leafType) {
+
+        String valueOfLeaf;
+        try {
+            valueOfLeaf = isValueOrSelectLeafSet(holder, parentObj,
+                                                 getJavaName(yangLeaf),
+                                                 IS_LEAF_VALUE_SET_METHOD);
+        } catch (NoSuchMethodException e) {
+            throw new YtbException(e);
+        }
         if (valueOfLeaf.equals(TRUE)) {
-            return getStringFromDataType(leafType, yangLeaf.getDataType());
+            return getStringFromType(holder, parentObj,
+                                     getJavaName(yangLeaf), leafType,
+                                     yangLeaf.getDataType());
         }
         return null;
     }
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbUtil.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbUtil.java
index b81743b..0b6c8dc 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbUtil.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ytb/YtbUtil.java
@@ -18,11 +18,14 @@
 
 import org.onosproject.yangutils.datamodel.YangAugment;
 import org.onosproject.yangutils.datamodel.YangCase;
+import org.onosproject.yangutils.datamodel.YangIdentity;
+import org.onosproject.yangutils.datamodel.YangIdentityRef;
 import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangNotification;
 import org.onosproject.yangutils.datamodel.YangOutput;
 import org.onosproject.yangutils.datamodel.YangRpc;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 import org.onosproject.yangutils.translator.tojava.javamodel.JavaLeafInfoContainer;
@@ -34,14 +37,13 @@
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Base64;
+import java.util.Collection;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_AUGMENT_NODE;
 import static org.onosproject.yangutils.datamodel.YangSchemaNodeType.YANG_MULTI_INSTANCE_NODE;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
-import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DECIMAL64;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT16;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT32;
@@ -50,8 +52,8 @@
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT16;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT32;
-import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT64;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT8;
+import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
 import static org.onosproject.yms.app.utils.TraversalType.PARENT;
 
 /**
@@ -70,16 +72,14 @@
     public static final String PERIOD = ".";
 
     private static final int ONE = 1;
-    private static final String SCHEMA_NAME_IN_ENUM = "schemaName";
-    private static final String OPERATION_TYPE = "onosYangNodeOperationType";
+    private static final String YANG = "yang";
+    private static final String OP_TYPE = "OpType";
     private static final String STR_NONE = "NONE";
-    private static final String EQUALS = "=";
     private static final String ENUM_LEAF_IDENTIFIER = "$LeafIdentifier";
-    private static final char CLOSE_BRACE = '}';
     private static final Set<YangDataTypes> PRIMITIVE_TYPES =
             new HashSet<>(Arrays.asList(INT8, INT16, INT32, INT64, UINT8,
-                                        UINT16, UINT32, UINT64, DECIMAL64,
-                                        BOOLEAN, EMPTY));
+                                        UINT16, UINT32, BOOLEAN, EMPTY));
+    private static final String TO_STRING = "toString";
 
     // No instantiation.
     private YtbUtil() {
@@ -107,18 +107,6 @@
     }
 
     /**
-     * Returns the capital cased first letter of the given string.
-     *
-     * @param name string to be capital cased
-     * @return capital cased string
-     */
-    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);
-    }
-
-    /**
      * Returns the value of an attribute, in a class object. The attribute
      * name is taken from the YANG node java name.
      *
@@ -143,13 +131,13 @@
      * Returns the object of the declared method in parent class by invoking
      * through the child class object.
      *
-     * @param parentClass parent class of the declared method
-     * @param childClass  child class which inherits the parent class
-     * @param methodName  name of the declared method
+     * @param childClass child class which inherits the parent class
+     * @param methodName name of the declared method
      * @return value of the method
      */
-    public static Object getAttributeFromInheritance(
-            Class<?> parentClass, Object childClass, String methodName) {
+    public static Object getAttributeFromInheritance(Object childClass,
+                                                     String methodName) {
+        Class<?> parentClass = childClass.getClass().getSuperclass();
         Method getterMethod;
         try {
             getterMethod = parentClass.getDeclaredMethod(methodName);
@@ -163,12 +151,11 @@
     /**
      * Returns interface class from an implementation class object.
      *
-     * @param implClassObj implementation class object
+     * @param obj implementation class object
      * @return interface class
      */
-    public static Class<?> getInterfaceClassFromImplClass(Object implClassObj) {
-        Class<?> implClass = implClassObj.getClass();
-        Class<?>[] interfaces = implClass.getInterfaces();
+    public static Class<?> getInterfaceClassFromImplClass(Object obj) {
+        Class<?>[] interfaces = obj.getClass().getInterfaces();
         if (interfaces.length > ONE) {
             // TODO: Need to handle when impl class has more than one interface.
             throw new YtbException("Implementation class having more than one" +
@@ -181,20 +168,21 @@
      * Returns the operation type value for a class object. If the operation
      * type is not set, then none type is returned.
      *
-     * @param nodeObj node object
+     * @param nodeObj  node object
+     * @param typeName data type name
      * @return operation type of the class
      */
-    public static YdtContextOperationType getOperationTypeOfTheNode(
-            Object nodeObj) {
+    public static YdtContextOperationType getNodeOpType(Object nodeObj,
+                                                        String typeName) {
         Object opTypeObj;
         try {
-            opTypeObj = getAttributeOfObject(nodeObj, OPERATION_TYPE);
+            opTypeObj = getAttributeOfObject(nodeObj, typeName);
         } catch (NoSuchMethodException e) {
             return YdtContextOperationType.valueOf(STR_NONE);
         }
         String opTypeValue = String.valueOf(opTypeObj);
         if (opTypeValue.equals(STR_NULL)) {
-            opTypeValue = STR_NONE;
+            return null;
         }
         return YdtContextOperationType.valueOf(opTypeValue);
     }
@@ -237,21 +225,25 @@
      * Returns the string true, if the leaf data is actually set; false
      * otherwise.
      *
+     * @param holder     leaf holder
      * @param nodeObj    object if the node
      * @param javaName   java name of the leaf
      * @param methodName getter method name
      * @return string value of the boolean method
+     * @throws NoSuchMethodException if the method is not present
      */
-    public static String isValueOrSelectLeafSet(
-            Object nodeObj, String javaName, String methodName) {
+    public static String isValueOrSelectLeafSet(YangSchemaNode holder, Object nodeObj,
+                                                String javaName, String methodName)
+            throws NoSuchMethodException {
 
         Class<?> nodeClass = nodeObj.getClass();
-        Class<?> interfaceClass = getInterfaceClassFromImplClass(nodeObj);
 
         // Appends the enum inner package to the interface class package.
-        String enumPackage = interfaceClass.getName() + ENUM_LEAF_IDENTIFIER;
+        String enumPackage = holder.getJavaPackage() + PERIOD +
+                getCapitalCase(holder.getJavaClassNameOrBuiltInType()) +
+                ENUM_LEAF_IDENTIFIER;
 
-        ClassLoader classLoader = interfaceClass.getClassLoader();
+        ClassLoader classLoader = nodeClass.getClassLoader();
         Class leafEnum;
         try {
             leafEnum = classLoader.loadClass(enumPackage);
@@ -261,7 +253,7 @@
             // Invokes the method with the value of enum as param.
             return String.valueOf(getterMethod.invoke(nodeObj, value));
         } catch (IllegalAccessException | InvocationTargetException |
-                NoSuchMethodException | ClassNotFoundException e) {
+                ClassNotFoundException e) {
             throw new YtbException(e);
         }
     }
@@ -269,14 +261,21 @@
     /**
      * Returns the string value from the respective data types of the
      * leaf/leaf-list.
-     * // TODO: Remove this method and append to the data model utils.
      *
-     * @param fieldObj object of the leaf/leaf-list field
-     * @param dataType type of the leaf/leaf-list
+     * @param holder    leaf/leaf-list holder
+     * @param holderObj leaf/leaf-list holder object
+     * @param name      leaf/leaf-list name
+     * @param fieldObj  object of the leaf/leaf-list field
+     * @param dataType  type of the leaf/leaf-list
      * @return string value from the type
      */
-    public static String getStringFromDataType(Object fieldObj,
-                                               YangType dataType) {
+    public static String getStringFromType(YangSchemaNode holder, Object holderObj,
+                                           String name, Object fieldObj, YangType dataType) {
+
+        if (fieldObj == null) {
+            throw new YtbException("Value of " + holder.getName() + " is null");
+        }
+
         YangDataTypes type = dataType.getDataType();
         switch (type) {
             case INT8:
@@ -288,36 +287,34 @@
             case UINT32:
             case UINT64:
             case EMPTY:
-            case IDENTITYREF:
             case STRING:
             case DECIMAL64:
             case INSTANCE_IDENTIFIER:
             case DERIVED:
             case UNION:
-                //TODO: Generated code has to be changed, it must select
-                // the setting leaf and it must give back the corresponding
-                // toString of that type.
+            case ENUMERATION:
             case BOOLEAN:
+                return String.valueOf(fieldObj).trim();
+
             case BITS:
-                return getValueFromToStringHelper(String.valueOf(fieldObj));
+                return getBitsValue(holder, holderObj, name, fieldObj).trim();
 
             case BINARY:
                 return Base64.getEncoder().encodeToString((byte[]) fieldObj);
 
+            case IDENTITYREF:
+                YangIdentityRef ir =
+                        (YangIdentityRef) dataType.getDataTypeExtendedInfo();
+                if (ir.isInGrouping()) {
+                    return String.valueOf(fieldObj).trim();
+                }
+                return getIdentityRefValue(fieldObj, ir, holderObj);
+
             case LEAFREF:
                 YangLeafRef leafRef =
                         (YangLeafRef) dataType.getDataTypeExtendedInfo();
-                return getStringFromDataType(fieldObj,
-                                             leafRef.getEffectiveDataType());
-
-            case ENUMERATION:
-                Object value;
-                try {
-                    value = getAttributeOfObject(fieldObj, SCHEMA_NAME_IN_ENUM);
-                } catch (NoSuchMethodException e) {
-                    throw new YtbException(e);
-                }
-                return getValueFromToStringHelper(String.valueOf(value));
+                return getStringFromType(holder, holderObj, name, fieldObj,
+                                         leafRef.getEffectiveDataType());
 
             default:
                 throw new YtbException("Unsupported data type. Cannot be " +
@@ -326,24 +323,63 @@
     }
 
     /**
-     * Returns the value, from the toString value which uses toStringHelper.
-     * It gives values in non-usable format(e.g., {value = 5}). But the value
-     * that has to be returned is only 5.So it parses the string and returns
-     * only the value. In certain toString, to string helper is not used, so
-     * the original value is sent without parsing.
+     * Returns the string values for the data type bits.
      *
-     * @param rawString raw string
-     * @return parsed value
+     * @param holder    leaf/leaf-list holder
+     * @param holderObj leaf/leaf-list holder object
+     * @param name      leaf/leaf-list name
+     * @param fieldObj  object of the leaf/leaf-list field
+     * @return string value for bits type
      */
-    private static String getValueFromToStringHelper(String rawString) {
-        if (rawString.contains(EQUALS)) {
-            int index = rawString.lastIndexOf(EQUALS);
-            int braceIndex = rawString.indexOf(CLOSE_BRACE);
-            if (index != -1) {
-                return rawString.substring(index + 1, braceIndex);
-            }
+    private static String getBitsValue(YangSchemaNode holder, Object holderObj,
+                                       String name, Object fieldObj) {
+
+        Class<?> holderClass = holderObj.getClass();
+        String interfaceName = holder.getJavaClassNameOrBuiltInType();
+        String className = interfaceName.toLowerCase() + PERIOD +
+                getCapitalCase(name);
+        String pkgName = holder.getJavaPackage() + PERIOD + className;
+        ClassLoader classLoader = holderClass.getClassLoader();
+
+        Class<?> bitClass;
+        try {
+            bitClass = classLoader.loadClass(pkgName);
+            Method getterMethod = bitClass.getDeclaredMethod(
+                    TO_STRING, fieldObj.getClass());
+            return String.valueOf(getterMethod.invoke(null, fieldObj));
+        } catch (ClassNotFoundException | NoSuchMethodException |
+                InvocationTargetException | IllegalAccessException e) {
+            throw new YtbException(e);
         }
-        return rawString;
+    }
+
+    /**
+     * Returns the string value of the type identity-ref.
+     *
+     * @param fieldObj  object of the leaf/leaf-list field
+     * @param ir        YANG identity ref
+     * @param holderObj leaf/leaf-list holder object
+     * @return string value for identity ref type
+     */
+    private static String getIdentityRefValue(Object fieldObj, YangIdentityRef ir,
+                                              Object holderObj) {
+
+        YangIdentity id = ir.getReferredIdentity();
+        String idName = id.getJavaClassNameOrBuiltInType();
+        String idPkg = id.getJavaPackage() + PERIOD + getCapitalCase(idName);
+        String methodName = idName + getCapitalCase(TO_STRING);
+
+        Class<?> holderClass = holderObj.getClass();
+        ClassLoader classLoader = holderClass.getClassLoader();
+        Class<?> idClass;
+        try {
+            idClass = classLoader.loadClass(idPkg);
+            Method method = idClass.getDeclaredMethod(methodName, null);
+            return String.valueOf(method.invoke(fieldObj, null)).trim();
+        } catch (ClassNotFoundException | NoSuchMethodException |
+                InvocationTargetException | IllegalAccessException e) {
+            throw new YtbException(e);
+        }
     }
 
     /**
@@ -413,11 +449,11 @@
     /**
      * Returns true, if the list is not null and non-empty; false otherwise.
      *
-     * @param object list object
+     * @param c collection object
      * @return true, if the list is not null and non-empty; false otherwise
      */
-    public static boolean isNonEmpty(List object) {
-        return object != null && !object.isEmpty();
+    public static boolean nonEmpty(Collection<?> c) {
+        return c != null && !c.isEmpty();
     }
 
     /**
@@ -426,7 +462,7 @@
      * @param str string value
      * @return true, if the string is not null and non-empty; false otherwise.
      */
-    public static boolean isNonEmpty(String str) {
+    public static boolean nonEmpty(String str) {
         return str != null && !str.isEmpty();
     }
 
@@ -446,4 +482,14 @@
                 curNode instanceof YangOutput;
     }
 
+    /**
+     * Returns the name of the operation type variable from the yang name.
+     *
+     * @param curNode YANG node
+     * @return name of operation type
+     */
+    public static String getOpTypeName(YangNode curNode) {
+        return YANG + getCapitalCase(curNode.getJavaClassNameOrBuiltInType()) +
+                OP_TYPE;
+    }
 }