Bug 527: fixed augment deserialization from xml.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / util / CopyUtils.java
index efd3736c6385bc7a811eeb3ec9001cb2cc2d3706..4ab49fea230e960cbc475d6d932a03096ba4d7aa 100644 (file)
@@ -9,12 +9,11 @@ package org.opendaylight.yangtools.yang.parser.util;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
@@ -39,9 +38,25 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.UsesNodeBuilderImpl;
 
-public class CopyUtils {
+public final class CopyUtils {
 
-    public static DataSchemaNodeBuilder copy(DataSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
+    private CopyUtils() {
+    }
+
+    /**
+     * Create copy of DataSchemaNodeBuilder with new parent. If updateQName is
+     * true, qname of node will be corrected based on new parent.
+     *
+     * @param old
+     *            builder to copy
+     * @param newParent
+     *            new parent
+     * @param updateQName
+     *            flag to indicate if qname should be updated based on new
+     *            parent location
+     * @return copy of given builder
+     */
+    public static DataSchemaNodeBuilder copy(final DataSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
         if (old instanceof AnyXmlBuilder) {
             return copy((AnyXmlBuilder) old, newParent, updateQName);
         } else if (old instanceof ChoiceBuilder) {
@@ -57,312 +72,287 @@ public class CopyUtils {
         } else if (old instanceof ChoiceCaseBuilder) {
             return copy((ChoiceCaseBuilder) old, newParent, updateQName);
         } else {
-            throw new YangParseException(old.getModuleName(), old.getLine(), "Failed to copy node " + old);
+            throw new YangParseException(old.getModuleName(), old.getLine(),
+                    "Failed to copy node: Unknown type of DataSchemaNode: " + old);
         }
     }
 
-    private static AnyXmlBuilder copy(AnyXmlBuilder old, Builder newParent, boolean updateQName) {
+    private static AnyXmlBuilder copy(final AnyXmlBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        AnyXmlBuilder c = new AnyXmlBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
-        copyConstraints(c.getConstraints(), old.getConstraints());
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setAugmenting(old.isAugmenting());
-        c.setAddedByUses(old.isAddedByUses());
-        c.setConfiguration(old.isConfiguration());
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        AnyXmlBuilder copy = new AnyXmlBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
+        copyConstraints(copy.getConstraints(), old.getConstraints());
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setAugmenting(old.isAugmenting());
+        copy.setAddedByUses(old.isAddedByUses());
+        copy.setConfiguration(old.isConfiguration());
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
-        return c;
+        return copy;
     }
 
-    private static ChoiceBuilder copy(ChoiceBuilder old, Builder newParent, boolean updateQName) {
+    private static ChoiceBuilder copy(final ChoiceBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        ChoiceBuilder c = new ChoiceBuilder(newParent.getModuleName(), newParent.getLine(), newQName);
-        copyConstraints(c.getConstraints(), old.getConstraints());
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setAugmenting(old.isAugmenting());
-        c.setAddedByUses(old.isAddedByUses());
-        c.setConfiguration(old.isConfiguration());
-        // TODO: built child nodes?
+        ChoiceBuilder copy = new ChoiceBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
+        copyConstraints(copy.getConstraints(), old.getConstraints());
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setAugmenting(old.isAugmenting());
+        copy.setAddedByUses(old.isAddedByUses());
+        copy.setConfiguration(old.isConfiguration());
         for (ChoiceCaseBuilder childNode : old.getCases()) {
-            c.addCase(copy(childNode, c, updateQName));
+            copy.addCase(copy(childNode, copy, updateQName));
         }
-        // TODO: built augments?
-        for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
-            c.addAugmentation(copyAugment(augment, c));
+        for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
+            copy.addAugmentation(copyAugment(augment, copy));
         }
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
-        return c;
+        return copy;
     }
 
-    private static ChoiceCaseBuilder copy(ChoiceCaseBuilder old, Builder newParent, boolean updateQName) {
+    private static ChoiceCaseBuilder copy(final ChoiceCaseBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        ChoiceCaseBuilder c = new ChoiceCaseBuilder(newParent.getModuleName(), newParent.getLine(), newQName);
-        copyConstraints(c.getConstraints(), old.getConstraints());
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setAugmenting(old.isAugmenting());
-        // TODO: built child nodes?
+        ChoiceCaseBuilder copy = new ChoiceCaseBuilder(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
+        copyConstraints(copy.getConstraints(), old.getConstraints());
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setAugmenting(old.isAugmenting());
         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
-            c.addChildNode(copy(childNode, c, updateQName));
+            copy.addChildNode(copy(childNode, copy, updateQName));
+        }
+        copy.getGroupings().addAll(old.getGroupings());
+        for (GroupingBuilder grouping : old.getGroupingBuilders()) {
+            copy.addGrouping(copy(grouping, copy, updateQName));
         }
-        // TODO: built groupings?
-        // TODO: copy groupings?
-        c.getGroupings().addAll(old.getGroupings());
-        // TODO: build typedefs?
         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
-            c.addTypedef(copy(tdb, c, updateQName));
+            copy.addTypedef(copy(tdb, copy, updateQName));
         }
-        // TODO: built uses?
-        for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
-            c.addUsesNode(copyUses(oldUses, c));
+        for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
+            copy.addUsesNode(copyUses(oldUses, copy));
         }
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
-        return c;
+        return copy;
     }
 
-    private static ContainerSchemaNodeBuilder copy(ContainerSchemaNodeBuilder old, Builder newParent,
-            boolean updateQName) {
+    private static ContainerSchemaNodeBuilder copy(final ContainerSchemaNodeBuilder old, final Builder newParent,
+            final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        ContainerSchemaNodeBuilder c = new ContainerSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
-                newQName, newSchemaPath);
-        copyConstraints(c.getConstraints(), old.getConstraints());
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setPresence(old.isPresence());
-        c.setAugmenting(old.isAugmenting());
-        c.setAddedByUses(old.isAddedByUses());
-        c.setConfiguration(old.isConfiguration());
-        // TODO: built child nodes?
+        ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(newParent.getModuleName(),
+                newParent.getLine(), newQName, newSchemaPath);
+        copyConstraints(copy.getConstraints(), old.getConstraints());
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setPresence(old.isPresence());
+        copy.setAugmenting(old.isAugmenting());
+        copy.setAddedByUses(old.isAddedByUses());
+        copy.setConfiguration(old.isConfiguration());
         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
-            c.addChildNode(copy(childNode, c, updateQName));
+            copy.addChildNode(copy(childNode, copy, updateQName));
         }
-        // TODO: built groupings?
+        copy.getGroupings().addAll(old.getGroupings());
         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
-            c.addGrouping(copy(grouping, c, updateQName));
+            copy.addGrouping(copy(grouping, copy, updateQName));
         }
-
-        // TODO: build typedefs?
         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
-            c.addTypedef(copy(tdb, c, updateQName));
+            copy.addTypedef(copy(tdb, copy, updateQName));
         }
-        // TODO: built uses?
-        for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
-            c.addUsesNode(copyUses(oldUses, c));
+        for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
+            copy.addUsesNode(copyUses(oldUses, copy));
         }
-        // TODO: built augments?
-        for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
-            c.addAugmentation(copyAugment(augment, c));
+        for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
+            copy.addAugmentation(copyAugment(augment, copy));
         }
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
-        return c;
+        return copy;
     }
 
