[ONOS-5330] Code-Reusability by generating code for Grouping rather then uses

Change-Id: I80a7d5c92a47e30c5ea0fe45c407a8246d9994d7
diff --git a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java
index 5e1413f..83f4a1a 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/linker/impl/YangXpathLinker.java
@@ -32,6 +32,7 @@
 import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
 import org.onosproject.yangutils.datamodel.YangOutput;
 import org.onosproject.yangutils.datamodel.YangSubModule;
+import org.onosproject.yangutils.datamodel.YangUses;
 import org.onosproject.yangutils.linker.exceptions.LinkerException;
 
 import java.util.ArrayList;
@@ -670,7 +671,8 @@
                     return node;
                 }
             }
-            if (node.getName().equals(curNodeId.getName())) {
+            if (node.getName().equals(curNodeId.getName()) &&
+                    !(node instanceof YangUses)) {
                 return node;
             }
             node = node.getNextSibling();
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityrefListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityrefListener.java
index ad197a6..17f197a 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityrefListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/IdentityrefListener.java
@@ -121,6 +121,8 @@
                         resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
                                 (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
                         addToResolutionList(resolutionInfo, ctx);
+                    } else {
+                        identityRef.setInGrouping(true);
                     }
                     break;
                 case LEAF_LIST_DATA:
@@ -145,6 +147,8 @@
                         resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
                                 (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
                         addToResolutionList(resolutionInfo, ctx);
+                    } else {
+                        identityRef.setInGrouping(true);
                     }
                     break;
                 case UNION_DATA:
@@ -164,9 +168,14 @@
                         resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
                                 (YangNode) parentNodeOfUnionNode, errorLine, errorPosition);
                         addToResolutionList(resolutionInfo, ctx);
+                    } else {
+                        identityRef.setInGrouping(true);
                     }
                     break;
                 case TYPEDEF_DATA:
