Merge "Custom Node Type jaxb string to id"
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / parser / impl / YangParserImpl.java
index 7c2aa6692b8df09ec97a9e70f92a65726613e1b4..ac2b5334fb3ec66e0cf8915fee70101f5da2e8bc 100644 (file)
@@ -12,7 +12,6 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -34,13 +33,8 @@ 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.DataSchemaNode;
-import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
 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.RpcDefinition;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
@@ -58,9 +52,10 @@ 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.ChildNodeBuilder;
+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;
@@ -73,11 +68,11 @@ import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBu
 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.TypedefBuilder;
+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.ModuleDependencySort.ModuleSimple;
 import org.opendaylight.controller.yang.parser.util.ParserUtils;
 import org.opendaylight.controller.yang.parser.util.RefineHolder;
 import org.opendaylight.controller.yang.parser.util.TypeConstraints;
@@ -86,7 +81,7 @@ import org.opendaylight.controller.yang.validator.YangModelBasicValidator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class YangParserImpl implements YangModelParser {
+public final class YangParserImpl implements YangModelParser {
 
     private static final Logger logger = LoggerFactory
             .getLogger(YangParserImpl.class);
@@ -124,6 +119,8 @@ public class YangParserImpl implements YangModelParser {
 
     private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
             final List<InputStream> yangFileStreams) {
+        // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER
+        // of items stored in map.
         final Map<String, TreeMap<Date, ModuleBuilder>> modules = new LinkedHashMap<String, TreeMap<Date, ModuleBuilder>>();
         final ParseTreeWalker walker = new ParseTreeWalker();
         final List<ParseTree> trees = parseStreams(yangFileStreams);
@@ -140,24 +137,9 @@ public class YangParserImpl implements YangModelParser {
         }
 
         // module dependency graph sorted
-        List<ModuleSimple> sorted = new ModuleDependencySort(builders).sort();
-
-        // TODO FIX THIS ASAP!
-        // FIXME this is just temp workaround the ModuleDependencySort MUST
-        // RETURN ordered List
-        // of SORTED and DEPENDECNY RESOLVED MODULE BUILDERS!!!!!!
-        final List<ModuleBuilder> orderedBuilders = new ArrayList<ModuleBuilder>();
-        for (final ModuleSimple ms : sorted) {
-            for (int i = 0; i < builders.length; ++i) {
-                if (ms.getName().equals(builders[i].getName())
-                        && ms.getRevision().equals(builders[i].getRevision())) {
-                    orderedBuilders.add(builders[i]);
-                }
-            }
-        }
-        // FIXME END OF WORKAROUND
+        List<ModuleBuilder> sorted = ModuleDependencySort.sort(builders);
 
-        for (ModuleBuilder builder : orderedBuilders) {
+        for (ModuleBuilder builder : sorted) {
             final String builderName = builder.getName();
             Date builderRevision = builder.getRevision();
             if (builderRevision == null) {
@@ -210,6 +192,9 @@ public class YangParserImpl implements YangModelParser {
         resolveAugments(modules);
 
         // build
+        // LinkedHashSet MUST be used otherwise the Set will not maintain
+        // order!
+        // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
         final Set<Module> result = new LinkedHashSet<Module>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
                 .entrySet()) {
@@ -230,7 +215,7 @@ public class YangParserImpl implements YangModelParser {
             final ModuleBuilder builder) {
         resolveDirtyNodes(modules, builder);
         resolveIdentities(modules, builder);
-        resolveUses(modules, builder);
+        resolveUsesRefines(modules, builder);
         resolveUnknownNodes(modules, builder);
     }
 
@@ -263,12 +248,13 @@ public class YangParserImpl implements YangModelParser {
                             final UnknownType unknownType = (UnknownType) td;
                             final TypeDefinitionBuilder resolvedType = resolveTypeUnion(
                                     nodeToResolve, unknownType, modules, module);
-                            union.setType(resolvedType);
+                            union.setTypedef(resolvedType);
                             toRemove.add(unknownType);
                         }
                     }
                     unionTypes.removeAll(toRemove);
                 } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
+                    // different handling for identityref types
                     IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve
                             .getTypedef();
                     nodeToResolve.setType(new IdentityrefType(findFullQName(
@@ -276,28 +262,28 @@ public class YangParserImpl implements YangModelParser {
                 } else {
                     final TypeDefinitionBuilder resolvedType = resolveType(
                             nodeToResolve, modules, module);
-                    nodeToResolve.setType(resolvedType);
+                    nodeToResolve.setTypedef(resolvedType);
                 }
             }
         }
     }
 
     private TypeDefinitionBuilder resolveType(
-            final TypeAwareBuilder typeToResolve,
+            final TypeAwareBuilder nodeToResolve,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
         final TypeConstraints constraints = new TypeConstraints();
 
-        final TypeDefinitionBuilder targetType = getTypedefBuilder(
-                typeToResolve, modules, builder);
-        final TypeConstraints tConstraints = findConstraints(typeToResolve,
+        final TypeDefinitionBuilder targetTypeBuilder = getTypeDefinitionBuilderFromDirtyNode(
+                nodeToResolve, modules, builder);
+        final TypeConstraints tConstraints = findConstraints(nodeToResolve,
                 constraints, modules, builder);
-        targetType.setRanges(tConstraints.getRange());
-        targetType.setLengths(tConstraints.getLength());
-        targetType.setPatterns(tConstraints.getPatterns());
-        targetType.setFractionDigits(tConstraints.getFractionDigits());
+        targetTypeBuilder.setRanges(tConstraints.getRange());
+        targetTypeBuilder.setLengths(tConstraints.getLength());
+        targetTypeBuilder.setPatterns(tConstraints.getPatterns());
+        targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits());
 
-        return targetType;
+        return targetTypeBuilder;
     }
 
     private TypeDefinitionBuilder resolveTypeUnion(
@@ -307,38 +293,34 @@ public class YangParserImpl implements YangModelParser {
             final ModuleBuilder builder) {
         final TypeConstraints constraints = new TypeConstraints();
 
-        final TypeDefinitionBuilder targetType = getUnionBuilder(typeToResolve,
-                unknownType, modules, builder);
+        final TypeDefinitionBuilder targetTypeBuilder = getUnionBuilder(
+                typeToResolve, unknownType, modules, builder);
         final TypeConstraints tConstraints = findConstraints(typeToResolve,
                 constraints, modules, builder);
-        targetType.setRanges(tConstraints.getRange());
-        targetType.setLengths(tConstraints.getLength());
-        targetType.setPatterns(tConstraints.getPatterns());
-        targetType.setFractionDigits(tConstraints.getFractionDigits());
+        targetTypeBuilder.setRanges(tConstraints.getRange());
+        targetTypeBuilder.setLengths(tConstraints.getLength());
+        targetTypeBuilder.setPatterns(tConstraints.getPatterns());
+        targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits());
 
-        return targetType;
+        return targetTypeBuilder;
     }
 
-    private TypeDefinitionBuilder getTypedefBuilder(
+    private TypeDefinitionBuilder getTypeDefinitionBuilderFromDirtyNode(
             final TypeAwareBuilder nodeToResolve,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder builder) {
-
-        final TypeDefinition<?> nodeToResolveBase = nodeToResolve.getType();
-        if (nodeToResolveBase != null
-                && !(nodeToResolveBase instanceof UnknownType)) {
-            return (TypeDefinitionBuilder) nodeToResolve;
-        }
+            final ModuleBuilder module) {
 
         final UnknownType unknownType = (UnknownType) nodeToResolve.getType();
         final QName unknownTypeQName = unknownType.getQName();
 
         // search for module which contains referenced typedef
         final ModuleBuilder dependentModule = findDependentModule(modules,
-                builder, unknownTypeQName.getPrefix(), nodeToResolve.getLine());
-        final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName(
-                dependentModule, unknownTypeQName.getLocalName(),
-                builder.getName(), nodeToResolve.getLine());
+                module, unknownTypeQName.getPrefix(), nodeToResolve.getLine());
+
+        final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder(
+                nodeToResolve.getPath(), dependentModule,
+                unknownTypeQName.getLocalName(), module.getName(),
+                nodeToResolve.getLine());
 
         final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
                 lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder);
@@ -363,9 +345,10 @@ public class YangParserImpl implements YangModelParser {
         // search for module which contains referenced typedef
         final ModuleBuilder dependentModule = findDependentModule(modules,
                 module, unknownTypeQName.getPrefix(), nodeToResolve.getLine());
-        final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName(
-                dependentModule, unknownTypeQName.getLocalName(),
-                module.getName(), nodeToResolve.getLine());
+        final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder(
+                nodeToResolve.getPath(), dependentModule,
+                unknownTypeQName.getLocalName(), module.getName(),
+                nodeToResolve.getLine());
 
         final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
                 lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder);
@@ -379,14 +362,14 @@ public class YangParserImpl implements YangModelParser {
         if (old instanceof UnionTypeBuilder) {
             final UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
             final UnionTypeBuilder newUnion = new UnionTypeBuilder(
-                    oldUnion.getActualPath(), oldUnion.getNamespace(),
-                    oldUnion.getRevision(), old.getLine());
+                    old.getLine());
             for (TypeDefinition<?> td : oldUnion.getTypes()) {
                 newUnion.setType(td);
             }
             for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
-                newUnion.setType(copyTypedefBuilder(tdb, true));
+                newUnion.setTypedef(copyTypedefBuilder(tdb, true));
             }
+            newUnion.setPath(old.getPath());
             return newUnion;
         }
 
@@ -394,8 +377,8 @@ public class YangParserImpl implements YangModelParser {
         final QName newName = new QName(oldName.getNamespace(),
                 oldName.getRevision(), oldName.getPrefix(),
                 oldName.getLocalName());
-        final TypeDefinitionBuilder tdb = new TypedefBuilder(newName,
-                old.getLine());
+        final TypeDefinitionBuilder tdb = new TypeDefinitionBuilderImpl(
+                newName, old.getLine());
 
         tdb.setRanges(old.getRanges());
         tdb.setLengths(old.getLengths());
@@ -405,7 +388,7 @@ public class YangParserImpl implements YangModelParser {
 
         final TypeDefinition<?> oldType = old.getType();
         if (oldType == null) {
-            tdb.setType(old.getTypedef());
+            tdb.setTypedef(old.getTypedef());
         } else {
             tdb.setType(oldType);
         }
@@ -434,7 +417,7 @@ public class YangParserImpl implements YangModelParser {
                     final UnknownType unknownType = (UnknownType) td;
                     final TypeDefinitionBuilder resolvedType = resolveTypeUnion(
                             union, unknownType, modules, builder);
-                    union.setType(resolvedType);
+                    union.setTypedef(resolvedType);
                     toRemove.add(unknownType);
                 }
             }
@@ -453,9 +436,9 @@ public class YangParserImpl implements YangModelParser {
             final String unknownTypePrefix = unknownTypeQName.getPrefix();
             final ModuleBuilder dependentModule = findDependentModule(modules,
                     builder, unknownTypePrefix, copy.getLine());
-            final TypeDefinitionBuilder utBuilder = getTypedefBuilder(copy,
-                    modules, dependentModule);
-            copy.setType(utBuilder);
+            final TypeDefinitionBuilder utBuilder = getTypeDefinitionBuilderFromDirtyNode(
+                    copy, modules, dependentModule);
+            copy.setTypedef(utBuilder);
             return copy;
         } else if (base == null && baseTdb != null) {
             // make a copy of baseTypeDef and call again
@@ -463,27 +446,14 @@ public class YangParserImpl implements YangModelParser {
                     baseTdb, true);
             final TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder(
                     baseTdbCopy, modules, builder);
-            copy.setType(baseTdbCopyResolved);
+            copy.setTypedef(baseTdbCopyResolved);
             return copy;
         } else {
-            throw new IllegalStateException("Failed to resolve type "
-                    + copy.getQName().getLocalName());
+            throw new YangParseException(copy.getLine(),
+                    "Failed to resolve type " + copy.getQName().getLocalName());
         }
     }
 
-    private TypeDefinitionBuilder findTypedefBuilder(
-            final QName unknownTypeQName,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder builder, int line) {
-        // search for module which contains referenced typedef
-        final ModuleBuilder dependentModule = findDependentModule(modules,
-                builder, unknownTypeQName.getPrefix(), line);
-        final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName(
-                dependentModule, unknownTypeQName.getLocalName(),
-                builder.getName(), line);
-        return copyTypedefBuilder(lookedUpBuilder, true);
-    }
-
     private TypeConstraints findConstraints(
             final TypeAwareBuilder nodeToResolve,
             final TypeConstraints constraints,
@@ -523,7 +493,8 @@ public class YangParserImpl implements YangModelParser {
             fractionDigits = ext.getFractionDigits();
             constraints.setFractionDigits(fractionDigits);
             return findConstraints(
-                    findTypedefBuilder(ext.getQName(), modules, builder,
+                    findTypeDefinitionBuilder(nodeToResolve.getPath(), builder,
+                            ext.getQName().getLocalName(), builder.getName(),
                             nodeToResolve.getLine()), constraints, modules,
                     builder);
         } else if (referencedType instanceof UnknownType) {
@@ -544,8 +515,9 @@ public class YangParserImpl implements YangModelParser {
             final ModuleBuilder dependentModule = findDependentModule(modules,
                     builder, unknown.getQName().getPrefix(),
                     nodeToResolve.getLine());
-            final TypeDefinitionBuilder utBuilder = findTypedefBuilder(
-                    unknown.getQName(), modules, builder,
+            final TypeDefinitionBuilder utBuilder = findTypeDefinitionBuilder(
+                    nodeToResolve.getPath(), dependentModule, unknown
+                            .getQName().getLocalName(), builder.getName(),
                     nodeToResolve.getLine());
             return findConstraints(utBuilder, constraints, modules,
                     dependentModule);
@@ -557,33 +529,73 @@ public class YangParserImpl implements YangModelParser {
     }
 
     /**
-     * Go through all typedef statements from given module and search for one
-     * with given name
+     * Search for type definition builder by name.
      *
-     * @param typedefs
-     *            typedef statements to search
-     * @param name
-     *            name of searched typedef
-     * @return typedef with name equals to given 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
      */
-    private TypeDefinitionBuilder findTypedefBuilderByName(
-            final ModuleBuilder dependentModule, final String name,
+    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;
-        final Set<TypeDefinitionBuilder> typedefs = dependentModule
+
+        Set<TypeDefinitionBuilder> typedefs = dependentModule
                 .getModuleTypedefs();
-        for (TypeDefinitionBuilder td : typedefs) {
-            if (td.getQName().getLocalName().equals(name)) {
-                result = td;
-                break;
+        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;
+                }
             }
         }
-        if (result == null) {
-            throw new YangParseException(currentModuleName, line,
-                    "Target module '" + dependentModule.getName()
-                            + "' does not contain typedef '" + name + "'.");
+
+        if (result != null) {
+            return result;
         }
-        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;
+            }
+        }
+        return null;
     }
 
     /**
@@ -616,8 +628,8 @@ public class YangParserImpl implements YangModelParser {
     }
 
     /**
-     * Go through all augmentation definitions and resolve them. This method
-     * also finds referenced node and add child nodes to it.
+     * Go through all augment definitions and resolve them. This method also
+     * finds augment target node and add child nodes to it.
      *
      * @param modules
      *            all available modules
@@ -642,7 +654,7 @@ public class YangParserImpl implements YangModelParser {
             // while all augments are not resolved
             final Iterator<ModuleBuilder> allModulesIterator = allModulesSet
                     .iterator();
-            while (!(module.getAugmentsResolved() == module.getAddedAugments()
+            while (!(module.getAugmentsResolved() == module.getAugments()
                     .size())) {
                 ModuleBuilder nextModule = null;
                 // try resolve other module augments
@@ -670,17 +682,16 @@ public class YangParserImpl implements YangModelParser {
     private void resolveAugment(
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
-        if (module.getAugmentsResolved() < module.getAddedAugments().size()) {
+        if (module.getAugmentsResolved() < module.getAugments().size()) {
             for (AugmentationSchemaBuilder augmentBuilder : module
-                    .getAddedAugments()) {
+                    .getAugments()) {
 
                 if (!augmentBuilder.isResolved()) {
                     final SchemaPath augmentTargetSchemaPath = augmentBuilder
                             .getTargetPath();
                     final List<QName> path = augmentTargetSchemaPath.getPath();
 
-                    int i = 0;
-                    final QName qname = path.get(i);
+                    final QName qname = path.get(0);
                     String prefix = qname.getPrefix();
                     if (prefix == null) {
                         prefix = module.getPrefix();
@@ -695,15 +706,18 @@ public class YangParserImpl implements YangModelParser {
                         if (childQName.getLocalName().equals(
                                 qname.getLocalName())) {
                             currentParent = child;
-                            i++;
                             break;
                         }
                     }
 
-                    for (; i < path.size(); i++) {
+                    if (currentParent == null) {
+                        continue;
+                    }
+
+                    for (int i = 1; i < path.size(); i++) {
                         final QName currentQName = path.get(i);
                         DataSchemaNodeBuilder newParent = null;
-                        for (DataSchemaNodeBuilder child : ((ChildNodeBuilder) currentParent)
+                        for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent)
                                 .getChildNodes()) {
                             final QName childQName = child.getQName();
                             if (childQName.getLocalName().equals(
@@ -724,8 +738,14 @@ public class YangParserImpl implements YangModelParser {
                             .get(path.size() - 1);
                     if (currentQName.getLocalName().equals(
                             lastAugmentPathElement.getLocalName())) {
-                        ParserUtils.fillAugmentTarget(augmentBuilder,
-                                (ChildNodeBuilder) currentParent);
+
+                        if(currentParent instanceof ChoiceBuilder) {
+                            ParserUtils.fillAugmentTarget(augmentBuilder,
+                                    (ChoiceBuilder) currentParent);
+                        } else {
+                            ParserUtils.fillAugmentTarget(augmentBuilder,
+                                    (DataNodeContainerBuilder) currentParent);
+                        }
                         ((AugmentationTargetBuilder) currentParent)
                                 .addAugmentation(augmentBuilder);
                         SchemaPath oldPath = currentParent.getPath();
@@ -753,7 +773,7 @@ public class YangParserImpl implements YangModelParser {
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         final Set<IdentitySchemaNodeBuilder> identities = module
-                .getAddedIdentities();
+                .getIdentities();
         for (IdentitySchemaNodeBuilder identity : identities) {
             final String baseIdentityName = identity.getBaseIdentityName();
             if (baseIdentityName != null) {
@@ -771,7 +791,7 @@ public class YangParserImpl implements YangModelParser {
                         modules, module, baseIdentityPrefix, identity.getLine());
 
                 final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule
-                        .getAddedIdentities();
+                        .getIdentities();
                 for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
                     if (idBuilder.getQName().getLocalName()
                             .equals(baseIdentityLocalName)) {
@@ -791,128 +811,64 @@ public class YangParserImpl implements YangModelParser {
      * @param module
      *            module being resolved
      */
-    private void resolveUses(
+    private void resolveUsesRefines(
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         final Map<List<String>, UsesNodeBuilder> moduleUses = module
-                .getAddedUsesNodes();
+                .getUsesNodes();
         for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses
                 .entrySet()) {
             final List<String> key = entry.getKey();
             final UsesNodeBuilder usesNode = entry.getValue();
+            final int line = usesNode.getLine();
 
             final String groupingName = key.get(key.size() - 1);
 
             for (RefineHolder refine : usesNode.getRefines()) {
-                // refine statements
-                final String defaultStr = refine.getDefaultStr();
-                final Boolean mandatory = refine.isMandatory();
-                final MustDefinition must = refine.getMust();
-                final Boolean presence = refine.isPresence();
-                final Integer min = refine.getMinElements();
-                final Integer max = refine.getMaxElements();
-                final List<UnknownSchemaNodeBuilder> unknownNodes = refine
-                        .getUnknownNodes();
-
-                Builder refineTarget = getRefineTargetBuilder(groupingName,
-                        refine, modules, module);
+                SchemaNodeBuilder refineTarget = getRefineNodeBuilderCopy(
+                        groupingName, refine, modules, module);
+                ParserUtils.checkRefine(refineTarget, refine);
+                ParserUtils.refineDefault(refineTarget, refine, line);
                 if (refineTarget instanceof LeafSchemaNodeBuilder) {
                     final LeafSchemaNodeBuilder leaf = (LeafSchemaNodeBuilder) refineTarget;
-                    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);
-                        }
-                    }
+                    ParserUtils.refineLeaf(leaf, refine, line);
                     usesNode.addRefineNode(leaf);
                 } else if (refineTarget instanceof ContainerSchemaNodeBuilder) {
                     final ContainerSchemaNodeBuilder container = (ContainerSchemaNodeBuilder) refineTarget;
-                    if (presence != null) {
-                        container.setPresence(presence);
-                    }
-                    if (must != null) {
-                        container.getConstraints().addMustDefinition(must);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            container.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineContainer(container, refine, line);
                     usesNode.addRefineNode(container);
                 } else if (refineTarget instanceof ListSchemaNodeBuilder) {
                     final ListSchemaNodeBuilder list = (ListSchemaNodeBuilder) refineTarget;
-                    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);
-                        }
-                    }
+                    ParserUtils.refineList(list, refine, line);
+                    usesNode.addRefineNode(list);
                 } else if (refineTarget instanceof LeafListSchemaNodeBuilder) {
-                    final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) getRefineTargetBuilder(
-                            groupingName, refine, modules, module);
-                    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);
-                        }
-                    }
+                    final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) refineTarget;
+                    ParserUtils.refineLeafList(leafList, refine, line);
+                    usesNode.addRefineNode(leafList);
                 } else if (refineTarget instanceof ChoiceBuilder) {
                     final ChoiceBuilder choice = (ChoiceBuilder) refineTarget;
-                    if (defaultStr != null) {
-                        choice.setDefaultCase(defaultStr);
-                    }
-                    if (mandatory != null) {
-                        choice.getConstraints().setMandatory(mandatory);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            choice.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineChoice(choice, refine, line);
+                    usesNode.addRefineNode(choice);
                 } else if (refineTarget instanceof AnyXmlBuilder) {
                     final AnyXmlBuilder anyXml = (AnyXmlBuilder) refineTarget;
-                    if (mandatory != null) {
-                        anyXml.getConstraints().setMandatory(mandatory);
-                    }
-                    if (must != null) {
-                        anyXml.getConstraints().addMustDefinition(must);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            anyXml.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineAnyxml(anyXml, refine, line);
+                    usesNode.addRefineNode(anyXml);
+                } else if (refineTarget instanceof GroupingBuilder) {
+                    usesNode.addRefineNode(refineTarget);
+                } else if (refineTarget instanceof TypeDefinitionBuilder) {
+                    usesNode.addRefineNode(refineTarget);
                 }
             }
         }
     }
 
     /**
-     * Find original builder of refine node and return copy of this builder.
+     * 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 groupingPath
      *            path to grouping which contains node to refine
@@ -922,11 +878,11 @@ public class YangParserImpl implements YangModelParser {
      *            all loaded modules
      * @param module
      *            current module
-     * @return copy of Builder object of node to be refined if it is present in
-     *         grouping, null otherwise
+     * @return copy of node to be refined if it is present in grouping, null
+     *         otherwise
      */
