diff --git a/lib/intl.dart b/lib/intl.dart
index 880dbcc..7b0c6b9 100644
--- a/lib/intl.dart
+++ b/lib/intl.dart
@@ -29,7 +29,8 @@
 export 'src/intl/bidi.dart' show Bidi;
 export 'src/intl/bidi_formatter.dart' show BidiFormatter;
 export 'src/intl/date_format.dart' show DateFormat;
-export 'src/intl/number_format.dart' show NumberFormat, MicroMoney;
+export 'src/intl/micro_money.dart' show MicroMoney;
+export 'src/intl/number_format.dart' show NumberFormat;
 export 'src/intl/text_direction.dart' show TextDirection;
 
 /// The Intl class provides a common entry point for internationalization
diff --git a/lib/src/intl/compact_number_format.dart b/lib/src/intl/compact_number_format.dart
index fd53814..99f5280 100644
--- a/lib/src/intl/compact_number_format.dart
+++ b/lib/src/intl/compact_number_format.dart
@@ -192,10 +192,10 @@
     locale = Intl.verifiedLocale(locale, NumberFormat.localeExists);
     var symbols = numberFormatSymbols[locale];
     var localeZero = symbols.ZERO_DIGIT.codeUnitAt(0);
-    var zeroOffset = localeZero - NumberFormat._zero;
+    var zeroOffset = localeZero - constants.asciiZeroCodeUnit;
     name ??= symbols.DEF_CURRENCY_CODE;
     if (currencySymbol == null && lookupSimpleCurrencySymbol) {
-      currencySymbol = NumberFormat._simpleCurrencySymbols[name];
+      currencySymbol = constants.simpleCurrencySymbols[name];
     }
     currencySymbol ??= name;
     var pattern = getPattern(symbols);
@@ -256,7 +256,7 @@
         pattern,
         symbols,
         zeroOffset,
-        _NumberFormatParser.parse(symbols, pattern, isForCurrency,
+        NumberFormatParser.parse(symbols, pattern, isForCurrency,
             currencySymbol, name, decimalDigits),
         styles);
   }
@@ -270,7 +270,7 @@
       String pattern,
       NumberSymbols symbols,
       int zeroOffset,