-    private static LeafSchemaNodeBuilder copy(LeafSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
+    private static LeafSchemaNodeBuilder copy(final LeafSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        LeafSchemaNodeBuilder c = new LeafSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(), newQName,
-                newSchemaPath);
-        copyConstraints(c.getConstraints(), old.getConstraints());
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setAugmenting(old.isAugmenting());
-        c.setAddedByUses(old.isAddedByUses());
-        c.setConfiguration(old.isConfiguration());
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
+                newQName, newSchemaPath);
+        copyConstraints(copy.getConstraints(), old.getConstraints());
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setAugmenting(old.isAugmenting());
+        copy.setAddedByUses(old.isAddedByUses());
+        copy.setConfiguration(old.isConfiguration());
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
         if (old.getType() == null) {
-            c.setTypedef(copy(old.getTypedef(), c, updateQName));
+            copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
         } else {
-            c.setType(old.getType());
+            copy.setType(old.getType());
         }
 
-        c.setDefaultStr(old.getDefaultStr());
-        c.setUnits(old.getUnits());
+        copy.setDefaultStr(old.getDefaultStr());
+        copy.setUnits(old.getUnits());
 
-        return c;
+        return copy;
     }
 
-    public static LeafListSchemaNodeBuilder copy(LeafListSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
+    public static LeafListSchemaNodeBuilder copy(final LeafListSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        LeafListSchemaNodeBuilder c = new LeafListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
+        LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
                 newQName, newSchemaPath);
-        copyConstraints(c.getConstraints(), old.getConstraints());
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setAugmenting(old.isAugmenting());
-        c.setAddedByUses(old.isAddedByUses());
-        c.setConfiguration(old.isConfiguration());
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        copyConstraints(copy.getConstraints(), old.getConstraints());
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setAugmenting(old.isAugmenting());
+        copy.setAddedByUses(old.isAddedByUses());
+        copy.setConfiguration(old.isConfiguration());
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
         if (old.getType() == null) {
-            c.setTypedef(copy(old.getTypedef(), c, updateQName));
+            copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
         } else {
-            c.setType(old.getType());
+            copy.setType(old.getType());
         }
 
-        c.setUserOrdered(old.isUserOrdered());
+        copy.setUserOrdered(old.isUserOrdered());
 
-        return c;
+        return copy;
     }
 
