[ONOS-3904] Derived data type and formatting fixes

Change-Id: I1d68899e0056fa0db6322e83f7e9d3ff9b3b1ee0
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDataTypes.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDataTypes.java
index 4edf482..37176bd 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDataTypes.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDataTypes.java
@@ -215,7 +215,7 @@
     INSTANCE_IDENTIFIER,
 
     /**
-     * Derived Data type.
+     * Derived data type.
      */
     DERIVED;
 
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedType.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedType.java
new file mode 100644
index 0000000..31484ba
--- /dev/null
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedType.java
@@ -0,0 +1,122 @@
+/*Copyright 2016.year 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.yangutils.datamodel;
+
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.Parsable;
+import org.onosproject.yangutils.parser.ParsableDataType;
+
+/*-
+ * The typedef Statement
+ *
+ * The "typedef" statement defines a new type that may be used locally
+ * in the module, in modules or submodules which include it, and by
+ * other modules that import from it. The new type is called the
+ * "derived type", and the type from which it was derived is called
+ * the "base type".  All derived types can be traced back to a YANG
+ * built-in type.
+ *
+ * The "typedef" statement's argument is an identifier that is the name
+ * of the type to be defined, and MUST be followed by a block of
+ * sub-statements that holds detailed typedef information.
+ *
+ * The name of the type MUST NOT be one of the YANG built-in types.  If
+ * the typedef is defined at the top level of a YANG module or
+ * submodule, the name of the type to be defined MUST be unique within
+ * the module.
+ */
+/**
+ * Derived type information.
+ */
+public class YangDerivedType implements Parsable {
+
+    /**
+     * All derived types can be traced back to a YANG built-in type.
+     */
+    private YangDataTypes effectiveYangBuiltInType;
+
+    /**
+     * Base type from which the current type is derived.
+     */
+    private YangType<?> baseType;
+
+    /**
+     * Default constructor.
+     */
+    public YangDerivedType() {
+    }
+
+    /**
+     * Get the effective YANG built-in type of the derived data type.
+     *
+     * @return effective YANG built-in type of the derived data type.
+     */
+    public YangDataTypes getEffectiveYangBuiltInType() {
+        return effectiveYangBuiltInType;
+    }
+
+    /**
+     * Set the effective YANG built-in type of the derived data type.
+     *
+     * @param builtInType effective YANG built-in type of the derived data type.
+     */
+    public void setEffectiveYangBuiltInType(YangDataTypes builtInType) {
+        effectiveYangBuiltInType = builtInType;
+    }
+
+    /**
+     * Get the base type information.
+     *
+     * @return base type information.
+     */
+    public YangType<?> getBaseType() {
+        return baseType;
+    }
+
+    /**
+     * Get the base type information.
+     *
+     * @param baseType base type information.
+     */
+    public void setBaseType(YangType<?> baseType) {
+        this.baseType = baseType;
+    }
+
+    /**
+     * Get the parsable type.
+     */
+    @Override
+    public ParsableDataType getParsableDataType() {
+        return ParsableDataType.DERIVED;
+    }
+
+    /**
+     * TODO.
+     */
+    @Override
+    public void validateDataOnEntry() throws DataModelException {
+        // TODO Auto-generated method stub
+
+    }
+
+    /**
+     * TODO.
+     */
+    @Override
+    public void validateDataOnExit() throws DataModelException {
+        // TODO Auto-generated method stub
+
+    }
+
+}
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangEnumeration.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangEnumeration.java
index ec5374e..b89cc82 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangEnumeration.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangEnumeration.java
@@ -16,13 +16,13 @@
 
 package org.onosproject.yangutils.datamodel;
 
+import java.util.HashSet;
+import java.util.Set;
+
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.parser.Parsable;
 import org.onosproject.yangutils.parser.ParsableDataType;
 