-      _NumberFormatParseResult result,
+      NumberFormatParseResult result,
       // Fields introduced in this class.
       this._styles)
       : super._(currencyName, currencySymbol, isForCurrency, locale, localeZero,
diff --git a/lib/src/intl/constants.dart b/lib/src/intl/constants.dart
index 51ac779..83e2607 100644
--- a/lib/src/intl/constants.dart
+++ b/lib/src/intl/constants.dart
@@ -3,3 +3,166 @@
 // BSD-style license that can be found in the LICENSE file.
 
 final int asciiZeroCodeUnit = '0'.codeUnitAt(0);
+
+final Map<String, String> simpleCurrencySymbols = {
+  'AFN': 'Af.',
+  'TOP': r'T$',
+  'MGA': 'Ar',
+  'THB': '\u0e3f',
+  'PAB': 'B/.',
+  'ETB': 'Birr',
+  'VEF': 'Bs',
+  'BOB': 'Bs',
+  'GHS': 'GHS',
+  'CRC': '\u20a1',
+  'NIO': r'C$',
+  'GMD': 'GMD',
+  'MKD': 'din',
+  'BHD': 'din',
+  'DZD': 'din',
+  'IQD': 'din',
+  'JOD': 'din',
+  'KWD': 'din',
+  'LYD': 'din',
+  'RSD': 'din',
+  'TND': 'din',
+  'AED': 'dh',
+  'MAD': 'dh',
+  'STD': 'Db',
+  'BSD': r'$',
+  'FJD': r'$',
+  'GYD': r'$',
+  'KYD': r'$',
+  'LRD': r'$',
+  'SBD': r'$',
+  'SRD': r'$',
+  'AUD': r'$',
+  'BBD': r'$',
+  'BMD': r'$',
+  'BND': r'$',
+  'BZD': r'$',
+  'CAD': r'$',
+  'HKD': r'$',
+  'JMD': r'$',
+  'NAD': r'$',
+  'NZD': r'$',
+  'SGD': r'$',
+  'TTD': r'$',
+  'TWD': r'NT$',
+  'USD': r'$',
+  'XCD': r'$',
+  'VND': '\u20ab',
+  'AMD': 'Dram',
+  'CVE': 'CVE',
+  'EUR': '\u20ac',
+  'AWG': 'Afl.',
+  'HUF': 'Ft',
+  'BIF': 'FBu',
+  'CDF': 'FrCD',
+  'CHF': 'CHF',
+  'DJF': 'Fdj',
+  'GNF': 'FG',
+  'RWF': 'RF',
+  'XOF': 'CFA',
+  'XPF': 'FCFP',
+  'KMF': 'CF',
+  'XAF': 'FCFA',
+  'HTG': 'HTG',
+  'PYG': 'Gs',
+  'UAH': '\u20b4',
+  'PGK': 'PGK',
+  'LAK': '\u20ad',
+  'CZK': 'K\u010d',
+  'SEK': 'kr',
+  'ISK': 'kr',
+  'DKK': 'kr',
+  'NOK': 'kr',
+  'HRK': 'kn',
+  'MWK': 'MWK',
+  'ZMK': 'ZWK',
+  'AOA': 'Kz',
+  'MMK': 'K',
+  'GEL': 'GEL',
+  'LVL': 'Ls',
+  'ALL': 'Lek',
+  'HNL': 'L',
+  'SLL': 'SLL',
+  'MDL': 'MDL',
+  'RON': 'RON',
+  'BGN': 'lev',
+  'SZL': 'SZL',
+  'TRY': 'TL',
+  'LTL': 'Lt',
+  'LSL': 'LSL',
+  'AZN': 'man.',
+  'BAM': 'KM',
+  'MZN': 'MTn',
+  'NGN': '\u20a6',
+  'ERN': 'Nfk',
+  'BTN': 'Nu.',
+  'MRO': 'MRO',
+  'MOP': 'MOP',
+  'CUP': r'$',
+  'CUC': r'$',
+  'ARS': r'$',
+  'CLF': 'UF',
+  'CLP': r'$',
+  'COP': r'$',
+  'DOP': r'$',
+  'MXN': r'$',
+  'PHP': '\u20b1',
+  'UYU': r'$',
+  'FKP': '£',
+  'GIP': '£',
+  'SHP': '£',
+  'EGP': 'E£',
+  'LBP': 'L£',
+  'SDG': 'SDG',
+  'SSP': 'SSP',
+  'GBP': '£',
+  'SYP': '£',
+  'BWP': 'P',
+  'GTQ': 'Q',
+  'ZAR': 'R',
+  'BRL': r'R$',
+  'OMR': 'Rial',
+  'QAR': 'Rial',
+  'YER': 'Rial',
+  'IRR': 'Rial',
+  'KHR': 'Riel',
+  'MYR': 'RM',
+  'SAR': 'Riyal',
+  'BYR': 'BYR',
+  'RUB': 'руб.',
+  'MUR': 'Rs',
+  'SCR': 'SCR',
+  'LKR': 'Rs',
+  'NPR': 'Rs',
+  'INR': '\u20b9',
+  'PKR': 'Rs',
+  'IDR': 'Rp',
+  'ILS': '\u20aa',
+  'KES': 'Ksh',
+  'SOS': 'SOS',
+  'TZS': 'TSh',
+  'UGX': 'UGX',
+  'PEN': 'S/.',
+  'KGS': 'KGS',
+  'UZS': 'so\u02bcm',
+  'TJS': 'Som',
+  'BDT': '\u09f3',
+  'WST': 'WST',
+  'KZT': '\u20b8',
+  'MNT': '\u20ae',
+  'VUV': 'VUV',
+  'KPW': '\u20a9',
+  'KRW': '\u20a9',
+  'JPY': '¥',
+  'CNY': '¥',
+  'PLN': 'z\u0142',
+  'MVR': 'Rf',
+  'NLG': 'NAf',
+  'ZMW': 'ZK',
+  'ANG': 'ƒ',
+  'TMT': 'TMT',
+};
diff --git a/lib/src/intl/micro_money.dart b/lib/src/intl/micro_money.dart
new file mode 100644
index 0000000..f773660
--- /dev/null
+++ b/lib/src/intl/micro_money.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// @dart=2.9
+
+/// Used primarily for currency formatting, this number-like class stores
+/// millionths of a currency unit, typically as an Int64.
+///
+/// It supports no operations other than being used for Intl number formatting.
+abstract class MicroMoney {
+  factory MicroMoney(micros) => _MicroMoney(micros);
+}
+
+/// Used primarily for currency formatting, this stores millionths of a
+/// currency unit, typically as an Int64.
+///
+/// This private class provides the operations needed by the formatting code.
+class _MicroMoney implements MicroMoney {
+  final dynamic _micros;
+  _MicroMoney(this._micros);
+  static const _multiplier = 1000000;
+
+  dynamic get _integerPart => _micros ~/ _multiplier;
+  int get _fractionPart => (this - _integerPart)._micros.toInt().abs();
+
+  bool get isNegative => _micros.isNegative;
+
+  _MicroMoney abs() => isNegative ? _MicroMoney(_micros.abs()) : this;
+
+  // Note that if this is done in a general way there's a risk of integer
+  // overflow on JS when multiplying out the [other] parameter, which may be
+  // an Int64. In formatting we only ever subtract out our own integer part.
+  _MicroMoney operator -(other) {
+    if (other is _MicroMoney) return _MicroMoney(_micros - other._micros);
+    return _MicroMoney(_micros - (other * _multiplier));
+  }
+
+  _MicroMoney operator +(other) {
+    if (other is _MicroMoney) return _MicroMoney(_micros + other._micros);
+    return _MicroMoney(_micros + (other * _multiplier));
+  }
+
+  _MicroMoney operator ~/(divisor) {
+    if (divisor is! int) {
+      throw ArgumentError.value(
+          divisor, 'divisor', '_MicroMoney ~/ only supports int arguments.');
+    }
+    return _MicroMoney((_integerPart ~/ divisor) * _multiplier);
+  }
+
+  _MicroMoney operator *(other) {
+    if (other is! int) {
+      throw ArgumentError.value(
+          other, 'other', '_MicroMoney * only supports int arguments.');
+    }
+    return _MicroMoney(
+        (_integerPart * other) * _multiplier + (_fractionPart * other));
+  }
+
+  /// Note that this only really supports remainder from an int,
+  /// not division by another MicroMoney
+  _MicroMoney remainder(other) {
+    if (other is! int) {
+      throw ArgumentError.value(
+          other, 'other', '_MicroMoney.remainder only supports int arguments.');
+    }
+    return _MicroMoney(_micros.remainder(other * _multiplier));
+  }
+
+  double toDouble() => _micros.toDouble() / _multiplier;
+
+  int toInt() => _integerPart.toInt();
+
+  String toString() {
+    var beforeDecimal = '$_integerPart';
+    var decimalPart = '';
+    var fractionPart = _fractionPart;
+    if (fractionPart != 0) {
+      decimalPart = '.$fractionPart';
+    }
+    return '$beforeDecimal$decimalPart';
+  }
+}
diff --git a/lib/src/intl/number_format.dart b/lib/src/intl/number_format.dart
index be92ab8..d3d8454 100644
--- a/lib/src/intl/number_format.dart
+++ b/lib/src/intl/number_format.dart
@@ -3,14 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 // @dart=2.9
 
-import 'dart:collection';
 import 'dart:math';
 
 import 'package:intl/intl.dart';
 import 'package:intl/number_symbols.dart';
 import 'package:intl/number_symbols_data.dart';
 
-import 'intl_stream.dart';
+import 'constants.dart' as constants;
+import 'number_format_parser.dart';
+import 'number_parser.dart';
 
 part 'compact_number_format.dart';
 
@@ -60,10 +61,10 @@
 /// equivalent to "#E0" and does not take into account significant digits.
 class NumberFormat {
   /// Variables to determine how number printing behaves.
-  final String _negativePrefix;
-  final String _positivePrefix;
-  final String _negativeSuffix;
-  final String _positiveSuffix;
+  final String negativePrefix;
+  final String positivePrefix;
+  final String negativeSuffix;
+  final String positiveSuffix;
 
   /// How many numbers in a group when using punctuation to group digits in
   /// large numbers. e.g. in en_US: "1,000,000" has a grouping size of 3 digits
@@ -106,9 +107,9 @@
 
   /// For percent and permille, what are we multiplying by in order to
   /// get the printed value, e.g. 100 for percent.
-  final int _multiplier;
+  final int multiplier;
 
-  /// How many digits are there in the [_multiplier].
+  /// How many digits are there in the [multiplier].
   final int _multiplierDigits;
 
   /// Stores the pattern used to create this format. This isn't used, but
@@ -295,182 +296,7 @@
   /// (The current implementation is the same for all locales, but this is
   /// temporary and callers shouldn't rely on it.)
   String simpleCurrencySymbol(String currencyCode) =>
-      _simpleCurrencySymbols[currencyCode] ?? currencyCode;
-
-  /// A map from currency names to the simple name/symbol.
-  ///
-  /// The simple currency symbol is generally short, and the same or related to
-  /// what is used in countries having the currency as an official symbol. It
-  /// may be a symbol character, or may have letters, or both. It may be
-  /// different according to the locale: for example, for an Arabic locale it
-  /// may consist of Arabic letters, but for a French locale consist of Latin
-  /// letters. It will not be unique: for example, "$" can appear for both USD
-  /// and CAD.
-  ///
-  /// (The current implementation is the same for all locales, but this is
-  /// temporary and callers shouldn't rely on it.)
-  static final Map<String, String> _simpleCurrencySymbols = {
-    'AFN': 'Af.',
-    'TOP': r'T$',
-    'MGA': 'Ar',
-    'THB': '\u0e3f',
-    'PAB': 'B/.',
-    'ETB': 'Birr',
-    'VEF': 'Bs',
-    'BOB': 'Bs',
-    'GHS': 'GHS',
-    'CRC': '\u20a1',
-    'NIO': r'C$',
-    'GMD': 'GMD',
-    'MKD': 'din',
-    'BHD': 'din',
-    'DZD': 'din',
-    'IQD': 'din',
-    'JOD': 'din',
-    'KWD': 'din',
-    'LYD': 'din',
-    'RSD': 'din',
-    'TND': 'din',
-    'AED': 'dh',
-    'MAD': 'dh',
-    'STD': 'Db',
-    'BSD': r'$',
-    'FJD': r'$',
-    'GYD': r'$',
-    'KYD': r'$',
-    'LRD': r'$',
-    'SBD': r'$',
-    'SRD': r'$',
-    'AUD': r'$',
-    'BBD': r'$',
-    'BMD': r'$',
-    'BND': r'$',
-    'BZD': r'$',
-    'CAD': r'$',
-    'HKD': r'$',
-    'JMD': r'$',
-    'NAD': r'$',
-    'NZD': r'$',
-    'SGD': r'$',
-    'TTD': r'$',
-    'TWD': r'NT$',
-    'USD': r'$',
-    'XCD': r'$',
-    'VND': '\u20ab',
-    'AMD': 'Dram',
-    'CVE': 'CVE',
-    'EUR': '\u20ac',
-    'AWG': 'Afl.',
-    'HUF': 'Ft',
-    'BIF': 'FBu',
-    'CDF': 'FrCD',
-    'CHF': 'CHF',
-    'DJF': 'Fdj',
-    'GNF': 'FG',
-    'RWF': 'RF',
-    'XOF': 'CFA',
-    'XPF': 'FCFP',
-    'KMF': 'CF',
-    'XAF': 'FCFA',
-    'HTG': 'HTG',
-    'PYG': 'Gs',
-    'UAH': '\u20b4',
-    'PGK': 'PGK',
-    'LAK': '\u20ad',
-    'CZK': 'K\u010d',
-    'SEK': 'kr',
-    'ISK': 'kr',
-    'DKK': 'kr',
-    'NOK': 'kr',
-    'HRK': 'kn',
-    'MWK': 'MWK',
-    'ZMK': 'ZWK',
-    'AOA': 'Kz',
-    'MMK': 'K',
-    'GEL': 'GEL',
-    'LVL': 'Ls',
-    'ALL': 'Lek',
-    'HNL': 'L',
-    'SLL': 'SLL',
-    'MDL': 'MDL',
-    'RON': 'RON',
-    'BGN': 'lev',
-    'SZL': 'SZL',
-    'TRY': 'TL',
-    'LTL': 'Lt',
-    'LSL': 'LSL',
-    'AZN': 'man.',
-    'BAM': 'KM',
-    'MZN': 'MTn',
-    'NGN': '\u20a6',
-    'ERN': 'Nfk',
-    'BTN': 'Nu.',
-    'MRO': 'MRO',
-    'MOP': 'MOP',
-    'CUP': r'$',
-    'CUC': r'$',
-    'ARS': r'$',
-    'CLF': 'UF',
-    'CLP': r'$',
-    'COP': r'$',
-    'DOP': r'$',
-    'MXN': r'$',
-    'PHP': '\u20b1',
-    'UYU': r'$',
-    'FKP': '£',
-    'GIP': '£',
-    'SHP': '£',
-    'EGP': 'E£',
-    'LBP': 'L£',
-    'SDG': 'SDG',
-    'SSP': 'SSP',
-    'GBP': '£',
-    'SYP': '£',
-    'BWP': 'P',
-    'GTQ': 'Q',
-    'ZAR': 'R',
-    'BRL': r'R$',
-    'OMR': 'Rial',
-    'QAR': 'Rial',
-    'YER': 'Rial',
-    'IRR': 'Rial',
-    'KHR': 'Riel',
-    'MYR': 'RM',
-    'SAR': 'Riyal',
-    'BYR': 'BYR',
-    'RUB': 'руб.',
-    'MUR': 'Rs',
-    'SCR': 'SCR',
-    'LKR': 'Rs',
-    'NPR': 'Rs',
-    'INR': '\u20b9',
-    'PKR': 'Rs',
-    'IDR': 'Rp',
-    'ILS': '\u20aa',
-    'KES': 'Ksh',
-    'SOS': 'SOS',
-    'TZS': 'TSh',
-    'UGX': 'UGX',
-    'PEN': 'S/.',
-    'KGS': 'KGS',
-    'UZS': 'so\u02bcm',
-    'TJS': 'Som',
-    'BDT': '\u09f3',
-    'WST': 'WST',
-    'KZT': '\u20b8',
-    'MNT': '\u20ae',
-    'VUV': 'VUV',
-    'KPW': '\u20a9',
-    'KRW': '\u20a9',
-    'JPY': '¥',
-    'CNY': '¥',
-    'PLN': 'z\u0142',
-    'MVR': 'Rf',
-    'NLG': 'NAf',
-    'ZMW': 'ZK',
-    'ANG': 'ƒ',
-    'TMT': 'TMT',
-  };
+      constants.simpleCurrencySymbols[currencyCode] ?? currencyCode;
 
   /// Create a number format that prints in a pattern we get from
   /// the [getPattern] function using the locale [locale].
@@ -487,10 +313,10 @@
     locale = Intl.verifiedLocale(locale, localeExists);
     var symbols = numberFormatSymbols[locale];
     var localeZero = symbols.ZERO_DIGIT.codeUnitAt(0);
-    var zeroOffset = localeZero - _zero;
+    var zeroOffset = localeZero - constants.asciiZeroCodeUnit;
     name ??= symbols.DEF_CURRENCY_CODE;
     if (currencySymbol == null && lookupSimpleCurrencySymbol) {
-      currencySymbol = _simpleCurrencySymbols[name];
+      currencySymbol = constants.simpleCurrencySymbols[name];
     }
     currencySymbol ??= name;
 
@@ -505,7 +331,7 @@
         pattern,
         symbols,
         zeroOffset,
-        _NumberFormatParser.parse(symbols, pattern, isForCurrency,
+        NumberFormatParser.parse(symbols, pattern, isForCurrency,
             currencySymbol, name, decimalDigits));
   }
 
@@ -514,16 +340,16 @@
       this.currencySymbol,
       this._isForCurrency,
       this._locale,
-      this._localeZero,
+      this.localeZero,
       this._pattern,
       this._symbols,
       this._zeroOffset,
-      _NumberFormatParseResult result)
-      : _positivePrefix = result.positivePrefix,
-        _negativePrefix = result.negativePrefix,
-        _positiveSuffix = result.positiveSuffix,
-        _negativeSuffix = result.negativeSuffix,
-        _multiplier = result.multiplier,
+      NumberFormatParseResult result)
+      : positivePrefix = result.positivePrefix,
+        negativePrefix = result.negativePrefix,
+        positiveSuffix = result.positiveSuffix,
+        negativeSuffix = result.negativeSuffix,
+        multiplier = result.multiplier,
         _multiplierDigits = result.multiplierDigits,
         _useExponentialNotation = result.useExponentialNotation,
         minimumExponentDigits = result.minimumExponentDigits,
