Remove javax.annotation nullness from yang-model-export
[yangtools.git] / yang / yang-model-export / src / main / java / org / opendaylight / yangtools / yang / model / export / SchemaContextEmitter.java
index aedcb8f716c14afd7151e9fda109c506676b1563..09d427955d7a5265f31a41452a411b7922dda1b5 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.model.export;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Collections2;
 import com.google.common.collect.Range;
 import com.google.common.collect.RangeSet;
 import com.google.common.primitives.UnsignedInteger;
@@ -23,9 +24,9 @@ import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import javax.annotation.concurrent.NotThreadSafe;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.YangVersion;
@@ -33,14 +34,14 @@ import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
 import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Deviation;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
+import org.opendaylight.yangtools.yang.model.api.ElementCountConstraint;
 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
 import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
@@ -50,6 +51,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.MustConstraintAware;
 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
@@ -154,17 +156,17 @@ import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.RangeRestrictedTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
 
+@Deprecated
 @Beta
 @NotThreadSafe
 abstract class SchemaContextEmitter {
@@ -182,10 +184,10 @@ abstract class SchemaContextEmitter {
 
     SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
             final YangVersion yangVersion, final boolean emitInstantiated, final boolean emitUses) {
-        this.writer = Preconditions.checkNotNull(writer);
+        this.writer = requireNonNull(writer);
         this.emitInstantiated = emitInstantiated;
         this.emitUses = emitUses;
-        this.extensions = Preconditions.checkNotNull(extensions);
+        this.extensions = requireNonNull(extensions);
         this.yangVersion = yangVersion;
     }
 
@@ -201,7 +203,7 @@ abstract class SchemaContextEmitter {
              * use DeclaredSchemaContextEmitter
              */
             new DeclaredSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion())
-            .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
+                .emitModule(((EffectiveStatement<?, ?>) module).getDeclared());
         } else {
             /*
              * if we don't have access to declared form of supplied module or we
@@ -209,7 +211,7 @@ abstract class SchemaContextEmitter {
              * by uses or augment), we use EffectiveSchemaContextEmitter.
              */
             new EffectiveSchemaContextEmitter(yangSchemaWriter, extensions, module.getYangVersion(), emitInstantiated)
-            .emitModule(module);
+                .emitModule(module);
         }
     }
 
