Merge "Added support for parsing yang models with already resolved context."
authorEd Warnicke <eaw@cisco.com>
Wed, 26 Jun 2013 12:52:16 +0000 (12:52 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 26 Jun 2013 12:52:16 +0000 (12:52 +0000)
41 files changed:
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/YangModelParser.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationTargetBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/SchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/AbstractUnsignedInteger.java

index 842bb43d79bd00573cd69a4ab298a4805a4bda5e..142f199af42e02979d443537b35880912887975d 100644 (file)
@@ -26,7 +26,7 @@ public interface YangModelParser {
 
     /**
      * Parse one or more Yang model files and return the definitions of Yang
-     * modules defined in *.Yang files; <br>
+     * modules defined in *.yang files; <br>
      * This method SHOULD be used if user need to parse multiple yang models
      * that are referenced either through import or include statements.
      *
@@ -36,6 +36,21 @@ public interface YangModelParser {
      */
     Set<Module> parseYangModels(final List<File> yangFiles);
 
+    /**
+     * Parse one or more Yang model files and return the definitions of Yang
+     * modules defined in *.yang files. <br>
+     * This method SHOULD be used if user has already parsed context and need to
+     * parse additinal yang models which can have dependencies on models in this
+     * context.
+     *
+     * @param yangFiles
+     *            yang files to parse
+     * @param context
+     *            SchemaContext containing already parsed yang models
+     * @return Set of Yang Modules
+     */
+    Set<Module> parseYangModels(final List<File> yangFiles, final SchemaContext context);
+
     /**
      * Equivalent to {@link #parseYangModels(List)} that returns parsed modules
      * mapped to Files from which they were parsed.
@@ -46,11 +61,42 @@ public interface YangModelParser {
      */
     Map<File, Module> parseYangModelsMapped(final List<File> yangFiles);
 
-    Set<Module> parseYangModelsFromStreams(
-            final List<InputStream> yangModelStreams);
+    /**
+     * Parse one or more Yang model streams and return the definitions of Yang
+     * modules defined in *.yang files; <br>
+     * This method SHOULD be used if user need to parse multiple yang models
+     * that are referenced either through import or include statements.
+     *
+     * @param yangModelStreams
+     *            yang streams to parse
+     * @return Set of Yang Modules
+     */
+    Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams);
+
+    /**
+     * Parse one or more Yang model streams and return the definitions of Yang
+     * modules defined in *.yang files. <br>
+     * This method SHOULD be used if user has already parsed context and need to
+     * parse additinal yang models which can have dependencies on models in this
+     * context.
+     *
+     * @param yangModelStreams
+     *            yang streams to parse
+     * @param context
+     *            SchemaContext containing already parsed yang models
+     * @return Set of Yang Modules
+     */
+    Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams, final SchemaContext context);
 
-    Map<InputStream, Module> parseYangModelsFromStreamsMapped(
-            final List<InputStream> yangModelStreams);
+    /**
+     * Equivalent to {@link #parseYangModels(List)} that returns parsed modules
+     * mapped to IputStreams from which they were parsed.
+     *
+     * @param yangModelStreams
+     *            yang streams to parse
+     * @return Map of Yang Modules
+     */
+    Map<InputStream, Module> parseYangModelsFromStreamsMapped(final List<InputStream> yangModelStreams);
 
     /**
      * Creates {@link SchemaContext} from specified Modules. The modules SHOULD
index c56b40488c525978811566670fbe94396065d244..8ca88d8d6110aa6807da562ff3c2543c10faeb57 100644 (file)
@@ -11,12 +11,18 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
 
 public abstract class AbstractDataNodeContainerBuilder implements DataNodeContainerBuilder {
 
     private final QName qname;
-    protected final Set<DataSchemaNodeBuilder> childNodes = new HashSet<DataSchemaNodeBuilder>();
-    protected final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();
+
+    protected Set<DataSchemaNode> childNodes;
+    protected final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<DataSchemaNodeBuilder>();
+
+    protected Set<GroupingDefinition> groupings;
+    protected final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
 
     protected AbstractDataNodeContainerBuilder(QName qname) {
         this.qname = qname;
@@ -29,21 +35,29 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
 
     @Override
     public Set<DataSchemaNodeBuilder> getChildNodes() {
-        return childNodes;
+        return addedChildNodes;
     }
 
     @Override
     public void addChildNode(DataSchemaNodeBuilder childNode) {
-        childNodes.add(childNode);
+        addedChildNodes.add(childNode);
+    }
+
+    public void setChildNodes(Set<DataSchemaNode> childNodes) {
+        this.childNodes = childNodes;
     }
 
     public Set<GroupingBuilder> getGroupings() {
-        return groupings;
+        return addedGroupings;
     }
 
     @Override
     public void addGrouping(GroupingBuilder grouping) {
-        groupings.add(grouping);
+        addedGroupings.add(grouping);
+    }
+
+    public void setGroupings(final Set<GroupingDefinition> groupings) {
+        this.groupings = groupings;
     }
 
 }
index add9bac333569bc3b5e109837d03984b043f33a4..639e18c3ad796abec45254770263df670c268262 100644 (file)
@@ -20,4 +20,15 @@ public interface AugmentationTargetBuilder {
      */
     void addAugmentation(AugmentationSchemaBuilder augment);
 
+    /**
+     * Build again already built data node.
+     *
+     * In general, when Builder.build is called first time, it creates YANG data
+     * model node instance. With every other call it just return this instance
+     * without checking for properties change. This method causes that builder
+     * object process again all its properties and return an updated instance of
+     * YANG data node.
+     */
+    void rebuild();
+
 }
