diff --git a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
index a0e83ec..8c94d7d 100644
--- a/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
+++ b/utils/yangutils/src/main/java/org/onosproject/yangutils/datamodel/YangDerivedInfo.java
@@ -16,12 +16,30 @@
 
 package org.onosproject.yangutils.datamodel;
 
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import com.google.common.base.Strings;
+
+import static org.onosproject.yangutils.datamodel.ResolvableStatus.INTRA_FILE_RESOLVED;
+import static org.onosproject.yangutils.datamodel.ResolvableStatus.RESOLVED;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.BITS;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.BOOLEAN;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.EMPTY;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.ENUMERATION;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.IDENTITYREF;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.LEAFREF;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UNION;
+import static org.onosproject.yangutils.utils.RestrictionResolver.isOfRangeRestrictedType;
+import static org.onosproject.yangutils.utils.RestrictionResolver.processLengthRestriction;
+import static org.onosproject.yangutils.utils.RestrictionResolver.processRangeRestriction;
+
 /**
  * Represents the derived information.
  *
  * @param <T> extended information.
  */
-public class YangDerivedInfo<T> {
+public class YangDerivedInfo<T> implements LocationInfo {
 
     /**
      * YANG typedef reference.
@@ -36,11 +54,38 @@
     private T resolvedExtendedInfo;
 
     /**
-     * Additional information about data type, example restriction info, named
-     * values, etc. The extra information is based on the data type. Based on
-     * the data type, the extended info can vary.
+     * Line number of pattern restriction in YANG file.
      */
-    private T extendedInfo;
+    private int lineNumber;
+
+    /**
+     * Position of pattern restriction in line.
+     */
+    private int charPositionInLine;
+
+    /**
+     * Effective built-in type, requried in case type of typedef is again a
+     * derived type. This information is to be added during linking.
+     */
+    private YangDataTypes effectiveBuiltInType;
+
+    /**
+     * Length restriction string to temporary store the length restriction when the type
+     * is derived.
+     */
+    private String lengthRestrictionString;
+
+    /**
+     * Range restriction string to temporary store the range restriction when the type
+     * is derived.
+     */
+    private String rangeRestrictionString;
+
+    /**
+     * Pattern restriction string to  temporary store the pattern restriction when the type
+     * is derived.
+     */
+    private YangPatternRestriction patternRestriction;
 
     /**
      * Returns the referred typedef reference.
@@ -78,21 +123,503 @@
         this.resolvedExtendedInfo = resolvedExtendedInfo;
     }
 
-    /**
-     * Returns extended information.
-     *
-     * @return extended information
-     */
-    public T getExtendedInfo() {
-        return extendedInfo;
+    @Override
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public int getCharPosition() {
+        return charPositionInLine;
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        this.lineNumber = lineNumber;
+    }
+
+    @Override
+    public void setCharPosition(int charPositionInLine) {
+        this.charPositionInLine = charPositionInLine;
     }
 
     /**
-     * Sets extended information.
+     * Returns the length restriction string.
      *
-     * @param extendedInfo extended information
+     * @return the length restriction string
      */
-    public void setExtendedInfo(T extendedInfo) {
-        this.extendedInfo = extendedInfo;
+    public String getLengthRestrictionString() {
+        return lengthRestrictionString;
+    }
+
+    /**
+     * Sets the length restriction string.
+     *
+     * @param lengthRestrictionString the length restriction string
+     */
+    public void setLengthRestrictionString(String lengthRestrictionString) {
+        this.lengthRestrictionString = lengthRestrictionString;
+    }
+
+    /**
+     * Returns the range restriction string.
+     *
+     * @return the range restriction string
+     */
+    public String getRangeRestrictionString() {
+        return rangeRestrictionString;
+    }
+
+    /**
+     * Sets the range restriction string.
+     *
+     * @param rangeRestrictionString the range restriction string
+     */
+    public void setRangeRestrictionString(String rangeRestrictionString) {
+        this.rangeRestrictionString = rangeRestrictionString;
+    }
+
+    /**
+     * Returns the pattern restriction.
+     *
+     * @return the pattern restriction
+     */
+    public YangPatternRestriction getPatternRestriction() {
+        return patternRestriction;
+    }
+
+    /**
+     * Sets the pattern restriction.
+     *
+     * @param patternRestriction the pattern restriction
+     */
+    public void setPatternRestriction(YangPatternRestriction patternRestriction) {
+        this.patternRestriction = patternRestriction;
+    }
+
+    /**
+     * Returns effective built-in type.
+     *
+     * @return effective built-in type
+     */
+    public YangDataTypes getEffectiveBuiltInType() {
+        return effectiveBuiltInType;
+    }
+
+    /**
+     * Sets effective built-in type.
+     *
+     * @param effectiveBuiltInType effective built-in type
+     */
+    public void setEffectiveBuiltInType(YangDataTypes effectiveBuiltInType) {
+        this.effectiveBuiltInType = effectiveBuiltInType;
+    }
+
+    /**
+     * Resolves the type derived info, by obtaining the effective built-in type
+     * and resolving the restrictions.
+     *
+     * @return resolution status
+     * @throws DataModelException a violation in data mode rule
+     */
+    public ResolvableStatus resolve() throws DataModelException {
+
+        YangType<?> baseType = getReferredTypeDef().getTypeDefBaseType();
+
+        /*
+         * Checks the data type of the referred typedef, if it's derived,
+         * obtain effective built-in type and restrictions from it's derived
+         * info, otherwise take from the base type of type itself.
+         */
+        if (baseType.getDataType() == DERIVED) {
+            /*
+             * Check whether the referred typedef is resolved.
+             */
+            if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED && baseType.getResolvableStatus() != RESOLVED) {
+                throw new DataModelException("Linker Error: Referred typedef is not resolved.");
+            }
+
+            /*
+             * Check if the referred typedef is intra file resolved, if yes sets
+             * current status also to intra file resolved .
+             */
+            if (getReferredTypeDef().getTypeDefBaseType().getResolvableStatus() == INTRA_FILE_RESOLVED) {
+                return INTRA_FILE_RESOLVED;
+            }
+            setEffectiveBuiltInType(((YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo())
+                    .getEffectiveBuiltInType());
+            YangDerivedInfo refDerivedInfo = ((YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo());
+            /*
+             * Check whether the effective built-in type can have range
+             * restrictions, if yes call resolution of range.
+             */
+            if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
+                if (refDerivedInfo.getResolvedExtendedInfo() == null) {
+                    resolveRangeRestriction(null);
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                } else {
+                    if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
+                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
+                                "type.");
+                    }
+                    resolveRangeRestriction((YangRangeRestriction) refDerivedInfo.getResolvedExtendedInfo());
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                }
+                /*
+                 * If the effective built-in type is of type string calls
+                 * for string resolution.
+                 */
+            } else if (getEffectiveBuiltInType() == STRING) {
+                if (refDerivedInfo.getResolvedExtendedInfo() == null) {
+                    resolveStringRestriction(null);
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                } else {
+                    if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangStringRestriction)) {
+                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
+                                "type.");
+                    }
+                    resolveStringRestriction((YangStringRestriction) refDerivedInfo.getResolvedExtendedInfo());
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                }
+            }
+        } else {
+            setEffectiveBuiltInType((baseType.getDataType()));
+            /*
+             * Check whether the effective built-in type can have range
+             * restrictions, if yes call resolution of range.
+             */
+            if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
+                if (baseType.getDataTypeExtendedInfo() == null) {
+                    resolveRangeRestriction(null);
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                } else {
+                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangRangeRestriction)) {
+                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
+                                "type.");
+                    }
+                    resolveRangeRestriction((YangRangeRestriction) baseType.getDataTypeExtendedInfo());
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                }
+                /*
+                 * If the effective built-in type is of type string calls
+                 * for string resolution.
+                 */
+            } else if (getEffectiveBuiltInType() == STRING) {
+                if (baseType.getDataTypeExtendedInfo() == null) {
+                    resolveStringRestriction(null);
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                } else {
+                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangStringRestriction)) {
+                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
+                                "type.");
+                    }
+                    resolveStringRestriction((YangStringRestriction) baseType.getDataTypeExtendedInfo());
+                    /*
+                     * Return the resolution status as resolved, if it's not
+                     * resolve range/string restriction will throw exception
+                     * in previous function.
+                     */
+                    return RESOLVED;
+                }
+            }
+        }
+
+        /*
+         * Check if the data type is the one which can't be restricted, in
+         * this case check whether no self restrictions should be present.
+         */
+        if (isOfValidNonRestrictedType(getEffectiveBuiltInType())) {
+            if (Strings.isNullOrEmpty(getLengthRestrictionString())
+                    && Strings.isNullOrEmpty(getRangeRestrictionString())
+                    && getPatternRestriction() == null) {
+                return RESOLVED;
+            } else {
+                throw new DataModelException("YANG file error: Restrictions can't be applied to a given type");
+            }
+        }
+
+        // Throw exception for unsupported types
+        throw new DataModelException("Linker error: Unable to process the derived type.");
+    }
+
+    /**
+     * Resolves the string restrictions.
+     *
+     * @param refStringRestriction referred string restriction of typedef
+     * @throws DataModelException a violation in data model rule
+     */
+    private void resolveStringRestriction(YangStringRestriction refStringRestriction) throws DataModelException {
+        YangStringRestriction curStringRestriction = null;
+        YangRangeRestriction refRangeRestriction = null;
+        YangPatternRestriction refPatternRestriction = null;
+
+        /*
+         * Check that range restriction should be null when built-in type is
+         * string.
+         */
+        if (!(Strings.isNullOrEmpty(getRangeRestrictionString()))) {
+            DataModelException dataModelException = new DataModelException("YANG file error: Range restriction " +
+                    "should't be present for string data type.");
+            dataModelException.setLine(lineNumber);
+            dataModelException.setCharPosition(charPositionInLine);
+            throw dataModelException;
+        }
+
+        /*
+         * If referred restriction and self restriction both are null, no
+         * resolution is required.
+         */
+        if (refStringRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())
+                && getPatternRestriction() == null) {
+            return;
+        }
+
+        /*
+         * If referred string restriction is not null, take value of length
+         * and pattern restriction and assign.
+         */
+        if (refStringRestriction != null) {
+            refRangeRestriction = refStringRestriction.getLengthRestriction();
+            refPatternRestriction = refStringRestriction.getPatternRestriction();
+        }
+
+        YangRangeRestriction lengthRestriction = resolveLengthRestriction(refRangeRestriction);
+        YangPatternRestriction patternRestriction = resolvePatternRestriction(refPatternRestriction);
+
+        /*
+         * Check if either of length or pattern restriction is present, if yes
+         * create string restriction and assign value.
+         */
+        if (lengthRestriction != null || patternRestriction != null) {
+            curStringRestriction = new YangStringRestriction();
+            curStringRestriction.setLengthRestriction(lengthRestriction);
+            curStringRestriction.setPatternRestriction(patternRestriction);
+        }
+        setResolvedExtendedInfo((T) curStringRestriction);
+    }
+
+    /**
+     * Resolves pattern restriction.
+     *
+     * @param refPatternRestriction referred pattern restriction of typedef
+     * @return resolved pattern restriction
+     */
+    private YangPatternRestriction resolvePatternRestriction(YangPatternRestriction refPatternRestriction) {
+        /*
+         * If referred restriction and self restriction both are null, no
+         * resolution is required.
+         */
+        if (refPatternRestriction == null && getPatternRestriction() == null) {
+            return null;
+        }
+
+        /*
+         * If self restriction is null, and referred restriction is present
+         * shallow copy the referred to self.
+         */
+        if (getPatternRestriction() == null) {
+            return refPatternRestriction;
+        }
+
+        /*
+         * If referred restriction is null, and self restriction is present
+         * carry out self resolution.
+         */
+        if (refPatternRestriction == null) {
+            return getPatternRestriction();
+        }
+
+        /*
+         * Get patterns of referred type and add it to current pattern
+         * restrictions.
+         */
+        for (String pattern : refPatternRestriction.getPatternList()) {
+            getPatternRestriction().addPattern(pattern);
+        }
+        return getPatternRestriction();
+    }
+
+    /**
+     * Resolves the length restrictions.
+     *
+     * @param refLengthRestriction referred length restriction of typedef
+     * @return resolved length restriction
+     * @throws DataModelException a violation in data model rule
+     */
+    private YangRangeRestriction resolveLengthRestriction(YangRangeRestriction refLengthRestriction) throws
+            DataModelException {
+
+        /*
+         * If referred restriction and self restriction both are null, no
+         * resolution is required.
+         */
+        if (refLengthRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())) {
+            return null;
+        }
+
+        /*
+         * If self restriction is null, and referred restriction is present
+         * shallow copy the referred to self.
+         */
+        if (Strings.isNullOrEmpty(getLengthRestrictionString())) {
+            return refLengthRestriction;
+        }
+
+        /*
+         * If referred restriction is null, and self restriction is present
+         * carry out self resolution.
+         */
+        if (refLengthRestriction == null) {
+            YangRangeRestriction curLengthRestriction = processLengthRestriction(null, lineNumber,
+                    charPositionInLine, false, getLengthRestrictionString());
+            return curLengthRestriction;
+        }
+
+        /*
+         * Carry out self resolution based with obtained effective built-in
+         * type and MIN/MAX values as per the referred typedef's values.
+         */
+        YangRangeRestriction curLengthRestriction = processLengthRestriction(refLengthRestriction, lineNumber,
+                charPositionInLine, true, getLengthRestrictionString());
+
+        // Resolve the range with referred typedef's restriction.
+        resolveLengthAndRangeRestriction(refLengthRestriction, curLengthRestriction);
+        return curLengthRestriction;
+    }
+
+    /**
+     * Resolves the length/range self and referred restriction, to check whether
+     * the all the range interval in self restriction is stricter than the
+     * referred typedef's restriction.
+     *
+     * @param refRestriction referred restriction
+     * @param curRestriction self restriction
+     */
+    private void resolveLengthAndRangeRestriction(YangRangeRestriction refRestriction,
+                                                  YangRangeRestriction curRestriction) throws DataModelException {
+        for (Object curInterval : curRestriction.getAscendingRangeIntervals()) {
+            if (!(curInterval instanceof YangRangeInterval)) {
+                throw new DataModelException("Linker error: Current range intervals not processed correctly.");
+            }
+            try {
+                refRestriction.isValidInterval((YangRangeInterval) curInterval);
+            } catch (DataModelException e) {
+                DataModelException dataModelException = new DataModelException(e);
+                dataModelException.setLine(lineNumber);
+                dataModelException.setCharPosition(charPositionInLine);
+                throw dataModelException;
+            }
+        }
+    }
+
+    /**
+     * Resolves the range restrictions.
+     *
+     * @param refRangeRestriction referred range restriction of typedef
+     * @throws DataModelException a violation in data model rule
+     */
+    private void resolveRangeRestriction(YangRangeRestriction refRangeRestriction) throws DataModelException {
+
+        /*
+         * Check that string restriction should be null when built-in type is
+         * of range type.
+         */
+        if (!(Strings.isNullOrEmpty(getLengthRestrictionString())) || getPatternRestriction() != null) {
+            DataModelException dataModelException = new DataModelException("YANG file error: Length/Pattern " +
+                    "restriction should't be present for int/uint/decimal data type.");
+            dataModelException.setLine(lineNumber);
+            dataModelException.setCharPosition(charPositionInLine);
+            throw dataModelException;
+        }
+
+        /*
+         * If referred restriction and self restriction both are null, no
+         * resolution is required.
+         */
+        if (refRangeRestriction == null && Strings.isNullOrEmpty(getRangeRestrictionString())) {
+            return;
+        }
+
+        /*
+         * If self restriction is null, and referred restriction is present
+         * shallow copy the referred to self.
+         */
+        if (Strings.isNullOrEmpty(getRangeRestrictionString())) {
+            setResolvedExtendedInfo((T) refRangeRestriction);
+            return;
+        }
+
+        /*
+         * If referred restriction is null, and self restriction is present
+         * carry out self resolution.
+         */
+        if (refRangeRestriction == null) {
+            YangRangeRestriction curRangeRestriction = processRangeRestriction(null, lineNumber,
+                    charPositionInLine, false, getRangeRestrictionString(), getEffectiveBuiltInType());
+            setResolvedExtendedInfo((T) curRangeRestriction);
+            return;
+        }
+
+        /*
+         * Carry out self resolution based with obtained effective built-in
+         * type and MIN/MAX values as per the referred typedef's values.
+         */
+        YangRangeRestriction curRangeRestriction = processRangeRestriction(refRangeRestriction, lineNumber,
+                charPositionInLine, true, getRangeRestrictionString(), getEffectiveBuiltInType());
+
+        // Resolve the range with referred typedef's restriction.
+        resolveLengthAndRangeRestriction(refRangeRestriction, curRangeRestriction);
+        setResolvedExtendedInfo((T) curRangeRestriction);
+    }
+
+    /**
+     * Returns whether the data type is of non restricted type.
+     *
+     * @param dataType data type to be checked
+     * @return true, if data type can't be restricted, false otherwise
+     */
+    private boolean isOfValidNonRestrictedType(YangDataTypes dataType) {
+        return (dataType == BOOLEAN
+                || dataType == ENUMERATION
+                || dataType == BITS
+                || dataType == EMPTY
+                || dataType == UNION
+                || dataType == IDENTITYREF
+                || dataType == LEAFREF);
     }
 }
