Bug 2444 - Yin export of all YANG statements 06/59006/25
authorPeter Kajsa <pkajsa@cisco.com>
Mon, 26 Jun 2017 09:34:49 +0000 (11:34 +0200)
committerRobert Varga <nite@hq.sk>
Tue, 3 Oct 2017 09:19:19 +0000 (09:19 +0000)
Currently yang-export exports effective world of yang into yin,
what is not correct, because lot of information is not accesible
in effective world anymore.
So the correct solution is to export declared world of yang,
where all information is accessible and in raw form and that is
exactly what we need.
Export of effective world is still retained for cases when
we don't have access to declared form of supplied module or
we want to emit also instantiated statements (e.g. statements added
by uses or augment)

Change-Id: Ic2bc559623d9e72c59e2ed7f6a797cd67933ada6
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
37 files changed:
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaContextEmitter.java
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaToStatementWriterAdaptor.java
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YangModuleWriter.java
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinExportUtils.java
yang/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/test/Bug2444Test.java
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/default.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/deviation-target.yang [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/deviation.yang [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/identities.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/import-yang1.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/include.yang [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/leafref-yang1.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/modifier-yang1.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/must.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/notification.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/submodule.yang [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yang/unique.yang
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/action@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/anydata@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/binary-spec@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/default@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/deviation-target@2017-01-20.yin [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/deviation@2017-01-20.yin [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/identities@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/import-yang1@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/import@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/include@2017-06-26.yin [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/leafref-yang1@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/leafref@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/modifier-yang1@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/modifier@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/must-yang1@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/must@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/notification@1970-01-01.yin
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/submodule@1970-01-01.yin [new file with mode: 0644]
yang/yang-model-export/src/test/resources/bugs/bug2444/yin/unique@1970-01-01.yin
yang/yang-model-export/src/test/resources/schema-context-emitter-test/foo.yin

index 96a18596daf6a40f5c13a2b4221a4ad15a9cae90..4e61b4a6f2dc99d6b4cc328363b13296b7cdd588 100644 (file)
@@ -10,7 +10,9 @@ package org.opendaylight.yangtools.yang.model.export;
 import com.google.common.annotations.Beta;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
 import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
 import com.google.common.primitives.UnsignedInteger;
 import java.net.URI;
 import java.util.Collection;
@@ -60,9 +62,87 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+import org.opendaylight.yangtools.yang.model.api.stmt.ActionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BodyGroup;
+import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContactStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionContainer;
+import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DefaultStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DocumentationGroup;
+import org.opendaylight.yangtools.yang.model.api.stmt.DocumentedConstraintGroup;
+import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IncludeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LinkageGroup;
+import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MetaGroup;
+import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModifierStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OperationGroup;
+import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PathStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PresenceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionGroup;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RpcStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement;
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
@@ -86,13 +166,13 @@ import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
 
 @Beta
 @NotThreadSafe
-class SchemaContextEmitter {
+abstract class SchemaContextEmitter {
 
-    private final YangModuleWriter writer;
-    private final boolean emitInstantiated;
-    private final boolean emitUses;
-    private final Map<QName, StatementDefinition> extensions;
-    private final YangVersion yangVersion;
+    final YangModuleWriter writer;
+    final boolean emitInstantiated;
+    final boolean emitUses;
+    final Map<QName, StatementDefinition> extensions;
+    final YangVersion yangVersion;
 
     SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
             final YangVersion yangVersion) {
@@ -109,1182 +189,2113 @@ class SchemaContextEmitter {
     }
 
     static void writeToStatementWriter(final Module module, final SchemaContext ctx,
-            final StatementTextWriter statementWriter) {
+            final StatementTextWriter statementWriter, final boolean emitInstantiated) {
         final YangModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
         final Map<QName, StatementDefinition> extensions = ExtensionStatement.mapFrom(ctx.getExtensions());
-        new SchemaContextEmitter(yangSchemaWriter, extensions, YangVersion.parse(module.getYangVersion()).orElse(null)).emitModule(module);
+        if (module instanceof EffectiveStatement && !emitInstantiated) {
+            /*
+             * if module is an effective statement and we don't want to export
+             * instantiated statements (e.g. statements added by uses or
+             * augment) we can get declared form i.e. ModuleStatement and then
+             * use DeclaredSchemaContextEmitter
+             */
+            new DeclaredSchemaContextEmitter(yangSchemaWriter, extensions,
+                    YangVersion.parse(module.getYangVersion()).orElse(null))
+                            .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
+        } else {
+            /*
+             * if we don't have access to declared form of supplied module or we
+             * want to emit also instantiated statements (e.g. statements added
+             * by uses or augment), we use EffectiveSchemaContextEmitter.
+             */
+            new EffectiveSchemaContextEmitter(yangSchemaWriter, extensions,
+                    YangVersion.parse(module.getYangVersion()).orElse(null), emitInstantiated).emitModule(module);
+        }
     }
 
-    void emitModule(final Module input) {
-        writer.startModuleNode(input.getName());
-        emitModuleHeader(input);
-        emitLinkageNodes(input);
-        emitMetaNodes(input);
-        emitRevisionNodes(input);
-        emitBodyNodes(input);
-        writer.endNode();
+    // FIXME: Probably should be moved to utils bundle.
+    static <T> boolean isPrefix(final Iterable<T> prefix, final Iterable<T> other) {
+        final Iterator<T> prefixIt = prefix.iterator();
+        final Iterator<T> otherIt = other.iterator();
+        while (prefixIt.hasNext()) {
+            if (!otherIt.hasNext()) {
+                return false;
+            }
+            if (!Objects.deepEquals(prefixIt.next(), otherIt.next())) {
+                return false;
+            }
+        }
+        return true;
     }
 
-    private void emitModuleHeader(final Module input) {
-        emitYangVersionNode(input.getYangVersion());
-        emitNamespace(input.getNamespace());
-        emitPrefixNode(input.getPrefix());
-    }
+    static class DeclaredSchemaContextEmitter extends SchemaContextEmitter {
 
-    @SuppressWarnings("unused")
-    private void emitSubmodule(final String input) {
-        /*
-         * FIXME: BUG-2444:  Implement submodule export
-         *
-         * submoduleHeaderNodes linkageNodes metaNodes revisionNodes bodyNodes
-         * writer.endNode();
-         */
-    }
+        DeclaredSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
+                final YangVersion yangVersion) {
+            super(writer, extensions, yangVersion);
+        }
 
-    @SuppressWarnings("unused")
-    private void emitSubmoduleHeaderNodes(final Module input) {
-        /*
-         * FIXME: BUG-2444:  Implement submodule headers properly
-         *
-         * :yangVersionNode //Optional
-         *
-         * :belongsToNode
-         */
-    }
+        void emitModule(final DeclaredStatement<?> declaredRootStmt) {
+            if (declaredRootStmt instanceof ModuleStatement) {
+                emitModule((ModuleStatement) declaredRootStmt);
+            } else if (declaredRootStmt instanceof SubmoduleStatement) {
+                emitSubmodule((SubmoduleStatement) declaredRootStmt);
+            } else {
+                throw new UnsupportedOperationException(
+                        String.format("Yin export: unsupported declared statement %s", declaredRootStmt));
+            }
+        }
 
-    private void emitMetaNodes(final Module input) {
-        emitOrganizationNode(input.getOrganization());
-        emitContact(input.getContact());
-        emitDescriptionNode(input.getDescription());
-        emitReferenceNode(input.getReference());
-    }
+        private void emitModule(final ModuleStatement module) {
+            super.writer.startModuleNode(module.rawArgument());
+            emitModuleHeader(module);
+            emitLinkageNodes(module);
+            emitMetaNodes(module);
+            emitRevisionNodes(module);
+            emitBodyNodes(module);
+            emitUnknownStatementNodes(module);
+            super.writer.endNode();
+        }
 
-    private void emitLinkageNodes(final Module input) {
-        for (final ModuleImport importNode : input.getImports()) {
-            emitImport(importNode);
+        private void emitModuleHeader(final ModuleStatement input) {
+            emitYangVersionNode(input.getYangVersion());
+            emitNamespace(input.getNamespace());
+            emitPrefixNode(input.getPrefix());
         }
-        /*
-         * FIXME: BUG-2444:  Emit include statements
-         */
-    }
 
-    private void emitRevisionNodes(final Module input) {
-        /*
-         * FIXME: BUG-2444:  emit revisions properly, when parsed model will provide enough
-         * information
-         */
-        emitRevision(input.getRevision());
+        private void emitSubmodule(final SubmoduleStatement submodule) {
+            super.writer.startSubmoduleNode(submodule.rawArgument());
+            emitSubmoduleHeaderNodes(submodule);
+            emitLinkageNodes(submodule);
+            emitMetaNodes(submodule);
+            emitRevisionNodes(submodule);
+            emitBodyNodes(submodule);
+            emitUnknownStatementNodes(submodule);
+            super.writer.endNode();
+        }
 
-    }
+        private void emitSubmoduleHeaderNodes(final SubmoduleStatement input) {
+            emitYangVersionNode(input.getYangVersion());
+            emitBelongsTo(input.getBelongsTo());
+        }
 
-    private void emitBodyNodes(final Module input) {
+        private void emitBelongsTo(final BelongsToStatement belongsTo) {
+            super.writer.startBelongsToNode(belongsTo.rawArgument());
+            emitPrefixNode(belongsTo.getPrefix());
+            super.writer.endNode();
+        }
 
-        for (final ExtensionDefinition extension : input.getExtensionSchemaNodes()) {
-            emitExtension(extension);
+        private void emitMetaNodes(final MetaGroup input) {
+            emitOrganizationNode(input.getOrganization());
+            emitContact(input.getContact());
+            emitDescriptionNode(input.getDescription());
+            emitReferenceNode(input.getReference());
         }
-        for (final FeatureDefinition definition : input.getFeatures()) {
-            emitFeature(definition);
+
+        private void emitLinkageNodes(final LinkageGroup input) {
+            for (final ImportStatement importNode : input.getImports()) {
+                emitImport(importNode);
+            }
+            for (final IncludeStatement importNode : input.getIncludes()) {
+                emitInclude(importNode);
+            }
         }
-        for (final IdentitySchemaNode identity : input.getIdentities()) {
-            emitIdentity(identity);
+
+        private void emitRevisionNodes(final RevisionGroup input) {
+            emitRevisions(input.getRevisions());
         }
-        for (final Deviation deviation : input.getDeviations()) {
-            emitDeviation(deviation);
+
+        private void emitBodyNodes(final BodyGroup input) {
+
+            for (final org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement extension : input
+                    .getExtensions()) {
+                emitExtension(extension);
+            }
+            for (final FeatureStatement definition : input.getFeatures()) {
+                emitFeature(definition);
+            }
+            for (final IdentityStatement identity : input.getIdentities()) {
+                emitIdentity(identity);
+            }
+            for (final DeviationStatement deviation : input.getDeviations()) {
+                emitDeviation(deviation);
+            }
+
+            emitDataNodeContainer(input);
+
+            for (final AugmentStatement augmentation : input.getAugments()) {
+                emitAugment(augmentation);
+            }
+            for (final RpcStatement rpc : input.getRpcs()) {
+                emitRpc(rpc);
+            }
+
+            emitNotifications(input.getNotifications());
         }
 
-        emitDataNodeContainer(input);
+        private void emitDataNodeContainer(final DataDefinitionContainer input) {
+            for (final DataDefinitionStatement child : input.getDataDefinitions()) {
+                emitDataSchemaNode(child);
+            }
+        }
 
-        for (final AugmentationSchema augmentation : input.getAugmentations()) {
-            emitAugment(augmentation);
+        private void emitDataNodeContainer(final DataDefinitionContainer.WithReusableDefinitions input) {
+            for (final TypedefStatement typedef : input.getTypedefs()) {
+                emitTypedefNode(typedef);
+            }
+            for (final GroupingStatement grouping : input.getGroupings()) {
+                emitGrouping(grouping);
+            }
+            for (final DataDefinitionStatement child : input.getDataDefinitions()) {
+                emitDataSchemaNode(child);
+            }
         }
-        for (final RpcDefinition rpc : input.getRpcs()) {
-            emitRpc(rpc);
+
+        private void emitDataSchemaNode(final DataDefinitionStatement child) {
+            if (child instanceof ContainerStatement) {
+                emitContainer((ContainerStatement) child);
+            } else if (child instanceof LeafStatement) {
+                emitLeaf((LeafStatement) child);
+            } else if (child instanceof LeafListStatement) {
+                emitLeafList((LeafListStatement) child);
+            } else if (child instanceof ListStatement) {
+                emitList((ListStatement) child);
+            } else if (child instanceof ChoiceStatement) {
+                emitChoice((ChoiceStatement) child);
+            } else if (child instanceof AnyxmlStatement) {
+                emitAnyxml((AnyxmlStatement) child);
+            } else if (child instanceof AnydataStatement) {
+                emitAnydata((AnydataStatement) child);
+            } else if (child instanceof UsesStatement) {
+                emitUsesNode((UsesStatement) child);
+            } else {
+                throw new UnsupportedOperationException("Not supported DataStatement type " + child.getClass());
+            }
         }
 
-        emitNotifications(input.getNotifications());
-    }
+        private void emitYangVersionNode(@Nullable final YangVersionStatement yangVersionStatement) {
+            if (yangVersionStatement != null) {
+                super.writer.startYangVersionNode(yangVersionStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitDataNodeContainer(final DataNodeContainer input) {
-        for (final TypeDefinition<?> typedef : input.getTypeDefinitions()) {
-            emitTypedefNode(typedef);
+        private void emitImport(final ImportStatement importNode) {
+            super.writer.startImportNode(importNode.rawArgument());
+            emitDocumentedNode(importNode);
+            emitPrefixNode(importNode.getPrefix());
+            emitRevisionDateNode(importNode.getRevisionDate());
+            super.writer.endNode();
         }
-        for (final GroupingDefinition grouping : input.getGroupings()) {
-            emitGrouping(grouping);
+
+        private void emitInclude(final IncludeStatement include) {
+            super.writer.startIncludeNode(include.rawArgument());
+            emitDocumentedNode(include);
+            emitRevisionDateNode(include.getRevisionDate());
+            super.writer.endNode();
         }
-        for (final DataSchemaNode child : input.getChildNodes()) {
-            emitDataSchemaNode(child);
+
+        private void emitNamespace(final NamespaceStatement namespaceStatement) {
+            Preconditions.checkNotNull(namespaceStatement, "Namespace must not be null");
+            super.writer.startNamespaceNode(namespaceStatement.getUri());
+            super.writer.endNode();
         }
-        for (final UsesNode usesNode : input.getUses()) {
-            emitUsesNode(usesNode);
+
+        private void emitPrefixNode(final PrefixStatement prefixStatement) {
+            Preconditions.checkNotNull(prefixStatement, "Prefix must not be null");
+            super.writer.startPrefixNode(prefixStatement.rawArgument());
+            super.writer.endNode();
         }
-    }
 
-    private void emitDataSchemaNode(final DataSchemaNode child) {
-        if (!emitInstantiated && (child.isAddedByUses() || child.isAugmenting())) {
-            // We skip instantiated nodes.
-            return;
-        }
-
-        if (child instanceof ContainerSchemaNode) {
-            emitContainer((ContainerSchemaNode) child);
-        } else if (child instanceof LeafSchemaNode) {
-            emitLeaf((LeafSchemaNode) child);
-        } else if (child instanceof LeafListSchemaNode) {
-            emitLeafList((LeafListSchemaNode) child);
-        } else if (child instanceof ListSchemaNode) {
-            emitList((ListSchemaNode) child);
-        } else if (child instanceof ChoiceSchemaNode) {
-            emitChoice((ChoiceSchemaNode) child);
-        } else if (child instanceof AnyXmlSchemaNode) {
-            emitAnyxml((AnyXmlSchemaNode) child);
-        } else if (child instanceof AnyDataSchemaNode) {
-            emitAnydata((AnyDataSchemaNode) child);
-        } else {
-            throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
+        private void emitOrganizationNode(@Nullable final OrganizationStatement organizationStatement) {
+            if (organizationStatement != null) {
+                super.writer.startOrganizationNode(organizationStatement.rawArgument());
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitYangVersionNode(final String input) {
-        writer.startYangVersionNode(input);
-        writer.endNode();
-    }
+        private void emitContact(@Nullable final ContactStatement contactStatement) {
+            if (contactStatement != null) {
+                super.writer.startContactNode(contactStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitImport(final ModuleImport importNode) {
-        writer.startImportNode(importNode.getModuleName());
-        emitDescriptionNode(importNode.getDescription());
-        emitReferenceNode(importNode.getReference());
-        emitPrefixNode(importNode.getPrefix());
-        emitRevisionDateNode(importNode.getRevision());
-        writer.endNode();
-    }
+        private void emitDescriptionNode(@Nullable final DescriptionStatement descriptionStatement) {
+            if (descriptionStatement != null) {
+                super.writer.startDescriptionNode(descriptionStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    @SuppressWarnings("unused")
-    private void emitInclude(final String input) {
-        /*
-         * FIXME: BUG-2444:  Implement proper export of include statements
-         * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
-         *
-         *
-         * :revisionDateNode :writer.endNode();)
-         */
-    }
+        private void emitReferenceNode(@Nullable final ReferenceStatement referenceStatement) {
+            if (referenceStatement != null) {
+                super.writer.startReferenceNode(referenceStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitNamespace(final URI uri) {
-        writer.startNamespaceNode(uri);
-        writer.endNode();
+        private void emitUnitsNode(@Nullable final UnitsStatement unitsStatement) {
+            if (unitsStatement != null) {
+                super.writer.startUnitsNode(unitsStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitRevisions(final Collection<? extends RevisionStatement> revisions) {
+            for (final RevisionStatement revisionStatement : revisions) {
+                emitRevision(revisionStatement);
+            }
+        }
 
-    private void emitPrefixNode(final String input) {
-        writer.startPrefixNode(input);
-        writer.endNode();
+        private void emitRevision(final RevisionStatement revision) {
+            super.writer.startRevisionNode(revision.rawArgument());
+            emitDocumentedNode(revision);
+            super.writer.endNode();
+        }
 
-    }
+        private void emitRevisionDateNode(@Nullable final RevisionDateStatement revisionDateStatement) {
+            if (revisionDateStatement != null) {
+                super.writer.startRevisionDateNode(revisionDateStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    @SuppressWarnings("unused")
-    private void emitBelongsTo(final String input) {
-        /*
-         * FIXME: BUG-2444:  Implement proper export of belongs-to statements
-         * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
-         *
-         *
-         * :writer.startBelongsToNode(IdentifierHelper.getIdentifier(String
-         * :input));
-         *
-         *
-         * :prefixNode
-         * :writer.endNode();
-         *
-         */
+        private void emitExtension(final org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement extension) {
+            super.writer.startExtensionNode(extension.rawArgument());
+            emitArgument(extension.getArgument());
+            emitDocumentedNodeWithStatus(extension);
+            emitUnknownStatementNodes(extension);
+            super.writer.endNode();
+        }
 
-    }
+        private void emitArgument(@Nullable final ArgumentStatement input) {
+            if (input != null) {
+                super.writer.startArgumentNode(input.rawArgument());
+                emitYinElement(input.getYinElement());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitOrganizationNode(final String input) {
-        if (!Strings.isNullOrEmpty(input)) {
-            writer.startOrganizationNode(input);
-            writer.endNode();
+        private void emitYinElement(@Nullable final YinElementStatement yinElementStatement) {
+            if (yinElementStatement != null) {
+                super.writer.startYinElementNode(yinElementStatement.rawArgument());
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitContact(final String input) {
-        if (!Strings.isNullOrEmpty(input)) {
-            writer.startContactNode(input);
-            writer.endNode();
+        private void emitIdentity(final IdentityStatement identity) {
+            super.writer.startIdentityNode(identity.rawArgument());
+            emitBaseIdentities(identity.getBases());
+            emitStatusNode(identity.getStatus());
+            emitDescriptionNode(identity.getDescription());
+            emitReferenceNode(identity.getReference());
+            super.writer.endNode();
         }
-    }
 
-    private void emitDescriptionNode(@Nullable final String input) {
-        if (!Strings.isNullOrEmpty(input)) {
-            writer.startDescriptionNode(input);
-            writer.endNode();
+        private void emitBaseIdentities(final Collection<? extends BaseStatement> collection) {
+            for (final BaseStatement baseStmt : collection) {
+                emitBase(baseStmt);
+            }
         }
-    }
 
-    private void emitReferenceNode(@Nullable final String input) {
-        if (!Strings.isNullOrEmpty(input)) {
-            writer.startReferenceNode(input);
-            writer.endNode();
+        private void emitBase(final BaseStatement baseStmt) {
+            super.writer.startBaseNode(baseStmt.rawArgument());
+            super.writer.endNode();
         }
-    }
 
-    private void emitUnitsNode(@Nullable final String input) {
-        if (!Strings.isNullOrEmpty(input)) {
-            writer.startUnitsNode(input);
-            writer.endNode();
+        private void emitFeature(final FeatureStatement feature) {
+            super.writer.startFeatureNode(feature.rawArgument());
+            emitIfFeatures(feature.getIfFeatures());
+            emitDocumentedNodeWithStatus(feature);
+            super.writer.endNode();
         }
-    }
 
-    private void emitRevision(final Date date) {
-        writer.startRevisionNode(date);
+        private void emitIfFeatures(final Collection<? extends IfFeatureStatement> ifFeatures) {
+            for (final IfFeatureStatement ifFeatureStatement : ifFeatures) {
+                emitIfFeature(ifFeatureStatement);
+            }
+        }
 
-        //
-        // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode //FIXME: BUG-2444: Optional
-        // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode //FIXME: BUG-2444: Optional
-        writer.endNode();
+        private void emitIfFeature(final IfFeatureStatement ifFeature) {
+            super.writer.startIfFeatureNode(ifFeature.rawArgument());
+            super.writer.endNode();
+        }
+
+        private void emitTypedefNode(final TypedefStatement typedef) {
+            super.writer.startTypedefNode(typedef.rawArgument());
+            emitType(typedef.getType());
+            emitUnitsNode(typedef.getUnits());
+            emitDefaultNode(typedef.getDefault());
+            emitStatusNode(typedef.getStatus());
+            emitDescriptionNode(typedef.getDescription());
+            emitReferenceNode(typedef.getReference());
+            emitUnknownStatementNodes(typedef);
+            super.writer.endNode();
+        }
+
+        private void emitType(final TypeStatement typeStatement) {
+            super.writer.startTypeNode(typeStatement.rawArgument());
+            for (final DeclaredStatement<?> typeSubstmt : typeStatement.declaredSubstatements()) {
+                if (typeSubstmt instanceof RangeStatement) {
+                    emitRange((RangeStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof LengthStatement) {
+                    emitLength((LengthStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof PatternStatement) {
+                    emitPattern((PatternStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof FractionDigitsStatement) {
+                    emitFractionDigits((FractionDigitsStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof EnumStatement) {
+                    emitEnum((EnumStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof PathStatement) {
+                    emitPath((PathStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof RequireInstanceStatement) {
+                    emitRequireInstance((RequireInstanceStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof BaseStatement) {
+                    emitBase((BaseStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof BitStatement) {
+                    emitBit((BitStatement) typeSubstmt);
+                } else if (typeSubstmt instanceof TypeStatement) {
+                    emitType((TypeStatement) typeSubstmt);
+                }
+            }
+            super.writer.endNode();
+        }
 
-    }
+        private void emitRange(final RangeStatement range) {
+            super.writer.startRangeNode(range.rawArgument());
+            emitDocumentedConstraint(range);
+            super.writer.endNode();
+        }
 
-    private void emitRevisionDateNode(@Nullable final Date date) {
-        if (date != null) {
-            writer.startRevisionDateNode(date);
-            writer.endNode();
+        private void emitFractionDigits(final FractionDigitsStatement fractionDigits) {
+            super.writer.startFractionDigitsNode(fractionDigits.rawArgument());
+            super.writer.endNode();
         }
-    }
 
-    private void emitExtension(final ExtensionDefinition extension) {
-        writer.startExtensionNode(extension.getQName());
-        emitArgument(extension.getArgument(),extension.isYinElement());
-        emitStatusNode(extension.getStatus());
-        emitDescriptionNode(extension.getDescription());
-        emitReferenceNode(extension.getReference());
-        emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
-        writer.endNode();
+        private void emitLength(final LengthStatement lengthStatement) {
+            super.writer.startLengthNode(lengthStatement.rawArgument());
+            emitDocumentedConstraint(lengthStatement);
+            super.writer.endNode();
+        }
 
-    }
+        private void emitPattern(final PatternStatement pattern) {
+            super.writer.startPatternNode(pattern.rawArgument());
+            emitModifier(pattern.getModifierStatement());
+            emitDocumentedConstraint(pattern);
+            super.writer.endNode();
+        }
 
-    private void emitArgument(final @Nullable String input, final boolean yinElement) {
-        if (input != null) {
-            writer.startArgumentNode(input);
-            emitYinElement(yinElement);
-            writer.endNode();
+        private void emitModifier(final ModifierStatement modifierStatement) {
+            if (modifierStatement != null) {
+                super.writer.startModifierNode(modifierStatement.rawArgument());
+                super.writer.endNode();
+            }
         }
 
-    }
+        private void emitDefaultNodes(final Collection<? extends DefaultStatement> collection) {
+            for (final DefaultStatement defaultValue : collection) {
+                emitDefaultNode(defaultValue);
+            }
+        }
 
-    private void emitYinElement(final boolean yinElement) {
-        writer.startYinElementNode(yinElement);
-        writer.endNode();
+        private void emitDefaultNode(@Nullable final DefaultStatement defaultStmt) {
+            if (defaultStmt != null) {
+                super.writer.startDefaultNode(defaultStmt.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitEnum(final EnumStatement enumStmt) {
+            super.writer.startEnumNode(enumStmt.rawArgument());
+            emitDocumentedNodeWithStatus(enumStmt);
+            emitValueNode(enumStmt.getValue());
+            super.writer.endNode();
+        }
 
-    private void emitIdentity(final IdentitySchemaNode identity) {
-        writer.startIdentityNode(identity.getQName());
-        emitBaseIdentities(identity.getBaseIdentities());
-        emitStatusNode(identity.getStatus());
-        emitDescriptionNode(identity.getDescription());
-        emitReferenceNode(identity.getReference());
-        writer.endNode();
-    }
+        private void emitPath(final PathStatement path) {
+            super.writer.startPathNode(path.rawArgument());
+            super.writer.endNode();
+        }
 
-    private void emitBaseIdentities(final Set<IdentitySchemaNode> identities) {
-        for (final IdentitySchemaNode identitySchemaNode : identities) {
-            emitBase(identitySchemaNode.getQName());
+        private void emitRequireInstance(final RequireInstanceStatement require) {
+            super.writer.startRequireInstanceNode(require.rawArgument());
+            super.writer.endNode();
         }
-    }
 
-    private void emitBase(final QName qName) {
-        writer.startBaseNode(qName);
-        writer.endNode();
-    }
+        private void emitBit(final BitStatement bit) {
+            super.writer.startBitNode(bit.rawArgument());
+            emitPositionNode(bit.getPosition());
+            emitDocumentedNodeWithStatus(bit);
+            super.writer.endNode();
+        }
 
-    private void emitFeature(final FeatureDefinition definition) {
-        writer.startFeatureNode(definition.getQName());
+        private void emitPositionNode(@Nullable final PositionStatement positionStatement) {
+            if (positionStatement != null) {
+                super.writer.startPositionNode(positionStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-        // FIXME: BUG-2444: FIXME: BUG-2444:  Expose ifFeature *(ifFeatureNode )
-        emitStatusNode(definition.getStatus());
-        emitDescriptionNode(definition.getDescription());
-        emitReferenceNode(definition.getReference());
-        writer.endNode();
+        private void emitStatusNode(@Nullable final StatusStatement statusStatement) {
+            if (statusStatement != null) {
+                super.writer.startStatusNode(statusStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitConfigNode(@Nullable final ConfigStatement configStatement) {
+            if (configStatement != null) {
+                super.writer.startConfigNode(configStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    @SuppressWarnings("unused")
-    private void emitIfFeature(final String input) {
-        /*
-         * FIXME: BUG-2444:  Implement proper export of include statements
-         * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
-         *
-         */
-    }
+        private void emitMandatoryNode(@Nullable final MandatoryStatement mandatoryStatement) {
+            if (mandatoryStatement != null) {
+                super.writer.startMandatoryNode(mandatoryStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitTypedefNode(final TypeDefinition<?> typedef) {
-        writer.startTypedefNode(typedef.getQName());
-        // Differentiate between derived type and existing type
-        // name.
-        emitTypeNodeDerived(typedef);
-        emitUnitsNode(typedef.getUnits());
-        emitDefaultNode(typedef.getDefaultValue());
-        emitStatusNode(typedef.getStatus());
-        emitDescriptionNode(typedef.getDescription());
-        emitReferenceNode(typedef.getReference());
-        emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
-        writer.endNode();
+        private void emitPresenceNode(@Nullable final PresenceStatement presenceStatement) {
+            if (presenceStatement != null) {
+                super.writer.startPresenceNode(presenceStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitOrderedBy(@Nullable final OrderedByStatement orderedByStatement) {
+            if (orderedByStatement != null) {
+                super.writer.startOrderedByNode(orderedByStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
-        final SchemaPath path = subtype.getPath();
-        if (isPrefix(parentPath.getPathFromRoot(), path.getPathFromRoot())) {
-            emitTypeNodeDerived(subtype);
-        } else {
-            emitTypeNodeReferenced(subtype);
+        private void emitMust(@Nullable final MustStatement must) {
+            if (must != null) {
+                super.writer.startMustNode(must.rawArgument());
+                emitErrorMessageNode(must.getErrorMessageStatement());
+                emitErrorAppTagNode(must.getErrorAppTagStatement());
+                emitDescriptionNode(must.getDescription());
+                emitReferenceNode(must.getReference());
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitTypeNodeReferenced(final TypeDefinition<?> typeDefinition) {
-        writer.startTypeNode(typeDefinition.getQName());
-        writer.endNode();
+        private void emitErrorMessageNode(@Nullable final ErrorMessageStatement errorMessageStatement) {
+            if (errorMessageStatement != null) {
+                super.writer.startErrorMessageNode(errorMessageStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitErrorAppTagNode(@Nullable final ErrorAppTagStatement errorAppTagStatement) {
+            if (errorAppTagStatement != null) {
+                super.writer.startErrorAppTagNode(errorAppTagStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitTypeNodeDerived(final TypeDefinition<?> typeDefinition) {
-        final TypeDefinition<?> b = typeDefinition.getBaseType();
-        final TypeDefinition<?> baseType = b == null ? typeDefinition : b;
-        writer.startTypeNode(baseType.getQName());
-        emitTypeBodyNodes(typeDefinition);
-        writer.endNode();
+        private void emitMinElementsNode(@Nullable final MinElementsStatement minElementsStatement) {
+            if (minElementsStatement != null) {
+                super.writer.startMinElementsNode(minElementsStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitMaxElementsNode(@Nullable final MaxElementsStatement maxElementsStatement) {
+            if (maxElementsStatement != null) {
+                super.writer.startMaxElementsNode(maxElementsStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
-        if (typeDef instanceof UnsignedIntegerTypeDefinition) {
-            emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition) typeDef);
-        } else if (typeDef instanceof IntegerTypeDefinition) {
-            emitIntegerSpefication((IntegerTypeDefinition) typeDef);
-        } else if (typeDef instanceof DecimalTypeDefinition) {
-            emitDecimal64Specification((DecimalTypeDefinition) typeDef);
-        } else if (typeDef instanceof StringTypeDefinition) {
-            emitStringRestrictions((StringTypeDefinition) typeDef);
-        } else if (typeDef instanceof EnumTypeDefinition) {
-            emitEnumSpecification((EnumTypeDefinition) typeDef);
-        } else if (typeDef instanceof LeafrefTypeDefinition) {
-            emitLeafrefSpecification((LeafrefTypeDefinition) typeDef);
-        } else if (typeDef instanceof IdentityrefTypeDefinition) {
-            emitIdentityrefSpecification((IdentityrefTypeDefinition) typeDef);
-        } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
-            emitInstanceIdentifierSpecification((InstanceIdentifierTypeDefinition) typeDef);
-        } else if (typeDef instanceof BitsTypeDefinition) {
-            emitBitsSpecification((BitsTypeDefinition) typeDef);
-        } else if (typeDef instanceof UnionTypeDefinition) {
-            emitUnionSpecification((UnionTypeDefinition) typeDef);
-        } else if (typeDef instanceof BinaryTypeDefinition) {
-            emitLength(((BinaryTypeDefinition) typeDef).getLengthConstraints());
-        } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
-            // NOOP
-        } else {
-            throw new IllegalArgumentException("Not supported type " + typeDef.getClass());
+        private void emitValueNode(@Nullable final ValueStatement valueStatement) {
+            if (valueStatement != null) {
+                super.writer.startValueNode(valueStatement.rawArgument());
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
-        emitRangeNodeOptional(typeDef.getRangeConstraints());
-    }
+        private void emitDocumentedNodeWithStatus(final DocumentationGroup.WithStatus input) {
+            emitStatusNode(input.getStatus());
+            emitDocumentedNode(input);
+        }
+
+        private void emitDocumentedNode(final DocumentationGroup input) {
+            emitDescriptionNode(input.getDescription());
+            emitReferenceNode(input.getReference());
+        }
+
+        private void emitDocumentedConstraint(final DocumentedConstraintGroup input) {
+            emitDescriptionNode(input.getDescription());
+            emitReferenceNode(input.getReference());
+            emitErrorMessageNode(input.getErrorMessageStatement());
+            emitErrorAppTagNode(input.getErrorAppTagStatement());
+        }
+
+        private void emitGrouping(final GroupingStatement grouping) {
+            super.writer.startGroupingNode(grouping.rawArgument());
+            emitDocumentedNodeWithStatus(grouping);
+            emitDataNodeContainer(grouping);
+            emitUnknownStatementNodes(grouping);
+            emitNotifications(grouping.getNotifications());
+            emitActions(grouping.getActions());
+            super.writer.endNode();
+
+        }
+
+        private void emitContainer(final ContainerStatement container) {
+            super.writer.startContainerNode(container.rawArgument());
+            emitWhen(container.getWhenStatement());
+            emitMustNodes(container.getMusts());
+            emitIfFeatures(container.getIfFeatures());
+            emitPresenceNode(container.getPresence());
+            emitConfigNode(container.getConfig());
+            emitDocumentedNodeWithStatus(container);
+            emitDataNodeContainer(container);
+            emitUnknownStatementNodes(container);
+            emitNotifications(container.getNotifications());
+            emitActions(container.getActions());
+            super.writer.endNode();
+
+        }
+
+        private void emitLeaf(final LeafStatement leaf) {
+            super.writer.startLeafNode(leaf.rawArgument());
+            emitWhen(leaf.getWhenStatement());
+            emitIfFeatures(leaf.getIfFeatures());
+            emitType(leaf.getType());
+            emitUnitsNode(leaf.getUnits());
+            emitMustNodes(leaf.getMusts());
+            emitDefaultNode(leaf.getDefault());
+            emitConfigNode(leaf.getConfig());
+            emitMandatoryNode(leaf.getMandatory());
+            emitDocumentedNodeWithStatus(leaf);
+            emitUnknownStatementNodes(leaf);
+            super.writer.endNode();
+        }
+
+        private void emitLeafList(final LeafListStatement leafList) {
+            super.writer.startLeafListNode(leafList.rawArgument());
+            emitWhen(leafList.getWhenStatement());
+            emitIfFeatures(leafList.getIfFeatures());
+            emitType(leafList.getType());
+            emitUnitsNode(leafList.getUnits());
+            emitMustNodes(leafList.getMusts());
+            emitConfigNode(leafList.getConfig());
+            emitDefaultNodes(leafList.getDefaults());
+            emitMinElementsNode(leafList.getMinElements());
+            emitMaxElementsNode(leafList.getMaxElements());
+            emitOrderedBy(leafList.getOrderedBy());
+            emitDocumentedNodeWithStatus(leafList);
+            emitUnknownStatementNodes(leafList);
+            super.writer.endNode();
+        }
+
+        private void emitList(final ListStatement list) {
+            super.writer.startListNode(list.rawArgument());
+            emitWhen(list.getWhenStatement());
+            emitIfFeatures(list.getIfFeatures());
+            emitMustNodes(list.getMusts());
+            emitKey(list.getKey());
+            emitUniqueConstraints(list.getUnique());
+            emitConfigNode(list.getConfig());
+            emitMinElementsNode(list.getMinElements());
+            emitMaxElementsNode(list.getMaxElements());
+            emitOrderedBy(list.getOrderedBy());
+            emitDocumentedNodeWithStatus(list);
+            emitDataNodeContainer(list);
+            emitUnknownStatementNodes(list);
+            emitNotifications(list.getNotifications());
+            emitActions(list.getActions());
+            super.writer.endNode();
+        }
+
+        private void emitMustNodes(final Collection<? extends MustStatement> collection) {
+            for (final MustStatement must : collection) {
+                emitMust(must);
+            }
+        }
 
-    private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
-        emitRangeNodeOptional(typeDef.getRangeConstraints());
+        private void emitKey(final KeyStatement keyStatement) {
+            if (keyStatement != null) {
+                super.writer.startKeyNode(keyStatement.rawArgument());
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitUniqueConstraints(final Collection<? extends UniqueStatement> collection) {
+            for (final UniqueStatement uniqueConstraint : collection) {
+                emitUnique(uniqueConstraint);
+            }
+        }
 
-    private void emitRangeNodeOptional(final List<RangeConstraint> list) {
-        // FIXME: BUG-2444:  Wrong decomposition in API, should be LenghtConstraint
-        // which contains ranges.
-        if (!list.isEmpty()) {
-            writer.startRangeNode(toRangeString(list));
-            final RangeConstraint first = list.iterator().next();
-            emitErrorMessageNode(first.getErrorMessage());
-            emitErrorAppTagNode(first.getErrorAppTag());
-            emitDescriptionNode(first.getDescription());
-            emitReferenceNode(first.getReference());
-            writer.endNode();
+        private void emitUnique(final UniqueStatement uniqueConstraint) {
+            if (uniqueConstraint != null) {
+                super.writer.startUniqueNode(uniqueConstraint.rawArgument());
+                super.writer.endNode();
+            }
         }
 
-    }
+        private void emitChoice(final ChoiceStatement choice) {
+            super.writer.startChoiceNode(choice.rawArgument());
+            emitWhen(choice.getWhenStatement());
+            emitIfFeatures(choice.getIfFeatures());
+            emitDefaultNode(choice.getDefault());
+            emitConfigNode(choice.getConfig());
+            emitMandatoryNode(choice.getMandatory());
+            emitDocumentedNodeWithStatus(choice);
+            emitCases(choice.getCases());
+            emitUnknownStatementNodes(choice);
+            super.writer.endNode();
+        }
+
+        private void emitShortCases(final Collection<? extends DeclaredStatement<?>> declaredSubstatements) {
+            for (final DeclaredStatement<?> child : declaredSubstatements) {
+                if (child instanceof ContainerStatement) {
+                    emitContainer((ContainerStatement) child);
+                } else if (child instanceof LeafStatement) {
+                    emitLeaf((LeafStatement) child);
+                } else if (child instanceof LeafListStatement) {
+                    emitLeafList((LeafListStatement) child);
+                } else if (child instanceof ListStatement) {
+                    emitList((ListStatement) child);
+                } else if (child instanceof ChoiceStatement) {
+                    emitChoice((ChoiceStatement) child);
+                } else if (child instanceof AnyxmlStatement) {
+                    emitAnyxml((AnyxmlStatement) child);
+                } else if (child instanceof AnydataStatement) {
+                    emitAnydata((AnydataStatement) child);
+                }
+            }
+        }
 
-    private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
-        emitFranctionDigitsNode(typeDefinition.getFractionDigits());
-        emitRangeNodeOptional(typeDefinition.getRangeConstraints());
+        private void emitCases(final Collection<? extends CaseStatement> cases) {
+            for (final CaseStatement caze : cases) {
+                if (isExplicitStatement(caze)) {
+                    emitCaseNode(caze);
+                } else {
+                    final Collection<? extends DeclaredStatement<?>> shortCaseChilds = caze.declaredSubstatements();
+                    Preconditions.checkState(shortCaseChilds.size() == 1,
+                            "Only one child is allowed for each short case node");
+                    emitShortCases(shortCaseChilds);
+                }
+            }
+        }
 
-    }
+        private void emitCaseNode(final CaseStatement caze) {
+            super.writer.startCaseNode(caze.rawArgument());
+            emitWhen(caze.getWhenStatement());
+            emitIfFeatures(caze.getIfFeatures());
+            emitDocumentedNodeWithStatus(caze);
+            emitDataNodeContainer(caze);
+            emitUnknownStatementNodes(caze);
+            super.writer.endNode();
+        }
+
+        private void emitAnyxml(final AnyxmlStatement anyxml) {
+            super.writer.startAnyxmlNode(anyxml.rawArgument());
+            emitDocumentedNodeWithStatus(anyxml);
+            emitWhen(anyxml.getWhenStatement());
+            emitIfFeatures(anyxml.getIfFeatures());
+            emitMustNodes(anyxml.getMusts());
+            emitConfigNode(anyxml.getConfig());
+            emitMandatoryNode(anyxml.getMandatory());
+            emitDocumentedNodeWithStatus(anyxml);
+            emitUnknownStatementNodes(anyxml);
+            super.writer.endNode();
+        }
+
+        private void emitAnydata(final AnydataStatement anydata) {
+            super.writer.startAnydataNode(anydata.rawArgument());
+            emitWhen(anydata.getWhenStatement());
+            emitIfFeatures(anydata.getIfFeatures());
+            emitMustNodes(anydata.getMusts());
+            emitConfigNode(anydata.getConfig());
+            emitMandatoryNode(anydata.getMandatory());
+            emitDocumentedNodeWithStatus(anydata);
+            emitUnknownStatementNodes(anydata);
+            super.writer.endNode();
+        }
+
+        private void emitUsesNode(final UsesStatement uses) {
+            super.writer.startUsesNode(uses.rawArgument());
+            emitWhen(uses.getWhenStatement());
+            emitIfFeatures(uses.getIfFeatures());
+            emitDocumentedNodeWithStatus(uses);
+            for (final RefineStatement refine : uses.getRefines()) {
+                emitRefine(refine);
+            }
+            for (final AugmentStatement aug : uses.getAugments()) {
+                emitUsesAugmentNode(aug);
+            }
+            super.writer.endNode();
+        }
+
+        private void emitRefine(final RefineStatement refine) {
+            super.writer.startRefineNode(refine.rawArgument());
+            emitDocumentedNode(refine);
+            emitIfFeatures(refine.getIfFeatures());
+            emitMustNodes(refine.getMusts());
+            emitPresenceNode(refine.getPresence());
+            emitDefaultNodes(refine.getDefaults());
+            emitConfigNode(refine.getConfig());
+            emitMandatoryNode(refine.getMandatory());
+            emitMinElementsNode(refine.getMinElements());
+            emitMaxElementsNode(refine.getMaxElements());
+            super.writer.endNode();
+        }
+
+        private void emitUsesAugmentNode(final AugmentStatement aug) {
+            /**
+             * differs only in location in schema, otherwise currently (as of
+             * RFC6020) it is same, so we could freely reuse path.
+             */
+            emitAugment(aug);
+        }
+
+        private void emitAugment(final AugmentStatement augmentation) {
+            super.writer.startAugmentNode(augmentation.rawArgument());
+            emitIfFeatures(augmentation.getIfFeatures());
+            emitWhen(augmentation.getWhenStatement());
+            emitDocumentedNodeWithStatus(augmentation);
+            emitDataNodeContainer(augmentation);
+            emitCases(augmentation.getCases());
+            emitUnknownStatementNodes(augmentation);
+            emitNotifications(augmentation.getNotifications());
+            emitActions(augmentation.getActions());
+            super.writer.endNode();
+        }
+
+        private void emitUnknownStatementNodes(final DeclaredStatement<?> decaredStmt) {
+            final Collection<? extends DeclaredStatement<?>> unknownStmts = Collections2
+                    .filter(decaredStmt.declaredSubstatements(), Predicates.instanceOf(UnknownStatement.class));
+            for (final DeclaredStatement<?> unknonwnStmt : unknownStmts) {
+                emitUnknownStatementNode(unknonwnStmt);
+            }
+        }
 
-    private void emitFranctionDigitsNode(final Integer fractionDigits) {
-        writer.startFractionDigitsNode(fractionDigits);
-        writer.endNode();
-    }
+        private void emitUnknownStatementNode(final DeclaredStatement<?> unknonwnStmt) {
+            final StatementDefinition def = unknonwnStmt.statementDefinition();
+            if (def.getArgumentName() == null) {
+                super.writer.startUnknownNode(def);
+            } else {
+                super.writer.startUnknownNode(def, unknonwnStmt.rawArgument());
+            }
+            emitUnknownStatementNodes(unknonwnStmt);
+            super.writer.endNode();
+        }
+
+        private void emitWhen(final WhenStatement whenStatement) {
+            if (whenStatement != null) {
+                super.writer.startWhenNode(whenStatement.rawArgument());
+                emitDocumentedNode(whenStatement);
+                super.writer.endNode();
+            }
+        }
 
-    private void emitStringRestrictions(final StringTypeDefinition typeDef) {
+        private void emitRpc(final RpcStatement rpc) {
+            super.writer.startRpcNode(rpc.rawArgument());
+            emitOperationBody(rpc);
+            emitUnknownStatementNodes(rpc);
+            super.writer.endNode();
+        }
 
-        // FIXME: BUG-2444:  Wrong decomposition in API, should be LenghtConstraint
-        // which contains ranges.
-        emitLength(typeDef.getLengthConstraints());
+        private void emitOperationBody(final OperationGroup operationStmt) {
+            emitIfFeatures(operationStmt.getIfFeatures());
+            emitStatusNode(operationStmt.getStatus());
+            emitDescriptionNode(operationStmt.getDescription());
+            emitReferenceNode(operationStmt.getReference());
 
-        for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
-            emitPatternNode(pattern);
+            for (final TypedefStatement typedef : operationStmt.getTypedefs()) {
+                emitTypedefNode(typedef);
+            }
+            for (final GroupingStatement grouping : operationStmt.getGroupings()) {
+                emitGrouping(grouping);
+            }
+            emitInput(operationStmt.getInput());
+            emitOutput(operationStmt.getOutput());
         }
 
-    }
+        private void emitActions(final Collection<? extends ActionStatement> collection) {
+            for (final ActionStatement actionDefinition : collection) {
+                emitAction(actionDefinition);
+            }
+        }
 
-    private void emitLength(final List<LengthConstraint> list) {
-        if (!list.isEmpty()) {
-            writer.startLengthNode(toLengthString(list));
-            // FIXME: BUG-2444:  Workaround for incorrect decomposition in API
-            final LengthConstraint first = list.iterator().next();
-            emitErrorMessageNode(first.getErrorMessage());
-            emitErrorAppTagNode(first.getErrorAppTag());
-            emitDescriptionNode(first.getDescription());
-            emitReferenceNode(first.getReference());
-            writer.endNode();
+        private void emitAction(final ActionStatement actionDefinition) {
+            super.writer.startActionNode(actionDefinition.rawArgument());
+            emitOperationBody(actionDefinition);
+            emitUnknownStatementNodes(actionDefinition);
+            super.writer.endNode();
         }
-    }
 
-    private static String toLengthString(final List<LengthConstraint> list) {
-        final Iterator<LengthConstraint> it = list.iterator();
-        if (!it.hasNext()) {
-            return "";
+        private void emitInput(final InputStatement inputStatement) {
+            if (isExplicitStatement(inputStatement)) {
+                super.writer.startInputNode();
+                emitMustNodes(inputStatement.getMusts());
+                emitDataNodeContainer(inputStatement);
+                emitUnknownStatementNodes(inputStatement);
+                super.writer.endNode();
+            }
         }
 
-        final StringBuilder sb = new StringBuilder();
-        boolean haveNext;
-        do {
-            final LengthConstraint current = it.next();
-            haveNext = it.hasNext();
-            appendRange(sb, current.getMin(), current.getMax(), haveNext);
-        } while (haveNext);
+        private void emitOutput(final OutputStatement output) {
+            if (isExplicitStatement(output)) {
+                super.writer.startOutputNode();
+                emitMustNodes(output.getMusts());
+                emitDataNodeContainer(output);
+                emitUnknownStatementNodes(output);
+                super.writer.endNode();
+            }
+        }
 
-        return sb.toString();
-    }
+        private static boolean isExplicitStatement(final DeclaredStatement<?> stmt) {
+            return stmt != null && stmt.getStatementSource() == StatementSource.DECLARATION;
+        }
 
-    private static String toRangeString(final List<RangeConstraint> list) {
-        final Iterator<RangeConstraint> it = list.iterator();
-        if (!it.hasNext()) {
-            return "";
+        private void emitNotifications(final Collection<? extends NotificationStatement> collection) {
+            for (final NotificationStatement notification : collection) {
+                emitNotificationNode(notification);
+            }
         }
 
-        final StringBuilder sb = new StringBuilder();
-        boolean haveNext;
-        do {
-            final RangeConstraint current = it.next();
-            haveNext = it.hasNext();
-            appendRange(sb, current.getMin(), current.getMax(), haveNext);
-        } while (haveNext);
+        private void emitNotificationNode(final NotificationStatement notification) {
+            super.writer.startNotificationNode(notification.rawArgument());
+            emitIfFeatures(notification.getIfFeatures());
+            emitMustNodes(notification.getMusts());
+            emitDocumentedNodeWithStatus(notification);
+            emitDataNodeContainer(notification);
+            emitUnknownStatementNodes(notification);
+            super.writer.endNode();
+        }
 
-        return sb.toString();
-    }
+        private void emitDeviation(final DeviationStatement deviation) {
+            super.writer.startDeviationNode(deviation.rawArgument());
+            emitDeviateStatements(deviation.getDeviateStatements());
+            emitUnknownStatementNodes(deviation);
+            super.writer.endNode();
+        }
 
-    private static void appendRange(final StringBuilder sb, final Number min, final Number max,
-            final boolean haveNext) {
-        sb.append(min);
-        if (!min.equals(max)) {
-            sb.append("..");
-            sb.append(max);
+        private void emitDeviateStatements(final Collection<? extends DeviateStatement> deviateStatements) {
+            for (final DeviateStatement deviateStatement : deviateStatements) {
+                emitDeviate(deviateStatement);
+            }
         }
-        if (haveNext) {
-            sb.append('|');
+
+        private void emitDeviate(final DeviateStatement deviateStatement) {
+            super.writer.startDeviateNode(deviateStatement.rawArgument());
+            /*
+             * :FIXME Currently, DeviateStatementImpl contains implementation
+             * for all deviate types (i.e. add, replace, delete). However it
+             * would be better to create subinterfaces of DeviateStatement for
+             * each deviate type (i.e. AddDeviateStatement,
+             * ReplaceDeviateStatement,..) and create argument specific supports
+             * (i.e. definitions) for each deviate type (very similarly like by
+             * TypeStatement).
+             */
+            for (final DeclaredStatement<?> child : deviateStatement.declaredSubstatements()) {
+                if (child instanceof MustStatement) {
+                    emitMust((MustStatement) child);
+                } else if (child instanceof DefaultStatement) {
+                    emitDefaultNode((DefaultStatement) child);
+                } else if (child instanceof UniqueStatement) {
+                    emitUnique((UniqueStatement) child);
+                } else if (child instanceof UnitsStatement) {
+                    emitUnitsNode((UnitsStatement) child);
+                } else if (child instanceof TypeStatement) {
+                    emitType((TypeStatement) child);
+                } else if (child instanceof MinElementsStatement) {
+                    emitMinElementsNode((MinElementsStatement) child);
+                } else if (child instanceof MaxElementsStatement) {
+                    emitMaxElementsNode((MaxElementsStatement) child);
+                } else if (child instanceof MandatoryStatement) {
+                    emitMandatoryNode((MandatoryStatement) child);
+                } else if (child instanceof ConfigStatement) {
+                    emitConfigNode((ConfigStatement) child);
+                } else if (child instanceof UnknownStatement) {
+                    emitUnknownStatementNode((UnknownStatement<?>) child);
+                }
+            }
+            super.writer.endNode();
         }
     }
 
-    private void emitPatternNode(final PatternConstraint pattern) {
-        writer.startPatternNode(pattern.getRawRegularExpression());
-        // FIXME: BUG-2444: Optional
-        emitErrorMessageNode(pattern.getErrorMessage());
-        // FIXME: BUG-2444: Optional
-        emitErrorAppTagNode(pattern.getErrorAppTag());
-        emitDescriptionNode(pattern.getDescription());
-        emitModifier(pattern.getModifier());
-        writer.endNode();
-    }
+    static class EffectiveSchemaContextEmitter extends SchemaContextEmitter {
 
-    private void emitModifier(final ModifierKind modifier) {
-        if(modifier != null) {
-            writer.startModifierNode(modifier);
-            writer.endNode();
+        EffectiveSchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
+                final YangVersion yangVersion, final boolean emitInstantiated) {
+            super(writer, extensions, yangVersion, emitInstantiated, true);
         }
-    }
 
-    private void emitDefaultNodes(final Collection<String> defaults) {
-        for (final String defaultValue : defaults) {
-            emitDefaultNode(defaultValue);
+        void emitModule(final Module input) {
+            super.writer.startModuleNode(input.getName());
+            emitModuleHeader(input);
+            emitLinkageNodes(input);
+            emitMetaNodes(input);
+            emitRevisionNodes(input);
+            emitBodyNodes(input);
+            super.writer.endNode();
         }
-    }
 
-    private void emitDefaultNode(@Nullable final Object object) {
-        if (object != null) {
-            writer.startDefaultNode(object.toString());
-            writer.endNode();
+        private void emitModuleHeader(final Module input) {
+            emitYangVersionNode(input.getYangVersion());
+            emitNamespace(input.getNamespace());
+            emitPrefixNode(input.getPrefix());
         }
-    }
 
-    private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
-        for (final EnumPair enumValue : typeDefinition.getValues()) {
-            emitEnumNode(enumValue);
+        @SuppressWarnings("unused")
+        private void emitSubmodule(final String input) {
+            /*
+             * FIXME: BUG-2444: Implement submodule export
+             *
+             * submoduleHeaderNodes linkageNodes metaNodes revisionNodes
+             * bodyNodes super.writer.endNode();
+             */
         }
-    }
 
-    private void emitEnumNode(final EnumPair enumValue) {
-        writer.startEnumNode(enumValue.getName());
-        emitValueNode(enumValue.getValue());
-        emitStatusNode(enumValue.getStatus());
-        emitDescriptionNode(enumValue.getDescription());
-        emitReferenceNode(enumValue.getReference());
-        writer.endNode();
-    }
+        @SuppressWarnings("unused")
+        private void emitSubmoduleHeaderNodes(final Module input) {
+            /*
+             * FIXME: BUG-2444: Implement submodule headers properly
+             *
+             * :yangVersionNode //Optional
+             *
+             * :belongsToNode
+             */
+        }
 
-    private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
-        emitPathNode(typeDefinition.getPathStatement());
-        if (YangVersion.VERSION_1_1 == yangVersion) {
-            emitRequireInstanceNode(typeDefinition.requireInstance());
+        private void emitMetaNodes(final Module input) {
+            emitOrganizationNode(input.getOrganization());
+            emitContact(input.getContact());
+            emitDescriptionNode(input.getDescription());
+            emitReferenceNode(input.getReference());
         }
-    }
 
-    private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
-        writer.startPathNode(revisionAwareXPath);
-        writer.endNode();
-    }
+        private void emitLinkageNodes(final Module input) {
+            for (final ModuleImport importNode : input.getImports()) {
+                emitImport(importNode);
+            }
+            /*
+             * FIXME: BUG-2444: Emit include statements
+             */
+        }
 
-    private void emitRequireInstanceNode(final boolean require) {
-        writer.startRequireInstanceNode(require);
-        writer.endNode();
-    }
+        private void emitRevisionNodes(final Module input) {
+            /*
+             * FIXME: BUG-2444: emit revisions properly, when parsed model will
+             * provide enough information
+             */
+            emitRevision(input.getRevision());
 
-    private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
-        emitRequireInstanceNode(typeDefinition.requireInstance());
-    }
+        }
 
-    private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
-        emitBaseIdentities(typeDefinition.getIdentities());
-    }
+        private void emitBodyNodes(final Module input) {
+
+            for (final ExtensionDefinition extension : input.getExtensionSchemaNodes()) {
+                emitExtension(extension);
+            }
+            for (final FeatureDefinition definition : input.getFeatures()) {
+                emitFeature(definition);
+            }
+            for (final IdentitySchemaNode identity : input.getIdentities()) {
+                emitIdentity(identity);
+            }
+            for (final Deviation deviation : input.getDeviations()) {
+                emitDeviation(deviation);
+            }
 
-    private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
-        for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
-            // FIXME: BUG-2444:  What if we have locally modified types here?
-            // is solution to look-up in schema path?
-            emitTypeNode(typeDefinition.getPath(), subtype);
+            emitDataNodeContainer(input);
+
+            for (final AugmentationSchema augmentation : input.getAugmentations()) {
+                emitAugment(augmentation);
+            }
+            for (final RpcDefinition rpc : input.getRpcs()) {
+                emitRpc(rpc);
+            }
+
+            emitNotifications(input.getNotifications());
         }
-    }
 
-    private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
-        for (final Bit bit : typeDefinition.getBits()) {
-            emitBit(bit);
+        private void emitDataNodeContainer(final DataNodeContainer input) {
+            for (final TypeDefinition<?> typedef : input.getTypeDefinitions()) {
+                emitTypedefNode(typedef);
+            }
+            for (final GroupingDefinition grouping : input.getGroupings()) {
+                emitGrouping(grouping);
+            }
+            for (final DataSchemaNode child : input.getChildNodes()) {
+                emitDataSchemaNode(child);
+            }
+            for (final UsesNode usesNode : input.getUses()) {
+                emitUsesNode(usesNode);
+            }
         }
-    }
 
-    private void emitBit(final Bit bit) {
-        writer.startBitNode(bit.getName());
-        emitPositionNode(bit.getPosition());
-        emitStatusNode(bit.getStatus());
-        emitDescriptionNode(bit.getDescription());
-        emitReferenceNode(bit.getReference());
-        writer.endNode();
-    }
+        private void emitDataSchemaNode(final DataSchemaNode child) {
+            if (!super.emitInstantiated && (child.isAddedByUses() || child.isAugmenting())) {
+                // We skip instantiated nodes.
+                return;
+            }
 
-    private void emitPositionNode(@Nullable final Long position) {
-        if (position != null) {
-            writer.startPositionNode(UnsignedInteger.valueOf(position));
-            writer.endNode();
+            if (child instanceof ContainerSchemaNode) {
+                emitContainer((ContainerSchemaNode) child);
+            } else if (child instanceof LeafSchemaNode) {
+                emitLeaf((LeafSchemaNode) child);
+            } else if (child instanceof LeafListSchemaNode) {
+                emitLeafList((LeafListSchemaNode) child);
+            } else if (child instanceof ListSchemaNode) {
+                emitList((ListSchemaNode) child);
+            } else if (child instanceof ChoiceSchemaNode) {
+                emitChoice((ChoiceSchemaNode) child);
+            } else if (child instanceof AnyXmlSchemaNode) {
+                emitAnyxml((AnyXmlSchemaNode) child);
+            } else if (child instanceof AnyDataSchemaNode) {
+                emitAnydata((AnyDataSchemaNode) child);
+            } else {
+                throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
+            }
         }
-    }
 
-    private void emitStatusNode(@Nullable final Status status) {
-        if (status != null) {
-            writer.startStatusNode(status);
-            writer.endNode();
+        private void emitYangVersionNode(final String input) {
+            super.writer.startYangVersionNode(input);
+            super.writer.endNode();
         }
-    }
 
-    private void emitConfigNode(final boolean config) {
-        writer.startConfigNode(config);
-        writer.endNode();
-    }
+        private void emitImport(final ModuleImport importNode) {
+            super.writer.startImportNode(importNode.getModuleName());
+            emitDescriptionNode(importNode.getDescription());
+            emitReferenceNode(importNode.getReference());
+            emitPrefixNode(importNode.getPrefix());
+            emitRevisionDateNode(importNode.getRevision());
+            super.writer.endNode();
+        }
 
-    private void emitMandatoryNode(final boolean mandatory) {
-        writer.startMandatoryNode(mandatory);
-        writer.endNode();
-    }
+        @SuppressWarnings("unused")
+        private void emitInclude(final String input) {
+            /*
+             * FIXME: BUG-2444: Implement proper export of include statements
+             * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+             *
+             *
+             * :revisionDateNode :super.writer.endNode();)
+             */
+        }
 
-    private void emitPresenceNode(final boolean presence) {
-        writer.startPresenceNode(presence);
-        writer.endNode();
-    }
+        private void emitNamespace(final URI uri) {
+            super.writer.startNamespaceNode(uri);
+            super.writer.endNode();
 
-    private void emitOrderedBy(final boolean userOrdered) {
-        if (userOrdered) {
-            writer.startOrderedByNode("user");
-        } else {
-            writer.startOrderedByNode("system");
         }
-        writer.endNode();
-    }
 
-    private void emitMust(@Nullable final MustDefinition mustCondition) {
-        if (mustCondition != null && mustCondition.getXpath() != null) {
-            writer.startMustNode(mustCondition.getXpath());
-            emitErrorMessageNode(mustCondition.getErrorMessage());
-            emitErrorAppTagNode(mustCondition.getErrorAppTag());
-            emitDescriptionNode(mustCondition.getDescription());
-            emitReferenceNode(mustCondition.getReference());
-            writer.endNode();
+        private void emitPrefixNode(final String input) {
+            super.writer.startPrefixNode(input);
+            super.writer.endNode();
+
         }
 
-    }
+        @SuppressWarnings("unused")
+        private void emitBelongsTo(final String input) {
+            /*
+             * FIXME: BUG-2444: Implement proper export of belongs-to statements
+             * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+             *
+             *
+             * :super.writer.startBelongsToNode(IdentifierHelper.getIdentifier(
+             * String :input));
+             *
+             *
+             * :prefixNode :super.writer.endNode();
+             *
+             */
 
-    private void emitErrorMessageNode(@Nullable final String input) {
-        if (input != null && !input.isEmpty()) {
-            writer.startErrorMessageNode(input);
-            writer.endNode();
         }
-    }
 
-    private void emitErrorAppTagNode(final String input) {
-        if (input != null && !input.isEmpty()) {
-            writer.startErrorAppTagNode(input);
-            writer.endNode();
+        private void emitOrganizationNode(final String input) {
+            if (!Strings.isNullOrEmpty(input)) {
+                super.writer.startOrganizationNode(input);
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitMinElementsNode(final Integer min) {
-        if (min != null) {
-            writer.startMinElementsNode(min);
-            writer.endNode();
+        private void emitContact(final String input) {
+            if (!Strings.isNullOrEmpty(input)) {
+                super.writer.startContactNode(input);
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitMaxElementsNode(final Integer max) {
-        if (max != null) {
-            writer.startMaxElementsNode(max);
-            writer.endNode();
+        private void emitDescriptionNode(@Nullable final String input) {
+            if (!Strings.isNullOrEmpty(input)) {
+                super.writer.startDescriptionNode(input);
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitValueNode(@Nullable final Integer value) {
-        if (value != null) {
-            writer.startValueNode(value);
-            writer.endNode();
+        private void emitReferenceNode(@Nullable final String input) {
+            if (!Strings.isNullOrEmpty(input)) {
+                super.writer.startReferenceNode(input);
+                super.writer.endNode();
+            }
         }
-    }
 
-    private void emitDocumentedNode(final DocumentedNode.WithStatus input) {
-        emitStatusNode(input.getStatus());
-        emitDescriptionNode(input.getDescription());
-        emitReferenceNode(input.getReference());
-    }
+        private void emitUnitsNode(@Nullable final String input) {
+            if (!Strings.isNullOrEmpty(input)) {
+                super.writer.startUnitsNode(input);
+                super.writer.endNode();
+            }
+        }
 
-    private void emitGrouping(final GroupingDefinition grouping) {
-        writer.startGroupingNode(grouping.getQName());
-        emitDocumentedNode(grouping);
-        emitDataNodeContainer(grouping);
-        emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
-        emitNotifications(grouping.getNotifications());
-        emitActions(grouping.getActions());
-        writer.endNode();
+        private void emitRevision(final Date date) {
+            super.writer.startRevisionNode(date);
 
-    }
+            //
+            // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode
+            // //FIXME: BUG-2444: Optional
+            // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode
+            // //FIXME: BUG-2444: Optional
+            super.writer.endNode();
 
-    private void emitContainer(final ContainerSchemaNode child) {
-        writer.startContainerNode(child.getQName());
+        }
 
-        //
+        private void emitRevisionDateNode(@Nullable final Date date) {
+            if (date != null) {
+                super.writer.startRevisionDateNode(date);
+                super.writer.endNode();
+            }
+        }
 
-        emitConstraints(child.getConstraints());
-        // FIXME: BUG-2444: whenNode //:Optional
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        emitPresenceNode(child.isPresenceContainer());
-        emitConfigNode(child.isConfiguration());
-        emitDocumentedNode(child);
-        emitDataNodeContainer(child);
-        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
-        emitNotifications(child.getNotifications());
-        emitActions(child.getActions());
-        writer.endNode();
+        private void emitExtension(final ExtensionDefinition extension) {
+            super.writer.startExtensionNode(extension.getQName());
+            emitArgument(extension.getArgument(), extension.isYinElement());
+            emitStatusNode(extension.getStatus());
+            emitDescriptionNode(extension.getDescription());
+            emitReferenceNode(extension.getReference());
+            emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
+            super.writer.endNode();
 
-    }
+        }
+
+        private void emitArgument(final @Nullable String input, final boolean yinElement) {
+            if (input != null) {
+                super.writer.startArgumentNode(input);
+                emitYinElement(yinElement);
+                super.writer.endNode();
+            }
 
-    private void emitConstraints(final ConstraintDefinition constraints) {
-        emitWhen(constraints.getWhenCondition());
-        for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
-            emitMust(mustCondition);
         }
-    }
 
-    private void emitLeaf(final LeafSchemaNode child) {
-        writer.startLeafNode(child.getQName());
-        emitWhen(child.getConstraints().getWhenCondition());
-        // FIXME: BUG-2444:  *(ifFeatureNode )
-        emitTypeNode(child.getPath(), child.getType());
-        emitUnitsNode(child.getUnits());
-        emitMustNodes(child.getConstraints().getMustConstraints());
-        emitDefaultNode(child.getDefault());
-        emitConfigNode(child.isConfiguration());
-        emitMandatoryNode(child.getConstraints().isMandatory());
-        emitDocumentedNode(child);
-        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
-        writer.endNode();
+        private void emitYinElement(final boolean yinElement) {
+            super.writer.startYinElementNode(yinElement);
+            super.writer.endNode();
 
-    }
+        }
 
-    private void emitLeafList(final LeafListSchemaNode child) {
-        writer.startLeafListNode(child.getQName());
-
-        emitWhen(child.getConstraints().getWhenCondition());
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        emitTypeNode(child.getPath(), child.getType());
-        emitUnitsNode(child.getType().getUnits());
-        // FIXME: BUG-2444: unitsNode /Optional
-        emitMustNodes(child.getConstraints().getMustConstraints());
-        emitConfigNode(child.isConfiguration());
-        emitDefaultNodes(child.getDefaults());
-        emitMinElementsNode(child.getConstraints().getMinElements());
-        emitMaxElementsNode(child.getConstraints().getMaxElements());
-        emitOrderedBy(child.isUserOrdered());
-        emitDocumentedNode(child);
-        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
-        writer.endNode();
+        private void emitIdentity(final IdentitySchemaNode identity) {
+            super.writer.startIdentityNode(identity.getQName());
+            emitBaseIdentities(identity.getBaseIdentities());
+            emitStatusNode(identity.getStatus());
+            emitDescriptionNode(identity.getDescription());
+            emitReferenceNode(identity.getReference());
+            super.writer.endNode();
+        }
 
-    }
+        private void emitBaseIdentities(final Set<IdentitySchemaNode> identities) {
+            for (final IdentitySchemaNode identitySchemaNode : identities) {
+                emitBase(identitySchemaNode.getQName());
+            }
+        }
 
-    private void emitList(final ListSchemaNode child) {
-        writer.startListNode(child.getQName());
-        emitWhen(child.getConstraints().getWhenCondition());
-
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        emitMustNodes(child.getConstraints().getMustConstraints());
-        emitKey(child.getKeyDefinition());
-        emitUniqueConstraints(child.getUniqueConstraints());
-        emitConfigNode(child.isConfiguration());
-        emitMinElementsNode(child.getConstraints().getMinElements());
-        emitMaxElementsNode(child.getConstraints().getMaxElements());
-        emitOrderedBy(child.isUserOrdered());
-        emitDocumentedNode(child);
-        emitDataNodeContainer(child);
-        emitUnknownStatementNodes(child.getUnknownSchemaNodes());
-        emitNotifications(child.getNotifications());
-        emitActions(child.getActions());
-        writer.endNode();
+        private void emitBase(final QName qName) {
+            super.writer.startBaseNode(qName);
+            super.writer.endNode();
+        }
 
-    }
+        private void emitFeature(final FeatureDefinition definition) {
+            super.writer.startFeatureNode(definition.getQName());
+
+            // FIXME: BUG-2444: FIXME: BUG-2444: Expose ifFeature
+            // *(ifFeatureNode )
+            emitStatusNode(definition.getStatus());
+            emitDescriptionNode(definition.getDescription());
+            emitReferenceNode(definition.getReference());
+            super.writer.endNode();
 
-    private void emitMustNodes(final Set<MustDefinition> mustConstraints) {
-        for (final MustDefinition must : mustConstraints) {
-            emitMust(must);
         }
-    }
 
-    private void emitKey(final List<QName> keyList) {
-        if (keyList != null && !keyList.isEmpty()) {
-            writer.startKeyNode(keyList);
-            writer.endNode();
+        @SuppressWarnings("unused")
+        private void emitIfFeature(final String input) {
+            /*
+             * FIXME: BUG-2444: Implement proper export of include statements
+             * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+             *
+             */
         }
-    }
 
-    private void emitUniqueConstraints(final Collection<UniqueConstraint> uniqueConstraints) {
-        for (final UniqueConstraint uniqueConstraint : uniqueConstraints) {
-            emitUnique(uniqueConstraint);
+        private void emitTypedefNode(final TypeDefinition<?> typedef) {
+            super.writer.startTypedefNode(typedef.getQName());
+            // Differentiate between derived type and existing type
+            // name.
+            emitTypeNodeDerived(typedef);
+            emitUnitsNode(typedef.getUnits());
+            emitDefaultNode(typedef.getDefaultValue());
+            emitStatusNode(typedef.getStatus());
+            emitDescriptionNode(typedef.getDescription());
+            emitReferenceNode(typedef.getReference());
+            emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
+            super.writer.endNode();
+
         }
-    }
 
-    private void emitUnique(final UniqueConstraint uniqueConstraint) {
-        writer.startUniqueNode(uniqueConstraint);
-        writer.endNode();
-    }
+        private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
+            final SchemaPath path = subtype.getPath();
+            if (isPrefix(parentPath.getPathFromRoot(), path.getPathFromRoot())) {
+                emitTypeNodeDerived(subtype);
+            } else {
+                emitTypeNodeReferenced(subtype);
+            }
+        }
 
-    private void emitChoice(final ChoiceSchemaNode choice) {
-        writer.startChoiceNode(choice.getQName());
-        emitWhen(choice.getConstraints().getWhenCondition());
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        // FIXME: BUG-2444: defaultNode //Optional
-        emitConfigNode(choice.isConfiguration());
-        emitMandatoryNode(choice.getConstraints().isMandatory());
-        emitDocumentedNode(choice);
-        for (final ChoiceCaseNode caze : choice.getCases()) {
-            // TODO: emit short case?
-            emitCaseNode(caze);
-        }
-        emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
-        writer.endNode();
-    }
+        private void emitTypeNodeReferenced(final TypeDefinition<?> typeDefinition) {
+            super.writer.startTypeNode(typeDefinition.getQName());
+            super.writer.endNode();
+
+        }
+
+        private void emitTypeNodeDerived(final TypeDefinition<?> typeDefinition) {
+            final TypeDefinition<?> b = typeDefinition.getBaseType();
+            final TypeDefinition<?> baseType = b == null ? typeDefinition : b;
+            super.writer.startTypeNode(baseType.getQName());
+            emitTypeBodyNodes(typeDefinition);
+            super.writer.endNode();
+
+        }
+
+        private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
+            if (typeDef instanceof UnsignedIntegerTypeDefinition) {
+                emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition) typeDef);
+            } else if (typeDef instanceof IntegerTypeDefinition) {
+                emitIntegerSpefication((IntegerTypeDefinition) typeDef);
+            } else if (typeDef instanceof DecimalTypeDefinition) {
+                emitDecimal64Specification((DecimalTypeDefinition) typeDef);
+            } else if (typeDef instanceof StringTypeDefinition) {
+                emitStringRestrictions((StringTypeDefinition) typeDef);
+            } else if (typeDef instanceof EnumTypeDefinition) {
+                emitEnumSpecification((EnumTypeDefinition) typeDef);
+            } else if (typeDef instanceof LeafrefTypeDefinition) {
+                emitLeafrefSpecification((LeafrefTypeDefinition) typeDef);
+            } else if (typeDef instanceof IdentityrefTypeDefinition) {
+                emitIdentityrefSpecification((IdentityrefTypeDefinition) typeDef);
+            } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
+                emitInstanceIdentifierSpecification((InstanceIdentifierTypeDefinition) typeDef);
+            } else if (typeDef instanceof BitsTypeDefinition) {
+                emitBitsSpecification((BitsTypeDefinition) typeDef);
+            } else if (typeDef instanceof UnionTypeDefinition) {
+                emitUnionSpecification((UnionTypeDefinition) typeDef);
+            } else if (typeDef instanceof BinaryTypeDefinition) {
+                emitLength(((BinaryTypeDefinition) typeDef).getLengthConstraints());
+            } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
+                // NOOP
+            } else {
+                throw new IllegalArgumentException("Not supported type " + typeDef.getClass());
+            }
+        }
 
-    private void emitCaseNode(final ChoiceCaseNode caze) {
-        if (!emitInstantiated && caze.isAugmenting()) {
-            return;
+        private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
+            emitRangeNodeOptional(typeDef.getRangeConstraints());
         }
-        writer.startCaseNode(caze.getQName());
-        emitWhen(caze.getConstraints().getWhenCondition());
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        emitDocumentedNode(caze);
-        emitDataNodeContainer(caze);
-        emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
-        writer.endNode();
 
-    }
+        private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
+            emitRangeNodeOptional(typeDef.getRangeConstraints());
 
-    private void emitAnyxml(final AnyXmlSchemaNode anyxml) {
-        writer.startAnyxmlNode(anyxml.getQName());
-        emitBodyOfDataSchemaNode(anyxml);
-        writer.endNode();
-    }
+        }
 
-    private void emitAnydata(final AnyDataSchemaNode anydata) {
-        writer.startAnydataNode(anydata.getQName());
-        emitBodyOfDataSchemaNode(anydata);
-        writer.endNode();
-    }
+        private void emitRangeNodeOptional(final List<RangeConstraint> list) {
+            // FIXME: BUG-2444: Wrong decomposition in API, should be
+            // LenghtConstraint
+            // which contains ranges.
+            if (!list.isEmpty()) {
+                super.writer.startRangeNode(toRangeString(list));
+                final RangeConstraint first = list.iterator().next();
+                emitErrorMessageNode(first.getErrorMessage());
+                emitErrorAppTagNode(first.getErrorAppTag());
+                emitDescriptionNode(first.getDescription());
+                emitReferenceNode(first.getReference());
+                super.writer.endNode();
+            }
 
-    private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
-        emitWhen(dataSchemaNode.getConstraints().getWhenCondition());
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
-        emitConfigNode(dataSchemaNode.isConfiguration());
-        emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
-        emitDocumentedNode(dataSchemaNode);
-        emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
-    }
+        }
 
-    private void emitUsesNode(final UsesNode usesNode) {
-        if (emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
-            writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
-            /*
-             * FIXME: BUG-2444:
-             *  whenNode /
-             *  *(ifFeatureNode )
-             * statusNode // Optional F
-             * : descriptionNode // Optional
-             * referenceNode // Optional
-             */
-            for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
-                emitRefine(refine);
+        private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
+            emitFranctionDigitsNode(typeDefinition.getFractionDigits());
+            emitRangeNodeOptional(typeDefinition.getRangeConstraints());
+
+        }
+
+        private void emitFranctionDigitsNode(final Integer fractionDigits) {
+            super.writer.startFractionDigitsNode(fractionDigits);
+            super.writer.endNode();
+        }
+
+        private void emitStringRestrictions(final StringTypeDefinition typeDef) {
+
+            // FIXME: BUG-2444: Wrong decomposition in API, should be
+            // LenghtConstraint
+            // which contains ranges.
+            emitLength(typeDef.getLengthConstraints());
+
+            for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
+                emitPatternNode(pattern);
             }
-            for (final AugmentationSchema aug : usesNode.getAugmentations()) {
-                emitUsesAugmentNode(aug);
+
+        }
+
+        private void emitLength(final List<LengthConstraint> list) {
+            if (!list.isEmpty()) {
+                super.writer.startLengthNode(toLengthString(list));
+                // FIXME: BUG-2444: Workaround for incorrect decomposition in
+                // API
+                final LengthConstraint first = list.iterator().next();
+                emitErrorMessageNode(first.getErrorMessage());
+                emitErrorAppTagNode(first.getErrorAppTag());
+                emitDescriptionNode(first.getDescription());
+                emitReferenceNode(first.getReference());
+                super.writer.endNode();
             }
-            writer.endNode();
         }
-    }
 
-    private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
-        final SchemaPath path = refine.getKey();
-        final SchemaNode value = refine.getValue();
-        writer.startRefineNode(path);
-
-        if (value instanceof LeafSchemaNode) {
-            emitRefineLeafNodes((LeafSchemaNode) value);
-        } else if (value instanceof LeafListSchemaNode) {
-            emitRefineLeafListNodes((LeafListSchemaNode) value);
-        } else if (value instanceof ListSchemaNode) {
-            emitRefineListNodes((ListSchemaNode) value);
-        } else if (value instanceof ChoiceSchemaNode) {
-            emitRefineChoiceNodes((ChoiceSchemaNode) value);
-        } else if (value instanceof ChoiceCaseNode) {
-            emitRefineCaseNodes((ChoiceCaseNode) value);
-        } else if (value instanceof ContainerSchemaNode) {
-            emitRefineContainerNodes((ContainerSchemaNode) value);
-        } else if (value instanceof AnyXmlSchemaNode) {
-            emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
-        }
-        writer.endNode();
+        private static String toLengthString(final List<LengthConstraint> list) {
+            final Iterator<LengthConstraint> it = list.iterator();
+            if (!it.hasNext()) {
+                return "";
+            }
 
-    }
+            final StringBuilder sb = new StringBuilder();
+            boolean haveNext;
+            do {
+                final LengthConstraint current = it.next();
+                haveNext = it.hasNext();
+                appendRange(sb, current.getMin(), current.getMax(), haveNext);
+            } while (haveNext);
 
-    private static <T extends SchemaNode> T getOriginalChecked(final T value) {
-        final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
-        Preconditions.checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
-        @SuppressWarnings("unchecked")
-        final T ret = (T) original.get();
-        return ret;
-    }
+            return sb.toString();
+        }
+
+        private static String toRangeString(final List<RangeConstraint> list) {
+            final Iterator<RangeConstraint> it = list.iterator();
+            if (!it.hasNext()) {
+                return "";
+            }
 
-    private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
-        if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
-            emitDescriptionNode(value.getDescription());
+            final StringBuilder sb = new StringBuilder();
+            boolean haveNext;
+            do {
+                final RangeConstraint current = it.next();
+                haveNext = it.hasNext();
+                appendRange(sb, current.getMin(), current.getMax(), haveNext);
+            } while (haveNext);
+
+            return sb.toString();
         }
-        if (Objects.deepEquals(original.getReference(), value.getReference())) {
-            emitReferenceNode(value.getReference());
+
+        private static void appendRange(final StringBuilder sb, final Number min, final Number max,
+                final boolean haveNext) {
+            sb.append(min);
+            if (!min.equals(max)) {
+                sb.append("..");
+                sb.append(max);
+            }
+            if (haveNext) {
+                sb.append('|');
+            }
         }
-    }
 
-    private void emitRefineContainerNodes(final ContainerSchemaNode value) {
-        final ContainerSchemaNode original = getOriginalChecked(value);
+        private void emitPatternNode(final PatternConstraint pattern) {
+            super.writer.startPatternNode(pattern.getRawRegularExpression());
+            // FIXME: BUG-2444: Optional
+            emitErrorMessageNode(pattern.getErrorMessage());
+            // FIXME: BUG-2444: Optional
+            emitErrorAppTagNode(pattern.getErrorAppTag());
+            emitDescriptionNode(pattern.getDescription());
+            emitModifier(pattern.getModifier());
+            super.writer.endNode();
+        }
 
-        // emitMustNodes(child.getConstraints().getMustConstraints());
-        if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
-            emitPresenceNode(value.isPresenceContainer());
+        private void emitModifier(final ModifierKind modifier) {
+            if (modifier != null) {
+                super.writer.startModifierNode(modifier);
+                super.writer.endNode();
+            }
         }
-        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
-            emitConfigNode(value.isConfiguration());
+
+        private void emitDefaultNodes(final Collection<String> defaults) {
+            for (final String defaultValue : defaults) {
+                emitDefaultNode(defaultValue);
+            }
         }
-        emitDocumentedNodeRefine(original, value);
 
-    }
+        private void emitDefaultNode(@Nullable final Object object) {
+            if (object != null) {
+                super.writer.startDefaultNode(object.toString());
+                super.writer.endNode();
+            }
+        }
+
+        private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
+            for (final EnumPair enumValue : typeDefinition.getValues()) {
+                emitEnumNode(enumValue);
+            }
+        }
 
-    private void emitRefineLeafNodes(final LeafSchemaNode value) {
-        final LeafSchemaNode original = getOriginalChecked(value);
+        private void emitEnumNode(final EnumPair enumValue) {
+            super.writer.startEnumNode(enumValue.getName());
+            emitValueNode(enumValue.getValue());
+            emitStatusNode(enumValue.getStatus());
+            emitDescriptionNode(enumValue.getDescription());
+            emitReferenceNode(enumValue.getReference());
+            super.writer.endNode();
+        }
 
-        // emitMustNodes(child.getConstraints().getMustConstraints());
-        if (Objects.deepEquals(original.getDefault(), value.getDefault())) {
-            emitDefaultNode(value.getDefault());
+        private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
+            emitPathNode(typeDefinition.getPathStatement());
+            if (YangVersion.VERSION_1_1 == super.yangVersion) {
+                emitRequireInstanceNode(typeDefinition.requireInstance());
+            }
         }
-        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
-            emitConfigNode(value.isConfiguration());
+
+        private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
+            super.writer.startPathNode(revisionAwareXPath);
+            super.writer.endNode();
         }
-        emitDocumentedNodeRefine(original, value);
-        if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-            emitMandatoryNode(value.getConstraints().isMandatory());
+
+        private void emitRequireInstanceNode(final boolean require) {
+            super.writer.startRequireInstanceNode(require);
+            super.writer.endNode();
         }
 
-    }
+        private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
+            emitRequireInstanceNode(typeDefinition.requireInstance());
+        }
 
-    private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
-        final LeafListSchemaNode original = getOriginalChecked(value);
+        private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
+            emitBaseIdentities(typeDefinition.getIdentities());
+        }
 
-        // emitMustNodes(child.getConstraints().getMustConstraints());
-        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
-            emitConfigNode(value.isConfiguration());
+        private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
+            for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
+                // FIXME: BUG-2444: What if we have locally modified types here?
+                // is solution to look-up in schema path?
+                emitTypeNode(typeDefinition.getPath(), subtype);
+            }
         }
-        if (Objects.deepEquals(original.getConstraints().getMinElements(), value.getConstraints().getMinElements())) {
-            emitMinElementsNode(value.getConstraints().getMinElements());
+
+        private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
+            for (final Bit bit : typeDefinition.getBits()) {
+                emitBit(bit);
+            }
         }
-        if (Objects.deepEquals(original.getConstraints().getMaxElements(), value.getConstraints().getMaxElements())) {
-            emitMaxElementsNode(value.getConstraints().getMaxElements());
+
+        private void emitBit(final Bit bit) {
+            super.writer.startBitNode(bit.getName());
+            emitPositionNode(bit.getPosition());
+            emitStatusNode(bit.getStatus());
+            emitDescriptionNode(bit.getDescription());
+            emitReferenceNode(bit.getReference());
+            super.writer.endNode();
         }
-        emitDocumentedNodeRefine(original, value);
 
-    }
+        private void emitPositionNode(@Nullable final Long position) {
+            if (position != null) {
+                super.writer.startPositionNode(UnsignedInteger.valueOf(position));
+                super.writer.endNode();
+            }
+        }
 
-    private void emitRefineListNodes(final ListSchemaNode value) {
-        final ListSchemaNode original = getOriginalChecked(value);
+        private void emitStatusNode(@Nullable final Status status) {
+            if (status != null) {
+                super.writer.startStatusNode(status);
+                super.writer.endNode();
+            }
+        }
 
-        // emitMustNodes(child.getConstraints().getMustConstraints());
-        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
-            emitConfigNode(value.isConfiguration());
+        private void emitConfigNode(final boolean config) {
+            super.writer.startConfigNode(config);
+            super.writer.endNode();
         }
-        if (Objects.deepEquals(original.getConstraints().getMinElements(), value.getConstraints().getMinElements())) {
-            emitMinElementsNode(value.getConstraints().getMinElements());
+
+        private void emitMandatoryNode(final boolean mandatory) {
+            super.writer.startMandatoryNode(mandatory);
+            super.writer.endNode();
         }
-        if (Objects.deepEquals(original.getConstraints().getMaxElements(), value.getConstraints().getMaxElements())) {
-            emitMaxElementsNode(value.getConstraints().getMaxElements());
+
+        private void emitPresenceNode(final boolean presence) {
+            super.writer.startPresenceNode(presence);
+            super.writer.endNode();
         }
-        emitDocumentedNodeRefine(original, value);
 
-    }
+        private void emitOrderedBy(final boolean userOrdered) {
+            if (userOrdered) {
+                super.writer.startOrderedByNode("user");
+            } else {
+                super.writer.startOrderedByNode("system");
+            }
+            super.writer.endNode();
+        }
 
-    private void emitRefineChoiceNodes(final ChoiceSchemaNode value) {
-        final ChoiceSchemaNode original = getOriginalChecked(value);
+        private void emitMust(@Nullable final MustDefinition mustCondition) {
+            if (mustCondition != null && mustCondition.getXpath() != null) {
+                super.writer.startMustNode(mustCondition.getXpath());
+                emitErrorMessageNode(mustCondition.getErrorMessage());
+                emitErrorAppTagNode(mustCondition.getErrorAppTag());
+                emitDescriptionNode(mustCondition.getDescription());
+                emitReferenceNode(mustCondition.getReference());
+                super.writer.endNode();
+            }
 
-        // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
-        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
-            emitConfigNode(value.isConfiguration());
         }
-        if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-            emitMandatoryNode(value.getConstraints().isMandatory());
+
+        private void emitErrorMessageNode(@Nullable final String input) {
+            if (input != null && !input.isEmpty()) {
+                super.writer.startErrorMessageNode(input);
+                super.writer.endNode();
+            }
         }
-        emitDocumentedNodeRefine(original, value);
 
-    }
+        private void emitErrorAppTagNode(final String input) {
+            if (input != null && !input.isEmpty()) {
+                super.writer.startErrorAppTagNode(input);
+                super.writer.endNode();
+            }
+        }
+
+        private void emitMinElementsNode(final Integer min) {
+            if (min != null) {
+                super.writer.startMinElementsNode(min);
+                super.writer.endNode();
+            }
+        }
 
-    private void emitRefineCaseNodes(final ChoiceCaseNode value) {
-        final ChoiceCaseNode original = getOriginalChecked(value);
-        emitDocumentedNodeRefine(original, value);
+        private void emitMaxElementsNode(final Integer max) {
+            if (max != null) {
+                super.writer.startMaxElementsNode(max);
+                super.writer.endNode();
+            }
+        }
 
-    }
+        private void emitValueNode(@Nullable final Integer value) {
+            if (value != null) {
+                super.writer.startValueNode(value);
+                super.writer.endNode();
+            }
+        }
+
+        private void emitDocumentedNode(final DocumentedNode.WithStatus input) {
+            emitStatusNode(input.getStatus());
+            emitDescriptionNode(input.getDescription());
+            emitReferenceNode(input.getReference());
+        }
 
-    private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
-        final AnyXmlSchemaNode original = getOriginalChecked(value);
+        private void emitGrouping(final GroupingDefinition grouping) {
+            super.writer.startGroupingNode(grouping.getQName());
+            emitDocumentedNode(grouping);
+            emitDataNodeContainer(grouping);
+            emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
+            emitNotifications(grouping.getNotifications());
+            emitActions(grouping.getActions());
+            super.writer.endNode();
 
-        // FIXME: BUG-2444:  emitMustNodes(child.getConstraints().getMustConstraints());
-        if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
-            emitConfigNode(value.isConfiguration());
         }
-        if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-            emitMandatoryNode(value.getConstraints().isMandatory());
+
+        private void emitContainer(final ContainerSchemaNode child) {
+            super.writer.startContainerNode(child.getQName());
+
+            //
+
+            emitConstraints(child.getConstraints());
+            // FIXME: BUG-2444: whenNode //:Optional
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitPresenceNode(child.isPresenceContainer());
+            emitConfigNode(child.isConfiguration());
+            emitDocumentedNode(child);
+            emitDataNodeContainer(child);
+            emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+            emitNotifications(child.getNotifications());
+            emitActions(child.getActions());
+            super.writer.endNode();
+
         }
-        emitDocumentedNodeRefine(original, value);
 
-    }
+        private void emitConstraints(final ConstraintDefinition constraints) {
+            emitWhen(constraints.getWhenCondition());
+            for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
+                emitMust(mustCondition);
+            }
+        }
 
-    private void emitUsesAugmentNode(final AugmentationSchema aug) {
-        /**
-         * differs only in location in schema, otherwise currently (as of
-         * RFC6020) it is same, so we could freely reuse path.
-         */
-        emitAugment(aug);
-    }
+        private void emitLeaf(final LeafSchemaNode child) {
+            super.writer.startLeafNode(child.getQName());
+            emitWhen(child.getConstraints().getWhenCondition());
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitTypeNode(child.getPath(), child.getType());
+            emitUnitsNode(child.getUnits());
+            emitMustNodes(child.getConstraints().getMustConstraints());
+            emitDefaultNode(child.getDefault());
+            emitConfigNode(child.isConfiguration());
+            emitMandatoryNode(child.getConstraints().isMandatory());
+            emitDocumentedNode(child);
+            emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+            super.writer.endNode();
+
+        }
+
+        private void emitLeafList(final LeafListSchemaNode child) {
+            super.writer.startLeafListNode(child.getQName());
+
+            emitWhen(child.getConstraints().getWhenCondition());
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitTypeNode(child.getPath(), child.getType());
+            emitUnitsNode(child.getType().getUnits());
+            // FIXME: BUG-2444: unitsNode /Optional
+            emitMustNodes(child.getConstraints().getMustConstraints());
+            emitConfigNode(child.isConfiguration());
+            emitDefaultNodes(child.getDefaults());
+            emitMinElementsNode(child.getConstraints().getMinElements());
+            emitMaxElementsNode(child.getConstraints().getMaxElements());
+            emitOrderedBy(child.isUserOrdered());
+            emitDocumentedNode(child);
+            emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+            super.writer.endNode();
+
+        }
+
+        private void emitList(final ListSchemaNode child) {
+            super.writer.startListNode(child.getQName());
+            emitWhen(child.getConstraints().getWhenCondition());
+
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitMustNodes(child.getConstraints().getMustConstraints());
+            emitKey(child.getKeyDefinition());
+            emitUniqueConstraints(child.getUniqueConstraints());
+            emitConfigNode(child.isConfiguration());
+            emitMinElementsNode(child.getConstraints().getMinElements());
+            emitMaxElementsNode(child.getConstraints().getMaxElements());
+            emitOrderedBy(child.isUserOrdered());
+            emitDocumentedNode(child);
+            emitDataNodeContainer(child);
+            emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+            emitNotifications(child.getNotifications());
+            emitActions(child.getActions());
+            super.writer.endNode();
+
+        }
+
+        private void emitMustNodes(final Set<MustDefinition> mustConstraints) {
+            for (final MustDefinition must : mustConstraints) {
+                emitMust(must);
+            }
+        }
+
+        private void emitKey(final List<QName> keyList) {
+            if (keyList != null && !keyList.isEmpty()) {
+                super.writer.startKeyNode(keyList);
+                super.writer.endNode();
+            }
+        }
 
-    private void emitAugment(final AugmentationSchema augmentation) {
-        writer.startAugmentNode(augmentation.getTargetPath());
-        // FIXME: BUG-2444: whenNode //Optional
-        // FIXME: BUG-2444: *(ifFeatureNode )
+        private void emitUniqueConstraints(final Collection<UniqueConstraint> uniqueConstraints) {
+            for (final UniqueConstraint uniqueConstraint : uniqueConstraints) {
+                emitUnique(uniqueConstraint);
+            }
+        }
 
-        emitStatusNode(augmentation.getStatus());
-        emitDescriptionNode(augmentation.getDescription());
-        emitReferenceNode(augmentation.getReference());
-        for (final UsesNode uses: augmentation.getUses()) {
-            emitUsesNode(uses);
+        private void emitUnique(final UniqueConstraint uniqueConstraint) {
+            super.writer.startUniqueNode(uniqueConstraint);
+            super.writer.endNode();
         }
 
-        for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
-            if (childNode instanceof ChoiceCaseNode) {
-                emitCaseNode((ChoiceCaseNode) childNode);
-            } else {
-                emitDataSchemaNode(childNode);
+        private void emitChoice(final ChoiceSchemaNode choice) {
+            super.writer.startChoiceNode(choice.getQName());
+            emitWhen(choice.getConstraints().getWhenCondition());
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            // FIXME: BUG-2444: defaultNode //Optional
+            emitConfigNode(choice.isConfiguration());
+            emitMandatoryNode(choice.getConstraints().isMandatory());
+            emitDocumentedNode(choice);
+            for (final ChoiceCaseNode caze : choice.getCases()) {
+                // TODO: emit short case?
+                emitCaseNode(caze);
             }
+            emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
+            super.writer.endNode();
         }
-        emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
-        emitNotifications(augmentation.getNotifications());
-        emitActions(augmentation.getActions());
-        writer.endNode();
-    }
 
-    private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
-        for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
-            if (!unknonwnNode.isAddedByAugmentation() && !unknonwnNode.isAddedByUses()) {
-                emitUnknownStatementNode(unknonwnNode);
+        private void emitCaseNode(final ChoiceCaseNode caze) {
+            if (!super.emitInstantiated && caze.isAugmenting()) {
+                return;
+            }
+            super.writer.startCaseNode(caze.getQName());
+            emitWhen(caze.getConstraints().getWhenCondition());
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitDocumentedNode(caze);
+            emitDataNodeContainer(caze);
+            emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
+            super.writer.endNode();
+
+        }
+
+        private void emitAnyxml(final AnyXmlSchemaNode anyxml) {
+            super.writer.startAnyxmlNode(anyxml.getQName());
+            emitBodyOfDataSchemaNode(anyxml);
+            super.writer.endNode();
+        }
+
+        private void emitAnydata(final AnyDataSchemaNode anydata) {
+            super.writer.startAnydataNode(anydata.getQName());
+            emitBodyOfDataSchemaNode(anydata);
+            super.writer.endNode();
+        }
+
+        private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
+            emitWhen(dataSchemaNode.getConstraints().getWhenCondition());
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
+            emitConfigNode(dataSchemaNode.isConfiguration());
+            emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
+            emitDocumentedNode(dataSchemaNode);
+            emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
+        }
+
+        private void emitUsesNode(final UsesNode usesNode) {
+            if (super.emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
+                super.writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
+                /*
+                 * FIXME: BUG-2444: whenNode / *(ifFeatureNode ) statusNode //
+                 * Optional F : descriptionNode // Optional referenceNode //
+                 * Optional
+                 */
+                for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
+                    emitRefine(refine);
+                }
+                for (final AugmentationSchema aug : usesNode.getAugmentations()) {
+                    emitUsesAugmentNode(aug);
+                }
+                super.writer.endNode();
             }
         }
-    }
 
-    private void emitUnknownStatementNode(final UnknownSchemaNode node) {
-        final StatementDefinition def = getStatementChecked(node.getNodeType());
-        if (def.getArgumentName() == null) {
-            writer.startUnknownNode(def);
-        } else {
-            writer.startUnknownNode(def, node.getNodeParameter());
+        private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
+            final SchemaPath path = refine.getKey();
+            final SchemaNode value = refine.getValue();
+            super.writer.startRefineNode(path);
+
+            if (value instanceof LeafSchemaNode) {
+                emitRefineLeafNodes((LeafSchemaNode) value);
+            } else if (value instanceof LeafListSchemaNode) {
+                emitRefineLeafListNodes((LeafListSchemaNode) value);
+            } else if (value instanceof ListSchemaNode) {
+                emitRefineListNodes((ListSchemaNode) value);
+            } else if (value instanceof ChoiceSchemaNode) {
+                emitRefineChoiceNodes((ChoiceSchemaNode) value);
+            } else if (value instanceof ChoiceCaseNode) {
+                emitRefineCaseNodes((ChoiceCaseNode) value);
+            } else if (value instanceof ContainerSchemaNode) {
+                emitRefineContainerNodes((ContainerSchemaNode) value);
+            } else if (value instanceof AnyXmlSchemaNode) {
+                emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
+            }
+            super.writer.endNode();
+
         }
-        emitUnknownStatementNodes(node.getUnknownSchemaNodes());
-        writer.endNode();
-    }
 
-    private StatementDefinition getStatementChecked(final QName nodeType) {
-        final StatementDefinition ret = extensions.get(nodeType);
-        Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.",nodeType);
-        return ret;
-    }
+        private static <T extends SchemaNode> T getOriginalChecked(final T value) {
+            final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
+            Preconditions.checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
+            @SuppressWarnings("unchecked")
+            final T ret = (T) original.get();
+            return ret;
+        }
 
-    private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
-        if (revisionAwareXPath != null) {
-            writer.startWhenNode(revisionAwareXPath);
-            writer.endNode();
+        private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
+            if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
+                emitDescriptionNode(value.getDescription());
+            }
+            if (Objects.deepEquals(original.getReference(), value.getReference())) {
+                emitReferenceNode(value.getReference());
+            }
         }
-                // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
-        // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
-        // FIXME: BUG-2444: writer.endNode();)
 
-    }
+        private void emitRefineContainerNodes(final ContainerSchemaNode value) {
+            final ContainerSchemaNode original = getOriginalChecked(value);
 
-    private void emitRpc(final RpcDefinition rpc) {
-        writer.startRpcNode(rpc.getQName());
-        emitOperationBody(rpc);
-        writer.endNode();
-    }
+            // emitMustNodes(child.getConstraints().getMustConstraints());
+            if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
+                emitPresenceNode(value.isPresenceContainer());
+            }
+            if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+                emitConfigNode(value.isConfiguration());
+            }
+            emitDocumentedNodeRefine(original, value);
+
+        }
+
+        private void emitRefineLeafNodes(final LeafSchemaNode value) {
+            final LeafSchemaNode original = getOriginalChecked(value);
 
-    private void emitOperationBody(final OperationDefinition rpc) {
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        emitStatusNode(rpc.getStatus());
-        emitDescriptionNode(rpc.getDescription());
-        emitReferenceNode(rpc.getReference());
+            // emitMustNodes(child.getConstraints().getMustConstraints());
+            if (Objects.deepEquals(original.getDefault(), value.getDefault())) {
+                emitDefaultNode(value.getDefault());
+            }
+            if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+                emitConfigNode(value.isConfiguration());
+            }
+            emitDocumentedNodeRefine(original, value);
+            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+                emitMandatoryNode(value.getConstraints().isMandatory());
+            }
 
-        for (final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
-            emitTypedefNode(typedef);
         }
-        for (final GroupingDefinition grouping : rpc.getGroupings()) {
-            emitGrouping(grouping);
+
+        private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
+            final LeafListSchemaNode original = getOriginalChecked(value);
+
+            // emitMustNodes(child.getConstraints().getMustConstraints());
+            if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+                emitConfigNode(value.isConfiguration());
+            }
+            if (Objects.deepEquals(original.getConstraints().getMinElements(),
+                    value.getConstraints().getMinElements())) {
+                emitMinElementsNode(value.getConstraints().getMinElements());
+            }
+            if (Objects.deepEquals(original.getConstraints().getMaxElements(),
+                    value.getConstraints().getMaxElements())) {
+                emitMaxElementsNode(value.getConstraints().getMaxElements());
+            }
+            emitDocumentedNodeRefine(original, value);
+
         }
-        emitInput(rpc.getInput());
-        emitOutput(rpc.getOutput());
-        emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
-    }
 
-    private void emitActions(final Set<ActionDefinition> actions) {
-        for (final ActionDefinition actionDefinition : actions) {
-            emitAction(actionDefinition);
+        private void emitRefineListNodes(final ListSchemaNode value) {
+            final ListSchemaNode original = getOriginalChecked(value);
+
+            // emitMustNodes(child.getConstraints().getMustConstraints());
+            if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+                emitConfigNode(value.isConfiguration());
+            }
+            if (Objects.deepEquals(original.getConstraints().getMinElements(),
+                    value.getConstraints().getMinElements())) {
+                emitMinElementsNode(value.getConstraints().getMinElements());
+            }
+            if (Objects.deepEquals(original.getConstraints().getMaxElements(),
+                    value.getConstraints().getMaxElements())) {
+                emitMaxElementsNode(value.getConstraints().getMaxElements());
+            }
+            emitDocumentedNodeRefine(original, value);
+
         }
-    }
 
-    private void emitAction(final ActionDefinition action) {
-        writer.startActionNode(action.getQName());
-        emitOperationBody(action);
-        writer.endNode();
-    }
+        private void emitRefineChoiceNodes(final ChoiceSchemaNode value) {
+            final ChoiceSchemaNode original = getOriginalChecked(value);
+
+            // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
+            if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+                emitConfigNode(value.isConfiguration());
+            }
+            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+                emitMandatoryNode(value.getConstraints().isMandatory());
+            }
+            emitDocumentedNodeRefine(original, value);
 
-    private void emitInput(@Nonnull final ContainerSchemaNode input) {
-        if (isExplicitStatement(input)) {
-            writer.startInputNode();
-            emitConstraints(input.getConstraints());
-            emitDataNodeContainer(input);
-            emitUnknownStatementNodes(input.getUnknownSchemaNodes());
-            writer.endNode();
         }
 
-    }
+        private void emitRefineCaseNodes(final ChoiceCaseNode value) {
+            final ChoiceCaseNode original = getOriginalChecked(value);
+            emitDocumentedNodeRefine(original, value);
 
-    private void emitOutput(@Nonnull final ContainerSchemaNode output) {
-        if (isExplicitStatement(output)) {
-            writer.startOutputNode();
-            emitConstraints(output.getConstraints());
-            emitDataNodeContainer(output);
-            emitUnknownStatementNodes(output.getUnknownSchemaNodes());
-            writer.endNode();
         }
 
-    }
+        private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
+            final AnyXmlSchemaNode original = getOriginalChecked(value);
 
-    private static boolean isExplicitStatement(final ContainerSchemaNode node) {
-        return node instanceof EffectiveStatement
-                && ((EffectiveStatement<?, ?>) node).getDeclared().getStatementSource() == StatementSource.DECLARATION;
-    }
+            // FIXME: BUG-2444:
+            // emitMustNodes(child.getConstraints().getMustConstraints());
+            if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+                emitConfigNode(value.isConfiguration());
+            }
+            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+                emitMandatoryNode(value.getConstraints().isMandatory());
+            }
+            emitDocumentedNodeRefine(original, value);
 
-    private void emitNotifications(final Set<NotificationDefinition> notifications) {
-        for (final NotificationDefinition notification : notifications) {
-            emitNotificationNode(notification);
         }
-    }
 
-    private void emitNotificationNode(final NotificationDefinition notification) {
-        writer.startNotificationNode(notification.getQName());
-        // FIXME: BUG-2444: *(ifFeatureNode )
-        emitConstraints(notification.getConstraints());
-        emitDocumentedNode(notification);
-        emitDataNodeContainer(notification);
-        emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
-        writer.endNode();
+        private void emitUsesAugmentNode(final AugmentationSchema aug) {
+            /**
+             * differs only in location in schema, otherwise currently (as of
+             * RFC6020) it is same, so we could freely reuse path.
+             */
+            emitAugment(aug);
+        }
 
-    }
+        private void emitAugment(final AugmentationSchema augmentation) {
+            super.writer.startAugmentNode(augmentation.getTargetPath());
+            // FIXME: BUG-2444: whenNode //Optional
+            // FIXME: BUG-2444: *(ifFeatureNode )
 
+            emitStatusNode(augmentation.getStatus());
+            emitDescriptionNode(augmentation.getDescription());
+            emitReferenceNode(augmentation.getReference());
+            for (final UsesNode uses : augmentation.getUses()) {
+                emitUsesNode(uses);
+            }
 
-    //FIXME: Probably should be moved to utils bundle.
-    private static <T> boolean  isPrefix(final Iterable<T> prefix, final Iterable<T> other) {
-        final Iterator<T> prefixIt = prefix.iterator();
-        final Iterator<T> otherIt = other.iterator();
-        while (prefixIt.hasNext()) {
-            if (!otherIt.hasNext()) {
-                return false;
+            for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
+                if (childNode instanceof ChoiceCaseNode) {
+                    emitCaseNode((ChoiceCaseNode) childNode);
+                } else {
+                    emitDataSchemaNode(childNode);
+                }
             }
-            if (!Objects.deepEquals(prefixIt.next(), otherIt.next())) {
-                return false;
+            emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
+            emitNotifications(augmentation.getNotifications());
+            emitActions(augmentation.getActions());
+            super.writer.endNode();
+        }
+
+        private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
+            for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
+                if (!unknonwnNode.isAddedByAugmentation() && !unknonwnNode.isAddedByUses()) {
+                    emitUnknownStatementNode(unknonwnNode);
+                }
             }
         }
-        return true;
-    }
 
-    private void emitDeviation(final Deviation deviation) {
-        /*
-         * FIXME: BUG-2444:  Deviation is not modeled properly and we are loosing lot of
-         * information in order to export it properly
-         *
-         * writer.startDeviationNode(deviation.getTargetPath());
-         *
-         * :descriptionNode //:Optional
-         *
-         *
-         * emitReferenceNode(deviation.getReference());
-         * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
-         * :deviateDeleteNode)) :writer.endNode();
-         */
+        private void emitUnknownStatementNode(final UnknownSchemaNode node) {
+            final StatementDefinition def = getStatementChecked(node.getNodeType());
+            if (def.getArgumentName() == null) {
+                super.writer.startUnknownNode(def);
+            } else {
+                super.writer.startUnknownNode(def, node.getNodeParameter());
+            }
+            emitUnknownStatementNodes(node.getUnknownSchemaNodes());
+            super.writer.endNode();
+        }
+
+        private StatementDefinition getStatementChecked(final QName nodeType) {
+            final StatementDefinition ret = super.extensions.get(nodeType);
+            Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.", nodeType);
+            return ret;
+        }
+
+        private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
+            if (revisionAwareXPath != null) {
+                super.writer.startWhenNode(revisionAwareXPath);
+                super.writer.endNode();
+            }
+            // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
+            // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
+            // FIXME: BUG-2444: super.writer.endNode();)
+
+        }
+
+        private void emitRpc(final RpcDefinition rpc) {
+            super.writer.startRpcNode(rpc.getQName());
+            emitOperationBody(rpc);
+            super.writer.endNode();
+        }
+
+        private void emitOperationBody(final OperationDefinition rpc) {
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitStatusNode(rpc.getStatus());
+            emitDescriptionNode(rpc.getDescription());
+            emitReferenceNode(rpc.getReference());
+
+            for (final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
+                emitTypedefNode(typedef);
+            }
+            for (final GroupingDefinition grouping : rpc.getGroupings()) {
+                emitGrouping(grouping);
+            }
+            emitInput(rpc.getInput());
+            emitOutput(rpc.getOutput());
+            emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
+        }
+
+        private void emitActions(final Set<ActionDefinition> actions) {
+            for (final ActionDefinition actionDefinition : actions) {
+                emitAction(actionDefinition);
+            }
+        }
+
+        private void emitAction(final ActionDefinition action) {
+            // :FIXME add addedByUses & addedByAugmentation in API and perform
+            // check here..
+            super.writer.startActionNode(action.getQName());
+            emitOperationBody(action);
+            super.writer.endNode();
+        }
+
+        private void emitInput(@Nonnull final ContainerSchemaNode input) {
+            if (isExplicitStatement(input)) {
+                super.writer.startInputNode();
+                emitConstraints(input.getConstraints());
+                emitDataNodeContainer(input);
+                emitUnknownStatementNodes(input.getUnknownSchemaNodes());
+                super.writer.endNode();
+            }
+
+        }
+
+        private void emitOutput(@Nonnull final ContainerSchemaNode output) {
+            if (isExplicitStatement(output)) {
+                super.writer.startOutputNode();
+                emitConstraints(output.getConstraints());
+                emitDataNodeContainer(output);
+                emitUnknownStatementNodes(output.getUnknownSchemaNodes());
+                super.writer.endNode();
+            }
+        }
+
+        private static boolean isExplicitStatement(final ContainerSchemaNode node) {
+            return node instanceof EffectiveStatement && ((EffectiveStatement<?, ?>) node).getDeclared()
+                    .getStatementSource() == StatementSource.DECLARATION;
+        }
+
+        private void emitNotifications(final Set<NotificationDefinition> notifications) {
+            for (final NotificationDefinition notification : notifications) {
+                emitNotificationNode(notification);
+            }
+        }
+
+        private void emitNotificationNode(final NotificationDefinition notification) {
+            // :FIXME add addedByUses & addedByAugmentation in API and perform
+            // check here..
+
+            super.writer.startNotificationNode(notification.getQName());
+            // FIXME: BUG-2444: *(ifFeatureNode )
+            emitConstraints(notification.getConstraints());
+            emitDocumentedNode(notification);
+            emitDataNodeContainer(notification);
+            emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
+            super.writer.endNode();
+
+        }
+
+        private void emitDeviation(final Deviation deviation) {
+            /*
+             * FIXME: BUG-2444: Deviation is not modeled properly and we are
+             * loosing lot of information in order to export it properly
+             *
+             * super.writer.startDeviationNode(deviation.getTargetPath());
+             *
+             * :descriptionNode //:Optional
+             *
+             *
+             * emitReferenceNode(deviation.getReference());
+             * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
+             * :deviateDeleteNode)) :super.writer.endNode();
+             */
+        }
     }
 }
index 20a7242cff19326435a37bdf654a867b17ea9380..bbbdc9e4c5b360b898b8e06fc771ab7cc530893e 100644 (file)
@@ -446,4 +446,280 @@ final class SchemaToStatementWriterAdaptor implements YangModuleWriter {
         }
         writer.writeArgument(uniqueStr.toString());
     }
+
+    @Override
+    public void startRevisionNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.REVISION);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startRevisionDateNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.REVISION_DATE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startExtensionNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.EXTENSION);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startBaseNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.BASE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startFeatureNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.FEATURE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startYinElementNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.YIN_ELEMENT);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startIdentityNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.IDENTITY);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startTypedefNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.TYPEDEF);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startRpcNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.RPC);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startTypeNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.TYPE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startContainerNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.CONTAINER);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startPresenceNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.PRESENCE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startStatusNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.STATUS);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startConfigNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.CONFIG);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startLeafNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.LEAF);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startWhenNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.WHEN);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startLeafListNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.LEAF_LIST);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startMustNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.MUST);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startMinElementsNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.MIN_ELEMENTS);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startMaxElementsNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.MAX_ELEMENTS);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startListNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.LIST);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startKeyNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.KEY);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startUniqueNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.UNIQUE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startActionNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.ACTION);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startChoiceNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.CHOICE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startMandatoryNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.MANDATORY);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startAnyxmlNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.ANYXML);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startCaseNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.CASE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startAnydataNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.ANYDATA);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startGroupingNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.GROUPING);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startUsesNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.USES);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startRefineNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.REFINE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startAugmentNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.AUGMENT);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startNotificationNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.NOTIFICATION);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startValueNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.VALUE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startModifierNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.MODIFIER);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startFractionDigitsNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.FRACTION_DIGITS);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startPathNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.PATH);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startRequireInstanceNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.REQUIRE_INSTANCE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startPositionNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.POSITION);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startBelongsToNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.BELONGS_TO);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startIfFeatureNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.IF_FEATURE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startSubmoduleNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.SUBMODULE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startIncludeNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.INCLUDE);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startDeviationNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.DEVIATION);
+        writer.writeArgument(rawArgument);
+    }
+
+    @Override
+    public void startDeviateNode(final String rawArgument) {
+        writer.startStatement(YangStmtMapping.DEVIATE);
+        writer.writeArgument(rawArgument);
+    }
 }
index 64305aa76926608ecb5df05f1d227a7ac3860ba1..c6b66ae9d1a2dd2db5df04e2d775d36d2cab1a1c 100644 (file)
@@ -151,4 +151,95 @@ interface YangModuleWriter {
 
     void startUniqueNode(UniqueConstraint uniqueConstraint);
 
+    void startRevisionNode(String rawArgument);
+
+    void startRevisionDateNode(String rawArgument);
+
+    void startExtensionNode(String rawArgument);
+
+    void startBaseNode(String rawArgument);
+
+    void startFeatureNode(String rawArgument);
+
+    void startYinElementNode(String rawArgument);
+
+    void startIdentityNode(String rawArgument);
+
+    void startTypedefNode(String rawArgument);
+
+    void startRpcNode(String rawArgument);
+
+    void startTypeNode(String rawArgument);
+
+    void startContainerNode(String rawArgument);
+
+    void startPresenceNode(String rawArgument);
+
+    void startStatusNode(String rawArgument);
+
+    void startConfigNode(String rawArgument);
+
+    void startLeafNode(String rawArgument);
+
+    void startWhenNode(String rawArgument);
+
+    void startLeafListNode(String rawArgument);
+
+    void startMustNode(String rawArgument);
+
+    void startMinElementsNode(String rawArgument);
+
+    void startMaxElementsNode(String rawArgument);
+
+    void startListNode(String rawArgument);
+
+    void startKeyNode(String rawArgument);
+
+    void startUniqueNode(String rawArgument);
+
+    void startActionNode(String rawArgument);
+
+    void startChoiceNode(String rawArgument);
+
+    void startMandatoryNode(String rawArgument);
+
+    void startAnyxmlNode(String rawArgument);
+
+    void startCaseNode(String rawArgument);
+
+    void startAnydataNode(String rawArgument);
+
+    void startGroupingNode(String rawArgument);
+
+    void startUsesNode(String rawArgument);
+
+    void startRefineNode(String rawArgument);
+
+    void startAugmentNode(String rawArgument);
+
+    void startNotificationNode(String rawArgument);
+
+    void startValueNode(String rawArgument);
+
+    void startModifierNode(String rawArgument);
+
+    void startFractionDigitsNode(String rawArgument);
+
+    void startPathNode(String rawArgument);
+
+    void startRequireInstanceNode(String rawArgument);
+
+    void startPositionNode(String rawArgument);
+
+    void startBelongsToNode(String rawArgument);
+
+    void startIfFeatureNode(String rawArgument);
+
+    void startSubmoduleNode(String rawArgument);
+
+    void startIncludeNode(String rawArgument);
+
+    void startDeviationNode(String rawArgument);
+
+    void startDeviateNode(String rawArgument);
 }
index dcc63639ce403f62ad7e6fbb4fbbdbba93168f2b..ba7c917151b4a1fc63de892b2c7936158d9fda3a 100644 (file)
@@ -24,18 +24,18 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public final class YinExportUtils {
 
-
     private YinExportUtils() {
         throw new UnsupportedOperationException("Utility class");
     }
 
-
     /**
      *
      * Returns well-formed file name of YIN file as defined in RFC6020.
      *
-     * @param name Module or submodule name
-     * @param revision Revision of module or submodule
+     * @param name
+     *            Module or submodule name
+     * @param revision
+     *            Revision of module or submodule
      * @return well-formed file name of YIN file as defined in RFC6020.
      */
     public static String wellFormedYinName(final String name, final Date revision) {
@@ -53,7 +53,25 @@ public final class YinExportUtils {
      * @return well-formed file name of YIN file as defined in RFC6020.
      */
     public static String wellFormedYinName(final String name, final String revision) {
-        return String.format("%s@%s.yin", Preconditions.checkNotNull(name),Preconditions.checkNotNull(revision));
+        return String.format("%s@%s.yin", Preconditions.checkNotNull(name), Preconditions.checkNotNull(revision));
+    }
+
+    /**
+     * Writes YIN representation of supplied module to specified output stream.
+     *
+     * @param ctx
+     *            Schema Context which contains module and extension definitions
+     *            to be used during export of model.
+     * @param module
+     *            Module to be exported.
+     * @param str
+     *            Output stream to which YIN representation of model will be
+     *            written.
+     * @throws XMLStreamException
+     */
+    public static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final OutputStream str)
+            throws XMLStreamException {
+        writeModuleToOutputStream(ctx, module, str, false);
     }
 
     /**
@@ -67,20 +85,26 @@ public final class YinExportUtils {
      * @param str
      *            Output stream to which YIN representation of model will be
      *            written.
+     * @param emitInstantiated
+     *            Option to emit also instantiated statements (e.g. statements
+     *            added by uses or augment)
      * @throws XMLStreamException
      */
-    public static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final OutputStream str) throws XMLStreamException {
+    public static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final OutputStream str,
+            final boolean emitInstantiated) throws XMLStreamException {
         final XMLOutputFactory factory = XMLOutputFactory.newFactory();
         final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(str);
-        writeModuleToOutputStream(ctx,module, xmlStreamWriter);
+        writeModuleToOutputStream(ctx, module, xmlStreamWriter, emitInstantiated);
         xmlStreamWriter.flush();
     }
 
-    private static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final XMLStreamWriter xmlStreamWriter) {
+    private static void writeModuleToOutputStream(final SchemaContext ctx, final Module module,
+            final XMLStreamWriter xmlStreamWriter, final boolean emitInstantiated) {
         final URI moduleNs = module.getNamespace();
-        final Map<String, URI> prefixToNs = prefixToNamespace(ctx,module);
-        final StatementTextWriter yinWriter = SingleModuleYinStatementWriter.create(xmlStreamWriter, moduleNs, prefixToNs);
-        SchemaContextEmitter.writeToStatementWriter(module, ctx,yinWriter);
+        final Map<String, URI> prefixToNs = prefixToNamespace(ctx, module);
+        final StatementTextWriter yinWriter = SingleModuleYinStatementWriter.create(xmlStreamWriter, moduleNs,
+                prefixToNs);
+        SchemaContextEmitter.writeToStatementWriter(module, ctx, yinWriter, emitInstantiated);
     }
 
     private static Map<String, URI> prefixToNamespace(final SchemaContext ctx, final Module module) {
@@ -88,7 +112,7 @@ public final class YinExportUtils {
         prefixMap.put(module.getPrefix(), module.getNamespace());
         for (final ModuleImport imp : module.getImports()) {
             final String prefix = imp.getPrefix();
-            final URI namespace = getModuleNamespace(ctx,imp.getModuleName());
+            final URI namespace = getModuleNamespace(ctx, imp.getModuleName());
             prefixMap.put(prefix, namespace);
         }
         return prefixMap;
index c9bbcc6a3f9271d29e67237561f15188291d8b64..34ceedb09f491b71efe969ab3ae540c6a40d3edf 100644 (file)
@@ -10,10 +10,10 @@ package org.opendaylight.yangtools.yang.model.export.test;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import org.custommonkey.xmlunit.Diff;
@@ -35,12 +35,8 @@ public class Bug2444Test {
         final SchemaContext schema = YangParserTestUtils.parseYangResourceDirectory("/bugs/bug2444/yang");
         assertNotNull(schema);
 
-        final File outDir = new File("target/bug2444-export");
-        outDir.mkdirs();
-
-        for (final Module module : schema.getModules()) {
-            exportModule(schema, module, outDir);
-
+        final ImmutableSet<Module> modulesAndSubmodules = getAllModulesAndSubmodules(schema);
+        for (final Module module : modulesAndSubmodules) {
             final OutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
             try {
@@ -59,6 +55,15 @@ public class Bug2444Test {
         }
     }
 
+    private ImmutableSet<Module> getAllModulesAndSubmodules(final SchemaContext schema) {
+        final Builder<Module> builder = ImmutableSet.builder();
+        builder.addAll(schema.getModules());
+        for (final Module module : schema.getModules()) {
+            builder.addAll(module.getSubmodules());
+        }
+        return builder.build();
+    }
+
     private static void assertXMLEquals(final Document expectedXMLDoc, final String output)
             throws SAXException, IOException {
         final String expected = YinExportTestUtils.toString(expectedXMLDoc.getDocumentElement());
@@ -71,13 +76,4 @@ public class Bug2444Test {
         diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
         XMLAssert.assertXMLEqual(diff, true);
     }
-
-    private static File exportModule(final SchemaContext schemaContext, final Module module, final File outDir)
-            throws Exception {
-        final File outFile = new File(outDir, YinExportUtils.wellFormedYinName(module.getName(), module.getRevision()));
-        try (OutputStream output = new FileOutputStream(outFile)) {
-            YinExportUtils.writeModuleToOutputStream(schemaContext, module, output);
-        }
-        return outFile;
-    }
 }
index 375771a2125a600af53f7b8c15b82f71c1b5c038..d8ef249df8d61daf76046d1e6422ba5e135b459f 100644 (file)
@@ -8,9 +8,11 @@ module default {
         default "def-val-1";
         default "def-val-2";
         default "def-val-3";
+        ordered-by user;
     }
 
     leaf-list my-leaflist-2 {
         type string;
+        status "deprecated";
     }
 }
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/deviation-target.yang b/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/deviation-target.yang
new file mode 100644 (file)
index 0000000..a405a32
--- /dev/null
@@ -0,0 +1,76 @@
+module deviation-target {
+    namespace deviation-target;
+    prefix tgt;
+    yang-version 1.1;
+
+    revision 2017-01-20;
+
+    leaf-list my-leaf-list {
+        type int32;
+        default 50;
+    }
+
+    list my-list {
+        key key-leaf;
+
+        leaf key-leaf {
+            type string;
+        }
+
+        leaf my-leaf-a {
+            type string;
+        }
+
+        leaf my-leaf-b {
+            type string;
+        }
+
+        leaf my-leaf-c {
+            type string;
+        }
+
+        leaf my-leaf-d {
+            type string;
+        }
+    }
+
+    choice my-choice {
+        case c1 {
+            leaf c1-leaf {
+                type string;
+                default "heaven";
+            }
+        }
+
+        case c2 {
+            leaf c2-leaf {
+                type string;
+                default "hell";
+            }
+        }
+        container shortcase {
+        }
+    }
+
+    rpc my-rpc {
+        input {
+            leaf my-rpc-input-leaf {
+                type string;
+            }
+        }
+
+        output {
+            leaf my-rpc-output-leaf {
+                type string;
+            }
+        }
+    }
+
+    notification my-notification {
+
+    }
+
+    anyxml my-anyxml {
+
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/deviation.yang b/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/deviation.yang
new file mode 100644 (file)
index 0000000..077ac6b
--- /dev/null
@@ -0,0 +1,69 @@
+module deviation {
+    namespace "deviation";
+    prefix "dev";
+    yang-version 1.1;
+
+    import deviation-target {
+        prefix dev-tgt;
+        revision-date 2017-01-20;
+    }
+
+    revision 2017-01-20;
+
+    deviation "/dev-tgt:my-leaf-list" {
+        deviate add {
+            config false;
+            min-elements 5;
+            max-elements 10;
+            default 100;
+            default 200;
+            units "hours";
+        }
+    }
+
+    deviation "/dev-tgt:my-list" {
+        deviate add {
+            unique "my-leaf-a my-leaf-b";
+            unique "my-leaf-c my-leaf-d";
+        }
+    }
+
+    deviation "/dev-tgt:my-choice" {
+        deviate add {
+            default c2;
+        }
+    }
+
+    deviation "/dev-tgt:my-rpc/dev-tgt:input" {
+        deviate add {
+            must "day or night";
+            must "black and white";
+        }
+    }
+
+    deviation "/dev-tgt:my-rpc/dev-tgt:output" {
+        deviate add {
+            must "day or night";
+            must "black and white";
+        }
+    }
+
+    deviation "/dev-tgt:my-notification" {
+        deviate add {
+            must "day or night";
+            must "black and white";
+        }
+    }
+
+    deviation "/dev-tgt:my-anyxml" {
+        deviate add {
+            mandatory true;
+            dev:custom-property "arg";
+            dev:custom-property "another arg";
+        }
+    }
+
+    extension custom-property {
+        argument name;
+    }
+}
\ No newline at end of file
index 0fd488265cb7e42aecdf38a27e0fbc8158dc1a09..d1b676b873bc6d5999a7450563c0716d9cd06306 100644 (file)
@@ -5,7 +5,9 @@ module identities {
 
     identity id-a;
     identity id-b;
-    identity id-c;
+    identity id-c {
+        status "deprecated";
+    }
 
     identity derived-id {
         base id-a;
@@ -19,11 +21,13 @@ module identities {
             base id-b;
             base id-c;
         }
+        mandatory true;
     }
 
     leaf idref-leaf-2 {
         type identityref {
             base derived-id;
         }
+        config true;
     }
 }
index c7f76ae86d8b8a9bc93e61389a66760c9660cf8b..bd716f6a60ebc747699e1dfb5add80cfd992e34f 100644 (file)
@@ -4,4 +4,6 @@ module import-yang1 {
     yang-version 1;
 
     import action { prefix ac; revision-date 1970-01-01; }
+    
+    revision 1970-01-01;
 }
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/include.yang b/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/include.yang
new file mode 100644 (file)
index 0000000..d04249e
--- /dev/null
@@ -0,0 +1,34 @@
+module include {
+    yang-version 1.1;
+    namespace include;
+    prefix inc;
+
+    import deviation-target { prefix dev-tgt; revision-date 2017-01-20; reference "import ref"; description "import desc"; }
+
+    include submodule {
+        revision-date 1970-01-01;
+        reference "include ref";
+        description "include desc";
+    }
+
+    reference "module ref";
+    description "module desc";
+
+    revision 2017-06-26 {
+        description "2017-06-26 revision desc";
+        reference "2017-06-26 revision ref";
+    }
+
+    revision 2016-06-26 {
+        description "2016-06-26 revision desc";
+        reference "2016-06-26 revision ref";
+    }
+
+    revision 2015-06-26 {
+        description "2015-06-26 revision desc";
+        reference "2015-06-26 revision ref";
+    }
+
+    container root {
+    }
+}
index 8831696c2c9c0c13c3a7096d5e951b5a5cf6431c..2e66c27afd6e28d6e9c92a84b37e78a4ed00fb93 100644 (file)
@@ -7,6 +7,9 @@ module leafref-yang1 {
         type leafref {
             path "/target";
         }
+        status current;
+        mandatory true;
+        config false;
     }
 
     leaf target {
index 1cfae57ad2d41fa516b9bf4751d1f4f6a0a6258c..21f425ca92c1b4e4979ff2c88a83937d9ebb6c11 100644 (file)
@@ -5,7 +5,14 @@ module modifier-yang1 {
 
     leaf my-leaf {
         type string {
-            pattern ".*";
+            length 0..2 {
+                error-message "Error message length";
+                error-app-tag "length-out";
+            }
+            pattern ".*" {
+                error-message "Error message pattern";
+                error-app-tag "regex-err";
+            }
         }
     }
 }
index ec66c42505590f098e17dfc8335bfe53ac00705c..66cab845fe552262c4e11b9f9ca2f0d353a04e95 100644 (file)
@@ -17,6 +17,7 @@ module must {
     }
 
     container root {
+        presence "This is a presence container.";
         action a {
             input {
                 must "1!=0";
index 647aa713750dd3c3566adf5d323c007daa1108d1..be8285ab23ac631c591b0ebf712fe8c5c4c5d72a 100644 (file)
@@ -4,7 +4,10 @@ module notification {
     yang-version 1.1;
 
     notification n1 {
+        status deprecated;
         container c {
+            config true;
+            status current;
         }
     }
 
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/submodule.yang b/yang/yang-model-export/src/test/resources/bugs/bug2444/yang/submodule.yang
new file mode 100644 (file)
index 0000000..1347d67
--- /dev/null
@@ -0,0 +1,8 @@
+submodule submodule {
+    belongs-to include {
+        prefix incl;
+    }
+
+    container sub-con {
+    }
+}
index 01ba622d4e947f83420929fe6694985447c7708c..34e41a6029e4cecdd7678e4700a100c3c3803468 100644 (file)
@@ -7,7 +7,7 @@ module unique {
         leaf id {
             type string;
         }
-
+        ordered-by user;
         unique "c1/c2/my-leaf-2";
         unique "my-container/my-leaf-3";
         leaf my-leaf-1 {
index 134f0cd28d80fb201d33adbf8125ab290072e280..8b98c19f641f29551f8239c36eb46ae7f4098b22 100644 (file)
@@ -1,21 +1,12 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:ac="action"
-    name="action">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="action"></namespace>
-    <prefix value="ac"></prefix>
-    <revision date="1970-01-01"></revision>
-    <extension name="my-ext">
-        <argument name="my-arg">
-            <yin-element value="false"></yin-element>
-        </argument>
-        <status value="current"></status>
-    </extension>
+<module name="action" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:ac="action">
+    <namespace uri="action" />
+    <prefix value="ac" />
+    <yang-version value="1.1" />
     <container name="root">
-        <presence value="false"></presence>
-        <config value="true"></config>
-        <status value="current"></status>
         <action name="a">
-            <status value="deprecated"></status>
+            <if-feature name="my-feature-1 or my-feature-2" />
+            <status value="deprecated" />
             <description>
                 <text>decs</text>
             </description>
                 <text>ref</text>
             </reference>
             <typedef name="my-type">
-                <type name="string"></type>
-                <status value="current"></status>
+                <type name="string" />
             </typedef>
             <grouping name="my-grp">
-                <status value="current"></status>
-                <container name="con-in-grp">
-                    <presence value="false"></presence>
-                    <config value="true"></config>
-                    <status value="current"></status>
-                </container>
+                <container name="con-in-grp" />
             </grouping>
             <input>
-                <container name="i">
-                    <presence value="false"></presence>
-                    <config value="true"></config>
-                    <status value="current"></status>
-                </container>
+                <container name="i" />
             </input>
             <output>
-                <container name="o">
-                    <presence value="false"></presence>
-                    <config value="true"></config>
-                    <status value="current"></status>
-                </container>
+                <container name="o" />
             </output>
-            <ac:my-ext ac:my-arg="arg-val"></ac:my-ext>
+            <ac:my-ext ac:my-arg="arg-val" />
         </action>
     </container>
-</module>
\ No newline at end of file
+    <extension name="my-ext">
+        <argument name="my-arg" />
+    </extension>
+</module>
index 3b03bfdb1e0ae48c68ce633b1172da2a5877e181..98c2c4cb9e39ddbd35d270b509fb963503d26e6f 100644 (file)
@@ -1,27 +1,24 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:ad="anydata"
-    name="anydata">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="anydata"></namespace>
-    <prefix value="ad"></prefix>
-    <revision date="1970-01-01"></revision>
-    <extension name="my-ext">
-        <argument name="my-arg">
-            <yin-element value="false"></yin-element>
-        </argument>
-        <status value="current"></status>
-    </extension>
+<module name="anydata" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:ad="anydata">
+    <namespace uri="anydata" />
+    <prefix value="ad" />
+    <yang-version value="1.1" />
     <anydata name="my-anydata">
-        <when condition="1!=0"></when>
-        <must condition="1=1"></must>
-        <config value="true"></config>
-        <mandatory value="true"></mandatory>
-        <status value="deprecated"></status>
+        <when condition="1!=0" />
+        <must condition="1=1" />
+        <config value="true" />
+        <mandatory value="true" />
+        <if-feature name="my-feature-1 or my-feature-2" />
+        <status value="deprecated" />
         <description>
             <text>decs</text>
         </description>
         <reference>
             <text>ref</text>
         </reference>
-        <ad:my-ext ad:my-arg="arg-val"></ad:my-ext>
+        <ad:my-ext ad:my-arg="arg-val" />
     </anydata>
-</module>
\ No newline at end of file
+    <extension name="my-ext">
+        <argument name="my-arg" />
+    </extension>
+</module>
index 25dcb84dd5280ac81494ce214cc0b79ee65149cb..bd2ef73882081d0661684ad0332657af3cbc7195 100644 (file)
@@ -1,27 +1,13 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:bin="binary-spec"
-    name="binary-spec">
-    <yang-version value="1"></yang-version>
-    <namespace uri="binary-spec"></namespace>
-    <prefix value="bin"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="binary-spec" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:bin="binary-spec">
+    <namespace uri="binary-spec" />
+    <prefix value="bin" />
     <leaf name="bin-leaf">
         <type name="binary">
-            <length value="1..99">
-                <error-message>
-                    <value>The argument is out of bounds &lt;1, 99&gt;
-                    </value>
-                </error-message>
-                <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
-            </length>
+            <length value="1..99" />
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
     </leaf>
     <leaf name="bin-leaf-2">
-        <type name="binary"></type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
+        <type name="binary" />
     </leaf>
 </module>
\ No newline at end of file
index 4b30a3209b3b8fd34cd1efdfffd62ec0a9e61a1f..d2b439edda2ec42c7443bea9adaf8bbe719a14c0 100644 (file)
@@ -1,22 +1,17 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:def="default"
-    name="default">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="default"></namespace>
-    <prefix value="def"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="default" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:def="default">
+    <namespace uri="default" />
+    <prefix value="def" />
+    <yang-version value="1.1" />
     <leaf-list name="my-leaflist-1">
-        <type name="string"></type>
-        <config value="true"></config>
-        <default value="def-val-1"></default>
-        <default value="def-val-2"></default>
-        <default value="def-val-3"></default>
-        <ordered-by value="system"></ordered-by>
-        <status value="current"></status>
+        <type name="string" />
+        <default value="def-val-1" />
+        <default value="def-val-2" />
+        <default value="def-val-3" />
+        <ordered-by value="user" />
     </leaf-list>
     <leaf-list name="my-leaflist-2">
-        <type name="string"></type>
-        <config value="true"></config>
-        <ordered-by value="system"></ordered-by>
-        <status value="current"></status>
+        <type name="string" />
+        <status value="deprecated" />
     </leaf-list>
 </module>
\ No newline at end of file
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/deviation-target@2017-01-20.yin b/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/deviation-target@2017-01-20.yin
new file mode 100644 (file)
index 0000000..e261b27
--- /dev/null
@@ -0,0 +1,58 @@
+<module name="deviation-target" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:tgt="deviation-target">
+    <namespace uri="deviation-target" />
+    <prefix value="tgt" />
+    <yang-version value="1.1" />
+    <revision date="2017-01-20" />
+    <leaf-list name="my-leaf-list">
+        <type name="int32" />
+        <default value="50" />
+    </leaf-list>
+    <list name="my-list">
+        <key value="key-leaf" />
+        <leaf name="key-leaf">
+            <type name="string" />
+        </leaf>
+        <leaf name="my-leaf-a">
+            <type name="string" />
+        </leaf>
+        <leaf name="my-leaf-b">
+            <type name="string" />
+        </leaf>
+        <leaf name="my-leaf-c">
+            <type name="string" />
+        </leaf>
+        <leaf name="my-leaf-d">
+            <type name="string" />
+        </leaf>
+    </list>
+    <choice name="my-choice">
+        <case name="c1">
+            <leaf name="c1-leaf">
+                <type name="string" />
+                <default value="heaven" />
+            </leaf>
+        </case>
+        <case name="c2">
+            <leaf name="c2-leaf">
+                <type name="string" />
+                <default value="hell" />
+            </leaf>
+        </case>
+        <container name="shortcase" />
+    </choice>
+    <rpc name="my-rpc">
+        <input>
+            <leaf name="my-rpc-input-leaf">
+                <type name="string" />
+            </leaf>
+        </input>
+        <output>
+            <leaf name="my-rpc-output-leaf">
+                <type name="string" />
+            </leaf>
+        </output>
+    </rpc>
+    <notification name="my-notification" />
+    <anyxml name="my-anyxml" />
+</module>
\ No newline at end of file
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/deviation@2017-01-20.yin b/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/deviation@2017-01-20.yin
new file mode 100644 (file)
index 0000000..698a656
--- /dev/null
@@ -0,0 +1,60 @@
+<module name="deviation" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:dev="deviation" xmlns:dev-tgt="deviation-target">
+    <namespace uri="deviation" />
+    <prefix value="dev" />
+    <yang-version value="1.1" />
+    <import module="deviation-target">
+        <prefix value="dev-tgt" />
+        <revision-date date="2017-01-20" />
+    </import>
+    <revision date="2017-01-20" />
+    <deviation target-node="/dev-tgt:my-leaf-list">
+        <deviate value="add">
+            <config value="false" />
+            <min-elements value="5" />
+            <max-elements value="10" />
+            <default value="100" />
+            <default value="200" />
+            <units name="hours" />
+        </deviate>
+    </deviation>
+    <deviation target-node="/dev-tgt:my-list">
+        <deviate value="add">
+            <unique tag="my-leaf-a my-leaf-b" />
+            <unique tag="my-leaf-c my-leaf-d" />
+        </deviate>
+    </deviation>
+    <deviation target-node="/dev-tgt:my-choice">
+        <deviate value="add">
+            <default value="c2" />
+        </deviate>
+    </deviation>
+    <deviation target-node="/dev-tgt:my-rpc/dev-tgt:input">
+        <deviate value="add">
+            <must condition="day or night" />
+            <must condition="black and white" />
+        </deviate>
+    </deviation>
+    <deviation target-node="/dev-tgt:my-rpc/dev-tgt:output">
+        <deviate value="add">
+            <must condition="day or night" />
+            <must condition="black and white" />
+        </deviate>
+    </deviation>
+    <deviation target-node="/dev-tgt:my-notification">
+        <deviate value="add">
+            <must condition="day or night" />
+            <must condition="black and white" />
+        </deviate>
+    </deviation>
+    <deviation target-node="/dev-tgt:my-anyxml">
+        <deviate value="add">
+            <mandatory value="true" />
+            <dev:custom-property dev:name="arg" />
+            <dev:custom-property dev:name="another arg" />
+        </deviate>
+    </deviation>
+    <extension name="custom-property">
+        <argument name="name" />
+    </extension>
+</module>
\ No newline at end of file
index a590545443d79576fcfea6d123068f2a50c472e6..6ccd52528563ec442e4edae674061527d89f82f8 100644 (file)
@@ -1,40 +1,30 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:iden="identities"
-    name="identities">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="identities"></namespace>
-    <prefix value="iden"></prefix>
-    <revision date="1970-01-01"></revision>
-    <identity name="id-a">
-        <status value="current"></status>
-    </identity>
-    <identity name="id-b">
-        <status value="current"></status>
-    </identity>
+<module name="identities" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:iden="identities">
+    <namespace uri="identities" />
+    <prefix value="iden" />
+    <yang-version value="1.1" />
+    <identity name="id-a" />
+    <identity name="id-b" />
     <identity name="id-c">
-        <status value="current"></status>
+        <status value="deprecated" />
     </identity>
     <identity name="derived-id">
-        <base name="id-a"></base>
-        <base name="id-b"></base>
-        <base name="id-c"></base>
-        <status value="current"></status>
+        <base name="id-a" />
+        <base name="id-b" />
+        <base name="id-c" />
     </identity>
     <leaf name="idref-leaf">
         <type name="identityref">
-            <base name="id-a"></base>
-            <base name="id-b"></base>
-            <base name="id-c"></base>
+            <base name="id-a" />
+            <base name="id-b" />
+            <base name="id-c" />
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
+        <mandatory value="true" />
     </leaf>
     <leaf name="idref-leaf-2">
         <type name="identityref">
-            <base name="derived-id"></base>
+            <base name="derived-id" />
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
+        <config value="true" />
     </leaf>
 </module>
\ No newline at end of file
index 135dc091181096f5a620088148198c48df330855..4bfc82419e833cd1a7bf4cf9a78209a8d329a219 100644 (file)
@@ -1,11 +1,11 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:iy1="import-yang1"
-    xmlns:ac="action" name="import-yang1">
-    <yang-version value="1"></yang-version>
-    <namespace uri="import-yang1"></namespace>
-    <prefix value="iy1"></prefix>
+<module name="import-yang1" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:iy1="import-yang1">
+    <namespace uri="import-yang1" />
+    <prefix value="iy1" />
+    <yang-version value="1" />
     <import module="action">
-        <prefix value="ac"></prefix>
-        <revision-date date="1970-01-01"></revision-date>
+        <prefix value="ac" />
+        <revision-date date="1970-01-01" />
     </import>
-    <revision date="1970-01-01"></revision>
-</module>
\ No newline at end of file
+    <revision date="1970-01-01" />
+</module>
index 8b6520b467c1191bfc65532bc8a4d111b5b14087..3b97daa05c579f44f26f566648c590cea30dac7e 100644 (file)
@@ -1,8 +1,8 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:i="import"
-    xmlns:ac="action" name="import">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="import"></namespace>
-    <prefix value="i"></prefix>
+<module name="import" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:i="import">
+    <namespace uri="import" />
+    <prefix value="i" />
+    <yang-version value="1.1" />
     <import module="action">
         <description>
             <text>txt</text>
@@ -10,8 +10,7 @@
         <reference>
             <text>ref</text>
         </reference>
-        <prefix value="ac"></prefix>
-        <revision-date date="1970-01-01"></revision-date>
+        <prefix value="ac" />
+        <revision-date date="1970-01-01" />
     </import>
-    <revision date="1970-01-01"></revision>
-</module>
\ No newline at end of file
+</module>
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/include@2017-06-26.yin b/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/include@2017-06-26.yin
new file mode 100644 (file)
index 0000000..3e4996b
--- /dev/null
@@ -0,0 +1,56 @@
+<module name="include" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:inc="include" xmlns:dev-tgt="deviation-target">
+    <yang-version value="1.1" />
+    <namespace uri="include" />
+    <prefix value="inc" />
+    <import module="deviation-target">
+        <prefix value="dev-tgt" />
+        <revision-date date="2017-01-20" />
+        <reference>
+            <text>import ref</text>
+        </reference>
+        <description>
+            <text>import desc</text>
+        </description>
+    </import>
+    <include module="submodule">
+        <revision-date date="1970-01-01" />
+        <reference>
+            <text>include ref</text>
+        </reference>
+        <description>
+            <text>include desc</text>
+        </description>
+    </include>
+    <reference>
+        <text>module ref</text>
+    </reference>
+    <description>
+        <text>module desc</text>
+    </description>
+    <revision date="2017-06-26">
+        <description>
+            <text>2017-06-26 revision desc</text>
+        </description>
+        <reference>
+            <text>2017-06-26 revision ref</text>
+        </reference>
+    </revision>
+    <revision date="2016-06-26">
+        <description>
+            <text>2016-06-26 revision desc</text>
+        </description>
+        <reference>
+            <text>2016-06-26 revision ref</text>
+        </reference>
+    </revision>
+    <revision date="2015-06-26">
+        <description>
+            <text>2015-06-26 revision desc</text>
+        </description>
+        <reference>
+            <text>2015-06-26 revision ref</text>
+        </reference>
+    </revision>
+    <container name="root" />
+</module>
index c04d24d42307c42b67a3435c150c6dad501a21a4..7c940f756163bdd260807b6cdabb275f51a91f00 100644 (file)
@@ -1,21 +1,17 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:lr="leafref-yang1"
-    name="leafref-yang1">
-    <yang-version value="1"></yang-version>
-    <namespace uri="leafref-yang1"></namespace>
-    <prefix value="lr"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="leafref-yang1" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:lr="leafref-yang1">
+    <namespace uri="leafref-yang1" />
+    <prefix value="lr" />
+    <yang-version value="1" />
     <leaf name="my-leafref-3">
         <type name="leafref">
-            <path value="/target"></path>
+            <path value="/target" />
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
+        <status value="current" />
+        <mandatory value="true" />
+        <config value="false" />
     </leaf>
     <leaf name="target">
-        <type name="string"></type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
+        <type name="string" />
     </leaf>
-</module>
\ No newline at end of file
+</module>
index 6b46b4ff9296f0d60867183e89cd419527579e65..d006ac3e22ba6b797ee209609efea35525f80d9e 100644 (file)
@@ -1,40 +1,26 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:lr="leafref"
-    name="leafref">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="leafref"></namespace>
-    <prefix value="lr"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="leafref" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:lr="leafref">
+    <namespace uri="leafref" />
+    <prefix value="lr" />
+    <yang-version value="1.1" />
     <leaf name="my-leafref">
         <type name="leafref">
-            <path value="/target"></path>
-            <require-instance value="false"></require-instance>
+            <path value="/target" />
+            <require-instance value="false" />
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
     </leaf>
     <leaf name="my-leafref-2">
         <type name="leafref">
-            <path value="/target"></path>
-            <require-instance value="true"></require-instance>
+            <path value="/target" />
+            <require-instance value="true" />
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
     </leaf>
     <leaf name="my-leafref-3">
         <type name="leafref">
-            <path value="/target"></path>
-            <require-instance value="false"></require-instance>
+            <path value="/target" />
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
     </leaf>
     <leaf name="target">
-        <type name="string"></type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
+        <type name="string" />
     </leaf>
-</module>
\ No newline at end of file
+</module>
index 55b167b7be2727b715af62b41046d1b6a216440a..601ba778f6188a0bb7991e51ca6424b1763a895d 100644 (file)
@@ -1,28 +1,22 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:my1="modifier-yang1"
-    name="modifier-yang1">
-    <yang-version value="1"></yang-version>
-    <namespace uri="modifier-yang1"></namespace>
-    <prefix value="my1"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="modifier-yang1" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:my1="modifier-yang1">
+    <namespace uri="modifier-yang1" />
+    <prefix value="my1" />
+    <yang-version value="1" />
     <leaf name="my-leaf">
         <type name="string">
-            <length value="0..2147483647">
+            <length value="0..2">
                 <error-message>
-                    <value>The argument is out of bounds &lt;0,
-                        2147483647&gt;</value>
+                    <value>Error message length</value>
                 </error-message>
-                <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
+                <error-app-tag value="length-out" />
             </length>
             <pattern value=".*">
                 <error-message>
-                    <value>Supplied value does not match the regular
-                        expression ^.*$.</value>
+                    <value>Error message pattern</value>
                 </error-message>
-                <error-app-tag value="invalid-regular-expression"></error-app-tag>
+                <error-app-tag value="regex-err" />
             </pattern>
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
     </leaf>
-</module>
\ No newline at end of file
+</module>
index d31a2e837b1e886e1109ae8c7c82886256f96215..fcf5787910fe49c200128ca9724b29bc36dbb485 100644 (file)
@@ -1,29 +1,13 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:m="modifier"
-    name="modifier">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="modifier"></namespace>
-    <prefix value="m"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="modifier" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:m="modifier">
+    <namespace uri="modifier" />
+    <prefix value="m" />
+    <yang-version value="1.1" />
     <leaf name="my-leaf">
         <type name="string">
-            <length value="0..2147483647">
-                <error-message>
-                    <value>The argument is out of bounds &lt;0,
-                        2147483647&gt;</value>
-                </error-message>
-                <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
-            </length>
             <pattern value=".*">
-                <error-message>
-                    <value>Supplied value does not match the regular
-                        expression ^.*$.</value>
-                </error-message>
-                <error-app-tag value="invalid-regular-expression"></error-app-tag>
-                <modifier value="invert-match"></modifier>
+                <modifier value="invert-match" />
             </pattern>
         </type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
     </leaf>
-</module>
\ No newline at end of file
+</module>
index 7cf963f111e60788d9fc4752fab7a70c07b2284f..c4934d0cec86ba17d8ddebc75b0708991bf29f31 100644 (file)
@@ -1,15 +1,11 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:muy1="must-yang1"
-    name="must-yang1">
-    <yang-version value="1"></yang-version>
-    <namespace uri="must-yang1"></namespace>
-    <prefix value="muy1"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="must-yang1" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:muy1="must-yang1">
+    <namespace uri="must-yang1" />
+    <prefix value="muy1" />
+    <yang-version value="1" />
+    <notification name="n" />
     <rpc name="r">
-        <status value="current"></status>
-        <input></input>
-        <output></output>
+        <input />
+        <output />
     </rpc>
-    <notification name="n">
-        <status value="current"></status>
-    </notification>
-</module>
\ No newline at end of file
+</module>
index ba63fb152d455720f81945ff2dce307f5fe5ce9d..2008e0170e821018cbf91496848518db03489864 100644 (file)
@@ -1,34 +1,28 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:mu="must"
-    name="must">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="must"></namespace>
-    <prefix value="mu"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="must" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:mu="must">
+    <namespace uri="must" />
+    <prefix value="mu" />
+    <yang-version value="1.1" />
+    <notification name="n">
+        <must condition="1!=0" />
+    </notification>
+    <rpc name="r">
+        <input>
+            <must condition="1!=0" />
+        </input>
+        <output>
+            <must condition="1!=0" />
+        </output>
+    </rpc>
     <container name="root">
-        <presence value="false"></presence>
-        <config value="true"></config>
-        <status value="current"></status>
+        <presence value="This is a presence container." />
         <action name="a">
-            <status value="current"></status>
             <input>
-                <must condition="1!=0"></must>
+                <must condition="1!=0" />
             </input>
             <output>
-                <must condition="1!=0"></must>
+                <must condition="1!=0" />
             </output>
         </action>
     </container>
-    <rpc name="r">
-        <status value="current"></status>
-        <input>
-            <must condition="1!=0"></must>
-        </input>
-        <output>
-            <must condition="1!=0"></must>
-        </output>
-    </rpc>
-    <notification name="n">
-        <must condition="1!=0"></must>
-        <status value="current"></status>
-    </notification>
-</module>
\ No newline at end of file
+</module>
index 0653b6563710c58bccf99ed2b61c7dcfaf9f0726..5d51bf1d656bb4f8780d0217f7415c743702d2da 100644 (file)
@@ -1,60 +1,30 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:n="notification"
-    name="notification">
-    <yang-version value="1.1"></yang-version>
-    <namespace uri="notification"></namespace>
-    <prefix value="n"></prefix>
-    <revision date="1970-01-01"></revision>
-    <grouping name="grp">
-        <status value="current"></status>
-        <notification name="n5">
-            <status value="current"></status>
-        </notification>
-    </grouping>
+<module name="notification" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:n="notification">
+    <namespace uri="notification" />
+    <prefix value="n" />
+    <yang-version value="1.1" />
+    <notification name="n1">
+        <status value="deprecated" />
+        <container name="c">
+            <config value="true" />
+            <status value="current" />
+        </container>
+    </notification>
     <container name="r">
-        <presence value="false"></presence>
-        <config value="true"></config>
-        <status value="current"></status>
-        <notification name="n2">
-            <status value="current"></status>
-        </notification>
-        <notification name="n4">
-            <status value="current"></status>
-        </notification>
-        <notification name="n5">
-            <status value="current"></status>
-        </notification>
+        <notification name="n2" />
     </container>
     <list name="l">
-        <key value="id"></key>
-        <config value="true"></config>
-        <ordered-by value="system"></ordered-by>
-        <status value="current"></status>
+        <key value="id" />
         <leaf name="id">
-            <type name="int16"></type>
-            <config value="true"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
+            <type name="int16" />
         </leaf>
-        <notification name="n3">
-            <status value="current"></status>
-        </notification>
+        <notification name="n3" />
     </list>
     <augment target-node="/r">
-        <status value="current"></status>
-        <uses name="grp"></uses>
-        <notification name="n5">
-            <status value="current"></status>
-        </notification>
-        <notification name="n4">
-            <status value="current"></status>
-        </notification>
+        <uses name="grp" />
+        <notification name="n4" />
     </augment>
-    <notification name="n1">
-        <status value="current"></status>
-        <container name="c">
-            <presence value="false"></presence>
-            <config value="true"></config>
-            <status value="current"></status>
-        </container>
-    </notification>
-</module>
\ No newline at end of file
+    <grouping name="grp">
+        <notification name="n5" />
+    </grouping>
+</module>
diff --git a/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/submodule@1970-01-01.yin b/yang/yang-model-export/src/test/resources/bugs/bug2444/yin/submodule@1970-01-01.yin
new file mode 100644 (file)
index 0000000..7be82fb
--- /dev/null
@@ -0,0 +1,7 @@
+<submodule name="submodule" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:incl="include">
+    <belongs-to module="include">
+        <prefix value="incl" />
+    </belongs-to>
+    <container name="sub-con" />
+</submodule>
index bab20f315f01c60d24db0640f24a39c844ed4047..a878d2666ad32d5bcda45ee78fd146e51043535c 100644 (file)
@@ -1,54 +1,29 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:u="unique"
-    name="unique">
-    <yang-version value="1"></yang-version>
-    <namespace uri="unique"></namespace>
-    <prefix value="u"></prefix>
-    <revision date="1970-01-01"></revision>
+<module name="unique" xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:u="unique">
+    <namespace uri="unique" />
+    <prefix value="u" />
     <list name="l">
-        <key value="id"></key>
-        <unique tag="c1/c2/my-leaf-2"></unique>
-        <unique tag="my-container/my-leaf-3"></unique>
-        <config value="true"></config>
-        <ordered-by value="system"></ordered-by>
-        <status value="current"></status>
+        <key value="id" />
         <leaf name="id">
-            <type name="string"></type>
-            <config value="true"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
+            <type name="string" />
         </leaf>
+        <ordered-by value="user" />
+        <unique tag="c1/c2/my-leaf-2" />
+        <unique tag="my-container/my-leaf-3" />
         <leaf name="my-leaf-1">
-            <type name="string"></type>
-            <config value="true"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
+            <type name="string" />
         </leaf>
         <container name="c1">
-            <presence value="false"></presence>
-            <config value="true"></config>
-            <status value="current"></status>
             <container name="c2">
-                <presence value="false"></presence>
-                <config value="true"></config>
-                <status value="current"></status>
                 <leaf name="my-leaf-2">
-                    <type name="string"></type>
-                    <config value="true"></config>
-                    <mandatory value="false"></mandatory>
-                    <status value="current"></status>
+                    <type name="string" />
                 </leaf>
             </container>
         </container>
         <container name="my-container">
-            <presence value="false"></presence>
-            <config value="true"></config>
-            <status value="current"></status>
             <leaf name="my-leaf-3">
-                <type name="string"></type>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
-                <status value="current"></status>
+                <type name="string" />
             </leaf>
         </container>
     </list>
-</module>
\ No newline at end of file
+</module>
index b070218452963740aaf8fb87a8513f541b717de2..6464ee46793a7924934ed21d1411ef57d1524019 100644 (file)
@@ -1,10 +1,9 @@
-<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:foo-prefix="foo-namespace" name="foo">
-    <yang-version value="1"></yang-version>
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1"
+    xmlns:foo-prefix="foo-namespace" name="foo">
     <namespace uri="foo-namespace"></namespace>
     <prefix value="foo-prefix"></prefix>
     <revision date="2016-08-05"></revision>
     <extension name="test-extension">
-        <status value="current"></status>
     </extension>
     <feature name="test-feature">
         <status value="current"></status>
         </reference>
     </identity>
     <identity name="test-base-identity">
-        <status value="current"></status>
     </identity>
     <typedef name="test-uint32-typedef">
         <type name="uint32">
             <range value="50..100">
-                <error-message>
-                    <value>The argument is out of bounds &lt;50, 100&gt;</value>
-                </error-message>
-                <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
             </range>
         </type>
         <units name="seconds"></units>
-        <status value="current"></status>
     </typedef>
     <typedef name="test-int32-typedef">
         <type name="int32">
             <range value="50..100">
-                <error-message>
-                    <value>The argument is out of bounds &lt;50, 100&gt;</value>
-                </error-message>
-                <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
             </range>
         </type>
-        <status value="current"></status>
     </typedef>
     <typedef name="test-leafref-typedef">
         <type name="leafref">
             <path value="../leafref-target-leaf"></path>
         </type>
-        <status value="current"></status>
     </typedef>
     <typedef name="test-iid-typedef">
         <type name="instance-identifier">
             <require-instance value="false"></require-instance>
         </type>
-        <status value="current"></status>
     </typedef>
     <grouping name="test-grouping-1">
-        <status value="current"></status>
         <leaf name="test-leaf-1">
             <type name="string"></type>
             <default value="def-val"></default>
-            <config value="true"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
         </leaf>
         <leaf-list name="test-leaf-list">
             <type name="string"></type>
             <config value="false"></config>
             <ordered-by value="user"></ordered-by>
-            <status value="current"></status>
         </leaf-list>
         <list name="test-list">
             <key value="key-leaf-1 key-leaf-2"></key>
-            <config value="true"></config>
             <min-elements value="5"></min-elements>
-            <ordered-by value="system"></ordered-by>
-            <status value="current"></status>
             <leaf name="key-leaf-1">
                 <type name="string"></type>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
-                <status value="current"></status>
             </leaf>
             <leaf name="key-leaf-2">
                 <type name="string"></type>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
-                <status value="current"></status>
             </leaf>
         </list>
         <container name="test-container-2">
-            <presence value="false"></presence>
             <config value="false"></config>
-            <status value="current"></status>
         </container>
     </grouping>
     <grouping name="test-grouping-2">
-        <status value="current"></status>
         <anyxml name="test-anyxml-2">
             <config value="false"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
         </anyxml>
         <choice name="test-choice-2">
             <config value="false"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
             <case name="first">
-                <status value="current"></status>
                 <leaf name="first-case-leaf">
                     <type name="string">
-                        <length value="10|15">
-                            <error-message>
-                                <value>The argument is out of bounds &lt;10, 10&gt;</value>
-                            </error-message>
-                            <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
+                        <length value="10..10 | 15">
                         </length>
                     </type>
-                    <config value="false"></config>
-                    <mandatory value="false"></mandatory>
-                    <status value="current"></status>
                 </leaf>
             </case>
             <case name="second">
-                <status value="current"></status>
                 <leaf name="second-case-leaf">
                     <type name="int32">
-                        <range value="10|15">
-                            <error-message>
-                                <value>The argument is out of bounds &lt;10, 10&gt;</value>
-                            </error-message>
-                            <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
+                        <range value="10..10 | 15">
                         </range>
                     </type>
-                    <config value="false"></config>
-                    <mandatory value="false"></mandatory>
-                    <status value="current"></status>
                 </leaf>
             </case>
         </choice>
     <anyxml name="test-anyxml">
         <when condition="foo != 'bar'"></when>
         <must condition="bar != 'foo'"></must>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
         <foo-prefix:test-extension></foo-prefix:test-extension>
     </anyxml>
     <leaf name="leafref-target-leaf">
         <type name="string"></type>
-        <config value="true"></config>
-        <mandatory value="false"></mandatory>
-        <status value="current"></status>
     </leaf>
     <container name="test-container-1">
         <must condition="bar != 'foo'"></must>
-        <presence value="false"></presence>
-        <config value="true"></config>
-        <status value="current"></status>
     </container>
     <container name="test-container-3">
-        <presence value="false"></presence>
-        <config value="true"></config>
-        <status value="current"></status>
         <choice name="test-choice">
-            <config value="true"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
             <case name="a">
-                <status value="current"></status>
                 <leaf name="case-a-leaf">
                     <type name="int32"></type>
-                    <config value="true"></config>
-                    <mandatory value="false"></mandatory>
-                    <status value="current"></status>
                 </leaf>
             </case>
             <case name="b">
-                <status value="current"></status>
                 <leaf name="case-b-leaf">
                     <type name="decimal64">
                         <fraction-digits value="3"></fraction-digits>
-                        <range value="-9223372036854775.808..9223372036854775.807">
-                            <error-message>
-                                <value>The argument is out of bounds &lt;-9223372036854775.808, 9223372036854775.807&gt;</value>
-                            </error-message>
-                            <error-app-tag value="range-out-of-specified-bounds"></error-app-tag>
-                            <reference>
-                                <text>https://tools.ietf.org/html/rfc6020#section-9.3.4</text>
-                            </reference>
-                        </range>
                     </type>
-                    <config value="true"></config>
-                    <mandatory value="false"></mandatory>
-                    <status value="current"></status>
                 </leaf>
             </case>
         </choice>
             <type name="bits">
                 <bit name="one">
                     <position value="1"></position>
-                    <status value="current"></status>
                 </bit>
                 <bit name="two">
                     <position value="2"></position>
-                    <status value="current"></status>
                 </bit>
             </type>
-            <config value="true"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
         </leaf>
         <leaf name="identityref-leaf">
             <type name="identityref">
                 <base name="test-base-identity"></base>
             </type>
-            <config value="true"></config>
-            <mandatory value="false"></mandatory>
-            <status value="current"></status>
         </leaf>
     </container>
     <augment target-node="/test-container-3/test-choice">
-        <status value="current"></status>
         <case name="c">
-            <status value="current"></status>
             <leaf name="case-c-leaf">
                 <type name="string"></type>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
-                <status value="current"></status>
             </leaf>
         </case>
     </augment>
     <augment target-node="/test-container-1">
-        <status value="current"></status>
         <uses name="test-grouping-1">
             <refine target-node="test-list">
-                <config value="true"></config>
                 <min-elements value="5"></min-elements>
             </refine>
             <refine target-node="test-leaf-list">
             </refine>
             <refine target-node="test-leaf-1">
                 <default value="def-val"></default>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
             </refine>
             <refine target-node="test-container-2">
-                <presence value="false"></presence>
                 <config value="false"></config>
             </refine>
             <augment target-node="test-container-2">
-                <status value="current"></status>
                 <leaf name="test-leaf-2">
                     <type name="string"></type>
-                    <config value="true"></config>
-                    <mandatory value="false"></mandatory>
-                    <status value="current"></status>
                 </leaf>
             </augment>
         </uses>
     </augment>
     <rpc name="test-rpc">
-        <status value="current"></status>
         <grouping name="rpc-grouping">
-            <status value="current"></status>
             <leaf name="rpc-grouping-leaf">
                 <type name="string"></type>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
-                <status value="current"></status>
             </leaf>
         </grouping>
         <input>
             <leaf name="input-leaf">
                 <type name="string"></type>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
-                <status value="current"></status>
             </leaf>
         </input>
         <output>
             <leaf name="output-leaf">
                 <type name="string"></type>
-                <config value="true"></config>
-                <mandatory value="false"></mandatory>
-                <status value="current"></status>
             </leaf>
         </output>
     </rpc>
     <notification name="test-notification">
-        <status value="current"></status>
         <uses name="test-grouping-2">
             <refine target-node="test-choice-2">
                 <config value="false"></config>
-                <mandatory value="false"></mandatory>
             </refine>
             <refine target-node="test-anyxml-2">
                 <config value="false"></config>
-                <mandatory value="false"></mandatory>
             </refine>
         </uses>
     </notification>