@@ -613,7 +439,7 @@
 
   /// Parse the number represented by the string. If it's not
   /// parseable, throws a [FormatException].
-  num parse(String text) => _NumberParser(this, text).value;
+  num parse(String text) => NumberParser(this, text).value;
 
   /// Format the main part of the number in the form dictated by the pattern.
   void _formatNumber(number) {
@@ -789,7 +615,7 @@
         }
       }
       power = pow(10, fractionDigits);
-      digitMultiplier = power * _multiplier;
+      digitMultiplier = power * multiplier;
 
       // Multiply out to the number of decimal places and the percent, then
       // round. For fixed-size integer types this should always be zero, so
@@ -871,7 +697,8 @@
   /// Format the part after the decimal place in a fixed point number.
   void _formatFractionPart(String fractionPart) {
     var fractionLength = fractionPart.length;
-    while (fractionPart.codeUnitAt(fractionLength - 1) == _zero &&
+    while (fractionPart.codeUnitAt(fractionLength - 1) ==
+            constants.asciiZeroCodeUnit &&
         fractionLength > minimumFractionDigits + 1) {
       fractionLength--;
     }
@@ -943,13 +770,10 @@
     }
   }
 
-  /// The code point for the character '0'.
-  static const _zero = 48;
-
   /// The code point for the locale's zero digit.
   ///
   ///  Initialized when the locale is set.
-  final int _localeZero;
+  final int localeZero;
 
   /// The difference between our zero and '0'.
   ///
@@ -959,11 +783,11 @@
 
   /// Returns the prefix for [x] based on whether it's positive or negative.
   /// In en_US this would be '' and '-' respectively.
-  String _signPrefix(x) => x.isNegative ? _negativePrefix : _positivePrefix;
+  String _signPrefix(x) => x.isNegative ? negativePrefix : positivePrefix;
 
   /// Returns the suffix for [x] based on wether it's positive or negative.
   /// In en_US there are no suffixes for positive or negative.
-  String _signSuffix(x) => x.isNegative ? _negativeSuffix : _positiveSuffix;
+  String _signSuffix(x) => x.isNegative ? negativeSuffix : positiveSuffix;
 
   /// Explicitly turn off any grouping (e.g. by thousands) in this format.
   ///
@@ -977,715 +801,4 @@
   String toString() => 'NumberFormat($_locale, $_pattern)';
 }
 