+                    if (listener.getGroupingDepth() != 0) {
+                        identityRef.setInGrouping(true);
+                    }
                     /**
                      * Do not add the identity ref to resolution list. It needs to be
                      * added to resolution list, when leaf/leaf list references to
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
index a90b87b..25ac31c 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
@@ -139,6 +139,8 @@
                     YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
                             (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
                     addToResolutionList(resolutionInfo);
+                } else {
+                    leafRef.setInGrouping(true);
                 }
                 break;
 
@@ -163,12 +165,17 @@
                     YangResolutionInfoImpl resolutionInfoImpl = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
                             (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
                     addToResolutionList(resolutionInfoImpl);
+                } else {
+                    leafRef.setInGrouping(true);
                 }
                 break;
 
             case TYPEDEF_DATA:
                 Parsable parentNodeOfLeafref = listener.getParsedDataStack().peek();
                 leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafref);
+                if (listener.getGroupingDepth() != 0) {
+                    leafRef.setInGrouping(true);
+                }
                 /*
                  * Do not add the leaf ref to resolution list. It needs to be
                  * added to resolution list, when leaf/leaf list references to
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
index ab0ad3c..8ed701e 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/TypeListener.java
@@ -35,13 +35,13 @@
 import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
 import static org.onosproject.yangutils.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
 import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
+import static org.onosproject.yangutils.datamodel.utils.YangConstructType.TYPEDEF_DATA;
 import static org.onosproject.yangutils.datamodel.utils.YangConstructType.TYPE_DATA;
+import static org.onosproject.yangutils.datamodel.utils.YangConstructType.UNION_DATA;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
-        .constructExtendedListenerErrorMessage;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
-        .constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
@@ -141,12 +141,12 @@
 
                     type.setResolvableStatus(UNRESOLVED);
 
-                    if (listener.getGroupingDepth() == 0) {
-                        // Add resolution information to the list
-                        YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangType>(type,
-                                (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
-                        addToResolutionList(resolutionInfo, ctx);
-                    }
+                    // Add resolution information to the list
+                    YangResolutionInfoImpl resolutionInfo =
+                            new YangResolutionInfoImpl<YangType>(
+                                    type,(YangNode) parentNodeOfLeaf, errorLine,
+                                    errorPosition);
+                    addToResolutionList(resolutionInfo, ctx);
                 }
                 break;
             case LEAF_LIST_DATA:
@@ -173,13 +173,12 @@
                     YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
                     ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
 
-                    if (listener.getGroupingDepth() == 0) {
-                        // Add resolution information to the list
-                        YangResolutionInfoImpl resolutionInfo =
-                                new YangResolutionInfoImpl<YangType>(type, (YangNode) parentNodeOfLeafList, errorLine,
-                                        errorPosition);
-                        addToResolutionList(resolutionInfo, ctx);
-                    }
+                    // Add resolution information to the list
+                    YangResolutionInfoImpl resolutionInfo =
+                            new YangResolutionInfoImpl<YangType>(
+                                    type, (YangNode) parentNodeOfLeafList,
+                                    errorLine, errorPosition);
+                    addToResolutionList(resolutionInfo, ctx);
                 }
                 break;
             case UNION_DATA:
@@ -205,12 +204,11 @@
 
                     type.setResolvableStatus(UNRESOLVED);
 
-                    if (listener.getGroupingDepth() == 0) {
-                        // Add resolution information to the list
-                        YangResolutionInfoImpl resolutionInfo =
-                                new YangResolutionInfoImpl<YangType>(type, unionNode, errorLine, errorPosition);
-                        addToResolutionList(resolutionInfo, ctx);
-                    }
+                    // Add resolution information to the list
+                    YangResolutionInfoImpl resolutionInfo =
+                            new YangResolutionInfoImpl<YangType>(
+                                    type, unionNode, errorLine, errorPosition);
+                    addToResolutionList(resolutionInfo, ctx);
                 }
 
                 break;
@@ -229,12 +227,11 @@
                     ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
 
                     type.setResolvableStatus(UNRESOLVED);
-                    if (listener.getGroupingDepth() == 0) {
-                        // Add resolution information to the list
-                        YangResolutionInfoImpl resolutionInfo =
-                                new YangResolutionInfoImpl<YangType>(type, typeDef, errorLine, errorPosition);
-                        addToResolutionList(resolutionInfo, ctx);
-                    }
+                    // Add resolution information to the list
+                    YangResolutionInfoImpl resolutionInfo =
+                            new YangResolutionInfoImpl<YangType>(
+                                    type, typeDef, errorLine, errorPosition);
+                    addToResolutionList(resolutionInfo, ctx);
                 }
                 break;
             //TODO: deviate replacement statement.
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGenerator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGenerator.java
index fce7dec..49beff0 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGenerator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/JavaCodeGenerator.java
@@ -19,6 +19,8 @@
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.utils.io.YangPluginConfig;
 
+import java.io.IOException;
+
 /**
  * Abstraction of an entity which provides Code generator functionalities.
  */
@@ -37,7 +39,8 @@
      * Traverse the schema of application and generate corresponding code.
      *
      * @throws TranslatorException when fails to generate java code
+     * @throws IOException         a violation in IO rule
      */
     void generateCodeExit()
-            throws TranslatorException;
+            throws TranslatorException, IOException;
 }
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaFragmentFiles.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaFragmentFiles.java
index 4cba71d..237b6bb 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaFragmentFiles.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/TempJavaFragmentFiles.java
@@ -558,9 +558,26 @@
              */
             return;
         }
+        addCurNodeInfoInParentTempFile(curNode, isList, config, parent);
+    }
+
+    /**
+     * Adds current node info as and attribute to a specified parent generated
+     * file. In case of grouping parent will be referred grouping node or
+     * referred node in grouping.
+     *
+     * @param curNode current node
+     * @param isList  is list construct
+     * @param config  plugin configurations
+     * @param parent  parent node
+     * @throws IOException IO operation exception
+     */
+    protected static void addCurNodeInfoInParentTempFile(
+            YangNode curNode, boolean isList, YangPluginConfig config,
+            YangNode parent)
+            throws IOException {
         TempJavaBeanFragmentFiles tempFiles =
                 getBeanFiles((JavaCodeGeneratorInfo) parent);
-
         JavaAttributeInfo attr =
                 getCurNodeAsAttributeInTarget(curNode, parent, isList,
                                               tempFiles);
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/YangJavaModelUtils.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/YangJavaModelUtils.java
index 064229a..136fad5 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/YangJavaModelUtils.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/YangJavaModelUtils.java
@@ -21,11 +21,13 @@
 import org.onosproject.yangutils.datamodel.YangAugment;
 import org.onosproject.yangutils.datamodel.YangCase;
 import org.onosproject.yangutils.datamodel.YangChoice;
+import org.onosproject.yangutils.datamodel.YangGrouping;
 import org.onosproject.yangutils.datamodel.YangInput;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
 import org.onosproject.yangutils.datamodel.YangOutput;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
 import org.onosproject.yangutils.datamodel.YangTranslatorOperatorNode;
 import org.onosproject.yangutils.datamodel.YangTypeHolder;
 import org.onosproject.yangutils.datamodel.utils.DataModelUtils;
@@ -336,6 +338,16 @@
                                                 info));
         }
 