-    private static ListSchemaNodeBuilder copy(ListSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
+    private static ListSchemaNodeBuilder copy(final ListSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        ListSchemaNodeBuilder c = new ListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(), newQName,
-                newSchemaPath);
-        copyConstraints(c.getConstraints(), old.getConstraints());
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setAugmenting(old.isAugmenting());
-        c.setAddedByUses(old.isAddedByUses());
-        c.setConfiguration(old.isConfiguration());
-        // TODO: built child nodes?
+        ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
+                newQName, newSchemaPath);
+        copyConstraints(copy.getConstraints(), old.getConstraints());
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setAugmenting(old.isAugmenting());
+        copy.setAddedByUses(old.isAddedByUses());
+        copy.setConfiguration(old.isConfiguration());
         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
-            c.addChildNode(copy(childNode, c, updateQName));
+            copy.addChildNode(copy(childNode, copy, updateQName));
         }
-        // TODO: built groupings?
+        copy.getGroupings().addAll(old.getGroupings());
         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
-            c.addGrouping(copy(grouping, c, updateQName));
+            copy.addGrouping(copy(grouping, copy, updateQName));
         }
-
-        // TODO: build typedefs?
         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
-            c.addTypedef(copy(tdb, c, updateQName));
+            copy.addTypedef(copy(tdb, copy, updateQName));
         }
-        // TODO: built uses?
-        for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
-            c.addUsesNode(copyUses(oldUses, c));
+        for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
+            copy.addUsesNode(copyUses(oldUses, copy));
         }
-        // TODO: built augments?
-        for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
-            c.addAugmentation(copyAugment(augment, c));
+        for (AugmentationSchemaBuilder augment : old.getAugmentationBuilders()) {
+            copy.addAugmentation(copyAugment(augment, copy));
         }
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
-        c.setUserOrdered(old.isUserOrdered());
-        c.setKeyDefinition(old.getKeyDefinition());
+        copy.setUserOrdered(old.isUserOrdered());
+        copy.setKeys(old.getKeys());
 
-        return c;
+        return copy;
     }
 
-    public static GroupingBuilder copy(GroupingBuilder old, Builder newParent, boolean updateQName) {
+    public static GroupingBuilder copy(final GroupingBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
-        GroupingBuilder c = new GroupingBuilderImpl(newParent.getModuleName(), newParent.getLine(), newQName);
-        c.setParent(newParent);
-        c.setPath(newSchemaPath);
-        c.setDescription(old.getDescription());
-        c.setReference(old.getReference());
-        c.setStatus(old.getStatus());
-        c.setAddedByUses(old.isAddedByUses());
-        // TODO: built child nodes?
+        GroupingBuilderImpl copy = new GroupingBuilderImpl(newParent.getModuleName(), newParent.getLine(), newQName, newSchemaPath);
+        copy.setParent(newParent);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.setAddedByUses(old.isAddedByUses());
         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
-            c.addChildNode(copy(childNode, c, updateQName));
+            copy.addChildNode(copy(childNode, copy, updateQName));
         }
-        // TODO: built groupings?
+        copy.getGroupings().addAll(old.getGroupings());
         for (GroupingBuilder grouping : old.getGroupingBuilders()) {
-            c.addGrouping(copy(grouping, c, updateQName));
+            copy.addGrouping(copy(grouping, copy, updateQName));
         }
-
-        // TODO: build typedefs?
         for (TypeDefinitionBuilder tdb : old.getTypeDefinitionBuilders()) {
-            c.addTypedef(copy(tdb, c, updateQName));
+            copy.addTypedef(copy(tdb, copy, updateQName));
         }
-        // TODO: built uses?
-        for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
-            c.addUsesNode(copyUses(oldUses, c));
+        for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
+            copy.addUsesNode(copyUses(oldUses, copy));
         }
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            c.addUnknownNodeBuilder((copy(un, c, updateQName)));
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, updateQName)));
         }
 