-///  A one-time object for parsing a particular numeric string. One-time here
-/// means an instance can only parse one string. This is implemented by
-/// transforming from a locale-specific format to one that the system can parse,
-/// then calls the system parsing methods on it.
-class _NumberParser {
-  /// The format for which we are parsing.
-  final NumberFormat format;
-
-  /// The text we are parsing.
-  final String text;
-
-  /// What we use to iterate over the input text.
-  final IntlStream input;
-
-  /// The result of parsing [text] according to [format]. Automatically
-  /// populated in the constructor.
-  num value;
-
-  /// The symbols used by our format.
-  NumberSymbols get symbols => format.symbols;
-
-  /// Where we accumulate the normalized representation of the number.
-  final StringBuffer _normalized = StringBuffer();
-
-  /// Did we see something that indicates this is, or at least might be,
-  /// a positive number.
-  bool gotPositive = false;
-
-  /// Did we see something that indicates this is, or at least might be,
-  /// a negative number.
-  bool gotNegative = false;
-
-  /// Did we see the required positive suffix at the end. Should
-  /// match [gotPositive].
-  bool gotPositiveSuffix = false;
-
-  /// Did we see the required negative suffix at the end. Should
-  /// match [gotNegative].
-  bool gotNegativeSuffix = false;
-
-  /// Should we stop parsing before hitting the end of the string.
-  bool done = false;
-
-  /// Have we already skipped over any required prefixes.
-  bool prefixesSkipped = false;
-
-  /// If the number is percent or permill, what do we divide by at the end.
-  int scale = 1;
-
-  String get _positivePrefix => format._positivePrefix;
-  String get _negativePrefix => format._negativePrefix;
-  String get _positiveSuffix => format._positiveSuffix;
-  String get _negativeSuffix => format._negativeSuffix;
-  int get _zero => NumberFormat._zero;
-  int get _localeZero => format._localeZero;
-
-  ///  Create a new [_NumberParser] on which we can call parse().
-  _NumberParser(this.format, this.text) : input = IntlStream(text) {
-    scale = format._multiplier;
-    value = parse();
-  }
-
-  ///  The strings we might replace with functions that return the replacement
-  /// values. They are functions because we might need to check something
-  /// in the context. Note that the ordering is important here. For example,
-  /// `symbols.PERCENT` might be " %", and we must handle that before we
-  /// look at an individual space.
-  Map<String, Function> get replacements =>
-      _replacements ??= _initializeReplacements();
-
-  Map<String, Function> _replacements;
-
-  Map<String, Function> _initializeReplacements() => {
-        symbols.DECIMAL_SEP: () => '.',
-        symbols.EXP_SYMBOL: () => 'E',
-        symbols.GROUP_SEP: handleSpace,
-        symbols.PERCENT: () {
-          scale = _NumberFormatParser._PERCENT_SCALE;
-          return '';
-        },
-        symbols.PERMILL: () {
-          scale = _NumberFormatParser._PER_MILLE_SCALE;
-          return '';
-        },
-        ' ': handleSpace,
-        '\u00a0': handleSpace,
-        '+': () => '+',
-        '-': () => '-',
-      };
-
-  void invalidFormat() =>
-      throw FormatException('Invalid number: ${input.contents}');
-
-  /// Replace a space in the number with the normalized form. If space is not
-  /// a significant character (normally grouping) then it's just invalid. If it
-  /// is the grouping character, then it's only valid if it's followed by a
-  /// digit. e.g. '$12 345.00'
-  void handleSpace() =>
-      groupingIsNotASpaceOrElseItIsSpaceFollowedByADigit ? '' : invalidFormat();
-
-  /// Determine if a space is a valid character in the number. See
-  /// [handleSpace].
-  bool get groupingIsNotASpaceOrElseItIsSpaceFollowedByADigit {
-    if (symbols.GROUP_SEP != '\u00a0' || symbols.GROUP_SEP != ' ') return true;
-    var peeked = input.peek(symbols.GROUP_SEP.length + 1);
-    return asDigit(peeked[peeked.length - 1]) != null;
-  }
-
-  /// Turn [char] into a number representing a digit, or null if it doesn't
-  /// represent a digit in this locale.
-  int asDigit(String char) {
-    var charCode = char.codeUnitAt(0);
-    var digitValue = charCode - _localeZero;
-    if (digitValue >= 0 && digitValue < 10) {
-      return digitValue;
-    } else {
-      return null;
-    }
-  }
-
-  /// Check to see if the input begins with either the positive or negative
-  /// prefixes. Set the [gotPositive] and [gotNegative] variables accordingly.
-  void checkPrefixes({bool skip = false}) {
-    bool checkPrefix(String prefix) =>
-        prefix.isNotEmpty && input.startsWith(prefix);
-
-    // TODO(alanknight): There's a faint possibility of a bug here where
-    // a positive prefix is followed by a negative prefix that's also a valid
-    // part of the number, but that seems very unlikely.
-    if (checkPrefix(_positivePrefix)) gotPositive = true;
-    if (checkPrefix(_negativePrefix)) gotNegative = true;
-
-    // The positive prefix might be a substring of the negative, in
-    // which case both would match.
-    if (gotPositive && gotNegative) {
-      if (_positivePrefix.length > _negativePrefix.length) {
-        gotNegative = false;
-      } else if (_negativePrefix.length > _positivePrefix.length) {
-        gotPositive = false;
-      }
-    }
-    if (skip) {
-      if (gotPositive) input.read(_positivePrefix.length);
-      if (gotNegative) input.read(_negativePrefix.length);
-    }
-  }
-
-  /// If the rest of our input is either the positive or negative suffix,
-  /// set [gotPositiveSuffix] or [gotNegativeSuffix] accordingly.
-  void checkSuffixes() {
-    var remainder = input.rest();
-    if (remainder == _positiveSuffix) gotPositiveSuffix = true;
-    if (remainder == _negativeSuffix) gotNegativeSuffix = true;
-  }
-
-  /// We've encountered a character that's not a digit. Go through our
-  /// replacement rules looking for how to handle it. If we see something
-  /// that's not a digit and doesn't have a replacement, then we're done
-  /// and the number is probably invalid.
-  void processNonDigit() {
-    // It might just be a prefix that we haven't skipped. We don't want to
-    // skip them initially because they might also be semantically meaningful,
-    // e.g. leading %. So we allow them through the loop, but only once.
-    var foundAnInterpretation = false;
-    if (input.index == 0 && !prefixesSkipped) {
-      prefixesSkipped = true;
-      checkPrefixes(skip: true);
-      foundAnInterpretation = true;
-    }
-
-    for (var key in replacements.keys) {
-      if (input.startsWith(key)) {
-        _normalized.write(replacements[key]());
-        input.read(key.length);
-        return;
-      }
-    }
-    // We haven't found either of these things, this seems invalid.
-    if (!foundAnInterpretation) {
-      done = true;
-    }
-  }
-
-  /// Parse [text] and return the resulting number. Throws [FormatException]
-  /// if we can't parse it.
-  num parse() {
-    if (text == symbols.NAN) return 0.0 / 0.0;
-    if (text == '$_positivePrefix${symbols.INFINITY}$_positiveSuffix') {
-      return 1.0 / 0.0;
-    }
-    if (text == '$_negativePrefix${symbols.INFINITY}$_negativeSuffix') {
-      return -1.0 / 0.0;
-    }
-
-    checkPrefixes();
-    var parsed = parseNumber(input);
-
-    if (gotPositive && !gotPositiveSuffix) invalidNumber();
-    if (gotNegative && !gotNegativeSuffix) invalidNumber();
-    if (!input.atEnd()) invalidNumber();
-
-    return parsed;
-  }
-
-  /// The number is invalid, throw a [FormatException].
-  void invalidNumber() =>
-      throw FormatException('Invalid Number: ${input.contents}');
-
-  /// Parse the number portion of the input, i.e. not any prefixes or suffixes,
-  /// and assuming NaN and Infinity are already handled.
-  num parseNumber(IntlStream input) {
-    if (gotNegative) {
-      _normalized.write('-');
-    }
-    while (!done && !input.atEnd()) {
-      var digit = asDigit(input.peek());
-      if (digit != null) {
-        _normalized.writeCharCode(_zero + digit);
-        input.next();
-      } else {
-        processNonDigit();
-      }
-      checkSuffixes();
-    }
-
-    var normalizedText = _normalized.toString();
-    num parsed = int.tryParse(normalizedText);
-    parsed ??= double.parse(normalizedText);
-    return parsed / scale;
-  }
-}
-
-/// Output of [_NumberFormatParser.parse].
-///
-/// Everything needed to initialize a [NumberFormat].
-class _NumberFormatParseResult {
-  String negativePrefix;
-  String positivePrefix = '';
-  String negativeSuffix = '';
-  String positiveSuffix = '';
-
-  int multiplier = 1;
-  int get multiplierDigits => (log(multiplier) / _ln10).round();
-
-  int minimumExponentDigits = 0;
-
-  int maximumIntegerDigits = 40;
-  int minimumIntegerDigits = 1;
-  int maximumFractionDigits = 3;
-  int minimumFractionDigits = 0;
-
-  int groupingSize = 3;
-  int finalGroupingSize = 3;
-
-  bool decimalSeparatorAlwaysShown = false;
-  bool useSignForPositiveExponent = false;
-  bool useExponentialNotation = false;
-
-  int decimalDigits;
-
-  // [decimalDigits] is both input and output of parsing.
-  _NumberFormatParseResult(NumberSymbols symbols, this.decimalDigits) {
-    negativePrefix = symbols.MINUS_SIGN;
-  }
-}
-
-/// Private class that parses the numeric formatting pattern and sets the
-/// variables in [format] to appropriate values. Instances of this are
-/// transient and store parsing state in instance variables, so can only be used
-/// to parse a single pattern.
-class _NumberFormatParser {
-  /// The special characters in the pattern language. All others are treated
-  /// as literals.
-  static const _PATTERN_SEPARATOR = ';';
-  static const _QUOTE = "'";
-  static const _PATTERN_DIGIT = '#';
-  static const _PATTERN_ZERO_DIGIT = '0';
-  static const _PATTERN_GROUPING_SEPARATOR = ',';
-  static const _PATTERN_DECIMAL_SEPARATOR = '.';
-  static const _PATTERN_CURRENCY_SIGN = '\u00A4';
-  static const _PATTERN_PER_MILLE = '\u2030';
-  static const _PER_MILLE_SCALE = 1000;
-  static const _PATTERN_PERCENT = '%';
-  static const _PERCENT_SCALE = 100;
-  static const _PATTERN_EXPONENT = 'E';
-  static const _PATTERN_PLUS = '+';
-
-  /// The format whose state we are setting.
-  final NumberSymbols symbols;
-
-  /// The pattern we are parsing.
-  final _StringIterator pattern;
-
-  /// Whether this is a currency.
-  final bool isForCurrency;
-
-  /// We can be passed a specific currency symbol, regardless of the locale.
-  final String currencySymbol;
-
-  final String currencyName;
-
-  // The result being constructed.
-  final _NumberFormatParseResult result;
-
-  bool groupingSizeSetExplicitly = false;
-
-  /// Create a new [_NumberFormatParser] for a particular [NumberFormat] and
-  /// [input] pattern.
-  ///
-  /// [decimalDigits] is optional, if specified it overrides the default.
-  _NumberFormatParser(this.symbols, String input, this.isForCurrency,
-      this.currencySymbol, this.currencyName, int decimalDigits)
-      : result = _NumberFormatParseResult(symbols, decimalDigits),
-        pattern = _iterator(input) {
-    pattern.moveNext();
-  }
-
-  static _NumberFormatParseResult parse(
-          NumberSymbols symbols,
-          String input,
-          bool isForCurrency,
-          String currencySymbol,
-          String currencyName,
-          int decimalDigits) =>
-      input == null
-          ? _NumberFormatParseResult(symbols, decimalDigits)
-          : (_NumberFormatParser(symbols, input, isForCurrency, currencySymbol,
-                  currencyName, decimalDigits)
-                .._parse())
-              .result;
-
-  /// For currencies, the default number of decimal places to use in
-  /// formatting. Defaults to two for non-currencies or currencies where it's
-  /// not specified.
-  int get _defaultDecimalDigits =>
-      currencyFractionDigits[currencyName.toUpperCase()] ??
-      currencyFractionDigits['DEFAULT'];
-
-  /// Parse the input pattern and update [result].
-  void _parse() {
-    result.positivePrefix = _parseAffix();
-    var trunk = _parseTrunk();
-    result.positiveSuffix = _parseAffix();
-    // If we have separate positive and negative patterns, now parse the
-    // the negative version.
-    if (pattern.current == _NumberFormatParser._PATTERN_SEPARATOR) {
-      pattern.moveNext();
-      result.negativePrefix = _parseAffix();
-      // Skip over the negative trunk, verifying that it's identical to the
-      // positive trunk.
-      for (var each in _iterable(trunk)) {
-        if (pattern.current != each && pattern.current != null) {
-          throw FormatException(
-              'Positive and negative trunks must be the same', trunk);
-        }
-        pattern.moveNext();
-      }
-      result.negativeSuffix = _parseAffix();
-    } else {
-      // If no negative affix is specified, they share the same positive affix.
-      result.negativePrefix = result.negativePrefix + result.positivePrefix;
-      result.negativeSuffix = result.positiveSuffix + result.negativeSuffix;
-    }
-
-    if (isForCurrency) {
-      result.decimalDigits ??= _defaultDecimalDigits;
-    }
-    if (result.decimalDigits != null) {
-      result.minimumFractionDigits = result.decimalDigits;
-      result.maximumFractionDigits = result.decimalDigits;
-    }
-  }
-
-  /// Variable used in parsing prefixes and suffixes to keep track of
-  /// whether or not we are in a quoted region.
-  bool inQuote = false;
-
-  /// Parse a prefix or suffix and return the prefix/suffix string. Note that
-  /// this also may modify the state of [format].
-  String _parseAffix() {
-    var affix = StringBuffer();
-    inQuote = false;
-    while (parseCharacterAffix(affix) && pattern.moveNext()) {}
-    return affix.toString();
-  }
-
-  /// Parse an individual character as part of a prefix or suffix.  Return true
-  /// if we should continue to look for more affix characters, and false if
-  /// we have reached the end.
-  bool parseCharacterAffix(StringBuffer affix) {
-    var ch = pattern.current;
-    if (ch == null) return false;
-    if (ch == _QUOTE) {
-      if (pattern.peek == _QUOTE) {
-        pattern.moveNext();
-        affix.write(_QUOTE); // 'don''t'
-      } else {
-        inQuote = !inQuote;
-      }
-      return true;
-    }
-
-    if (inQuote) {
-      affix.write(ch);
-    } else {
-      switch (ch) {
-        case _PATTERN_DIGIT:
-        case _PATTERN_ZERO_DIGIT:
-        case _PATTERN_GROUPING_SEPARATOR:
-        case _PATTERN_DECIMAL_SEPARATOR:
-        case _PATTERN_SEPARATOR:
-          return false;
-        case _PATTERN_CURRENCY_SIGN:
-          // TODO(alanknight): Handle the local/global/portable currency signs
-          affix.write(currencySymbol);
-          break;
-        case _PATTERN_PERCENT:
-          if (result.multiplier != 1 && result.multiplier != _PERCENT_SCALE) {
-            throw const FormatException('Too many percent/permill');
-          }
-          result.multiplier = _PERCENT_SCALE;
-          affix.write(symbols.PERCENT);
-          break;
-        case _PATTERN_PER_MILLE:
-          if (result.multiplier != 1 && result.multiplier != _PER_MILLE_SCALE) {
-            throw const FormatException('Too many percent/permill');
-          }
-          result.multiplier = _PER_MILLE_SCALE;
-          affix.write(symbols.PERMILL);
-          break;
-        default:
-          affix.write(ch);
-      }
-    }
-    return true;
-  }
-
-  /// Variables used in [_parseTrunk] and [parseTrunkCharacter].
-  var decimalPos = -1;
-  var digitLeftCount = 0;
-  var zeroDigitCount = 0;
-  var digitRightCount = 0;
-  var groupingCount = -1;
-
-  /// Parse the "trunk" portion of the pattern, the piece that doesn't include
-  /// positive or negative prefixes or suffixes.
-  String _parseTrunk() {
-    var loop = true;
-    var trunk = StringBuffer();
-    while (pattern.current != null && loop) {
-      loop = parseTrunkCharacter(trunk);
-    }
-
-    if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
-      // Handle '###.###' and '###.' and '.###'
-      // Handle '.###'
-      var n = decimalPos == 0 ? 1 : decimalPos;
-      digitRightCount = digitLeftCount - n;
-      digitLeftCount = n - 1;
-      zeroDigitCount = 1;
-    }
-
-    // Do syntax checking on the digits.
-    if (decimalPos < 0 && digitRightCount > 0 ||
-        decimalPos >= 0 &&
-            (decimalPos < digitLeftCount ||
-                decimalPos > digitLeftCount + zeroDigitCount) ||
-        groupingCount == 0) {
-      throw FormatException('Malformed pattern "${pattern.input}"');
-    }
-    var totalDigits = digitLeftCount + zeroDigitCount + digitRightCount;
-
-    result.maximumFractionDigits =
-        decimalPos >= 0 ? totalDigits - decimalPos : 0;
-    if (decimalPos >= 0) {
-      result.minimumFractionDigits =
-          digitLeftCount + zeroDigitCount - decimalPos;
-      if (result.minimumFractionDigits < 0) {
-        result.minimumFractionDigits = 0;
-      }
-    }
-
-    // The effectiveDecimalPos is the position the decimal is at or would be at
-    // if there is no decimal. Note that if decimalPos<0, then digitTotalCount
-    // == digitLeftCount + zeroDigitCount.
-    var effectiveDecimalPos = decimalPos >= 0 ? decimalPos : totalDigits;
-    result.minimumIntegerDigits = effectiveDecimalPos - digitLeftCount;
-    if (result.useExponentialNotation) {
-      result.maximumIntegerDigits =
-          digitLeftCount + result.minimumIntegerDigits;
-
-      // In exponential display, we need to at least show something.
-      if (result.maximumFractionDigits == 0 &&
-          result.minimumIntegerDigits == 0) {
-        result.minimumIntegerDigits = 1;
-      }
-    }
-
-    result.finalGroupingSize = max(0, groupingCount);
-    if (!groupingSizeSetExplicitly) {
-      result.groupingSize = result.finalGroupingSize;
-    }
-    result.decimalSeparatorAlwaysShown =
-        decimalPos == 0 || decimalPos == totalDigits;
-
-    return trunk.toString();
-  }
-
-  /// Parse an individual character of the trunk. Return true if we should
-  /// continue to look for additional trunk characters or false if we have
-  /// reached the end.
-  bool parseTrunkCharacter(trunk) {
-    var ch = pattern.current;
-    switch (ch) {
-      case _PATTERN_DIGIT:
-        if (zeroDigitCount > 0) {
-          digitRightCount++;
-        } else {
-          digitLeftCount++;
-        }
-        if (groupingCount >= 0 && decimalPos < 0) {
-          groupingCount++;
-        }
-        break;
-      case _PATTERN_ZERO_DIGIT:
-        if (digitRightCount > 0) {
-          throw FormatException('Unexpected "0" in pattern "${pattern.input}');
-        }
-        zeroDigitCount++;
-        if (groupingCount >= 0 && decimalPos < 0) {
-          groupingCount++;
-        }
-        break;
-      case _PATTERN_GROUPING_SEPARATOR:
-        if (groupingCount > 0) {
-          groupingSizeSetExplicitly = true;
-          result.groupingSize = groupingCount;
-        }
-        groupingCount = 0;
-        break;
-      case _PATTERN_DECIMAL_SEPARATOR:
-        if (decimalPos >= 0) {
-          throw FormatException(
-              'Multiple decimal separators in pattern "$pattern"');
-        }
-        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
-        break;
-      case _PATTERN_EXPONENT:
-        trunk.write(ch);
-        if (result.useExponentialNotation) {
-          throw FormatException(
-              'Multiple exponential symbols in pattern "$pattern"');
-        }
-        result.useExponentialNotation = true;
-        result.minimumExponentDigits = 0;
-
-        // exponent pattern can have a optional '+'.
-        pattern.moveNext();
-        var nextChar = pattern.current;
-        if (nextChar == _PATTERN_PLUS) {
-          trunk.write(pattern.current);
-          pattern.moveNext();
-          result.useSignForPositiveExponent = true;
-        }
-
-        // Use lookahead to parse out the exponential part
-        // of the pattern, then jump into phase 2.
-        while (pattern.current == _PATTERN_ZERO_DIGIT) {
-          trunk.write(pattern.current);
-          pattern.moveNext();
-          result.minimumExponentDigits++;
-        }
-
-        if ((digitLeftCount + zeroDigitCount) < 1 ||
-            result.minimumExponentDigits < 1) {
-          throw FormatException('Malformed exponential pattern "$pattern"');
-        }
-        return false;
-      default:
-        return false;
-    }
-    trunk.write(ch);
-    pattern.moveNext();
-    return true;
-  }
-}
-
-/// Returns an [Iterable] on the string as a list of substrings.
-Iterable<String> _iterable(String s) => _StringIterable(s);
-
-/// Return an iterator on the string as a list of substrings.
-Iterator<String> _iterator(String s) => _StringIterator(s);
-
-// TODO(nweiz): remove this when issue 3780 is fixed.
-/// Provides an Iterable that wraps [_iterator] so it can be used in a `for`
-/// loop.
-class _StringIterable extends IterableBase<String> {
-  final Iterator<String> iterator;
-
-  _StringIterable(String s) : iterator = _iterator(s);
-}
-
-/// Provides an iterator over a string as a list of substrings, and also
-/// gives us a lookahead of one via the [peek] method.
-class _StringIterator implements Iterator<String> {
-  final String input;
-  int nextIndex = 0;
-  String _current;
-
-  _StringIterator(input) : input = _validate(input);
-
-  String get current => _current;
-
-  bool moveNext() {
-    if (nextIndex >= input.length) {
-      _current = null;
-      return false;
-    }
-    _current = input[nextIndex++];
-    return true;
-  }
-
-  String get peek => nextIndex >= input.length ? null : input[nextIndex];
-
-  Iterator<String> get iterator => this;
-
-  static String _validate(input) {
-    if (input is! String) throw ArgumentError(input);
-    return input;
-  }
-}
-
-/// Used primarily for currency formatting, this number-like class stores
-/// millionths of a currency unit, typically as an Int64.
-///
-/// It supports no operations other than being used for Intl number formatting.
-abstract class MicroMoney {
-  factory MicroMoney(micros) => _MicroMoney(micros);
-}
-
-/// Used primarily for currency formatting, this stores millionths of a
-/// currency unit, typically as an Int64.
-///
-/// This private class provides the operations needed by the formatting code.
-class _MicroMoney implements MicroMoney {
-  final dynamic _micros;
-  _MicroMoney(this._micros);
-  static const _multiplier = 1000000;
-
-  dynamic get _integerPart => _micros ~/ _multiplier;
-  int get _fractionPart => (this - _integerPart)._micros.toInt().abs();
-
-  bool get isNegative => _micros.isNegative;
-
-  _MicroMoney abs() => isNegative ? _MicroMoney(_micros.abs()) : this;
-
-  // Note that if this is done in a general way there's a risk of integer
-  // overflow on JS when multiplying out the [other] parameter, which may be
-  // an Int64. In formatting we only ever subtract out our own integer part.
-  _MicroMoney operator -(other) {
-    if (other is _MicroMoney) return _MicroMoney(_micros - other._micros);
-    return _MicroMoney(_micros - (other * _multiplier));
-  }
-
-  _MicroMoney operator +(other) {
-    if (other is _MicroMoney) return _MicroMoney(_micros + other._micros);
-    return _MicroMoney(_micros + (other * _multiplier));
-  }
-
-  _MicroMoney operator ~/(divisor) {
-    if (divisor is! int) {
-      throw ArgumentError.value(
-          divisor, 'divisor', '_MicroMoney ~/ only supports int arguments.');
-    }
-    return _MicroMoney((_integerPart ~/ divisor) * _multiplier);
-  }
-
-  _MicroMoney operator *(other) {
-    if (other is! int) {
-      throw ArgumentError.value(
-          other, 'other', '_MicroMoney * only supports int arguments.');
-    }
-    return _MicroMoney(
-        (_integerPart * other) * _multiplier + (_fractionPart * other));
-  }
-
-  /// Note that this only really supports remainder from an int,
-  /// not division by another MicroMoney
-  _MicroMoney remainder(other) {
-    if (other is! int) {
-      throw ArgumentError.value(
-          other, 'other', '_MicroMoney.remainder only supports int arguments.');
-    }
-    return _MicroMoney(_micros.remainder(other * _multiplier));
-  }
-
-  double toDouble() => _micros.toDouble() / _multiplier;
-
-  int toInt() => _integerPart.toInt();
-
-  String toString() {
-    var beforeDecimal = '$_integerPart';
-    var decimalPart = '';
-    var fractionPart = _fractionPart;
-    if (fractionPart != 0) {
-      decimalPart = '.$fractionPart';
-    }
-    return '$beforeDecimal$decimalPart';
-  }
-}
-
 final _ln10 = log(10);