index 49be55737c6a9be0bfc3d8499c8152eed7af1a9f..ee50d2ad02cc3b422ee5eebd227abffd2aa48bd9 100644 (file)
@@ -12,6 +12,15 @@ package org.opendaylight.controller.yang.parser.builder.api;
  */
 public interface Builder {
 
+    /**
+     * Build YANG data model node.
+     *
+     * This method should create an instance of YANG data model node. After
+     * creating an instance, this instance should be returned for each call
+     * without repeating build process.
+     *
+     * @return YANG data model node
+     */
     Object build();
 
     int getLine();
index de0453105fa2c846403b9accfc16f66b0f43b51c..a831b3d92f9130eb713e4d6160dedca74a76fa3d 100644 (file)
@@ -18,8 +18,12 @@ public interface DataSchemaNodeBuilder extends SchemaNodeBuilder {
 
     DataSchemaNode build();
 
+    boolean isAugmenting();
+
     void setAugmenting(boolean augmenting);
 
+    boolean isConfiguration();
+
     void setConfiguration(boolean configuration);
 
     ConstraintsBuilder getConstraints();
index eb3286e4f6f7d47e85207b2bd9df41c950483d19..6e872b3d1f90bf4d99ed3b94f6c0c25c0e4b521a 100644 (file)
@@ -24,10 +24,16 @@ public interface SchemaNodeBuilder extends Builder {
 \r
     void setPath(SchemaPath schemaPath);\r
 \r
+    String getDescription();\r
+\r
     void setDescription(String description);\r
 \r
+    String getReference();\r
+\r
     void setReference(String reference);\r
 \r
+    Status getStatus();\r
+\r
     void setStatus(Status status);\r
 \r
     void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode);\r
index d82cbe215e1e8f76233a21fb95fb52be1d971821..78284c142e108cf9d70d92cac2ba809be2a29266 100644 (file)
@@ -26,6 +26,8 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder {
     private SchemaPath path;
     private final AnyXmlSchemaNodeImpl instance;
     private final ConstraintsBuilder constraints;
+
+    private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
     private String description;
@@ -53,9 +55,11 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder {
             instance.setAugmenting(augmenting);
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-                unknownNodes.add(b.build());
+            if(unknownNodes == null) {
+                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                    unknownNodes.add(b.build());
+                }
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -97,6 +101,10 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder {
         return addedUnknownNodes;
     }
 
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
     public String getDescription() {
         return description;
     }
@@ -126,6 +134,11 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder {
         }
     }
 
+    @Override
+    public boolean isAugmenting() {
+        return augmenting;
+    }
+
     @Override
     public void setAugmenting(final boolean augmenting) {
         this.augmenting = augmenting;
index f520bf917a814ac362fc30e62f36b6616691fd5d..1ba1a2dfdcb3dd1224710da31cdf4ba7ff50813b 100644 (file)
@@ -26,7 +26,7 @@ import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBui
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 
 public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationTargetBuilder {
-    private boolean built;
+    private boolean isBuilt;
     private final ChoiceNodeImpl instance;
     private final int line;
     // SchemaNode args
@@ -35,6 +35,7 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
     private String description;
     private String reference;
     private Status status = Status.CURRENT;
+    private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
     // DataSchemaNode args
     private boolean augmenting;
@@ -43,7 +44,8 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
     // AugmentationTarget args
     private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
     // ChoiceNode args
-    private final Set<ChoiceCaseBuilder> cases = new HashSet<ChoiceCaseBuilder>();
+    private Set<ChoiceCaseNode> cases;
+    private final Set<ChoiceCaseBuilder> addedCases = new HashSet<ChoiceCaseBuilder>();
     private String defaultCase;
 
     public ChoiceBuilder(final QName qname, final int line) {
@@ -55,7 +57,7 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
 
     @Override
     public ChoiceNode build() {
-        if (!built) {
+        if (!isBuilt) {
             instance.setPath(schemaPath);
             instance.setDescription(description);
             instance.setReference(reference);
@@ -66,11 +68,13 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
             instance.setDefaultCase(defaultCase);
 
             // CASES
-            final Set<ChoiceCaseNode> choiceCases = new HashSet<ChoiceCaseNode>();
-            for (ChoiceCaseBuilder caseBuilder : cases) {
-                choiceCases.add(caseBuilder.build());
+            if(cases == null) {
+                cases = new HashSet<ChoiceCaseNode>();
+                for (ChoiceCaseBuilder caseBuilder : addedCases) {
+                    cases.add(caseBuilder.build());
+                }
             }
-            instance.setCases(choiceCases);
+            instance.setCases(cases);
 
             // AUGMENTATIONS
             final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
@@ -80,36 +84,48 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
             instance.setAvailableAugmentations(augmentations);
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-                unknownNodes.add(b.build());
+            if(unknownNodes == null) {
+                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                    unknownNodes.add(b.build());
+                }
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
-            built = true;
+            isBuilt = true;
         }
         return instance;
     }
 
+    @Override
+    public void rebuild() {
+        isBuilt = false;
+        build();
+    }
+
     @Override
     public int getLine() {
         return line;
     }
 
     public Set<ChoiceCaseBuilder> getCases() {
-        return cases;
+        return addedCases;
     }
 
     public void addChildNode(DataSchemaNodeBuilder childNode) {
         if (!(childNode instanceof ChoiceCaseBuilder)) {
             ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(childNode.getQName(), childNode.getLine());
             caseBuilder.addChildNode(childNode);
-            cases.add(caseBuilder);
+            addedCases.add(caseBuilder);
         } else {
-            cases.add((ChoiceCaseBuilder) childNode);
+            addedCases.add((ChoiceCaseBuilder) childNode);
         }
     }
 
+    public void setCases(Set<ChoiceCaseNode> cases) {
+        this.cases = cases;
+    }
+
     @Override
     public QName getQName() {
         return qname;
@@ -176,10 +192,6 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
         return constraints;
     }
 
-    public List<UnknownSchemaNodeBuilder> getUnknownNodes() {
-        return addedUnknownNodes;
-    }
-
     public Set<AugmentationSchemaBuilder> getAugmentations() {
         return addedAugmentations;
     }
@@ -189,11 +201,19 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
         addedAugmentations.add(augment);
     }
 
+    public List<UnknownSchemaNodeBuilder> getUnknownNodes() {
+        return addedUnknownNodes;
+    }
+
     @Override
     public void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode) {
         addedUnknownNodes.add(unknownNode);
     }
 
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
     public String getDefaultCase() {
         return defaultCase;
     }
@@ -202,7 +222,7 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
         this.defaultCase = defaultCase;
     }
 
-    private final class ChoiceNodeImpl implements ChoiceNode {
+    public final class ChoiceNodeImpl implements ChoiceNode {
         private final QName qname;
         private SchemaPath path;
         private String description;
@@ -332,6 +352,10 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT
             this.defaultCase = defaultCase;
         }
 
+        public ChoiceBuilder toBuilder() {
+            return ChoiceBuilder.this;
+        }
+
         @Override
         public int hashCode() {
             final int prime = 31;
index 7117afe4693c9380aad602112a7350d5b6092db4..d54cd22ec8615e5fa2652656e614e4305cd5557b 100644 (file)
@@ -20,13 +20,16 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.model.api.UsesNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder implements
-        DataSchemaNodeBuilder {
+        DataSchemaNodeBuilder, AugmentationTargetBuilder {
+    private boolean isBuilt;
     private final ChoiceCaseNodeImpl instance;
     private final int line;
     private SchemaPath schemaPath;
@@ -37,7 +40,7 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
     private boolean augmenting;
     private final ConstraintsBuilder constraints;
     private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
-    private final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+    private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
 
     ChoiceCaseBuilder(final QName qname, final int line) {
         super(qname);
@@ -48,38 +51,54 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
 
     @Override
     public ChoiceCaseNode build() {
-        instance.setConstraints(constraints.build());
-        instance.setPath(schemaPath);
-        instance.setDescription(description);
-        instance.setReference(reference);
-        instance.setStatus(status);
-        instance.setAugmenting(augmenting);
-        instance.setAvailableAugmentations(augmentations);
+        if(!isBuilt) {
+            instance.setConstraints(constraints.build());
+            instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+            instance.setAugmenting(augmenting);
+
+            // CHILD NODES
+            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            for (DataSchemaNodeBuilder node : addedChildNodes) {
+                childs.put(node.getQName(), node.build());
+            }
+            instance.setChildNodes(childs);
 
-        // CHILD NODES
-        final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-        for (DataSchemaNodeBuilder node : childNodes) {
-            childs.put(node.getQName(), node.build());
-        }
-        instance.setChildNodes(childs);
+            // USES
+            final Set<UsesNode> uses = new HashSet<UsesNode>();
+            for (UsesNodeBuilder builder : addedUsesNodes) {
+                uses.add(builder.build());
+            }
+            instance.setUses(uses);
 
-        // USES
-        final Set<UsesNode> uses = new HashSet<UsesNode>();
-        for (UsesNodeBuilder builder : addedUsesNodes) {
-            uses.add(builder.build());
-        }
-        instance.setUses(uses);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
+
+            // AUGMENTATIONS
+            final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+            for (AugmentationSchemaBuilder builder : addedAugmentations) {
+                augmentations.add(builder.build());
+            }
+            instance.setAvailableAugmentations(augmentations);
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
+            isBuilt = true;
         }
-        instance.setUnknownSchemaNodes(unknownNodes);
 
         return instance;
     }
 
+    @Override
+    public void rebuild() {
+        isBuilt = false;
+        build();
+    }
+
     @Override
     public int getLine() {
         return line;
@@ -161,6 +180,11 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
                 "Can not add type definition to choice case.");
     }
 
+    @Override
+    public boolean isConfiguration() {
+        return false;
+    }
+
     @Override
     public void setConfiguration(boolean configuration) {
         throw new YangParseException(line,
@@ -172,11 +196,12 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
         return constraints;
     }
 
-    public Set<AugmentationSchema> getAugmentations() {
-        return augmentations;
+    @Override
+    public void addAugmentation(AugmentationSchemaBuilder augment) {
+        addedAugmentations.add(augment);
     }
 
-    private final class ChoiceCaseNodeImpl implements ChoiceCaseNode {
+    public final class ChoiceCaseNodeImpl implements ChoiceCaseNode {
         private final QName qname;
         private SchemaPath path;
         private String description;
@@ -335,6 +360,10 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
             }
         }
 
+        public ChoiceCaseBuilder toBuilder() {
+            return ChoiceCaseBuilder.this;
+        }
+
         @Override
         public int hashCode() {
             final int prime = 31;
index 4831a2218eeeb1a5da8cacc1579fa5e272c1a77a..e677d3c7a5c2d9412ec533b474e60e984febba2a 100644 (file)
@@ -49,10 +49,13 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     private boolean presence;
     private boolean augmenting;
     private boolean configuration;
-
+    private Set<TypeDefinition<?>> typedefs;
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
+    private Set<UsesNode> usesNodes;
     private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
+    private Set<AugmentationSchema> augmentations;
     private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
+    private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
     public ContainerSchemaNodeBuilder(final QName qname, final int line) {
@@ -75,43 +78,59 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
 
             // CHILD NODES
             final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-            for (DataSchemaNodeBuilder node : childNodes) {
-                childs.put(node.getQName(), node.build());
+            if(childNodes == null) {
+                for (DataSchemaNodeBuilder node : addedChildNodes) {
+                    childs.put(node.getQName(), node.build());
+                }
+            } else {
+                for(DataSchemaNode node : childNodes) {
+                    childs.put(node.getQName(), node);
+                }
             }
             instance.setChildNodes(childs);
 
             // GROUPINGS
-            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-            for (GroupingBuilder builder : groupings) {
-                groupingDefs.add(builder.build());
+            if(groupings == null) {
+                groupings = new HashSet<GroupingDefinition>();
+                for (GroupingBuilder builder : addedGroupings) {
+                    groupings.add(builder.build());
+                }
             }
-            instance.setGroupings(groupingDefs);
+            instance.setGroupings(groupings);
 
             // TYPEDEFS
-            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-            for (TypeDefinitionBuilder entry : addedTypedefs) {
-                typedefs.add(entry.build());
+            if(typedefs == null) {
+                typedefs = new HashSet<TypeDefinition<?>>();
+                for (TypeDefinitionBuilder entry : addedTypedefs) {
+                    typedefs.add(entry.build());
+                }
             }
             instance.setTypeDefinitions(typedefs);
 
             // USES
-            final Set<UsesNode> uses = new HashSet<UsesNode>();
-            for (UsesNodeBuilder builder : addedUsesNodes) {
-                uses.add(builder.build());
+            if(usesNodes == null) {
+                usesNodes = new HashSet<UsesNode>();
+                for (UsesNodeBuilder builder : addedUsesNodes) {
+                    usesNodes.add(builder.build());
+                }
             }
-            instance.setUses(uses);
+            instance.setUses(usesNodes);
 
             // AUGMENTATIONS
-            final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
-            for (AugmentationSchemaBuilder builder : addedAugmentations) {
-                augmentations.add(builder.build());
+            if(augmentations == null) {
+                augmentations = new HashSet<AugmentationSchema>();
+                for (AugmentationSchemaBuilder builder : addedAugmentations) {
+                    augmentations.add(builder.build());
+                }
             }
             instance.setAvailableAugmentations(augmentations);
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-                unknownNodes.add(b.build());
+            if(unknownNodes == null) {
+                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                    unknownNodes.add(b.build());
+                }
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -123,6 +142,12 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         return instance;
     }
 
+    @Override
+    public void rebuild() {
+        isBuilt = false;
+        build();
+    }
+
     @Override
     public int getLine() {
         return line;
@@ -138,6 +163,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         addedTypedefs.add(type);
     }
 
+    public void setTypedefs(final Set<TypeDefinition<?>> typedefs) {
+        this.typedefs = typedefs;
+    }
+
     public Set<AugmentationSchemaBuilder> getAugmentations() {
         return addedAugmentations;
     }
@@ -147,6 +176,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         addedAugmentations.add(augment);
     }
 
+    public void setAugmentations(final Set<AugmentationSchema> augmentations) {
+        this.augmentations = augmentations;
+    }
+
     public SchemaPath getPath() {
         return schemaPath;
     }
@@ -156,6 +189,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         this.schemaPath = schemaPath;
     }
 
+    @Override
     public String getDescription() {
         return description;
     }
@@ -165,6 +199,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         this.description = description;
     }
 
+    @Override
     public String getReference() {
         return reference;
     }
@@ -174,6 +209,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         this.reference = reference;
     }
 
+    @Override
     public Status getStatus() {
         return status;
     }
@@ -185,6 +221,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         }
     }
 
+    @Override
     public boolean isAugmenting() {
         return augmenting;
     }
@@ -194,6 +231,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         this.augmenting = augmenting;
     }
 
+    @Override
     public boolean isConfiguration() {
         return configuration;
     }
@@ -217,6 +255,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         addedUsesNodes.add(usesNodeBuilder);
     }
 
+    public void setUsesnodes(final Set<UsesNode> usesNodes) {
+        this.usesNodes = usesNodes;
+    }
+
     public boolean isPresence() {
         return presence;
     }
@@ -234,12 +276,16 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         addedUnknownNodes.add(unknownNode);
     }
 
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
     @Override
     public String toString() {
         return "container " + getQName().getLocalName();
     }
 
-    private final class ContainerSchemaNodeImpl implements ContainerSchemaNode {
+    public final class ContainerSchemaNodeImpl implements ContainerSchemaNode {
         private final QName qname;
         private SchemaPath path;
         private String description;
@@ -424,6 +470,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
             }
         }
 
+        public ContainerSchemaNodeBuilder toBuilder() {
+            return ContainerSchemaNodeBuilder.this;
+        }
+
         @Override
         public int hashCode() {
             final int prime = 31;
index a04fc3c1a68b06fa0e1667265b50417fa4831488..0558b91cd0c0ed97140c99eef9600a30dd893848 100644 (file)
@@ -24,6 +24,9 @@ public final class ExtensionBuilder implements SchemaNodeBuilder {
     private final int line;
     private final QName qname;
     private SchemaPath schemaPath;
+    private String description;
+    private String reference;
+    private Status status = Status.CURRENT;
     private final List<UnknownSchemaNodeBuilder> addedExtensions = new ArrayList<UnknownSchemaNodeBuilder>();
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
@@ -37,6 +40,9 @@ public final class ExtensionBuilder implements SchemaNodeBuilder {
     public ExtensionDefinition build() {
         if(!isBuilt) {
             instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
 
             // UNKNOWN NODES
             final List<UnknownSchemaNode> extensions = new ArrayList<UnknownSchemaNode>();
@@ -84,22 +90,37 @@ public final class ExtensionBuilder implements SchemaNodeBuilder {
     }
 
     @Override
-    public void setDescription(String description) {
-        instance.setDescription(description);
+    public String getDescription() {
+        return description;
     }
 
     @Override
-    public void setReference(String reference) {
-        instance.setReference(reference);
+    public void setDescription(final String description) {
+        this.description = description;
     }
 
     @Override
-    public void setStatus(Status status) {
+    public String getReference() {
+        return reference;
+    }
+
+    @Override
+    public void setReference(final String reference) {
+        this.reference = reference;
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
+    }
+
+    @Override
+    public void setStatus(final Status status) {
         instance.setStatus(status);
     }
 
     @Override
-    public void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode) {
+    public void addUnknownSchemaNode(final UnknownSchemaNodeBuilder unknownNode) {
         addedUnknownNodes.add(unknownNode);
     }
 
index 5418e09451eb087d4d6d19ea2c9b20e8f08f1474..0681cf6b155211b6b017c2e66f493f41fabb5cda 100644 (file)
@@ -24,6 +24,9 @@ public final class FeatureBuilder implements SchemaNodeBuilder {
     private final int line;
     private final QName qname;
     private SchemaPath schemaPath;
+    private String description;
+    private String reference;
+    private Status status = Status.CURRENT;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
     FeatureBuilder(final QName qname, final int line) {
@@ -36,6 +39,9 @@ public final class FeatureBuilder implements SchemaNodeBuilder {
     public FeatureDefinitionImpl build() {
         if(!isBuilt) {
             instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
 
             // UNKNOWN NODES
             final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
@@ -69,19 +75,34 @@ public final class FeatureBuilder implements SchemaNodeBuilder {
         this.schemaPath = schemaPath;
     }
 
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
     @Override
     public void setDescription(final String description) {
-        instance.setDescription(description);
+        this.description = description;
+    }
+
+    @Override
+    public String getReference() {
+        return reference;
     }
 
     @Override
     public void setReference(final String reference) {
-        instance.setReference(reference);
+        this.reference = reference;
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
     }
 
     @Override
     public void setStatus(final Status status) {
-        instance.setStatus(status);
+        this.status = status;
     }
 
     @Override
index 6fe43addd049906c5b2b5c0dd15ea826c92f2752..5428259324a700a5c65ed9ac8378d0dd4df4e7ef 100644 (file)
@@ -36,11 +36,21 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
     private SchemaPath schemaPath;
     private String description;
     private String reference;
-    private Status status;
-    private final Set<DataSchemaNodeBuilder> childNodes = new HashSet<DataSchemaNodeBuilder>();
-    private final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();
+    private Status status = Status.CURRENT;
+
+    private Set<DataSchemaNode> childNodes;
+    private final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<DataSchemaNodeBuilder>();
+
+    private Set<GroupingDefinition> groupings;
+    private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
+
+    private Set<TypeDefinition<?>> typedefs;
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
-    private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();
+
+    private Set<UsesNode> usesNodes;
+    private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
+
+    private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
     public GroupingBuilderImpl(final QName qname, final int line) {
@@ -59,36 +69,50 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
 
             // CHILD NODES
             final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-            for (DataSchemaNodeBuilder node : childNodes) {
-                childs.put(node.getQName(), node.build());
+            if(childNodes == null) {
+                for (DataSchemaNodeBuilder node : addedChildNodes) {
+                    childs.put(node.getQName(), node.build());
+                }
+            } else {
+                for(DataSchemaNode node : childNodes) {
+                    childs.put(node.getQName(), node);
+                }
             }
             instance.setChildNodes(childs);
 
             // GROUPINGS
-            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-            for (GroupingBuilder builder : groupings) {
-                groupingDefs.add(builder.build());
+            if(groupings == null) {
+                groupings = new HashSet<GroupingDefinition>();
+                for (GroupingBuilder builder : addedGroupings) {
+                    groupings.add(builder.build());
+                }
             }
-            instance.setGroupings(groupingDefs);
+            instance.setGroupings(groupings);
 
             // TYPEDEFS
-            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-            for (TypeDefinitionBuilder entry : addedTypedefs) {
-                typedefs.add(entry.build());
+            if(typedefs == null) {
+                typedefs = new HashSet<TypeDefinition<?>>();
+                for (TypeDefinitionBuilder entry : addedTypedefs) {
+                    typedefs.add(entry.build());
+                }
             }
             instance.setTypeDefinitions(typedefs);
 
             // USES
-            final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
-            for (UsesNodeBuilder builder : usesNodes) {
-                usesNodeDefs.add(builder.build());
+            if(usesNodes == null) {
+                usesNodes = new HashSet<UsesNode>();
+                for (UsesNodeBuilder builder : addedUsesNodes) {
+                    usesNodes.add(builder.build());
+                }
             }
-            instance.setUses(usesNodeDefs);
+            instance.setUses(usesNodes);
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-                unknownNodes.add(b.build());
+            if(unknownNodes == null) {
+                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                    unknownNodes.add(b.build());
+                }
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -118,6 +142,10 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
         addedTypedefs.add(type);
     }
 
+    public void setTypedefs(final Set<TypeDefinition<?>> typedefs) {
+        this.typedefs = typedefs;
+    }
+
     @Override
     public SchemaPath getPath() {
         return schemaPath;
@@ -161,7 +189,7 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
     @Override
     public DataSchemaNodeBuilder getChildNode(String name) {
         DataSchemaNodeBuilder result = null;
-        for (DataSchemaNodeBuilder node : childNodes) {
+        for (DataSchemaNodeBuilder node : addedChildNodes) {
             if (node.getQName().getLocalName().equals(name)) {
                 result = node;
                 break;
@@ -172,32 +200,44 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
 
     @Override
     public void addChildNode(final DataSchemaNodeBuilder childNode) {
-        childNodes.add(childNode);
+        addedChildNodes.add(childNode);
     }
 
     @Override
     public Set<DataSchemaNodeBuilder> getChildNodes() {
-        return childNodes;
+        return addedChildNodes;
+    }
+
+    public void setChildNodes(final Set<DataSchemaNode> childNodes) {
+        this.childNodes = childNodes;
     }
 
     @Override
     public Set<GroupingBuilder> getGroupings() {
-        return groupings;
+        return addedGroupings;
     }
 
     @Override
     public void addGrouping(final GroupingBuilder grouping) {
-        groupings.add(grouping);
+        addedGroupings.add(grouping);
+    }
+
+    public void setGroupings(final Set<GroupingDefinition> groupings) {
+        this.groupings = groupings;
     }
 
     @Override
     public Set<UsesNodeBuilder> getUses() {
-        return usesNodes;
+        return addedUsesNodes;
     }
 
     @Override
     public void addUsesNode(final UsesNodeBuilder usesBuilder) {
-        usesNodes.add(usesBuilder);
+        addedUsesNodes.add(usesBuilder);
+    }
+
+    public void setUsesnodes(final Set<UsesNode> usesNodes) {
+        this.usesNodes = usesNodes;
     }
 
     @Override
@@ -210,6 +250,11 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
         addedUnknownNodes.add(unknownNode);
     }
 
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
+
     private final class GroupingDefinitionImpl implements GroupingDefinition {
         private final QName qname;
         private SchemaPath path;
index 96c4121653562f0abcd3059aa986383911b6f12b..6b76314e5cd5163c950a84ca88bc94a1664006ef 100644 (file)
@@ -19,11 +19,16 @@ import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 
 public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder {
+    private boolean isBuilt;
     private final IdentitySchemaNodeImpl instance;
     private final int line;
     private final QName qname;
     private SchemaPath schemaPath;
-    private IdentitySchemaNodeBuilder baseIdentity;
+    private String description;
+    private String reference;
+    private Status status = Status.CURRENT;
+    private IdentitySchemaNodeBuilder baseIdentityBuilder;
+    private IdentitySchemaNode baseIdentity;
     private String baseIdentityName;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
@@ -35,17 +40,29 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder {
 
     @Override
     public IdentitySchemaNode build() {
-        instance.setPath(schemaPath);
-        if (baseIdentity != null) {
-            instance.setBaseIdentity(baseIdentity.build());
-        }
+        if(!isBuilt) {
+            instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+
+            if (baseIdentity == null) {
+                if (baseIdentityBuilder != null) {
+                    instance.setBaseIdentity(baseIdentityBuilder.build());
+                }
+            } else {
+                instance.setBaseIdentity(baseIdentity);
+            }
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
+
+            isBuilt = true;
         }
-        instance.setUnknownSchemaNodes(unknownNodes);
 
         return instance;
     }
@@ -70,27 +87,40 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder {
         this.schemaPath = schemaPath;
     }
 
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
     @Override
     public void setDescription(final String description) {
-        instance.setDescription(description);
+        this.description = description;
+    }
+
+    @Override
+    public String getReference() {
+        return reference;
     }
 
     @Override
     public void setReference(final String reference) {
-        instance.setReference(reference);
+        this.reference = reference;
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
     }
 
     @Override
     public void setStatus(final Status status) {
         if (status != null) {
-            instance.setStatus(status);
+            this.status = status;
         }
     }
 
     @Override
     public void addUnknownSchemaNode(final UnknownSchemaNodeBuilder unknownNode) {
-
-
         addedUnknownNodes.add(unknownNode);
     }
 
@@ -103,6 +133,10 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder {
     }
 
     public void setBaseIdentity(final IdentitySchemaNodeBuilder baseType) {
+        this.baseIdentityBuilder = baseType;
+    }
+
+    public void setBaseIdentity(final IdentitySchemaNode baseType) {
         this.baseIdentity = baseType;
     }
 
@@ -176,8 +210,7 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder {
             return unknownNodes;
         }
 
-        private void setUnknownSchemaNodes(
-                List<UnknownSchemaNode> unknownSchemaNodes) {
+        private void setUnknownSchemaNodes(List<UnknownSchemaNode> unknownSchemaNodes) {
             if (unknownSchemaNodes != null) {
                 this.unknownNodes = unknownSchemaNodes;
             }
@@ -223,8 +256,7 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder {
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    IdentitySchemaNodeImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(IdentitySchemaNodeImpl.class.getSimpleName());
             sb.append("[");
             sb.append("base=" + baseIdentity);
             sb.append(", qname=" + qname);
index b35ff4e9f1146f71241ae79dfe7a00edcb3d3d34..fdc8cd72dd6f576a2538e876e46a7e3ce7200690 100644 (file)
@@ -20,10 +20,8 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractTypeAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
-import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 
-public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder
-        implements SchemaNodeBuilder, DataSchemaNodeBuilder {
+public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder implements DataSchemaNodeBuilder {
     private boolean isBuilt;
     private final LeafListSchemaNodeImpl instance;
     private final int line;
@@ -33,6 +31,7 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder
     private String description;
     private String reference;
     private Status status = Status.CURRENT;
+    private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
     // DataSchemaNode args
     private boolean augmenting;
@@ -67,9 +66,11 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder
             }
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-                unknownNodes.add(b.build());
+            if (unknownNodes == null) {
+                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                    unknownNodes.add(b.build());
+                }
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -166,6 +167,10 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder
         addedUnknownNodes.add(unknownNode);
     }
 
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
     private final class LeafListSchemaNodeImpl implements LeafListSchemaNode {
         private final QName qname;
         private SchemaPath path;
@@ -320,16 +325,9 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    LeafListSchemaNodeImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(LeafListSchemaNodeImpl.class.getSimpleName());
             sb.append("[");
-            sb.append("qname=" + qname);
-            sb.append(", path=" + path);
-            sb.append(", augmenting=" + augmenting);
-            sb.append(", configuration=" + configuration);
-            sb.append(", constraints=" + constraintsDef);
-            sb.append(", type=" + type);
-            sb.append(", userOrdered=" + userOrdered);
+            sb.append(qname);
             sb.append("]");
             return sb.toString();
         }
index ec9c35c1bd37c14f97cc93994174bfb10c7f384d..786f08de49551957a2a43bc514450faebdd632f7 100644 (file)
@@ -20,10 +20,8 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractTypeAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
-import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 
-public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder
-        implements DataSchemaNodeBuilder, SchemaNodeBuilder {
+public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implements DataSchemaNodeBuilder {
     private boolean isBuilt;
     private final LeafSchemaNodeImpl instance;
     private final int line;
@@ -33,6 +31,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder
     private String description;
     private String reference;
     private Status status = Status.CURRENT;
+    private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
     // DataSchemaNode args
     private boolean augmenting;
@@ -70,9 +69,11 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder
             }
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-                unknownNodes.add(b.build());
+            if (unknownNodes == null) {
+                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                    unknownNodes.add(b.build());
+                }
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -114,6 +115,10 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder
         return addedUnknownNodes;
     }
 
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
     public String getDescription() {
         return description;
     }
@@ -348,8 +353,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    LeafSchemaNodeImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(LeafSchemaNodeImpl.class.getSimpleName());
             sb.append("[");
             sb.append("qname=" + qname);
             sb.append(", path=" + path);
index 65839d34b1e4ccedec5a29d8b7aeba7b33aaca9e..63a66e0892425e2f3698cc2358aabcbb74a7cb6f 100644 (file)
@@ -46,15 +46,19 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     private String description;
     private String reference;
     private Status status = Status.CURRENT;
+    private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
     // DataSchemaNode args
     private boolean augmenting;
     private boolean configuration;
     private final ConstraintsBuilder constraints;
     // DataNodeContainer args
+    private Set<TypeDefinition<?>> typedefs;
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
+    private Set<UsesNode> usesNodes;
     private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
     // AugmentationTarget args
+    private Set<AugmentationSchema> augmentations;
     private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
     // ListSchemaNode args
     private List<QName> keyDefinition = Collections.emptyList();
@@ -81,43 +85,59 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
 
             // CHILD NODES
             final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-            for (DataSchemaNodeBuilder node : childNodes) {
-                childs.put(node.getQName(), node.build());
+            if(childNodes == null) {
+                for (DataSchemaNodeBuilder node : addedChildNodes) {
+                    childs.put(node.getQName(), node.build());
+                }
+            } else {
+                for(DataSchemaNode node : childNodes) {
+                    childs.put(node.getQName(), node);
+                }
             }
             instance.setChildNodes(childs);
 
             // TYPEDEFS
-            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-            for (TypeDefinitionBuilder entry : addedTypedefs) {
-                typedefs.add(entry.build());
+            if(typedefs == null) {
+                typedefs = new HashSet<TypeDefinition<?>>();
+                for (TypeDefinitionBuilder entry : addedTypedefs) {
+                    typedefs.add(entry.build());
+                }
             }
             instance.setTypeDefinitions(typedefs);
 
             // USES
-            final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
-            for (UsesNodeBuilder builder : addedUsesNodes) {
-                usesNodeDefs.add(builder.build());
+            if(usesNodes == null) {
+                usesNodes = new HashSet<UsesNode>();
+                for (UsesNodeBuilder builder : addedUsesNodes) {
+                    usesNodes.add(builder.build());
+                }
             }
-            instance.setUses(usesNodeDefs);
+            instance.setUses(usesNodes);
 
             // GROUPINGS
-            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-            for (GroupingBuilder builder : groupings) {
-                groupingDefs.add(builder.build());
+            if(groupings == null) {
+                groupings = new HashSet<GroupingDefinition>();
+                for (GroupingBuilder builder : addedGroupings) {
+                    groupings.add(builder.build());
+                }
             }
-            instance.setGroupings(groupingDefs);
+            instance.setGroupings(groupings);
 
             // AUGMENTATIONS
-            final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
-            for (AugmentationSchemaBuilder builder : addedAugmentations) {
-                augmentations.add(builder.build());
+            if(augmentations == null) {
+                augmentations = new HashSet<AugmentationSchema>();
+                for (AugmentationSchemaBuilder builder : addedAugmentations) {
+                    augmentations.add(builder.build());
+                }
             }
             instance.setAvailableAugmentations(augmentations);
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-                unknownNodes.add(b.build());
+            if(unknownNodes == null) {
+                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                    unknownNodes.add(b.build());
+                }
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -129,6 +149,12 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         return instance;
     }
 
+    @Override
+    public void rebuild() {
+        isBuilt = false;
+        build();
+    }
+
     @Override
     public int getLine() {
         return line;
@@ -144,6 +170,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         addedTypedefs.add(type);
     }
 
+    public void setTypedefs(final Set<TypeDefinition<?>> typedefs) {
+        this.typedefs = typedefs;
+    }
+
     public SchemaPath getPath() {
         return schemaPath;
     }
@@ -191,6 +221,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         addedUsesNodes.add(usesBuilder);
     }
 
+    public void setUsesnodes(final Set<UsesNode> usesNodes) {
+        this.usesNodes = usesNodes;
+    }
+
     public Set<AugmentationSchemaBuilder> getAugmentations() {
         return addedAugmentations;
     }
@@ -200,6 +234,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         addedAugmentations.add(augment);
     }
 
+    public void setAugmentations(final Set<AugmentationSchema> augmentations) {
+        this.augmentations = augmentations;
+    }
+
     public List<QName> getKeyDefinition() {
         return keyDefinition;
     }
@@ -250,7 +288,12 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         addedUnknownNodes.add(unknownNode);
     }
 
-    private final class ListSchemaNodeImpl implements ListSchemaNode {
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
+
+    public final class ListSchemaNodeImpl implements ListSchemaNode {
         private final QName qname;
         private SchemaPath path;
         private String description;
@@ -444,6 +487,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
             }
         }
 
+        public ListSchemaNodeBuilder toBuilder() {
+            return ListSchemaNodeBuilder.this;
+        }
+
         @Override
         public int hashCode() {
             final int prime = 31;
index fa307972d49c7be12e57a12f7d9a9901881075b5..efa3849e90db4423f5ffee79d1d59ca2b1fec80a 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.controller.yang.model.api.NotificationDefinition;
 import org.opendaylight.controller.yang.model.api.RpcDefinition;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
+import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.model.api.UsesNode;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.Builder;
@@ -79,7 +80,7 @@ public class ModuleBuilder implements Builder {
     private final Map<List<String>, TypeDefinitionBuilder> addedTypedefs = new HashMap<List<String>, TypeDefinitionBuilder>();
     private final Map<List<String>, UnionTypeBuilder> addedUnionTypes = new HashMap<List<String>, UnionTypeBuilder>();
     private final List<ExtensionBuilder> addedExtensions = new ArrayList<ExtensionBuilder>();
-    private final Set<UnknownSchemaNodeBuilder> addedUnknownNodes = new HashSet<UnknownSchemaNodeBuilder>();
+    private final Map<List<String>, UnknownSchemaNodeBuilder> addedUnknownNodes = new HashMap<List<String>, UnknownSchemaNodeBuilder>();
 
     private final Map<List<String>, TypeAwareBuilder> dirtyNodes = new HashMap<List<String>, TypeAwareBuilder>();
 
@@ -123,7 +124,7 @@ public class ModuleBuilder implements Builder {
         // NOTIFICATIONS
         final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
         for (NotificationBuilder entry : addedNotifications) {
-            notifications.add((NotificationDefinition) entry.build());
+            notifications.add(entry.build());
         }
         instance.setNotifications(notifications);
 
@@ -140,8 +141,7 @@ public class ModuleBuilder implements Builder {
 
         // DEVIATIONS
         final Set<Deviation> deviations = new HashSet<Deviation>();
-        for (Map.Entry<List<String>, DeviationBuilder> entry : addedDeviations
-                .entrySet()) {
+        for (Map.Entry<List<String>, DeviationBuilder> entry : addedDeviations.entrySet()) {
             deviations.add(entry.getValue().build());
         }
         instance.setDeviations(deviations);
@@ -160,6 +160,10 @@ public class ModuleBuilder implements Builder {
         }
         instance.setIdentities(identities);
 
+        // UNKNOWN NODES
+        final List<UnknownSchemaNode> unknownNodes = buildModuleUnknownNodes(addedUnknownNodes);
+        instance.setUnknownSchemaNodes(unknownNodes);
+
         return instance;
     }
 
@@ -198,8 +202,7 @@ public class ModuleBuilder implements Builder {
 
     public Set<DataSchemaNodeBuilder> getChildNodes() {
         final Set<DataSchemaNodeBuilder> children = new HashSet<DataSchemaNodeBuilder>();
-        for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : childNodes
-                .entrySet()) {
+        for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : childNodes.entrySet()) {
             final List<String> path = entry.getKey();
             final DataSchemaNodeBuilder child = entry.getValue();
             if (path.size() == 2) {
@@ -226,13 +229,12 @@ public class ModuleBuilder implements Builder {
     }
 
     public Set<UnknownSchemaNodeBuilder> getUnknownNodes() {
-        return addedUnknownNodes;
+        return new HashSet<UnknownSchemaNodeBuilder>(addedUnknownNodes.values());
     }
 
     public Set<TypeDefinitionBuilder> getModuleTypedefs() {
         final Set<TypeDefinitionBuilder> typedefs = new HashSet<TypeDefinitionBuilder>();
-        for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs
-                .entrySet()) {
+        for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {
             if (entry.getKey().size() == 2) {
                 typedefs.add(entry.getValue());
             }
@@ -242,8 +244,7 @@ public class ModuleBuilder implements Builder {
 
     public Set<GroupingBuilder> getModuleGroupings() {
         final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();
-        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings
-                .entrySet()) {
+        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings.entrySet()) {
             if (entry.getKey().size() == 2) {
                 groupings.add(entry.getValue());
             }
@@ -281,8 +282,7 @@ public class ModuleBuilder implements Builder {
 
     public void addDirtyNode(final List<String> path) {
         final List<String> dirtyNodePath = new ArrayList<String>(path);
-        final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) actualPath
-                .getFirst();
+        final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) actualPath.getFirst();
         dirtyNodes.put(dirtyNodePath, nodeBuilder);
     }
 
@@ -314,10 +314,8 @@ public class ModuleBuilder implements Builder {
         instance.setContact(contact);
     }
 
-    public boolean addModuleImport(final String moduleName,
-            final Date revision, final String prefix) {
-        final ModuleImport moduleImport = createModuleImport(moduleName,
-                revision, prefix);
+    public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) {
+        final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix);
         return imports.add(moduleImport);
     }
 
@@ -331,12 +329,10 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public ContainerSchemaNodeBuilder addContainerNode(
-            final QName containerName, final List<String> parentPath,
+    public ContainerSchemaNodeBuilder addContainerNode(final QName containerName, final List<String> parentPath,
             final int line) {
         final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final ContainerSchemaNodeBuilder containerBuilder = new ContainerSchemaNodeBuilder(
-                containerName, line);
+        final ContainerSchemaNodeBuilder containerBuilder = new ContainerSchemaNodeBuilder(containerName, line);
         updateParent(containerBuilder, line, "container");
 
         pathToNode.add(containerName.getLocalName());
@@ -345,11 +341,9 @@ public class ModuleBuilder implements Builder {
         return containerBuilder;
     }
 
-    public ListSchemaNodeBuilder addListNode(final QName listName,
-            final List<String> parentPath, final int line) {
+    public ListSchemaNodeBuilder addListNode(final QName listName, final List<String> parentPath, final int line) {
         final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final ListSchemaNodeBuilder listBuilder = new ListSchemaNodeBuilder(
-                listName, line);
+        final ListSchemaNodeBuilder listBuilder = new ListSchemaNodeBuilder(listName, line);
         updateParent(listBuilder, line, "list");
 
         pathToNode.add(listName.getLocalName());
@@ -358,11 +352,9 @@ public class ModuleBuilder implements Builder {
         return listBuilder;
     }
 
-    public LeafSchemaNodeBuilder addLeafNode(final QName leafName,
-            final List<String> parentPath, final int line) {
+    public LeafSchemaNodeBuilder addLeafNode(final QName leafName, final List<String> parentPath, final int line) {
         final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final LeafSchemaNodeBuilder leafBuilder = new LeafSchemaNodeBuilder(
-                leafName, line);
+        final LeafSchemaNodeBuilder leafBuilder = new LeafSchemaNodeBuilder(leafName, line);
         updateParent(leafBuilder, line, "leaf");
 
         pathToNode.add(leafName.getLocalName());
@@ -371,11 +363,9 @@ public class ModuleBuilder implements Builder {
         return leafBuilder;
     }
 
-    public LeafListSchemaNodeBuilder addLeafListNode(final QName qname,
-            final List<String> parentPath, final int line) {
+    public LeafListSchemaNodeBuilder addLeafListNode(final QName qname, final List<String> parentPath, final int line) {
         final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final LeafListSchemaNodeBuilder leafListBuilder = new LeafListSchemaNodeBuilder(
-                qname, line);
+        final LeafListSchemaNodeBuilder leafListBuilder = new LeafListSchemaNodeBuilder(qname, line);
         updateParent(leafListBuilder, line, "leaf-list");
 
         pathToNode.add(qname.getLocalName());
@@ -384,8 +374,7 @@ public class ModuleBuilder implements Builder {
         return leafListBuilder;
     }
 
-    public GroupingBuilder addGrouping(final QName qname,
-            final List<String> parentPath, final int line) {
+    public GroupingBuilder addGrouping(final QName qname, final List<String> parentPath, final int line) {
         final List<String> pathToGroup = new ArrayList<String>(parentPath);
         final GroupingBuilder builder = new GroupingBuilderImpl(qname, line);
 
@@ -394,8 +383,7 @@ public class ModuleBuilder implements Builder {
             if (parent instanceof DataNodeContainerBuilder) {
                 ((DataNodeContainerBuilder) parent).addGrouping(builder);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of grouping " + qname.getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of grouping " + qname.getLocalName());
             }
         }
 
@@ -405,11 +393,9 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public AugmentationSchemaBuilder addAugment(final String name,
-            final List<String> parentPath, final int line) {
+    public AugmentationSchemaBuilder addAugment(final String name, final List<String> parentPath, final int line) {
         final List<String> pathToAugment = new ArrayList<String>(parentPath);
-        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(
-                name, line);
+        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line);
 
         // augment can only be in 'module' or 'uses' statement
         if (!(actualPath.isEmpty())) {
@@ -417,8 +403,7 @@ public class ModuleBuilder implements Builder {
             if (parent instanceof UsesNodeBuilder) {
                 ((UsesNodeBuilder) parent).addAugment(builder);
             } else {
-                throw new YangParseException(this.name, line,
-                        "Unresolved parent of augment " + name);
+                throw new YangParseException(this.name, line, "Unresolved parent of augment " + name);
             }
         }
 
@@ -428,11 +413,9 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public UsesNodeBuilder addUsesNode(final String groupingPathStr,
-            final List<String> parentPath, final int line) {
+    public UsesNodeBuilder addUsesNode(final String groupingPathStr, final List<String> parentPath, final int line) {
         final List<String> pathToUses = new ArrayList<String>(parentPath);
-        final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(
-                groupingPathStr, line);
+        final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(groupingPathStr, line);
 
         if (!(actualPath.isEmpty())) {
             final Builder parent = actualPath.getFirst();
@@ -442,8 +425,7 @@ public class ModuleBuilder implements Builder {
                 }
                 ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of uses " + groupingPathStr);
+                throw new YangParseException(name, line, "Unresolved parent of uses " + groupingPathStr);
             }
         }
 
@@ -452,37 +434,31 @@ public class ModuleBuilder implements Builder {
         return usesBuilder;
     }
 
-    public void addRefine(final RefineHolder refine,
-            final List<String> parentPath) {
+    public void addRefine(final RefineHolder refine, final List<String> parentPath) {
         final List<String> path = new ArrayList<String>(parentPath);
 
         if (actualPath.isEmpty()) {
-            throw new YangParseException(name, refine.getLine(),
-                    "refine can be defined only in uses statement");
+            throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
         } else {
             final Builder parent = actualPath.getFirst();
             if (parent instanceof UsesNodeBuilder) {
                 ((UsesNodeBuilder) parent).addRefine(refine);
             } else {
-                throw new YangParseException(name, refine.getLine(),
-                        "refine can be defined only in uses statement");
+                throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
             }
         }
 
         path.add(refine.getName());
     }
 
-    public RpcDefinitionBuilder addRpc(final QName qname,
-            final List<String> parentPath, final int line) {
+    public RpcDefinitionBuilder addRpc(final QName qname, final List<String> parentPath, final int line) {
 
         if (!(actualPath.isEmpty())) {
-            throw new YangParseException(name, line,
-                    "rpc can be defined only in module or submodule");
+            throw new YangParseException(name, line, "rpc can be defined only in module or submodule");
         }
 
         final List<String> pathToRpc = new ArrayList<String>(parentPath);
-        final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(qname,
-                line);
+        final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(qname, line);
 
         pathToRpc.add(qname.getLocalName());
         addedRpcs.put(pathToRpc, rpcBuilder);
@@ -490,45 +466,36 @@ public class ModuleBuilder implements Builder {
         return rpcBuilder;
     }
 
-    public ContainerSchemaNodeBuilder addRpcInput(final QName inputQName,
-            final int line) {
+    public ContainerSchemaNodeBuilder addRpcInput(final QName inputQName, final int line) {
         final Builder parent = actualPath.getFirst();
         if (!(parent instanceof RpcDefinitionBuilder)) {
-            throw new YangParseException(name, line,
-                    "input can be defined only in rpc statement");
+            throw new YangParseException(name, line, "input can be defined only in rpc statement");
         }
         final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
 
-        final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(
-                inputQName, line);
+        final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(inputQName, line);
         rpc.setInput(inputBuilder);
         return inputBuilder;
     }
 
-    public ContainerSchemaNodeBuilder addRpcOutput(final QName outputQName,
-            final int line) {
+    public ContainerSchemaNodeBuilder addRpcOutput(final QName outputQName, final int line) {
         final Builder parent = actualPath.getFirst();
         if (!(parent instanceof RpcDefinitionBuilder)) {
-            throw new YangParseException(name, line,
-                    "output can be defined only in rpc statement");
+            throw new YangParseException(name, line, "output can be defined only in rpc statement");
         }
         final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
 
-        final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(
-                outputQName, line);
+        final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(outputQName, line);
         rpc.setOutput(outputBuilder);
         return outputBuilder;
     }
 
-    public NotificationBuilder addNotification(final QName notificationName,
-            final List<String> parentPath, final int line) {
+    public NotificationBuilder addNotification(final QName notificationName, final List<String> parentPath,
+            final int line) {
         if (!(actualPath.isEmpty())) {
-            throw new YangParseException(name, line,
-                    "notification can be defined only in module or submodule");
+            throw new YangParseException(name, line, "notification can be defined only in module or submodule");
         }
-
-        final NotificationBuilder builder = new NotificationBuilder(
-                notificationName, line);
+        final NotificationBuilder builder = new NotificationBuilder(notificationName, line);
 
         final List<String> notificationPath = new ArrayList<String>(parentPath);
         notificationPath.add(notificationName.getLocalName());
@@ -537,11 +504,9 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public FeatureBuilder addFeature(final QName featureName,
-            final List<String> parentPath, final int line) {
+    public FeatureBuilder addFeature(final QName featureName, final List<String> parentPath, final int line) {
         if (!(actualPath.isEmpty())) {
-            throw new YangParseException(name, line,
-                    "feature can be defined only in module or submodule");
+            throw new YangParseException(name, line, "feature can be defined only in module or submodule");
         }
 
         final List<String> pathToFeature = new ArrayList<String>(parentPath);
@@ -552,22 +517,19 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public ChoiceBuilder addChoice(final QName choiceName,
-            final List<String> parentPath, final int line) {
+    public ChoiceBuilder addChoice(final QName choiceName, final List<String> parentPath, final int line) {
         final List<String> pathToChoice = new ArrayList<String>(parentPath);
         final ChoiceBuilder builder = new ChoiceBuilder(choiceName, line);
 
         if (!(actualPath.isEmpty())) {
-            Builder parent = actualPath.getFirst();
+            final Builder parent = actualPath.getFirst();
             if (parent instanceof DataNodeContainerBuilder) {
                 if (parent instanceof AugmentationSchemaBuilder) {
                     builder.setAugmenting(true);
                 }
                 ((DataNodeContainerBuilder) parent).addChildNode(builder);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of choice "
-                                + choiceName.getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of choice " + choiceName.getLocalName());
             }
         }
 
@@ -577,8 +539,7 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public ChoiceCaseBuilder addCase(final QName caseName,
-            final List<String> parentPath, final int line) {
+    public ChoiceCaseBuilder addCase(final QName caseName, final List<String> parentPath, final int line) {
         final List<String> pathToCase = new ArrayList<String>(parentPath);
         final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(caseName, line);
 
@@ -592,9 +553,7 @@ public class ModuleBuilder implements Builder {
                 builder.setAugmenting(true);
                 ((AugmentationSchemaBuilder) parent).addChildNode(builder);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of 'case' "
-                                + caseName.getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of 'case' " + caseName.getLocalName());
             }
         }
 
@@ -604,8 +563,7 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public AnyXmlBuilder addAnyXml(final QName anyXmlName,
-            final List<String> parentPath, final int line) {
+    public AnyXmlBuilder addAnyXml(final QName anyXmlName, final List<String> parentPath, final int line) {
         final List<String> pathToAnyXml = new ArrayList<String>(parentPath);
         final AnyXmlBuilder builder = new AnyXmlBuilder(anyXmlName, line);
         updateParent(builder, line, "anyxml");
@@ -616,20 +574,16 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public TypeDefinitionBuilderImpl addTypedef(final QName typeDefName,
-            final List<String> parentPath, final int line) {
+    public TypeDefinitionBuilderImpl addTypedef(final QName typeDefName, final List<String> parentPath, final int line) {
         final List<String> pathToType = new ArrayList<String>(parentPath);
-        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(
-                typeDefName, line);
+        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typeDefName, line);
 
         if (!(actualPath.isEmpty())) {
             final Builder parent = actualPath.getFirst();
             if (parent instanceof TypeDefinitionAwareBuilder) {
                 ((TypeDefinitionAwareBuilder) parent).addTypedef(builder);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of typedef "
-                                + typeDefName.getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of typedef " + typeDefName.getLocalName());
             }
         }
 
@@ -638,23 +592,20 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public void setType(final TypeDefinition<?> type,
-            final List<String> parentPath) {
-
+    public void setType(final TypeDefinition<?> type, final List<String> parentPath) {
         if (!(actualPath.isEmpty())) {
             final Builder parent = actualPath.getFirst();
             if (parent instanceof TypeAwareBuilder) {
                 ((TypeAwareBuilder) parent).setType(type);
             } else {
-                throw new YangParseException("Failed to set type '"
-                        + type.getQName().getLocalName()
+                throw new YangParseException("Failed to set type '" + type.getQName().getLocalName()
                         + "'. Unknown parent node: " + parent);
             }
         }
     }
 
-    public UnionTypeBuilder addUnionType(final List<String> currentPath,
-            final URI namespace, final Date revision, final int line) {
+    public UnionTypeBuilder addUnionType(final List<String> currentPath, final URI namespace, final Date revision,
+            final int line) {
         final List<String> pathToUnion = new ArrayList<String>(currentPath);
         final UnionTypeBuilder union = new UnionTypeBuilder(line);
 
@@ -672,18 +623,15 @@ public class ModuleBuilder implements Builder {
                 addedUnionTypes.put(path, union);
                 return union;
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of union type.");
+                throw new YangParseException(name, line, "Unresolved parent of union type.");
             }
         }
     }
 
-    public void addIdentityrefType(final String baseString,
-            final List<String> parentPath, final SchemaPath schemaPath,
+    public void addIdentityrefType(final String baseString, final List<String> parentPath, final SchemaPath schemaPath,
             final int line) {
         final List<String> pathToIdentityref = new ArrayList<String>(parentPath);
-        final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(
-                baseString, schemaPath, line);
+        final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(baseString, schemaPath, line);
 
         if (actualPath.isEmpty()) {
             throw new YangParseException(line, "identityref error");
@@ -694,17 +642,14 @@ public class ModuleBuilder implements Builder {
                 typeParent.setTypedef(identityref);
                 dirtyNodes.put(pathToIdentityref, typeParent);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of identityref type.");
+                throw new YangParseException(name, line, "Unresolved parent of identityref type.");
             }
         }
     }
 
-    public DeviationBuilder addDeviation(final String targetPath,
-            final List<String> parentPath, final int line) {
+    public DeviationBuilder addDeviation(final String targetPath, final List<String> parentPath, final int line) {
         if (!(actualPath.isEmpty())) {
-            throw new YangParseException(name, line,
-                    "deviation can be defined only in module or submodule");
+            throw new YangParseException(name, line, "deviation can be defined only in module or submodule");
         }
 
         final List<String> pathToDeviation = new ArrayList<String>(parentPath);
@@ -714,31 +659,25 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
-    public IdentitySchemaNodeBuilder addIdentity(final QName qname,
-            final List<String> parentPath, final int line) {
+    public IdentitySchemaNodeBuilder addIdentity(final QName qname, final List<String> parentPath, final int line) {
         if (!(actualPath.isEmpty())) {
-            throw new YangParseException(name, line,
-                    "identity can be defined only in module or submodule");
+            throw new YangParseException(name, line, "identity can be defined only in module or submodule");
         }
 
         final List<String> pathToIdentity = new ArrayList<String>(parentPath);
-        final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(
-                qname, line);
+        final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(qname, line);
         pathToIdentity.add(qname.getLocalName());
         addedIdentities.add(builder);
         return builder;
     }
 
-    public void addConfiguration(final boolean configuration,
-            final List<String> parentPath, final int line) {
+    public void addConfiguration(final boolean configuration, final List<String> parentPath, final int line) {
         if (actualPath.isEmpty()) {
-            throw new YangParseException(name, line,
-                    "Parent node of config statement not found.");
+            throw new YangParseException(name, line, "Parent node of config statement not found.");
         } else {
             final Builder parent = actualPath.getFirst();
             if (parent instanceof DataSchemaNodeBuilder) {
-                ((DataSchemaNodeBuilder) parent)
-                        .setConfiguration(configuration);
+                ((DataSchemaNodeBuilder) parent).setConfiguration(configuration);
             } else if (parent instanceof RefineHolder) {
                 ((RefineHolder) parent).setConfig(configuration);
             } else if (parent instanceof DeviationBuilder) {
@@ -746,16 +685,14 @@ public class ModuleBuilder implements Builder {
                 // current api
                 return;
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of config statement.");
+                throw new YangParseException(name, line, "Unresolved parent of config statement.");
             }
         }
     }
 
-    public UnknownSchemaNodeBuilder addUnknownSchemaNode(final QName qname,
-            final List<String> parentPath, final int line) {
-        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(
-                qname, line);
+    public UnknownSchemaNodeBuilder addUnknownSchemaNode(final QName qname, final List<String> parentPath,
+            final int line) {
+        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(qname, line);
 
         if (!(actualPath.isEmpty())) {
             final Builder parent = actualPath.getFirst();
@@ -764,13 +701,13 @@ public class ModuleBuilder implements Builder {
             } else if (parent instanceof RefineHolder) {
                 ((RefineHolder) parent).addUnknownSchemaNode(builder);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of unknown node '"
-                                + qname.getLocalName() + "'");
+                throw new YangParseException(name, line, "Unresolved parent of unknown node '" + qname.getLocalName()
+                        + "'");
             }
         }
-
-        addedUnknownNodes.add(builder);
+        final List<String> unPath = new ArrayList<String>(parentPath);
+        unPath.add(qname.getLocalName());
+        addedUnknownNodes.put(unPath, builder);
         return builder;
     }
 
@@ -792,17 +729,16 @@ public class ModuleBuilder implements Builder {
         private Set<ModuleImport> imports = Collections.emptySet();
         private Set<FeatureDefinition> features = Collections.emptySet();
         private Set<TypeDefinition<?>> typeDefinitions = Collections.emptySet();
-        private Set<NotificationDefinition> notifications = Collections
-                .emptySet();
+        private Set<NotificationDefinition> notifications = Collections.emptySet();
         private Set<AugmentationSchema> augmentations = Collections.emptySet();
         private Set<RpcDefinition> rpcs = Collections.emptySet();
         private Set<Deviation> deviations = Collections.emptySet();
         private Map<QName, DataSchemaNode> childNodes = Collections.emptyMap();
         private Set<GroupingDefinition> groupings = Collections.emptySet();
         private Set<UsesNode> uses = Collections.emptySet();
-        private List<ExtensionDefinition> extensionNodes = Collections
-                .emptyList();
+        private List<ExtensionDefinition> extensionNodes = Collections.emptyList();
         private Set<IdentitySchemaNode> identities = Collections.emptySet();
+        private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();
 
         private ModuleImpl(String name) {
             this.name = name;
@@ -1000,8 +936,7 @@ public class ModuleBuilder implements Builder {
             return extensionNodes;
         }
 
-        private void setExtensionSchemaNodes(
-                List<ExtensionDefinition> extensionNodes) {
+        private void setExtensionSchemaNodes(final List<ExtensionDefinition> extensionNodes) {
             if (extensionNodes != null) {
                 this.extensionNodes = extensionNodes;
             }
@@ -1012,12 +947,23 @@ public class ModuleBuilder implements Builder {
             return identities;
         }
 
-        private void setIdentities(Set<IdentitySchemaNode> identities) {
+        private void setIdentities(final Set<IdentitySchemaNode> identities) {
             if (identities != null) {
                 this.identities = identities;
             }
         }
 
+        @Override
+        public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+            return unknownNodes;
+        }
+
+        private void setUnknownSchemaNodes(final List<UnknownSchemaNode> unknownNodes) {
+            if (unknownNodes != null) {
+                this.unknownNodes = unknownNodes;
+            }
+        }
+
         @Override
         public DataSchemaNode getDataChildByName(QName name) {
             return childNodes.get(name);
@@ -1039,15 +985,11 @@ public class ModuleBuilder implements Builder {
         public int hashCode() {
             final int prime = 31;
             int result = 1;
-            result = prime * result
-                    + ((namespace == null) ? 0 : namespace.hashCode());
+            result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
             result = prime * result + ((name == null) ? 0 : name.hashCode());
-            result = prime * result
-                    + ((revision == null) ? 0 : revision.hashCode());
-            result = prime * result
-                    + ((prefix == null) ? 0 : prefix.hashCode());
-            result = prime * result
-                    + ((yangVersion == null) ? 0 : yangVersion.hashCode());
+            result = prime * result + ((revision == null) ? 0 : revision.hashCode());
+            result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
+            result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode());
             return result;
         }
 
@@ -1103,8 +1045,7 @@ public class ModuleBuilder implements Builder {
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    ModuleImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName());
             sb.append("[");
             sb.append("name=" + name);
             sb.append(", namespace=" + namespace);
@@ -1116,8 +1057,7 @@ public class ModuleBuilder implements Builder {
         }
     }
 
-    private void updateParent(DataSchemaNodeBuilder nodeBuilder, int line,
-            String nodeTypeName) {
+    private void updateParent(DataSchemaNodeBuilder nodeBuilder, int line, String nodeTypeName) {
         if (!(actualPath.isEmpty())) {
             final Builder parent = actualPath.getFirst();
             if (parent instanceof DataNodeContainerBuilder) {
@@ -1128,16 +1068,14 @@ public class ModuleBuilder implements Builder {
             } else if (parent instanceof ChoiceBuilder) {
                 ((ChoiceBuilder) parent).addChildNode(nodeBuilder);
             } else {
-                throw new YangParseException(name, line,
-                        "Unresolved parent of " + nodeTypeName + " "
-                                + nodeBuilder.getQName().getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of " + nodeTypeName + " "
+                        + nodeBuilder.getQName().getLocalName());
             }
         }
     }
 
-    private ModuleImport createModuleImport(final String moduleName,
-            final Date revision, final String prefix) {
-        ModuleImport moduleImport = new ModuleImport() {
+    private ModuleImport createModuleImport(final String moduleName, final Date revision, final String prefix) {
+        final ModuleImport moduleImport = new ModuleImport() {
             @Override
             public String getModuleName() {
                 return moduleName;
@@ -1157,12 +1095,9 @@ public class ModuleBuilder implements Builder {
             public int hashCode() {
                 final int prime = 31;
                 int result = 1;
-                result = prime * result
-                        + ((moduleName == null) ? 0 : moduleName.hashCode());
-                result = prime * result
-                        + ((revision == null) ? 0 : revision.hashCode());
-                result = prime * result
-                        + ((prefix == null) ? 0 : prefix.hashCode());
+                result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode());
+                result = prime * result + ((revision == null) ? 0 : revision.hashCode());
+                result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
                 return result;
             }
 
@@ -1204,8 +1139,7 @@ public class ModuleBuilder implements Builder {
 
             @Override
             public String toString() {
-                return "ModuleImport[moduleName=" + moduleName + ", revision="
-                        + revision + ", prefix=" + prefix + "]";
+                return "ModuleImport[moduleName=" + moduleName + ", revision=" + revision + ", prefix=" + prefix + "]";
             }
         };
         return moduleImport;
@@ -1219,11 +1153,9 @@ public class ModuleBuilder implements Builder {
      * @return map of children, where key is child QName and value is child
      *         itself
      */
-    private Map<QName, DataSchemaNode> buildModuleChildNodes(
-            Map<List<String>, DataSchemaNodeBuilder> addedChilds) {
+    private Map<QName, DataSchemaNode> buildModuleChildNodes(Map<List<String>, DataSchemaNodeBuilder> addedChilds) {
         final Map<QName, DataSchemaNode> childNodes = new HashMap<QName, DataSchemaNode>();
-        for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : addedChilds
-                .entrySet()) {
+        for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : addedChilds.entrySet()) {
             List<String> path = entry.getKey();
             DataSchemaNodeBuilder child = entry.getValue();
             if (path.size() == 2) {
@@ -1243,11 +1175,9 @@ public class ModuleBuilder implements Builder {
      * @param addedGroupings
      * @return set of built GroupingDefinition objects
      */
-    private Set<GroupingDefinition> buildModuleGroupings(
-            Map<List<String>, GroupingBuilder> addedGroupings) {
+    private Set<GroupingDefinition> buildModuleGroupings(Map<List<String>, GroupingBuilder> addedGroupings) {
         final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
-        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings
-                .entrySet()) {
+        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings.entrySet()) {
             if (entry.getKey().size() == 2) {
                 groupings.add(entry.getValue().build());
             }
@@ -1261,12 +1191,10 @@ public class ModuleBuilder implements Builder {
      * @param addedRpcs
      * @return set of built RpcDefinition objects
      */
-    private Set<RpcDefinition> buildModuleRpcs(
-            Map<List<String>, RpcDefinitionBuilder> addedRpcs) {
+    private Set<RpcDefinition> buildModuleRpcs(Map<List<String>, RpcDefinitionBuilder> addedRpcs) {
         final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
         RpcDefinitionBuilder builder;
-        for (Map.Entry<List<String>, RpcDefinitionBuilder> entry : addedRpcs
-                .entrySet()) {
+        for (Map.Entry<List<String>, RpcDefinitionBuilder> entry : addedRpcs.entrySet()) {
             builder = entry.getValue();
             RpcDefinition rpc = builder.build();
             rpcs.add(rpc);
@@ -1282,16 +1210,13 @@ public class ModuleBuilder implements Builder {
      * @param addedTypedefs
      * @return set of built module typedef statements
      */
-    private Set<TypeDefinition<?>> buildModuleTypedefs(
-            Map<List<String>, TypeDefinitionBuilder> addedTypedefs) {
+    private Set<TypeDefinition<?>> buildModuleTypedefs(Map<List<String>, TypeDefinitionBuilder> addedTypedefs) {
         Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-        for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs
-                .entrySet()) {
+        for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {
             List<String> key = entry.getKey();
             TypeDefinitionBuilder typedefBuilder = entry.getValue();
             if (key.size() == 2) {
-                TypeDefinition<? extends TypeDefinition<?>> node = typedefBuilder
-                        .build();
+                TypeDefinition<? extends TypeDefinition<?>> node = typedefBuilder.build();
                 typedefs.add(node);
             }
         }
@@ -1306,11 +1231,9 @@ public class ModuleBuilder implements Builder {
      * @param addedUsesNodes
      * @return set of built module uses nodes
      */
-    private Set<UsesNode> buildUsesNodes(
-            Map<List<String>, UsesNodeBuilder> addedUsesNodes) {
+    private Set<UsesNode> buildUsesNodes(Map<List<String>, UsesNodeBuilder> addedUsesNodes) {
         final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
-        for (Map.Entry<List<String>, UsesNodeBuilder> entry : addedUsesNodes
-                .entrySet()) {
+        for (Map.Entry<List<String>, UsesNodeBuilder> entry : addedUsesNodes.entrySet()) {
             if (entry.getKey().size() == 2) {
                 usesNodeDefs.add(entry.getValue().build());
             }
@@ -1325,11 +1248,9 @@ public class ModuleBuilder implements Builder {
      * @param addedFeatures
      * @return set of built module features
      */
-    private Set<FeatureDefinition> buildModuleFeatures(
-            Map<List<String>, FeatureBuilder> addedFeatures) {
+    private Set<FeatureDefinition> buildModuleFeatures(Map<List<String>, FeatureBuilder> addedFeatures) {
         Set<FeatureDefinition> features = new HashSet<FeatureDefinition>();
-        for (Map.Entry<List<String>, FeatureBuilder> entry : addedFeatures
-                .entrySet()) {
+        for (Map.Entry<List<String>, FeatureBuilder> entry : addedFeatures.entrySet()) {
             if (entry.getKey().size() == 2) {
                 features.add(entry.getValue().build());
             }
@@ -1337,4 +1258,18 @@ public class ModuleBuilder implements Builder {
         return features;
     }
 
+    private List<UnknownSchemaNode> buildModuleUnknownNodes(
+            final Map<List<String>, UnknownSchemaNodeBuilder> addedUnknownNodes) {
+        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+        for (Map.Entry<List<String>, UnknownSchemaNodeBuilder> entry : addedUnknownNodes.entrySet()) {
+            final List<String> path = entry.getKey();
+            final UnknownSchemaNodeBuilder child = entry.getValue();
+            if (path.size() == 2) {
+                final UnknownSchemaNode node = child.build();
+                unknownNodes.add(node);
+            }
+        }
+        return unknownNodes;
+    }
+
 }
index f75b97d1d73146762e9983399a59857b98b8c37d..956d8fe449e9d9301dd020a7b6a1c628da7111c5 100644 (file)
@@ -16,16 +16,18 @@ import java.util.Map;
 import java.util.Set;
 
 import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;
 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
 import org.opendaylight.controller.yang.model.api.GroupingDefinition;
 import org.opendaylight.controller.yang.model.api.NotificationDefinition;
-import org.opendaylight.controller.yang.model.api.SchemaNode;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.model.api.UsesNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractDataNodeContainerBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
@@ -34,13 +36,18 @@ import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 
 public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
-        implements TypeDefinitionAwareBuilder, SchemaNodeBuilder {
+        implements TypeDefinitionAwareBuilder, SchemaNodeBuilder, AugmentationTargetBuilder {
     private boolean isBuilt;
     private final NotificationDefinitionImpl instance;
     private final int line;
     private SchemaPath schemaPath;
+    private String description;
+    private String reference;
+    private Status status = Status.CURRENT;
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
     private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
+    private Set<AugmentationSchema> augmentations;
+    private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
     NotificationBuilder(final QName qname, final int line) {
@@ -50,20 +57,23 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public SchemaNode build() {
+    public NotificationDefinition build() {
         if (!isBuilt) {
             instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
 
             // CHILD NODES
             final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-            for (DataSchemaNodeBuilder node : childNodes) {
+            for (DataSchemaNodeBuilder node : addedChildNodes) {
                 childs.put(node.getQName(), node.build());
             }
             instance.setChildNodes(childs);
 
             // GROUPINGS
             final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-            for (GroupingBuilder builder : groupings) {
+            for (GroupingBuilder builder : addedGroupings) {
                 groupingDefs.add(builder.build());
             }
             instance.setGroupings(groupingDefs);
@@ -82,6 +92,15 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
             }
             instance.setUses(uses);
 
+            // AUGMENTATIONS
+            if(augmentations == null) {
+                augmentations = new HashSet<AugmentationSchema>();
+                for (AugmentationSchemaBuilder builder : addedAugmentations) {
+                    augmentations.add(builder.build());
+                }
+            }
+            instance.setAvailableAugmentations(augmentations);
+
             // UNKNOWN NODES
             final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
@@ -95,6 +114,12 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
         return instance;
     }
 
+    @Override
+    public void rebuild() {
+        isBuilt = false;
+        build();
+    }
+
     @Override
     public int getLine() {
         return line;
@@ -125,19 +150,49 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
         this.schemaPath = schemaPath;
     }
 
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
     @Override
     public void setDescription(final String description) {
-        instance.setDescription(description);
+        this.description = description;
+    }
+
+    @Override
+    public String getReference() {
+        return reference;
     }
 
     @Override
     public void setReference(final String reference) {
-        instance.setReference(reference);
+        this.reference = reference;
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
     }
 
     @Override
     public void setStatus(final Status status) {
-        instance.setStatus(status);
+        if(status != null) {
+            this.status = status;
+        }
+    }
+
+    public Set<AugmentationSchemaBuilder> getAugmentations() {
+        return addedAugmentations;
+    }
+
+    @Override
+    public void addAugmentation(AugmentationSchemaBuilder augment) {
+        addedAugmentations.add(augment);
+    }
+
+    public void setAugmentations(final Set<AugmentationSchema> augmentations) {
+        this.augmentations = augmentations;
     }
 
     @Override
@@ -150,7 +205,7 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
         return "notification " + getQName().getLocalName();
     }
 
-    private final class NotificationDefinitionImpl implements NotificationDefinition {
+    public final class NotificationDefinitionImpl implements NotificationDefinition {
         private final QName qname;
         private SchemaPath path;
         private String description;
@@ -160,6 +215,7 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
         private Set<GroupingDefinition> groupings = Collections.emptySet();
         private Set<TypeDefinition<?>> typeDefinitions = Collections.emptySet();
         private Set<UsesNode> uses = Collections.emptySet();
+        private Set<AugmentationSchema> augmentations = Collections.emptySet();
         private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();
 
         private NotificationDefinitionImpl(final QName qname) {
@@ -254,6 +310,18 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
             }
         }
 
+        @Override
+        public Set<AugmentationSchema> getAvailableAugmentations() {
+            return augmentations;
+        }
+
+        private void setAvailableAugmentations(
+                Set<AugmentationSchema> augmentations) {
+            if (augmentations != null) {
+                this.augmentations = augmentations;
+            }
+        }
+
         @Override
         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
             return unknownNodes;
@@ -283,6 +351,10 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
             return result;
         }
 
+        public NotificationBuilder toBuilder() {
+            return NotificationBuilder.this;
+        }
+
         @Override
         public int hashCode() {
             final int prime = 31;
index 855d0264ae911f875951f04a3a6b0ae94a55b529..e36adbdeb2850f09102f244ef2fc2422377a1946 100644 (file)
@@ -32,6 +32,9 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini
     private final int line;
     private final QName qname;
     private SchemaPath schemaPath;
+    private String description;
+    private String reference;
+    private Status status = Status.CURRENT;
     private ContainerSchemaNodeBuilder inputBuilder;
     private ContainerSchemaNodeBuilder outputBuilder;
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
@@ -47,6 +50,10 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini
     @Override
     public RpcDefinition build() {
         if (!isBuilt) {
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+
             final ContainerSchemaNode input = inputBuilder == null ? null : inputBuilder.build();
             final ContainerSchemaNode output = outputBuilder == null ? null : outputBuilder.build();
             instance.setInput(input);
@@ -120,19 +127,36 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini
         this.schemaPath = schemaPath;
     }
 
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
     @Override
     public void setDescription(final String description) {
-        instance.setDescription(description);
+        this.description = description;
+    }
+
+    @Override
+    public String getReference() {
+        return reference;
+    }
+
+    @Override
+    public void setReference(String reference) {
+        this.reference = reference;
     }
 
     @Override
-    public void setReference(final String reference) {
-        instance.setReference(reference);
+    public Status getStatus() {
+        return status;
     }
 
     @Override
     public void setStatus(final Status status) {
-        instance.setStatus(status);
+        if (status != null) {
+            this.status = status;
+        }
     }
 
     @Override
@@ -147,7 +171,11 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini
 
     @Override
     public int hashCode() {
-        return qname.hashCode();
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((qname == null) ? 0 : qname.hashCode());
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
     }
 
     @Override
@@ -166,6 +194,13 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini
         } else if (!other.qname.equals(this.qname)) {
             return false;
         }
+        if (other.schemaPath == null) {
+            if (this.schemaPath != null) {
+                return false;
+            }
+        } else if (!other.schemaPath.equals(this.schemaPath)) {
+            return false;
+        }
         return true;
     }
 
index 222290188e3ad019ad23300666c792aede587376..3d3ad28891b92eba2ae222582afd905f252262a1 100644 (file)
@@ -23,6 +23,9 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder {
     private final int line;
     private final QName qname;
     private SchemaPath schemaPath;
+    private String description;
+    private String reference;
+    private Status status = Status.CURRENT;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
     private QName nodeType;
     private String nodeParameter;
@@ -35,10 +38,13 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder {
 
     @Override
     public UnknownSchemaNode build() {
-        if(!isBuilt) {
+        if (!isBuilt) {
             instance.setPath(schemaPath);
             instance.setNodeType(nodeType);
             instance.setNodeParameter(nodeParameter);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
 
             // UNKNOWN NODES
             final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
@@ -73,19 +79,36 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder {
         this.schemaPath = schemaPath;
     }
 
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
     @Override
     public void setDescription(final String description) {
-        instance.setDescription(description);
+        this.description = description;
+    }
+
+    @Override
+    public String getReference() {
+        return reference;
     }
 
     @Override
-    public void setReference(final String reference) {
-        instance.setReference(reference);
+    public void setReference(String reference) {
+        this.reference = reference;
     }
 
     @Override
-    public void setStatus(final Status status) {
-        instance.setStatus(status);
+    public Status getStatus() {
+        return status;
+    }
+
+    @Override
+    public void setStatus(Status status) {
+        if (status != null) {
+            this.status = status;
+        }
     }
 
     @Override
@@ -171,8 +194,7 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder {
             return unknownNodes;
         }
 
-        private void setUnknownSchemaNodes(
-                final List<UnknownSchemaNode> unknownNodes) {
+        private void setUnknownSchemaNodes(final List<UnknownSchemaNode> unknownNodes) {
             if (unknownNodes != null) {
                 this.unknownNodes = unknownNodes;
             }
index 1a71abf70cc52a0c082a15b78764dd955d6ec3a8..611d2ce1bd3119f0c29f7294dbfe2468dd2081b1 100644 (file)
@@ -75,8 +75,7 @@ final class SchemaContextImpl implements SchemaContext {
                     if (module.getName().equals(name)) {
                         return module;
                     }
-                } else if (module.getName().equals(name)
-                        && module.getRevision().equals(revision)) {
+                } else if (module.getName().equals(name) && module.getRevision().equals(revision)) {
                     return module;
                 }
             }
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java
new file mode 100644 (file)
index 0000000..2725162
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.yang.parser.impl;
+
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class YangErrorListener extends BaseErrorListener {
+    private final static Logger logger = LoggerFactory.getLogger(YangErrorListener.class);
+
+    @Override
+    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
+            String msg, RecognitionException e) {
+        logger.warn("line " + line + ":" + charPositionInLine + " " + msg);
+    }
+
+}
index 6814322bde1721ef7b7ba3f258279bf2882bc601..e74029b424750b2b318f04df447fb7292a26c6cd 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.controller.yang.parser.impl;
 
+import static org.opendaylight.controller.yang.parser.util.ParserUtils.*;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -19,6 +21,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -33,45 +36,33 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
 import org.opendaylight.controller.antlrv4.code.gen.YangLexer;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
 import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
+import org.opendaylight.controller.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.controller.yang.model.api.Module;
-import org.opendaylight.controller.yang.model.api.ModuleImport;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
 import org.opendaylight.controller.yang.model.util.ExtendedType;
 import org.opendaylight.controller.yang.model.util.IdentityrefType;
 import org.opendaylight.controller.yang.model.util.UnknownType;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
-import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.Builder;
 import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder;
-import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.IdentityrefTypeBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.RpcDefinitionBuilder;
-import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.util.ModuleDependencySort;
-import org.opendaylight.controller.yang.parser.util.ParserUtils;
 import org.opendaylight.controller.yang.parser.util.RefineHolder;
+import org.opendaylight.controller.yang.parser.util.RefineUtils;
 import org.opendaylight.controller.yang.parser.util.TypeConstraints;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 import org.opendaylight.controller.yang.validator.YangModelBasicValidator;
@@ -87,7 +78,12 @@ public final class YangParserImpl implements YangModelParser {
     private static final Logger logger = LoggerFactory.getLogger(YangParserImpl.class);
 
     @Override
-    public Map<File, Module> parseYangModelsMapped(List<File> yangFiles) {
+    public Set<Module> parseYangModels(final List<File> yangFiles) {
+        return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values());
+    }
+
+    @Override
+    public Set<Module> parseYangModels(final List<File> yangFiles, final SchemaContext context) {
         if (yangFiles != null) {
             final Map<InputStream, File> inputStreams = Maps.newHashMap();
 
@@ -103,7 +99,60 @@ public final class YangParserImpl implements YangModelParser {
 
             final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(
                     Lists.newArrayList(inputStreams.keySet()), builderToStreamMap);
-            // return new LinkedHashSet<Module>(build(modules).values());
+
+            for (InputStream is : inputStreams.keySet()) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    logger.debug("Failed to close stream.");
+                }
+            }
+
+            return new LinkedHashSet<Module>(buildWithContext(modules, context).values());
+        }
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams) {
+        return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values());
+    }
+
+    @Override
+    public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams, SchemaContext context) {
+        if (yangModelStreams != null) {
+            Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersWithContext(
+                    yangModelStreams, builderToStreamMap, context);
+            return new LinkedHashSet<Module>(buildWithContext(modules, context).values());
+        }
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Map<File, Module> parseYangModelsMapped(List<File> yangFiles) {
+        if (yangFiles != null) {
+            final Map<InputStream, File> inputStreams = Maps.newHashMap();
+
+            for (final File yangFile : yangFiles) {
+                try {
+                    inputStreams.put(new FileInputStream(yangFile), yangFile);
+                } catch (FileNotFoundException e) {
+                    logger.warn("Exception while reading yang file: " + yangFile.getName(), e);
+                }
+            }
+
+            Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(
+                    Lists.newArrayList(inputStreams.keySet()), builderToStreamMap);
+
+            for (InputStream is : inputStreams.keySet()) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    logger.debug("Failed to close stream.");
+                }
+            }
 
             Map<File, Module> retVal = Maps.newLinkedHashMap();
             Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
@@ -118,16 +167,6 @@ public final class YangParserImpl implements YangModelParser {
         return Collections.emptyMap();
     }
 
-    @Override
-    public Set<Module> parseYangModels(final List<File> yangFiles) {
-        return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values());
-    }
-
-    @Override
-    public Set<Module> parseYangModelsFromStreams(final List<InputStream> yangModelStreams) {
-        return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values());
-    }
-
     @Override
     public Map<InputStream, Module> parseYangModelsFromStreamsMapped(final List<InputStream> yangModelStreams) {
         Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
@@ -173,7 +212,12 @@ public final class YangParserImpl implements YangModelParser {
 
     private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(final List<InputStream> yangFileStreams,
             Map<ModuleBuilder, InputStream> streamToBuilderMap) {
+        return resolveModuleBuildersWithContext(yangFileStreams, streamToBuilderMap, null);
+    }
 
+    private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersWithContext(
+            final List<InputStream> yangFileStreams, final Map<ModuleBuilder, InputStream> streamToBuilderMap,
+            final SchemaContext context) {
         final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, streamToBuilderMap);
 
         // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER
@@ -181,9 +225,17 @@ public final class YangParserImpl implements YangModelParser {
         final LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = new LinkedHashMap<String, TreeMap<Date, ModuleBuilder>>();
 
         // module dependency graph sorted
-        List<ModuleBuilder> sorted = ModuleDependencySort.sort(builders);
+        List<ModuleBuilder> sorted = null;
+        if (context == null) {
+            sorted = ModuleDependencySort.sort(builders);
+        } else {
+            sorted = ModuleDependencySort.sortWithContext(context, builders);
+        }
 
-        for (ModuleBuilder builder : sorted) {
+        for (final ModuleBuilder builder : sorted) {
+            if (builder == null) {
+                continue;
+            }
             final String builderName = builder.getName();
             Date builderRevision = builder.getRevision();
             if (builderRevision == null) {
@@ -214,6 +266,8 @@ public final class YangParserImpl implements YangModelParser {
             final YangLexer lexer = new YangLexer(input);
             final CommonTokenStream tokens = new CommonTokenStream(lexer);
             final YangParser parser = new YangParser(tokens);
+            parser.removeErrorListeners();
+            parser.addErrorListener(new YangErrorListener());
 
             result = parser.yang();
         } catch (IOException e) {
@@ -249,13 +303,49 @@ public final class YangParserImpl implements YangModelParser {
         return result;
     }
 
+    private Map<ModuleBuilder, Module> buildWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            SchemaContext context) {
+        // fix unresolved nodes
+        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+            for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
+                final ModuleBuilder moduleBuilder = childEntry.getValue();
+                fixUnresolvedNodesWithContext(modules, moduleBuilder, context);
+            }
+        }
+        resolveAugmentsWithContext(modules, context);
+
+        // build
+        // LinkedHashMap MUST be used otherwise the values will not maintain
+        // order!
+        // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html
+        final Map<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
+        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+            final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
+            for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
+                final ModuleBuilder moduleBuilder = childEntry.getValue();
+                final Module module = moduleBuilder.build();
+                modulesByRevision.put(childEntry.getKey(), module);
+                result.put(moduleBuilder, module);
+            }
+        }
+        return result;
+    }
+
     private void fixUnresolvedNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
         resolveDirtyNodes(modules, builder);
         resolveIdentities(modules, builder);
-        resolveUsesRefines(modules, builder);
+        resolveUsesRefine(modules, builder);
         resolveUnknownNodes(modules, builder);
     }
 
+    private void fixUnresolvedNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder builder, final SchemaContext context) {
+        resolveDirtyNodesWithContext(modules, builder, context);
+        resolveIdentitiesWithContext(modules, builder, context);
+        resolveUsesRefineWithContext(modules, builder, context);
+        resolveUnknownNodesWithContext(modules, builder, context);
+    }
+
     /**
      * Search for dirty nodes (node which contains UnknownType) and resolve
      * unknown types.
@@ -285,34 +375,135 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    private void resolveDirtyNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, SchemaContext context) {
+        final Map<List<String>, TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
+        if (!dirtyNodes.isEmpty()) {
+            for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes.entrySet()) {
+                final TypeAwareBuilder nodeToResolve = entry.getValue();
+
+                if (nodeToResolve instanceof UnionTypeBuilder) {
+                    // special handling for union types
+                    resolveTypeUnionWithContext((UnionTypeBuilder) nodeToResolve, modules, module, context);
+                } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
+                    // special handling for identityref types
+                    IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef();
+                    nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath()));
+                } else {
+                    resolveTypeWithContext(nodeToResolve, modules, module, context);
+                }
+            }
+        }
+    }
+
+    /**
+     * Resolve unknown type of node. It is assumed that type of node is either
+     * UnknownType or ExtendedType with UnknownType as base type.
+     *
+     * @param nodeToResolve
+     *            node with type to resolve
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     */
     private void resolveType(final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         TypeDefinitionBuilder resolvedType = null;
         final int line = nodeToResolve.getLine();
         final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
         final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
-        final ModuleBuilder dependentModule = findDependentModule(modules, builder, unknownTypeQName.getPrefix(), line);
+        final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, unknownTypeQName.getPrefix(),
+                line);
 
         final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(),
-                dependentModule, unknownTypeQName.getLocalName(), builder.getName(), line);
+                dependentModule, unknownTypeQName.getLocalName(), module.getName(), line);
 
         if (nodeToResolveType instanceof ExtendedType) {
             final ExtendedType extType = (ExtendedType) nodeToResolveType;
-            final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(nodeToResolve, targetTypeBuilder,
-                    extType, modules, builder);
+            final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
+                    modules, module, nodeToResolve.getLine());
             resolvedType = newType;
         } else {
             resolvedType = targetTypeBuilder;
         }
 
         // validate constraints
-        final TypeConstraints constraints = findConstraints(nodeToResolve, new TypeConstraints(builder.getName(),
-                nodeToResolve.getLine()), modules, builder);
+        final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve,
+                new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, null);
         constraints.validateConstraints();
 
         nodeToResolve.setTypedef(resolvedType);
     }
 
+    /**
+     * Resolve unknown type of node. It is assumed that type of node is either
+     * UnknownType or ExtendedType with UnknownType as base type.
+     *
+     * @param nodeToResolve
+     *            node with type to resolve
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @param context
+     *            SchemaContext containing already resolved modules
+     */
+    private void resolveTypeWithContext(final TypeAwareBuilder nodeToResolve,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
+            final SchemaContext context) {
+        TypeDefinitionBuilder resolvedType = null;
+        final int line = nodeToResolve.getLine();
+        final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
+        final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
+        final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module,
+                unknownTypeQName.getPrefix(), line);
+
+        if (dependentModuleBuilder == null) {
+            final Module dependentModule = findModuleFromContext(context, module, unknownTypeQName.getPrefix(), line);
+            final Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
+            final TypeDefinition<?> type = findTypeByName(types, unknownTypeQName.getLocalName());
+
+            if (nodeToResolveType instanceof ExtendedType) {
+                final ExtendedType extType = (ExtendedType) nodeToResolveType;
+                final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, module,
+                        nodeToResolve.getLine());
+
+                nodeToResolve.setTypedef(newType);
+            } else {
+                if(nodeToResolve instanceof TypeDefinitionBuilder) {
+                    TypeDefinitionBuilder tdb = (TypeDefinitionBuilder)nodeToResolve;
+                    TypeConstraints tc = findConstraintsFromTypeBuilder(nodeToResolve, new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, context);
+                    tdb.setLengths(tc.getLength());
+                    tdb.setPatterns(tc.getPatterns());
+                    tdb.setRanges(tc.getRange());
+                    tdb.setFractionDigits(tc.getFractionDigits());
+                }
+                nodeToResolve.setType(type);
+            }
+
+        } else {
+            final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(),
+                    dependentModuleBuilder, unknownTypeQName.getLocalName(), module.getName(), line);
+
+            if (nodeToResolveType instanceof ExtendedType) {
+                final ExtendedType extType = (ExtendedType) nodeToResolveType;
+                final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType,
+                        modules, module, nodeToResolve.getLine());
+                resolvedType = newType;
+            } else {
+                resolvedType = targetTypeBuilder;
+            }
+
+            // validate constraints
+            final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve, new TypeConstraints(
+                    module.getName(), nodeToResolve.getLine()), modules, module, context);
+            constraints.validateConstraints();
+
+            nodeToResolve.setTypedef(resolvedType);
+        }
+    }
+
     private void resolveTypeUnion(final UnionTypeBuilder union,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
 
@@ -321,24 +512,24 @@ public final class YangParserImpl implements YangModelParser {
         for (TypeDefinition<?> unionType : unionTypes) {
             if (unionType instanceof UnknownType) {
                 final UnknownType ut = (UnknownType) unionType;
-                final ModuleBuilder dependentModule = findDependentModule(modules, builder, ut.getQName().getPrefix(),
-                        union.getLine());
+                final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
+                        .getPrefix(), union.getLine());
                 final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(), dependentModule,
                         ut.getQName().getLocalName(), builder.getName(), union.getLine());
                 union.setTypedef(resolvedType);
                 toRemove.add(ut);
             } else if (unionType instanceof ExtendedType) {
                 final ExtendedType extType = (ExtendedType) unionType;
-                TypeDefinition<?> extTypeBase = extType.getBaseType();
+                final TypeDefinition<?> extTypeBase = extType.getBaseType();
                 if (extTypeBase instanceof UnknownType) {
                     final UnknownType ut = (UnknownType) extTypeBase;
-                    final ModuleBuilder dependentModule = findDependentModule(modules, builder, ut.getQName()
+                    final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
                             .getPrefix(), union.getLine());
                     final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(),
                             dependentModule, ut.getQName().getLocalName(), builder.getName(), union.getLine());
 
-                    final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(targetTypeBuilder,
-                            targetTypeBuilder, extType, modules, builder);
+                    final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
+                            extType, modules, builder, union.getLine());
 
                     union.setTypedef(newType);
                     toRemove.add(extType);
@@ -348,173 +539,150 @@ public final class YangParserImpl implements YangModelParser {
         unionTypes.removeAll(toRemove);
     }
 
-    private TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeAwareBuilder nodeToResolve,
-            final TypeDefinitionBuilder newBaseType, final ExtendedType oldExtendedType,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
-        final TypeConstraints constraints = findConstraints(nodeToResolve, new TypeConstraints(builder.getName(),
-                nodeToResolve.getLine()), modules, builder);
-        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(),
-                nodeToResolve.getLine());
-        newType.setTypedef(newBaseType);
-        newType.setPath(oldExtendedType.getPath());
-        newType.setDescription(oldExtendedType.getDescription());
-        newType.setReference(oldExtendedType.getReference());
-        newType.setStatus(oldExtendedType.getStatus());
-        newType.setLengths(constraints.getLength());
-        newType.setPatterns(constraints.getPatterns());
-        newType.setRanges(constraints.getRange());
-        newType.setFractionDigits(constraints.getFractionDigits());
-        newType.setUnits(oldExtendedType.getUnits());
-        newType.setDefaultValue(oldExtendedType.getDefaultValue());
-        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
-        return newType;
-    }
-
-    private TypeConstraints findConstraints(final TypeAwareBuilder nodeToResolve, final TypeConstraints constraints,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
-
-        // union type cannot be restricted
-        if (nodeToResolve instanceof UnionTypeBuilder) {
-            return constraints;
-        }
-
-        if (nodeToResolve instanceof TypeDefinitionBuilder) {
-            TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve;
-            constraints.addFractionDigits(typedefToResolve.getFractionDigits());
-            constraints.addLengths(typedefToResolve.getLengths());
-            constraints.addPatterns(typedefToResolve.getPatterns());
-            constraints.addRanges(typedefToResolve.getRanges());
-        }
+    private void resolveTypeUnionWithContext(final UnionTypeBuilder union,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder,
+            final SchemaContext context) {
 
-        TypeDefinition<?> type = nodeToResolve.getType();
-        if (type == null) {
-            return findConstraints(nodeToResolve.getTypedef(), constraints, modules, builder);
-        } else {
-            if (type instanceof UnknownType) {
-                ModuleBuilder dependentModule = findDependentModule(modules, builder, type.getQName().getPrefix(),
-                        nodeToResolve.getLine());
-                TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), dependentModule, type
-                        .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
-                return findConstraints(tdb, constraints, modules, dependentModule);
-            } else if (type instanceof ExtendedType) {
-                ExtendedType extType = (ExtendedType) type;
-                constraints.addFractionDigits(extType.getFractionDigits());
-                constraints.addLengths(extType.getLengths());
-                constraints.addPatterns(extType.getPatterns());
-                constraints.addRanges(extType.getRanges());
-
-                TypeDefinition<?> base = extType.getBaseType();
-                if (base instanceof UnknownType) {
-                    ModuleBuilder dependentModule = findDependentModule(modules, builder, base.getQName().getPrefix(),
-                            nodeToResolve.getLine());
-                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), dependentModule,
-                            base.getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
-                    return findConstraints(tdb, constraints, modules, dependentModule);
+        final List<TypeDefinition<?>> unionTypes = union.getTypes();
+        final List<TypeDefinition<?>> toRemove = new ArrayList<TypeDefinition<?>>();
+        for (TypeDefinition<?> unionType : unionTypes) {
+            if (unionType instanceof UnknownType) {
+                final UnknownType ut = (UnknownType) unionType;
+                final QName utQName = ut.getQName();
+                final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
+                        utQName.getPrefix(), union.getLine());
+
+                if (dependentModuleBuilder == null) {
+                    Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
+                            union.getLine());
+                    Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
+                    TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
+                    union.setType(type);
+                    toRemove.add(ut);
                 } else {
-                    // it has to be base yang type
-                    mergeConstraints(type, constraints);
-                    return constraints;
+                    final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(),
+                            dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
+                    union.setTypedef(resolvedType);
+                    toRemove.add(ut);
+                }
+
+            } else if (unionType instanceof ExtendedType) {
+                final ExtendedType extType = (ExtendedType) unionType;
+                TypeDefinition<?> extTypeBase = extType.getBaseType();
+                if (extTypeBase instanceof UnknownType) {
+                    final UnknownType ut = (UnknownType) extTypeBase;
+                    final QName utQName = ut.getQName();
+                    final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder,
+                            utQName.getPrefix(), union.getLine());
+
+                    if (dependentModuleBuilder == null) {
+                        final Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(),
+                                union.getLine());
+                        Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
+                        TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
+                        final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, builder, 0);
+
+                        union.setTypedef(newType);
+                        toRemove.add(extType);
+                    } else {
+                        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(),
+                                dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
+
+                        final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
+                                extType, modules, builder, union.getLine());
+
+                        union.setTypedef(newType);
+                        toRemove.add(extType);
+                    }
                 }
-            } else {
-                // it is base yang type
-                mergeConstraints(type, constraints);
-                return constraints;
             }
         }
+        unionTypes.removeAll(toRemove);
     }
 
     /**
-     * Search for type definition builder by name.
+     * Go through all augment definitions and resolve them. It is expected that
+     * modules are already sorted by their dependencies. This method also finds
+     * augment target node and add child nodes to it.
      *
-     * @param dirtyNodeSchemaPath
-     *            schema path of node which contains unresolved type
-     * @param dependentModule
-     *            module which should contains referenced type
-     * @param typeName
-     *            name of type definition
-     * @param currentModuleName
-     *            name of current module
-     * @param line
-     *            current line in yang model
-     * @return
+     * @param modules
+     *            all available modules
      */
-    private TypeDefinitionBuilder findTypeDefinitionBuilder(SchemaPath dirtyNodeSchemaPath,
-            final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) {
-        final List<QName> path = dirtyNodeSchemaPath.getPath();
-        TypeDefinitionBuilder result = null;
-
-        Set<TypeDefinitionBuilder> typedefs = dependentModule.getModuleTypedefs();
-        result = findTdb(typedefs, typeName);
-
-        if (result == null) {
-            Builder currentNode = null;
-            final List<String> currentPath = new ArrayList<String>();
-            currentPath.add(dependentModule.getName());
-
-            for (int i = 0; i < path.size(); i++) {
-                QName qname = path.get(i);
-                currentPath.add(qname.getLocalName());
-                currentNode = dependentModule.getModuleNode(currentPath);
-
-                if (currentNode instanceof RpcDefinitionBuilder) {
-                    typedefs = ((RpcDefinitionBuilder) currentNode).getTypeDefinitions();
-                } else if (currentNode instanceof DataNodeContainerBuilder) {
-                    typedefs = ((DataNodeContainerBuilder) currentNode).getTypeDefinitions();
-                } else {
-                    typedefs = Collections.emptySet();
-                }
-
-                result = findTdb(typedefs, typeName);
-                if (result != null) {
-                    break;
-                }
+    private void resolveAugments(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
+        final List<ModuleBuilder> allModulesList = new ArrayList<ModuleBuilder>();
+        final Set<ModuleBuilder> allModulesSet = new HashSet<ModuleBuilder>();
+        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+            for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
+                allModulesList.add(inner.getValue());
+                allModulesSet.add(inner.getValue());
             }
         }
 
-        if (result != null) {
-            return result;
-        }
-        throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found.");
-    }
-
-    private TypeDefinitionBuilder findTdb(Set<TypeDefinitionBuilder> types, String name) {
-        for (TypeDefinitionBuilder td : types) {
-            if (td.getQName().getLocalName().equals(name)) {
-                return td;
+        for (int i = 0; i < allModulesList.size(); i++) {
+            final ModuleBuilder module = allModulesList.get(i);
+            // try to resolve augments in module
+            resolveAugment(modules, module);
+            // while all augments are not resolved
+            final Iterator<ModuleBuilder> allModulesIterator = allModulesSet.iterator();
+            while (!(module.getAugmentsResolved() == module.getAugments().size())) {
+                ModuleBuilder nextModule = null;
+                // try resolve other module augments
+                try {
+                    nextModule = allModulesIterator.next();
+                    resolveAugment(modules, nextModule);
+                } catch (NoSuchElementException e) {
+                    throw new YangParseException("Failed to resolve augments in module '" + module.getName() + "'.", e);
+                }
+                // then try to resolve first module again
+                resolveAugment(modules, module);
             }
         }
-        return null;
     }
 
     /**
-     * Pull restriction from referenced type and add them to given constraints
+     * Tries to resolve augments in given module. If augment target node is not
+     * found, do nothing.
      *
-     * @param referencedType
-     * @param constraints
+     * @param modules
+     *            all available modules
+     * @param module
+     *            current module
      */
-    private void mergeConstraints(final TypeDefinition<?> referencedType, final TypeConstraints constraints) {
+    private void resolveAugment(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+        if (module.getAugmentsResolved() < module.getAugments().size()) {
+            for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) {
+
+                if (!augmentBuilder.isResolved()) {
+                    final SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
+                    final List<QName> path = augmentTargetSchemaPath.getPath();
+
+                    final QName qname = path.get(0);
+                    String prefix = qname.getPrefix();
+                    if (prefix == null) {
+                        prefix = module.getPrefix();
+                    }
 
-        if (referencedType instanceof DecimalTypeDefinition) {
-            constraints.addRanges(((DecimalTypeDefinition) referencedType).getRangeStatements());
-            constraints.addFractionDigits(((DecimalTypeDefinition) referencedType).getFractionDigits());
-        } else if (referencedType instanceof IntegerTypeDefinition) {
-            constraints.addRanges(((IntegerTypeDefinition) referencedType).getRangeStatements());
-        } else if (referencedType instanceof StringTypeDefinition) {
-            constraints.addPatterns(((StringTypeDefinition) referencedType).getPatterns());
-            constraints.addLengths(((StringTypeDefinition) referencedType).getLengthStatements());
-        } else if (referencedType instanceof BinaryTypeDefinition) {
-            constraints.addLengths(((BinaryTypeDefinition) referencedType).getLengthConstraints());
+                    final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix,
+                            augmentBuilder.getLine());
+                    processAugmentation(augmentBuilder, path, module, qname, dependentModule);
+                }
+
+            }
         }
     }
 
     /**
-     * Go through all augment definitions and resolve them. This method also
-     * finds augment target node and add child nodes to it.
+     * Go through all augment definitions and resolve them. This method works in
+     * same way as {@link #resolveAugments(Map)} except that if target node is not
+     * found in loaded modules, it search for target node in given context.
      *
      * @param modules
-     *            all available modules
+     *            all loaded modules
+     * @param context
+     *            SchemaContext containing already resolved modules
      */
-    private void resolveAugments(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
+    private void resolveAugmentsWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final SchemaContext context) {
         final List<ModuleBuilder> allModulesList = new ArrayList<ModuleBuilder>();
         final Set<ModuleBuilder> allModulesSet = new HashSet<ModuleBuilder>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
@@ -527,7 +695,7 @@ public final class YangParserImpl implements YangModelParser {
         for (int i = 0; i < allModulesList.size(); i++) {
             final ModuleBuilder module = allModulesList.get(i);
             // try to resolve augments in module
-            resolveAugment(modules, module);
+            resolveAugmentWithContext(modules, module, context);
             // while all augments are not resolved
             final Iterator<ModuleBuilder> allModulesIterator = allModulesSet.iterator();
             while (!(module.getAugmentsResolved() == module.getAugments().size())) {
@@ -535,83 +703,50 @@ public final class YangParserImpl implements YangModelParser {
                 // try resolve other module augments
                 try {
                     nextModule = allModulesIterator.next();
-                    resolveAugment(modules, nextModule);
+                    resolveAugmentWithContext(modules, nextModule, context);
                 } catch (NoSuchElementException e) {
                     throw new YangParseException("Failed to resolve augments in module '" + module.getName() + "'.", e);
                 }
                 // then try to resolve first module again
-                resolveAugment(modules, module);
+                resolveAugmentWithContext(modules, module, context);
             }
         }
     }
 
     /**
+     * Tries to resolve augments in given module. If augment target node is not
+     * found, do nothing.
      *
      * @param modules
      *            all available modules
      * @param module
      *            current module
      */
-    private void resolveAugment(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+    private void resolveAugmentWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, final SchemaContext context) {
         if (module.getAugmentsResolved() < module.getAugments().size()) {
+
             for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) {
+                final int line = augmentBuilder.getLine();
 
                 if (!augmentBuilder.isResolved()) {
-                    final SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
-                    final List<QName> path = augmentTargetSchemaPath.getPath();
-
+                    final List<QName> path = augmentBuilder.getTargetPath().getPath();
                     final QName qname = path.get(0);
                     String prefix = qname.getPrefix();
                     if (prefix == null) {
                         prefix = module.getPrefix();
                     }
 
-                    DataSchemaNodeBuilder currentParent = null;
-                    final ModuleBuilder dependentModule = findDependentModule(modules, module, prefix,
-                            augmentBuilder.getLine());
-                    for (DataSchemaNodeBuilder child : dependentModule.getChildNodes()) {
-                        final QName childQName = child.getQName();
-                        if (childQName.getLocalName().equals(qname.getLocalName())) {
-                            currentParent = child;
-                            break;
-                        }
-                    }
-
-                    if (currentParent == null) {
+                    // try to find augment target module in loaded modules...
+                    final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix,
+                            line);
+                    if (dependentModuleBuilder == null) {
+                        // perform augmentation on module from context and
+                        // continue to next augment
+                        processAugmentationOnContext(augmentBuilder, path, module, prefix, line, context);
                         continue;
-                    }
-
-                    for (int i = 1; i < path.size(); i++) {
-                        final QName currentQName = path.get(i);
-                        DataSchemaNodeBuilder newParent = null;
-                        for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodes()) {
-                            final QName childQName = child.getQName();
-                            if (childQName.getLocalName().equals(currentQName.getLocalName())) {
-                                newParent = child;
-                                break;
-                            }
-                        }
-                        if (newParent == null) {
-                            break; // node not found, quit search
-                        } else {
-                            currentParent = newParent;
-                        }
-                    }
-
-                    final QName currentQName = currentParent.getQName();
-                    final QName lastAugmentPathElement = path.get(path.size() - 1);
-                    if (currentQName.getLocalName().equals(lastAugmentPathElement.getLocalName())) {
-
-                        if (currentParent instanceof ChoiceBuilder) {
-                            ParserUtils.fillAugmentTarget(augmentBuilder, (ChoiceBuilder) currentParent);
-                        } else {
-                            ParserUtils.fillAugmentTarget(augmentBuilder, (DataNodeContainerBuilder) currentParent);
-                        }
-                        ((AugmentationTargetBuilder) currentParent).addAugmentation(augmentBuilder);
-                        SchemaPath oldPath = currentParent.getPath();
-                        augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
-                        augmentBuilder.setResolved(true);
-                        module.augmentResolved();
+                    } else {
+                        processAugmentation(augmentBuilder, path, module, qname, dependentModuleBuilder);
                     }
                 }
 
@@ -643,7 +778,7 @@ public final class YangParserImpl implements YangModelParser {
                     baseIdentityPrefix = module.getPrefix();
                     baseIdentityLocalName = baseIdentityName;
                 }
-                final ModuleBuilder dependentModule = findDependentModule(modules, module, baseIdentityPrefix,
+                final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, baseIdentityPrefix,
                         identity.getLine());
 
                 final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule.getIdentities();
@@ -656,6 +791,59 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
+    /**
+     * Go through identity statements defined in current module and resolve
+     * their 'base' statement. Method tries to find base identity in given
+     * modules. If base identity is not found, method will search it in context.
+     *
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @param context
+     *            SchemaContext containing already resolved modules
+     */
+    private void resolveIdentitiesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, SchemaContext context) {
+        final Set<IdentitySchemaNodeBuilder> identities = module.getIdentities();
+        for (IdentitySchemaNodeBuilder identity : identities) {
+            final String baseIdentityName = identity.getBaseIdentityName();
+            if (baseIdentityName != null) {
+                String baseIdentityPrefix = null;
+                String baseIdentityLocalName = null;
+                if (baseIdentityName.contains(":")) {
+                    final String[] splitted = baseIdentityName.split(":");
+                    baseIdentityPrefix = splitted[0];
+                    baseIdentityLocalName = splitted[1];
+                } else {
+                    baseIdentityPrefix = module.getPrefix();
+                    baseIdentityLocalName = baseIdentityName;
+                }
+                final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module,
+                        baseIdentityPrefix, identity.getLine());
+
+                if (dependentModuleBuilder == null) {
+                    final Module dependentModule = findModuleFromContext(context, module, baseIdentityPrefix,
+                            identity.getLine());
+                    final Set<IdentitySchemaNode> dependentModuleIdentities = dependentModule.getIdentities();
+                    for (IdentitySchemaNode idNode : dependentModuleIdentities) {
+                        if (idNode.getQName().getLocalName().equals(baseIdentityLocalName)) {
+                            identity.setBaseIdentity(idNode);
+                        }
+                    }
+                } else {
+                    final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModuleBuilder
+                            .getIdentities();
+                    for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
+                        if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) {
+                            identity.setBaseIdentity(idBuilder);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Go through uses statements defined in current module and resolve their
      * refine statements.
@@ -665,56 +853,78 @@ public final class YangParserImpl implements YangModelParser {
      * @param module
      *            module being resolved
      */
-    private void resolveUsesRefines(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
+    private void resolveUsesRefine(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final Map<List<String>, UsesNodeBuilder> moduleUses = module.getUsesNodes();
         for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses.entrySet()) {
             final UsesNodeBuilder usesNode = entry.getValue();
             final int line = usesNode.getLine();
-
-            GroupingBuilder targetGrouping = getTargetGrouping(usesNode, modules, module);
+            final GroupingBuilder targetGrouping = getTargetGroupingFromModules(usesNode, modules, module);
             usesNode.setGroupingPath(targetGrouping.getPath());
-
             for (RefineHolder refine : usesNode.getRefines()) {
-                SchemaNodeBuilder refineTarget = getRefineNodeBuilderCopy(targetGrouping, refine, modules, module);
-                ParserUtils.checkRefine(refineTarget, refine);
-                ParserUtils.refineDefault(refineTarget, refine, line);
-                if (refineTarget instanceof LeafSchemaNodeBuilder) {
-                    final LeafSchemaNodeBuilder leaf = (LeafSchemaNodeBuilder) refineTarget;
-                    ParserUtils.refineLeaf(leaf, refine, line);
-                    usesNode.addRefineNode(leaf);
-                } else if (refineTarget instanceof ContainerSchemaNodeBuilder) {
-                    final ContainerSchemaNodeBuilder container = (ContainerSchemaNodeBuilder) refineTarget;
-                    ParserUtils.refineContainer(container, refine, line);
-                    usesNode.addRefineNode(container);
-                } else if (refineTarget instanceof ListSchemaNodeBuilder) {
-                    final ListSchemaNodeBuilder list = (ListSchemaNodeBuilder) refineTarget;
-                    ParserUtils.refineList(list, refine, line);
-                    usesNode.addRefineNode(list);
-                } else if (refineTarget instanceof LeafListSchemaNodeBuilder) {
-                    final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) refineTarget;
-                    ParserUtils.refineLeafList(leafList, refine, line);
-                    usesNode.addRefineNode(leafList);
-                } else if (refineTarget instanceof ChoiceBuilder) {
-                    final ChoiceBuilder choice = (ChoiceBuilder) refineTarget;
-                    ParserUtils.refineChoice(choice, refine, line);
-                    usesNode.addRefineNode(choice);
-                } else if (refineTarget instanceof AnyXmlBuilder) {
-                    final AnyXmlBuilder anyXml = (AnyXmlBuilder) refineTarget;
-                    ParserUtils.refineAnyxml(anyXml, refine, line);
-                    usesNode.addRefineNode(anyXml);
-                } else if (refineTarget instanceof GroupingBuilder) {
-                    usesNode.addRefineNode(refineTarget);
-                } else if (refineTarget instanceof TypeDefinitionBuilder) {
-                    usesNode.addRefineNode(refineTarget);
+                final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(targetGrouping,
+                        refine, module.getName());
+                RefineUtils.performRefine(nodeToRefine, refine, line);
+                usesNode.addRefineNode(nodeToRefine);
+            }
+        }
+    }
+
+    /**
+     * Tries to search target grouping in given modules and resolve refine
+     * nodes. If grouping is not found in modules, method tries to find it in
+     * modules from context.
+     *
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @param context
+     *            SchemaContext containing already resolved modules
+     */
+    private void resolveUsesRefineWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, SchemaContext context) {
+        final Map<List<String>, UsesNodeBuilder> moduleUses = module.getUsesNodes();
+        for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses.entrySet()) {
+            final UsesNodeBuilder usesNode = entry.getValue();
+            final int line = usesNode.getLine();
+
+            final GroupingBuilder targetGroupingBuilder = getTargetGroupingFromModules(usesNode, modules, module);
+            if (targetGroupingBuilder == null) {
+                final GroupingDefinition targetGrouping = getTargetGroupingFromContext(usesNode, module, context);
+                usesNode.setGroupingPath(targetGrouping.getPath());
+                for (RefineHolder refine : usesNode.getRefines()) {
+                    final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingDefinition(
+                            targetGrouping, refine, module.getName());
+                    RefineUtils.performRefine(nodeToRefine, refine, line);
+                    usesNode.addRefineNode(nodeToRefine);
+                }
+            } else {
+                usesNode.setGroupingPath(targetGroupingBuilder.getPath());
+                for (RefineHolder refine : usesNode.getRefines()) {
+                    final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(
+                            targetGroupingBuilder, refine, module.getName());
+                    RefineUtils.performRefine(nodeToRefine, refine, line);
+                    usesNode.addRefineNode(nodeToRefine);
                 }
             }
         }
     }
 
-    private GroupingBuilder getTargetGrouping(final UsesNodeBuilder usesBuilder,
+    /**
+     * Search given modules for grouping by name defined in uses node.
+     *
+     * @param usesBuilder
+     *            builder of uses statement
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @return grouping with given name if found, null otherwise
+     */
+    private GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final int line = usesBuilder.getLine();
-        String groupingString = usesBuilder.getGroupingName();
+        final String groupingString = usesBuilder.getGroupingName();
         String groupingPrefix;
         String groupingName;
 
@@ -734,13 +944,17 @@ public final class YangParserImpl implements YangModelParser {
         if (groupingPrefix.equals(module.getPrefix())) {
             dependentModule = module;
         } else {
-            dependentModule = findDependentModule(modules, module, groupingPrefix, line);
+            dependentModule = findDependentModuleBuilder(modules, module, groupingPrefix, line);
+        }
+
+        if (dependentModule == null) {
+            return null;
         }
 
         List<QName> path = usesBuilder.getPath().getPath();
         GroupingBuilder result = null;
         Set<GroupingBuilder> groupings = dependentModule.getModuleGroupings();
-        result = findGrouping(groupings, groupingName);
+        result = findGroupingBuilder(groupings, groupingName);
 
         if (result == null) {
             Builder currentNode = null;
@@ -760,111 +974,48 @@ public final class YangParserImpl implements YangModelParser {
                     groupings = Collections.emptySet();
                 }
 
-                result = findGrouping(groupings, groupingName);
+                result = findGroupingBuilder(groupings, groupingName);
                 if (result != null) {
                     break;
                 }
             }
         }
 
-        if (result != null) {
-            return result;
-        }
-        throw new YangParseException(module.getName(), line, "Referenced grouping '" + groupingName + "' not found.");
-    }
-
-    private GroupingBuilder findGrouping(Set<GroupingBuilder> groupings, String name) {
-        for (GroupingBuilder grouping : groupings) {
-            if (grouping.getQName().getLocalName().equals(name)) {
-                return grouping;
-            }
-        }
-        return null;
+        return result;
     }
 
     /**
-     * Find original builder of node to refine and return copy of this builder.
-     * <p>
-     * We must create and use a copy of builder to preserve original builder
-     * state, because this object will be refined (modified) and later added to
-     * {@link UsesNodeBuilder}.
-     * </p>
+     * Search context for grouping by name defined in uses node.
      *
-     * @param groupingPath
-     *            path to grouping which contains node to refine
-     * @param refine
-     *            refine object containing informations about refine
-     * @param modules
-     *            all loaded modules
+     * @param usesBuilder
+     *            builder of uses statement
      * @param module
      *            current module
-     * @return copy of node to be refined if it is present in grouping, null
-     *         otherwise
+     * @param context
+     *            SchemaContext containing already resolved modules
+     * @return grouping with given name if found, null otherwise
      */
-    private SchemaNodeBuilder getRefineNodeBuilderCopy(final GroupingBuilder targetGrouping, final RefineHolder refine,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        Builder result = null;
-        final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping, refine, modules, module);
-        if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) {
-            result = ParserUtils.copyLeafBuilder((LeafSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof ContainerSchemaNodeBuilder) {
-            result = ParserUtils.copyContainerBuilder((ContainerSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof ListSchemaNodeBuilder) {
-            result = ParserUtils.copyListBuilder((ListSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof LeafListSchemaNodeBuilder) {
-            result = ParserUtils.copyLeafListBuilder((LeafListSchemaNodeBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof ChoiceBuilder) {
-            result = ParserUtils.copyChoiceBuilder((ChoiceBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof AnyXmlBuilder) {
-            result = ParserUtils.copyAnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof GroupingBuilder) {
-            result = ParserUtils.copyGroupingBuilder((GroupingBuilder) lookedUpBuilder);
-        } else if (lookedUpBuilder instanceof TypeDefinitionBuilder) {
-            result = ParserUtils.copyTypedefBuilder((TypeDefinitionBuilderImpl) lookedUpBuilder);
-        } else {
-            throw new YangParseException(module.getName(), refine.getLine(), "Target '" + refine.getName()
-                    + "' can not be refined");
-        }
-        return (SchemaNodeBuilder) result;
-    }
+    private GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
+            final ModuleBuilder module, SchemaContext context) {
+        final int line = usesBuilder.getLine();
+        String groupingString = usesBuilder.getGroupingName();
+        String groupingPrefix;
+        String groupingName;
 
-    /**
-     * Find builder of refine node.
-     *
-     * @param groupingPath
-     *            path to grouping which contains node to refine
-     * @param refine
-     *            object containing refine information
-     * @param modules
-     *            all loaded modules
-     * @param module
-     *            current module
-     * @return Builder object of refine node if it is present in grouping, null
-     *         otherwise
-     */
-    private Builder findRefineTargetBuilder(final GroupingBuilder builder, final RefineHolder refine,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        final String refineNodeName = refine.getName();
-        Builder result = builder.getChildNode(refineNodeName);
-        if (result == null) {
-            Set<GroupingBuilder> grps = builder.getGroupings();
-            for (GroupingBuilder gr : grps) {
-                if (gr.getQName().getLocalName().equals(refineNodeName)) {
-                    result = gr;
-                    break;
-                }
-            }
-        }
-        if (result == null) {
-            Set<TypeDefinitionBuilder> typedefs = builder.getTypeDefinitions();
-            for (TypeDefinitionBuilder typedef : typedefs) {
-                if (typedef.getQName().getLocalName().equals(refineNodeName)) {
-                    result = typedef;
-                    break;
-                }
+        if (groupingString.contains(":")) {
+            String[] splitted = groupingString.split(":");
+            if (splitted.length != 2 || groupingString.contains("/")) {
+                throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
             }
+            groupingPrefix = splitted[0];
+            groupingName = splitted[1];
+        } else {
+            groupingPrefix = module.getPrefix();
+            groupingName = groupingString;
         }
-        return result;
+
+        Module dependentModule = findModuleFromContext(context, module, groupingPrefix, line);
+        return findGroupingDefinition(dependentModule.getGroupings(), groupingName);
     }
 
     private QName findFullQName(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
@@ -879,7 +1030,7 @@ public final class YangParserImpl implements YangModelParser {
             }
             String prefix = splittedBase[0];
             String name = splittedBase[1];
-            ModuleBuilder dependentModule = findDependentModule(modules, module, prefix, idref.getLine());
+            ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine());
             result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name);
         } else {
             result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString);
@@ -892,7 +1043,7 @@ public final class YangParserImpl implements YangModelParser {
             QName nodeType = usnb.getNodeType();
             if (nodeType.getNamespace() == null || nodeType.getRevision() == null) {
                 try {
-                    ModuleBuilder dependentModule = findDependentModule(modules, module, nodeType.getPrefix(),
+                    ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, nodeType.getPrefix(),
                             usnb.getLine());
                     QName newNodeType = new QName(dependentModule.getNamespace(), dependentModule.getRevision(),
                             nodeType.getPrefix(), nodeType.getLocalName());
@@ -904,51 +1055,33 @@ public final class YangParserImpl implements YangModelParser {
         }
     }
 
-    /**
-     * Find dependent module based on given prefix
-     *
-     * @param modules
-     *            all available modules
-     * @param module
-     *            current module
-     * @param prefix
-     *            target module prefix
-     * @param line
-     *            current line in yang model
-     * @return
-     */
-    private ModuleBuilder findDependentModule(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module, final String prefix, final int line) {
-        ModuleBuilder dependentModule = null;
-        Date dependentModuleRevision = null;
-
-        if (prefix.equals(module.getPrefix())) {
-            dependentModule = module;
-        } else {
-            final ModuleImport dependentModuleImport = ParserUtils.getModuleImport(module, prefix);
-            if (dependentModuleImport == null) {
-                throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
-            }
-            final String dependentModuleName = dependentModuleImport.getModuleName();
-            dependentModuleRevision = dependentModuleImport.getRevision();
+    private void resolveUnknownNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, SchemaContext context) {
+        for (UnknownSchemaNodeBuilder unknownNodeBuilder : module.getUnknownNodes()) {
+            QName nodeType = unknownNodeBuilder.getNodeType();
+            if (nodeType.getNamespace() == null || nodeType.getRevision() == null) {
+                try {
+                    ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module,
+                            nodeType.getPrefix(), unknownNodeBuilder.getLine());
+
+                    QName newNodeType = null;
+                    if (dependentModuleBuilder == null) {
+                        Module dependentModule = findModuleFromContext(context, module, nodeType.getPrefix(),
+                                unknownNodeBuilder.getLine());
+                        newNodeType = new QName(dependentModule.getNamespace(), dependentModule.getRevision(),
+                                nodeType.getPrefix(), nodeType.getLocalName());
+                    } else {
+                        newNodeType = new QName(dependentModuleBuilder.getNamespace(),
+                                dependentModuleBuilder.getRevision(), nodeType.getPrefix(), nodeType.getLocalName());
+                    }
 
-            final TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules.get(dependentModuleName);
-            if (moduleBuildersByRevision == null) {
-                throw new YangParseException(module.getName(), line, "Failed to find dependent module '"
-                        + dependentModuleName + "'.");
-            }
-            if (dependentModuleRevision == null) {
-                dependentModule = moduleBuildersByRevision.lastEntry().getValue();
-            } else {
-                dependentModule = moduleBuildersByRevision.get(dependentModuleRevision);
+                    unknownNodeBuilder.setNodeType(newNodeType);
+                } catch (YangParseException e) {
+                    logger.debug(module.getName(), unknownNodeBuilder.getLine(), "Failed to find unknown node type: "
+                            + nodeType);
+                }
             }
         }
-
-        if (dependentModule == null) {
-            throw new YangParseException(module.getName(), line, "Failed to find dependent module with prefix '"
-                    + prefix + "' and revision '" + dependentModuleRevision + "'.");
-        }
-        return dependentModule;
     }
 
 }
index 8cf9cea0cf65490b087b522771a563a10ed8afb5..5c42b290a02b88507d54bc1d113ecf8996300984 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.controller.yang.parser.util;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -15,6 +17,7 @@ import java.util.Set;
 
 import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.ModuleImport;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
 import org.opendaylight.controller.yang.parser.impl.YangParserListenerImpl;
 import org.opendaylight.controller.yang.parser.util.TopologicalSort.Node;
@@ -58,6 +61,26 @@ public final class ModuleDependencySort {
         });
     }
 
+    public static List<ModuleBuilder> sortWithContext(SchemaContext context, ModuleBuilder... builders) {
+        List<Object> modules = new ArrayList<Object>();
+        Collections.addAll(modules, builders);
+        modules.addAll(context.getModules());
+
+        List<Node> sorted = sortInternal(modules);
+        // Cast to ModuleBuilder from Node if possible and return
+        return Lists.transform(sorted, new Function<Node, ModuleBuilder>() {
+
+            @Override
+            public ModuleBuilder apply(Node input) {
+                if(((ModuleNodeImpl) input).getReference() instanceof ModuleBuilder) {
+                    return (ModuleBuilder) ((ModuleNodeImpl) input).getReference();
+                } else {
+                    return null;
+                }
+            }
+        });
+    }
+
     /**
      * Topological sort of module dependency graph.
      *
index d38bc5e7adf22f74f6678e9614d38e2872a8099d..ba3599ca97b8f86378162845684f3cb83da79c55 100644 (file)
@@ -7,14 +7,33 @@
  */
 package org.opendaylight.controller.yang.parser.util;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.controller.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.controller.yang.model.api.ChoiceNode;
+import org.opendaylight.controller.yang.model.api.ConstraintDefinition;
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.DataNodeContainer;
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
+import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;
+import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.ModuleImport;
 import org.opendaylight.controller.yang.model.api.MustDefinition;
+import org.opendaylight.controller.yang.model.api.NotificationDefinition;
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
+import org.opendaylight.controller.yang.model.api.SchemaNode;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
@@ -49,8 +68,14 @@ import org.opendaylight.controller.yang.model.util.Int64;
 import org.opendaylight.controller.yang.model.util.Int8;
 import org.opendaylight.controller.yang.model.util.Leafref;
 import org.opendaylight.controller.yang.model.util.StringType;
+import org.opendaylight.controller.yang.model.util.Uint16;
+import org.opendaylight.controller.yang.model.util.Uint32;
+import org.opendaylight.controller.yang.model.util.Uint64;
+import org.opendaylight.controller.yang.model.util.Uint8;
 import org.opendaylight.controller.yang.model.util.UnionType;
+import org.opendaylight.controller.yang.model.util.UnknownType;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.Builder;
 import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
@@ -61,15 +86,23 @@ import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder.ChoiceNodeImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder.ChoiceCaseNodeImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder.ListSchemaNodeImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.NotificationBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl;
+import org.opendaylight.controller.yang.parser.builder.impl.RpcDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
+import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.UsesNodeBuilderImpl;
 
@@ -80,15 +113,14 @@ public final class ParserUtils {
 
     /**
      * Get module import referenced by given prefix.
-     * 
+     *
      * @param builder
      *            module to search
      * @param prefix
      *            prefix associated with import
      * @return ModuleImport based on given prefix
      */
-    public static ModuleImport getModuleImport(final ModuleBuilder builder,
-            final String prefix) {
+    public static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) {
         ModuleImport moduleImport = null;
         for (ModuleImport mi : builder.getModuleImports()) {
             if (mi.getPrefix().equals(prefix)) {
@@ -99,9 +131,170 @@ public final class ParserUtils {
         return moduleImport;
     }
 
+    /**
+     * Find dependent module based on given prefix
+     *
+     * @param modules
+     *            all available modules
+     * @param module
+     *            current module
+     * @param prefix
+     *            target module prefix
+     * @param line
+     *            current line in yang model
+     * @return
+     */
+    public static ModuleBuilder findDependentModuleBuilder(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, final String prefix, final int line) {
+        ModuleBuilder dependentModule = null;
+        Date dependentModuleRevision = null;
+
+        if (prefix.equals(module.getPrefix())) {
+            dependentModule = module;
+        } else {
+            final ModuleImport dependentModuleImport = getModuleImport(module, prefix);
+            if (dependentModuleImport == null) {
+                throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
+            }
+            final String dependentModuleName = dependentModuleImport.getModuleName();
+            dependentModuleRevision = dependentModuleImport.getRevision();
+
+            final TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules.get(dependentModuleName);
+            if (moduleBuildersByRevision == null) {
+                return null;
+            }
+            if (dependentModuleRevision == null) {
+                dependentModule = moduleBuildersByRevision.lastEntry().getValue();
+            } else {
+                dependentModule = moduleBuildersByRevision.get(dependentModuleRevision);
+            }
+        }
+        return dependentModule;
+    }
+
+    /**
+     * Find module from context based on prefix.
+     *
+     * @param context
+     *            schema context
+     * @param currentModule
+     *            current module
+     * @param prefix
+     *            current prefix used to reference dependent module
+     * @param line
+     *            current line in yang model
+     * @return module based on given prefix if found in context, null otherwise
+     */
+    public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
+            final String prefix, final int line) {
+        TreeMap<Date, Module> modulesByRevision = new TreeMap<Date, Module>();
+
+        Date dependentModuleRevision = null;
+
+        final ModuleImport dependentModuleImport = ParserUtils.getModuleImport(currentModule, prefix);
+        if (dependentModuleImport == null) {
+            throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'.");
+        }
+        final String dependentModuleName = dependentModuleImport.getModuleName();
+        dependentModuleRevision = dependentModuleImport.getRevision();
+
+        for (Module contextModule : context.getModules()) {
+            if (contextModule.getName().equals(dependentModuleName)) {
+                Date revision = contextModule.getRevision();
+                if (revision == null) {
+                    revision = new Date(0L);
+                }
+                modulesByRevision.put(revision, contextModule);
+                break;
+            }
+        }
+
+        Module result = null;
+        if (dependentModuleRevision == null) {
+            result = modulesByRevision.get(modulesByRevision.firstKey());
+        } else {
+            result = modulesByRevision.get(dependentModuleRevision);
+        }
+
+        return result;
+    }
+
+    /**
+     * Find grouping by name.
+     *
+     * @param groupings
+     *            collection of grouping builders to search
+     * @param name
+     *            name of grouping
+     * @return grouping with given name if present in collection, null otherwise
+     */
+    public static GroupingBuilder findGroupingBuilder(Set<GroupingBuilder> groupings, String name) {
+        for (GroupingBuilder grouping : groupings) {
+            if (grouping.getQName().getLocalName().equals(name)) {
+                return grouping;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Find grouping by name.
+     *
+     * @param groupings
+     *            collection of grouping definitions to search
+     * @param name
+     *            name of grouping
+     * @return grouping with given name if present in collection, null otherwise
+     */
+    public static GroupingDefinition findGroupingDefinition(Set<GroupingDefinition> groupings, String name) {
+        for (GroupingDefinition grouping : groupings) {
+            if (grouping.getQName().getLocalName().equals(name)) {
+                return grouping;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Search types for type with given name.
+     *
+     * @param types
+     *            types to search
+     * @param name
+     *            name of type
+     * @return type with given name if present in collection, null otherwise
+     */
+    public static TypeDefinitionBuilder findTypedefBuilderByName(Set<TypeDefinitionBuilder> types, String name) {
+        for (TypeDefinitionBuilder td : types) {
+            if (td.getQName().getLocalName().equals(name)) {
+                return td;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Find type by name.
+     *
+     * @param types
+     *            collection of types
+     * @param typeName
+     *            type name
+     * @return type with given name if it is present in collection, null
+     *         otherwise
+     */
+    public static TypeDefinition<?> findTypeByName(Set<TypeDefinition<?>> types, String typeName) {
+        for (TypeDefinition<?> type : types) {
+            if (type.getQName().getLocalName().equals(typeName)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
     /**
      * Parse uses path.
-     * 
+     *
      * @param usesPath
      *            as String
      * @return SchemaPath from given String
@@ -117,8 +310,7 @@ public final class ParserUtils {
                 if (splittedElement.length == 1) {
                     name = new QName(null, null, null, splittedElement[0]);
                 } else {
-                    name = new QName(null, null, splittedElement[0],
-                            splittedElement[1]);
+                    name = new QName(null, null, splittedElement[0], splittedElement[1]);
                 }
                 path.add(name);
             }
@@ -126,15 +318,103 @@ public final class ParserUtils {
         return new SchemaPath(path, absolute);
     }
 
+    /**
+     * Pull restriction from type and add them to constraints.
+     *
+     * @param type
+     * @param constraints
+     */
+    public static void mergeConstraints(final TypeDefinition<?> type, final TypeConstraints constraints) {
+        if (type instanceof DecimalTypeDefinition) {
+            constraints.addRanges(((DecimalTypeDefinition) type).getRangeStatements());
+            constraints.addFractionDigits(((DecimalTypeDefinition) type).getFractionDigits());
+        } else if (type instanceof IntegerTypeDefinition) {
+            constraints.addRanges(((IntegerTypeDefinition) type).getRangeStatements());
+        } else if (type instanceof StringTypeDefinition) {
+            constraints.addPatterns(((StringTypeDefinition) type).getPatterns());
+            constraints.addLengths(((StringTypeDefinition) type).getLengthStatements());
+        } else if (type instanceof BinaryTypeDefinition) {
+            constraints.addLengths(((BinaryTypeDefinition) type).getLengthConstraints());
+        }
+    }
+
+    /**
+     * Find node in grouping by name.
+     *
+     * @param grouping
+     *            grouping to search
+     * @param refineNodeName
+     *            name of node
+     * @return builder of node with given name if present in grouping, null
+     *         otherwise
+     */
+    public static Builder findRefineTargetBuilder(final GroupingBuilder grouping, final String refineNodeName) {
+        // search child nodes
+        Builder result = grouping.getChildNode(refineNodeName);
+        // search groupings
+        if (result == null) {
+            Set<GroupingBuilder> grps = grouping.getGroupings();
+            for (GroupingBuilder gr : grps) {
+                if (gr.getQName().getLocalName().equals(refineNodeName)) {
+                    result = gr;
+                    break;
+                }
+            }
+        }
+        // search typedefs
+        if (result == null) {
+            Set<TypeDefinitionBuilder> typedefs = grouping.getTypeDefinitions();
+            for (TypeDefinitionBuilder typedef : typedefs) {
+                if (typedef.getQName().getLocalName().equals(refineNodeName)) {
+                    result = typedef;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Find node in grouping by name.
+     *
+     * @param builder
+     *            grouping to search
+     * @param refineNodeName
+     *            name of node
+     * @return node with given name if present in grouping, null otherwise
+     */
+    public static Object findRefineTargetNode(final GroupingDefinition builder, final String refineNodeName) {
+        Object result = builder.getDataChildByName(refineNodeName);
+        if (result == null) {
+            Set<GroupingDefinition> grps = builder.getGroupings();
+            for (GroupingDefinition gr : grps) {
+                if (gr.getQName().getLocalName().equals(refineNodeName)) {
+                    result = gr;
+                    break;
+                }
+            }
+        }
+        if (result == null) {
+            Set<TypeDefinition<?>> typedefs = builder.getTypeDefinitions();
+            for (TypeDefinition<?> typedef : typedefs) {
+                if (typedef.getQName().getLocalName().equals(refineNodeName)) {
+                    result = typedef;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
     /**
      * Add all augment's child nodes to given target.
-     * 
+     *
      * @param augment
+     *            builder of augment statement
      * @param target
+     *            augmentation target node
      */
-    public static void fillAugmentTarget(
-            final AugmentationSchemaBuilder augment,
-            final DataNodeContainerBuilder target) {
+    public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final DataNodeContainerBuilder target) {
         for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
             builder.setAugmenting(true);
             correctAugmentChildPath(builder, target.getPath());
@@ -142,8 +422,15 @@ public final class ParserUtils {
         }
     }
 
-    public static void fillAugmentTarget(
-            final AugmentationSchemaBuilder augment, final ChoiceBuilder target) {
+    /**
+     * Add all augment's child nodes to given target.
+     *
+     * @param augment
+     *            builder of augment statement
+     * @param target
+     *            augmentation target choice node
+     */
+    public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final ChoiceBuilder target) {
         for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
             builder.setAugmenting(true);
             correctAugmentChildPath(builder, target.getPath());
@@ -151,21 +438,16 @@ public final class ParserUtils {
         }
     }
 
-    private static void correctAugmentChildPath(
-            final DataSchemaNodeBuilder childNode,
-            final SchemaPath parentSchemaPath) {
-
+    private static void correctAugmentChildPath(final DataSchemaNodeBuilder childNode, final SchemaPath parentSchemaPath) {
         // set correct path
-        List<QName> targetNodePath = new ArrayList<QName>(
-                parentSchemaPath.getPath());
+        List<QName> targetNodePath = new ArrayList<QName>(parentSchemaPath.getPath());
         targetNodePath.add(childNode.getQName());
         childNode.setPath(new SchemaPath(targetNodePath, true));
 
         // set correct path for all child nodes
         if (childNode instanceof DataNodeContainerBuilder) {
             DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) childNode;
-            for (DataSchemaNodeBuilder child : dataNodeContainer
-                    .getChildNodes()) {
+            for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodes()) {
                 correctAugmentChildPath(child, childNode.getPath());
             }
         }
@@ -179,14 +461,13 @@ public final class ParserUtils {
 
     /**
      * Repair schema path of node type.
-     * 
+     *
      * @param node
      *            node which contains type statement
      * @param parentSchemaPath
      *            schema path of parent node
      */
-    private static void correctTypeAwareNodePath(
-            TypeAwareBuilder node, SchemaPath parentSchemaPath) {
+    private static void correctTypeAwareNodePath(final TypeAwareBuilder node, final SchemaPath parentSchemaPath) {
         final QName nodeBuilderQName = node.getQName();
         final TypeDefinition<?> nodeType = node.getType();
 
@@ -198,11 +479,7 @@ public final class ParserUtils {
         if (nodeType != null) {
             if (nodeType instanceof ExtendedType) {
                 ExtendedType et = (ExtendedType) nodeType;
-                if (nodeType
-                        .getQName()
-                        .getLocalName()
-                        .equals(nodeType.getBaseType().getQName()
-                                .getLocalName())) {
+                if (nodeType.getQName().getLocalName().equals(nodeType.getBaseType().getQName().getLocalName())) {
                     fd = et.getFractionDigits();
                     lengths = et.getLengths();
                     patterns = et.getPatterns();
@@ -212,8 +489,7 @@ public final class ParserUtils {
                     }
                 }
             }
-            TypeDefinition<?> newType = createCorrectTypeDefinition(
-                    parentSchemaPath, nodeBuilderQName, nodeType);
+            TypeDefinition<?> newType = createCorrectTypeDefinition(parentSchemaPath, nodeBuilderQName, nodeType);
             node.setType(newType);
         } else {
             TypeDefinitionBuilder nodeBuilderTypedef = node.getTypedef();
@@ -226,11 +502,9 @@ public final class ParserUtils {
             String tdbTypeName = nodeBuilderTypedef.getQName().getLocalName();
             String baseTypeName = null;
             if (nodeBuilderTypedef.getType() == null) {
-                baseTypeName = nodeBuilderTypedef.getTypedef().getQName()
-                        .getLocalName();
+                baseTypeName = nodeBuilderTypedef.getTypedef().getQName().getLocalName();
             } else {
-                baseTypeName = nodeBuilderTypedef.getType().getQName()
-                        .getLocalName();
+                baseTypeName = nodeBuilderTypedef.getType().getQName().getLocalName();
             }
             if (!(tdbTypeName.equals(baseTypeName))) {
                 return;
@@ -240,8 +514,7 @@ public final class ParserUtils {
                 return;
             }
 
-            SchemaPath newSchemaPath = createNewSchemaPath(
-                    nodeBuilderTypedef.getPath(), nodeBuilderQName,
+            SchemaPath newSchemaPath = createNewSchemaPath(nodeBuilderTypedef.getPath(), nodeBuilderQName,
                     nodeBuilderTypedef.getQName());
             nodeBuilderTypedef.setPath(newSchemaPath);
         }
@@ -249,7 +522,7 @@ public final class ParserUtils {
 
     /**
      * Check if there are some constraints.
-     * 
+     *
      * @param fd
      *            fraction digits
      * @param lengths
@@ -260,12 +533,9 @@ public final class ParserUtils {
      *            range constraints
      * @return true, if any of constraints are present, false otherwise
      */
-    private static boolean hasConstraints(final Integer fd,
-            final List<LengthConstraint> lengths,
-            final List<PatternConstraint> patterns,
-            final List<RangeConstraint> ranges) {
-        if (fd == null && (lengths == null || lengths.isEmpty())
-                && (patterns == null || patterns.isEmpty())
+    private static boolean hasConstraints(final Integer fd, final List<LengthConstraint> lengths,
+            final List<PatternConstraint> patterns, final List<RangeConstraint> ranges) {
+        if (fd == null && (lengths == null || lengths.isEmpty()) && (patterns == null || patterns.isEmpty())
                 && (ranges == null || ranges.isEmpty())) {
             return false;
         } else {
@@ -273,122 +543,106 @@ public final class ParserUtils {
         }
     }
 
-    private static TypeDefinition<?> createCorrectTypeDefinition(
-            SchemaPath parentSchemaPath, QName nodeQName,
+    private static TypeDefinition<?> createCorrectTypeDefinition(SchemaPath parentSchemaPath, QName nodeQName,
             TypeDefinition<?> nodeType) {
+        QName nodeTypeQName = nodeType.getQName();
+        SchemaPath newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeTypeQName);
         TypeDefinition<?> result = null;
-        SchemaPath newSchemaPath = null;
+
         if (nodeType != null) {
             if (nodeType instanceof BinaryTypeDefinition) {
                 BinaryTypeDefinition binType = (BinaryTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, binType.getQName());
-                List<Byte> bytes = (List<Byte>) binType.getDefaultValue();
+
+                // List<Byte> bytes = (List<Byte>) binType.getDefaultValue();
+                // workaround to get rid of 'Unchecked cast' warning
+                List<Byte> bytes = new ArrayList<Byte>();
+                Object defaultValue = binType.getDefaultValue();
+                if (defaultValue instanceof List) {
+                    for (Object o : List.class.cast(defaultValue)) {
+                        if (o instanceof Byte) {
+                            bytes.add((Byte) o);
+                        }
+                    }
+                }
                 result = new BinaryType(newSchemaPath, bytes);
             } else if (nodeType instanceof BitsTypeDefinition) {
                 BitsTypeDefinition bitsType = (BitsTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, nodeType.getQName());
                 result = new BitsType(newSchemaPath, bitsType.getBits());
             } else if (nodeType instanceof BooleanTypeDefinition) {
-                BooleanTypeDefinition booleanType = (BooleanTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, booleanType.getQName());
                 result = new BooleanType(newSchemaPath);
             } else if (nodeType instanceof DecimalTypeDefinition) {
                 DecimalTypeDefinition decimalType = (DecimalTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, decimalType.getQName());
-                result = new Decimal64(newSchemaPath,
-                        decimalType.getFractionDigits());
+                result = new Decimal64(newSchemaPath, decimalType.getFractionDigits());
             } else if (nodeType instanceof EmptyTypeDefinition) {
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, nodeType.getQName());
                 result = new EmptyType(newSchemaPath);
             } else if (nodeType instanceof EnumTypeDefinition) {
                 EnumTypeDefinition enumType = (EnumTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, enumType.getQName());
-                result = new EnumerationType(newSchemaPath,
-                        (EnumPair) enumType.getDefaultValue(),
-                        enumType.getValues());
+                result = new EnumerationType(newSchemaPath, (EnumPair) enumType.getDefaultValue(), enumType.getValues());
             } else if (nodeType instanceof IdentityrefTypeDefinition) {
                 IdentityrefTypeDefinition idrefType = (IdentityrefTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, idrefType.getQName());
-                result = new IdentityrefType(idrefType.getIdentity(),
-                        newSchemaPath);
+                result = new IdentityrefType(idrefType.getIdentity(), newSchemaPath);
             } else if (nodeType instanceof InstanceIdentifierTypeDefinition) {
                 InstanceIdentifierTypeDefinition instIdType = (InstanceIdentifierTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, instIdType.getQName());
-                return new InstanceIdentifier(newSchemaPath,
-                        instIdType.getPathStatement(),
+                return new InstanceIdentifier(newSchemaPath, instIdType.getPathStatement(),
                         instIdType.requireInstance());
             } else if (nodeType instanceof StringTypeDefinition) {
-                result = createNewStringType(parentSchemaPath, nodeQName,
-                        (StringTypeDefinition) nodeType);
+                result = createNewStringType(parentSchemaPath, nodeQName, (StringTypeDefinition) nodeType);
             } else if (nodeType instanceof IntegerTypeDefinition) {
-                result = createNewIntType(parentSchemaPath, nodeQName,
-                        (IntegerTypeDefinition) nodeType);
+                result = createNewIntType(parentSchemaPath, nodeQName, (IntegerTypeDefinition) nodeType);
             } else if (nodeType instanceof UnsignedIntegerTypeDefinition) {
-                result = createNewUintType(parentSchemaPath, nodeQName,
-                        (UnsignedIntegerTypeDefinition) nodeType);
+                result = createNewUintType(parentSchemaPath, nodeQName, (UnsignedIntegerTypeDefinition) nodeType);
             } else if (nodeType instanceof LeafrefTypeDefinition) {
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, nodeType.getQName());
-                result = new Leafref(newSchemaPath,
-                        ((LeafrefTypeDefinition) nodeType).getPathStatement());
+                result = new Leafref(newSchemaPath, ((LeafrefTypeDefinition) nodeType).getPathStatement());
             } else if (nodeType instanceof UnionTypeDefinition) {
                 UnionTypeDefinition unionType = (UnionTypeDefinition) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, unionType.getQName());
                 return new UnionType(newSchemaPath, unionType.getTypes());
             } else if (nodeType instanceof ExtendedType) {
                 ExtendedType extType = (ExtendedType) nodeType;
-                newSchemaPath = createNewSchemaPath(parentSchemaPath,
-                        nodeQName, extType.getQName());
-                result = createNewExtendedType(newSchemaPath, extType);
+                result = createNewExtendedType(extType, newSchemaPath);
             }
         }
         return result;
     }
 
-    private static TypeDefinition<?> createNewExtendedType(
-            SchemaPath newSchemaPath, ExtendedType oldExtendedType) {
-        QName qname = oldExtendedType.getQName();
-        TypeDefinition<?> baseType = oldExtendedType.getBaseType();
-        String desc = oldExtendedType.getDescription();
-        String ref = oldExtendedType.getReference();
-        ExtendedType.Builder builder = new ExtendedType.Builder(qname,
-                baseType, desc, ref, newSchemaPath);
-        builder.status(oldExtendedType.getStatus());
-        builder.lengths(oldExtendedType.getLengths());
-        builder.patterns(oldExtendedType.getPatterns());
-        builder.ranges(oldExtendedType.getRanges());
-        builder.fractionDigits(oldExtendedType.getFractionDigits());
-        builder.unknownSchemaNodes(oldExtendedType.getUnknownSchemaNodes());
+    /**
+     * Create new ExtendedType based on given type and with schema path.
+     *
+     * @param newPath
+     *            schema path for new type
+     * @param oldType
+     *            type based
+     * @return
+     */
+    private static ExtendedType createNewExtendedType(final ExtendedType oldType, final SchemaPath newPath) {
+        QName qname = oldType.getQName();
+        TypeDefinition<?> baseType = oldType.getBaseType();
+        String desc = oldType.getDescription();
+        String ref = oldType.getReference();
+        ExtendedType.Builder builder = new ExtendedType.Builder(qname, baseType, desc, ref, newPath);
+        builder.status(oldType.getStatus());
+        builder.lengths(oldType.getLengths());
+        builder.patterns(oldType.getPatterns());
+        builder.ranges(oldType.getRanges());
+        builder.fractionDigits(oldType.getFractionDigits());
+        builder.unknownSchemaNodes(oldType.getUnknownSchemaNodes());
         return builder.build();
     }
 
-    private static TypeDefinition<?> createNewStringType(SchemaPath schemaPath,
-            QName nodeQName, StringTypeDefinition nodeType) {
-        List<QName> path = schemaPath.getPath();
-        List<QName> newPath = new ArrayList<QName>(path);
+    private static StringTypeDefinition createNewStringType(final SchemaPath schemaPath, final QName nodeQName,
+            final StringTypeDefinition nodeType) {
+        final List<QName> path = schemaPath.getPath();
+        final List<QName> newPath = new ArrayList<QName>(path);
         newPath.add(nodeQName);
         newPath.add(nodeType.getQName());
-        SchemaPath newSchemaPath = new SchemaPath(newPath,
-                schemaPath.isAbsolute());
-
+        final SchemaPath newSchemaPath = new SchemaPath(newPath, schemaPath.isAbsolute());
         return new StringType(newSchemaPath);
     }
 
-    private static TypeDefinition<?> createNewIntType(SchemaPath schemaPath,
-            QName nodeQName, IntegerTypeDefinition type) {
-        QName typeQName = type.getQName();
-        SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName,
-                typeQName);
-        String localName = typeQName.getLocalName();
+    private static IntegerTypeDefinition createNewIntType(final SchemaPath schemaPath, final QName nodeQName,
+            final IntegerTypeDefinition type) {
+        final QName typeQName = type.getQName();
+        final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
+        final String localName = typeQName.getLocalName();
 
         if ("int8".equals(localName)) {
             return new Int8(newSchemaPath);
@@ -403,335 +657,55 @@ public final class ParserUtils {
         }
     }
 
-    private static TypeDefinition<?> createNewUintType(SchemaPath schemaPath,
-            QName nodeQName, UnsignedIntegerTypeDefinition type) {
-        QName typeQName = type.getQName();
-        SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName,
-                typeQName);
-        String localName = typeQName.getLocalName();
+    private static UnsignedIntegerTypeDefinition createNewUintType(final SchemaPath schemaPath, final QName nodeQName,
+            final UnsignedIntegerTypeDefinition type) {
+        final QName typeQName = type.getQName();
+        final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName);
+        final String localName = typeQName.getLocalName();
 
         if ("uint8".equals(localName)) {
-            return new Int8(newSchemaPath);
+            return new Uint8(newSchemaPath);
         } else if ("uint16".equals(localName)) {
-            return new Int16(newSchemaPath);
+            return new Uint16(newSchemaPath);
         } else if ("uint32".equals(localName)) {
-            return new Int32(newSchemaPath);
+            return new Uint32(newSchemaPath);
         } else if ("uint64".equals(localName)) {
-            return new Int64(newSchemaPath);
+            return new Uint64(newSchemaPath);
         } else {
             return null;
         }
     }
 
-    private static SchemaPath createNewSchemaPath(SchemaPath schemaPath,
-            QName currentQName, QName qname) {
+    private static SchemaPath createNewSchemaPath(final SchemaPath schemaPath, final QName currentQName,
+            final QName qname) {
         List<QName> newPath = new ArrayList<QName>(schemaPath.getPath());
         newPath.add(currentQName);
         newPath.add(qname);
         return new SchemaPath(newPath, schemaPath.isAbsolute());
     }
 
-    public static void refineLeaf(LeafSchemaNodeBuilder leaf,
-            RefineHolder refine, int line) {
-        String defaultStr = refine.getDefaultStr();
-        Boolean mandatory = refine.isMandatory();
-        MustDefinition must = refine.getMust();
-        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
-
-        if (defaultStr != null && !("".equals(defaultStr))) {
-            leaf.setDefaultStr(defaultStr);
-        }
-        if (mandatory != null) {
-            leaf.getConstraints().setMandatory(mandatory);
-        }
-        if (must != null) {
-            leaf.getConstraints().addMustDefinition(must);
-        }
-        if (unknownNodes != null) {
-            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                leaf.addUnknownSchemaNode(unknown);
-            }
-        }
-    }
-
-    public static void refineContainer(ContainerSchemaNodeBuilder container,
-            RefineHolder refine, int line) {
-        Boolean presence = refine.isPresence();
-        MustDefinition must = refine.getMust();
-        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
-
-        if (presence != null) {
-            container.setPresence(presence);
-        }
-        if (must != null) {
-            container.getConstraints().addMustDefinition(must);
-        }
-        if (unknownNodes != null) {
-            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                container.addUnknownSchemaNode(unknown);
-            }
-        }
-    }
-
-    public static void refineList(ListSchemaNodeBuilder list,
-            RefineHolder refine, int line) {
-        MustDefinition must = refine.getMust();
-        Integer min = refine.getMinElements();
-        Integer max = refine.getMaxElements();
-        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
-
-        if (must != null) {
-            list.getConstraints().addMustDefinition(must);
-        }
-        if (min != null) {
-            list.getConstraints().setMinElements(min);
-        }
-        if (max != null) {
-            list.getConstraints().setMaxElements(max);
-        }
-        if (unknownNodes != null) {
-            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                list.addUnknownSchemaNode(unknown);
-            }
-        }
-    }
-
-    public static void refineLeafList(LeafListSchemaNodeBuilder leafList,
-            RefineHolder refine, int line) {
-        MustDefinition must = refine.getMust();
-        Integer min = refine.getMinElements();
-        Integer max = refine.getMaxElements();
-        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
-
-        if (must != null) {
-            leafList.getConstraints().addMustDefinition(must);
-        }
-        if (min != null) {
-            leafList.getConstraints().setMinElements(min);
-        }
-        if (max != null) {
-            leafList.getConstraints().setMaxElements(max);
-        }
-        if (unknownNodes != null) {
-            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                leafList.addUnknownSchemaNode(unknown);
-            }
-        }
-    }
-
-    public static void refineChoice(ChoiceBuilder choice, RefineHolder refine,
-            int line) {
-        String defaultStr = refine.getDefaultStr();
-        Boolean mandatory = refine.isMandatory();
-        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
-
-        if (defaultStr != null) {
-            choice.setDefaultCase(defaultStr);
-        }
-        if (mandatory != null) {
-            choice.getConstraints().setMandatory(mandatory);
-        }
-        if (unknownNodes != null) {
-            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                choice.addUnknownSchemaNode(unknown);
-            }
-        }
-    }
-
-    public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine,
-            int line) {
-        Boolean mandatory = refine.isMandatory();
-        MustDefinition must = refine.getMust();
-        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
-
-        if (mandatory != null) {
-            anyXml.getConstraints().setMandatory(mandatory);
-        }
-        if (must != null) {
-            anyXml.getConstraints().addMustDefinition(must);
-        }
-        if (unknownNodes != null) {
-            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                anyXml.addUnknownSchemaNode(unknown);
-            }
-        }
-    }
-
-    public static void checkRefine(SchemaNodeBuilder node, RefineHolder refine) {
-        String name = node.getQName().getLocalName();
-        int line = refine.getLine();
-
-        String defaultStr = refine.getDefaultStr();
-        Boolean mandatory = refine.isMandatory();
-        Boolean presence = refine.isPresence();
-        MustDefinition must = refine.getMust();
-        Integer min = refine.getMinElements();
-        Integer max = refine.getMaxElements();
-
-        if (node instanceof AnyXmlBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefinePresence(node, presence, line);
-            checkRefineMinMax(name, line, min, max);
-        } else if (node instanceof ChoiceBuilder) {
-            checkRefinePresence(node, presence, line);
-            checkRefineMust(node, must, line);
-            checkRefineMinMax(name, line, min, max);
-        } else if (node instanceof ContainerSchemaNodeBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefineMandatory(node, mandatory, line);
-            checkRefineMust(node, must, line);
-            checkRefineMinMax(name, line, min, max);
-        } else if (node instanceof LeafSchemaNodeBuilder) {
-            checkRefinePresence(node, presence, line);
-            checkRefineMinMax(name, line, min, max);
-        } else if (node instanceof LeafListSchemaNodeBuilder
-                || node instanceof ListSchemaNodeBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefinePresence(node, presence, line);
-            checkRefineMandatory(node, mandatory, line);
-        } else if (node instanceof GroupingBuilder
-                || node instanceof TypeDefinitionBuilder
-                || node instanceof UsesNodeBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefinePresence(node, presence, line);
-            checkRefineMandatory(node, mandatory, line);
-            checkRefineMust(node, must, line);
-            checkRefineMinMax(name, line, min, max);
-        }
-    }
-
-    private static void checkRefineDefault(SchemaNodeBuilder node,
-            String defaultStr, int line) {
-        if (defaultStr != null) {
-            throw new YangParseException(line, "Can not refine 'default' for '"
-                    + node.getQName().getLocalName() + "'.");
-        }
-    }
-
-    private static void checkRefineMandatory(SchemaNodeBuilder node,
-            Boolean mandatory, int line) {
-        if (mandatory != null) {
-            throw new YangParseException(line,
-                    "Can not refine 'mandatory' for '"
-                            + node.getQName().getLocalName() + "'.");
-        }
-    }
-
-    private static void checkRefinePresence(SchemaNodeBuilder node,
-            Boolean presence, int line) {
-        if (presence != null) {
-            throw new YangParseException(line,
-                    "Can not refine 'presence' for '"
-                            + node.getQName().getLocalName() + "'.");
-        }
-    }
-
-    private static void checkRefineMust(SchemaNodeBuilder node,
-            MustDefinition must, int line) {
-        if (must != null) {
-            throw new YangParseException(line, "Can not refine 'must' for '"
-                    + node.getQName().getLocalName() + "'.");
-        }
-    }
-
-    private static void checkRefineMinMax(String refineTargetName,
-            int refineLine, Integer min, Integer max) {
-        if (min != null || max != null) {
-            throw new YangParseException(refineLine,
-                    "Can not refine 'min-elements' or 'max-elements' for '"
-                            + refineTargetName + "'.");
-        }
-    }
-
-    /**
-     * Perform refine operation of following parameters:
-     * <ul>
-     * <li>description</li>
-     * <li>reference</li>
-     * <li>config</li>
-     * </ul>
-     * 
-     * These parameters may be refined for any node.
-     * 
-     * @param node
-     *            node to refine
-     * @param refine
-     *            refine holder containing values to refine
-     * @param line
-     *            current line in yang model
-     */
-    public static void refineDefault(Builder node, RefineHolder refine, int line) {
-        Class<? extends Builder> cls = node.getClass();
-
-        String description = refine.getDescription();
-        if (description != null) {
-            try {
-                Method method = cls.getDeclaredMethod("setDescription",
-                        String.class);
-                method.invoke(node, description);
-            } catch (Exception e) {
-                throw new YangParseException(line,
-                        "Cannot refine description in " + cls.getName(), e);
-            }
-        }
-
-        String reference = refine.getReference();
-        if (reference != null) {
-            try {
-                Method method = cls.getDeclaredMethod("setReference",
-                        String.class);
-                method.invoke(node, reference);
-            } catch (Exception e) {
-                throw new YangParseException(line,
-                        "Cannot refine reference in " + cls.getName(), e);
-            }
-        }
-
-        Boolean config = refine.isConfig();
-        if (config != null) {
-            try {
-                Method method = cls.getDeclaredMethod("setConfiguration",
-                        Boolean.TYPE);
-                method.invoke(node, config);
-            } catch (Exception e) {
-                throw new YangParseException(line, "Cannot refine config in "
-                        + cls.getName(), e);
-            }
-        }
-    }
-
-    public static LeafSchemaNodeBuilder copyLeafBuilder(
-            final LeafSchemaNodeBuilder old) {
-        final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(
-                old.getQName(), old.getLine());
+    public static LeafSchemaNodeBuilder copyLeafBuilder(final LeafSchemaNodeBuilder old) {
+        final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(old.getQName(), old.getLine());
         final TypeDefinition<?> type = old.getType();
-
         if (type == null) {
             copy.setTypedef(old.getTypedef());
         } else {
             copy.setType(type);
         }
-        copy.setPath(old.getPath());
-        copyConstraints(old, copy);
+        copyDataSchemaNodeArgs(old, copy);
+        copyConstraintsFromBuilder(old, copy);
         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
             copy.addUnknownSchemaNode(unknown);
         }
-        copy.setDescription(old.getDescription());
-        copy.setReference(old.getReference());
-        copy.setStatus(old.getStatus());
-        copy.setAugmenting(old.isAugmenting());
-        copy.setConfiguration(old.isConfiguration());
         copy.setDefaultStr(old.getDefaultStr());
         copy.setUnits(old.getUnits());
         return copy;
     }
 
-    public static ContainerSchemaNodeBuilder copyContainerBuilder(
-            final ContainerSchemaNodeBuilder old) {
-        final ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(
-                old.getQName(), old.getLine());
-        copy.setPath(old.getPath());
-        copyConstraints(old, copy);
+    public static ContainerSchemaNodeBuilder copyContainerBuilder(final ContainerSchemaNodeBuilder old) {
+        final ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(old.getQName(), old.getLine());
+        copyDataSchemaNodeArgs(old, copy);
+        copyConstraintsFromBuilder(old, copy);
         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
             copy.addUnknownSchemaNode(unknown);
         }
@@ -750,21 +724,14 @@ public final class ParserUtils {
         for (UsesNodeBuilder use : old.getUsesNodes()) {
             copy.addUsesNode(use);
         }
-        copy.setDescription(old.getDescription());
-        copy.setReference(old.getReference());
-        copy.setStatus(old.getStatus());
-        copy.setAugmenting(old.isAugmenting());
-        copy.setConfiguration(old.isConfiguration());
         copy.setPresence(old.isPresence());
         return copy;
     }
 
-    public static ListSchemaNodeBuilder copyListBuilder(
-            final ListSchemaNodeBuilder old) {
-        final ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(
-                old.getQName(), old.getLine());
-        copy.setPath(old.getPath());
-        copyConstraints(old, copy);
+    public static ListSchemaNodeBuilder copyListBuilder(final ListSchemaNodeBuilder old) {
+        final ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(old.getQName(), old.getLine());
+        copyDataSchemaNodeArgs(old, copy);
+        copyConstraintsFromBuilder(old, copy);
         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
             copy.addUnknownSchemaNode(unknown);
         }
@@ -783,21 +750,14 @@ public final class ParserUtils {
         for (UsesNodeBuilder use : old.getUsesNodes()) {
             copy.addUsesNode(use);
         }
-        copy.setDescription(old.getDescription());
-        copy.setReference(old.getReference());
-        copy.setStatus(old.getStatus());
-        copy.setAugmenting(old.isAugmenting());
-        copy.setConfiguration(old.isConfiguration());
         copy.setUserOrdered(old.isUserOrdered());
         return copy;
     }
 
-    public static LeafListSchemaNodeBuilder copyLeafListBuilder(
-            final LeafListSchemaNodeBuilder old) {
-        final LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(
-                old.getQName(), old.getLine());
-        copy.setPath(old.getPath());
-        copyConstraints(old, copy);
+    public static LeafListSchemaNodeBuilder copyLeafListBuilder(final LeafListSchemaNodeBuilder old) {
+        final LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(old.getQName(), old.getLine());
+        copyDataSchemaNodeArgs(old, copy);
+        copyConstraintsFromBuilder(old, copy);
         final TypeDefinition<?> type = old.getType();
         if (type == null) {
             copy.setTypedef(old.getTypedef());
@@ -807,20 +767,14 @@ public final class ParserUtils {
         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
             copy.addUnknownSchemaNode(unknown);
         }
-        copy.setDescription(old.getDescription());
-        copy.setReference(old.getReference());
-        copy.setStatus(old.getStatus());
-        copy.setAugmenting(old.isAugmenting());
-        copy.setConfiguration(old.isConfiguration());
         copy.setUserOrdered(old.isUserOrdered());
         return copy;
     }
 
     public static ChoiceBuilder copyChoiceBuilder(final ChoiceBuilder old) {
-        final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(),
-                old.getLine());
-        copy.setPath(old.getPath());
-        copyConstraints(old, copy);
+        final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(), old.getLine());
+        copyDataSchemaNodeArgs(old, copy);
+        copyConstraintsFromBuilder(old, copy);
         for (ChoiceCaseBuilder caseBuilder : old.getCases()) {
             copy.addChildNode(caseBuilder);
         }
@@ -828,32 +782,21 @@ public final class ParserUtils {
             copy.addUnknownSchemaNode(unknown);
         }
         copy.setDefaultCase(old.getDefaultCase());
-        copy.setDescription(old.getDescription());
-        copy.setReference(old.getReference());
-        copy.setStatus(old.getStatus());
-        copy.setAugmenting(old.isAugmenting());
-        copy.setConfiguration(old.isConfiguration());
         return copy;
     }
 
     public static AnyXmlBuilder copyAnyXmlBuilder(final AnyXmlBuilder old) {
-        final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(),
-                old.getLine());
-        copy.setPath(old.getPath());
-        copyConstraints(old, copy);
+        final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(), old.getLine());
+        copyDataSchemaNodeArgs(old, copy);
+        copyConstraintsFromBuilder(old, copy);
         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
             copy.addUnknownSchemaNode(unknown);
         }
-        copy.setDescription(old.getDescription());
-        copy.setReference(old.getReference());
-        copy.setStatus(old.getStatus());
-        copy.setConfiguration(old.isConfiguration());
         return copy;
     }
 
     public static GroupingBuilder copyGroupingBuilder(final GroupingBuilder old) {
-        final GroupingBuilder copy = new GroupingBuilderImpl(old.getQName(),
-                old.getLine());
+        final GroupingBuilder copy = new GroupingBuilderImpl(old.getQName(), old.getLine());
         copy.setPath(old.getPath());
         for (DataSchemaNodeBuilder child : old.getChildNodes()) {
             copy.addChildNode(child);
@@ -876,10 +819,8 @@ public final class ParserUtils {
         return copy;
     }
 
-    public static TypeDefinitionBuilderImpl copyTypedefBuilder(
-            TypeDefinitionBuilderImpl old) {
-        final TypeDefinitionBuilderImpl copy = new TypeDefinitionBuilderImpl(
-                old.getQName(), old.getLine());
+    public static TypeDefinitionBuilderImpl copyTypedefBuilder(final TypeDefinitionBuilderImpl old) {
+        final TypeDefinitionBuilderImpl copy = new TypeDefinitionBuilderImpl(old.getQName(), old.getLine());
         copy.setPath(old.getPath());
         copy.setDefaultValue(old.getDefaultValue());
         copy.setUnits(old.getUnits());
@@ -905,9 +846,8 @@ public final class ParserUtils {
         return copy;
     }
 
-    public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) {
-        final UsesNodeBuilder copy = new UsesNodeBuilderImpl(
-                old.getGroupingName(), old.getLine());
+    public static UsesNodeBuilder copyUsesNodeBuilder(final UsesNodeBuilder old) {
+        final UsesNodeBuilder copy = new UsesNodeBuilderImpl(old.getGroupingName(), old.getLine());
         for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
             copy.addAugment(augment);
         }
@@ -918,7 +858,25 @@ public final class ParserUtils {
         return copy;
     }
 
-    private static void copyConstraints(final DataSchemaNodeBuilder oldBuilder,
+    private static void copyDataSchemaNodeArgs(final DataSchemaNodeBuilder oldBuilder,
+            final DataSchemaNodeBuilder newBuilder) {
+        newBuilder.setPath(oldBuilder.getPath());
+        newBuilder.setDescription(oldBuilder.getDescription());
+        newBuilder.setReference(oldBuilder.getReference());
+        newBuilder.setStatus(oldBuilder.getStatus());
+        newBuilder.setAugmenting(oldBuilder.isAugmenting());
+        if (!(oldBuilder instanceof ChoiceCaseNode)) {
+            newBuilder.setConfiguration(oldBuilder.isConfiguration());
+        }
+    }
+
+    /**
+     * Copy constraints from old builder to new builder.
+     *
+     * @param oldBuilder
+     * @param newBuilder
+     */
+    private static void copyConstraintsFromBuilder(final DataSchemaNodeBuilder oldBuilder,
             final DataSchemaNodeBuilder newBuilder) {
         final ConstraintsBuilder oldConstraints = oldBuilder.getConstraints();
         final ConstraintsBuilder newConstraints = newBuilder.getConstraints();
@@ -931,4 +889,528 @@ public final class ParserUtils {
         newConstraints.setMaxElements(oldConstraints.getMaxElements());
     }
 
+    /**
+     * Create LeafSchemaNodeBuilder from given LeafSchemaNode.
+     *
+     * @param leaf
+     *            leaf from which to create builder
+     * @param line
+     *            line in module
+     * @return builder object from leaf
+     */
+    public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, int line) {
+        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(leaf.getQName(), line);
+        convertDataSchemaNode(leaf, builder);
+        final TypeDefinition<?> type = leaf.getType();
+        builder.setType(type);
+        builder.setPath(leaf.getPath());
+        builder.setUnknownNodes(leaf.getUnknownSchemaNodes());
+        builder.setDefaultStr(leaf.getDefault());
+        builder.setUnits(leaf.getUnits());
+        return builder;
+    }
+
+    public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, int line) {
+        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(container.getQName(), line);
+        convertDataSchemaNode(container, builder);
+        builder.setUnknownNodes(container.getUnknownSchemaNodes());
+        builder.setChildNodes(container.getChildNodes());
+        builder.setGroupings(container.getGroupings());
+        builder.setTypedefs(container.getTypeDefinitions());
+        builder.setAugmentations(container.getAvailableAugmentations());
+        builder.setUsesnodes(container.getUses());
+        builder.setPresence(container.isPresenceContainer());
+        return builder;
+    }
+
+    public static ListSchemaNodeBuilder createList(ListSchemaNode list, int line) {
+        ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(list.getQName(), line);
+        convertDataSchemaNode(list, builder);
+        builder.setUnknownNodes(list.getUnknownSchemaNodes());
+        builder.setTypedefs(list.getTypeDefinitions());
+        builder.setChildNodes(list.getChildNodes());
+        builder.setGroupings(list.getGroupings());
+        builder.setAugmentations(list.getAvailableAugmentations());
+        builder.setUsesnodes(list.getUses());
+        builder.setUserOrdered(builder.isUserOrdered());
+        return builder;
+    }
+
+    public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, int line) {
+        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(leafList.getQName(), line);
+        convertDataSchemaNode(leafList, builder);
+        builder.setType(leafList.getType());
+        builder.setUnknownNodes(leafList.getUnknownSchemaNodes());
+        builder.setUserOrdered(leafList.isUserOrdered());
+        return builder;
+    }
+
+    public static ChoiceBuilder createChoice(ChoiceNode choice, int line) {
+        final ChoiceBuilder builder = new ChoiceBuilder(choice.getQName(), line);
+        convertDataSchemaNode(choice, builder);
+        builder.setCases(choice.getCases());
+        builder.setUnknownNodes(choice.getUnknownSchemaNodes());
+        builder.setDefaultCase(choice.getDefaultCase());
+        return builder;
+    }
+
+    public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, int line) {
+        final AnyXmlBuilder builder = new AnyXmlBuilder(anyxml.getQName(), line);
+        convertDataSchemaNode(anyxml, builder);
+        builder.setUnknownNodes(anyxml.getUnknownSchemaNodes());
+        return builder;
+    }
+
+    public static GroupingBuilder createGrouping(GroupingDefinition grouping, int line) {
+        final GroupingBuilderImpl builder = new GroupingBuilderImpl(grouping.getQName(), line);
+        builder.setPath(grouping.getPath());
+        builder.setChildNodes(grouping.getChildNodes());
+        builder.setGroupings(grouping.getGroupings());
+        builder.setTypedefs(grouping.getTypeDefinitions());
+        builder.setUsesnodes(grouping.getUses());
+        builder.setUnknownNodes(grouping.getUnknownSchemaNodes());
+        builder.setDescription(grouping.getDescription());
+        builder.setReference(grouping.getReference());
+        builder.setStatus(grouping.getStatus());
+        return builder;
+    }
+
+    public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, int line) {
+        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typedef.getQName(), line);
+        builder.setPath(typedef.getPath());
+        builder.setDefaultValue(typedef.getDefaultValue());
+        builder.setUnits(typedef.getUnits());
+        builder.setDescription(typedef.getDescription());
+        builder.setReference(typedef.getReference());
+        builder.setStatus(typedef.getStatus());
+        builder.setRanges(typedef.getRanges());
+        builder.setLengths(typedef.getLengths());
+        builder.setPatterns(typedef.getPatterns());
+        builder.setFractionDigits(typedef.getFractionDigits());
+        final TypeDefinition<?> type = typedef.getBaseType();
+        builder.setType(type);
+        builder.setUnits(typedef.getUnits());
+        builder.setUnknownNodes(typedef.getUnknownSchemaNodes());
+        return builder;
+    }
+
+    /**
+     * Set DataSchemaNode arguments to builder object
+     *
+     * @param node
+     *            node from which arguments should be read
+     * @param builder
+     *            builder to which arguments should be set
+     */
+    private static void convertDataSchemaNode(DataSchemaNode node, DataSchemaNodeBuilder builder) {
+        builder.setPath(node.getPath());
+        builder.setDescription(node.getDescription());
+        builder.setReference(node.getReference());
+        builder.setStatus(node.getStatus());
+        builder.setAugmenting(node.isAugmenting());
+        if (!(node instanceof ChoiceCaseNode)) {
+            builder.setConfiguration(node.isConfiguration());
+        }
+        copyConstraintsFromDefinition(node.getConstraints(), builder.getConstraints());
+    }
+
+    /**
+     * Copy constraints from constraints definition to constraints builder.
+     *
+     * @param nodeConstraints
+     *            definition from which constraints will be copied
+     * @param constraints
+     *            builder to which constraints will be added
+     */
+    private static void copyConstraintsFromDefinition(final ConstraintDefinition nodeConstraints,
+            final ConstraintsBuilder constraints) {
+        final RevisionAwareXPath when = nodeConstraints.getWhenCondition();
+        final Set<MustDefinition> must = nodeConstraints.getMustConstraints();
+
+        if (when != null) {
+            constraints.addWhenCondition(when.toString());
+        }
+        if (must != null) {
+            for (MustDefinition md : must) {
+                constraints.addMustDefinition(md);
+            }
+        }
+        constraints.setMandatory(nodeConstraints.isMandatory());
+        constraints.setMinElements(nodeConstraints.getMinElements());
+        constraints.setMaxElements(nodeConstraints.getMaxElements());
+    }
+
+    public static void processAugmentationOnContext(final AugmentationSchemaBuilder augmentBuilder,
+            final List<QName> path, final ModuleBuilder module, final String prefix, final int line,
+            final SchemaContext context) {
+        final Module dependentModule = findModuleFromContext(context, module, prefix, line);
+        if (dependentModule == null) {
+            throw new YangParseException(module.getName(), line, "Failed to find referenced module with prefix "
+                    + prefix + ".");
+        }
+        SchemaNode node = dependentModule.getDataChildByName(path.get(0).getLocalName());
+        if (node == null) {
+            Set<NotificationDefinition> notifications = dependentModule.getNotifications();
+            for (NotificationDefinition ntf : notifications) {
+                if (ntf.getQName().getLocalName().equals(path.get(0).getLocalName())) {
+                    node = ntf;
+                    break;
+                }
+            }
+        }
+        if (node == null) {
+            return;
+        }
+
+        for (int i = 1; i < path.size(); i++) {
+            if (node instanceof DataNodeContainer) {
+                DataNodeContainer ref = (DataNodeContainer) node;
+                node = ref.getDataChildByName(path.get(i).getLocalName());
+            }
+        }
+        if (node == null) {
+            return;
+        }
+
+        if (node instanceof ContainerSchemaNodeImpl) {
+            // includes container, input and output statement
+            ContainerSchemaNodeImpl c = (ContainerSchemaNodeImpl) node;
+            ContainerSchemaNodeBuilder cb = c.toBuilder();
+            fillAugmentTarget(augmentBuilder, cb);
+            ((AugmentationTargetBuilder) cb).addAugmentation(augmentBuilder);
+            SchemaPath oldPath = cb.getPath();
+            cb.rebuild();
+            augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
+            augmentBuilder.setResolved(true);
+            module.augmentResolved();
+        } else if (node instanceof ListSchemaNodeImpl) {
+            ListSchemaNodeImpl l = (ListSchemaNodeImpl) node;
+            ListSchemaNodeBuilder lb = l.toBuilder();
+            fillAugmentTarget(augmentBuilder, lb);
+            ((AugmentationTargetBuilder) lb).addAugmentation(augmentBuilder);
+            SchemaPath oldPath = lb.getPath();
+            lb.rebuild();
+            augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
+            augmentBuilder.setResolved(true);
+            module.augmentResolved();
+        } else if (node instanceof ChoiceNodeImpl) {
+            ChoiceNodeImpl ch = (ChoiceNodeImpl) node;
+            ChoiceBuilder chb = ch.toBuilder();
+            fillAugmentTarget(augmentBuilder, chb);
+            ((AugmentationTargetBuilder) chb).addAugmentation(augmentBuilder);
+            SchemaPath oldPath = chb.getPath();
+            chb.rebuild();
+            augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
+            augmentBuilder.setResolved(true);
+            module.augmentResolved();
+        } else if (node instanceof ChoiceCaseNodeImpl) {
+            ChoiceCaseNodeImpl chc = (ChoiceCaseNodeImpl) node;
+            ChoiceCaseBuilder chcb = chc.toBuilder();
+            fillAugmentTarget(augmentBuilder, chcb);
+            ((AugmentationTargetBuilder) chcb).addAugmentation(augmentBuilder);
+            SchemaPath oldPath = chcb.getPath();
+            chcb.rebuild();
+            augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
+            augmentBuilder.setResolved(true);
+            module.augmentResolved();
+        } else if (node instanceof NotificationDefinitionImpl) {
+            NotificationDefinitionImpl nd = (NotificationDefinitionImpl) node;
+            NotificationBuilder nb = nd.toBuilder();
+            fillAugmentTarget(augmentBuilder, nb);
+            ((AugmentationTargetBuilder) nb).addAugmentation(augmentBuilder);
+            SchemaPath oldPath = nb.getPath();
+            nb.rebuild();
+            augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
+            augmentBuilder.setResolved(true);
+            module.augmentResolved();
+        } else {
+            throw new YangParseException(module.getName(), line, "Target of type " + node.getClass()
+                    + " can not be augmented.");
+        }
+    }
+
+    public static void processAugmentation(final AugmentationSchemaBuilder augmentBuilder, final List<QName> path,
+            final ModuleBuilder module, final QName qname, final ModuleBuilder dependentModuleBuilder) {
+        DataSchemaNodeBuilder currentParent = null;
+        for (DataSchemaNodeBuilder child : dependentModuleBuilder.getChildNodes()) {
+            final QName childQName = child.getQName();
+            if (childQName.getLocalName().equals(qname.getLocalName())) {
+                currentParent = child;
+                break;
+            }
+        }
+
+        if (currentParent == null) {
+            return;
+        }
+
+        for (int i = 1; i < path.size(); i++) {
+            final QName currentQName = path.get(i);
+            DataSchemaNodeBuilder newParent = null;
+            for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodes()) {
+                final QName childQName = child.getQName();
+                if (childQName.getLocalName().equals(currentQName.getLocalName())) {
+                    newParent = child;
+                    break;
+                }
+            }
+            if (newParent == null) {
+                break; // node not found, quit search
+            } else {
+                currentParent = newParent;
+            }
+        }
+
+        final String currentName = currentParent.getQName().getLocalName();
+        final String lastAugmentPathElementName = path.get(path.size() - 1).getLocalName();
+        if (currentName.equals(lastAugmentPathElementName)) {
+
+            if (currentParent instanceof ChoiceBuilder) {
+                fillAugmentTarget(augmentBuilder, (ChoiceBuilder) currentParent);
+            } else {
+                fillAugmentTarget(augmentBuilder, (DataNodeContainerBuilder) currentParent);
+            }
+            ((AugmentationTargetBuilder) currentParent).addAugmentation(augmentBuilder);
+            SchemaPath oldPath = currentParent.getPath();
+            augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute()));
+            augmentBuilder.setResolved(true);
+            module.augmentResolved();
+        }
+    }
+
+    /**
+     * Create new type builder based on old type with new base type.
+     *
+     * @param newBaseType
+     *            new base type builder
+     * @param oldExtendedType
+     *            old type
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @param line
+     *            current line in module
+     * @return new type builder based on old type with new base type
+     */
+    public static TypeDefinitionBuilder extendedTypeWithNewBaseTypeBuilder(final TypeDefinitionBuilder newBaseType,
+            final ExtendedType oldExtendedType, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder module, final int line) {
+        final TypeConstraints tc = new TypeConstraints(module.getName(), line);
+        tc.addFractionDigits(oldExtendedType.getFractionDigits());
+        tc.addLengths(oldExtendedType.getLengths());
+        tc.addPatterns(oldExtendedType.getPatterns());
+        tc.addRanges(oldExtendedType.getRanges());
+
+        final TypeConstraints constraints = findConstraintsFromTypeBuilder(newBaseType, tc, modules, module, null);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line);
+        newType.setTypedef(newBaseType);
+        newType.setPath(oldExtendedType.getPath());
+        newType.setDescription(oldExtendedType.getDescription());
+        newType.setReference(oldExtendedType.getReference());
+        newType.setStatus(oldExtendedType.getStatus());
+        newType.setLengths(constraints.getLength());
+        newType.setPatterns(constraints.getPatterns());
+        newType.setRanges(constraints.getRange());
+        newType.setFractionDigits(constraints.getFractionDigits());
+        newType.setUnits(oldExtendedType.getUnits());
+        newType.setDefaultValue(oldExtendedType.getDefaultValue());
+        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
+        return newType;
+    }
+
+    /**
+     * Create new type builder based on old type with new base type.
+     *
+     * @param newBaseType
+     *            new base type
+     * @param oldExtendedType
+     *            old type
+     * @param modules
+     *            all loaded modules
+     * @param module
+     *            current module
+     * @param line
+     *            current line in module
+     * @return new type builder based on old type with new base type
+     */
+    public static TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeDefinition<?> newBaseType,
+            final ExtendedType oldExtendedType, final ModuleBuilder module, final int line) {
+        final TypeConstraints tc = new TypeConstraints(module.getName(), line);
+
+        final TypeConstraints constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line);
+        newType.setType(newBaseType);
+        newType.setPath(oldExtendedType.getPath());
+        newType.setDescription(oldExtendedType.getDescription());
+        newType.setReference(oldExtendedType.getReference());
+        newType.setStatus(oldExtendedType.getStatus());
+        newType.setLengths(constraints.getLength());
+        newType.setPatterns(constraints.getPatterns());
+        newType.setRanges(constraints.getRange());
+        newType.setFractionDigits(constraints.getFractionDigits());
+        newType.setUnits(oldExtendedType.getUnits());
+        newType.setDefaultValue(oldExtendedType.getDefaultValue());
+        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
+        return newType;
+    }
+
+    /**
+     * Pull restrictions from type and add them to constraints.
+     *
+     * @param typeToResolve
+     *            type from which constraints will be read
+     * @param constraints
+     *            constraints object to which constraints will be added
+     * @return constraints contstraints object containing constraints from given
+     *         type
+     */
+    private static TypeConstraints findConstraintsFromTypeDefinition(final TypeDefinition<?> typeToResolve,
+            final TypeConstraints constraints) {
+        // union type cannot be restricted
+        if (typeToResolve instanceof UnionTypeDefinition) {
+            return constraints;
+        }
+        if (typeToResolve instanceof ExtendedType) {
+            ExtendedType extType = (ExtendedType) typeToResolve;
+            constraints.addFractionDigits(extType.getFractionDigits());
+            constraints.addLengths(extType.getLengths());
+            constraints.addPatterns(extType.getPatterns());
+            constraints.addRanges(extType.getRanges());
+            return findConstraintsFromTypeDefinition(extType.getBaseType(), constraints);
+        } else {
+            mergeConstraints(typeToResolve, constraints);
+            return constraints;
+        }
+    }
+
+    public static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve,
+            final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder builder, final SchemaContext context) {
+
+        // union type cannot be restricted
+        if (nodeToResolve instanceof UnionTypeBuilder) {
+            return constraints;
+        }
+
+        if (nodeToResolve instanceof TypeDefinitionBuilder) {
+            TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve;
+            constraints.addFractionDigits(typedefToResolve.getFractionDigits());
+            constraints.addLengths(typedefToResolve.getLengths());
+            constraints.addPatterns(typedefToResolve.getPatterns());
+            constraints.addRanges(typedefToResolve.getRanges());
+        }
+
+        TypeDefinition<?> type = nodeToResolve.getType();
+        if (type == null) {
+            return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context);
+        } else {
+            QName qname = type.getQName();
+            if (type instanceof UnknownType) {
+                ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder, qname.getPrefix(),
+                        nodeToResolve.getLine());
+                if (dependentModuleBuilder == null) {
+                    if (context == null) {
+                        throw new YangParseException(builder.getName(), nodeToResolve.getLine(),
+                                "Failed to resolved type constraints.");
+                    }
+                    Module dm = findModuleFromContext(context, builder, qname.getPrefix(), nodeToResolve.getLine());
+                    TypeDefinition<?> t = findTypeByName(dm.getTypeDefinitions(), qname.getLocalName());
+                    if (t instanceof ExtendedType) {
+                        ExtendedType extType = (ExtendedType) t;
+                        constraints.addFractionDigits(extType.getFractionDigits());
+                        constraints.addLengths(extType.getLengths());
+                        constraints.addPatterns(extType.getPatterns());
+                        constraints.addRanges(extType.getRanges());
+                        return constraints;
+                    } else {
+                        mergeConstraints(t, constraints);
+                        return constraints;
+                    }
+                } else {
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(),
+                            dependentModuleBuilder, qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
+                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context);
+                }
+            } else if (type instanceof ExtendedType) {
+                ExtendedType extType = (ExtendedType) type;
+                constraints.addFractionDigits(extType.getFractionDigits());
+                constraints.addLengths(extType.getLengths());
+                constraints.addPatterns(extType.getPatterns());
+                constraints.addRanges(extType.getRanges());
+
+                TypeDefinition<?> base = extType.getBaseType();
+                if (base instanceof UnknownType) {
+                    ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, base.getQName()
+                            .getPrefix(), nodeToResolve.getLine());
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), dependentModule,
+                            base.getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
+                    return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context);
+                } else {
+                    // it has to be base yang type
+                    mergeConstraints(type, constraints);
+                    return constraints;
+                }
+            } else {
+                // it is base yang type
+                mergeConstraints(type, constraints);
+                return constraints;
+            }
+        }
+    }
+
+    /**
+     * Search for type definition builder by name.
+     *
+     * @param dirtyNodeSchemaPath
+     *            schema path of node which contains unresolved type
+     * @param dependentModule
+     *            module which should contains referenced type
+     * @param typeName
+     *            name of type definition
+     * @param currentModuleName
+     *            name of current module
+     * @param line
+     *            current line in yang model
+     * @return
+     */
+    public static TypeDefinitionBuilder findTypeDefinitionBuilder(final SchemaPath dirtyNodeSchemaPath,
+            final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) {
+        final List<QName> path = dirtyNodeSchemaPath.getPath();
+        TypeDefinitionBuilder result = null;
+
+        Set<TypeDefinitionBuilder> typedefs = dependentModule.getModuleTypedefs();
+        result = findTypedefBuilderByName(typedefs, typeName);
+
+        if (result == null) {
+            Builder currentNode = null;
+            final List<String> currentPath = new ArrayList<String>();
+            currentPath.add(dependentModule.getName());
+
+            for (int i = 0; i < path.size(); i++) {
+                QName qname = path.get(i);
+                currentPath.add(qname.getLocalName());
+                currentNode = dependentModule.getModuleNode(currentPath);
+
+                if (currentNode instanceof RpcDefinitionBuilder) {
+                    typedefs = ((RpcDefinitionBuilder) currentNode).getTypeDefinitions();
+                } else if (currentNode instanceof DataNodeContainerBuilder) {
+                    typedefs = ((DataNodeContainerBuilder) currentNode).getTypeDefinitions();
+                } else {
+                    typedefs = Collections.emptySet();
+                }
+
+                result = findTypedefBuilderByName(typedefs, typeName);
+                if (result != null) {
+                    break;
+                }
+            }
+        }
+
+        if (result != null) {
+            return result;
+        }
+        throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found.");
+    }
+
 }
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java
new file mode 100644 (file)
index 0000000..8db4e8e
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.yang.parser.util;
+
+import static org.opendaylight.controller.yang.parser.util.ParserUtils.*;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.controller.yang.model.api.ChoiceNode;
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
+import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;
+import org.opendaylight.controller.yang.model.api.MustDefinition;
+import org.opendaylight.controller.yang.model.api.TypeDefinition;
+import org.opendaylight.controller.yang.model.util.ExtendedType;
+import org.opendaylight.controller.yang.parser.builder.api.Builder;
+import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
+import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
+
+/**
+ * Utility class with helper methods to perform operations tied to refine
+ * process.
+ */
+public class RefineUtils {
+
+    private RefineUtils() {
+    }
+
+    /**
+     * Find original builder of node to refine and return copy of this builder.
+     * <p>
+     * We must create and use a copy of builder to preserve original builder
+     * state, because this object will be refined (modified) and later added to
+     * {@link UsesNodeBuilder}.
+     * </p>
+     *
+     * @param targetGrouping
+     *            builder of grouping which should contains node to refine
+     * @param refine
+     *            refine object containing informations about refine
+     * @param moduleName
+     *            current module name
+     * @return
+     */
+    public static SchemaNodeBuilder getRefineNodeFromGroupingBuilder(final GroupingBuilder targetGrouping,
+            final RefineHolder refine, final String moduleName) {
+        Builder result = null;
+        final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping, refine.getName());
+        if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) {
+            result = copyLeafBuilder((LeafSchemaNodeBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof ContainerSchemaNodeBuilder) {
+            result = copyContainerBuilder((ContainerSchemaNodeBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof ListSchemaNodeBuilder) {
+            result = copyListBuilder((ListSchemaNodeBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof LeafListSchemaNodeBuilder) {
+            result = copyLeafListBuilder((LeafListSchemaNodeBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof ChoiceBuilder) {
+            result = copyChoiceBuilder((ChoiceBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof AnyXmlBuilder) {
+            result = copyAnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof GroupingBuilder) {
+            result = copyGroupingBuilder((GroupingBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof TypeDefinitionBuilder) {
+            result = copyTypedefBuilder((TypeDefinitionBuilderImpl) lookedUpBuilder);
+        } else {
+            throw new YangParseException(moduleName, refine.getLine(), "Target '" + refine.getName()
+                    + "' can not be refined");
+        }
+        return (SchemaNodeBuilder) result;
+    }
+
+    /**
+     * Create builder object from refine target node.
+     *
+     * @param grouping
+     *            grouping which should contains node to refine
+     * @param refine
+     *            refine object containing informations about refine
+     * @param moduleName
+     *            current module name
+     * @return
+     */
+    public static SchemaNodeBuilder getRefineNodeFromGroupingDefinition(final GroupingDefinition grouping,
+            final RefineHolder refine, final String moduleName) {
+        SchemaNodeBuilder result = null;
+        final int line = refine.getLine();
+        final Object lookedUpNode = findRefineTargetNode(grouping, refine.getName());
+        if (lookedUpNode instanceof LeafSchemaNode) {
+            result = createLeafBuilder((LeafSchemaNode) lookedUpNode, line);
+        } else if (lookedUpNode instanceof ContainerSchemaNode) {
+            result = createContainer((ContainerSchemaNode) lookedUpNode, line);
+        } else if (lookedUpNode instanceof ListSchemaNode) {
+            result = createList((ListSchemaNode) lookedUpNode, line);
+        } else if (lookedUpNode instanceof LeafListSchemaNode) {
+            result = createLeafList((LeafListSchemaNode) lookedUpNode, line);
+        } else if (lookedUpNode instanceof ChoiceNode) {
+            result = createChoice((ChoiceNode) lookedUpNode, line);
+        } else if (lookedUpNode instanceof AnyXmlSchemaNode) {
+            result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, line);
+        } else if (lookedUpNode instanceof GroupingDefinition) {
+            result = createGrouping((GroupingDefinition) lookedUpNode, line);
+        } else if (lookedUpNode instanceof TypeDefinition) {
+            result = createTypedef((ExtendedType) lookedUpNode, line);
+        } else {
+            throw new YangParseException(moduleName, line, "Target '" + refine.getName() + "' can not be refined");
+        }
+        return result;
+    }
+
+    public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine, int line) {
+        String defaultStr = refine.getDefaultStr();
+        Boolean mandatory = refine.isMandatory();
+        MustDefinition must = refine.getMust();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (defaultStr != null && !("".equals(defaultStr))) {
+            leaf.setDefaultStr(defaultStr);
+        }
+        if (mandatory != null) {
+            leaf.getConstraints().setMandatory(mandatory);
+        }
+        if (must != null) {
+            leaf.getConstraints().addMustDefinition(must);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                leaf.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineContainer(ContainerSchemaNodeBuilder container, RefineHolder refine, int line) {
+        Boolean presence = refine.isPresence();
+        MustDefinition must = refine.getMust();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (presence != null) {
+            container.setPresence(presence);
+        }
+        if (must != null) {
+            container.getConstraints().addMustDefinition(must);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                container.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineList(ListSchemaNodeBuilder list, RefineHolder refine, int line) {
+        MustDefinition must = refine.getMust();
+        Integer min = refine.getMinElements();
+        Integer max = refine.getMaxElements();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (must != null) {
+            list.getConstraints().addMustDefinition(must);
+        }
+        if (min != null) {
+            list.getConstraints().setMinElements(min);
+        }
+        if (max != null) {
+            list.getConstraints().setMaxElements(max);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                list.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineLeafList(LeafListSchemaNodeBuilder leafList, RefineHolder refine, int line) {
+        MustDefinition must = refine.getMust();
+        Integer min = refine.getMinElements();
+        Integer max = refine.getMaxElements();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (must != null) {
+            leafList.getConstraints().addMustDefinition(must);
+        }
+        if (min != null) {
+            leafList.getConstraints().setMinElements(min);
+        }
+        if (max != null) {
+            leafList.getConstraints().setMaxElements(max);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                leafList.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineChoice(ChoiceBuilder choice, RefineHolder refine, int line) {
+        String defaultStr = refine.getDefaultStr();
+        Boolean mandatory = refine.isMandatory();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (defaultStr != null) {
+            choice.setDefaultCase(defaultStr);
+        }
+        if (mandatory != null) {
+            choice.getConstraints().setMandatory(mandatory);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                choice.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine, int line) {
+        Boolean mandatory = refine.isMandatory();
+        MustDefinition must = refine.getMust();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (mandatory != null) {
+            anyXml.getConstraints().setMandatory(mandatory);
+        }
+        if (must != null) {
+            anyXml.getConstraints().addMustDefinition(must);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                anyXml.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    /**
+     * Check if refine can be performed on given node.
+     *
+     * @param node
+     *            node to refine
+     * @param refine
+     *            refine object containing information about refine process
+     */
+    public static void checkRefine(SchemaNodeBuilder node, RefineHolder refine) {
+        String name = node.getQName().getLocalName();
+        int line = refine.getLine();
+
+        String defaultStr = refine.getDefaultStr();
+        Boolean mandatory = refine.isMandatory();
+        Boolean presence = refine.isPresence();
+        MustDefinition must = refine.getMust();
+        Integer min = refine.getMinElements();
+        Integer max = refine.getMaxElements();
+
+        if (node instanceof AnyXmlBuilder) {
+            checkRefineDefault(node, defaultStr, line);
+            checkRefinePresence(node, presence, line);
+            checkRefineMinMax(name, line, min, max);
+        } else if (node instanceof ChoiceBuilder) {
+            checkRefinePresence(node, presence, line);
+            checkRefineMust(node, must, line);
+            checkRefineMinMax(name, line, min, max);
+        } else if (node instanceof ContainerSchemaNodeBuilder) {
+            checkRefineDefault(node, defaultStr, line);
+            checkRefineMandatory(node, mandatory, line);
+            checkRefineMust(node, must, line);
+            checkRefineMinMax(name, line, min, max);
+        } else if (node instanceof LeafSchemaNodeBuilder) {
+            checkRefinePresence(node, presence, line);
+            checkRefineMinMax(name, line, min, max);
+        } else if (node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder) {
+            checkRefineDefault(node, defaultStr, line);
+            checkRefinePresence(node, presence, line);
+            checkRefineMandatory(node, mandatory, line);
+        } else if (node instanceof GroupingBuilder || node instanceof TypeDefinitionBuilder
+                || node instanceof UsesNodeBuilder) {
+            checkRefineDefault(node, defaultStr, line);
+            checkRefinePresence(node, presence, line);
+            checkRefineMandatory(node, mandatory, line);
+            checkRefineMust(node, must, line);
+            checkRefineMinMax(name, line, min, max);
+        }
+    }
+
+    private static void checkRefineDefault(SchemaNodeBuilder node, String defaultStr, int line) {
+        if (defaultStr != null) {
+            throw new YangParseException(line, "Can not refine 'default' for '" + node.getQName().getLocalName() + "'.");
+        }
+    }
+
+    private static void checkRefineMandatory(SchemaNodeBuilder node, Boolean mandatory, int line) {
+        if (mandatory != null) {
+            throw new YangParseException(line, "Can not refine 'mandatory' for '" + node.getQName().getLocalName()
+                    + "'.");
+        }
+    }
+
+    private static void checkRefinePresence(SchemaNodeBuilder node, Boolean presence, int line) {
+        if (presence != null) {
+            throw new YangParseException(line, "Can not refine 'presence' for '" + node.getQName().getLocalName()
+                    + "'.");
+        }
+    }
+
+    private static void checkRefineMust(SchemaNodeBuilder node, MustDefinition must, int line) {
+        if (must != null) {
+            throw new YangParseException(line, "Can not refine 'must' for '" + node.getQName().getLocalName() + "'.");
+        }
+    }
+
+    private static void checkRefineMinMax(String refineTargetName, int refineLine, Integer min, Integer max) {
+        if (min != null || max != null) {
+            throw new YangParseException(refineLine, "Can not refine 'min-elements' or 'max-elements' for '"
+                    + refineTargetName + "'.");
+        }
+    }
+
+    /**
+     * Perform refine operation of following parameters:
+     * <ul>
+     * <li>description</li>
+     * <li>reference</li>
+     * <li>config</li>
+     * </ul>
+     *
+     * These parameters may be refined for any node.
+     *
+     * @param node
+     *            node to refine
+     * @param refine
+     *            refine object containing information about refine process
+     * @param line
+     *            current line in yang model
+     */
+    public static void refineDefault(final Builder node, final RefineHolder refine, final int line) {
+        Class<? extends Builder> cls = node.getClass();
+
+        String description = refine.getDescription();
+        if (description != null) {
+            try {
+                Method method = cls.getDeclaredMethod("setDescription", String.class);
+                method.invoke(node, description);
+            } catch (Exception e) {
+                throw new YangParseException(line, "Cannot refine description in " + cls.getName(), e);
+            }
+        }
+
+        String reference = refine.getReference();
+        if (reference != null) {
+            try {
+                Method method = cls.getDeclaredMethod("setReference", String.class);
+                method.invoke(node, reference);
+            } catch (Exception e) {
+                throw new YangParseException(line, "Cannot refine reference in " + cls.getName(), e);
+            }
+        }
+
+        Boolean config = refine.isConfig();
+        if (config != null) {
+            try {
+                Method method = cls.getDeclaredMethod("setConfiguration", Boolean.TYPE);
+                method.invoke(node, config);
+            } catch (Exception e) {
+                throw new YangParseException(line, "Cannot refine config in " + cls.getName(), e);
+            }
+        }
+    }
+
+    /**
+     * Perform refine operation on given node.
+     *
+     * @param nodeToRefine
+     *            builder of node to refine
+     * @param refine
+     *            refine object containing information about refine process
+     * @param line
+     *            current line in yang model
+     */
+    public static void performRefine(SchemaNodeBuilder nodeToRefine, RefineHolder refine, int line) {
+        checkRefine(nodeToRefine, refine);
+        refineDefault(nodeToRefine, refine, line);
+        if (nodeToRefine instanceof LeafSchemaNodeBuilder) {
+            refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine, line);
+        } else if (nodeToRefine instanceof ContainerSchemaNodeBuilder) {
+            refineContainer((ContainerSchemaNodeBuilder) nodeToRefine, refine, line);
+        } else if (nodeToRefine instanceof ListSchemaNodeBuilder) {
+            refineList((ListSchemaNodeBuilder) nodeToRefine, refine, line);
+        } else if (nodeToRefine instanceof LeafListSchemaNodeBuilder) {
+            refineLeafList((LeafListSchemaNodeBuilder) nodeToRefine, refine, line);
+        } else if (nodeToRefine instanceof ChoiceBuilder) {
+            refineChoice((ChoiceBuilder) nodeToRefine, refine, line);
+        } else if (nodeToRefine instanceof AnyXmlBuilder) {
+            refineAnyxml((AnyXmlBuilder) nodeToRefine, refine, line);
+        }
+    }
+
+}
index ae405c06a88805d0c744c1fb2a5b97f2c9dda9ec..5423e486db13a9101eff84d9f849fb40ad5ec054 100644 (file)
@@ -672,16 +672,13 @@ public final class YangModelBuilderUtil {
     private static List<PatternConstraint> getPatternConstraint(final Type_body_stmtsContext ctx) {
         List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();
 
-        outer: for (int j = 0; j < ctx.getChildCount(); j++) {
+        for (int j = 0; j < ctx.getChildCount(); j++) {
             ParseTree stringRestrChild = ctx.getChild(j);
             if (stringRestrChild instanceof String_restrictionsContext) {
                 for (int k = 0; k < stringRestrChild.getChildCount(); k++) {
                     ParseTree lengthChild = stringRestrChild.getChild(k);
                     if (lengthChild instanceof Pattern_stmtContext) {
                         patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild));
-                        if (k == lengthChild.getChildCount() - 1) {
-                            break outer;
-                        }
                     }
                 }
             }
index 26c2c61b98a783aae48517b6cb5c259db85c8bb0..fed8cde9655c8dc2232cd068501b523ae69777fa 100644 (file)
@@ -25,6 +25,7 @@ import java.util.Set;
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.ModuleImport;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
@@ -69,6 +70,25 @@ final class TestUtils {
         return modules.iterator().next();
     }
 
+    public static Module loadModuleWithContext(final InputStream stream, final SchemaContext context) throws IOException {
+        final YangModelParser parser = new YangParserImpl();
+        final List<InputStream> input = Collections.singletonList(stream);
+        final Set<Module> modules = new HashSet<Module>(parser.parseYangModelsFromStreams(input, context));
+        stream.close();
+        return modules.iterator().next();
+    }
+
+    public static Set<Module> loadModulesWithContext(final List<InputStream> input, final SchemaContext context) throws IOException {
+        final YangModelParser parser = new YangParserImpl();
+        final Set<Module> modules = new HashSet<Module>(parser.parseYangModelsFromStreams(input, context));
+        for(InputStream is : input) {
+            if(is != null) {
+                is.close();
+            }
+        }
+        return modules;
+    }
+
     public static Module findModule(Set<Module> modules, String moduleName) {
         Module result = null;
         for (Module module : modules) {
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java
new file mode 100644 (file)
index 0000000..ff32ee1
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.yang.parser.impl;
+
+import static org.junit.Assert.*;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.URI;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Test;
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
+import org.opendaylight.controller.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.MustDefinition;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
+import org.opendaylight.controller.yang.model.api.SchemaNode;
+import org.opendaylight.controller.yang.model.api.SchemaPath;
+import org.opendaylight.controller.yang.model.api.TypeDefinition;
+import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.controller.yang.model.api.UsesNode;
+import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
+import org.opendaylight.controller.yang.model.util.ExtendedType;
+
+import com.google.common.collect.Lists;
+
+public class YangParserWithContextTest {
+    private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+    private final YangParserImpl parser = new YangParserImpl();
+
+    @Test
+    public void testTypeFromContext() throws Exception {
+        SchemaContext context = null;
+        String resource = "/types/ietf-inet-types@2010-09-24.yang";
+        InputStream stream = new FileInputStream(getClass().getResource(resource).getPath());
+        context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+        stream.close();
+
+        Module module = null;
+        resource = "/context-test/test1.yang";
+        InputStream stream2 = new FileInputStream(getClass().getResource(resource).getPath());
+        module = TestUtils.loadModuleWithContext(stream2, context);
+        stream2.close();
+        assertNotNull(module);
+
+        LeafSchemaNode leaf = (LeafSchemaNode) module.getDataChildByName("id");
+
+        ExtendedType leafType = (ExtendedType) leaf.getType();
+        QName qname = leafType.getQName();
+        assertEquals(URI.create("urn:simple.demo.test1"), qname.getNamespace());
+        assertEquals(simpleDateFormat.parse("2013-06-18"), qname.getRevision());
+        assertEquals("t1", qname.getPrefix());
+        assertEquals("port-number", qname.getLocalName());
+
+        ExtendedType leafBaseType = (ExtendedType) leafType.getBaseType();
+        qname = leafBaseType.getQName();
+        assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-inet-types"), qname.getNamespace());
+        assertEquals(simpleDateFormat.parse("2010-09-24"), qname.getRevision());
+        assertEquals("inet", qname.getPrefix());
+        assertEquals("port-number", qname.getLocalName());
+
+        ExtendedType dscpExt = (ExtendedType)TestUtils.findTypedef(module.getTypeDefinitions(), "dscp-ext");
+        List<RangeConstraint> ranges = dscpExt.getRanges();
+        assertEquals(1, ranges.size());
+        RangeConstraint range = ranges.get(0);
+        assertEquals(0L, range.getMin());
+        assertEquals(63L, range.getMax());
+
+    }
+
+    @Test
+    public void testUsesGroupingFromContext() throws Exception {
+        SchemaContext context = null;
+        try (InputStream stream = new FileInputStream(getClass().getResource("/model/testfile2.yang").getPath())) {
+            context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+        }
+        Module module = null;
+        try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test2.yang").getPath())) {
+            module = TestUtils.loadModuleWithContext(stream, context);
+        }
+        assertNotNull(module);
+
+        ContainerSchemaNode peer = (ContainerSchemaNode) module.getDataChildByName("peer");
+        ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName("destination");
+        Set<UsesNode> usesNodes = destination.getUses();
+        assertEquals(1, usesNodes.size());
+        UsesNode usesNode = usesNodes.iterator().next();
+
+        // test grouping path
+        List<QName> path = new ArrayList<QName>();
+        QName qname = new QName(URI.create("urn:simple.types.data.demo"), simpleDateFormat.parse("2013-02-27"), "t2",
+                "target");
+        path.add(qname);
+        SchemaPath expectedPath = new SchemaPath(path, true);
+        assertEquals(expectedPath, usesNode.getGroupingPath());
+
+        // test refine
+        Map<SchemaPath, SchemaNode> refines = usesNode.getRefines();
+        assertEquals(5, refines.size());
+
+        LeafSchemaNode refineLeaf = null;
+        ContainerSchemaNode refineContainer = null;
+        ListSchemaNode refineList = null;
+        GroupingDefinition refineGrouping = null;
+        TypeDefinition<?> typedef = null;
+        for (Map.Entry<SchemaPath, SchemaNode> entry : refines.entrySet()) {
+            SchemaNode value = entry.getValue();
+            if (value instanceof LeafSchemaNode) {
+                refineLeaf = (LeafSchemaNode) value;
+            } else if (value instanceof ContainerSchemaNode) {
+                refineContainer = (ContainerSchemaNode) value;
+            } else if (value instanceof ListSchemaNode) {
+                refineList = (ListSchemaNode) value;
+            } else if (value instanceof GroupingDefinition) {
+                refineGrouping = (GroupingDefinition) value;
+            } else if (value instanceof TypeDefinition<?>) {
+                typedef = (TypeDefinition<?>) value;
+            }
+        }
+
+        // leaf address
+        assertNotNull(refineLeaf);
+        assertEquals("address", refineLeaf.getQName().getLocalName());
+        assertEquals("description of address defined by refine", refineLeaf.getDescription());
+        assertEquals("address reference added by refine", refineLeaf.getReference());
+        assertFalse(refineLeaf.isConfiguration());
+        assertTrue(refineLeaf.getConstraints().isMandatory());
+        Set<MustDefinition> leafMustConstraints = refineLeaf.getConstraints().getMustConstraints();
+        assertEquals(1, leafMustConstraints.size());
+        MustDefinition leafMust = leafMustConstraints.iterator().next();
+        assertEquals("\"ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)\"", leafMust.toString());
+
+        // container port
+        assertNotNull(refineContainer);
+        Set<MustDefinition> mustConstraints = refineContainer.getConstraints().getMustConstraints();
+        assertTrue(mustConstraints.isEmpty());
+        assertEquals("description of port defined by refine", refineContainer.getDescription());
+        assertEquals("port reference added by refine", refineContainer.getReference());
+        assertFalse(refineContainer.isConfiguration());
+        assertTrue(refineContainer.isPresenceContainer());
+
+        // list addresses
+        assertNotNull(refineList);
+        assertEquals("description of addresses defined by refine", refineList.getDescription());
+        assertEquals("addresses reference added by refine", refineList.getReference());
+        assertFalse(refineList.isConfiguration());
+        assertEquals(2, (int) refineList.getConstraints().getMinElements());
+        assertEquals(12, (int) refineList.getConstraints().getMaxElements());
+
+        // grouping target-inner
+        assertNotNull(refineGrouping);
+        Set<DataSchemaNode> refineGroupingChildren = refineGrouping.getChildNodes();
+        assertEquals(1, refineGroupingChildren.size());
+        LeafSchemaNode refineGroupingLeaf = (LeafSchemaNode) refineGroupingChildren.iterator().next();
+        assertEquals("inner-grouping-id", refineGroupingLeaf.getQName().getLocalName());
+        assertEquals("new target-inner grouping description", refineGrouping.getDescription());
+
+        // typedef group-type
+        assertNotNull(typedef);
+        assertEquals("new group-type description", typedef.getDescription());
+        assertEquals("new group-type reference", typedef.getReference());
+        assertTrue(typedef.getBaseType() instanceof ExtendedType);
+    }
+
+    @Test
+    public void testIdentity() throws Exception {
+        SchemaContext context = null;
+        try (InputStream stream = new FileInputStream(getClass().getResource("/types/custom-types-test@2012-4-4.yang")
+                .getPath())) {
+            context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+        }
+        Module module = null;
+        try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test3.yang").getPath())) {
+            module = TestUtils.loadModuleWithContext(stream, context);
+        }
+        assertNotNull(module);
+
+        Set<IdentitySchemaNode> identities = module.getIdentities();
+        assertEquals(1, identities.size());
+
+        IdentitySchemaNode identity = identities.iterator().next();
+        QName idQName = identity.getQName();
+        assertEquals(URI.create("urn:simple.demo.test3"), idQName.getNamespace());
+        assertEquals(simpleDateFormat.parse("2013-06-18"), idQName.getRevision());
+        assertEquals("t3", idQName.getPrefix());
+        assertEquals("pt", idQName.getLocalName());
+
+        IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
+        QName idBaseQName = baseIdentity.getQName();
+        assertEquals(URI.create("urn:simple.container.demo"), idBaseQName.getNamespace());
+        assertEquals(simpleDateFormat.parse("2012-04-16"), idBaseQName.getRevision());
+        assertEquals("iit", idBaseQName.getPrefix());
+        assertEquals("service-type", idBaseQName.getLocalName());
+    }
+
+    @Test
+    public void testUnknownNodes() throws Exception {
+        SchemaContext context = null;
+        try (InputStream stream = new FileInputStream(getClass().getResource("/types/custom-types-test@2012-4-4.yang").getPath())) {
+            context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+        }
+
+        Module module = null;
+        try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test3.yang").getPath())) {
+            module = TestUtils.loadModuleWithContext(stream, context);
+        }
+
+        ContainerSchemaNode network = (ContainerSchemaNode) module.getDataChildByName("network");
+        List<UnknownSchemaNode> unknownNodes = network.getUnknownSchemaNodes();
+        assertEquals(1, unknownNodes.size());
+
+        UnknownSchemaNode un = unknownNodes.iterator().next();
+        QName unType = un.getNodeType();
+        assertEquals(URI.create("urn:simple.container.demo"), unType.getNamespace());
+        assertEquals(simpleDateFormat.parse("2012-04-16"), unType.getRevision());
+        assertEquals("custom", unType.getPrefix());
+        assertEquals("mountpoint", unType.getLocalName());
+        assertEquals("point", un.getNodeParameter());
+    }
+
+    @Test
+    public void testAugment() throws Exception {
+        // load first module
+        SchemaContext context = null;
+        String resource = "/context-augment-test/test4.yang";
+
+        try (InputStream stream = new FileInputStream(getClass().getResource(resource).getPath())) {
+            context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
+        }
+
+        Set<Module> contextModules = context.getModules();
+        Module t3 = TestUtils.findModule(contextModules, "test4");
+        ContainerSchemaNode interfaces = (ContainerSchemaNode) t3.getDataChildByName("interfaces");
+        ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
+
+        // load another modules and parse them against already existing context
+        Set<Module> modules = null;
+        try (InputStream stream1 = new FileInputStream(getClass().getResource("/context-augment-test/test1.yang")
+                .getPath());
+                InputStream stream2 = new FileInputStream(getClass().getResource("/context-augment-test/test2.yang")
+                        .getPath());
+                InputStream stream3 = new FileInputStream(getClass().getResource("/context-augment-test/test3.yang")
+                        .getPath())) {
+            List<InputStream> input = Lists.newArrayList(stream1, stream2, stream3);
+            modules = TestUtils.loadModulesWithContext(input, context);
+        }
+        assertNotNull(modules);
+
+        // test augmentation process
+        ContainerSchemaNode augmentHolder = (ContainerSchemaNode) ifEntry.getDataChildByName("augment-holder");
+        assertNotNull(augmentHolder);
+        DataSchemaNode ds0 = augmentHolder.getDataChildByName("ds0ChannelNumber");
+        assertNotNull(ds0);
+        DataSchemaNode interfaceId = augmentHolder.getDataChildByName("interface-id");
+        assertNotNull(interfaceId);
+        DataSchemaNode higherLayerIf = augmentHolder.getDataChildByName("higher-layer-if");
+        assertNotNull(higherLayerIf);
+        ContainerSchemaNode schemas = (ContainerSchemaNode) augmentHolder.getDataChildByName("schemas");
+        assertNotNull(schemas);
+        assertNotNull(schemas.getDataChildByName("id"));
+
+        // test augment target after augmentation: check if it is same instance
+        ListSchemaNode ifEntryAfterAugment = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
+        assertTrue(ifEntry == ifEntryAfterAugment);
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang
new file mode 100644 (file)
index 0000000..04468fb
--- /dev/null
@@ -0,0 +1,34 @@
+module test1 {
+
+    yang-version 1;
+    namespace "urn:simple.demo.test1";
+    prefix "t1";
+
+    import test3 {
+        prefix "t3";
+        revision-date 2013-06-18;
+    }
+
+    import test2 {
+        prefix "t2";
+        revision-date 2013-06-18;
+    }
+
+    import test4 {
+        prefix "t4";
+        revision-date 2013-06-18;
+    }
+
+    organization "opendaylight";
+    contact "WILL-BE-DEFINED-LATER";
+        revision 2013-06-18 {
+    }
+
+    augment "/t4:interfaces/t4:ifEntry/t2:augment-holder/t3:schemas" {
+        when "if:ifType='ds0'";
+        leaf id {
+            type string;
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang
new file mode 100644 (file)
index 0000000..44bdf66
--- /dev/null
@@ -0,0 +1,41 @@
+module test2 {
+
+    yang-version 1;
+    namespace "urn:simple.demo.test2";
+    prefix "t2";
+
+    import test3 {
+        prefix "t3";
+        revision-date 2013-06-18;
+    }
+
+    import test4 {
+        prefix "t4";
+        revision-date 2013-06-18;
+    }
+
+    organization "opendaylight";
+    contact "WILL-BE-DEFINED-LATER";
+        revision 2013-06-18 {
+    }
+
+    augment "/t4:interfaces/t4:ifEntry/t3:augment-holder" {
+        when "if:ifType='ds0'";
+        leaf ds0ChannelNumber {
+            type string;
+        }
+        leaf interface-id {
+            type leafref {
+                path "/if:interfaces/if:interface/if:name";
+            }
+        }
+        leaf-list higher-layer-if {
+            type leafref {
+                path "/if:interfaces/if:interface/if:higher-layer-if";
+            }
+        }
+        container schemas {
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang
new file mode 100644 (file)
index 0000000..f954153
--- /dev/null
@@ -0,0 +1,24 @@
+module test3 {
+
+    yang-version 1;
+    namespace "urn:simple.demo.test3";
+    prefix "t3";
+
+    import test4 {
+        prefix "t4";
+        revision-date 2013-06-18;
+    }
+
+    organization "opendaylight";
+    contact "WILL-BE-DEFINED-LATER";
+        revision 2013-06-18 {
+    }
+
+    augment "/t4:interfaces/t4:ifEntry" {
+        when "if:ifType='ds0'";
+        container augment-holder {
+            description "Description for augment holder";
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang
new file mode 100644 (file)
index 0000000..9d57a9e
--- /dev/null
@@ -0,0 +1,27 @@
+module test4 {
+
+    yang-version 1;
+    namespace "urn:simple.demo.test4";
+    prefix "t4";
+
+    organization "opendaylight";
+    contact "WILL-BE-DEFINED-LATER";
+        revision 2013-06-18 {
+    }
+
+    container interfaces {
+         list ifEntry {
+             key "ifIndex";
+             leaf ifIndex {
+                 type uint32;
+                 units minutes;
+             }
+             leaf ifMtu {
+                 type int32;
+             }
+             min-elements 1;
+             max-elements 11;
+         }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang
new file mode 100644 (file)
index 0000000..1ba5142
--- /dev/null
@@ -0,0 +1,29 @@
+module test1 {
+
+    yang-version 1;
+    namespace "urn:simple.demo.test1";
+    prefix "t1";
+    
+    import ietf-inet-types {
+        prefix "inet";
+        revision-date 2010-09-24;
+    }
+    
+    organization "opendaylight";
+    contact "WILL-BE-DEFINED-LATER";
+        revision 2013-06-18 {
+    }
+    
+    typedef dscp-ext {
+        type inet:dscp {
+            range "min..max";
+        }
+    }
+
+    leaf id {
+        type inet:port-number {
+            range "0..65536";
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang
new file mode 100644 (file)
index 0000000..74704d5
--- /dev/null
@@ -0,0 +1,54 @@
+module test2 {
+
+    yang-version 1;
+    namespace "urn:simple.demo.test2";
+    prefix "t2";
+
+    import types2 {
+        prefix "data";
+    }
+
+    organization "opendaylight";
+    contact "WILL-BE-DEFINED-LATER";
+        revision 2013-06-18 {
+    }
+
+    container peer {
+        container destination {
+            uses data:target {
+                refine address {
+                    default "1.2.3.4";
+                    description "description of address defined by refine";
+                    reference "address reference added by refine";
+                    config false;
+                    mandatory true;
+                    must "ifType != 'ethernet' or " +
+                            "(ifType = 'ethernet' and ifMTU = 1500)" {
+                        error-message "An ethernet MTU must be 1500";
+                    }
+                }
+                refine port {
+                    description "description of port defined by refine";
+                    reference "port reference added by refine";
+                    config false;
+                    presence "presence is required";
+                }
+                refine addresses {
+                    description "description of addresses defined by refine";
+                    reference "addresses reference added by refine";
+                    config false;
+                    min-elements 2;
+                    max-elements 12;
+                }
+                refine target-inner {
+                    description "new target-inner grouping description";
+                }
+                refine group-type {
+                    description "new group-type description";
+                    reference "new group-type reference";
+                }
+            }
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang
new file mode 100644 (file)
index 0000000..b597aab
--- /dev/null
@@ -0,0 +1,32 @@
+module test3 {
+
+    yang-version 1;
+    namespace "urn:simple.demo.test3";
+    prefix "t3";
+    
+    import custom-types-test {
+        prefix "custom";
+    }
+    
+    organization "opendaylight";
+    contact "WILL-BE-DEFINED-LATER";
+        revision 2013-06-18 {
+    }
+
+    identity pt {
+        base custom:service-type;
+    }
+    
+    container network {
+        custom:mountpoint point {
+            mnt:target-ref target;
+        }
+        
+        description "network-description";
+        reference "network-reference";
+        status obsolete;
+        config true;
+        presence "some presence text";
+    }
+
+}
index 03a8962d552c26031e51f178e0160c30a77e8d8f..ee4163da48c082531c4f4c99179d242b7f5c383c 100644 (file)
@@ -19,7 +19,7 @@ public interface ChoiceNode extends DataSchemaNode, AugmentationTarget {
      * @return ChoiceCaseNode objects defined in this node
      */
     Set<ChoiceCaseNode> getCases();
-    
+
     String getDefaultCase();
 
 }
index f2171480a07c2b2316358a826afe9c70c162a03b..51dd9f65074d2113314d6a27182d889b8b0adc37 100644 (file)
@@ -48,4 +48,6 @@ public interface Module extends DataNodeContainer {
 \r
     List<ExtensionDefinition> getExtensionSchemaNodes();\r
 \r
+    List<UnknownSchemaNode> getUnknownSchemaNodes();\r
+\r
 }\r
index 8e7686cf3b72d0554d92a5547fef99d518498557..b3e06777c5e8a7fe4ddc748f9cbeeeed9f2d88eb 100644 (file)
@@ -8,9 +8,9 @@
 package org.opendaylight.controller.yang.model.api;\r
 \r
 /**\r
- * Interface describing YANG 'notification' statement. The\r
- * notification statement is used to define a NETCONF notification.\r
+ * Interface describing YANG 'notification' statement. The notification\r
+ * statement is used to define a NETCONF notification.\r
  */\r
-public interface NotificationDefinition extends SchemaNode, DataNodeContainer {\r
+public interface NotificationDefinition extends SchemaNode, DataNodeContainer, AugmentationTarget {\r
 \r
 }\r
index 79b211f263e3fc40415463eb48a9743185d2eba5..ad903e9e52c45e7e0f74ad950f487fee35fb3930 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefini
  * interface which represents UNSIGNED Integer values defined in Yang language. <br>
  * The integer built-in types in Yang are uint8, uint16, uint32, and uint64.
  * They represent unsigned integers of different sizes:
- * 
+ *
  * <ul>
  * <li>uint8 - represents integer values between 0 and 255, inclusively.</li>
  * <li>uint16 - represents integer values between 0 and 65535, inclusively.</li>
@@ -28,7 +28,7 @@ import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefini
  * <li>uint64 - represents integer values between 0 and 18446744073709551615,
  * inclusively.</li>
  * </ul>
- * 
+ *
  */
 public abstract class AbstractUnsignedInteger implements UnsignedIntegerTypeDefinition {
     private static final long MIN_VALUE = 0;
@@ -40,7 +40,7 @@ public abstract class AbstractUnsignedInteger implements UnsignedIntegerTypeDefi
     private final List<RangeConstraint> rangeStatements;
 
     /**
-     * 
+     *
      * @param actualPath
      * @param namespace
      * @param revision