BUG-865: deprecate pre-Beryllium parser elements
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / ParserListenerUtils.java
index 49f4178731f59221fa5660efd59a1816ba210efc..fadb1a23536237d29688e11c8da6a42b340ee92f 100644 (file)
@@ -3,20 +3,28 @@
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/eplv10.html
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
+
 package org.opendaylight.yangtools.yang.parser.impl;
 
 import static com.google.common.base.Preconditions.checkState;
-
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Optional;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
 import java.math.BigDecimal;
-import java.net.URI;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Date;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Stack;
-
+import java.util.Objects;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
@@ -103,7 +111,7 @@ import org.opendaylight.yangtools.yang.model.util.BitsType;
 import org.opendaylight.yangtools.yang.model.util.Decimal64;
 import org.opendaylight.yangtools.yang.model.util.EnumerationType;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
-import org.opendaylight.yangtools.yang.model.util.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
 import org.opendaylight.yangtools.yang.model.util.Int16;
 import org.opendaylight.yangtools.yang.model.util.Int32;
 import org.opendaylight.yangtools.yang.model.util.Int64;
@@ -116,15 +124,17 @@ import org.opendaylight.yangtools.yang.model.util.Uint16;
 import org.opendaylight.yangtools.yang.model.util.Uint32;
 import org.opendaylight.yangtools.yang.model.util.Uint64;
 import org.opendaylight.yangtools.yang.model.util.Uint8;
-import org.opendaylight.yangtools.yang.model.util.UnknownType;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
-import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.ConstraintsBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.RefineBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.RefineHolderImpl;
+import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl;
 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
 import org.opendaylight.yangtools.yang.parser.util.TypeConstraints;
 import org.opendaylight.yangtools.yang.parser.util.UnknownBoundaryNumber;