-        return c;
+        return copy;
     }
 
-    public static TypeDefinitionBuilder copy(TypeDefinitionBuilder old, Builder newParent, boolean updateQName) {
+    public static TypeDefinitionBuilder copy(final TypeDefinitionBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
-        TypeDefinitionBuilder type = null;
+        TypeDefinitionBuilder type;
 
         if (old instanceof UnionTypeBuilder) {
+            UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
             type = new UnionTypeBuilder(newParent.getModuleName(), newParent.getLine());
+            type.setParent(newParent);
+            for (TypeDefinition<?> td : oldUnion.getTypes()) {
+                type.setType(td);
+            }
+            for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
+                type.setTypedef(copy(tdb, type, updateQName));
+            }
         } else if (old instanceof IdentityrefTypeBuilder) {
             type = new IdentityrefTypeBuilder(newParent.getModuleName(), newParent.getLine(),
                     ((IdentityrefTypeBuilder) old).getBaseString(), newSchemaPath);
+            type.setParent(newParent);
         } else {
-            type = new TypeDefinitionBuilderImpl(old.getModuleName(), newParent.getLine(), newQName);
+            type = new TypeDefinitionBuilderImpl(old.getModuleName(), newParent.getLine(), newQName, old.getPath());
             type.setParent(newParent);
-            type.setPath(newSchemaPath);
 
             if (old.getType() == null) {
                 type.setTypedef(copy(old.getTypedef(), type, updateQName));
@@ -370,7 +360,7 @@ public class CopyUtils {
                 type.setType(old.getType());
             }
 
-            for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
+            for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
                 type.addUnknownNodeBuilder((copy(un, type, updateQName)));
             }
 
@@ -389,7 +379,7 @@ public class CopyUtils {
         return type;
     }
 
-    private static ConstraintsBuilder copyConstraints(ConstraintsBuilder newConstraints, ConstraintsBuilder old) {
+    private static ConstraintsBuilder copyConstraints(final ConstraintsBuilder newConstraints, final ConstraintsBuilder old) {
         newConstraints.getMustDefinitions().addAll(old.getMustDefinitions());
         newConstraints.addWhenCondition(old.getWhenCondition());
         newConstraints.setMandatory(old.isMandatory());
@@ -398,118 +388,68 @@ public class CopyUtils {
         return newConstraints;
     }
 
-    public static UsesNodeBuilder copyUses(UsesNodeBuilder old, Builder newParent) {
-        UsesNodeBuilder u = new UsesNodeBuilderImpl(newParent.getModuleName(), newParent.getLine(),
-                old.getGroupingName());
-        u.setParent(newParent);
-        u.setGroupingPath(old.getGroupingPath());
-        u.setAugmenting(old.isAugmenting());
-        u.setAddedByUses(old.isAddedByUses());
-        u.getAugmentations().addAll(old.getAugmentations());
-        u.getRefineNodes().addAll(old.getRefineNodes());
-        u.getRefines().addAll(old.getRefines());
-        u.getFinalChildren().addAll(old.getFinalChildren());
-        u.getFinalGroupings().addAll(old.getFinalGroupings());
-        u.getFinalTypedefs().addAll(old.getFinalTypedefs());
-        u.getFinalUnknownNodes().addAll(old.getFinalUnknownNodes());
-
-        Set<DataSchemaNodeBuilder> oldChildren = old.getTargetChildren();
-        Set<DataSchemaNodeBuilder> newChildren = new HashSet<>();
-        if (oldChildren != null) {
-            for (DataSchemaNodeBuilder child : old.getTargetChildren()) {
-                newChildren.add(CopyUtils.copy(child, newParent, true));
-            }
-        }
-        u.setTargetChildren(newChildren);
-
-        Set<TypeDefinitionBuilder> oldTypedefs = old.getTargetTypedefs();
-        Set<TypeDefinitionBuilder> newTypedefs = new HashSet<>();
-        if (oldTypedefs != null) {
-            for (TypeDefinitionBuilder typedef : old.getTargetTypedefs()) {
-                newTypedefs.add(CopyUtils.copy(typedef, newParent, true));
-            }
-        }
-        u.setTargetTypedefs(newTypedefs);
-
-        Set<GroupingBuilder> oldGroupings = old.getTargetGroupings();
-        Set<GroupingBuilder> newGroupings = new HashSet<>();
-        if (oldGroupings != null) {
-            for (GroupingBuilder grouping : old.getTargetGroupings()) {
-                newGroupings.add(copy(grouping, newParent, true));
-            }
-        }
-        u.setTargetGroupings(newGroupings);
-
-        List<UnknownSchemaNodeBuilder> oldUN = old.getTargetUnknownNodes();
-        List<UnknownSchemaNodeBuilder> newUN = new ArrayList<>();
-        if (oldUN != null) {
-            for (UnknownSchemaNodeBuilder un : oldUN) {
-                newUN.add(copy(un, newParent, true));
-            }
-        }
-        u.setTargetUnknownNodes(newUN);
-
-        // u.getTargetGroupingUses().addAll(old.getTargetGroupingUses());
-        for (UsesNodeBuilder uses : old.getTargetGroupingUses()) {
-            u.getTargetGroupingUses().add(copyUses(uses, uses.getParent()));
-        }
-
-        // add new uses to collection of uses in module
-        ModuleBuilder module = ParserUtils.getParentModule(newParent);
-        module.addUsesNode(u);
-
-        return u;
+    private static UsesNodeBuilder copyUses(final UsesNodeBuilder old, final Builder newParent) {
+        UsesNodeBuilder copy = new UsesNodeBuilderImpl(newParent.getModuleName(), newParent.getLine(),
+                old.getGroupingPathAsString());
+        copy.setParent(newParent);
+        copy.setGroupingDefinition(old.getGroupingDefinition());
+        copy.setGrouping(old.getGroupingBuilder());
+        copy.setAddedByUses(old.isAddedByUses());
+        copy.getAugmentations().addAll(old.getAugmentations());
+        copy.getRefineNodes().addAll(old.getRefineNodes());
+        copy.getRefines().addAll(old.getRefines());
+        copy.setAugmenting(old.isAugmenting());
+        return copy;
     }
 
-    private static AugmentationSchemaBuilder copyAugment(AugmentationSchemaBuilder old, Builder newParent) {
-        AugmentationSchemaBuilder a = new AugmentationSchemaBuilderImpl(newParent.getModuleName(), newParent.getLine(),
-                old.getTargetPathAsString());
-        a.setParent(newParent);
-
-        a.setDescription(old.getDescription());
-        a.setReference(old.getReference());
-        a.setStatus(old.getStatus());
-        a.addWhenCondition(old.getWhenCondition());
-        // TODO: built child nodes?
+    private static AugmentationSchemaBuilder copyAugment(final AugmentationSchemaBuilder old, final Builder newParent) {
+        AugmentationSchemaBuilderImpl copy = new AugmentationSchemaBuilderImpl(newParent.getModuleName(),
+                newParent.getLine(), old.getTargetPathAsString());
+        copy.setParent(newParent);
+        copy.setCopyOf(old);
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        copy.addWhenCondition(old.getWhenCondition());
+        copy.setTargetNodeSchemaPath(old.getTargetNodeSchemaPath());
         for (DataSchemaNodeBuilder childNode : old.getChildNodeBuilders()) {
-            a.addChildNode(copy(childNode, a, false));
+            copy.addChildNode(copy(childNode, copy, false));
         }
-        // TODO: built uses?
-        for (UsesNodeBuilder oldUses : old.getUsesNodes()) {
-            a.addUsesNode(copyUses(oldUses, a));
+        for (UsesNodeBuilder oldUses : old.getUsesNodeBuilders()) {
+            copy.addUsesNode(copyUses(oldUses, copy));
         }
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
-            a.addUnknownNodeBuilder((copy(un, a, false)));
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
+            copy.addUnknownNodeBuilder((copy(un, copy, false)));
         }
 
-        return a;
+        return copy;
     }
 
-    public static UnknownSchemaNodeBuilder copy(UnknownSchemaNodeBuilder old, Builder newParent, boolean updateQName) {
+    public static UnknownSchemaNodeBuilder copy(final UnknownSchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
         DataBean data = getdata(old, newParent, updateQName);
         QName newQName = data.qname;
         SchemaPath newSchemaPath = data.schemaPath;
 
         UnknownSchemaNodeBuilder c = new UnknownSchemaNodeBuilder(newParent.getModuleName(), newParent.getLine(),
-                newQName);
+                newQName, newSchemaPath);
 
+        c.setNodeType(old.getNodeType());
+        c.setNodeParameter(old.getNodeParameter());
         c.setParent(newParent);
-        c.setPath(newSchemaPath);
         c.setDescription(old.getDescription());
         c.setReference(old.getReference());
         c.setStatus(old.getStatus());
         c.setAddedByUses(old.isAddedByUses());
-
-        // TODO: built un?
-        for (UnknownSchemaNodeBuilder un : old.getUnknownNodeBuilders()) {
+        for (UnknownSchemaNodeBuilder un : old.getUnknownNodes()) {
             c.addUnknownNodeBuilder((copy(un, c, updateQName)));
         }
+        c.setExtensionBuilder(old.getExtensionBuilder());
+        c.setExtensionDefinition(old.getExtensionDefinition());
 
         return c;
     }
 
-    private static DataBean getdata(SchemaNodeBuilder old, Builder newParent, boolean updateQName) {
+    private static DataBean getdata(final SchemaNodeBuilder old, final Builder newParent, final boolean updateQName) {
         List<QName> newPath = null;
         QName newQName = null;
         if (newParent instanceof ModuleBuilder) {
@@ -523,27 +463,23 @@ public class CopyUtils {
                 newPath = Collections.singletonList(newQName);
             }
         } else if (newParent instanceof AugmentationSchemaBuilder) {
-            // TODO: new parent is augment?
+            AugmentationSchemaBuilder augment = (AugmentationSchemaBuilder) newParent;
             ModuleBuilder parent = ParserUtils.getParentModule(newParent);
             if (updateQName) {
                 newQName = new QName(parent.getNamespace(), parent.getRevision(), parent.getPrefix(), old.getQName()
                         .getLocalName());
-                newPath = Collections.singletonList(newQName);
+                newPath = new ArrayList<>(augment.getTargetNodeSchemaPath().getPath());
+                newPath.add(newQName);
             } else {
                 newQName = old.getQName();
-                newPath = Collections.singletonList(newQName);
+                newPath = new ArrayList<>(augment.getTargetNodeSchemaPath().getPath());
+                newPath.add(newQName);
             }
 
         } else if (newParent instanceof SchemaNodeBuilder) {
             SchemaNodeBuilder parent = (SchemaNodeBuilder) newParent;
             QName parentQName = parent.getQName();
             if (updateQName) {
-                if (parentQName == null) {
-                    System.out.println("NULL");
-                }
-                if (old == null) {
-                    System.out.println("2NULL");
-                }
                 newQName = new QName(parentQName.getNamespace(), parentQName.getRevision(), parentQName.getPrefix(),
                         old.getQName().getLocalName());
                 newPath = new ArrayList<>(parent.getPath().getPath());
@@ -559,11 +495,11 @@ public class CopyUtils {
         return new DataBean(newQName, newSchemaPath);
     }
 
-    private static class DataBean {
-        private QName qname;
-        private SchemaPath schemaPath;
+    private static final class DataBean {
+        private final QName qname;
+        private final SchemaPath schemaPath;
 
-        private DataBean(QName qname, SchemaPath schemaPath) {
+        private DataBean(final QName qname, final SchemaPath schemaPath) {
             this.qname = qname;
             this.schemaPath = schemaPath;
         }