Added support for parsing yang models with already resolved context. 19/519/4
authorMartin Vitez <mvitez@cisco.com>
Mon, 24 Jun 2013 09:48:14 +0000 (11:48 +0200)
committerMartin Vitez <mvitez@cisco.com>
Wed, 26 Jun 2013 09:08:33 +0000 (11:08 +0200)
Added rebuild method to AugmentationTargetBuilder interface to support augmentation of resolved context.
Refactored YangParserImpl to improve readability, internal utility methods moved to ParserUtils class.
Added test to check parsing with context.
Added YangErrorListener to redirect antlr4 error messages from standard error output to logger.
Added more javadocs.

Change-Id: I838646cc4b3593a03420c1b578ee39c043f89e3d
Signed-off-by: Martin Vitez <mvitez@cisco.com>
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 842bb43..142f199 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 c56b404..8ca88d8 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 add9bac..639e18c 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 49be557..ee50d2a 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 eb3286e..6e872b3 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 d82cbe2..78284c1 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 f520bf9..1ba1a2d 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 7117afe..d54cd22 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 4831a22..e677d3c 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 a04fc3c..0558b91 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 5418e09..0681cf6 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 6fe43ad..5428259 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 96c4121..6b76314 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 b35ff4e..fdc8cd7 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 ec9c35c..786f08d 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 65839d3..63a66e0 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 fa30797..efa3849 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 f75b97d..956d8fe 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 855d026..e36adbd 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 2222901..3d3ad28 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 1a71abf..611d2ce 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 6814322..e74029b 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 8cf9cea..5c42b29 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 d38bc5e..ba3599c 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);