+        YangSchemaNode node = getRefSchema(info);
+        if (node != null) {
+            YangNode parent = ((YangNode) info).getParent();
+            if (!(parent instanceof YangGrouping)) {
+                addCurNodeInfoInParentTempFile((YangNode) node, isMultiInstance,
+                                               config, parent);
+            }
+            return;
+        }
+
         /*
          * Generate the Java files corresponding to the current node.
          */
@@ -349,6 +361,29 @@
     }
 
     /**
+     * Returns referred schema node in case of grouping uses.
+     *
+     * @param info YANG java file info node
+     * @return referred schema node
+     */
+    private static YangSchemaNode getRefSchema(JavaCodeGeneratorInfo info) {
+
+        YangSchemaNode node = ((YangSchemaNode) info);
+        if (node.getReferredSchema() == null) {
+            return null;
+        }
+
+        /*
+         * Obtain last referred node in case grouping is embedded inside
+         * another grouping.
+         */
+        while (node.getReferredSchema() != null) {
+            node = node.getReferredSchema();
+        }
+        return node;
+    }
+
+    /**
      * Generates code for the current data model node and adds support for it to
      * be augmented.
      *
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/AttributesJavaDataType.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/AttributesJavaDataType.java
index ae7b016..2d70219 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/AttributesJavaDataType.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/AttributesJavaDataType.java
@@ -16,8 +16,6 @@
 
 package org.onosproject.yangutils.translator.tojava.javamodel;
 
-import java.util.Stack;
-
 import org.onosproject.yangutils.datamodel.YangDerivedInfo;
 import org.onosproject.yangutils.datamodel.YangEnumeration;
 import org.onosproject.yangutils.datamodel.YangIdentity;
@@ -33,6 +31,8 @@
 import org.onosproject.yangutils.translator.tojava.JavaFileInfoTranslator;
 import org.onosproject.yangutils.utils.io.YangToJavaNamingConflictUtil;
 
+import java.util.Stack;
+
 import static org.onosproject.yangutils.translator.tojava.YangJavaModelUtils.getCurNodePackage;
 import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getRootPackage;
 import static org.onosproject.yangutils.utils.UtilConstants.BIG_DECIMAL;
@@ -49,6 +49,7 @@
 import static org.onosproject.yangutils.utils.UtilConstants.JAVA_MATH;
 import static org.onosproject.yangutils.utils.UtilConstants.LONG;
 import static org.onosproject.yangutils.utils.UtilConstants.LONG_WRAPPER;
+import static org.onosproject.yangutils.utils.UtilConstants.OBJECT_STRING;
 import static org.onosproject.yangutils.utils.UtilConstants.PERIOD;
 import static org.onosproject.yangutils.utils.UtilConstants.SHORT;
 import static org.onosproject.yangutils.utils.UtilConstants.SHORT_WRAPPER;
@@ -109,6 +110,10 @@
             case INSTANCE_IDENTIFIER:
                 return STRING_DATA_TYPE;
             case LEAFREF:
+                YangType refType = getReferredTypeFromLeafref(yangType);
+                if (refType == null) {
+                    return OBJECT_STRING;
+                }
                 return getJavaDataType(getReferredTypeFromLeafref(yangType));
             default:
                 throw new TranslatorException("given data type is not supported. " +
@@ -165,13 +170,9 @@
                 case BINARY:
                     return BYTE + SQUARE_BRACKETS;
                 case LEAFREF:
-                    YangType<?> referredType = getReferredTypeFromLeafref(yangType);
-                    return getJavaImportClass(referredType, true, pluginConfig);
+                    return getLeafRefImpClass(yangType, pluginConfig, true);
                 case IDENTITYREF:
-                    YangIdentityRef identityRef = (YangIdentityRef) yangType.getDataTypeExtendedInfo();
-                    YangIdentity identity = identityRef.getReferredIdentity();
-                    return getCapitalCase(getCamelCase(identity.
-                            getName(), pluginConfig));
+                    return getIdentityRefImpClass(yangType, pluginConfig);
                 case EMPTY:
                     return BOOLEAN_WRAPPER;
                 case UNION:
@@ -204,12 +205,9 @@
                 case DECIMAL64:
                     return BIG_DECIMAL;
                 case LEAFREF:
-                    YangType<?> referredType = getReferredTypeFromLeafref(yangType);
-                    return getJavaImportClass(referredType, false, pluginConfig);
+                    return getLeafRefImpClass(yangType, pluginConfig, false);
                 case IDENTITYREF:
-                    YangIdentityRef identityRef = (YangIdentityRef) yangType.getDataTypeExtendedInfo();
-                    YangIdentity identity = identityRef.getReferredIdentity();
-                    return getCapitalCase(getCamelCase(identity.getName(), pluginConfig));
+                    return getIdentityRefImpClass(yangType, pluginConfig);
                 case EMPTY:
                     return BOOLEAN_DATA_TYPE;
                 case UNION:
@@ -261,8 +259,7 @@
                 case BITS:
                     return COLLECTION_IMPORTS;
                 case LEAFREF:
-                    YangType<?> referredType = getReferredTypeFromLeafref(yangType);
-                    return getJavaImportPackage(referredType, true, conflictResolver);
+                    return getLeafRefImpPkg(yangType, conflictResolver, true);
                 case IDENTITYREF:
                     return getIdentityRefPackage(yangType, conflictResolver);
                 case UNION:
@@ -291,8 +288,7 @@
                 case BITS:
                     return COLLECTION_IMPORTS;
                 case LEAFREF:
-                    YangType<?> referredType = getReferredTypeFromLeafref(yangType);
-                    return getJavaImportPackage(referredType, false, conflictResolver);
+                    return getLeafRefImpPkg(yangType, conflictResolver, false);
                 case IDENTITYREF:
                     return getIdentityRefPackage(yangType, conflictResolver);
                 case UNION:
@@ -333,10 +329,7 @@
         }
 
         YangJavaTypeDefTranslator typedef = (YangJavaTypeDefTranslator) ((YangDerivedInfo<?>) var).getReferredTypeDef();
-        if (typedef.getJavaFileInfo().getPackage() == null) {
-            return getPackageFromParent(typedef.getParent(), conflictResolver);
-        }
-        return typedef.getJavaFileInfo().getPackage();
+        return getTypePackage(typedef, conflictResolver);
     }
 
     /**
@@ -357,10 +350,7 @@
         }
 
         YangJavaUnionTranslator union = (YangJavaUnionTranslator) type.getDataTypeExtendedInfo();
-        if (union.getJavaFileInfo().getPackage() == null) {
-            return getPackageFromParent(union.getParent(), conflictResolver);
-        }
-        return union.getJavaFileInfo().getPackage();
+        return getTypePackage(union, conflictResolver);
     }
 
     /**
@@ -380,10 +370,7 @@
                                                   + " in " + type.getFileName());
         }
         YangJavaEnumerationTranslator enumeration = (YangJavaEnumerationTranslator) type.getDataTypeExtendedInfo();
-        if (enumeration.getJavaFileInfo().getPackage() == null) {
-            return getPackageFromParent(enumeration.getParent(), conflictResolver);
-        }
-        return enumeration.getJavaFileInfo().getPackage();
+        return getTypePackage(enumeration, conflictResolver);
     }
 
     /**
@@ -403,11 +390,32 @@
                                                   + " in " + type.getFileName());
         }
         YangIdentityRef identityRef = (YangIdentityRef) type.getDataTypeExtendedInfo();
-        YangJavaIdentityTranslator identity = (YangJavaIdentityTranslator) (identityRef.getReferredIdentity());
-        if (identity.getJavaFileInfo().getPackage() == null) {
-            return getPackageFromParent(identity.getParent(), conflictResolver);
+        if (identityRef.isInGrouping()) {
+            return JAVA_LANG;
         }
-        return identity.getJavaFileInfo().getPackage();
+        YangJavaIdentityTranslator identity = (YangJavaIdentityTranslator) (identityRef.getReferredIdentity());
+        return getTypePackage(identity, conflictResolver);
+    }
+
+    /**
+     * Returns type package.
+     *
+     * @param info             YANG code generator info
+     * @param conflictResolver object of YANG to java naming conflict util
+     * @return type java package
+     */
+    private static String getTypePackage(JavaCodeGeneratorInfo info,
+                                         YangToJavaNamingConflictUtil conflictResolver) {
+        YangNode node = (YangNode) info;
+        // Check for referred schema type node for grouping scenario.
+        while (node.getReferredSchema() != null) {
+            node = (YangNode) node.getReferredSchema();
+        }
+        info = (JavaCodeGeneratorInfo) node;
+        if (info.getJavaFileInfo().getPackage() == null) {
+            return getPackageFromParent(node.getParent(), conflictResolver);
+        }
+        return info.getJavaFileInfo().getPackage();
     }
 
     /**
@@ -476,7 +484,6 @@
                                                       yangNode.getLineNumber() + " at " +
                                                       yangNode.getCharPosition()
                                                       + " in " + yangNode.getFileName());
-
             }
 
             ((JavaCodeGeneratorInfo) yangNode).getJavaFileInfo()
@@ -513,7 +520,53 @@
      * @return type from the leafref
      */
     private static YangType<?> getReferredTypeFromLeafref(YangType type) {
-        YangLeafRef<?> leafRefInfo = (YangLeafRef<?>) type.getDataTypeExtendedInfo();
-        return leafRefInfo.getEffectiveDataType();
+        YangLeafRef<?> lri = (YangLeafRef<?>) type.getDataTypeExtendedInfo();
+        return lri.isInGrouping() ? null : lri.getEffectiveDataType();
+    }
+
+    /**
+     * Returns leaf ref import string.
+     *
+     * @param type   YANG type
+     * @param cnfg   YANG to java naming conflict util
+     * @param isList true if list, false otherwise
+     * @return import class
+     */
+    private static String getLeafRefImpClass(
+            YangType type, YangToJavaNamingConflictUtil cnfg, boolean isList) {
+        YangType<?> rt = getReferredTypeFromLeafref(type);
+        return rt == null ? OBJECT_STRING : getJavaImportClass(rt, isList,
+                                                               cnfg);
+    }
+
+    /**
+     * Returns identity ref import class.
+     *
+     * @param type YANG type
+     * @param cnfg YANG to java naming conflict util
+     * @return import class
+     */
+    private static String getIdentityRefImpClass(
+            YangType type, YangToJavaNamingConflictUtil cnfg) {
+        YangIdentityRef ir = (YangIdentityRef) type.getDataTypeExtendedInfo();
+        if (ir.isInGrouping()) {
+            return OBJECT_STRING;
+        }
+        YangIdentity identity = ir.getReferredIdentity();
+        return getCapitalCase(getCamelCase(identity.getName(), cnfg));
+    }
+
+    /**
+     * Returns leaf ref import package.
+     *
+     * @param type   YANG type
+     * @param cnfg   YANG to java naming conflict util
+     * @param isList true if list, false otherwise
+     * @return import package
+     */
+    private static String getLeafRefImpPkg(
+            YangType type, YangToJavaNamingConflictUtil cnfg, boolean isList) {
+        YangType<?> rt = getReferredTypeFromLeafref(type);
+        return rt == null ? JAVA_LANG : getJavaImportPackage(rt, isList, cnfg);
     }
 }
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaChoiceTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaChoiceTranslator.java
index 1c253eb..d37b59f 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaChoiceTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaChoiceTranslator.java
@@ -18,6 +18,7 @@
 import java.io.IOException;
 
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaChoice;
+import org.onosproject.yangutils.translator.exception.InvalidNodeForTranslatorException;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
@@ -110,6 +111,9 @@
     public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
         try {
             generateCodeAndUpdateInParent(this, yangPlugin, false);
+            if (getReferredSchema() != null) {
+                throw new InvalidNodeForTranslatorException();
+            }
         } catch (IOException e) {
             throw new TranslatorException(
                     "Failed to prepare generate code entry for choice node " +
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaContainerTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaContainerTranslator.java
index 31e51c9..4efaf2c 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaContainerTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaContainerTranslator.java
@@ -18,6 +18,7 @@
 import java.io.IOException;
 
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaContainer;
+import org.onosproject.yangutils.translator.exception.InvalidNodeForTranslatorException;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
@@ -110,6 +111,9 @@
     public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
         try {
             generateCodeAndUpdateInParent(this, yangPlugin, false);
+            if (getReferredSchema() != null) {
+                throw new InvalidNodeForTranslatorException();
+            }
         } catch (IOException e) {
             throw new TranslatorException(
                     "Failed to prepare generate code entry for container node " +
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaEnumerationTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaEnumerationTranslator.java
index 605df86..57339e7 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaEnumerationTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaEnumerationTranslator.java
@@ -17,6 +17,7 @@
 package org.onosproject.yangutils.translator.tojava.javamodel;
 
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaEnumeration;
+import org.onosproject.yangutils.translator.exception.InvalidNodeForTranslatorException;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
@@ -110,6 +111,9 @@
     @Override
     public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
         try {
+            if (getReferredSchema() != null) {
+                throw new InvalidNodeForTranslatorException();
+            }
             generateCodeOfNode(this, yangPlugin);
         } catch (IOException e) {
             throw new TranslatorException(getErrorMsg(FAIL_AT_ENTRY, this,
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaGroupingTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaGroupingTranslator.java
index bd54469..b36de60 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaGroupingTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaGroupingTranslator.java
@@ -24,6 +24,11 @@
 import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFiles;
 import org.onosproject.yangutils.utils.io.YangPluginConfig;
 
+import java.io.IOException;
+
+import static org.onosproject.yangutils.translator.tojava.YangJavaModelUtils.updatePackageInfo;
+import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.createPackage;
+
 /**
  * Represents grouping information extended to support java code generation.
  */
@@ -98,18 +103,12 @@
     @Override
     public void generateCodeEntry(YangPluginConfig yangPlugin)
             throws TranslatorException {
-        InvalidNodeForTranslatorException exception = new InvalidNodeForTranslatorException();
-        exception.setFileName(this.getFileName());
-        exception.setCharPosition(this.getCharPosition());
-        exception.setLine(this.getLineNumber());
-        throw exception;
+        updatePackageInfo(this, yangPlugin);
     }
 
     @Override
     public void generateCodeExit()
-            throws TranslatorException {
-        /*
-         * Do nothing.
-         */
+            throws TranslatorException, IOException {
+        createPackage(this);
     }
 }
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaListTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaListTranslator.java
index 6082963..6ab5a03 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaListTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaListTranslator.java
@@ -18,6 +18,7 @@
 import java.io.IOException;
 
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaList;
+import org.onosproject.yangutils.translator.exception.InvalidNodeForTranslatorException;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
@@ -110,6 +111,9 @@
     public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
         try {
             generateCodeAndUpdateInParent(this, yangPlugin, true);
+            if (getReferredSchema() != null) {
+                throw new InvalidNodeForTranslatorException();
+            }
         } catch (IOException e) {
             throw new TranslatorException(
                     "Failed to prepare generate code entry for list node " +
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java
index 1f043cf..8f2c300 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaTypeDefTranslator.java
@@ -15,8 +15,6 @@
  */
 package org.onosproject.yangutils.translator.tojava.javamodel;
 
-import java.io.IOException;
-
 import org.onosproject.yangutils.datamodel.YangDerivedInfo;
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaTypeDef;
@@ -28,6 +26,8 @@
 import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFiles;
 import org.onosproject.yangutils.utils.io.YangPluginConfig;
 
+import java.io.IOException;
+
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DERIVED;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_TYPEDEF_CLASS;
@@ -67,10 +67,10 @@
 
         if (javaFileInfo == null) {
             throw new TranslatorException("Missing java info in java datamodel node " +
-                    getName() + " in " +
-                    getLineNumber() + " at " +
-                    getCharPosition()
-                    + " in " + getFileName());
+                                                  getName() + " in " +
+                                                  getLineNumber() + " at " +
+                                                  getCharPosition()
+                                                  + " in " + getFileName());
         }
         return (JavaFileInfoTranslator) javaFileInfo;
     }
@@ -114,6 +114,11 @@
      */
     @Override
     public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
+        if (getReferredSchema() != null) {
+            throw new InvalidNodeForTranslatorException();
+        }
+        // TODO update the below exception in all related places, remove file
+        // name and other information.
         YangType typeInTypeDef = this.getTypeDefBaseType();
         InvalidNodeForTranslatorException exception = new InvalidNodeForTranslatorException();
         exception.setFileName(this.getFileName());
@@ -135,7 +140,6 @@
                             + "in " + getLineNumber() + " at " + getCharPosition() + " in " + getFileName()
                             + " " + e.getLocalizedMessage());
         }
-
     }
 
     /**
@@ -154,5 +158,4 @@
                             + " " + e.getLocalizedMessage());
         }
     }
-
 }
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaUnionTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaUnionTranslator.java
index 60f200f..3ca66f9 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaUnionTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaUnionTranslator.java
@@ -18,6 +18,7 @@
 import java.io.IOException;
 
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaUnion;
+import org.onosproject.yangutils.translator.exception.InvalidNodeForTranslatorException;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
@@ -108,6 +109,9 @@
     @Override
     public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
         try {
+            if (getReferredSchema() != null) {
+                throw new InvalidNodeForTranslatorException();
+            }
             generateCodeOfNode(this, yangPlugin);
         } catch (IOException e) {
             throw new TranslatorException(
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
index 2d9538f..e22465c 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/JavaFileGeneratorUtils.java
@@ -489,11 +489,11 @@
     /**
      * Appends all the contents into a generated java file.
      *
-     * @param file         generated file
-     * @param fileName     generated file name
-     * @param genType      generated file type
-     * @param importsList  list of java imports
-     * @param pkg          generated file package
+     * @param file        generated file
+     * @param fileName    generated file name
+     * @param genType     generated file type
+     * @param importsList list of java imports
+     * @param pkg         generated file package
      * @throws IOException when fails to append contents
      */
     private static void appendContents(File file, String fileName, int genType,
@@ -794,9 +794,13 @@
     public static String isTypeNameLeafref(String attributeName,
                                            YangType<?> attributeType) {
         if (attributeName.equalsIgnoreCase(LEAFREF)) {
-            return attributeType.getDataTypeName();
+            YangLeafRef leafRef = (YangLeafRef) attributeType.getDataTypeExtendedInfo();
+            if (!leafRef.isInGrouping()) {
+                return attributeType.getDataTypeName();
+            }
         }
         return attributeName;
+        // TODO handle union scenario, having multiple leafref.
     }
 
     /**
@@ -809,7 +813,9 @@
         if (attributeType.getDataType() == YangDataTypes.LEAFREF) {
             YangLeafRef leafRef = (YangLeafRef) attributeType
                     .getDataTypeExtendedInfo();
-            return leafRef.getEffectiveDataType();
+            if (!leafRef.isInGrouping()) {
+                return leafRef.getEffectiveDataType();
+            }
         }
         return attributeType;
     }
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java
index e7e83f4..e1b4913 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/utils/SubtreeFilteringMethodsGenerator.java
@@ -216,16 +216,27 @@
                     getAttrTypeForFilterContentMatchWhenPrimitiveDataType(
                             attributeName);
         } else if (dataType.getDataType() == LEAFREF) {
-            YangType type = ((YangLeafRef) dataType.getDataTypeExtendedInfo())
-                    .getEffectiveDataType();
-            if (StringGenerator.isPrimitiveDataType(type.getDataType())) {
-                attrQualifiedType =
-                        getAttrTypeForFilterContentMatchWhenPrimitiveDataType(
-                                attributeName);
-            } else {
+
+            // When leafref in grouping.
+            if (((YangLeafRef) dataType.getDataTypeExtendedInfo())
+                    .isInGrouping()) {
                 attrQualifiedType =
                         getAttrTypeForFilterContentMatchWhenNonPrimitiveDataTypes(
                                 attributeName);
+            } else {
+
+                YangType type = ((YangLeafRef) dataType.getDataTypeExtendedInfo())
+                        .getEffectiveDataType();
+
+                if (StringGenerator.isPrimitiveDataType(type.getDataType())) {
+                    attrQualifiedType =
+                            getAttrTypeForFilterContentMatchWhenPrimitiveDataType(
+                                    attributeName);
+                } else {
+                    attrQualifiedType =
+                            getAttrTypeForFilterContentMatchWhenNonPrimitiveDataTypes(
+                                    attributeName);
+                }
             }
         } else {
             attrQualifiedType =