[ONOS-5483] Leafref with path-predicate linking.

Change-Id: Id1f95e7b82de9d0b9b1717b8a0f96fb8d03939b1
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
index 8c2a812..eefb208 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeafRef.java
@@ -108,12 +108,12 @@
     /**
      * Parent node of the leafref's leaf.
      */
-    private YangNode parentNodeOfLeafref;
+    private YangNode parentNode;
 
     /**
      * Prefix in the nodes of the leafref path and its imported node name.
      */
-    private Map<String, String> prefixAndItsImportedModule;
+    private Map<String, String> prefixAndNode;
 
     /**
      * Flag to indicate whether the leaf ref is inside grouping.
@@ -123,19 +123,19 @@
     /**
      * Returns the prefix in the leafref path and its imported node name.
      *
-     * @return the list of leafref prefix and imported node name
+     * @return map of prefix with node
      */
-    public Map<String, String> getPrefixAndItsImportedModule() {
-        return prefixAndItsImportedModule;
+    public Map<String, String> getPrefixAndNode() {
+        return prefixAndNode;
     }
 
     /**
-     * Sets the prefix in the leafref path and its imported node name.
+     * Sets the prefix in the leaf-ref path and its imported node name.
      *
-     * @param prefixAndItsImportedModule the list of leafref prefix and imported node name
+     * @param prefixAndNode prefix with node map
      */
-    public void setPrefixAndItsImportedModule(Map<String, String> prefixAndItsImportedModule) {
-        this.prefixAndItsImportedModule = prefixAndItsImportedModule;
+    public void setPrefixAndNode(Map<String, String> prefixAndNode) {
+        this.prefixAndNode = prefixAndNode;
     }
 
     /**
@@ -143,17 +143,17 @@
      *
      * @return parent node of the leafref
      */
-    public YangNode getParentNodeOfLeafref() {
-        return parentNodeOfLeafref;
+    public YangNode getParentNode() {
+        return parentNode;
     }
 
     /**
      * Sets the parent node from the leafref's leaf.
      *
-     * @param parentNodeOfLeafref parent node of the leafref
+     * @param parentNode parent node
      */
-    public void setParentNodeOfLeafref(YangNode parentNodeOfLeafref) {
-        this.parentNodeOfLeafref = parentNodeOfLeafref;
+    public void setParentNode(YangNode parentNode) {
+        this.parentNode = parentNode;
     }
 
     /**
@@ -166,7 +166,7 @@
      */
     public YangLeafRef() {
         yangAppErrorInfo = new YangAppErrorInfo();
-        prefixAndItsImportedModule = new HashMap<>();
+        prefixAndNode = new HashMap<>();
         atomicPath = new ArrayList<>();
         ifFeatureList = new ArrayList<>();
         yangAppErrorInfo.setErrorTag(DATA_MISSING_ERROR_TAG);
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java
index 2af0e65..da38acd 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangPathPredicate.java
@@ -18,116 +18,126 @@
 import java.io.Serializable;
 
 /**
- * Representation of data model node to maintain path predicate in YANG absolute-path or relative-path.
+ * Representation of data model node to maintain path predicate in YANG
+ * absolute-path or relative-path.
  */
-public class YangPathPredicate<T> extends DefaultLocationInfo
+public class YangPathPredicate extends DefaultLocationInfo
         implements Serializable {
 
     private static final long serialVersionUID = 806201689L;
 
-    // YANG node identifier.
-    private YangNodeIdentifier nodeIdentifier;
+    /**
+     * YANG node id.
+     */
+    private YangNodeIdentifier nodeId;
 
-    // Left axis node will represent the nodeidentifier before equality sign in path predicate.
-    private T leftAxisNode;
+    /**
+     * Left axis represents node-id before equality sign.
+     */
+    private Object leftAxisNode;
 
-    // YANG path operator.
-    private YangPathOperator pathOperator;
+    /**
+     * YANG path operator.
+     */
+    private YangPathOperator pathOp;
 
-    // YANG relative path.
-    private YangRelativePath rightRelativePath;
+    /**
+     * YANG right relative path in path-predicate.
+     */
+    private YangRelativePath relPath;
 
-    // Right axis node will represent the nodeidentifier after equality sign in path predicate.
-    private T rightAxisNode;
+    /**
+     * Right axis node represents the node-id after the equality sign.
+     */
+    private Object rightAxisNode;
 
     /**
      * Returns the path expression operator.
      *
-     * @return the path expression operator
+     * @return path operator
      */
-    public YangPathOperator getPathOperator() {
-        return pathOperator;
+    public YangPathOperator getPathOp() {
+        return pathOp;
     }
 
     /**
      * Sets the path expression operator.
      *
-     * @param pathOperator Sets the path expression operator
+     * @param pathOp path operator
      */
-    public void setPathOperator(YangPathOperator pathOperator) {
-        this.pathOperator = pathOperator;
+    public void setPathOp(YangPathOperator pathOp) {
+        this.pathOp = pathOp;
     }
 
     /**
      * Returns the right relative path expression.
      *
-     * @return the right relative path expression
+     * @return relative path
      */
-    public YangRelativePath getRightRelativePath() {
-        return rightRelativePath;
+    public YangRelativePath getRelPath() {
+        return relPath;
     }
 
     /**
      * Sets the right relative path expression.
      *
-     * @param rightRelativePath Sets the right relative path expression
+     * @param relPath relative path
      */
-    public void setRightRelativePath(YangRelativePath rightRelativePath) {
-        this.rightRelativePath = rightRelativePath;
+    public void setRelPath(YangRelativePath relPath) {
+        this.relPath = relPath;
     }
 
     /**
-     * Returns the nodeidentifier.
+     * Returns the node identifier.
      *
-     * @return the nodeidentifier
+     * @return node id
      */
-    public YangNodeIdentifier getNodeIdentifier() {
-        return nodeIdentifier;
+    public YangNodeIdentifier getNodeId() {
+        return nodeId;
     }
 
     /**
      * Sets the YANG node identifier.
      *
-     * @param nodeIdentifier Sets the node identifier
-     *
+     * @param nodeId node id
      */
-    public void setNodeIdentifier(YangNodeIdentifier nodeIdentifier) {
-        this.nodeIdentifier = nodeIdentifier;
+    public void setNodeId(YangNodeIdentifier nodeId) {
+        this.nodeId = nodeId;
     }
 
     /**
      * Returns the left axis node.
      *
-     * @return the left axis node
+     * @return left axis node
      */
-    public T getLeftAxisNode() {
+    public Object getLeftAxisNode() {
         return leftAxisNode;
     }
 
     /**
      * Sets the left axis node.
      *
-     * @param leftAxisNode Sets the left axis node
+     * @param leftAxisNode left axis node
      */
-    public void setLeftAxisNode(T leftAxisNode) {
+    public void setLeftAxisNode(Object leftAxisNode) {
         this.leftAxisNode = leftAxisNode;
     }
 
     /**
      * Returns the right axis node.
      *
-     * @return the right axis node
+     * @return right axis node
      */
-    public T getRightAxisNode() {
+    public Object getRightAxisNode() {
         return rightAxisNode;
     }
 
     /**
      * Sets the right axis node.
      *
-     * @param rightAxisNode Sets the right axis node
+     * @param rightAxisNode right axis node
      */
-    public void setRightAxisNode(T rightAxisNode) {
+    public void setRightAxisNode(Object rightAxisNode) {
         this.rightAxisNode = rightAxisNode;
     }
 }
diff --git a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 411e88e..5943f17 100644
--- a/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -49,6 +49,7 @@
 import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -351,7 +352,7 @@
             throws CloneNotSupportedException, DataModelException {
 
         List<YangLeaf> leaves = clonedNode.getListOfLeaf();
-        if (isListPresent(leaves)) {
+        if (nonEmpty(leaves)) {
             List<YangLeaf> clonedLeaves = new LinkedList<>();
             for (YangLeaf leaf : leaves) {
                 YangLeaf clonedLeaf = leaf.clone();
@@ -382,20 +383,21 @@
         List<YangEntityToResolveInfoImpl> infoList;
         if (yangUses != null && yangUses.getCurrentGroupingDepth() == 0) {
             infoList = getTypesToBeResolved(clonedObj, clonedNode, yangUses);
-            if (isListPresent(infoList)) {
+            if (nonEmpty(infoList)) {
                 yangUses.addEntityToResolve(infoList);
             }
         }
     }
 
     /**
-     * Returns true if list object is non-null and non-empty; false otherwise.
+     * Returns true if collection object is non-null and non-empty; false
+     * otherwise.
      *
-     * @param listObj list object
-     * @return true if list object is non-null and non-empty; false otherwise
+     * @param c collection object
+     * @return true if object is non-null and non-empty; false otherwise
      */
-    private static boolean isListPresent(List listObj) {
-        return listObj != null && !listObj.isEmpty();
+    public static boolean nonEmpty(Collection<?> c) {
+        return c != null && !c.isEmpty();
     }
 
     /**
@@ -413,7 +415,7 @@
             throws CloneNotSupportedException, DataModelException {
 
         List<YangLeafList> listOfLeafList = clonedNode.getListOfLeafList();
-        if (isListPresent(listOfLeafList)) {
+        if (nonEmpty(listOfLeafList)) {
             List<YangLeafList> clonedList = new LinkedList<>();
             for (YangLeafList leafList : listOfLeafList) {
                 YangLeafList clonedLeafList = leafList.clone();
@@ -500,7 +502,7 @@
                 return null;
         }
         infoList.add(entity);
-        if (isListPresent(entityList)) {
+        if (nonEmpty(entityList)) {
             infoList.addAll(entityList);
         }
         return infoList;
@@ -528,7 +530,7 @@
 
         // Conversion of prefixes in absolute path while cloning them.
         convertThePrefixesDuringChange(leafRef, yangUses);
-        leafRef.setParentNodeOfLeafref(holder);
+        leafRef.setParentNode(holder);
         leafRefInfo.setEntityToResolve(leafRef);
 
         return setInformationInEntity(
@@ -632,7 +634,7 @@
         for (YangType unionType : typeList) {
             entity = getUnresolvedTypeList(unionType.getDataType(),
                                            unionType, union, null, isLeaf);
-            if (isListPresent(entity)) {
+            if (nonEmpty(entity)) {
                 unionList.addAll(entity);
             }
         }
@@ -653,7 +655,7 @@
             Iterator<YangAtomicPath> atomicPathIterator = atomicPathList.listIterator();
             while (atomicPathIterator.hasNext()) {
                 YangAtomicPath atomicPath = atomicPathIterator.next();
-                Map<String, String> prefixesAndItsImportNameNode = leafrefForCloning.getPrefixAndItsImportedModule();
+                Map<String, String> prefixesAndItsImportNameNode = leafrefForCloning.getPrefixAndNode();
                 String prefixInPath = atomicPath.getNodeIdentifier().getPrefix();
                 String importedNodeName = prefixesAndItsImportNameNode.get(prefixInPath);
                 assignCurrentLeafedWithNewPrefixes(importedNodeName, atomicPath, yangUses);
diff --git a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
index 507ebf3..aa55b96 100644
--- a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
+++ b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangLinkerUtils.java
@@ -32,9 +32,12 @@
 import org.onosproject.yangutils.datamodel.YangLeafList;
 import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
+import org.onosproject.yangutils.datamodel.YangList;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
+import org.onosproject.yangutils.datamodel.YangPathPredicate;
 import org.onosproject.yangutils.datamodel.YangReferenceResolver;
+import org.onosproject.yangutils.datamodel.YangRelativePath;
 import org.onosproject.yangutils.datamodel.YangType;
 import org.onosproject.yangutils.datamodel.YangTypeDef;
 import org.onosproject.yangutils.datamodel.YangUses;
@@ -54,7 +57,6 @@
 import static org.onosproject.yangutils.datamodel.TraversalType.PARENT;
 import static org.onosproject.yangutils.datamodel.TraversalType.ROOT;
 import static org.onosproject.yangutils.datamodel.TraversalType.SIBILING;
-import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.CASE;
 import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.COLLISION_DETECTION;
 import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.FAILED_TO_ADD_CASE;
 import static org.onosproject.yangutils.datamodel.exceptions.ErrorMessages.TARGET_NODE;
@@ -74,6 +76,7 @@
 import static org.onosproject.yangutils.utils.UtilConstants.FEATURE_LINKER_ERROR;
 import static org.onosproject.yangutils.utils.UtilConstants.GROUPING_LINKER_ERROR;
 import static org.onosproject.yangutils.utils.UtilConstants.IDENTITYREF_LINKER_ERROR;
+import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TREE;
 import static org.onosproject.yangutils.utils.UtilConstants.IS_INVALID;
 import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_ERROR;
 import static org.onosproject.yangutils.utils.UtilConstants.LEAFREF_LINKER_ERROR;
@@ -85,9 +88,24 @@
 public final class YangLinkerUtils {
 
     private static final int IDENTIFIER_LENGTH = 64;
-    private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
+    private static final Pattern IDENTIFIER_PATTERN =
+            Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
     private static final String XML = "xml";
+    private static final String INVALID_PATH_PRE =
+            "YANG file error: The path predicate of the leafref has an " +
+                    "invalid path in ";
+    private static final String EMPTY_PATH_LIST_ERR =
+            "YANG file error : The atomic path list cannot be empty of the " +
+                    "leafref in the path ";
+    private static final String TGT_LEAF_ERR =
+            "YANG file error: There is no leaf/leaf-list in YANG node as " +
+                    "mentioned in the path predicate of the leafref path ";
+    private static final String LEAF_REF_LIST_ERR =
+            "YANG file error: Path predicates are only applicable for YANG " +
+                    "list. The leafref path has path predicate for non-list " +
+                    "node in the path ";
 
+    // No instantiation.
     private YangLinkerUtils() {
     }
 
@@ -257,33 +275,6 @@
                         .getFileName());
     }
 
-    //Detect collision between augment and choice children.
-    private void detectCollisionForChoiceNode(YangNode choice, YangNode augment) {
-        YangNode choiceChild = choice.getChild();
-        YangNode augmentChild = augment.getChild();
-
-        List<YangNode> choiceChildren = new ArrayList<>();
-        List<YangNode> augmentChildren = new ArrayList<>();
-        while (choiceChild != null) {
-            choiceChildren.add(choiceChild);
-        }
-        while (augmentChild != null) {
-            augmentChildren.add(augmentChild);
-        }
-
-        for (YangNode cChild : choiceChildren) {
-            for (YangNode aChild : augmentChildren) {
-                if (cChild.getName().equals(aChild.getName())) {
-                    ;
-                    throw new LinkerException(getErrorMsgCollision(
-                            COLLISION_DETECTION, cChild.getName(),
-                            cChild.getLineNumber(), cChild.getCharPosition(),
-                            CASE, cChild.getFileName()));
-                }
-            }
-        }
-    }
-
     /**
      * Detects collision between target nodes and its all leaf/leaf-list or child node with augmented leaf/leaf-list or
      * child node.
@@ -328,25 +319,25 @@
     /**
      * Skips the invalid nodes which cannot have data from YANG.
      *
-     * @param currentParent current parent node reference
-     * @param leafref       instance of YANG leafref
+     * @param curParent current parent
+     * @param leafRef   YANG leaf-ref
      * @return parent node which can hold data
-     * @throws LinkerException a violation of linker rules
+     * @throws LinkerException if linker rules are violated
      */
-    static YangNode skipInvalidDataNodes(YangNode currentParent, YangLeafRef leafref)
+    public static YangNode skipInvalidDataNodes(YangNode curParent,
+                                                YangLeafRef leafRef)
             throws LinkerException {
-        while (currentParent instanceof YangChoice || currentParent instanceof YangCase) {
-            if (currentParent.getParent() == null) {
-                LinkerException ex = new LinkerException(
-                        LEAFREF_ERROR + leafref.getPath() + IS_INVALID);
-                ex.setCharPosition(leafref.getCharPosition());
-                ex.setLine(leafref.getLineNumber());
-                ex.setFileName(leafref.getFileName());
-                throw ex;
+
+        YangNode node = curParent;
+        while (node instanceof YangChoice ||
+                node instanceof YangCase) {
+
+            if (node.getParent() == null) {
+                throw new LinkerException(getLeafRefErrorInfo(leafRef));
             }
-            currentParent = currentParent.getParent();
+            node = node.getParent();
         }
-        return currentParent;
+        return node;
     }
 
     /**
@@ -610,4 +601,254 @@
         }
     }
 
+    /**
+     * Fills the path predicates of the leaf-ref with right axis node and
+     * left axis node, after linking the nodes.
+     *
+     * @param leafRef YANG leaf-ref
+     * @throws DataModelException if there is a data model error
+     */
+    public static void fillPathPredicates(YangLeafRef<?> leafRef)
+            throws DataModelException {
+
+        List<YangAtomicPath> atomics = leafRef.getAtomicPath();
+        if (atomics != null) {
+            for (YangAtomicPath atom : atomics) {
+                List<YangPathPredicate> predicates =
+                        atom.getPathPredicatesList();
+
+                if (predicates != null) {
+                    for (YangPathPredicate predicate : predicates) {
+                        setLeftAxisNode(leafRef, atom, predicate);
+                        setRightAxisNode(leafRef, predicate);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the left axis node in the YANG path predicate after finding it
+     * under the YANG list node.
+     *
+     * @param leafRef   YANG leaf-ref
+     * @param atom      atomic path content
+     * @param predicate predicate in the atomic path
+     * @throws DataModelException if there is a data model error
+     */
+    private static void setLeftAxisNode(YangLeafRef<?> leafRef,
+                                        YangAtomicPath atom,
+                                        YangPathPredicate predicate)
+            throws DataModelException {
+        YangNode resolvedNode = atom.getResolvedNode();
+        if (!(resolvedNode instanceof YangList)) {
+            throw getDataModelExc(LEAF_REF_LIST_ERR, leafRef);
+        }
+
+        YangNodeIdentifier leftAxisName = predicate.getNodeId();
+        Object target = getTarget(leftAxisName, resolvedNode, leafRef);
+        predicate.setLeftAxisNode(target);
+    }
+
+    /**
+     * Returns the target leaf/leaf-list from the provided YANG node.
+     *
+     * @param leftAxisName name of node
+     * @param node         node having target
+     * @param leafRef      YANG leaf-ref
+     * @return target leaf/leaf-list
+     * @throws DataModelException if there is a data model error
+     */
+    private static Object getTarget(YangNodeIdentifier leftAxisName,
+                                    YangNode node, YangLeafRef leafRef)
+            throws DataModelException {
+
+        YangLeaf leaf = getLeaf(leftAxisName, (YangLeavesHolder) node);
+        if (leaf != null) {
+            return leaf;
+        }
+        YangLeafList leafList = getLeafList(leftAxisName,
+                                            (YangLeavesHolder) node);
+        if (leafList == null) {
+            throw getDataModelExc(TGT_LEAF_ERR, leafRef);
+        }
+        return leafList;
+    }
+
+    /**
+     * Returns the leaf by searching it in the node by the leaf name. Returns
+     * null when the name doesn't match.
+     *
+     * @param name   leaf name
+     * @param holder holder of leaf
+     * @return YANG leaf
+     */
+    private static YangLeaf getLeaf(YangNodeIdentifier name,
+                                    YangLeavesHolder holder) {
+
+        List<YangLeaf> listOfLeaf = holder.getListOfLeaf();
+        if (listOfLeaf != null) {
+            for (YangLeaf yangLeaf : listOfLeaf) {
+                if (yangLeaf.getName().equals(name.getName())) {
+                    return yangLeaf;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the leaf-list by searching it in the node by the leaf-list name.
+     * Returns null when the name doesn't match.
+     *
+     * @param name   leaf-list name
+     * @param holder holder of leaf-list
+     * @return YANG leaf-list
+     */
+    private static YangLeafList getLeafList(YangNodeIdentifier name,
+                                            YangLeavesHolder holder) {
+
+        List<YangLeafList> listOfLeafList = holder.getListOfLeafList();
+        if (listOfLeafList != null) {
+            for (YangLeafList yangLeafList : listOfLeafList) {
+                if (yangLeafList.getName().equals(name.getName())) {
+                    return yangLeafList;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the root node from which the path with the atomic node names
+     * has to be traversed through. With the ancestor count the nodes are
+     * moved upward.
+     *
+     * @param count   ancestor count
+     * @param node    current leaf-ref parent
+     * @param leafRef YANG leaf-ref
+     * @return root node from ancestor count
+     * @throws DataModelException if there is a data model error
+     */
+    private static YangNode getRootNode(int count, YangNode node,
+                                        YangLeafRef leafRef)
+            throws DataModelException {
+
+        YangNode curParent = node;
+        int curCount = 0;
+        while (curCount < count) {
+            curCount = curCount + 1;
+            if (curCount != 1) {
+                if (curParent.getParent() == null) {
+                    throw getDataModelExc(INVALID_TREE, leafRef);
+                }
+                curParent = curParent.getParent();
+            }
+            curParent = skipInvalidDataNodes(curParent, leafRef);
+            if (curParent instanceof YangAugment) {
+                YangAugment augment = (YangAugment) curParent;
+                curParent = augment.getAugmentedNode();
+                curCount = curCount + 1;
+            }
+        }
+        return curParent;
+    }
+
+    /**
+     * Returns the last node by traversing through the atomic node id by
+     * leaving the last target leaf/leaf-list.
+     *
+     * @param curNode current node
+     * @param relPath relative path
+     * @param leafRef YANG leaf-ref
+     * @return last YANG node
+     * @throws DataModelException if there is a data model error
+     */
+    private static Object getLastNode(YangNode curNode,
+                                      YangRelativePath relPath,
+                                      YangLeafRef leafRef)
+            throws DataModelException {
+
+        YangNode node = curNode;
+        List<YangAtomicPath> atomics = new ArrayList<>();
+        atomics.addAll(relPath.getAtomicPathList());
+
+        if (atomics.isEmpty()) {
+            throw getDataModelExc(EMPTY_PATH_LIST_ERR, leafRef);
+        }
+
+        YangAtomicPath pathTgt = atomics.get(atomics.size() - 1);
+        if (atomics.size() == 1) {
+            return getTarget(pathTgt.getNodeIdentifier(), node, leafRef);
+        }
+
+        atomics.remove(atomics.size() - 1);
+        for (YangAtomicPath atomicPath : atomics) {
+            node = getNode(node.getChild(), atomicPath.getNodeIdentifier());
+            if (node == null) {
+                throw getDataModelExc(INVALID_PATH_PRE, leafRef);
+            }
+        }
+        return getTarget(pathTgt.getNodeIdentifier(), node, leafRef);
+    }
+
+    /**
+     * Returns the node from the parent node by matching it with the atomic
+     * name. If no child node matches the name then it returns null.
+     *
+     * @param curNode    current node
+     * @param identifier atomic name
+     * @return node to be traversed
+     */
+    private static YangNode getNode(YangNode curNode,
+                                    YangNodeIdentifier identifier) {
+        YangNode node = curNode;
+        while (node != null) {
+            if (node.getName().equals(identifier.getName())) {
+                return node;
+            }
+            node = node.getNextSibling();
+        }
+        return null;
+    }
+
+    /**
+     * Sets the right axis node in the YANG path predicate after finding it
+     * from the relative path.
+     *
+     * @param leafRef   YANG leaf-ref
+     * @param predicate YANG path predicate
+     * @throws DataModelException if there is a data model error
+     */
+    private static void setRightAxisNode(YangLeafRef leafRef,
+                                         YangPathPredicate predicate)
+            throws DataModelException {
+
+        YangNode parentNode = leafRef.getParentNode();
+        YangRelativePath relPath = predicate.getRelPath();
+        int ancestor = relPath.getAncestorNodeCount();
+
+        YangNode rootNode = getRootNode(ancestor, parentNode, leafRef);
+        Object target = getLastNode(rootNode, relPath, leafRef);
+        if (target == null) {
+            throw getDataModelExc(INVALID_PATH_PRE, leafRef);
+        }
+        predicate.setRightAxisNode(target);
+    }
+
+    /**
+     * Returns data model error messages for leaf-ref with the path.
+     *
+     * @param msg     error message
+     * @param leafRef YANG leaf-ref
+     * @return data model exception
+     */
+    private static DataModelException getDataModelExc(String msg,
+                                                      YangLeafRef leafRef) {
+        DataModelException exc = new DataModelException(
+                msg + leafRef.getPath());
+        exc.setCharPosition(leafRef.getCharPosition());
+        exc.setLine(leafRef.getLineNumber());
+        return exc;
+    }
 }
diff --git a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
index 480d8c6..3400cfe 100644
--- a/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
+++ b/generator/src/main/java/org/onosproject/yangutils/linker/impl/YangResolutionInfoImpl.java
@@ -81,6 +81,7 @@
 import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.AUGMENT_LINKING;
 import static org.onosproject.yangutils.linker.impl.XpathLinkingTypes.LEAF_REF_LINKING;
 import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.detectCollisionForAugmentedNode;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.fillPathPredicates;
 import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getErrorInfoForLinker;
 import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getLeafRefErrorInfo;
 import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.getPathWithAugment;
@@ -294,7 +295,7 @@
             YangLeafRef leafRefInTypeDef = (YangLeafRef) extendedInfo;
             addRefTypeInfo(YangDataTypes.LEAFREF, LEAFREF, extendedInfo,
                            yangType, refNode, YANG_LEAFREF);
-            leafRefInTypeDef.setParentNodeOfLeafref(refNode);
+            leafRefInTypeDef.setParentNode(refNode);
         } else {
             addRefTypeInfo(YangDataTypes.IDENTITYREF, IDENTITYREF, extendedInfo,
                            yangType, refNode, YANG_IDENTITYREF);
@@ -379,7 +380,7 @@
                         .getEntityToResolve();
                 YangNode parentNodeOfLeafref = entityToResolveInfo
                         .getHolderOfEntityToResolve();
-                leafref.setParentNodeOfLeafref(parentNodeOfLeafref);
+                leafref.setParentNode(parentNodeOfLeafref);
                 if (leafref.getResolvableStatus() == UNRESOLVED) {
                     leafref.setResolvableStatus(INTRA_FILE_RESOLVED);
                 }
@@ -1018,9 +1019,11 @@
      *
      * @param entityToResolve entity to resolve
      * @param root            root node
+     * @throws DataModelException if there is a data model error
      */
     private void processXPathLinking(T entityToResolve,
-                                     YangReferenceResolver root) {
+                                     YangReferenceResolver root)
+            throws DataModelException {
 
         YangXpathLinker<T> xPathLinker = new YangXpathLinker<T>();
 
@@ -1094,7 +1097,7 @@
                     addUnResolvedLeafRefTypeToStack(
                             (T) leafList, entityToResolveInfo.getHolderOfEntityToResolve());
                 }
-                //TODO: add logic for leaf-ref for path predicates.
+                fillPathPredicates(leafRef);
             } else {
                 LinkerException ex = new LinkerException(
                         FAILED_TO_FIND_LEAD_INFO_HOLDER + leafRef.getPath());
@@ -1266,7 +1269,7 @@
         if (resolutionInfo instanceof YangLeafRef) {
 
             YangNode leafParent = ((YangLeafRef) resolutionInfo)
-                    .getParentNodeOfLeafref();
+                    .getParentNode();
             YangLeafRef leafref = (YangLeafRef) resolutionInfo;
 
             // Checks if the leafref has relative path in it.
diff --git a/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java b/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
index d73a0d6..48ea81d 100644
--- a/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
+++ b/generator/src/main/java/org/onosproject/yangutils/utils/UtilConstants.java
@@ -631,12 +631,12 @@
     /**
      * Static attribute for ancestor accessor.
      */
-    public static final String ANCESTOR_ACCESSOR = "..";
+    public static final String ANCESTOR = "..";
 
     /**
      * Static attribute for ancestor accessor along with path.
      */
-    public static final String ANCESTOR_ACCESSOR_IN_PATH = "../";
+    public static final String SLASH_ANCESTOR = "../";
 
     /**
      * Static attribute for add syntax.
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
index 25ac31c..9c1b466 100644
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/LeafrefListener.java
@@ -133,7 +133,7 @@
                 }
 
                 leafRef.setResolvableStatus(UNRESOLVED);
-                leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeaf);
+                leafRef.setParentNode((YangNode) parentNodeOfLeaf);
                 if (listener.getGroupingDepth() == 0) {
                     // Add resolution information to the list.
                     YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangLeafRef>(leafRef,
@@ -158,7 +158,7 @@
                 }
 
                 leafRef.setResolvableStatus(UNRESOLVED);
-                leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafList);
+                leafRef.setParentNode((YangNode) parentNodeOfLeafList);
 
                 if (listener.getGroupingDepth() == 0) {
                     // Add resolution information to the list.
@@ -172,7 +172,7 @@
 
             case TYPEDEF_DATA:
                 Parsable parentNodeOfLeafref = listener.getParsedDataStack().peek();
-                leafRef.setParentNodeOfLeafref((YangNode) parentNodeOfLeafref);
+                leafRef.setParentNode((YangNode) parentNodeOfLeafref);
                 if (listener.getGroupingDepth() != 0) {
                     leafRef.setInGrouping(true);
                 }
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java
index b02c6f4..681225d 100644
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PathListener.java
@@ -18,17 +18,17 @@
 
 import org.onosproject.yangutils.datamodel.YangLeafRef;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
-import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser.PathStatementContext;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 import org.onosproject.yangutils.parser.impl.TreeWalkListener;
 
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.validatePathArgument;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
 import static org.onosproject.yangutils.datamodel.utils.YangConstructType.PATH_DATA;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
 import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+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_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.validatePath;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
 
 /*
  * Reference: RFC6020 and YANG ANTLR Grammar
@@ -43,7 +43,8 @@
  *
  * ANTLR grammar rule
  *
- * leafrefSpecification : (pathStatement (requireInstanceStatement)?) | ((requireInstanceStatement)? pathStatement);
+ * leafrefSpecification : (pathStatement (requireInstanceStatement)?) |
+ * ((requireInstanceStatement)? pathStatement);
  *
  * pathStatement : PATH_KEYWORD path STMTEND;
  */
@@ -55,9 +56,7 @@
  */
 public final class PathListener {
 
-    /**
-     * Creates a new path listener.
-     */
+    // No instantiation.
     private PathListener() {
     }
 
@@ -66,24 +65,26 @@
      * (path), performs validation and updates the data model tree.
      *
      * @param listener listener's object
-     * @param ctx context object of the grammar rule
+     * @param ctx      context object of the grammar rule
      */
     public static void processPathEntry(TreeWalkListener listener,
-            GeneratedYangParser.PathStatementContext ctx) {
+                                        PathStatementContext ctx) {
 
         // Check for stack to be non empty.
-        checkStackIsNotEmpty(listener, MISSING_HOLDER, PATH_DATA, ctx.path().getText(), ENTRY);
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, PATH_DATA,
+                             ctx.path().getText(), ENTRY);
 
         Parsable curData = listener.getParsedDataStack().peek();
 
-        // Checks the holder of path as leafref, else throws error.
+        // Checks the holder of path as leaf-ref, else throws error.
         if (curData instanceof YangLeafRef) {
-
-            // Splitting the path argument and updating it in the datamodel tree.
-            validatePathArgument(ctx.path().getText(), PATH_DATA, ctx, (YangLeafRef) curData);
+            // Parsing the path and updating in leaf-ref path.
+            validatePath(ctx.path().getText(), PATH_DATA, ctx,
+                         (YangLeafRef) curData);
         } else {
-            throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, PATH_DATA,
-                    ctx.path().getText(), ENTRY));
+            throw new ParserException(
+                    constructListenerErrorMessage(INVALID_HOLDER, PATH_DATA,
+                                                  ctx.path().getText(), ENTRY));
         }
     }
 }
diff --git a/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java b/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
index 65d054c..3c3e08d 100644
--- a/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
+++ b/parser/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerUtil.java
@@ -16,16 +16,6 @@
 
 package org.onosproject.yangutils.parser.impl.parserutils;
 
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.regex.Pattern;
-
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.onosproject.yangutils.datamodel.YangAtomicPath;
 import org.onosproject.yangutils.datamodel.YangImport;
@@ -44,15 +34,26 @@
 import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
 import org.onosproject.yangutils.parser.exceptions.ParserException;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import static org.onosproject.yangutils.datamodel.YangPathArgType.ABSOLUTE_PATH;
 import static org.onosproject.yangutils.datamodel.YangPathArgType.RELATIVE_PATH;
 import static org.onosproject.yangutils.datamodel.YangPathOperator.EQUALTO;
 import static org.onosproject.yangutils.datamodel.utils.YangConstructType.getYangConstructType;
+import static org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser.PathStatementContext;
 import static org.onosproject.yangutils.utils.UtilConstants.ADD;
-import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR;
-import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR_ACCESSOR_IN_PATH;
+import static org.onosproject.yangutils.utils.UtilConstants.ANCESTOR;
 import static org.onosproject.yangutils.utils.UtilConstants.CARET;
-import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_CLOSE_SQUARE_BRACKET;
 import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_OPEN_SQUARE_BRACKET;
 import static org.onosproject.yangutils.utils.UtilConstants.CHAR_OF_SLASH;
 import static org.onosproject.yangutils.utils.UtilConstants.CLOSE_PARENTHESIS;
@@ -60,9 +61,11 @@
 import static org.onosproject.yangutils.utils.UtilConstants.CURRENT;
 import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
 import static org.onosproject.yangutils.utils.UtilConstants.FALSE;
+import static org.onosproject.yangutils.utils.UtilConstants.INVALID_TREE;
 import static org.onosproject.yangutils.utils.UtilConstants.OPEN_SQUARE_BRACKET;
 import static org.onosproject.yangutils.utils.UtilConstants.QUOTES;
 import static org.onosproject.yangutils.utils.UtilConstants.SLASH;
+import static org.onosproject.yangutils.utils.UtilConstants.SLASH_ANCESTOR;
 import static org.onosproject.yangutils.utils.UtilConstants.SLASH_FOR_STRING;
 import static org.onosproject.yangutils.utils.UtilConstants.TRUE;
 import static org.onosproject.yangutils.utils.UtilConstants.YANG_FILE_ERROR;
@@ -72,19 +75,27 @@
  */
 public final class ListenerUtil {
 
-    private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
-    private static final String DATE_PATTERN = "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
+    private static final Pattern IDENTIFIER_PATTERN =
+            Pattern.compile("[a-zA-Z_][a-zA-Z0-9_.-]*");
+    private static final String DATE_PATTERN =
+            "[0-9]{4}-([0-9]{2}|[0-9])-([0-9]{2}|[0-9])";
     private static final String NON_NEGATIVE_INTEGER_PATTERN = "[0-9]+";
-    private static final Pattern INTEGER_PATTERN = Pattern.compile("[-][0-9]+|[0-9]+");
-    private static final Pattern PATH_PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
+    private static final Pattern INTEGER_PATTERN =
+            Pattern.compile("[-][0-9]+|[0-9]+");
+    private static final Pattern PREDICATE =
+            Pattern.compile("\\[(.*?)\\]");
     private static final String XML = "xml";
     private static final String ONE = "1";
     private static final int IDENTIFIER_LENGTH = 64;
     private static final String DATE_FORMAT = "yyyy-MM-dd";
+    private static final String REGEX_EQUAL = "[=]";
+    private static final String REGEX_OPEN_BRACE = "[(]";
 
-    /**
-     * Creates a new listener util.
-     */
+    private static YangConstructType pathType;
+    private static PathStatementContext pathCtx;
+    private static YangLeafRef yangLeafRef;
+
+    // No instantiation.
     private ListenerUtil() {
     }
 
@@ -140,42 +151,6 @@
     }
 
     /**
-     * Validates identifier and returns concatenated string if string contains plus symbol.
-     *
-     * @param identifier    string from yang file
-     * @param yangConstruct yang construct for creating error message
-     * @param ctx           yang construct's context to get the line number and character position
-     * @param yangLeafRef   instance of leafref where the path argument has to be set
-     * @return concatenated string after removing double quotes
-     */
-    public static String getValidIdentifierForLeafref(String identifier, YangConstructType yangConstruct,
-                                                      ParserRuleContext ctx, YangLeafRef yangLeafRef) {
-
-        String identifierString = removeQuotesAndHandleConcat(identifier);
-        ParserException parserException;
-
-        if (identifierString.length() > IDENTIFIER_LENGTH) {
-            parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
-                                                          getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is " +
-                                                          "greater than 64 characters.");
-        } else if (!IDENTIFIER_PATTERN.matcher(identifierString).matches()) {
-            parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
-                                                          getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() + " is not " +
-                                                          "valid.");
-        } else if (identifierString.toLowerCase().startsWith(XML)) {
-            parserException = new ParserException("YANG file error : " + " identifier " + identifierString + " in " +
-                                                          getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
-                                                          " must not start with (('X'|'x') ('M'|'m') ('L'|'l')).");
-        } else {
-            return identifierString;
-        }
-
-        parserException.setLine(ctx.getStart().getLine());
-        parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-        throw parserException;
-    }
-
-    /**
      * Validates the revision date.
      *
      * @param dateToValidate input revision date
@@ -367,137 +342,83 @@
     }
 
     /**
-     * Checks and return valid node identifier specific to nodes in leafref path.
+     * Validates the prefix of the YANG file where leaf-ref is present and
+     * puts it in the map of node and prefix in leaf-ref.
      *
-     * @param nodeIdentifierString string from yang file
-     * @param yangConstruct        yang construct for creating error message
-     * @param ctx                  yang construct's context to get the line number and character position
-     * @param yangLeafRef          instance of leafref where the path argument has to be set
-     * @return valid node identifier
+     * @param atomicList atomic content list in leaf-ref
+     * @param leafRef    YANG leaf-ref
      */
-    public static YangNodeIdentifier getValidNodeIdentifierForLeafref(String nodeIdentifierString,
-                                                                      YangConstructType yangConstruct,
-                                                                      ParserRuleContext ctx, YangLeafRef yangLeafRef) {
+    private static void valPrefix(List<YangAtomicPath> atomicList,
+                                  YangLeafRef leafRef) {
 
-        String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
-        String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
-        if (tmpData.length == 1) {
-            YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
-            nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
-            return nodeIdentifier;
-        } else if (tmpData.length == 2) {
-            YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
-            nodeIdentifier.setPrefix(getValidIdentifierForLeafref(tmpData[0], yangConstruct, ctx, yangLeafRef));
-            nodeIdentifier.setName(getValidIdentifierForLeafref(tmpData[1], yangConstruct, ctx, yangLeafRef));
-            return nodeIdentifier;
-        } else {
-            ParserException parserException = new ParserException("YANG file error : " +
-                                                                          getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
-                                                                          " is not valid.");
-            parserException.setLine(ctx.getStart().getLine());
-            parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-            throw parserException;
-        }
-    }
-
-    /**
-     * Validates the path argument. It can be either absolute or relative path.
-     *
-     * @param pathString    the path string from the path type
-     * @param yangConstruct yang construct for creating error message
-     * @param ctx           yang construct's context to get the line number and character position
-     * @param yangLeafRef   instance of leafref where the path argument has to be set
-     */
-    public static void validatePathArgument(String pathString, YangConstructType yangConstruct,
-                                            ParserRuleContext ctx, YangLeafRef yangLeafRef) {
-
-        String completePathString = removeQuotesAndHandleConcat(pathString);
-        yangLeafRef.setPath(completePathString);
-        if (completePathString.startsWith(SLASH)) {
-            yangLeafRef.setPathType(ABSOLUTE_PATH);
-            List<YangAtomicPath> yangAtomicPathListList = validateAbsolutePath(completePathString, yangConstruct, ctx,
-                                                                               yangLeafRef);
-            validatePrefixAndYangNode(yangAtomicPathListList, yangLeafRef);
-            yangLeafRef.setAtomicPath(yangAtomicPathListList);
-        } else if (completePathString.startsWith(ANCESTOR_ACCESSOR)) {
-            yangLeafRef.setPathType(RELATIVE_PATH);
-            validateRelativePath(completePathString, yangConstruct, ctx, yangLeafRef);
-        } else {
-            ParserException parserException = new ParserException("YANG file error : " +
-                                                                          getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
-                                                                          " does not follow valid path syntax");
-            parserException.setLine(ctx.getStart().getLine());
-            parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-            throw parserException;
-        }
-    }
-
-    /**
-     * Validates the prefixes in the leafref and assigns them to the respective imported name in map.
-     *
-     * @param yangAtomicPathList list of atomic poth
-     * @param yangLeafRef        instance YANG leafref
-     */
-    private static void validatePrefixAndYangNode(List<YangAtomicPath> yangAtomicPathList, YangLeafRef yangLeafRef) {
-        Iterator<YangAtomicPath> yangAtomicPathIterator = yangAtomicPathList.listIterator();
-        while (yangAtomicPathIterator.hasNext()) {
-            YangAtomicPath atomicPath = yangAtomicPathIterator.next();
+        for (YangAtomicPath atomicPath : atomicList) {
             String prefix = atomicPath.getNodeIdentifier().getPrefix();
-            YangNode parentNodeOfLeafref = yangLeafRef.getParentNodeOfLeafref();
-            YangNode moduleOrSubModule = getModuleOrSubmoduleInFileOfTheCurrentNode(parentNodeOfLeafref);
-            YangModule moduleNode = null;
-            if (moduleOrSubModule instanceof YangModule) {
-                moduleNode = (YangModule) moduleOrSubModule;
+            YangNode parent = leafRef.getParentNode();
+            YangNode rootNode = getRootNode(parent);
+
+            List<YangImport> imports;
+            if (rootNode instanceof YangModule) {
+                imports = ((YangModule) rootNode).getImportList();
+            } else {
+                imports = ((YangSubModule) rootNode).getImportList();
             }
-            if (moduleNode != null) {
-                updatePrefixWithTheImportedList(moduleNode, prefix, yangLeafRef);
-            }
+            updatePrefixWithNode(rootNode, imports, prefix, leafRef);
         }
     }
 
     /**
-     * Updates the prefix with the imported list in the module.
+     * Updates the prefix and its respective node in the leaf-ref by taking
+     * the node from the import list of the root node which matches with the
+     * prefix.
      *
-     * @param moduleNode   root node of the leafref
-     * @param prefixInPath prefix in the path
-     * @param yangLeafRef  instance YANG leafref
+     * @param root    root node
+     * @param imports import list
+     * @param prefix  prefix in path
+     * @param leafRef YANG leaf-ref
      */
-    private static void updatePrefixWithTheImportedList(YangModule moduleNode, String prefixInPath, YangLeafRef
-            yangLeafRef) {
-        if (prefixInPath != null && prefixInPath != EMPTY_STRING && !prefixInPath.equals(moduleNode.getPrefix())) {
-            List<YangImport> moduleImportList = moduleNode.getImportList();
-            if (moduleImportList != null && !moduleImportList.isEmpty()) {
-                Iterator<YangImport> yangImportIterator = moduleImportList.listIterator();
-                while (yangImportIterator.hasNext()) {
-                    YangImport yangImport = yangImportIterator.next();
-                    if (yangImport.getPrefixId().equals(prefixInPath)) {
-                        HashMap prefixMap = new HashMap();
-                        prefixMap.put(prefixInPath, yangImport.getModuleName());
-                        yangLeafRef.setPrefixAndItsImportedModule(prefixMap);
-                    }
+    private static void updatePrefixWithNode(YangNode root,
+                                             List<YangImport> imports,
+                                             String prefix,
+                                             YangLeafRef<?> leafRef) {
+
+        Map<String, String> prefixMap = leafRef.getPrefixAndNode();
+        if (prefixMap == null) {
+            prefixMap = new HashMap<>();
+            leafRef.setPrefixAndNode(prefixMap);
+        }
+
+        if (prefix == null ||
+                prefix.equals(((YangReferenceResolver) root).getPrefix())) {
+            prefixMap.put(prefix, root.getName());
+            return;
+        }
+
+        if (imports != null) {
+            for (YangImport yangImp : imports) {
+                if (yangImp.getPrefixId().equals(prefix)) {
+                    prefixMap.put(prefix, yangImp.getModuleName());
                 }
             }
-        } else {
-            HashMap prefixMap = new HashMap();
-            prefixMap.put(prefixInPath, moduleNode.getName());
-            yangLeafRef.setPrefixAndItsImportedModule(prefixMap);
         }
     }
 
     /**
-     * Returns module or submodule node from the current node.
+     * Returns the root node from the current node.
      *
      * @param node current node
      * @return root node
      */
-    private static YangNode getModuleOrSubmoduleInFileOfTheCurrentNode(YangNode node) {
-        while (!(node instanceof YangModule) && !(node instanceof YangSubModule)) {
-            if (node == null) {
-                throw new ParserException("Internal datamodel error: Datamodel tree is not correct");
+    private static YangNode getRootNode(YangNode node) {
+
+        YangNode curNode = node;
+        while (!(curNode instanceof YangModule) &&
+                !(curNode instanceof YangSubModule)) {
+            if (curNode == null) {
+                throw new ParserException(INVALID_TREE);
             }
-            node = node.getParent();
+            curNode = curNode.getParent();
         }
-        return node;
+        return curNode;
     }
 
     /**
@@ -657,292 +578,19 @@
     }
 
     /**
-     * Validates the relative path.
+     * Returns the matched first path predicate in a given string. Returns
+     * null if match is not found.
      *
-     * @param completePathString the path string of relative path
-     * @param yangConstruct      yang construct for creating error message
-     * @param ctx                yang construct's context to get the line number and character position
-     * @param yangLeafRef        instance of leafref where the path argument has to be set
-     */
-    private static void validateRelativePath(String completePathString, YangConstructType yangConstruct,
-                                             ParserRuleContext ctx, YangLeafRef yangLeafRef) {
-
-        YangRelativePath relativePath = new YangRelativePath();
-        int numberOfAncestors = 0;
-        while (completePathString.startsWith(ANCESTOR_ACCESSOR_IN_PATH)) {
-            completePathString = completePathString.replaceFirst(ANCESTOR_ACCESSOR_IN_PATH, EMPTY_STRING);
-            numberOfAncestors = numberOfAncestors + 1;
-        }
-        if (completePathString == null || completePathString.length() == 0) {
-            ParserException parserException = new ParserException("YANG file error : "
-                                                                          + getYangConstructType(yangConstruct) + yangLeafRef.getPath() +
-                                                                          " does not follow valid path syntax");
-            parserException.setLine(ctx.getStart().getLine());
-            parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-            throw parserException;
-        }
-        relativePath.setAncestorNodeCount(numberOfAncestors);
-        List<YangAtomicPath> atomicPath = validateAbsolutePath(SLASH_FOR_STRING + completePathString,
-                                                               yangConstruct,
-                                                               ctx, yangLeafRef);
-        validatePrefixAndYangNode(atomicPath, yangLeafRef);
-        relativePath.setAtomicPathList(atomicPath);
-        yangLeafRef.setRelativePath(relativePath);
-    }
-
-    /**
-     * Validates the absolute path.
-     *
-     * @param completePathString the path string of absolute path
-     * @param yangConstruct      yang construct for creating error message
-     * @param ctx                yang construct's context to get the line number and character position
-     * @param yangLeafRef        instance of leafref where the path argument has to be set
-     * @return list of object of node in absolute path
-     */
-    private static List<YangAtomicPath> validateAbsolutePath(String completePathString,
-                                                             YangConstructType yangConstruct, ParserRuleContext
-                                                                     ctx, YangLeafRef yangLeafRef) {
-
-        List<YangAtomicPath> absolutePathList = new LinkedList<>();
-        YangPathPredicate yangPathPredicate = new YangPathPredicate();
-        YangNodeIdentifier yangNodeIdentifier;
-
-        while (completePathString != null) {
-            String path = completePathString.replaceFirst(SLASH_FOR_STRING, EMPTY_STRING);
-            if (path == null || path.length() == 0) {
-                ParserException parserException = new ParserException("YANG file error : "
-                                                                              + getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
-                                                                              " does not follow valid path syntax");
-                parserException.setLine(ctx.getStart().getLine());
-                parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-                throw parserException;
-            }
-            String matchedPathPredicate;
-            String nodeIdentifier;
-            String[] differentiate = new String[2];
-            int forNodeIdentifier = path.indexOf(CHAR_OF_SLASH);
-            int forPathPredicate = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
-
-            // Checks if path predicate is present for the node.
-            if ((forPathPredicate < forNodeIdentifier) && (forPathPredicate != -1)) {
-                List<String> pathPredicate = new ArrayList<>();
-                matchedPathPredicate = matchForPathPredicate(path);
-
-                if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
-                    ParserException parserException = new ParserException("YANG file error : "
-                                                                                  + getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
-                                                                                  " does not follow valid path syntax");
-                    parserException.setLine(ctx.getStart().getLine());
-                    parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-                    throw parserException;
-                }
-                int indexOfMatchedFirstOpenBrace = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
-                differentiate[0] = path.substring(0, indexOfMatchedFirstOpenBrace);
-                differentiate[1] = path.substring(indexOfMatchedFirstOpenBrace);
-                pathPredicate.add(matchedPathPredicate);
-                nodeIdentifier = differentiate[0];
-                // Starts adding all path predicates of a node into the list.
-                if (!differentiate[1].isEmpty()) {
-                    while (differentiate[1].startsWith(OPEN_SQUARE_BRACKET)) {
-                        matchedPathPredicate = matchForPathPredicate(differentiate[1]);
-                        if (matchedPathPredicate == null || matchedPathPredicate.length() == 0) {
-                            ParserException parserException = new ParserException(
-                                    "YANG file error : " + getYangConstructType(yangConstruct) + " "
-                                            + yangLeafRef.getPath() +
-                                            " does not follow valid path syntax");
-                            parserException.setLine(ctx.getStart().getLine());
-                            parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-                            throw parserException;
-                        }
-                        pathPredicate.add(matchedPathPredicate);
-                        differentiate[1] = differentiate[1].substring(matchedPathPredicate.length());
-                    }
-                }
-
-                List<YangPathPredicate> pathPredicateList = validatePathPredicate(pathPredicate, yangConstruct, ctx,
-                                                                                  yangPathPredicate, yangLeafRef);
-                YangAtomicPath atomicPath = new YangAtomicPath();
-                yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
-                atomicPath.setNodeIdentifier(yangNodeIdentifier);
-                atomicPath.setPathPredicatesList(pathPredicateList);
-                absolutePathList.add(atomicPath);
-            } else {
-                if (path.contains(SLASH_FOR_STRING)) {
-                    nodeIdentifier = path.substring(0, path.indexOf(CHAR_OF_SLASH));
-                    differentiate[1] = path.substring(path.indexOf(CHAR_OF_SLASH));
-                } else {
-                    nodeIdentifier = path;
-                    differentiate[1] = null;
-                }
-                yangNodeIdentifier = getValidNodeIdentifierForLeafref(nodeIdentifier, yangConstruct, ctx, yangLeafRef);
-
-                YangAtomicPath atomicPath = new YangAtomicPath();
-                atomicPath.setNodeIdentifier(yangNodeIdentifier);
-                atomicPath.setPathPredicatesList(null);
-                absolutePathList.add(atomicPath);
-            }
-            if (differentiate[1] == null || differentiate[1].length() == 0) {
-                completePathString = null;
-            } else {
-                completePathString = differentiate[1];
-            }
-        }
-        return absolutePathList;
-    }
-
-    /**
-     * Validates path predicate in the absolute path's node.
-     *
-     * @param pathPredicate     list of path predicates in the node of absolute path
-     * @param yangConstruct     yang construct for creating error message
-     * @param ctx               yang construct's context to get the line number and character position
-     * @param yangPathPredicate instance of path predicate where it has to be set
-     * @param yangLeafRef       instance of leafref where the path argument has to be set
-     * @return list of object of path predicates in absolute path's node
-     */
-    private static List<YangPathPredicate> validatePathPredicate(List<String> pathPredicate,
-                                                                 YangConstructType yangConstruct, ParserRuleContext
-                                                                         ctx, YangPathPredicate yangPathPredicate,
-                                                                 YangLeafRef yangLeafRef) {
-
-        Iterator<String> pathPredicateString = pathPredicate.iterator();
-        List<String> pathEqualityExpression = new ArrayList<>();
-
-        while (pathPredicateString.hasNext()) {
-            String pathPredicateForNode = pathPredicateString.next();
-            pathPredicateForNode = (pathPredicateForNode.substring(1)).trim();
-            pathPredicateForNode = pathPredicateForNode.substring(0,
-                                                                  pathPredicateForNode.indexOf(CHAR_OF_CLOSE_SQUARE_BRACKET));
-            pathEqualityExpression.add(pathPredicateForNode);
-        }
-        List<YangPathPredicate> validatedPathPredicateList = validatePathEqualityExpression(pathEqualityExpression,
-                                                                                            yangConstruct, ctx, yangPathPredicate, yangLeafRef);
-        return validatedPathPredicateList;
-    }
-
-    /**
-     * Validates the path equality expression.
-     *
-     * @param pathEqualityExpression list of path equality expression in the path predicates of the node
-     * @param yangConstruct          yang construct for creating error message
-     * @param ctx                    yang construct's context to get the line number and character position
-     * @param yangPathPredicate      instance of path predicate where it has to be set
-     * @param yangLeafRef            instance of leafref where the path argument has to be set
-     * @return list of object of path predicates in absolute path's node
-     */
-    private static List<YangPathPredicate> validatePathEqualityExpression(List<String> pathEqualityExpression,
-                                                                          YangConstructType yangConstruct,
-                                                                          ParserRuleContext ctx, YangPathPredicate
-                                                                                  yangPathPredicate,
-                                                                          YangLeafRef yangLeafRef) {
-
-        Iterator<String> pathEqualityExpressionString = pathEqualityExpression.iterator();
-        List<YangPathPredicate> yangPathPredicateList = new ArrayList<>();
-
-        while (pathEqualityExpressionString.hasNext()) {
-            String pathEqualityExpressionForNode = pathEqualityExpressionString.next();
-            String[] pathEqualityExpressionArray = pathEqualityExpressionForNode.split("[=]");
-
-            YangNodeIdentifier yangNodeIdentifierForPredicate;
-            YangRelativePath yangRelativePath;
-            yangNodeIdentifierForPredicate = getValidNodeIdentifierForLeafref(pathEqualityExpressionArray[0].trim(),
-                                                                              yangConstruct, ctx, yangLeafRef);
-            yangRelativePath = validatePathKeyExpression(pathEqualityExpressionArray[1].trim(), yangConstruct, ctx,
-                                                         yangLeafRef);
-            yangPathPredicate.setNodeIdentifier(yangNodeIdentifierForPredicate);
-            yangPathPredicate.setPathOperator(EQUALTO);
-            yangPathPredicate.setRightRelativePath(yangRelativePath);
-            yangPathPredicateList.add(yangPathPredicate);
-        }
-        return yangPathPredicateList;
-    }
-
-    /**
-     * Validate the path key expression.
-     *
-     * @param rightRelativePath relative path in the path predicate
-     * @param yangConstruct     yang construct for creating error message
-     * @param ctx               yang construct's context to get the line number and character position
-     * @param yangLeafRef       instance of leafref where the path argument has to be set
-     * @return object of right relative path in path predicate
-     */
-    private static YangRelativePath validatePathKeyExpression(String rightRelativePath,
-                                                              YangConstructType yangConstruct, ParserRuleContext ctx,
-                                                              YangLeafRef yangLeafRef) {
-
-        YangRelativePath yangRelativePath = new YangRelativePath();
-        String[] relativePath = rightRelativePath.split(SLASH_FOR_STRING);
-        List<String> rightAbsolutePath = new ArrayList<>();
-        int accessAncestor = 0;
-        for (String path : relativePath) {
-            if (path.trim().equals(ANCESTOR_ACCESSOR)) {
-                accessAncestor = accessAncestor + 1;
-            } else {
-                rightAbsolutePath.add(path);
-            }
-        }
-        List<YangAtomicPath> atomicPathInRelativePath = validateRelativePathKeyExpression(rightAbsolutePath,
-                                                                                          yangConstruct, ctx, yangLeafRef);
-        yangRelativePath.setAtomicPathList(atomicPathInRelativePath);
-        yangRelativePath.setAncestorNodeCount(accessAncestor);
-        return yangRelativePath;
-    }
-
-    /**
-     * Validates the relative path key expression.
-     *
-     * @param rightAbsolutePath absolute path nodes present in the relative path
-     * @param yangConstruct     yang construct for creating error message
-     * @param ctx               yang construct's context to get the line number and character position
-     * @param yangLeafRef       instance of leafref where the path argument has to be set
-     * @return list of object of absolute path nodes present in the relative path
-     */
-    private static List<YangAtomicPath> validateRelativePathKeyExpression(List<String> rightAbsolutePath,
-                                                                          YangConstructType yangConstruct,
-                                                                          ParserRuleContext ctx, YangLeafRef
-                                                                                  yangLeafRef) {
-
-        List<YangAtomicPath> atomicPathList = new ArrayList<>();
-        YangNodeIdentifier yangNodeIdentifier;
-
-        Iterator<String> nodes = rightAbsolutePath.iterator();
-        String currentInvocationFunction = nodes.next();
-        currentInvocationFunction = currentInvocationFunction.trim();
-        String[] currentFunction = currentInvocationFunction.split("[(]");
-
-        if (!(currentFunction[0].trim().equals(CURRENT)) || !(currentFunction[1].trim().equals(CLOSE_PARENTHESIS))) {
-            ParserException parserException = new ParserException("YANG file error : "
-                                                                          + getYangConstructType(yangConstruct) + " " + yangLeafRef.getPath() +
-                                                                          " does not follow valid path syntax");
-            parserException.setLine(ctx.getStart().getLine());
-            parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
-            throw parserException;
-        }
-
-        while (nodes.hasNext()) {
-            YangAtomicPath atomicPath = new YangAtomicPath();
-            String node = nodes.next();
-            yangNodeIdentifier = getValidNodeIdentifierForLeafref(node.trim(), yangConstruct, ctx, yangLeafRef);
-            atomicPath.setNodeIdentifier(yangNodeIdentifier);
-            atomicPathList.add(atomicPath);
-        }
-        return atomicPathList;
-    }
-
-    /**
-     * Validates the match for first path predicate in a given string.
-     *
-     * @param matchRequiredString string for which match has to be done
+     * @param str string to be matched
      * @return the matched string
      */
-    private static String matchForPathPredicate(String matchRequiredString) {
+    private static String getMatchedPredicate(String str) {
 
-        String matchedString = null;
-        java.util.regex.Matcher matcher = PATH_PREDICATE_PATTERN.matcher(matchRequiredString);
+        Matcher matcher = PREDICATE.matcher(str);
         if (matcher.find()) {
-            matchedString = matcher.group(0);
+            return matcher.group(0);
         }
-        return matchedString;
+        return null;
     }
 
     /**
@@ -983,16 +631,18 @@
     /**
      * Throws parser exception for unsupported YANG constructs.
      *
-     * @param yangConstructType yang construct for creating error message
-     * @param ctx               yang construct's context to get the line number and character position
-     * @param errorInfo         error information
-     * @param fileName          YANG file name
+     * @param type      construct type
+     * @param ctx       construct context
+     * @param errorInfo error msg
+     * @param fileName  YANG file name
      */
-    public static void handleUnsupportedYangConstruct(YangConstructType yangConstructType,
-                                                      ParserRuleContext ctx, String errorInfo, String fileName) {
-        ParserException parserException = new ParserException(YANG_FILE_ERROR
-                + QUOTES + getYangConstructType(yangConstructType) + QUOTES
-                + errorInfo);
+    public static void handleUnsupportedYangConstruct(YangConstructType type,
+                                                      ParserRuleContext ctx,
+                                                      String errorInfo,
+                                                      String fileName) {
+        ParserException parserException = new ParserException(
+                YANG_FILE_ERROR + QUOTES + getYangConstructType(
+                        type) + QUOTES + errorInfo);
         parserException.setLine(ctx.getStart().getLine());
         parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
         //FIXME this exception should probably be thrown rather than just logged
@@ -1052,4 +702,274 @@
             throw parserException;
         }
     }
+
+    /**
+     * Validates path under leaf-ref and parses the path and stores in the
+     * leaf-ref.
+     *
+     * @param path    path of leaf-ref
+     * @param type    construct type
+     * @param ctx     construct details
+     * @param leafRef YANG leaf-ref having path
+     */
+    public static void validatePath(String path, YangConstructType type,
+                                    PathStatementContext ctx,
+                                    YangLeafRef leafRef) {
+
+        String concatPath = removeQuotesAndHandleConcat(path);
+        pathType = type;
+        pathCtx = ctx;
+        yangLeafRef = leafRef;
+        if (!concatPath.startsWith(SLASH_FOR_STRING) &&
+                !concatPath.startsWith(ANCESTOR)) {
+            throw getPathException();
+        }
+        leafRef.setPath(concatPath);
+        if (concatPath.startsWith(SLASH_FOR_STRING)) {
+            List<YangAtomicPath> atomicList = new LinkedList<>();
+            valAbsPath(concatPath, atomicList);
+            leafRef.setPathType(ABSOLUTE_PATH);
+            valPrefix(atomicList, leafRef);
+            leafRef.setAtomicPath(atomicList);
+            return;
+        }
+        leafRef.setPathType(RELATIVE_PATH);
+        valRelPath(concatPath, leafRef);
+    }
+
+    /**
+     * Validates relative path, parses the string and stores it in the leaf-ref.
+     *
+     * @param path    leaf-ref path
+     * @param leafRef YANG leaf-ref
+     */
+    private static void valRelPath(String path, YangLeafRef leafRef) {
+
+        YangRelativePath relPath = new YangRelativePath();
+        int count = 0;
+        while (path.startsWith(SLASH_ANCESTOR)) {
+            path = path.replaceFirst(SLASH_ANCESTOR, EMPTY_STRING);
+            count = count + 1;
+        }
+        if (path.isEmpty()) {
+            throw getPathException();
+        }
+
+        List<YangAtomicPath> atomicList = new ArrayList<>();
+        relPath.setAncestorNodeCount(count);
+        valAbsPath(SLASH_FOR_STRING + path, atomicList);
+        valPrefix(atomicList, leafRef);
+        relPath.setAtomicPathList(atomicList);
+        leafRef.setRelativePath(relPath);
+    }
+
+    /**
+     * Validates absolute path, parses the string and stores it in leaf-ref.
+     *
+     * @param path    leaf-ref path
+     * @param atomics atomic content list
+     */
+    private static void valAbsPath(String path, List<YangAtomicPath> atomics) {
+
+        String comPath = path;
+        while (comPath != null) {
+            comPath = comPath.substring(1);
+            if (comPath.isEmpty()) {
+                throw getPathException();
+            }
+            int nodeId = comPath.indexOf(CHAR_OF_SLASH);
+            int predicate = comPath.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
+            if (predicate < nodeId && predicate != -1) {
+                comPath = getPathWithPredicate(comPath, atomics);
+            } else {
+                comPath = getPath(comPath, atomics);
+            }
+        }
+    }
+
+    /**
+     * Returns the remaining path after parsing and the predicates of an atomic
+     * content.
+     *
+     * @param path    leaf-ref path
+     * @param atomics atomic content list
+     * @return parsed path after removing one atomic content.
+     */
+    private static String getPathWithPredicate(String path,
+                                               List<YangAtomicPath> atomics) {
+
+        String[] node = new String[2];
+        int bracket = path.indexOf(CHAR_OF_OPEN_SQUARE_BRACKET);
+        node[0] = path.substring(0, bracket);
+        node[1] = path.substring(bracket);
+        return getParsedPath(node[0], node[1], atomics);
+    }
+
+    /**
+     * Returns the path after taking all the path predicates of an atomic
+     * content.
+     *
+     * @param nodeId  atomic content nodeId
+     * @param path    leaf-ref path
+     * @param atomics atomic content list
+     * @return parsed path after removing one atomic content.
+     */
+    public static String getParsedPath(String nodeId, String path,
+                                       List<YangAtomicPath> atomics) {
+
+        String comPath = path;
+        List<String> predicateList = new ArrayList<>();
+        while (comPath.startsWith(OPEN_SQUARE_BRACKET)) {
+            String matchedVal = getMatchedPredicate(comPath);
+            if (matchedVal == null || matchedVal.isEmpty()) {
+                throw getPathException();
+            }
+            predicateList.add(matchedVal);
+            comPath = comPath.substring(matchedVal.length());
+        }
+
+        YangAtomicPath atomicPath = new YangAtomicPath();
+        YangNodeIdentifier validId =
+                getValidNodeIdentifier(nodeId, pathType, pathCtx);
+
+        List<YangPathPredicate> predicates = valPathPredicates(predicateList);
+        atomicPath.setNodeIdentifier(validId);
+        atomicPath.setPathPredicatesList(predicates);
+        atomics.add(atomicPath);
+        return comPath;
+    }
+
+    /**
+     * Validates the path predicates of an atomic content after parsing the
+     * predicates and storing it in the leaf-ref.
+     *
+     * @param predicates list of predicates
+     * @return list of path predicates of an atomic content
+     */
+    private static List<YangPathPredicate> valPathPredicates(List<String> predicates) {
+
+        List<YangPathPredicate> result = new ArrayList<>();
+        for (String p : predicates) {
+            p = p.substring(1, p.length() - 1);
+            result.add(valPathEqualityExp(p.trim()));
+        }
+        return result;
+    }
+
+    /**
+     * Validates the path equality expression of a path predicate and after
+     * parsing the string assigns it to the YANG path predicate.
+     *
+     * @param predicate path predicate
+     * @return YANG path predicate
+     */
+    private static YangPathPredicate valPathEqualityExp(String predicate) {
+
+        String[] exp = predicate.split(REGEX_EQUAL);
+        YangNodeIdentifier nodeId =
+                getValidNodeIdentifier(exp[0].trim(), pathType, pathCtx);
+        YangRelativePath relPath = valPathKeyExp(exp[1].trim());
+
+        YangPathPredicate pathPredicate = new YangPathPredicate();
+        pathPredicate.setNodeId(nodeId);
+        pathPredicate.setPathOp(EQUALTO);
+        pathPredicate.setRelPath(relPath);
+        return pathPredicate;
+    }
+
+    /**
+     * Validates the path key expression of the path-predicate and stores it
+     * in the relative path of the leaf-ref.
+     *
+     * @param relPath relative path
+     * @return YANG relative path
+     */
+    private static YangRelativePath valPathKeyExp(String relPath) {
+
+        String[] relative = relPath.split(SLASH_FOR_STRING);
+        int count = 0;
+        List<String> atomicContent = new ArrayList<>();
+        for (String val : relative) {
+            if (val.trim().equals(ANCESTOR)) {
+                count = count + 1;
+            } else {
+                atomicContent.add(val);
+            }
+        }
+
+        YangRelativePath relativePath = new YangRelativePath();
+        relativePath.setAncestorNodeCount(count);
+        relativePath.setAtomicPathList(valRelPathKeyExp(atomicContent));
+        return relativePath;
+    }
+
+    /**
+     * Validates relative path key expression in the right relative path of
+     * the path predicate, by taking every atomic content in it.
+     *
+     * @param content atomic content list
+     * @return YANG atomic content list
+     */
+    private static List<YangAtomicPath> valRelPathKeyExp(List<String> content) {
+
+        String current = content.get(0);
+        String[] curStr = (current.trim()).split(REGEX_OPEN_BRACE);
+        if (!(curStr[0].trim().equals(CURRENT)) ||
+                !(curStr[1].trim().equals(CLOSE_PARENTHESIS))) {
+            throw getPathException();
+        }
+
+        content.remove(0);
+        List<YangAtomicPath> atomicList = new ArrayList<>();
+        for (String relPath : content) {
+            YangNodeIdentifier nodeId =
+                    getValidNodeIdentifier(relPath, pathType, pathCtx);
+            YangAtomicPath atomicPath = new YangAtomicPath();
+            atomicPath.setNodeIdentifier(nodeId);
+            atomicList.add(atomicPath);
+        }
+        return atomicList;
+    }
+
+    /**
+     * Returns the remaining path after parsing and processing an atomic
+     * content which doesn't have path-predicate.
+     *
+     * @param path       leaf-ref path
+     * @param atomicList atomic content list
+     * @return remaining path after parsing one atomic content
+     */
+    public static String getPath(String path, List<YangAtomicPath> atomicList) {
+
+        String comPath = path;
+        String nodeId;
+        if (comPath.contains(SLASH_FOR_STRING)) {
+            nodeId = comPath.substring(0, comPath.indexOf(CHAR_OF_SLASH));
+            comPath = comPath.substring(comPath.indexOf(CHAR_OF_SLASH));
+        } else {
+            nodeId = comPath;
+            comPath = null;
+        }
+
+        YangNodeIdentifier validNodeId =
+                getValidNodeIdentifier(nodeId, pathType, pathCtx);
+        YangAtomicPath atomicPath = new YangAtomicPath();
+        atomicPath.setNodeIdentifier(validNodeId);
+        atomicList.add(atomicPath);
+        return comPath;
+    }
+
+    /**
+     * Returns the path syntax parser exception.
+     *
+     * @return parser exception
+     */
+    private static ParserException getPathException() {
+        ParserException exception = new ParserException(
+                "YANG file error : Path " + yangLeafRef.getPath() +
+                        " does not follow valid path syntax");
+        exception.setLine(pathCtx.getStart().getLine());
+        exception.setCharPosition(pathCtx.getStart().getCharPositionInLine());
+        return exception;
+    }
 }
diff --git a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
index f02fe65..e128979 100644
--- a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
+++ b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/IntraFileLeafrefLinkingTest.java
@@ -1552,11 +1552,11 @@
         List<YangPathPredicate> pathPredicateList = abspath.getPathPredicatesList();
         Iterator<YangPathPredicate> pathPredicate = pathPredicateList.listIterator();
         YangPathPredicate pathPredicate1 = pathPredicate.next();
-        assertThat(pathPredicate1.getNodeIdentifier().getName(), is("name"));
-        assertThat(pathPredicate1.getNodeIdentifier().getPrefix(), nullValue());
-        assertThat(pathPredicate1.getRightRelativePath().getAncestorNodeCount(), is(1));
-        assertThat(pathPredicate1.getPathOperator(), is(YangPathOperator.EQUALTO));
-        assertThat(pathPredicate1.getRightRelativePath().getAtomicPathList().listIterator().next().getNodeIdentifier()
+        assertThat(pathPredicate1.getNodeId().getName(), is("name"));
+        assertThat(pathPredicate1.getNodeId().getPrefix(), nullValue());
+        assertThat(pathPredicate1.getRelPath().getAncestorNodeCount(), is(1));
+        assertThat(pathPredicate1.getPathOp(), is(YangPathOperator.EQUALTO));
+        assertThat(pathPredicate1.getRelPath().getAtomicPathList().listIterator().next().getNodeIdentifier()
                 .getName(), is("ifname"));
         //TODO : Fill the path predicates
 //        assertThat(pathPredicate1.getLeftAxisNode(), is(leafNameInList));
diff --git a/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/PathPredicateLinkingTest.java b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/PathPredicateLinkingTest.java
new file mode 100644
index 0000000..e7ae30d
--- /dev/null
+++ b/plugin/maven/src/test/java/org/onosproject/yangutils/plugin/manager/PathPredicateLinkingTest.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.plugin.manager;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onosproject.yangutils.datamodel.YangAtomicPath;
+import org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangContainer;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafRef;
+import org.onosproject.yangutils.datamodel.YangList;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangPathPredicate;
+import org.onosproject.yangutils.linker.exceptions.LinkerException;
+import org.onosproject.yangutils.linker.impl.YangLinkerManager;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.onosproject.yangutils.linker.impl.YangLinkerUtils.updateFilePriority;
+import static org.onosproject.yangutils.utils.io.impl.YangFileScanner.getYangFiles;
+
+/**
+ * Test cases for path predicate linking in leaf-ref.
+ */
+public class PathPredicateLinkingTest {
+
+    private static final String DIR = "src/test/resources/pathpredicate/";
+
+    private final YangUtilManager utilMgr = new YangUtilManager();
+    private final YangLinkerManager linkerMgr = new YangLinkerManager();
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    private ListIterator<YangLeaf> leafItr;
+    private YangLeaf ifName;
+    private YangLeaf address;
+    private YangLeaf name;
+    private Iterator<YangAtomicPath> pathItr;
+    private YangAtomicPath atomicPath;
+    private Iterator<YangPathPredicate> predicateItr;
+    private YangPathPredicate predicate;
+
+    /**
+     * Processes simple path predicate which gets linked within the same file
+     * using relative path.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processSimplePathPredicate() throws IOException {
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "simple"));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+        YangNode selfNode;
+
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+        Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+        selfNode = nodeItr.next();
+
+        // Gets the list node.
+        YangList yangList = (YangList) selfNode.getChild();
+        // Gets the container node.
+        YangContainer container = (YangContainer) yangList.getNextSibling();
+
+        leafItr = container.getListOfLeaf().listIterator();
+        ifName = leafItr.next();
+        address = leafItr.next();
+
+        // Gets the address leaf's leaf-ref type.
+        YangLeafRef<?> leafRef2 = (YangLeafRef) address.getDataType()
+                .getDataTypeExtendedInfo();
+        pathItr = leafRef2.getAtomicPath().listIterator();
+        atomicPath = pathItr.next();
+
+        // Gets the path-predicate.
+        predicateItr = atomicPath.getPathPredicatesList().listIterator();
+        predicate = predicateItr.next();
+
+        // Gets the left and right axis node in path-predicate.
+        YangLeaf yangLeftLeaf = (YangLeaf) predicate.getLeftAxisNode();
+        YangLeaf yangRightLeaf = (YangLeaf) predicate.getRightAxisNode();
+
+        leafItr = yangList.getListOfLeaf().listIterator();
+        name = leafItr.next();
+
+        // Checks that right and left path-predicates are correct.
+        assertThat(yangLeftLeaf, is(name));
+        assertThat(yangRightLeaf, is(ifName));
+    }
+
+    /**
+     * Processes simple inter file path predicate which gets linked to another
+     * file using absolute path.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processSimpleInterFilePathPredicate() throws IOException {
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "simpleinterfile"));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+        YangModule selfNode;
+
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+        Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+        YangNode rootNode = nodeItr.next();
+        YangModule refNode;
+        if (rootNode.getName().equals("ietf-network")) {
+            selfNode = (YangModule) rootNode;
+            refNode = (YangModule) nodeItr.next();
+        } else {
+            refNode = (YangModule) rootNode;
+            selfNode = (YangModule) nodeItr.next();
+        }
+
+        // Gets the container node.
+        YangContainer container = (YangContainer) selfNode.getChild();
+        // Gets the list node.
+        YangList yangList = (YangList) refNode.getChild();
+
+        leafItr = container.getListOfLeaf().listIterator();
+        ifName = leafItr.next();
+        address = leafItr.next();
+
+        // Gets the address leaf's leaf-ref type.
+        YangLeafRef<?> leafRef2 = (YangLeafRef) address.getDataType()
+                .getDataTypeExtendedInfo();
+        pathItr = leafRef2.getAtomicPath().listIterator();
+        atomicPath = pathItr.next();
+
+        // Gets the path-predicate.
+        predicateItr = atomicPath.getPathPredicatesList().listIterator();
+        predicate = predicateItr.next();
+
+        // Gets the left and right axis node in path-predicate.
+        YangLeaf yangLeftLeaf = (YangLeaf) predicate.getLeftAxisNode();
+        YangLeaf yangRightLeaf = (YangLeaf) predicate.getRightAxisNode();
+
+        leafItr = yangList.getListOfLeaf().listIterator();
+        name = leafItr.next();
+
+        // Checks that right and left path-predicates are correct.
+        assertThat(yangLeftLeaf, is(name));
+        assertThat(yangRightLeaf, is(ifName));
+    }
+
+    /**
+     * Processes inter file path predicate, where leaf-ref is present under
+     * YANG augment.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processInterFilePathPredicateFromAugment() throws IOException {
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "interfileaugment"));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+        YangModule selfNode;
+
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+        Iterator<YangNode> nodeItr = utilMgr.getYangNodeSet().iterator();
+
+        YangNode rootNode = nodeItr.next();
+        YangModule refNode;
+        if (rootNode.getName().equals("ietf-network")) {
+            selfNode = (YangModule) rootNode;
+            refNode = (YangModule) nodeItr.next();
+        } else {
+            refNode = (YangModule) rootNode;
+            selfNode = (YangModule) nodeItr.next();
+        }
+
+        // Gets the augment node.
+        YangList list = (YangList) selfNode.getChild().getChild();
+
+        // Gets the augment node.
+        YangAugment augment = (YangAugment) refNode.getChild();
+
+        YangLeaf test;
+        YangLeaf networkId;
+        YangLeaf networkRef;
+
+        leafItr = augment.getListOfLeaf().listIterator();
+        test = leafItr.next();
+
+        YangLeafRef<?> leafRef =
+                (YangLeafRef) test.getDataType().getDataTypeExtendedInfo();
+        pathItr = leafRef.getAtomicPath().listIterator();
+        pathItr.next();
+        atomicPath = pathItr.next();
+
+        // Gets the path-predicate.
+        predicateItr = atomicPath.getPathPredicatesList().listIterator();
+        predicate = predicateItr.next();
+
+        // Gets the left and right axis node in path-predicate.
+        YangLeaf yangLeftLeaf = (YangLeaf) predicate.getLeftAxisNode();
+        YangLeaf yangRightLeaf = (YangLeaf) predicate.getRightAxisNode();
+
+        leafItr = list.getListOfLeaf().listIterator();
+        networkId = leafItr.next();
+        YangContainer reference = (YangContainer) list.getChild();
+        leafItr = reference.getListOfLeaf().listIterator();
+        networkRef = leafItr.next();
+
+        // Checks that right and left path-predicates are correct.
+        assertThat(yangLeftLeaf, is(networkId));
+        assertThat(yangRightLeaf, is(networkRef));
+    }
+
+    /**
+     * Processes an invalid scenario where the target leaf/leaf-list in
+     * path-predicate is not found.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processInvalidPathLink() throws IOException {
+        thrown.expect(LinkerException.class);
+        thrown.expectMessage(
+                "YANG file error: There is no leaf/leaf-list in YANG node as " +
+                        "mentioned in the path predicate of the leafref path " +
+                        "../../interface[ifname = current()/../../ifname]" +
+                        "/address/ip");
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "invalidlinking"));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+    }
+
+    /**
+     * Processes an invalid scenario where the right axis node doesn't come
+     * under YANG list node.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processInvalidPathLinkForList() throws IOException {
+        thrown.expect(LinkerException.class);
+        thrown.expectMessage(
+                "YANG file error: Path predicates are only applicable for " +
+                        "YANG list. The leafref path has path predicate for" +
+                        " non-list node in the path ../../default-address" +
+                        "[ifname = current()/../ifname]/ifname");
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "invalidlinking2"));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+    }
+
+    /**
+     * Processes an invalid scenario where the node in path predicate is not
+     * present in the traversal.
+     *
+     * @throws IOException if violates IO operation
+     */
+    @Test
+    public void processInvalidPathLinkForInvalidNode()
+            throws IOException {
+        thrown.expect(LinkerException.class);
+        thrown.expectMessage(
+                "YANG file error: The path predicate of the leafref has an " +
+                        "invalid path in ../../interface[name = current()/" +
+                        "../../address/ifname]/address/ip");
+
+        utilMgr.createYangFileInfoSet(getYangFiles(DIR + "invalidlinking3"));
+        utilMgr.parseYangFileInfoSet();
+        utilMgr.createYangNodeSet();
+
+        linkerMgr.createYangNodeSet(utilMgr.getYangNodeSet());
+        linkerMgr.addRefToYangFilesImportList(utilMgr.getYangNodeSet());
+
+        updateFilePriority(utilMgr.getYangNodeSet());
+
+        linkerMgr.processInterFileLinking(utilMgr.getYangNodeSet());
+    }
+}
diff --git a/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-network.yang
new file mode 100644
index 0000000..8e650da
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-network.yang
@@ -0,0 +1,21 @@
+module ietf-network {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+    prefix nd;
+    container networks {
+        list network {
+            key "network-id";
+            leaf network-id {
+                type uint8;
+            }
+            container reference {
+                leaf network-ref {
+                    type string;
+                }
+            }
+            leaf node-id {
+                type int8;
+            }
+        }
+    }
+}
diff --git a/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-topology.yang b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-topology.yang
new file mode 100644
index 0000000..93bfa80
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/interfileaugment/ietf-topology.yang
@@ -0,0 +1,18 @@
+module ietf-topology {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-te-topology";
+    // replace with IANA namespace when assigned
+    prefix "tet";
+
+    import ietf-network {
+        prefix "nw";
+    }
+    augment "/nw:networks/nw:network" {
+        leaf test {
+            type leafref {
+                path "../../nw:network[nw:network-id = current()/../" +
+                "nw:reference/nw:network-ref]/nw:node-id";
+            }
+        }
+    }
+}
diff --git a/plugin/maven/src/test/resources/pathpredicate/invalidlinking/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/invalidlinking/ietf-network.yang
new file mode 100644
index 0000000..13bcb3e
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/invalidlinking/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+    prefix nd;
+    list interface {
+        key "name";
+        leaf name {
+            type string;
+        }
+        leaf admin-status {
+            type uint8;
+        }
+        list address {
+            key "ip";
+            leaf ip {
+                type int8;
+            }
+        }
+    }
+    container default-address {
+        leaf ifname {
+            type leafref {
+                path "../../interface/name";
+            }
+        }
+        leaf address {
+            type leafref {
+                path "../../interface[ifname = current()/../../ifname]"
+                    + "/address/ip";
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/invalidlinking2/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/invalidlinking2/ietf-network.yang
new file mode 100644
index 0000000..7c1881b
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/invalidlinking2/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+    prefix nd;
+    list interface {
+        key "name";
+        leaf name {
+            type string;
+        }
+        leaf admin-status {
+            type uint8;
+        }
+        list address {
+            key "ip";
+            leaf ip {
+                type int8;
+            }
+        }
+    }
+    container default-address {
+        leaf ifname {
+            type leafref {
+                path "../../interface/name";
+            }
+        }
+        leaf address {
+            type leafref {
+                path "../../default-address[ifname = current()/../ifname]/" +
+                "ifname";
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/invalidlinking3/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/invalidlinking3/ietf-network.yang
new file mode 100644
index 0000000..9ebb2ce
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/invalidlinking3/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+    prefix nd;
+    list interface {
+        key "name";
+        leaf name {
+            type string;
+        }
+        leaf admin-status {
+            type uint8;
+        }
+        list address {
+            key "ip";
+            leaf ip {
+                type int8;
+            }
+        }
+    }
+    container default-address {
+        leaf ifname {
+            type leafref {
+                path "../../interface/name";
+            }
+        }
+        leaf address {
+            type leafref {
+                path "../../interface[name = current()/../../address/ifname]"
+                    + "/address/ip";
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/simple/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/simple/ietf-network.yang
new file mode 100644
index 0000000..5c1ecdd
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/simple/ietf-network.yang
@@ -0,0 +1,33 @@
+module ietf-network {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+    prefix nd;
+    list interface {
+        key "name";
+        leaf name {
+            type string;
+        }
+        leaf admin-status {
+            type uint8;
+        }
+        list address {
+            key "ip";
+            leaf ip {
+                type int8;
+            }
+        }
+    }
+    container default-address {
+        leaf ifname {
+            type leafref {
+                path "../../interface/name";
+            }
+        }
+        leaf address {
+            type leafref {
+                path "../../interface[name = current()/../ifname]"
+                    + "/address/ip";
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-network.yang b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-network.yang
new file mode 100644
index 0000000..33d77dd
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-network.yang
@@ -0,0 +1,22 @@
+module ietf-network {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:ietf-network";
+    prefix nd;
+    import ietf-topology {
+        prefix tp;
+    }
+    container default-address {
+        leaf ifname {
+            type leafref {
+                path "/tp:interface/tp:name";
+            }
+        }
+        leaf address {
+            type leafref {
+                path "/tp:interface[tp:name = current()/../nd:ifname]"
+                + "/tp:address/ip";
+            }
+        }
+    }
+}
+
diff --git a/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-topology.yang b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-topology.yang
new file mode 100644
index 0000000..63db761
--- /dev/null
+++ b/plugin/maven/src/test/resources/pathpredicate/simpleinterfile/ietf-topology.yang
@@ -0,0 +1,21 @@
+   module ietf-topology {
+     yang-version 1;
+     namespace "urn:ietf:params:xml:ns:yang:ietf-topology";
+     prefix tp;
+     list interface {
+         key "name";
+         leaf name {
+             type string;
+         }
+         leaf admin-status {
+             type uint8;
+         }
+         list address {
+             key "ip";
+             leaf ip {
+                 type int8;
+             }
+         }
+     }
+   }
+