-import java.util.HashSet;
-import java.util.Set;
-
 /*
  * The enumeration built-in type represents values from a set of
  *  assigned names.
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangList.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
index 624790e..d2ee876 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangList.java
@@ -438,7 +438,7 @@
      */
     @Override
     public void validateDataOnExit() throws DataModelException {
-        List<String> keyList = getKeyList();
+        List<String> keys = getKeyList();
         List<YangLeaf> leaves = getListOfLeaf();
         List<YangLeafList> leafLists = getListOfLeafList();
 
@@ -447,29 +447,32 @@
 
         /* A list must have atleast one key leaf if config is true */
         if ((isConfig)
-            && ((keyList == null) || (leaves == null && leafLists == null))) {
-                throw new DataModelException("A list must have atleast one key leaf if config is true;");
-        } else if (keyList != null) {
+                && ((keys == null) || ((leaves == null) && (leafLists == null)))) {
+            throw new DataModelException("A list must have atleast one key leaf if config is true;");
+        } else if (keys != null) {
             if (leaves != null) {
-                validateLeafKey(leaves, keyList);
+                validateLeafKey(leaves, keys);
             }
 
             if (leafLists != null) {
-                validateLeafListKey(leafLists, keyList);
+                validateLeafListKey(leafLists, keys);
             }
         }
     }
 
     /**
-     * Sets the config's value to all leaf if leaf's config statement is not specified.
+     * Sets the config's value to all leaf if leaf's config statement is not
+     * specified.
      *
      * @param leaves list of leaf attributes of YANG list.
      * @param leafLists list of leaf-list attributes of YANG list.
      */
     private void setDefaultConfigValueToChild(List<YangLeaf> leaves, List<YangLeafList> leafLists) {
 
-        /* If "config" is not specified, the default is the same as the parent
-            schema node's "config" value.*/
+        /*
+         * If "config" is not specified, the default is the same as the parent
+         * schema node's "config" value.
+         */
         if (leaves != null) {
             for (YangLeaf leaf : leaves) {
                 if (leaf.isConfig() == null) {
@@ -478,8 +481,10 @@
             }
         }
 
-        /* If "config" is not specified, the default is the same as the parent
-           schema node's "config" value.*/
+        /*
+         * If "config" is not specified, the default is the same as the parent
+         * schema node's "config" value.
+         */
         if (leafLists != null) {
             for (YangLeafList leafList : leafLists) {
                 if (leafList.isConfig() == null) {
@@ -498,8 +503,10 @@
      */
     private void validateConfig(List<YangLeaf> leaves, List<YangLeafList> leafLists) throws DataModelException {
 
-        /* If a node has "config" set to "false", no node underneath it can have
-             "config" set to "true".*/
+        /*
+         * If a node has "config" set to "false", no node underneath it can have
+         * "config" set to "true".
+         */
         if ((!isConfig) && (leaves != null)) {
             for (YangLeaf leaf : leaves) {
                 if (leaf.isConfig()) {
@@ -523,19 +530,21 @@
      * Validates key statement of list.
      *
      * @param leaves list of leaf attributes of list.
-     * @param keyList list of key attributes of list.
+     * @param keys list of key attributes of list.
      * @throws DataModelException a violation of data model rules.
      */
-    private void validateLeafKey(List<YangLeaf> leaves, List<String> keyList) throws DataModelException {
+    private void validateLeafKey(List<YangLeaf> leaves, List<String> keys) throws DataModelException {
         boolean leafFound = false;
         List<YangLeaf> keyLeaves = new LinkedList<>();
 
-        /* 1. Leaf identifier must refer to a child leaf of the list
-           2.  A leaf that is part of the key must not be the built-in type "empty". */
-        for (String key : keyList) {
+        /*
+         * 1. Leaf identifier must refer to a child leaf of the list 2. A leaf
+         * that is part of the key must not be the built-in type "empty".
+         */
+        for (String key : keys) {
             for (YangLeaf leaf : leaves) {
                 if (key.equals(leaf.getLeafName())) {
-                    if (leaf.getDataType().getDataTypeName().replace("\"", "").equals("empty")) {
+                    if (leaf.getDataType().getDataType() == YangDataTypes.EMPTY) {
                         throw new DataModelException(" A leaf that is part of the key must not be the built-in " +
                                 "type \"empty\".");
                     }
@@ -550,8 +559,10 @@
             leafFound = false;
         }
 
-        /* All key leafs in a list MUST have the same value for their "config"
-           as the list itself. */
+        /*
+         * All key leafs in a list MUST have the same value for their "config"
+         * as the list itself.
+         */
         for (YangLeaf keyLeaf : keyLeaves) {
             if (isConfig != keyLeaf.isConfig()) {
                 throw new DataModelException("All key leafs in a list must have the same value for their" +
@@ -564,19 +575,21 @@
      * Validates key statement of list.
      *
      * @param leafLists list of leaf-list attributes of list.
-     * @param keyList list of key attributes of list.
+     * @param keys list of key attributes of list.
      * @throws DataModelException a violation of data model rules.
      */
-    private void validateLeafListKey(List<YangLeafList> leafLists, List<String> keyList) throws DataModelException {
+    private void validateLeafListKey(List<YangLeafList> leafLists, List<String> keys) throws DataModelException {
         boolean leafFound = false;
         List<YangLeafList> keyLeafLists = new LinkedList<>();
 
-        /* 1. Leaf identifier must refer to a child leaf of the list
-           2.  A leaf that is part of the key must not be the built-in type "empty". */
-        for (String key : keyList) {
+        /*
+         * 1. Leaf identifier must refer to a child leaf of the list 2. A leaf
+         * that is part of the key must not be the built-in type "empty".
+         */
+        for (String key : keys) {
             for (YangLeafList leafList : leafLists) {
                 if (key.equals(leafList.getLeafName())) {
-                    if (leafList.getDataType().getDataTypeName().replace("\"", "").equals("empty")) {
+                    if (leafList.getDataType().getDataType() == YangDataTypes.EMPTY) {
                         throw new DataModelException(" A leaf-list that is part of the key must not be the built-in " +
                                 "type \"empty\".");
                     }
@@ -591,8 +604,10 @@
             leafFound = false;
         }
 
-        /* All key leafs in a list MUST have the same value for their "config"
-             as the list itself. */
+        /*
+         * All key leafs in a list MUST have the same value for their "config"
+         * as the list itself.
+         */
         for (YangLeafList keyLeafList : keyLeafLists) {
             if (isConfig() != keyLeafList.isConfig()) {
                 throw new DataModelException("All key leaf-lists in a list must have the same value for their" +
@@ -601,8 +616,9 @@
         }
     }
 
-    /* (non-Javadoc)
-     * @see org.onosproject.yangutils.translator.CodeGenerator#generateJavaCodeEntry()
+    /**
+     * Populate the cached handle with information about the list attributes to
+     * generate java code.
      */
     @Override
     public void generateJavaCodeEntry() {
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
index 8eda617..5644d82 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangModule.java
@@ -166,6 +166,43 @@
      */
     private CachedFileHandle fileHandle;
 
+    /*-
+     * Nested typedefs and groupings.
+     * Typedefs and groupings may appear nested under many YANG statements,
+     * allowing these to be lexically scoped by the hierarchy under which
+     * they appear.  This allows types and groupings to be defined near
+     * where they are used, rather than placing them at the top level of the
+     * hierarchy.  The close proximity increases readability.
+     *
+     * Scoping also allows types to be defined without concern for naming
+     * conflicts between types in different submodules.  Type names can be
+     * specified without adding leading strings designed to prevent name
+     * collisions within large modules.
+     *
+     * Finally, scoping allows the module author to keep types and groupings
+     * private to their module or submodule, preventing their reuse.  Since
+     * only top-level types and groupings (i.e., those appearing as
+     * sub-statements to a module or submodule statement) can be used outside
+     * the module or submodule, the developer has more control over what
+     * pieces of their module are presented to the outside world, supporting
+     * the need to hide internal information and maintaining a boundary
+     * between what is shared with the outside world and what is kept
+     * private.
+     *
+     * Scoped definitions MUST NOT shadow definitions at a higher scope.  A
+     * type or grouping cannot be defined if a higher level in the schema
+     * hierarchy has a definition with a matching identifier.
+     *
+     * A reference to an unprefixed type or grouping, or one which uses the
+     * prefix of the current module, is resolved by locating the closest
+     * matching "typedef" or "grouping" statement among the immediate
+     * sub-statements of each ancestor statement.
+     */
+    /**
+     * List of nodes which require nested reference resolution.
+     */
+    private List<YangNode> nestedReferenceResoulutionList;
+
     /**
      * Create a YANG node of module type.
      */
@@ -173,16 +210,20 @@
         super(YangNodeType.MODULE_NODE);
     }
 
-    /* (non-Javadoc)
-     * @see org.onosproject.yangutils.datamodel.YangNode#getName()
+    /**
+     * Get name of the module.
+     *
+     * @return module name.
      */
     @Override
     public String getName() {
         return name;
     }
 
-    /* (non-Javadoc)
-     * @see org.onosproject.yangutils.datamodel.YangNode#setName(java.lang.String)
+    /**
+     * Set module name.
+     *
+     * @param moduleName module name.
      */
     @Override
     public void setName(String moduleName) {
@@ -511,6 +552,37 @@
     }
 
     /**
+     * Get the list of nested reference's which required resolution.
+     *
+     * @return list of nested reference's which required resolution.
+     */
+    public List<YangNode> getNestedReferenceResoulutionList() {
+        return nestedReferenceResoulutionList;
+    }
+
+    /**
+     * Set list of nested reference's which requires resolution.
+     *
+     * @param nestedReferenceResoulutionList list of nested reference's which
+     *            requires resolution.
+     */
+    private void setNestedReferenceResoulutionList(List<YangNode> nestedReferenceResoulutionList) {
+        this.nestedReferenceResoulutionList = nestedReferenceResoulutionList;
+    }
+
+    /**
+     * Set list of nested reference's which requires resolution.
+     *
+     * @param nestedReference nested reference which requires resolution.
+     */
+    public void addToNestedReferenceResoulutionList(YangNode nestedReference) {
+        if (getNestedReferenceResoulutionList() == null) {
+            setNestedReferenceResoulutionList(new LinkedList<YangNode>());
+        }
+        getNestedReferenceResoulutionList().add(nestedReference);
+    }
+
+    /**
      * Returns the type of the parsed data.
      *
      * @return returns MODULE_DATA.
@@ -601,4 +673,28 @@
         }
     }
 
+    /**
+     * Add a type to resolve the nested references.
+     *
+     * @param node grouping or typedef node which needs to be resolved.
+     * @throws DataModelException data model exception.
+     */
+    public static void addToResolveList(YangNode node) throws DataModelException {
+        /* get the module node to add maintain the list of nested reference */
+        YangModule module;
+        YangNode curNode = node;
+        while (curNode.getNodeType() != YangNodeType.MODULE_NODE) {
+            curNode = curNode.getParent();
+            if (curNode == null) {
+                break;
+            }
+        }
+        if (curNode == null) {
+            throw new DataModelException("Datamodel tree is not correct");
+        }
+
+        module = (YangModule) curNode;
+        module.addToNestedReferenceResoulutionList(node);
+        return;
+    }
 }
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangPatternRestriction.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangPatternRestriction.java
index dca527e..a229b9c 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangPatternRestriction.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangPatternRestriction.java
@@ -13,6 +13,7 @@
 limitations under the License.*/
 package org.onosproject.yangutils.datamodel;
 
+import java.util.LinkedList;
 import java.util.List;
 
 /*-
@@ -51,7 +52,7 @@
     /**
      * Pattern restriction defined for the current type.
      */
-    private List<String> pattern;
+    private List<String> patternList;
 
     /**
      * Effective pattern restriction that needs inherited from base type.
@@ -62,6 +63,7 @@
      * Default constructor.
      */
     public YangPatternRestriction() {
+        setPatternList(new LinkedList<String>());
     }
 
     /**
@@ -69,8 +71,8 @@
      *
      * @return pattern restriction defined for the current type.
      */
-    public List<String> getPattern() {
-        return pattern;
+    public List<String> getPatternList() {
+        return patternList;
     }
 
     /**
@@ -78,8 +80,17 @@
      *
      * @param pattern pattern restriction defined for the current type..
      */
-    public void setPattern(List<String> pattern) {
-        this.pattern = pattern;
+    private void setPatternList(List<String> pattern) {
+        patternList = pattern;
+    }
+
+    /**
+     * Add a new pattern to the list of pattern restriction.
+     *
+     * @param newPattern pattern restriction.
+     */
+    public void addPattern(String newPattern) {
+        getPatternList().add(newPattern);
     }
 
     /**
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangRangeRestriction.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangRangeRestriction.java
index abbc6c2..88fdb42 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangRangeRestriction.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangRangeRestriction.java
@@ -143,7 +143,7 @@
      * @param newInterval restricted length interval.
      * @throws DataModelException data model exception for range restriction.
      */
-    public void addLenghtRestrictionInterval(YangRangeInterval<T> newInterval) throws DataModelException {
+    public void addRangeRestrictionInterval(YangRangeInterval<T> newInterval) throws DataModelException {
 
         checkNotNull(newInterval);
         checkNotNull(newInterval.getStartValue());
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java
index 9cccaee..d2b6462 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java
@@ -109,7 +109,19 @@
      *
      * @param patternRestriction pattern restriction for the type.
      */
-    public void setPatternRestriction(YangPatternRestriction patternRestriction) {
+    private void setPatternRestriction(YangPatternRestriction patternRestriction) {
         this.patternRestriction = patternRestriction;
     }
+
+    /**
+     * Add a new pattern restriction for the type.
+     *
+     * @param newPattern new pattern restriction for the type.
+     */
+    public void addPattern(String newPattern) {
+        if (getPatternRestriction() == null) {
+            setPatternRestriction(new YangPatternRestriction());
+        }
+        getPatternRestriction().addPattern(newPattern);
+    }
 }
diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java
index 0ce074e..f1250a2 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java
@@ -54,10 +54,6 @@
  */
 public class YangTypeDef extends YangNode implements YangCommonInfo, Parsable {
 
-    /**
-     * Name of derived data type.
-     */
-    private String derivedName;
 
     /**
      * Default value in string, needs to be converted to the target object,
@@ -81,14 +77,9 @@
     private YangStatusType status;
 
     /**
-     * Derived data type. The type will be set when the parser detects the type
-     * parsing. Hence it is of raw type and it not know at the time of creation
-     * of the object. i.e. in entry parse, it will not be know, in the exit
-     * parse we may know the type implicitly based on the restriction. We must
-     * know and validate the base built in type, by the linking phase. It is a
-     * RAW type and it usage needs to be validate in linking phase.
+     * Maintain the derived type information.
      */
-    private YangType<?> derivedType;
+    private YangType<YangDerivedType> derivedType;
 
     /**
      * Units of the data type.
@@ -96,11 +87,6 @@
     private String units;
 
     /**
-     * YANG base built in data type.
-     */
-    private YangDataTypes baseBuiltInType;
-
-    /**
      * package of the generated java code.
      */
     private String pkg;
@@ -112,23 +98,7 @@
         super(YangNodeType.TYPEDEF_NODE);
     }
 
-    /**
-     * Get the data type name.
-     *
-     * @return the data type name.
-     */
-    public String getDerivedName() {
-        return derivedName;
-    }
 
-    /**
-     * Set the data type name.
-     *
-     * @param derrivedName data type name.
-     */
-    public void setDerivedName(String derrivedName) {
-        derivedName = derrivedName;
-    }
 
     /**
      * Get the default value.
@@ -209,20 +179,20 @@
     }
 
     /**
-     * Get the referenced type.
+     * Get the derived type.
      *
-     * @return the referenced type.
+     * @return the derived type.
      */
-    public YangType<?> getDerivedType() {
+    public YangType<YangDerivedType> getDerivedType() {
         return derivedType;
     }
 
     /**
-     * Get the referenced type.
+     * Set the derived type.
      *
-     * @param derivedType the referenced type.
+     * @param derivedType the derived type.
      */
-    public void setDerivedType(YangType<?> derivedType) {
+    public void setDerivedType(YangType<YangDerivedType> derivedType) {
         this.derivedType = derivedType;
     }
 
@@ -245,24 +215,6 @@
     }
 
     /**
-     * Get the base built in YANG data type.
-     *
-     * @return base built in YANG data type.
-     */
-    public YangDataTypes getBaseBuiltInType() {
-        return baseBuiltInType;
-    }
-
-    /**
-     * Set the base built in YANG data type.
-     *
-     * @param baseBuiltInType base built in YANG data type.
-     */
-    public void setBaseBuiltInType(YangDataTypes baseBuiltInType) {
-        this.baseBuiltInType = baseBuiltInType;
-    }
-
-    /**
      * Returns the type of the data.
      *
      * @return returns TYPEDEF_DATA
@@ -289,7 +241,34 @@
      */
     @Override
     public void validateDataOnExit() throws DataModelException {
-        // TODO auto-generated method stub, to be implemented by parser
+        YangType<YangDerivedType> type = getDerivedType();
+        if (type == null) {
+            throw new DataModelException("Typedef does not have type info.");
+        }
+        if ((type.getDataType() != YangDataTypes.DERIVED)
+                || (type.getDataTypeName() == null)) {
+            throw new DataModelException("Typedef type is not derived.");
+        }
+
+        YangDerivedType derivedTypeInfo = type.getDataTypeExtendedInfo();
+        if (derivedTypeInfo == null) {
+            throw new DataModelException("derrived type does not have derived info.");
+        }
+
+        YangType<?> baseType = derivedTypeInfo.getBaseType();
+        if (baseType == null) {
+            throw new DataModelException("Base type of a derived type is missing.");
+        }
+
+        if (derivedTypeInfo.getEffectiveYangBuiltInType() == null) {
+            /* resolve the effective type from the data tree. */
+            /*
+             * TODO: try to resolve the nested reference, if possible in the
+             * partial tree, otherwise we need to resolve finally when the
+             * complete module is created.
+             */
+            YangModule.addToResolveList(this);
+        }
     }
 
     /**
@@ -299,7 +278,10 @@
      */
     @Override
     public String getName() {
-        return derivedName;
+        if (getDerivedType() != null) {
+            return getDerivedType().getDataTypeName();
+        }
+        return null;
     }
 
     /**
@@ -309,8 +291,12 @@
      */
     @Override
     public void setName(String name) {
-        // TODO Auto-generated method stub
-
+        if (getDerivedType() == null) {
+            throw new RuntimeException(
+                    "Derrived Type info needs to be set in parser when the typedef listner is processed");
+        }
+        getDerivedType().setDataTypeName(name);
+        getDerivedType().setDataType(YangDataTypes.DERIVED);
     }
 
     /**