@@ -373,7 +375,7 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitYangVersionNode(@Nullable final YangVersionStatement yangVersionStatement) {
+        private void emitYangVersionNode(final @Nullable YangVersionStatement yangVersionStatement) {
             if (yangVersionStatement != null) {
                 super.writer.startYangVersionNode(yangVersionStatement.rawArgument());
                 super.writer.endNode();
@@ -396,46 +398,44 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitNamespace(final NamespaceStatement namespaceStatement) {
-            Preconditions.checkNotNull(namespaceStatement, "Namespace must not be null");
-            super.writer.startNamespaceNode(namespaceStatement.getUri());
+            super.writer.startNamespaceNode(requireNonNull(namespaceStatement, "Namespace must not be null").getUri());
             super.writer.endNode();
         }
 
         private void emitPrefixNode(final PrefixStatement prefixStatement) {
-            Preconditions.checkNotNull(prefixStatement, "Prefix must not be null");
-            super.writer.startPrefixNode(prefixStatement.rawArgument());
+            super.writer.startPrefixNode(requireNonNull(prefixStatement, "Prefix must not be null").rawArgument());
             super.writer.endNode();
         }
 
-        private void emitOrganizationNode(@Nullable final OrganizationStatement organizationStatement) {
+        private void emitOrganizationNode(final @Nullable OrganizationStatement organizationStatement) {
             if (organizationStatement != null) {
                 super.writer.startOrganizationNode(organizationStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitContact(@Nullable final ContactStatement contactStatement) {
+        private void emitContact(final @Nullable ContactStatement contactStatement) {
             if (contactStatement != null) {
                 super.writer.startContactNode(contactStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitDescriptionNode(@Nullable final DescriptionStatement descriptionStatement) {
+        private void emitDescriptionNode(final @Nullable DescriptionStatement descriptionStatement) {
             if (descriptionStatement != null) {
                 super.writer.startDescriptionNode(descriptionStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitReferenceNode(@Nullable final ReferenceStatement referenceStatement) {
+        private void emitReferenceNode(final @Nullable ReferenceStatement referenceStatement) {
             if (referenceStatement != null) {
                 super.writer.startReferenceNode(referenceStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitUnitsNode(@Nullable final UnitsStatement unitsStatement) {
+        private void emitUnitsNode(final @Nullable UnitsStatement unitsStatement) {
             if (unitsStatement != null) {
                 super.writer.startUnitsNode(unitsStatement.rawArgument());
                 super.writer.endNode();
@@ -454,7 +454,7 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitRevisionDateNode(@Nullable final RevisionDateStatement revisionDateStatement) {
+        private void emitRevisionDateNode(final @Nullable RevisionDateStatement revisionDateStatement) {
             if (revisionDateStatement != null) {
                 super.writer.startRevisionDateNode(revisionDateStatement.rawArgument());
                 super.writer.endNode();
@@ -469,7 +469,7 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitArgument(@Nullable final ArgumentStatement input) {
+        private void emitArgument(final @Nullable ArgumentStatement input) {
             if (input != null) {
                 super.writer.startArgumentNode(input.rawArgument());
                 emitYinElement(input.getYinElement());
@@ -477,7 +477,7 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitYinElement(@Nullable final YinElementStatement yinElementStatement) {
+        private void emitYinElement(final @Nullable YinElementStatement yinElementStatement) {
             if (yinElementStatement != null) {
                 super.writer.startYinElementNode(yinElementStatement.rawArgument());
                 super.writer.endNode();
@@ -599,7 +599,7 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitDefaultNode(@Nullable final DefaultStatement defaultStmt) {
+        private void emitDefaultNode(final @Nullable DefaultStatement defaultStmt) {
             if (defaultStmt != null) {
                 super.writer.startDefaultNode(defaultStmt.rawArgument());
                 super.writer.endNode();
@@ -630,49 +630,49 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitPositionNode(@Nullable final PositionStatement positionStatement) {
+        private void emitPositionNode(final @Nullable PositionStatement positionStatement) {
             if (positionStatement != null) {
                 super.writer.startPositionNode(positionStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitStatusNode(@Nullable final StatusStatement statusStatement) {
+        private void emitStatusNode(final @Nullable StatusStatement statusStatement) {
             if (statusStatement != null) {
                 super.writer.startStatusNode(statusStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitConfigNode(@Nullable final ConfigStatement configStatement) {
+        private void emitConfigNode(final @Nullable ConfigStatement configStatement) {
             if (configStatement != null) {
                 super.writer.startConfigNode(configStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitMandatoryNode(@Nullable final MandatoryStatement mandatoryStatement) {
+        private void emitMandatoryNode(final @Nullable MandatoryStatement mandatoryStatement) {
             if (mandatoryStatement != null) {
                 super.writer.startMandatoryNode(mandatoryStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitPresenceNode(@Nullable final PresenceStatement presenceStatement) {
+        private void emitPresenceNode(final @Nullable PresenceStatement presenceStatement) {
             if (presenceStatement != null) {
                 super.writer.startPresenceNode(presenceStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitOrderedBy(@Nullable final OrderedByStatement orderedByStatement) {
+        private void emitOrderedBy(final @Nullable OrderedByStatement orderedByStatement) {
             if (orderedByStatement != null) {
                 super.writer.startOrderedByNode(orderedByStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitMust(@Nullable final MustStatement must) {
+        private void emitMust(final @Nullable MustStatement must) {
             if (must != null) {
                 super.writer.startMustNode(must.rawArgument());
                 emitErrorMessageNode(must.getErrorMessageStatement());
@@ -683,35 +683,35 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitErrorMessageNode(@Nullable final ErrorMessageStatement errorMessageStatement) {
+        private void emitErrorMessageNode(final @Nullable ErrorMessageStatement errorMessageStatement) {
             if (errorMessageStatement != null) {
                 super.writer.startErrorMessageNode(errorMessageStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitErrorAppTagNode(@Nullable final ErrorAppTagStatement errorAppTagStatement) {
+        private void emitErrorAppTagNode(final @Nullable ErrorAppTagStatement errorAppTagStatement) {
             if (errorAppTagStatement != null) {
                 super.writer.startErrorAppTagNode(errorAppTagStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitMinElementsNode(@Nullable final MinElementsStatement minElementsStatement) {
+        private void emitMinElementsNode(final @Nullable MinElementsStatement minElementsStatement) {
             if (minElementsStatement != null) {
                 super.writer.startMinElementsNode(minElementsStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitMaxElementsNode(@Nullable final MaxElementsStatement maxElementsStatement) {
+        private void emitMaxElementsNode(final @Nullable MaxElementsStatement maxElementsStatement) {
             if (maxElementsStatement != null) {
                 super.writer.startMaxElementsNode(maxElementsStatement.rawArgument());
                 super.writer.endNode();
             }
         }
 
-        private void emitValueNode(@Nullable final ValueStatement valueStatement) {
+        private void emitValueNode(final @Nullable ValueStatement valueStatement) {
             if (valueStatement != null) {
                 super.writer.startValueNode(valueStatement.rawArgument());
                 super.writer.endNode();
@@ -878,8 +878,7 @@ abstract class SchemaContextEmitter {
                     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");
+                    checkState(shortCaseChilds.size() == 1, "Only one child is allowed for each short case node");
                     emitShortCases(shortCaseChilds);
                 }
             }
@@ -969,15 +968,11 @@ abstract class SchemaContextEmitter {
             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 emitUnknownStatementNodes(final DeclaredStatement<?> declaredStmt) {
+            declaredStmt.streamDeclaredSubstatements(UnknownStatement.class).forEach(this::emitUnknownStatementNode);
         }
 
-        private void emitUnknownStatementNode(final DeclaredStatement<?> unknonwnStmt) {
+        private void emitUnknownStatementNode(final UnknownStatement<?> unknonwnStmt) {
             final StatementDefinition def = unknonwnStmt.statementDefinition();
             if (def.getArgumentName() == null) {
                 super.writer.startUnknownNode(def);
@@ -1116,7 +1111,7 @@ abstract class SchemaContextEmitter {
                 } else if (child instanceof ConfigStatement) {
                     emitConfigNode((ConfigStatement) child);
                 } else if (child instanceof UnknownStatement) {
-                    emitUnknownStatementNode(child);
+                    emitUnknownStatementNode((UnknownStatement<?>) child);
                 }
             }
             super.writer.endNode();
@@ -1330,7 +1325,7 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitUnitsNode(@Nullable final String input) {
+        private void emitUnitsNode(final @Nullable String input) {
             super.writer.startUnitsNode(input);
             super.writer.endNode();
         }
@@ -1389,8 +1384,8 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitBase(final QName qName) {
-            super.writer.startBaseNode(qName);
+        private void emitBase(final QName qname) {
+            super.writer.startBaseNode(qname);
             super.writer.endNode();
         }
 
@@ -1449,12 +1444,10 @@ abstract class SchemaContextEmitter {
         }
 
         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) {
+            if (typeDef instanceof DecimalTypeDefinition) {
                 emitDecimal64Specification((DecimalTypeDefinition) typeDef);
+            } else if (typeDef instanceof RangeRestrictedTypeDefinition) {
+                emitRangeRestrictedSpecification((RangeRestrictedTypeDefinition<?, ?>) typeDef);
             } else if (typeDef instanceof StringTypeDefinition) {
                 emitStringRestrictions((StringTypeDefinition) typeDef);
             } else if (typeDef instanceof EnumTypeDefinition) {
@@ -1478,33 +1471,21 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
-            emitRangeNodeOptional(typeDef.getRangeConstraints());
-        }
-
-        private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
-            emitRangeNodeOptional(typeDef.getRangeConstraints());
-
+        private void emitRangeRestrictedSpecification(final RangeRestrictedTypeDefinition<?, ?> typeDef) {
+            typeDef.getRangeConstraint().ifPresent(this::emitRangeNode);
         }
 
-        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();
-                first.getErrorMessage().ifPresent(this::emitErrorMessageNode);
-                first.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
-                emitDocumentedNode(first);
-                super.writer.endNode();
-            }
-
+        private void emitRangeNode(final RangeConstraint<?> constraint) {
+            super.writer.startRangeNode(toRangeString(constraint.getAllowedRanges()));
+            constraint.getErrorMessage().ifPresent(this::emitErrorMessageNode);
+            constraint.getErrorAppTag().ifPresent(this::emitErrorAppTagNode);
+            emitDocumentedNode(constraint);
+            super.writer.endNode();
         }
 
         private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
             emitFranctionDigitsNode(typeDefinition.getFractionDigits());
-            emitRangeNodeOptional(typeDefinition.getRangeConstraints());
+            emitRangeRestrictedSpecification(typeDefinition);
         }
 
         private void emitFranctionDigitsNode(final Integer fractionDigits) {
@@ -1545,8 +1526,8 @@ abstract class SchemaContextEmitter {
             return sb.toString();
         }
 
-        private static String toRangeString(final List<RangeConstraint> list) {
-            final Iterator<RangeConstraint> it = list.iterator();
+        private static String toRangeString(final RangeSet<?> ranges) {
+            final Iterator<? extends Range<?>> it = ranges.asRanges().iterator();
             if (!it.hasNext()) {
                 return "";
             }
@@ -1554,15 +1535,15 @@ abstract class SchemaContextEmitter {
             final StringBuilder sb = new StringBuilder();
             boolean haveNext;
             do {
-                final RangeConstraint current = it.next();
+                final Range<?> current = it.next();
                 haveNext = it.hasNext();
-                appendRange(sb, current.getMin(), current.getMax(), haveNext);
+                appendRange(sb, current.lowerEndpoint(), current.upperEndpoint(), haveNext);
             } while (haveNext);
 
             return sb.toString();
         }
 
-        private static void appendRange(final StringBuilder sb, final Number min, final Number max,
+        private static void appendRange(final StringBuilder sb, final Object min, final Object max,
                 final boolean haveNext) {
             sb.append(min);
             if (!min.equals(max)) {
@@ -1588,13 +1569,13 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitDefaultNodes(final Collection<String> defaults) {
-            for (final String defaultValue : defaults) {
+        private void emitDefaultNodes(final Collection<? extends Object> defaults) {
+            for (final Object defaultValue : defaults) {
                 emitDefaultNode(defaultValue);
             }
         }
 
-        private void emitDefaultNode(@Nullable final Object object) {
+        private void emitDefaultNode(final @Nullable Object object) {
             super.writer.startDefaultNode(object.toString());
             super.writer.endNode();
         }
@@ -1658,14 +1639,14 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitPositionNode(@Nullable final Long position) {
+        private void emitPositionNode(final @Nullable Long position) {
             if (position != null) {
                 super.writer.startPositionNode(UnsignedInteger.valueOf(position));
                 super.writer.endNode();
             }
         }
 
-        private void emitStatusNode(@Nullable final Status status) {
+        private void emitStatusNode(final @Nullable Status status) {
             if (status != null) {
                 super.writer.startStatusNode(status);
                 super.writer.endNode();
@@ -1696,7 +1677,7 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitMust(@Nullable final MustDefinition mustCondition) {
+        private void emitMust(final @Nullable MustDefinition mustCondition) {
             if (mustCondition != null && mustCondition.getXpath() != null) {
                 super.writer.startMustNode(mustCondition.getXpath());
                 mustCondition.getErrorMessage().ifPresent(this::emitErrorMessageNode);
@@ -1706,7 +1687,7 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitErrorMessageNode(@Nullable final String input) {
+        private void emitErrorMessageNode(final @Nullable String input) {
             super.writer.startErrorMessageNode(input);
             super.writer.endNode();
         }
@@ -1723,14 +1704,14 @@ abstract class SchemaContextEmitter {
             }
         }
 
-        private void emitMaxElementsNode(final Integer max) {
+        private void emitMaxElementsNode(final @Nullable Integer max) {
             if (max != null) {
                 super.writer.startMaxElementsNode(max);
                 super.writer.endNode();
             }
         }
 
-        private void emitValueNode(@Nullable final Integer value) {
+        private void emitValueNode(final @Nullable Integer value) {
             if (value != null) {
                 super.writer.startValueNode(value);
                 super.writer.endNode();
@@ -1760,7 +1741,8 @@ abstract class SchemaContextEmitter {
 
         private void emitContainer(final ContainerSchemaNode child) {
             super.writer.startContainerNode(child.getQName());
-            emitConstraints(child.getConstraints());
+            child.getMustConstraints().forEach(this::emitMust);
+            child.getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: whenNode //:Optional
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitPresenceNode(child.isPresenceContainer());
@@ -1774,60 +1756,55 @@ abstract class SchemaContextEmitter {
 
         }
 
-        private void emitConstraints(final ConstraintDefinition constraints) {
-            constraints.getWhenCondition().ifPresent(this::emitWhen);
-            for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
-                emitMust(mustCondition);
-            }
-        }
-
         private void emitLeaf(final LeafSchemaNode child) {
             super.writer.startLeafNode(child.getQName());
-            child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
+            child.getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitTypeNode(child.getPath(), child.getType());
             child.getType().getUnits().ifPresent(this::emitUnitsNode);
-            emitMustNodes(child.getConstraints().getMustConstraints());
+            child.getMustConstraints().forEach(this::emitMust);
             child.getType().getDefaultValue().ifPresent(this::emitDefaultNode);
             emitConfigNode(child.isConfiguration());
-            emitMandatoryNode(child.getConstraints().isMandatory());
+            emitMandatoryNode(child.isMandatory());
             emitDocumentedNode(child);
             emitUnknownStatementNodes(child.getUnknownSchemaNodes());
             super.writer.endNode();
 
         }
 
+        private void emitCountConstraint(final ElementCountConstraint constraint) {
+            emitMinElementsNode(constraint.getMinElements());
+            emitMaxElementsNode(constraint.getMaxElements());
+        }
+
         private void emitLeafList(final LeafListSchemaNode child) {
             super.writer.startLeafListNode(child.getQName());
 
-            child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
+            child.getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitTypeNode(child.getPath(), child.getType());
             child.getType().getUnits().ifPresent(this::emitUnitsNode);
             // FIXME: BUG-2444: unitsNode /Optional
-            emitMustNodes(child.getConstraints().getMustConstraints());
+            child.getMustConstraints().forEach(this::emitMust);
             emitConfigNode(child.isConfiguration());
             emitDefaultNodes(child.getDefaults());
-            emitMinElementsNode(child.getConstraints().getMinElements());
-            emitMaxElementsNode(child.getConstraints().getMaxElements());
+            child.getElementCountConstraint().ifPresent(this::emitCountConstraint);
             emitOrderedBy(child.isUserOrdered());
             emitDocumentedNode(child);
             emitUnknownStatementNodes(child.getUnknownSchemaNodes());
             super.writer.endNode();
-
         }
 
         private void emitList(final ListSchemaNode child) {
             super.writer.startListNode(child.getQName());
-            child.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
+            child.getWhenCondition().ifPresent(this::emitWhen);
 
             // FIXME: BUG-2444: *(ifFeatureNode )
-            emitMustNodes(child.getConstraints().getMustConstraints());
+            child.getMustConstraints().forEach(this::emitMust);
             emitKey(child.getKeyDefinition());
             emitUniqueConstraints(child.getUniqueConstraints());
             emitConfigNode(child.isConfiguration());
-            emitMinElementsNode(child.getConstraints().getMinElements());
-            emitMaxElementsNode(child.getConstraints().getMaxElements());
+            child.getElementCountConstraint().ifPresent(this::emitCountConstraint);
             emitOrderedBy(child.isUserOrdered());
             emitDocumentedNode(child);
             emitDataNodeContainer(child);
@@ -1838,12 +1815,6 @@ abstract class SchemaContextEmitter {
 
         }
 
-        private void emitMustNodes(final Collection<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);
@@ -1864,13 +1835,13 @@ abstract class SchemaContextEmitter {
 
         private void emitChoice(final ChoiceSchemaNode choice) {
             super.writer.startChoiceNode(choice.getQName());
-            choice.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
+            choice.getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             // FIXME: BUG-2444: defaultNode //Optional
             emitConfigNode(choice.isConfiguration());
-            emitMandatoryNode(choice.getConstraints().isMandatory());
+            emitMandatoryNode(choice.isMandatory());
             emitDocumentedNode(choice);
-            for (final ChoiceCaseNode caze : choice.getCases().values()) {
+            for (final CaseSchemaNode caze : choice.getCases().values()) {
                 // TODO: emit short case?
                 emitCaseNode(caze);
             }
@@ -1878,12 +1849,12 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitCaseNode(final ChoiceCaseNode caze) {
+        private void emitCaseNode(final CaseSchemaNode caze) {
             if (!super.emitInstantiated && caze.isAugmenting()) {
                 return;
             }
             super.writer.startCaseNode(caze.getQName());
-            caze.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
+            caze.getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitDocumentedNode(caze);
             emitDataNodeContainer(caze);
@@ -1905,11 +1876,12 @@ abstract class SchemaContextEmitter {
         }
 
         private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
-            dataSchemaNode.getConstraints().getWhenCondition().ifPresent(this::emitWhen);
+            dataSchemaNode.getWhenCondition().ifPresent(this::emitWhen);
             // FIXME: BUG-2444: *(ifFeatureNode )
-            emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
+            if (dataSchemaNode instanceof MustConstraintAware) {
+                ((MustConstraintAware) dataSchemaNode).getMustConstraints().forEach(this::emitMust);
+            }
             emitConfigNode(dataSchemaNode.isConfiguration());
-            emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
             emitDocumentedNode(dataSchemaNode);
             emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
         }
@@ -1945,8 +1917,8 @@ abstract class SchemaContextEmitter {
                 emitRefineListNodes((ListSchemaNode) value);
             } else if (value instanceof ChoiceSchemaNode) {
                 emitRefineChoiceNodes((ChoiceSchemaNode) value);
-            } else if (value instanceof ChoiceCaseNode) {
-                emitRefineCaseNodes((ChoiceCaseNode) value);
+            } else if (value instanceof CaseSchemaNode) {
+                emitRefineCaseNodes((CaseSchemaNode) value);
             } else if (value instanceof ContainerSchemaNode) {
                 emitRefineContainerNodes((ContainerSchemaNode) value);
             } else if (value instanceof AnyXmlSchemaNode) {
@@ -1958,7 +1930,7 @@ abstract class SchemaContextEmitter {
 
         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.");
+            checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
             @SuppressWarnings("unchecked")
             final T ret = (T) original.get();
             return ret;
@@ -1998,10 +1970,24 @@ abstract class SchemaContextEmitter {
                 emitConfigNode(value.isConfiguration());
             }
             emitDocumentedNodeRefine(original, value);
-            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-                emitMandatoryNode(value.getConstraints().isMandatory());
+            if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
+                emitMandatoryNode(value.isMandatory());
             }
+        }
 
+        private void emitRefinedMinMaxNodes(final Optional<ElementCountConstraint> value,
+                final Optional<ElementCountConstraint> original) {
+            Integer val = value.map(ElementCountConstraint::getMinElements).orElse(null);
+            Integer orig = original.map(ElementCountConstraint::getMinElements).orElse(null);
+            if (Objects.equals(val, orig)) {
+                emitMinElementsNode(val);
+            }
+
+            val = value.map(ElementCountConstraint::getMinElements).orElse(null);
+            orig = original.map(ElementCountConstraint::getMinElements).orElse(null);
+            if (Objects.equals(val, orig)) {
+                emitMaxElementsNode(val);
+            }
         }
 
         private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
@@ -2011,14 +1997,8 @@ abstract class SchemaContextEmitter {
             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());
-            }
+
+            emitRefinedMinMaxNodes(value.getElementCountConstraint(), original.getElementCountConstraint());
             emitDocumentedNodeRefine(original, value);
 
         }
@@ -2030,14 +2010,7 @@ abstract class SchemaContextEmitter {
             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());
-            }
+            emitRefinedMinMaxNodes(value.getElementCountConstraint(), original.getElementCountConstraint());
             emitDocumentedNodeRefine(original, value);
 
         }
@@ -2049,15 +2022,15 @@ abstract class SchemaContextEmitter {
             if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
                 emitConfigNode(value.isConfiguration());
             }
-            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-                emitMandatoryNode(value.getConstraints().isMandatory());
+            if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
+                emitMandatoryNode(value.isMandatory());
             }
             emitDocumentedNodeRefine(original, value);
 
         }
 
-        private void emitRefineCaseNodes(final ChoiceCaseNode value) {
-            final ChoiceCaseNode original = getOriginalChecked(value);
+        private void emitRefineCaseNodes(final CaseSchemaNode value) {
+            final CaseSchemaNode original = getOriginalChecked(value);
             emitDocumentedNodeRefine(original, value);
 
         }
@@ -2070,8 +2043,8 @@ abstract class SchemaContextEmitter {
             if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
                 emitConfigNode(value.isConfiguration());
             }
-            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-                emitMandatoryNode(value.getConstraints().isMandatory());
+            if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
+                emitMandatoryNode(value.isMandatory());
             }
             emitDocumentedNodeRefine(original, value);
 
@@ -2096,8 +2069,8 @@ abstract class SchemaContextEmitter {
             }
 
             for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
-                if (childNode instanceof ChoiceCaseNode) {
-                    emitCaseNode((ChoiceCaseNode) childNode);
+                if (childNode instanceof CaseSchemaNode) {
+                    emitCaseNode((CaseSchemaNode) childNode);
                 } else {
                     emitDataSchemaNode(childNode);
                 }
@@ -2129,7 +2102,7 @@ abstract class SchemaContextEmitter {
 
         private StatementDefinition getStatementChecked(final QName nodeType) {
             final StatementDefinition ret = super.extensions.get(nodeType);
-            Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.", nodeType);
+            checkArgument(ret != null, "Unknown extension %s used during export.", nodeType);
             return ret;
         }
 
@@ -2181,10 +2154,10 @@ abstract class SchemaContextEmitter {
             super.writer.endNode();
         }
 
-        private void emitInput(@Nonnull final ContainerSchemaNode input) {
+        private void emitInput(final @NonNull ContainerSchemaNode input) {
             if (isExplicitStatement(input)) {
                 super.writer.startInputNode();
-                emitConstraints(input.getConstraints());
+                input.getMustConstraints().forEach(this::emitMust);
                 emitDataNodeContainer(input);
                 emitUnknownStatementNodes(input.getUnknownSchemaNodes());
                 super.writer.endNode();
@@ -2192,10 +2165,10 @@ abstract class SchemaContextEmitter {
 
         }
 
-        private void emitOutput(@Nonnull final ContainerSchemaNode output) {
+        private void emitOutput(final @NonNull ContainerSchemaNode output) {
             if (isExplicitStatement(output)) {
                 super.writer.startOutputNode();
-                emitConstraints(output.getConstraints());
+                output.getMustConstraints().forEach(this::emitMust);
                 emitDataNodeContainer(output);
                 emitUnknownStatementNodes(output.getUnknownSchemaNodes());
                 super.writer.endNode();