@@ -132,10 +142,225 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
-
 public final class ParserListenerUtils {
+    private static final int UNICODE_SCRIPT_FIX_COUNTER = 30;
     private static final Logger LOG = LoggerFactory.getLogger(ParserListenerUtils.class);
+    private static final Splitter KEYDEF_SPLITTER = Splitter.on(' ').omitEmptyStrings();
+    private static final Splitter PIPE_SPLITTER = Splitter.on('|').trimResults();
+    private static final Splitter DOT_DOT_SPLITTER = Splitter.on("..").trimResults();
+    private static final CharMatcher DOUBLE_QUOTE_MATCHER = CharMatcher.is('"');
+    private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher.is('\'');
+    private static final Pattern BETWEEN_CURLY_BRACES_PATTERN = Pattern.compile("\\{(.+?)\\}");
+    private static final Set<String> JAVA_UNICODE_BLOCKS = ImmutableSet.<String>builder()
+            .add("AegeanNumbers")
+            .add("AlchemicalSymbols")
+            .add("AlphabeticPresentationForms")
+            .add("AncientGreekMusicalNotation")
+            .add("AncientGreekNumbers")
+            .add("AncientSymbols")
+            .add("Arabic")
+            .add("ArabicPresentationForms-A")
+            .add("ArabicPresentationForms-B")
+            .add("ArabicSupplement")
+            .add("Armenian")
+            .add("Arrows")
+            .add("Avestan")
+            .add("Balinese")
+            .add("Bamum")
+            .add("BamumSupplement")
+            .add("BasicLatin")
+            .add("Batak")
+            .add("Bengali")
+            .add("BlockElements")
+            .add("Bopomofo")
+            .add("BopomofoExtended")
+            .add("BoxDrawing")
+            .add("Brahmi")
+            .add("BraillePatterns")
+            .add("Buginese")
+            .add("Buhid")
+            .add("ByzantineMusicalSymbols")
+            .add("Carian")
+            .add("Cham")
+            .add("Cherokee")
+            .add("CJKCompatibility")
+            .add("CJKCompatibilityForms")
+            .add("CJKCompatibilityIdeographs")
+            .add("CJKCompatibilityIdeographsSupplement")
+            .add("CJKRadicalsSupplement")
+            .add("CJKStrokes")
+            .add("CJKSymbolsandPunctuation")
+            .add("CJKUnifiedIdeographs")
+            .add("CJKUnifiedIdeographsExtensionA")
+            .add("CJKUnifiedIdeographsExtensionB")
+            .add("CJKUnifiedIdeographsExtensionC")
+            .add("CJKUnifiedIdeographsExtensionD")
+            .add("CombiningDiacriticalMarks")
+            .add("CombiningDiacriticalMarksSupplement")
+            .add("CombiningHalfMarks")
+            .add("CombiningDiacriticalMarksforSymbols")
+            .add("CommonIndicNumberForms")
+            .add("ControlPictures")
+            .add("Coptic")
+            .add("CountingRodNumerals")
+            .add("Cuneiform")
+            .add("CuneiformNumbersandPunctuation")
+            .add("CurrencySymbols")
+            .add("CypriotSyllabary")
+            .add("Cyrillic")
+            .add("CyrillicExtended-A")
+            .add("CyrillicExtended-B")
+            .add("CyrillicSupplementary")
+            .add("Deseret")
+            .add("Devanagari")
+            .add("DevanagariExtended")
+            .add("Dingbats")
+            .add("DominoTiles")
+            .add("EgyptianHieroglyphs")
+            .add("Emoticons")
+            .add("EnclosedAlphanumericSupplement")
+            .add("EnclosedAlphanumerics")
+            .add("EnclosedCJKLettersandMonths")
+            .add("EnclosedIdeographicSupplement")
+            .add("Ethiopic")
+            .add("EthiopicExtended")
+            .add("EthiopicExtended-A")
+            .add("EthiopicSupplement")
+            .add("GeneralPunctuation")
+            .add("GeometricShapes")
+            .add("Georgian")
+            .add("GeorgianSupplement")
+            .add("Glagolitic")
+            .add("Gothic")
+            .add("GreekandCoptic")
+            .add("GreekExtended")
+            .add("Gujarati")
+            .add("Gurmukhi")
+            .add("HalfwidthandFullwidthForms")
+            .add("HangulCompatibilityJamo")
+            .add("HangulJamo")
+            .add("HangulJamoExtended-A")
+            .add("HangulJamoExtended-B")
+            .add("HangulSyllables")
+            .add("Hanunoo")
+            .add("Hebrew")
+            .add("HighPrivateUseSurrogates")
+            .add("HighSurrogates")
+            .add("Hiragana")
+            .add("IdeographicDescriptionCharacters")
+            .add("ImperialAramaic")
+            .add("InscriptionalPahlavi")
+            .add("InscriptionalParthian")
+            .add("IPAExtensions")
+            .add("Javanese")
+            .add("Kaithi")
+            .add("KanaSupplement")
+            .add("Kanbun")
+            .add("Kangxi Radicals")
+            .add("Kannada")
+            .add("Katakana")
+            .add("KatakanaPhoneticExtensions")
+            .add("KayahLi")
+            .add("Kharoshthi")
+            .add("Khmer")
+            .add("KhmerSymbols")
+            .add("Lao")
+            .add("Latin-1Supplement")
+            .add("LatinExtended-A")
+            .add("LatinExtendedAdditional")
+            .add("LatinExtended-B")
+            .add("LatinExtended-C")
+            .add("LatinExtended-D")
+            .add("Lepcha")
+            .add("LetterlikeSymbols")
+            .add("Limbu")
+            .add("LinearBIdeograms")
+            .add("LinearBSyllabary")
+            .add("Lisu")
+            .add("LowSurrogates")
+            .add("Lycian")
+            .add("Lydian")
+            .add("MahjongTiles")
+            .add("Malayalam")
+            .add("Mandaic")
+            .add("MathematicalAlphanumericSymbols")
+            .add("MathematicalOperators")
+            .add("MeeteiMayek")
+            .add("MiscellaneousMathematicalSymbols-A")
+            .add("MiscellaneousMathematicalSymbols-B")
+            .add("MiscellaneousSymbols")
+            .add("MiscellaneousSymbolsandArrows")
+            .add("MiscellaneousSymbolsAndPictographs")
+            .add("MiscellaneousTechnical")
+            .add("ModifierToneLetters")
+            .add("Mongolian")
+            .add("MusicalSymbols")
+            .add("Myanmar")
+            .add("MyanmarExtended-A")
+            .add("NewTaiLue")
+            .add("NKo")
+            .add("NumberForms")
+            .add("Ogham")
+            .add("OlChiki")
+            .add("OldItalic")
+            .add("OldPersian")
+            .add("OldSouthArabian")
+            .add("OldTurkic")
+            .add("OpticalCharacterRecognition")
+            .add("Oriya")
+            .add("Osmanya")
+            .add("Phags-pa")
+            .add("PhaistosDisc")
+            .add("Phoenician")
+            .add("PhoneticExtensions")
+            .add("PhoneticExtensionsSupplement")
+            .add("PlayingCards")
+            .add("PrivateUseArea")
+            .add("Rejang")
+            .add("RumiNumeralSymbols")
+            .add("Runic")
+            .add("Samaritan")
+            .add("Saurashtra")
+            .add("Shavian")
+            .add("Sinhala")
+            .add("SmallFormVariants")
+            .add("SpacingModifierLetters")
+            .add("Specials")
+            .add("Sundanese")
+            .add("SuperscriptsandSubscripts")
+            .add("SupplementalArrows-A")
+            .add("SupplementalArrows-B")
+            .add("SupplementalMathematicalOperators")
+            .add("SupplementalPunctuation")
+            .add("SupplementaryPrivateUseArea-A")
+            .add("SupplementaryPrivateUseArea-B")
+            .add("SylotiNagri")
+            .add("Syriac")
+            .add("Tagalog")
+            .add("Tagbanwa")
+            .add("Tags")
+            .add("TaiLe")
+            .add("TaiTham")
+            .add("TaiViet")
+            .add("TaiXuanJingSymbols")
+            .add("Tamil")
+            .add("Telugu")
+            .add("Thaana")
+            .add("Thai")
+            .add("Tibetan")
+            .add("Tifinagh")
+            .add("TransportAndMapSymbols")
+            .add("Ugaritic")
+            .add("UnifiedCanadianAboriginalSyllabics")
+            .add("UnifiedCanadianAboriginalSyllabicsExtended")
+            .add("Vai")
+            .add("VariationSelectors")
+            .add("VariationSelectorsSupplement")
+            .add("VedicExtensions")
+            .add("VerticalForms")
+            .add("YiRadicals")
+            .add("YiSyllables")
+            .add("YijingHexagramSymbols").build();
 
     private ParserListenerUtils() {
     }
@@ -150,31 +375,40 @@ public final class ParserListenerUtils {
     public static String stringFromNode(final ParseTree treeNode) {
         String result = "";
         for (int i = 0; i < treeNode.getChildCount(); ++i) {
-            if (treeNode.getChild(i) instanceof StringContext) {
-                final StringContext context = (StringContext) treeNode.getChild(i);
-                if (context != null) {
-                    return stringFromStringContext(context);
-
-                }
+            final ParseTree child = treeNode.getChild(i);
+            if (child instanceof StringContext) {
+                return stringFromStringContext((StringContext)child);
             }
         }
         return result;
     }
 
-    public static String stringFromStringContext(final StringContext context) {
-        StringBuilder str = new StringBuilder();
+    private static String stringFromStringContext(final StringContext context) {
+        StringBuilder sb = new StringBuilder();
         for (TerminalNode stringNode : context.STRING()) {
-            String result = stringNode.getText();
-            if(!result.contains("\"")){
-                str.append(result);
-            } else if (!(result.startsWith("\"")) && result.endsWith("\"")) {
-                LOG.error("Syntax error in module {} at line {}: missing '\"'.", getParentModule(context),
-                        context.getStart().getLine());
+            final String str = stringNode.getText();
+            char firstChar = str.charAt(0);
+            final CharMatcher quoteMatcher;
+            if(SINGLE_QUOTE_MATCHER.matches(firstChar)) {
+                quoteMatcher = SINGLE_QUOTE_MATCHER;
+            } else if (DOUBLE_QUOTE_MATCHER.matches(firstChar)) {
+                quoteMatcher = DOUBLE_QUOTE_MATCHER;
             } else {
-                str.append(result.replace("\"", ""));
+                sb.append(str);
+                continue;
             }
-        }
-        return str.toString();
+            /*
+             *
+             * It is safe not to check last argument to be same
+             * grammars enforces that.
+             *
+             * FIXME: Introduce proper escaping and translation of escaped
+             * characters here.
+             *
+             */
+            sb.append(quoteMatcher.removeFrom(str.substring(1, str.length()-1)));
+        }
+        return sb.toString();
     }
 
     private static String getParentModule(final ParseTree ctx) {
@@ -182,7 +416,7 @@ public final class ParserListenerUtils {
         while (current != null && !(current instanceof Module_stmtContext)) {
             current = current.getParent();
         }
-        if (current instanceof Module_stmtContext) {
+        if (current != null) {
             Module_stmtContext module = (Module_stmtContext) current;
             for (int i = 0; i < module.getChildCount(); i++) {
                 if (module.getChild(i) instanceof StringContext) {
@@ -202,7 +436,9 @@ public final class ParserListenerUtils {
      *            context to parse
      * @param builder
      *            builder to fill in with parsed statements
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
      */
+    @Deprecated
     public static void parseSchemaNodeArgs(final ParseTree ctx, final SchemaNodeBuilder builder) {
         for (int i = 0; i < ctx.getChildCount(); i++) {
             final ParseTree child = ctx.getChild(i);
@@ -259,15 +495,13 @@ public final class ParserListenerUtils {
      *         statement
      */
     public static String parseUnits(final ParseTree ctx) {
-        String units = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Units_stmtContext) {
-                units = stringFromNode(child);
-                break;
+                return stringFromNode(child);
             }
         }
-        return units;
+        return null;
     }
 
     /**
@@ -279,45 +513,25 @@ public final class ParserListenerUtils {
      *         default statement
      */
     public static String parseDefault(final ParseTree ctx) {
-        String defaultValue = null;
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Default_stmtContext) {
-                defaultValue = stringFromNode(child);
-                break;
+                return stringFromNode(child);
             }
         }
-        return defaultValue;
-    }
-
-    /**
-     * Create SchemaPath from actualPath and new node name.
-     *
-     * @param actualPath
-     *            current position in model
-     * @return SchemaPath object
-     */
-    public static SchemaPath createActualSchemaPath(final Stack<QName> actualPath) {
-        return SchemaPath.create(actualPath, true);
+        return null;
     }
 
     /**
-     * Create java.util.List of key node names.
+     * Create java.util.LinkedHashSet of key node names.
      *
      * @param ctx
      *            Key_stmtContext context
-     * @return YANG list key as java.util.List of key node names
+     * @return YANG list key as java.util.LinkedHashSet of key node names
      */
-    public static List<String> createListKey(final Key_stmtContext ctx) {
-        String keyDefinition = stringFromNode(ctx);
-        List<String> keys = new ArrayList<>();
-        String[] splittedKey = keyDefinition.split(" ");
-        for (String keyElement : splittedKey) {
-            if (!keyElement.isEmpty()) {
-                keys.add(keyElement);
-            }
-        }
-        return keys;
+    public static Set<String> createListKey(final Key_stmtContext ctx) {
+        final String keyDefinition = stringFromNode(ctx);
+        return Sets.<String>newLinkedHashSet(KEYDEF_SPLITTER.split(keyDefinition));
     }
 
     /**
@@ -332,7 +546,7 @@ public final class ParserListenerUtils {
      * @return List of EnumPair object parsed from given context
      */
     private static List<EnumTypeDefinition.EnumPair> getEnumConstants(final Type_body_stmtsContext ctx,
-            final Stack<QName> path, final String moduleName) {
+            final SchemaPath path, final String moduleName) {
         List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<>();
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -368,7 +582,7 @@ public final class ParserListenerUtils {
      * @return EnumPair object parsed from given context
      */
     private static EnumTypeDefinition.EnumPair createEnumPair(final Enum_stmtContext ctx, final int highestValue,
-            final Stack<QName> actualPath, final String moduleName) {
+            final SchemaPath actualPath, final String moduleName) {
         final String name = stringFromNode(ctx);
         SchemaPath path = createTypePath(actualPath, name);
         Integer value = null;
@@ -381,7 +595,15 @@ public final class ParserListenerUtils {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Value_stmtContext) {
                 String valueStr = stringFromNode(child);
-                value = Integer.valueOf(valueStr);
+                try {
+                    // yang enum value has same restrictions as JAVA Integer
+                    value = Integer.valueOf(valueStr);
+                } catch (NumberFormatException e) {
+                    String err = String
+                            .format("Error on enum '%s': the enum value MUST be in the range from -2147483648 to 2147483647, but was: %s",
+                                    name, valueStr);
+                    throw new YangParseException(moduleName, ctx.getStart().getLine(), err, e);
+                }
             } else if (child instanceof Description_stmtContext) {
                 description = stringFromNode(child);
             } else if (child instanceof Reference_stmtContext) {
@@ -394,10 +616,6 @@ public final class ParserListenerUtils {
         if (value == null) {
             value = highestValue + 1;
         }
-        if (value < -2147483648 || value > 2147483647) {
-            throw new YangParseException(moduleName, ctx.getStart().getLine(), "Error on enum '" + name
-                    + "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: " + value);
-        }
 
         EnumPairImpl result = new EnumPairImpl();
         result.qname = path.getPathTowardsRoot().iterator().next();
@@ -467,11 +685,11 @@ public final class ParserListenerUtils {
         public int hashCode() {
             final int prime = 31;
             int result = 1;
-            result = prime * result + ((qname == null) ? 0 : qname.hashCode());
-            result = prime * result + ((path == null) ? 0 : path.hashCode());
-            result = prime * result + ((unknownNodes == null) ? 0 : unknownNodes.hashCode());
-            result = prime * result + ((name == null) ? 0 : name.hashCode());
-            result = prime * result + ((value == null) ? 0 : value.hashCode());
+            result = prime * result + Objects.hashCode(qname);
+            result = prime * result + Objects.hashCode(path);
+            result = prime * result + Objects.hashCode(unknownNodes);
+            result = prime * result + Objects.hashCode(name);
+            result = prime * result + Objects.hashCode(value);
             return result;
         }
 
@@ -541,16 +759,14 @@ public final class ParserListenerUtils {
      * @return List of RangeConstraint created from this context
      */
     private static List<RangeConstraint> getRangeConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
-        List<RangeConstraint> rangeConstraints = Collections.emptyList();
-        outer: for (int i = 0; i < ctx.getChildCount(); i++) {
+        for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree numRestrChild = ctx.getChild(i);
 
             if (numRestrChild instanceof Numerical_restrictionsContext) {
                 for (int j = 0; j < numRestrChild.getChildCount(); j++) {
                     ParseTree rangeChild = numRestrChild.getChild(j);
                     if (rangeChild instanceof Range_stmtContext) {
-                        rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
-                        break outer;
+                        return parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
                     }
                 }
             }
@@ -562,16 +778,14 @@ public final class ParserListenerUtils {
                         for (int k = 0; k < decRestr.getChildCount(); k++) {
                             ParseTree rangeChild = decRestr.getChild(k);
                             if (rangeChild instanceof Range_stmtContext) {
-                                rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
-                                break outer;
+                                return parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
                             }
                         }
-
                     }
                 }
             }
         }
-        return rangeConstraints;
+        return Collections.emptyList();
     }
 
     /**
@@ -585,33 +799,34 @@ public final class ParserListenerUtils {
      */
     private static List<RangeConstraint> parseRangeConstraints(final Range_stmtContext ctx, final String moduleName) {
         final int line = ctx.getStart().getLine();
-        List<RangeConstraint> rangeConstraints = new ArrayList<>();
-        String description = null;
-        String reference = null;
+        Optional<String> description = Optional.absent();
+        Optional<String> reference = Optional.absent();
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
-                description = stringFromNode(child);
+                description = Optional.fromNullable(stringFromNode(child));
             } else if (child instanceof Reference_stmtContext) {
-                reference = stringFromNode(child);
+                reference = Optional.fromNullable(stringFromNode(child));
             }
         }
 
-        String rangeStr = stringFromNode(ctx);
-        String trimmed = rangeStr.replace(" ", "");
-        String[] splittedRange = trimmed.split("\\|");
-        for (String rangeDef : splittedRange) {
-            String[] splittedRangeDef = rangeDef.split("\\.\\.");
-            Number min;
-            Number max;
-            if (splittedRangeDef.length == 1) {
-                min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+        List<RangeConstraint> rangeConstraints = new ArrayList<>();
+        for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) {
+            final Iterator<String> split = DOT_DOT_SPLITTER.split(def).iterator();
+            final Number min = parseNumberConstraintValue(split.next(), moduleName, line);
+
+            final Number max;
+            if (split.hasNext()) {
+                max = parseNumberConstraintValue(split.next(), moduleName, line);
+                if (split.hasNext()) {
+                    throw new YangParseException(moduleName, ctx.getStart().getLine(), "Malformed length constraint \"" + def + "\".");
+                }
             } else {
-                min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
-                max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
+                max = min;
             }
-            RangeConstraint range = BaseConstraints.rangeConstraint(min, max, description, reference);
+
+            RangeConstraint range = BaseConstraints.newRangeConstraint(min, max, description, reference);
             rangeConstraints.add(range);
         }
 
@@ -628,20 +843,18 @@ public final class ParserListenerUtils {
      * @return List of LengthConstraint created from this context
      */
     private static List<LengthConstraint> getLengthConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
-        List<LengthConstraint> lengthConstraints = Collections.emptyList();
-        outer: for (int i = 0; i < ctx.getChildCount(); i++) {
+        for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree stringRestrChild = ctx.getChild(i);
             if (stringRestrChild instanceof String_restrictionsContext) {
                 for (int j = 0; j < stringRestrChild.getChildCount(); j++) {
                     ParseTree lengthChild = stringRestrChild.getChild(j);
                     if (lengthChild instanceof Length_stmtContext) {
-                        lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
-                        break outer;
+                        return parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
                     }
                 }
             }
         }
-        return lengthConstraints;
+        return Collections.emptyList();
     }
 
     /**
@@ -655,33 +868,34 @@ public final class ParserListenerUtils {
      */
     private static List<LengthConstraint> parseLengthConstraints(final Length_stmtContext ctx, final String moduleName) {
         final int line = ctx.getStart().getLine();
-        List<LengthConstraint> lengthConstraints = new ArrayList<>();
-        String description = null;
-        String reference = null;
+        Optional<String> description = Optional.absent();
+        Optional<String> reference = Optional.absent();
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
-                description = stringFromNode(child);
+                description = Optional.fromNullable(stringFromNode(child));
             } else if (child instanceof Reference_stmtContext) {
-                reference = stringFromNode(child);
+                reference = Optional.fromNullable(stringFromNode(child));
             }
         }
 
-        String lengthStr = stringFromNode(ctx);
-        String trimmed = lengthStr.replace(" ", "");
-        String[] splittedRange = trimmed.split("\\|");
-        for (String rangeDef : splittedRange) {
-            String[] splittedRangeDef = rangeDef.split("\\.\\.");
-            Number min;
-            Number max;
-            if (splittedRangeDef.length == 1) {
-                min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+        List<LengthConstraint> lengthConstraints = new ArrayList<>();
+        for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) {
+            final Iterator<String> split = DOT_DOT_SPLITTER.split(def).iterator();
+            final Number min = parseNumberConstraintValue(split.next(), moduleName, line);
+
+            final Number max;
+            if (split.hasNext()) {
+                max = parseNumberConstraintValue(split.next(), moduleName, line);
+                if (split.hasNext()) {
+                    throw new YangParseException(moduleName, ctx.getStart().getLine(), "Malformed length constraint \"" + def + "\".");
+                }
             } else {
-                min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
-                max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
+                max = min;
             }
-            LengthConstraint range = BaseConstraints.lengthConstraint(min, max, description, reference);
+
+            LengthConstraint range = BaseConstraints.newLengthConstraint(min, max, description, reference);
             lengthConstraints.add(range);
         }
 
@@ -704,10 +918,10 @@ public final class ParserListenerUtils {
             result = new UnknownBoundaryNumber(value);
         } else {
             try {
-                if (value.contains(".")) {
+                if (value.indexOf('.') != -1) {
                     result = new BigDecimal(value);
                 } else {
-                    result = Long.valueOf(value);
+                    result = new BigInteger(value);
                 }
             } catch (NumberFormatException e) {
                 throw new YangParseException(moduleName, line, "Unable to parse range value '" + value + "'.", e);
@@ -723,7 +937,7 @@ public final class ParserListenerUtils {
      *            type body
      * @return list of pattern constraints
      */
-    private static List<PatternConstraint> getPatternConstraint(final Type_body_stmtsContext ctx) {
+    private static List<PatternConstraint> getPatternConstraint(final Type_body_stmtsContext ctx, final String moduleName) {
         List<PatternConstraint> patterns = new ArrayList<>();
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -732,7 +946,11 @@ public final class ParserListenerUtils {
                 for (int j = 0; j < stringRestrChild.getChildCount(); j++) {
                     ParseTree lengthChild = stringRestrChild.getChild(j);
                     if (lengthChild instanceof Pattern_stmtContext) {
-                        patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild));
+                        final PatternConstraint constraint = parsePatternConstraint((Pattern_stmtContext) lengthChild,
+                            moduleName);
+                        if (constraint != null) {
+                            patterns.add(constraint);
+                        }
                     }
                 }
             }
@@ -747,19 +965,75 @@ public final class ParserListenerUtils {
      *            pattern context
      * @return PatternConstraint object
      */
-    private static PatternConstraint parsePatternConstraint(final Pattern_stmtContext ctx) {
-        String description = null;
-        String reference = null;
+    private static PatternConstraint parsePatternConstraint(final Pattern_stmtContext ctx, final String moduleName) {
+        Optional<String> description = Optional.absent();
+        Optional<String> reference = Optional.absent();
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
-                description = stringFromNode(child);
+                description = Optional.of(stringFromNode(child));
             } else if (child instanceof Reference_stmtContext) {
-                reference = stringFromNode(child);
+                reference = Optional.of(stringFromNode(child));
+            }
+        }
+        final String rawPattern = parsePatternString(ctx);
+        final String fixedRawPattern = fixUnicodeScriptPattern(rawPattern);
+        final String pattern = wrapPattern(fixedRawPattern);
+        if (isValidPattern(pattern, ctx, moduleName)) {
+            return BaseConstraints.newPatternConstraint(pattern, description, reference);
+        }
+        return null;
+    }
+
+    private static String fixUnicodeScriptPattern(String rawPattern) {
+        for (int i = 0; i < UNICODE_SCRIPT_FIX_COUNTER; i++) {
+            try {
+                Pattern.compile(rawPattern);
+                return rawPattern;
+            } catch(PatternSyntaxException ex) {
+                LOG.debug("Invalid regex pattern syntax in: {}", rawPattern, ex);
+                if (ex.getMessage().contains("Unknown character script name")) {
+                    rawPattern = fixUnknownScripts(ex.getMessage(), rawPattern);
+                } else {
+                    return rawPattern;
+                }
+            }
+        }
+
+        LOG.warn("Regex pattern could not be fixed: {}", rawPattern);
+        return rawPattern;
+    }
+
+    private static String fixUnknownScripts(final String exMessage, final String rawPattern) {
+        StringBuilder result = new StringBuilder(rawPattern);
+        Matcher matcher = BETWEEN_CURLY_BRACES_PATTERN.matcher(exMessage);
+        if (matcher.find()) {
+            String capturedGroup = matcher.group(1);
+            if (JAVA_UNICODE_BLOCKS.contains(capturedGroup)) {
+                int idx = rawPattern.indexOf("Is" + capturedGroup);
+                result = result.replace(idx, idx + 2, "In");
             }
         }
-        String pattern = parsePatternString(ctx);
-        return BaseConstraints.patternConstraint(pattern, description, reference);
+        return result.toString();
+    }
+
+    private static String wrapPattern(final String rawPattern) {
+        final StringBuilder wrapPatternBuilder = new StringBuilder(rawPattern.length() + 2);
+        wrapPatternBuilder.append('^');
+        wrapPatternBuilder.append(rawPattern);
+        wrapPatternBuilder.append('$');
+        return wrapPatternBuilder.toString();
+    }
+
+    private static boolean isValidPattern(final String pattern, final Pattern_stmtContext ctx, final String moduleName) {
+        try {
+            Pattern.compile(pattern);
+            return true;
+        } catch (PatternSyntaxException ex) {
+            LOG.warn("Unable to compile pattern defined in module {} at line {}. Error message: {}",
+                moduleName, ctx.getStart().getLine(), ex.getMessage());
+        }
+        return false;
     }
 
     /**
@@ -844,7 +1118,7 @@ public final class ParserListenerUtils {
      *            current module name
      * @return List of Bit objects created from this context
      */
-    private static List<BitsTypeDefinition.Bit> getBits(final Type_body_stmtsContext ctx, final Stack<QName> actualPath,
+    private static List<BitsTypeDefinition.Bit> getBits(final Type_body_stmtsContext ctx, final SchemaPath actualPath,
             final String moduleName) {
         final List<BitsTypeDefinition.Bit> bits = new ArrayList<>();
         for (int j = 0; j < ctx.getChildCount(); j++) {
@@ -880,7 +1154,7 @@ public final class ParserListenerUtils {
      * @return Bit object parsed from this context
      */
     private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx, final long highestPosition,
-            final Stack<QName> actualPath, final String moduleName) {
+            final SchemaPath actualPath, final String moduleName) {
         String name = stringFromNode(ctx);
         Long position = null;
 
@@ -962,7 +1236,9 @@ public final class ParserListenerUtils {
      * @param line
      *            line in current module
      * @return config statement parsed from given context
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
      */
+    @Deprecated
     public static boolean getConfig(final ParseTree ctx, final Builder node, final String moduleName, final int line) {
         boolean result;
         // parse configuration statement
@@ -993,9 +1269,13 @@ public final class ParserListenerUtils {
         return result;
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static boolean getParentConfig(final Builder node) {
         Builder parent = node.getParent();
-        boolean config = false;
+        boolean config;
 
         if (parent instanceof ChoiceCaseBuilder) {
             parent = parent.getParent();
@@ -1042,61 +1322,54 @@ public final class ParserListenerUtils {
     }
 
     /**
-     * Parse type body and create UnknownType definition.
+     * Parse unknown type with body.
      *
-     * @param typedefQName
-     *            qname of current type
-     * @param ctx
+     * @param typeBody
      *            type body
-     * @param actualPath
-     *            actual path in model
-     * @param namespace
-     *            module namespace
-     * @param revision
-     *            module revision
-     * @param prefix
-     *            module prefix
      * @param parent
      *            current node parent
-     * @return UnknownType object with constraints from parsed type body
+     * @param prefixedQName
+     *            type qname with prefix
+     * @param moduleBuilder
+     *            current module builder
+     * @param moduleQName
+     *            current module qname
+     * @param actualPath
+     *            actual path in model
+     *
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
      */
-    public static TypeDefinition<?> parseUnknownTypeWithBody(final QName typedefQName,
-            final Type_body_stmtsContext ctx, final Stack<QName> actualPath, final URI namespace, final Date revision,
-            final String prefix, final Builder parent) {
-        String moduleName = parent.getModuleName();
-        String typeName = typedefQName.getLocalName();
-
-        UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName);
-
-        if (ctx != null) {
-            List<RangeConstraint> rangeStatements = getRangeConstraints(ctx, moduleName);
-            List<LengthConstraint> lengthStatements = getLengthConstraints(ctx, moduleName);
-            List<PatternConstraint> patternStatements = getPatternConstraint(ctx);
-            Integer fractionDigits = getFractionDigits(ctx, moduleName);
-
-            if (parent instanceof TypeDefinitionBuilder) {
-                TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent;
-                typedef.setRanges(rangeStatements);
-                typedef.setLengths(lengthStatements);
-                typedef.setPatterns(patternStatements);
-                typedef.setFractionDigits(fractionDigits);
-                return unknownType.build();
-            } else {
-                TypeDefinition<?> baseType = unknownType.build();
-                QName qname = new QName(namespace, revision, prefix, typeName);
-                SchemaPath schemaPath = createTypePath(actualPath, typeName);
+    @Deprecated
+    public static void parseUnknownTypeWithBody(final Type_body_stmtsContext typeBody, final TypeAwareBuilder parent,
+            final QName prefixedQName, final ModuleBuilder moduleBuilder, final QName moduleQName, final SchemaPath actualPath) {
+        final int line = typeBody.getStart().getLine();
 
-                ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, null, null, schemaPath);
-                typeBuilder.ranges(rangeStatements);
-                typeBuilder.lengths(lengthStatements);
-                typeBuilder.patterns(patternStatements);
-                typeBuilder.fractionDigits(fractionDigits);
+        List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody, moduleBuilder.getName());
+        List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody, moduleBuilder.getName());
+        List<PatternConstraint> patternStatements = getPatternConstraint(typeBody, moduleBuilder.getName());
+        Integer fractionDigits = getFractionDigits(typeBody, moduleBuilder.getName());
 
-                return typeBuilder.build();
-            }
+        if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
+            TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent;
+            typedef.setRanges(rangeStatements);
+            typedef.setLengths(lengthStatements);
+            typedef.setPatterns(patternStatements);
+            typedef.setFractionDigits(fractionDigits);
+            typedef.setTypeQName(prefixedQName);
+            // add parent node of this type statement to dirty nodes
+            moduleBuilder.markActualNodeDirty();
+        } else {
+            QName qname = QName.create(moduleQName, prefixedQName.getLocalName());
+            SchemaPath schemaPath = createTypePath(actualPath, prefixedQName.getLocalName());
+            TypeDefinitionBuilder typeBuilder = new TypeDefinitionBuilderImpl(moduleBuilder.getName(), line, qname, schemaPath);
+            typeBuilder.setRanges(rangeStatements);
+            typeBuilder.setLengths(lengthStatements);
+            typeBuilder.setPatterns(patternStatements);
+            typeBuilder.setFractionDigits(fractionDigits);
+            typeBuilder.setTypeQName(prefixedQName);
+            parent.setTypedef(typeBuilder);
+            moduleBuilder.getDirtyNodes().add(typeBuilder);
         }
-
-        return unknownType.build();
     }
 
     /**
@@ -1108,19 +1381,17 @@ public final class ParserListenerUtils {
      *            type body context
      * @param actualPath
      *            current path in schema
-     * @param namespace
-     *            current namespace
-     * @param revision
-     *            current revision
-     * @param prefix
-     *            current prefix
+     * @param moduleQName
+     *            current module qname
      * @param parent
      *            parent builder
      * @return TypeDefinition object based on parsed values.
+     *
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
      */
+    @Deprecated
     public static TypeDefinition<?> parseTypeWithBody(final String typeName, final Type_body_stmtsContext typeBody,
-            final Stack<QName> actualPath, final URI namespace, final Date revision, final String prefix,
-            final Builder parent) {
+            final SchemaPath actualPath, final QName moduleQName, final Builder parent) {
 
         final String moduleName = parent.getModuleName();
         final int line = typeBody.getStart().getLine();
@@ -1128,7 +1399,7 @@ public final class ParserListenerUtils {
 
         Integer fractionDigits = getFractionDigits(typeBody, moduleName);
         List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody, moduleName);
-        List<PatternConstraint> patternStatements = getPatternConstraint(typeBody);
+        List<PatternConstraint> patternStatements = getPatternConstraint(typeBody, moduleName);
         List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody, moduleName);
 
         TypeConstraints constraints = new TypeConstraints(moduleName, line);
@@ -1138,7 +1409,7 @@ public final class ParserListenerUtils {
         constraints.addRanges(rangeStatements);
 
         SchemaPath baseTypePath = createBaseTypePath(actualPath, typeName);
-        SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, namespace, revision, prefix, typeName);
+        SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, moduleQName, typeName);
 
         if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
             extBaseTypePath = baseTypePath;
@@ -1147,12 +1418,12 @@ public final class ParserListenerUtils {
         if ("decimal64".equals(typeName)) {
             if (rangeStatements.isEmpty()) {
                 try {
-                    return new Decimal64(baseTypePath, fractionDigits);
+                    return Decimal64.create(baseTypePath, fractionDigits);
                 } catch(Exception e) {
                     throw new YangParseException(moduleName, line, e.getMessage());
                 }
             }
-            Decimal64 decimalType = new Decimal64(extBaseTypePath, fractionDigits);
+            Decimal64 decimalType = Decimal64.create(extBaseTypePath, fractionDigits);
             constraints.addRanges(decimalType.getRangeConstraints());
             baseType = decimalType;
         } else if (typeName.startsWith("int")) {
@@ -1199,13 +1470,13 @@ public final class ParserListenerUtils {
             baseType = uintType;
         } else if ("enumeration".equals(typeName)) {
             List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, moduleName);
-            return new EnumerationType(baseTypePath, enumConstants);
+            return EnumerationType.create(baseTypePath, enumConstants, Optional.<EnumPair> absent());
         } else if ("string".equals(typeName)) {
             StringTypeDefinition stringType = StringType.getInstance();
             constraints.addLengths(stringType.getLengthConstraints());
             baseType = stringType;
         } else if ("bits".equals(typeName)) {
-            return new BitsType(baseTypePath, getBits(typeBody, actualPath, moduleName));
+            return BitsType.create(baseTypePath, getBits(typeBody, actualPath, moduleName));
         } else if ("leafref".equals(typeName)) {
             final String path = parseLeafrefPath(typeBody);
             final boolean absolute = path.startsWith("/");
@@ -1216,8 +1487,7 @@ public final class ParserListenerUtils {
             constraints.addLengths(binaryType.getLengthConstraints());
             baseType = binaryType;
         } else if ("instance-identifier".equals(typeName)) {
-            boolean requireInstance = isRequireInstance(typeBody);
-            return new InstanceIdentifier(null, requireInstance);
+            return InstanceIdentifierType.create(isRequireInstance(typeBody));
         }
 
         if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
@@ -1229,12 +1499,10 @@ public final class ParserListenerUtils {
             return baseType;
         }
 
-        List<QName> path = new ArrayList<>(actualPath);
-        path.add(new QName(namespace, revision, prefix, typeName));
-        SchemaPath schemaPath = SchemaPath.create(path, true);
-
-        QName qname = schemaPath.getPath().get(schemaPath.getPath().size() - 1);
-        ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", schemaPath);
+        QName qname = QName.create(moduleQName, typeName);
+        SchemaPath schemaPath = actualPath.createChild(qname);
+        final Optional<String> opt = Optional.of("");
+        ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, opt, opt, schemaPath);
 
         typeBuilder.ranges(constraints.getRange());
         typeBuilder.lengths(constraints.getLength());
@@ -1244,28 +1512,19 @@ public final class ParserListenerUtils {
         return typeBuilder.build();
     }
 
-    private static SchemaPath createTypePath(final Stack<QName> actual, final String typeName) {
-        QName last = actual.peek();
-        QName typeQName = new QName(last.getNamespace(), last.getRevision(), last.getPrefix(), typeName);
-        List<QName> path = new ArrayList<>(actual);
-        path.add(typeQName);
-        return SchemaPath.create(path, true);
+    private static SchemaPath createTypePath(final SchemaPath actual, final String typeName) {
+        QName last = actual.getLastComponent();
+        return actual.createChild(QName.create(last, typeName));
     }
 
-    private static SchemaPath createBaseTypePath(final Stack<QName> actual, final String typeName) {
-        List<QName> path = new ArrayList<>(actual);
-        path.add(BaseTypes.constructQName(typeName));
-        return SchemaPath.create(path, true);
+    private static SchemaPath createBaseTypePath(final SchemaPath actual, final String typeName) {
+        return actual.createChild(BaseTypes.constructQName(typeName));
     }
 
-    private static SchemaPath createExtendedBaseTypePath(final Stack<QName> actual, final URI namespace, final Date revision,
-            final String prefix, final String typeName) {
-        QName extTypeName = new QName(namespace, revision, prefix, typeName);
-        QName baseTypeName = BaseTypes.constructQName(typeName);
-        List<QName> path = new ArrayList<>(actual);
-        path.add(extTypeName);
-        path.add(baseTypeName);
-        return SchemaPath.create(path, true);
+    private static SchemaPath createExtendedBaseTypePath(final SchemaPath actual, final QName moduleQName, final String typeName) {
+        return actual.createChild(
+                QName.create(moduleQName, typeName),
+                BaseTypes.constructQName(typeName));
     }
 
     /**
@@ -1348,12 +1607,12 @@ public final class ParserListenerUtils {
      *            Must_stmtContext
      * @return MustDefinition object based on parsed context
      */
-    public static MustDefinition parseMust(final YangParser.Must_stmtContext ctx) {
+    private static MustDefinition parseMust(final YangParser.Must_stmtContext ctx) {
         StringBuilder mustText = new StringBuilder();
-        String description = null;
-        String reference = null;
-        String errorAppTag = null;
-        String errorMessage = null;
+        Optional<String> description = Optional.absent();
+        Optional<String> reference = Optional.absent();
+        Optional<String> errorAppTag = Optional.absent();
+        Optional<String> errorMessage = Optional.absent();
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof StringContext) {
@@ -1375,17 +1634,17 @@ public final class ParserListenerUtils {
                     }
                 }
             } else if (child instanceof Description_stmtContext) {
-                description = stringFromNode(child);
+                description = Optional.of(stringFromNode(child));
             } else if (child instanceof Reference_stmtContext) {
-                reference = stringFromNode(child);
+                reference = Optional.of(stringFromNode(child));
             } else if (child instanceof Error_app_tag_stmtContext) {
-                errorAppTag = stringFromNode(child);
+                errorAppTag = Optional.of(stringFromNode(child));
             } else if (child instanceof Error_message_stmtContext) {
-                errorMessage = stringFromNode(child);
+                errorMessage = Optional.of(stringFromNode(child));
             }
         }
 
-        return new MustDefinitionImpl(mustText.toString(), description, reference, errorAppTag, errorMessage);
+        return MustDefinitionImpl.create(mustText.toString(), description, reference, errorAppTag, errorMessage);
     }
 
     /**
@@ -1395,7 +1654,10 @@ public final class ParserListenerUtils {
      *            context to parse
      * @param constraints
      *            ConstraintsBuilder to fill
+     *
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
      */
+    @Deprecated
     public static void parseConstraints(final ParseTree ctx, final ConstraintsBuilder constraints) {
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree childNode = ctx.getChild(i);
@@ -1446,7 +1708,12 @@ public final class ParserListenerUtils {
             for (int i = 0; i < ctx.getChildCount(); i++) {
                 ParseTree maxArg = ctx.getChild(i);
                 if (maxArg instanceof Max_value_argContext) {
-                    result = Integer.valueOf(stringFromNode(maxArg));
+                    String maxValue = stringFromNode(maxArg);
+                    if ("unbounded".equals(maxValue)) {
+                        result = Integer.MAX_VALUE;
+                    } else {
+                        result = Integer.valueOf(maxValue);
+                    }
                 }
             }
             if (result == null) {
@@ -1525,7 +1792,10 @@ public final class ParserListenerUtils {
      * @param moduleName
      *            name of current module
      * @return RefineHolder object representing this refine statement
+     *
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
      */
+    @Deprecated
     public static RefineHolderImpl parseRefine(final Refine_stmtContext refineCtx, final String moduleName) {
         final String refineTarget = stringFromNode(refineCtx);
         final RefineHolderImpl refine = new RefineHolderImpl(moduleName, refineCtx.getStart().getLine(), refineTarget);
@@ -1555,6 +1825,10 @@ public final class ParserListenerUtils {
         return refine;
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static void parseRefineDefault(final RefineHolderImpl refine, final ParseTree refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
             ParseTree refineArg = refineStmt.getChild(i);
@@ -1571,6 +1845,10 @@ public final class ParserListenerUtils {
         }
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_leaf_stmtsContext refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
             ParseTree refineArg = refineStmt.getChild(i);
@@ -1594,6 +1872,10 @@ public final class ParserListenerUtils {
         return refine;
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static RefineBuilder parseRefine(final RefineBuilder refine, final Refine_container_stmtsContext refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
             ParseTree refineArg = refineStmt.getChild(i);
@@ -1607,6 +1889,10 @@ public final class ParserListenerUtils {
         return refine;
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_list_stmtsContext refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
             ParseTree refineArg = refineStmt.getChild(i);
@@ -1624,6 +1910,10 @@ public final class ParserListenerUtils {
         return refine;
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_leaf_list_stmtsContext refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
             ParseTree refineArg = refineStmt.getChild(i);
@@ -1641,6 +1931,10 @@ public final class ParserListenerUtils {
         return refine;
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static RefineBuilder parseRefine(final RefineHolderImpl refine, final Refine_choice_stmtsContext refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
             ParseTree refineArg = refineStmt.getChild(i);
@@ -1660,6 +1954,10 @@ public final class ParserListenerUtils {
         return refine;
     }
 
+    /**
+     * @deprecated Pre-Beryllium implementation, scheduled for removal.
+     */
+    @Deprecated
     private static RefineBuilder parseRefine(final RefineBuilder refine, final Refine_anyxml_stmtsContext refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
             ParseTree refineArg = refineStmt.getChild(i);