diff --git a/lib/src/intl/number_format_parser.dart b/lib/src/intl/number_format_parser.dart
new file mode 100644
index 0000000..a2609b1
--- /dev/null
+++ b/lib/src/intl/number_format_parser.dart
@@ -0,0 +1,369 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// @dart=2.9
+import 'dart:math';
+
+import 'package:intl/number_symbols.dart';
+import 'package:intl/number_symbols_data.dart';
+
+import 'string_iterator.dart';
+
+// ignore_for_file: constant_identifier_names
+
+/// Output of [_NumberFormatParser.parse].
+///
+/// Everything needed to initialize a [NumberFormat].
+class NumberFormatParseResult {
+  String negativePrefix;
+  String positivePrefix = '';
+  String negativeSuffix = '';
+  String positiveSuffix = '';
+
+  int multiplier = 1;
+  int get multiplierDigits => (log(multiplier) / _ln10).round();
+
+  int minimumExponentDigits = 0;
+
+  int maximumIntegerDigits = 40;
+  int minimumIntegerDigits = 1;
+  int maximumFractionDigits = 3;
+  int minimumFractionDigits = 0;
+
+  int groupingSize = 3;
+  int finalGroupingSize = 3;
+
+  bool decimalSeparatorAlwaysShown = false;
+  bool useSignForPositiveExponent = false;
+  bool useExponentialNotation = false;
+
+  int decimalDigits;
+
+  // [decimalDigits] is both input and output of parsing.
+  NumberFormatParseResult(NumberSymbols symbols, this.decimalDigits) {
+    negativePrefix = symbols.MINUS_SIGN;
+  }
+}
+
+/// Private class that parses the numeric formatting pattern and sets the
+/// variables in [format] to appropriate values. Instances of this are
+/// transient and store parsing state in instance variables, so can only be used
+/// to parse a single pattern.
+class NumberFormatParser {
+  /// The special characters in the pattern language. All others are treated
+  /// as literals.
+  static const PATTERN_SEPARATOR = ';';
+  static const QUOTE = "'";
+  static const PATTERN_DIGIT = '#';
+  static const PATTERN_ZERO_DIGIT = '0';
+  static const PATTERN_GROUPING_SEPARATOR = ',';
+  static const PATTERN_DECIMAL_SEPARATOR = '.';
+  static const PATTERN_CURRENCY_SIGN = '\u00A4';
+  static const PATTERN_PER_MILLE = '\u2030';
+  static const PER_MILLE_SCALE = 1000;
+  static const PATTERN_PERCENT = '%';
+  static const PERCENT_SCALE = 100;
+  static const PATTERN_EXPONENT = 'E';
+  static const PATTERN_PLUS = '+';
+
+  /// The format whose state we are setting.
+  final NumberSymbols symbols;
+
+  /// The pattern we are parsing.
+  final StringIterator pattern;
+
+  /// Whether this is a currency.
+  final bool isForCurrency;
+
+  /// We can be passed a specific currency symbol, regardless of the locale.
+  final String currencySymbol;
+
+  final String currencyName;
+
+  // The result being constructed.
+  final NumberFormatParseResult result;
+
+  bool groupingSizeSetExplicitly = false;
+
+  /// Create a new [_NumberFormatParser] for a particular [NumberFormat] and
+  /// [input] pattern.
+  ///
+  /// [decimalDigits] is optional, if specified it overrides the default.
+  NumberFormatParser(this.symbols, String input, this.isForCurrency,
+      this.currencySymbol, this.currencyName, int decimalDigits)
+      : result = NumberFormatParseResult(symbols, decimalDigits),
+        pattern = StringIterator(input) {
+    pattern.moveNext();
+  }
+
+  static NumberFormatParseResult parse(
+          NumberSymbols symbols,
+          String input,
+          bool isForCurrency,
+          String currencySymbol,
+          String currencyName,
+          int decimalDigits) =>
+      input == null
+          ? NumberFormatParseResult(symbols, decimalDigits)
+          : (NumberFormatParser(symbols, input, isForCurrency, currencySymbol,
+                  currencyName, decimalDigits)
+                .._parse())
+              .result;
+
+  /// For currencies, the default number of decimal places to use in
+  /// formatting. Defaults to two for non-currencies or currencies where it's
+  /// not specified.
+  int get _defaultDecimalDigits =>
+      currencyFractionDigits[currencyName.toUpperCase()] ??
+      currencyFractionDigits['DEFAULT'];
+
+  /// Parse the input pattern and update [result].
+  void _parse() {
+    result.positivePrefix = _parseAffix();
+    var trunk = _parseTrunk();
+    result.positiveSuffix = _parseAffix();
+    // If we have separate positive and negative patterns, now parse the
+    // the negative version.
+    if (pattern.current == NumberFormatParser.PATTERN_SEPARATOR) {
+      pattern.moveNext();
+      result.negativePrefix = _parseAffix();
+      // Skip over the negative trunk, verifying that it's identical to the
+      // positive trunk.
+      for (var each in StringIterable(trunk)) {
+        if (pattern.current != each && pattern.current != null) {
+          throw FormatException(
+              'Positive and negative trunks must be the same', trunk);
+        }
+        pattern.moveNext();
+      }
+      result.negativeSuffix = _parseAffix();
+    } else {
+      // If no negative affix is specified, they share the same positive affix.
+      result.negativePrefix = result.negativePrefix + result.positivePrefix;
+      result.negativeSuffix = result.positiveSuffix + result.negativeSuffix;
+    }
+
+    if (isForCurrency) {
+      result.decimalDigits ??= _defaultDecimalDigits;
+    }
+    if (result.decimalDigits != null) {
+      result.minimumFractionDigits = result.decimalDigits;
+      result.maximumFractionDigits = result.decimalDigits;
+    }
+  }
+
+  /// Variable used in parsing prefixes and suffixes to keep track of
+  /// whether or not we are in a quoted region.
+  bool inQuote = false;
+
+  /// Parse a prefix or suffix and return the prefix/suffix string. Note that
+  /// this also may modify the state of [format].
+  String _parseAffix() {
+    var affix = StringBuffer();
+    inQuote = false;
+    while (parseCharacterAffix(affix) && pattern.moveNext()) {}
+    return affix.toString();
+  }
+
+  /// Parse an individual character as part of a prefix or suffix.  Return true
+  /// if we should continue to look for more affix characters, and false if
+  /// we have reached the end.
+  bool parseCharacterAffix(StringBuffer affix) {
+    var ch = pattern.current;
+    if (ch == null) return false;
+    if (ch == QUOTE) {
+      if (pattern.peek == QUOTE) {
+        pattern.moveNext();
+        affix.write(QUOTE); // 'don''t'
+      } else {
+        inQuote = !inQuote;
+      }
+      return true;
+    }
+
+    if (inQuote) {
+      affix.write(ch);
+    } else {
+      switch (ch) {
+        case PATTERN_DIGIT:
+        case PATTERN_ZERO_DIGIT:
+        case PATTERN_GROUPING_SEPARATOR:
+        case PATTERN_DECIMAL_SEPARATOR:
+        case PATTERN_SEPARATOR:
+          return false;
+        case PATTERN_CURRENCY_SIGN:
+          // TODO(alanknight): Handle the local/global/portable currency signs
+          affix.write(currencySymbol);
+          break;
+        case PATTERN_PERCENT:
+          if (result.multiplier != 1 && result.multiplier != PERCENT_SCALE) {
+            throw const FormatException('Too many percent/permill');
+          }
+          result.multiplier = PERCENT_SCALE;
+          affix.write(symbols.PERCENT);
+          break;
+        case PATTERN_PER_MILLE:
+          if (result.multiplier != 1 && result.multiplier != PER_MILLE_SCALE) {
+            throw const FormatException('Too many percent/permill');
+          }
+          result.multiplier = PER_MILLE_SCALE;
+          affix.write(symbols.PERMILL);
+          break;
+        default:
+          affix.write(ch);
+      }
+    }
+    return true;
+  }
+
+  /// Variables used in [_parseTrunk] and [parseTrunkCharacter].
+  var decimalPos = -1;
+  var digitLeftCount = 0;
+  var zeroDigitCount = 0;
+  var digitRightCount = 0;
+  var groupingCount = -1;
+
+  /// Parse the "trunk" portion of the pattern, the piece that doesn't include
+  /// positive or negative prefixes or suffixes.
+  String _parseTrunk() {
+    var loop = true;
+    var trunk = StringBuffer();
+    while (pattern.current != null && loop) {
+      loop = parseTrunkCharacter(trunk);
+    }
+
+    if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
+      // Handle '###.###' and '###.' and '.###'
+      // Handle '.###'
+      var n = decimalPos == 0 ? 1 : decimalPos;
+      digitRightCount = digitLeftCount - n;
+      digitLeftCount = n - 1;
+      zeroDigitCount = 1;
+    }
+
+    // Do syntax checking on the digits.
+    if (decimalPos < 0 && digitRightCount > 0 ||
+        decimalPos >= 0 &&
+            (decimalPos < digitLeftCount ||
+                decimalPos > digitLeftCount + zeroDigitCount) ||
+        groupingCount == 0) {
+      throw FormatException('Malformed pattern "${pattern.input}"');
+    }
+    var totalDigits = digitLeftCount + zeroDigitCount + digitRightCount;
+
+    result.maximumFractionDigits =
+        decimalPos >= 0 ? totalDigits - decimalPos : 0;
+    if (decimalPos >= 0) {
+      result.minimumFractionDigits =
+          digitLeftCount + zeroDigitCount - decimalPos;
+      if (result.minimumFractionDigits < 0) {
+        result.minimumFractionDigits = 0;
+      }
+    }
+
+    // The effectiveDecimalPos is the position the decimal is at or would be at
+    // if there is no decimal. Note that if decimalPos<0, then digitTotalCount
+    // == digitLeftCount + zeroDigitCount.
+    var effectiveDecimalPos = decimalPos >= 0 ? decimalPos : totalDigits;
+    result.minimumIntegerDigits = effectiveDecimalPos - digitLeftCount;
+    if (result.useExponentialNotation) {
+      result.maximumIntegerDigits =
+          digitLeftCount + result.minimumIntegerDigits;
+
+      // In exponential display, we need to at least show something.
+      if (result.maximumFractionDigits == 0 &&
+          result.minimumIntegerDigits == 0) {
+        result.minimumIntegerDigits = 1;
+      }
+    }
+
+    result.finalGroupingSize = max(0, groupingCount);
+    if (!groupingSizeSetExplicitly) {
+      result.groupingSize = result.finalGroupingSize;
+    }
+    result.decimalSeparatorAlwaysShown =
+        decimalPos == 0 || decimalPos == totalDigits;
+
+    return trunk.toString();
+  }
+
+  /// Parse an individual character of the trunk. Return true if we should
+  /// continue to look for additional trunk characters or false if we have
+  /// reached the end.
+  bool parseTrunkCharacter(trunk) {
+    var ch = pattern.current;
+    switch (ch) {
+      case PATTERN_DIGIT:
+        if (zeroDigitCount > 0) {
+          digitRightCount++;
+        } else {
+          digitLeftCount++;
+        }
+        if (groupingCount >= 0 && decimalPos < 0) {
+          groupingCount++;
+        }
+        break;
+      case PATTERN_ZERO_DIGIT:
+        if (digitRightCount > 0) {
+          throw FormatException('Unexpected "0" in pattern "${pattern.input}');
+        }
+        zeroDigitCount++;
+        if (groupingCount >= 0 && decimalPos < 0) {
+          groupingCount++;
+        }
+        break;
+      case PATTERN_GROUPING_SEPARATOR:
+        if (groupingCount > 0) {
+          groupingSizeSetExplicitly = true;
+          result.groupingSize = groupingCount;
+        }
+        groupingCount = 0;
+        break;
+      case PATTERN_DECIMAL_SEPARATOR:
+        if (decimalPos >= 0) {
+          throw FormatException(
+              'Multiple decimal separators in pattern "$pattern"');
+        }
+        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
+        break;
+      case PATTERN_EXPONENT:
+        trunk.write(ch);
+        if (result.useExponentialNotation) {
+          throw FormatException(
+              'Multiple exponential symbols in pattern "$pattern"');
+        }
+        result.useExponentialNotation = true;
+        result.minimumExponentDigits = 0;
+
+        // exponent pattern can have a optional '+'.
+        pattern.moveNext();
+        var nextChar = pattern.current;
+        if (nextChar == PATTERN_PLUS) {
+          trunk.write(pattern.current);
+          pattern.moveNext();
+          result.useSignForPositiveExponent = true;
+        }
+
+        // Use lookahead to parse out the exponential part
+        // of the pattern, then jump into phase 2.
+        while (pattern.current == PATTERN_ZERO_DIGIT) {
+          trunk.write(pattern.current);
+          pattern.moveNext();
+          result.minimumExponentDigits++;
+        }
+
+        if ((digitLeftCount + zeroDigitCount) < 1 ||
+            result.minimumExponentDigits < 1) {
+          throw FormatException('Malformed exponential pattern "$pattern"');
+        }
+        return false;
+      default:
+        return false;
+    }
+    trunk.write(ch);
+    pattern.moveNext();
+    return true;
+  }
+}
+
+final _ln10 = log(10);
diff --git a/lib/src/intl/number_parser.dart b/lib/src/intl/number_parser.dart
new file mode 100644
index 0000000..318a18b
--- /dev/null
+++ b/lib/src/intl/number_parser.dart
@@ -0,0 +1,242 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// @dart=2.9
+
+import 'package:intl/number_symbols.dart';
+
+import 'constants.dart' as constants;
+import 'intl_stream.dart';
+import 'number_format.dart';
+import 'number_format_parser.dart';
+
+///  A one-time object for parsing a particular numeric string. One-time here
+/// means an instance can only parse one string. This is implemented by
+/// transforming from a locale-specific format to one that the system can parse,
+/// then calls the system parsing methods on it.
+class NumberParser {
+  /// The format for which we are parsing.
+  final NumberFormat format;
+
+  /// The text we are parsing.
+  final String text;
+
+  /// What we use to iterate over the input text.
+  final IntlStream input;
+
+  /// The result of parsing [text] according to [format]. Automatically
+  /// populated in the constructor.
+  num value;
+
+  /// The symbols used by our format.
+  NumberSymbols get symbols => format.symbols;
+
+  /// Where we accumulate the normalized representation of the number.
+  final StringBuffer _normalized = StringBuffer();
+
+  /// Did we see something that indicates this is, or at least might be,
+  /// a positive number.
+  bool gotPositive = false;
+
+  /// Did we see something that indicates this is, or at least might be,
+  /// a negative number.
+  bool gotNegative = false;
+
+  /// Did we see the required positive suffix at the end. Should
+  /// match [gotPositive].
+  bool gotPositiveSuffix = false;
+
+  /// Did we see the required negative suffix at the end. Should
+  /// match [gotNegative].
+  bool gotNegativeSuffix = false;
+
+  /// Should we stop parsing before hitting the end of the string.
+  bool done = false;
+
+  /// Have we already skipped over any required prefixes.
+  bool prefixesSkipped = false;
+
+  /// If the number is percent or permill, what do we divide by at the end.
+  int scale = 1;
+
+  String get _positivePrefix => format.positivePrefix;
+  String get _negativePrefix => format.negativePrefix;
+  String get _positiveSuffix => format.positiveSuffix;
+  String get _negativeSuffix => format.negativeSuffix;
+  int get _localeZero => format.localeZero;
+
+  ///  Create a new [_NumberParser] on which we can call parse().
+  NumberParser(this.format, this.text) : input = IntlStream(text) {
+    scale = format.multiplier;
+    value = parse();
+  }
+
+  ///  The strings we might replace with functions that return the replacement
+  /// values. They are functions because we might need to check something
+  /// in the context. Note that the ordering is important here. For example,
+  /// `symbols.PERCENT` might be " %", and we must handle that before we
+  /// look at an individual space.
+  Map<String, Function> get replacements =>
+      _replacements ??= _initializeReplacements();
+
+  Map<String, Function> _replacements;
+
+  Map<String, Function> _initializeReplacements() => {
+        symbols.DECIMAL_SEP: () => '.',
+        symbols.EXP_SYMBOL: () => 'E',
+        symbols.GROUP_SEP: handleSpace,
+        symbols.PERCENT: () {
+          scale = NumberFormatParser.PERCENT_SCALE;
+          return '';
+        },
+        symbols.PERMILL: () {
+          scale = NumberFormatParser.PER_MILLE_SCALE;
+          return '';
+        },
+        ' ': handleSpace,
+        '\u00a0': handleSpace,
+        '+': () => '+',
+        '-': () => '-',
+      };
+
+  void invalidFormat() =>
+      throw FormatException('Invalid number: ${input.contents}');
+
+  /// Replace a space in the number with the normalized form. If space is not
+  /// a significant character (normally grouping) then it's just invalid. If it
+  /// is the grouping character, then it's only valid if it's followed by a
+  /// digit. e.g. '$12 345.00'
+  void handleSpace() =>
+      groupingIsNotASpaceOrElseItIsSpaceFollowedByADigit ? '' : invalidFormat();
+
+  /// Determine if a space is a valid character in the number. See
+  /// [handleSpace].
+  bool get groupingIsNotASpaceOrElseItIsSpaceFollowedByADigit {
+    if (symbols.GROUP_SEP != '\u00a0' || symbols.GROUP_SEP != ' ') return true;
+    var peeked = input.peek(symbols.GROUP_SEP.length + 1);
+    return asDigit(peeked[peeked.length - 1]) != null;
+  }
+
+  /// Turn [char] into a number representing a digit, or null if it doesn't
+  /// represent a digit in this locale.
+  int asDigit(String char) {
+    var charCode = char.codeUnitAt(0);
+    var digitValue = charCode - _localeZero;
+    if (digitValue >= 0 && digitValue < 10) {
+      return digitValue;
+    } else {
+      return null;
+    }
+  }
+
+  /// Check to see if the input begins with either the positive or negative
+  /// prefixes. Set the [gotPositive] and [gotNegative] variables accordingly.
+  void checkPrefixes({bool skip = false}) {
+    bool checkPrefix(String prefix) =>
+        prefix.isNotEmpty && input.startsWith(prefix);
+
+    // TODO(alanknight): There's a faint possibility of a bug here where
+    // a positive prefix is followed by a negative prefix that's also a valid
+    // part of the number, but that seems very unlikely.
+    if (checkPrefix(_positivePrefix)) gotPositive = true;
+    if (checkPrefix(_negativePrefix)) gotNegative = true;
+
+    // The positive prefix might be a substring of the negative, in
+    // which case both would match.
+    if (gotPositive && gotNegative) {
+      if (_positivePrefix.length > _negativePrefix.length) {
+        gotNegative = false;
+      } else if (_negativePrefix.length > _positivePrefix.length) {
+        gotPositive = false;
+      }
+    }
+    if (skip) {
+      if (gotPositive) input.read(_positivePrefix.length);
+      if (gotNegative) input.read(_negativePrefix.length);
+    }
+  }
+
+  /// If the rest of our input is either the positive or negative suffix,
+  /// set [gotPositiveSuffix] or [gotNegativeSuffix] accordingly.
+  void checkSuffixes() {
+    var remainder = input.rest();
+    if (remainder == _positiveSuffix) gotPositiveSuffix = true;
+    if (remainder == _negativeSuffix) gotNegativeSuffix = true;
+  }
+
+  /// We've encountered a character that's not a digit. Go through our
+  /// replacement rules looking for how to handle it. If we see something
+  /// that's not a digit and doesn't have a replacement, then we're done
+  /// and the number is probably invalid.
+  void processNonDigit() {
+    // It might just be a prefix that we haven't skipped. We don't want to
+    // skip them initially because they might also be semantically meaningful,
+    // e.g. leading %. So we allow them through the loop, but only once.
+    var foundAnInterpretation = false;
+    if (input.index == 0 && !prefixesSkipped) {
+      prefixesSkipped = true;
+      checkPrefixes(skip: true);
+      foundAnInterpretation = true;
+    }
+
+    for (var key in replacements.keys) {
+      if (input.startsWith(key)) {
+        _normalized.write(replacements[key]());
+        input.read(key.length);
+        return;
+      }
+    }
+    // We haven't found either of these things, this seems invalid.
+    if (!foundAnInterpretation) {
+      done = true;
+    }
+  }
+
+  /// Parse [text] and return the resulting number. Throws [FormatException]
+  /// if we can't parse it.
+  num parse() {
+    if (text == symbols.NAN) return 0.0 / 0.0;
+    if (text == '$_positivePrefix${symbols.INFINITY}$_positiveSuffix') {
+      return 1.0 / 0.0;
+    }
+    if (text == '$_negativePrefix${symbols.INFINITY}$_negativeSuffix') {
+      return -1.0 / 0.0;
+    }
+
+    checkPrefixes();
+    var parsed = parseNumber(input);
+
+    if (gotPositive && !gotPositiveSuffix) invalidNumber();
+    if (gotNegative && !gotNegativeSuffix) invalidNumber();
+    if (!input.atEnd()) invalidNumber();
+
+    return parsed;
+  }
+
+  /// The number is invalid, throw a [FormatException].
+  void invalidNumber() =>
+      throw FormatException('Invalid Number: ${input.contents}');
+
+  /// Parse the number portion of the input, i.e. not any prefixes or suffixes,
+  /// and assuming NaN and Infinity are already handled.
+  num parseNumber(IntlStream input) {
+    if (gotNegative) {
+      _normalized.write('-');
+    }
+    while (!done && !input.atEnd()) {
+      var digit = asDigit(input.peek());
+      if (digit != null) {
+        _normalized.writeCharCode(constants.asciiZeroCodeUnit + digit);
+        input.next();
+      } else {
+        processNonDigit();
+      }
+      checkSuffixes();
+    }
+
+    var normalizedText = _normalized.toString();
+    num parsed = int.tryParse(normalizedText);
+    parsed ??= double.parse(normalizedText);
+    return parsed / scale;
+  }
+}
diff --git a/lib/src/intl/string_iterator.dart b/lib/src/intl/string_iterator.dart
new file mode 100644
index 0000000..839574d
--- /dev/null
+++ b/lib/src/intl/string_iterator.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// @dart=2.9
+
+// TODO(nweiz): remove this when issue 3780 is fixed.
+import 'dart:collection';
+
+/// Provides an Iterable that wraps [_iterator] so it can be used in a `for`
+/// loop.
+class StringIterable extends IterableBase<String> {
+  final Iterator<String> iterator;
+
+  StringIterable(String s) : iterator = StringIterator(s);
+}
+
+/// Provides an iterator over a string as a list of substrings, and also
+/// gives us a lookahead of one via the [peek] method.
+class StringIterator implements Iterator<String> {
+  final String input;
+  int nextIndex = 0;
+  String _current;
+
+  StringIterator(input) : input = _validate(input);
+
+  String get current => _current;
+
+  bool moveNext() {
+    if (nextIndex >= input.length) {
+      _current = null;
+      return false;
+    }
+    _current = input[nextIndex++];
+    return true;
+  }
+
+  String get peek => nextIndex >= input.length ? null : input[nextIndex];
+
+  Iterator<String> get iterator => this;
+
+  static String _validate(input) {
+    if (input is! String) throw ArgumentError(input);
+    return input;
+  }
+}