-    private Builder getRefineTargetBuilder(final String groupingPath,
-            final RefineHolder refine,
+    private SchemaNodeBuilder getRefineNodeBuilderCopy(
+            final String groupingPath, final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
         Builder result = null;
@@ -950,11 +906,17 @@ public class YangParserImpl implements YangModelParser {
         } 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 result;
+        return (SchemaNodeBuilder) result;
     }
 
     /**
@@ -962,8 +924,8 @@ public class YangParserImpl implements YangModelParser {
      *
      * @param groupingPath
      *            path to grouping which contains node to refine
-     * @param refineNodeName
-     *            name of node to be refined
+     * @param refine
+     *            object containing refine information
      * @param modules
      *            all loaded modules
      * @param module
@@ -975,6 +937,7 @@ public class YangParserImpl implements YangModelParser {
             final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
+        final String refineNodeName = refine.getName();
         final SchemaPath path = ParserUtils.parseUsesPath(groupingPath);
         final List<String> builderPath = new ArrayList<String>();
         String prefix = null;
@@ -988,12 +951,30 @@ public class YangParserImpl implements YangModelParser {
 
         final ModuleBuilder dependentModule = findDependentModule(modules,
                 module, prefix, refine.getLine());
-        builderPath.add(0, "grouping");
         builderPath.add(0, dependentModule.getName());
-        final GroupingBuilder builder = (GroupingBuilder) dependentModule
-                .getNode(builderPath);
+        final GroupingBuilder builder = dependentModule
+                .getGrouping(builderPath);
 
-        return builder.getChildNode(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;
+                }
+            }
+        }
+        return result;
     }
 
     private QName findFullQName(
@@ -1023,7 +1004,7 @@ public class YangParserImpl implements YangModelParser {
     private void resolveUnknownNodes(
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
-        for (UnknownSchemaNodeBuilder usnb : module.getAddedUnknownNodes()) {
+        for (UnknownSchemaNodeBuilder usnb : module.getUnknownNodes()) {
             QName nodeType = usnb.getNodeType();
             if (nodeType.getNamespace() == null
                     || nodeType.getRevision() == null) {
@@ -1053,6 +1034,8 @@ public class YangParserImpl implements YangModelParser {
      *            current module
      * @param prefix
      *            target module prefix
+     * @param line
+     *            current line in yang model
      * @return
      */
     private ModuleBuilder findDependentModule(
@@ -1099,82 +1082,4 @@ public class YangParserImpl implements YangModelParser {
         return dependentModule;
     }
 
-    private static class SchemaContextImpl implements SchemaContext {
-        private final Set<Module> modules;
-
-        private SchemaContextImpl(final Set<Module> modules) {
-            this.modules = modules;
-        }
-
-        @Override
-        public Set<DataSchemaNode> getDataDefinitions() {
-            final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
-            for (Module m : modules) {
-                dataDefs.addAll(m.getChildNodes());
-            }
-            return dataDefs;
-        }
-
-        @Override
-        public Set<Module> getModules() {
-            return modules;
-        }
-
-        @Override
-        public Set<NotificationDefinition> getNotifications() {
-            final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
-            for (Module m : modules) {
-                notifications.addAll(m.getNotifications());
-            }
-            return notifications;
-        }
-
-        @Override
-        public Set<RpcDefinition> getOperations() {
-            final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
-            for (Module m : modules) {
-                rpcs.addAll(m.getRpcs());
-            }
-            return rpcs;
-        }
-
-        @Override
-        public Set<ExtensionDefinition> getExtensions() {
-            final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
-            for (Module m : modules) {
-                extensions.addAll(m.getExtensionSchemaNodes());
-            }
-            return extensions;
-        }
-
-        @Override
-        public Module findModuleByName(final String name, final Date revision) {
-            if (name != null) {
-                for (final Module module : modules) {
-                    if (revision == null) {
-                        if (module.getName().equals(name)) {
-                            return module;
-                        }
-                    } else if (module.getName().equals(name)
-                            && module.getRevision().equals(revision)) {
-                        return module;
-                    }
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public Module findModuleByNamespace(final URI namespace) {
-            if (namespace != null) {
-                for (final Module module : modules) {
-                    if (module.getNamespace().equals(namespace)) {
-                        return module;
-                    }
-                }
-            }
-            return null;
-        }
-    }
-
 }